@Test public void testSshConfigFromDefault() throws Exception { RecordingSshTool.setCustomResponse(".*myCommand.*", new RecordingSshTool.CustomResponse(0, "myResponse", null)); String bp = loadYaml("config-type-coercion-test.yaml", "location:", " localhost:", " sshToolClass: "+RecordingSshTool.class.getName()); // remove all lines referring to "exact" -- that's useful for expository and running in UI // but it will fail (timeout) if the port isn't available so not good in tests bp = Strings.removeLines(bp, StringPredicates.containsLiteralIgnoreCase("exact")); Entity app = createAndStartApplication(bp); waitForApplicationTasks(app); Map<?, ?> props = RecordingSshTool.getLastExecCmd().env; Assert.assertEquals(props.get("RANGE_PORT_SENSOR"), "20003"); Asserts.assertStringContains((String)props.get("RANGE_PORT_CONFIG"), "{\"start\"", "20003"); Assert.assertEquals(props.get("INT_PORT_CONFIG"), "20001"); Assert.assertEquals(props.get("INT_PORT_DEFAULT_CONFIG"), "30001"); Assert.assertEquals(props.get("RANGE_PORT_DEFAULT_SENSOR"), "30003"); // NB: change in Oct 2016, default values are now coerced just like explicit value // (previous to Oct 2016 this would have returned just "30003+", no json) Asserts.assertStringContains((String)props.get("RANGE_PORT_DEFAULT_CONFIG"), "{\"start\"", "30003"); }
public static void setCustomResponse(String cmdRegex, CustomResponse response) { customResponses.put(cmdRegex, checkNotNull(response, "response").toGenerator()); }
RecordingSshTool.setCustomResponse( ".*os-release.*", new RecordingSshTool.CustomResponse(0, osDetailsResponse, ""));
@Test public void testSshCommandEffectorWithParameter() throws Exception { RecordingSshTool.setCustomResponse(".*myCommand.*", new RecordingSshTool.CustomResponse(0, "myResponse", null));
(Integer) execParams.constructorProps.get("port")); int exitCode = authorisedHostAndPort.equals(hap) ? 0 : 1; return new RecordingSshTool.CustomResponse(exitCode, "", "");
@Test public void testSubTypeUsesDefaultsFromSuperInConfigMerging() throws Exception { RecordingSshTool.setCustomResponse(".*myCommand.*", new RecordingSshTool.CustomResponse(0, "myResponse", null));
@Test public void testSshCommandEffectorWithExecutionDir() throws Exception { RecordingSshTool.setCustomResponse(".*myCommand.*", new RecordingSshTool.CustomResponse(0, "myResponse", null)); Entity app = createAndStartApplication( "location:", " localhost:", " sshToolClass: "+RecordingSshTool.class.getName(), "services:", "- type: " + VanillaSoftwareProcess.class.getName(), " brooklyn.config:", " onbox.base.dir.skipResolution: true", " softwareProcess.serviceProcessIsRunningPollPeriod: forever", " brooklyn.initializers:", " - type: org.apache.brooklyn.core.effector.ssh.SshCommandEffector", " brooklyn.config:", " name: myEffector", " description: myDescription", " command: myCommand", " executionDir: /my/path/execDir"); waitForApplicationTasks(app); VanillaSoftwareProcess entity = (VanillaSoftwareProcess) Iterables.getOnlyElement(app.getChildren()); Effector<?> effector = entity.getEntityType().getEffectorByName("myEffector").get(); Object result = entity.invoke(effector, ImmutableMap.<String, Object>of()).get(); assertEquals(((String)result).trim(), "myResponse"); ExecCmd lastExecCmd = RecordingSshTool.getLastExecCmd(); assertIncludesCmd(lastExecCmd.commands, "mkdir -p '/my/path/execDir'"); assertIncludesCmd(lastExecCmd.commands, "cd '/my/path/execDir'"); }
@Test public void testGetMachineDetails() throws Exception { String response = Joiner.on("\n").join( "name:Test OS Y", "version:1.2.3", "architecture:x86_64", "ram:1234", "cpus:3"); RecordingSshTool.setCustomResponse(".*uname.*", new CustomResponse(0, response, "")); BasicExecutionManager execManager = new BasicExecutionManager("mycontextid"); BasicExecutionContext execContext = new BasicExecutionContext(execManager); try { MachineDetails details = execContext.submit(new Callable<MachineDetails>() { @Override public MachineDetails call() { return host.getMachineDetails(); }}).get(); LOG.info("machineDetails="+details); assertNotNull(details); assertEquals(details.getOsDetails().getName(), "Test OS Y", "details="+details); assertEquals(details.getOsDetails().getVersion(), "1.2.3", "details="+details); assertEquals(details.getOsDetails().getArch(), "x86_64", "details="+details); assertEquals(details.getHardwareDetails().getCpuCount(), Integer.valueOf(3), "details="+details); assertEquals(details.getHardwareDetails().getRam(), Integer.valueOf(1234), "details="+details); } finally { execManager.shutdownNow(); } }
tmpApp.subscriptions().subscribe(null, mySensor, listener); RecordingSshTool.setCustomResponse(".*myCommand.*", new RecordingSshTool.CustomResponse(0, "myResponse", null));
"ram:15948", "cpus:4"); RecordingSshTool.setCustomResponse(".*uname.*", new CustomResponse(0, response, ""));
@Test public void testSshCommandEffectorWithShellEnv() throws Exception { RecordingSshTool.setCustomResponse(".*myCommand.*", new RecordingSshTool.CustomResponse(0, "myResponse", null));
@Test public void testLogsStdoutAndStderr() { RecordingSshTool.setCustomResponse(".*mycommand.*", new CustomResponse(0, "mystdout1\nmystdout2", "mystderr1\nmystderr2")); List<String> loggerNames = ImmutableList.of( SshMachineLocation.class.getName(), BrooklynLogging.SSH_IO, SshjTool.class.getName()); ch.qos.logback.classic.Level logLevel = ch.qos.logback.classic.Level.DEBUG; Predicate<ILoggingEvent> filter = Predicates.alwaysTrue(); LogWatcher watcher = new LogWatcher(loggerNames, logLevel, filter); watcher.start(); try { host.execCommands("mySummary", ImmutableList.of("mycommand")); watcher.assertHasEvent(EventPredicates.containsMessage("[1.2.3.4:22:stdout] mystdout1")); watcher.assertHasEvent(EventPredicates.containsMessage("[1.2.3.4:22:stdout] mystdout2")); watcher.assertHasEvent(EventPredicates.containsMessage("[1.2.3.4:22:stderr] mystderr1")); watcher.assertHasEvent(EventPredicates.containsMessage("[1.2.3.4:22:stderr] mystderr2")); } finally { watcher.close(); } }
@Test public void testTurningOffLoggingStdoutAndStderr() { RecordingSshTool.setCustomResponse(".*mycommand.*", new CustomResponse(0, "mystdout1\nmystdout2", "mystderr1\nmystderr2")); List<String> loggerNames = ImmutableList.of( SshMachineLocation.class.getName(), BrooklynLogging.SSH_IO, SshjTool.class.getName()); ch.qos.logback.classic.Level logLevel = ch.qos.logback.classic.Level.DEBUG; Predicate<ILoggingEvent> filter = Predicates.alwaysTrue(); LogWatcher watcher = new LogWatcher(loggerNames, logLevel, filter); watcher.start(); try { host.execCommands( ImmutableMap.of(SshMachineLocation.NO_STDOUT_LOGGING.getName(), true, SshMachineLocation.NO_STDERR_LOGGING.getName(), true), "mySummary", ImmutableList.of("mycommand")); assertFalse(Iterables.tryFind(watcher.getEvents(), EventPredicates.containsMessage(":stdout]")).isPresent()); assertFalse(Iterables.tryFind(watcher.getEvents(), EventPredicates.containsMessage(":stderr]")).isPresent()); } finally { watcher.close(); } } }
@Test public void testSshCommandSensorWithEffectorInEnv() throws Exception { RecordingSshTool.setCustomResponse(".*myCommand.*", new RecordingSshTool.CustomResponse(0, "myResponse", null)); Entity app = createAndStartApplication( "location:", " localhost:", " sshToolClass: "+RecordingSshTool.class.getName(), "services:", "- type: " + VanillaSoftwareProcess.class.getName(), " brooklyn.config:", " onbox.base.dir.skipResolution: true", " brooklyn.initializers:", " - type: org.apache.brooklyn.core.sensor.ssh.SshCommandSensor", " brooklyn.config:", " name: mySensor", " command: myCommand", " period: 10ms", " onlyIfServiceUp: false"); waitForApplicationTasks(app); VanillaSoftwareProcess entity = (VanillaSoftwareProcess) Iterables.getOnlyElement(app.getChildren()); EntityAsserts.assertAttributeEqualsEventually(entity, Sensors.newStringSensor("mySensor"), "myResponse"); }
@Test public void testTestCredentialWithWindowsMachine() throws Exception { final String allowedUser = "Mr. Big"; // Match every command. RecordingWinRmTool.setCustomResponse(".*", new RecordingWinRmTool.CustomResponseGenerator() { @Override public RecordingWinRmTool.CustomResponse generate(RecordingWinRmTool.ExecParams execParams) { boolean valid = allowedUser.equals(execParams.constructorProps.get("user")); return new RecordingWinRmTool.CustomResponse(valid ? 0 : 1, "", ""); } }); initNodeCreatorAndJcloudsLocation(newNodeCreator(), ImmutableMap.of()); DefaultConnectivityResolver customizer = new DefaultConnectivityResolver(); final ConfigBag config = ConfigBag.newInstanceExtending(jcloudsLocation.config().getBag(), ImmutableMap.of( JcloudsLocationConfig.WAIT_FOR_WINRM_AVAILABLE, "1ms", JcloudsLocationConfig.POLL_FOR_FIRST_REACHABLE_ADDRESS, "1ms")); assertTrue(customizer.checkCredential( jcloudsLocation, HostAndPort.fromParts("10.0.0.234", 22), LoginCredentials.builder().user(allowedUser).password("password1").build(), config, true)); assertFalse(customizer.checkCredential( jcloudsLocation, HostAndPort.fromParts("10.0.0.234", 22), credential, config, true)); }
@Test public void testTestCredentialWithLinuxMachine() throws Exception { final String allowedUser = "Mr. Big"; // Match every command. RecordingSshTool.setCustomResponse(".*", new RecordingSshTool.CustomResponseGenerator() { @Override public RecordingSshTool.CustomResponse generate(RecordingSshTool.ExecParams execParams) throws Exception { boolean valid = allowedUser.equals(execParams.constructorProps.get("user")); return new RecordingSshTool.CustomResponse(valid ? 0 : 1, "", ""); } }); initNodeCreatorAndJcloudsLocation(newNodeCreator(), ImmutableMap.of()); DefaultConnectivityResolver customizer = new DefaultConnectivityResolver(); final ConfigBag config = ConfigBag.newInstanceExtending(jcloudsLocation.config().getBag(), ImmutableMap.of( JcloudsLocationConfig.WAIT_FOR_SSHABLE, "1ms", JcloudsLocationConfig.POLL_FOR_FIRST_REACHABLE_ADDRESS, "1ms")); assertTrue(customizer.checkCredential( jcloudsLocation, HostAndPort.fromParts("10.0.0.234", 22), LoginCredentials.builder().user(allowedUser).password("password1").build(), config, false)); assertFalse(customizer.checkCredential( jcloudsLocation, HostAndPort.fromParts("10.0.0.234", 22), credential, config, false)); }
@Test public void testObtainsHostnameFromAwsMachine() throws Exception { final String expectedHostname = "ec2-awshostname"; RecordingSshTool.setCustomResponse(".*curl.*169.254.169.254.*", new RecordingSshTool.CustomResponse(0, expectedHostname, "")); initNodeCreatorAndJcloudsLocation(newNodeCreator(), ImmutableMap.of( JcloudsLocationConfig.LOOKUP_AWS_HOSTNAME, true)); ConnectivityResolverOptions options = newResolveOptions() .waitForConnectable(true) .pollForReachableAddresses(Predicates.<HostAndPort>alwaysTrue(), Duration.millis(1), true) .userCredentials(credential) .build(); DefaultConnectivityResolver customizer = new DefaultConnectivityResolver(); ConfigBag configBag = jcloudsLocation.config().getBag(); ManagementAddressResolveResult result = customizer.resolve( jcloudsLocation, newNodeMetadata(), configBag, options); assertEquals(result.hostAndPort().getHostText(), expectedHostname); }
@Override public RecordingSshTool.CustomResponse generate(RecordingSshTool.ExecParams execParams) throws Exception { HostAndPort hap = HostAndPort.fromParts( (String) execParams.constructorProps.get("host"), (Integer) execParams.constructorProps.get("port")); int exitCode = authorisedHostAndPort.equals(hap) ? 0 : 1; return new RecordingSshTool.CustomResponse(exitCode, "", ""); } });
@Override public CustomResponse generate(ExecParams execParams) throws Exception { String stdout = Joiner.on("\n").join( "name:centos", "version:7.0", "architecture:myarch", "ram:1024", "cpus:1"); return new CustomResponse(0, stdout, ""); }}); }
@Override public CustomResponse generate(ExecParams execParams) throws Exception { return new CustomResponse(0, Integer.toString(counter.getAndIncrement()), ""); }}); RecordingSshTool.setCustomResponse(".*/etc/os-release.*", new RecordingSshTool.CustomResponseGenerator() {