Skip to content

Commit 7bc9dd7

Browse files
authored
Release watcher objects (#100)
When each test finishes, release registered watchers
1 parent 734d1f5 commit 7bc9dd7

File tree

4 files changed

+61
-15
lines changed

4 files changed

+61
-15
lines changed

src/main/java/com/nordstrom/automation/junit/ArtifactCollector.java

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.nordstrom.automation.junit;
22

3+
import static com.nordstrom.automation.junit.LifecycleHooks.toMapKey;
4+
35
import java.io.IOException;
46
import java.nio.file.Files;
57
import java.nio.file.Path;
@@ -20,14 +22,14 @@
2022
*/
2123
public class ArtifactCollector<T extends ArtifactType> extends AtomIdentity {
2224

23-
private static final ConcurrentHashMap<Description, List<ArtifactCollector<? extends ArtifactType>>> WATCHER_MAP;
24-
private static final Function<Description, List<ArtifactCollector<? extends ArtifactType>>> NEW_INSTANCE;
25+
private static final ConcurrentHashMap<String, List<ArtifactCollector<? extends ArtifactType>>> WATCHER_MAP;
26+
private static final Function<String, List<ArtifactCollector<? extends ArtifactType>>> NEW_INSTANCE;
2527

2628
static {
2729
WATCHER_MAP = new ConcurrentHashMap<>();
28-
NEW_INSTANCE = new Function<Description, List<ArtifactCollector<? extends ArtifactType>>>() {
30+
NEW_INSTANCE = new Function<String, List<ArtifactCollector<? extends ArtifactType>>>() {
2931
@Override
30-
public List<ArtifactCollector<? extends ArtifactType>> apply(Description input) {
32+
public List<ArtifactCollector<? extends ArtifactType>> apply(String input) {
3133
return new ArrayList<>();
3234
}
3335
};
@@ -48,7 +50,7 @@ public ArtifactCollector(Object instance, T provider) {
4850
public void starting(Description description) {
4951
super.starting(description);
5052
List<ArtifactCollector<? extends ArtifactType>> watcherList =
51-
LifecycleHooks.computeIfAbsent(WATCHER_MAP, description, NEW_INSTANCE);
53+
LifecycleHooks.computeIfAbsent(WATCHER_MAP, toMapKey(description), NEW_INSTANCE);
5254
watcherList.add(this);
5355
}
5456

@@ -189,7 +191,7 @@ public T getArtifactProvider() {
189191
@SuppressWarnings("unchecked")
190192
public static <S extends ArtifactCollector<? extends ArtifactType>> Optional<S>
191193
getWatcher(Description description, Class<S> watcherType) {
192-
List<ArtifactCollector<? extends ArtifactType>> watcherList = WATCHER_MAP.get(description);
194+
List<ArtifactCollector<? extends ArtifactType>> watcherList = WATCHER_MAP.get(toMapKey(description));
193195
if (watcherList != null) {
194196
for (ArtifactCollector<? extends ArtifactType> watcher : watcherList) {
195197
if (watcher.getClass() == watcherType) {
@@ -200,4 +202,13 @@ public T getArtifactProvider() {
200202
return Optional.absent();
201203
}
202204

205+
/**
206+
* Release the watchers for the specified description.
207+
*
208+
* @param description JUnit method description
209+
*/
210+
static void releaseWatchersOf(Description description) {
211+
WATCHER_MAP.remove(toMapKey(description));
212+
}
213+
203214
}

src/main/java/com/nordstrom/automation/junit/EachTestNotifierInit.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ static void releaseMappingsFor(EachTestNotifier notifier) {
169169
}
170170

171171
RunReflectiveCall.releaseCallableOf(description);
172+
ArtifactCollector.releaseWatchersOf(description);
172173
CreateTest.releaseMappingsFor(atomicTest.getRunner(), atomicTest.getIdentity(), target);
173174
}
174175

src/test/java/com/nordstrom/automation/junit/ArtifactCollectorTest.java

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import static org.testng.Assert.assertEquals;
44
import static org.testng.Assert.assertFalse;
5+
import static org.testng.Assert.assertNotNull;
56
import static org.testng.Assert.assertNull;
67
import static org.testng.Assert.assertTrue;
78

@@ -28,7 +29,8 @@ public void verifyHappyPath() {
2829
assertEquals(rla.getIgnoredTests().size(), 0, "Incorrect ignored test count");
2930

3031
Description description = rla.getPassedTests().get(0);
31-
UnitTestCapture watcher = ArtifactCollector.getWatcher(description, UnitTestCapture.class).get();
32+
UnitTestCapture watcher = rla.getWatcher(description);
33+
assertNotNull(watcher, "Unit test watcher not registered");
3234
assertNull(watcher.getArtifactProvider().getCaptureState(), "Artifact provider capture state should be 'null'");
3335
assertNull(watcher.getArtifactPath(), "Artifact capture should not have been requested");
3436
}
@@ -47,7 +49,8 @@ public void verifyCaptureOnFailure() {
4749
assertEquals(rla.getIgnoredTests().size(), 0, "Incorrect ignored test count");
4850

4951
Description description = rla.getFailedTests().get(0);
50-
UnitTestCapture watcher = ArtifactCollector.getWatcher(description, UnitTestCapture.class).get();
52+
UnitTestCapture watcher = rla.getWatcher(description);
53+
assertNotNull(watcher, "Unit test watcher not registered");
5154
assertEquals(watcher.getArtifactProvider().getCaptureState(), CaptureState.CAPTURE_SUCCESS, "Incorrect artifact provider capture state");
5255
assertTrue(watcher.getArtifactPath().isPresent(), "Artifact capture output path is not present");
5356
}
@@ -66,7 +69,8 @@ public void verifyCanNotCapture() {
6669
assertEquals(rla.getIgnoredTests().size(), 0, "Incorrect ignored test count");
6770

6871
Description description = rla.getFailedTests().get(0);
69-
UnitTestCapture watcher = ArtifactCollector.getWatcher(description, UnitTestCapture.class).get();
72+
UnitTestCapture watcher = rla.getWatcher(description);
73+
assertNotNull(watcher, "Unit test watcher not registered");
7074
assertEquals(watcher.getArtifactProvider().getCaptureState(), CaptureState.CAN_NOT_CAPTURE, "Incorrect artifact provider capture state");
7175
assertFalse(watcher.getArtifactPath().isPresent(), "Artifact capture output path should not be present");
7276
}
@@ -85,7 +89,8 @@ public void verifyWillNotCapture() {
8589
assertEquals(rla.getIgnoredTests().size(), 0, "Incorrect ignored test count");
8690

8791
Description description = rla.getFailedTests().get(0);
88-
UnitTestCapture watcher = ArtifactCollector.getWatcher(description, UnitTestCapture.class).get();
92+
UnitTestCapture watcher = rla.getWatcher(description);
93+
assertNotNull(watcher, "Unit test watcher not registered");
8994
assertEquals(watcher.getArtifactProvider().getCaptureState(), CaptureState.CAPTURE_FAILED, "Incorrect artifact provider capture state");
9095
assertFalse(watcher.getArtifactPath().isPresent(), "Artifact capture output path should not be present");
9196
}
@@ -104,7 +109,8 @@ public void verifyOnDemandCapture() {
104109
assertEquals(rla.getIgnoredTests().size(), 0, "Incorrect ignored test count");
105110

106111
Description description = rla.getPassedTests().get(0);
107-
UnitTestCapture watcher = ArtifactCollector.getWatcher(description, UnitTestCapture.class).get();
112+
UnitTestCapture watcher = rla.getWatcher(description);
113+
assertNotNull(watcher, "Unit test watcher not registered");
108114
assertEquals(watcher.getArtifactProvider().getCaptureState(), CaptureState.CAPTURE_SUCCESS, "Incorrect artifact provider capture state");
109115
assertTrue(watcher.getArtifactPath().isPresent(), "Artifact capture output path is not present");
110116
}
@@ -123,7 +129,8 @@ public void verifyParameterizedCapture() {
123129
assertEquals(rla.getIgnoredTests().size(), 0, "Incorrect ignored test count");
124130

125131
Description description = rla.getFailedTests().get(0);
126-
UnitTestCapture watcher = ArtifactCollector.getWatcher(description, UnitTestCapture.class).get();
132+
UnitTestCapture watcher = rla.getWatcher(description);
133+
assertNotNull(watcher, "Unit test watcher not registered");
127134
assertEquals(watcher.getArtifactProvider().getCaptureState(), CaptureState.CAPTURE_SUCCESS, "Incorrect artifact provider capture state");
128135
assertTrue(watcher.getArtifactPath().isPresent(), "Artifact capture output path is not present");
129136
}
@@ -142,7 +149,8 @@ public void verifyJUnitParamsCapture() {
142149
assertEquals(rla.getIgnoredTests().size(), 0, "Incorrect ignored test count");
143150

144151
Description description = rla.getFailedTests().get(0);
145-
UnitTestCapture watcher = ArtifactCollector.getWatcher(description, UnitTestCapture.class).get();
152+
UnitTestCapture watcher = rla.getWatcher(description);
153+
assertNotNull(watcher, "Unit test watcher not registered");
146154
assertEquals(watcher.getArtifactProvider().getCaptureState(), CaptureState.CAPTURE_SUCCESS, "Incorrect artifact provider capture state");
147155
assertTrue(watcher.getArtifactPath().isPresent(), "Artifact capture output path is not present");
148156
}
@@ -163,7 +171,8 @@ public void verifyTheoriesCapture() {
163171
assertEquals(rla.getFailedTheories().size(), 1, "Incorrect failed theory count");
164172

165173
Description description = rla.getFailedTheories().get(0);
166-
UnitTestCapture watcher = ArtifactCollector.getWatcher(description, UnitTestCapture.class).get();
174+
UnitTestCapture watcher = rla.getWatcher(description);
175+
assertNotNull(watcher, "Unit test watcher not registered");
167176
assertEquals(watcher.getArtifactProvider().getCaptureState(), CaptureState.CAPTURE_SUCCESS, "Incorrect artifact provider capture state");
168177
assertTrue(watcher.getArtifactPath().isPresent(), "Artifact capture output path is not present");
169178
}

src/test/java/com/nordstrom/automation/junit/RunListenerAdapter.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33
import java.util.ArrayList;
44
import java.util.Collections;
55
import java.util.List;
6+
import java.util.concurrent.ConcurrentHashMap;
67

78
import org.junit.runner.Description;
89
import org.junit.runner.notification.Failure;
910
import org.junit.runner.notification.RunListener;
1011

12+
import com.google.common.base.Optional;
13+
1114
/**
1215
* This run listener tracks the results of executed tests.
1316
*/
@@ -27,6 +30,7 @@ public class RunListenerAdapter extends RunListener {
2730
private List<Description> m_failedTheories = Collections.synchronizedList(new ArrayList<Description>());
2831
private List<Description> m_ignoredTheories = Collections.synchronizedList(new ArrayList<Description>());
2932
private List<Description> m_passedTheories = Collections.synchronizedList(new ArrayList<Description>());
33+
private ConcurrentHashMap<Description, UnitTestCapture> watcherMap = new ConcurrentHashMap<>();
3034

3135
/**
3236
* Called when an atomic test is about to be started.
@@ -92,6 +96,17 @@ public void testIgnored(Description description) throws Exception {
9296
}
9397
}
9498

99+
/**
100+
* Called when an atomic test has finished, whether the test succeeds or fails.
101+
*
102+
* @param description the description of the test that just ran
103+
*/
104+
@Override
105+
public void testFinished(Description description) {
106+
Optional<UnitTestCapture> watcher = ArtifactCollector.getWatcher(description, UnitTestCapture.class);
107+
if (watcher.isPresent()) watcherMap.put(description, watcher.get());
108+
}
109+
95110
/**
96111
* Get list of all tests that were run.
97112
*
@@ -219,7 +234,17 @@ public List<Description> getFailedTheories() {
219234
public List<Description> getIgnoredTheories() {
220235
return m_ignoredTheories;
221236
}
222-
237+
238+
/**
239+
* Get unit test watcher registered for the specified description.
240+
*
241+
* @param description JUnit method description
242+
* @return {@link UnitTestWatcher} object; may be {@code null}
243+
*/
244+
public UnitTestCapture getWatcher(Description description) {
245+
return watcherMap.get(description);
246+
}
247+
223248
/**
224249
* Determine if the specified description represents a theory.
225250
*

0 commit comments

Comments
 (0)