Closed CCThorstenSauter closed 1 week ago
We see the same problem at the moment.
This is also affecting us when it's running inside our GitHub Actions for CI/CD. It's currently preventing us from doing any releases.
I confirm that our tests using TestContainers and MsSQL stopped passing today 🤕
When looking at the image it seems that path for sqlcmd
has changed from /opt/mssql-tools/bin/sqlcmd
to /opt/mssql-tools18/bin/sqlcmd
. Not sure if this was intentional or not.
FYI someone has reported it on MSSQL-Docker: https://github.com/microsoft/mssql-docker/issues/892
As mentioned in Slack, we likely need to adapt the default wait strategy (see https://github.com/testcontainers/testcontainers-dotnet/blob/develop/src/Testcontainers.MsSql/MsSqlBuilder.cs#L132-L145).
Users can provide their own wait strategy configuration as a workaround.
This started blocking our Azure DevOps pipeline yesterday.
after @pascalberger comment en combined with @kiview i first ran into certificate issues:
Sqlcmd: Error: Microsoft ODBC Driver 18 for SQL Server : SSL Provider: [error:0A000086:SSL routines::certificate verify failed:self-signed certificate]. Sqlcmd: Error: Microsoft ODBC Driver 18 for SQL Server : Client unable to establish connection. For solutions related to encryption errors, see https://go.microsoft.com/fwlink/?linkid=2226722.
but got it working for now by also adding the -C option:
.WithWaitStrategy( Wait.ForUnixContainer() .UntilCommandIsCompleted("/opt/mssql-tools18/bin/sqlcmd", "-C", "-Q", "SELECT 1;") )
This works when run locally, but still times out when run in an Azure DevOps pipeline:
new MsSqlBuilder()
.WithImage("mcr.microsoft.com/mssql/server:2022-latest")
.WithEnvironment("ACCEPT_EULA", "Y")
.WithPortBinding(11143, 1433)
.WithWaitStrategy(
Wait.ForUnixContainer()
.UntilCommandIsCompleted(
"/opt/mssql-tools/bin/sqlcmd",
"-C",
"-Q",
"SELECT 1;"
)
)
.Build();
This times out in both:
new MsSqlBuilder()
.WithImage("mcr.microsoft.com/mssql/server:2022-latest")
.WithEnvironment("ACCEPT_EULA", "Y")
.WithPortBinding(11143, 1433)
.WithWaitStrategy(
Wait.ForUnixContainer()
.UntilCommandIsCompleted(
"/opt/mssql-tools18/bin/sqlcmd",
"-C",
"-Q",
"SELECT 1;"
)
)
.Build();
I have been able to replicate this locally by deleting the cached 2022-latest container image. After it downloads the latest image, it hangs indefinitely.
Adding .WithWaitStrategy( Wait.ForUnixContainer() .UntilCommandIsCompleted("/opt/mssql-tools18/bin/sqlcmd", "-C", "-Q", "SELECT 1;") )
resolved the issue. Thanks @Fireblade954!
@tscrip that did it. We missed a test project so had a false negative. Thanks!
This is also affecting .NET Aspire - https://github.com/dotnet/aspire/issues/5057
After reading all these comments, I would like to point out that we recommend pinning the image version. Using the latest
tag does not automatically update the cached image on your development machine; it will use the version it pulled weeks ago. Meanwhile, the ephemeral CI pipeline pulls the actual latest version because it is not cached (this may lead to different behaviors on developer machines and in the CI pipeline).
Since it looks like the new path will remain (https://github.com/microsoft/mssql-docker/issues/892#issuecomment-2249029917), we can update the default wait strategy for the new version. Overriding the wait strategy, as @Fireblade954 suggested, or pinning the version are workarounds to avoid this issue.
We can probably do something similar to what we are doing in the MongoDB module to determine which binary (path) is available.
BTW this will also break the ExecScriptAsync
method as it also uses sqlcmd. (additionally they are now defaulting to encryption required, which means you need to pass -C
with the sqlcmd to tell it to trust the server cert).
This works for us:
.WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(1433))
This works for us:
.WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(1433))
This won't always work as the container might be ready but MSSQL might not be ready to receive requests.
This works for us: .WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(1433))
This won't always work as the container might be ready but MSSQL might not be ready to receive requests.
Thats true, although it fails very rarely, atleast for us, and it will usually work, regardless of old or new image from microsoft.
I have now rewritten to use
.WithWaitStrategy( Wait.ForUnixContainer() .UntilCommandIsCompleted("/opt/mssql-tools18/bin/sqlcmd", "-C", "-Q", "SELECT 1;") )
and downloaded the new image locally.
Testcontainers version
3.9.0
Using the latest Testcontainers version?
Yes
Host OS
Linux
Host arch
x64
.NET version
8.0.303
Docker version
Docker info
What happened?
When using the
MsSql
package with the newest container image mcr.microsoft.com/mssql/server:2022-latest with a digest ofsha256:c1aa8afe9b06eab64c9774a4802dcd032205d1be785b1fd51e1c0151e7586b74
, the health check specified in the waiting strategy never completes, even though the logs of the SQL server container show it being ready, leading to a timeout.This behavior is not present when using a slightly older container image version, e.g. mcr.microsoft.com/mssql/server:2022-CU13-ubuntu-22.04 with a digest of
sha256:c4369c38385eba011c10906dc8892425831275bb035d5ce69656da8e29de50d8
.Relevant log output
Additional information
No response