Skip to content

Bootstrap entitlements for testing #129268

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 56 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
2daa627
Fix ExceptionSerializationTests to use getCodeSource instead of getRe…
prdoyle Jun 11, 2025
87b58f6
FIx logging tests to use org.elasticsearch.index instead of root logger.
prdoyle Jun 11, 2025
3248fd2
Fix entitlement error message by stashing the module name in ModuleEn…
prdoyle Jun 12, 2025
afaaf3d
Ignore server locations whose representative class isn't loaded
prdoyle Jun 6, 2025
c363a24
Partial initial implementation
prdoyle Jun 17, 2025
ee60773
System properties: testOnlyClasspath and enableForTests
prdoyle Jun 17, 2025
ad955a5
Trivially allow some packages
prdoyle Jun 17, 2025
3dd3962
DEBUG: use TreeMap in TestScopeResolver for readability
prdoyle Jun 17, 2025
caa6a70
Special case bouncycastle for security plugin
prdoyle Jun 17, 2025
08b16bb
Add CONFIG to TestPathLookup
prdoyle Jun 17, 2025
c3b6388
Add the classpath to the source path list for every plugin
prdoyle Jun 17, 2025
687b904
Add @WithoutEntitlements to tests that run ES nodes
prdoyle Jun 17, 2025
c8f1af6
Set es.entitlement.enableForTests for all libs
prdoyle Jun 17, 2025
38c3f9c
Use @WithoutEntitlements on ingest plugin tests
prdoyle Jun 17, 2025
f5a7c86
Substitute ALL-UNNAMED for module name in non-modular plugins
prdoyle Jun 17, 2025
93878f9
Add missing entitlements found by unit tests
prdoyle Jun 17, 2025
bda4331
Comment in TestScopeResolver
prdoyle Jun 17, 2025
852eb83
Properly compute bridge jar location for patch-module
prdoyle Jun 17, 2025
d039ba4
Call out nonServerLibs
prdoyle Jun 18, 2025
c53e10a
Don't build two TestPathLookups
prdoyle Jun 18, 2025
6c1b7fd
More comments for meta-tests
prdoyle Jun 18, 2025
8776617
Remove redundant dependencies for bridgeJarConfig.
prdoyle Jun 18, 2025
3737d0a
Merge branch 'main' into bootstrap-entitlements-for-testing
prdoyle Jun 18, 2025
d9517f7
Add bridge+agent dependencies only if those exist.
prdoyle Jun 18, 2025
2381c88
[CI] Auto commit changes from spotless
elasticsearchmachine Jun 18, 2025
26baece
Pass testOnlyPath in environment instead of command line.
prdoyle Jun 18, 2025
a846c50
[CI] Auto commit changes from spotless
elasticsearchmachine Jun 18, 2025
e9093d3
Split testOnlyPathString at File.pathSeparator
prdoyle Jun 18, 2025
b2bbf94
Use doFirst to delay setting testOnlyPath env var
prdoyle Jun 18, 2025
3c760da
Trivially allow jimfs (??)
prdoyle Jun 18, 2025
65a7678
Merge branch 'main' into bootstrap-entitlements-for-testing
prdoyle Jun 19, 2025
5ef8233
Don't enforce entitlements on internalClusterTest for now
prdoyle Jun 19, 2025
0b4273a
Merge branch 'main' into bootstrap-entitlements-for-testing
ldematte Jun 20, 2025
4c9acbb
Replace forbidden APIs
prdoyle Jun 20, 2025
a2fcb3a
Match testOnlyClasspath using URI instead of String.
prdoyle Jun 20, 2025
4b36d55
[CI] Auto commit changes from spotless
elasticsearchmachine Jun 20, 2025
48fe7cc
Merge branch 'main' into bootstrap-entitlements-for-testing
prdoyle Jun 20, 2025
a2d8eb8
More forbidden APIs
prdoyle Jun 20, 2025
eea9cca
Merge branch 'main' into bootstrap-entitlements-for-testing
prdoyle Jun 20, 2025
846c8b7
Merge branch 'main' into bootstrap-entitlements-for-testing
prdoyle Jun 20, 2025
a9c83cc
Disable configuration cache for LegacyYamlRestTestPluginFuncTest
prdoyle Jun 24, 2025
3dffea1
Merge remote-tracking branch 'upstream/main' into bootstrap-entitleme…
prdoyle Jun 24, 2025
ec76635
Strip carriage-return characters in expected output for ReleaseNotesG…
prdoyle Jun 24, 2025
a5579b6
Merge branch 'main' into bootstrap-entitlements-for-testing
prdoyle Jun 24, 2025
4338605
Merge branch 'main' into bootstrap-entitlements-for-testing
prdoyle Jun 24, 2025
bc6b6c8
Move configureEntitlements to ElasticsearchTestBasePlugin as-is
prdoyle Jun 24, 2025
8c62d00
Use matching instead of if
prdoyle Jun 24, 2025
c7ff726
Remove requireNonNull
prdoyle Jun 24, 2025
b5a1672
Remove default configuration
prdoyle Jun 24, 2025
4e1a3b6
Set inputs instead of dependencies
prdoyle Jun 24, 2025
82d61e4
Use test.systemProperty
prdoyle Jun 24, 2025
b5d3088
Merge remote-tracking branch 'upstream/main' into bootstrap-entitleme…
prdoyle Jun 24, 2025
67ddd9c
Merge branch 'main' into bootstrap-entitlements-for-testing
prdoyle Jun 25, 2025
f880bbc
Respond to PR comments
prdoyle Jun 26, 2025
015ad9f
Disable entitlement enforcement for ScopedSettingsTests.
prdoyle Jun 26, 2025
4f0bc69
Merge remote-tracking branch 'upstream/main' into bootstrap-entitleme…
prdoyle Jun 26, 2025
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import org.gradle.testkit.runner.TaskOutcome
class LegacyYamlRestTestPluginFuncTest extends AbstractRestResourcesFuncTest {

def setup() {
configurationCacheCompatible = true
configurationCacheCompatible = false // This is interfering with the entitlements logic in ElasticsearchTestBasePlugin
buildApiRestrictionsDisabled = true
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.ConfigurationContainer;
import org.gradle.api.file.FileCollection;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.provider.ProviderFactory;
Expand Down Expand Up @@ -173,6 +174,16 @@ public void execute(Task t) {
// we use 'temp' relative to CWD since this is per JVM and tests are forbidden from writing to CWD
nonInputProperties.systemProperty("java.io.tmpdir", test.getWorkingDir().toPath().resolve("temp"));

SourceSetContainer sourceSets = project.getExtensions().getByType(SourceSetContainer.class);
SourceSet mainSourceSet = sourceSets.findByName(SourceSet.MAIN_SOURCE_SET_NAME);
SourceSet testSourceSet = sourceSets.findByName(SourceSet.TEST_SOURCE_SET_NAME);
if (mainSourceSet != null && testSourceSet != null) {
FileCollection mainRuntime = mainSourceSet.getRuntimeClasspath();
FileCollection testRuntime = testSourceSet.getRuntimeClasspath();
FileCollection testOnlyFiles = testRuntime.minus(mainRuntime);
test.doFirst(task -> test.environment("es.entitlement.testOnlyPath", testOnlyFiles.getAsPath()));
}

test.systemProperties(getProviderFactory().systemPropertiesPrefixedBy("tests.").get());
test.systemProperties(getProviderFactory().systemPropertiesPrefixedBy("es.").get());

Expand Down Expand Up @@ -205,27 +216,27 @@ public void execute(Task t) {
}

/*
* If this project builds a shadow JAR than any unit tests should test against that artifact instead of
* If this project builds a shadow JAR then any unit tests should test against that artifact instead of
* compiled class output and dependency jars. This better emulates the runtime environment of consumers.
*/
project.getPluginManager().withPlugin("com.gradleup.shadow", p -> {
if (test.getName().equals(JavaPlugin.TEST_TASK_NAME)) {
// Remove output class files and any other dependencies from the test classpath, since the shadow JAR includes these
SourceSetContainer sourceSets = project.getExtensions().getByType(SourceSetContainer.class);
FileCollection mainRuntime = sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME).getRuntimeClasspath();
// Add any "shadow" dependencies. These are dependencies that are *not* bundled into the shadow JAR
Configuration shadowConfig = project.getConfigurations().getByName(ShadowBasePlugin.CONFIGURATION_NAME);
// Add the shadow JAR artifact itself
FileCollection shadowJar = project.files(project.getTasks().named("shadowJar"));
FileCollection testRuntime = sourceSets.getByName(SourceSet.TEST_SOURCE_SET_NAME).getRuntimeClasspath();
FileCollection mainRuntime = mainSourceSet.getRuntimeClasspath();
FileCollection testRuntime = testSourceSet.getRuntimeClasspath();
test.setClasspath(testRuntime.minus(mainRuntime).plus(shadowConfig).plus(shadowJar));
}
});
});
configureImmutableCollectionsPatch(project);
configureJavaBasePatch(project);
configureEntitlements(project);
}

private void configureImmutableCollectionsPatch(Project project) {
private void configureJavaBasePatch(Project project) {
String patchProject = ":test:immutable-collections-patch";
if (project.findProject(patchProject) == null) {
return; // build tests may not have this project, just skip
Expand All @@ -235,16 +246,74 @@ private void configureImmutableCollectionsPatch(Project project) {
.create(configurationName, config -> config.setCanBeConsumed(false));
var deps = project.getDependencies();
deps.add(configurationName, deps.project(Map.of("path", patchProject, "configuration", "patch")));

// If ElasticsearchJavaBasePlugin has specified a dependency on the entitlement bridge jar,
// then it needs to be added to the --patch-module=java.base command line option.
ConfigurationContainer configurations = project.getConfigurations();

project.getTasks().withType(Test.class).matching(task -> task.getName().equals("test")).configureEach(test -> {
test.getInputs().files(patchedFileCollection);
test.systemProperty("tests.hackImmutableCollections", "true");

Configuration bridgeJarConfig = configurations.findByName("entitlementBridgeJar");
String bridgeJarPart;
if (bridgeJarConfig == null) {
bridgeJarPart = "";
} else {
test.getInputs().files(bridgeJarConfig);
bridgeJarPart = File.pathSeparator + bridgeJarConfig.getSingleFile().getAbsolutePath();
}

test.getJvmArgumentProviders()
.add(
() -> List.of(
"--patch-module=java.base=" + patchedFileCollection.getSingleFile() + "/java.base",
"--patch-module=java.base=" + patchedFileCollection.getSingleFile() + "/java.base" + bridgeJarPart,
"--add-opens=java.base/java.util=ALL-UNNAMED"
)
);
});
}

private static void configureEntitlements(Project project) {
Configuration agentJarConfig = project.getConfigurations().create("entitlementAgentJar");
Project agent = project.findProject(":libs:entitlement:agent");
if (agent != null) {
agentJarConfig.defaultDependencies(
deps -> { deps.add(project.getDependencies().project(Map.of("path", ":libs:entitlement:agent"))); }
);
}
FileCollection agentFiles = agentJarConfig;

Configuration bridgeJarConfig = project.getConfigurations().create("entitlementBridgeJar");
Project bridge = project.findProject(":libs:entitlement:bridge");
if (bridge != null) {
bridgeJarConfig.defaultDependencies(
deps -> { deps.add(project.getDependencies().project(Map.of("path", ":libs:entitlement:bridge"))); }
);
}
FileCollection bridgeFiles = bridgeJarConfig;

project.getTasks().withType(Test.class).configureEach(test -> {
// See also SystemJvmOptions.maybeAttachEntitlementAgent.

// Agent
if (agentFiles.isEmpty() == false) {
test.getInputs().files(agentFiles);
test.systemProperty("es.entitlement.agentJar", agentFiles.getAsPath());
test.systemProperty("jdk.attach.allowAttachSelf", true);
}

// Bridge
if (bridgeFiles.isEmpty() == false) {
String modulesContainingEntitlementInstrumentation = "java.logging,java.net.http,java.naming,jdk.net";
test.getInputs().files(bridgeFiles);
// Tests may not be modular, but the JDK still is
test.jvmArgs(
"--add-exports=java.base/org.elasticsearch.entitlement.bridge=ALL-UNNAMED,"
+ modulesContainingEntitlementInstrumentation
);
}
});
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ private ChangelogEntry makeHighlightsEntry(int pr, boolean notable) {
}

private String getResource(String name) throws Exception {
return Files.readString(Paths.get(Objects.requireNonNull(this.getClass().getResource(name)).toURI()), StandardCharsets.UTF_8);
return Files.readString(Paths.get(Objects.requireNonNull(this.getClass().getResource(name)).toURI()), StandardCharsets.UTF_8).replace("\r", "");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is that for?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test wasn't working on Windows. Tag @brianseeders

}

private void writeResource(String name, String contents) throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@
import org.gradle.api.provider.ProviderFactory;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.SourceSetContainer;
import org.gradle.api.tasks.testing.Test;
import org.gradle.language.jvm.tasks.ProcessResources;

import java.util.List;

import javax.inject.Inject;

/**
Expand Down Expand Up @@ -53,5 +56,9 @@ public void apply(Project project) {
project.getTasks().withType(ProcessResources.class).named("processResources").configure(task -> {
task.into("META-INF", copy -> copy.from(testBuildInfoTask));
});

project.getTasks().withType(Test.class).matching(test -> List.of("test").contains(test.getName())).configureEach(test -> {
test.systemProperty("es.entitlement.enableForTests", "true");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@breskeby is there a way to NOT enable this for serverless initially?

});
}
}
10 changes: 10 additions & 0 deletions libs/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,14 @@ configure(childProjects.values()) {
*/
apply plugin: 'elasticsearch.build'
}

// This is for any code potentially included in the server at runtime.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just add this to the plugin-scanner project for now. In general we want to move more configuration where it belongs. adding code that might be needed in the future in sometime just adds clutter for now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It needs to apply to every lib except plugin-scanner.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Really, plugin-scanner shouldn't be in libs in the first place.)

// Omit oddball libraries that aren't in server.
def nonServerLibs = ['plugin-scanner']
if (false == nonServerLibs.contains(project.name)) {
project.getTasks().withType(Test.class).matching(test -> ['test'].contains(test.name)).configureEach(test -> {
test.systemProperty('es.entitlement.enableForTests', 'true')
})
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ private void neverEntitled(Class<?> callerClass, Supplier<String> operationDescr
Strings.format(
"component [%s], module [%s], class [%s], operation [%s]",
entitlements.componentName(),
PolicyCheckerImpl.getModuleName(requestingClass),
entitlements.moduleName(),
requestingClass,
operationDescription.get()
),
Expand Down Expand Up @@ -247,7 +247,7 @@ public void checkFileRead(Class<?> callerClass, Path path, boolean followLinks)
Strings.format(
"component [%s], module [%s], class [%s], entitlement [file], operation [read], path [%s]",
entitlements.componentName(),
PolicyCheckerImpl.getModuleName(requestingClass),
entitlements.moduleName(),
requestingClass,
realPath == null ? path : Strings.format("%s -> %s", path, realPath)
),
Expand Down Expand Up @@ -279,7 +279,7 @@ public void checkFileWrite(Class<?> callerClass, Path path) {
Strings.format(
"component [%s], module [%s], class [%s], entitlement [file], operation [write], path [%s]",
entitlements.componentName(),
PolicyCheckerImpl.getModuleName(requestingClass),
entitlements.moduleName(),
requestingClass,
path
),
Expand Down Expand Up @@ -383,7 +383,7 @@ public void checkWriteProperty(Class<?> callerClass, String property) {
() -> Strings.format(
"Entitled: component [%s], module [%s], class [%s], entitlement [write_system_properties], property [%s]",
entitlements.componentName(),
PolicyCheckerImpl.getModuleName(requestingClass),
entitlements.moduleName(),
requestingClass,
property
)
Expand All @@ -394,7 +394,7 @@ public void checkWriteProperty(Class<?> callerClass, String property) {
Strings.format(
"component [%s], module [%s], class [%s], entitlement [write_system_properties], property [%s]",
entitlements.componentName(),
PolicyCheckerImpl.getModuleName(requestingClass),
entitlements.moduleName(),
requestingClass,
property
),
Expand Down Expand Up @@ -447,7 +447,7 @@ private void checkFlagEntitlement(
Strings.format(
"component [%s], module [%s], class [%s], entitlement [%s]",
classEntitlements.componentName(),
PolicyCheckerImpl.getModuleName(requestingClass),
classEntitlements.moduleName(),
requestingClass,
PolicyParser.buildEntitlementNameFromClass(entitlementClass)
),
Expand All @@ -460,7 +460,7 @@ private void checkFlagEntitlement(
() -> Strings.format(
"Entitled: component [%s], module [%s], class [%s], entitlement [%s]",
classEntitlements.componentName(),
PolicyCheckerImpl.getModuleName(requestingClass),
classEntitlements.moduleName(),
requestingClass,
PolicyParser.buildEntitlementNameFromClass(entitlementClass)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,9 @@ public enum ComponentKind {
*
* @param componentName the plugin name or else one of the special component names like "(server)".
*/
record ModuleEntitlements(
protected record ModuleEntitlements(
String componentName,
String moduleName,
Map<Class<? extends Entitlement>, List<Entitlement>> entitlementsByType,
FileAccessTree fileAccess,
Logger logger
Expand Down Expand Up @@ -148,7 +149,13 @@ private FileAccessTree getDefaultFileAccess(Collection<Path> componentPaths) {

// pkg private for testing
ModuleEntitlements defaultEntitlements(String componentName, Collection<Path> componentPaths, String moduleName) {
return new ModuleEntitlements(componentName, Map.of(), getDefaultFileAccess(componentPaths), getLogger(componentName, moduleName));
return new ModuleEntitlements(
componentName,
moduleName,
Map.of(),
getDefaultFileAccess(componentPaths),
getLogger(componentName, moduleName)
);
}

// pkg private for testing
Expand All @@ -166,6 +173,7 @@ ModuleEntitlements policyEntitlements(
}
return new ModuleEntitlements(
componentName,
moduleName,
entitlements.stream().collect(groupingBy(Entitlement::getClass)),
FileAccessTree.of(componentName, moduleName, filesEntitlement, pathLookup, componentPaths, exclusivePaths),
getLogger(componentName, moduleName)
Expand Down Expand Up @@ -293,11 +301,11 @@ private static Logger getLogger(String componentName, String moduleName) {
*/
private static final ConcurrentHashMap<String, Logger> MODULE_LOGGERS = new ConcurrentHashMap<>();

ModuleEntitlements getEntitlements(Class<?> requestingClass) {
protected ModuleEntitlements getEntitlements(Class<?> requestingClass) {
return moduleEntitlementsMap.computeIfAbsent(requestingClass.getModule(), m -> computeEntitlements(requestingClass));
}

private ModuleEntitlements computeEntitlements(Class<?> requestingClass) {
protected final ModuleEntitlements computeEntitlements(Class<?> requestingClass) {
var policyScope = scopeResolver.apply(requestingClass);
var componentName = policyScope.componentName();
var moduleName = policyScope.moduleName();
Expand Down Expand Up @@ -336,8 +344,7 @@ private ModuleEntitlements computeEntitlements(Class<?> requestingClass) {
}
}

// pkg private for testing
static Collection<Path> getComponentPathsFromClass(Class<?> requestingClass) {
protected Collection<Path> getComponentPathsFromClass(Class<?> requestingClass) {
var codeSource = requestingClass.getProtectionDomain().getCodeSource();
if (codeSource == null) {
return List.of();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ public void testGetEntitlements() {
AtomicReference<PolicyScope> policyScope = new AtomicReference<>();

// A common policy with a variety of entitlements to test
Collection<Path> thisSourcePaths = PolicyManager.getComponentPathsFromClass(getClass());
var plugin1SourcePaths = List.of(Path.of("modules", "plugin1"));
var policyManager = new PolicyManager(
new Policy("server", List.of(new Scope("org.example.httpclient", List.of(new OutboundNetworkEntitlement())))),
Expand All @@ -99,6 +98,7 @@ public void testGetEntitlements() {
Map.of("plugin1", plugin1SourcePaths),
TEST_PATH_LOOKUP
);
Collection<Path> thisSourcePaths = policyManager.getComponentPathsFromClass(getClass());

// "Unspecified" below means that the module is not named in the policy

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.elasticsearch.ingest.Processor;
import org.elasticsearch.ingest.RandomDocumentPicks;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.ESTestCase.WithoutEntitlements;
import org.junit.Before;

import java.io.InputStream;
Expand All @@ -38,6 +39,7 @@
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;

@WithoutEntitlements // ES-12084
public class AttachmentProcessorTests extends ESTestCase {

private Processor processor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.apache.tika.metadata.Metadata;
import org.elasticsearch.core.PathUtils;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.ESTestCase.WithoutEntitlements;

import java.nio.file.DirectoryStream;
import java.nio.file.Files;
Expand All @@ -25,6 +26,7 @@
* comes back and no exception.
*/
@SuppressFileSystems("ExtrasFS") // don't try to parse extraN
@WithoutEntitlements // ES-12084
public class TikaDocTests extends ESTestCase {

/** some test files from tika test suite, zipped up */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
package org.elasticsearch.ingest.attachment;

import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.ESTestCase.WithoutEntitlements;

@WithoutEntitlements // ES-12084
public class TikaImplTests extends ESTestCase {

public void testTikaLoads() throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@

import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.ESTestCase.WithoutEntitlements;
import org.junit.Before;

import java.util.HashMap;
import java.util.Map;

import static org.hamcrest.Matchers.equalTo;

@WithoutEntitlements // ES-12084
public class RegisteredDomainProcessorFactoryTests extends ESTestCase {

private RegisteredDomainProcessor.Factory factory;
Expand Down
Loading