From 07045f46f5f1fcf20f73daea1a46cbc74abc7492 Mon Sep 17 00:00:00 2001 From: Abhijeet V <31417623+abvaidya@users.noreply.github.com> Date: Mon, 30 Oct 2023 11:18:21 -0700 Subject: [PATCH] replacing wix-embedded-mysql with testcontainers-java (#2384) Signed-off-by: Abhijeet V <31417623+abvaidya@users.noreply.github.com> --- .gitignore | 1 + pom.xml | 2 + screwdriver.yaml | 5 +- screwdriver/scripts/build.sh | 2 + screwdriver/scripts/install_deps.sh | 24 ++++++- servers/zms/pom.xml | 24 +++++-- .../com/yahoo/athenz/zms/DBServiceTest.java | 6 +- .../com/yahoo/athenz/zms/ZMSBinderTest.java | 6 +- .../yahoo/athenz/zms/ZMSTestInitializer.java | 13 ++-- .../com/yahoo/athenz/zms/ZMSTestUtils.java | 70 +++++++++++++------ servers/zms/src/test/resources/logback.xml | 5 +- servers/zms/src/test/resources/sd_logback.xml | 5 ++ 12 files changed, 119 insertions(+), 44 deletions(-) diff --git a/.gitignore b/.gitignore index 6056d90d92c..4da2f7a2fa3 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ servers/zms/zms_logs/ servers/zms/zms_root/ servers/zms/bin/ servers/zms/schema/zms_server.mwb.bak +servers/zms/src/test/resources/mysql/zms_server.sql servers/zts/zts_logs/ servers/zts/zts_store/ servers/zts/bin/ diff --git a/pom.xml b/pom.xml index f1bd89d28ee..a407e9aa76c 100644 --- a/pom.xml +++ b/pom.xml @@ -91,6 +91,7 @@ 3.1.3 11.0.17 0.11.5 + 5.13.0 1.2.12 1.4.11 3.6.0 @@ -115,6 +116,7 @@ 1.5.4 1.7.36 2.0.9 + 1.19.1 7.8.0 2.2.17 1.2 diff --git a/screwdriver.yaml b/screwdriver.yaml index 8992df97dff..a367ffcd5b0 100644 --- a/screwdriver.yaml +++ b/screwdriver.yaml @@ -2,12 +2,15 @@ --- shared: - image: openjdk:11 + image: eclipse-temurin:11-jdk-focal annotations: screwdriver.cd/cpu: 8 screwdriver.cd/ram: 16 screwdriver.cd/disk: HIGH screwdriver.cd/timeout: 120 + screwdriver.cd/dockerEnabled: true + screwdriver.cd/dockerCpu: TURBO + screwdriver.cd/dockerRam: HIGH environment: USER_SHELL_BIN: /bin/bash diff --git a/screwdriver/scripts/build.sh b/screwdriver/scripts/build.sh index 54f5c4f79bd..86a934e4afa 100755 --- a/screwdriver/scripts/build.sh +++ b/screwdriver/scripts/build.sh @@ -3,4 +3,6 @@ set -e export PATH=$PATH:/usr/local/go/bin +cp ${SD_SOURCE_DIR}/servers/zms/schema/zms_server.sql ${SD_SOURCE_DIR}/servers/zms/src/test/resources/mysql +ls -ltr ${SD_SOURCE_DIR}/servers/zms/src/test/resources/mysql mvn -B install diff --git a/screwdriver/scripts/install_deps.sh b/screwdriver/scripts/install_deps.sh index fdf6fb6fa4b..cf7b3033351 100755 --- a/screwdriver/scripts/install_deps.sh +++ b/screwdriver/scripts/install_deps.sh @@ -13,8 +13,14 @@ echo "-----------------Install maven: -----------------" apt-get install -y maven echo "-----------------Install nodejs: -----------------" -curl -sL https://deb.nodesource.com/setup_18.x | bash - -apt-get install -y nodejs +apt-get update +apt-get install -y ca-certificates curl gnupg apt-transport-https +mkdir -p /etc/apt/keyrings +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +NODE_MAJOR=18 +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list +apt-get update +apt-get install nodejs -y aptitude install -y npm npm install -g npm@latest @@ -29,6 +35,18 @@ wget https://golang.org/dl/go1.19.linux-amd64.tar.gz tar -C /usr/local -xzf go1.19.linux-amd64.tar.gz export PATH=$PATH:/usr/local/go/bin +echo "-----------------Install Docker: -----------------" +# Add Docker's official GPG key: +apt-get update +curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - +apt-key fingerprint 0EBFCD88 + +add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable" +apt-get update +apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin +docker system info +ls -la $SD_DIND_SHARE_PATH + # check all installed dependencies echo "-----------------Java Version: -----------------" java -version @@ -40,3 +58,5 @@ echo "-----------------NPM Version: -----------------" npm -v echo "-----------------Golang Version: -----------------" go version +echo "-----------------Docker Version: -----------------" +docker version diff --git a/servers/zms/pom.xml b/servers/zms/pom.xml index 9aec97c642e..279208719d4 100644 --- a/servers/zms/pom.xml +++ b/servers/zms/pom.xml @@ -11,7 +11,7 @@ See the License for the specific language governing permissions and limitations under the License. --> - + 4.0.0 @@ -176,12 +176,6 @@ swagger-jaxrs2-servlet-initializer-jakarta ${swagger.version} - - com.wix - wix-embedded-mysql - 4.6.2 - test - com.nimbusds nimbus-jose-jwt @@ -196,6 +190,22 @@ software.amazon.awssdk dynamodb-enhanced + + org.testcontainers + mysql + ${testcontainers.version} + test + + + + net.java.dev.jna + jna + ${jna.version} + test + diff --git a/servers/zms/src/test/java/com/yahoo/athenz/zms/DBServiceTest.java b/servers/zms/src/test/java/com/yahoo/athenz/zms/DBServiceTest.java index e078fc94cd8..35e0f30c1d5 100644 --- a/servers/zms/src/test/java/com/yahoo/athenz/zms/DBServiceTest.java +++ b/servers/zms/src/test/java/com/yahoo/athenz/zms/DBServiceTest.java @@ -19,7 +19,6 @@ import ch.qos.logback.classic.spi.LoggingEvent; import ch.qos.logback.core.AppenderBase; import com.google.common.io.Resources; -import com.wix.mysql.EmbeddedMysql; import com.yahoo.athenz.auth.Authority; import com.yahoo.athenz.auth.Principal; import com.yahoo.athenz.auth.impl.FilePrivateKeyStore; @@ -46,6 +45,7 @@ import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.slf4j.LoggerFactory; +import org.testcontainers.containers.MySQLContainer; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -76,7 +76,7 @@ public class DBServiceTest { private String pubKeyK1 = null; private String pubKeyK2 = null; private final String auditRef = "audittest"; - private EmbeddedMysql mysqld; + private MySQLContainer mysqld; // typically used when creating and deleting domains with all the tests // @@ -111,7 +111,7 @@ public void setup() throws Exception { System.setProperty(ZMSConsts.ZMS_PROP_DOMAIN_ADMIN, "user.testadminuser"); System.setProperty(ZMSConsts.ZMS_PROP_OBJECT_STORE_FACTORY_CLASS, "com.yahoo.athenz.zms.store.impl.JDBCObjectStoreFactory"); - System.setProperty(ZMSConsts.ZMS_PROP_JDBC_RW_STORE, "jdbc:mysql://localhost:3310/zms_server"); + System.setProperty(ZMSConsts.ZMS_PROP_JDBC_RW_STORE, mysqld.getJdbcUrl()); System.setProperty(ZMSConsts.ZMS_PROP_JDBC_RW_USER, DB_USER); System.setProperty(ZMSConsts.ZMS_PROP_JDBC_RW_PASSWORD, DB_PASS); diff --git a/servers/zms/src/test/java/com/yahoo/athenz/zms/ZMSBinderTest.java b/servers/zms/src/test/java/com/yahoo/athenz/zms/ZMSBinderTest.java index ca79b2015e9..b6d4369ee81 100644 --- a/servers/zms/src/test/java/com/yahoo/athenz/zms/ZMSBinderTest.java +++ b/servers/zms/src/test/java/com/yahoo/athenz/zms/ZMSBinderTest.java @@ -1,7 +1,7 @@ package com.yahoo.athenz.zms; -import com.wix.mysql.EmbeddedMysql; import com.yahoo.athenz.auth.impl.FilePrivateKeyStore; +import org.testcontainers.containers.MySQLContainer; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -11,14 +11,14 @@ public class ZMSBinderTest { private static final String DB_USER = "admin"; private static final String DB_PASS = "unit-test"; - private EmbeddedMysql mysqld; + private MySQLContainer mysqld; @BeforeClass public void setUp() { mysqld = ZMSTestUtils.startMemoryMySQL(DB_USER, DB_PASS); System.setProperty(ZMSConsts.ZMS_PROP_OBJECT_STORE_FACTORY_CLASS, "com.yahoo.athenz.zms.store.impl.JDBCObjectStoreFactory"); - System.setProperty(ZMSConsts.ZMS_PROP_JDBC_RW_STORE, "jdbc:mysql://localhost:3310/zms_server"); + System.setProperty(ZMSConsts.ZMS_PROP_JDBC_RW_STORE, mysqld.getJdbcUrl()); System.setProperty(ZMSConsts.ZMS_PROP_JDBC_RW_USER, DB_USER); System.setProperty(ZMSConsts.ZMS_PROP_JDBC_RW_PASSWORD, DB_PASS); System.setProperty(ZMSConsts.ZMS_PROP_PRINCIPAL_STATE_UPDATER_DISABLE_TIMER, "true"); diff --git a/servers/zms/src/test/java/com/yahoo/athenz/zms/ZMSTestInitializer.java b/servers/zms/src/test/java/com/yahoo/athenz/zms/ZMSTestInitializer.java index 4371ee76a69..1559f98f6c7 100644 --- a/servers/zms/src/test/java/com/yahoo/athenz/zms/ZMSTestInitializer.java +++ b/servers/zms/src/test/java/com/yahoo/athenz/zms/ZMSTestInitializer.java @@ -19,7 +19,6 @@ package com.yahoo.athenz.zms; import com.google.common.io.Resources; -import com.wix.mysql.EmbeddedMysql; import com.yahoo.athenz.auth.Authority; import com.yahoo.athenz.auth.Principal; import com.yahoo.athenz.auth.impl.FilePrivateKeyStore; @@ -37,6 +36,8 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import org.testcontainers.containers.MySQLContainer; + import java.io.File; import java.io.IOException; import java.lang.reflect.Field; @@ -91,7 +92,7 @@ public class ZMSTestInitializer { public static synchronized int getRandomProductId() { return BASE_PRODUCT_ID + domainProductId.nextInt(99999999); } - private EmbeddedMysql mysqld; + private MySQLContainer mysqld; public void startMemoryMySQL() { mysqld = ZMSTestUtils.startMemoryMySQL(DB_USER, DB_PASS); @@ -103,14 +104,18 @@ public void stopMemoryMySQL() { public void setDatabaseReadOnlyMode(boolean readOnlyMode) { zms.dbService.defaultRetryCount = 3; - ZMSTestUtils.setDatabaseReadOnlyMode(mysqld, readOnlyMode); + try { + ZMSTestUtils.setDatabaseReadOnlyMode(mysqld, readOnlyMode, DB_USER, DB_PASS); + } catch (IOException | InterruptedException e) { + fail(); + } } public void setUp() throws Exception { MockitoAnnotations.openMocks(this); System.setProperty(ZMSConsts.ZMS_PROP_OBJECT_STORE_FACTORY_CLASS, "com.yahoo.athenz.zms.store.impl.JDBCObjectStoreFactory"); - System.setProperty(ZMSConsts.ZMS_PROP_JDBC_RW_STORE, "jdbc:mysql://localhost:3310/zms_server"); + System.setProperty(ZMSConsts.ZMS_PROP_JDBC_RW_STORE, mysqld.getJdbcUrl()); System.setProperty(ZMSConsts.ZMS_PROP_JDBC_RW_USER, DB_USER); System.setProperty(ZMSConsts.ZMS_PROP_JDBC_RW_PASSWORD, DB_PASS); diff --git a/servers/zms/src/test/java/com/yahoo/athenz/zms/ZMSTestUtils.java b/servers/zms/src/test/java/com/yahoo/athenz/zms/ZMSTestUtils.java index ab61e311f03..36f4eb710bc 100644 --- a/servers/zms/src/test/java/com/yahoo/athenz/zms/ZMSTestUtils.java +++ b/servers/zms/src/test/java/com/yahoo/athenz/zms/ZMSTestUtils.java @@ -15,48 +15,72 @@ */ package com.yahoo.athenz.zms; -import com.wix.mysql.EmbeddedMysql; -import com.wix.mysql.Sources; -import com.wix.mysql.config.MysqldConfig; import com.yahoo.rdl.Timestamp; import com.yahoo.rdl.UUID; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testcontainers.containers.MySQLContainer; +import org.testcontainers.containers.output.Slf4jLogConsumer; +import org.testcontainers.shaded.org.apache.commons.io.FileUtils; +import org.testcontainers.utility.DockerImageName; +import org.testcontainers.utility.MountableFile; import java.io.File; +import java.io.IOException; +import java.nio.file.Paths; +import java.time.Duration; import java.util.Date; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.function.Function; -import static com.wix.mysql.EmbeddedMysql.anEmbeddedMysql; -import static com.wix.mysql.ScriptResolver.classPathScript; -import static com.wix.mysql.config.MysqldConfig.aMysqldConfig; -import static com.wix.mysql.distribution.Version.v5_7_latest; - public class ZMSTestUtils { - public static EmbeddedMysql startMemoryMySQL(final String userName, final String password) { + private static final Logger LOG = LoggerFactory.getLogger(ZMSTestUtils.class); + + public static MySQLContainer startMemoryMySQL(final String userName, final String password) { - System.out.println("Starting Embedded MySQL server..."); + System.out.println("Starting MySQL server using testcontainers..."); + MySQLContainer mysql = null; + try { - final MysqldConfig config = aMysqldConfig(v5_7_latest) - .withPort(3310) - .withUser(userName, password) - .build(); + String externalInitScriptPath = "schema/zms_server.sql"; + File destinationInitScript = new File("src/test/resources/mysql/zms_server.sql"); + FileUtils.copyFile(new File(externalInitScriptPath), destinationInitScript); + LOG.info("Copied {} to {}", externalInitScriptPath, destinationInitScript.getAbsolutePath()); + + mysql = new MySQLContainer<>(DockerImageName.parse("mysql/mysql-server:5.7").asCompatibleSubstituteFor("mysql")) + .withDatabaseName("zms_server") + .withUsername(userName) + .withPassword(password) + .withEnv("MYSQL_ROOT_PASSWORD", password) + .withInitScript("mysql/zms_server.sql") + .withStartupTimeout(Duration.ofMinutes(1)) + .withCopyFileToContainer( + MountableFile.forClasspathResource("mysql/"), + "/athenz-mysql-scripts/"); + mysql.start(); + mysql.followOutput(new Slf4jLogConsumer(LOG)); + } catch (Throwable t) { + LOG.error("Unable to start MySQL server using testcontainers", t); + } - File sqlSchemaFile = new File("schema/zms_server.sql"); - return anEmbeddedMysql(config) - .addSchema("zms_server", Sources.fromFile(sqlSchemaFile)) - .start(); + return mysql; } - public static void stopMemoryMySQL(EmbeddedMysql mysqld) { - System.out.println("Stopping Embedded MySQL server..."); + public static void stopMemoryMySQL(MySQLContainer mysqld) { + System.out.println("Stopping testcontainers MySQL server..."); mysqld.stop(); } - public static void setDatabaseReadOnlyMode(EmbeddedMysql mysqld, boolean readOnly) { - final String scriptName = readOnly ? "mysql/set-read-only.sql" : "mysql/unset-read-only.sql"; - mysqld.executeScripts("zms_server", classPathScript(scriptName)); + public static void setDatabaseReadOnlyMode(MySQLContainer mysqld, boolean readOnly, final String username, final String password) throws IOException, InterruptedException { + final String scriptName = readOnly ? "set-read-only.sql" : "unset-read-only.sql"; + try { + mysqld.execInContainer("mysql", "-u", "root", "-p"+password, "zms_server", "-e", "source /athenz-mysql-scripts/" + scriptName); + } catch (Throwable t) { + LOG.error("Unable to execute script in testcontainers mysql container: " + scriptName, t); + } + } public static boolean verifyDomainRoleMember(DomainRoleMember domainRoleMember, MemberRole memberRole) { diff --git a/servers/zms/src/test/resources/logback.xml b/servers/zms/src/test/resources/logback.xml index 9297d1db86d..2203cc12c2f 100644 --- a/servers/zms/src/test/resources/logback.xml +++ b/servers/zms/src/test/resources/logback.xml @@ -49,7 +49,10 @@ - + + + + diff --git a/servers/zms/src/test/resources/sd_logback.xml b/servers/zms/src/test/resources/sd_logback.xml index 47117097a5d..6cc28cfc760 100644 --- a/servers/zms/src/test/resources/sd_logback.xml +++ b/servers/zms/src/test/resources/sd_logback.xml @@ -7,6 +7,11 @@ %-4relative [%thread] %-5level %class - %msg%n + + + + +