Skip to content

Commit fc88bfd

Browse files
authored
Bug in retries logic was fixed (#141)
* * Bug in retries logic was fixed. The client didn't report if a test failed after retries. We should clean failed Test hashmap after the retries count exceed * New tests was added * * Logic was fixed with tests according to internal code review.
1 parent 9442c06 commit fc88bfd

File tree

4 files changed

+80
-18
lines changed

4 files changed

+80
-18
lines changed

src/main/java/com/github/invictum/reportportal/SuiteStorage.java

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,18 @@
22

33
import io.reactivex.Maybe;
44

5-
import java.util.HashSet;
5+
import java.util.HashMap;
6+
import java.util.Map;
67
import java.util.concurrent.ConcurrentHashMap;
8+
import java.util.concurrent.atomic.AtomicInteger;
79
import java.util.function.Supplier;
810

911
/**
1012
* Abstraction used to control active suites lifecycle
1113
*/
1214
public class SuiteStorage {
1315

14-
private ConcurrentHashMap<String, SuiteMetadata> suites = new ConcurrentHashMap<>();
16+
private final ConcurrentHashMap<String, SuiteMetadata> suites = new ConcurrentHashMap<>();
1517

1618
/**
1719
* Starts a new suite entity
@@ -64,9 +66,9 @@ public void finalizeActive() {
6466
* @param suiteId id of suite where fail test was detected
6567
* @param testId id of failed test
6668
*/
67-
public void addFail(String suiteId, String testId) {
69+
public void addNewFail(String suiteId, String testId) {
6870
SuiteMetadata meta = suites.get(suiteId);
69-
meta.failedTests.add(testId);
71+
meta.failedTests.put(testId, new AtomicInteger(0));
7072
}
7173

7274
/**
@@ -77,7 +79,7 @@ public void addFail(String suiteId, String testId) {
7779
*/
7880
public boolean isFailPresent(String suiteId, String testId) {
7981
SuiteMetadata meta = suites.get(suiteId);
80-
return meta.failedTests.contains(testId);
82+
return meta.failedTests.containsKey(testId);
8183
}
8284

8385
/**
@@ -91,12 +93,25 @@ public void removeFail(String suiteId, String testId) {
9193
meta.failedTests.remove(testId);
9294
}
9395

96+
/**
97+
* Increase count of failed test to track when exceed count of retires.
98+
*
99+
* @param suiteId id of suite where fail test was detected
100+
* @param testId id of failed test
101+
* @return failCount count of retires after ++
102+
*/
103+
public int incrementAndGetRetriesCount(String suiteId, String testId) {
104+
SuiteMetadata meta = suites.get(suiteId);
105+
AtomicInteger failCount = meta.failedTests.get(testId);
106+
return failCount.incrementAndGet();
107+
}
108+
94109
/**
95110
* Node class that holds suite metadata
96111
*/
97112
private static class SuiteMetadata {
98113
private Maybe<String> id;
99114
private Runnable finisher;
100-
private final HashSet<String> failedTests = new HashSet<>();
115+
private final Map<String, AtomicInteger> failedTests = new HashMap<>();
101116
}
102117
}

src/main/java/com/github/invictum/reportportal/recorder/Regular.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,12 @@ private void processRetries(TestOutcome out, StartEventBuilder builder) {
8383
String suiteId = out.getUserStory().getId();
8484
if (suiteStorage.isFailPresent(suiteId, testId)) {
8585
builder.withRetry();
86-
if (!isTestFailed(out)) {
86+
int retriesCount = suiteStorage.incrementAndGetRetriesCount(suiteId, testId);
87+
if (!isTestFailed(out) || retriesCount == RETRIES_COUNT) {
8788
suiteStorage.removeFail(suiteId, testId);
8889
}
8990
} else if (isTestFailed(out)) {
90-
suiteStorage.addFail(suiteId, testId);
91+
suiteStorage.addNewFail(suiteId, testId);
9192
}
9293
}
9394
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.github.invictum.reportportal;
2+
3+
import io.reactivex.Maybe;
4+
import org.junit.Assert;
5+
import org.junit.Before;
6+
import org.junit.Test;
7+
8+
public class SuiteStorageTest {
9+
10+
SuiteStorage storage;
11+
12+
@Before
13+
public void setupStorage() {
14+
storage = new SuiteStorage();
15+
storage.start("suite", Maybe::empty);
16+
}
17+
18+
19+
@Test
20+
public void testAddNewFail() {
21+
storage.addNewFail("suite", "storage");
22+
Assert.assertTrue(storage.isFailPresent("suite", "storage"));
23+
}
24+
25+
@Test
26+
public void testIncrementRetiresCount() {
27+
storage.addNewFail("suite", "storage");
28+
Assert.assertEquals(1, storage.incrementAndGetRetriesCount("suite", "storage"));
29+
Assert.assertEquals(2, storage.incrementAndGetRetriesCount("suite", "storage"));
30+
Assert.assertEquals(3, storage.incrementAndGetRetriesCount("suite", "storage"));
31+
}
32+
33+
}

src/test/java/com/github/invictum/reportportal/recorder/RegularTest.java

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,9 @@ public void regularRecordTest() {
4343
Mockito.when(testOutcome.getName()).thenReturn("Test name");
4444
recorder.record(testOutcome);
4545
Mockito.verify(suiteStorageMock,
46-
Mockito.times(1)).start(
47-
Mockito.eq("story"), Mockito.any());
46+
Mockito.times(1)).start(Mockito.eq("story"), Mockito.any());
4847
Mockito.verify(suiteStorageMock,
49-
Mockito.times(1)).suiteFinisher(
50-
Mockito.eq("story"), Mockito.any());
48+
Mockito.times(1)).suiteFinisher(Mockito.eq("story"), Mockito.any());
5149
}
5250

5351
@Test
@@ -62,8 +60,7 @@ public void retryRecordCallIsFailPresentTest() {
6260
Mockito.when(testOutcome.getName()).thenReturn("Test name");
6361
recorder.record(testOutcome);
6462
Mockito.verify(suiteStorageMock,
65-
Mockito.times(1)).isFailPresent(
66-
Mockito.eq("story"), Mockito.eq("testId"));
63+
Mockito.times(1)).isFailPresent("story", "testId");
6764
}
6865

6966
@Test
@@ -82,8 +79,7 @@ public void retryRecordStoreNewFailTest() {
8279
Mockito.when(testOutcome.getResult()).thenReturn(TestResult.FAILURE);
8380
recorder.record(testOutcome);
8481
Mockito.verify(suiteStorageMock,
85-
Mockito.times(2)).addFail(
86-
Mockito.eq("story"), Mockito.eq("testId"));
82+
Mockito.times(2)).addNewFail("story", "testId");
8783
}
8884

8985
@Test
@@ -100,9 +96,26 @@ public void retryRecordClearSuiteIsRetryPassedTest() {
10096
Mockito.when(suiteStorageMock.isFailPresent(Mockito.any(), Mockito.any())).thenReturn(true);
10197
recorder.record(testOutcome);
10298
Mockito.verify(suiteStorageMock,
103-
Mockito.times(1)).removeFail(
104-
Mockito.eq("story"), Mockito.eq("testId"));
99+
Mockito.times(1)).removeFail("story", "testId");
105100
}
106101

107102

103+
@Test
104+
public void retryRecordClearSuiteIfRetryCountExceed() {
105+
System.setProperty(FAILSAFE_RERUN_KEY, "5");
106+
TestRecorder recorder = new Regular(suiteStorageMock, launchMock, logUnitsHolderMock);
107+
TestOutcome testOutcome = Mockito.mock(TestOutcome.class);
108+
Mockito.when(testOutcome.getUserStory()).thenReturn(Story.called("story").withNarrative("narrative"));
109+
Mockito.when(testOutcome.getId()).thenReturn("testId");
110+
Mockito.when(testOutcome.getResult()).thenReturn(TestResult.UNSUCCESSFUL);
111+
ZonedDateTime start = ZonedDateTime.now();
112+
Mockito.when(testOutcome.getStartTime()).thenReturn(start);
113+
Mockito.when(testOutcome.getName()).thenReturn("Test name");
114+
Mockito.when(suiteStorageMock.isFailPresent(Mockito.any(), Mockito.any())).thenReturn(true);
115+
Mockito.when(suiteStorageMock.incrementAndGetRetriesCount(Mockito.any(), Mockito.any())).thenReturn(5);
116+
recorder.record(testOutcome);
117+
Mockito.verify(suiteStorageMock,
118+
Mockito.times(1)).removeFail("story", "testId");
119+
}
120+
108121
}

0 commit comments

Comments
 (0)