Skip to content

Commit 0ee3de3

Browse files
committed
Subscription IT: intro retry rule for flaky tests (#15698)
1 parent f3a06cc commit 0ee3de3

File tree

5 files changed

+125
-0
lines changed

5 files changed

+125
-0
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.apache.iotdb.subscription.it;
21+
22+
import java.lang.annotation.ElementType;
23+
import java.lang.annotation.Retention;
24+
import java.lang.annotation.RetentionPolicy;
25+
import java.lang.annotation.Target;
26+
27+
/** Marks a test method to specify how many times it should be retried (first run + retries). */
28+
@Retention(RetentionPolicy.RUNTIME)
29+
@Target(ElementType.METHOD)
30+
public @interface Retry {
31+
/** Total execution count = 1 (initial run) + number of retries */
32+
int times() default 3;
33+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.apache.iotdb.subscription.it;
21+
22+
import org.junit.rules.TestRule;
23+
import org.junit.runner.Description;
24+
import org.junit.runners.model.Statement;
25+
26+
/** Controls retry logic for test failures based on the {@link Retry} annotation. */
27+
public class RetryRule implements TestRule {
28+
29+
@Override
30+
public Statement apply(final Statement base, final Description description) {
31+
// Read the annotation on the method; if absent, do not retry (times = 1)
32+
final Retry retry = description.getAnnotation(Retry.class);
33+
final int times = (retry != null ? retry.times() : 1);
34+
return new RetryStatement(base, description, times);
35+
}
36+
37+
private static class RetryStatement extends Statement {
38+
private final Statement base;
39+
private final Description description;
40+
private final int times;
41+
42+
RetryStatement(final Statement base, final Description description, final int times) {
43+
this.base = base;
44+
this.description = description;
45+
this.times = times;
46+
}
47+
48+
@Override
49+
public void evaluate() throws Throwable {
50+
Throwable lastThrowable;
51+
for (int i = 1; i <= times; i++) {
52+
try {
53+
base.evaluate();
54+
return; // Return immediately on success
55+
} catch (final Throwable t) {
56+
lastThrowable = t;
57+
System.err.printf(
58+
"[%s] run %d/%d failed: %s%n",
59+
description.getDisplayName(), i, times, t.getMessage());
60+
if (i == times) {
61+
// If it's the last attempt, and it still fails, throw the exception
62+
throw lastThrowable;
63+
}
64+
// Otherwise, continue to the next retry
65+
}
66+
}
67+
}
68+
}
69+
}

integration-test/src/test/java/org/apache/iotdb/subscription/it/triple/regression/pushconsumer/mode/IoTDBSnapshotTSPatternDatasetPushConsumerIT.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import org.apache.iotdb.session.subscription.consumer.ConsumeResult;
2929
import org.apache.iotdb.session.subscription.consumer.SubscriptionPushConsumer;
3030
import org.apache.iotdb.session.subscription.payload.SubscriptionSessionDataSet;
31+
import org.apache.iotdb.subscription.it.Retry;
32+
import org.apache.iotdb.subscription.it.RetryRule;
3133
import org.apache.iotdb.subscription.it.triple.regression.AbstractSubscriptionRegressionIT;
3234

3335
import org.apache.thrift.TException;
@@ -38,6 +40,7 @@
3840
import org.apache.tsfile.write.schema.MeasurementSchema;
3941
import org.junit.After;
4042
import org.junit.Before;
43+
import org.junit.Rule;
4144
import org.junit.Test;
4245
import org.junit.experimental.categories.Category;
4346
import org.junit.runner.RunWith;
@@ -56,6 +59,9 @@
5659
@RunWith(IoTDBTestRunner.class)
5760
@Category({MultiClusterIT2SubscriptionRegressionConsumer.class})
5861
public class IoTDBSnapshotTSPatternDatasetPushConsumerIT extends AbstractSubscriptionRegressionIT {
62+
63+
@Rule public RetryRule retryRule = new RetryRule();
64+
5965
private static final String database = "root.test.SnapshotTSPatternDatasetPushConsumer";
6066
private static final String database2 = "root.SnapshotTSPatternDatasetPushConsumer";
6167
private static final String device = database + ".d_0";
@@ -108,6 +114,7 @@ public void tearDown() throws Exception {
108114
subs.dropTopic(topicName);
109115
dropDB(database);
110116
dropDB(database2);
117+
schemaList.clear();
111118
super.tearDown();
112119
}
113120

@@ -127,6 +134,7 @@ private void insert_data(long timestamp)
127134
}
128135

129136
@Test
137+
@Retry
130138
public void do_test()
131139
throws InterruptedException,
132140
TException,

integration-test/src/test/java/org/apache/iotdb/subscription/it/triple/regression/pushconsumer/mode/IoTDBSnapshotTSPatternTsfilePushConsumerIT.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import org.apache.iotdb.session.subscription.consumer.AckStrategy;
2828
import org.apache.iotdb.session.subscription.consumer.ConsumeResult;
2929
import org.apache.iotdb.session.subscription.consumer.SubscriptionPushConsumer;
30+
import org.apache.iotdb.subscription.it.Retry;
31+
import org.apache.iotdb.subscription.it.RetryRule;
3032
import org.apache.iotdb.subscription.it.triple.regression.AbstractSubscriptionRegressionIT;
3133

3234
import org.apache.thrift.TException;
@@ -42,6 +44,7 @@
4244
import org.apache.tsfile.write.schema.MeasurementSchema;
4345
import org.junit.After;
4446
import org.junit.Before;
47+
import org.junit.Rule;
4548
import org.junit.Test;
4649
import org.junit.experimental.categories.Category;
4750
import org.junit.runner.RunWith;
@@ -63,6 +66,9 @@
6366
@RunWith(IoTDBTestRunner.class)
6467
@Category({MultiClusterIT2SubscriptionRegressionConsumer.class})
6568
public class IoTDBSnapshotTSPatternTsfilePushConsumerIT extends AbstractSubscriptionRegressionIT {
69+
70+
@Rule public RetryRule retryRule = new RetryRule();
71+
6672
private static final String database = "root.test.SnapshotTSPatternTsfilePushConsumer";
6773
private static final String database2 = "root.SnapshotTSPatternTsfilePushConsumer";
6874
private static final String device = database + ".d_0";
@@ -122,6 +128,7 @@ public void tearDown() throws Exception {
122128
subs.dropTopic(topicName);
123129
dropDB(database);
124130
dropDB(database2);
131+
schemaList.clear();
125132
super.tearDown();
126133
}
127134

@@ -141,6 +148,7 @@ private void insert_data(long timestamp)
141148
}
142149

143150
@Test
151+
@Retry
144152
public void do_test()
145153
throws InterruptedException,
146154
TException,

integration-test/src/test/java/org/apache/iotdb/subscription/it/triple/regression/pushconsumer/multi/IoTDBOneConsumerMultiTopicsTsfileIT.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
import org.apache.iotdb.session.subscription.consumer.AckStrategy;
2727
import org.apache.iotdb.session.subscription.consumer.ConsumeResult;
2828
import org.apache.iotdb.session.subscription.consumer.SubscriptionPushConsumer;
29+
import org.apache.iotdb.subscription.it.Retry;
30+
import org.apache.iotdb.subscription.it.RetryRule;
2931
import org.apache.iotdb.subscription.it.triple.regression.AbstractSubscriptionRegressionIT;
3032

3133
import org.apache.thrift.TException;
@@ -41,6 +43,7 @@
4143
import org.apache.tsfile.write.schema.MeasurementSchema;
4244
import org.junit.After;
4345
import org.junit.Before;
46+
import org.junit.Rule;
4447
import org.junit.Test;
4548
import org.junit.experimental.categories.Category;
4649
import org.junit.runner.RunWith;
@@ -60,6 +63,9 @@
6063
@RunWith(IoTDBTestRunner.class)
6164
@Category({MultiClusterIT2SubscriptionRegressionConsumer.class})
6265
public class IoTDBOneConsumerMultiTopicsTsfileIT extends AbstractSubscriptionRegressionIT {
66+
67+
@Rule public RetryRule retryRule = new RetryRule();
68+
6369
private static final String database = "root.test.OneConsumerMultiTopicsTsfile";
6470
private static final String database2 = "root.OneConsumerMultiTopicsTsfile";
6571
private static final String device = database + ".d_0";
@@ -122,6 +128,7 @@ private void insert_data(long timestamp, String device)
122128
}
123129

124130
@Test
131+
@Retry
125132
public void do_test()
126133
throws InterruptedException,
127134
TException,

0 commit comments

Comments
 (0)