Skip to content

Mikelehen/prime backend merged with revert proxy #52

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions buildSrc/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@ plugins {
}

repositories {
if (System.getenv().containsKey("FIREBASE_CI")) {
maven {
url "http://maven-proxy/"
}
}
maven {
url 'https://maven.google.com/'
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import java.util.Map;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

Expand All @@ -38,9 +37,6 @@
*/
@RunWith(AndroidJUnit4.class)
public class ArrayTransformsTest {
// TODO(b/114769487): These tests have been flaky in CI so temporarily retrying.
@Rule public RetryRule retryRule = new RetryRule(3);

// A document reference to read and write to.
private DocumentReference docRef;

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -62,20 +62,18 @@ public class IntegrationTestUtil {
/** Online status of all active Firestore clients. */
private static final Map<FirebaseFirestore, Boolean> firestoreStatus = new HashMap<>();

private static final long SEMAPHORE_WAIT_TIMEOUT_MS = 30000;
private static final long SHUTDOWN_WAIT_TIMEOUT_MS = 10000;
private static final long BATCH_WAIT_TIMEOUT_MS = 120000;

private static final FirestoreProvider provider = new FirestoreProvider();
/** Default amount of time to wait for a given operation to complete, used by waitFor() helper. */
private static final long OPERATION_WAIT_TIMEOUT_MS = 30000;

/**
* TODO: There's some flakiness with hexa / emulator / whatever that causes the first write in a
* run to frequently time out. So for now we always send an initial write with an extra long
* timeout to improve test reliability.
* Firestore databases can be subject to a ~30s "cold start" delay if they have not been used
* recently, so before any tests run we "prime" the backend.
*/
private static final long FIRST_WRITE_TIMEOUT_MS = 60000;
private static final long PRIMING_TIMEOUT_MS = 45000;

private static final FirestoreProvider provider = new FirestoreProvider();

private static boolean sentFirstWrite = false;
private static boolean backendPrimed = false;

public static FirestoreProvider provider() {
return provider;
Expand Down Expand Up @@ -113,15 +111,45 @@ public static FirebaseFirestore testFirestore() {
*/
public static FirebaseFirestore testFirestore(FirebaseFirestoreSettings settings) {
FirebaseFirestore firestore = testFirestore(provider.projectId(), Level.DEBUG, settings);
if (!sentFirstWrite) {
sentFirstWrite = true;
waitFor(
firestore.document("test-collection/initial-write-doc").set(map("foo", 1)),
FIRST_WRITE_TIMEOUT_MS);
}
primeBackend();
return firestore;
}

private static void primeBackend() {
if (!backendPrimed) {
backendPrimed = true;
TaskCompletionSource<Void> watchInitialized = new TaskCompletionSource<>();
TaskCompletionSource<Void> watchUpdateReceived = new TaskCompletionSource<>();
DocumentReference docRef = testDocument();
ListenerRegistration listenerRegistration =
docRef.addSnapshotListener(
(snapshot, error) -> {
if ("done".equals(snapshot.get("value"))) {
watchUpdateReceived.setResult(null);
} else {
watchInitialized.setResult(null);
}
});

// Wait for watch to initialize and deliver first event.
waitFor(watchInitialized.getTask());

// Use a transaction to perform a write without triggering any local events.
docRef
.getFirestore()
.runTransaction(
transaction -> {
transaction.set(docRef, map("value", "done"));
return null;
});

// Wait to see the write on the watch stream.
waitFor(watchUpdateReceived.getTask(), PRIMING_TIMEOUT_MS);

listenerRegistration.remove();
}
}

/** Initializes a new Firestore instance that uses a non-existing default project. */
public static FirebaseFirestore testAlternateFirestore() {
return testFirestore(BAD_PROJECT_ID, Level.DEBUG, newTestSettings());
Expand Down Expand Up @@ -181,11 +209,7 @@ public static void tearDown() {
try {
for (FirebaseFirestore firestore : firestoreStatus.keySet()) {
Task<Void> result = AccessHelper.shutdown(firestore);
try {
Tasks.await(result, SHUTDOWN_WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
} catch (TimeoutException | ExecutionException | InterruptedException e) {
throw new RuntimeException(e);
}
waitFor(result);
}
} finally {
firestoreStatus.clear();
Expand Down Expand Up @@ -246,7 +270,7 @@ public static void waitFor(Semaphore semaphore) {
public static void waitFor(Semaphore semaphore, int count) {
try {
boolean acquired =
semaphore.tryAcquire(count, SEMAPHORE_WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
semaphore.tryAcquire(count, OPERATION_WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
if (!acquired) {
throw new TimeoutException("Failed to acquire semaphore within test timeout");
}
Expand All @@ -257,7 +281,7 @@ public static void waitFor(Semaphore semaphore, int count) {

public static void waitFor(CountDownLatch countDownLatch) {
try {
boolean acquired = countDownLatch.await(SEMAPHORE_WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
boolean acquired = countDownLatch.await(OPERATION_WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
if (!acquired) {
throw new TimeoutException("Failed to acquire countdown latch within test timeout");
}
Expand All @@ -266,16 +290,8 @@ public static void waitFor(CountDownLatch countDownLatch) {
}
}

public static void waitFor(List<Task<?>> task) {
try {
Tasks.await(Tasks.whenAll(task), BATCH_WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
} catch (TimeoutException | ExecutionException | InterruptedException e) {
throw new RuntimeException(e);
}
}

public static <T> T waitFor(Task<T> task) {
return waitFor(task, SEMAPHORE_WAIT_TIMEOUT_MS);
return waitFor(task, OPERATION_WAIT_TIMEOUT_MS);
}

public static <T> T waitFor(Task<T> task, long timeoutMS) {
Expand All @@ -288,7 +304,7 @@ public static <T> T waitFor(Task<T> task, long timeoutMS) {

public static <T> Exception waitForException(Task<T> task) {
try {
Tasks.await(task, SEMAPHORE_WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
Tasks.await(task, OPERATION_WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
throw new RuntimeException("Expected Exception but Task completed successfully.");
} catch (ExecutionException e) {
return (Exception) e.getCause();
Expand Down
10 changes: 0 additions & 10 deletions root-project.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,6 @@ import groovy.io.FileType
buildscript {

repositories {
if (System.getenv().containsKey("FIREBASE_CI")) {
maven {
url "http://maven-proxy/"
}
}
google()
jcenter()
mavenCentral()
Expand Down Expand Up @@ -52,11 +47,6 @@ apply plugin: com.google.firebase.gradle.plugins.publish.PublishingPlugin

configure(subprojects) {
repositories {
if (System.getenv().containsKey("FIREBASE_CI")) {
maven {
url "http://maven-proxy/"
}
}
google()
jcenter()
mavenLocal()
Expand Down
12 changes: 1 addition & 11 deletions test-apps/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@

buildscript {
repositories {
if (System.getenv().containsKey("FIREBASE_CI")) {
maven {
url "http://maven-proxy/"
}
}
jcenter()
mavenLocal()
google()
Expand Down Expand Up @@ -49,11 +44,6 @@ allprojects {
}

repositories {
if (System.getenv().containsKey("FIREBASE_CI")) {
maven {
url "http://maven-proxy/"
}
}
//mavenLocal() can be overridden via GRADLE_OPTS="-Dmaven.repo.local=<path>"
mavenLocal()
jcenter()
Expand Down Expand Up @@ -132,4 +122,4 @@ allprojects {

task clean(type: Delete) {
delete rootProject.buildDir
}
}