Skip to content

Commit

Permalink
add tests for ConfigInjectionPoint
Browse files Browse the repository at this point in the history
  • Loading branch information
paullatzelsperger committed Nov 11, 2024
1 parent 0f51662 commit 0781206
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,9 @@ public Object resolve(ServiceExtensionContext context, DefaultServiceSupplier de
// set the field values on the newly-constructed object instance
valueAnnotatedFields.forEach(fe -> {
try {
pojoClass.getDeclaredField(fe.fieldName()).set(instance, fe.value());
var field = pojoClass.getDeclaredField(fe.fieldName());
field.setAccessible(true);
field.set(instance, fe.value());
} catch (IllegalAccessException | NoSuchFieldException e) {
throw new RuntimeException(e);
}
Expand All @@ -137,22 +139,6 @@ public Object resolve(ServiceExtensionContext context, DefaultServiceSupplier de
}
}

private @NotNull List<FieldValue> resolveConfigValueFields(ServiceExtensionContext context, Field[] fields) {
return injectionPointsFrom(fields)
.map(ip -> {
var val = ip.resolve(context, null /*the default supplier arg is not used anyway*/);
var fieldName = ip.getTargetField().getName();
return new FieldValue(fieldName, val);
})
.toList();
}

private @NotNull Stream<ValueInjectionPoint<Object>> injectionPointsFrom(Field[] fields) {
return Arrays.stream(fields)
.filter(f -> f.getAnnotation(Setting.class) != null)
.map(f -> new ValueInjectionPoint<>(null, f, f.getAnnotation(Setting.class), targetInstance.getClass()));
}

@Override
public Result<Void> isSatisfiedBy(Map<Class<?>, List<ServiceExtension>> dependencyMap, ServiceExtensionContext context) {
var violators = injectionPointsFrom(configurationObject.getType().getDeclaredFields())
Expand Down Expand Up @@ -181,6 +167,22 @@ private Predicate<Constructor<?>> constructorFilter(List<FieldValue> args) {

}

private @NotNull List<FieldValue> resolveConfigValueFields(ServiceExtensionContext context, Field[] fields) {
return injectionPointsFrom(fields)
.map(ip -> {
var val = ip.resolve(context, null /*the default supplier arg is not used anyway*/);
var fieldName = ip.getTargetField().getName();
return new FieldValue(fieldName, val);
})
.toList();
}

private @NotNull Stream<ValueInjectionPoint<Object>> injectionPointsFrom(Field[] fields) {
return Arrays.stream(fields)
.filter(f -> f.getAnnotation(Setting.class) != null)
.map(f -> new ValueInjectionPoint<>(null, f, f.getAnnotation(Setting.class), targetInstance.getClass()));
}

private record FieldValue(String fieldName, Object value) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,47 +14,107 @@

package org.eclipse.edc.boot.system.injection;

import org.eclipse.edc.boot.system.testextensions.ConfigurationObject;
import org.eclipse.edc.boot.system.testextensions.ExtensionWithConfigObject;
import org.eclipse.edc.spi.system.ServiceExtensionContext;
import org.eclipse.edc.spi.system.configuration.ConfigFactory;
import org.junit.jupiter.api.Test;

import java.util.Map;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.eclipse.edc.boot.system.TestFunctions.getDeclaredField;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

class ConfigurationInjectionPointTest {

private final ExtensionWithConfigObject targetInstance = new ExtensionWithConfigObject();
private final ConfigurationInjectionPoint<ExtensionWithConfigObject> injectionPoint = new ConfigurationInjectionPoint<>(targetInstance, getDeclaredField(ExtensionWithConfigObject.class, "configurationObject"));

@Test
void getTargetInstance() {
assertThat(injectionPoint.getTargetInstance()).isEqualTo(targetInstance);
}

@Test
void getType() {
assertThat(injectionPoint.getType()).isEqualTo(ConfigurationObject.class);
}

@Test
void isRequired() {
assertThat(injectionPoint.isRequired()).isTrue();
var ip = new ConfigurationInjectionPoint<>(targetInstance, getDeclaredField(ExtensionWithConfigObject.class, "optionalConfigurationObject"));
assertThat(ip.isRequired()).isFalse();
}

@Test
void setTargetValue() {
void setTargetValue() throws IllegalAccessException {
assertThat(injectionPoint.setTargetValue(new ConfigurationObject("foo", 42L, null, 3.14159)).succeeded())
.isTrue();
}

@Test
void getDefaultServiceProvider() {
assertThat(injectionPoint.getDefaultServiceProvider()).isNull();
}

@Test
void setDefaultServiceProvider() {
//noop
}

@Test
void resolve() {
void resolve_record_isRequired_notResolved() {
var context = mock(ServiceExtensionContext.class);
when(context.getConfig()).thenReturn(ConfigFactory.fromMap(Map.of()));
assertThatThrownBy(() -> injectionPoint.resolve(context, mock())).isInstanceOf(EdcInjectionException.class);
}

@Test
void isSatisfiedBy() {
void resolve_objectIsRecord() {
var context = mock(ServiceExtensionContext.class);
when(context.getMonitor()).thenReturn(mock());
when(context.getConfig()).thenReturn(ConfigFactory.fromMap(Map.of("foo.bar.baz", "asdf",
"test.key3", "42")));

var res = injectionPoint.resolve(context, mock());
assertThat(res).isInstanceOf(ConfigurationObject.class);
}

@Test
void getTypeString() {
void resolve_objectIsClass() {
var ip = new ConfigurationInjectionPoint<>(targetInstance, getDeclaredField(ExtensionWithConfigObject.class, "optionalConfigurationObject"));
var context = mock(ServiceExtensionContext.class);
when(context.getMonitor()).thenReturn(mock());
when(context.getConfig()).thenReturn(ConfigFactory.fromMap(Map.of("optional.key", "asdf")));

var result = ip.resolve(context, mock());

assertThat(result).isInstanceOf(ExtensionWithConfigObject.OptionalConfigurationObject.class);
assertThat(((ExtensionWithConfigObject.OptionalConfigurationObject) result).getVal()).isEqualTo("asdf");
}

@Test
void testToString() {
void isSatisfiedBy() {
var context = mock(ServiceExtensionContext.class);
when(context.getMonitor()).thenReturn(mock());
when(context.getConfig()).thenReturn(ConfigFactory.fromMap(Map.of("foo.bar.baz", "asdf",
"test.key3", "42")));

assertThat(injectionPoint.isSatisfiedBy(Map.of(), context).succeeded()).isTrue();
}

@Test
void isSatisfiedBy_hasViolations() {
var context = mock(ServiceExtensionContext.class);
when(context.getMonitor()).thenReturn(mock());
when(context.getConfig()).thenReturn(ConfigFactory.fromMap(Map.of()));

var result = injectionPoint.isSatisfiedBy(Map.of(), context);
assertThat(result.succeeded()).isFalse();
assertThat(result.getFailureDetail()).isEqualTo("configurationObject (ConfigurationObject) --> [requiredVal (property \"foo.bar.baz\")]");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation
*
*/

package org.eclipse.edc.boot.system.testextensions;

import org.eclipse.edc.runtime.metamodel.annotation.Configuration;
import org.eclipse.edc.runtime.metamodel.annotation.Setting;
import org.eclipse.edc.runtime.metamodel.annotation.Settings;
import org.eclipse.edc.spi.system.ServiceExtension;

public class ExtensionWithConfigObject implements ServiceExtension {

@Configuration
private ConfigurationObject configurationObject;

@Configuration // is optional because all @Settings within are optionsl
private OptionalConfigurationObject optionalConfigurationObject;

public ConfigurationObject getConfigurationObject() {
return configurationObject;
}

@Settings
public static class OptionalConfigurationObject {
@Setting(key = "optional.key", required = false)
private String val;

public String getVal() {
return val;
}
}
}

0 comments on commit 0781206

Please sign in to comment.