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
1 change: 1 addition & 0 deletions data-prepper-plugins/grok-processor/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ dependencies {
implementation "io.krakens:java-grok:0.1.9"
implementation 'io.micrometer:micrometer-core'
testImplementation project(':data-prepper-test:test-common')
testImplementation project(':data-prepper-test:plugin-test-framework')
}

jacocoTestCoverageVerification {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
import org.opensearch.dataprepper.model.configuration.PluginSetting;
import org.opensearch.dataprepper.model.event.Event;
import org.opensearch.dataprepper.model.plugin.InvalidPluginConfigurationException;
import org.opensearch.dataprepper.model.processor.Processor;
import org.opensearch.dataprepper.model.record.Record;
import org.opensearch.dataprepper.test.plugins.DataPrepperPluginTest;
import org.opensearch.dataprepper.test.plugins.junit.BaseDataPrepperPluginStandardTestSuite;

import java.util.ArrayList;
import java.util.Collections;
Expand All @@ -39,7 +42,8 @@
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.opensearch.dataprepper.plugins.processor.grok.GrokProcessorTests.buildRecordWithEvent;

public class GrokProcessorIT {
@DataPrepperPluginTest(pluginName = "grok", pluginType = Processor.class)
public class GrokProcessorIT extends BaseDataPrepperPluginStandardTestSuite {
private PluginSetting pluginSetting;
private PluginMetrics pluginMetrics;
private GrokProcessorConfig grokProcessorConfig;
Expand Down Expand Up @@ -81,7 +85,9 @@ public void setup() {

@AfterEach
public void tearDown() {
grokProcessor.shutdown();
if(grokProcessor != null) {
grokProcessor.shutdown();
}
}

private PluginSetting completePluginSettingForGrokProcessor(final boolean breakOnMatch,
Expand Down
18 changes: 18 additions & 0 deletions data-prepper-test/plugin-test-framework/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

dependencies {
implementation testLibs.junit.core
implementation testLibs.hamcrest
implementation project(':data-prepper-api')
implementation project(':data-prepper-plugin-framework')
implementation(libs.spring.context) {
exclude group: 'commons-logging', module: 'commons-logging'
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.dataprepper.test.plugins;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* An annotation for configuring plugin tests for a given plugin.
*
* @since 2.13
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface DataPrepperPluginTest {
/**
* Provides the name of the plugin.
*
* @since 2.13
* @return the plugin name
*/
String pluginName();

/**
* Configures the type of the plugin. This should be the same type
* that is used with Data Prepper, such as {@link org.opensearch.dataprepper.model.processor.Processor}.
*
* @since 2.13
* @return The class type of the plugin.
*/
Class<?> pluginType();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.dataprepper.test.plugins.junit;

import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
import org.junit.jupiter.api.extension.ExtendWith;
import org.opensearch.dataprepper.plugin.PluginProvider;

import java.util.stream.Stream;

/**
* Provides a common base class that plugin authors can use to create
* Data Prepper plugin tests along with standard tests.
*
* @since 2.13
*/
@ExtendWith(DataPrepperPluginTestFrameworkExtension.class)
public class BaseDataPrepperPluginStandardTestSuite {
@TestFactory
Stream<DynamicTest> standardDataPrepperPluginTests(
final DataPrepperPluginTestContext dataPrepperPluginTestContext,
final PluginProvider pluginProvider) {
return DataPrepperPluginAutoTestSuite.generateTests(dataPrepperPluginTestContext, pluginProvider);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.dataprepper.test.plugins.junit;

import org.junit.jupiter.api.DynamicTest;
import org.opensearch.dataprepper.plugin.PluginProvider;

import java.util.Optional;
import java.util.stream.Stream;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.matchesPattern;

class DataPrepperPluginAutoTestSuite {
static Stream<DynamicTest> generateTests(
final DataPrepperPluginTestContext dataPrepperPluginTestContext,
final PluginProvider pluginProvider) {
return Stream.of(
DynamicTest.dynamicTest("Plugin can be found by the plugin framework", () ->
{
final Optional<Class<?>> optional = pluginProvider.findPluginClass(
(Class) dataPrepperPluginTestContext.getPluginType(),
dataPrepperPluginTestContext.getPluginName());

assertThat("Unable to locate the plugin class", optional.isPresent(), equalTo(true));
}

),
DynamicTest.dynamicTest("Plugin name conforms to standard naming convention", () ->
assertThat(dataPrepperPluginTestContext.getPluginName(), matchesPattern("^[a-z0-9_]+$"))
)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.dataprepper.test.plugins.junit;

import java.util.Objects;

class DataPrepperPluginTestContext {
private final String pluginName;
private final Class<?> pluginType;

DataPrepperPluginTestContext(
final String pluginName,
final Class<?> pluginType) {
this.pluginName = Objects.requireNonNull(pluginName);
this.pluginType = Objects.requireNonNull(pluginType);
}

public String getPluginName() {
return pluginName;
}

public Class<?> getPluginType() {
return pluginType;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.dataprepper.test.plugins.junit;

import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.ParameterContext;
import org.junit.jupiter.api.extension.ParameterResolutionException;
import org.junit.jupiter.api.extension.ParameterResolver;
import org.opensearch.dataprepper.plugin.ClasspathPluginProvider;
import org.opensearch.dataprepper.plugin.PluginProvider;
import org.opensearch.dataprepper.test.plugins.DataPrepperPluginTest;

import java.util.Set;

/**
* A JUnit extension for using the Data Prepper plugin test framework.
*/
public class DataPrepperPluginTestFrameworkExtension implements ParameterResolver {
private static final Set<Class<?>> SUPPORTED_CLASSES = Set.of(
DataPrepperPluginTestContext.class,
PluginProvider.class
);

@Override
public boolean supportsParameter(final ParameterContext parameterContext, final ExtensionContext extensionContext) throws ParameterResolutionException {
return SUPPORTED_CLASSES.contains(parameterContext.getParameter().getType());
}

@Override
public Object resolveParameter(
final ParameterContext parameterContext,
final ExtensionContext extensionContext) throws ParameterResolutionException {
final Class<?> type = parameterContext.getParameter().getType();

if (type.equals(DataPrepperPluginTestContext.class)) {
final Class<?> testClass = extensionContext.getRequiredTestClass();
final DataPrepperPluginTest annotation = testClass.getAnnotation(DataPrepperPluginTest.class);
if (annotation == null) {
throw new ParameterResolutionException("Missing @DataPrepperPluginTest annotation on class: " + testClass.getName());
}
return new DataPrepperPluginTestContext(annotation.pluginName(), annotation.pluginType());
} else if (type.equals(PluginProvider.class)) {
return new ClasspathPluginProvider();
}

throw new ParameterResolutionException("Unsupported parameter type: " + type);
}
}
Loading
Loading