http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/018a0e15/brooklyn-server/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherTest.java
----------------------------------------------------------------------
diff --cc
brooklyn-server/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherTest.java
index 0000000,ff7e0d4..78c99a5
mode 000000,100644..100644
---
a/brooklyn-server/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherTest.java
+++
b/brooklyn-server/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherTest.java
@@@ -1,0 -1,368 +1,392 @@@
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF 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.apache.brooklyn.launcher;
+
+ import org.apache.brooklyn.api.entity.Application;
+ import org.apache.brooklyn.api.entity.EntitySpec;
+ import org.apache.brooklyn.api.location.Location;
+ import org.apache.brooklyn.api.mgmt.ManagementContext;
+ import org.apache.brooklyn.core.catalog.internal.CatalogInitialization;
+ import org.apache.brooklyn.core.entity.factory.ApplicationBuilder;
+ import org.apache.brooklyn.core.internal.BrooklynProperties;
+ import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
+ import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
+ import org.apache.brooklyn.core.mgmt.rebind.RebindTestUtils;
+ import org.apache.brooklyn.core.server.BrooklynServerConfig;
+ import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
+ import org.apache.brooklyn.core.test.entity.TestApplication;
+ import org.apache.brooklyn.core.test.entity.TestApplicationImpl;
+ import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.launcher.BrooklynLauncher;
+
+ import static org.testng.Assert.assertEquals;
+ import static org.testng.Assert.assertNotNull;
+ import static org.testng.Assert.assertNull;
+ import static org.testng.Assert.assertSame;
+ import static org.testng.Assert.assertTrue;
+
+ import java.io.File;
+ import java.io.IOException;
+ import java.io.StringWriter;
+ import java.io.Writer;
+ import java.net.URI;
+ import java.nio.charset.Charset;
++import java.nio.file.Path;
++import java.nio.file.Paths;
+ import java.util.Properties;
+
+ import org.apache.brooklyn.test.HttpTestUtils;
+ import org.apache.brooklyn.util.exceptions.FatalRuntimeException;
+ import org.apache.brooklyn.util.io.FileUtil;
+ import org.apache.brooklyn.util.net.Urls;
+ import org.apache.brooklyn.util.os.Os;
+ import org.apache.brooklyn.util.text.StringFunctions;
+ import org.apache.brooklyn.util.text.Strings;
+ import org.testng.Assert;
+ import org.testng.annotations.AfterMethod;
+ import org.testng.annotations.Test;
+ import
org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
+
-import com.google.api.client.util.Preconditions;
+ import com.google.common.base.Charsets;
+ import com.google.common.base.Function;
++import com.google.common.base.Preconditions;
+ import com.google.common.base.Predicates;
+ import com.google.common.collect.ImmutableList;
+ import com.google.common.collect.Iterables;
+ import com.google.common.collect.Maps;
+ import com.google.common.io.Files;
+
+ public class BrooklynLauncherTest {
+
+ private BrooklynLauncher launcher;
- private File persistenceDir;
-
++
+ @AfterMethod(alwaysRun=true)
+ public void tearDown() throws Exception {
+ if (launcher != null) launcher.terminate();
- if (persistenceDir != null)
RebindTestUtils.deleteMementoDir(persistenceDir);
+ launcher = null;
+ }
+
+ // Integration because takes a few seconds to start web-console
+ @Test(groups="Integration")
+ public void testStartsWebServerOnExpectectedPort() throws Exception {
+ launcher = newLauncherForTests(true)
+ .webconsolePort("10000+")
+ .start();
+
+ String webServerUrlStr =
launcher.getServerDetails().getWebServerUrl();
+ URI webServerUri = new URI(webServerUrlStr);
+
+ assertEquals(launcher.getApplications(), ImmutableList.of());
+ assertTrue(webServerUri.getPort() >= 10000 && webServerUri.getPort()
< 10100, "port="+webServerUri.getPort()+"; uri="+webServerUri);
+ HttpTestUtils.assertUrlReachable(webServerUrlStr);
+ }
+
+ // Integration because takes a few seconds to start web-console
+ @Test(groups="Integration")
+ public void testWebServerTempDirRespectsDataDirConfig() throws Exception {
+ String dataDirName = ".brooklyn-foo"+Strings.makeRandomId(4);
+ String dataDir = "~/"+dataDirName;
+
+ launcher = newLauncherForTests(true)
+ .brooklynProperties(BrooklynServerConfig.MGMT_BASE_DIR,
dataDir)
+ .start();
+
+ ManagementContext managementContext =
launcher.getServerDetails().getManagementContext();
+ String expectedTempDir = Os.mergePaths(Os.home(), dataDirName,
"planes", managementContext.getManagementPlaneId(),
managementContext.getManagementNodeId(), "jetty");
+
+ File webappTempDir =
launcher.getServerDetails().getWebServer().getWebappTempDir();
+ assertEquals(webappTempDir.getAbsolutePath(), expectedTempDir);
+ }
+
+ @Test
+ public void testCanDisableWebServerStartup() throws Exception {
+ launcher = newLauncherForTests(true)
+ .webconsole(false)
+ .start();
+
+ assertNull(launcher.getServerDetails().getWebServer());
+ assertNull(launcher.getServerDetails().getWebServerUrl());
+ Assert.assertTrue(
((ManagementContextInternal)launcher.getServerDetails().getManagementContext()).errors().isEmpty()
);
+ }
+
+ @Test
+ public void testStartsAppInstance() throws Exception {
+ launcher = newLauncherForTests(true)
+ .webconsole(false)
+ .application(new TestApplicationImpl())
+ .start();
+
+ assertOnlyApp(launcher, TestApplication.class);
+ }
+
+ @Test
+ public void testStartsAppFromSpec() throws Exception {
+ launcher = newLauncherForTests(true)
+ .webconsole(false)
+ .application(EntitySpec.create(TestApplication.class))
+ .start();
+
+ assertOnlyApp(launcher, TestApplication.class);
+ }
+
+ @Test
+ public void testStartsAppFromBuilder() throws Exception {
+ launcher = newLauncherForTests(true)
+ .webconsole(false)
+ .application(new
ApplicationBuilder(EntitySpec.create(TestApplication.class)) {
+ @Override protected void doBuild() {
+ }})
+ .start();
+
+ assertOnlyApp(launcher, TestApplication.class);
+ }
+
+ @Test
+ public void testStartsAppFromYAML() throws Exception {
+ String yaml = "name: example-app\n" +
+ "services:\n" +
+ "- serviceType:
org.apache.brooklyn.core.test.entity.TestEntity\n" +
+ " name: test-app";
+ launcher = newLauncherForTests(true)
+ .webconsole(false)
+ .application(yaml)
+ .start();
+
+ assertEquals(launcher.getApplications().size(), 1,
"apps="+launcher.getApplications());
+ Application app =
Iterables.getOnlyElement(launcher.getApplications());
+ assertEquals(app.getChildren().size(), 1, "children=" +
app.getChildren());
+ assertTrue(Iterables.getOnlyElement(app.getChildren()) instanceof
TestEntity);
+ }
+
+ @Test // may take 2s initializing location if running this test case
alone, but noise if running suite
+ public void testStartsAppInSuppliedLocations() throws Exception {
+ launcher = newLauncherForTests(true)
+ .webconsole(false)
+ .location("localhost")
+ .application(new
ApplicationBuilder(EntitySpec.create(TestApplication.class)) {
+ @Override protected void doBuild() {
+ }})
+ .start();
+
+ Application app = Iterables.find(launcher.getApplications(),
Predicates.instanceOf(TestApplication.class));
+ assertOnlyLocation(app, LocalhostMachineProvisioningLocation.class);
+ }
+
+ @Test
+ public void testUsesSuppliedManagementContext() throws Exception {
+ LocalManagementContext myManagementContext =
LocalManagementContextForTests.newInstance();
+ launcher = newLauncherForTests(false)
+ .webconsole(false)
+ .managementContext(myManagementContext)
+ .start();
+
+ assertSame(launcher.getServerDetails().getManagementContext(),
myManagementContext);
+ }
+
+ @Test
+ public void testUsesSuppliedBrooklynProperties() throws Exception {
+ BrooklynProperties props =
LocalManagementContextForTests.builder(true).buildProperties();
+ props.put("mykey", "myval");
+ launcher = newLauncherForTests(false)
+ .webconsole(false)
+ .brooklynProperties(props)
+ .start();
+
+
assertEquals(launcher.getServerDetails().getManagementContext().getConfig().getFirst("mykey"),
"myval");
+ }
+
+ @Test
+ public void testUsesSupplementaryBrooklynProperties() throws Exception {
+ launcher = newLauncherForTests(true)
+ .webconsole(false)
+ .brooklynProperties("mykey", "myval")
+ .start();
+
+
assertEquals(launcher.getServerDetails().getManagementContext().getConfig().getFirst("mykey"),
"myval");
+ }
+
+ @Test
+ public void testReloadBrooklynPropertiesRestoresProgrammaticProperties()
throws Exception {
+ launcher = newLauncherForTests(true)
+ .webconsole(false)
+ .brooklynProperties("mykey", "myval")
+ .start();
+ LocalManagementContext managementContext =
(LocalManagementContext)launcher.getServerDetails().getManagementContext();
+ assertEquals(managementContext.getConfig().getFirst("mykey"),
"myval");
+ managementContext.getBrooklynProperties().put("mykey", "newval");
+ assertEquals(managementContext.getConfig().getFirst("mykey"),
"newval");
+ managementContext.reloadBrooklynProperties();
+ assertEquals(managementContext.getConfig().getFirst("mykey"),
"myval");
+ }
+
+ @Test
+ public void testReloadBrooklynPropertiesFromFile() throws Exception {
+ File globalPropertiesFile =
File.createTempFile("local-brooklyn-properties-test", ".properties");
+ FileUtil.setFilePermissionsTo600(globalPropertiesFile);
+ try {
+ String property = "mykey=myval";
+ Files.append(getMinimalLauncherPropertiesString()+property,
globalPropertiesFile, Charsets.UTF_8);
+ launcher = newLauncherForTests(false)
+ .webconsole(false)
+
.globalBrooklynPropertiesFile(globalPropertiesFile.getAbsolutePath())
+ .start();
+ LocalManagementContext managementContext =
(LocalManagementContext)launcher.getServerDetails().getManagementContext();
+ assertEquals(managementContext.getConfig().getFirst("mykey"),
"myval");
+ property = "mykey=newval";
+ Files.write(getMinimalLauncherPropertiesString()+property,
globalPropertiesFile, Charsets.UTF_8);
+ managementContext.reloadBrooklynProperties();
+ assertEquals(managementContext.getConfig().getFirst("mykey"),
"newval");
+ } finally {
+ globalPropertiesFile.delete();
+ }
+ }
+
+ @Test(groups="Integration")
+ public void testChecksGlobalBrooklynPropertiesPermissionsX00() throws
Exception {
+ File propsFile =
File.createTempFile("testChecksGlobalBrooklynPropertiesPermissionsX00",
".properties");
+ propsFile.setReadable(true, false);
+ try {
+ launcher = newLauncherForTests(false)
+ .webconsole(false)
+ .globalBrooklynPropertiesFile(propsFile.getAbsolutePath())
+ .start();
+
+ Assert.fail("Should have thrown");
+ } catch (FatalRuntimeException e) {
+ if (!e.toString().contains("Invalid permissions for file")) throw
e;
+ } finally {
+ propsFile.delete();
+ }
+ }
+
+ @Test(groups="Integration")
+ public void testChecksLocalBrooklynPropertiesPermissionsX00() throws
Exception {
+ File propsFile =
File.createTempFile("testChecksLocalBrooklynPropertiesPermissionsX00",
".properties");
+ propsFile.setReadable(true, false);
+ try {
+ launcher = newLauncherForTests(false)
+ .webconsole(false)
+ .localBrooklynPropertiesFile(propsFile.getAbsolutePath())
+ .start();
+
+ Assert.fail("Should have thrown");
+ } catch (FatalRuntimeException e) {
+ if (!e.toString().contains("Invalid permissions for file")) throw
e;
+ } finally {
+ propsFile.delete();
+ }
+ }
+
+ @Test(groups="Integration")
++ public void testStartsWithSymlinkedBrooklynPropertiesPermissionsX00()
throws Exception {
++ File dir = Files.createTempDir();
++ Path globalPropsFile =
java.nio.file.Files.createFile(Paths.get(dir.toString(),
"globalProps.properties"));
++ Path globalSymlink =
java.nio.file.Files.createSymbolicLink(Paths.get(dir.toString(), "globalLink"),
globalPropsFile);
++ Path localPropsFile =
java.nio.file.Files.createFile(Paths.get(dir.toString(),
"localPropsFile.properties"));
++ Path localSymlink =
java.nio.file.Files.createSymbolicLink(Paths.get(dir.toString(), "localLink"),
localPropsFile);
++
++ Files.write(getMinimalLauncherPropertiesString() + "key_in_global=1",
globalPropsFile.toFile(), Charset.defaultCharset());
++ Files.write("key_in_local=2", localPropsFile.toFile(),
Charset.defaultCharset());
++ FileUtil.setFilePermissionsTo600(globalPropsFile.toFile());
++ FileUtil.setFilePermissionsTo600(localPropsFile.toFile());
++ try {
++ launcher = newLauncherForTests(false)
++ .webconsole(false)
++
.localBrooklynPropertiesFile(localSymlink.toAbsolutePath().toString())
++
.globalBrooklynPropertiesFile(globalSymlink.toAbsolutePath().toString())
++ .start();
++
assertEquals(launcher.getServerDetails().getManagementContext().getConfig().getFirst("key_in_global"),
"1");
++
assertEquals(launcher.getServerDetails().getManagementContext().getConfig().getFirst("key_in_local"),
"2");
++ } finally {
++ Os.deleteRecursively(dir);
++ }
++ }
++
++ @Test(groups="Integration")
+ public void testStartsWithBrooklynPropertiesPermissionsX00() throws
Exception {
+ File globalPropsFile =
File.createTempFile("testChecksLocalBrooklynPropertiesPermissionsX00_global",
".properties");
+ Files.write(getMinimalLauncherPropertiesString()+"key_in_global=1",
globalPropsFile, Charset.defaultCharset());
+ File localPropsFile =
File.createTempFile("testChecksLocalBrooklynPropertiesPermissionsX00_local",
".properties");
+ Files.write("key_in_local=2", localPropsFile,
Charset.defaultCharset());
+ FileUtil.setFilePermissionsTo600(globalPropsFile);
+ FileUtil.setFilePermissionsTo600(localPropsFile);
+ try {
+ launcher = newLauncherForTests(false)
+ .webconsole(false)
+
.localBrooklynPropertiesFile(localPropsFile.getAbsolutePath())
+
.globalBrooklynPropertiesFile(globalPropsFile.getAbsolutePath())
+ .start();
+
assertEquals(launcher.getServerDetails().getManagementContext().getConfig().getFirst("key_in_global"),
"1");
+
assertEquals(launcher.getServerDetails().getManagementContext().getConfig().getFirst("key_in_local"),
"2");
+ } finally {
+ globalPropsFile.delete();
+ localPropsFile.delete();
+ }
+ }
+
+ @Test // takes a bit of time because starts webapp, but also tests rest
api so useful
+ public void testErrorsCaughtByApiAndRestApiWorks() throws Exception {
+ launcher = newLauncherForTests(true)
+ .catalogInitialization(new CatalogInitialization(null, false,
null, false).addPopulationCallback(new Function<CatalogInitialization, Void>() {
+ @Override
+ public Void apply(CatalogInitialization input) {
+ throw new
RuntimeException("deliberate-exception-for-testing");
+ }
+ }))
+ .start();
+ // such an error should be thrown, then caught in this calling thread
+ ManagementContext mgmt =
launcher.getServerDetails().getManagementContext();
+ Assert.assertFalse(
((ManagementContextInternal)mgmt).errors().isEmpty() );
+ Assert.assertTrue(
((ManagementContextInternal)mgmt).errors().get(0).toString().contains("deliberate"),
""+((ManagementContextInternal)mgmt).errors() );
+ HttpTestUtils.assertContentMatches(
+ Urls.mergePaths(launcher.getServerDetails().getWebServerUrl(),
"v1/server/up"),
+ "true");
+ HttpTestUtils.assertContentMatches(
+ Urls.mergePaths(launcher.getServerDetails().getWebServerUrl(),
"v1/server/healthy"),
+ "false");
+ // TODO test errors api?
+ }
+
+ private BrooklynLauncher newLauncherForTests(boolean minimal) {
- Preconditions.checkArgument(launcher==null, "can only be used if no
launcher yet");
++ Preconditions.checkArgument(launcher == null, "can only be used if no
launcher yet");
+ BrooklynLauncher launcher = BrooklynLauncher.newInstance();
+ if (minimal)
+
launcher.brooklynProperties(LocalManagementContextForTests.builder(true).buildProperties());
+ return launcher;
+ }
+
+ private String getMinimalLauncherPropertiesString() throws IOException {
+ BrooklynProperties p1 =
LocalManagementContextForTests.builder(true).buildProperties();
+ Properties p = new Properties();
+ p.putAll(Maps.transformValues(p1.asMapWithStringKeys(),
StringFunctions.toStringFunction()));
+ Writer w = new StringWriter();
+ p.store(w, "test");
+ w.close();
+ return w.toString()+"\n";
+ }
+
+ private void assertOnlyApp(BrooklynLauncher launcher, Class<? extends
Application> expectedType) {
+ assertEquals(launcher.getApplications().size(), 1,
"apps="+launcher.getApplications());
+ assertNotNull(Iterables.find(launcher.getApplications(),
Predicates.instanceOf(TestApplication.class), null),
"apps="+launcher.getApplications());
+ }
+
+ private void assertOnlyLocation(Application app, Class<? extends
Location> expectedType) {
+ assertEquals(app.getLocations().size(), 1,
"locs="+app.getLocations());
+ assertNotNull(Iterables.find(app.getLocations(),
Predicates.instanceOf(LocalhostMachineProvisioningLocation.class), null),
"locs="+app.getLocations());
+ }
+ }