Add support for rest tests

This commit adds support for rest tests using the same yaml and json formatting as for core elasticsearch.
Also added is support for shield in the rest tests.

Original commit: elastic/x-pack-elasticsearch@bbeb9c0fc9
This commit is contained in:
Brian Murphy 2015-03-27 10:11:38 -04:00
parent baf0901b3a
commit 3a09914b67
5 changed files with 247 additions and 1 deletions

34
pom.xml
View File

@ -111,6 +111,21 @@
<scope>test</scope>
</dependency>
<dependency> <!-- required for rest tests -->
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-expressions</artifactId>
<version>${lucene.maven.version}</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<!-- Regular dependencies -->
<dependency>
@ -254,6 +269,25 @@
<filtering>true</filtering>
</resource>
</resources>
<testResources>
<testResource>
<directory>${basedir}/src/test/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</testResource>
<testResource>
<directory>${basedir}/rest-api-spec</directory>
<targetPath>rest-api-spec</targetPath>
<includes>
<include>api/*.json</include>
<include>test/**/*.yaml</include>
</includes>
</testResource>
</testResources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>

View File

@ -0,0 +1,20 @@
{
"watcher_stats": {
"documentation": "http://elastic.co/alertsdocs",
"methods": ["GET"],
"url": {
"path": "/_watcher/stats",
"paths": ["/_watcher/stats"],
"parts": {
},
"params": {
"pretty": {
"type": "boolean",
"description": "Pretty the output",
"default": false
}
}
},
"body": null
}
}

View File

@ -0,0 +1,9 @@
---
"Test watcher stats output":
- do:
watcher_stats:
pretty: true
- match: { "watch_service_state": "started" }
- match: { "watch_count": 0 }
- match: { "execution_queue": { "size": 0, "max_size": 0 } }

View File

@ -37,6 +37,7 @@ public class RestWatcherStatsAction extends WatcherRestHandler {
watcherClient.watcherStats(new WatcherStatsRequest(), new RestBuilderListener<WatcherStatsResponse>(restChannel) {
@Override
public RestResponse buildResponse(WatcherStatsResponse watcherStatsResponse, XContentBuilder builder) throws Exception {
builder.startObject();
builder.field("watch_service_state", watcherStatsResponse.getWatchServiceState().toString().toLowerCase(Locale.ROOT))
.field("watch_count", watcherStatsResponse.getWatchesCount());
@ -44,7 +45,7 @@ public class RestWatcherStatsAction extends WatcherRestHandler {
.field("size", watcherStatsResponse.getExecutionQueueSize())
.field("max_size", watcherStatsResponse.getWatchExecutionQueueMaxSize())
.endObject();
builder.endObject();
return new BytesRestResponse(OK, builder);
}

View File

@ -0,0 +1,182 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.test.rest;
import com.carrotsearch.randomizedtesting.annotations.Name;
import org.apache.lucene.util.AbstractRandomizedTest;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.common.base.Charsets;
import org.elasticsearch.common.io.FileSystemUtils;
import org.elasticsearch.common.io.Streams;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.license.plugin.LicensePlugin;
import org.elasticsearch.node.internal.InternalNode;
import org.elasticsearch.shield.ShieldPlugin;
import org.elasticsearch.shield.authc.esusers.ESUsersRealm;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.elasticsearch.test.junit.annotations.TestLogging;
import org.elasticsearch.test.rest.ElasticsearchRestTests;
import org.elasticsearch.test.rest.RestTestCandidate;
import org.elasticsearch.watcher.WatcherPlugin;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
@AbstractRandomizedTest.Rest
@ElasticsearchIntegrationTest.ClusterScope(scope = ElasticsearchIntegrationTest.Scope.SUITE, numClientNodes = 1, transportClientRatio = 0, numDataNodes = 1, randomDynamicTemplates = false)
@TestLogging("_root:DEBUG")
public class WatcherRestTests extends ElasticsearchRestTests {
private final boolean shieldEnabled = randomBoolean();
public WatcherRestTests(@Name("yaml") RestTestCandidate testCandidate) {
super(testCandidate);
}
@Override
protected Settings nodeSettings(int nodeOrdinal) {
return ImmutableSettings.builder()
.put(super.nodeSettings(nodeOrdinal))
.put("scroll.size", randomIntBetween(1, 100))
.put("plugin.types", WatcherPlugin.class.getName() + ","
+ (shieldEnabled ? ShieldPlugin.class.getName() + "," : "")
+ "," + LicensePlugin.class.getName())
.put(InternalNode.HTTP_ENABLED, true)
.put("shield.user", "admin:changeme")
.put(ShieldSettings.settings(shieldEnabled))
.build();
}
/**
* Used to obtain settings for the REST client that is used to send REST requests.
*/
@Override
protected Settings restClientSettings() {
if (shieldEnabled) {
return ImmutableSettings.builder()
.put("client.transport.sniff", false)
.put("plugin.types", WatcherPlugin.class.getName() + ","
+ (shieldEnabled ? ShieldPlugin.class.getName() + "," : "")
+ "," + LicensePlugin.class.getName())
.put(InternalNode.HTTP_ENABLED, true)
.put("shield.user", "admin:changeme")
.put(ShieldSettings.settings(shieldEnabled))
.build();
}
return ImmutableSettings.builder()
.put("plugin.types", WatcherPlugin.class.getName())
.put(InternalNode.HTTP_ENABLED, true)
.build();
}
@Override
protected Settings transportClientSettings() {
if (shieldEnabled) {
return ImmutableSettings.builder()
.put(super.transportClientSettings())
.put("client.transport.sniff", false)
.put("plugin.types", WatcherPlugin.class.getName() + ","
+ (shieldEnabled ? ShieldPlugin.class.getName() + "," : ""))
.put(ShieldSettings.settings(shieldEnabled))
.put("shield.user", "admin:changeme")
.put(InternalNode.HTTP_ENABLED, true)
.build();
}
return ImmutableSettings.builder()
.put("plugin.types", WatcherPlugin.class.getName())
.put(InternalNode.HTTP_ENABLED, true)
.build();
}
/** Shield related settings */
public static class ShieldSettings {
public static final String IP_FILTER = "allow: all\n";
public static final String USERS = "test:{plain}changeme\n" +
"admin:{plain}changeme\n" +
"monitor:{plain}changeme";
public static final String USER_ROLES = "test:test\n" +
"admin:admin\n" +
"monitor:monitor";
public static final String ROLES =
"test:\n" + // a user for the test infra.
" cluster: all, manage_watcher\n" +
" indices:\n" +
" '*': all\n" +
"\n" +
"admin:\n" +
" cluster: manage_watcher, cluster:monitor/nodes/info, cluster:monitor/state, cluster:monitor/health, cluster:admin/repository/delete\n" +
" indices:\n" +
" '*': all, indices:admin/template/delete\n" +
"\n" +
"monitor:\n" +
" cluster: monitor_watcher, cluster:monitor/nodes/info\n" +
"\n"
;
public static Settings settings(boolean enabled) {
ImmutableSettings.Builder builder = ImmutableSettings.builder();
if (!enabled) {
return builder.put("shield.enabled", false).build();
}
File folder = createFolder(globalTempDir(), "watcher_shield");
return builder.put("shield.enabled", true)
.put("shield.user", "test:changeme")
.put("shield.authc.realms.esusers.type", ESUsersRealm.TYPE)
.put("shield.authc.anonymous.username","anonymous_user")
.put("shield.authc.anonymous.roles", "monitor")
.put("shield.authc.realms.esusers.order", 0)
.put("shield.authc.realms.esusers.files.users", writeFile(folder, "users", USERS))
.put("shield.authc.realms.esusers.files.users_roles", writeFile(folder, "users_roles", USER_ROLES))
.put("shield.authz.store.files.roles", writeFile(folder, "roles.yml", ROLES))
.put("shield.transport.n2n.ip_filter.file", writeFile(folder, "ip_filter.yml", IP_FILTER))
.put("shield.audit.enabled", true)
.build();
}
static File createFolder(File parent, String name) {
File createdFolder = new File(parent, name);
//the directory might exist e.g. if the global cluster gets restarted, then we recreate the directory as well
if (createdFolder.exists()) {
if (!FileSystemUtils.deleteRecursively(createdFolder)) {
throw new RuntimeException("could not delete existing temporary folder: " + createdFolder.getAbsolutePath());
}
}
if (!createdFolder.mkdir()) {
throw new RuntimeException("could not create temporary folder: " + createdFolder.getAbsolutePath());
}
return createdFolder;
}
static String writeFile(File folder, String name, String content) {
return writeFile(folder, name, content.getBytes(Charsets.UTF_8));
}
static String writeFile(File folder, String name, byte[] content) {
Path file = folder.toPath().resolve(name);
try {
Streams.copy(content, file.toFile());
} catch (IOException e) {
throw new ElasticsearchException("error writing file in test", e);
}
return file.toFile().getAbsolutePath();
}
}
}