Skip to content

test(eventhubs): cover SAS auth and connection options - #5092

Draft
Johnathan W (j7nw4r) wants to merge 1 commit into
Azure:mainfrom
j7nw4r:j7nw4r/eventhubs-sas-auth-live-tests
Draft

test(eventhubs): cover SAS auth and connection options#5092
Johnathan W (j7nw4r) wants to merge 1 commit into
Azure:mainfrom
j7nw4r:j7nw4r/eventhubs-sas-auth-live-tests

Conversation

@j7nw4r

@j7nw4r Johnathan W (j7nw4r) commented Aug 20, 2026

Copy link
Copy Markdown
Member

Summary

The Event Hubs live tests authenticate with a token credential and with a connection string that carries a shared access key. This change adds a test file for Shared Access Signature (SAS) authentication and the connection options that go with it: a pre-formed SAS token, the SendOnly and ListenOnly authorization rules in both directions, and with_custom_endpoint. Nine tests are added, of which eight are live and one runs offline.

Motivation

Each authentication mode takes a different code path to build the AMQP claim, so a defect in one mode is invisible to the tests for another mode. No test presents a pre-formed SAS token today, although src/common/sas_credential.rs implements one. The SendOnly and ListenOnly rules that test-resources.bicep already creates are unused, so nothing proves that the SDK surfaces a clear error when a credential lacks a permission. The with_custom_endpoint option has only a unit test that asserts the field is stored, and nothing proves the value reaches the dial.

Changes

  • Add sdk/eventhubs/azure_messaging_eventhubs/tests/eventhubs_sas_auth.rs with nine tests.
  • minted_sas_token_matches_the_crate_reference_vector is a plain #[test]. It pins the file's own SAS signer against the reference vector that the crate's signer is tested with, and makes sure the built connection string carries no key fields.
  • preformed_sas_producer_sends and preformed_sas_consumer_receives open a producer and a consumer with a pre-formed token. The token reaches the client inside a connection string, because that is the only public route; SasCredential is crate-private and no public API accepts a token directly.
  • The test mints its own token rather than calling the crate signer, so the tests prove that the client accepts a token that a separate service minted. The token signs the audience amqps://{namespace}/{eventhub}, which is the path the client claims. A token signed with the sb:// form that the Microsoft samples show would fail the prefix match and give a spurious authorization error.
  • send_only_rule_can_send, send_only_rule_cannot_receive, listen_only_rule_can_receive, and listen_only_rule_cannot_send cover both scoped rules in both directions.
  • The two disallowed-direction tests assert on the first send and on the first stream poll, not on open. open ends at ensure_connection, which never authorizes a path, so a credential with the wrong rights still opens successfully. The claim reaches the wire only at the link attach.
  • custom_endpoint_completes_a_service_operation and custom_endpoint_is_used_for_the_dial cover with_custom_endpoint. The second test opens once against the namespace and once against an unreachable endpoint, so a custom endpoint that never reaches the dial makes the test fail.
  • Every event carries a per-run marker, so each test asserts on its own events and tolerates the foreign traffic that shares a partition. The tests serialize on a file-level async mutex.
  • No source change, no Cargo.toml edit, and no CHANGELOG entry. The file uses only crates the package already depends on.

Test plan

  • cargo test -p azure_messaging_eventhubs --all-features --test eventhubs_sas_auth -- --test-threads=1 reports 1 passed; 0 failed; 8 ignored. Each ignored line reads "ignored, skipping live tests".
  • The offline test carries a mutation proof. Removing the .to_lowercase() from the resource step makes it fail with uppercase percent-encoding against the expected literal. Adding a SharedAccessKey field to the built connection string makes its second assertion fail.
  • RUSTFLAGS=-Dwarnings cargo test --no-run --package azure_messaging_eventhubs passes, which is the gate that CI applies through eng/pipelines/templates/variables/rust.yml.
  • cargo test -p azure_messaging_eventhubs --all-features -- --test-threads=1, cargo fmt --package azure_messaging_eventhubs -- --check, cargo clippy -p azure_messaging_eventhubs --all-features --all-targets with -Dwarnings, cargo doc -p azure_messaging_eventhubs --all-features --no-deps with -Dwarnings, and cspell with the repository config all pass.
  • The eight live tests are NOT yet proven live. They were not run, because one shared namespace served several concurrent branches and a parallel live run reads the events of another run. To prove them, run AZURE_TEST_MODE=live cargo test -p azure_messaging_eventhubs --all-features --test eventhubs_sas_auth -- --test-threads=1.
  • That live run needs five environment variables: EVENTHUBS_HOST, EVENTHUB_NAME, EVENTHUBS_CONNECTION_STRING, EVENTHUBS_SEND_ONLY_CONNECTION_STRING, and EVENTHUBS_LISTEN_ONLY_CONNECTION_STRING. Read every secret from the environment at run time.
  • The last two variables are new. They carry the primary connection strings of the namespace-scope SendOnly and ListenOnly rules. The template creates the rules but publishes no key, and its only connection-string output stays commented out, so an operator sets the two variables by hand.
  • Precondition for the live run: the namespace must have local authentication enabled. test-resources.bicep sets disableLocalAuth: !tenantIsTME, so on a non-TME tenant every SAS test here fails at open for that reason and not for a defect.
  • Known limits. custom_endpoint_completes_a_service_operation cannot tell an honored custom endpoint from an ignored one when the endpoint is the namespace itself, and custom_endpoint_is_used_for_the_dial is the test that closes that gap. The helper that builds the pre-formed connection string has no offline coverage, because it reads environment variables.
  • The disallowed-direction tests match the rendered error on "unauthorized" or "401" rather than on an error variant. The public ErrorKind has no Unauthorized variant, and the broker can refuse at either the CBS put-token or the link attach, which surface as different types. The first live run prints the full error, so a follow-up can tighten the assertion.

Part of #4886.

Closes #4892.

Live validation

Every test here ran against a live Event Hubs namespace on 2026-08-20: 9 passed, 0 failed.

Command: AZURE_TEST_MODE=live cargo test --package azure_messaging_eventhubs --test eventhubs_sas_auth -- --test-threads=1.

No change was needed. The independently minted SAS token authenticated, both scoped rules failed in the disallowed direction and succeeded in the allowed one, and both custom endpoint tests passed.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
3 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Add one test file for Shared Access Signature authentication and for the
connection options that go with it.

- Mint a SAS token with an independent signer and pin it against the
  vector the crate's own signer is tested with. This test is offline and
  runs in every mode.
- Send and receive with a pre-formed SharedAccessSignature connection
  string that carries no key and no key name.
- Prove that a namespace rule with only Send rights can send and cannot
  receive, and that a rule with only Listen rights can receive and
  cannot send.
- Complete a service operation through an explicit custom endpoint, and
  show that an unreachable custom endpoint fails the open while the same
  connection string opens without it.

The eight live tests read EVENTHUBS_SEND_ONLY_CONNECTION_STRING and
EVENTHUBS_LISTEN_ONLY_CONNECTION_STRING, which come from the SendOnly
and ListenOnly rules in sdk/eventhubs/test-resources.bicep. They pass
only against a namespace that has local authentication enabled.

Refs Azure#4892
@j7nw4r
Johnathan W (j7nw4r) force-pushed the j7nw4r/eventhubs-sas-auth-live-tests branch from b12bc72 to f2cfe31 Compare August 25, 2026 18:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Event Hubs] Add live tests for SAS authentication and connection options

1 participant