下面列出了怎么用org.testcontainers.containers.Container的API类实例代码及写法,或者点击链接到github查看源代码。
private synchronized void startServers(Properties parameters) throws IOException, InterruptedException {
if (serverSettings.containsKey(parameters)) {
return;
}
if (!pgServer.isRunning()) {
pgServer.start();
mqttBus.start();
Container.ExecResult execResult = pgServer.execInContainer("psql", "-U" + VAL_PG_USER, "-d" + VAL_PG_DB, "-c CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\";");
LOGGER.info("Installing extension uuid-ossp: {} {}", execResult.getStdout(), execResult.getStderr());
pgConnectUrl = "jdbc:postgresql://" + pgServer.getContainerIpAddress() + ":" + pgServer.getFirstMappedPort() + "/" + VAL_PG_DB;
}
startHttpServer(parameters);
startMqttServer(parameters);
}
/**
* To be called by a test class method annotated with {@link org.junit.BeforeClass}.
* This logic doesn't work when placed inside of the constructor, presumably
* because the Docker container spawned by TestContainers is not ready to accept commands until after those
* methods complete.
*
* <p>This method initializes the Vault server, capturing the unseal key and root token that are displayed on the
* console. It then uses the key to unseal the Vault instance, and stores the token in a member field so it
* will be available to other methods.</p>
*
* @throws IOException
* @throws InterruptedException
*/
public void initAndUnsealVault() throws IOException, InterruptedException {
// Initialize the Vault server
final Container.ExecResult initResult = runCommand("vault", "operator", "init", "-ca-cert=" +
CONTAINER_CERT_PEMFILE, "-key-shares=1", "-key-threshold=1", "-format=json");
final String stdout = initResult.getStdout().replaceAll("\\r?\\n", "");
JsonObject initJson = Json.parse(stdout).asObject();
this.unsealKey = initJson.get("unseal_keys_b64").asArray().get(0).asString();
this.rootToken = initJson.get("root_token").asString();
System.out.println("Root token: " + rootToken);
// Unseal the Vault server
runCommand("vault", "operator", "unseal", "-tls-skip-verify", unsealKey);
runCommand("vault", "login", "-tls-skip-verify", rootToken);
}
public static ExecResultWithExitCode exec(Container container, String shellCommand) {
final Logger log = LoggerFactory.getLogger("[" + container.getContainerName() + "]");
log.info("Executing command: {}", shellCommand);
final String exitCodeMarker = "ExitCode=";
final Container.ExecResult result = execInContainerUnchecked(container,
"sh", "-c", shellCommand + "; echo \"" + exitCodeMarker + "$?\""
);
final String stdout = result.getStdout();
final int i = stdout.lastIndexOf(exitCodeMarker);
if (i < 0) {
throw new RuntimeException("failed to determine exit code: " + result.getStdout() + "/" + result.getStderr());
}
final int exitCode = Integer.parseInt(stdout.substring(i + exitCodeMarker.length()).trim());
final ExecResultWithExitCode resultWithExitCode = new ExecResultWithExitCode(stdout.substring(0, i), result.getStderr(), exitCode);
if (resultWithExitCode.exitCode != 0) {
log.warn("{}", resultWithExitCode);
} else {
log.info("{}", resultWithExitCode);
}
return resultWithExitCode;
}
@Override
void runCommand() throws IOException, InterruptedException {
Flyway flyway =
Flyway.configure()
.locations("sql/flyway")
.dataSource(
postgresContainer.getJdbcUrl(),
postgresContainer.getUsername(),
postgresContainer.getPassword())
.load();
flyway.migrate();
String userName = postgresContainer.getUsername();
String databaseName = postgresContainer.getDatabaseName();
Container.ExecResult result =
postgresContainer.execInContainer(getSchemaDumpCommand(userName, databaseName));
if (result.getExitCode() != 0) {
throw new RuntimeException(result.toString());
}
result =
postgresContainer.execInContainer("cp", CONTAINER_MOUNT_POINT_TMP, CONTAINER_MOUNT_POINT);
if (result.getExitCode() != 0) {
throw new RuntimeException(result.toString());
}
}
@Test
public void testDatabaseHasTmpFsViaConnectionString() throws Exception {
final String jdbcUrl = "jdbc:tc:postgresql:9.6.8://hostname/databasename?TC_TMPFS=/testtmpfs:rw";
try (Connection ignored = DriverManager.getConnection(jdbcUrl)) {
JdbcDatabaseContainer<?> container = ContainerDatabaseDriver.getContainer(jdbcUrl);
// check file doesn't exist
String path = "/testtmpfs/test.file";
Container.ExecResult execResult = container.execInContainer("ls", path);
assertNotEquals("tmpfs inside container doesn't have file that doesn't exist", 0, execResult.getExitCode());
// touch && check file does exist
container.execInContainer("touch", path);
execResult = container.execInContainer("ls", path);
assertEquals("tmpfs inside container has file that does exist", 0, execResult.getExitCode());
}
}
@Test
public void withTmpFsTest() throws Exception {
try (
GenericContainer container = new GenericContainer()
.withCommand("top")
.withTmpFs(singletonMap("/testtmpfs", "rw"))
) {
container.start();
// check file doesn't exist
String path = "/testtmpfs/test.file";
Container.ExecResult execResult = container.execInContainer("ls", path);
assertEquals("tmpfs inside container works fine", execResult.getStderr(),
"ls: /testtmpfs/test.file: No such file or directory\n");
// touch && check file does exist
container.execInContainer("touch", path);
execResult = container.execInContainer("ls", path);
assertEquals("tmpfs inside container works fine", execResult.getStdout(), path + "\n");
}
}
private void validateExporter(final String taskId, final String traceId) throws Exception {
final String exportShell = String.format(
"/skywalking/tools/profile-exporter/profile_exporter.sh --taskid=%s --traceid=%s /tmp",
taskId, traceId
);
final Container.ExecResult exportResult = oapContainer.execInContainer("/bin/sh", "-c", exportShell);
LOGGER.info("exported result: {}", exportResult);
assertThat(exportResult.getExitCode()).isEqualTo(0);
final String lsExportedFileShell = String.format("ls /tmp/%s.tar.gz", traceId);
final Container.ExecResult checkExportedFileResult = oapContainer.execInContainer("/bin/sh", "-c", lsExportedFileShell);
LOGGER.info("check exported file result: {}", checkExportedFileResult);
assertThat(checkExportedFileResult.getExitCode()).isEqualTo(0);
}
public void start() {
swiftContainer.start();
Integer swiftPort = swiftContainer.getMappedPort(SWIFT_PORT);
String containerIpAddress = swiftContainer.getContainerIpAddress();
Container.ExecResult execResult =
Throwing.supplier(() ->
swiftContainer.execInContainer(
"/swift/bin/register-swift-endpoint.sh",
"http://" + containerIpAddress + ":" + swiftPort))
.sneakyThrow()
.get();
if (!execResult.getStdout().isEmpty()) {
LOGGER.debug(execResult.getStdout());
}
if (!execResult.getStderr().isEmpty()) {
LOGGER.error(execResult.getStderr());
}
URI keystoneV2Endpoint =
URI.create("http://" + getKeystoneHost().asString() + "/v2.0");
URI keystoneV3Endpoint =
URI.create("http://" + getKeystoneHost().asString() + "/v3");
URI swiftEndpoint =
URI.create("http://" + getSwiftHost().asString() + "/auth/v1.0");
dockerSwift = new DockerSwift(keystoneV2Endpoint, keystoneV3Endpoint, swiftEndpoint);
}
private void wait(Collection<Container<?>> containers)
{
try {
while (containers.stream().anyMatch(ContainerState::isRunning)) {
Thread.sleep(1_000);
}
throw new RuntimeException("All containers have been stopped");
}
catch (InterruptedException e) {
log.info("Interrupted");
// It's OK not to restore interrupt flag here. When we return we're exiting the process.
}
}
private void waitForContainerToStart() throws InterruptedException, IOException {
Instant started = Instant.now();
while (Instant.now().isBefore(started.plusSeconds(20))) {
Container.ExecResult vault_status = vaultContainer.execInContainer(createVaultCommand("vault status"));
if (vault_status.getExitCode() == 2) { // 2 => sealed
return;
}
}
fail("vault failed to start");
}
private static Container.ExecResult exec(GenericContainer container, String[] cmd)
throws IOException, InterruptedException {
Container.ExecResult execResult = container.execInContainer(cmd);
if (execResult.getExitCode() != 0) {
throw new RuntimeException(
"command " + Arrays.asList(cmd) + " failed with exit code " + execResult.getExitCode() + "\n"
+ execResult.getStderr());
}
return execResult;
}
/**
* Runs the specified command from within the Docker container.
*
* @param command The command to run, broken up by whitespace
* (e.g. "vault mount -path=pki pki" becomes "vault", "mount", "-path=pki", "pki")
* @return
* @throws IOException
* @throws InterruptedException
*/
private Container.ExecResult runCommand(final String... command) throws IOException, InterruptedException {
LOGGER.info("Command: {}", String.join(" ", command));
final Container.ExecResult result = execInContainer(command);
final String out = result.getStdout();
final String err = result.getStderr();
if (out != null && !out.isEmpty()) {
LOGGER.info("Command stdout: {}", result.getStdout());
}
if (err != null && !err.isEmpty()) {
LOGGER.info("Command stderr: {}", result.getStderr());
}
return result;
}
@Test
public void deploySchema_success() throws Exception {
Flyway flyway =
Flyway.configure()
.locations("sql/flyway")
.dataSource(
sqlContainer.getJdbcUrl(), sqlContainer.getUsername(), sqlContainer.getPassword())
.load();
// flyway.migrate() returns the number of newly pushed scripts. This is a variable
// number as our schema evolves.
assertThat(flyway.migrate()).isGreaterThan(0);
flyway.validate();
Container.ExecResult execResult =
sqlContainer.execInContainer(
StandardCharsets.UTF_8,
getSchemaDumpCommand(sqlContainer.getUsername(), sqlContainer.getDatabaseName()));
if (execResult.getExitCode() != 0) {
throw new RuntimeException(execResult.toString());
}
URL dumpedSchema =
Resources.getResource(
Joiner.on(File.separatorChar).join(MOUNTED_RESOURCE_PATH, DUMP_OUTPUT_FILE));
assertThat(dumpedSchema)
.hasSameContentAs(Resources.getResource("sql/schema/nomulus.golden.sql"));
}
@Test
public void testSimpleExec() throws IOException, InterruptedException {
// standaloneExec {
container.execInContainer("touch", "/somefile.txt");
// }
// execReadingStdout {
Container.ExecResult lsResult = container.execInContainer("ls", "-al", "/");
String stdout = lsResult.getStdout();
int exitCode = lsResult.getExitCode();
assertTrue(stdout.contains("somefile.txt"));
assertTrue(exitCode == 0);
// }
}
private String runAwsCliAgainstDockerNetworkContainer(String command, final int port) throws Exception {
final String[] commandParts = String.format("/usr/bin/aws --region eu-west-1 %s --endpoint-url http://localstack:%d --no-verify-ssl", command, port).split(" ");
final Container.ExecResult execResult = awsCliInDockerNetwork.execInContainer(commandParts);
Assert.assertEquals(0, execResult.getExitCode());
final String logs = execResult.getStdout() + execResult.getStderr();
log.info(logs);
return logs;
}
@Override
public void addDomain(String domain) throws Exception {
Container.ExecResult execResult = exec("adddomain", domain);
if (execResult.getExitCode() != 0) {
throw new ProvisioningException("Failed to add domain" + executionResultToString(execResult));
}
}
@Override
public void addUser(Username user, String password) throws Exception {
Container.ExecResult execResult = exec("adduser", user.asString(), password);
if (execResult.getExitCode() != 0) {
throw new ProvisioningException("Failed to add user" + executionResultToString(execResult));
}
}
private String[] shCmd() throws IOException, InterruptedException, ProvisioningException {
Container.ExecResult findCli = container.exec("find", "/root", "-name", "james-cli.sh");
if (findCli.getExitCode() != 0) {
throw new ProvisioningException("Failed to getCliPath" + executionResultToString(findCli));
}
return new String[]{findCli.getStdout().trim()};
}
private String getKnoxToken(boolean forceKnoxSpecifcToken) throws Exception {
String token;
if(forceKnoxSpecifcToken) {
LOG.info("Using Knox specific token");
Container.ExecResult tokenCreationExecResult = vaultContainer.execInContainer("vault", "token",
"create", "-policy=" + getVaultPolicy(), "-field=token");
token = tokenCreationExecResult.getStdout().replaceAll("\\s", "").trim();
} else {
LOG.info("Using root token");
token = vaultToken;
}
return token;
}
@Test
public void shouldPerformDockerAuthAgainstRegistry() throws Exception {
log.info("Starting the attempt for login...");
Container.ExecResult dockerLoginResult = dockerClientContainer.execInContainer("docker", "login", "-u", DOCKER_USER, "-p", DOCKER_USER_PASSWORD, REGISTRY_HOSTNAME + ":" + REGISTRY_PORT);
printCommandResult(dockerLoginResult);
assertThat(dockerLoginResult.getStdout(), containsString("Login Succeeded"));
}
public Container<?> getContainer(String name)
{
return Optional.ofNullable(containers.get(requireNonNull(name, "name is null")))
.orElseThrow(() -> new IllegalArgumentException("No container with name " + name));
}
public Collection<Container<?>> getContainers()
{
return ImmutableList.copyOf(containers.values());
}
@Test
public void readFromMsSql() throws Exception {
execInContainer("setup.sql");
assertTrueEventually(() -> {
Container.ExecResult result = execInContainer("cdc.sql");
assertContains(result.getStdout(), "already");
});
Configuration configuration = Configuration
.create()
.with("name", "mssql-inventory-connector")
.with("connector.class", "io.debezium.connector.sqlserver.SqlServerConnector")
/* begin connector properties */
.with("tasks.max", "1")
.with("database.hostname", mssql.getContainerIpAddress())
.with("database.port", mssql.getMappedPort(MS_SQL_SERVER_PORT))
.with("database.user", mssql.getUsername())
.with("database.password", mssql.getPassword())
.with("database.dbname", "MyDB")
.with("database.server.name", "fulfillment")
.with("table.whitelist", "inventory.customers")
.with("database.history.hazelcast.list.name", "test")
.build();
JetInstance jet = createJetMember();
Pipeline pipeline = Pipeline.create();
pipeline.readFrom(DebeziumSources.cdc(configuration))
.withoutTimestamps()
.map(record -> Values.convertToString(record.valueSchema(), record.value()))
.writeTo(AssertionSinks.assertCollectedEventually(60,
list -> assertTrue(list.stream().anyMatch(s -> s.contains("Anne Marie")))));
JobConfig jobConfig = new JobConfig();
jobConfig.addJarsInZip(Objects.requireNonNull(this.getClass()
.getClassLoader()
.getResource("debezium-connector-sqlserver.zip")));
Job job = jet.newJob(pipeline, jobConfig);
assertJobStatusEventually(job, JobStatus.RUNNING);
sleepAtLeastSeconds(30);
// update record
try (Connection connection = DriverManager.getConnection(mssql.getJdbcUrl() + ";databaseName=MyDB",
mssql.getUsername(), mssql.getPassword())) {
connection.setSchema("inventory");
PreparedStatement preparedStatement = connection.prepareStatement("update MyDB.inventory.customers set " +
"first_name = 'Anne Marie' where id = 1001;");
preparedStatement.executeUpdate();
}
try {
job.join();
fail("Job should have completed with an AssertionCompletedException, but completed normally");
} catch (CompletionException e) {
String errorMsg = e.getCause().getMessage();
assertTrue("Job was expected to complete with AssertionCompletedException, but completed with: "
+ e.getCause(), errorMsg.contains(AssertionCompletedException.class.getName()));
}
}
private Container.ExecResult execInContainer(String script) throws Exception {
return mssql.execInContainer("/opt/mssql-tools/bin/sqlcmd", "-S", "localhost", "-U", mssql.getUsername(),
"-P", mssql.getPassword(), "-d", "master", "-i", "/tmp/" + script);
}
public static ExecResultWithExitCode execOrDie(Container container, String shellCommand) {
return checkExitCode(exec(container, shellCommand));
}
@Test
public void testHostnameModified() throws IOException, InterruptedException {
final Container.ExecResult execResult = theCache.execInContainer("hostname");
assertEquals("the-cache", execResult.getStdout().trim());
}
@Test
public void testMemoryLimitModified() throws IOException, InterruptedException {
final Container.ExecResult execResult = memoryLimitedRedis.execInContainer("cat", "/sys/fs/cgroup/memory/memory.limit_in_bytes");
assertEquals("8388608", execResult.getStdout().trim());
}
private Container.ExecResult exec(String... commands) throws Exception {
String[] command = ArrayUtils.addAll(ArrayUtils.addAll(cmd, hostAndPort), commands);
return container.exec(command);
}
private String executionResultToString(Container.ExecResult execResult) {
return StringUtils.join(ImmutableList.of(execResult.getStdout(), execResult.getStderr()), " ");
}
public Container.ExecResult exec(String... command) throws IOException, InterruptedException {
return container.execInContainer(command);
}