Skip to content

Commit

Permalink
fix: Add fail-fast when node sharing is enabled in SolverConfig inste…
Browse files Browse the repository at this point in the history
…ad of application.properties (TimefoldAI#766)
  • Loading branch information
Christopher-Chianelli authored Apr 2, 2024
1 parent bc2d5a2 commit 6da1776
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ SolverConfigBuildItem recordAndRegisterBuildTimeBeans(CombinedIndexBuildItem com

// Step 2 - validate all SolverConfig definitions
assertNoMemberAnnotationWithoutClassAnnotation(indexView);
assertNodeSharingDisabled(solverConfigMap);
assertSolverConfigSolutionClasses(indexView, solverConfigMap);
assertSolverConfigEntityClasses(indexView);
assertSolverConfigConstraintClasses(indexView, solverConfigMap);
Expand Down Expand Up @@ -330,6 +331,22 @@ Some solver configs (%s) don't specify a %s class, yet there are multiple availa
assertTargetClasses(targetList, DotNames.PLANNING_SOLUTION);
}

private void assertNodeSharingDisabled(Map<String, SolverConfig> solverConfigMap) {
for (var entry : solverConfigMap.entrySet()) {
var solverConfig = entry.getValue();
if (solverConfig.getScoreDirectorFactoryConfig() != null &&
Boolean.TRUE
.equals(solverConfig.getScoreDirectorFactoryConfig().getConstraintStreamAutomaticNodeSharing())) {
throw new IllegalStateException("""
SolverConfig %s enabled automatic node sharing via SolverConfig, which is not allowed.
Enable automatic node sharing with the property %s instead."""
.formatted(
entry.getKey(),
"quarkus.timefold.solver.constraint-stream-automatic-node-sharing=true"));
}
}
}

private void assertSolverConfigEntityClasses(IndexView indexView) {
// No entity classes
assertEmptyInstances(indexView, DotNames.PLANNING_ENTITY);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package ai.timefold.solver.quarkus;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.fail;

import ai.timefold.solver.quarkus.testdata.normal.constraints.TestdataQuarkusConstraintProvider;
import ai.timefold.solver.quarkus.testdata.normal.domain.TestdataQuarkusEntity;
import ai.timefold.solver.quarkus.testdata.normal.domain.TestdataQuarkusSolution;

import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;

public class TimefoldProcessorNodeSharingFailFastTest {

@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.overrideConfigKey("quarkus.timefold.solver-config-xml",
"ai/timefold/solver/quarkus/solverConfigWithNodeSharing.xml")
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
.addClasses(TestdataQuarkusEntity.class,
TestdataQuarkusSolution.class, TestdataQuarkusConstraintProvider.class)
.addAsResource("ai/timefold/solver/quarkus/solverConfigWithNodeSharing.xml"))
.assertException(exception -> {
assertThat(exception).isInstanceOf(IllegalStateException.class)
.hasMessageContainingAll(
"enabled automatic node sharing via SolverConfig, which is not allowed.",
"Enable automatic node sharing with the property",
"quarkus.timefold.solver.constraint-stream-automatic-node-sharing=true");
});

@Test
void test() {
fail("Should not call this method.");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<solver xmlns="https://timefold.ai/xsd/solver" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://timefold.ai/xsd/solver https://timefold.ai/xsd/solver/solver.xsd">
<scoreDirectorFactory>
<constraintStreamAutomaticNodeSharing>true</constraintStreamAutomaticNodeSharing>
</scoreDirectorFactory>
</solver>

0 comments on commit 6da1776

Please sign in to comment.