/* * Copyright (c) 2011-2014 The original author or authors * ------------------------------------------------------ * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Apache License v2.0 which accompanies this distribution. * * The Eclipse Public License is available at * http://www.eclipse.org/legal/epl-v10.html * * The Apache License v2.0 is available at * http://www.opensource.org/licenses/apache2.0.php * * You may elect to redistribute this code under either of these licenses. */ package io.vertx.test.core; import io.vertx.core.DeploymentOptions; import io.vertx.core.Starter; import io.vertx.core.Vertx; import io.vertx.core.VertxOptions; import io.vertx.core.impl.launcher.VertxCommandLauncher; import io.vertx.core.json.JsonObject; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import java.io.File; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.util.Arrays; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; /** * @author <a href="http://tfox.org">Tim Fox</a> */ public class StarterTest extends VertxTestBase { Vertx vertx; @Override public void setUp() throws Exception { super.setUp(); TestVerticle.instanceCount.set(0); TestVerticle.processArgs = null; TestVerticle.conf = null; VertxCommandLauncher.resetProcessArguments(); File manifest = new File("target/test-classes/META-INF/MANIFEST-Starter.MF"); if (!manifest.isFile()) { throw new IllegalStateException("Cannot find the MANIFEST-Starter.MF file"); } File target = new File("target/test-classes/META-INF/MANIFEST.MF"); Files.copy(manifest.toPath(), target.toPath(), StandardCopyOption.REPLACE_EXISTING); } @Override public void tearDown() throws Exception { clearProperties(); super.tearDown(); if (vertx != null) { vertx.close(); } } @Test public void testVersion() throws Exception { String[] args = {"-version"}; MyStarter starter = new MyStarter(); starter.run(args); // TODO some way of getting this from the version in pom.xml assertEquals(System.getProperty("vertxVersion"), starter.getVersion()); cleanup(starter); } @Test public void testRunVerticle() throws Exception { testRunVerticleMultiple(1); } @Test public void testRunVerticleMultipleInstances() throws Exception { testRunVerticleMultiple(10); } public void testRunVerticleMultiple(int instances) throws Exception { MyStarter starter = new MyStarter(); String[] args = {"run", "java:" + TestVerticle.class.getCanonicalName(), "-instances", String.valueOf(instances)}; starter.run(args); assertWaitUntil(() -> TestVerticle.instanceCount.get() == instances); assertEquals(Arrays.asList(args), TestVerticle.processArgs); starter.assertHooksInvoked(); cleanup(starter); } @Test public void testRunVerticleClustered() throws Exception { MyStarter starter = new MyStarter(); String[] args = {"run", "java:" + TestVerticle.class.getCanonicalName(), "-cluster"}; starter.run(args); assertWaitUntil(() -> TestVerticle.instanceCount.get() == 1); assertEquals(Arrays.asList(args), TestVerticle.processArgs); starter.assertHooksInvoked(); cleanup(starter); } @Test public void testRunVerticleHA() throws Exception { MyStarter starter = new MyStarter(); String[] args = {"run", "java:" + TestVerticle.class.getCanonicalName(), "-ha"}; starter.run(args); assertWaitUntil(() -> TestVerticle.instanceCount.get() == 1); assertEquals(Arrays.asList(args), TestVerticle.processArgs); starter.assertHooksInvoked(); cleanup(starter); } @Test public void testRunVerticleWithMainVerticleInManifestNoArgs() throws Exception { MyStarter starter = new MyStarter(); String[] args = {}; starter.run(args); assertWaitUntil(() -> TestVerticle.instanceCount.get() == 1); assertEquals(Arrays.asList(args), TestVerticle.processArgs); cleanup(starter); } private void cleanup(MyStarter starter) { if (starter != null && starter.getVertx() != null) { starter.getVertx().close(); } } @Test public void testRunVerticleWithMainVerticleInManifestWithHA() throws Exception { MyStarter starter = new MyStarter(); String[] args = {"-ha"}; starter.run(args); assertWaitUntil(() -> TestVerticle.instanceCount.get() == 1); assertEquals(Arrays.asList(args), TestVerticle.processArgs); cleanup(starter); } @Test public void testRunVerticleWithMainVerticleInManifestWithArgs() throws Exception { MyStarter starter = new MyStarter(); String[] args = {"-cluster", "-worker"}; starter.run(args); assertWaitUntil(() -> TestVerticle.instanceCount.get() == 1); assertEquals(Arrays.asList(args), TestVerticle.processArgs); cleanup(starter); } @Test public void testRunVerticleWithConfString() throws Exception { MyStarter starter = new MyStarter(); JsonObject conf = new JsonObject().put("foo", "bar").put("wibble", 123); String[] args = {"run", "java:" + TestVerticle.class.getCanonicalName(), "-conf", conf.encode()}; starter.run(args); assertWaitUntil(() -> TestVerticle.instanceCount.get() == 1); assertEquals(conf, TestVerticle.conf); cleanup(starter); } @Rule public TemporaryFolder testFolder = new TemporaryFolder(); @Test public void testRunVerticleWithConfFile() throws Exception { Path tempDir = testFolder.newFolder().toPath(); Path tempFile = Files.createTempFile(tempDir, "conf", "json"); MyStarter starter = new MyStarter(); JsonObject conf = new JsonObject().put("foo", "bar").put("wibble", 123); Files.write(tempFile, conf.encode().getBytes()); String[] args = {"run", "java:" + TestVerticle.class.getCanonicalName(), "-conf", tempFile.toString()}; starter.run(args); assertWaitUntil(() -> TestVerticle.instanceCount.get() == 1); assertEquals(conf, TestVerticle.conf); cleanup(starter); } @Test public void testConfigureFromSystemProperties() throws Exception { testConfigureFromSystemProperties(false); } @Test public void testConfigureFromSystemPropertiesClustered() throws Exception { testConfigureFromSystemProperties(true); } private void testConfigureFromSystemProperties(boolean clustered) throws Exception { // One for each type that we support System.setProperty(Starter.VERTX_OPTIONS_PROP_PREFIX + "eventLoopPoolSize", "123"); System.setProperty(Starter.VERTX_OPTIONS_PROP_PREFIX + "maxEventLoopExecuteTime", "123767667"); System.setProperty(Starter.METRICS_OPTIONS_PROP_PREFIX + "enabled", "true"); System.setProperty(Starter.VERTX_OPTIONS_PROP_PREFIX + "haGroup", "somegroup"); MyStarter starter = new MyStarter(); String[] args; if (clustered) { args = new String[] {"run", "java:" + TestVerticle.class.getCanonicalName(), "-cluster"}; } else { args = new String[] {"run", "java:" + TestVerticle.class.getCanonicalName()}; } starter.run(args); assertWaitUntil(() -> TestVerticle.instanceCount.get() == 1); VertxOptions opts = starter.getVertxOptions(); assertEquals(123, opts.getEventLoopPoolSize(), 0); assertEquals(123767667L, opts.getMaxEventLoopExecuteTime()); assertEquals(true, opts.getMetricsOptions().isEnabled()); assertEquals("somegroup", opts.getHAGroup()); cleanup(starter); } private void clearProperties() { Set<String> toClear = new HashSet<>(); Enumeration e = System.getProperties().propertyNames(); // Uhh, properties suck while (e.hasMoreElements()) { String propName = (String) e.nextElement(); if (propName.startsWith("vertx.options")) { toClear.add(propName); } } for (String propName : toClear) { System.clearProperty(propName); } } @Test public void testCustomMetricsOptions() throws Exception { System.setProperty(Starter.METRICS_OPTIONS_PROP_PREFIX + "enabled", "true"); System.setProperty(Starter.METRICS_OPTIONS_PROP_PREFIX + "customProperty", "customPropertyValue"); MyStarter starter = new MyStarter(); String[] args = {"run", "java:" + TestVerticle.class.getCanonicalName()}; ClassLoader oldCL = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(MetricsOptionsTest.createMetricsFromMetaInfLoader("io.vertx.test.core.CustomMetricsFactory")); try { starter.run(args); } finally { Thread.currentThread().setContextClassLoader(oldCL); } assertWaitUntil(() -> TestVerticle.instanceCount.get() == 1); VertxOptions opts = starter.getVertxOptions(); CustomMetricsOptions custom = (CustomMetricsOptions) opts.getMetricsOptions(); assertEquals("customPropertyValue", custom.getCustomProperty()); cleanup(starter); } @Test public void testConfigureFromSystemPropertiesInvalidPropertyName() throws Exception { System.setProperty(Starter.VERTX_OPTIONS_PROP_PREFIX + "nosuchproperty", "123"); // Should be ignored MyStarter starter = new MyStarter(); String[] args = {"run", "java:" + TestVerticle.class.getCanonicalName()}; starter.run(args); assertWaitUntil(() -> TestVerticle.instanceCount.get() == 1); VertxOptions opts = starter.getVertxOptions(); VertxOptions def = new VertxOptions(); if (opts.getMetricsOptions().isEnabled()) { def.getMetricsOptions().setEnabled(true); } assertEquals(def, opts); cleanup(starter); } @Test public void testConfigureFromSystemPropertiesInvalidPropertyType() throws Exception { // One for each type that we support System.setProperty(Starter.VERTX_OPTIONS_PROP_PREFIX + "eventLoopPoolSize", "sausages"); // Should be ignored MyStarter starter = new MyStarter(); String[] args = {"run", "java:" + TestVerticle.class.getCanonicalName()}; starter.run(args); assertWaitUntil(() -> TestVerticle.instanceCount.get() == 1); VertxOptions opts = starter.getVertxOptions(); VertxOptions def = new VertxOptions(); if (opts.getMetricsOptions().isEnabled()) { def.getMetricsOptions().setEnabled(true); } assertEquals(def, opts); cleanup(starter); } @Test public void testRunWithCommandLine() throws Exception { MyStarter starter = new MyStarter(); int instances = 10; String cl = "run java:" + TestVerticle.class.getCanonicalName() + " -instances " + instances; starter.run(cl); assertWaitUntil(() -> TestVerticle.instanceCount.get() == instances); cleanup(starter); } class MyStarter extends Starter { boolean beforeStartingVertxInvoked = false; boolean afterStartingVertxInvoked = false; boolean beforeDeployingVerticle = false; public Vertx getVertx() { return vertx; } public VertxOptions getVertxOptions() { return options; } public DeploymentOptions getDeploymentOptions() { return deploymentOptions; } @Override public void run(String[] sargs) { super.run(sargs); } @Override public void run(String commandLine) { super.run(commandLine); } @Override public void beforeStartingVertx(VertxOptions options) { beforeStartingVertxInvoked = true; } @Override public void afterStartingVertx() { afterStartingVertxInvoked = true; } @Override protected void beforeDeployingVerticle(DeploymentOptions deploymentOptions) { beforeDeployingVerticle = true; } public void assertHooksInvoked() { StarterTest.this.vertx = vertx; assertTrue(beforeStartingVertxInvoked); assertTrue(afterStartingVertxInvoked); assertTrue(beforeDeployingVerticle); } } }