1

Ansible 1.9.2/latest. OS: CentOS 6.7/later JAVA_HOME, PATH variable and all other things are setup correctly.

I have the following playbook runs in my perf_tests/tasks/main.yml. To just run this playbook run only, I'm using Ansible tags.

# Run JMeter tests
- name: Run JMeter test(s)
#  command: "export PATH={{ jdk_install_dir }}/bin:$PATH && export JAVA_HOME={{ jdk_install_dir }} && {{ jmeter_install_dir }}/bin/jmeter -n -t {{ common_download_dir}}/perf_tests/ProjectTest1.jmx -l {{ common_download_dir}}/perf_tests/log_jmeter_ProjectTest1.jtl"
  command: export PATH={{ jdk_install_dir }}/bin:$PATH && export JAVA_HOME={{ jdk_install_dir }} && /apps/jmeter/apache-jmeter-2.13/bin/jmeter -n -t /tmp/perf_tests/ProjectTest1.jmx -l /tmp/perf_tests/log_jmeter_ProjectTest1.jtl
  become_user: "{{ common_user }}"
  tags:
     - giga

Files required by JMeter executable are present on the target machine and I'm using "command" module in ansible to start JMeter.

[appuser@jmeter01 ~]$ ls -l /apps/jmeter/apache-jmeter-2.13/bin/jmeter /tmp/perf_tests/ProjectTest1.jmx
-rwxr-xr-x. 1 appuser appgroup  5589 Mar  8  2015 /apps/jmeter/apache-jmeter-2.13/bin/jmeter
-rw-r--r--. 1 appuser appgroup 50194 Oct  2 12:19 /tmp/perf_tests/ProjectTest1.jmx
[appuser@jmeter01 ~]$

[appuser@jmeter01 ~]$ which java
/apps/jdk/jdk1.7.0_67/bin/java

When I'm running the above playbook run jmeter on a .jmx file to generate a a result .jtl file (using ANSIBLE), it's errors out with an error code 2 (as shown below): msg: [Errno 2] No such file or directory

ANSIBLE output:

TASK: [perf_tests | Run JMeter test(s)] ***************************************
<jmeter01.perf.jenkins> ESTABLISH CONNECTION FOR USER: confman on PORT 22 TO jmeter01.perf.jenkins
<jmeter01.perf.jenkins> REMOTE_MODULE command export PATH=/apps/jdk/jdk1.7.0_67/bin:$PATH && export JAVA_HOME=/apps/jdk/jdk1.7.0_67 && /apps/jmeter/apache-jmeter-2.13/bin/jmeter -n -t /tmp/perf_tests/ProjectTest1.jmx -l /tmp/perf_tests/log_jmeter_ProjectTest1.jtl
<jmeter01.perf.jenkins> EXEC /bin/sh -c 'mkdir -p /tmp/ansible-tmp-1443821195.89-232957509929426 && chmod a+rx /tmp/ansible-tmp-1443821195.89-232957509929426 && echo /tmp/ansible-tmp-1443821195.89-232957509929426'
<jmeter01.perf.jenkins> PUT /tmp/tmp6fAr1W TO /tmp/ansible-tmp-1443821195.89-232957509929426/command
<jmeter01.perf.jenkins> EXEC /bin/sh -c 'chmod a+r /tmp/ansible-tmp-1443821195.89-232957509929426/command'
<jmeter01.perf.jenkins> EXEC /bin/sh -c 'sudo -k && sudo -H -S -p "[sudo via ansible, key=pkivlaidiolrcxvyxxixeysvrfkpvroy] password: " -u appuser /bin/sh -c '"'"'echo BECOME-SUCCESS-pkivlaidiolrcxvyxxixeysvrfkpvroy; LANG=en_US.UTF-8 LC_CTYPE=en_US.UTF-8 /usr/bin/python /tmp/ansible-tmp-1443821195.89-232957509929426/command'"'"''
<jmeter01.perf.jenkins> EXEC /bin/sh -c 'rm -rf /tmp/ansible-tmp-1443821195.89-232957509929426/ >/dev/null 2>&1'
failed: [jmeter01.perf.jenkins] => {"cmd": "export PATH=/apps/jdk/jdk1.7.0_67/bin:/sbin:/bin:/usr/sbin:/usr/bin '&&' export JAVA_HOME=/apps/jdk/jdk1.7.0_67 '&&' /apps/jmeter/apache-jmeter-2.13/bin/jmeter -n -t /tmp/perf_tests/ProjectTest1.jmx -l /tmp/perf_tests/log_jmeter_ProjectTest1.jtl", "failed": true, "rc": 2}
msg: [Errno 2] No such file or directory

FATAL: all hosts have already failed -- aborting

PLAY RECAP ********************************************************************

The "cmd" above in ansible's -vvvv verbose output shows, everything is getting passed/expanded successfully by Ansible for calling the jmeter command but it's failing.

IF I go to the remote machine (jmeter01) and "appuser" and run the command, it works fine and successfully creates the -l option provided .jtl result file.

[appuser@jmeter01 ~]$ /apps/jmeter/apache-jmeter-2.13/bin/jmeter -n -t /tmp/perf_tests/ProjectTest1.jmx -l /tmp/perf_tests/log_jmeter_ProjectTest1.jtl
Creating summariser <summary>
Created the tree successfully using /tmp/perf_tests/ProjectTest1.jmx
Starting the test @ Fri Oct 02 17:23:50 EDT 2015 (1443821030343)
Waiting for possible shutdown message on port 4445
summary =    240 in   4.4s =   54.0/s Avg:    82 Min:     2 Max:  1113 Err:     0 (0.00%)
Tidying up ...    @ Fri Oct 02 17:23:55 EDT 2015 (1443821035009)
... end of run
[appuser@jmeter01 ~]$ ls -l /tmp/perf_tests
total 80
-rw-r--r--. 1 appuser appgroup 50194 Oct  2 12:19 ProjectTest1.jmx
-rw-r--r--. 1 appuser appgroup 22412 Oct  2 17:23 log_jmeter_ProjectTest1.jtl
drwxr-xr-x. 3 appuser appgroup  4096 Oct  2 12:19 META-INF
[appuser@jmeter01 ~]$

I'm stumped why JMeter is erroring out with this error while running it with Ansible!!! ?

2 Answers 2

5

You can't use export or && with the command module as it executes the command directly, not through a shell, and export is a shell builtin.

You want the shell module.

Compare the outputs of:

ansible myserver -m command -a "echo Hello && echo Goodbye"
ansible myserver -m command -a "export GREET=Hello && echo '$GREET'"

ansible myserver -m shell -a "echo Hello && echo Goodbye"
ansible myserver -m shell -a "export GREET=Hello && echo '$GREET'"

and you can see this clearly.

5
  • Yes, shell worked. I'll share the solution but the fact that && didn't work, that's wrong. I used it to set JAVA_HOME n PATH variables and ansible command module didn't error out and found "java" executable for running "jmeter" executable. Earlier when I was not using command: "export JAVA_HOME={{ jdk_install_dir }} && export PATH={{ jdk_install_dir }}/bin:$PATH && ....whole...jmeter with params" command.. Jmeter executable was failing to find java but after using && it worked but the error was No such file or directory (for jmx file i guess or not sure)
    – AKS
    Commented Oct 2, 2015 at 22:56
  • First you were trying to run the command ".../jmeter <stuff>" and it wouldn't work because the java environment variables weren't set up. Then you tried to run "export PATH=<stuff> &&..." and that gave "no such file or directory" because there's no such program as "export": it's a shell builtin. And also && wouldn't work anyway.
    – seumasmac
    Commented Oct 2, 2015 at 23:18
  • @ArunSangal but you're correct that in your case, it was the "export" rather than the && that was throwing the error first. I've updated my answer to expand on this.
    – seumasmac
    Commented Oct 2, 2015 at 23:27
  • Strange, one thing is sure that using export and && solved the issue for JMeter not detecting java executable (my first error which I didn't past) and also after using export and &&, the command module didn't error out. I saw in the docs as you mentioned that it doesn't expand shell expansion, >, <, |, & etc and you are correct there.
    – AKS
    Commented Oct 3, 2015 at 0:53
  • @ArunSangal Using export and && only looked like it fixed the JMeter not detecting Java error. That error was caused by JMeter running and not finding Java, because the environment variable wasn't set. When you added the "export JAVA_HOME..." stuff, the command actually failed earlier. It stopped complaining about Java because it never even got as far as running JMeter. It failed immediately on "export" because that wasn't a command it could run (because it was a builtin). Hope this explains it better!
    – seumasmac
    Commented Oct 3, 2015 at 1:04
1

Seumasmac is correct. I couldn't find anywhere "command" module able to run jmeter to run the tests (I even tried hardcoding the values and passed it to command: xxx xxx xxx).

Using the following "shell" module I was able to run multiple .jmx (if a project has) and also fetch (get the result .jtl file back to Source server which was running ansible).

Using "with_items", I can pass jmxfile values and get multiple jmeter runs. Script: run_jmeter_test.sh is bundled in a ZIP file which I'm pushing first (using copy module) to the target/remote jmeter01 server in {{ common_download_dir }} == /tmp and I'm able to create perf_tests folder and unpack the ZIP there to get everything setup before running the playbook to run JMeter executable/command.

# Run JMeter tests using Ansible shell module on remote Jmeter node
- name: Run JMeter tests using Ansible shell module on remote Jmeter node and pass parameters
  shell: "sudo {{ common_download_dir }}/perf_tests/run_jmeter_test.sh {{ jdk_install_dir }} {{ jmeter_install_dir }}/bin/jmeter {{ common_download_dir }}/perf_tests/{{ item.jmxfile }}.jmx {{ common_download_dir }}/perf_tests/log_jmeter_{{ item.jmxfile }}.jtl"
  become_user: "{{ common_user }}"
  with_items:
    - { jmxfile: 'ProjectTest1' }
#    - { jmxfile: 'ProjectTest101' }
#    - { jmxfile: 'ProjectTest102' }

# Fetch JMeter test(s) result .jtl file(s) from remote server and put it in local workspace.
- name: Fetch JMeter test(s) result .jtl file(s)
  fetch: src="{{ common_download_dir}}/perf_tests/log_jmeter_{{ item.jmxfile }}.jtl" dest="perf_tests/{{ item.jmxfile}}.jtl" flat=yes fail_on_missing=yes
  with_items:
    - { jmxfile: 'ProjectTest1' }
#    - { jmxfile: 'ProjectTest101' }
#    - { jmxfile: 'ProjectTest102' }

run_jmeter_test.sh looks like (very plain / simple version):

#!/bin/sh

javaHome=$1
jmExec=$2
jmxFile=$3
jtlFile=$4

export PATH=$javaHome/bin:$PATH

$jmExec -n -t $jmxFile -l $jtlFile

Other posts by me also shows how I got JMeter executable and it's Extra/Standard/WebDriver plugins.

Not the answer you're looking for? Browse other questions tagged or ask your own question.