Added custom transport client settings to test infra

It's now possible to define the additional customesettings for transport clients by extending `transportClientSettings` callback method on `ElasticsearchIntegrationTest`.
This commit is contained in:
uboness 2014-08-01 19:10:42 +02:00
parent 74aa35bdcd
commit 0da5cecc3c
5 changed files with 100 additions and 47 deletions

View File

@ -32,7 +32,6 @@ import org.elasticsearch.discovery.zen.ZenDiscoveryModule;
import org.elasticsearch.transport.TransportModule;
import org.elasticsearch.transport.TransportService;
import org.elasticsearch.transport.netty.NettyTransportModule;
import org.hamcrest.CoreMatchers;
import org.junit.Before;
import org.junit.Ignore;
@ -104,11 +103,16 @@ public abstract class ElasticsearchBackwardsCompatIntegrationTest extends Elasti
protected TestCluster buildTestCluster(Scope scope) throws IOException {
TestCluster cluster = super.buildTestCluster(scope);
ExternalNode externalNode = new ExternalNode(backwardsCompatibilityPath(), randomLong(), new NodeSettingsSource() {
ExternalNode externalNode = new ExternalNode(backwardsCompatibilityPath(), randomLong(), new SettingsSource() {
@Override
public Settings settings(int nodeOrdinal) {
public Settings node(int nodeOrdinal) {
return externalNodeSettings(nodeOrdinal);
}
@Override
public Settings transportClient() {
return transportClientSettings();
}
});
return new CompositeTestCluster((InternalTestCluster) cluster, between(minExternalNodes(), maxExternalNodes()), externalNode);
}

View File

@ -1453,14 +1453,29 @@ public abstract class ElasticsearchIntegrationTest extends ElasticsearchTestCase
return ImmutableSettings.EMPTY;
}
/**
* This method is used to obtain additional settings for clients created by the internal cluster.
* These settings will be applied on the client in addition to some randomized settings defined in
* the cluster. These setttings will also override any other settings the internal cluster might
* add by default.
*/
protected Settings transportClientSettings() {
return ImmutableSettings.EMPTY;
}
protected TestCluster buildTestCluster(Scope scope) throws IOException {
long currentClusterSeed = randomLong();
NodeSettingsSource nodeSettingsSource = new NodeSettingsSource() {
SettingsSource settingsSource = new SettingsSource() {
@Override
public Settings settings(int nodeOrdinal) {
public Settings node(int nodeOrdinal) {
return nodeSettings(nodeOrdinal);
}
@Override
public Settings transportClient() {
return transportClientSettings();
}
};
int numDataNodes = getNumDataNodes();
@ -1474,7 +1489,7 @@ public abstract class ElasticsearchIntegrationTest extends ElasticsearchTestCase
int numClientNodes = getNumClientNodes();
boolean enableRandomBenchNodes = enableRandomBenchNodes();
return new InternalTestCluster(currentClusterSeed, minNumDataNodes, maxNumDataNodes, clusterName(scope.name(), ElasticsearchTestCase.CHILD_VM_ID, currentClusterSeed), nodeSettingsSource, numClientNodes, enableRandomBenchNodes);
return new InternalTestCluster(currentClusterSeed, minNumDataNodes, maxNumDataNodes, clusterName(scope.name(), ElasticsearchTestCase.CHILD_VM_ID, currentClusterSeed), settingsSource, numClientNodes, enableRandomBenchNodes);
}
/**

View File

@ -46,29 +46,29 @@ final class ExternalNode implements Closeable {
private final File path;
private final Random random;
private final NodeSettingsSource nodeSettingsSource;
private final SettingsSource settingsSource;
private Process process;
private NodeInfo nodeInfo;
private final String clusterName;
private TransportClient client;
ExternalNode(File path, long seed, NodeSettingsSource nodeSettingsSource) {
this(path, null, seed, nodeSettingsSource);
ExternalNode(File path, long seed, SettingsSource settingsSource) {
this(path, null, seed, settingsSource);
}
ExternalNode(File path, String clusterName, long seed, NodeSettingsSource nodeSettingsSource) {
ExternalNode(File path, String clusterName, long seed, SettingsSource settingsSource) {
if (!path.isDirectory()) {
throw new IllegalArgumentException("path must be a directory");
}
this.path = path;
this.clusterName = clusterName;
this.random = new Random(seed);
this.nodeSettingsSource = nodeSettingsSource;
this.settingsSource = settingsSource;
}
synchronized ExternalNode start(Client localNode, Settings defaultSettings, String nodeName, String clusterName, int nodeOrdinal) throws IOException, InterruptedException {
ExternalNode externalNode = new ExternalNode(path, clusterName, random.nextLong(), nodeSettingsSource);
Settings settings = ImmutableSettings.builder().put(nodeSettingsSource.settings(nodeOrdinal)).put(defaultSettings).build();
ExternalNode externalNode = new ExternalNode(path, clusterName, random.nextLong(), settingsSource);
Settings settings = ImmutableSettings.builder().put(settingsSource.node(nodeOrdinal)).put(defaultSettings).build();
externalNode.startInternal(localNode, settings, nodeName, clusterName);
return externalNode;
}

View File

@ -103,6 +103,7 @@ import static com.carrotsearch.randomizedtesting.RandomizedTest.systemPropertyAs
import static junit.framework.Assert.fail;
import static org.apache.lucene.util.LuceneTestCase.rarely;
import static org.apache.lucene.util.LuceneTestCase.usually;
import static org.elasticsearch.common.settings.ImmutableSettings.EMPTY;
import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
import static org.elasticsearch.node.NodeBuilder.nodeBuilder;
import static org.elasticsearch.test.ElasticsearchTestCase.assertBusy;
@ -178,21 +179,21 @@ public final class InternalTestCluster extends TestCluster {
private final boolean enableRandomBenchNodes;
private final NodeSettingsSource nodeSettingsSource;
private final SettingsSource settingsSource;
private final ExecutorService executor;
private final boolean hasFilterCache;
public InternalTestCluster(long clusterSeed, String clusterName) {
this(clusterSeed, DEFAULT_MIN_NUM_DATA_NODES, DEFAULT_MAX_NUM_DATA_NODES, clusterName, NodeSettingsSource.EMPTY, DEFAULT_NUM_CLIENT_NODES, DEFAULT_ENABLE_RANDOM_BENCH_NODES);
this(clusterSeed, DEFAULT_MIN_NUM_DATA_NODES, DEFAULT_MAX_NUM_DATA_NODES, clusterName, SettingsSource.EMPTY, DEFAULT_NUM_CLIENT_NODES, DEFAULT_ENABLE_RANDOM_BENCH_NODES);
}
public InternalTestCluster(long clusterSeed, int minNumDataNodes, int maxNumDataNodes, String clusterName, int numClientNodes, boolean enableRandomBenchNodes) {
this(clusterSeed, minNumDataNodes, maxNumDataNodes, clusterName, NodeSettingsSource.EMPTY, numClientNodes, enableRandomBenchNodes);
this(clusterSeed, minNumDataNodes, maxNumDataNodes, clusterName, SettingsSource.EMPTY, numClientNodes, enableRandomBenchNodes);
}
public InternalTestCluster(long clusterSeed, int minNumDataNodes, int maxNumDataNodes, String clusterName, NodeSettingsSource nodeSettingsSource, int numClientNodes, boolean enableRandomBenchNodes) {
public InternalTestCluster(long clusterSeed, int minNumDataNodes, int maxNumDataNodes, String clusterName, SettingsSource settingsSource, int numClientNodes, boolean enableRandomBenchNodes) {
this.clusterName = clusterName;
if (minNumDataNodes < 0 || maxNumDataNodes < 0) {
@ -235,7 +236,7 @@ public final class InternalTestCluster extends TestCluster {
}
logger.info("Setup InternalTestCluster [{}] with seed [{}] using [{}] data nodes and [{}] client nodes", clusterName, SeedUtils.formatSeed(clusterSeed), numSharedDataNodes, numSharedClientNodes);
this.nodeSettingsSource = nodeSettingsSource;
this.settingsSource = settingsSource;
Builder builder = ImmutableSettings.settingsBuilder();
if (random.nextInt(5) == 0) { // sometimes set this
// randomize (multi/single) data path, special case for 0, don't set it at all...
@ -298,7 +299,7 @@ public final class InternalTestCluster extends TestCluster {
Builder builder = ImmutableSettings.settingsBuilder().put(defaultSettings)
.put(getRandomNodeSettings(nodeSeed))
.put(FilterCacheModule.FilterCacheSettings.FILTER_CACHE_TYPE, hasFilterCache() ? WeightedFilterCache.class : NoneFilterCache.class);
Settings settings = nodeSettingsSource.settings(nodeOrdinal);
Settings settings = settingsSource.node(nodeOrdinal);
if (settings != null) {
if (settings.get(ClusterName.SETTING) != null) {
throw new ElasticsearchIllegalStateException("Tests must not set a '" + ClusterName.SETTING + "' as a node setting set '" + ClusterName.SETTING + "': [" + settings.get(ClusterName.SETTING) + "]");
@ -519,7 +520,7 @@ public final class InternalTestCluster extends TestCluster {
.put("tests.mock.version", version)
.build();
Node node = nodeBuilder().settings(finalSettings).build();
return new NodeAndClient(name, node, new RandomClientFactory());
return new NodeAndClient(name, node, new RandomClientFactory(settingsSource));
}
private String buildNodeName(int id) {
@ -592,6 +593,17 @@ public final class InternalTestCluster extends TestCluster {
return getRandomNodeAndClient(new ClientNodePredicate()).client(random);
}
public synchronized Client startNodeClient(Settings settings) {
ensureOpen(); // currently unused
Builder builder = settingsBuilder().put(settings).put("node.client", true).put("node.data", false);
if (size() == 0) {
// if we are the first node - don't wait for a state
builder.put("discovery.initial_state_timeout", 0);
}
String name = startNode(builder);
return nodes.get(name).nodeClient();
}
/**
* Returns a transport client
*/
@ -711,7 +723,7 @@ public final class InternalTestCluster extends TestCluster {
if (maybeTransportClient instanceof TransportClient) {
transportClient = maybeTransportClient;
} else {
transportClient = TransportClientFactory.NO_SNIFF_CLIENT_FACTORY.client(node, clusterName, random);
transportClient = TransportClientFactory.noSniff(settingsSource.transportClient()).client(node, clusterName, random);
}
}
return transportClient;
@ -767,27 +779,46 @@ public final class InternalTestCluster extends TestCluster {
public static final String TRANSPORT_CLIENT_PREFIX = "transport_client_";
static class TransportClientFactory extends ClientFactory {
private boolean sniff;
public static TransportClientFactory NO_SNIFF_CLIENT_FACTORY = new TransportClientFactory(false);
public static TransportClientFactory SNIFF_CLIENT_FACTORY = new TransportClientFactory(true);
private static TransportClientFactory NO_SNIFF_CLIENT_FACTORY = new TransportClientFactory(false, ImmutableSettings.EMPTY);
private static TransportClientFactory SNIFF_CLIENT_FACTORY = new TransportClientFactory(true, ImmutableSettings.EMPTY);
private TransportClientFactory(boolean sniff) {
private final boolean sniff;
private final Settings settings;
public static TransportClientFactory noSniff(Settings settings) {
if (settings == null || settings.names().isEmpty()) {
return NO_SNIFF_CLIENT_FACTORY;
}
return new TransportClientFactory(false, settings);
}
public static TransportClientFactory sniff(Settings settings) {
if (settings == null || settings.names().isEmpty()) {
return SNIFF_CLIENT_FACTORY;
}
return new TransportClientFactory(true, settings);
}
TransportClientFactory(boolean sniff, Settings settings) {
this.sniff = sniff;
this.settings = settings != null ? settings : ImmutableSettings.EMPTY;
}
@Override
public Client client(Node node, String clusterName, Random random) {
TransportAddress addr = ((InternalNode) node).injector().getInstance(TransportService.class).boundAddress().publishAddress();
Settings nodeSettings = node.settings();
Builder builder = settingsBuilder().put("client.transport.nodes_sampler_interval", "1s")
Builder builder = settingsBuilder()
.put("client.transport.nodes_sampler_interval", "1s")
.put("name", TRANSPORT_CLIENT_PREFIX + node.settings().get("name"))
.put("plugins." + PluginsService.LOAD_PLUGIN_FROM_CLASSPATH, false)
.put(ClusterName.SETTING, clusterName).put("client.transport.sniff", sniff);
builder.put("node.mode", nodeSettings.get("node.mode", NODE_MODE));
builder.put("node.local", nodeSettings.get("node.local", ""));
builder.put("logger.prefix", nodeSettings.get("logger.prefix", ""));
builder.put("logger.level", nodeSettings.get("logger.level", "INFO"));
builder.put("config.ignore_system_properties", true);
.put(ClusterName.SETTING, clusterName).put("client.transport.sniff", sniff)
.put("node.mode", nodeSettings.get("node.mode", NODE_MODE))
.put("node.local", nodeSettings.get("node.local", ""))
.put("logger.prefix", nodeSettings.get("logger.prefix", ""))
.put("logger.level", nodeSettings.get("logger.level", "INFO"))
.put("config.ignore_system_properties", true)
.put(settings);
TransportClient client = new TransportClient(builder.build());
client.addTransportAddress(addr);
@ -797,6 +828,12 @@ public final class InternalTestCluster extends TestCluster {
class RandomClientFactory extends ClientFactory {
private SettingsSource settingsSource;
RandomClientFactory(SettingsSource settingsSource) {
this.settingsSource = settingsSource;
}
@Override
public Client client(Node node, String clusterName, Random random) {
double nextDouble = random.nextDouble();
@ -807,7 +844,7 @@ public final class InternalTestCluster extends TestCluster {
/* no sniff client for now - doesn't work will all tests since it might throw NoNodeAvailableException if nodes are shut down.
* we first need support of transportClientRatio as annotations or so
*/
return TransportClientFactory.NO_SNIFF_CLIENT_FACTORY.client(node, clusterName, random);
return TransportClientFactory.noSniff(settingsSource.transportClient()).client(node, clusterName, random);
} else {
return node.client();
}
@ -1200,16 +1237,6 @@ public final class InternalTestCluster extends TestCluster {
return Sets.newHashSet(Iterators.limit(dataNodes.keySet().iterator(), numNodes));
}
public synchronized void startNodeClient(Settings settings) {
ensureOpen(); // currently unused
Builder builder = settingsBuilder().put(settings).put("node.client", true).put("node.data", false);
if (size() == 0) {
// if we are the first node - don't wait for a state
builder.put("discovery.initial_state_timeout", 0);
}
startNode(builder);
}
/**
* Returns a set of nodes that have at least one shard of the given index.
*/

View File

@ -20,11 +20,16 @@ package org.elasticsearch.test;
import org.elasticsearch.common.settings.Settings;
abstract class NodeSettingsSource {
abstract class SettingsSource {
public static final NodeSettingsSource EMPTY = new NodeSettingsSource() {
public static final SettingsSource EMPTY = new SettingsSource() {
@Override
public Settings settings(int nodeOrdinal) {
public Settings node(int nodeOrdinal) {
return null;
}
@Override
public Settings transportClient() {
return null;
}
};
@ -32,6 +37,8 @@ abstract class NodeSettingsSource {
/**
* @return the settings for the node represented by the given ordinal, or {@code null} if there are no settings defined
*/
public abstract Settings settings(int nodeOrdinal);
public abstract Settings node(int nodeOrdinal);
public abstract Settings transportClient();
}