Skip to content
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

feat(azure)!: add Azurite, EventHubs and ServiceBus in the new Azure module, deprecating the old Azurite module #3008

Open
wants to merge 47 commits into
base: main
Choose a base branch
from

Conversation

mdelapenya
Copy link
Member

@mdelapenya mdelapenya commented Mar 5, 2025

What does this PR do?

This PR is doing a few things:

  1. adding a new modules package for azure, in which the new Azure containers will live, each on its own subpackage. In example modules/azure/eventhubs.
  2. deprecating the old modules/azurite module, in favor of modules/azure/azurite. The feature has been migrated to the new module, and the deprecated code is linking to the new module, including the imports. There is a breaking change (BC) because we are intentionally removing the access to the azurite container settings, as is an implementation detail.
  3. Updates the wait strategy for the MSSQL Server, to use the listening port.

Regarding the new module containers, we are adding:

Azurite

As mentioned, deprecates the former Azurite module, using the same features. It also adds more robust wait strategies for the different service types (Bloc, Queue and Table).

EventHubs

The EventHubs emulator needs an Azurite container, so the module starts it under the hood. For that:

  • a network is created for the stack
  • an Azurite container is created in the network, with an alias
  • an EventHubs container is created in the network, with an alias

As a result, container communication happens using the aliases and the well-known ports. For the end-users, it's transparent, and they just have to talk to the EventHubs container using the provided API. The testable examples include how to connect to the container.

ServiceBus

The ServiceBus emulator needs a MSSQL Server container, so the module starts it under the hood. For that:

  • a network is created for the stack
  • an MSSQL Server container is created in the network, with an alias
  • an ServiceBus container is created in the network, with an alias

As a result, container communication happens using the aliases and the well-known ports. For the end-users, it's transparent, and they just have to talk to the ServiceBus container using the provided API. The testable examples include how to connect to the container.

Why is it important?

More cloud modules! this time to verify interactions with Azure Cloud.

Follow-ups

I'm not porting the CosmosDB emulator module, as it's broken in the upstream. I tried to run the tc-java implementation and it fails:

java.lang.IllegalStateException: [javax.net](http://javax.net/).ssl.SSLHandshakeException: Remote host terminated the handshake
	at org.testcontainers.containers.KeyStoreBuilder.buildByDownloadingCertificate(KeyStoreBuilder.java:33)
	at org.testcontainers.containers.CosmosDBEmulatorContainer.buildNewKeyStore(CosmosDBEmulatorContainer.java:37)
	at org.testcontainers.containers.CosmosDBEmulatorContainerTest.testWithCosmosClient(CosmosDBEmulatorContainerTest.java:50)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.testcontainers.containers.FailureDetectingExternalResource$1.evaluate(FailureDetectingExternalResource.java:29)
	at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:54)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:112)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:40)
	at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:54)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:53)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:92)
	at jdk.proxy1/jdk.proxy1.$Proxy4.processTestClass(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker$2.run(TestWorker.java:181)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:130)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:101)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:61)
	at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:122)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:69)
	at [worker.org](http://worker.org/).gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
	at [worker.org](http://worker.org/).gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
Caused by: [javax.net](http://javax.net/).ssl.SSLHandshakeException: Remote host terminated the handshake

Copy link

netlify bot commented Mar 5, 2025

Deploy Preview for testcontainers-go ready!

Name Link
🔨 Latest commit f23f143
🔍 Latest deploy log https://app.netlify.com/sites/testcontainers-go/deploys/67dd3d4e00bf5400088674ac
😎 Deploy Preview https://deploy-preview-3008--testcontainers-go.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@mdelapenya mdelapenya marked this pull request as ready for review March 11, 2025 13:30
@mdelapenya mdelapenya requested a review from a team as a code owner March 11, 2025 13:30
@mdelapenya mdelapenya self-assigned this Mar 11, 2025
@mdelapenya mdelapenya added the feature New functionality or new behaviors on the existing one label Mar 11, 2025
@mdelapenya mdelapenya changed the title feat: azure modules feat: add Azurite, EventHubs and ServiceBus in the new Azure module, deprecating the old Azurite module Mar 11, 2025
* main:
  chore(deps)!: bump github.com/docker/docker from 27.1.1+incompatible to 28.0.1+incompatible (testcontainers#3017)
  chore!: export DockerCompose type in compose package (testcontainers#2953)
  chore(deps): bump golang.org/x/net from 0.33.0 to 0.36.0 in /modules (testcontainers#3033)
  chore(sonar): set main as default branch (testcontainers#3038)
  fix(sonar): run on ubuntu and the lowest Go version (testcontainers#3037)
  fix(ci): update core path in sonar build (testcontainers#3036)
  fix: use empty dir for the core (testcontainers#3035)
  fix: pass secret to the reusable workflow (testcontainers#3034)
  chore(ci): use new GH action for SonarQube (testcontainers#3007)
@mdelapenya
Copy link
Member Author

@eddumelendez I'd like to move forward and eventually add cosmosdb module: it "kind of works" on my side, but the TLS connection from my example get lost in the azure go SDK (it swaps the container host-port to the internal hostIP + well-known port of the emulator). I'll add a branch with this code to debug it together is possible.

eddumelendez
eddumelendez previously approved these changes Mar 20, 2025
Copy link
Member

@eddumelendez eddumelendez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@mdelapenya
Copy link
Member Author

@eddumelendez I noticed the code for the latest tag (4 months ago) of the cosmosdb emulator should be different to the one for the vnext-preview one (8 weeks ago): log is different, more env vars supported... I'll send a draft PR with the cosmosdb emultator so we can discuss in there

@mdelapenya mdelapenya changed the title feat(azure): add Azurite, EventHubs and ServiceBus in the new Azure module, deprecating the old Azurite module feat(azure)!: add Azurite, EventHubs and ServiceBus in the new Azure module, deprecating the old Azurite module Mar 21, 2025
@mdelapenya mdelapenya added the breaking change Causing compatibility issues. label Mar 21, 2025
@mdelapenya
Copy link
Member Author

@stevenh I'm merging this one, want to add anything else before that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change Causing compatibility issues. feature New functionality or new behaviors on the existing one
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants