You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by bd...@apache.org on 2024/07/30 22:06:42 UTC

(directory-scimple) branch parallel-tests created (now 0235ac0d)

This is an automated email from the ASF dual-hosted git repository.

bdemers pushed a change to branch parallel-tests
in repository https://gitbox.apache.org/repos/asf/directory-scimple.git


      at 0235ac0d Enables parallel testing for UTs and ITs

This branch includes the following new commits:

     new 0235ac0d Enables parallel testing for UTs and ITs

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(directory-scimple) 01/01: Enables parallel testing for UTs and ITs

Posted by bd...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

bdemers pushed a commit to branch parallel-tests
in repository https://gitbox.apache.org/repos/asf/directory-scimple.git

commit 0235ac0d6804088084ee9b2a93ff0fb0bd5a4ee3
Author: Brian Demers <bd...@apache.org>
AuthorDate: Mon Jul 29 17:36:56 2024 -0400

    Enables parallel testing for UTs and ITs
    
    A handfull of minor issues were found and fixed after enabling parallel tests:
    - In memory example test servers were not thread safe
    - Quarkus tests needed to use dynamic server port
    - Test servers needed to use a shared single instance (shared between tests)
    - Similarly, single instance of Weld
---
 pom.xml                                            | 12 +++++
 .../rest/junit/MockServerClientTestRunner.java     | 20 +++------
 .../compliance/junit/EmbeddedServerExtension.java  | 51 +++++++++++++---------
 .../jersey/service/InMemoryUserService.java        | 29 ++++++------
 .../memory/service/InMemoryGroupService.java       |  4 +-
 .../memory/service/InMemoryUserService.java        | 29 ++++++------
 .../quarkus/service/InMemoryGroupService.java      | 15 +++----
 .../quarkus/service/InMemoryUserService.java       | 25 +++++++----
 .../src/test/resources/application.properties      |  1 +
 .../spring/service/InMemoryUserService.java        | 29 +++++++-----
 .../server/it/testapp/InMemoryGroupService.java    | 15 ++++---
 .../server/it/testapp/InMemoryUserService.java     | 16 ++++---
 .../scim/spring/it/app/InMemoryGroupService.java   | 10 +++--
 .../scim/spring/it/app/InMemoryUserService.java    | 16 +++++--
 14 files changed, 165 insertions(+), 107 deletions(-)

diff --git a/pom.xml b/pom.xml
index 82f23a11..09c4f1ff 100644
--- a/pom.xml
+++ b/pom.xml
@@ -580,6 +580,12 @@
                 <include>**/*Tests.java</include>
                 <include>**/*TestCase.java</include>
               </includes>
+              <properties>
+                <configurationParameters>
+                  junit.jupiter.execution.parallel.enabled = true
+                  junit.jupiter.execution.parallel.mode.default = concurrent
+                </configurationParameters>
+              </properties>
             </configuration>
           </plugin>
           <plugin>
@@ -594,6 +600,12 @@
               <dependenciesToScan>
                 <dependency>org.apache.directory.scimple:scim-compliance-tests</dependency>
               </dependenciesToScan>
+              <properties>
+                <configurationParameters>
+                  junit.jupiter.execution.parallel.enabled = true
+                  junit.jupiter.execution.parallel.mode.default = concurrent
+                </configurationParameters>
+              </properties>
             </configuration>
           </plugin>
           <plugin>
diff --git a/scim-client/src/test/java/org/apache/directory/scim/client/rest/junit/MockServerClientTestRunner.java b/scim-client/src/test/java/org/apache/directory/scim/client/rest/junit/MockServerClientTestRunner.java
index 2120ba8f..c11bfd86 100644
--- a/scim-client/src/test/java/org/apache/directory/scim/client/rest/junit/MockServerClientTestRunner.java
+++ b/scim-client/src/test/java/org/apache/directory/scim/client/rest/junit/MockServerClientTestRunner.java
@@ -34,6 +34,13 @@ public class MockServerClientTestRunner implements ParameterResolver, BeforeEach
 
   private final List<Class<?>> supportedClasses = List.of(MockWebServer.class, ScimUserClient.class, Client.class);
 
+  private final static Weld WELD = new Weld();
+  static {
+    // Use single instance of Weld for all tests using this runner
+    WELD.initialize();
+    Runtime.getRuntime().addShutdownHook(new Thread(WELD::shutdown));
+  }
+
   @Override
   public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
     return supportedClasses.contains(parameterContext.getParameter().getType());
@@ -59,9 +66,6 @@ public class MockServerClientTestRunner implements ParameterResolver, BeforeEach
   @Override
   public void beforeEach(ExtensionContext context) throws Exception {
 
-    Weld weld = new Weld();
-    getStore(context).put(Weld.class, weld);
-
     MockWebServer server = new MockWebServer();
     getStore(context).put(MockWebServer.class, server);
 
@@ -79,11 +83,6 @@ public class MockServerClientTestRunner implements ParameterResolver, BeforeEach
     if (server != null) {
       server.start();
     }
-
-    Weld weld = fromStore(Weld.class, context);
-    if (weld != null) {
-      weld.initialize();
-    }
   }
 
   @Override
@@ -93,11 +92,6 @@ public class MockServerClientTestRunner implements ParameterResolver, BeforeEach
       server.shutdown();
     }
 
-    Weld weld = fromStore(Weld.class, context);
-    if (weld != null) {
-      weld.shutdown();
-    }
-
     Client client = fromStore(Client.class, context);
     if (client != null) {
       client.close();
diff --git a/scim-compliance-tests/src/main/java/org/apache/directory/scim/compliance/junit/EmbeddedServerExtension.java b/scim-compliance-tests/src/main/java/org/apache/directory/scim/compliance/junit/EmbeddedServerExtension.java
index 34df7638..e51f2d29 100644
--- a/scim-compliance-tests/src/main/java/org/apache/directory/scim/compliance/junit/EmbeddedServerExtension.java
+++ b/scim-compliance-tests/src/main/java/org/apache/directory/scim/compliance/junit/EmbeddedServerExtension.java
@@ -20,10 +20,9 @@
 package org.apache.directory.scim.compliance.junit;
 
 import org.apache.commons.lang3.reflect.FieldUtils;
-import org.junit.jupiter.api.extension.AfterAllCallback;
-import org.junit.jupiter.api.extension.BeforeAllCallback;
 import org.junit.jupiter.api.extension.BeforeEachCallback;
 import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.TestInstantiationException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -39,22 +38,41 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.ServiceLoader;
 
-public class EmbeddedServerExtension implements BeforeAllCallback, BeforeEachCallback, AfterAllCallback {
+public class EmbeddedServerExtension implements BeforeEachCallback {
 
   private static final Logger logger = LoggerFactory.getLogger(EmbeddedServerExtension.class);
 
-  private ScimTestServer server;
-  private URI uri;
+  private static ScimTestServer server;
+  private static URI uri;
 
-  @Override
-  public void beforeAll(ExtensionContext context) throws Exception {
+  static {
+    // Start a single instance of the ScimTestServer
+    // this instance is shared for all tests using this extension
+    setupServer();
+  }
+
+  private static void setupServer() {
     ServiceLoader<ScimTestServer> serviceLoader = ServiceLoader.load(ScimTestServer.class);
-    if (serviceLoader.findFirst().isPresent()) {
-      server = serviceLoader.findFirst().get();
-      uri = server.start(randomPort());
-    } else {
-      logger.info("Could not find implementation of ScimTestServer via ServiceLoader, assuming server is started using different technique");
-    }
+    serviceLoader.findFirst()
+      .ifPresentOrElse(testServer -> {
+        try {
+          server = testServer;
+          uri = server.start(randomPort());
+
+          Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+            if (server != null) {
+              try {
+                server.shutdown();
+              } catch (Exception e) {
+                logger.warn("Failed to shutdown test server", e);
+              }
+            }
+          }));
+
+        } catch (Exception e) {
+          throw new TestInstantiationException("Failed to start test server: "+ testServer, e);
+        }
+      }, () -> logger.info("Could not find implementation of ScimTestServer via ServiceLoader, assuming server is started using different technique"));
   }
 
   @Override
@@ -76,13 +94,6 @@ public class EmbeddedServerExtension implements BeforeAllCallback, BeforeEachCal
     }
   }
 
-  @Override
-  public void afterAll(ExtensionContext context) throws Exception {
-    if (server != null) {
-      server.shutdown();
-    }
-  }
-
   private static int randomPort() {
     try (ServerSocket socket = new ServerSocket(0)) {
       return socket.getLocalPort();
diff --git a/scim-server-examples/scim-server-jersey/src/main/java/org/apache/directory/scim/example/jersey/service/InMemoryUserService.java b/scim-server-examples/scim-server-jersey/src/main/java/org/apache/directory/scim/example/jersey/service/InMemoryUserService.java
index cbbe1b0b..715bc1db 100644
--- a/scim-server-examples/scim-server-jersey/src/main/java/org/apache/directory/scim/example/jersey/service/InMemoryUserService.java
+++ b/scim-server-examples/scim-server-jersey/src/main/java/org/apache/directory/scim/example/jersey/service/InMemoryUserService.java
@@ -19,35 +19,38 @@
 
 package org.apache.directory.scim.example.jersey.service;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.stream.Collectors;
-
 import jakarta.annotation.PostConstruct;
 import jakarta.enterprise.context.ApplicationScoped;
 import jakarta.inject.Inject;
 import jakarta.inject.Named;
-
 import jakarta.ws.rs.core.Response;
 import org.apache.directory.scim.core.repository.ETag;
 import org.apache.directory.scim.core.repository.PatchHandler;
+import org.apache.directory.scim.core.repository.Repository;
+import org.apache.directory.scim.core.schema.SchemaRegistry;
 import org.apache.directory.scim.example.jersey.extensions.LuckyNumberExtension;
 import org.apache.directory.scim.server.exception.UnableToCreateResourceException;
-import org.apache.directory.scim.core.repository.Repository;
 import org.apache.directory.scim.spec.exception.ResourceException;
 import org.apache.directory.scim.spec.extension.EnterpriseExtension;
+import org.apache.directory.scim.spec.filter.Filter;
 import org.apache.directory.scim.spec.filter.FilterExpressions;
 import org.apache.directory.scim.spec.filter.FilterResponse;
-import org.apache.directory.scim.spec.filter.Filter;
 import org.apache.directory.scim.spec.filter.PageRequest;
 import org.apache.directory.scim.spec.filter.SortRequest;
 import org.apache.directory.scim.spec.filter.attribute.AttributeReference;
 import org.apache.directory.scim.spec.patch.PatchOperation;
-import org.apache.directory.scim.spec.resources.*;
-import org.apache.directory.scim.core.schema.SchemaRegistry;
+import org.apache.directory.scim.spec.resources.Email;
+import org.apache.directory.scim.spec.resources.Name;
+import org.apache.directory.scim.spec.resources.ScimExtension;
+import org.apache.directory.scim.spec.resources.ScimResource;
+import org.apache.directory.scim.spec.resources.ScimUser;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
 
 /**
  * Creates a singleton (effectively) Repository<ScimUser> with a memory-based
@@ -66,7 +69,7 @@ public class InMemoryUserService implements Repository<ScimUser> {
   static final String DEFAULT_USER_EMAIL_TYPE = "work";
   static final int DEFAULT_USER_LUCKY_NUMBER = 7;
 
-  private final Map<String, ScimUser> users = new HashMap<>();
+  private final Map<String, ScimUser> users = new ConcurrentHashMap<>();
 
   private SchemaRegistry schemaRegistry;
 
diff --git a/scim-server-examples/scim-server-memory/src/main/java/org/apache/directory/scim/example/memory/service/InMemoryGroupService.java b/scim-server-examples/scim-server-memory/src/main/java/org/apache/directory/scim/example/memory/service/InMemoryGroupService.java
index 2d9ad1e5..6feb58e8 100644
--- a/scim-server-examples/scim-server-memory/src/main/java/org/apache/directory/scim/example/memory/service/InMemoryGroupService.java
+++ b/scim-server-examples/scim-server-memory/src/main/java/org/apache/directory/scim/example/memory/service/InMemoryGroupService.java
@@ -39,11 +39,11 @@ import org.apache.directory.scim.spec.resources.ScimExtension;
 import org.apache.directory.scim.spec.resources.ScimGroup;
 
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.stream.Collectors;
 
 import jakarta.enterprise.context.ApplicationScoped;
@@ -54,7 +54,7 @@ import org.apache.directory.scim.core.schema.SchemaRegistry;
 @ApplicationScoped
 public class InMemoryGroupService implements Repository<ScimGroup> {
 
-  private final Map<String, ScimGroup> groups = new HashMap<>();
+  private final Map<String, ScimGroup> groups = new ConcurrentHashMap<>();
 
   private SchemaRegistry schemaRegistry;
 
diff --git a/scim-server-examples/scim-server-memory/src/main/java/org/apache/directory/scim/example/memory/service/InMemoryUserService.java b/scim-server-examples/scim-server-memory/src/main/java/org/apache/directory/scim/example/memory/service/InMemoryUserService.java
index f465f0ad..6e3ba000 100644
--- a/scim-server-examples/scim-server-memory/src/main/java/org/apache/directory/scim/example/memory/service/InMemoryUserService.java
+++ b/scim-server-examples/scim-server-memory/src/main/java/org/apache/directory/scim/example/memory/service/InMemoryUserService.java
@@ -19,35 +19,38 @@
 
 package org.apache.directory.scim.example.memory.service;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.stream.Collectors;
-
 import jakarta.annotation.PostConstruct;
 import jakarta.enterprise.context.ApplicationScoped;
 import jakarta.inject.Inject;
 import jakarta.inject.Named;
-
 import jakarta.ws.rs.core.Response;
 import org.apache.directory.scim.core.repository.ETag;
 import org.apache.directory.scim.core.repository.PatchHandler;
+import org.apache.directory.scim.core.repository.Repository;
+import org.apache.directory.scim.core.schema.SchemaRegistry;
 import org.apache.directory.scim.example.memory.extensions.LuckyNumberExtension;
 import org.apache.directory.scim.server.exception.UnableToCreateResourceException;
-import org.apache.directory.scim.core.repository.Repository;
 import org.apache.directory.scim.spec.exception.ResourceException;
 import org.apache.directory.scim.spec.extension.EnterpriseExtension;
+import org.apache.directory.scim.spec.filter.Filter;
 import org.apache.directory.scim.spec.filter.FilterExpressions;
 import org.apache.directory.scim.spec.filter.FilterResponse;
-import org.apache.directory.scim.spec.filter.Filter;
 import org.apache.directory.scim.spec.filter.PageRequest;
 import org.apache.directory.scim.spec.filter.SortRequest;
 import org.apache.directory.scim.spec.filter.attribute.AttributeReference;
 import org.apache.directory.scim.spec.patch.PatchOperation;
-import org.apache.directory.scim.spec.resources.*;
-import org.apache.directory.scim.core.schema.SchemaRegistry;
+import org.apache.directory.scim.spec.resources.Email;
+import org.apache.directory.scim.spec.resources.Name;
+import org.apache.directory.scim.spec.resources.ScimExtension;
+import org.apache.directory.scim.spec.resources.ScimResource;
+import org.apache.directory.scim.spec.resources.ScimUser;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
 
 /**
  * Creates a singleton (effectively) Repository<ScimUser> with a memory-based
@@ -66,7 +69,7 @@ public class InMemoryUserService implements Repository<ScimUser> {
   static final String DEFAULT_USER_EMAIL_TYPE = "work";
   static final int DEFAULT_USER_LUCKY_NUMBER = 7;
 
-  private final Map<String, ScimUser> users = new HashMap<>();
+  private final Map<String, ScimUser> users = new ConcurrentHashMap<>();
 
   private SchemaRegistry schemaRegistry;
 
diff --git a/scim-server-examples/scim-server-quarkus/src/main/java/org/apache/directory/scim/example/quarkus/service/InMemoryGroupService.java b/scim-server-examples/scim-server-quarkus/src/main/java/org/apache/directory/scim/example/quarkus/service/InMemoryGroupService.java
index f17bde14..79b4c2d9 100644
--- a/scim-server-examples/scim-server-quarkus/src/main/java/org/apache/directory/scim/example/quarkus/service/InMemoryGroupService.java
+++ b/scim-server-examples/scim-server-quarkus/src/main/java/org/apache/directory/scim/example/quarkus/service/InMemoryGroupService.java
@@ -20,17 +20,20 @@
 package org.apache.directory.scim.example.quarkus.service;
 
 import jakarta.annotation.PostConstruct;
+import jakarta.enterprise.context.ApplicationScoped;
 import jakarta.inject.Inject;
+import jakarta.inject.Named;
 import jakarta.ws.rs.core.Response;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.directory.scim.core.repository.ETag;
 import org.apache.directory.scim.core.repository.PatchHandler;
-import org.apache.directory.scim.server.exception.UnableToCreateResourceException;
 import org.apache.directory.scim.core.repository.Repository;
+import org.apache.directory.scim.core.schema.SchemaRegistry;
+import org.apache.directory.scim.server.exception.UnableToCreateResourceException;
 import org.apache.directory.scim.spec.exception.ResourceException;
+import org.apache.directory.scim.spec.filter.Filter;
 import org.apache.directory.scim.spec.filter.FilterExpressions;
 import org.apache.directory.scim.spec.filter.FilterResponse;
-import org.apache.directory.scim.spec.filter.Filter;
 import org.apache.directory.scim.spec.filter.PageRequest;
 import org.apache.directory.scim.spec.filter.SortRequest;
 import org.apache.directory.scim.spec.filter.attribute.AttributeReference;
@@ -39,22 +42,18 @@ import org.apache.directory.scim.spec.resources.ScimExtension;
 import org.apache.directory.scim.spec.resources.ScimGroup;
 
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.stream.Collectors;
 
-import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.inject.Named;
-import org.apache.directory.scim.core.schema.SchemaRegistry;
-
 @Named
 @ApplicationScoped
 public class InMemoryGroupService implements Repository<ScimGroup> {
 
-  private final Map<String, ScimGroup> groups = new HashMap<>();
+  private final Map<String, ScimGroup> groups = new ConcurrentHashMap<>();
 
   private SchemaRegistry schemaRegistry;
 
diff --git a/scim-server-examples/scim-server-quarkus/src/main/java/org/apache/directory/scim/example/quarkus/service/InMemoryUserService.java b/scim-server-examples/scim-server-quarkus/src/main/java/org/apache/directory/scim/example/quarkus/service/InMemoryUserService.java
index 8aa6784f..42d626b9 100644
--- a/scim-server-examples/scim-server-quarkus/src/main/java/org/apache/directory/scim/example/quarkus/service/InMemoryUserService.java
+++ b/scim-server-examples/scim-server-quarkus/src/main/java/org/apache/directory/scim/example/quarkus/service/InMemoryUserService.java
@@ -19,31 +19,38 @@
 
 package org.apache.directory.scim.example.quarkus.service;
 
-import java.util.*;
-import java.util.stream.Collectors;
-
 import jakarta.annotation.PostConstruct;
 import jakarta.enterprise.context.ApplicationScoped;
 import jakarta.inject.Inject;
 import jakarta.inject.Named;
-
 import jakarta.ws.rs.core.Response;
 import org.apache.directory.scim.core.repository.ETag;
 import org.apache.directory.scim.core.repository.PatchHandler;
+import org.apache.directory.scim.core.repository.Repository;
+import org.apache.directory.scim.core.schema.SchemaRegistry;
 import org.apache.directory.scim.example.quarkus.extensions.LuckyNumberExtension;
 import org.apache.directory.scim.server.exception.UnableToCreateResourceException;
-import org.apache.directory.scim.core.repository.Repository;
 import org.apache.directory.scim.spec.exception.ResourceException;
 import org.apache.directory.scim.spec.extension.EnterpriseExtension;
+import org.apache.directory.scim.spec.filter.Filter;
 import org.apache.directory.scim.spec.filter.FilterExpressions;
 import org.apache.directory.scim.spec.filter.FilterResponse;
-import org.apache.directory.scim.spec.filter.Filter;
 import org.apache.directory.scim.spec.filter.PageRequest;
 import org.apache.directory.scim.spec.filter.SortRequest;
 import org.apache.directory.scim.spec.filter.attribute.AttributeReference;
 import org.apache.directory.scim.spec.patch.PatchOperation;
-import org.apache.directory.scim.spec.resources.*;
-import org.apache.directory.scim.core.schema.SchemaRegistry;
+import org.apache.directory.scim.spec.resources.Email;
+import org.apache.directory.scim.spec.resources.Name;
+import org.apache.directory.scim.spec.resources.ScimExtension;
+import org.apache.directory.scim.spec.resources.ScimResource;
+import org.apache.directory.scim.spec.resources.ScimUser;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
 
 /**
  * Creates a singleton (effectively) Repository<ScimUser> with a memory-based
@@ -62,7 +69,7 @@ public class InMemoryUserService implements Repository<ScimUser> {
   static final String DEFAULT_USER_EMAIL_TYPE = "work";
   static final int DEFAULT_USER_LUCKY_NUMBER = 7;
 
-  private final Map<String, ScimUser> users = new HashMap<>();
+  private final Map<String, ScimUser> users = new ConcurrentHashMap<>();
 
   private SchemaRegistry schemaRegistry;
 
diff --git a/scim-server-examples/scim-server-quarkus/src/test/resources/application.properties b/scim-server-examples/scim-server-quarkus/src/test/resources/application.properties
new file mode 100644
index 00000000..74870ba9
--- /dev/null
+++ b/scim-server-examples/scim-server-quarkus/src/test/resources/application.properties
@@ -0,0 +1 @@
+quarkus.http.test-port=0
diff --git a/scim-server-examples/scim-server-spring-boot/src/main/java/org/apache/directory/scim/example/spring/service/InMemoryUserService.java b/scim-server-examples/scim-server-spring-boot/src/main/java/org/apache/directory/scim/example/spring/service/InMemoryUserService.java
index 39c2eeff..77c9f581 100644
--- a/scim-server-examples/scim-server-spring-boot/src/main/java/org/apache/directory/scim/example/spring/service/InMemoryUserService.java
+++ b/scim-server-examples/scim-server-spring-boot/src/main/java/org/apache/directory/scim/example/spring/service/InMemoryUserService.java
@@ -19,15 +19,7 @@
 
 package org.apache.directory.scim.example.spring.service;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.stream.Collectors;
-
 import jakarta.annotation.PostConstruct;
-
 import jakarta.ws.rs.core.Response;
 import org.apache.directory.scim.core.repository.ETag;
 import org.apache.directory.scim.core.repository.PatchHandler;
@@ -37,12 +29,27 @@ import org.apache.directory.scim.example.spring.extensions.LuckyNumberExtension;
 import org.apache.directory.scim.server.exception.UnableToCreateResourceException;
 import org.apache.directory.scim.spec.exception.ResourceException;
 import org.apache.directory.scim.spec.extension.EnterpriseExtension;
-import org.apache.directory.scim.spec.filter.*;
+import org.apache.directory.scim.spec.filter.Filter;
+import org.apache.directory.scim.spec.filter.FilterExpressions;
+import org.apache.directory.scim.spec.filter.FilterResponse;
+import org.apache.directory.scim.spec.filter.PageRequest;
+import org.apache.directory.scim.spec.filter.SortRequest;
 import org.apache.directory.scim.spec.filter.attribute.AttributeReference;
 import org.apache.directory.scim.spec.patch.PatchOperation;
-import org.apache.directory.scim.spec.resources.*;
+import org.apache.directory.scim.spec.resources.Email;
+import org.apache.directory.scim.spec.resources.Name;
+import org.apache.directory.scim.spec.resources.ScimExtension;
+import org.apache.directory.scim.spec.resources.ScimResource;
+import org.apache.directory.scim.spec.resources.ScimUser;
 import org.springframework.stereotype.Service;
 
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+
 /**
  * Creates a singleton (effectively) Provider<User> with a memory-based
  * persistence layer.
@@ -59,7 +66,7 @@ public class InMemoryUserService implements Repository<ScimUser> {
   static final String DEFAULT_USER_EMAIL_TYPE = "work";
   static final int DEFAULT_USER_LUCKY_NUMBER = 7;
 
-  private final Map<String, ScimUser> users = new HashMap<>();
+  private final Map<String, ScimUser> users = new ConcurrentHashMap<>();
 
   private final SchemaRegistry schemaRegistry;
 
diff --git a/scim-server/src/test/java/org/apache/directory/scim/server/it/testapp/InMemoryGroupService.java b/scim-server/src/test/java/org/apache/directory/scim/server/it/testapp/InMemoryGroupService.java
index 9af8eeb5..2d73deed 100644
--- a/scim-server/src/test/java/org/apache/directory/scim/server/it/testapp/InMemoryGroupService.java
+++ b/scim-server/src/test/java/org/apache/directory/scim/server/it/testapp/InMemoryGroupService.java
@@ -27,28 +27,33 @@ import jakarta.ws.rs.core.Response;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.directory.scim.core.repository.ETag;
 import org.apache.directory.scim.core.repository.PatchHandler;
-import org.apache.directory.scim.server.exception.UnableToCreateResourceException;
 import org.apache.directory.scim.core.repository.Repository;
+import org.apache.directory.scim.core.schema.SchemaRegistry;
+import org.apache.directory.scim.server.exception.UnableToCreateResourceException;
 import org.apache.directory.scim.spec.exception.ResourceException;
+import org.apache.directory.scim.spec.filter.Filter;
 import org.apache.directory.scim.spec.filter.FilterExpressions;
 import org.apache.directory.scim.spec.filter.FilterResponse;
-import org.apache.directory.scim.spec.filter.Filter;
 import org.apache.directory.scim.spec.filter.PageRequest;
 import org.apache.directory.scim.spec.filter.SortRequest;
 import org.apache.directory.scim.spec.filter.attribute.AttributeReference;
 import org.apache.directory.scim.spec.patch.PatchOperation;
 import org.apache.directory.scim.spec.resources.ScimExtension;
 import org.apache.directory.scim.spec.resources.ScimGroup;
-import org.apache.directory.scim.core.schema.SchemaRegistry;
 
-import java.util.*;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.stream.Collectors;
 
 @Named
 @ApplicationScoped
 public class InMemoryGroupService implements Repository<ScimGroup> {
 
-  private final Map<String, ScimGroup> groups = new HashMap<>();
+  private final Map<String, ScimGroup> groups = new ConcurrentHashMap<>();
 
   private SchemaRegistry schemaRegistry;
 
diff --git a/scim-server/src/test/java/org/apache/directory/scim/server/it/testapp/InMemoryUserService.java b/scim-server/src/test/java/org/apache/directory/scim/server/it/testapp/InMemoryUserService.java
index a8706103..f8ac2cc4 100644
--- a/scim-server/src/test/java/org/apache/directory/scim/server/it/testapp/InMemoryUserService.java
+++ b/scim-server/src/test/java/org/apache/directory/scim/server/it/testapp/InMemoryUserService.java
@@ -26,23 +26,27 @@ import jakarta.inject.Named;
 import jakarta.ws.rs.core.Response;
 import org.apache.directory.scim.core.repository.ETag;
 import org.apache.directory.scim.core.repository.PatchHandler;
-import org.apache.directory.scim.server.exception.UnableToCreateResourceException;
 import org.apache.directory.scim.core.repository.Repository;
+import org.apache.directory.scim.core.schema.SchemaRegistry;
+import org.apache.directory.scim.server.exception.UnableToCreateResourceException;
 import org.apache.directory.scim.spec.exception.ResourceException;
+import org.apache.directory.scim.spec.filter.Filter;
 import org.apache.directory.scim.spec.filter.FilterExpressions;
 import org.apache.directory.scim.spec.filter.FilterResponse;
-import org.apache.directory.scim.spec.filter.Filter;
 import org.apache.directory.scim.spec.filter.PageRequest;
 import org.apache.directory.scim.spec.filter.SortRequest;
 import org.apache.directory.scim.spec.filter.attribute.AttributeReference;
 import org.apache.directory.scim.spec.patch.PatchOperation;
-import org.apache.directory.scim.spec.resources.*;
-import org.apache.directory.scim.core.schema.SchemaRegistry;
+import org.apache.directory.scim.spec.resources.Email;
+import org.apache.directory.scim.spec.resources.Name;
+import org.apache.directory.scim.spec.resources.ScimExtension;
+import org.apache.directory.scim.spec.resources.ScimResource;
+import org.apache.directory.scim.spec.resources.ScimUser;
 
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.stream.Collectors;
 
 /**
@@ -62,7 +66,7 @@ public class InMemoryUserService implements Repository<ScimUser> {
   static final String DEFAULT_USER_EMAIL_TYPE = "work";
   static final int DEFAULT_USER_LUCKY_NUMBER = 7;
 
-  private final Map<String, ScimUser> users = new HashMap<>();
+  private final Map<String, ScimUser> users = new ConcurrentHashMap<>();
 
   private SchemaRegistry schemaRegistry;
 
diff --git a/support/spring-boot/src/test/java/org/apache/directory/scim/spring/it/app/InMemoryGroupService.java b/support/spring-boot/src/test/java/org/apache/directory/scim/spring/it/app/InMemoryGroupService.java
index d849b72c..ff767652 100644
--- a/support/spring-boot/src/test/java/org/apache/directory/scim/spring/it/app/InMemoryGroupService.java
+++ b/support/spring-boot/src/test/java/org/apache/directory/scim/spring/it/app/InMemoryGroupService.java
@@ -28,7 +28,11 @@ import org.apache.directory.scim.core.repository.Repository;
 import org.apache.directory.scim.core.schema.SchemaRegistry;
 import org.apache.directory.scim.server.exception.UnableToCreateResourceException;
 import org.apache.directory.scim.spec.exception.ResourceException;
-import org.apache.directory.scim.spec.filter.*;
+import org.apache.directory.scim.spec.filter.Filter;
+import org.apache.directory.scim.spec.filter.FilterExpressions;
+import org.apache.directory.scim.spec.filter.FilterResponse;
+import org.apache.directory.scim.spec.filter.PageRequest;
+import org.apache.directory.scim.spec.filter.SortRequest;
 import org.apache.directory.scim.spec.filter.attribute.AttributeReference;
 import org.apache.directory.scim.spec.patch.PatchOperation;
 import org.apache.directory.scim.spec.resources.ScimExtension;
@@ -36,17 +40,17 @@ import org.apache.directory.scim.spec.resources.ScimGroup;
 import org.springframework.stereotype.Service;
 
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.stream.Collectors;
 
 @Service
 public class InMemoryGroupService implements Repository<ScimGroup> {
 
-  private final Map<String, ScimGroup> groups = new HashMap<>();
+  private final Map<String, ScimGroup> groups = new ConcurrentHashMap<>();
 
   private final SchemaRegistry schemaRegistry;
 
diff --git a/support/spring-boot/src/test/java/org/apache/directory/scim/spring/it/app/InMemoryUserService.java b/support/spring-boot/src/test/java/org/apache/directory/scim/spring/it/app/InMemoryUserService.java
index 9ec72a87..69a2aea2 100644
--- a/support/spring-boot/src/test/java/org/apache/directory/scim/spring/it/app/InMemoryUserService.java
+++ b/support/spring-boot/src/test/java/org/apache/directory/scim/spring/it/app/InMemoryUserService.java
@@ -27,17 +27,25 @@ import org.apache.directory.scim.core.repository.Repository;
 import org.apache.directory.scim.core.schema.SchemaRegistry;
 import org.apache.directory.scim.server.exception.UnableToCreateResourceException;
 import org.apache.directory.scim.spec.exception.ResourceException;
-import org.apache.directory.scim.spec.filter.*;
+import org.apache.directory.scim.spec.filter.Filter;
+import org.apache.directory.scim.spec.filter.FilterExpressions;
+import org.apache.directory.scim.spec.filter.FilterResponse;
+import org.apache.directory.scim.spec.filter.PageRequest;
+import org.apache.directory.scim.spec.filter.SortRequest;
 import org.apache.directory.scim.spec.filter.attribute.AttributeReference;
 import org.apache.directory.scim.spec.patch.PatchOperation;
-import org.apache.directory.scim.spec.resources.*;
+import org.apache.directory.scim.spec.resources.Email;
+import org.apache.directory.scim.spec.resources.Name;
+import org.apache.directory.scim.spec.resources.ScimExtension;
+import org.apache.directory.scim.spec.resources.ScimResource;
+import org.apache.directory.scim.spec.resources.ScimUser;
 import org.springframework.stereotype.Service;
 
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.stream.Collectors;
 
 /**
@@ -56,7 +64,7 @@ public class InMemoryUserService implements Repository<ScimUser> {
   static final String DEFAULT_USER_EMAIL_TYPE = "work";
   static final int DEFAULT_USER_LUCKY_NUMBER = 7;
 
-  private final Map<String, ScimUser> users = new HashMap<>();
+  private final Map<String, ScimUser> users = new ConcurrentHashMap<>();
 
   private final SchemaRegistry schemaRegistry;