Skip to content

Commit 0f2967a

Browse files
committed
Improved tests for MqttSubscriptionFlowTree
1 parent 0cc70ff commit 0f2967a

File tree

2 files changed

+110
-2
lines changed

2 files changed

+110
-2
lines changed

src/test/java/com/hivemq/client/internal/mqtt/handler/publish/incoming/MqttSubscriptionFlowTreeTest.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,60 @@ class MqttSubscriptionFlowTreeTest extends MqttSubscriptionFlowsTest {
3636

3737
@ParameterizedTest
3838
@CsvSource({
39+
// split single level before and after
3940
"unsubscribe, test/topic1, test/topic2, test/topic3, test/topic1, test/topic2, test/topic3",
41+
// split single level before, single level wildcard after
4042
"unsubscribe, test/+, test/topic2, test/topic3, test/topic1, test/topic2, test/topic3",
43+
// split single level before, single level wildcard after, fuse different order
44+
"unsubscribe, test/topic1, test/topic2, test/+, test/topic1, test/topic2, test/topic3",
45+
// split multiple levels before, single level after
4146
"unsubscribe, test/topic/filter1, test/topic/filter2, test/topic/filter3, test/topic/filter1, test/topic/filter2, test/topic/filter3",
47+
// split multiple levels before, single level wildcard after
4248
"unsubscribe, test/topic/+, test/topic/filter2, test/topic/filter3, test/topic/filter1, test/topic/filter2, test/topic/filter3",
49+
// split multiple levels before, single level wildcard after, fuse different order
50+
"unsubscribe, test/topic/filter1, test/topic/filter2, test/topic/+, test/topic/filter1, test/topic/filter2, test/topic/filter3",
51+
// split single level before, multiple levels after
4352
"unsubscribe, test/topic1/filter, test/topic2/filter, test/topic3/filter, test/topic1/filter, test/topic2/filter, test/topic3/filter",
53+
// split single level before, single level wildcard with multiple levels after
4454
"unsubscribe, test/+/filter, test/topic2/filter, test/topic3/filter, test/topic1/filter, test/topic2/filter, test/topic3/filter",
55+
// split single level before, single level wildcard with multiple levels after, fuse different order
56+
"unsubscribe, test/topic1/filter, test/topic2/filter, test/+/filter, test/topic1/filter, test/topic2/filter, test/topic3/filter",
57+
// split multiple levels before, multiple levels after
58+
"unsubscribe, test/topic/filter1/abc, test/topic/filter2/abc, test/topic/filter3/abc, test/topic/filter1/abc, test/topic/filter2/abc, test/topic/filter3/abc",
59+
// split multi levels before, single level wildcard with multiple levels after
60+
"unsubscribe, test/topic/+/abc, test/topic/filter2/abc, test/topic/filter3/abc, test/topic/filter1/abc, test/topic/filter2/abc, test/topic/filter3/abc",
61+
// split multi levels before, single level wildcard with multiple levels after, fuse different order
62+
"unsubscribe, test/topic/filter1/abc, test/topic/filter2/abc, test/topic/+/abc, test/topic/filter1/abc, test/topic/filter2/abc, test/topic/filter3/abc",
63+
// split single level wildcard before, single level after
64+
"unsubscribe, +/topic1, +/topic2, +/topic3, test/topic1, test/topic2, test/topic3",
65+
// split single level wildcard before, multiple levels after
66+
"unsubscribe, +/topic1/filter, +/topic2/filter, +/topic3/filter, test/topic1/filter, test/topic2/filter, test/topic3/filter",
67+
// split single level wildcard with multiple levels before, single level after
68+
"unsubscribe, +/topic/filter1, +/topic/filter2, +/topic/filter3, test/topic/filter1, test/topic/filter2, test/topic/filter3",
69+
// split single level wildcard with multiple levels before, multiple levels after
70+
"unsubscribe, +/topic/filter1/abc, +/topic/filter2/abc, +/topic/filter3/abc, test/topic/filter1/abc, test/topic/filter2/abc, test/topic/filter3/abc",
71+
// split linear chain
4572
"unsubscribe, test/topic/filter, test/topic//filter, test/topic///filter, test/topic/filter, test/topic//filter, test/topic///filter",
73+
// split linear chain, do not fuse
74+
"unsubscribe, test/topic/filter, test/topic//filter, test/topic///filter, test/topic///filter, test/topic//filter, test/topic/filter",
4675
"remove, test/topic1, test/topic2, test/topic3, test/topic1, test/topic2, test/topic3",
4776
"remove, test/+, test/topic2, test/topic3, test/topic1, test/topic2, test/topic3",
77+
"remove, test/topic1, test/topic2, test/+, test/topic1, test/topic2, test/topic3",
4878
"remove, test/topic/filter1, test/topic/filter2, test/topic/filter3, test/topic/filter1, test/topic/filter2, test/topic/filter3",
4979
"remove, test/topic/+, test/topic/filter2, test/topic/filter3, test/topic/filter1, test/topic/filter2, test/topic/filter3",
80+
"remove, test/topic/filter1, test/topic/filter2, test/topic/+, test/topic/filter1, test/topic/filter2, test/topic/filter3",
5081
"remove, test/topic1/filter, test/topic2/filter, test/topic3/filter, test/topic1/filter, test/topic2/filter, test/topic3/filter",
5182
"remove, test/+/filter, test/topic2/filter, test/topic3/filter, test/topic1/filter, test/topic2/filter, test/topic3/filter",
83+
"remove, test/topic1/filter, test/topic2/filter, test/+/filter, test/topic1/filter, test/topic2/filter, test/topic3/filter",
84+
"remove, test/topic/filter1/abc, test/topic/filter2/abc, test/topic/filter3/abc, test/topic/filter1/abc, test/topic/filter2/abc, test/topic/filter3/abc",
85+
"remove, test/topic/+/abc, test/topic/filter2/abc, test/topic/filter3/abc, test/topic/filter1/abc, test/topic/filter2/abc, test/topic/filter3/abc",
86+
"remove, test/topic/filter1/abc, test/topic/filter2/abc, test/topic/+/abc, test/topic/filter1/abc, test/topic/filter2/abc, test/topic/filter3/abc",
87+
"remove, +/filter1, +/filter2, +/filter3, topic/filter1, topic/filter2, topic/filter3",
88+
"remove, +/topic1/filter, +/topic2/filter, +/topic3/filter, test/topic1/filter, test/topic2/filter, test/topic3/filter",
89+
"remove, +/topic/filter1, +/topic/filter2, +/topic/filter3, test/topic/filter1, test/topic/filter2, test/topic/filter3",
90+
"remove, +/topic/filter1/abc, +/topic/filter2/abc, +/topic/filter3/abc, test/topic/filter1/abc, test/topic/filter2/abc, test/topic/filter3/abc",
5291
"remove, test/topic/filter, test/topic//filter, test/topic///filter, test/topic/filter, test/topic//filter, test/topic///filter",
92+
"remove, test/topic/filter, test/topic//filter, test/topic///filter, test/topic///filter, test/topic//filter, test/topic/filter",
5393
})
5494
void branching_compaction(
5595
final @NotNull String compactOperation, final @NotNull String filter1, final @NotNull String filter2,

src/test/java/com/hivemq/client/internal/mqtt/handler/publish/incoming/MqttSubscriptionFlowsTest.java

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.hivemq.client.internal.util.collections.HandleList;
2424
import org.jetbrains.annotations.NotNull;
2525
import org.junit.jupiter.api.BeforeEach;
26+
import org.junit.jupiter.api.Test;
2627
import org.junit.jupiter.params.ParameterizedTest;
2728
import org.junit.jupiter.params.converter.ArgumentConversionException;
2829
import org.junit.jupiter.params.converter.ConvertWith;
@@ -32,8 +33,7 @@
3233
import java.util.function.Supplier;
3334

3435
import static org.junit.jupiter.api.Assertions.*;
35-
import static org.mockito.Mockito.mock;
36-
import static org.mockito.Mockito.when;
36+
import static org.mockito.Mockito.*;
3737

3838
/**
3939
* @author Silvio Giebl
@@ -270,6 +270,23 @@ void cancel_notPresentFlows_areIgnored(final @NotNull String topic, final @NotNu
270270
assertEquals(ImmutableSet.of(flow1), ImmutableSet.copyOf(matching));
271271
}
272272

273+
@Test
274+
void cancel_partiallyUnsubscribedFlow() {
275+
final MqttSubscribedPublishFlow flow = mockSubscriptionFlow("test/topic(2)");
276+
flows.subscribe(MqttTopicFilterImpl.of("test/topic"), flow);
277+
flows.subscribe(MqttTopicFilterImpl.of("test/topic2"), flow);
278+
279+
flows.unsubscribe(MqttTopicFilterImpl.of("test/topic"), null);
280+
flows.cancel(flow);
281+
282+
final MqttMatchingPublishFlows matching = new MqttMatchingPublishFlows();
283+
flows.findMatching(MqttTopicImpl.of("test/topic"), matching);
284+
assertFalse(matching.subscriptionFound);
285+
flows.findMatching(MqttTopicImpl.of("test/topic2"), matching);
286+
assertTrue(matching.subscriptionFound);
287+
assertTrue(matching.isEmpty());
288+
}
289+
273290
@ParameterizedTest
274291
@CsvSource({
275292
"1/a, 1/a, 2/a, 2/a", "1/a, 1/+, 2/a, 2/+", "1/a, 1/#, 2/a, 2/#", "1/a/b, 1/a/b, 2/a/b, 2/a/b",
@@ -364,6 +381,57 @@ void remove_doesNotUnsubscribe_noFlow(final @NotNull String topic, final @NotNul
364381
assertTrue(matching.isEmpty());
365382
}
366383

384+
@ParameterizedTest
385+
@CsvSource({"a/b, a/b/c, +/b/c, +/+/+", "a/b/c/d, a/b/c/d/e, +/b//d/ec, +/+/+/+/+"})
386+
void findMatching_matchingMultipleButNotAllLevels(
387+
final @NotNull String topic, final @NotNull String filter1, final @NotNull String filter2,
388+
final @NotNull String filter3) {
389+
390+
flows.subscribe(MqttTopicFilterImpl.of(filter1), null);
391+
flows.subscribe(MqttTopicFilterImpl.of(filter2), null);
392+
flows.subscribe(MqttTopicFilterImpl.of(filter3), null);
393+
394+
final MqttMatchingPublishFlows matching = new MqttMatchingPublishFlows();
395+
flows.findMatching(MqttTopicImpl.of(topic), matching);
396+
assertFalse(matching.subscriptionFound);
397+
assertTrue(matching.isEmpty());
398+
}
399+
400+
@Test
401+
void clear() {
402+
final MqttSubscribedPublishFlow flow1 = mockSubscriptionFlow("test/topic/filter");
403+
final MqttSubscribedPublishFlow flow2 = mockSubscriptionFlow("test2/topic/filter");
404+
final MqttSubscribedPublishFlow flow3 = mockSubscriptionFlow("test/topic2/filter");
405+
final MqttSubscribedPublishFlow flow4 = mockSubscriptionFlow("test/topic/filter2");
406+
final MqttSubscribedPublishFlow flow5 = mockSubscriptionFlow("+/topic");
407+
final MqttSubscribedPublishFlow flow6 = mockSubscriptionFlow("topic/#");
408+
flows.subscribe(MqttTopicFilterImpl.of(flow1.toString()), flow1);
409+
flows.subscribe(MqttTopicFilterImpl.of(flow2.toString()), flow2);
410+
flows.subscribe(MqttTopicFilterImpl.of(flow3.toString()), flow3);
411+
flows.subscribe(MqttTopicFilterImpl.of(flow4.toString()), flow4);
412+
flows.subscribe(MqttTopicFilterImpl.of(flow5.toString()), flow5);
413+
flows.subscribe(MqttTopicFilterImpl.of(flow6.toString()), flow6);
414+
415+
final Exception cause = new Exception("test");
416+
flows.clear(cause);
417+
verify(flow1).onError(cause);
418+
verify(flow2).onError(cause);
419+
verify(flow3).onError(cause);
420+
verify(flow4).onError(cause);
421+
verify(flow5).onError(cause);
422+
verify(flow6).onError(cause);
423+
424+
final MqttMatchingPublishFlows matching = new MqttMatchingPublishFlows();
425+
flows.findMatching(MqttTopicImpl.of("test/topic"), matching);
426+
flows.findMatching(MqttTopicImpl.of("test/topic/filter"), matching);
427+
flows.findMatching(MqttTopicImpl.of("test2/topic/filter"), matching);
428+
flows.findMatching(MqttTopicImpl.of("test/topic2/filter"), matching);
429+
flows.findMatching(MqttTopicImpl.of("test/topic/filter2"), matching);
430+
flows.findMatching(MqttTopicImpl.of("abc/topic"), matching);
431+
flows.findMatching(MqttTopicImpl.of("topic/abc"), matching);
432+
assertFalse(matching.subscriptionFound);
433+
}
434+
367435
@NotNull
368436
private static MqttSubscribedPublishFlow mockSubscriptionFlow(final @NotNull String name) {
369437
final MqttSubscribedPublishFlow flow = mock(MqttSubscribedPublishFlow.class);

0 commit comments

Comments
 (0)