/*
* 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.jclouds;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.Nullable;
import org.apache.brooklyn.api.location.LocationSpec;
import org.apache.brooklyn.api.location.MachineLocation;
import org.apache.brooklyn.api.location.MachineLocationCustomizer;
import org.apache.brooklyn.api.location.NoMachinesAvailableException;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.internal.BrooklynProperties;
import org.apache.brooklyn.core.location.LocationConfigKeys;
import org.apache.brooklyn.core.location.cloud.names.CustomMachineNamer;
import org.apache.brooklyn.core.location.geo.HostGeoInfo;
import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
import org.apache.brooklyn.location.jclouds.JcloudsLocation.UserCreation;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.jclouds.scriptbuilder.domain.OsFamily;
import org.jclouds.scriptbuilder.domain.StatementList;
import org.mockito.Mockito;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.ContiguousSet;
import com.google.common.collect.DiscreteDomain;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Range;
import com.google.common.primitives.Ints;
import com.google.common.reflect.TypeToken;
/**
* @author Shane Witbeck
*/
public class JcloudsLocationTest implements JcloudsLocationConfig {
private static final Logger log = LoggerFactory.getLogger(JcloudsLocationTest.class);
public static Predicate<ConfigBag> checkerFor(final String user, final Integer minRam, final Integer minCores) {
return new Predicate<ConfigBag>() {
@Override
public boolean apply(@Nullable ConfigBag input) {
Assert.assertEquals(input.get(USER), user);
Assert.assertEquals(input.get(MIN_RAM), minRam);
Assert.assertEquals(input.get(MIN_CORES), minCores);
return true;
}
};
}
public static Predicate<ConfigBag> templateCheckerFor(final String ports) {
return new Predicate<ConfigBag>() {
@Override
public boolean apply(@Nullable ConfigBag input) {
Assert.assertEquals(input.get(INBOUND_PORTS), ports);
return false;
}
};
}
private LocalManagementContext managementContext;
@BeforeMethod(alwaysRun=true)
public void setUp() throws Exception {
managementContext = LocalManagementContextForTests.newInstance(BrooklynProperties.Factory.newDefault());
}
@AfterMethod(alwaysRun=true)
public void tearUp() throws Exception {
if (managementContext != null) Entities.destroyAll(managementContext);
}
@Test
public void testCreateWithFlagsDirectly() throws Exception {
BailOutJcloudsLocation jcl = BailOutJcloudsLocation.newBailOutJcloudsLocation(managementContext);
jcl.tryObtainAndCheck(MutableMap.of(MIN_CORES, 2), checkerFor("fred", 16, 2));
}
@Test
public void testCreateWithFlagsDirectlyAndOverride() throws Exception {
BailOutJcloudsLocation jcl = BailOutJcloudsLocation.newBailOutJcloudsLocation(managementContext);
jcl.tryObtainAndCheck(MutableMap.of(MIN_CORES, 2, MIN_RAM, 8), checkerFor("fred", 8, 2));
}
@Test
public void testCreateWithFlagsSubLocation() throws Exception {
BailOutJcloudsLocation jcl = BailOutJcloudsLocation.newBailOutJcloudsLocation(managementContext);
jcl = (BailOutJcloudsLocation) jcl.newSubLocation(MutableMap.of(USER, "jon", MIN_CORES, 2));
jcl.tryObtainAndCheck(MutableMap.of(MIN_CORES, 3), checkerFor("jon", 16, 3));
}
@Test
public void testSingleInttoIntPortArray() {
int port = 1;
int[] intArray = new int[] {1};
Assert.assertEquals(JcloudsLocation.toIntPortArray(port), intArray);
}
@Test
public void testSingleStringtoIntPortArray() {
String portString = "1";
int[] intArray = new int[] {1};
Assert.assertEquals(JcloudsLocation.toIntPortArray(portString), intArray);
}
@Test
public void testStringListWithBracketstoIntPortArray() {
String listString = "[1, 2, 3, 4]";
int[] intArray = new int[] {1, 2, 3, 4};
Assert.assertEquals(JcloudsLocation.toIntPortArray(listString), intArray);
}
@Test
public void testStringListWithoutBracketstoIntPortArray() {
String listString = "1, 2, 3, 4";
int[] intArray = new int[] {1, 2, 3, 4};
Assert.assertEquals(JcloudsLocation.toIntPortArray(listString), intArray);
}
@Test
public void testEmptyStringListtoIntPortArray() {
String listString = "[]";
int[] intArray = new int[] {};
Assert.assertEquals(JcloudsLocation.toIntPortArray(listString), intArray);
}
@Test
public void testIntArraytoIntPortArray() {
int[] intArray = new int[] {1, 2, 3, 4};
Assert.assertEquals(JcloudsLocation.toIntPortArray(intArray), intArray);
}
@Test
public void testObjectArrayOfIntegerstoIntPortArray() {
Object[] integerObjectArray = new Object[] {1, 2, 3, 4};
int[] intArray = new int[] {1, 2, 3, 4};
Assert.assertEquals(JcloudsLocation.toIntPortArray(integerObjectArray), intArray);
}
@Test
public void testObjectArrayOfStringstoIntPortArray() {
Object[] stringObjectArray = new Object[] {"1", "2", "3", "4"};
int[] intArray = new int[] {1, 2, 3, 4};
Assert.assertEquals(JcloudsLocation.toIntPortArray(stringObjectArray), intArray);
}
@Test
public void testStringArraytoIntPortArray() {
String[] stringArray = new String[] {"1", "2", "3"};
int[] intArray = new int[] {1, 2, 3};
Assert.assertEquals(JcloudsLocation.toIntPortArray(stringArray), intArray);
}
@Test
public void testStringPortRangetoIntPortArray() {
String portRange = "1-100";
int[] intArray = Ints.toArray(ContiguousSet.create(Range.closed(1, 100), DiscreteDomain.integers()));
Assert.assertEquals(intArray, JcloudsLocation.toIntPortArray(portRange));
}
@Test
public void testStringPortPlustoIntPortArray() {
String portPlus = "100+";
int[] intArray = Ints.toArray(ContiguousSet.create(Range.closed(100, 65535), DiscreteDomain.integers()));
Assert.assertEquals(intArray, JcloudsLocation.toIntPortArray(portPlus));
}
@Test
public void testCombinationOfInputstoIntPortArray() {
Collection<Object> portInputs = Lists.newLinkedList();
portInputs.add(1);
portInputs.add("2");
portInputs.add("3-100");
portInputs.add("101,102,103");
portInputs.add("[104,105,106]");
portInputs.add(new int[] {107, 108, 109});
portInputs.add(new String[] {"110", "111", "112"});
portInputs.add(new Object[] {113, 114, 115});
int[] intArray = Ints.toArray(ContiguousSet.create(Range.closed(1, 115), DiscreteDomain.integers()));
Assert.assertEquals(intArray, JcloudsLocation.toIntPortArray(portInputs));
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testMalformedStringNumbertoIntPortArray() {
String numberStr = "1i";
JcloudsLocation.toIntPortArray(numberStr);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testMalformedStringRangetoIntPortArray() {
String rangeString = "1-";
JcloudsLocation.toIntPortArray(rangeString);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testMalformedStringListWithBracketstoIntPortArray() {
String listString = "[1,2,e]";
JcloudsLocation.toIntPortArray(listString);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testMalformedStringListWithoutBracketstoIntPortArray() {
String listString = "1,2,e";
JcloudsLocation.toIntPortArray(listString);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testMalformedStringArraytoIntPortArray() {
String[] stringArray = new String[] {"1", "2", "e"};
JcloudsLocation.toIntPortArray(stringArray);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testIllegalObjectArrayOfDoublestoIntPortArray() {
Object[] doubleObjectArray = new Object[] {1.0, 2.0, 3.0};
JcloudsLocation.toIntPortArray(doubleObjectArray);
}
@Test
public void testVMCreationIsRetriedOnFailure() {
final AtomicInteger count = new AtomicInteger();
Function<ConfigBag, Void> countingInterceptor = new Function<ConfigBag, Void>() {
@Override public Void apply(ConfigBag input) {
count.incrementAndGet();
return null;
}
};
BailOutJcloudsLocation loc = BailOutJcloudsLocation.newBailOutJcloudsLocation(managementContext, ImmutableMap.<ConfigKey<?>, Object>of(
MACHINE_CREATE_ATTEMPTS, 3,
BailOutJcloudsLocation.BUILD_TEMPLATE_INTERCEPTOR, countingInterceptor));
loc.tryObtain();
Assert.assertEquals(count.get(), 3);
}
@Test(groups={"Live", "Live-sanity"})
public void testCreateWithInboundPorts() {
BailOutJcloudsLocation jcloudsLocation = BailOutJcloudsLocation.newBailOutJcloudsLocationForLiveTest(managementContext);
jcloudsLocation = (BailOutJcloudsLocation) jcloudsLocation.newSubLocation(MutableMap.of());
jcloudsLocation.tryObtainAndCheck(MutableMap.of(), templateCheckerFor("[22, 80, 9999]"));
int[] ports = new int[] {22, 80, 9999};
Assert.assertEquals(jcloudsLocation.getTemplate().getOptions().getInboundPorts(), ports);
}
@Test(groups={"Live", "Live-sanity"})
public void testCreateWithInboundPortsOverride() {
BailOutJcloudsLocation jcloudsLocation = BailOutJcloudsLocation.newBailOutJcloudsLocationForLiveTest(managementContext);
jcloudsLocation = (BailOutJcloudsLocation) jcloudsLocation.newSubLocation(MutableMap.of());
jcloudsLocation.tryObtainAndCheck(MutableMap.of(INBOUND_PORTS, "[23, 81, 9998]"), templateCheckerFor("[23, 81, 9998]"));
int[] ports = new int[] {23, 81, 9998};
Assert.assertEquals(jcloudsLocation.getTemplate().getOptions().getInboundPorts(), ports);
}
@Test
public void testCreateWithMaxConcurrentCallsUnboundedByDefault() throws Exception {
final int numCalls = 20;
ConcurrencyTracker interceptor = new ConcurrencyTracker();
ExecutorService executor = Executors.newCachedThreadPool();
try {
final BailOutJcloudsLocation jcloudsLocation = BailOutJcloudsLocation.newBailOutJcloudsLocation(
managementContext, ImmutableMap.<ConfigKey<?>, Object>of(
BailOutJcloudsLocation.BUILD_TEMPLATE_INTERCEPTOR, interceptor));
for (int i = 0; i < numCalls; i++) {
executor.execute(new Runnable() {
@Override
public void run() {
jcloudsLocation.tryObtain();
}
});
}
interceptor.assertCallCountEventually(numCalls);
interceptor.unblock();
executor.shutdown();
executor.awaitTermination(10, TimeUnit.SECONDS);
} finally {
executor.shutdownNow();
}
}
@Test(groups="Integration") // because takes 1 sec
public void testCreateWithMaxConcurrentCallsRespectsConfig() throws Exception {
final int numCalls = 4;
final int maxConcurrentCreations = 2;
ConcurrencyTracker interceptor = new ConcurrencyTracker();
ExecutorService executor = Executors.newCachedThreadPool();
try {
final BailOutJcloudsLocation jcloudsLocation = BailOutJcloudsLocation.newBailOutJcloudsLocation(
managementContext, ImmutableMap.of(
BailOutJcloudsLocation.BUILD_TEMPLATE_INTERCEPTOR, interceptor,
MAX_CONCURRENT_MACHINE_CREATIONS, maxConcurrentCreations));
for (int i = 0; i < numCalls; i++) {
executor.execute(new Runnable() {
@Override
public void run() {
jcloudsLocation.tryObtain();
}
});
}
interceptor.assertCallCountEventually(maxConcurrentCreations);
interceptor.assertCallCountContinually(maxConcurrentCreations);
interceptor.unblock();
interceptor.assertCallCountEventually(numCalls);
executor.shutdown();
executor.awaitTermination(10, TimeUnit.SECONDS);
} finally {
executor.shutdownNow();
}
}
@Test(groups="Integration") // because takes 1 sec
public void testCreateWithMaxConcurrentCallsAppliesToSubLocations() throws Exception {
final int numCalls = 4;
final int maxConcurrentCreations = 2;
ConcurrencyTracker interceptor = new ConcurrencyTracker();
ExecutorService executor = Executors.newCachedThreadPool();
try {
final BailOutJcloudsLocation jcloudsLocation = BailOutJcloudsLocation.newBailOutJcloudsLocation(
managementContext, ImmutableMap.of(
BailOutJcloudsLocation.BUILD_TEMPLATE_INTERCEPTOR, interceptor,
MAX_CONCURRENT_MACHINE_CREATIONS, maxConcurrentCreations));
for (int i = 0; i < numCalls; i++) {
final BailOutJcloudsLocation subLocation = (BailOutJcloudsLocation) jcloudsLocation.newSubLocation(MutableMap.of());
executor.execute(new Runnable() {
@Override
public void run() {
subLocation.tryObtain();
}
});
}
interceptor.assertCallCountEventually(maxConcurrentCreations);
interceptor.assertCallCountContinually(maxConcurrentCreations);
interceptor.unblock();
interceptor.assertCallCountEventually(numCalls);
executor.shutdown();
executor.awaitTermination(10, TimeUnit.SECONDS);
} finally {
executor.shutdownNow();
}
}
@Test
public void testCreateWithCustomMachineNamer() {
final String machineNamerClass = CustomMachineNamer.class.getName();
BailOutJcloudsLocation jcloudsLocation = BailOutJcloudsLocation.newBailOutJcloudsLocation(
managementContext, ImmutableMap.<ConfigKey<?>, Object>of(
LocationConfigKeys.CLOUD_MACHINE_NAMER_CLASS, machineNamerClass));
jcloudsLocation.tryObtainAndCheck(ImmutableMap.of(CustomMachineNamer.MACHINE_NAME_TEMPLATE, "ignored"), new Predicate<ConfigBag>() {
public boolean apply(ConfigBag input) {
Assert.assertEquals(input.get(LocationConfigKeys.CLOUD_MACHINE_NAMER_CLASS), machineNamerClass);
return true;
}
});
}
@Test
public void testCreateWithCustomMachineNamerOnObtain() {
final String machineNamerClass = CustomMachineNamer.class.getName();
BailOutJcloudsLocation jcloudsLocation = BailOutJcloudsLocation.newBailOutJcloudsLocation(managementContext);
ImmutableMap<ConfigKey<String>, String> flags = ImmutableMap.of(
CustomMachineNamer.MACHINE_NAME_TEMPLATE, "ignored",
LocationConfigKeys.CLOUD_MACHINE_NAMER_CLASS, machineNamerClass);
jcloudsLocation.tryObtainAndCheck(flags, new Predicate<ConfigBag>() {
public boolean apply(ConfigBag input) {
Assert.assertEquals(input.get(LocationConfigKeys.CLOUD_MACHINE_NAMER_CLASS), machineNamerClass);
return true;
}
});
}
public static class ConcurrencyTracker implements Function<ConfigBag,Void> {
final AtomicInteger concurrentCallsCounter = new AtomicInteger();
final CountDownLatch continuationLatch = new CountDownLatch(1);
@Override public Void apply(ConfigBag input) {
concurrentCallsCounter.incrementAndGet();
try {
continuationLatch.await();
} catch (InterruptedException e) {
throw Exceptions.propagate(e);
}
return null;
}
public void unblock() {
continuationLatch.countDown();
}
public void assertCallCountEventually(final int expected) {
Asserts.succeedsEventually(new Runnable() {
@Override public void run() {
Assert.assertEquals(concurrentCallsCounter.get(), expected);
}
});
}
public void assertCallCountContinually(final int expected) {
Asserts.succeedsContinually(new Runnable() {
@Override public void run() {
Assert.assertEquals(concurrentCallsCounter.get(), expected);
}
});
}
}
@SuppressWarnings("serial")
public static class FakeLocalhostWithParentJcloudsLocation extends JcloudsLocation {
public static final ConfigKey<Function<ConfigBag,Void>> BUILD_TEMPLATE_INTERCEPTOR = ConfigKeys.newConfigKey(new TypeToken<Function<ConfigBag,Void>>() {}, "buildtemplateinterceptor");
ConfigBag lastConfigBag;
public FakeLocalhostWithParentJcloudsLocation() {
super();
}
public FakeLocalhostWithParentJcloudsLocation(Map<?, ?> conf) {
super(conf);
}
@Override
public JcloudsSshMachineLocation obtain(Map<?, ?> flags) throws NoMachinesAvailableException {
JcloudsSshMachineLocation result = getManagementContext().getLocationManager().createLocation(LocationSpec.create(JcloudsSshMachineLocation.class)
.configure("address", "127.0.0.1")
.configure("port", 22)
.configure("user", "bob")
.configure("jcloudsParent", this)
.configure("nodeId", "myNodeId")
.configure("imageId", "myImageId")
.configure("privateAddresses", ImmutableSet.of("10.0.0.1"))
.configure("publicAddresses", ImmutableSet.of("56.0.0.1"))
);
registerJcloudsMachineLocation("bogus", result);
// explicitly invoke this customizer, to comply with tests
for (JcloudsLocationCustomizer customizer : getCustomizers(config().getBag())) {
customizer.customize(this, null, (JcloudsMachineLocation)result);
}
for (MachineLocationCustomizer customizer : getMachineCustomizers(config().getBag())) {
customizer.customize((JcloudsMachineLocation)result);
}
return result;
}
@Override
protected void releaseNode(String instanceId) {
// no-op
}
}
@Test
public void testInheritsGeo() throws Exception {
ConfigBag allConfig = ConfigBag.newInstance()
.configure(IMAGE_ID, "bogus")
.configure(CLOUD_PROVIDER, "aws-ec2")
.configure(CLOUD_REGION_ID, "bogus")
.configure(ACCESS_IDENTITY, "bogus")
.configure(ACCESS_CREDENTIAL, "bogus")
.configure(LocationConfigKeys.LATITUDE, 42d)
.configure(LocationConfigKeys.LONGITUDE, -20d)
.configure(MACHINE_CREATE_ATTEMPTS, 1);
FakeLocalhostWithParentJcloudsLocation ll = managementContext.getLocationManager().createLocation(LocationSpec.create(FakeLocalhostWithParentJcloudsLocation.class).configure(allConfig.getAllConfig()));
MachineLocation l = ll.obtain();
log.info("loc:" +l);
HostGeoInfo geo = HostGeoInfo.fromLocation(l);
log.info("geo: "+geo);
Assert.assertEquals(geo.latitude, 42d, 0.00001);
Assert.assertEquals(geo.longitude, -20d, 0.00001);
}
@SuppressWarnings("unchecked")
@Test
public void testInheritsGeoFromLocationMetadataProperties() throws Exception {
// in location-metadata.properties:
// brooklyn.location.jclouds.softlayer@wdc01.latitude=38.909202
// brooklyn.location.jclouds.softlayer@wdc01.longitude=-77.47314
ConfigBag allConfig = ConfigBag.newInstance()
.configure(IMAGE_ID, "bogus")
.configure(CLOUD_PROVIDER, "softlayer")
.configure(CLOUD_REGION_ID, "wdc01")
.configure(ACCESS_IDENTITY, "bogus")
.configure(ACCESS_CREDENTIAL, "bogus")
.configure(MACHINE_CREATE_ATTEMPTS, 1);
FakeLocalhostWithParentJcloudsLocation ll = managementContext.getLocationManager().createLocation(LocationSpec.create(FakeLocalhostWithParentJcloudsLocation.class)
.configure(new JcloudsPropertiesFromBrooklynProperties().getJcloudsProperties("softlayer", "wdc01", null, managementContext.getBrooklynProperties()))
.configure(allConfig.getAllConfig()));
MachineLocation l = ll.obtain();
log.info("loc:" +l);
HostGeoInfo geo = HostGeoInfo.fromLocation(l);
log.info("geo: "+geo);
Assert.assertEquals(geo.latitude, 38.909202d, 0.00001);
Assert.assertEquals(geo.longitude, -77.47314d, 0.00001);
}
@Test
public void testInvokesCustomizerCallbacks() throws Exception {
JcloudsLocationCustomizer customizer = Mockito.mock(JcloudsLocationCustomizer.class);
MachineLocationCustomizer machineCustomizer = Mockito.mock(MachineLocationCustomizer.class);
// Mockito.when(customizer.customize(Mockito.any(JcloudsLocation.class), Mockito.any(ComputeService.class), Mockito.any(JcloudsSshMachineLocation.class)));
ConfigBag allConfig = ConfigBag.newInstance()
.configure(CLOUD_PROVIDER, "aws-ec2")
.configure(ACCESS_IDENTITY, "bogus")
.configure(ACCESS_CREDENTIAL, "bogus")
.configure(JcloudsLocationConfig.JCLOUDS_LOCATION_CUSTOMIZERS, ImmutableList.of(customizer))
.configure(JcloudsLocation.MACHINE_LOCATION_CUSTOMIZERS, ImmutableList.of(machineCustomizer))
.configure(MACHINE_CREATE_ATTEMPTS, 1);
FakeLocalhostWithParentJcloudsLocation ll = managementContext.getLocationManager().createLocation(LocationSpec.create(FakeLocalhostWithParentJcloudsLocation.class).configure(allConfig.getAllConfig()));
JcloudsMachineLocation l = (JcloudsMachineLocation)ll.obtain();
Mockito.verify(customizer, Mockito.times(1)).customize(ll, null, l);
Mockito.verify(customizer, Mockito.never()).preRelease(l);
Mockito.verify(customizer, Mockito.never()).postRelease(l);
Mockito.verify(machineCustomizer, Mockito.times(1)).customize(l);
Mockito.verify(machineCustomizer, Mockito.never()).preRelease(l);
ll.release(l);
Mockito.verify(customizer, Mockito.times(1)).preRelease(l);
Mockito.verify(customizer, Mockito.times(1)).postRelease(l);
Mockito.verify(machineCustomizer, Mockito.times(1)).preRelease(l);
}
// now test creating users
protected String getCreateUserStatementsFor(Map<ConfigKey<?>,?> config) {
BailOutJcloudsLocation jl = BailOutJcloudsLocation.newBailOutJcloudsLocation(
managementContext, MutableMap.<ConfigKey<?>, Object>builder()
.put(JcloudsLocationConfig.LOGIN_USER, "root").put(JcloudsLocationConfig.LOGIN_USER_PASSWORD, "m0ck")
.put(JcloudsLocationConfig.USER, "bob").put(JcloudsLocationConfig.LOGIN_USER_PASSWORD, "b0b")
.putAll(config).build());
UserCreation creation = jl.createUserStatements(null, jl.config().getBag());
return new StatementList(creation.statements).render(OsFamily.UNIX);
}
@Test
public void testDisablesRoot() {
String statements = getCreateUserStatementsFor(ImmutableMap.<ConfigKey<?>, Object>of());
Assert.assertTrue(statements.contains("PermitRootLogin"), "Error:\n"+statements);
Assert.assertTrue(statements.matches("(?s).*sudoers.*useradd.*bob.*wheel.*"), "Error:\n"+statements);
}
@Test
public void testDisableRootFalse() {
String statements = getCreateUserStatementsFor(ImmutableMap.<ConfigKey<?>, Object>of(
JcloudsLocationConfig.DISABLE_ROOT_AND_PASSWORD_SSH, false));
Assert.assertFalse(statements.contains("PermitRootLogin"), "Error:\n"+statements);
Assert.assertTrue(statements.matches("(?s).*sudoers.*useradd.*bob.*wheel.*"), "Error:\n"+statements);
}
@Test
public void testDisableRootAndSudoFalse() {
String statements = getCreateUserStatementsFor(ImmutableMap.<ConfigKey<?>, Object>of(
JcloudsLocationConfig.DISABLE_ROOT_AND_PASSWORD_SSH, false,
JcloudsLocationConfig.GRANT_USER_SUDO, false));
Assert.assertFalse(statements.contains("PermitRootLogin"), "Error:\n"+statements);
Assert.assertFalse(statements.matches("(?s).*sudoers.*useradd.*bob.*wheel.*"), "Error:\n"+statements);
}
// TODO more tests, where flags come in from resolver, named locations, etc
}