PageRenderTime 64ms CodeModel.GetById 36ms RepoModel.GetById 0ms app.codeStats 0ms

/compute/src/test/java/org/jclouds/compute/callables/RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilCompleteTest.java

https://github.com/markkent/jclouds
Java | 245 lines | 161 code | 52 blank | 32 comment | 0 complexity | 277eabd2669203d0ce3c060fc6e88b7d MD5 | raw file
  1. /**
  2. * Licensed to jclouds, Inc. (jclouds) under one or more
  3. * contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. jclouds licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing,
  13. * software distributed under the License is distributed on an
  14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. * KIND, either express or implied. See the License for the
  16. * specific language governing permissions and limitations
  17. * under the License.
  18. */
  19. package org.jclouds.compute.callables;
  20. import static org.easymock.EasyMock.createMock;
  21. import static org.easymock.EasyMock.expect;
  22. import static org.easymock.EasyMock.replay;
  23. import static org.easymock.EasyMock.verify;
  24. import static org.jclouds.scriptbuilder.domain.Statements.exec;
  25. import static org.testng.Assert.assertEquals;
  26. import org.jclouds.Constants;
  27. import org.jclouds.compute.domain.ExecResponse;
  28. import org.jclouds.compute.domain.NodeMetadata;
  29. import org.jclouds.compute.domain.NodeMetadataBuilder;
  30. import org.jclouds.compute.domain.NodeState;
  31. import org.jclouds.compute.options.RunScriptOptions;
  32. import org.jclouds.compute.reference.ComputeServiceConstants;
  33. import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
  34. import org.jclouds.concurrent.MoreExecutors;
  35. import org.jclouds.concurrent.config.ExecutorServiceModule;
  36. import org.jclouds.domain.Credentials;
  37. import org.jclouds.scriptbuilder.InitBuilder;
  38. import org.jclouds.scriptbuilder.domain.OsFamily;
  39. import org.jclouds.scriptbuilder.domain.Statement;
  40. import org.jclouds.ssh.SshClient;
  41. import org.testng.annotations.Test;
  42. import com.google.common.base.Functions;
  43. import com.google.common.collect.ImmutableMap;
  44. import com.google.common.collect.ImmutableSet;
  45. import com.google.inject.AbstractModule;
  46. import com.google.inject.Guice;
  47. import com.google.inject.assistedinject.FactoryModuleBuilder;
  48. import com.google.inject.name.Names;
  49. /**
  50. * @author Adrian Cole
  51. */
  52. @Test(groups = "unit", singleThreaded = true, testName = "RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilCompleteTest")
  53. public class RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilCompleteTest {
  54. BlockUntilInitScriptStatusIsZeroThenReturnOutput.Factory statusFactory = Guice.createInjector(
  55. new ExecutorServiceModule(MoreExecutors.sameThreadExecutor(), MoreExecutors.sameThreadExecutor()),
  56. new AbstractModule() {
  57. @Override
  58. protected void configure() {
  59. bindConstant().annotatedWith(Names.named(Constants.PROPERTY_USER_THREADS)).to(1);
  60. bindConstant().annotatedWith(Names.named(Constants.PROPERTY_IO_WORKER_THREADS)).to(1);
  61. bindConstant().annotatedWith(Names.named(ComputeServiceConstants.PROPERTY_TIMEOUT_SCRIPT_COMPLETE))
  62. .to(100);
  63. install(new FactoryModuleBuilder()
  64. .build(BlockUntilInitScriptStatusIsZeroThenReturnOutput.Factory.class));
  65. }
  66. }).getInstance(BlockUntilInitScriptStatusIsZeroThenReturnOutput.Factory.class);
  67. // fail faster than normal
  68. Timeouts timeouts = Guice.createInjector(new AbstractModule() {
  69. @Override
  70. protected void configure() {
  71. bindConstant().annotatedWith(Names.named(ComputeServiceConstants.PROPERTY_TIMEOUT_SCRIPT_COMPLETE)).to(100l);
  72. }
  73. }).getInstance(Timeouts.class);
  74. @Test(expectedExceptions = IllegalStateException.class)
  75. public void testWithoutInitThrowsIllegalStateException() {
  76. Statement command = exec("doFoo");
  77. NodeMetadata node = new NodeMetadataBuilder().ids("id").state(NodeState.RUNNING).credentials(
  78. new Credentials("tester", "notalot")).build();
  79. SshClient sshClient = createMock(SshClient.class);
  80. replay(sshClient);
  81. RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete testMe = new RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete(
  82. statusFactory, timeouts, Functions.forMap(ImmutableMap.of(node, sshClient)),
  83. InitScriptConfigurationForTasks.create().appendIncrementingNumberToAnonymousTaskNames(), node, command,
  84. new RunScriptOptions());
  85. testMe.call();
  86. }
  87. public void testDefault() {
  88. Statement command = exec("doFoo");
  89. NodeMetadata node = new NodeMetadataBuilder().ids("id").state(NodeState.RUNNING).credentials(
  90. new Credentials("tester", "notalot")).build();
  91. SshClient sshClient = createMock(SshClient.class);
  92. InitBuilder init = new InitBuilder("jclouds-script-0", "/tmp/jclouds-script-0", "/tmp/jclouds-script-0",
  93. ImmutableMap.<String, String> of(), ImmutableSet.of(command));
  94. sshClient.connect();
  95. sshClient.put("/tmp/init-jclouds-script-0", init.render(OsFamily.UNIX));
  96. expect(sshClient.getUsername()).andReturn("tester").atLeastOnce();
  97. expect(sshClient.getHostAddress()).andReturn("somewhere.example.com").atLeastOnce();
  98. // setup script as default user
  99. expect(sshClient.exec("chmod 755 /tmp/init-jclouds-script-0")).andReturn(new ExecResponse("", "", 0));
  100. expect(sshClient.exec("ln -fs /tmp/init-jclouds-script-0 jclouds-script-0")).andReturn(
  101. new ExecResponse("", "", 0));
  102. expect(sshClient.exec("./jclouds-script-0 init")).andReturn(new ExecResponse("", "", 0));
  103. // start script as root via sudo, note that since there's no adminPassword we do a straight
  104. // sudo
  105. expect(sshClient.exec("sudo ./jclouds-script-0 start")).andReturn(new ExecResponse("", "", 0));
  106. // signal the command completed
  107. expect(sshClient.exec("./jclouds-script-0 status")).andReturn(new ExecResponse("", "", 1));
  108. expect(sshClient.exec("./jclouds-script-0 tail")).andReturn(new ExecResponse("out", "", 0));
  109. expect(sshClient.exec("./jclouds-script-0 tailerr")).andReturn(new ExecResponse("err", "", 0));
  110. sshClient.disconnect();
  111. replay(sshClient);
  112. RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete testMe = new RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete(
  113. statusFactory, timeouts, Functions.forMap(ImmutableMap.of(node, sshClient)),
  114. InitScriptConfigurationForTasks.create().appendIncrementingNumberToAnonymousTaskNames(), node, command,
  115. new RunScriptOptions());
  116. assertEquals(testMe.getInitFile(), "/tmp/init-jclouds-script-0");
  117. assertEquals(testMe.getNode(), node);
  118. assertEquals(testMe.getStatement(), init);
  119. testMe.init();
  120. assertEquals(testMe.call(), new ExecResponse("out", "err", 0));
  121. verify(sshClient);
  122. }
  123. public void testWithSudoPassword() {
  124. Statement command = exec("doFoo");
  125. NodeMetadata node = new NodeMetadataBuilder().ids("id").state(NodeState.RUNNING).credentials(
  126. new Credentials("tester", "notalot")).adminPassword("rootme").build();
  127. SshClient sshClient = createMock(SshClient.class);
  128. InitBuilder init = new InitBuilder("jclouds-script-0", "/tmp/jclouds-script-0", "/tmp/jclouds-script-0",
  129. ImmutableMap.<String, String> of(), ImmutableSet.of(command));
  130. sshClient.connect();
  131. sshClient.put("/tmp/init-jclouds-script-0", init.render(OsFamily.UNIX));
  132. expect(sshClient.getUsername()).andReturn("tester").atLeastOnce();
  133. expect(sshClient.getHostAddress()).andReturn("somewhere.example.com").atLeastOnce();
  134. // setup script as default user
  135. expect(sshClient.exec("chmod 755 /tmp/init-jclouds-script-0")).andReturn(new ExecResponse("", "", 0));
  136. expect(sshClient.exec("ln -fs /tmp/init-jclouds-script-0 jclouds-script-0")).andReturn(
  137. new ExecResponse("", "", 0));
  138. expect(sshClient.exec("./jclouds-script-0 init")).andReturn(new ExecResponse("", "", 0));
  139. // since there's an adminPassword we must pass this in
  140. expect(sshClient.exec("echo 'rootme'|sudo -S ./jclouds-script-0 start")).andReturn(new ExecResponse("", "", 0));
  141. // signal the command completed
  142. expect(sshClient.exec("./jclouds-script-0 status")).andReturn(new ExecResponse("", "", 1));
  143. expect(sshClient.exec("./jclouds-script-0 tail")).andReturn(new ExecResponse("out", "", 0));
  144. expect(sshClient.exec("./jclouds-script-0 tailerr")).andReturn(new ExecResponse("err", "", 0));
  145. sshClient.disconnect();
  146. replay(sshClient);
  147. RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete testMe = new RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete(
  148. statusFactory, timeouts, Functions.forMap(ImmutableMap.of(node, sshClient)),
  149. InitScriptConfigurationForTasks.create().appendIncrementingNumberToAnonymousTaskNames(), node, command,
  150. new RunScriptOptions());
  151. assertEquals(testMe.getInitFile(), "/tmp/init-jclouds-script-0");
  152. assertEquals(testMe.getNode(), node);
  153. assertEquals(testMe.getStatement(), init);
  154. testMe.init();
  155. assertEquals(testMe.call(), new ExecResponse("out", "err", 0));
  156. verify(sshClient);
  157. }
  158. public void testNotRoot() {
  159. Statement command = exec("doFoo");
  160. NodeMetadata node = new NodeMetadataBuilder().ids("id").state(NodeState.RUNNING).credentials(
  161. new Credentials("tester", "notalot")).adminPassword("rootme").build();
  162. SshClient sshClient = createMock(SshClient.class);
  163. InitBuilder init = new InitBuilder("jclouds-script-0", "/tmp/jclouds-script-0", "/tmp/jclouds-script-0",
  164. ImmutableMap.<String, String> of(), ImmutableSet.of(command));
  165. sshClient.connect();
  166. sshClient.put("/tmp/init-jclouds-script-0", init.render(OsFamily.UNIX));
  167. expect(sshClient.getUsername()).andReturn("tester").atLeastOnce();
  168. expect(sshClient.getHostAddress()).andReturn("somewhere.example.com").atLeastOnce();
  169. // setup script as default user
  170. expect(sshClient.exec("chmod 755 /tmp/init-jclouds-script-0")).andReturn(new ExecResponse("", "", 0));
  171. expect(sshClient.exec("ln -fs /tmp/init-jclouds-script-0 jclouds-script-0")).andReturn(
  172. new ExecResponse("", "", 0));
  173. expect(sshClient.exec("./jclouds-script-0 init")).andReturn(new ExecResponse("", "", 0));
  174. // kick off as current user
  175. expect(sshClient.exec("./jclouds-script-0 start")).andReturn(new ExecResponse("", "", 0));
  176. // signal the command completed
  177. expect(sshClient.exec("./jclouds-script-0 status")).andReturn(new ExecResponse("", "", 1));
  178. expect(sshClient.exec("./jclouds-script-0 tail")).andReturn(new ExecResponse("out", "", 0));
  179. expect(sshClient.exec("./jclouds-script-0 tailerr")).andReturn(new ExecResponse("err", "", 0));
  180. sshClient.disconnect();
  181. replay(sshClient);
  182. RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete testMe = new RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete(
  183. statusFactory, timeouts, Functions.forMap(ImmutableMap.of(node, sshClient)),
  184. InitScriptConfigurationForTasks.create().appendIncrementingNumberToAnonymousTaskNames(), node, command,
  185. new RunScriptOptions().runAsRoot(false));
  186. assertEquals(testMe.getInitFile(), "/tmp/init-jclouds-script-0");
  187. assertEquals(testMe.getNode(), node);
  188. assertEquals(testMe.getStatement(), init);
  189. testMe.init();
  190. assertEquals(testMe.call(), new ExecResponse("out", "err", 0));
  191. verify(sshClient);
  192. }
  193. }