Skip to content

Commit

Permalink
test : Add tests for Docker BuildX --driver-opts flag while creating …
Browse files Browse the repository at this point in the history
…builder

+ Add BuildXServiceCreateBuilderTest for verifying --driver-opt flag is
  passed while creating builder
+ Add buildx-driver-opt integration test

Signed-off-by: Rohan Kumar <rohaan@redhat.com>
  • Loading branch information
rohanKanojia committed Jan 7, 2024
1 parent 06f8882 commit 478b930
Show file tree
Hide file tree
Showing 5 changed files with 209 additions and 4 deletions.
1 change: 1 addition & 0 deletions doc/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
- Add new option "useDefaultExclusion" for build configuration to handle exclusion of hidden files ([1708](https://github.com/fabric8io/docker-maven-plugin/issues/1708))
- The <noCache> option is now propagated down to the buildx command, if it is set in the <build> section. ([1717](https://github.com/fabric8io/docker-maven-plugin/pull/1717))
- Fix Buildx build with Dockerfile outside of the Docker build context directory ([1721](https://github.com/fabric8io/docker-maven-plugin/pull/1721))
- Add support setting driverOpts for buildx ([1704](https://github.com/fabric8io/docker-maven-plugin/pull/1704))

* **0.43.4** (2023-08-18):
- Always pass `--config` option for latest versions of Docker CLI ([1701](https://github.com/fabric8io/docker-maven-plugin/issues/1701))
Expand Down
89 changes: 89 additions & 0 deletions it/buildx-driver-opt/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>io.fabric8.dmp.itests</groupId>
<artifactId>dmp-it-parent</artifactId>
<version>0.44-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

<artifactId>dmp-it-buildx-driver-opts</artifactId>

<build>
<plugins>

<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<images>
<image>
<name>hello/buildx-driver-opt:${project.version}</name>
<alias>hello-world-buildx-driver-opt</alias>
<build>
<from>azul/zulu-openjdk-alpine:17-jre</from>
<assembly>
<descriptorRef>artifact</descriptorRef>
</assembly>
<cmd>java -jar maven/${project.name}-${project.version}.jar</cmd>
<buildx>
<driverOpts>
<network>host</network>
</driverOpts>
<platforms>
<platform>linux/amd64</platform>
<platform>linux/arm64</platform>
</platforms>
</buildx>
<tags>
<tag>${project.version}</tag>
</tags>
</build>
<run>
<log>
<file>${project.build.directory}/docker.log</file>
</log>
<wait>
<log>Hello World</log>
<kill>5000</kill>
<shutdown>1000</shutdown>
<time>5000</time>
</wait>
</run>
</image>
</images>
</configuration>
<executions>
<execution>
<id>docker-build</id>
<goals>
<goal>build</goal>
</goals>
<phase>package</phase>
</execution>
<execution>
<id>integration-test</id>
<goals>
<goal>start</goal>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>

<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>io.fabric8.dmp.sample.multiarch.helloworld.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>

</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package io.fabric8.dmp.sample.multiarch.helloworld;

/**
* Hello world!
*/
public class App {
public static void main(String[] args) throws InterruptedException {
System.out.println("Hello World from " + System.getProperty("os.arch"));
Thread.sleep(100000);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -269,10 +269,8 @@ protected String createBuilder(Path configPath, List<String> buildX, ImageConfig
append(cmds, "--node", nodeName);
}

if (buildXConfiguration.getDriverOpts() != null) {
buildXConfiguration.getDriverOpts().forEach((key, value) -> {
append(cmds, "--driver-opt", key + '=' + value);
});
if (buildXConfiguration.getDriverOpts() != null && !buildXConfiguration.getDriverOpts().isEmpty()) {
buildXConfiguration.getDriverOpts().forEach((key, value) -> append(cmds, "--driver-opt", key + '=' + value));
}

String buildConfig = buildXConfiguration.getConfigFile();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package io.fabric8.maven.docker.service;

import io.fabric8.maven.docker.access.DockerAccess;
import io.fabric8.maven.docker.assembly.BuildDirs;
import io.fabric8.maven.docker.assembly.DockerAssemblyManager;
import io.fabric8.maven.docker.config.BuildImageConfiguration;
import io.fabric8.maven.docker.config.BuildXConfiguration;
import io.fabric8.maven.docker.config.ImageConfiguration;
import io.fabric8.maven.docker.util.Logger;
import io.fabric8.maven.docker.util.ProjectPaths;
import org.apache.maven.plugin.MojoExecutionException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;

import java.io.File;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.BiConsumer;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;

class BuildXServiceCreateBuilderTest {
private BuildXService buildXService;
private ImageConfiguration imageConfig;
private BuildXService.Exec exec;
private BuildDirs buildDirs;
private Path configPath;
private List<String> execArgs;

@TempDir
private File temporaryFolder;

@BeforeEach
void setUp() {
configPath = temporaryFolder.toPath().resolve(".docker").resolve("config.json");
buildDirs = new BuildDirs(new ProjectPaths(temporaryFolder, "target"), "foo/bar:latest");
DockerAssemblyManager dockerAssemblyManager = mock(DockerAssemblyManager.class);
DockerAccess dockerAccess = mock(DockerAccess.class);
Logger logger = mock(Logger.class);
exec = mock(BuildXService.Exec.class);
buildXService = new BuildXService(dockerAccess, dockerAssemblyManager, logger, exec);
}

@Test
void driverOptIsPresentIfProvided() throws Exception {
//Given
buildConfigUsingBuildX(temporaryFolder, (buildX, buildImage) -> buildX.driverOpts(Collections.singletonMap("network", "foonet")));

// When
buildXService.createBuilder(configPath, Arrays.asList("docker", "buildx"), imageConfig, buildDirs);

//Then
verifyBuildXArgumentContains("--driver-opt", "network=foonet");
}

@Test
void driverOptIsAbsentIfNotProvided() throws Exception {
//Given
buildConfigUsingBuildX(temporaryFolder, (buildX, buildImage) -> {});

// When
buildXService.createBuilder(configPath, Arrays.asList("docker", "buildx"), imageConfig, buildDirs);

//Then
verifyBuildXArgumentDoesNotContain("--driver-opt", "network=foonet");
}

private void captureBuildXArguments() throws MojoExecutionException {
ArgumentCaptor<List<String>> buildXArgCaptor = ArgumentCaptor.forClass(List.class);
Mockito.verify(exec).process(buildXArgCaptor.capture());
execArgs = buildXArgCaptor.getValue();
}

private void verifyBuildXArgumentContains(String... args) throws MojoExecutionException {
captureBuildXArguments();
assertTrue(execArgs.containsAll(Arrays.asList(args)));
}

private void verifyBuildXArgumentDoesNotContain(String... args) throws MojoExecutionException {
captureBuildXArguments();
assertFalse(execArgs.containsAll(Arrays.asList(args)));
}

private void buildConfigUsingBuildX(File temporaryFolder, BiConsumer<BuildXConfiguration.Builder, BuildImageConfiguration.Builder> spec) {
final BuildXConfiguration.Builder buildXConfigurationBuilder = new BuildXConfiguration.Builder()
.dockerStateDir(temporaryFolder.getAbsolutePath())
.platforms(Collections.singletonList("linux/amd64"));
final BuildImageConfiguration.Builder buildImageConfigBuilder = new BuildImageConfiguration.Builder();
spec.accept(buildXConfigurationBuilder, buildImageConfigBuilder);
final BuildXConfiguration buildXConfig = buildXConfigurationBuilder.build();
final BuildImageConfiguration buildImageConfig = buildImageConfigBuilder
.buildx(buildXConfig)
.build();
imageConfig = new ImageConfiguration.Builder()
.name("foo/bar:latest")
.buildConfig(buildImageConfig)
.build();
}
}

0 comments on commit 478b930

Please sign in to comment.