diff --git a/lib/beaker/host/mac/exec.rb b/lib/beaker/host/mac/exec.rb index b5330e8b95..33046a2526 100644 --- a/lib/beaker/host/mac/exec.rb +++ b/lib/beaker/host/mac/exec.rb @@ -35,4 +35,13 @@ def selinux_enabled?() false end + # Update ModifiedDate on a file + # @param [String] file Path to the file + # @param [String] timestamp Timestamp to set + def modified_at(file, timestamp = nil) + require 'date' + time = timestamp ? DateTime.parse("#{timestamp}") : DateTime.now + timestamp = time.strftime('%Y%m%d%H%M') + execute("touch -mt #{timestamp} #{file}") + end end diff --git a/lib/beaker/host/pswindows/exec.rb b/lib/beaker/host/pswindows/exec.rb index 40b009dba4..23a5479ae9 100644 --- a/lib/beaker/host/pswindows/exec.rb +++ b/lib/beaker/host/pswindows/exec.rb @@ -37,6 +37,28 @@ def mv(orig, dest, rm=true) execute("move /y #{orig} #{dest}") end + # Update ModifiedDate on a file + # @param [String] file Path to the file + # @param [String] timestamp Timestamp to set + def modified_at(file, timestamp = nil) + require 'date' + time = timestamp ? DateTime.parse("#{timestamp}") : DateTime.now + + result = execute("powershell Test-Path #{file} -PathType Leaf") + + if result.include? 'False' + execute("powershell New-Item -ItemType file #{file}") + end + execute("powershell (gci #{file}).LastWriteTime = Get-Date " \ + "-Year '#{time.year}'" \ + "-Month '#{time.month}'" \ + "-Day '#{time.day}'" \ + "-Hour '#{time.hour}'" \ + "-Minute '#{time.minute}'" \ + "-Second '#{time.second}'" + ) + end + def path 'c:/windows/system32;c:/windows' end diff --git a/lib/beaker/host/unix/exec.rb b/lib/beaker/host/unix/exec.rb index 895a60316a..a80e8e48e5 100644 --- a/lib/beaker/host/unix/exec.rb +++ b/lib/beaker/host/unix/exec.rb @@ -2,9 +2,9 @@ module Unix::Exec include Beaker::CommandFactory # Reboots the host, comparing uptime values to verify success - # @param [Integer] wait_time How long to wait after sending the reboot + # @param [Integer] wait_time How long to wait after sending the reboot # command before attempting to check in on the host - # @param [Integer] max_connection_tries How many times to retry connecting to + # @param [Integer] max_connection_tries How many times to retry connecting to # host after reboot. Note that there is an fibbonacci # backoff when attempting retries so the time spent # waiting on this can grow quickly. @@ -40,7 +40,7 @@ def reboot(wait_time=10, max_connection_tries=9, uptime_retries=18) current_uptime_str = parse_uptime current_uptime current_uptime_int = uptime_int current_uptime_str unless original_uptime_int > current_uptime_int - raise Beaker::Host::RebootFailure, "Uptime did not reset. Reboot appears to have failed." + raise Beaker::Host::RebootFailure, "Uptime did not reset. Reboot appears to have failed." end rescue Beaker::Host::RebootFailure => e attempts += 1 @@ -89,7 +89,7 @@ def parse_uptime(uptime) return "0 min" end raise "Couldn't parse uptime: #{uptime}" if result.nil? - + result[1].strip.chomp(",") end @@ -101,6 +101,16 @@ def touch(file, abs=true) (abs ? '/bin/touch' : 'touch') + " #{file}" end + # Update ModifiedDate on a file + # @param [String] file Path to the file + # @param [String] timestamp Timestamp to set + def modified_at(file, timestamp = nil) + require 'date' + time = timestamp ? DateTime.parse("#{timestamp}") : DateTime.now + timestamp = time.strftime('%Y%m%d%H%M') + execute("/bin/touch -mt #{timestamp} #{file}") + end + def path '/bin:/usr/bin' end @@ -117,7 +127,7 @@ def get_ip # @param [String] dir The directory structure to create on the host # @return [Boolean] True, if directory construction succeeded, otherwise False def mkdir_p dir - cmd = "mkdir -p #{dir}" + cmd = "mkdir -p '#{dir}'" result = exec(Beaker::Command.new(cmd), :acceptable_exit_codes => [0, 1]) result.exit_code == 0 end @@ -125,7 +135,7 @@ def mkdir_p dir # Recursively remove the path provided # @param [String] path The path to remove def rm_rf path - execute("rm -rf #{path}") + execute("rm -rf '#{path}'") end # Move the origin to destination. The destination is removed prior to moving. @@ -134,7 +144,7 @@ def rm_rf path # @param [Boolean] rm Remove the destination prior to move def mv orig, dest, rm=true rm_rf dest unless !rm - execute("mv #{orig} #{dest}") + execute("mv '#{orig}' '#{dest}'") end # Attempt to ping the provided target hostname diff --git a/lib/beaker/host/unix/file.rb b/lib/beaker/host/unix/file.rb index aab32f6a00..a7a4c421b9 100644 --- a/lib/beaker/host/unix/file.rb +++ b/lib/beaker/host/unix/file.rb @@ -30,6 +30,10 @@ def chown(user, path, recursive=false) execute("chown #{recursive ? '-R ' : ''}#{user} #{path}") end + def chmod(mod, path, recursive=false) + execute("chmod #{recursive ? '-R ' : ''}#{mod} #{path}") + end + # Change group ownership of a path # # @see http://pubs.opengroup.org/onlinepubs/9699919799/utilities/chgrp.html diff --git a/lib/beaker/host/windows/file.rb b/lib/beaker/host/windows/file.rb index 32dd574f8a..b76aa10a11 100644 --- a/lib/beaker/host/windows/file.rb +++ b/lib/beaker/host/windows/file.rb @@ -35,6 +35,9 @@ def chgrp(group, path, recursive=false) super(group, cygpath, recursive) end + # Not needed on windows + def chmod(mod, path, recursive=false); end + # (see {Beaker::Host::Unix::File#ls_ld}) # @note Cygwin's `ls_ld` implementation does not support # windows-, DOS-, or mixed-style paths, only UNIX/POSIX-style. diff --git a/spec/beaker/host/mac/exec_spec.rb b/spec/beaker/host/mac/exec_spec.rb index 79d8acc789..4382c04877 100644 --- a/spec/beaker/host/mac/exec_spec.rb +++ b/spec/beaker/host/mac/exec_spec.rb @@ -31,5 +31,15 @@ def to_s expect(instance.selinux_enabled?).to be === false end end + + describe '#modified_at' do + it 'calls execute with touch and timestamp' do + time = '190101010000' + path = '/path/to/file' + expect( instance ).to receive(:execute).with("touch -mt #{time} #{path}").and_return(0) + + instance.modified_at(path, time) + end + end end end diff --git a/spec/beaker/host/pswindows/exec_spec.rb b/spec/beaker/host/pswindows/exec_spec.rb index c5d408dfef..c8fb64b499 100644 --- a/spec/beaker/host/pswindows/exec_spec.rb +++ b/spec/beaker/host/pswindows/exec_spec.rb @@ -50,6 +50,38 @@ def to_s expect( instance.mv(origin, destination, false) ).to be === 0 end end + + describe '#modified_at' do + before do + allow(instance).to receive(:execute).and_return(stdout) + end + + context 'file exists' do + let(:stdout) { 'True' } + it 'sets the modified_at date' do + file = 'C:\path\to\file' + expect(instance).to receive(:execute).with("powershell Test-Path #{file} -PathType Leaf") + expect(instance).to receive(:execute).with( + "powershell (gci C:\\path\\to\\file).LastWriteTime = Get-Date -Year '1970'-Month '1'-Day '1'-Hour '0'-Minute '0'-Second '0'" + ) + instance.modified_at(file, '197001010000') + end + end + + context 'file does not exist' do + let(:stdout) { 'False' } + it 'creates it and sets the modified_at date' do + file = 'C:\path\to\file' + expect(instance).to receive(:execute).with("powershell Test-Path #{file} -PathType Leaf") + expect(instance).to receive(:execute).with("powershell New-Item -ItemType file #{file}") + expect(instance).to receive(:execute).with( + "powershell (gci C:\\path\\to\\file).LastWriteTime = Get-Date -Year '1970'-Month '1'-Day '1'-Hour '0'-Minute '0'-Second '0'" + ) + instance.modified_at(file, '197001010000') + end + end + end + describe '#environment_string' do let(:host) { {'pathseparator' => ':'} } diff --git a/spec/beaker/host/unix/exec_spec.rb b/spec/beaker/host/unix/exec_spec.rb index dc5bbeb1fb..6128c045dc 100644 --- a/spec/beaker/host/unix/exec_spec.rb +++ b/spec/beaker/host/unix/exec_spec.rb @@ -29,7 +29,7 @@ def to_s it "deletes" do path = '/path/to/delete' - expect( instance ).to receive(:execute).with("rm -rf #{path}").and_return(0) + expect( instance ).to receive(:execute).with("rm -rf '#{path}'").and_return(0) expect( instance.rm_rf(path) ).to be === 0 end end @@ -39,18 +39,28 @@ def to_s let(:destination) { '/destination/path/of/content' } it 'rm first' do - expect( instance ).to receive(:execute).with("rm -rf #{destination}").and_return(0) - expect( instance ).to receive(:execute).with("mv #{origin} #{destination}").and_return(0) + expect( instance ).to receive(:execute).with("rm -rf '#{destination}'").and_return(0) + expect( instance ).to receive(:execute).with("mv '#{origin}' '#{destination}'").and_return(0) expect( instance.mv(origin, destination) ).to be === 0 end it 'does not rm' do - expect( instance ).to receive(:execute).with("mv #{origin} #{destination}").and_return(0) + expect( instance ).to receive(:execute).with("mv '#{origin}' '#{destination}'").and_return(0) expect( instance.mv(origin, destination, false) ).to be === 0 end end + describe '#modified_at' do + it 'calls execute with touch and timestamp' do + time = '190101010000' + path = '/path/to/file' + expect( instance ).to receive(:execute).with("/bin/touch -mt #{time} #{path}").and_return(0) + + instance.modified_at(path, time) + end + end + describe '#environment_string' do let(:host) { {'pathseparator' => ':'} } diff --git a/spec/beaker/host/unix/file_spec.rb b/spec/beaker/host/unix/file_spec.rb index ceafb85fb2..e87fc45045 100644 --- a/spec/beaker/host/unix/file_spec.rb +++ b/spec/beaker/host/unix/file_spec.rb @@ -196,6 +196,28 @@ def logger end end + describe '#chmod' do + context 'not recursive' do + it 'calls execute with chmod' do + path = '/path/to/file' + mod = '+x' + + expect( instance ).to receive(:execute).with("chmod #{mod} #{path}") + instance.chmod(mod, path) + end + end + + context 'recursive' do + it 'calls execute with chmod' do + path = '/path/to/file' + mod = '+x' + + expect( instance ).to receive(:execute).with("chmod -R #{mod} #{path}") + instance.chmod(mod, path, true) + end + end + end + describe '#chgrp' do let (:group) { 'somegroup' } let (:path) { '/path/to/chgrp/on' } diff --git a/spec/beaker/host_spec.rb b/spec/beaker/host_spec.rb index 0850192910..77147c272b 100644 --- a/spec/beaker/host_spec.rb +++ b/spec/beaker/host_spec.rb @@ -325,7 +325,7 @@ module Beaker allow( result ).to receive( :exit_code ).and_return( 0 ) allow( host ).to receive( :exec ).and_return( result ) - expect( Beaker::Command ).to receive(:new).with("mkdir -p test/test/test") + expect( Beaker::Command ).to receive(:new).with("mkdir -p 'test/test/test'") expect( host.mkdir_p('test/test/test') ).to be == true end @@ -337,7 +337,7 @@ module Beaker allow( result ).to receive( :exit_code ).and_return( 0 ) allow( host ).to receive( :exec ).and_return( result ) - expect( Beaker::Command ).to receive(:new).with("mkdir -p test/test/test") + expect( Beaker::Command ).to receive(:new).with("mkdir -p 'test/test/test'") expect( host.mkdir_p('test/test/test') ).to be == true end