From 62a4610a7110a6f05c78b233906acf70b3cbc7d5 Mon Sep 17 00:00:00 2001 From: Rico Schrage Date: Sun, 28 Feb 2021 18:05:59 +0100 Subject: [PATCH 1/3] Fixes #44. --- .../ppi/deepsampler/core/api/Execution.java | 21 +++++++++++++++++ .../ppi/deepsampler/core/api/ScopeType.java | 23 +++++++++++++++++++ .../core/model/ExecutionRepository.java | 17 +++++++++++--- .../core/model/SampleRepository.java | 15 ++++++------ .../de/ppi/deepsampler/core/model/Scope.java | 22 +++++++----------- .../core/model/SingletonScope.java | 20 ++++++---------- .../deepsampler/core/model/ThreadScope.java | 22 ++++++++---------- .../provider/common/SamplerAspectTest.java | 20 ++++++++-------- 8 files changed, 99 insertions(+), 61 deletions(-) create mode 100644 deepsampler-core/src/main/java/de/ppi/deepsampler/core/api/ScopeType.java diff --git a/deepsampler-core/src/main/java/de/ppi/deepsampler/core/api/Execution.java b/deepsampler-core/src/main/java/de/ppi/deepsampler/core/api/Execution.java index 90186d76..3a971e99 100644 --- a/deepsampler-core/src/main/java/de/ppi/deepsampler/core/api/Execution.java +++ b/deepsampler-core/src/main/java/de/ppi/deepsampler/core/api/Execution.java @@ -5,8 +5,11 @@ package de.ppi.deepsampler.core.api; +import de.ppi.deepsampler.core.error.InvalidConfigException; import de.ppi.deepsampler.core.model.ExecutionRepository; import de.ppi.deepsampler.core.model.SampleRepository; +import de.ppi.deepsampler.core.model.SingletonScope; +import de.ppi.deepsampler.core.model.ThreadScope; /** * Provides functionality for influencing the execution phase of the stubbing done by deepsampler. @@ -36,4 +39,22 @@ public static void useGlobal(SampleReturnProcessor sampleReturnProcessor) { public static void useForLastSample(SampleReturnProcessor sampleReturnProcessor) { ExecutionRepository.getInstance().addSampleReturnProcessor(SampleRepository.getInstance().getLastSampleDefinition(), sampleReturnProcessor); } + + /** + * Set the scope for all samples created with deepsampler. + * + * @see ScopeType, {@link de.ppi.deepsampler.core.model.Scope} + * @param type the type of the scope you want to set + */ + public static void setScope(ScopeType type) { + if (type == ScopeType.SINGLETON) { + ExecutionRepository.setScope(new SingletonScope<>()); + SampleRepository.setScope(new SingletonScope<>()); + } else if (type == ScopeType.THREAD) { + ExecutionRepository.setScope(new ThreadScope<>()); + SampleRepository.setScope(new ThreadScope<>()); + } else { + throw new InvalidConfigException("The scope type %s is not supported!", type); + } + } } diff --git a/deepsampler-core/src/main/java/de/ppi/deepsampler/core/api/ScopeType.java b/deepsampler-core/src/main/java/de/ppi/deepsampler/core/api/ScopeType.java new file mode 100644 index 00000000..d1f55dbe --- /dev/null +++ b/deepsampler-core/src/main/java/de/ppi/deepsampler/core/api/ScopeType.java @@ -0,0 +1,23 @@ +package de.ppi.deepsampler.core.api; + +/** + * Type of the scope used by deepsampler. The scope defines how samples are bound respectively how long they will live in the JVM. + */ +public enum ScopeType { + + /** + * Samples are bound to a thread. So every Sample will live and die with the thread they are created in. + * + * @see de.ppi.deepsampler.core.model.ThreadScope + */ + THREAD, + + /** + * Samples are bound to the jvm. So every sample will live as long the jvm is active. + * + * @see de.ppi.deepsampler.core.model.SingletonScope + */ + SINGLETON + +} + diff --git a/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/ExecutionRepository.java b/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/ExecutionRepository.java index 17fe0391..981141a0 100644 --- a/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/ExecutionRepository.java +++ b/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/ExecutionRepository.java @@ -14,7 +14,7 @@ public class ExecutionRepository { private final List globalProcessors = new ArrayList<>(); private final Map> sampleDefinitionSampleReturnProcessorMap = new HashMap<>(); - private static final ThreadLocal myInstance = ThreadLocal.withInitial(ExecutionRepository::new); + private static Scope myInstance = new ThreadScope<>(); /** * Singleton Constructor. @@ -22,13 +22,25 @@ public class ExecutionRepository { private ExecutionRepository() {} public static synchronized ExecutionRepository getInstance() { - return myInstance.get(); + return myInstance.getOrCreate(ExecutionRepository::new); } public Map, ExecutionInformation> getAll() { return Collections.unmodifiableMap(executionInformation); } + /** + * Sets the scope of the {@link SampleRepository} end defines the visibility limits of Samples. + * The default {@link Scope} is {@link ThreadScope}, so by default Samples are not shared across {@link Thread}s. + * + * @param executionRepositoryRepository The {@link Scope} that should be used by the {@link SampleRepository}. + */ + public static synchronized void setScope(Scope executionRepositoryRepository) { + Objects.requireNonNull(executionRepositoryRepository, "The ExecutionRepositoryRepository must not be null."); + + ExecutionRepository.myInstance = executionRepositoryRepository; + } + public ExecutionInformation getOrCreate(final Class cls) { return executionInformation.computeIfAbsent(cls, k -> new ExecutionInformation()); } @@ -54,6 +66,5 @@ public void clear() { executionInformation.clear(); globalProcessors.clear(); sampleDefinitionSampleReturnProcessorMap.clear(); - myInstance.remove(); } } diff --git a/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/SampleRepository.java b/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/SampleRepository.java index 73102a85..876c6e25 100644 --- a/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/SampleRepository.java +++ b/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/SampleRepository.java @@ -18,7 +18,7 @@ public class SampleRepository { private SampleDefinition lastSample; private List> currentParameterMatchers = new ArrayList<>(); - private static Scope sampleRepositoryScope = new ThreadScope(); + private static Scope sampleRepositoryScope = new ThreadScope<>(); /** * Singleton Constructor. @@ -36,10 +36,9 @@ public static synchronized SampleRepository getInstance() { * * @param sampleRepositoryScope The {@link Scope} that should be used by the {@link SampleRepository}. */ - public static synchronized void setScope(Scope sampleRepositoryScope) { + public static synchronized void setScope(Scope sampleRepositoryScope) { Objects.requireNonNull(sampleRepositoryScope, "The SampleRepositoryScope must not be null."); - SampleRepository.sampleRepositoryScope.cleanUp(); SampleRepository.sampleRepositoryScope = sampleRepositoryScope; } @@ -57,8 +56,8 @@ public void add(final SampleDefinition sampleDefinition) { /** * Checks whether both methods are the same or not * - * @param wantedSampledMethod - * @param sampledMethod + * @param wantedSampledMethod the sampled method defined by the user + * @param sampledMethod the actual method the provider came across * @return true if both methods are the same */ private boolean methodMatches(SampledMethod wantedSampledMethod, SampledMethod sampledMethod) { @@ -69,9 +68,9 @@ private boolean methodMatches(SampledMethod wantedSampledMethod, SampledMethod s * Returns true if the declaring types of wantedSampledMethod and sampledMethod are the same, or if the declaring * type of wantedSampleMethod extends the declaring type of sampledMethod. * - * @param wantedSampledMethod - * @param sampledMethod - * @return + * @param wantedSampledMethod the sampled method defined by the user + * @param sampledMethod the actual method the provider came across + * @return true if the type in which the wanted method has been defined matches with the actual method */ private boolean wantedTypeExtendsSampledType(SampledMethod wantedSampledMethod, SampledMethod sampledMethod) { return sampledMethod.getTarget().isAssignableFrom(wantedSampledMethod.getTarget()); diff --git a/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/Scope.java b/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/Scope.java index ae5989b4..af0f0827 100644 --- a/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/Scope.java +++ b/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/Scope.java @@ -10,30 +10,24 @@ import java.util.function.Supplier; /** - * Defines the {@link SampleRepository}s scope by providing a container that holds the {@link SampleRepository}. - * The {@link Scope} can be set using {@link SampleRepository#setScope(Scope)}. + * Defines the a scope by providing a container that holds the Repositories used by deepsampler. + * The {@link Scope} can be set using {@link de.ppi.deepsampler.core.api.Execution#setScope(de.ppi.deepsampler.core.api.ScopeType)}. * * The default scope is {@link ThreadScope}, so Samples and all data associated with Samples are not * shared across different {@link Thread}s. */ -public interface Scope { +public interface Scope { /** - * Retrieves a {@link SampleRepository}, or creates a new one if no one exists yet. The implementation decides - * where the SampleRepository is stored. E.g. If it is stored in a session scoped Bean, the SampleRepository is also + * Retrieves the hold object, or creates a new one if no one exists yet. The implementation decides + * where the object is stored. E.g. If it is stored in a session scoped Bean, the object is also * session scoped. If it is stored in a {@link ThreadLocal} the scope is thread scoped. * * The default scope is thread scope ({@link ThreadScope}. * - * @param supplier If the current scope doesn't have a {@link SampleRepository} yet, this supplier is used to create a new one. - * @return the {@link SampleRepository} of the current scope. + * @param supplier If the current scope doesn't have an instance of the hold class yet, this supplier is used to create a new one. + * @return T the instance hold by the current scope. */ - SampleRepository getOrCreate(Supplier supplier); - - /** - * Cleans resources that might be referenced by a Scope. cleanUp() is called on a Scope that will be - * replaced by a new Scope. - */ - void cleanUp(); + T getOrCreate(Supplier supplier); } diff --git a/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/SingletonScope.java b/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/SingletonScope.java index e1383407..dfccf537 100644 --- a/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/SingletonScope.java +++ b/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/SingletonScope.java @@ -10,25 +10,25 @@ import java.util.function.Supplier; /** - * A singleton scope for the {@link SampleRepository}. If this scope is used, Samples and all associated data are + * A singleton scope for the repositories in deepsampler. If this scope is used, Samples and all associated data are * shared across separated {@link Thread}s. * * The default scope is {@link ThreadScope}. * - * The scope can be changed using {@link SampleRepository#setScope(Scope)}. + * The scope can be changed using {@link de.ppi.deepsampler.core.api.Execution#setScope(de.ppi.deepsampler.core.api.ScopeType)}. */ -public class SingletonScope implements Scope { +public class SingletonScope implements Scope { - private static SampleRepository sampleRepository; + private T sampleRepository; /** - * Delivers the global SampleRepository or creates a new one if none exists yet. + * Delivers the global object hold by the scope or creates a new one if none exists yet. * - * @param supplier A Supplier that is used to create a new {@link SampleRepository} if non exists yet. + * @param supplier A Supplier that is used to create a new object of the hold class if non exists yet. * @return The global {@link SampleRepository}. */ @Override - public synchronized SampleRepository getOrCreate(Supplier supplier) { + public synchronized T getOrCreate(Supplier supplier) { if (sampleRepository == null) { sampleRepository = supplier.get(); } @@ -36,10 +36,4 @@ public synchronized SampleRepository getOrCreate(Supplier supp return sampleRepository; } - @Override - public void cleanUp() { - if (sampleRepository != null) { - sampleRepository.clear(); - } - } } diff --git a/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/ThreadScope.java b/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/ThreadScope.java index 3366f0e4..f8587880 100644 --- a/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/ThreadScope.java +++ b/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/ThreadScope.java @@ -10,27 +10,27 @@ import java.util.function.Supplier; /** - * A thread scope for the {@link SampleRepository}. If this scope is used, Samples and all associated data cannot be + * A thread scope for an arbitrary object. If this scope is used, Samples and all associated data cannot be * shared across separated {@link Thread}s. * * This is the default scope. * - * The scope can be changed using {@link SampleRepository#setScope(Scope)}. + * The scope can be changed using {@link de.ppi.deepsampler.core.api.Execution#setScope(de.ppi.deepsampler.core.api.ScopeType)}. */ -public class ThreadScope implements Scope { +public class ThreadScope implements Scope { - private final ThreadLocal sampleRepository = new ThreadLocal<>(); + private final ThreadLocal sampleRepository = new ThreadLocal<>(); /** - * Delivers the SampleRepository of the current {@link Thread} or creates a new one if the current {@link Thread} doesn't - * have a {@link SampleRepository}. + * Delivers the hold object of the current {@link Thread} or creates a new one if the current {@link Thread} doesn't + * have an instance yet. * - * @param supplier A Supplier that is used to create a new {@link SampleRepository} if the current {@link Thread} doesn't have one. - * @return The {@link SampleRepository} of the current {@link Thread}. + * @param supplier A Supplier that is used to create a new object of the hold class if the current {@link Thread} doesn't have one. + * @return The hold instance of the current {@link Thread}. */ @Override - public synchronized SampleRepository getOrCreate(Supplier supplier) { + public synchronized T getOrCreate(Supplier supplier) { if (sampleRepository.get() == null) { sampleRepository.set(supplier.get()); } @@ -38,8 +38,4 @@ public synchronized SampleRepository getOrCreate(Supplier supp return sampleRepository.get(); } - @Override - public void cleanUp() { - sampleRepository.remove(); - } } diff --git a/deepsampler-provider/src/testFixtures/java/de/ppi/deepsampler/provider/common/SamplerAspectTest.java b/deepsampler-provider/src/testFixtures/java/de/ppi/deepsampler/provider/common/SamplerAspectTest.java index d46e156c..dde3b26e 100644 --- a/deepsampler-provider/src/testFixtures/java/de/ppi/deepsampler/provider/common/SamplerAspectTest.java +++ b/deepsampler-provider/src/testFixtures/java/de/ppi/deepsampler/provider/common/SamplerAspectTest.java @@ -5,16 +5,12 @@ package de.ppi.deepsampler.provider.common; -import de.ppi.deepsampler.core.api.Execution; -import de.ppi.deepsampler.core.api.Matchers; -import de.ppi.deepsampler.core.api.Sample; -import de.ppi.deepsampler.core.api.Sampler; +import de.ppi.deepsampler.core.api.*; import de.ppi.deepsampler.core.error.InvalidConfigException; import de.ppi.deepsampler.core.error.VerifyException; import de.ppi.deepsampler.core.internal.FixedQuantity; +import de.ppi.deepsampler.core.model.ExecutionRepository; import de.ppi.deepsampler.core.model.SampleRepository; -import de.ppi.deepsampler.core.model.SingletonScope; -import de.ppi.deepsampler.core.model.ThreadScope; import de.ppi.deepsampler.persistence.api.PersistentSampleManager; import de.ppi.deepsampler.persistence.api.PersistentSampler; import de.ppi.deepsampler.persistence.error.PersistenceException; @@ -676,7 +672,7 @@ public void threadScopeWorks() throws ExecutionException, InterruptedException { assertEquals(VALUE_A, getTestService().echoParameter(VALUE_A)); // GIVEN - SampleRepository.setScope(new ThreadScope()); + Execution.setScope(ScopeType.THREAD); ExecutorService executorService = Executors.newFixedThreadPool(2); @@ -687,6 +683,7 @@ public void threadScopeWorks() throws ExecutionException, InterruptedException { Sample.of(testServiceSampler.echoParameter(VALUE_B)).is(VALUE_A); assertEquals(VALUE_A, getTestService().echoParameter(VALUE_B)); + assertFalse(ExecutionRepository.getInstance().getOrCreate(TestService.class).getAll().isEmpty()); }); Future findsNoSampler = executorService.submit(() -> { @@ -698,6 +695,7 @@ public void threadScopeWorks() throws ExecutionException, InterruptedException { // THEN assertEquals(VALUE_B, getTestService().echoParameter(VALUE_B)); + assertTrue(ExecutionRepository.getInstance().getOrCreate(TestService.class).getAll().isEmpty()); }); createsASampler.get(); @@ -705,7 +703,7 @@ public void threadScopeWorks() throws ExecutionException, InterruptedException { // THEN assertEquals(VALUE_B, getTestService().echoParameter(VALUE_B)); - + assertTrue(ExecutionRepository.getInstance().getOrCreate(TestService.class).getAll().isEmpty()); } @Test @@ -717,7 +715,7 @@ public void singletonScopeWorks() throws ExecutionException, InterruptedExceptio assertEquals(VALUE_A, getTestService().echoParameter(VALUE_A)); // GIVEN - SampleRepository.setScope(new SingletonScope()); + Execution.setScope(ScopeType.SINGLETON); ExecutorService executorService = Executors.newFixedThreadPool(2); @@ -728,6 +726,7 @@ public void singletonScopeWorks() throws ExecutionException, InterruptedExceptio Sample.of(testServiceSampler.echoParameter(VALUE_B)).is(VALUE_A); assertEquals(VALUE_A, getTestService().echoParameter(VALUE_B)); + assertFalse(ExecutionRepository.getInstance().getOrCreate(TestService.class).getAll().isEmpty()); }); Future findsNoSampler = executorService.submit(() -> { @@ -739,6 +738,7 @@ public void singletonScopeWorks() throws ExecutionException, InterruptedExceptio // THEN assertEquals(VALUE_A, getTestService().echoParameter(VALUE_B)); + assertFalse(ExecutionRepository.getInstance().getOrCreate(TestService.class).getAll().isEmpty()); }); createsASampler.get(); @@ -746,7 +746,7 @@ public void singletonScopeWorks() throws ExecutionException, InterruptedExceptio // THEN assertEquals(VALUE_A, getTestService().echoParameter(VALUE_B)); - + assertFalse(ExecutionRepository.getInstance().getOrCreate(TestService.class).getAll().isEmpty()); } @Test From 4f606679d789f8688a2803682fdc7fab17032b56 Mon Sep 17 00:00:00 2001 From: Rico Schrage Date: Sun, 28 Feb 2021 18:08:21 +0100 Subject: [PATCH 2/3] Fixes #44. --- .../java/de/ppi/deepsampler/core/api/ExecutionTest.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/deepsampler-core/src/test/java/de/ppi/deepsampler/core/api/ExecutionTest.java b/deepsampler-core/src/test/java/de/ppi/deepsampler/core/api/ExecutionTest.java index 2f06e884..583932a5 100644 --- a/deepsampler-core/src/test/java/de/ppi/deepsampler/core/api/ExecutionTest.java +++ b/deepsampler-core/src/test/java/de/ppi/deepsampler/core/api/ExecutionTest.java @@ -1,11 +1,13 @@ package de.ppi.deepsampler.core.api; +import de.ppi.deepsampler.core.error.InvalidConfigException; import de.ppi.deepsampler.core.model.ExecutionRepository; import de.ppi.deepsampler.core.model.SampleDefinition; import de.ppi.deepsampler.core.model.SampleRepository; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; class ExecutionTest { @@ -34,4 +36,10 @@ void useForLastSample() { // THEN assertEquals(sampleReturnProcessor, ExecutionRepository.getInstance().getSampleReturnProcessorsFor(SampleRepository.getInstance().getLastSampleDefinition()).get(0)); } + + @Test + void testNotSupported() { + // GIVEN WHEN THEN + assertThrows(InvalidConfigException.class, () -> Execution.setScope(null)); + } } \ No newline at end of file From e9cbc327c1976caf260083675e6dfb48893d6f87 Mon Sep 17 00:00:00 2001 From: Rico Schrage Date: Sun, 28 Feb 2021 18:20:57 +0100 Subject: [PATCH 3/3] Sonar issue. --- .../de/ppi/deepsampler/core/model/ExecutionRepository.java | 1 + .../de/ppi/deepsampler/core/model/SampleRepository.java | 1 + .../src/main/java/de/ppi/deepsampler/core/model/Scope.java | 6 +++++- .../java/de/ppi/deepsampler/core/model/SingletonScope.java | 4 ++++ .../java/de/ppi/deepsampler/core/model/ThreadScope.java | 4 ++++ 5 files changed, 15 insertions(+), 1 deletion(-) diff --git a/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/ExecutionRepository.java b/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/ExecutionRepository.java index 981141a0..abe56dc3 100644 --- a/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/ExecutionRepository.java +++ b/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/ExecutionRepository.java @@ -38,6 +38,7 @@ public Map, ExecutionInformation> getAll() { public static synchronized void setScope(Scope executionRepositoryRepository) { Objects.requireNonNull(executionRepositoryRepository, "The ExecutionRepositoryRepository must not be null."); + ExecutionRepository.myInstance.close(); ExecutionRepository.myInstance = executionRepositoryRepository; } diff --git a/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/SampleRepository.java b/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/SampleRepository.java index 876c6e25..6127428c 100644 --- a/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/SampleRepository.java +++ b/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/SampleRepository.java @@ -39,6 +39,7 @@ public static synchronized SampleRepository getInstance() { public static synchronized void setScope(Scope sampleRepositoryScope) { Objects.requireNonNull(sampleRepositoryScope, "The SampleRepositoryScope must not be null."); + SampleRepository.sampleRepositoryScope.close(); SampleRepository.sampleRepositoryScope = sampleRepositoryScope; } diff --git a/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/Scope.java b/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/Scope.java index af0f0827..2afaca98 100644 --- a/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/Scope.java +++ b/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/Scope.java @@ -16,7 +16,7 @@ * The default scope is {@link ThreadScope}, so Samples and all data associated with Samples are not * shared across different {@link Thread}s. */ -public interface Scope { +public interface Scope extends AutoCloseable { /** * Retrieves the hold object, or creates a new one if no one exists yet. The implementation decides @@ -30,4 +30,8 @@ public interface Scope { */ T getOrCreate(Supplier supplier); + /** + * {@inheritDoc} + */ + void close(); } diff --git a/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/SingletonScope.java b/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/SingletonScope.java index dfccf537..0b60cbd3 100644 --- a/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/SingletonScope.java +++ b/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/SingletonScope.java @@ -36,4 +36,8 @@ public synchronized T getOrCreate(Supplier supplier) { return sampleRepository; } + @Override + public void close() { + // nothing to do + } } diff --git a/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/ThreadScope.java b/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/ThreadScope.java index f8587880..346dc3b9 100644 --- a/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/ThreadScope.java +++ b/deepsampler-core/src/main/java/de/ppi/deepsampler/core/model/ThreadScope.java @@ -38,4 +38,8 @@ public synchronized T getOrCreate(Supplier supplier) { return sampleRepository.get(); } + @Override + public void close() { + sampleRepository.remove(); + } }