Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions libraryValidations/Spring/validation-tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.3</version>
<version>3.5.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.microsoft</groupId>
Expand Down Expand Up @@ -37,7 +37,7 @@
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-feature-management</artifactId>
<version>5.17.0</version>
<version>6.0.0-beta.2</version>
</dependency>

<dependency>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package com.microsoft.validation_tests;

import static org.junit.jupiter.api.Assumptions.assumeTrue;

import java.io.IOException;
import java.util.Iterator;

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.MockitoAnnotations;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;

import com.azure.spring.cloud.feature.management.telemetry.LoggerTelemetryPublisher;

import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.read.ListAppender;

@SpringJUnitConfig
@TestPropertySource(locations = "file:./../../../Samples/BasicTelemetry.sample.json", factory = YamlPropertySourceFactory.class)
@SpringBootTest(classes = { SpringBootTest.class, Filters.class })
@EnableConfigurationProperties
@ComponentScan(basePackages = { "com.azure.spring.cloud.feature.management" })
class BasicTelemetryTests extends ValidationTestsApplicationTests {

private Logger publisherLogger;

private ListAppender<ILoggingEvent> listAppender;

@BeforeAll
public static void setUpLogging() {
// Force SLF4J to initialize
LoggerFactory.getLogger(BasicTelemetryTests.class).info("Initializing SLF4J in test");
}


@BeforeEach
public void setup() {
MockitoAnnotations.openMocks(this);

org.slf4j.Logger slf4jLogger = LoggerFactory.getLogger(LoggerTelemetryPublisher.class);

// Check if we can cast to Logback's Logger
if (slf4jLogger instanceof ch.qos.logback.classic.Logger) {
publisherLogger = (ch.qos.logback.classic.Logger) slf4jLogger;

// Create a new ListAppender for each test
listAppender = new ListAppender<>();
listAppender.start();

// Remove any existing appenders of this type first
for (Iterator<Appender<ILoggingEvent>> it = publisherLogger.iteratorForAppenders(); it.hasNext();) {
Appender<ILoggingEvent> appender = it.next();
if (appender instanceof ListAppender) {
publisherLogger.detachAppender(appender);
}
}

// Add the fresh appender
publisherLogger.addAppender(listAppender);
} else {
assumeTrue(
false,
"Tests require Logback implementation, but found: " + slf4jLogger.getClass().getName()
);
}
}

@Test
void validateTest() throws IOException {
runTests("BasicTelemetry", listAppender);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class BasicVariantTests extends ValidationTestsApplicationTests {

@Test
void validateTest() throws IOException {
runTests("BasicVariant");
runTests("BasicVariant", null);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class NoFiltersTests extends ValidationTestsApplicationTests {

@Test
void validateTest() throws IOException {
runTests("NoFilters");
runTests("NoFilters", null);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class RequirementTypeTests extends ValidationTestsApplicationTests {

@Test
void validateTest() throws IOException {
runTests("RequirementType");
runTests("RequirementType", null);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class TargetingFilterModifiedTests extends ValidationTestsApplicationTests {

@Test
void validateTest() throws IOException {
runTests("TargetingFilter.modified");
runTests("TargetingFilter.modified", null);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class TargetingFilterTests extends ValidationTestsApplicationTests {

@Test
void validateTest() throws IOException {
runTests("TargetingFilter");
runTests("TargetingFilter", null);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class TimeWindowFilterTests extends ValidationTestsApplicationTests {

@Test
void validateTest() throws IOException {
runTests("TimeWindowFilter");
runTests("TimeWindowFilter", null);
}

}
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
package com.microsoft.validation_tests;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assumptions.assumeTrue;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.azure.spring.cloud.feature.management.FeatureManager;
import com.azure.spring.cloud.feature.management.models.Variant;
import com.azure.spring.cloud.feature.management.validation_tests.models.ValidationTestCase;
import com.azure.spring.cloud.feature.management.validation_tests.models.VariantResult;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.microsoft.validation_tests.models.ValidationTestCase;
import com.microsoft.validation_tests.models.VariantResult;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.read.ListAppender;

class ValidationTestsApplicationTests {

Expand All @@ -37,13 +42,27 @@ class ValidationTestsApplicationTests {
private final String inputsUser = "User";

private final String inputsGroups = "Groups";

static final String EVENT_NAME = "FeatureEvaluation";

static final String FEATURE_NAME = "FeatureName";

static final String ENABLED = "Enabled";

static final String REASON = "VariantAssignmentReason";

static final String VERSION = "Version";

static final String EVALUATION_EVENT_VERSION = "1.1.0";

static final String APPLICATION_INSIGHTS_CUSTOM_EVENT_KEY = "microsoft.custom_event.name";

@Autowired
private FeatureManager featureManager;
@Autowired
private TargetingFilterTestContextAccessor accessor;

void runTests(String name) throws IOException {
void runTests(String name, ListAppender<ILoggingEvent> listAppender) throws IOException {
LOGGER.debug("Running test case from file: " + name);
final File testsFile = new File(PATH + name + TEST_FILE_POSTFIX);
List<ValidationTestCase> testCases = readTestcasesFromFile(testsFile);
Expand Down Expand Up @@ -76,6 +95,21 @@ void runTests(String name) throws IOException {
assertEquals(variantResult.getResult().getConfigurationValue(), getVariantResult.getValue());

}

if (testCase.getTelemetry() != null) {
ILoggingEvent logEvent = getEvent(listAppender.list, testCase.getFeatureFlagName());
Map<String, String> mdcMap = logEvent.getMDCPropertyMap();
Map<String, String> expectedProperties = testCase.getTelemetry().getEventProperties();

assertEquals(EVENT_NAME, logEvent.getMessage());
assertEquals(Level.INFO, logEvent.getLevel());
assertEquals(expectedProperties.get(REASON), mdcMap.get(REASON));
assertEquals(testCase.getFeatureFlagName(), mdcMap.get(FEATURE_NAME));
assertEquals("false", mdcMap.get(ENABLED));
assertEquals(EVALUATION_EVENT_VERSION, mdcMap.get(VERSION));
assertEquals(EVENT_NAME, mdcMap.get(APPLICATION_INSIGHTS_CUSTOM_EVENT_KEY));

}

}
}
Expand All @@ -96,5 +130,18 @@ private List<ValidationTestCase> readTestcasesFromFile(File testFile) throws IOE
ValidationTestCase.class);
return OBJECT_MAPPER.readValue(jsonString, typeReference);
}

ILoggingEvent getEvent(List<ILoggingEvent> events, String featureName) {
for (ILoggingEvent event : events) {
if (featureName.equals(event.getMDCPropertyMap().get(FEATURE_NAME))) {
return event;
}
}
assumeTrue(
false,
"Log event not found for feature: " + featureName
);
return null; // This line will never be reached due to the assumption above
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class VariantAssignmentTests extends ValidationTestsApplicationTests {

@Test
void validateTest() throws IOException {
runTests("VariantAssignment");
runTests("VariantAssignment", null);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.microsoft.validation_tests.models;

import java.util.Map;

public class TelemetryResult {

private String eventName;
private Map<String, String> eventProperties;
/**
* @return the eventName
*/
public String getEventName() {
return eventName;
}
/**
* @param eventName the eventName to set
*/
public void setEventName(String eventName) {
this.eventName = eventName;
}
/**
* @return the eventProperties
*/
public Map<String, String> getEventProperties() {
return eventProperties;
}
/**
* @param eventProperties the eventProperties to set
*/
public void setEventProperties(Map<String, String> eventProperties) {
this.eventProperties = eventProperties;
}

}
Loading