Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions core/src/main/java/cz/xtf/core/bm/BinaryBuild.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.util.Map;
import java.util.concurrent.TimeUnit;

import cz.xtf.core.config.BuildManagerConfig;
import cz.xtf.core.config.WaitingConfig;
import cz.xtf.core.openshift.OpenShift;
import cz.xtf.core.waiting.SimpleWaiter;
Expand All @@ -16,6 +17,8 @@
import io.fabric8.kubernetes.api.model.EnvVarBuilder;
import io.fabric8.kubernetes.api.model.ObjectMeta;
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
import io.fabric8.kubernetes.api.model.Quantity;
import io.fabric8.kubernetes.api.model.ResourceRequirementsBuilder;
import io.fabric8.openshift.api.model.Build;
import io.fabric8.openshift.api.model.BuildConfig;
import io.fabric8.openshift.api.model.BuildConfigBuilder;
Expand All @@ -36,17 +39,26 @@ public abstract class BinaryBuild implements ManagedBuild {

private final String builderImage;
private final Map<String, String> envProperties;
private final String memoryRequest;
private final String memoryLimit;

protected final ImageStream is;
protected final BuildConfig bc;

protected String contentHash = null;

public BinaryBuild(String builderImage, Path path, Map<String, String> envProperties, String id) {
this(builderImage, path, envProperties, id, BuildManagerConfig.memoryRequest(), BuildManagerConfig.memoryLimit());
}

public BinaryBuild(String builderImage, Path path, Map<String, String> envProperties, String id, String memoryRequest,
String memoryLimit) {
this.builderImage = builderImage;
this.path = path;
this.envProperties = envProperties;
this.id = id;
this.memoryRequest = memoryRequest;
this.memoryLimit = memoryLimit;

this.is = this.createIsDefinition();
this.bc = this.createBcDefinition();
Expand Down Expand Up @@ -197,6 +209,18 @@ private BuildConfig createBcDefinition() {

configureBuildStrategy(bcBuilder, builderImage, envVarList);

// Add resource requirements if specified
if (memoryRequest != null || memoryLimit != null) {
ResourceRequirementsBuilder rrb = new ResourceRequirementsBuilder();
if (memoryRequest != null) {
rrb.withRequests(Collections.singletonMap("memory", new Quantity(memoryRequest)));
}
if (memoryLimit != null) {
rrb.withLimits(Collections.singletonMap("memory", new Quantity(memoryLimit)));
}
bcBuilder.withResources(rrb.build());
}

return new BuildConfigBuilder().withMetadata(metadata).withSpec(bcBuilder.build()).build();
}
}
5 changes: 5 additions & 0 deletions core/src/main/java/cz/xtf/core/bm/BinaryBuildFromSources.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ public BinaryBuildFromSources(String builderImage, Path path, Map<String, String
super(builderImage, path, envProperties, id);
}

public BinaryBuildFromSources(String builderImage, Path path, Map<String, String> envProperties, String id,
String memoryRequest, String memoryLimit) {
super(builderImage, path, envProperties, id, memoryRequest, memoryLimit);
}

@Override
public void build(OpenShift openShift) {
openShift.imageStreams().create(is);
Expand Down
20 changes: 20 additions & 0 deletions core/src/main/java/cz/xtf/core/config/BuildManagerConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ public class BuildManagerConfig {
public static final String FORCE_REBUILD = "xtf.bm.force_rebuild";
public static final String SKIP_REBUILD = "xtf.bm.skip_rebuild";
public static final String MAX_RUNNING_BUILDS = "xtf.bm.max_running_builds";
public static final String MEMORY_REQUEST = "xtf.bm.memory.request";
public static final String MEMORY_LIMIT = "xtf.bm.memory.limit";

public static String namespace() {
return XTFConfig.get(BUILD_NAMESPACE, "xtf-builds");
Expand All @@ -21,4 +23,22 @@ public static boolean skipRebuild() {
public static int maxRunningBuilds() {
return Integer.valueOf(XTFConfig.get(MAX_RUNNING_BUILDS, "5"));
}

/**
* Memory request for builds (e.g., "2Gi", "512Mi")
*
* @return memory request string or null if not configured
*/
public static String memoryRequest() {
return XTFConfig.get(MEMORY_REQUEST);
}

/**
* Memory limit for builds (e.g., "4Gi", "1Gi")
*
* @return memory limit string or null if not configured
*/
public static String memoryLimit() {
return XTFConfig.get(MEMORY_LIMIT);
}
}
146 changes: 146 additions & 0 deletions core/src/test/java/cz/xtf/core/bm/BinaryBuildTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
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 cz.xtf.core.openshift.OpenShift;
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
import io.fabric8.openshift.api.model.Build;
Expand Down Expand Up @@ -153,6 +155,150 @@ public void testNeedsUpdate_WhenBuildIsNull_ShouldReturnTrue() {
"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");
}

// Helper methods to create test resources

private ImageStream createImageStream(String name) {
Expand Down