theNoob
theNoob

Reputation: 19

How to control which user "kitchen verify" uses when testing a command resource?

I have a Chef cookbook that installs "git version 2.5.2". I'm using a CentOS 6.4 vm to apply this cookbook and have written a test to check the git version.

The snippet looks like this:

# Test if git exists
describe command('git --version') do
  its(:stdout) { should match "git version 2.5.2" }
end

When I run kitchen verify, the test is executed but returns a different version of git than I was expecting which results in the test failing.

Here is the error:

 2) Command "git --version" stdout should match "git version 2.5.2"
    Failure/Error: its(:stdout) { should match "git version 2.5.2" }
      expected "git version 1.7.1\n" to match "git version 2.5.2"
      Diff:
      @@ -1,2 +1,2 @@
      -git version 2.5.2
      +git version 1.7.1

      /bin/sh -c git\ --version
      git version 1.7.1

The VM happens to have git version 1.7.1 installed in the /usr/bin directory. The recipe installs git version 2.5.2 in the /usr/local/bin directory. When I login to the VM using the command "kitchen login", I'm connected as the vagrant user. The /usr/local/bin directory is higher in the PATH than /usr/bin, so when I run "git --version", I'll get "git version 2.5.2" as my output. When I run kitchen verify though, it will execute my tests with the root user. The root user's PATH doesn't include /usr/local/bin, but does have /usr/bin so it returns "git version 1.7.1".

How do I control which user on the VM that kitchen verify will use when executing tests?


I tried using the "su -c" command in a test like this:

describe command('su -c "whoami" vagrant') do
  its(:stdout) { should match "vagrant" }
end

The result was as expected:

   Command "su -c "whoami" vagrant"
     stdout
       should match "vagrant"

Making the change with the git command:

describe command('su -c "git --version" vagrant') do
  its(:stdout) { should match "git version 2.5.2" }
end

The result:

     1) Command "su -c "git --version" vagrant" stdout should match "git version 2.5.2"
        Failure/Error: its(:stdout) { should match "git version 2.5.2" }
          expected "" to match "git version 2.5.2"
          /bin/sh -c su\ -c\ \"git\ --version\"\ vagrant

Checking for vagrant user's path:

describe command('su -c "echo $PATH" vagrant') do
  its(:stdout) { should match "" }
end

The test succeeds in this case. The path doesn't get set for the vagrant user so a plain "git --version" command will not work.


Upvotes: 1

Views: 561

Answers (1)

theNoob
theNoob

Reputation: 19

Since the -c switch worked to change the user, I looked up the man page for su to see what other switches I could try. The -l or --login switch looked promising.

describe command('su -c --login "git --version" vagrant') do
  its(:stdout) { should match "git version 2.5.2" }
end

The test still fails...

     1) Command "su -c --login "git --version" vagrant" stdout should match "git version 2.5.2"
        Failure/Error: its(:stdout) { should match "git version 2.5.2" }
          expected "" to match "git version 2.5.2"
          /bin/sh -c su\ -c\ --login\ \"git\ --version\"\ vagrant

Looking at the order of the switches though...

describe command('su --login -c "git --version" vagrant') do
  its(:stdout) { should match "git version 2.5.2" }
end

The test succeeds. I didn't think the order of the switches would influence the outcome, but it does. Thanks to Draco Ater for the helpful comments.

Upvotes: 0

Related Questions