google-cloud-go icon indicating copy to clipboard operation
google-cloud-go copied to clipboard

firestore: Provide function to configure emulator

Open joshlf opened this issue 4 years ago • 6 comments

Is your feature request related to a problem? Please describe. I'm writing unit tests to exercise code which connects to Firestore. What would be really nice is to have an in-process mock for testing. However, barring that, it's sufficient to run the Firestore emulator as a subprocess, and connect to it from unit tests.

However, the only officially supported way to connect to an emulator is to set the FIRESTORE_EMULATOR_HOST environment variable. Even if I were to do something like os.Setenv("FIRESTORE_EMULATOR_HOST", ...), that would mean that I couldn't run tests in parallel with different emulators, as the environment variable is global.

What I've resorted to instead is to adapt the logic that is used internally here:

https://github.com/googleapis/google-cloud-go/blob/096c584342beb49d9653a670d7813b9dbaca72b8/firestore/client.go#L64-L71

and here:

https://github.com/googleapis/google-cloud-go/blob/096c584342beb49d9653a670d7813b9dbaca72b8/firestore/client.go#L335-L346

Describe the solution you'd like I would like there to be a first-class API for creating a *firestore.Client which accepts an emulator address as an argument rather than by consulting FIRESTORE_EMULATOR_HOST.

joshlf avatar May 09 '20 23:05 joshlf

Thanks for filing the issue and for your clear description!

I know the FIRESTORE_EMULATOR_HOST approach is used across the language clients for firestore. @BenWhitehead is an owner for the firestore clients so I'm asking him to chime in on whether adding an API for this as well would be feasible.

tritone avatar May 15 '20 05:05 tritone

Emulator boostrapping and lifecycle management is something that has recently come up for several languages and as such is going to be larger than any one client to be improved. I'll include this request in the discussion around the improvements.

Related issues:

  • https://github.com/googleapis/java-firestore/issues/190
  • https://github.com/googleapis/java-firestore/issues/210
  • https://github.com/firebase/firebase-admin-node/issues/776

BenWhitehead avatar May 15 '20 20:05 BenWhitehead

Even if I were to do something like os.Setenv("FIRESTORE_EMULATOR_HOST", ...), that would mean that I couldn't run tests in parallel with different emulators, as the environment variable is global.

For what it's worth, the emulator is a reasonably heavyweight and slow-starting Java process, I wouldn't want to run multiple, nor would I want to start a new one per test.

Since the Firestore emulator accepts any project id and doesn't require authentication, I have a helper that picks a random project id (prefixed with the test name, for debugging), and clears the data for each project id before the test. It works great with parallel tests, subtests, etc.

tv42 avatar Oct 08 '20 15:10 tv42

This is a reasonable point, have you considered using unique project ids per test (or per parallel group)?

crwilcox avatar Aug 11 '21 20:08 crwilcox

I'm no longer working on this project, but I don't see why that approach wouldn't work (maybe with the modification that, instead of random project IDs, you use an atomic counter to guarantee uniqueness).

joshlf avatar Aug 13 '21 17:08 joshlf

@joshlf In my case, the tests run in multiple subprocesses, and I didn't want to impose coordination. The project id used concatenates a prefix, name of current test, and a 64-bit random number. It's realistically never going to collide.

tv42 avatar Aug 13 '21 20:08 tv42

If you look at the Firestore tests, you'll see that we use a mockServer that creates a gRPC interceptor for emulating service responses. If the emulator is too-heavyweight for you, you might consider a similar approach.

telpirion avatar Nov 02 '22 17:11 telpirion

Hi, I want to write a test using testcontainers-go and as you can see here java client already allows to set the host and port, which is a random port provided by testcontainers. Can we reconsider it and make it available in go client, please?

eddumelendez avatar Nov 23 '22 21:11 eddumelendez