[cloud-gce] replace integration tests by unit tests

We use google transport mock as we can simulate whatever JSON answer GCE platform will send us and really test Gce implementation.

We also remove GceSimpleITest as the goal of this class was only to check that when we start elasticsearch with this plugin, elasticsearch works fine.
We don't need that anymore as we now have RestIT which do that right (and better)!

Closes #12622
This commit is contained in:
David Pilato 2015-08-10 13:08:21 +02:00
parent 99fccddcf2
commit beb7e16a43
32 changed files with 936 additions and 910 deletions

View File

@ -401,30 +401,6 @@ If you have created a machine without the correct permissions, you will see `403
way to alter these permissions is to delete the instance (NOT THE DISK). Then create another with the correct permissions. way to alter these permissions is to delete the instance (NOT THE DISK). Then create another with the correct permissions.
Testing
=======
Integrations tests in this plugin require working GCE configuration and therefore disabled by default.
To enable tests prepare a config file elasticsearch.yml with the following content:
```
cloud:
gce:
project_id: es-cloud
zone: europe-west1-a
discovery:
type: gce
```
Replaces `project_id` and `zone` with your settings.
To run test:
```sh
mvn -Dtests.gce=true -Dtests.config=/path/to/config/file/elasticsearch.yml clean test
```
License License
------- -------

View File

@ -1 +0,0 @@
cfcaa34e7743f493808835cc1f3d70950a848e22

View File

@ -0,0 +1 @@
2fa36fff3b5bf59a63c4f2bbfac1f88251cd7986

View File

@ -28,10 +28,7 @@ governing permissions and limitations under the License. -->
<properties> <properties>
<elasticsearch.plugin.classname>org.elasticsearch.plugin.cloud.gce.CloudGcePlugin</elasticsearch.plugin.classname> <elasticsearch.plugin.classname>org.elasticsearch.plugin.cloud.gce.CloudGcePlugin</elasticsearch.plugin.classname>
<google.gce.version>v1-rev71-1.20.0</google.gce.version> <google.gce.version>v1-rev71-1.20.0</google.gce.version>
<es.plugin.port>9300</es.plugin.port>
<!-- currently has no unit tests --> <!-- currently has no unit tests -->
<tests.ifNoTests>warn</tests.ifNoTests>
<tests.jvms>1</tests.jvms>
<tests.rest.suite>cloud_gce</tests.rest.suite> <tests.rest.suite>cloud_gce</tests.rest.suite>
<tests.rest.load_packaged>false</tests.rest.load_packaged> <tests.rest.load_packaged>false</tests.rest.load_packaged>
</properties> </properties>

View File

@ -34,12 +34,13 @@ import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.common.component.AbstractLifecycleComponent; import org.elasticsearch.common.component.AbstractLifecycleComponent;
import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsFilter;
import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.unit.TimeValue;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.List; import java.util.List;
/** /**
@ -49,26 +50,26 @@ public class GceComputeServiceImpl extends AbstractLifecycleComponent<GceCompute
implements GceComputeService { implements GceComputeService {
private final String project; private final String project;
private final List<String> zoneList; private final List<String> zones;
// Forcing Google Token API URL as set in GCE SDK to // Forcing Google Token API URL as set in GCE SDK to
// http://metadata/computeMetadata/v1/instance/service-accounts/default/token // http://metadata/computeMetadata/v1/instance/service-accounts/default/token
// See https://developers.google.com/compute/docs/metadata#metadataserver // See https://developers.google.com/compute/docs/metadata#metadataserver
private static final String TOKEN_SERVER_ENCODED_URL = "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"; public static final String TOKEN_SERVER_ENCODED_URL = "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token";
@Override @Override
public Collection<Instance> instances() { public Collection<Instance> instances() {
logger.debug("get instances for project [{}], zoneList [{}]", project, zoneList); logger.debug("get instances for project [{}], zones [{}]", project, zones);
List<List<Instance>> instanceListByZone = Lists.transform(zoneList, new Function<String, List<Instance>>() { List<List<Instance>> instanceListByZone = Lists.transform(zones, new Function<String, List<Instance>>() {
@Override @Override
public List<Instance> apply(String zoneId) { public List<Instance> apply(String zoneId) {
try { try {
Compute.Instances.List list = client().instances().list(project, zoneId); Compute.Instances.List list = client().instances().list(project, zoneId);
InstanceList instanceList = list.execute(); InstanceList instanceList = list.execute();
if (instanceList.isEmpty()) { if (instanceList.isEmpty()) {
return new ArrayList(); return Collections.EMPTY_LIST;
} }
return instanceList.getItems(); return instanceList.getItems();
@ -76,7 +77,7 @@ public class GceComputeServiceImpl extends AbstractLifecycleComponent<GceCompute
logger.warn("Problem fetching instance list for zone {}", zoneId); logger.warn("Problem fetching instance list for zone {}", zoneId);
logger.debug("Full exception:", e); logger.debug("Full exception:", e);
return new ArrayList(); return Collections.EMPTY_LIST;
} }
} }
}); });
@ -96,17 +97,24 @@ public class GceComputeServiceImpl extends AbstractLifecycleComponent<GceCompute
private long lastRefresh; private long lastRefresh;
/** Global instance of the HTTP transport. */ /** Global instance of the HTTP transport. */
private static HttpTransport HTTP_TRANSPORT; private HttpTransport gceHttpTransport;
/** Global instance of the JSON factory. */ /** Global instance of the JSON factory. */
private static JsonFactory JSON_FACTORY; private JsonFactory gceJsonFactory;
@Inject @Inject
public GceComputeServiceImpl(Settings settings, SettingsFilter settingsFilter) { public GceComputeServiceImpl(Settings settings) {
super(settings); super(settings);
this.project = settings.get(Fields.PROJECT); this.project = settings.get(Fields.PROJECT);
String[] zoneList = settings.getAsArray(Fields.ZONE); String[] zoneList = settings.getAsArray(Fields.ZONE);
this.zoneList = Lists.newArrayList(zoneList); this.zones = Arrays.asList(zoneList);
}
protected synchronized HttpTransport getGceHttpTransport() throws GeneralSecurityException, IOException {
if (gceHttpTransport == null) {
gceHttpTransport = GoogleNetHttpTransport.newTrustedTransport();
}
return gceHttpTransport;
} }
public synchronized Compute client() { public synchronized Compute client() {
@ -120,27 +128,27 @@ public class GceComputeServiceImpl extends AbstractLifecycleComponent<GceCompute
} }
try { try {
HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport(); gceJsonFactory = new JacksonFactory();
JSON_FACTORY = new JacksonFactory();
logger.info("starting GCE discovery service"); logger.info("starting GCE discovery service");
ComputeCredential credential = new ComputeCredential.Builder(getGceHttpTransport(), gceJsonFactory)
ComputeCredential credential = new ComputeCredential.Builder(HTTP_TRANSPORT, JSON_FACTORY)
.setTokenServerEncodedUrl(TOKEN_SERVER_ENCODED_URL) .setTokenServerEncodedUrl(TOKEN_SERVER_ENCODED_URL)
.build(); .build();
credential.refreshToken(); credential.refreshToken();
logger.debug("token [{}] will expire in [{}] s", credential.getAccessToken(), credential.getExpiresInSeconds()); logger.debug("token [{}] will expire in [{}] s", credential.getAccessToken(), credential.getExpiresInSeconds());
if (credential.getExpiresInSeconds() != null) {
refreshInterval = TimeValue.timeValueSeconds(credential.getExpiresInSeconds()-1); refreshInterval = TimeValue.timeValueSeconds(credential.getExpiresInSeconds()-1);
}
// Once done, let's use this token // Once done, let's use this token
this.client = new Compute.Builder(HTTP_TRANSPORT, JSON_FACTORY, null) this.client = new Compute.Builder(getGceHttpTransport(), gceJsonFactory, null)
.setApplicationName(Fields.VERSION) .setApplicationName(Fields.VERSION)
.setHttpRequestInitializer(credential) .setHttpRequestInitializer(credential)
.build(); .build();
} catch (Exception e) { } catch (Exception e) {
logger.warn("unable to start GCE discovery service: {} : {}", e.getClass().getName(), e.getMessage()); logger.warn("unable to start GCE discovery service", e);
throw new IllegalArgumentException("unable to start GCE discovery service", e); throw new IllegalArgumentException("unable to start GCE discovery service", e);
} }
@ -153,6 +161,14 @@ public class GceComputeServiceImpl extends AbstractLifecycleComponent<GceCompute
@Override @Override
protected void doStop() throws ElasticsearchException { protected void doStop() throws ElasticsearchException {
if (gceHttpTransport != null) {
try {
gceHttpTransport.shutdown();
} catch (IOException e) {
logger.warn("unable to shutdown GCE Http Transport", e);
}
gceHttpTransport = null;
}
} }
@Override @Override

View File

@ -59,7 +59,7 @@ public class GceUnicastHostsProvider extends AbstractComponent implements Unicas
private final Version version; private final Version version;
private final String project; private final String project;
private final String zone; private final String[] zones;
private final String[] tags; private final String[] tags;
private final TimeValue refreshInterval; private final TimeValue refreshInterval;
@ -79,11 +79,11 @@ public class GceUnicastHostsProvider extends AbstractComponent implements Unicas
this.refreshInterval = settings.getAsTime(Fields.REFRESH, TimeValue.timeValueSeconds(0)); this.refreshInterval = settings.getAsTime(Fields.REFRESH, TimeValue.timeValueSeconds(0));
this.project = settings.get(Fields.PROJECT); this.project = settings.get(Fields.PROJECT);
this.zone = settings.get(Fields.ZONE); this.zones = settings.getAsArray(Fields.ZONE);
// Check that we have all needed properties // Check that we have all needed properties
checkProperty(Fields.PROJECT, project); checkProperty(Fields.PROJECT, project);
checkProperty(Fields.ZONE, zone); checkProperty(Fields.ZONE, zones);
this.tags = settings.getAsArray(Fields.TAGS); this.tags = settings.getAsArray(Fields.TAGS);
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
@ -125,7 +125,7 @@ public class GceUnicastHostsProvider extends AbstractComponent implements Unicas
Collection<Instance> instances = gceComputeService.instances(); Collection<Instance> instances = gceComputeService.instances();
if (instances == null) { if (instances == null) {
logger.trace("no instance found for project [{}], zone [{}].", this.project, this.zone); logger.trace("no instance found for project [{}], zones [{}].", this.project, this.zones);
return cachedDiscoNodes; return cachedDiscoNodes;
} }
@ -172,7 +172,7 @@ public class GceUnicastHostsProvider extends AbstractComponent implements Unicas
} }
if (filterByTag) { if (filterByTag) {
logger.trace("filtering out instance {} based tags {}, not part of {}", name, tags, logger.trace("filtering out instance {} based tags {}, not part of {}", name, tags,
instance.getTags() == null || instance.getTags().getItems() == null ? "" : ""); instance.getTags() == null || instance.getTags().getItems() == null ? "" : instance.getTags());
continue; continue;
} else { } else {
logger.trace("instance {} with tags {} is added to discovery", name, tags); logger.trace("instance {} with tags {} is added to discovery", name, tags);
@ -253,4 +253,10 @@ public class GceUnicastHostsProvider extends AbstractComponent implements Unicas
logger.warn("{} is not set.", name); logger.warn("{} is not set.", name);
} }
} }
private void checkProperty(String name, String[] values) {
if (values == null || values.length == 0) {
logger.warn("{} is not set.", name);
}
}
} }

View File

@ -1,58 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.cloud.gce;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment;
import org.elasticsearch.env.FailedToResolveConfigException;
import org.elasticsearch.plugin.cloud.gce.CloudGcePlugin;
import org.elasticsearch.test.ESIntegTestCase;
import org.elasticsearch.test.ESIntegTestCase.ThirdParty;
/**
*
*/
@ThirdParty
public abstract class AbstractGceTest extends ESIntegTestCase {
@Override
protected Settings nodeSettings(int nodeOrdinal) {
Settings.Builder settings = Settings.builder()
.put(super.nodeSettings(nodeOrdinal))
.put("path.home", createTempDir())
.put("plugin.types", CloudGcePlugin.class.getName());
Environment environment = new Environment(settings.build());
// if explicit, just load it and don't load from env
try {
if (Strings.hasText(System.getProperty("tests.config"))) {
settings.loadFromUrl(environment.resolveConfig(System.getProperty("tests.config")));
} else {
throw new IllegalStateException("to run integration tests, you need to set -Dtests.thirdparty=true and -Dtests.config=/path/to/elasticsearch.yml");
}
} catch (FailedToResolveConfigException exception) {
throw new IllegalStateException("your test configuration file is incorrect: " + System.getProperty("tests.config"), exception);
}
return settings.build();
}
}

View File

@ -1,69 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.cloud.gce;
import org.elasticsearch.cloud.gce.GceModule;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.discovery.gce.mock.GceComputeServiceAbstractMock;
import org.elasticsearch.plugins.AbstractPlugin;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
*
*/
public class GceComputeServiceTwoNodesDifferentTagsMock extends GceComputeServiceAbstractMock {
public static class Plugin extends AbstractPlugin {
@Override
public String name() {
return "mock-compute-service";
}
@Override
public String description() {
return "a mock compute service for testing";
}
public void onModule(GceModule gceModule) {
gceModule.computeServiceImpl = GceComputeServiceTwoNodesDifferentTagsMock.class;
}
}
private static List<List<String>> tags = Arrays.asList(
Arrays.asList("dev"),
Arrays.asList("elasticsearch", "dev"));
@Override
protected List<List<String>> getTags() {
return tags;
}
@Override
protected List<String> getZones() {
return new ArrayList();
}
@Inject
protected GceComputeServiceTwoNodesDifferentTagsMock(Settings settings) {
super(settings);
}
}

View File

@ -1,62 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.cloud.gce;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.discovery.gce.mock.GceComputeServiceAbstractMock;
import org.elasticsearch.plugins.AbstractPlugin;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class GceComputeServiceTwoNodesOneZoneMock extends GceComputeServiceAbstractMock {
public static class Plugin extends AbstractPlugin {
@Override
public String name() {
return "mock-compute-service";
}
@Override
public String description() {
return "a mock compute service for testing";
}
public void onModule(GceModule gceModule) {
gceModule.computeServiceImpl = GceComputeServiceTwoNodesOneZoneMock.class;
}
}
private static List<String> zones = Arrays.asList("us-central1-a", "us-central1-a");
@Override
protected List<List<String>> getTags() {
return new ArrayList<>();
}
@Override
protected List<String> getZones() {
return zones;
}
@Inject
protected GceComputeServiceTwoNodesOneZoneMock(Settings settings) {
super(settings);
}
}

View File

@ -1,65 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.cloud.gce;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.discovery.gce.mock.GceComputeServiceAbstractMock;
import org.elasticsearch.plugins.AbstractPlugin;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class GceComputeServiceTwoNodesSameTagsMock extends GceComputeServiceAbstractMock {
public static class Plugin extends AbstractPlugin {
@Override
public String name() {
return "mock-compute-service";
}
@Override
public String description() {
return "a mock compute service for testing";
}
public void onModule(GceModule gceModule) {
gceModule.computeServiceImpl = GceComputeServiceTwoNodesSameTagsMock.class;
}
}
private static List<List<String>> tags = Arrays.asList(
Arrays.asList("elasticsearch", "dev"),
Arrays.asList("elasticsearch", "dev"));
@Override
protected List<List<String>> getTags() {
return tags;
}
@Override
protected List<String> getZones() {
return new ArrayList<>();
}
@Inject
protected GceComputeServiceTwoNodesSameTagsMock(Settings settings) {
super(settings);
}
}

View File

@ -1,62 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.cloud.gce;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.discovery.gce.mock.GceComputeServiceAbstractMock;
import org.elasticsearch.plugins.AbstractPlugin;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class GceComputeServiceTwoNodesTwoZonesMock extends GceComputeServiceAbstractMock {
public static class Plugin extends AbstractPlugin {
@Override
public String name() {
return "mock-compute-service";
}
@Override
public String description() {
return "a mock compute service for testing";
}
public void onModule(GceModule gceModule) {
gceModule.computeServiceImpl = GceComputeServiceTwoNodesTwoZonesMock.class;
}
}
private static List<String> zones = Arrays.asList("us-central1-a", "europe-west1-a");
@Override
protected List<List<String>> getTags() {
return new ArrayList();
}
@Override
protected List<String> getZones() {
return zones;
}
@Inject
protected GceComputeServiceTwoNodesTwoZonesMock(Settings settings) {
super(settings);
}
}

View File

@ -1,90 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.cloud.gce;
import com.google.api.services.compute.model.Instance;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.discovery.gce.mock.GceComputeServiceAbstractMock;
import org.elasticsearch.plugins.AbstractPlugin;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class GceComputeServiceZeroNodeMock extends GceComputeServiceAbstractMock {
public static class Plugin extends AbstractPlugin {
@Override
public String name() {
return "mock-compute-service";
}
@Override
public String description() {
return "a mock compute service for testing";
}
public void onModule(GceModule gceModule) {
gceModule.computeServiceImpl = GceComputeServiceZeroNodeMock.class;
}
}
@Override
protected List<List<String>> getTags() {
return new ArrayList();
}
@Override
protected List<String> getZones() {
return new ArrayList();
}
private final List<String> zoneList;
@Override
public Collection<Instance> instances() {
logger.debug("get instances for zoneList [{}]", zoneList);
List<List<Instance>> instanceListByZone = Lists.transform(zoneList, new Function<String, List<Instance>>() {
@Override
public List<Instance> apply(String zoneId) {
// If we return null here we will get a trace as explained in issue 43
return new ArrayList();
}
});
//Collapse instances from all zones into one neat list
List<Instance> instanceList = Lists.newArrayList(Iterables.concat(instanceListByZone));
if (instanceList.size() == 0) {
logger.warn("disabling GCE discovery. Can not get list of nodes");
}
return instanceList;
}
@Inject
protected GceComputeServiceZeroNodeMock(Settings settings) {
super(settings);
String[] zoneList = settings.getAsArray(Fields.ZONE);
this.zoneList = Lists.newArrayList(zoneList);
}
}

View File

@ -1,227 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.discovery.gce;
import com.google.common.collect.Lists;
import org.apache.lucene.util.LuceneTestCase;
import org.elasticsearch.action.admin.cluster.node.info.NodesInfoResponse;
import org.elasticsearch.cloud.gce.GceComputeService.Fields;
import org.elasticsearch.cloud.gce.GceComputeServiceTwoNodesDifferentTagsMock;
import org.elasticsearch.cloud.gce.GceComputeServiceTwoNodesOneZoneMock;
import org.elasticsearch.cloud.gce.GceComputeServiceTwoNodesSameTagsMock;
import org.elasticsearch.cloud.gce.GceComputeServiceTwoNodesTwoZonesMock;
import org.elasticsearch.cloud.gce.GceComputeServiceZeroNodeMock;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.plugin.cloud.gce.CloudGcePlugin;
import org.elasticsearch.test.ESIntegTestCase;
import org.junit.Test;
import java.io.IOException;
import static org.hamcrest.Matchers.notNullValue;
@ESIntegTestCase.ClusterScope(
scope = ESIntegTestCase.Scope.TEST,
numDataNodes = 0,
numClientNodes = 0,
transportClientRatio = 0.0)
@LuceneTestCase.AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/12622")
public class GceComputeEngineTest extends ESIntegTestCase {
public static int getPort(int nodeOrdinal) {
try {
return PropertiesHelper.getAsInt("plugin.port")
+ nodeOrdinal * 10;
} catch (IOException e) {
}
return -1;
}
protected void checkNumberOfNodes(int expected) {
NodesInfoResponse nodeInfos = client().admin().cluster().prepareNodesInfo().execute().actionGet();
assertNotNull(nodeInfos);
assertNotNull(nodeInfos.getNodes());
assertEquals(expected, nodeInfos.getNodes().length);
}
protected Settings settingsBuilder(int nodeOrdinal, String mockClass, Settings settings) {
Settings.Builder builder = Settings.settingsBuilder()
.put("discovery.type", "gce")
// We need the network to make the mock working
.put("node.mode", "network")
// Make the tests run faster
.put("discovery.zen.join.timeout", "100ms")
.put("discovery.zen.ping.timeout", "10ms")
.put("discovery.initial_state_timeout", "300ms")
// We use a specific port for each node
.put("transport.tcp.port", getPort(nodeOrdinal))
// We disable http
.put("http.enabled", false)
// We force plugin loading
.extendArray("plugin.types", CloudGcePlugin.class.getName(), mockClass)
.put(settings)
.put(super.nodeSettings(nodeOrdinal));
return builder.build();
}
protected void startNode(int nodeOrdinal, String mockClass, Settings settings) {
logger.info("--> start node #{}, mock [{}], settings [{}]", nodeOrdinal, mockClass, settings.getAsMap());
internalCluster().startNode(settingsBuilder(
nodeOrdinal,
mockClass,
settings));
assertThat(client().admin().cluster().prepareState().setMasterNodeTimeout("1s").execute().actionGet().getState().nodes().masterNodeId(), notNullValue());
}
@Test
public void nodes_with_different_tags_and_no_tag_set() {
startNode(1,
GceComputeServiceTwoNodesDifferentTagsMock.Plugin.class.getName(),
Settings.EMPTY);
startNode(2,
GceComputeServiceTwoNodesDifferentTagsMock.Plugin.class.getName(),
Settings.EMPTY);
// We expect having 2 nodes as part of the cluster, let's test that
checkNumberOfNodes(2);
}
/**
* We need to ignore this test from elasticsearch version 1.2.1 as
* expected nodes running is 2 and this test will create 2 clusters with one node each.
* @see ESIntegTestCase#ensureClusterSizeConsistency()
* TODO Reactivate when it will be possible to set the number of running nodes
*/
@Test
public void nodes_with_different_tags_and_one_tag_set() {
startNode(1,
GceComputeServiceTwoNodesDifferentTagsMock.Plugin.class.getName(),
Settings.settingsBuilder().put(Fields.TAGS, "elasticsearch").build());
startNode(2,
GceComputeServiceTwoNodesDifferentTagsMock.Plugin.class.getName(),
Settings.settingsBuilder().put(Fields.TAGS, "elasticsearch").build());
// We expect having 1 nodes as part of the cluster, let's test that
checkNumberOfNodes(1);
}
/**
* We need to ignore this test from elasticsearch version 1.2.1 as
* expected nodes running is 2 and this test will create 2 clusters with one node each.
* @see ESIntegTestCase#ensureClusterSizeConsistency()
* TODO Reactivate when it will be possible to set the number of running nodes
*/
@Test
public void nodes_with_different_tags_and_two_tag_set() {
startNode(1,
GceComputeServiceTwoNodesDifferentTagsMock.Plugin.class.getName(),
Settings.settingsBuilder().put(Fields.TAGS, Lists.newArrayList("elasticsearch", "dev")).build());
startNode(2,
GceComputeServiceTwoNodesDifferentTagsMock.Plugin.class.getName(),
Settings.settingsBuilder().put(Fields.TAGS, Lists.newArrayList("elasticsearch", "dev")).build());
// We expect having 1 nodes as part of the cluster, let's test that
checkNumberOfNodes(1);
}
@Test
public void nodes_with_same_tags_and_no_tag_set() {
startNode(1,
GceComputeServiceTwoNodesSameTagsMock.Plugin.class.getName(),
Settings.EMPTY);
startNode(2,
GceComputeServiceTwoNodesSameTagsMock.Plugin.class.getName(),
Settings.EMPTY);
// We expect having 2 nodes as part of the cluster, let's test that
checkNumberOfNodes(2);
}
@Test
public void nodes_with_same_tags_and_one_tag_set() {
startNode(1,
GceComputeServiceTwoNodesSameTagsMock.Plugin.class.getName(),
Settings.settingsBuilder().put(Fields.TAGS, "elasticsearch").build());
startNode(2,
GceComputeServiceTwoNodesSameTagsMock.Plugin.class.getName(),
Settings.settingsBuilder().put(Fields.TAGS, "elasticsearch").build());
// We expect having 2 nodes as part of the cluster, let's test that
checkNumberOfNodes(2);
}
@Test
public void nodes_with_same_tags_and_two_tags_set() {
startNode(1,
GceComputeServiceTwoNodesSameTagsMock.Plugin.class.getName(),
Settings.settingsBuilder().put(Fields.TAGS, Lists.newArrayList("elasticsearch", "dev")).build());
startNode(2,
GceComputeServiceTwoNodesSameTagsMock.Plugin.class.getName(),
Settings.settingsBuilder().put(Fields.TAGS, Lists.newArrayList("elasticsearch", "dev")).build());
// We expect having 2 nodes as part of the cluster, let's test that
checkNumberOfNodes(2);
}
@Test
public void multiple_zones_and_two_nodes_in_same_zone() {
startNode(1,
GceComputeServiceTwoNodesOneZoneMock.Plugin.class.getName(),
Settings.settingsBuilder().put(Fields.ZONE, Lists.newArrayList("us-central1-a", "us-central1-b",
"us-central1-f", "europe-west1-a", "europe-west1-b")).build());
startNode(2,
GceComputeServiceTwoNodesOneZoneMock.Plugin.class.getName(),
Settings.settingsBuilder().put(Fields.ZONE, Lists.newArrayList("us-central1-a", "us-central1-b",
"us-central1-f", "europe-west1-a", "europe-west1-b")).build());
// We expect having 2 nodes as part of the cluster, let's test that
checkNumberOfNodes(2);
}
@Test
public void multiple_zones_and_two_nodes_in_different_zones() {
startNode(1,
GceComputeServiceTwoNodesTwoZonesMock.Plugin.class.getName(),
Settings.settingsBuilder().put(Fields.ZONE, Lists.newArrayList("us-central1-a", "us-central1-b",
"us-central1-f", "europe-west1-a", "europe-west1-b")).build());
startNode(2,
GceComputeServiceTwoNodesTwoZonesMock.Plugin.class.getName(),
Settings.settingsBuilder().put(Fields.ZONE, Lists.newArrayList("us-central1-a", "us-central1-b",
"us-central1-f", "europe-west1-a", "europe-west1-b")).build());
// We expect having 2 nodes as part of the cluster, let's test that
checkNumberOfNodes(2);
}
/**
* For issue https://github.com/elastic/elasticsearch-cloud-gce/issues/43
*/
@Test
public void zero_node_43() {
startNode(1,
GceComputeServiceZeroNodeMock.Plugin.class.getName(),
Settings.settingsBuilder().put(Fields.ZONE, Lists.newArrayList("us-central1-a", "us-central1-b",
"us-central1-f", "europe-west1-a", "europe-west1-b")).build());
}
}

View File

@ -0,0 +1,113 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.discovery.gce;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.LowLevelHttpRequest;
import com.google.api.client.http.LowLevelHttpResponse;
import com.google.api.client.json.Json;
import com.google.api.client.testing.http.MockHttpTransport;
import com.google.api.client.testing.http.MockLowLevelHttpRequest;
import com.google.api.client.testing.http.MockLowLevelHttpResponse;
import org.elasticsearch.cloud.gce.GceComputeServiceImpl;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.Streams;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.Callback;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.GeneralSecurityException;
/**
*
*/
public class GceComputeServiceMock extends GceComputeServiceImpl {
protected HttpTransport mockHttpTransport;
public GceComputeServiceMock(Settings settings) {
super(settings);
this.mockHttpTransport = configureMock();
}
@Override
protected HttpTransport getGceHttpTransport() throws GeneralSecurityException, IOException {
return this.mockHttpTransport;
}
protected HttpTransport configureMock() {
HttpTransport transport = new MockHttpTransport() {
@Override
public LowLevelHttpRequest buildRequest(String method, final String url) throws IOException {
return new MockLowLevelHttpRequest() {
@Override
public LowLevelHttpResponse execute() throws IOException {
MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
response.setStatusCode(200);
response.setContentType(Json.MEDIA_TYPE);
if (url.equals(TOKEN_SERVER_ENCODED_URL)) {
logger.info("--> Simulate GCE Auth response for [{}]", url);
response.setContent(readGoogleInternalJsonResponse(url));
} else {
logger.info("--> Simulate GCE API response for [{}]", url);
response.setContent(readGoogleApiJsonResponse(url));
}
return response;
}
};
}
};
return transport;
}
private String readGoogleInternalJsonResponse(String url) throws IOException {
return readJsonResponse(url, "http://metadata.google.internal/");
}
private String readGoogleApiJsonResponse(String url) throws IOException {
return readJsonResponse(url, "https://www.googleapis.com/");
}
private String readJsonResponse(String url, String urlRoot) throws IOException {
// We extract from the url the mock file path we want to use
String mockFileName = Strings.replace(url, urlRoot, "") + ".json";
logger.debug("--> read mock file from [{}]", mockFileName);
URL resource = GceComputeServiceMock.class.getResource(mockFileName);
try (InputStream is = resource.openStream()) {
final StringBuilder sb = new StringBuilder();
Streams.readAllLines(is, new Callback<String>() {
@Override
public void handle(String s) {
sb.append(s).append("\n");
}
});
String response = sb.toString();
logger.trace("{}", response);
return response;
} catch (IOException e) {
throw e;
}
}
}

View File

@ -0,0 +1,217 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.discovery.gce;
import org.elasticsearch.Version;
import org.elasticsearch.cloud.gce.GceComputeService;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
import org.elasticsearch.common.network.NetworkService;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.transport.MockTransportService;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.local.LocalTransport;
import org.junit.*;
import java.util.List;
import java.util.Locale;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
/**
* This test class uses a GCE HTTP Mock system which allows to simulate JSON Responses.
*
* To implement a new test you'll need to create an `instances.json` file which contains expected response
* for a given project-id and zone under the src/test/resources/org/elasticsearch/discovery/gce with dir name:
*
* compute/v1/projects/[project-id]/zones/[zone]
*
* By default, project-id is the test method name, lowercase.
*
* For example, if you create a test `myNewAwesomeTest` with following settings:
*
* Settings nodeSettings = Settings.builder()
* .put(GceComputeService.Fields.PROJECT, projectName)
* .put(GceComputeService.Fields.ZONE, "europe-west1-b")
* .build();
*
* You need to create a file under `src/test/resources/org/elasticsearch/discovery/gce/` named:
*
* compute/v1/projects/mynewawesometest/zones/europe-west1-b/instances.json
*
*/
public class GceDiscoveryTest extends ESTestCase {
protected static ThreadPool threadPool;
protected MockTransportService transportService;
protected GceComputeService mock;
protected String projectName;
@BeforeClass
public static void createThreadPool() {
threadPool = new ThreadPool(GceDiscoveryTest.class.getName());
}
@AfterClass
public static void stopThreadPool() {
if (threadPool !=null) {
threadPool.shutdownNow();
threadPool = null;
}
}
@Before
public void setProjectName() {
projectName = getTestName().toLowerCase(Locale.ROOT);
}
@Before
public void createTransportService() {
transportService = new MockTransportService(
Settings.EMPTY,
new LocalTransport(Settings.EMPTY, threadPool, Version.CURRENT, new NamedWriteableRegistry()), threadPool);
}
@After
public void stopGceComputeService() {
if (mock != null) {
mock.stop();
}
}
protected List<DiscoveryNode> buildDynamicNodes(GceComputeService gceComputeService, Settings nodeSettings) {
GceUnicastHostsProvider provider = new GceUnicastHostsProvider(nodeSettings, gceComputeService,
transportService, new NetworkService(Settings.EMPTY), Version.CURRENT);
List<DiscoveryNode> discoveryNodes = provider.buildDynamicNodes();
logger.info("--> nodes found: {}", discoveryNodes);
return discoveryNodes;
}
@Test
public void nodesWithDifferentTagsAndNoTagSet() {
Settings nodeSettings = Settings.builder()
.put(GceComputeService.Fields.PROJECT, projectName)
.put(GceComputeService.Fields.ZONE, "europe-west1-b")
.build();
mock = new GceComputeServiceMock(nodeSettings);
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
assertThat(discoveryNodes, hasSize(2));
}
@Test
public void nodesWithDifferentTagsAndOneTagSet() {
Settings nodeSettings = Settings.builder()
.put(GceComputeService.Fields.PROJECT, projectName)
.put(GceComputeService.Fields.ZONE, "europe-west1-b")
.putArray(GceComputeService.Fields.TAGS, "elasticsearch")
.build();
mock = new GceComputeServiceMock(nodeSettings);
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
assertThat(discoveryNodes, hasSize(1));
assertThat(discoveryNodes.get(0).getId(), is("#cloud-test2-0"));
}
@Test
public void nodesWithDifferentTagsAndTwoTagSet() {
Settings nodeSettings = Settings.builder()
.put(GceComputeService.Fields.PROJECT, projectName)
.put(GceComputeService.Fields.ZONE, "europe-west1-b")
.putArray(GceComputeService.Fields.TAGS, "elasticsearch", "dev")
.build();
mock = new GceComputeServiceMock(nodeSettings);
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
assertThat(discoveryNodes, hasSize(1));
assertThat(discoveryNodes.get(0).getId(), is("#cloud-test2-0"));
}
@Test
public void nodesWithSameTagsAndNoTagSet() {
Settings nodeSettings = Settings.builder()
.put(GceComputeService.Fields.PROJECT, projectName)
.put(GceComputeService.Fields.ZONE, "europe-west1-b")
.build();
mock = new GceComputeServiceMock(nodeSettings);
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
assertThat(discoveryNodes, hasSize(2));
}
@Test
public void nodesWithSameTagsAndOneTagSet() {
Settings nodeSettings = Settings.builder()
.put(GceComputeService.Fields.PROJECT, projectName)
.put(GceComputeService.Fields.ZONE, "europe-west1-b")
.putArray(GceComputeService.Fields.TAGS, "elasticsearch")
.build();
mock = new GceComputeServiceMock(nodeSettings);
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
assertThat(discoveryNodes, hasSize(2));
}
@Test
public void nodesWithSameTagsAndTwoTagsSet() {
Settings nodeSettings = Settings.builder()
.put(GceComputeService.Fields.PROJECT, projectName)
.put(GceComputeService.Fields.ZONE, "europe-west1-b")
.putArray(GceComputeService.Fields.TAGS, "elasticsearch", "dev")
.build();
mock = new GceComputeServiceMock(nodeSettings);
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
assertThat(discoveryNodes, hasSize(2));
}
@Test
public void multipleZonesAndTwoNodesInSameZone() {
Settings nodeSettings = Settings.builder()
.put(GceComputeService.Fields.PROJECT, projectName)
.putArray(GceComputeService.Fields.ZONE, "us-central1-a", "europe-west1-b")
.build();
mock = new GceComputeServiceMock(nodeSettings);
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
assertThat(discoveryNodes, hasSize(2));
}
@Test
public void multipleZonesAndTwoNodesInDifferentZones() {
Settings nodeSettings = Settings.builder()
.put(GceComputeService.Fields.PROJECT, projectName)
.putArray(GceComputeService.Fields.ZONE, "us-central1-a", "europe-west1-b")
.build();
mock = new GceComputeServiceMock(nodeSettings);
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
assertThat(discoveryNodes, hasSize(2));
}
/**
* For issue https://github.com/elastic/elasticsearch-cloud-gce/issues/43
*/
@Test
public void zeroNode43() {
Settings nodeSettings = Settings.builder()
.put(GceComputeService.Fields.PROJECT, projectName)
.putArray(GceComputeService.Fields.ZONE, "us-central1-a", "us-central1-b")
.build();
mock = new GceComputeServiceMock(nodeSettings);
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
assertThat(discoveryNodes, hasSize(0));
}
}

View File

@ -1,34 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.discovery.gce;
import java.io.IOException;
import java.util.Properties;
/**
* Get information from plugin-test.properties file
*/
public class PropertiesHelper {
public static int getAsInt(String name) throws IOException {
final Properties properties = new Properties();
properties.load(PropertiesHelper.class.getResourceAsStream("/plugin-test.properties"));
return Integer.parseInt(properties.getProperty(name));
}
}

View File

@ -1,119 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.discovery.gce.mock;
import com.google.api.services.compute.model.Instance;
import com.google.api.services.compute.model.Metadata;
import com.google.api.services.compute.model.NetworkInterface;
import com.google.api.services.compute.model.Tags;
import com.google.common.collect.Lists;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.cloud.gce.GceComputeService;
import org.elasticsearch.common.component.AbstractLifecycleComponent;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.discovery.gce.GceComputeEngineTest;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import static com.carrotsearch.randomizedtesting.RandomizedTest.randomInt;
/**
*
*/
public abstract class GceComputeServiceAbstractMock extends AbstractLifecycleComponent<GceComputeService>
implements GceComputeService {
protected abstract List<List<String>> getTags();
protected abstract List<String> getZones();
private final List<String> zoneList;
protected GceComputeServiceAbstractMock(Settings settings) {
super(settings);
int numNodes = getTags().size() > getZones().size() ? getTags().size() : getZones().size();
logger.debug("starting GCE Api Mock with {} nodes:", numNodes);
for (int i = 0; i < numNodes; i++) {
List<String> tags = getTags().size() > i ? getTags().get(i) : null;
String zone = getZones().size() > i ? getZones().get(i) : null;
logger.debug(" - node #{}: tags [{}], zone [{}]", i, tags, zone);
}
String[] zoneList = settings.getAsArray(Fields.ZONE);
this.zoneList = Lists.newArrayList(zoneList);
}
private Collection<Instance> instances = null;
private void computeInstances() {
instances = new ArrayList<Instance>();
int nodeNumber = 0;
// For each instance (item of tags)
for (List<String> tags : getTags()) {
String zone = zoneList.isEmpty() ? "dummy" : zoneList.get(randomInt(zoneList.size()-1));
logger.info(" ----> GCE Mock API: Adding node [{}] in zone [{}]", nodeNumber, zone);
Instance instance = new Instance();
instance.setName("Mock Node " + tags);
instance.setMachineType("Mock Type machine");
instance.setStatus("STARTED");
instance.setZone(zone);
Tags instanceTags = new Tags();
instanceTags.setItems(tags);
instance.setTags(instanceTags);
NetworkInterface networkInterface = new NetworkInterface();
networkInterface.setNetworkIP("localhost");
List<NetworkInterface> networkInterfaces = new ArrayList<NetworkInterface>();
networkInterfaces.add(networkInterface);
instance.setNetworkInterfaces(networkInterfaces);
// Add metadata es_port:930X where X is the instance number
Metadata metadata = new Metadata();
metadata.put("es_port", "" + GceComputeEngineTest.getPort(nodeNumber));
instance.setMetadata(metadata);
instances.add(instance);
nodeNumber++;
}
}
@Override
public Collection<Instance> instances() {
if (instances == null || instances.size() == 0) {
computeInstances();
}
return instances;
}
@Override
protected void doStart() throws ElasticsearchException {
}
@Override
protected void doStop() throws ElasticsearchException {
}
@Override
protected void doClose() throws ElasticsearchException {
}
}

View File

@ -1,67 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.gce.itest;
import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse;
import org.elasticsearch.cloud.gce.AbstractGceTest;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.plugin.cloud.gce.CloudGcePlugin;
import org.elasticsearch.test.ESIntegTestCase;
import org.hamcrest.Matchers;
import org.junit.Test;
/**
* This test needs GCE to run and -Dtests.gce=true to be set
* and -Dtests.config=/path/to/elasticsearch.yml
* TODO: By now, it will only work from GCE platform as we don't support yet external auth.
* See https://github.com/elasticsearch/elasticsearch-cloud-gce/issues/10
* @see org.elasticsearch.cloud.gce.AbstractGceTest
*/
@ESIntegTestCase.ClusterScope(
scope = ESIntegTestCase.Scope.SUITE,
numDataNodes = 1,
transportClientRatio = 0.0)
public class GceSimpleITest extends AbstractGceTest {
@Override
protected Settings nodeSettings(int nodeOrdinal) {
return Settings.builder()
.put(super.nodeSettings(nodeOrdinal))
.put("plugin.types", CloudGcePlugin.class.getName())
.build();
}
@Test
public void one_node_should_run() {
// Do nothing... Just start :-)
// but let's check that we have at least 1 node (local node)
ClusterStateResponse clusterState = client().admin().cluster().prepareState().execute().actionGet();
assertThat(clusterState.getState().getNodes().getSize(), Matchers.greaterThanOrEqualTo(1));
}
@Override
public Settings indexSettings() {
// During restore we frequently restore index to exactly the same state it was before, that might cause the same
// checksum file to be written twice during restore operation
return Settings.builder().put(super.indexSettings())
.build();
}
}

View File

@ -0,0 +1,36 @@
{
"id": "dummy",
"items":[
{
"description": "ES Node 1",
"id": "9309873766428965105",
"kind": "compute#instance",
"machineType": "n1-standard-1",
"name": "test1",
"networkInterfaces": [
{
"accessConfigs": [
{
"kind": "compute#accessConfig",
"name": "External NAT",
"natIP": "104.155.13.147",
"type": "ONE_TO_ONE_NAT"
}
],
"name": "nic0",
"network": "default",
"networkIP": "10.240.79.59"
}
],
"status": "RUNNING",
"tags": {
"fingerprint": "xA6QJb-rGtg=",
"items": [
"elasticsearch",
"dev"
]
},
"zone": "europe-west1-b"
}
]
}

View File

@ -0,0 +1,36 @@
{
"id": "dummy",
"items":[
{
"description": "ES Node 2",
"id": "9309873766428965105",
"kind": "compute#instance",
"machineType": "n1-standard-1",
"name": "test2",
"networkInterfaces": [
{
"accessConfigs": [
{
"kind": "compute#accessConfig",
"name": "External NAT",
"natIP": "104.155.13.147",
"type": "ONE_TO_ONE_NAT"
}
],
"name": "nic0",
"network": "default",
"networkIP": "10.240.79.59"
}
],
"status": "RUNNING",
"tags": {
"fingerprint": "xA6QJb-rGtg=",
"items": [
"elasticsearch",
"dev"
]
},
"zone": "us-central1-a"
}
]
}

View File

@ -0,0 +1,67 @@
{
"id": "dummy",
"items":[
{
"description": "ES Node 1",
"id": "9309873766428965105",
"kind": "compute#instance",
"machineType": "n1-standard-1",
"name": "test1",
"networkInterfaces": [
{
"accessConfigs": [
{
"kind": "compute#accessConfig",
"name": "External NAT",
"natIP": "104.155.13.147",
"type": "ONE_TO_ONE_NAT"
}
],
"name": "nic0",
"network": "default",
"networkIP": "10.240.79.59"
}
],
"status": "RUNNING",
"tags": {
"fingerprint": "xA6QJb-rGtg=",
"items": [
"elasticsearch",
"dev"
]
},
"zone": "europe-west1-b"
},
{
"description": "ES Node 2",
"id": "9309873766428965105",
"kind": "compute#instance",
"machineType": "n1-standard-1",
"name": "test2",
"networkInterfaces": [
{
"accessConfigs": [
{
"kind": "compute#accessConfig",
"name": "External NAT",
"natIP": "104.155.13.147",
"type": "ONE_TO_ONE_NAT"
}
],
"name": "nic0",
"network": "default",
"networkIP": "10.240.79.59"
}
],
"status": "RUNNING",
"tags": {
"fingerprint": "xA6QJb-rGtg=",
"items": [
"elasticsearch",
"dev"
]
},
"zone": "europe-west1-b"
}
]
}

View File

@ -0,0 +1,66 @@
{
"id": "dummy",
"items":[
{
"description": "ES Node 1",
"id": "9309873766428965105",
"kind": "compute#instance",
"machineType": "n1-standard-1",
"name": "test1",
"networkInterfaces": [
{
"accessConfigs": [
{
"kind": "compute#accessConfig",
"name": "External NAT",
"natIP": "104.155.13.147",
"type": "ONE_TO_ONE_NAT"
}
],
"name": "nic0",
"network": "default",
"networkIP": "10.240.79.59"
}
],
"status": "RUNNING",
"tags": {
"fingerprint": "xA6QJb-rGtg=",
"items": [
"dev"
]
},
"zone": "europe-west1-b"
},
{
"description": "ES Node 2",
"id": "9309873766428965105",
"kind": "compute#instance",
"machineType": "n1-standard-1",
"name": "test2",
"networkInterfaces": [
{
"accessConfigs": [
{
"kind": "compute#accessConfig",
"name": "External NAT",
"natIP": "104.155.13.147",
"type": "ONE_TO_ONE_NAT"
}
],
"name": "nic0",
"network": "default",
"networkIP": "10.240.79.59"
}
],
"status": "RUNNING",
"tags": {
"fingerprint": "xA6QJb-rGtg=",
"items": [
"elasticsearch",
"dev"
]
},
"zone": "europe-west1-b"
}
]
}

View File

@ -0,0 +1,66 @@
{
"id": "dummy",
"items":[
{
"description": "ES Node 1",
"id": "9309873766428965105",
"kind": "compute#instance",
"machineType": "n1-standard-1",
"name": "test1",
"networkInterfaces": [
{
"accessConfigs": [
{
"kind": "compute#accessConfig",
"name": "External NAT",
"natIP": "104.155.13.147",
"type": "ONE_TO_ONE_NAT"
}
],
"name": "nic0",
"network": "default",
"networkIP": "10.240.79.59"
}
],
"status": "RUNNING",
"tags": {
"fingerprint": "xA6QJb-rGtg=",
"items": [
"dev"
]
},
"zone": "europe-west1-b"
},
{
"description": "ES Node 2",
"id": "9309873766428965105",
"kind": "compute#instance",
"machineType": "n1-standard-1",
"name": "test2",
"networkInterfaces": [
{
"accessConfigs": [
{
"kind": "compute#accessConfig",
"name": "External NAT",
"natIP": "104.155.13.147",
"type": "ONE_TO_ONE_NAT"
}
],
"name": "nic0",
"network": "default",
"networkIP": "10.240.79.59"
}
],
"status": "RUNNING",
"tags": {
"fingerprint": "xA6QJb-rGtg=",
"items": [
"elasticsearch",
"dev"
]
},
"zone": "europe-west1-b"
}
]
}

View File

@ -0,0 +1,66 @@
{
"id": "dummy",
"items":[
{
"description": "ES Node 1",
"id": "9309873766428965105",
"kind": "compute#instance",
"machineType": "n1-standard-1",
"name": "test1",
"networkInterfaces": [
{
"accessConfigs": [
{
"kind": "compute#accessConfig",
"name": "External NAT",
"natIP": "104.155.13.147",
"type": "ONE_TO_ONE_NAT"
}
],
"name": "nic0",
"network": "default",
"networkIP": "10.240.79.59"
}
],
"status": "RUNNING",
"tags": {
"fingerprint": "xA6QJb-rGtg=",
"items": [
"dev"
]
},
"zone": "europe-west1-b"
},
{
"description": "ES Node 2",
"id": "9309873766428965105",
"kind": "compute#instance",
"machineType": "n1-standard-1",
"name": "test2",
"networkInterfaces": [
{
"accessConfigs": [
{
"kind": "compute#accessConfig",
"name": "External NAT",
"natIP": "104.155.13.147",
"type": "ONE_TO_ONE_NAT"
}
],
"name": "nic0",
"network": "default",
"networkIP": "10.240.79.59"
}
],
"status": "RUNNING",
"tags": {
"fingerprint": "xA6QJb-rGtg=",
"items": [
"elasticsearch",
"dev"
]
},
"zone": "europe-west1-b"
}
]
}

View File

@ -0,0 +1,67 @@
{
"id": "dummy",
"items":[
{
"description": "ES Node 1",
"id": "9309873766428965105",
"kind": "compute#instance",
"machineType": "n1-standard-1",
"name": "test1",
"networkInterfaces": [
{
"accessConfigs": [
{
"kind": "compute#accessConfig",
"name": "External NAT",
"natIP": "104.155.13.147",
"type": "ONE_TO_ONE_NAT"
}
],
"name": "nic0",
"network": "default",
"networkIP": "10.240.79.59"
}
],
"status": "RUNNING",
"tags": {
"fingerprint": "xA6QJb-rGtg=",
"items": [
"elasticsearch",
"dev"
]
},
"zone": "europe-west1-b"
},
{
"description": "ES Node 2",
"id": "9309873766428965105",
"kind": "compute#instance",
"machineType": "n1-standard-1",
"name": "test2",
"networkInterfaces": [
{
"accessConfigs": [
{
"kind": "compute#accessConfig",
"name": "External NAT",
"natIP": "104.155.13.147",
"type": "ONE_TO_ONE_NAT"
}
],
"name": "nic0",
"network": "default",
"networkIP": "10.240.79.59"
}
],
"status": "RUNNING",
"tags": {
"fingerprint": "xA6QJb-rGtg=",
"items": [
"elasticsearch",
"dev"
]
},
"zone": "europe-west1-b"
}
]
}

View File

@ -0,0 +1,67 @@
{
"id": "dummy",
"items":[
{
"description": "ES Node 1",
"id": "9309873766428965105",
"kind": "compute#instance",
"machineType": "n1-standard-1",
"name": "test1",
"networkInterfaces": [
{
"accessConfigs": [
{
"kind": "compute#accessConfig",
"name": "External NAT",
"natIP": "104.155.13.147",
"type": "ONE_TO_ONE_NAT"
}
],
"name": "nic0",
"network": "default",
"networkIP": "10.240.79.59"
}
],
"status": "RUNNING",
"tags": {
"fingerprint": "xA6QJb-rGtg=",
"items": [
"elasticsearch",
"dev"
]
},
"zone": "europe-west1-b"
},
{
"description": "ES Node 2",
"id": "9309873766428965105",
"kind": "compute#instance",
"machineType": "n1-standard-1",
"name": "test2",
"networkInterfaces": [
{
"accessConfigs": [
{
"kind": "compute#accessConfig",
"name": "External NAT",
"natIP": "104.155.13.147",
"type": "ONE_TO_ONE_NAT"
}
],
"name": "nic0",
"network": "default",
"networkIP": "10.240.79.59"
}
],
"status": "RUNNING",
"tags": {
"fingerprint": "xA6QJb-rGtg=",
"items": [
"elasticsearch",
"dev"
]
},
"zone": "europe-west1-b"
}
]
}

View File

@ -0,0 +1,67 @@
{
"id": "dummy",
"items":[
{
"description": "ES Node 1",
"id": "9309873766428965105",
"kind": "compute#instance",
"machineType": "n1-standard-1",
"name": "test1",
"networkInterfaces": [
{
"accessConfigs": [
{
"kind": "compute#accessConfig",
"name": "External NAT",
"natIP": "104.155.13.147",
"type": "ONE_TO_ONE_NAT"
}
],
"name": "nic0",
"network": "default",
"networkIP": "10.240.79.59"
}
],
"status": "RUNNING",
"tags": {
"fingerprint": "xA6QJb-rGtg=",
"items": [
"elasticsearch",
"dev"
]
},
"zone": "europe-west1-b"
},
{
"description": "ES Node 2",
"id": "9309873766428965105",
"kind": "compute#instance",
"machineType": "n1-standard-1",
"name": "test2",
"networkInterfaces": [
{
"accessConfigs": [
{
"kind": "compute#accessConfig",
"name": "External NAT",
"natIP": "104.155.13.147",
"type": "ONE_TO_ONE_NAT"
}
],
"name": "nic0",
"network": "default",
"networkIP": "10.240.79.59"
}
],
"status": "RUNNING",
"tags": {
"fingerprint": "xA6QJb-rGtg=",
"items": [
"elasticsearch",
"dev"
]
},
"zone": "europe-west1-b"
}
]
}

View File

@ -0,0 +1,4 @@
{
"access_token":"1/fFAGRNJru1FTz70BzhT3Zg",
"token_type":"Bearer"
}

View File

@ -1,3 +0,0 @@
# This file contains specific needed properties for tests.
# You can use placeholders to extract values from Maven for example
plugin.port=${es.plugin.port}