Skip to content

Commit

Permalink
adding test to ensure environment variable mappings
Browse files Browse the repository at this point in the history
Signed-off-by: Atanas Atanasov <[email protected]>
  • Loading branch information
ata-nas committed Dec 12, 2024
1 parent e85fe16 commit dbdd3c8
Showing 1 changed file with 64 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,29 @@

package com.hedera.block.server.config;

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

import com.swirlds.common.metrics.config.MetricsConfig;
import com.swirlds.config.api.ConfigData;
import com.swirlds.config.api.ConfigProperty;
import com.swirlds.config.extensions.sources.ConfigMapping;
import com.swirlds.config.extensions.sources.MappedConfigSource;
import java.lang.reflect.Field;
import java.lang.reflect.RecordComponent;
import java.util.Arrays;
import java.util.Optional;
import java.util.Queue;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Stream;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

class ServerMappedConfigSourceInitializerTest {
private static final ConfigMapping[] SUPPORTED_MAPPINGS = {
Expand All @@ -39,13 +52,48 @@ class ServerMappedConfigSourceInitializerTest {
new ConfigMapping("server.maxMessageSizeBytes", "SERVER_MAX_MESSAGE_SIZE_BYTES"),
new ConfigMapping("server.port", "SERVER_PORT"),
};
private static final Set<Class<? extends Record>> SUPPORTED_CONFIG_DATA_TYPES =
new BlockNodeConfigExtension().getConfigDataTypes();
private static MappedConfigSource toTest;

@BeforeAll
static void setUp() {
toTest = ServerMappedConfigSourceInitializer.getMappedConfigSource();
}

@ParameterizedTest
@MethodSource("allConfigDataTypes")
void testVerifyAllFieldsInRecordsAreMapped(final Class<? extends Record> config) {
if (!config.isAnnotationPresent(ConfigData.class)) {
fail("Class %s is missing the ConfigData annotation! All config classes MUST have that annotation present!"
.formatted(config.getSimpleName()));
} else {
final ConfigData configDataAnnotation = config.getDeclaredAnnotation(ConfigData.class);
final String prefix = configDataAnnotation.value();
for (final RecordComponent recordComponent : config.getRecordComponents()) {
if (!recordComponent.isAnnotationPresent(ConfigProperty.class)) {
fail(
"Field %s in %s is missing the ConfigProperty annotation! All fields in config classes MUST have that annotation present!"
.formatted(recordComponent.getName(), config.getSimpleName()));
} else {
final String expectedMappedName = "%s.%s".formatted(prefix, recordComponent.getName());
final Optional<ConfigMapping> matchingMapping = Arrays.stream(SUPPORTED_MAPPINGS)
.filter(mapping -> mapping.mappedName().equals(expectedMappedName))
.findFirst();
assertThat(matchingMapping)
.isNotNull()
.withFailMessage(
"Field [%s] in [%s] is not present in the environment variable mappings! Expected config key [%s] to be present and to be mapped to [%s]",
recordComponent.getName(),
config.getSimpleName(),
expectedMappedName,
transformToEnvVarConvention(expectedMappedName))
.isPresent();
}
}
}
}

/**
* This test aims to fail if we have added or removed any {@link ConfigMapping} that will be
* initialized by the {@link ServerMappedConfigSourceInitializer#getMappedConfigSource()}
Expand All @@ -72,6 +120,12 @@ void test_VerifyAllSupportedMappingsAreAddedToInstance() throws ReflectiveOperat
}
}

private static String transformToEnvVarConvention(final String input) {
String underscored = input.replace(".", "_");
String resolved = underscored.replaceAll("(?<!_)([A-Z])", "_$1");
return resolved.toUpperCase();
}

private static Queue<ConfigMapping> extractConfigMappings() throws ReflectiveOperationException {
final Field configMappings = MappedConfigSource.class.getDeclaredField("configMappings");
try {
Expand All @@ -81,4 +135,14 @@ private static Queue<ConfigMapping> extractConfigMappings() throws ReflectiveOpe
configMappings.setAccessible(false);
}
}

private static Stream<Arguments> allConfigDataTypes() {
// Add any classes that should be excluded from the test for any reason in the set below
// MetricsConfig is not supported by us
final Set<Class<? extends Record>> excluded = Set.of(MetricsConfig.class);
return new BlockNodeConfigExtension()
.getConfigDataTypes().stream()
.filter(configType -> !excluded.contains(configType))
.map(Arguments::of);
}
}

0 comments on commit dbdd3c8

Please sign in to comment.