Skip to content

Commit

Permalink
add unit tests for buildX platforms
Browse files Browse the repository at this point in the history
Signed-off-by: Marsette Vona <[email protected]>
  • Loading branch information
Marsette Vona authored and rohanKanojia committed Apr 18, 2023
1 parent 618bb36 commit e1a9e88
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 10 deletions.
20 changes: 10 additions & 10 deletions src/main/java/io/fabric8/maven/docker/service/BuildXService.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public void push(ProjectPaths projectPaths, ImageConfiguration imageConfig, Stri
useBuilder(projectPaths, imageConfig, configuredRegistry, authConfig, archive, this::pushMultiPlatform);
}

private <C> void useBuilder(ProjectPaths projectPaths, ImageConfiguration imageConfig, String configuredRegistry, AuthConfig authConfig, C context, Builder<C> builder) throws MojoExecutionException {
protected <C> void useBuilder(ProjectPaths projectPaths, ImageConfiguration imageConfig, String configuredRegistry, AuthConfig authConfig, C context, Builder<C> builder) throws MojoExecutionException {
BuildDirs buildDirs = new BuildDirs(projectPaths, imageConfig.getName());

Path configPath = getDockerStateDir(imageConfig.getBuildConfiguration(), buildDirs);
Expand All @@ -74,7 +74,7 @@ private <C> void useBuilder(ProjectPaths projectPaths, ImageConfiguration imageC
}
}

private void createConfigJson(Path configJson, AuthConfig authConfig) throws MojoExecutionException {
protected void createConfigJson(Path configJson, AuthConfig authConfig) throws MojoExecutionException {
try (BufferedWriter bufferedWriter = Files.newBufferedWriter(configJson, StandardCharsets.UTF_8,
StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)
) {
Expand All @@ -84,15 +84,15 @@ private void createConfigJson(Path configJson, AuthConfig authConfig) throws Moj
}
}

private void removeConfigJson(Path configJson) {
protected void removeConfigJson(Path configJson) {
try {
Files.deleteIfExists(configJson);
} catch (IOException e) {
logger.warn("Unable to delete %s", configJson);
}
}

private void buildAndLoadSinglePlatform(List<String> buildX, String builderName, BuildDirs buildDirs, ImageConfiguration imageConfig, String configuredRegistry, File buildArchive) throws MojoExecutionException {
protected void buildAndLoadSinglePlatform(List<String> buildX, String builderName, BuildDirs buildDirs, ImageConfiguration imageConfig, String configuredRegistry, File buildArchive) throws MojoExecutionException {
List<String> platforms = imageConfig.getBuildConfiguration().getBuildX().getPlatforms();
// build and load the single-platform image by re-building, image should be cached and build should be quick
String nativePlatform = dockerAccess.getNativePlatform();
Expand All @@ -105,12 +105,12 @@ private void buildAndLoadSinglePlatform(List<String> buildX, String builderName,
}
}

private void pushMultiPlatform(List<String> buildX, String builderName, BuildDirs buildDirs, ImageConfiguration imageConfig, String configuredRegistry, File buildArchive) throws MojoExecutionException {
protected void pushMultiPlatform(List<String> buildX, String builderName, BuildDirs buildDirs, ImageConfiguration imageConfig, String configuredRegistry, File buildArchive) throws MojoExecutionException {
// build and push all images. The native platform may be re-built, image should be cached and build should be quick
buildX(buildX, builderName, buildDirs, imageConfig, configuredRegistry, imageConfig.getBuildConfiguration().getBuildX().getPlatforms(), buildArchive, "--push");
}

private void buildX(List<String> buildX, String builderName, BuildDirs buildDirs, ImageConfiguration imageConfig, String configuredRegistry, List<String> platforms, File buildArchive, String extraParam)
protected void buildX(List<String> buildX, String builderName, BuildDirs buildDirs, ImageConfiguration imageConfig, String configuredRegistry, List<String> platforms, File buildArchive, String extraParam)
throws MojoExecutionException {

BuildImageConfiguration buildConfiguration = imageConfig.getBuildConfiguration();
Expand Down Expand Up @@ -160,7 +160,7 @@ private void buildX(List<String> buildX, String builderName, BuildDirs buildDirs
}
}

private Path getContextPath(File buildArchive) throws MojoExecutionException {
protected Path getContextPath(File buildArchive) throws MojoExecutionException {
String archiveName = buildArchive.getName();
String fileName = archiveName.substring(0, archiveName.indexOf('.'));
File destinationDirectory = new File(buildArchive.getParentFile(), fileName);
Expand All @@ -174,22 +174,22 @@ private Path getContextPath(File buildArchive) throws MojoExecutionException {
return destinationPath;
}

private Path getDockerStateDir(BuildImageConfiguration buildConfiguration, BuildDirs buildDirs) {
protected Path getDockerStateDir(BuildImageConfiguration buildConfiguration, BuildDirs buildDirs) {
String stateDir = buildConfiguration.getBuildX().getDockerStateDir();
Path dockerStatePath = buildDirs.getBuildPath(stateDir != null ? EnvUtil.resolveHomeReference(stateDir) : "docker");
createDirectory(dockerStatePath);
return dockerStatePath;
}

private void createDirectory(Path cachePath) {
protected void createDirectory(Path cachePath) {
try {
Files.createDirectories(cachePath);
} catch (IOException e) {
throw new IllegalArgumentException("Cannot create " + cachePath);
}
}

private String createBuilder(Path configPath, List<String> buildX, ImageConfiguration imageConfig, BuildDirs buildDirs) throws MojoExecutionException {
protected String createBuilder(Path configPath, List<String> buildX, ImageConfiguration imageConfig, BuildDirs buildDirs) throws MojoExecutionException {
BuildXConfiguration buildXConfiguration = imageConfig.getBuildConfiguration().getBuildX();
String builderName = buildXConfiguration.getBuilderName();
if (builderName == null) {
Expand Down
132 changes: 132 additions & 0 deletions src/test/java/io/fabric8/maven/docker/service/BuildXServiceTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package io.fabric8.maven.docker.service;

import java.util.Arrays;
import java.util.List;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.Mockito;
import org.mockito.quality.Strictness;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;

import io.fabric8.maven.docker.access.DockerAccess;
import io.fabric8.maven.docker.access.AuthConfig;
import io.fabric8.maven.docker.assembly.DockerAssemblyManager;
import io.fabric8.maven.docker.util.Logger;
import io.fabric8.maven.docker.util.ProjectPaths;
import io.fabric8.maven.docker.config.BuildXConfiguration;
import io.fabric8.maven.docker.config.BuildImageConfiguration;
import io.fabric8.maven.docker.config.ImageConfiguration;

@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.WARN)
class BuildXServiceTest {

private static final String NATIVE = "linux/amd64";
private static final String FOREIGN1 = "linux/arm64";
private static final String FOREIGN2 = "darwin/amd64";

@Mock
private DockerAccess dockerAccess;

@Mock
private DockerAssemblyManager dockerAssemblyManager;

@Mock
private Logger logger;

@Mock
private BuildXService.Exec exec;

@InjectMocks
@Spy
private BuildXService buildx;

private ImageConfiguration imageConfig;

private final ProjectPaths projectPaths = new ProjectPaths(new File("project-base-dir"), "output-dir");
private final String configuredRegistry = "configured-registry";
private final File buildArchive = new File("build-archive");
private final AuthConfig authConfig = null;

@BeforeEach
void setup() throws Exception {

Mockito.when(dockerAccess.getNativePlatform()).thenReturn(NATIVE);

Mockito.doNothing().when(buildx).createConfigJson(Mockito.any(), Mockito.any());
Mockito.doNothing().when(buildx).removeConfigJson(Mockito.any());

Mockito.doReturn(Paths.get("docker-state-dir")).when(buildx).getDockerStateDir(Mockito.any(), Mockito.any());
Mockito.doReturn("maven").when(buildx).createBuilder(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any());
}

@Test
void testBuildNativePlatform() throws Exception {
givenAnImageConfiguration(NATIVE);
mockBuildX();
buildx.build(projectPaths, imageConfig, configuredRegistry, authConfig, buildArchive);
verifyBuildXPlatforms(NATIVE);
}

@Test
void testBuildForeignPlatform() throws Exception {
givenAnImageConfiguration(FOREIGN1);
mockBuildX();
buildx.build(projectPaths, imageConfig, configuredRegistry, authConfig, buildArchive);
verifyBuildXPlatforms(FOREIGN1);
}

@Test
void testBuildNativePlatformWithForeign() throws Exception {
givenAnImageConfiguration(NATIVE, FOREIGN1);
mockBuildX();
buildx.build(projectPaths, imageConfig, configuredRegistry, authConfig, buildArchive);
verifyBuildXPlatforms(NATIVE);
}

@Test
void testBuildForeignPlatforms() throws Exception {
givenAnImageConfiguration(FOREIGN1, FOREIGN2);
buildx.build(projectPaths, imageConfig, configuredRegistry, authConfig, buildArchive);
Mockito.verify(buildx, Mockito.times(0)).buildX(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(),
Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any());
}

private void givenAnImageConfiguration(String... platforms) {

final BuildXConfiguration buildxConfig = new BuildXConfiguration.Builder()
.platforms(Arrays.asList(platforms))
.build();

final BuildImageConfiguration buildImageConfig = new BuildImageConfiguration.Builder()
.buildx(buildxConfig)
.build();

imageConfig = new ImageConfiguration.Builder()
.name("build-image")
.buildConfig(buildImageConfig)
.build();
}

private void mockBuildX() throws Exception {
Mockito.doNothing().when(buildx).buildX(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(),
Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any());
}

private void verifyBuildXPlatforms(String... platforms) throws Exception {
final List<String> expect = Arrays.asList(platforms);
Mockito.verify(buildx).buildX(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(),
Mockito.argThat(l -> expect.equals(l)), Mockito.any(), Mockito.any());
}
}

0 comments on commit e1a9e88

Please sign in to comment.