diff --git a/.github/workflows/pull-request-check.yml b/.github/workflows/pull-request-check.yml
index a0389a7d..95dc610f 100644
--- a/.github/workflows/pull-request-check.yml
+++ b/.github/workflows/pull-request-check.yml
@@ -15,12 +15,12 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
- java: [ 8, 11, 17, 21 ]
+ java: [ 11, 17, 21 ]
fail-fast: false
steps:
- uses: actions/checkout@v3
- - name: Set up JDK 8
+ - name: Set up JDK 11
uses: actions/setup-java@v3
with:
distribution: 'temurin'
diff --git a/.github/workflows/xtf-maven-release.yml b/.github/workflows/xtf-maven-release.yml
index 35a95e3e..9c6865dd 100644
--- a/.github/workflows/xtf-maven-release.yml
+++ b/.github/workflows/xtf-maven-release.yml
@@ -14,10 +14,10 @@ jobs:
steps:
- uses: actions/checkout@v1
- - name: Set up JDK 8
+ - name: Set up JDK 11
uses: actions/setup-java@v1
with:
- java-version: 8
+ java-version: 11
java-package: jdk
architecture: x64
- name: Check well-formatted code
diff --git a/builder/pom.xml b/builder/pom.xml
index d67e1771..9aa25d54 100644
--- a/builder/pom.xml
+++ b/builder/pom.xml
@@ -28,11 +28,6 @@
provided
-
- io.fabric8
- openshift-server-mock
- test
-
diff --git a/builder/src/test/java/cz/xtf/builder/openshift/mocked/smoke/BasicOpenShiftTest.java b/builder/src/test/java/cz/xtf/builder/openshift/mocked/smoke/BasicOpenShiftTest.java
deleted file mode 100644
index 67e4b9ad..00000000
--- a/builder/src/test/java/cz/xtf/builder/openshift/mocked/smoke/BasicOpenShiftTest.java
+++ /dev/null
@@ -1,129 +0,0 @@
-package cz.xtf.builder.openshift.mocked.smoke;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import org.junit.Assert;
-import org.junit.jupiter.api.Test;
-
-import cz.xtf.builder.builders.ConfigMapBuilder;
-import cz.xtf.builder.builders.DeploymentConfigBuilder;
-import cz.xtf.core.openshift.OpenShift;
-import io.fabric8.kubernetes.api.model.ConfigMap;
-import io.fabric8.kubernetes.api.model.PodSpec;
-import io.fabric8.openshift.api.model.DeploymentConfig;
-import io.fabric8.openshift.client.OpenShiftClient;
-import io.fabric8.openshift.client.server.mock.OpenShiftServer;
-
-public class BasicOpenShiftTest {
-
- private static final String TEST_RESOURCE_LABEL_NAME_APP = "app";
- private static final String TEST_RESOURCE_LABEL_VALUE_APP = "xtf-core-test-openshift-mocked-smoke";
- private final static Map TEST_RESOURCE_LABELS = Collections.singletonMap(
- TEST_RESOURCE_LABEL_NAME_APP, TEST_RESOURCE_LABEL_VALUE_APP);
-
- private static final String TEST_CONFIGMAP_NAME = "test-configmap";
- private static final String TEST_DEPLOYMENT_NAME = "test-deployment";
- private static final String TEST_DEPLOYMENT_CONFIG_NAME = "test-deployment-config";
- private static final Integer TEST_DEPLOYMENT_CONFIG_REPLICAS = 3;
-
- private final OpenShiftServer openShiftServer;
- private final OpenShift openShiftClient;
-
- public BasicOpenShiftTest() {
- this.openShiftServer = new OpenShiftServer(false, true);
- this.openShiftServer.before();
- // we want to test the XTF OpenShift client, but we need to configure it with the mocked server client
- // properties
- OpenShiftClient mockedServerClient = openShiftServer.getOpenshiftClient();
- this.openShiftClient = OpenShift.get(
- mockedServerClient.getMasterUrl().toString(),
- mockedServerClient.getNamespace(),
- mockedServerClient.getConfiguration().getUsername(),
- mockedServerClient.getConfiguration().getPassword());
- }
-
- @Test
- public void testConfigMapBuilder() {
- // arrange
- final String dataEntryKey = "test.properties";
- final String dataEntryValue = "foo=bar";
- final ConfigMap configMap = new ConfigMapBuilder(TEST_CONFIGMAP_NAME)
- .addLabels(TEST_RESOURCE_LABELS)
- .configEntry(dataEntryKey, dataEntryValue)
- .build();
- // act
- openShiftClient.createResources(configMap);
- // assert
- List actualConfigMaps = openShiftClient.getConfigMaps();
- Assert.assertEquals(String.format("ConfigMap resource list has unexpected size: %d.",
- actualConfigMaps.size()), 1, actualConfigMaps.size());
- ConfigMap actualConfigMap = openShiftClient.getConfigMap(TEST_CONFIGMAP_NAME);
- Assert.assertNotNull("ConfigMap resource creation failed.", actualConfigMap);
- Assert.assertEquals("ConfigMap resource has unexpected name.",
- TEST_CONFIGMAP_NAME,
- actualConfigMap.getMetadata().getName());
- Assert.assertEquals(
- String.format("ConfigMap resource has unexpected data size: %d", actualConfigMap.getData().entrySet().size()),
- 1,
- actualConfigMap.getData().entrySet().size());
- // safe now
- final Map.Entry dataEntry = actualConfigMap.getData().entrySet().stream().findFirst().get();
- Assert.assertEquals(
- String.format("ConfigMap resource has unexpected data entry key: %s", dataEntry.getKey()),
- dataEntryKey,
- dataEntry.getKey());
- Assert.assertEquals(
- String.format("ConfigMap resource has unexpected data entry value: %s", dataEntry.getValue()),
- dataEntryValue,
- dataEntry.getValue());
- }
-
- @Test
- public void testDeploymentConfigBuilder() {
- // arrange
- final DeploymentConfig deploymentConfig = new DeploymentConfigBuilder(TEST_DEPLOYMENT_CONFIG_NAME)
- .addLabels(TEST_RESOURCE_LABELS)
- .setReplicas(TEST_DEPLOYMENT_CONFIG_REPLICAS)
- .onImageChange()
- .setRecreateStrategy()
- .build();
- // act
- openShiftClient.createResources(deploymentConfig);
- // assert
- List actualResources = openShiftClient.deploymentConfigs()
- .withLabel(TEST_RESOURCE_LABEL_NAME_APP, TEST_RESOURCE_LABEL_VALUE_APP)
- .list()
- .getItems();
- Assert.assertEquals(
- String.format("DeploymentConfig resource list has unexpected size: %d.", actualResources.size()),
- 1, actualResources.size());
- DeploymentConfig actualResource = actualResources.get(0);
- Assert.assertEquals(
- String.format("DeploymentConfig resource has unexpected name: %s.", actualResource.getMetadata().getName()),
- TEST_DEPLOYMENT_CONFIG_NAME, actualResource.getMetadata().getName());
- Assert.assertNotNull(String.format("DeploymentConfig resource has null \".spec\"", actualResource.getSpec()));
- Assert.assertEquals(
- String.format("DeploymentConfig resource has unexpected \".spec.replicas\": %s.",
- actualResource.getSpec().getReplicas()),
- TEST_DEPLOYMENT_CONFIG_REPLICAS,
- actualResource.getSpec().getReplicas());
- Assert.assertNotNull(
- String.format("DeploymentConfig resource has null \".spec.strategy\"", actualResource.getSpec().getStrategy()));
- Assert.assertEquals(
- String.format("DeploymentConfig resource has unexpected \".spec.strategy\": %s.",
- actualResource.getSpec().getStrategy().getType()),
- "Recreate",
- actualResource.getSpec().getStrategy().getType());
- Assert.assertNotNull(
- String.format("DeploymentConfig resource has null \".spec.template\"", actualResource.getSpec().getTemplate()));
- Assert.assertNotNull(String.format("DeploymentConfig resource has null \".spec.template.spec\"",
- actualResource.getSpec().getTemplate().getSpec()));
- PodSpec podSpec = actualResource.getSpec().getTemplate().getSpec();
- Assert.assertEquals(
- String.format("DeploymentConfig resource has unexpected \".spec.template.spec.containers\": %s.",
- podSpec.getContainers().size()),
- 0, podSpec.getContainers().size());
- }
-}
diff --git a/builder/src/test/java/cz/xtf/builder/openshift/smoke/BuildersTest.java b/builder/src/test/java/cz/xtf/builder/openshift/smoke/BuildersTest.java
new file mode 100644
index 00000000..92fe39b1
--- /dev/null
+++ b/builder/src/test/java/cz/xtf/builder/openshift/smoke/BuildersTest.java
@@ -0,0 +1,106 @@
+package cz.xtf.builder.openshift.smoke;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import cz.xtf.builder.builders.ConfigMapBuilder;
+import cz.xtf.builder.builders.DeploymentConfigBuilder;
+import io.fabric8.kubernetes.api.model.ConfigMap;
+import io.fabric8.kubernetes.api.model.PodSpec;
+import io.fabric8.openshift.api.model.DeploymentConfig;
+
+/**
+ * Unit tests for XTF builder classes.
+ * Tests verify that builders correctly construct Kubernetes/OpenShift resource objects.
+ *
+ * Replaces BasicOpenShiftTest which used OpenShiftServer mock (removed in Fabric8 7.4.0).
+ */
+public class BuildersTest {
+
+ private static final String TEST_RESOURCE_LABEL_NAME_APP = "app";
+ private static final String TEST_RESOURCE_LABEL_VALUE_APP = "xtf-core-test-openshift-mocked-smoke";
+ private final static Map TEST_RESOURCE_LABELS = Collections.singletonMap(
+ TEST_RESOURCE_LABEL_NAME_APP, TEST_RESOURCE_LABEL_VALUE_APP);
+
+ private static final String TEST_CONFIGMAP_NAME = "test-configmap";
+ private static final String TEST_DEPLOYMENT_CONFIG_NAME = "test-deployment-config";
+ private static final Integer TEST_DEPLOYMENT_CONFIG_REPLICAS = 3;
+
+ @Test
+ public void testConfigMapBuilder() {
+ // arrange
+ final String dataEntryKey = "test.properties";
+ final String dataEntryValue = "foo=bar";
+ final ConfigMap configMap = new ConfigMapBuilder(TEST_CONFIGMAP_NAME)
+ .addLabels(TEST_RESOURCE_LABELS)
+ .configEntry(dataEntryKey, dataEntryValue)
+ .build();
+
+ // assert - verify the built ConfigMap structure
+ Assertions.assertNotNull(configMap, "ConfigMap resource creation failed.");
+ Assertions.assertEquals(TEST_CONFIGMAP_NAME,
+ configMap.getMetadata().getName(),
+ "ConfigMap resource has unexpected name.");
+ Assertions.assertEquals(1,
+ configMap.getData().entrySet().size(),
+ String.format("ConfigMap resource has unexpected data size: %d",
+ configMap.getData().entrySet().size()));
+
+ // safe now
+ final Map.Entry dataEntry = configMap.getData().entrySet().stream().findFirst().get();
+ Assertions.assertEquals(dataEntryKey,
+ dataEntry.getKey(),
+ String.format("ConfigMap resource has unexpected data entry key: %s", dataEntry.getKey()));
+ Assertions.assertEquals(dataEntryValue,
+ dataEntry.getValue(),
+ String.format("ConfigMap resource has unexpected data entry value: %s", dataEntry.getValue()));
+ }
+
+ @Test
+ public void testDeploymentConfigBuilder() {
+ // arrange
+ final DeploymentConfig deploymentConfig = new DeploymentConfigBuilder(TEST_DEPLOYMENT_CONFIG_NAME)
+ .addLabels(TEST_RESOURCE_LABELS)
+ .setReplicas(TEST_DEPLOYMENT_CONFIG_REPLICAS)
+ .onImageChange()
+ .setRecreateStrategy()
+ .build();
+
+ // assert - verify the built DeploymentConfig structure
+ Assertions.assertNotNull(deploymentConfig, "DeploymentConfig resource creation failed.");
+ Assertions.assertEquals(TEST_DEPLOYMENT_CONFIG_NAME,
+ deploymentConfig.getMetadata().getName(),
+ String.format("DeploymentConfig resource has unexpected name: %s.",
+ deploymentConfig.getMetadata().getName()));
+ Assertions.assertEquals(TEST_RESOURCE_LABELS,
+ deploymentConfig.getMetadata().getLabels(),
+ "DeploymentConfig resource has unexpected labels.");
+ Assertions.assertNotNull(deploymentConfig.getSpec(),
+ String.format("DeploymentConfig resource has null \".spec\"", deploymentConfig.getSpec()));
+ Assertions.assertEquals(TEST_DEPLOYMENT_CONFIG_REPLICAS,
+ deploymentConfig.getSpec().getReplicas(),
+ String.format("DeploymentConfig resource has unexpected \".spec.replicas\": %s.",
+ deploymentConfig.getSpec().getReplicas()));
+ Assertions.assertNotNull(deploymentConfig.getSpec().getStrategy(),
+ String.format("DeploymentConfig resource has null \".spec.strategy\"",
+ deploymentConfig.getSpec().getStrategy()));
+ Assertions.assertEquals("Recreate",
+ deploymentConfig.getSpec().getStrategy().getType(),
+ String.format("DeploymentConfig resource has unexpected \".spec.strategy\": %s.",
+ deploymentConfig.getSpec().getStrategy().getType()));
+ Assertions.assertNotNull(deploymentConfig.getSpec().getTemplate(),
+ String.format("DeploymentConfig resource has null \".spec.template\"",
+ deploymentConfig.getSpec().getTemplate()));
+ Assertions.assertNotNull(deploymentConfig.getSpec().getTemplate().getSpec(),
+ String.format("DeploymentConfig resource has null \".spec.template.spec\"",
+ deploymentConfig.getSpec().getTemplate().getSpec()));
+ PodSpec podSpec = deploymentConfig.getSpec().getTemplate().getSpec();
+ Assertions.assertEquals(0,
+ podSpec.getContainers().size(),
+ String.format("DeploymentConfig resource has unexpected \".spec.template.spec.containers\": %s.",
+ podSpec.getContainers().size()));
+ }
+}
diff --git a/core/pom.xml b/core/pom.xml
index 9d1c3b08..fe3ec52d 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -16,11 +16,6 @@
io.fabric8
openshift-client
-
- io.fabric8
- openshift-server-mock
- test
-
org.projectlombok
@@ -77,6 +72,18 @@
test
+
+ org.mockito
+ mockito-core
+ test
+
+
+
+ org.mockito
+ mockito-junit-jupiter
+ test
+
+
org.assertj
assertj-core
diff --git a/core/src/test/java/cz/xtf/core/bm/BinaryBuildMemoryTest.java b/core/src/test/java/cz/xtf/core/bm/BinaryBuildMemoryTest.java
new file mode 100644
index 00000000..d4ba1ca9
--- /dev/null
+++ b/core/src/test/java/cz/xtf/core/bm/BinaryBuildMemoryTest.java
@@ -0,0 +1,187 @@
+package cz.xtf.core.bm;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import cz.xtf.core.config.BuildManagerConfig;
+import cz.xtf.core.config.XTFConfig;
+import io.fabric8.openshift.api.model.BuildConfig;
+
+public class BinaryBuildMemoryTest {
+
+ private static final String TEST_BUILD_ID = "test-binary-build";
+ private static final String TEST_BUILDER_IMAGE = "registry.access.redhat.com/ubi8/openjdk-11:latest";
+
+ @BeforeEach
+ public void cleanSystemProperties() {
+ // Safety net: ensure clean state before each test
+ // Each test also handles its own cleanup in finally blocks
+ System.clearProperty(BuildManagerConfig.MEMORY_REQUEST);
+ System.clearProperty(BuildManagerConfig.MEMORY_LIMIT);
+ XTFConfig.loadConfig();
+ }
+
+ @Test
+ public void testBuildConfig_WhenMemoryLimitsSet_ShouldContainResourceRequirements() throws IOException {
+ // Given: System properties configured for memory request and limit
+ String memoryRequest = "512Mi";
+ String memoryLimit = "2Gi";
+
+ try {
+ // Set properties inside try block to ensure cleanup via finally
+ System.setProperty(BuildManagerConfig.MEMORY_REQUEST, memoryRequest);
+ System.setProperty(BuildManagerConfig.MEMORY_LIMIT, memoryLimit);
+ XTFConfig.loadConfig();
+
+ Path tempFileWithLimits = Files.createTempFile("test-with-limits", ".war");
+ Files.write(tempFileWithLimits, "test content".getBytes());
+
+ BinaryBuildFromFile buildWithLimits = new BinaryBuildFromFile(
+ TEST_BUILDER_IMAGE,
+ tempFileWithLimits,
+ null,
+ TEST_BUILD_ID + "-with-limits");
+
+ // When: Getting the BuildConfig
+ BuildConfig buildConfig = buildWithLimits.bc;
+
+ // Then: BuildConfig should contain resource requirements
+ Assertions.assertNotNull(buildConfig.getSpec().getResources(),
+ "BuildConfig should have resources set when memory limits are configured");
+
+ Assertions.assertNotNull(buildConfig.getSpec().getResources().getRequests(),
+ "BuildConfig should have resource requests");
+ Assertions.assertEquals(memoryRequest,
+ buildConfig.getSpec().getResources().getRequests().get("memory").toString(),
+ "Memory request should match configured value");
+
+ Assertions.assertNotNull(buildConfig.getSpec().getResources().getLimits(),
+ "BuildConfig should have resource limits");
+ Assertions.assertEquals(memoryLimit,
+ buildConfig.getSpec().getResources().getLimits().get("memory").toString(),
+ "Memory limit should match configured value");
+
+ Files.delete(tempFileWithLimits);
+ } finally {
+ // Cleanup always runs, even if property setting or test fails
+ System.clearProperty(BuildManagerConfig.MEMORY_REQUEST);
+ System.clearProperty(BuildManagerConfig.MEMORY_LIMIT);
+ XTFConfig.loadConfig();
+ }
+ }
+
+ @Test
+ public void testBuildConfig_WhenOnlyMemoryRequestSet_ShouldContainOnlyRequest() throws IOException {
+ // Given: System property configured for memory request only
+ String memoryRequest = "256Mi";
+
+ try {
+ // Set properties inside try block to ensure cleanup via finally
+ System.setProperty(BuildManagerConfig.MEMORY_REQUEST, memoryRequest);
+ XTFConfig.loadConfig();
+
+ Path tempFileWithRequest = Files.createTempFile("test-with-request", ".war");
+ Files.write(tempFileWithRequest, "test content".getBytes());
+
+ BinaryBuildFromFile buildWithRequest = new BinaryBuildFromFile(
+ TEST_BUILDER_IMAGE,
+ tempFileWithRequest,
+ null,
+ TEST_BUILD_ID + "-with-request");
+
+ // When: Getting the BuildConfig
+ BuildConfig buildConfig = buildWithRequest.bc;
+
+ // Then: BuildConfig should contain only resource requests
+ Assertions.assertNotNull(buildConfig.getSpec().getResources(),
+ "BuildConfig should have resources set when memory request is configured");
+
+ Assertions.assertNotNull(buildConfig.getSpec().getResources().getRequests(),
+ "BuildConfig should have resource requests");
+ Assertions.assertEquals(memoryRequest,
+ buildConfig.getSpec().getResources().getRequests().get("memory").toString(),
+ "Memory request should match configured value");
+
+ Assertions.assertTrue(buildConfig.getSpec().getResources().getLimits() == null
+ || buildConfig.getSpec().getResources().getLimits().isEmpty(),
+ "BuildConfig should not have limits when only request is set");
+
+ Files.delete(tempFileWithRequest);
+ } finally {
+ // Cleanup always runs, even if property setting or test fails
+ System.clearProperty(BuildManagerConfig.MEMORY_REQUEST);
+ XTFConfig.loadConfig();
+ }
+ }
+
+ @Test
+ public void testBuildConfig_WhenOnlyMemoryLimitSet_ShouldContainOnlyLimit() throws IOException {
+ // Given: System property configured for memory limit only
+ String memoryLimit = "1Gi";
+
+ try {
+ // Set properties inside try block to ensure cleanup via finally
+ System.setProperty(BuildManagerConfig.MEMORY_LIMIT, memoryLimit);
+ XTFConfig.loadConfig();
+
+ Path tempFileWithLimit = Files.createTempFile("test-with-limit", ".war");
+ Files.write(tempFileWithLimit, "test content".getBytes());
+
+ BinaryBuildFromFile buildWithLimit = new BinaryBuildFromFile(
+ TEST_BUILDER_IMAGE,
+ tempFileWithLimit,
+ null,
+ TEST_BUILD_ID + "-with-limit");
+
+ // When: Getting the BuildConfig
+ BuildConfig buildConfig = buildWithLimit.bc;
+
+ // Then: BuildConfig should contain only resource limits
+ Assertions.assertNotNull(buildConfig.getSpec().getResources(),
+ "BuildConfig should have resources set when memory limit is configured");
+
+ Assertions.assertTrue(buildConfig.getSpec().getResources().getRequests() == null
+ || buildConfig.getSpec().getResources().getRequests().isEmpty(),
+ "BuildConfig should not have requests when only limit is set");
+
+ Assertions.assertNotNull(buildConfig.getSpec().getResources().getLimits(),
+ "BuildConfig should have resource limits");
+ Assertions.assertEquals(memoryLimit,
+ buildConfig.getSpec().getResources().getLimits().get("memory").toString(),
+ "Memory limit should match configured value");
+
+ Files.delete(tempFileWithLimit);
+ } finally {
+ // Cleanup always runs, even if property setting or test fails
+ System.clearProperty(BuildManagerConfig.MEMORY_LIMIT);
+ XTFConfig.loadConfig();
+ }
+ }
+
+ @Test
+ public void testBuildConfig_WhenMemoryLimitsNotSet_ShouldNotContainResources() throws IOException {
+ // Given: BinaryBuild without memory configuration
+ // Create a temporary test file for BinaryBuildFromFile
+ Path tempFile = Files.createTempFile("test", ".war");
+ Files.write(tempFile, "test content".getBytes());
+
+ try {
+ // Create BinaryBuild instance
+ BinaryBuildFromFile binaryBuild = new BinaryBuildFromFile(TEST_BUILDER_IMAGE, tempFile, null, TEST_BUILD_ID);
+
+ // When: Getting the BuildConfig
+ BuildConfig buildConfig = binaryBuild.bc;
+
+ // Then: BuildConfig should not contain resource requirements
+ Assertions.assertNull(buildConfig.getSpec().getResources(),
+ "BuildConfig should not have resources when memory limits are not configured");
+ } finally {
+ Files.delete(tempFile);
+ }
+ }
+}
diff --git a/core/src/test/java/cz/xtf/core/bm/BinaryBuildTest.java b/core/src/test/java/cz/xtf/core/bm/BinaryBuildTest.java
index 70536f44..3d6d0bda 100644
--- a/core/src/test/java/cz/xtf/core/bm/BinaryBuildTest.java
+++ b/core/src/test/java/cz/xtf/core/bm/BinaryBuildTest.java
@@ -1,5 +1,10 @@
package cz.xtf.core.bm;
+import static org.mockito.Mockito.lenient;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -8,47 +13,51 @@
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.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
-import cz.xtf.core.config.BuildManagerConfig;
-import cz.xtf.core.config.XTFConfig;
import cz.xtf.core.openshift.OpenShift;
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
+import io.fabric8.kubernetes.client.dsl.MixedOperation;
+import io.fabric8.kubernetes.client.dsl.Resource;
import io.fabric8.openshift.api.model.Build;
import io.fabric8.openshift.api.model.BuildBuilder;
import io.fabric8.openshift.api.model.BuildConfig;
import io.fabric8.openshift.api.model.BuildConfigBuilder;
+import io.fabric8.openshift.api.model.BuildConfigList;
import io.fabric8.openshift.api.model.BuildStatusBuilder;
import io.fabric8.openshift.api.model.ImageStream;
import io.fabric8.openshift.api.model.ImageStreamBuilder;
-import io.fabric8.openshift.client.OpenShiftClient;
-import io.fabric8.openshift.client.server.mock.OpenShiftServer;
+import io.fabric8.openshift.api.model.ImageStreamList;
+import io.fabric8.openshift.client.dsl.BuildConfigResource;
/**
* Tests for BinaryBuild class, specifically testing build status handling.
*/
+@ExtendWith(MockitoExtension.class)
public class BinaryBuildTest {
private static final String TEST_BUILD_ID = "test-binary-build";
private static final String TEST_BUILDER_IMAGE = "registry.access.redhat.com/ubi8/openjdk-11:latest";
- private OpenShiftServer openShiftServer;
+ @Mock
private OpenShift openShift;
+
+ @Mock
+ private MixedOperation> buildConfigOp;
+
+ @Mock
+ private MixedOperation> imageStreamOp;
+
private Path tempFile;
private BinaryBuildFromFile binaryBuild;
@BeforeEach
public void setup() throws IOException {
- // Initialize OpenShift mock server
- this.openShiftServer = new OpenShiftServer(false, true);
- this.openShiftServer.before();
-
- // Create XTF OpenShift client from mocked server
- OpenShiftClient mockedServerClient = openShiftServer.getOpenshiftClient();
- this.openShift = OpenShift.get(
- mockedServerClient.getMasterUrl().toString(),
- mockedServerClient.getNamespace(),
- mockedServerClient.getConfiguration().getUsername(),
- mockedServerClient.getConfiguration().getPassword());
+ // Setup fluent API chains
+ when(openShift.buildConfigs()).thenReturn(buildConfigOp);
+ when(openShift.imageStreams()).thenReturn(imageStreamOp);
// Create a temporary test file for BinaryBuildFromFile
tempFile = Files.createTempFile("test", ".war");
@@ -60,9 +69,6 @@ public void setup() throws IOException {
@AfterEach
public void cleanup() throws IOException {
- if (openShiftServer != null) {
- openShiftServer.after();
- }
if (tempFile != null && Files.exists(tempFile)) {
Files.delete(tempFile);
}
@@ -72,12 +78,14 @@ public void cleanup() throws IOException {
public void testNeedsUpdate_WhenBuildStatusIsError_ShouldReturnTrue() {
// Given: BuildConfig and ImageStream exist with a build in "Error" status
ImageStream imageStream = createImageStream(TEST_BUILD_ID);
- BuildConfig buildConfig = createBuildConfig(TEST_BUILD_ID, 1);
+ BuildConfig buildConfig = createBuildConfigWithContentHash(TEST_BUILD_ID, 1);
Build build = createBuildWithStatus(TEST_BUILD_ID + "-1", "Error");
- openShift.imageStreams().create(imageStream);
- openShift.buildConfigs().create(buildConfig);
- openShift.builds().create(build);
+ setupResourceMocks(buildConfig, imageStream);
+
+ // lenient() needed because getBuild() is only called if previous checks pass (conditional execution),
+ // and Mockito's strict stubbing sees this as potentially unused stubbing
+ lenient().when(openShift.getBuild(TEST_BUILD_ID + "-1")).thenReturn(build);
// When: Checking if build needs update
boolean needsUpdate = binaryBuild.needsUpdate(openShift);
@@ -85,18 +93,22 @@ public void testNeedsUpdate_WhenBuildStatusIsError_ShouldReturnTrue() {
// Then: Should return true because build is in Error status
Assertions.assertTrue(needsUpdate,
"Build with 'Error' status should trigger needsUpdate=true");
+
+ verify(openShift).getBuild(TEST_BUILD_ID + "-1");
}
@Test
public void testNeedsUpdate_WhenBuildStatusIsFailed_ShouldReturnTrue() {
// Given: BuildConfig and ImageStream exist with a build in "Failed" status
ImageStream imageStream = createImageStream(TEST_BUILD_ID);
- BuildConfig buildConfig = createBuildConfig(TEST_BUILD_ID, 1);
+ BuildConfig buildConfig = createBuildConfigWithContentHash(TEST_BUILD_ID, 1);
Build build = createBuildWithStatus(TEST_BUILD_ID + "-1", "Failed");
- openShift.imageStreams().create(imageStream);
- openShift.buildConfigs().create(buildConfig);
- openShift.builds().create(build);
+ setupResourceMocks(buildConfig, imageStream);
+
+ // lenient() needed because getBuild() is only called if previous checks pass (conditional execution),
+ // and Mockito's strict stubbing sees this as potentially unused stubbing
+ lenient().when(openShift.getBuild(TEST_BUILD_ID + "-1")).thenReturn(build);
// When: Checking if build needs update
boolean needsUpdate = binaryBuild.needsUpdate(openShift);
@@ -104,6 +116,8 @@ public void testNeedsUpdate_WhenBuildStatusIsFailed_ShouldReturnTrue() {
// Then: Should return true because build is in Failed status
Assertions.assertTrue(needsUpdate,
"Build with 'Failed' status should trigger needsUpdate=true");
+
+ verify(openShift).getBuild(TEST_BUILD_ID + "-1");
}
@Test
@@ -113,9 +127,11 @@ public void testNeedsUpdate_WhenBuildStatusIsComplete_ShouldReturnFalse() {
BuildConfig buildConfig = createBuildConfigWithContentHash(TEST_BUILD_ID, 1);
Build build = createBuildWithStatus(TEST_BUILD_ID + "-1", "Complete");
- openShift.imageStreams().create(imageStream);
- openShift.buildConfigs().create(buildConfig);
- openShift.builds().create(build);
+ setupResourceMocks(buildConfig, imageStream);
+
+ // lenient() needed because getBuild() is only called if previous checks pass (conditional execution),
+ // and Mockito's strict stubbing sees this as potentially unused stubbing
+ lenient().when(openShift.getBuild(TEST_BUILD_ID + "-1")).thenReturn(build);
// When: Checking if build needs update
boolean needsUpdate = binaryBuild.needsUpdate(openShift);
@@ -123,11 +139,14 @@ public void testNeedsUpdate_WhenBuildStatusIsComplete_ShouldReturnFalse() {
// Then: Should return false because build is successful
Assertions.assertFalse(needsUpdate,
"Build with 'Complete' status should trigger needsUpdate=false");
+
+ verify(openShift).getBuild(TEST_BUILD_ID + "-1");
}
@Test
public void testNeedsUpdate_WhenNoBuildConfigExists_ShouldReturnTrue() {
// Given: No BuildConfig or ImageStream exists
+ setupResourceMocks(null, null);
// When: Checking if build needs update
boolean needsUpdate = binaryBuild.needsUpdate(openShift);
@@ -141,11 +160,11 @@ public void testNeedsUpdate_WhenNoBuildConfigExists_ShouldReturnTrue() {
public void testNeedsUpdate_WhenBuildIsNull_ShouldReturnTrue() {
// Given: BuildConfig exists but no Build
ImageStream imageStream = createImageStream(TEST_BUILD_ID);
- BuildConfig buildConfig = createBuildConfig(TEST_BUILD_ID, 1);
+ BuildConfig buildConfig = createBuildConfigWithContentHash(TEST_BUILD_ID, 1);
- openShift.imageStreams().create(imageStream);
- openShift.buildConfigs().create(buildConfig);
+ setupResourceMocks(buildConfig, imageStream);
// Intentionally not creating the Build
+ lenient().when(openShift.getBuild(TEST_BUILD_ID + "-1")).thenReturn(null);
// When: Checking if build needs update
boolean needsUpdate = binaryBuild.needsUpdate(openShift);
@@ -153,150 +172,8 @@ public void testNeedsUpdate_WhenBuildIsNull_ShouldReturnTrue() {
// Then: Should return true because build doesn't exist
Assertions.assertTrue(needsUpdate,
"Missing Build should trigger needsUpdate=true");
- }
-
- @Test
- public void testBuildConfig_WhenMemoryLimitsSet_ShouldContainResourceRequirements() throws IOException {
- // Given: System properties configured for memory request and limit
- String memoryRequest = "512Mi";
- String memoryLimit = "2Gi";
- System.setProperty(BuildManagerConfig.MEMORY_REQUEST, memoryRequest);
- System.setProperty(BuildManagerConfig.MEMORY_LIMIT, memoryLimit);
- XTFConfig.loadConfig();
-
- try {
- Path tempFileWithLimits = Files.createTempFile("test-with-limits", ".war");
- Files.write(tempFileWithLimits, "test content".getBytes());
-
- BinaryBuildFromFile buildWithLimits = new BinaryBuildFromFile(
- TEST_BUILDER_IMAGE,
- tempFileWithLimits,
- null,
- TEST_BUILD_ID + "-with-limits");
-
- // When: Getting the BuildConfig
- BuildConfig buildConfig = buildWithLimits.bc;
-
- // Then: BuildConfig should contain resource requirements
- Assertions.assertNotNull(buildConfig.getSpec().getResources(),
- "BuildConfig should have resources set when memory limits are configured");
-
- Assertions.assertNotNull(buildConfig.getSpec().getResources().getRequests(),
- "BuildConfig should have resource requests");
- Assertions.assertEquals(memoryRequest,
- buildConfig.getSpec().getResources().getRequests().get("memory").toString(),
- "Memory request should match configured value");
-
- Assertions.assertNotNull(buildConfig.getSpec().getResources().getLimits(),
- "BuildConfig should have resource limits");
- Assertions.assertEquals(memoryLimit,
- buildConfig.getSpec().getResources().getLimits().get("memory").toString(),
- "Memory limit should match configured value");
-
- // Cleanup
- Files.delete(tempFileWithLimits);
- } finally {
- System.clearProperty(BuildManagerConfig.MEMORY_REQUEST);
- System.clearProperty(BuildManagerConfig.MEMORY_LIMIT);
- XTFConfig.loadConfig();
- }
- }
-
- @Test
- public void testBuildConfig_WhenOnlyMemoryRequestSet_ShouldContainOnlyRequest() throws IOException {
- // Given: System property configured for memory request only
- String memoryRequest = "256Mi";
- System.setProperty(BuildManagerConfig.MEMORY_REQUEST, memoryRequest);
- XTFConfig.loadConfig();
-
- try {
- Path tempFileWithRequest = Files.createTempFile("test-with-request", ".war");
- Files.write(tempFileWithRequest, "test content".getBytes());
-
- BinaryBuildFromFile buildWithRequest = new BinaryBuildFromFile(
- TEST_BUILDER_IMAGE,
- tempFileWithRequest,
- null,
- TEST_BUILD_ID + "-with-request");
-
- // When: Getting the BuildConfig
- BuildConfig buildConfig = buildWithRequest.bc;
-
- // Then: BuildConfig should contain only resource requests
- Assertions.assertNotNull(buildConfig.getSpec().getResources(),
- "BuildConfig should have resources set when memory request is configured");
-
- Assertions.assertNotNull(buildConfig.getSpec().getResources().getRequests(),
- "BuildConfig should have resource requests");
- Assertions.assertEquals(memoryRequest,
- buildConfig.getSpec().getResources().getRequests().get("memory").toString(),
- "Memory request should match configured value");
-
- Assertions.assertTrue(buildConfig.getSpec().getResources().getLimits() == null
- || buildConfig.getSpec().getResources().getLimits().isEmpty(),
- "BuildConfig should not have limits when only request is set");
-
- // Cleanup
- Files.delete(tempFileWithRequest);
- } finally {
- System.clearProperty(BuildManagerConfig.MEMORY_REQUEST);
- XTFConfig.loadConfig();
- }
- }
-
- @Test
- public void testBuildConfig_WhenOnlyMemoryLimitSet_ShouldContainOnlyLimit() throws IOException {
- // Given: System property configured for memory limit only
- String memoryLimit = "1Gi";
-
- System.setProperty(BuildManagerConfig.MEMORY_LIMIT, memoryLimit);
- XTFConfig.loadConfig();
-
- try {
- Path tempFileWithLimit = Files.createTempFile("test-with-limit", ".war");
- Files.write(tempFileWithLimit, "test content".getBytes());
-
- BinaryBuildFromFile buildWithLimit = new BinaryBuildFromFile(
- TEST_BUILDER_IMAGE,
- tempFileWithLimit,
- null,
- TEST_BUILD_ID + "-with-limit");
-
- // When: Getting the BuildConfig
- BuildConfig buildConfig = buildWithLimit.bc;
-
- // Then: BuildConfig should contain only resource limits
- Assertions.assertNotNull(buildConfig.getSpec().getResources(),
- "BuildConfig should have resources set when memory limit is configured");
-
- Assertions.assertTrue(buildConfig.getSpec().getResources().getRequests() == null
- || buildConfig.getSpec().getResources().getRequests().isEmpty(),
- "BuildConfig should not have requests when only limit is set");
-
- Assertions.assertNotNull(buildConfig.getSpec().getResources().getLimits(),
- "BuildConfig should have resource limits");
- Assertions.assertEquals(memoryLimit,
- buildConfig.getSpec().getResources().getLimits().get("memory").toString(),
- "Memory limit should match configured value");
-
- // Cleanup
- Files.delete(tempFileWithLimit);
- } finally {
- System.clearProperty(BuildManagerConfig.MEMORY_LIMIT);
- XTFConfig.loadConfig();
- }
- }
-
- @Test
- public void testBuildConfig_WhenMemoryLimitsNotSet_ShouldNotContainResources() {
- // Given: BinaryBuild without memory configuration (current setup in @BeforeEach)
-
- // When: Getting the BuildConfig
- BuildConfig buildConfig = binaryBuild.bc;
- // Then: BuildConfig should not contain resource requirements
- Assertions.assertNull(buildConfig.getSpec().getResources(),
- "BuildConfig should not have resources when memory limits are not configured");
+ verify(openShift).getBuild(TEST_BUILD_ID + "-1");
}
// Helper methods to create test resources
@@ -309,30 +186,6 @@ private ImageStream createImageStream(String name) {
.build();
}
- private BuildConfig createBuildConfig(String name, long lastVersion) {
- return new BuildConfigBuilder()
- .withMetadata(new ObjectMetaBuilder()
- .withName(name)
- .addToLabels("xtf.bm/content-hash", "differenthash")
- .build())
- .withNewSpec()
- .withNewStrategy()
- .withType("Source")
- .withNewSourceStrategy()
- .withForcePull(true)
- .withNewFrom()
- .withKind("DockerImage")
- .withName(TEST_BUILDER_IMAGE)
- .endFrom()
- .endSourceStrategy()
- .endStrategy()
- .endSpec()
- .withNewStatus()
- .withLastVersion(lastVersion)
- .endStatus()
- .build();
- }
-
private BuildConfig createBuildConfigWithContentHash(String name, long lastVersion) {
// Get the actual content hash from the BinaryBuild
String contentHash = binaryBuild.getContentHash();
@@ -370,4 +223,19 @@ private Build createBuildWithStatus(String name, String phase) {
.build())
.build();
}
+
+ private void setupResourceMocks(BuildConfig buildConfig, ImageStream imageStream) {
+ // Mock the fluent API chains properly
+ @SuppressWarnings("unchecked")
+ BuildConfigResource buildConfigResource = mock(BuildConfigResource.class);
+ @SuppressWarnings("unchecked")
+ Resource imageStreamResource = mock(Resource.class);
+
+ // Tell mocks what to return - chain each method call
+ when(buildConfigOp.withName(TEST_BUILD_ID)).thenReturn(buildConfigResource);
+ when(buildConfigResource.get()).thenReturn(buildConfig);
+
+ when(imageStreamOp.withName(TEST_BUILD_ID)).thenReturn(imageStreamResource);
+ when(imageStreamResource.get()).thenReturn(imageStream);
+ }
}
diff --git a/junit5/src/main/java/cz/xtf/junit5/model/DockerImageMetadata.java b/junit5/src/main/java/cz/xtf/junit5/model/DockerImageMetadata.java
index f475f57e..d09c7451 100644
--- a/junit5/src/main/java/cz/xtf/junit5/model/DockerImageMetadata.java
+++ b/junit5/src/main/java/cz/xtf/junit5/model/DockerImageMetadata.java
@@ -18,6 +18,7 @@
import cz.xtf.core.waiting.SimpleWaiter;
import cz.xtf.core.waiting.Waiter;
import cz.xtf.core.waiting.failfast.FailFastCheck;
+import io.fabric8.kubernetes.api.model.GenericKubernetesResource;
import io.fabric8.openshift.api.model.ImageStream;
import io.fabric8.openshift.api.model.ImageStreamTag;
import io.fabric8.openshift.api.model.NamedTagEventList;
@@ -107,14 +108,26 @@ private static DockerImageMetadata getMetadata(OpenShift openShift, Image image)
}
private static DockerImageMetadata getMetadataFromTag(ImageStreamTag imageStreamTag) {
- return areMetadataForImageReady(imageStreamTag)
- ? new DockerImageMetadata((Map) imageStreamTag.getImage().getDockerImageMetadata().getValue())
- : null;
+ if (!areMetadataForImageReady(imageStreamTag)) {
+ return null;
+ }
+
+ Object dockerImageMetadata = imageStreamTag.getImage().getDockerImageMetadata();
+
+ if (!(dockerImageMetadata instanceof GenericKubernetesResource)) {
+ throw new IllegalStateException(String.format(
+ "Fabric8 API compatibility issue: Expected GenericKubernetesResource from " +
+ "Image.getDockerImageMetadata() but got %s. This likely indicates a Fabric8 " +
+ "OpenShift Client version incompatibility.",
+ dockerImageMetadata != null ? dockerImageMetadata.getClass().getName() : "null"));
+ }
+
+ return new DockerImageMetadata(
+ ((GenericKubernetesResource) dockerImageMetadata).getAdditionalProperties());
}
private static boolean areMetadataForImageReady(ImageStreamTag tag) {
- return tag != null && tag.getImage() != null && tag.getImage().getDockerImageMetadata() != null
- && tag.getImage().getDockerImageMetadata().getValue() != null;
+ return tag != null && tag.getImage() != null && tag.getImage().getDockerImageMetadata() != null;
}
private static String randomString() {
diff --git a/pom.xml b/pom.xml
index d5978ff5..43edeb07 100644
--- a/pom.xml
+++ b/pom.xml
@@ -56,12 +56,12 @@
UTF-8
- 1.8
- 1.8
+ 11
+ 11
4.5.13
- 6.14.0
+ 7.4.0
2.15.1
3.11
1.26.0
@@ -76,6 +76,7 @@
5.7.0
5.7.0
2.0.1
+ 5.8.0
3.17.2
1.18.30
2.8.9
@@ -184,6 +185,20 @@
${version.junit5.jupiter.params}
+
+ org.mockito
+ mockito-core
+ ${version.mockito}
+
+
+
+ org.mockito
+ mockito-junit-jupiter
+ ${version.mockito}
+
+
+
+
org.assertj
assertj-core
@@ -222,12 +237,6 @@
${version.guava}
-
- io.fabric8
- openshift-server-mock
- ${version.openshift-client}
-
-
org.eclipse.jgit
org.eclipse.jgit