Skip to content

Allow specifying Spanner emulator host via Config - #165

Open
TangoEnSkai wants to merge 1 commit into
cloudspannerecosystem:masterfrom
TangoEnSkai:feat/emulator-host-config
Open

TangoEnSkai wants to merge 1 commit into
cloudspannerecosystem:masterfrom
TangoEnSkai:feat/emulator-host-config

Conversation

@TangoEnSkai

Copy link
Copy Markdown
Contributor

Context

close #73

When wrench is used as a library, the only way to point it at a Cloud Spanner emulator today is the SPANNER_EMULATOR_HOST environment variable. As the issue notes, calling os.Setenv from test code is process-wide and racy, which is exactly the situation where an emulator is most useful. @kazegusuri welcomed a PR for this in the issue thread; the original reporter never followed up, so here it is.

What

  • Add an EmulatorHost field to spanner.Config.
  • When set, NewClient appends the same three client options that the Cloud Spanner client libraries build from SPANNER_EMULATOR_HOST (see spanner.NewClientWithConfig and the admin client's init.go hook): a passthrough:/// endpoint with the scheme stripped, an insecure gRPC transport, and option.WithoutAuthentication().
  • CredentialsFile is ignored when EmulatorHost is set — the emulator takes no credentials, and combining WithCredentialsFile with WithoutAuthentication would fail dial-settings validation.
  • Tests:
    • TestEmulatorClientOptions (pure unit test) pins the endpoint normalization for http://, https://, and passthrough:/// prefixes.
    • TestNewClientWithEmulatorHostConfig (emulator integration test) clears SPANNER_EMULATOR_HOST via t.Setenv and verifies that both the data client and the admin client reach the emulator through Config.EmulatorHost alone (CreateDatabase → EnsureMigrationTable → DropDatabase).

Why

The field mirrors the client libraries' own emulator wiring rather than inventing a new path, so behaviour stays identical to SPANNER_EMULATOR_HOST — including the scheme-stripping regex. Existing behaviour is unchanged when EmulatorHost is empty. The new options are appended after Config.ClientOptions, consistent with the documented "config fields override ClientOptions" ordering already used by CredentialsFile.

Completion Criteria

  • go build ./..., go vet ./..., gofmt -l . clean
  • TestEmulatorClientOptions passes locally (no emulator needed)
  • Emulator integration tests pass in CI (TestNewClientWithEmulatorHostConfig runs under make test)

Add an EmulatorHost field to spanner.Config so that library users can
connect to a Cloud Spanner emulator without setting the process-wide
SPANNER_EMULATOR_HOST environment variable. When set, the client options
mirror what the Cloud Spanner client libraries build from
SPANNER_EMULATOR_HOST (passthrough endpoint, insecure gRPC transport,
no authentication), and CredentialsFile is ignored since the emulator
takes no credentials.
@TangoEnSkai

Copy link
Copy Markdown
Contributor Author

@kazegusuri you mentioned in #73 that a PR for this would be welcome — the original reporter never followed up, so here it is. The implementation mirrors the client libraries' own SPANNER_EMULATOR_HOST wiring. PTAL when you have a moment.

@TangoEnSkai

Copy link
Copy Markdown
Contributor Author

Following up on the Config option for the Spanner emulator host: the PR is still mergeable, with tests, security scan, and CLA checks passing. @kazegusuri could you review the approach when convenient, or let me know if you would prefer any changes? Thanks!

@sinmetal
sinmetal self-requested a review September 29, 2026 08:17
@sinmetal

Copy link
Copy Markdown
Collaborator

@TangoEnSkai Thank you. I have merged #164 first, so could you please resolve the conflicts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Option to define emulator host from Config

2 participants