testcontainers / testcontainers-java

Testcontainers is a Java library that supports JUnit tests, providing lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container.
https://testcontainers.org
MIT License
8k stars 1.65k forks source link

MSSQLServerContainer does not allow azure-sql-edge #5191

Open Trinition opened 2 years ago

Trinition commented 2 years ago

On an Apple M1, Microsoft's mcr.microsoft.com/mssql/server fails because the sqlcmd is not supported on ARM64; however, Microsoft makes an mcr.microsoft.com/azure-sql-edge Azure SQL Edge container that does work and claims to be fully T-SQL compatible (see here).

I managed to build my own provider that re-uses the MSSQLServerContainer, but with a different image:

/**
 * Uses a {@link MSSQLServerContainer} with a `mcr.microsoft.com/azure-sql-edge` image (default: "latest") in place of
 * the standard ` mcr.microsoft.com/mssql/server` image
 */
class AzureSqlEdgeContainerProvider extends JdbcDatabaseContainerProvider {

  private static final String NAME = 'azuresqledge'

  @Override boolean supports(String databaseType) {
    return databaseType.equals(NAME);
  }

  @Override JdbcDatabaseContainer newInstance() {
    return newInstance('latest');
  }

  @Override JdbcDatabaseContainer newInstance(String tag) {
    def taggedImageName = DockerImageName.parse("mcr.microsoft.com/azure-sql-edge")
      .withTag(tag)
      .asCompatibleSubstituteFor("mcr.microsoft.com/mssql/server") // From MSSQLServerContainer.DEFAULT_IMAGE_NAME
    return new MSSQLServerContainer(taggedImageName);
  }
}

I had to use a different databaseType name (azuresqledge instead of sqlserver) to prevent the two providers from competing. Perhaps there's a better way to avoid that competition without having to change the databaseType name.

Or perhaps there's a way to modify MSSQLServerContainer/...Provider to accept either image name.

Nonetheless, the above provider works fine with my limited, local testing thus far.

kiview commented 2 years ago

Hey @Trinition, thanks a lot for sharing your implementation with the community 🙌

The lack of configurability of the image used by the JdbcDatabaseContainerProvider is discussed in https://github.com/testcontainers/testcontainers-java/issues/4. As I see it, if we solve this issue, it would solve this issue as well.

Trinition commented 2 years ago

MSSQL's JDBC Driver 10.1+ enables encrypt=true by default, but not trustServerCertificate=true. You can either add certificate trusting...

return new MSSQLServerContainer(taggedImageName)
  .withUrlParam('trustServerCertificate', 'true')

Or disable encrypt...

return new MSSQLServerContainer(taggedImageName)
  .withUrlParam('encrypt', 'false')
gmelekh commented 1 year ago

@Trinition could you please elaborate more how to make image mcr.microsoft.com/azure-sql-edge work with MSSQLServerContainer. I am trying to make it work on my apple M1 pro .. without success so far...

Trinition commented 1 year ago

@gmelekh I apologize, but I don't recall what I did. The project I was doing this for got shelved last year, so I'm not currently working on it, and my memory has faded a lot.

Trinition commented 1 year ago

@gmelekh the little bi I was able to scape back together:

aswani-tiwari-thg commented 11 months ago

I am getting this error when try to start the container

com.microsoft.sqlserver.jdbc.SQLServerConnection Prelogin