package org.jenkinsci.plugins.ansible; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyMap; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.io.File; import java.util.Map; import com.cloudbees.jenkins.plugins.sshcredentials.SSHUserPrivateKey; import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; import com.cloudbees.plugins.credentials.common.UsernamePasswordCredentials; import hudson.EnvVars; import hudson.FilePath; import hudson.Launcher; import hudson.model.AbstractBuild; import hudson.model.BuildListener; import hudson.model.TaskListener; import hudson.util.ArgumentListBuilder; import hudson.util.Secret; import org.junit.*; import org.mockito.ArgumentCaptor; /** * Created with IntelliJ IDEA. * User: jcsirot * Date: 22/05/15 * Time: 19:30 * To change this template use File | Settings | File Templates. */ public class AnsibleAdHocCommandInvocationTest { @Test public void should_generate_simple_invocation() throws Exception { // Given Inventory inventory = new InventoryPath("/tmp/hosts"); BuildListener listener = mock(BuildListener.class); CLIRunner runner = mock(CLIRunner.class); AbstractBuild<?,?> build = mock(AbstractBuild.class); when(build.getEnvironment(any(TaskListener.class))).thenReturn(new EnvVars()); AnsibleAdHocCommandInvocation invocation = new AnsibleAdHocCommandInvocation("/usr/local/bin/ansible", build, listener); invocation.setHostPattern("localhost"); invocation.setInventory(inventory); invocation.setModule("ping"); invocation.setForks(5); // When invocation.execute(runner); // Then ArgumentCaptor<ArgumentListBuilder> argument = ArgumentCaptor.forClass(ArgumentListBuilder.class); verify(runner).execute(argument.capture(), anyMap()); assertThat(argument.getValue().toString()) .isEqualTo("/usr/local/bin/ansible localhost -i /tmp/hosts -m ping -f 5"); } @Test public void should_generate_simple_invocation_with_env() throws Exception { // Given Inventory inventory = new InventoryPath("/tmp/hosts"); BuildListener listener = mock(BuildListener.class); CLIRunner runner = mock(CLIRunner.class); AbstractBuild<?,?> build = mock(AbstractBuild.class); when(build.getEnvironment(any(TaskListener.class))).thenReturn(new EnvVars()); AnsibleAdHocCommandInvocation invocation = new AnsibleAdHocCommandInvocation("/usr/local/bin/ansible", build, listener); invocation.setHostPattern("localhost"); invocation.setInventory(inventory); invocation.setModule("ping"); invocation.setForks(5); invocation.setColorizedOutput(true); invocation.setHostKeyCheck(false); invocation.setUnbufferedOutput(true); // When invocation.execute(runner); // Then ArgumentCaptor<Map> argument = ArgumentCaptor.forClass(Map.class); verify(runner).execute(any(ArgumentListBuilder.class), argument.capture()); assertThat((Map<String, String>)argument.getValue()) .containsEntry("PYTHONUNBUFFERED", "1") .containsEntry("ANSIBLE_FORCE_COLOR", "true") .containsEntry("ANSIBLE_HOST_KEY_CHECKING", "False"); } @Test @Ignore("build.getWorkspace() cannot be mocked") public void should_handle_private_key_credentials() throws Exception { // Given Inventory inventory = new InventoryPath("/tmp/hosts"); SSHUserPrivateKey pkey = mock(SSHUserPrivateKey.class); when(pkey.getUsername()).thenReturn("mylogin"); BuildListener listener = mock(BuildListener.class); CLIRunner runner = mock(CLIRunner.class); AbstractBuild<?,?> build = mock(AbstractBuild.class); when(build.getEnvironment(any(TaskListener.class))).thenReturn(new EnvVars()); AnsibleAdHocCommandInvocation invocation = new AnsibleAdHocCommandInvocation("/usr/local/bin/ansible", build, listener); invocation.setHostPattern("localhost"); invocation.setInventory(inventory); invocation.setModule("ping"); invocation.setCredentials(pkey); invocation.setForks(5); // When invocation.execute(runner); // Then ArgumentCaptor<ArgumentListBuilder> argument = ArgumentCaptor.forClass(ArgumentListBuilder.class); verify(runner).execute(argument.capture(), anyMap()); assertThat(argument.getValue().toString()) .matches("/usr/local/bin/ansible localhost -i /tmp/hosts -m ping -f 5 --private-key .+ -u mylogin"); } @Test @Ignore("Secret can neither be instanced nor mocked") public void should_handle_password_credentials() throws Exception { // Given Inventory inventory = new InventoryPath("/tmp/hosts"); StandardUsernamePasswordCredentials password = mock(StandardUsernamePasswordCredentials.class); when(password.getUsername()).thenReturn("mylogin"); when(password.getPassword()).thenReturn(Secret.fromString("aStrongSecretPassword")); BuildListener listener = mock(BuildListener.class); CLIRunner runner = mock(CLIRunner.class); AbstractBuild<?,?> build = mock(AbstractBuild.class); when(build.getEnvironment(any(TaskListener.class))).thenReturn(new EnvVars()); AnsibleAdHocCommandInvocation invocation = new AnsibleAdHocCommandInvocation("/usr/local/bin/ansible", build, listener); invocation.setHostPattern("localhost"); invocation.setInventory(inventory); invocation.setModule("ping"); invocation.setCredentials(password); invocation.setForks(5); // When invocation.execute(runner); // Then ArgumentCaptor<ArgumentListBuilder> argument = ArgumentCaptor.forClass(ArgumentListBuilder.class); verify(runner).execute(argument.capture(), anyMap()); assertThat(argument.getValue().toString()) .isEqualTo("sshpass ****** /usr/local/bin/ansible localhost -i /tmp/hosts -m ping -f 5 " + "-u" + " mylogin -k"); } @Test public void should_handle_variables() throws Exception { // Given Inventory inventory = new InventoryPath("/tmp/hosts"); BuildListener listener = mock(BuildListener.class); CLIRunner runner = mock(CLIRunner.class); AbstractBuild<?,?> build = mock(AbstractBuild.class); EnvVars vars = new EnvVars(); vars.put("MODULE", "ping"); when(build.getEnvironment(any(TaskListener.class))).thenReturn(vars); AnsibleAdHocCommandInvocation invocation = new AnsibleAdHocCommandInvocation("/usr/local/bin/ansible", build, listener); invocation.setHostPattern("localhost"); invocation.setInventory(inventory); invocation.setModule("${MODULE}"); invocation.setForks(5); // When invocation.execute(runner); // Then ArgumentCaptor<ArgumentListBuilder> argument = ArgumentCaptor.forClass(ArgumentListBuilder.class); verify(runner).execute(argument.capture(), anyMap()); assertThat(argument.getValue().toString()) .isEqualTo("/usr/local/bin/ansible localhost -i /tmp/hosts -m ping -f 5"); } }