Tests & Refactoring:

- Added LicensesPluginsIntegrationTests (test with more than one consumer plugin)
 - Minor fix for LicensesService
 - Remove public_key_file from verify-license
 - WIP: STATE_NOT_RECOVERED_BLOCK tests

Original commit: elastic/x-pack-elasticsearch@372034a86a
This commit is contained in:
Areek Zillur 2014-11-03 10:44:52 -05:00
parent c5f5c807bb
commit e0ec8f6059
5 changed files with 141 additions and 26 deletions

View File

@ -25,17 +25,14 @@ public class LicenseVerificationTool {
static class Options {
private final Set<ESLicense> licenses;
private final String publicKeyFilePath;
Options(Set<ESLicense> licenses, String publicKeyFilePath) {
Options(Set<ESLicense> licenses) {
this.licenses = licenses;
this.publicKeyFilePath = publicKeyFilePath;
}
}
private static Options parse(String[] args) throws IOException {
Set<ESLicense> licenses = new HashSet<>();
String publicKeyPath = null;
for (int i = 0; i < args.length; i++) {
String command = args[i];
@ -53,18 +50,12 @@ public class LicenseVerificationTool {
case "--licenses":
licenses.addAll(ESLicenses.fromSource(args[++i]));
break;
case "--publicKeyPath":
publicKeyPath = args[++i];
break;
}
}
if (licenses.size() == 0) {
throw new IllegalArgumentException("mandatory option '--licensesFiles' or '--licenses' is missing");
}
if (publicKeyPath == null) {
throw new IllegalArgumentException("mandatory option '--publicKeyPath' is missing");
}
return new Options(licenses, publicKeyPath);
return new Options(licenses);
}
public static void main(String[] args) throws IOException {

View File

@ -614,7 +614,7 @@ public class LicensesService extends AbstractLifecycleComponent<LicensesService>
private void clearFinishedNotifications() {
while (!scheduledNotifications.isEmpty()) {
ScheduledFuture notification = scheduledNotifications.peek();
if (notification.isDone()) {
if (notification != null && notification.isDone()) {
// remove the notifications that are done
scheduledNotifications.poll();
} else {

View File

@ -23,6 +23,7 @@ import org.elasticsearch.license.plugin.core.LicensesManagerService;
import org.elasticsearch.license.plugin.core.LicensesMetaData;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.elasticsearch.test.InternalTestCluster;
import org.hamcrest.Matchers;
import java.util.*;
import java.util.concurrent.CountDownLatch;
@ -31,6 +32,7 @@ import java.util.concurrent.TimeUnit;
import static org.elasticsearch.license.AbstractLicensingTestBase.getTestPriKeyPath;
import static org.elasticsearch.license.AbstractLicensingTestBase.getTestPubKeyPath;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.Matchers.greaterThan;
/**
*/
@ -130,12 +132,14 @@ public abstract class AbstractLicensesIntegrationTests extends ElasticsearchInte
}
protected void assertConsumerPlugin2Notification(final boolean expectedEnabled, int timeoutInSec) throws InterruptedException {
final Iterable<TestPluginServiceBase> consumerPluginServices = consumerPlugin2Services();
final List<TestPluginServiceBase> consumerPluginServices = consumerPlugin2Services();
assertThat("At least one instance has to be present", consumerPluginServices.size(), greaterThan(0));
assertConsumerPluginNotification(consumerPluginServices, expectedEnabled, timeoutInSec);
}
protected void assertConsumerPlugin1Notification(final boolean expectedEnabled, int timeoutInSec) throws InterruptedException {
final Iterable<TestPluginServiceBase> consumerPluginServices = consumerPlugin1Services();
final List<TestPluginServiceBase> consumerPluginServices = consumerPlugin1Services();
assertThat("At least one instance has to be present", consumerPluginServices.size(), greaterThan(0));
assertConsumerPluginNotification(consumerPluginServices, expectedEnabled, timeoutInSec);
}
@ -154,7 +158,7 @@ public abstract class AbstractLicensesIntegrationTests extends ElasticsearchInte
}
private Iterable<TestPluginServiceBase> consumerPlugin2Services() {
private List<TestPluginServiceBase> consumerPlugin2Services() {
final InternalTestCluster clients = internalCluster();
List<TestPluginServiceBase> consumerPluginServices = new ArrayList<>();
for (TestPluginServiceBase service : clients.getDataNodeInstances(TestPluginService2.class)) {
@ -163,7 +167,7 @@ public abstract class AbstractLicensesIntegrationTests extends ElasticsearchInte
return consumerPluginServices;
}
private Iterable<TestPluginServiceBase> consumerPlugin1Services() {
private List<TestPluginServiceBase> consumerPlugin1Services() {
final InternalTestCluster clients = internalCluster();
List<TestPluginServiceBase> consumerPluginServices = new ArrayList<>();
for (TestPluginServiceBase service : clients.getDataNodeInstances(TestPluginService1.class)) {

View File

@ -24,7 +24,7 @@ import static org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
import static org.elasticsearch.test.ElasticsearchIntegrationTest.Scope.TEST;
import static org.hamcrest.CoreMatchers.equalTo;
@ClusterScope(scope = TEST, numDataNodes = 10, numClientNodes = 0)
@ClusterScope(scope = TEST, numDataNodes = 0, numClientNodes = 0)
public class LicensesPluginsIntegrationTests extends AbstractLicensesIntegrationTests {
private final int trialLicenseDurationInSeconds = 2;
@ -41,13 +41,72 @@ public class LicensesPluginsIntegrationTests extends AbstractLicensesIntegration
.build();
}
private Settings nodeSettingsWithConsumerPlugin(int consumer1TrialLicenseDuration, int consumer2TrialLicenseDuration) {
return ImmutableSettings.settingsBuilder()
.put(super.nodeSettings(0))
.put(TestConsumerPlugin1.NAME + ".trial_license_duration_in_seconds", consumer1TrialLicenseDuration)
.put(TestConsumerPlugin2.NAME + ".trial_license_duration_in_seconds", consumer2TrialLicenseDuration)
.putArray("plugin.types", LicensePlugin.class.getName(), TestConsumerPlugin1.class.getName(), TestConsumerPlugin2.class.getName())
.build();
}
@After
public void beforeTest() throws Exception {
wipeAllLicenses();
}
@Test
public void testWithNoTrialLicense() throws Exception {
int nNodes = randomIntBetween(2, 10);
String[] nodes = startNodesWithConsumerPlugins(nNodes, -1, -1);
assertConsumerPlugin1DisableNotification(trialLicenseDurationInSeconds * 2);
assertConsumerPlugin2DisableNotification(trialLicenseDurationInSeconds * 2);
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_1);
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_2);
}
@Test
public void testOneTrialAndNonTrialConsumer() throws Exception {
int nNodes = randomIntBetween(2, 10);
int consumer2TrialLicenseDuration = 2;
String[] nodes = startNodesWithConsumerPlugins(nNodes, -1, consumer2TrialLicenseDuration);
logger.info(" --> trial license generated for " + FEATURE_NAME_2 + " no trial license for " + FEATURE_NAME_1);
// managerService should report feature to be enabled on all data nodes
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_1);
assertLicenseManagerEnabledFeatureFor(FEATURE_NAME_2);
// consumer plugin service should return enabled on all data nodes
assertConsumerPlugin1DisableNotification(1);
assertConsumerPlugin2EnableNotification(1);
logger.info(" --> put signed license for " + FEATURE_NAME_1);
ESLicense license1 = generateSignedLicense(FEATURE_NAME_1, TimeValue.timeValueSeconds(consumer2TrialLicenseDuration));
final PutLicenseResponse putLicenseResponse = new PutLicenseRequestBuilder(client().admin().cluster()).setLicense(Lists.newArrayList(license1)).get();
assertThat(putLicenseResponse.isAcknowledged(), equalTo(true));
assertThat(putLicenseResponse.status(), equalTo(LicensesStatus.VALID));
logger.info(" --> check that both " + FEATURE_NAME_1 + " and " + FEATURE_NAME_2 + " are enabled");
assertConsumerPlugin1EnableNotification(1);
assertConsumerPlugin2EnableNotification(1);
assertLicenseManagerEnabledFeatureFor(FEATURE_NAME_1);
assertLicenseManagerEnabledFeatureFor(FEATURE_NAME_2);
logger.info(" --> check signed license expiry notification");
// consumer plugin should notify onDisabled on all data nodes (expired signed license)
assertConsumerPlugin1DisableNotification(consumer2TrialLicenseDuration * 2);
assertConsumerPlugin2DisableNotification(consumer2TrialLicenseDuration * 2);
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_1);
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_2);
}
@Test
public void testMultipleConsumerPlugins() throws Exception {
int nNodes = randomIntBetween(2, 10);
String[] nodes = startNodesWithConsumerPlugins(nNodes, trialLicenseDurationInSeconds, trialLicenseDurationInSeconds);
logger.info(" --> trial license generated");
// managerService should report feature to be enabled on all data nodes
assertLicenseManagerEnabledFeatureFor(FEATURE_NAME_1);
@ -64,11 +123,8 @@ public class LicensesPluginsIntegrationTests extends AbstractLicensesIntegration
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_2);
logger.info(" --> put signed license");
ESLicense license1 = generateSignedLicense(FEATURE_NAME_1, TimeValue.timeValueSeconds(trialLicenseDurationInSeconds));
ESLicense license2 = generateSignedLicense(FEATURE_NAME_2, TimeValue.timeValueSeconds(trialLicenseDurationInSeconds));
final PutLicenseResponse putLicenseResponse = new PutLicenseRequestBuilder(client().admin().cluster()).setLicense(Lists.newArrayList(license1, license2)).get();
assertThat(putLicenseResponse.isAcknowledged(), equalTo(true));
assertThat(putLicenseResponse.status(), equalTo(LicensesStatus.VALID));
putLicense(FEATURE_NAME_1, TimeValue.timeValueSeconds(trialLicenseDurationInSeconds));
putLicense(FEATURE_NAME_2, TimeValue.timeValueSeconds(trialLicenseDurationInSeconds));
logger.info(" --> check signed license enabled notification");
// consumer plugin should notify onEnabled on all data nodes (signed license)
@ -84,4 +140,60 @@ public class LicensesPluginsIntegrationTests extends AbstractLicensesIntegration
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_1);
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_2);
}
@Test
public void testRandomFeatureLicensesActions() throws Exception {
int nNodes = randomIntBetween(2, 10);
int trialLicenseDuration1 = rarely() ? -1 : randomIntBetween(1, 2);
int trialLicenseDuration2 = rarely() ? -1 : randomIntBetween(1, 2);
String[] nodes = startNodesWithConsumerPlugins(nNodes, trialLicenseDuration1, trialLicenseDuration2);
if (trialLicenseDuration1 != -1) {
assertConsumerPlugin1EnableNotification(1);
assertLicenseManagerEnabledFeatureFor(FEATURE_NAME_1);
} else {
assertConsumerPlugin1DisableNotification(1);
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_1);
putLicense(FEATURE_NAME_1, TimeValue.timeValueMillis(300 * 2));
}
if (trialLicenseDuration2 != -1) {
assertConsumerPlugin2EnableNotification(1);
assertLicenseManagerEnabledFeatureFor(FEATURE_NAME_2);
} else {
assertConsumerPlugin2DisableNotification(1);
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_2);
putLicense(FEATURE_NAME_2, TimeValue.timeValueMillis(300 * 2));
}
logger.info(" --> check license enabled notification");
assertConsumerPlugin1EnableNotification(1);
assertConsumerPlugin2EnableNotification(1);
assertLicenseManagerEnabledFeatureFor(FEATURE_NAME_1);
assertLicenseManagerEnabledFeatureFor(FEATURE_NAME_2);
logger.info(" --> check license expiry notification");
// consumer plugin should notify onDisabled on all data nodes (expired signed license)
assertConsumerPlugin1DisableNotification(2 * 2);
assertConsumerPlugin2DisableNotification(2 * 2);
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_1);
assertLicenseManagerDisabledFeatureFor(FEATURE_NAME_2);
}
private String[] startNodesWithConsumerPlugins(int nNodes, int consumer1TrialLicenseDuration, int consumer2TrialLicenseDuration) {
String[] nodes = new String[nNodes];
for (int i = 0; i < nNodes; i++) {
nodes[i] = internalCluster().startNode(nodeSettingsWithConsumerPlugin(consumer1TrialLicenseDuration, consumer2TrialLicenseDuration));
}
return nodes;
}
private void putLicense(String feature, TimeValue expiryDuration) throws Exception {
ESLicense license1 = generateSignedLicense(feature, expiryDuration);
final PutLicenseResponse putLicenseResponse = new PutLicenseRequestBuilder(client().admin().cluster()).setLicense(Lists.newArrayList(license1)).get();
assertThat(putLicenseResponse.isAcknowledged(), equalTo(true));
assertThat(putLicenseResponse.status(), equalTo(LicensesStatus.VALID));
}
}

View File

@ -6,9 +6,11 @@
package org.elasticsearch.license.plugin;
import org.elasticsearch.client.ClusterAdminClient;
import org.elasticsearch.cluster.block.ClusterBlockLevel;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.gateway.GatewayService;
import org.elasticsearch.license.TestUtils;
import org.elasticsearch.license.core.ESLicense;
import org.elasticsearch.license.plugin.action.get.GetLicenseRequestBuilder;
@ -25,11 +27,13 @@ import org.junit.Test;
import java.util.Arrays;
import java.util.List;
import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
import static org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
import static org.elasticsearch.test.ElasticsearchIntegrationTest.Scope.TEST;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.Matchers.hasItem;
@ClusterScope(scope = TEST, numDataNodes = 0, numClientNodes = 0)
@ClusterScope(scope = TEST, numDataNodes = 0, numClientNodes = 0, maxNumDataNodes = 0, transportClientRatio = 0)
public class LicensesServiceClusterTest extends AbstractLicensesIntegrationTests {
private final String FEATURE_NAME = TestPluginService1.FEATURE_NAME;
@ -44,7 +48,7 @@ public class LicensesServiceClusterTest extends AbstractLicensesIntegrationTests
}
private ImmutableSettings.Builder nodeSettingsBuilder(int nodeOrdinal) {
return ImmutableSettings.settingsBuilder()
return settingsBuilder()
.put(super.nodeSettings(nodeOrdinal))
.put("gateway.type", "local")
.put("plugins.load_classpath_plugins", false)
@ -84,9 +88,13 @@ public class LicensesServiceClusterTest extends AbstractLicensesIntegrationTests
@Test
public void testClusterNotRecovered() throws Exception {
logger.info("--> start first node (should not recover)");
internalCluster().startNode(nodeSettingsBuilder(0).put("gateway.recover_after_master_nodes", 2).put("node.master", true));
String name = internalCluster().startNode(nodeSettingsBuilder(0).put("gateway.recover_after_master_nodes", 2).put("node.master", true));
/* TODO: figure out why STATE_NOT_RECOVERED_BLOCK is not on
assertThat(internalCluster().client(name).admin().cluster().prepareState().setLocal(true).execute().actionGet()
.getState().blocks().global(ClusterBlockLevel.METADATA),
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
*/
assertLicenseManagerEnabledFeatureFor(FEATURE_NAME);
assertConsumerPlugin1EnableNotification(1);