rpuch commented on code in PR #7727:
URL: https://github.com/apache/ignite-3/pull/7727#discussion_r2903416786


##########
modules/client/src/test/java/org/apache/ignite/client/ClientAuthenticationTest.java:
##########
@@ -111,15 +112,7 @@ private TestServer startServer(boolean basicAuthn) {
                 null);
 
         if (basicAuthn) {
-            securityConfiguration.change(securityChange -> {
-                securityChange.changeEnabled(true);
-                
securityChange.changeAuthentication().changeProviders().create("basic", change 
->
-                        change.convert(BasicAuthenticationProviderChange.class)
-                                .changeUsers(users -> users.create("usr", user 
->
-                                        user.changePassword("pwd"))
-                                )
-                );
-            }).join();
+            securityConfiguration.change(securityChange -> 
securityChange.changeEnabled(true)).join();

Review Comment:
   Let's use `willCompleteSuccessfully()` as usual



##########
modules/low-watermark/src/test/java/org/apache/ignite/internal/lowwatermark/LowWatermarkImplTest.java:
##########
@@ -86,7 +86,7 @@
 /** For {@link LowWatermarkImpl} testing. */
 @ExtendWith(ConfigurationExtension.class)
 public class LowWatermarkImplTest extends BaseIgniteAbstractTest {
-    @InjectConfiguration
+    @InjectConfiguration(validate = false)

Review Comment:
   Why?



##########
modules/configuration/src/test/java/org/apache/ignite/internal/configuration/testframework/ConfigurationExtensionTest.java:
##########
@@ -140,4 +144,108 @@ public void testInjectInternalId(
     ) {
         assertNotNull(((ExtendedDiscoveryConfiguration) 
discoveryConfig).id().value());
     }
+
+    /** Tests that changing a value to one within the valid range succeeds. */
+    @Test
+    public void rangeValidationAcceptsValidChange(@InjectConfiguration 
ValidatedConfiguration cfg) {
+        assertThat(cfg.change(c -> c.changeRangeValue(80)), 
willCompleteSuccessfully());
+
+        assertEquals(80, cfg.rangeValue().value());
+    }
+
+    /** Tests that changing a value to one outside the valid range throws 
{@link ConfigurationValidationException}. */
+    @Test
+    public void rangeValidationRejectsInvalidChange(@InjectConfiguration 
ValidatedConfiguration cfg) {
+        assertThat(cfg.change(c -> c.changeRangeValue(0)), 
willThrowFast(ConfigurationValidationException.class));
+    }
+
+    /** Tests that changing an {@code @Immutable} field throws {@link 
ConfigurationValidationException}. */
+    @Test
+    public void immutableValidationRejectsChange(@InjectConfiguration 
ValidatedConfiguration cfg) {
+        assertThat(cfg.change(c -> c.changeConstValue("changed")), 
willThrowFast(ConfigurationValidationException.class));
+    }
+
+    /** Tests that a failed validation does not mutate the configuration 
value. */
+    @Test
+    public void failedValidationLeavesValueUnchanged(@InjectConfiguration 
ValidatedConfiguration cfg) {
+        assertThat(cfg.change(c -> c.changeRangeValue(0)), 
willThrowFast(ConfigurationValidationException.class));
+
+        assertEquals(50, cfg.rangeValue().value());
+    }
+
+    /** Tests that all violated constraints are collected and reported 
together. */
+    @Test
+    public void multipleValidationIssuesAreReported(@InjectConfiguration 
ValidatedConfiguration cfg) {
+        CompletableFuture<Void> future = cfg.change(c -> 
c.changeRangeValue(0).changeConstValue("changed"));
+
+        assertThat(future, 
willThrowFast(ConfigurationValidationException.class));
+
+        ExecutionException ex = assertThrows(ExecutionException.class, 
future::get);
+        assertEquals(2, ((ConfigurationValidationException) 
ex.getCause()).getIssues().size());

Review Comment:
   Let's use assertThat(..., hasSize(2))



##########
modules/configuration/src/testFixtures/java/org/apache/ignite/internal/configuration/testframework/ConfigurationExtension.java:
##########
@@ -86,35 +99,28 @@ public class ConfigurationExtension implements 
BeforeEachCallback, AfterEachCall
     /** Key to store {@link ExecutorService} in {@link 
ExtensionContext.Store}. */
     private static final Object POOL_KEY = new Object();
 
-    private static final List<ConfigurationModule> LOCAL_MODULES = new 
ArrayList<>();
-    private static final List<ConfigurationModule> DISTRIBUTED_MODULES = new 
ArrayList<>();
+    private static final ConfigurationModule LOCAL_MODULE;
 
-    /** All {@link ConfigurationExtension} classes in classpath. */
-    private static final List<Class<?>> EXTENSIONS;
-
-    /** All {@link PolymorphicConfigInstance} classes in classpath. */
-    private static final List<Class<?>> POLYMORPHIC_EXTENSIONS;
+    private static final ConfigurationModule DISTRIBUTED_MODULE;
 
     static {
         // Automatically find all @InternalConfiguration and 
@PolymorphicConfigInstance classes
         // to avoid configuring extensions manually in every test.
         ServiceLoader<ConfigurationModule> modules = 
ServiceLoader.load(ConfigurationModule.class);
 
-        List<Class<?>> extensions = new ArrayList<>();
-        List<Class<?>> polymorphicExtensions = new ArrayList<>();
+        List<ConfigurationModule> localModules = new ArrayList<>();
+        List<ConfigurationModule> distributedModules = new ArrayList<>();
 
         modules.forEach(configurationModule -> {
-            extensions.addAll(configurationModule.schemaExtensions());
-            
polymorphicExtensions.addAll(configurationModule.polymorphicSchemaExtensions());
             if (configurationModule.type() == LOCAL) {
-                LOCAL_MODULES.add(configurationModule);
+                localModules.add(configurationModule);
             } else {
-                DISTRIBUTED_MODULES.add(configurationModule);
+                distributedModules.add(configurationModule);
             }
         });
 
-        EXTENSIONS = List.copyOf(extensions);
-        POLYMORPHIC_EXTENSIONS = List.copyOf(polymorphicExtensions);
+        LOCAL_MODULE = new CompoundModule(LOCAL, localModules);

Review Comment:
   This class seems to duplicate a lot of code/logic from the production 
counterpart. Should that logic be extracted and used both in the extension and 
production code? The extension looks way too long and complex for 'if there is 
an injection annotation, spin up the configuration harness, obtain config 
object and inject it'



##########
modules/configuration/src/test/java/org/apache/ignite/internal/configuration/testframework/ConfigurationExtensionTest.java:
##########
@@ -140,4 +144,108 @@ public void testInjectInternalId(
     ) {
         assertNotNull(((ExtendedDiscoveryConfiguration) 
discoveryConfig).id().value());
     }
+
+    /** Tests that changing a value to one within the valid range succeeds. */
+    @Test
+    public void rangeValidationAcceptsValidChange(@InjectConfiguration 
ValidatedConfiguration cfg) {
+        assertThat(cfg.change(c -> c.changeRangeValue(80)), 
willCompleteSuccessfully());
+
+        assertEquals(80, cfg.rangeValue().value());
+    }
+
+    /** Tests that changing a value to one outside the valid range throws 
{@link ConfigurationValidationException}. */
+    @Test
+    public void rangeValidationRejectsInvalidChange(@InjectConfiguration 
ValidatedConfiguration cfg) {
+        assertThat(cfg.change(c -> c.changeRangeValue(0)), 
willThrowFast(ConfigurationValidationException.class));
+    }
+
+    /** Tests that changing an {@code @Immutable} field throws {@link 
ConfigurationValidationException}. */
+    @Test
+    public void immutableValidationRejectsChange(@InjectConfiguration 
ValidatedConfiguration cfg) {
+        assertThat(cfg.change(c -> c.changeConstValue("changed")), 
willThrowFast(ConfigurationValidationException.class));
+    }
+
+    /** Tests that a failed validation does not mutate the configuration 
value. */
+    @Test
+    public void failedValidationLeavesValueUnchanged(@InjectConfiguration 
ValidatedConfiguration cfg) {
+        assertThat(cfg.change(c -> c.changeRangeValue(0)), 
willThrowFast(ConfigurationValidationException.class));
+
+        assertEquals(50, cfg.rangeValue().value());
+    }
+
+    /** Tests that all violated constraints are collected and reported 
together. */
+    @Test
+    public void multipleValidationIssuesAreReported(@InjectConfiguration 
ValidatedConfiguration cfg) {
+        CompletableFuture<Void> future = cfg.change(c -> 
c.changeRangeValue(0).changeConstValue("changed"));
+
+        assertThat(future, 
willThrowFast(ConfigurationValidationException.class));
+
+        ExecutionException ex = assertThrows(ExecutionException.class, 
future::get);
+        assertEquals(2, ((ConfigurationValidationException) 
ex.getCause()).getIssues().size());
+    }
+
+    /**
+     * Tests that initial configuration values are validated at injection 
time, and that a value
+     * violating a constraint causes {@link ConfigurationValidationException} 
to be thrown.
+     */
+    @Test
+    public void initialValidationRejectsInvalidValue() {
+        assertExecutesWithFailure(
+                InvalidInitialValueTest.class,
+                new Condition<>(
+                        t -> ExceptionUtils.hasCause(t, 
ConfigurationValidationException.class),
+                        "ConfigurationValidationException"
+                )
+        );
+    }
+
+    /**
+     * Tests that {@code @Value(hasDefault = true)} schema defaults are 
applied when no explicit HOCON values
+     * are provided, and that those defaults satisfy their own constraints.

Review Comment:
   How is the part about 'satisfying their own constraints' tested?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to