Module: PSWindows::Exec

Includes:
Beaker::CommandFactory, Beaker::DSL::Wrappers
Included in:
Host
Defined in:
lib/beaker/host/pswindows/exec.rb

Constant Summary collapse

ABS_CMD =
'c:\\\\windows\\\\system32\\\\cmd.exe'
CMD =
'cmd.exe'

Instance Attribute Summary

Attributes included from Beaker::CommandFactory

#assertions

Instance Method Summary collapse

Methods included from Beaker::DSL::Wrappers

#encode_command, #powershell

Methods included from Beaker::CommandFactory

#execute, #fail_test

Instance Method Details

#add_env_var(key, val) ⇒ Object

Add the provided key/val to the current ssh environment

Examples:

host.add_env_var('PATH', '/usr/bin:PATH')

Parameters:

  • key (String)

    The key to add the value to

  • val (String)

    The value for the key



118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/beaker/host/pswindows/exec.rb', line 118

def add_env_var key, val
  key = key.to_s.upcase
  #see if the key/value pair already exists
  cur_val = subbed_val = get_env_var(key, true)
  subbed_val = cur_val.gsub(/#{Regexp.escape(val.gsub(/'|"/, ''))}/, '')
  if cur_val.empty?
    exec(powershell("[Environment]::SetEnvironmentVariable('#{key}', '#{val}', 'Machine')"))
    self.close #refresh the state
  elsif subbed_val == cur_val #not present, add it
    exec(powershell("[Environment]::SetEnvironmentVariable('#{key}', '#{val};#{cur_val}', 'Machine')"))
    self.close #refresh the state
  end
end

#clear_env_var(key) ⇒ Object

Delete the environment variable from the current ssh environment

Examples:

host.clear_env_var('PATH')

Parameters:

  • key (String)

    The key to delete



175
176
177
178
179
180
181
# File 'lib/beaker/host/pswindows/exec.rb', line 175

def clear_env_var key
  key = key.to_s.upcase
  exec(powershell("[Environment]::SetEnvironmentVariable('#{key}', $null, 'Machine')"))
  exec(powershell("[Environment]::SetEnvironmentVariable('#{key}', $null, 'User')"))
  exec(powershell("[Environment]::SetEnvironmentVariable('#{key}', $null, 'Process')"))
  self.close #refresh the state
end

#delete_env_var(key, val) ⇒ Object

Delete the provided key/val from the current ssh environment

Examples:

host.delete_env_var('PATH', '/usr/bin:PATH')

Parameters:

  • key (String)

    The key to delete the value from

  • val (String)

    The value to delete for the key



137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/beaker/host/pswindows/exec.rb', line 137

def delete_env_var key, val
  key = key.to_s.upcase
  #get the current value of the key
  cur_val = subbed_val = get_env_var(key, true)
  subbed_val = (cur_val.split(';') - [val.gsub(/'|"/, '')]).join(';')
  if subbed_val != cur_val
    #remove the current key value
    self.clear_env_var(key)
    #set to the truncated value
    self.add_env_var(key, subbed_val)
  end
end

#echo(msg, abs = true) ⇒ Object



14
15
16
# File 'lib/beaker/host/pswindows/exec.rb', line 14

def echo(msg, abs=true)
  (abs ? ABS_CMD : CMD) + " /c echo #{msg}"
end

#environment_string(env) ⇒ Object



183
184
185
186
187
188
189
190
191
192
# File 'lib/beaker/host/pswindows/exec.rb', line 183

def environment_string env
  return '' if env.empty?
  env_array = self.environment_variable_string_pair_array( env )

  environment_string = ''
  env_array.each_with_index do |env|
    environment_string += "set \"#{env}\" && "
  end
  environment_string
end

#environment_variable_string_pair_array(env) ⇒ Object



194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/beaker/host/pswindows/exec.rb', line 194

def environment_variable_string_pair_array env
  env_array = []
  env.each_key do |key|
    val = env[key]
    if val.is_a?(Array)
      val = val.join(':')
    else
      val = val.to_s
    end
    # doing this for the key itself & the upcase'd version allows us to remain
    # backwards compatible
    # TODO: (Next Major Version) get rid of upcase'd version
    key_str = key.to_s
    keys = [key_str]
    keys << key_str.upcase if key_str.upcase != key_str
    keys.each do |env_key|
      env_array << "#{env_key}=#{val}"
    end
  end
  env_array
end

#get_env_var(key, clean = false) ⇒ Object

Return the value of a specific env var

Examples:

host.get_env_var('path')

Parameters:

  • key (String)

    The key to look for

  • clean (Boolean) (defaults to: false)

    Remove the ‘KEY=’ and only return the value of the env var



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/beaker/host/pswindows/exec.rb', line 155

def get_env_var key, clean = false
  self.close #refresh the state
  key = key.to_s.upcase
  val = exec(Beaker::Command.new("set #{key}"), :accept_all_exit_codes => true).stdout.chomp
  if val.empty?
    return ''
  else
    val = val.split(/\n/)[0] # only take the first result
    if clean
      val.gsub(/#{key}=/i,'')
    else
      val
    end
  end
end

#get_ipObject



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/beaker/host/pswindows/exec.rb', line 66

def get_ip
  # when querying for an IP this way the return value can be formatted like:
  # IPAddress=
  # IPAddress={"129.168.0.1"}
  # IPAddress={"192.168.0.1","2001:db8:aaaa:bbbb:cccc:dddd:eeee:0001"}

  ips = execute("wmic nicconfig where ipenabled=true GET IPAddress /format:list")

  ip = ''
  ips.each_line do |line|
    matches = line.split('=')
    next if matches.length <= 1
    matches = matches[1].match(/^{"(.*?)"/)
    next if matches.nil? || matches.captures.nil? || matches.captures.empty?
    ip = matches.captures[0] if matches && matches.captures
    break if ip != ''
  end

  ip
end

#mkdir_p(dir) ⇒ Boolean

Create the provided directory structure on the host

Parameters:

  • dir (String)

    The directory structure to create on the host

Returns:

  • (Boolean)

    True, if directory construction succeeded, otherwise False



106
107
108
109
110
111
# File 'lib/beaker/host/pswindows/exec.rb', line 106

def mkdir_p dir
  normalized_path = dir.gsub('/','\\')
  result = exec(powershell("New-Item -Path '#{normalized_path}' -ItemType 'directory'"),
                :acceptable_exit_codes => [0, 1])
  result.exit_code == 0
end

#modified_at(file, timestamp = nil) ⇒ Object

Update ModifiedDate on a file

Parameters:

  • file (String)

    Path to the file

  • timestamp (String) (defaults to: nil)

    Timestamp to set



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/beaker/host/pswindows/exec.rb', line 43

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

#mv(orig, dest, rm = true) ⇒ Object

Move the origin to destination. The destination is removed prior to moving.

Parameters:

  • orig (String)

    The origin path

  • dest (String)

    the destination path

  • rm (Boolean) (defaults to: true)

    Remove the destination prior to move



32
33
34
35
36
37
38
# File 'lib/beaker/host/pswindows/exec.rb', line 32

def mv(orig, dest, rm=true)
  # ensure that we have the right slashes for windows
  orig = orig.gsub(/\//,'\\')
  dest = dest.gsub(/\//,'\\')
  rm_rf dest unless !rm
  execute("move /y #{orig} #{dest}")
end

#pathObject



62
63
64
# File 'lib/beaker/host/pswindows/exec.rb', line 62

def path
  'c:/windows/system32;c:/windows'
end

#ping(target, attempts = 5) ⇒ Boolean

Attempt to ping the provided target hostname

Parameters:

  • target (String)

    The hostname to ping

  • attempts (Integer) (defaults to: 5)

    Amount of times to attempt ping before giving up

Returns:

  • (Boolean)

    true of ping successful, overwise false



91
92
93
94
95
96
97
98
99
100
101
# File 'lib/beaker/host/pswindows/exec.rb', line 91

def ping target, attempts=5
  try = 0
  while try < attempts do
    result = exec(Beaker::Command.new("ping -n 1 #{target}"), :accept_all_exit_codes => true)
    if result.exit_code == 0
      return true
    end
    try+=1
  end
  result.exit_code == 0
end

#rebootObject



5
6
7
8
9
# File 'lib/beaker/host/pswindows/exec.rb', line 5

def reboot
  exec(Beaker::Command.new("shutdown /r /t 0"), :expect_connection_failure => true)
  # rebooting on windows is slooooow
  sleep(40)
end

#rm_rf(path) ⇒ Object



22
23
24
25
26
# File 'lib/beaker/host/pswindows/exec.rb', line 22

def rm_rf path
  # ensure that we have the right slashes for windows
  path = path.gsub(/\//, '\\')
  execute("del /s /q #{path}")
end

#ssh_permit_user_environmentObject

Overrides the Windows::Exec#ssh_permit_user_environment method, since no steps are needed in this setup to allow user ssh environments to work.



219
220
# File 'lib/beaker/host/pswindows/exec.rb', line 219

def ssh_permit_user_environment
end

#ssh_set_user_environment(env) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Note:

this class doesn’t manipulate an SSH environment file, it just sets

Sets the user SSH environment.

the environment variables on the system.

Parameters:

  • env (Hash{String=>String})

    Environment variables to set on the system, in the form of a hash of String variable names to their corresponding String values.

Returns:

  • nil



233
234
235
236
237
238
# File 'lib/beaker/host/pswindows/exec.rb', line 233

def ssh_set_user_environment(env)
  #add the env var set to this test host
  env.each_pair do |var, value|
    add_env_var(var, value)
  end
end

#touch(file, abs = true) ⇒ Object



18
19
20
# File 'lib/beaker/host/pswindows/exec.rb', line 18

def touch(file, abs=true)
  (abs ? ABS_CMD : CMD) + " /c echo. 2> #{file}"
end

#which(command) ⇒ String

First path it finds for the command executable

Examples:

host.which('ruby')

Parameters:

  • command (String)

    The command executable to search for

Returns:

  • (String)

    Path to the searched executable or empty string if not found



247
248
249
250
251
252
253
254
# File 'lib/beaker/host/pswindows/exec.rb', line 247

def which(command)
  where_command = "cmd /C \"where #{command}\""

  result = execute(where_command, :accept_all_exit_codes => true)
  return '' if result.empty?

  result
end