@@ -25,7 +25,7 @@ def call_exec_windows(command, arguments, stdin, stdout, stderr)
2525 let ( :pid ) { 5501 }
2626 let ( :null_file ) { Puppet . features . microsoft_windows? ? 'NUL' : '/dev/null' }
2727
28- describe "#execute_posix (stubs)" do
28+ describe "#execute_posix (stubs)" , :unless => Puppet . features . microsoft_windows? do
2929 before :each do
3030 # Most of the things this method does are bad to do during specs. :/
3131 Kernel . stubs ( :fork ) . returns ( pid ) . yields
@@ -41,8 +41,33 @@ def call_exec_windows(command, arguments, stdin, stdout, stderr)
4141 @stdin = File . open ( null_file , 'r' )
4242 @stdout = Tempfile . new ( 'stdout' )
4343 @stderr = File . open ( null_file , 'w' )
44+
45+ # there is a danger here that ENV will be modified by exec_posix. Normally it would only affect the ENV
46+ # of a forked process, but here, we're stubbing Kernel.fork, so the method has the ability to override the
47+ # "real" ENV. To guard against this, we'll capture a snapshot of ENV before each test.
48+ @saved_env = Hash [ ENV . map { |key , val | [ key , val ] } ]
49+
50+ # Now, we're going to effectively "mock" the magic ruby 'ENV' variable by creating a local definition of it
51+ # inside of the module we're testing.
52+ Puppet ::Util ::Execution ::ENV = { }
53+ end
54+
55+ after :each do
56+ # And here we remove our "mock" version of 'ENV', which will allow us to validate that the real ENV has been
57+ # left unharmed.
58+ Puppet ::Util ::Execution . send ( :remove_const , :ENV )
59+
60+ # capture the current environment and make sure it's the same as it was before the test
61+ cur_env = Hash [ ENV . map { |key , val | [ key , val ] } ]
62+
63+ # we will get some fairly useless output if we just use the raw == operator on the hashes here, so we'll
64+ # be a bit more explicit and laborious in the name of making the error more useful...
65+ @saved_env . each_pair { |key , val | cur_env [ key ] . should == val }
66+ ( cur_env . keys - @saved_env . keys ) . should == [ ]
67+
4468 end
4569
70+
4671 it "should fork a child process to execute the command" do
4772 Kernel . expects ( :fork ) . returns ( pid ) . yields
4873 Kernel . expects ( :exec ) . with ( 'test command' )
@@ -230,6 +255,27 @@ def call_exec_windows(command, arguments, stdin, stdout, stderr)
230255 end
231256
232257 describe "#execute (posix locale)" , :unless => Puppet . features . microsoft_windows? do
258+
259+ before :each do
260+ # there is a danger here that ENV will be modified by exec_posix. Normally it would only affect the ENV
261+ # of a forked process, but, in some of the previous tests in this file we're stubbing Kernel.fork., which could
262+ # allow the method to override the "real" ENV. This shouldn't be a problem for these tests because they are
263+ # not stubbing Kernel.fork, but, better safe than sorry... so, to guard against this, we'll capture a snapshot
264+ # of ENV before each test. We have to use this somewhat kludgy code to clone the ENV var, because ENV doesn't
265+ # provide a useful == method.
266+ @saved_env = Hash [ ENV . map { |key , val | [ key , val ] } ]
267+ end
268+
269+ after :each do
270+ # capture the current environment and make sure it's the same as it was before the test
271+ cur_env = Hash [ ENV . map { |key , val | [ key , val ] } ]
272+ # we will get some fairly useless output if we just use the raw == operator on the hashes here, so we'll
273+ # be a bit more explicit and laborious in the name of making the error more useful...
274+ @saved_env . each_pair { |key , val | cur_env [ key ] . should == val }
275+ ( cur_env . keys - @saved_env . keys ) . should == [ ]
276+ end
277+
278+
233279 # build up a printf-style string that contains a command to get the value of an environment variable
234280 # from the operating system. We can substitute into this with the names of the desired environment variables later.
235281 get_env_var_cmd = 'echo $%s'
0 commit comments