/*
* 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.location.localhost;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.api.location.NoMachinesAvailableException;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.internal.BrooklynProperties;
import org.apache.brooklyn.core.location.BasicLocationRegistry;
import org.apache.brooklyn.core.location.internal.LocationInternal;
import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
import org.apache.brooklyn.location.byon.FixedListMachineProvisioningLocation;
import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
import org.apache.brooklyn.util.text.StringEscapes.JavaStringEscapes;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
public class LocalhostLocationResolverTest {
private BrooklynProperties brooklynProperties;
private LocalManagementContext managementContext;
@BeforeMethod(alwaysRun=true)
public void setUp() throws Exception {
managementContext = LocalManagementContextForTests.newInstance();
brooklynProperties = managementContext.getBrooklynProperties();
}
@AfterMethod(alwaysRun=true)
public void tearDown() throws Exception {
if (managementContext != null) Entities.destroyAll(managementContext);
}
@Test
public void testTakesLocalhostScopedProperties() {
brooklynProperties.put("brooklyn.location.localhost.privateKeyFile", "myprivatekeyfile");
brooklynProperties.put("brooklyn.location.localhost.publicKeyFile", "mypublickeyfile");
brooklynProperties.put("brooklyn.location.localhost.privateKeyData", "myprivateKeyData");
brooklynProperties.put("brooklyn.location.localhost.publicKeyData", "myPublicKeyData");
brooklynProperties.put("brooklyn.location.localhost.privateKeyPassphrase", "myprivateKeyPassphrase");
Map<String, Object> conf = resolve("localhost").config().getBag().getAllConfig();
assertEquals(conf.get("privateKeyFile"), "myprivatekeyfile");
assertEquals(conf.get("publicKeyFile"), "mypublickeyfile");
assertEquals(conf.get("privateKeyData"), "myprivateKeyData");
assertEquals(conf.get("publicKeyData"), "myPublicKeyData");
assertEquals(conf.get("privateKeyPassphrase"), "myprivateKeyPassphrase");
}
@Test
public void testTakesLocalhostDeprecatedScopedProperties() {
brooklynProperties.put("brooklyn.localhost.privateKeyFile", "myprivatekeyfile");
brooklynProperties.put("brooklyn.localhost.publicKeyFile", "mypublickeyfile");
brooklynProperties.put("brooklyn.localhost.privateKeyData", "myprivateKeyData");
brooklynProperties.put("brooklyn.localhost.publicKeyData", "myPublicKeyData");
brooklynProperties.put("brooklyn.localhost.privateKeyPassphrase", "myprivateKeyPassphrase");
Map<String, Object> conf = resolve("localhost").config().getBag().getAllConfig();
assertEquals(conf.get("privateKeyFile"), "myprivatekeyfile");
assertEquals(conf.get("publicKeyFile"), "mypublickeyfile");
assertEquals(conf.get("privateKeyData"), "myprivateKeyData");
assertEquals(conf.get("publicKeyData"), "myPublicKeyData");
assertEquals(conf.get("privateKeyPassphrase"), "myprivateKeyPassphrase");
}
@Test
public void testTakesDeprecatedProperties() {
brooklynProperties.put("brooklyn.localhost.private-key-file", "myprivatekeyfile");
brooklynProperties.put("brooklyn.localhost.public-key-file", "mypublickeyfile");
brooklynProperties.put("brooklyn.localhost.private-key-data", "myprivateKeyData");
brooklynProperties.put("brooklyn.localhost.public-key-data", "myPublicKeyData");
brooklynProperties.put("brooklyn.localhost.private-key-passphrase", "myprivateKeyPassphrase");
Map<String, Object> conf = resolve("localhost").config().getBag().getAllConfig();
assertEquals(conf.get("privateKeyFile"), "myprivatekeyfile");
assertEquals(conf.get("publicKeyFile"), "mypublickeyfile");
assertEquals(conf.get("privateKeyData"), "myprivateKeyData");
assertEquals(conf.get("publicKeyData"), "myPublicKeyData");
assertEquals(conf.get("privateKeyPassphrase"), "myprivateKeyPassphrase");
}
@Test
public void testPropertyScopePrescedence() {
brooklynProperties.put("brooklyn.location.named.mynamed", "localhost");
// prefer those in "named" over everything else
brooklynProperties.put("brooklyn.location.named.mynamed.privateKeyFile", "privateKeyFile-inNamed");
brooklynProperties.put("brooklyn.location.localhost.privateKeyFile", "privateKeyFile-inProviderSpecific");
brooklynProperties.put("brooklyn.localhost.privateKeyFile", "privateKeyFile-inGeneric");
// prefer those in provider-specific over generic
brooklynProperties.put("brooklyn.location.localhost.publicKeyFile", "publicKeyFile-inProviderSpecific");
brooklynProperties.put("brooklyn.location.publicKeyFile", "publicKeyFile-inGeneric");
// prefer location-generic if nothing else
brooklynProperties.put("brooklyn.location.privateKeyData", "privateKeyData-inGeneric");
Map<String, Object> conf = resolve("named:mynamed").config().getBag().getAllConfig();
assertEquals(conf.get("privateKeyFile"), "privateKeyFile-inNamed");
assertEquals(conf.get("publicKeyFile"), "publicKeyFile-inProviderSpecific");
assertEquals(conf.get("privateKeyData"), "privateKeyData-inGeneric");
}
@Test
public void testLocalhostLoads() {
Assert.assertTrue(resolve("localhost") instanceof LocalhostMachineProvisioningLocation);
}
@Test
public void testThrowsOnInvalid() throws Exception {
assertThrowsNoSuchElement("wrongprefix");
assertThrowsIllegalArgument("localhost(name=abc"); // no closing bracket
assertThrowsIllegalArgument("localhost(name)"); // no value for name
assertThrowsIllegalArgument("localhost(name=)"); // no value for name
}
@Test
public void testAcceptsList() {
List<Location> l = getLocationResolver().resolve(ImmutableList.of("localhost"));
assertEquals(l.size(), 1, "l="+l);
assertTrue(l.get(0) instanceof LocalhostMachineProvisioningLocation, "l="+l);
}
@SuppressWarnings("unchecked")
@Test
public void testRegistryCommaResolution() throws NoMachinesAvailableException {
List<Location> l;
l = getLocationResolver().resolve(JavaStringEscapes.unwrapJsonishListIfPossible("localhost,localhost,localhost"));
assertEquals(l.size(), 3, "l="+l);
assertTrue(l.get(0) instanceof LocalhostMachineProvisioningLocation, "l="+l);
assertTrue(l.get(1) instanceof LocalhostMachineProvisioningLocation, "l="+l);
assertTrue(l.get(2) instanceof LocalhostMachineProvisioningLocation, "l="+l);
// And check works if comma in brackets
l = getLocationResolver().resolve(JavaStringEscapes.unwrapJsonishListIfPossible(
"[ \"byon:(hosts=\\\"192.168.0.1\\\",user=bob)\", \"byon:(hosts=\\\"192.168.0.2\\\",user=bob2)\" ]"));
assertEquals(l.size(), 2, "l="+l);
assertTrue(l.get(0) instanceof FixedListMachineProvisioningLocation, "l="+l);
assertTrue(l.get(1) instanceof FixedListMachineProvisioningLocation, "l="+l);
assertEquals(((FixedListMachineProvisioningLocation<SshMachineLocation>)l.get(0)).obtain().getUser(), "bob");
assertEquals(((FixedListMachineProvisioningLocation<SshMachineLocation>)l.get(1)).obtain().getUser(), "bob2");
}
@Test(expectedExceptions={NoSuchElementException.class})
public void testRegistryCommaResolutionInListNotAllowed1() throws NoMachinesAvailableException {
// disallowed since 0.7.0
getLocationResolver().resolve(ImmutableList.of("localhost,localhost,localhost"));
}
@Test(expectedExceptions={IllegalArgumentException.class})
public void testRegistryCommaResolutionInListNotAllowed2() throws NoMachinesAvailableException {
// disallowed since 0.7.0
// fails because it interprets the entire string as a single spec, which does not parse
getLocationResolver().resolve(ImmutableList.of("localhost(),localhost()"));
}
@Test(expectedExceptions={IllegalArgumentException.class})
public void testRegistryCommaResolutionInListNotAllowed3() throws NoMachinesAvailableException {
// disallowed since 0.7.0
// fails because it interprets the entire string as a single spec, which does not parse
getLocationResolver().resolve(ImmutableList.of("localhost(name=a),localhost(name=b)"));
}
@Test(expectedExceptions={IllegalArgumentException.class})
public void testDoesNotAcceptsListOLists() {
((BasicLocationRegistry)managementContext.getLocationRegistry()).resolve(ImmutableList.of(ImmutableList.of("localhost")));
}
@Test
public void testResolvesExplicitName() throws Exception {
Location location = resolve("localhost(name=myname)");
assertTrue(location instanceof LocalhostMachineProvisioningLocation);
assertEquals(location.getDisplayName(), "myname");
}
@Test
public void testWithOldStyleColon() throws Exception {
Location location = resolve("localhost:(name=myname)");
assertTrue(location instanceof LocalhostMachineProvisioningLocation);
assertEquals(location.getDisplayName(), "myname");
}
@Test
public void testResolvesPropertiesInSpec() throws Exception {
LocationInternal location = resolve("localhost(privateKeyFile=myprivatekeyfile,name=myname)");
assertTrue(location instanceof LocalhostMachineProvisioningLocation);
assertEquals(location.getDisplayName(), "myname");
assertEquals(location.config().getBag().getStringKey("privateKeyFile"), "myprivatekeyfile");
}
@Test
public void testResolvesDefaultName() throws Exception {
Location location = resolve("localhost");
assertTrue(location instanceof LocalhostMachineProvisioningLocation);
assertEquals(location.getDisplayName(), "localhost");
Location location2 = resolve("localhost()");
assertTrue(location2 instanceof LocalhostMachineProvisioningLocation);
assertEquals(location2.getDisplayName(), "localhost");
}
private BasicLocationRegistry getLocationResolver() {
return (BasicLocationRegistry) managementContext.getLocationRegistry();
}
private LocationInternal resolve(String val) {
Location l = managementContext.getLocationRegistry().resolve(val);
Assert.assertNotNull(l);
return (LocationInternal) l;
}
private void assertThrowsNoSuchElement(String val) {
try {
resolve(val);
fail();
} catch (NoSuchElementException e) {
// success
}
// and check the long form returns an Absent (not throwing)
Assert.assertTrue(managementContext.getLocationRegistry().resolve(val, false, null).isAbsent());
}
private void assertThrowsIllegalArgument(String val) {
try {
resolve(val);
fail();
} catch (IllegalArgumentException e) {
// success
}
// and check the long form returns an Absent (not throwing)
Assert.assertTrue(managementContext.getLocationRegistry().resolve(val, false, null).isAbsent());
}
}