This is an automated email from the ASF dual-hosted git repository.
apolovtsev pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push:
new 15ae1059e18 IGNITE-28091 Validate configuration in
ConfigurationExtension (#7727)
15ae1059e18 is described below
commit 15ae1059e18c48cee28bb17a5316ad1eaab00e2e
Author: Alexander Polovtcev <[email protected]>
AuthorDate: Mon Mar 9 13:01:26 2026 +0200
IGNITE-28091 Validate configuration in ConfigurationExtension (#7727)
---
.../ignite/client/handler/ItClientHandlerTest.java | 3 +-
.../ignite/client/ClientAuthenticationTest.java | 19 +--
modules/configuration/build.gradle | 8 ++
.../internal/configuration/CompoundModule.java | 0
.../testframework/ConfigurationExtensionTest.java | 156 +++++++++++++++++++--
.../InvalidDefaultConfigurationSchema.java} | 8 +-
.../MissingDefaultConfigurationSchema.java} | 7 +-
.../ValidatedConfigurationSchema.java} | 13 +-
.../testframework/BasicConfigurationSchema.java | 4 +-
.../testframework/ConfigurationExtension.java | 151 ++++++++++++++------
.../testframework/InjectConfiguration.java | 34 +++--
.../testframework/JunitExtensionTestUtils.java | 6 +-
.../eventlog/impl/ItEventLogConfigurationTest.java | 3 +-
.../ConfigurationBasedChannelRegistryTest.java | 3 +-
.../impl/ConfigurationBasedSinkRegistryTest.java | 3 +-
.../ignite/internal/eventlog/impl/LogSinkTest.java | 3 +-
.../internal/eventlog/impl/WebhookSinkTest.java | 6 +-
.../lowwatermark/LowWatermarkImplTest.java | 2 +-
.../exporters/otlp/OtlpPushMetricExporterTest.java | 6 +-
.../ignite/internal/metrics/MetricManagerTest.java | 6 +-
.../metrics/exporters/jmx/JmxExporterTest.java | 3 +-
.../metrics/exporters/log/LogPushExporterTest.java | 5 +-
.../PlacementDriverManagerTest.java | 2 +-
.../placementdriver/LeaseNegotiationTest.java | 2 +-
.../internal/placementdriver/LeaseUpdaterTest.java | 2 +-
.../segstore/RaftLogGarbageCollectorTest.java | 2 +-
.../segstore/SegmentFileManagerGetEntryTest.java | 2 +-
.../storage/segstore/SegmentFileManagerTest.java | 2 +-
.../SegstoreLogStorageConcurrencyTest.java | 2 +-
.../ignite/internal/rest/RestComponentTest.java | 3 +-
.../SecurityConfigurationModule.java | 6 +-
.../AuthenticationProvidersValidatorImplTest.java | 7 +-
32 files changed, 363 insertions(+), 116 deletions(-)
diff --git
a/modules/client-handler/src/integrationTest/java/org/apache/ignite/client/handler/ItClientHandlerTest.java
b/modules/client-handler/src/integrationTest/java/org/apache/ignite/client/handler/ItClientHandlerTest.java
index 943ceb20877..1d8a197991c 100644
---
a/modules/client-handler/src/integrationTest/java/org/apache/ignite/client/handler/ItClientHandlerTest.java
+++
b/modules/client-handler/src/integrationTest/java/org/apache/ignite/client/handler/ItClientHandlerTest.java
@@ -19,6 +19,7 @@ package org.apache.ignite.client.handler;
import static org.apache.ignite.client.handler.ItClientHandlerTestUtils.MAGIC;
import static
org.apache.ignite.configuration.annotation.ConfigurationType.DISTRIBUTED;
+import static
org.apache.ignite.internal.security.authentication.SecurityConfigurationModule.DEFAULT_PROVIDER_NAME;
import static
org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willCompleteSuccessfully;
import static
org.apache.ignite.lang.ErrorGroups.Authentication.INVALID_CREDENTIALS_ERR;
import static
org.apache.ignite.lang.ErrorGroups.Authentication.UNSUPPORTED_AUTHENTICATION_TYPE_ERR;
@@ -592,7 +593,7 @@ public class ItClientHandlerTest extends
BaseIgniteAbstractTest {
private void setupAuthentication(String username, String password) {
securityConfiguration.change(change -> {
change.changeEnabled(true);
- change.changeAuthentication().changeProviders().create("basic",
authenticationProviderChange -> {
+
change.changeAuthentication().changeProviders().update(DEFAULT_PROVIDER_NAME,
authenticationProviderChange -> {
authenticationProviderChange.convert(BasicAuthenticationProviderChange.class)
.changeUsers(users -> users.create(username, user ->
user.changePassword(password)));
});
diff --git
a/modules/client/src/test/java/org/apache/ignite/client/ClientAuthenticationTest.java
b/modules/client/src/test/java/org/apache/ignite/client/ClientAuthenticationTest.java
index cca0f44ae48..96704bffb46 100644
---
a/modules/client/src/test/java/org/apache/ignite/client/ClientAuthenticationTest.java
+++
b/modules/client/src/test/java/org/apache/ignite/client/ClientAuthenticationTest.java
@@ -18,14 +18,17 @@
package org.apache.ignite.client;
import static
org.apache.ignite.configuration.annotation.ConfigurationType.DISTRIBUTED;
+import static
org.apache.ignite.internal.security.authentication.SecurityConfigurationModule.DEFAULT_PASSWORD;
+import static
org.apache.ignite.internal.security.authentication.SecurityConfigurationModule.DEFAULT_USERNAME;
+import static
org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willCompleteSuccessfully;
import static org.apache.ignite.internal.util.IgniteUtils.closeAll;
+import static org.hamcrest.MatcherAssert.assertThat;
import java.util.UUID;
import org.apache.ignite.client.fakes.FakeIgnite;
import org.apache.ignite.internal.configuration.ClusterConfiguration;
import
org.apache.ignite.internal.configuration.testframework.ConfigurationExtension;
import
org.apache.ignite.internal.configuration.testframework.InjectConfiguration;
-import
org.apache.ignite.internal.security.authentication.basic.BasicAuthenticationProviderChange;
import org.apache.ignite.internal.security.configuration.SecurityConfiguration;
import
org.apache.ignite.internal.security.configuration.SecurityExtensionConfiguration;
import org.apache.ignite.internal.testframework.BaseIgniteAbstractTest;
@@ -85,9 +88,9 @@ public class ClientAuthenticationTest extends
BaseIgniteAbstractTest {
@Test
public void testAuthnOnClientAuthnOnServer() {
- server = startServer(false);
+ server = startServer(true);
- client =
startClient(BasicAuthenticator.builder().username("usr").password("pwd").build());
+ client =
startClient(BasicAuthenticator.builder().username(DEFAULT_USERNAME).password(DEFAULT_PASSWORD).build());
}
private IgniteClient startClient(@Nullable IgniteClientAuthenticator
authenticator) {
@@ -111,15 +114,7 @@ public class ClientAuthenticationTest extends
BaseIgniteAbstractTest {
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();
+ assertThat(securityConfiguration.change(securityChange ->
securityChange.changeEnabled(true)), willCompleteSuccessfully());
}
return server;
diff --git a/modules/configuration/build.gradle
b/modules/configuration/build.gradle
index f0f77c6676c..f4e10cd6a73 100644
--- a/modules/configuration/build.gradle
+++ b/modules/configuration/build.gradle
@@ -34,9 +34,17 @@ dependencies {
testAnnotationProcessor
project(':ignite-configuration-annotation-processor')
testImplementation project(':ignite-core')
testImplementation testFixtures(project(':ignite-core'))
+ testImplementation libs.junit.testkit
testFixturesAnnotationProcessor
project(':ignite-configuration-annotation-processor')
testFixturesImplementation project(':ignite-core')
testFixturesImplementation testFixtures(project(':ignite-core'))
testFixturesImplementation libs.typesafe.config
}
+
+// Exclude tests from inner static classes that use JUnit Platform Test Kit.
+test {
+ filter {
+ excludeTestsMatching "*ConfigurationExtensionTest\$*"
+ }
+}
diff --git
a/modules/runner/src/main/java/org/apache/ignite/internal/configuration/CompoundModule.java
b/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/CompoundModule.java
similarity index 100%
rename from
modules/runner/src/main/java/org/apache/ignite/internal/configuration/CompoundModule.java
rename to
modules/configuration/src/main/java/org/apache/ignite/internal/configuration/CompoundModule.java
diff --git
a/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/testframework/ConfigurationExtensionTest.java
b/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/testframework/ConfigurationExtensionTest.java
index 48c4a323d5a..71f66ee669e 100644
---
a/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/testframework/ConfigurationExtensionTest.java
+++
b/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/testframework/ConfigurationExtensionTest.java
@@ -17,21 +17,30 @@
package org.apache.ignite.internal.configuration.testframework;
-import static java.util.concurrent.TimeUnit.SECONDS;
+import static
org.apache.ignite.internal.testframework.JunitExtensionTestUtils.assertExecutesWithFailure;
+import static
org.apache.ignite.internal.testframework.matchers.CompletableFutureExceptionMatcher.willThrowFast;
import static
org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willCompleteSuccessfully;
import static
org.apache.ignite.internal.util.CompletableFutures.nullCompletedFuture;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasSize;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import
org.apache.ignite.configuration.validation.ConfigurationValidationException;
import org.apache.ignite.internal.configuration.sample.DiscoveryConfiguration;
import
org.apache.ignite.internal.configuration.sample.ExtendedDiscoveryConfiguration;
import
org.apache.ignite.internal.configuration.sample.ExtendedDiscoveryConfigurationSchema;
import org.apache.ignite.internal.testframework.BaseIgniteAbstractTest;
+import org.apache.ignite.internal.testframework.JunitExtensionTestUtils;
+import org.apache.ignite.internal.util.ExceptionUtils;
+import org.assertj.core.api.Condition;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -56,25 +65,23 @@ class ConfigurationExtensionTest extends
BaseIgniteAbstractTest {
/** Test that contains injected parameter. */
@Test
- public void injectConfiguration(
- @InjectConfiguration("mock.joinTimeout=100")
DiscoveryConfiguration paramCfg
- ) throws Exception {
+ void injectConfiguration(@InjectConfiguration("mock.joinTimeout=100")
DiscoveryConfiguration paramCfg) {
assertEquals(5000, fieldCfg.joinTimeout().value());
assertEquals(100, paramCfg.joinTimeout().value());
- paramCfg.change(d -> d.changeJoinTimeout(200)).get(1, SECONDS);
+ assertThat(paramCfg.change(d -> d.changeJoinTimeout(200)),
willCompleteSuccessfully());
assertEquals(200, paramCfg.joinTimeout().value());
- paramCfg.joinTimeout().update(300).get(1, SECONDS);
+ assertThat(paramCfg.joinTimeout().update(300),
willCompleteSuccessfully());
assertEquals(300, paramCfg.joinTimeout().value());
}
/** Tests that notifications work on injected configuration instance. */
@Test
- public void notifications() throws Exception {
+ void notifications() {
List<String> log = new ArrayList<>();
fieldCfg.listen(ctx -> {
@@ -95,35 +102,33 @@ class ConfigurationExtensionTest extends
BaseIgniteAbstractTest {
return nullCompletedFuture();
});
- fieldCfg.change(change -> change.changeJoinTimeout(1000_000)).get(1,
SECONDS);
+ assertThat(fieldCfg.change(change ->
change.changeJoinTimeout(1000_000)), willCompleteSuccessfully());
assertEquals(List.of("update", "join"), log);
log.clear();
- fieldCfg.failureDetectionTimeout().update(2000_000).get(1, SECONDS);
+ assertThat(fieldCfg.failureDetectionTimeout().update(2000_000),
willCompleteSuccessfully());
assertEquals(List.of("update", "failure"), log);
}
/** Tests that internal configuration extensions work properly on injected
configuration instance. */
@Test
- public void internalConfiguration(
- @InjectConfiguration(extensions =
{ExtendedConfigurationSchema.class}) BasicConfiguration cfg
- ) throws Exception {
+ void internalConfiguration(@InjectConfiguration(extensions =
ExtendedConfigurationSchema.class) BasicConfiguration cfg) {
assertThat(cfg, is(instanceOf(ExtendedConfiguration.class)));
assertEquals(1, cfg.visible().value());
assertEquals(2, ((ExtendedConfiguration) cfg).invisible().value());
- cfg.change(change -> {
+ assertThat(cfg.change(change -> {
assertThat(change, is(instanceOf(ExtendedChange.class)));
change.changeVisible(3);
((ExtendedChange) change).changeInvisible(4);
- }).get(1, SECONDS);
+ }), willCompleteSuccessfully());
assertEquals(3, cfg.visible().value());
@@ -132,7 +137,7 @@ class ConfigurationExtensionTest extends
BaseIgniteAbstractTest {
/** Test UUID generation in mocks. */
@Test
- public void testInjectInternalId(
+ void testInjectInternalId(
@InjectConfiguration(
extensions = ExtendedDiscoveryConfigurationSchema.class,
name = "test"
@@ -140,4 +145,125 @@ class ConfigurationExtensionTest extends
BaseIgniteAbstractTest {
) {
assertNotNull(((ExtendedDiscoveryConfiguration)
discoveryConfig).id().value());
}
+
+ /** Tests that changing a value to one within the valid range succeeds. */
+ @Test
+ 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
+ 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
+ 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
+ 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
+ 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);
+
+ assertThat(((ConfigurationValidationException)
ex.getCause()).getIssues(), hasSize(2));
+ }
+
+ /**
+ * Tests that {@code @Value(hasDefault = true)} schema defaults are
applied when no explicit HOCON values
+ * are provided.
+ */
+ @Test
+ void defaultValuesAreApplied(@InjectConfiguration ValidatedConfiguration
cfg) {
+ assertEquals(50, cfg.rangeValue().value());
+ assertEquals("constant", cfg.constValue().value());
+ }
+
+ /**
+ * Tests that initial configuration values are validated at injection
time, and that a value
+ * violating a constraint causes {@link ConfigurationValidationException}
to be thrown.
+ */
+ @Test
+ void initialValidationRejectsInvalidValue() {
+ assertInjectionFails(InvalidInitialValueTest.class);
+ }
+
+ @Test
+ void missingDefaultValueIsRejectedByValidation() {
+ assertInjectionFails(MissingDefaultValueTest.class);
+ }
+
+ @Test
+ void invalidDefaultValueIsRejectedByValidation() {
+ assertInjectionFails(InvalidDefaultValueTest.class);
+ }
+
+ private static void assertInjectionFails(Class<?> testClass) {
+ assertExecutesWithFailure(
+ testClass,
+ new Condition<>(
+ t -> ExceptionUtils.hasCause(t,
ConfigurationValidationException.class),
+ "ConfigurationValidationException"
+ )
+ );
+ }
+
+ /**
+ * A test class whose {@code @Value(hasDefault = true)} is not initialized.
+ * It is not a normal test and is only executed programmatically via
{@link JunitExtensionTestUtils}.
+ */
+ @ExtendWith(ConfigurationExtension.class)
+ static class MissingDefaultValueTest extends BaseIgniteAbstractTest {
+ @SuppressWarnings("unused")
+ @InjectConfiguration
+ InvalidDefaultConfiguration cfg;
+
+ @Test
+ void test() {}
+ }
+
+ /**
+ * A test class whose field injection intentionally violates {@code
@Range(min=1)}.
+ * It is not a normal test and is only executed programmatically via
{@link JunitExtensionTestUtils}.
+ */
+ @ExtendWith(ConfigurationExtension.class)
+ static class InvalidInitialValueTest extends BaseIgniteAbstractTest {
+ @SuppressWarnings("unused")
+ @InjectConfiguration("mock.rangeValue=0")
+ ValidatedConfiguration cfg;
+
+ @Test
+ void test() {}
+ }
+
+ /**
+ * A test class whose {@code @Value(hasDefault = true)} is inialized with
an invalid value.
+ * It is not a normal test and is only executed programmatically via
{@link JunitExtensionTestUtils}.
+ */
+ @ExtendWith(ConfigurationExtension.class)
+ static class InvalidDefaultValueTest extends BaseIgniteAbstractTest {
+ @SuppressWarnings("unused")
+ @InjectConfiguration
+ InvalidDefaultConfiguration cfg;
+
+ @Test
+ void test() {}
+ }
}
diff --git
a/modules/configuration/src/testFixtures/java/org/apache/ignite/internal/configuration/testframework/BasicConfigurationSchema.java
b/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/testframework/InvalidDefaultConfigurationSchema.java
similarity index 78%
copy from
modules/configuration/src/testFixtures/java/org/apache/ignite/internal/configuration/testframework/BasicConfigurationSchema.java
copy to
modules/configuration/src/test/java/org/apache/ignite/internal/configuration/testframework/InvalidDefaultConfigurationSchema.java
index 78f8a7dd7ec..223e1bc86ce 100644
---
a/modules/configuration/src/testFixtures/java/org/apache/ignite/internal/configuration/testframework/BasicConfigurationSchema.java
+++
b/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/testframework/InvalidDefaultConfigurationSchema.java
@@ -19,12 +19,14 @@ package
org.apache.ignite.internal.configuration.testframework;
import org.apache.ignite.configuration.annotation.Config;
import org.apache.ignite.configuration.annotation.Value;
+import org.apache.ignite.configuration.validation.Range;
/**
- * Configuration schema for {@link ConfigurationExtensionTest#notifications()}.
+ * Configuration schema whose {@code @Value(hasDefault = true)} field is
initialized with an invalid value.
*/
@Config
-public class BasicConfigurationSchema {
+public class InvalidDefaultConfigurationSchema {
@Value(hasDefault = true)
- public int visible = 1;
+ @Range(min = 1, max = 100)
+ public int invalidDefaultValue = -1;
}
diff --git
a/modules/configuration/src/testFixtures/java/org/apache/ignite/internal/configuration/testframework/BasicConfigurationSchema.java
b/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/testframework/MissingDefaultConfigurationSchema.java
similarity index 78%
copy from
modules/configuration/src/testFixtures/java/org/apache/ignite/internal/configuration/testframework/BasicConfigurationSchema.java
copy to
modules/configuration/src/test/java/org/apache/ignite/internal/configuration/testframework/MissingDefaultConfigurationSchema.java
index 78f8a7dd7ec..7ddf0e50163 100644
---
a/modules/configuration/src/testFixtures/java/org/apache/ignite/internal/configuration/testframework/BasicConfigurationSchema.java
+++
b/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/testframework/MissingDefaultConfigurationSchema.java
@@ -21,10 +21,11 @@ import org.apache.ignite.configuration.annotation.Config;
import org.apache.ignite.configuration.annotation.Value;
/**
- * Configuration schema for {@link ConfigurationExtensionTest#notifications()}.
+ * Configuration schema whose {@code @Value(hasDefault = true)} field is not
initialized.
+ * Used by {@link ConfigurationExtensionTest} to verify that schema defaults
are subject to validation.
*/
@Config
-public class BasicConfigurationSchema {
+public class MissingDefaultConfigurationSchema {
@Value(hasDefault = true)
- public int visible = 1;
+ public String defaultValue;
}
diff --git
a/modules/configuration/src/testFixtures/java/org/apache/ignite/internal/configuration/testframework/BasicConfigurationSchema.java
b/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/testframework/ValidatedConfigurationSchema.java
similarity index 71%
copy from
modules/configuration/src/testFixtures/java/org/apache/ignite/internal/configuration/testframework/BasicConfigurationSchema.java
copy to
modules/configuration/src/test/java/org/apache/ignite/internal/configuration/testframework/ValidatedConfigurationSchema.java
index 78f8a7dd7ec..8d34afc6e04 100644
---
a/modules/configuration/src/testFixtures/java/org/apache/ignite/internal/configuration/testframework/BasicConfigurationSchema.java
+++
b/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/testframework/ValidatedConfigurationSchema.java
@@ -19,12 +19,19 @@ package
org.apache.ignite.internal.configuration.testframework;
import org.apache.ignite.configuration.annotation.Config;
import org.apache.ignite.configuration.annotation.Value;
+import org.apache.ignite.configuration.validation.Immutable;
+import org.apache.ignite.configuration.validation.Range;
/**
- * Configuration schema for {@link ConfigurationExtensionTest#notifications()}.
+ * Configuration schema with validation annotations, used by {@link
ConfigurationExtensionTest}.
*/
@Config
-public class BasicConfigurationSchema {
+public class ValidatedConfigurationSchema {
+ @Range(min = 1, max = 100)
@Value(hasDefault = true)
- public int visible = 1;
+ public int rangeValue = 50;
+
+ @Immutable
+ @Value(hasDefault = true)
+ public String constValue = "constant";
}
diff --git
a/modules/configuration/src/testFixtures/java/org/apache/ignite/internal/configuration/testframework/BasicConfigurationSchema.java
b/modules/configuration/src/testFixtures/java/org/apache/ignite/internal/configuration/testframework/BasicConfigurationSchema.java
index 78f8a7dd7ec..b3fb2b6ab1e 100644
---
a/modules/configuration/src/testFixtures/java/org/apache/ignite/internal/configuration/testframework/BasicConfigurationSchema.java
+++
b/modules/configuration/src/testFixtures/java/org/apache/ignite/internal/configuration/testframework/BasicConfigurationSchema.java
@@ -17,13 +17,13 @@
package org.apache.ignite.internal.configuration.testframework;
-import org.apache.ignite.configuration.annotation.Config;
+import org.apache.ignite.configuration.annotation.ConfigurationRoot;
import org.apache.ignite.configuration.annotation.Value;
/**
* Configuration schema for {@link ConfigurationExtensionTest#notifications()}.
*/
-@Config
+@ConfigurationRoot(rootName = "basic")
public class BasicConfigurationSchema {
@Value(hasDefault = true)
public int visible = 1;
diff --git
a/modules/configuration/src/testFixtures/java/org/apache/ignite/internal/configuration/testframework/ConfigurationExtension.java
b/modules/configuration/src/testFixtures/java/org/apache/ignite/internal/configuration/testframework/ConfigurationExtension.java
index 3f13dbfb754..4dc605807f8 100644
---
a/modules/configuration/src/testFixtures/java/org/apache/ignite/internal/configuration/testframework/ConfigurationExtension.java
+++
b/modules/configuration/src/testFixtures/java/org/apache/ignite/internal/configuration/testframework/ConfigurationExtension.java
@@ -20,21 +20,27 @@ package
org.apache.ignite.internal.configuration.testframework;
import static java.lang.reflect.Modifier.isStatic;
import static java.util.concurrent.CompletableFuture.allOf;
import static java.util.concurrent.Executors.newSingleThreadExecutor;
+import static
org.apache.ignite.configuration.annotation.ConfigurationType.DISTRIBUTED;
import static
org.apache.ignite.configuration.annotation.ConfigurationType.LOCAL;
import static
org.apache.ignite.internal.configuration.notifications.ConfigurationNotifier.notifyListeners;
+import static
org.apache.ignite.internal.configuration.testframework.InjectConfiguration.MOCK_ROOT_NAME;
import static
org.apache.ignite.internal.configuration.util.ConfigurationUtil.findEx;
import static
org.apache.ignite.internal.configuration.util.ConfigurationUtil.polymorphicSchemaExtensions;
import static
org.apache.ignite.internal.configuration.util.ConfigurationUtil.schemaExtensions;
import static
org.apache.ignite.internal.configuration.util.ConfigurationUtil.touch;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import com.typesafe.config.ConfigFactory;
import com.typesafe.config.ConfigObject;
import java.lang.reflect.Field;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.ServiceLoader;
+import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
@@ -45,7 +51,11 @@ import org.apache.ignite.configuration.ConfigurationModule;
import org.apache.ignite.configuration.RootKey;
import org.apache.ignite.configuration.SuperRootChange;
import org.apache.ignite.configuration.annotation.ConfigurationType;
-import org.apache.ignite.configuration.annotation.PolymorphicConfigInstance;
+import
org.apache.ignite.configuration.validation.ConfigurationValidationException;
+import org.apache.ignite.configuration.validation.ValidationIssue;
+import org.apache.ignite.configuration.validation.Validator;
+import org.apache.ignite.internal.configuration.CompoundModule;
+import org.apache.ignite.internal.configuration.ConfigurationTreeGenerator;
import org.apache.ignite.internal.configuration.DynamicConfiguration;
import org.apache.ignite.internal.configuration.DynamicConfigurationChanger;
import org.apache.ignite.internal.configuration.RootInnerNode;
@@ -57,6 +67,9 @@ import
org.apache.ignite.internal.configuration.hocon.HoconConverter;
import org.apache.ignite.internal.configuration.tree.ConfigurationSource;
import org.apache.ignite.internal.configuration.tree.InnerNode;
import org.apache.ignite.internal.configuration.util.ConfigurationUtil;
+import
org.apache.ignite.internal.configuration.validation.ConfigurationValidator;
+import
org.apache.ignite.internal.configuration.validation.ConfigurationValidatorImpl;
+import org.jetbrains.annotations.Nullable;
import org.junit.jupiter.api.extension.AfterAllCallback;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeAllCallback;
@@ -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);
+ DISTRIBUTED_MODULE = new CompoundModule(DISTRIBUTED,
distributedModules);
}
@Override
@@ -220,14 +226,15 @@ public class ConfigurationExtension implements
BeforeEachCallback, AfterEachCall
// classes, extension is designed to mock actual configurations from
public API to configure Ignite components.
Class<?> schemaClass = Class.forName(type.getCanonicalName() +
"Schema");
- List<Class<?>> extensions = EXTENSIONS;
- List<Class<?>> polymorphicExtensions = POLYMORPHIC_EXTENSIONS;
+ Collection<Class<?>> extensions =
configurationModule(annotation.type()).schemaExtensions();
if (annotation.extensions().length > 0) {
extensions = new ArrayList<>(extensions);
extensions.addAll(List.of(annotation.extensions()));
}
+ Collection<Class<?>> polymorphicExtensions =
configurationModule(annotation.type()).polymorphicSchemaExtensions();
+
if (annotation.polymorphicExtensions().length > 0) {
polymorphicExtensions = new ArrayList<>(polymorphicExtensions);
polymorphicExtensions.addAll(List.of(annotation.polymorphicExtensions()));
@@ -240,22 +247,14 @@ public class ConfigurationExtension implements
BeforeEachCallback, AfterEachCall
);
// RootKey must be mocked, there's no way to instantiate it using a
public constructor.
- RootKey<?, ?, ?> rootKey = new RootKey<>(
- annotation.rootName().isBlank() ? "mock" :
annotation.rootName(),
- LOCAL,
- schemaClass,
- false
- );
+ RootKey<?, ?, ?> rootKey = new RootKey<>(rootName(annotation),
annotation.type(), schemaClass, false);
- // Accept both "mock" (HOCON convention per @InjectConfiguration docs)
and rootKey.key()
- // (for patchConfigurationWithDynamicDefaults which uses the real root
key).
- SuperRoot superRoot = new SuperRoot(s ->
- s.equals(rootKey.key()) || s.equals("mock")
- ? new RootInnerNode(rootKey,
cgen.instantiateNode(schemaClass))
- : null
- );
+ SuperRoot superRoot = createSuperRoot(rootKey, schemaClass, cgen);
+
+ // Use empty object as default.
+ String hoconStr = annotation.value().isBlank() ? rootKey.key() + " :
{}" : annotation.value();
- ConfigObject hoconCfg =
ConfigFactory.parseString(annotation.value()).root();
+ ConfigObject hoconCfg = ConfigFactory.parseString(hoconStr).root();
HoconConverter.hoconSource(hoconCfg).descend(superRoot);
@@ -265,7 +264,7 @@ public class ConfigurationExtension implements
BeforeEachCallback, AfterEachCall
ConfigurationUtil.addDefaults(superRoot);
- if (!annotation.name().isEmpty()) {
+ if (!annotation.name().isBlank()) {
InnerNode root = superRoot.getRoot(rootKey);
root.internalId(UUID.randomUUID());
@@ -274,6 +273,10 @@ public class ConfigurationExtension implements
BeforeEachCallback, AfterEachCall
superRoot.makeImmutable();
+ ConfigurationValidator validator = configurationValidator(annotation,
rootKey, schemaClass, cgen);
+
+ validateConfiguration(validator, superRoot);
+
// Reference to the super root is required to make
DynamicConfigurationChanger#change method atomic.
var superRootRef = new AtomicReference<>(superRoot);
@@ -296,19 +299,19 @@ public class ConfigurationExtension implements
BeforeEachCallback, AfterEachCall
ConfigurationUtil.dropNulls(copy);
+ validateConfiguration(validator, sr, copy);
+
if (superRootRef.compareAndSet(sr, copy)) {
long storageRevision =
storageRevisionCounter.incrementAndGet();
long notificationNumber =
notificationListenerCounter.incrementAndGet();
- List<CompletableFuture<?>> futures = new ArrayList<>();
-
- futures.addAll(notifyListeners(
+ Collection<CompletableFuture<?>> futures =
notifyListeners(
sr.getRoot(rootKey),
copy.getRoot(rootKey),
(DynamicConfiguration<InnerNode, ?>)
cfgRef.get(),
storageRevision,
notificationNumber
- ));
+ );
return
allOf(futures.toArray(CompletableFuture[]::new));
}
@@ -353,8 +356,8 @@ public class ConfigurationExtension implements
BeforeEachCallback, AfterEachCall
private static void patchWithDynamicDefault(ConfigurationType type,
SuperRoot superRoot) {
SuperRootChangeImpl rootChange = new SuperRootChangeImpl(superRoot);
- List<ConfigurationModule> modules = type == LOCAL ? LOCAL_MODULES :
DISTRIBUTED_MODULES;
- modules.forEach(module -> patchIfRootExists(module, rootChange));
+
+ patchIfRootExists(configurationModule(type), rootChange);
}
/**
@@ -369,4 +372,74 @@ public class ConfigurationExtension implements
BeforeEachCallback, AfterEachCall
// Module tried to access a root that doesn't exist in this
SuperRoot - skip
}
}
+
+ private static void validateConfiguration(@Nullable ConfigurationValidator
validator, SuperRoot configuration) {
+ if (validator == null) {
+ return;
+ }
+
+ List<ValidationIssue> validationIssues =
validator.validate(configuration);
+
+ if (!validationIssues.isEmpty()) {
+ throw new ConfigurationValidationException(validationIssues);
+ }
+ }
+
+ private static void validateConfiguration(@Nullable ConfigurationValidator
validator, SuperRoot curRoots, SuperRoot changes) {
+ if (validator == null) {
+ return;
+ }
+
+ List<ValidationIssue> validationIssues = validator.validate(curRoots,
changes);
+
+ if (!validationIssues.isEmpty()) {
+ throw new ConfigurationValidationException(validationIssues);
+ }
+ }
+
+ @Nullable
+ private static ConfigurationValidator configurationValidator(
+ InjectConfiguration annotation,
+ RootKey<?, ?, ?> rootKey,
+ Class<?> schemaClass,
+ ConfigurationAsmGenerator cgen
+ ) {
+ if (!annotation.validate()) {
+ return null;
+ }
+
+ ConfigurationTreeGenerator mockGenerator =
mockConfigurationTreeGenerator(rootKey, schemaClass, cgen);
+
+ Set<Validator<?, ?>> validators =
configurationModule(annotation.type()).validators();
+
+ return ConfigurationValidatorImpl.withDefaultValidators(mockGenerator,
validators);
+ }
+
+ private static SuperRoot createSuperRoot(RootKey<?, ?, ?> rootKey,
Class<?> schemaClass, ConfigurationAsmGenerator cgen) {
+ // Accept both "mock" (HOCON convention per @InjectConfiguration docs)
and rootKey.key()
+ // (for patchConfigurationWithDynamicDefaults which uses the real root
key).
+ return new SuperRoot(s ->
+ s.equals(rootKey.key()) || s.equals(MOCK_ROOT_NAME)
+ ? new RootInnerNode(rootKey,
cgen.instantiateNode(schemaClass))
+ : null
+ );
+ }
+
+ private static ConfigurationTreeGenerator mockConfigurationTreeGenerator(
+ RootKey<?, ?, ?> rootKey, Class<?> schemaClass,
ConfigurationAsmGenerator cgen
+ ) {
+ ConfigurationTreeGenerator generator =
mock(ConfigurationTreeGenerator.class);
+
+ when(generator.createSuperRoot()).thenAnswer(invocation ->
createSuperRoot(rootKey, schemaClass, cgen));
+
+ return generator;
+ }
+
+ private static ConfigurationModule configurationModule(ConfigurationType
type) {
+ return type == LOCAL ? LOCAL_MODULE : DISTRIBUTED_MODULE;
+ }
+
+ private static String rootName(InjectConfiguration annotation) {
+ return annotation.rootName().isBlank() ? MOCK_ROOT_NAME :
annotation.rootName();
+ }
}
diff --git
a/modules/configuration/src/testFixtures/java/org/apache/ignite/internal/configuration/testframework/InjectConfiguration.java
b/modules/configuration/src/testFixtures/java/org/apache/ignite/internal/configuration/testframework/InjectConfiguration.java
index 9ee019512e9..e2aca6dd1e7 100644
---
a/modules/configuration/src/testFixtures/java/org/apache/ignite/internal/configuration/testframework/InjectConfiguration.java
+++
b/modules/configuration/src/testFixtures/java/org/apache/ignite/internal/configuration/testframework/InjectConfiguration.java
@@ -34,13 +34,13 @@ import org.intellij.lang.annotations.Language;
/**
* Annotation for injecting configuration instances into tests.
- * <p/>
- * This annotation should be used on either fields or method parameters of the
{@code *Configuration} type.
- * <p/>
- * Injected instance is initialized with values passed in {@link #value()},
with schema defaults where explicit initial values are not
+ *
+ * <p>This annotation should be used on either fields or method parameters of
the {@code *Configuration} type.
+ *
+ * <p>Injected instance is initialized with values passed in {@link #value()},
with schema defaults where explicit initial values are not
* found.
- * <p/>
- * Although configuration instance is mutable, there's no {@link
ConfigurationRegistry} and {@link ConfigurationChanger} underneath. Main
+ *
+ * <p>Although configuration instance is mutable, there's no {@link
ConfigurationRegistry} and {@link ConfigurationChanger} underneath. Main
* point of the extension is to provide mocks.
*
* @see ConfigurationExtension
@@ -48,21 +48,23 @@ import org.intellij.lang.annotations.Language;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER})
public @interface InjectConfiguration {
+ String MOCK_ROOT_NAME = "mock";
+
/**
- * Configuration values to initialize the instance. Has HOCON syntax. Must
have a root value {@code mock}.
- * <p/>
- * Examples:
+ * Configuration values to initialize the instance. Has HOCON syntax. Must
have a root value {@link #MOCK_ROOT_NAME}.
+ *
+ * <p>Examples:
* <ul>
* <li>{@code mock.timeout=1000}</li>
* <li>{@code mock{cfg1=50, cfg2=90}}</li>
* </ul>
- * <p/>
- * Uses only default values by default.
+ *
+ * <p>Uses only default values by default.
*
* @return Initial configuration values in HOCON format.
*/
@Language("HOCON")
- String value() default "mock : {}";
+ String value() default "";
/**
* Name value to imitate named list elements. Default empty string value
is treated like the absence of the name.
@@ -96,4 +98,12 @@ public @interface InjectConfiguration {
* @return Array of configuration schema extensions.
*/
Class<?>[] polymorphicExtensions() default {};
+
+ /**
+ * Flag indicating whether the provided configuration should be validated.
+ *
+ * <p>It may be useful to disable validation in tests if the developer
needs to break the configuration contract on purpose,
+ * for example to set a smaller value than allowed by the corresponding
schema.
+ */
+ boolean validate() default true;
}
diff --git
a/modules/core/src/testFixtures/java/org/apache/ignite/internal/testframework/JunitExtensionTestUtils.java
b/modules/core/src/testFixtures/java/org/apache/ignite/internal/testframework/JunitExtensionTestUtils.java
index f7e43846b78..723a5da3f09 100644
---
a/modules/core/src/testFixtures/java/org/apache/ignite/internal/testframework/JunitExtensionTestUtils.java
+++
b/modules/core/src/testFixtures/java/org/apache/ignite/internal/testframework/JunitExtensionTestUtils.java
@@ -32,7 +32,7 @@ import org.junit.platform.testkit.engine.EventType;
*
* @see <a
href="https://junit.org/junit5/docs/current/user-guide/#testkit">JUnit Platform
Test Kit</a>
*/
-class JunitExtensionTestUtils {
+public class JunitExtensionTestUtils {
/**
* Executes the given test class on the Jupiter test engine.
*/
@@ -45,7 +45,7 @@ class JunitExtensionTestUtils {
/**
* Executes the given test class and checks that it has run all its tests
successfully.
*/
- static void assertExecutesSuccessfully(Class<?> testClass) {
+ public static void assertExecutesSuccessfully(Class<?> testClass) {
execute(testClass)
.allEvents()
.assertThatEvents()
@@ -58,7 +58,7 @@ class JunitExtensionTestUtils {
* Executes the given test class and checks that it fails with matching
error conditions.
*/
@SafeVarargs
- static void assertExecutesWithFailure(Class<?> testClass,
Condition<Throwable>... conditions) {
+ public static void assertExecutesWithFailure(Class<?> testClass,
Condition<Throwable>... conditions) {
execute(testClass)
.allEvents()
.assertThatEvents()
diff --git
a/modules/eventlog/src/integrationTest/java/org/apache/ignite/internal/eventlog/impl/ItEventLogConfigurationTest.java
b/modules/eventlog/src/integrationTest/java/org/apache/ignite/internal/eventlog/impl/ItEventLogConfigurationTest.java
index e94929047f4..a7ad204b0bb 100644
---
a/modules/eventlog/src/integrationTest/java/org/apache/ignite/internal/eventlog/impl/ItEventLogConfigurationTest.java
+++
b/modules/eventlog/src/integrationTest/java/org/apache/ignite/internal/eventlog/impl/ItEventLogConfigurationTest.java
@@ -17,6 +17,7 @@
package org.apache.ignite.internal.eventlog.impl;
+import static
org.apache.ignite.configuration.annotation.ConfigurationType.DISTRIBUTED;
import static
org.apache.ignite.internal.eventlog.impl.TestEventTypes.TEST_EVENT_TYPE_1;
import static
org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willCompleteSuccessfully;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -44,7 +45,7 @@ class ItEventLogConfigurationTest extends
BaseIgniteAbstractTest {
private static final String IN_MEMORY_SINK_TYPE = "inMemory";
private static final String TEST_SINK_NAME = "testSink";
- @InjectConfiguration(polymorphicExtensions =
InMemoryCollectionSinkConfigurationSchema.class)
+ @InjectConfiguration(polymorphicExtensions =
InMemoryCollectionSinkConfigurationSchema.class, type = DISTRIBUTED)
private EventLogConfiguration eventLogConfiguration;
private EventLogImpl eventLog;
diff --git
a/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/impl/ConfigurationBasedChannelRegistryTest.java
b/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/impl/ConfigurationBasedChannelRegistryTest.java
index 2a50c401d26..19d5ff4db83 100644
---
a/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/impl/ConfigurationBasedChannelRegistryTest.java
+++
b/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/impl/ConfigurationBasedChannelRegistryTest.java
@@ -17,6 +17,7 @@
package org.apache.ignite.internal.eventlog.impl;
+import static
org.apache.ignite.configuration.annotation.ConfigurationType.DISTRIBUTED;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasSize;
@@ -41,7 +42,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
class ConfigurationBasedChannelRegistryTest extends BaseIgniteAbstractTest {
private static final String TEST_CHANNEL = "testChannel";
- @InjectConfiguration
+ @InjectConfiguration(type = DISTRIBUTED)
private EventLogConfiguration cfg;
private ConfigurationBasedChannelRegistry registry;
diff --git
a/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/impl/ConfigurationBasedSinkRegistryTest.java
b/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/impl/ConfigurationBasedSinkRegistryTest.java
index c3a5f56b4b9..9e6c3799405 100644
---
a/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/impl/ConfigurationBasedSinkRegistryTest.java
+++
b/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/impl/ConfigurationBasedSinkRegistryTest.java
@@ -17,6 +17,7 @@
package org.apache.ignite.internal.eventlog.impl;
+import static
org.apache.ignite.configuration.annotation.ConfigurationType.DISTRIBUTED;
import static
org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willCompleteSuccessfully;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.nullValue;
@@ -41,7 +42,7 @@ class ConfigurationBasedSinkRegistryTest extends
BaseIgniteAbstractTest {
private static final String TEST_CHANNEL = "testChannel";
private static final String TEST_SINK = "testSink";
- @InjectConfiguration(polymorphicExtensions =
InMemoryCollectionSinkConfigurationSchema.class)
+ @InjectConfiguration(polymorphicExtensions =
InMemoryCollectionSinkConfigurationSchema.class, type = DISTRIBUTED)
private EventLogConfiguration cfg;
private InMemoryCollectionSink inMemoryCollectionSink;
diff --git
a/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/impl/LogSinkTest.java
b/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/impl/LogSinkTest.java
index 468abd8b73b..72e24754829 100644
---
a/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/impl/LogSinkTest.java
+++
b/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/impl/LogSinkTest.java
@@ -17,6 +17,7 @@
package org.apache.ignite.internal.eventlog.impl;
+import static
org.apache.ignite.configuration.annotation.ConfigurationType.DISTRIBUTED;
import static org.awaitility.Awaitility.await;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasItem;
@@ -44,7 +45,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
@ExtendWith(ConfigurationExtension.class)
class LogSinkTest extends BaseIgniteAbstractTest {
- @InjectConfiguration
+ @InjectConfiguration(type = DISTRIBUTED)
private EventLogConfiguration cfg;
private static Path eventlogPath;
diff --git
a/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/impl/WebhookSinkTest.java
b/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/impl/WebhookSinkTest.java
index c541cb8d8b5..a8af06144e9 100644
---
a/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/impl/WebhookSinkTest.java
+++
b/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/impl/WebhookSinkTest.java
@@ -28,6 +28,7 @@ import static
com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.client.WireMock.verify;
+import static
org.apache.ignite.configuration.annotation.ConfigurationType.DISTRIBUTED;
import static
org.apache.ignite.internal.rest.constants.MediaType.APPLICATION_JSON;
import static
org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willCompleteSuccessfully;
import static org.awaitility.Awaitility.await;
@@ -62,7 +63,10 @@ import org.junit.jupiter.params.provider.ValueSource;
class WebhookSinkTest extends BaseIgniteAbstractTest {
private static final UUID CLUSTER_ID = UUID.randomUUID();
-
@InjectConfiguration("mock{sinks.webhookSink{type=webhook,endpoint=\"http://localhost\"}}")
+ @InjectConfiguration(
+ value =
"mock{sinks.webhookSink{type=webhook,endpoint=\"http://localhost\"}}",
+ type = DISTRIBUTED
+ )
private EventLogConfiguration cfg;
private WebhookSink sink;
diff --git
a/modules/low-watermark/src/test/java/org/apache/ignite/internal/lowwatermark/LowWatermarkImplTest.java
b/modules/low-watermark/src/test/java/org/apache/ignite/internal/lowwatermark/LowWatermarkImplTest.java
index 2869a298f69..3d7a5385256 100644
---
a/modules/low-watermark/src/test/java/org/apache/ignite/internal/lowwatermark/LowWatermarkImplTest.java
+++
b/modules/low-watermark/src/test/java/org/apache/ignite/internal/lowwatermark/LowWatermarkImplTest.java
@@ -86,7 +86,7 @@ import org.mockito.InOrder;
/** For {@link LowWatermarkImpl} testing. */
@ExtendWith(ConfigurationExtension.class)
public class LowWatermarkImplTest extends BaseIgniteAbstractTest {
- @InjectConfiguration
+ @InjectConfiguration(validate = false)
private LowWatermarkConfiguration lowWatermarkConfig;
private final ClockService clockService = spy(new TestClockService(new
HybridClockImpl()));
diff --git
a/modules/metrics-exporter-otlp/src/test/java/org/apache/ignite/internal/metrics/exporters/otlp/OtlpPushMetricExporterTest.java
b/modules/metrics-exporter-otlp/src/test/java/org/apache/ignite/internal/metrics/exporters/otlp/OtlpPushMetricExporterTest.java
index db807fdc7e7..6ce1464cabb 100644
---
a/modules/metrics-exporter-otlp/src/test/java/org/apache/ignite/internal/metrics/exporters/otlp/OtlpPushMetricExporterTest.java
+++
b/modules/metrics-exporter-otlp/src/test/java/org/apache/ignite/internal/metrics/exporters/otlp/OtlpPushMetricExporterTest.java
@@ -18,6 +18,7 @@
package org.apache.ignite.internal.metrics.exporters.otlp;
import static io.opentelemetry.api.common.AttributeType.STRING;
+import static
org.apache.ignite.configuration.annotation.ConfigurationType.DISTRIBUTED;
import static
org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willCompleteSuccessfully;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
@@ -79,7 +80,10 @@ import org.mockito.quality.Strictness;
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
class OtlpPushMetricExporterTest extends BaseIgniteAbstractTest {
- @InjectConfiguration("mock.exporters = {otlp = {exporterName = otlp,
periodMillis = 300, endpoint = \"http://localhost:4317\"}}")
+ @InjectConfiguration(
+ value = "mock.exporters = {otlp = {exporterName = otlp,
periodMillis = 300, endpoint = \"http://localhost:4317\"}}",
+ type = DISTRIBUTED
+ )
private MetricConfiguration metricConfiguration;
private static final UUID CLUSTER_ID = UUID.randomUUID();
diff --git
a/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/MetricManagerTest.java
b/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/MetricManagerTest.java
index 97b4fa8e49d..3e2e894003a 100644
---
a/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/MetricManagerTest.java
+++
b/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/MetricManagerTest.java
@@ -17,6 +17,7 @@
package org.apache.ignite.internal.metrics;
+import static
org.apache.ignite.configuration.annotation.ConfigurationType.DISTRIBUTED;
import static
org.apache.ignite.internal.metrics.exporters.jmx.JmxExporter.JMX_EXPORTER_NAME;
import static
org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willSucceedFast;
import static org.apache.ignite.internal.util.IgniteUtils.makeMbeanName;
@@ -45,7 +46,10 @@ public class MetricManagerTest extends
BaseIgniteAbstractTest {
private static final UUID NODE_ID = UUID.randomUUID();
- @InjectConfiguration("mock.exporters = {" + JMX_EXPORTER_NAME + " =
{exporterName = " + JMX_EXPORTER_NAME + "}}")
+ @InjectConfiguration(
+ value = "mock.exporters = {" + JMX_EXPORTER_NAME + " =
{exporterName = " + JMX_EXPORTER_NAME + "}}",
+ type = DISTRIBUTED
+ )
private MetricConfiguration jmxMetricConfiguration;
@Test
diff --git
a/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/exporters/jmx/JmxExporterTest.java
b/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/exporters/jmx/JmxExporterTest.java
index f1c0252864c..f322aa52284 100644
---
a/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/exporters/jmx/JmxExporterTest.java
+++
b/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/exporters/jmx/JmxExporterTest.java
@@ -18,6 +18,7 @@
package org.apache.ignite.internal.metrics.exporters.jmx;
import static java.util.stream.Collectors.toMap;
+import static
org.apache.ignite.configuration.annotation.ConfigurationType.DISTRIBUTED;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -81,7 +82,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
*/
@ExtendWith({ConfigurationExtension.class})
public class JmxExporterTest extends BaseIgniteAbstractTest {
- @InjectConfiguration(value = "mock.exporters = {jmx = {exporterName =
jmx}}")
+ @InjectConfiguration(value = "mock.exporters = {jmx = {exporterName =
jmx}}", type = DISTRIBUTED)
private MetricConfiguration metricConfiguration;
private JmxExporterView jmxExporterConf;
diff --git
a/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/exporters/log/LogPushExporterTest.java
b/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/exporters/log/LogPushExporterTest.java
index d1abfcf37d5..ebbced059a7 100644
---
a/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/exporters/log/LogPushExporterTest.java
+++
b/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/exporters/log/LogPushExporterTest.java
@@ -17,6 +17,7 @@
package org.apache.ignite.internal.metrics.exporters.log;
+import static
org.apache.ignite.configuration.annotation.ConfigurationType.DISTRIBUTED;
import static
org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willCompleteSuccessfully;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
@@ -72,7 +73,7 @@ import org.junit.jupiter.params.provider.ValueSource;
*/
@ExtendWith({ConfigurationExtension.class})
public class LogPushExporterTest extends BaseIgniteAbstractTest {
- @InjectConfiguration("mock.exporters {log {"
+ @InjectConfiguration(value = "mock.exporters {log {"
+ "exporterName = logPush, "
+ "periodMillis = 300, "
+ "oneLinePerMetricSource = false,"
@@ -85,7 +86,7 @@ public class LogPushExporterTest extends
BaseIgniteAbstractTest {
+ " \"similar.name.*\", "
+ " \"ignored\""
+ "]"
- + "}}")
+ + "}}", type = DISTRIBUTED)
private MetricConfiguration metricConfiguration;
private static final UUID CLUSTER_ID = UUID.randomUUID();
diff --git
a/modules/placement-driver/src/integrationTest/java/org/apache/ignite/internal/placementdriver/PlacementDriverManagerTest.java
b/modules/placement-driver/src/integrationTest/java/org/apache/ignite/internal/placementdriver/PlacementDriverManagerTest.java
index d78d82bc742..a89a9ef5960 100644
---
a/modules/placement-driver/src/integrationTest/java/org/apache/ignite/internal/placementdriver/PlacementDriverManagerTest.java
+++
b/modules/placement-driver/src/integrationTest/java/org/apache/ignite/internal/placementdriver/PlacementDriverManagerTest.java
@@ -153,7 +153,7 @@ public class PlacementDriverManagerTest extends
BasePlacementDriverTest {
@InjectConfiguration
private SystemDistributedConfiguration systemDistributedConfiguration;
- @InjectConfiguration
+ @InjectConfiguration(validate = false)
private ReplicationConfiguration replicationConfiguration;
private MetaStorageManagerImpl metaStorageManager;
diff --git
a/modules/placement-driver/src/test/java/org/apache/ignite/internal/placementdriver/LeaseNegotiationTest.java
b/modules/placement-driver/src/test/java/org/apache/ignite/internal/placementdriver/LeaseNegotiationTest.java
index 8c445c7a91c..581337823fd 100644
---
a/modules/placement-driver/src/test/java/org/apache/ignite/internal/placementdriver/LeaseNegotiationTest.java
+++
b/modules/placement-driver/src/test/java/org/apache/ignite/internal/placementdriver/LeaseNegotiationTest.java
@@ -125,7 +125,7 @@ public class LeaseNegotiationTest extends
BaseIgniteAbstractTest {
private final long assignmentsTimestamp = new HybridTimestamp(0,
1).longValue();
- @InjectConfiguration("mock.leaseAgreementAcceptanceTimeLimitMillis = 2000")
+ @InjectConfiguration(value = "mock.leaseAgreementAcceptanceTimeLimitMillis
= 2000", validate = false)
private ReplicationConfiguration replicationConfiguration;
private static ZonePartitionId replicationGroupId(int objectId, int
partId) {
diff --git
a/modules/placement-driver/src/test/java/org/apache/ignite/internal/placementdriver/LeaseUpdaterTest.java
b/modules/placement-driver/src/test/java/org/apache/ignite/internal/placementdriver/LeaseUpdaterTest.java
index 3a8e71fc845..e23632ddef1 100644
---
a/modules/placement-driver/src/test/java/org/apache/ignite/internal/placementdriver/LeaseUpdaterTest.java
+++
b/modules/placement-driver/src/test/java/org/apache/ignite/internal/placementdriver/LeaseUpdaterTest.java
@@ -110,7 +110,7 @@ public class LeaseUpdaterTest extends
BaseIgniteAbstractTest {
private final LogicalNode stableNode = new LogicalNode(randomUUID(),
"test-node-stable", NetworkAddress.from("127.0.0.1:10000"));
private final LogicalNode pendingNode = new LogicalNode(randomUUID(),
"test-node-pending", NetworkAddress.from("127.0.0.1:10001"));
- @InjectConfiguration("mock.leaseExpirationIntervalMillis = " +
TEST_LEASE_INTERVAL_MILLIS)
+ @InjectConfiguration(value = "mock.leaseExpirationIntervalMillis = " +
TEST_LEASE_INTERVAL_MILLIS, validate = false)
private ReplicationConfiguration replicationConfiguration;
@Mock
diff --git
a/modules/raft/src/test/java/org/apache/ignite/internal/raft/storage/segstore/RaftLogGarbageCollectorTest.java
b/modules/raft/src/test/java/org/apache/ignite/internal/raft/storage/segstore/RaftLogGarbageCollectorTest.java
index 69b6e0c9f95..d17429bbb10 100644
---
a/modules/raft/src/test/java/org/apache/ignite/internal/raft/storage/segstore/RaftLogGarbageCollectorTest.java
+++
b/modules/raft/src/test/java/org/apache/ignite/internal/raft/storage/segstore/RaftLogGarbageCollectorTest.java
@@ -80,7 +80,7 @@ class RaftLogGarbageCollectorTest extends IgniteAbstractTest {
@InjectConfiguration
private RaftConfiguration raftConfiguration;
- @InjectConfiguration("mock.segmentFileSizeBytes=" + FILE_SIZE)
+ @InjectConfiguration(value = "mock.segmentFileSizeBytes=" + FILE_SIZE,
validate = false)
private LogStorageConfiguration storageConfiguration;
private SegmentFileManager fileManager;
diff --git
a/modules/raft/src/test/java/org/apache/ignite/internal/raft/storage/segstore/SegmentFileManagerGetEntryTest.java
b/modules/raft/src/test/java/org/apache/ignite/internal/raft/storage/segstore/SegmentFileManagerGetEntryTest.java
index 27b182a7124..6828daf5e4d 100644
---
a/modules/raft/src/test/java/org/apache/ignite/internal/raft/storage/segstore/SegmentFileManagerGetEntryTest.java
+++
b/modules/raft/src/test/java/org/apache/ignite/internal/raft/storage/segstore/SegmentFileManagerGetEntryTest.java
@@ -79,7 +79,7 @@ class SegmentFileManagerGetEntryTest extends
IgniteAbstractTest {
@BeforeEach
void setUp(
@InjectConfiguration RaftConfiguration raftConfiguration,
- @InjectConfiguration("mock.segmentFileSizeBytes=" + FILE_SIZE)
+ @InjectConfiguration(value = "mock.segmentFileSizeBytes=" +
FILE_SIZE, validate = false)
LogStorageConfiguration storageConfiguration
) throws IOException {
fileManager = new SegmentFileManager(
diff --git
a/modules/raft/src/test/java/org/apache/ignite/internal/raft/storage/segstore/SegmentFileManagerTest.java
b/modules/raft/src/test/java/org/apache/ignite/internal/raft/storage/segstore/SegmentFileManagerTest.java
index a11a96588db..6ff0d7c9460 100644
---
a/modules/raft/src/test/java/org/apache/ignite/internal/raft/storage/segstore/SegmentFileManagerTest.java
+++
b/modules/raft/src/test/java/org/apache/ignite/internal/raft/storage/segstore/SegmentFileManagerTest.java
@@ -101,7 +101,7 @@ class SegmentFileManagerTest extends IgniteAbstractTest {
@InjectConfiguration
private RaftConfiguration raftConfiguration;
- @InjectConfiguration("mock.segmentFileSizeBytes=" + FILE_SIZE)
+ @InjectConfiguration(value = "mock.segmentFileSizeBytes=" + FILE_SIZE,
validate = false)
private LogStorageConfiguration storageConfiguration;
private SegmentFileManager fileManager;
diff --git
a/modules/raft/src/test/java/org/apache/ignite/internal/raft/storage/segstore/SegstoreLogStorageConcurrencyTest.java
b/modules/raft/src/test/java/org/apache/ignite/internal/raft/storage/segstore/SegstoreLogStorageConcurrencyTest.java
index ca7ce4c605d..b6237aa569c 100644
---
a/modules/raft/src/test/java/org/apache/ignite/internal/raft/storage/segstore/SegstoreLogStorageConcurrencyTest.java
+++
b/modules/raft/src/test/java/org/apache/ignite/internal/raft/storage/segstore/SegstoreLogStorageConcurrencyTest.java
@@ -53,7 +53,7 @@ class SegstoreLogStorageConcurrencyTest extends
IgniteAbstractTest {
@BeforeEach
void setUp(
@InjectConfiguration RaftConfiguration raftConfiguration,
- @InjectConfiguration("mock.segmentFileSizeBytes=" + SEGMENT_SIZE)
+ @InjectConfiguration(value = "mock.segmentFileSizeBytes=" +
SEGMENT_SIZE, validate = false)
LogStorageConfiguration storageConfiguration
) throws IOException {
segmentFileManager = new SegmentFileManager(
diff --git
a/modules/rest/src/test/java/org/apache/ignite/internal/rest/RestComponentTest.java
b/modules/rest/src/test/java/org/apache/ignite/internal/rest/RestComponentTest.java
index 1071664048e..47f7a7102a0 100644
---
a/modules/rest/src/test/java/org/apache/ignite/internal/rest/RestComponentTest.java
+++
b/modules/rest/src/test/java/org/apache/ignite/internal/rest/RestComponentTest.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.rest;
import static io.micronaut.http.HttpStatus.CONFLICT;
import static io.micronaut.http.HttpStatus.NOT_FOUND;
import static io.micronaut.http.HttpStatus.OK;
+import static
org.apache.ignite.configuration.annotation.ConfigurationType.DISTRIBUTED;
import static
org.apache.ignite.configuration.annotation.ConfigurationType.LOCAL;
import static org.apache.ignite.internal.rest.RestState.INITIALIZATION;
import static org.apache.ignite.internal.rest.RestState.INITIALIZED;
@@ -82,7 +83,7 @@ public class RestComponentTest extends BaseIgniteAbstractTest
{
private HttpClient client;
- @InjectConfiguration
+ @InjectConfiguration(type = DISTRIBUTED, validate = false)
private SecurityConfiguration securityConfiguration;
@BeforeEach
diff --git
a/modules/security/src/main/java/org/apache/ignite/internal/security/authentication/SecurityConfigurationModule.java
b/modules/security/src/main/java/org/apache/ignite/internal/security/authentication/SecurityConfigurationModule.java
index 0fa05a6edc0..a75b9fabefd 100644
---
a/modules/security/src/main/java/org/apache/ignite/internal/security/authentication/SecurityConfigurationModule.java
+++
b/modules/security/src/main/java/org/apache/ignite/internal/security/authentication/SecurityConfigurationModule.java
@@ -38,11 +38,11 @@ import
org.apache.ignite.internal.security.configuration.SecurityExtensionConfig
*/
@AutoService(ConfigurationModule.class)
public class SecurityConfigurationModule implements ConfigurationModule {
- static final String DEFAULT_PROVIDER_NAME = "default";
+ public static final String DEFAULT_PROVIDER_NAME = "default";
- static final String DEFAULT_USERNAME = "ignite";
+ public static final String DEFAULT_USERNAME = "ignite";
- static final String DEFAULT_PASSWORD = "ignite";
+ public static final String DEFAULT_PASSWORD = "ignite";
@Override
public ConfigurationType type() {
diff --git
a/modules/security/src/test/java/org/apache/ignite/internal/security/authentication/AuthenticationProvidersValidatorImplTest.java
b/modules/security/src/test/java/org/apache/ignite/internal/security/authentication/AuthenticationProvidersValidatorImplTest.java
index 6735611d1fd..ce945539f34 100644
---
a/modules/security/src/test/java/org/apache/ignite/internal/security/authentication/AuthenticationProvidersValidatorImplTest.java
+++
b/modules/security/src/test/java/org/apache/ignite/internal/security/authentication/AuthenticationProvidersValidatorImplTest.java
@@ -23,6 +23,7 @@ import static org.mockito.Mockito.mock;
import java.util.function.Consumer;
import org.apache.ignite.configuration.NamedListView;
+import org.apache.ignite.configuration.annotation.ConfigurationType;
import org.apache.ignite.configuration.validation.ValidationContext;
import org.apache.ignite.internal.configuration.ClusterConfiguration;
import
org.apache.ignite.internal.configuration.testframework.ConfigurationExtension;
@@ -44,7 +45,11 @@ import org.junit.jupiter.api.extension.ExtendWith;
@ExtendWith(ConfigurationExtension.class)
class AuthenticationProvidersValidatorImplTest extends BaseIgniteAbstractTest {
- @InjectConfiguration(polymorphicExtensions =
CustomAuthenticationProviderConfigurationSchema.class)
+ @InjectConfiguration(
+ polymorphicExtensions =
CustomAuthenticationProviderConfigurationSchema.class,
+ type = ConfigurationType.DISTRIBUTED,
+ validate = false
+ )
private SecurityConfiguration securityConfiguration;
@Test