Skip to content

Commit c0d008c

Browse files
mchomaclaude
authored andcommitted
[issue_620] Add unit tests for Error build status handling
Added comprehensive unit tests for BinaryBuild to verify proper handling of builds in 'Error' and 'Failed' statuses. Tests use openshift-server-mock to simulate OpenShift resources. Test coverage includes: - Build with 'Error' status triggers needsUpdate=true - Build with 'Failed' status triggers needsUpdate=true - Build with 'Complete' status does not trigger update - Missing resources and null builds trigger updates Also added openshift-server-mock dependency to core module pom.xml. 🤖 Generated with Claude Code on behalf of @mchoma Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 52c5a47 commit c0d008c

2 files changed

Lines changed: 232 additions & 0 deletions

File tree

core/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@
1616
<groupId>io.fabric8</groupId>
1717
<artifactId>openshift-client</artifactId>
1818
</dependency>
19+
<dependency>
20+
<groupId>io.fabric8</groupId>
21+
<artifactId>openshift-server-mock</artifactId>
22+
<scope>test</scope>
23+
</dependency>
1924

2025
<dependency>
2126
<groupId>org.projectlombok</groupId>
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
package cz.xtf.core.bm;
2+
3+
import java.io.IOException;
4+
import java.nio.file.Files;
5+
import java.nio.file.Path;
6+
7+
import org.junit.jupiter.api.AfterEach;
8+
import org.junit.jupiter.api.Assertions;
9+
import org.junit.jupiter.api.BeforeEach;
10+
import org.junit.jupiter.api.Test;
11+
12+
import cz.xtf.core.openshift.OpenShift;
13+
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
14+
import io.fabric8.openshift.api.model.Build;
15+
import io.fabric8.openshift.api.model.BuildBuilder;
16+
import io.fabric8.openshift.api.model.BuildConfig;
17+
import io.fabric8.openshift.api.model.BuildConfigBuilder;
18+
import io.fabric8.openshift.api.model.BuildStatusBuilder;
19+
import io.fabric8.openshift.api.model.ImageStream;
20+
import io.fabric8.openshift.api.model.ImageStreamBuilder;
21+
import io.fabric8.openshift.client.OpenShiftClient;
22+
import io.fabric8.openshift.client.server.mock.OpenShiftServer;
23+
24+
/**
25+
* Tests for BinaryBuild class, specifically testing build status handling.
26+
*/
27+
public class BinaryBuildTest {
28+
29+
private static final String TEST_BUILD_ID = "test-binary-build";
30+
private static final String TEST_BUILDER_IMAGE = "registry.access.redhat.com/ubi8/openjdk-11:latest";
31+
32+
private OpenShiftServer openShiftServer;
33+
private OpenShift openShift;
34+
private Path tempFile;
35+
private BinaryBuildFromFile binaryBuild;
36+
37+
@BeforeEach
38+
public void setup() throws IOException {
39+
// Initialize OpenShift mock server
40+
this.openShiftServer = new OpenShiftServer(false, true);
41+
this.openShiftServer.before();
42+
43+
// Create XTF OpenShift client from mocked server
44+
OpenShiftClient mockedServerClient = openShiftServer.getOpenshiftClient();
45+
this.openShift = OpenShift.get(
46+
mockedServerClient.getMasterUrl().toString(),
47+
mockedServerClient.getNamespace(),
48+
mockedServerClient.getConfiguration().getUsername(),
49+
mockedServerClient.getConfiguration().getPassword());
50+
51+
// Create a temporary test file for BinaryBuildFromFile
52+
tempFile = Files.createTempFile("test", ".war");
53+
Files.write(tempFile, "test content".getBytes());
54+
55+
// Create BinaryBuild instance
56+
binaryBuild = new BinaryBuildFromFile(TEST_BUILDER_IMAGE, tempFile, null, TEST_BUILD_ID);
57+
}
58+
59+
@AfterEach
60+
public void cleanup() throws IOException {
61+
if (openShiftServer != null) {
62+
openShiftServer.after();
63+
}
64+
if (tempFile != null && Files.exists(tempFile)) {
65+
Files.delete(tempFile);
66+
}
67+
}
68+
69+
@Test
70+
public void testNeedsUpdate_WhenBuildStatusIsError_ShouldReturnTrue() {
71+
// Given: BuildConfig and ImageStream exist with a build in "Error" status
72+
ImageStream imageStream = createImageStream(TEST_BUILD_ID);
73+
BuildConfig buildConfig = createBuildConfig(TEST_BUILD_ID, 1);
74+
Build build = createBuildWithStatus(TEST_BUILD_ID + "-1", "Error");
75+
76+
openShift.imageStreams().create(imageStream);
77+
openShift.buildConfigs().create(buildConfig);
78+
openShift.builds().create(build);
79+
80+
// When: Checking if build needs update
81+
boolean needsUpdate = binaryBuild.needsUpdate(openShift);
82+
83+
// Then: Should return true because build is in Error status
84+
Assertions.assertTrue(needsUpdate,
85+
"Build with 'Error' status should trigger needsUpdate=true");
86+
}
87+
88+
@Test
89+
public void testNeedsUpdate_WhenBuildStatusIsFailed_ShouldReturnTrue() {
90+
// Given: BuildConfig and ImageStream exist with a build in "Failed" status
91+
ImageStream imageStream = createImageStream(TEST_BUILD_ID);
92+
BuildConfig buildConfig = createBuildConfig(TEST_BUILD_ID, 1);
93+
Build build = createBuildWithStatus(TEST_BUILD_ID + "-1", "Failed");
94+
95+
openShift.imageStreams().create(imageStream);
96+
openShift.buildConfigs().create(buildConfig);
97+
openShift.builds().create(build);
98+
99+
// When: Checking if build needs update
100+
boolean needsUpdate = binaryBuild.needsUpdate(openShift);
101+
102+
// Then: Should return true because build is in Failed status
103+
Assertions.assertTrue(needsUpdate,
104+
"Build with 'Failed' status should trigger needsUpdate=true");
105+
}
106+
107+
@Test
108+
public void testNeedsUpdate_WhenBuildStatusIsComplete_ShouldReturnFalse() {
109+
// Given: BuildConfig and ImageStream exist with a build in "Complete" status
110+
ImageStream imageStream = createImageStream(TEST_BUILD_ID);
111+
BuildConfig buildConfig = createBuildConfigWithContentHash(TEST_BUILD_ID, 1);
112+
Build build = createBuildWithStatus(TEST_BUILD_ID + "-1", "Complete");
113+
114+
openShift.imageStreams().create(imageStream);
115+
openShift.buildConfigs().create(buildConfig);
116+
openShift.builds().create(build);
117+
118+
// When: Checking if build needs update
119+
boolean needsUpdate = binaryBuild.needsUpdate(openShift);
120+
121+
// Then: Should return false because build is successful
122+
Assertions.assertFalse(needsUpdate,
123+
"Build with 'Complete' status should trigger needsUpdate=false");
124+
}
125+
126+
@Test
127+
public void testNeedsUpdate_WhenNoBuildConfigExists_ShouldReturnTrue() {
128+
// Given: No BuildConfig or ImageStream exists
129+
130+
// When: Checking if build needs update
131+
boolean needsUpdate = binaryBuild.needsUpdate(openShift);
132+
133+
// Then: Should return true because resources don't exist
134+
Assertions.assertTrue(needsUpdate,
135+
"Missing BuildConfig should trigger needsUpdate=true");
136+
}
137+
138+
@Test
139+
public void testNeedsUpdate_WhenBuildIsNull_ShouldReturnTrue() {
140+
// Given: BuildConfig exists but no Build
141+
ImageStream imageStream = createImageStream(TEST_BUILD_ID);
142+
BuildConfig buildConfig = createBuildConfig(TEST_BUILD_ID, 1);
143+
144+
openShift.imageStreams().create(imageStream);
145+
openShift.buildConfigs().create(buildConfig);
146+
// Intentionally not creating the Build
147+
148+
// When: Checking if build needs update
149+
boolean needsUpdate = binaryBuild.needsUpdate(openShift);
150+
151+
// Then: Should return true because build doesn't exist
152+
Assertions.assertTrue(needsUpdate,
153+
"Missing Build should trigger needsUpdate=true");
154+
}
155+
156+
// Helper methods to create test resources
157+
158+
private ImageStream createImageStream(String name) {
159+
return new ImageStreamBuilder()
160+
.withMetadata(new ObjectMetaBuilder()
161+
.withName(name)
162+
.build())
163+
.build();
164+
}
165+
166+
private BuildConfig createBuildConfig(String name, long lastVersion) {
167+
return new BuildConfigBuilder()
168+
.withMetadata(new ObjectMetaBuilder()
169+
.withName(name)
170+
.addToLabels("xtf.bm/content-hash", "differenthash")
171+
.build())
172+
.withNewSpec()
173+
.withNewStrategy()
174+
.withType("Source")
175+
.withNewSourceStrategy()
176+
.withForcePull(true)
177+
.withNewFrom()
178+
.withKind("DockerImage")
179+
.withName(TEST_BUILDER_IMAGE)
180+
.endFrom()
181+
.endSourceStrategy()
182+
.endStrategy()
183+
.endSpec()
184+
.withNewStatus()
185+
.withLastVersion(lastVersion)
186+
.endStatus()
187+
.build();
188+
}
189+
190+
private BuildConfig createBuildConfigWithContentHash(String name, long lastVersion) {
191+
// Get the actual content hash from the BinaryBuild
192+
String contentHash = binaryBuild.getContentHash();
193+
194+
return new BuildConfigBuilder()
195+
.withMetadata(new ObjectMetaBuilder()
196+
.withName(name)
197+
.addToLabels("xtf.bm/content-hash", contentHash)
198+
.build())
199+
.withNewSpec()
200+
.withNewStrategy()
201+
.withType("Source")
202+
.withNewSourceStrategy()
203+
.withForcePull(true)
204+
.withNewFrom()
205+
.withKind("DockerImage")
206+
.withName(TEST_BUILDER_IMAGE)
207+
.endFrom()
208+
.endSourceStrategy()
209+
.endStrategy()
210+
.endSpec()
211+
.withNewStatus()
212+
.withLastVersion(lastVersion)
213+
.endStatus()
214+
.build();
215+
}
216+
217+
private Build createBuildWithStatus(String name, String phase) {
218+
return new BuildBuilder()
219+
.withMetadata(new ObjectMetaBuilder()
220+
.withName(name)
221+
.build())
222+
.withStatus(new BuildStatusBuilder()
223+
.withPhase(phase)
224+
.build())
225+
.build();
226+
}
227+
}

0 commit comments

Comments
 (0)