Repository: firebase/firebase-admin-java
Pull request #563 (2021-05-24 05:02:35)

chore(deps): bump maven-source-plugin from 2.2.1 to 3.2.1
Bumps [maven-source-plugin](https://github.com/apache/maven-source-plugin) from 2.2.1 to 3.2.1.
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/apache/maven-source-plugin/commit/a59a2e481f7d8e46f2abbd339d2d27e9b2964eba"><code>a59a2e4</code></a> [maven-release-plugin] prepare release maven-source-plugin-3.2.1</li>
<li><a href="https://github.com/apache/maven-source-plugin/commit/c954a7e8fed86efc554e401361f88cdbf4109267"><code>c954a7e</code></a> make build as reproducible as possible for now</li>
<li><a href="https://github.com/apache/maven-source-plugin/commit/d5b98783436d9bff8737b63adc566466d2d8590a"><code>d5b9878</code></a> [MSOURCES-123] set archiver reproducible mode earlier</li>
<li><a href="https://github.com/apache/maven-source-plugin/commit/258d666ee76782c5211519313803fad9a8b408e1"><code>258d666</code></a> MSOURCES-122 make output independant from OS newline</li>
<li><a href="https://github.com/apache/maven-source-plugin/commit/5b4e02fbb49beb2f3e9ce3e001054519019a76fe"><code>5b4e02f</code></a> [maven-release-plugin] prepare for next development iteration</li>
<li><a href="https://github.com/apache/maven-source-plugin/commit/2a74824f267902808e1807c7f25989a3ce333916"><code>2a74824</code></a> [maven-release-plugin] prepare release maven-source-plugin-3.2.0</li>
<li><a href="https://github.com/apache/maven-source-plugin/commit/816ebc43984dfa852f50d8ed493a45f4b2384c9c"><code>816ebc4</code></a> MSOURCES-120 fix reproducible IT: remove plugin version from pom.xml</li>
<li><a href="https://github.com/apache/maven-source-plugin/commit/32f122aa7d2183fff36043c261d0a90bd9a4130a"><code>32f122a</code></a> MSOURCES-120 make output jar file binary Reproducible</li>
<li><a href="https://github.com/apache/maven-source-plugin/commit/6e715b18fecae00ebbf9704a37a5a0a77e06d690"><code>6e715b1</code></a> [MSOURCES-95] Source JAR is re-created even if sources are not changed</li>
<li><a href="https://github.com/apache/maven-source-plugin/commit/9154e1aba763594d653bfff7c395e940ace7e095"><code>9154e1a</code></a> [maven-release-plugin] prepare for next development iteration</li>
<li>Additional commits viewable in <a href="https://github.com/apache/maven-source-plugin/compare/maven-source-plugin-2.2.1...maven-source-plugin-3.2.1">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.apache.maven.plugins:maven-source-plugin&package-manager=maven&previous-version=2.2.1&new-version=3.2.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>


Patch:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 58ecbfa..e765291 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -19,13 +19,17 @@ jobs:
   build:
     runs-on: ubuntu-latest
 
+    strategy:
+      matrix:
+        java-version: [7, 8, 11]
+
     steps:
     - uses: actions/checkout@v1
 
-    - name: Set up JDK 1.7
+    - name: Set up JDK
       uses: actions/setup-java@v1
       with:
-        java-version: 1.7
+        java-version: ${{ matrix.java-version }}
 
     # Does the following:
     #  1. Runs the Checkstyle plugin (validate phase)
diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml
index c9259a6..dd3110c 100644
--- a/.github/workflows/nightly.yml
+++ b/.github/workflows/nightly.yml
@@ -33,10 +33,10 @@ jobs:
       with:
         ref: ${{ github.event.client_payload.ref || github.ref }}
 
-    - name: Set up JDK 1.7
+    - name: Set up JDK 1.8
       uses: actions/setup-java@v1
       with:
-        java-version: 1.7
+        java-version: 1.8
 
     - name: Compile, test and package
       run: ./.github/scripts/package_artifacts.sh
@@ -63,7 +63,7 @@ jobs:
         subject: 'Nightly build ${{github.run_id}} of ${{github.repository}} failed!'
         html: >
           <b>Nightly workflow ${{github.run_id}} failed on: ${{github.repository}}</b>
-          <br /><br />Navigate to the 
+          <br /><br />Navigate to the
           <a href="https://github.com/firebase/firebase-admin-java/actions/runs/${{github.run_id}}">failed workflow</a>.
       continue-on-error: true
 
@@ -78,6 +78,6 @@ jobs:
         subject: 'Nightly build ${{github.run_id}} of ${{github.repository}} cancelled!'
         html: >
           <b>Nightly workflow ${{github.run_id}} cancelled on: ${{github.repository}}</b>
-          <br /><br />Navigate to the 
+          <br /><br />Navigate to the
           <a href="https://github.com/firebase/firebase-admin-java/actions/runs/${{github.run_id}}">cancelled workflow</a>.
       continue-on-error: true
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 985ce94..b49a453 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -44,10 +44,10 @@ jobs:
       with:
         ref: ${{ github.event.client_payload.ref || github.ref }}
 
-    - name: Set up JDK 1.7
+    - name: Set up JDK 1.8
       uses: actions/setup-java@v1
       with:
-        java-version: 1.7
+        java-version: 1.8
 
     - name: Compile, test and package
       run: ./.github/scripts/package_artifacts.sh
@@ -82,10 +82,10 @@ jobs:
     - name: Checkout source for publish
       uses: actions/checkout@v2
 
-    - name: Set up JDK 1.7
+    - name: Set up JDK 1.8
       uses: actions/setup-java@v1
       with:
-        java-version: 1.7
+        java-version: 1.8
 
     - name: Publish preflight check
       id: preflight
diff --git a/pom.xml b/pom.xml
index b34f837..0b83ff8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -59,7 +59,7 @@
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
         <skipUTs>${skipTests}</skipUTs>
-        <netty.version>4.1.64.Final</netty.version>
+        <netty.version>4.1.65.Final</netty.version>
     </properties>
 
     <scm>
@@ -298,7 +298,7 @@
             <!-- Package Phase -->
             <plugin>
                 <artifactId>maven-source-plugin</artifactId>
-                <version>2.2.1</version>
+                <version>3.2.1</version>
                 <executions>
                     <execution>
                         <id>attach-sources</id>
@@ -393,7 +393,7 @@
             <dependency>
                 <groupId>com.google.cloud</groupId>
                 <artifactId>libraries-bom</artifactId>
-                <version>8.0.0</version>
+                <version>20.6.0</version>
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
@@ -446,7 +446,7 @@
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
-            <version>1.7.30</version>
+            <version>1.7.31</version>
         </dependency>
         <dependency>
             <groupId>io.netty</groupId>
diff --git a/src/main/java/com/google/firebase/FirebaseApp.java b/src/main/java/com/google/firebase/FirebaseApp.java
index d525d06..27727c3 100644
--- a/src/main/java/com/google/firebase/FirebaseApp.java
+++ b/src/main/java/com/google/firebase/FirebaseApp.java
@@ -35,6 +35,7 @@ import com.google.common.base.MoreObjects;
 import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableList;
 import com.google.firebase.internal.ApiClientUtils;
+import com.google.firebase.internal.FirebaseProcessEnvironment;
 import com.google.firebase.internal.FirebaseScheduledExecutor;
 import com.google.firebase.internal.FirebaseService;
 import com.google.firebase.internal.ListenableFuture2ApiFuture;
@@ -292,10 +293,10 @@ public class FirebaseApp {
 
     // Try to get project ID from the environment.
     if (Strings.isNullOrEmpty(projectId)) {
-      projectId = System.getenv("GOOGLE_CLOUD_PROJECT");
+      projectId = FirebaseProcessEnvironment.getenv("GOOGLE_CLOUD_PROJECT");
     }
     if (Strings.isNullOrEmpty(projectId)) {
-      projectId = System.getenv("GCLOUD_PROJECT");
+      projectId = FirebaseProcessEnvironment.getenv("GCLOUD_PROJECT");
     }
     return projectId;
   }
@@ -563,7 +564,7 @@ public class FirebaseApp {
   }
 
   private static FirebaseOptions getOptionsFromEnvironment() throws IOException {
-    String defaultConfig = System.getenv(FIREBASE_CONFIG_ENV_VAR);
+    String defaultConfig = FirebaseProcessEnvironment.getenv(FIREBASE_CONFIG_ENV_VAR);
     if (Strings.isNullOrEmpty(defaultConfig)) {
       return FirebaseOptions.builder()
           .setCredentials(APPLICATION_DEFAULT_CREDENTIALS)
diff --git a/src/main/java/com/google/firebase/FirebaseOptions.java b/src/main/java/com/google/firebase/FirebaseOptions.java
index f13f022..836f701 100644
--- a/src/main/java/com/google/firebase/FirebaseOptions.java
+++ b/src/main/java/com/google/firebase/FirebaseOptions.java
@@ -29,6 +29,7 @@ import com.google.common.base.Supplier;
 import com.google.common.base.Suppliers;
 import com.google.common.collect.ImmutableList;
 import com.google.firebase.internal.ApiClientUtils;
+import com.google.firebase.internal.ApplicationDefaultCredentialsProvider;
 import com.google.firebase.internal.FirebaseThreadManagers;
 import com.google.firebase.internal.NonNull;
 import com.google.firebase.internal.Nullable;
@@ -64,7 +65,8 @@ public final class FirebaseOptions {
         @Override
         public GoogleCredentials get() {
           try {
-            return GoogleCredentials.getApplicationDefault().createScoped(FIREBASE_SCOPES);
+            return ApplicationDefaultCredentialsProvider.getApplicationDefault()
+                .createScoped(FIREBASE_SCOPES);
           } catch (IOException e) {
             throw new IllegalStateException(e);
           }
diff --git a/src/main/java/com/google/firebase/auth/internal/Utils.java b/src/main/java/com/google/firebase/auth/internal/Utils.java
index 487892d..f4d0829 100644
--- a/src/main/java/com/google/firebase/auth/internal/Utils.java
+++ b/src/main/java/com/google/firebase/auth/internal/Utils.java
@@ -18,6 +18,7 @@ package com.google.firebase.auth.internal;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Strings;
+import com.google.firebase.internal.FirebaseProcessEnvironment;
 
 public class Utils {
   @VisibleForTesting
@@ -28,7 +29,7 @@ public class Utils {
   }
 
   public static String getEmulatorHost() {
-    return System.getenv(AUTH_EMULATOR_HOST);
+    return FirebaseProcessEnvironment.getenv(AUTH_EMULATOR_HOST);
   }
 
 }
diff --git a/src/main/java/com/google/firebase/database/util/EmulatorHelper.java b/src/main/java/com/google/firebase/database/util/EmulatorHelper.java
index c4ef2ff..11c358f 100644
--- a/src/main/java/com/google/firebase/database/util/EmulatorHelper.java
+++ b/src/main/java/com/google/firebase/database/util/EmulatorHelper.java
@@ -22,6 +22,7 @@ import com.google.firebase.database.annotations.Nullable;
 import com.google.firebase.database.core.RepoInfo;
 import com.google.firebase.database.utilities.ParsedUrl;
 import com.google.firebase.database.utilities.Utilities;
+import com.google.firebase.internal.FirebaseProcessEnvironment;
 
 public final class EmulatorHelper {
 
@@ -33,7 +34,7 @@ public final class EmulatorHelper {
       "FIREBASE_DATABASE_EMULATOR_HOST";
 
   public static String getEmulatorHostFromEnv() {
-    return System.getenv(FIREBASE_RTDB_EMULATOR_HOST_ENV_VAR);
+    return FirebaseProcessEnvironment.getenv(FIREBASE_RTDB_EMULATOR_HOST_ENV_VAR);
   }
 
   @VisibleForTesting
diff --git a/src/main/java/com/google/firebase/internal/ApplicationDefaultCredentialsProvider.java b/src/main/java/com/google/firebase/internal/ApplicationDefaultCredentialsProvider.java
new file mode 100644
index 0000000..93672bb
--- /dev/null
+++ b/src/main/java/com/google/firebase/internal/ApplicationDefaultCredentialsProvider.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2021 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.firebase.internal;
+
+import com.google.auth.oauth2.GoogleCredentials;
+import java.io.IOException;
+
+/**
+ * Provides a hook to override application default credentials (ADC) lookup for tests. ADC has
+ * a dependency on environment variables, and Java famously doesn't support environment variable
+ * manipulation at runtime. With this class, the test cases that require ADC has a way to register
+ * their own mock credentials as ADC.
+ *
+ * <p>Once we are able to upgrade to Mockito 3.x (requires Java 8+), we can drop this class
+ * altogether, and use Mockito tools to mock the behavior of the GoogleCredentials static methods.
+ */
+public class ApplicationDefaultCredentialsProvider {
+
+  private static GoogleCredentials cachedCredentials;
+
+  public static GoogleCredentials getApplicationDefault() throws IOException {
+    if (cachedCredentials != null) {
+      return cachedCredentials;
+    }
+
+    return GoogleCredentials.getApplicationDefault();
+  }
+
+  public static void setApplicationDefault(GoogleCredentials credentials) {
+    cachedCredentials = credentials;
+  }
+}
diff --git a/src/main/java/com/google/firebase/internal/FirebaseProcessEnvironment.java b/src/main/java/com/google/firebase/internal/FirebaseProcessEnvironment.java
new file mode 100644
index 0000000..a9c3022
--- /dev/null
+++ b/src/main/java/com/google/firebase/internal/FirebaseProcessEnvironment.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2021 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.firebase.internal;
+
+import com.google.common.base.Strings;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * A utility for overriding environment variables during tests.
+ */
+public class FirebaseProcessEnvironment {
+
+  private static final Map<String, String> localCache = new ConcurrentHashMap<>();
+
+  public static String getenv(String name) {
+    String cachedValue = localCache.get(name);
+    if (!Strings.isNullOrEmpty(cachedValue)) {
+      return  cachedValue;
+    }
+
+    return System.getenv(name);
+  }
+
+  public static void setenv(String name, String value) {
+    localCache.put(name, value);
+  }
+
+  public static void clearCache() {
+    localCache.clear();
+  }
+}
diff --git a/src/main/java/com/google/firebase/messaging/AndroidConfig.java b/src/main/java/com/google/firebase/messaging/AndroidConfig.java
index 888f00f..e38e561 100644
--- a/src/main/java/com/google/firebase/messaging/AndroidConfig.java
+++ b/src/main/java/com/google/firebase/messaging/AndroidConfig.java
@@ -112,9 +112,12 @@ public class AndroidConfig {
     private Builder() {}
 
     /**
-     * Sets a collapse key for the message. Collapse key serves as an identifier for a group of
+     * Sets a collapse key for the message. The collapse key serves as an identifier for a group of
      * messages that can be collapsed, so that only the last message gets sent when delivery can be
      * resumed. A maximum of 4 different collapse keys may be active at any given time.
+     * 
+     * <p>By default, the collapse key is the app package name registered in
+     * the Firebase console.</p>
      *
      * @param collapseKey A collapse key string.
      * @return This builder.


Test patch:
diff --git a/src/test/java/com/google/firebase/FirebaseAppTest.java b/src/test/java/com/google/firebase/FirebaseAppTest.java
index 56e025d..a35aefe 100644
--- a/src/test/java/com/google/firebase/FirebaseAppTest.java
+++ b/src/test/java/com/google/firebase/FirebaseAppTest.java
@@ -38,9 +38,10 @@ import com.google.common.base.Strings;
 import com.google.common.base.Suppliers;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
 import com.google.firebase.FirebaseApp.TokenRefresher;
 import com.google.firebase.database.FirebaseDatabase;
+import com.google.firebase.internal.ApplicationDefaultCredentialsProvider;
+import com.google.firebase.internal.FirebaseProcessEnvironment;
 import com.google.firebase.internal.FirebaseService;
 import com.google.firebase.testing.FirebaseAppRule;
 import com.google.firebase.testing.ServiceAccount;
@@ -62,7 +63,6 @@ import java.util.concurrent.Callable;
 import java.util.concurrent.TimeUnit;
 import org.junit.AfterClass;
 import org.junit.Assert;
-import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
 import org.mockito.Mockito;
@@ -72,21 +72,19 @@ import org.mockito.Mockito;
  */
 public class FirebaseAppTest {
 
+  private static final GoogleCredentials TEST_CREDENTIALS = TestUtils.getCertCredential(
+      ServiceAccount.EDITOR.asStream());
+
   private static final FirebaseOptions OPTIONS =
       FirebaseOptions.builder()
-          .setCredentials(TestUtils.getCertCredential(ServiceAccount.EDITOR.asStream()))
+          .setCredentials(TEST_CREDENTIALS)
           .build();
 
   @Rule public FirebaseAppRule firebaseAppRule = new FirebaseAppRule();
 
-  @BeforeClass
-  public static void setupClass() throws IOException {
-    TestUtils.getApplicationDefaultCredentials();
-  }
-
   @AfterClass
   public static void tearDownClass() {
-    TestUtils.unsetEnvironmentVariables(ImmutableSet.of(FirebaseApp.FIREBASE_CONFIG_ENV_VAR));
+    FirebaseProcessEnvironment.clearCache();
   }
 
   @Test(expected = NullPointerException.class)
@@ -128,8 +126,7 @@ public class FirebaseAppTest {
   public void testGetProjectIdFromEnvironment() {
     List<String> variables = ImmutableList.of("GCLOUD_PROJECT", "GOOGLE_CLOUD_PROJECT");
     for (String variable : variables) {
-      String gcloudProject = System.getenv(variable);
-      TestUtils.setEnvironmentVariables(ImmutableMap.of(variable, "project-id-1"));
+      FirebaseProcessEnvironment.setenv(variable, "project-id-1");
       FirebaseOptions options = FirebaseOptions.builder()
           .setCredentials(new MockGoogleCredentials())
           .build();
@@ -138,8 +135,7 @@ public class FirebaseAppTest {
         String projectId = ImplFirebaseTrampolines.getProjectId(app);
         assertEquals("project-id-1", projectId);
       } finally {
-        TestUtils.setEnvironmentVariables(ImmutableMap.of(
-            variable, Strings.nullToEmpty(gcloudProject)));
+        FirebaseProcessEnvironment.clearCache();
       }
     }
   }
@@ -152,8 +148,8 @@ public class FirebaseAppTest {
     currentValues.put("GOOGLE_CLOUD_PROJECT", Strings.nullToEmpty(
         System.getenv("GOOGLE_CLOUD_PROJECT")));
 
-    TestUtils.setEnvironmentVariables(ImmutableMap.of(
-        "GCLOUD_PROJECT", "project-id-1", "GOOGLE_CLOUD_PROJECT", "project-id-2"));
+    FirebaseProcessEnvironment.setenv("GCLOUD_PROJECT", "project-id-1");
+    FirebaseProcessEnvironment.setenv("GOOGLE_CLOUD_PROJECT", "project-id-2");
     FirebaseOptions options = FirebaseOptions.builder()
         .setCredentials(new MockGoogleCredentials())
         .build();
@@ -162,7 +158,7 @@ public class FirebaseAppTest {
       String projectId = ImplFirebaseTrampolines.getProjectId(app);
       assertEquals("project-id-2", projectId);
     } finally {
-      TestUtils.setEnvironmentVariables(currentValues);
+      FirebaseProcessEnvironment.clearCache();
     }
   }
 
@@ -264,11 +260,7 @@ public class FirebaseAppTest {
 
   @Test
   public void testToString() throws IOException {
-    FirebaseOptions options =
-        FirebaseOptions.builder()
-            .setCredentials(GoogleCredentials.fromStream(ServiceAccount.EDITOR.asStream()))
-            .build();
-    FirebaseApp app = FirebaseApp.initializeApp(options, "app");
+    FirebaseApp app = FirebaseApp.initializeApp(OPTIONS, "app");
     String pattern = "FirebaseApp\\{name=app}";
     assertTrue(app.toString().matches(pattern));
   }
@@ -503,23 +495,33 @@ public class FirebaseAppTest {
   }
 
   @Test
-  public void testEmptyFirebaseConfigString() {
+  public void testEmptyFirebaseConfigString() throws IOException {
     setFirebaseConfigEnvironmentVariable("");
-    FirebaseApp firebaseApp = FirebaseApp.initializeApp();
-    assertNull(firebaseApp.getOptions().getProjectId());
-    assertNull(firebaseApp.getOptions().getStorageBucket());
-    assertNull(firebaseApp.getOptions().getDatabaseUrl());
-    assertTrue(firebaseApp.getOptions().getDatabaseAuthVariableOverride().isEmpty());
+    ApplicationDefaultCredentialsProvider.setApplicationDefault(TEST_CREDENTIALS);
+    try {
+      FirebaseApp firebaseApp = FirebaseApp.initializeApp();
+      assertNull(firebaseApp.getOptions().getProjectId());
+      assertNull(firebaseApp.getOptions().getStorageBucket());
+      assertNull(firebaseApp.getOptions().getDatabaseUrl());
+      assertTrue(firebaseApp.getOptions().getDatabaseAuthVariableOverride().isEmpty());
+    } finally {
+      ApplicationDefaultCredentialsProvider.setApplicationDefault(null);
+    }
   }
 
   @Test
-  public void testEmptyFirebaseConfigJSONObject() {
+  public void testEmptyFirebaseConfigJSONObject() throws IOException {
     setFirebaseConfigEnvironmentVariable("{}");
-    FirebaseApp firebaseApp = FirebaseApp.initializeApp();
-    assertNull(firebaseApp.getOptions().getProjectId());
-    assertNull(firebaseApp.getOptions().getStorageBucket());
-    assertNull(firebaseApp.getOptions().getDatabaseUrl());
-    assertTrue(firebaseApp.getOptions().getDatabaseAuthVariableOverride().isEmpty());
+    ApplicationDefaultCredentialsProvider.setApplicationDefault(TEST_CREDENTIALS);
+    try {
+      FirebaseApp firebaseApp = FirebaseApp.initializeApp();
+      assertNull(firebaseApp.getOptions().getProjectId());
+      assertNull(firebaseApp.getOptions().getStorageBucket());
+      assertNull(firebaseApp.getOptions().getDatabaseUrl());
+      assertTrue(firebaseApp.getOptions().getDatabaseAuthVariableOverride().isEmpty());
+    } finally {
+      ApplicationDefaultCredentialsProvider.setApplicationDefault(null);
+    }
   }
 
   @Test(expected = IllegalArgumentException.class)
@@ -541,21 +543,33 @@ public class FirebaseAppTest {
   }
 
   @Test
-  public void testFirebaseConfigFileWithSomeKeysMissing() {
+  public void testFirebaseConfigFileWithSomeKeysMissing() throws IOException {
     setFirebaseConfigEnvironmentVariable("firebase_config_partial.json");
-    FirebaseApp firebaseApp = FirebaseApp.initializeApp();
-    assertEquals("hipster-chat-mock", firebaseApp.getOptions().getProjectId());
-    assertEquals("https://hipster-chat.firebaseio.mock", firebaseApp.getOptions().getDatabaseUrl());
+    ApplicationDefaultCredentialsProvider.setApplicationDefault(TEST_CREDENTIALS);
+    try {
+      FirebaseApp firebaseApp = FirebaseApp.initializeApp();
+      assertEquals("hipster-chat-mock", firebaseApp.getOptions().getProjectId());
+      assertEquals("https://hipster-chat.firebaseio.mock", firebaseApp.getOptions().getDatabaseUrl());
+    } finally {
+      ApplicationDefaultCredentialsProvider.setApplicationDefault(null);
+    }
   }
 
   @Test
-  public void testValidFirebaseConfigFile() {
+  public void testValidFirebaseConfigFile() throws IOException {
     setFirebaseConfigEnvironmentVariable("firebase_config.json");
-    FirebaseApp firebaseApp = FirebaseApp.initializeApp();
-    assertEquals("hipster-chat-mock", firebaseApp.getOptions().getProjectId());
-    assertEquals("hipster-chat.appspot.mock", firebaseApp.getOptions().getStorageBucket());
-    assertEquals("https://hipster-chat.firebaseio.mock", firebaseApp.getOptions().getDatabaseUrl());
-    assertEquals("testuser", firebaseApp.getOptions().getDatabaseAuthVariableOverride().get("uid"));
+    ApplicationDefaultCredentialsProvider.setApplicationDefault(TEST_CREDENTIALS);
+    try {
+      FirebaseApp firebaseApp = FirebaseApp.initializeApp();
+      assertEquals("hipster-chat-mock", firebaseApp.getOptions().getProjectId());
+      assertEquals("hipster-chat.appspot.mock", firebaseApp.getOptions().getStorageBucket());
+      assertEquals(
+          "https://hipster-chat.firebaseio.mock", firebaseApp.getOptions().getDatabaseUrl());
+      assertEquals(
+          "testuser", firebaseApp.getOptions().getDatabaseAuthVariableOverride().get("uid"));
+    } finally {
+      ApplicationDefaultCredentialsProvider.setApplicationDefault(null);
+    }
   }
 
   @Test
@@ -569,7 +583,7 @@ public class FirebaseAppTest {
   }
 
   @Test
-  public void testValidFirebaseConfigString() {
+  public void testValidFirebaseConfigString() throws IOException {
     setFirebaseConfigEnvironmentVariable("{"
         + "\"databaseAuthVariableOverride\": {"
         +   "\"uid\":"
@@ -579,29 +593,44 @@ public class FirebaseAppTest {
         + "\"projectId\": \"hipster-chat-mock\","
         + "\"storageBucket\": \"hipster-chat.appspot.mock\""
         + "}");
-    FirebaseApp firebaseApp = FirebaseApp.initializeApp();
-    assertEquals("hipster-chat-mock", firebaseApp.getOptions().getProjectId());
-    assertEquals("hipster-chat.appspot.mock", firebaseApp.getOptions().getStorageBucket());
-    assertEquals("https://hipster-chat.firebaseio.mock", firebaseApp.getOptions().getDatabaseUrl());
-    assertEquals("testuser",
-        firebaseApp.getOptions().getDatabaseAuthVariableOverride().get("uid"));
+    ApplicationDefaultCredentialsProvider.setApplicationDefault(TEST_CREDENTIALS);
+    try {
+      FirebaseApp firebaseApp = FirebaseApp.initializeApp();
+      assertEquals("hipster-chat-mock", firebaseApp.getOptions().getProjectId());
+      assertEquals("hipster-chat.appspot.mock", firebaseApp.getOptions().getStorageBucket());
+      assertEquals("https://hipster-chat.firebaseio.mock", firebaseApp.getOptions().getDatabaseUrl());
+      assertEquals("testuser",
+          firebaseApp.getOptions().getDatabaseAuthVariableOverride().get("uid"));
+    } finally {
+      ApplicationDefaultCredentialsProvider.setApplicationDefault(null);
+    }
   }
 
   @Test
-  public void testFirebaseConfigFileIgnoresInvalidKey() {
+  public void testFirebaseConfigFileIgnoresInvalidKey() throws IOException {
     setFirebaseConfigEnvironmentVariable("firebase_config_invalid_key.json");
-    FirebaseApp firebaseApp = FirebaseApp.initializeApp();
-    assertEquals("hipster-chat-mock", firebaseApp.getOptions().getProjectId());
+    ApplicationDefaultCredentialsProvider.setApplicationDefault(TEST_CREDENTIALS);
+    try {
+      FirebaseApp firebaseApp = FirebaseApp.initializeApp();
+      assertEquals("hipster-chat-mock", firebaseApp.getOptions().getProjectId());
+    } finally {
+      ApplicationDefaultCredentialsProvider.setApplicationDefault(null);
+    }
   }
 
   @Test
-  public void testFirebaseConfigStringIgnoresInvalidKey() {
+  public void testFirebaseConfigStringIgnoresInvalidKey() throws IOException {
     setFirebaseConfigEnvironmentVariable("{"
         + "\"databaseUareL\": \"https://hipster-chat.firebaseio.mock\","
         + "\"projectId\": \"hipster-chat-mock\""
         + "}");
-    FirebaseApp firebaseApp = FirebaseApp.initializeApp();
-    assertEquals("hipster-chat-mock", firebaseApp.getOptions().getProjectId());
+    ApplicationDefaultCredentialsProvider.setApplicationDefault(TEST_CREDENTIALS);
+    try {
+      FirebaseApp firebaseApp = FirebaseApp.initializeApp();
+      assertEquals("hipster-chat-mock", firebaseApp.getOptions().getProjectId());
+    } finally {
+      ApplicationDefaultCredentialsProvider.setApplicationDefault(null);
+    }
   }
 
   @Test
@@ -618,9 +647,8 @@ public class FirebaseAppTest {
     } else {
       configValue = new File("src/test/resources", configJSON).getAbsolutePath();
     }
-    Map<String, String> environmentVariables =
-        ImmutableMap.of(FirebaseApp.FIREBASE_CONFIG_ENV_VAR , configValue);
-    TestUtils.setEnvironmentVariables(environmentVariables);
+
+    FirebaseProcessEnvironment.setenv(FirebaseApp.FIREBASE_CONFIG_ENV_VAR, configValue);
   }
 
   private static FirebaseOptions getMockCredentialOptions() {
diff --git a/src/test/java/com/google/firebase/auth/EmulatorFirebaseTokenVerifierImplTest.java b/src/test/java/com/google/firebase/auth/EmulatorFirebaseTokenVerifierImplTest.java
index 0cc12c6..55ca7bf 100644
--- a/src/test/java/com/google/firebase/auth/EmulatorFirebaseTokenVerifierImplTest.java
+++ b/src/test/java/com/google/firebase/auth/EmulatorFirebaseTokenVerifierImplTest.java
@@ -29,11 +29,9 @@ import static org.junit.Assert.fail;
 
 import com.google.api.client.googleapis.auth.oauth2.GooglePublicKeysManager;
 import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
 import com.google.firebase.ErrorCode;
+import com.google.firebase.internal.FirebaseProcessEnvironment;
 import com.google.firebase.testing.ServiceAccount;
-import com.google.firebase.testing.TestUtils;
 import java.util.concurrent.TimeUnit;
 import org.junit.After;
 import org.junit.Before;
@@ -46,7 +44,7 @@ public class EmulatorFirebaseTokenVerifierImplTest {
   @Before
   public void setUp() throws Exception {
     // Set the Auth Emulator host prior to initialization
-    TestUtils.setEnvironmentVariables(ImmutableMap.of(AUTH_EMULATOR_HOST, "localhost:9099"));
+    FirebaseProcessEnvironment.setenv(AUTH_EMULATOR_HOST, "localhost:9099");
     ServiceAccount serviceAccount = ServiceAccount.EDITOR;
     GooglePublicKeysManager publicKeysManager = newPublicKeysManager(serviceAccount.getCert());
     this.tokenVerifier = newTestTokenVerifier(publicKeysManager);
@@ -55,7 +53,7 @@ public class EmulatorFirebaseTokenVerifierImplTest {
 
   @After
   public void tearDown() {
-    TestUtils.unsetEnvironmentVariables(ImmutableSet.of(AUTH_EMULATOR_HOST));
+    FirebaseProcessEnvironment.clearCache();
   }
 
   @Test
diff --git a/src/test/java/com/google/firebase/auth/FirebaseAuthTest.java b/src/test/java/com/google/firebase/auth/FirebaseAuthTest.java
index d385e7e..8784193 100644
--- a/src/test/java/com/google/firebase/auth/FirebaseAuthTest.java
+++ b/src/test/java/com/google/firebase/auth/FirebaseAuthTest.java
@@ -31,12 +31,12 @@ import com.google.api.core.ApiFuture;
 import com.google.common.base.Supplier;
 import com.google.common.base.Suppliers;
 import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
 import com.google.firebase.ErrorCode;
 
 import com.google.firebase.FirebaseApp;
 import com.google.firebase.FirebaseOptions;
 import com.google.firebase.TestOnlyImplFirebaseTrampolines;
+import com.google.firebase.internal.FirebaseProcessEnvironment;
 import com.google.firebase.testing.ServiceAccount;
 import com.google.firebase.testing.TestResponseInterceptor;
 import com.google.firebase.testing.TestUtils;
@@ -62,7 +62,7 @@ public class FirebaseAuthTest {
   @After
   public void cleanup() {
     // Cleanup for tests on Auth Emulator
-    TestUtils.unsetEnvironmentVariables(ImmutableSet.of("FIREBASE_AUTH_EMULATOR_HOST"));
+    FirebaseProcessEnvironment.clearCache();
     TestOnlyImplFirebaseTrampolines.clearInstancesForTest();
   }
 
@@ -269,8 +269,7 @@ public class FirebaseAuthTest {
   @Test
   public void testVerifyIdTokenWithEmulator() throws Exception {
     // Enable emulator mode
-    TestUtils.setEnvironmentVariables(
-        ImmutableMap.of("FIREBASE_AUTH_EMULATOR_HOST", AUTH_EMULATOR));
+    FirebaseProcessEnvironment.setenv("FIREBASE_AUTH_EMULATOR_HOST", AUTH_EMULATOR);
     MockTokenVerifier tokenVerifier = MockTokenVerifier.fromResult(
         getFirebaseToken(VALID_SINCE + 1000));
     FirebaseAuth auth = getAuthForIdTokenVerificationWithRevocationCheck(tokenVerifier);
@@ -284,8 +283,7 @@ public class FirebaseAuthTest {
   @Test
   public void testVerifyIdTokenFailureWithEmulator() {
     // Enable emulator mode
-    TestUtils.setEnvironmentVariables(
-        ImmutableMap.of("FIREBASE_AUTH_EMULATOR_HOST", AUTH_EMULATOR));
+    FirebaseProcessEnvironment.setenv("FIREBASE_AUTH_EMULATOR_HOST", AUTH_EMULATOR);
     MockTokenVerifier tokenVerifier = MockTokenVerifier.fromResult(
         getFirebaseToken(VALID_SINCE - 1000));
     FirebaseAuth auth = getAuthForIdTokenVerificationWithRevocationCheck(tokenVerifier);
diff --git a/src/test/java/com/google/firebase/auth/FirebaseTokenUtilsTest.java b/src/test/java/com/google/firebase/auth/FirebaseTokenUtilsTest.java
index ccc1ad6..a274c0b 100644
--- a/src/test/java/com/google/firebase/auth/FirebaseTokenUtilsTest.java
+++ b/src/test/java/com/google/firebase/auth/FirebaseTokenUtilsTest.java
@@ -27,13 +27,11 @@ import com.google.api.client.json.gson.GsonFactory;
 import com.google.api.client.testing.http.FixedClock;
 import com.google.api.client.util.Clock;
 import com.google.auth.oauth2.GoogleCredentials;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.firebase.FirebaseApp;
 import com.google.firebase.FirebaseOptions;
 import com.google.firebase.TestOnlyImplFirebaseTrampolines;
-import com.google.firebase.testing.TestUtils;
+import com.google.firebase.internal.FirebaseProcessEnvironment;
 import org.junit.After;
 import org.junit.Rule;
 import org.junit.Test;
@@ -51,7 +49,7 @@ public class FirebaseTokenUtilsTest {
 
   @After
   public void tearDown() {
-    TestUtils.unsetEnvironmentVariables(ImmutableSet.of("FIREBASE_AUTH_EMULATOR_HOST"));
+    FirebaseProcessEnvironment.clearCache();
     TestOnlyImplFirebaseTrampolines.clearInstancesForTest();
   }
 
@@ -79,8 +77,7 @@ public class FirebaseTokenUtilsTest {
 
   @Test
   public void testCreateIdTokenVerifierForEmulator() {
-    TestUtils.setEnvironmentVariables(
-        ImmutableMap.of("FIREBASE_AUTH_EMULATOR_HOST", AUTH_EMULATOR));
+    FirebaseProcessEnvironment.setenv("FIREBASE_AUTH_EMULATOR_HOST", AUTH_EMULATOR);
     FirebaseApp app = FirebaseApp.initializeApp(FirebaseOptions.builder()
         .setCredentials(MOCK_CREDENTIALS)
         .setProjectId(TEST_PROJECT_ID)
@@ -130,8 +127,7 @@ public class FirebaseTokenUtilsTest {
 
   @Test
   public void testSessionCookieVerifierForEmulator() {
-    TestUtils.setEnvironmentVariables(
-        ImmutableMap.of("FIREBASE_AUTH_EMULATOR_HOST", AUTH_EMULATOR));
+    FirebaseProcessEnvironment.setenv("FIREBASE_AUTH_EMULATOR_HOST", AUTH_EMULATOR);
     FirebaseApp app = FirebaseApp.initializeApp(FirebaseOptions.builder()
         .setCredentials(MOCK_CREDENTIALS)
         .setProjectId(TEST_PROJECT_ID)
diff --git a/src/test/java/com/google/firebase/auth/FirebaseUserManagerTest.java b/src/test/java/com/google/firebase/auth/FirebaseUserManagerTest.java
index 83b9806..cd43c01 100644
--- a/src/test/java/com/google/firebase/auth/FirebaseUserManagerTest.java
+++ b/src/test/java/com/google/firebase/auth/FirebaseUserManagerTest.java
@@ -38,7 +38,6 @@ import com.google.common.base.Strings;
 import com.google.common.base.Supplier;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.firebase.ErrorCode;
 import com.google.firebase.FirebaseApp;
@@ -48,6 +47,7 @@ import com.google.firebase.auth.FirebaseUserManager.EmailLinkType;
 import com.google.firebase.auth.multitenancy.TenantAwareFirebaseAuth;
 import com.google.firebase.auth.multitenancy.TenantManager;
 import com.google.firebase.internal.ApiClientUtils;
+import com.google.firebase.internal.FirebaseProcessEnvironment;
 import com.google.firebase.internal.SdkUtils;
 import com.google.firebase.testing.MultiRequestMockHttpTransport;
 import com.google.firebase.testing.TestResponseInterceptor;
@@ -108,7 +108,7 @@ public class FirebaseUserManagerTest {
 
   @After
   public void tearDown() {
-    TestUtils.unsetEnvironmentVariables(ImmutableSet.of("FIREBASE_AUTH_EMULATOR_HOST"));
+    FirebaseProcessEnvironment.clearCache();
     TestOnlyImplFirebaseTrampolines.clearInstancesForTest();
   }
 
@@ -2853,8 +2853,7 @@ public class FirebaseUserManagerTest {
 
   @Test
   public void testCreateOidcProviderFromEmulatorAuth() throws Exception {
-    TestUtils.setEnvironmentVariables(
-            ImmutableMap.of("FIREBASE_AUTH_EMULATOR_HOST", AUTH_EMULATOR));
+    FirebaseProcessEnvironment.setenv("FIREBASE_AUTH_EMULATOR_HOST", AUTH_EMULATOR);
     TestResponseInterceptor interceptor = initializeAppForUserManagement(OIDC_RESPONSE);
     OidcProviderConfig.CreateRequest createRequest =
             new OidcProviderConfig.CreateRequest()
diff --git a/src/test/java/com/google/firebase/auth/multitenancy/FirebaseTenantClientTest.java b/src/test/java/com/google/firebase/auth/multitenancy/FirebaseTenantClientTest.java
index b940389..3e57dc3 100644
--- a/src/test/java/com/google/firebase/auth/multitenancy/FirebaseTenantClientTest.java
+++ b/src/test/java/com/google/firebase/auth/multitenancy/FirebaseTenantClientTest.java
@@ -34,8 +34,6 @@ import com.google.api.client.testing.http.MockHttpTransport;
 import com.google.api.client.testing.http.MockLowLevelHttpResponse;
 import com.google.auth.oauth2.GoogleCredentials;
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.firebase.ErrorCode;
 import com.google.firebase.FirebaseApp;
@@ -46,6 +44,7 @@ import com.google.firebase.auth.FirebaseAuth;
 import com.google.firebase.auth.FirebaseAuthException;
 import com.google.firebase.auth.MockGoogleCredentials;
 import com.google.firebase.internal.ApiClientUtils;
+import com.google.firebase.internal.FirebaseProcessEnvironment;
 import com.google.firebase.internal.SdkUtils;
 import com.google.firebase.testing.MultiRequestMockHttpTransport;
 import com.google.firebase.testing.TestResponseInterceptor;
@@ -78,7 +77,7 @@ public class FirebaseTenantClientTest {
 
   @After
   public void tearDown() throws ReflectiveOperationException {
-    TestUtils.unsetEnvironmentVariables(ImmutableSet.of("FIREBASE_AUTH_EMULATOR_HOST"));
+    FirebaseProcessEnvironment.clearCache();
     TestOnlyImplFirebaseTrampolines.clearInstancesForTest();
   }
 
@@ -323,8 +322,7 @@ public class FirebaseTenantClientTest {
 
   @Test
   public void testGetTenantFromAuthEmulator() throws Exception {
-    TestUtils.setEnvironmentVariables(
-            ImmutableMap.of("FIREBASE_AUTH_EMULATOR_HOST", AUTH_EMULATOR));
+    FirebaseProcessEnvironment.setenv("FIREBASE_AUTH_EMULATOR_HOST", AUTH_EMULATOR);
     TestResponseInterceptor interceptor = initializeAppForTenantManagement(
             TestUtils.loadResource("tenant.json"));
 
diff --git a/src/test/java/com/google/firebase/cloud/FirestoreClientTest.java b/src/test/java/com/google/firebase/cloud/FirestoreClientTest.java
index 08ee49f..018d0e4 100644
--- a/src/test/java/com/google/firebase/cloud/FirestoreClientTest.java
+++ b/src/test/java/com/google/firebase/cloud/FirestoreClientTest.java
@@ -69,11 +69,9 @@ public class FirestoreClientTest {
         .build());
     Firestore firestore = FirestoreClient.getFirestore(app);
     assertEquals("explicit-project-id", firestore.getOptions().getProjectId());
-    assertTrue(firestore.getOptions().areTimestampsInSnapshotsEnabled());
 
     firestore = FirestoreClient.getFirestore();
     assertEquals("explicit-project-id", firestore.getOptions().getProjectId());
-    assertTrue(firestore.getOptions().areTimestampsInSnapshotsEnabled());
   }
 
   @Test
@@ -88,13 +86,11 @@ public class FirestoreClientTest {
         .build());
     Firestore firestore = FirestoreClient.getFirestore(app);
     assertEquals("explicit-project-id", firestore.getOptions().getProjectId());
-    assertTrue(firestore.getOptions().areTimestampsInSnapshotsEnabled());
     assertSame(ImplFirebaseTrampolines.getCredentials(app),
         firestore.getOptions().getCredentialsProvider().getCredentials());
 
     firestore = FirestoreClient.getFirestore();
     assertEquals("explicit-project-id", firestore.getOptions().getProjectId());
-    assertTrue(firestore.getOptions().areTimestampsInSnapshotsEnabled());
     assertSame(ImplFirebaseTrampolines.getCredentials(app),
         firestore.getOptions().getCredentialsProvider().getCredentials());
   }
diff --git a/src/test/java/com/google/firebase/database/FirebaseDatabaseTest.java b/src/test/java/com/google/firebase/database/FirebaseDatabaseTest.java
index 2bdc618..3dc2374 100644
--- a/src/test/java/com/google/firebase/database/FirebaseDatabaseTest.java
+++ b/src/test/java/com/google/firebase/database/FirebaseDatabaseTest.java
@@ -23,15 +23,13 @@ import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.fail;
 
-import com.google.auth.oauth2.GoogleCredentials;
 import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
 import com.google.firebase.FirebaseApp;
 import com.google.firebase.FirebaseOptions;
 import com.google.firebase.TestOnlyImplFirebaseTrampolines;
 import com.google.firebase.database.util.EmulatorHelper;
+import com.google.firebase.internal.FirebaseProcessEnvironment;
 import com.google.firebase.testing.ServiceAccount;
 import com.google.firebase.testing.TestUtils;
 import java.io.IOException;
@@ -220,9 +218,9 @@ public class FirebaseDatabaseTest {
     for (CustomTestCase tc : testCases) {
       try {
         FirebaseApp app = FirebaseApp.initializeApp(firebaseOptionsWithoutDatabaseUrl);
-        TestUtils.setEnvironmentVariables(
-            ImmutableMap.of(EmulatorHelper.FIREBASE_RTDB_EMULATOR_HOST_ENV_VAR,
-                Strings.nullToEmpty(tc.envVariableUrl)));
+        FirebaseProcessEnvironment.setenv(
+            EmulatorHelper.FIREBASE_RTDB_EMULATOR_HOST_ENV_VAR,
+            Strings.nullToEmpty(tc.envVariableUrl));
         FirebaseDatabase instance = FirebaseDatabase.getInstance(app, tc.rootDbUrl);
         assertEquals(tc.expectedEmulatorRootUrl,
             instance.getReference().repo.getRepoInfo().toString());
@@ -230,8 +228,7 @@ public class FirebaseDatabaseTest {
         // clean up after
         app.delete();
       } finally {
-        TestUtils.unsetEnvironmentVariables(
-            ImmutableSet.of(EmulatorHelper.FIREBASE_RTDB_EMULATOR_HOST_ENV_VAR));
+        FirebaseProcessEnvironment.clearCache();
       }
     }
   }
@@ -257,9 +254,9 @@ public class FirebaseDatabaseTest {
     for (CustomTestCase tc : testCases) {
       try {
         FirebaseApp app = FirebaseApp.initializeApp(firebaseOptionsWithoutDatabaseUrl);
-        TestUtils.setEnvironmentVariables(
-            ImmutableMap.of(EmulatorHelper.FIREBASE_RTDB_EMULATOR_HOST_ENV_VAR,
-                Strings.nullToEmpty(tc.envVariableUrl)));
+        FirebaseProcessEnvironment.setenv(
+            EmulatorHelper.FIREBASE_RTDB_EMULATOR_HOST_ENV_VAR,
+            Strings.nullToEmpty(tc.envVariableUrl));
         FirebaseDatabase instance = FirebaseDatabase.getInstance(app, tc.rootDbUrl);
         DatabaseReference dbRef = instance.getReferenceFromUrl(tc.pathUrl);
         assertEquals(tc.expectedEmulatorRootUrl, dbRef.repo.getRepoInfo().toString());
@@ -269,8 +266,7 @@ public class FirebaseDatabaseTest {
         app.delete();
 
       } finally {
-        TestUtils.unsetEnvironmentVariables(
-            ImmutableSet.of(EmulatorHelper.FIREBASE_RTDB_EMULATOR_HOST_ENV_VAR));
+        FirebaseProcessEnvironment.clearCache();
       }
     }
   }
diff --git a/src/test/java/com/google/firebase/testing/IntegrationTestUtils.java b/src/test/java/com/google/firebase/testing/IntegrationTestUtils.java
index 3d0c550..1c0a24c 100644
--- a/src/test/java/com/google/firebase/testing/IntegrationTestUtils.java
+++ b/src/test/java/com/google/firebase/testing/IntegrationTestUtils.java
@@ -193,7 +193,12 @@ public class IntegrationTestUtils {
 
     private ResponseInfo(HttpResponse response) throws IOException {
       this.status = response.getStatusCode();
-      this.payload = ByteStreams.toByteArray(response.getContent());
+      InputStream in = response.getContent();
+      if (in != null) {
+        this.payload = ByteStreams.toByteArray(in);
+      } else {
+        this.payload = new byte[0];
+      }
     }
 
     public int getStatus() {
diff --git a/src/test/java/com/google/firebase/testing/TestUtils.java b/src/test/java/com/google/firebase/testing/TestUtils.java
index e44ca2b..59f6b71 100644
--- a/src/test/java/com/google/firebase/testing/TestUtils.java
+++ b/src/test/java/com/google/firebase/testing/TestUtils.java
@@ -18,7 +18,6 @@ package com.google.firebase.testing;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
-import com.google.api.client.googleapis.testing.auth.oauth2.MockTokenServerTransport;
 import com.google.api.client.http.EmptyContent;
 import com.google.api.client.http.GenericUrl;
 import com.google.api.client.http.HttpRequest;
@@ -28,32 +27,20 @@ import com.google.api.client.http.LowLevelHttpRequest;
 import com.google.api.client.json.webtoken.JsonWebSignature;
 import com.google.api.client.testing.http.MockHttpTransport;
 import com.google.api.client.testing.http.MockLowLevelHttpRequest;
-import com.google.auth.http.HttpTransportFactory;
 import com.google.auth.oauth2.GoogleCredentials;
-import com.google.common.collect.ImmutableMap;
 import com.google.common.io.CharStreams;
-import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
 import java.security.PublicKey;
-import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
 
 /** Test Utils for use by all tests (both unit and integration tests). */
 public class TestUtils {
 
   public static final long TEST_TIMEOUT_MILLIS = 7 * 1000;
-  private static final String TEST_ADC_ACCESS_TOKEN = "test-adc-access-token";
   private static final GenericUrl TEST_URL = new GenericUrl("https://firebase.google.com");
 
-  private static GoogleCredentials defaultCredentials;
-
   public static boolean verifySignature(JsonWebSignature token, List<PublicKey> keys)
       throws Exception {
     for (PublicKey key : keys) {
@@ -64,52 +51,6 @@ public class TestUtils {
     return false;
   }
 
-  public static void setEnvironmentVariables(Map<String, String> vars) {
-    // Setting the environment variables after the JVM has started requires a bit of a hack:
-    // we reach into the package-private java.lang.ProcessEnvironment class, which incidentally
-    // is platform-specific, and replace the map held in a static final field there,
-    // using yet more reflection.
-    //
-    // This is copied from {#see com.google.apphosting.runtime.NullSandboxPlugin}
-    Map<String, String> allVars = new HashMap<>(System.getenv());
-    allVars.putAll(vars);
-    try {
-      Class<?> pe = Class.forName("java.lang.ProcessEnvironment", true, null);
-      Field f = pe.getDeclaredField("theUnmodifiableEnvironment");
-      f.setAccessible(true);
-      Field m = Field.class.getDeclaredField("modifiers");
-      m.setAccessible(true);
-      m.setInt(f, m.getInt(f) & ~Modifier.FINAL);
-      f.set(null, Collections.unmodifiableMap(allVars));
-    } catch (ReflectiveOperationException e) {
-      throw new RuntimeException("failed to set the environment variables", e);
-    }
-  }
-
-  public static void unsetEnvironmentVariables(Set<String> vars) {
-    // Unsetting the environment variables after the JVM has started requires a bit of a hack:
-    // we reach into the package-private java.lang.ProcessEnvironment class, which incidentally
-    // is platform-specific, and replace the map held in a static final field there,
-    // using yet more reflection.
-    //
-    // This is copied from {#see com.google.apphosting.runtime.NullSandboxPlugin}
-    Map<String, String> allVars = new HashMap<>(System.getenv());
-    for (String var : vars) {
-      allVars.remove(var);
-    }
-    try {
-      Class<?> pe = Class.forName("java.lang.ProcessEnvironment", true, null);
-      Field f = pe.getDeclaredField("theUnmodifiableEnvironment");
-      f.setAccessible(true);
-      Field m = Field.class.getDeclaredField("modifiers");
-      m.setAccessible(true);
-      m.setInt(f, m.getInt(f) & ~Modifier.FINAL);
-      f.set(null, Collections.unmodifiableMap(allVars));
-    } catch (ReflectiveOperationException e) {
-      throw new RuntimeException("failed to unset the environment variables", e);
-    }
-  }
-
   public static String loadResource(String path) {
     InputStream stream = TestUtils.class.getClassLoader().getResourceAsStream(path);
     checkNotNull(stream, "Failed to load resource: %s", path);
@@ -128,35 +69,6 @@ public class TestUtils {
     }
   }
 
-  /**
-   * Ensures initialization of Google Application Default Credentials. Any test that depends on
-   * ADC should consider this as a fixture, and invoke it before hand. Since ADC are initialized
-   * once per JVM, this makes sure that all dependent tests get the same ADC instance, and
-   * can reliably reason about the tokens minted using it.
-   */
-  public static synchronized GoogleCredentials getApplicationDefaultCredentials()
-      throws IOException {
-    if (defaultCredentials != null) {
-      return defaultCredentials;
-    }
-    final MockTokenServerTransport transport = new MockTokenServerTransport(
-        "https://accounts.google.com/o/oauth2/token");
-    transport.addServiceAccount(ServiceAccount.EDITOR.getEmail(), TEST_ADC_ACCESS_TOKEN);
-    File serviceAccount = new File("src/test/resources/service_accounts", "editor.json");
-    Map<String, String> environmentVariables =
-        ImmutableMap.<String, String>builder()
-            .put("GOOGLE_APPLICATION_CREDENTIALS", serviceAccount.getAbsolutePath())
-            .build();
-    setEnvironmentVariables(environmentVariables);
-    defaultCredentials = GoogleCredentials.getApplicationDefault(new HttpTransportFactory() {
-      @Override
-      public HttpTransport create() {
-        return transport;
-      }
-    });
-    return defaultCredentials;
-  }
-
   public static HttpRequest createRequest() throws IOException {
     return createRequest(new MockLowLevelHttpRequest());
   }