Repository: quarkusio/quarkus
Issue: NPE in ArcTestRequestScopeProvider.setup() in native mode with dependency on deployment test jar

while working on the quarkus vault extension, I encountered a NPE in ArcTestRequestScopeProvider in native mode, after adding a test jar (which contains helper classes to start and configure vault for integration testing) as a test dependency of integration test jpa-postgresql.

may be the issue is in the way I developed the vault extension, and specifically the test jar.
or may be there is a lack of robustness in the quarkus test framework (ie: protecting from NPE), or there is a situation that is not handled when testing native, and an improvement could be done in the test framework.

**To Reproduce**
go to branch:
https://github.com/vsevel/quarkus/tree/issue_NPE_ArcTestRequestScopeProvider

and execute:
```
docker run -d --rm --publish 5432:5432 --name build-postgres -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -d postgres:10.5

./mvnw -am clean install \\
    --settings azure-mvn-settings.xml \\
    -Dnative-image.docker-build -Dtest-postgresql -Dtest-elasticsearch -Dtest-dynamodb -Ddynamodb-local.port=8000 -Dnative-image.xmx=6g -Dnative -Dno-format \\
    -pl integration-tests/jpa-postgresql
```

**Expected behavior**
the build should pass

**Actual behavior**
the build fails with:
```
[INFO] Running io.quarkus.it.jpa.postgresql.JPAFunctionalityInGraalITCase
[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.001 s <<< FAILURE! - in io.quarkus.it.jpa.postgresql.JPAFunctionalityInGraalITCase
[ERROR] testJPAFunctionalityFromServlet  Time elapsed: 0 s  <<< ERROR!
java.lang.NullPointerException
        at io.quarkus.arc.deployment.ArcTestRequestScopeProvider.setup(ArcTestRequestScopeProvider.java:12)
        at io.quarkus.test.common.TestScopeManager.tearDown(TestScopeManager.java:27)
        at io.quarkus.test.junit.QuarkusTestExtension.beforeEach(QuarkusTestExtension.java:308)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeEachCallbacks$1(TestMethodTestDescriptor.java:151)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeMethodsOrCallbacksUntilExceptionOccurs$5(TestMethodTestDescriptor.java:187)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeMethodsOrCallbacksUntilExceptionOccurs(TestMethodTestDescriptor.java:187)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeEachCallbacks(TestMethodTestDescriptor.java:150)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:129)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:69)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
        at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
        at java.util.ArrayList.forEach(ArrayList.java:1257)
        at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
        at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
        at java.util.ArrayList.forEach(ArrayList.java:1257)
        at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
        at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
        at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
        at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
        at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
        at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:170)
        at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:154)
        at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:90)
        at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invokeAllTests(JUnitPlatformProvider.java:142)
        at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:117)
        at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:383)
        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:344)
        at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:125)
        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:417)
```

**Environment (please complete the following information):**
 - Output of `uname -a` or `ver`: Linux quarkus-fedora 4.15.0-1040-gcp #42~16.04.1-Ubuntu SMP Wed Aug 7 16:42:41 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
 - Output of `java -version`: openjdk version "1.8.0_222"
OpenJDK Runtime Environment (build 1.8.0_222-8u222-b10-1ubuntu1~16.04.1-b10)
OpenJDK 64-Bit Server VM (build 25.222-b10, mixed mode)
 - GraalVM version (if different from Java): /home/vvsevel/graalvm-ce-19.1.1/bin/java -version
openjdk version "1.8.0_222"
OpenJDK Runtime Environment (build 1.8.0_222-20190711120915.buildslave.jdk8u-src-tar--b08)
OpenJDK 64-Bit GraalVM CE 19.1.1 (build 25.222-b08-jvmci-19.1-b01, mixed mode)
 - Quarkus version or git rev: 

**Additional context**
In the meantime, to workaround the issue in the vault extension, I changed the code to:
https://github.com/vsevel/quarkus/blob/master/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/ArcTestRequestScopeProvider.java#L13-L31


Changed files:
test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusTestExtension.java
core/deployment/src/main/java/io/quarkus/deployment/test/TestScopeSetup.java
extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/ArcTestRequestScopeProvider.java
test-framework/common/src/main/java/io/quarkus/test/common/TestScopeManager.java

diff --git a/core/deployment/src/main/java/io/quarkus/deployment/test/TestScopeSetup.java b/core/deployment/src/main/java/io/quarkus/deployment/test/TestScopeSetup.java
index 3663d099a3e..29388b6b8ba 100644
--- a/core/deployment/src/main/java/io/quarkus/deployment/test/TestScopeSetup.java
+++ b/core/deployment/src/main/java/io/quarkus/deployment/test/TestScopeSetup.java
@@ -2,7 +2,7 @@
 
 public interface TestScopeSetup {
 
-    void setup();
+    void setup(boolean isSubstrateTest);
 
-    void tearDown();
+    void tearDown(boolean isSubstrateTest);
 }
diff --git a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/ArcTestRequestScopeProvider.java b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/ArcTestRequestScopeProvider.java
index 08e68fb13cd..692967f5685 100644
--- a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/ArcTestRequestScopeProvider.java
+++ b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/ArcTestRequestScopeProvider.java
@@ -1,21 +1,39 @@
 package io.quarkus.arc.deployment;
 
+import org.jboss.logging.Logger;
+
 import io.quarkus.arc.Arc;
 import io.quarkus.arc.ArcContainer;
 import io.quarkus.deployment.test.TestScopeSetup;
 
 public class ArcTestRequestScopeProvider implements TestScopeSetup {
 
+    private static final Logger LOGGER = Logger.getLogger(ArcTestRequestScopeProvider.class);
+
     @Override
-    public void setup() {
+    public void setup(boolean isSubstrateTest) {
+        if (isSubstrateTest) {
+            return;
+        }
         ArcContainer container = Arc.container();
-        container.requestContext().activate();
+        if (container == null) {
+            LOGGER.warn("Container not available, ignoring setup");
+        } else {
+            container.requestContext().activate();
+        }
 
     }
 
     @Override
-    public void tearDown() {
+    public void tearDown(boolean isSubstrateTest) {
+        if (isSubstrateTest) {
+            return;
+        }
         ArcContainer container = Arc.container();
-        container.requestContext().terminate();
+        if (container == null) {
+            LOGGER.warn("Container not available, ignoring tearDown");
+        } else {
+            container.requestContext().terminate();
+        }
     }
 }
diff --git a/test-framework/common/src/main/java/io/quarkus/test/common/TestScopeManager.java b/test-framework/common/src/main/java/io/quarkus/test/common/TestScopeManager.java
index 6cd26b25aec..f0851e42d8a 100644
--- a/test-framework/common/src/main/java/io/quarkus/test/common/TestScopeManager.java
+++ b/test-framework/common/src/main/java/io/quarkus/test/common/TestScopeManager.java
@@ -8,23 +8,23 @@
 
 public class TestScopeManager {
 
-    private static final List<TestScopeSetup> scopeManagers = new ArrayList<>();
+    private static final List<TestScopeSetup> SCOPE_MANAGERS = new ArrayList<>();
 
     static {
         for (TestScopeSetup i : ServiceLoader.load(TestScopeSetup.class)) {
-            scopeManagers.add(i);
+            SCOPE_MANAGERS.add(i);
         }
     }
 
-    public static void setup() {
-        for (TestScopeSetup i : scopeManagers) {
-            i.setup();
+    public static void setup(boolean isSubstrateTest) {
+        for (TestScopeSetup i : SCOPE_MANAGERS) {
+            i.setup(isSubstrateTest);
         }
     }
 
-    public static void tearDown() {
-        for (TestScopeSetup i : scopeManagers) {
-            i.tearDown();
+    public static void tearDown(boolean isSubstrateTest) {
+        for (TestScopeSetup i : SCOPE_MANAGERS) {
+            i.tearDown(isSubstrateTest);
         }
     }
 }
diff --git a/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusTestExtension.java b/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusTestExtension.java
index b063cd5bd67..275c41b6c46 100644
--- a/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusTestExtension.java
+++ b/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusTestExtension.java
@@ -298,14 +298,16 @@ private URLClassLoader createQuarkusBuildClassLoader(Path appClassLocation) {
 
     @Override
     public void afterEach(ExtensionContext context) throws Exception {
+        boolean substrateTest = context.getRequiredTestClass().isAnnotationPresent(SubstrateTest.class);
         restAssuredURLManager.clearURL();
-        TestScopeManager.tearDown();
+        TestScopeManager.tearDown(substrateTest);
     }
 
     @Override
     public void beforeEach(ExtensionContext context) throws Exception {
+        boolean substrateTest = context.getRequiredTestClass().isAnnotationPresent(SubstrateTest.class);
         restAssuredURLManager.setURL();
-        TestScopeManager.setup();
+        TestScopeManager.setup(substrateTest);
     }
 
     @Override