serverspec 0.10.6 → 0.10.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 22e4b599ab3a4fc8ff81faf1e55f41712e109631
4
- data.tar.gz: 7dd6658d68a7ab903add025a20225b151985e9c6
3
+ metadata.gz: 05c1dc06b5b4833b7e537d596b488b3bb07aba0e
4
+ data.tar.gz: c8fa93b1eab1507daa911da2a1e1b55c20dcac9c
5
5
  SHA512:
6
- metadata.gz: e929ccd2fd728a64bfd5e612319ec8d17c247f8dd7d1bc08bb590a70c8afc2c47c9deb69a0c8d101e8d98d7af004bb843c6d66e063a3817f9aa3188e4d334556
7
- data.tar.gz: 79b9091221264fb2ae68cdd43d3170acf804024bf2b5028d8f879a9e621f177c8f52c00f577b7193b8314588e0cf60ed705f1af653c757f00894caec2a761b58
6
+ metadata.gz: eeab306443ccc7261c6dacf25553d98481fed15453e650c55f79c574223485a02dab66ac73751b8ca7468275defb4fbf5de8d66dbc763b941023c26f4a00c5e4
7
+ data.tar.gz: 7c53f323cfcee38681c359ce7bdbef51b0e85089cec4dda10537a11aebf1af200ec93f1ca8a88a4d26e7a1084f5533b8483f57d44eba993737ccadf66ee2ba60
@@ -33,7 +33,7 @@ RSpec.configure do |c|
33
33
  end
34
34
  ```
35
35
 
36
- For different authentication mechanisms check the Microsoft WinRM documentation and verify the ones that are supported by [WinRb/WinRM](https://github.com/WinRb/WinRM)
36
+ For how to configure the guest to accept WinRM connections and the different authentication mechanisms check the Microsoft WinRM documentation and verify the ones that are supported by [WinRb/WinRM](https://github.com/WinRb/WinRM).
37
37
 
38
38
 
39
39
  ###RSpec Examples for windows target hosts
@@ -75,6 +75,10 @@ describe group('MYDOMAIN\Domain Users') do
75
75
  it { should exist }
76
76
  end
77
77
 
78
+ describe command('& "ipconfig"') do
79
+ it { should return_stdout(/IPv4 Address(\.| )*: 192\.168\.1\.100/) }
80
+ end
81
+
78
82
  describe windows_registry_key('HKEY_USERS\S-1-5-21-1319311448-2088773778-316617838-32407\Test MyKey') do
79
83
  it { should exist }
80
84
  it { should have_property('string value') }
@@ -85,4 +89,9 @@ describe windows_registry_key('HKEY_USERS\S-1-5-21-1319311448-2088773778-3166178
85
89
  it { should have_property_value('qword value', :type_qword, 'adff32') }
86
90
  it { should have_property_value('binary value', :type_binary, 'dfa0f066') }
87
91
  end
88
- ```
92
+ ```
93
+
94
+ ###Notes:
95
+ * Not all the matchers you are used to in Linux-like OS are supported in Windows, some because of differences between the operating systems (e.g. users and permissions model), some because they haven't been yet implemented.
96
+ * All commands in the windows backend are run via powershell, so the output in case of stderr is a pretty ugly xml-like thing. Still it should contain some information to help troubleshooting.
97
+ * The *command* type is executed again through powershell, so bear that in mind if you mean to run old CMD windows batch or programs. (i.e run the command using the **Invoke-Expression** Cmdlet, or the **&** Call Operator)
@@ -7,7 +7,7 @@ module Serverspec
7
7
 
8
8
  def run_command(cmd, opts={})
9
9
  script = create_script(cmd)
10
- result = execute_script script
10
+ result = execute_script %Q{powershell -encodedCommand #{encode_script(script)}}
11
11
 
12
12
  if @example
13
13
  @example.metadata[:command] = script
@@ -18,15 +18,14 @@ module Serverspec
18
18
  end
19
19
 
20
20
  def execute_script script
21
- ps_script = %Q{powershell -encodedCommand #{encode_script(script)}}
22
21
  if Open3.respond_to? :capture3
23
- stdout, stderr, status = Open3.capture3(ps_script)
22
+ stdout, stderr, status = Open3.capture3(script)
24
23
  # powershell still exits with 0 even if there are syntax errors, although it spits the error out into stderr
25
24
  # so we have to resort to return an error exit code if there is anything in the standard error
26
25
  status = 1 if status == 0 and !stderr.empty?
27
26
  { :stdout => stdout, :stderr => stderr, :status => status }
28
27
  else
29
- stdout = `#{ps_script} 2>&1`
28
+ stdout = `#{script} 2>&1`
30
29
  { :stdout => stdout, :stderr => nil, :status => $? }
31
30
  end
32
31
  end
@@ -30,6 +30,10 @@ module Serverspec
30
30
  raise "You must provide a specific Windows user/group" if id =~ /(owner|group|others)/
31
31
  identity = id || 'Everyone'
32
32
  end
33
+
34
+ def to_s
35
+ @script
36
+ end
33
37
  end
34
38
  end
35
39
  end
@@ -47,10 +47,11 @@ EOF
47
47
  end
48
48
 
49
49
  def create_script command
50
- script = build_command(command.script)
51
- script = add_pre_command(script)
52
- ps_functions = command.import_functions.map { |f| File.read(File.join(File.dirname(__FILE__), 'support', f)) }
53
- <<-EOF
50
+ if command.is_a? Command
51
+ ps_functions = command.import_functions.map { |f| File.read(File.join(File.dirname(__FILE__), 'support', f)) }
52
+ script = build_command(command.script)
53
+ script = add_pre_command(script)
54
+ <<-EOF
54
55
  $exitCode = 1
55
56
  try {
56
57
  #{ps_functions.join("\n")}
@@ -62,6 +63,21 @@ try {
62
63
  Write-Output "Exiting with code: $exitCode"
63
64
  exit $exitCode
64
65
  EOF
66
+ else
67
+ script = build_command(command.to_s)
68
+ add_pre_command(script)
69
+ end
70
+ end
71
+
72
+ def check_running(process)
73
+ ret = run_command(commands.check_running(process))
74
+
75
+ # If the service is not registered, check the process
76
+ if ret[:exit_status] == 1
77
+ ret = run_command(commands.check_process(process))
78
+ end
79
+
80
+ ret[:exit_status] == 0
65
81
  end
66
82
  end
67
83
  end
@@ -2,11 +2,7 @@ function CheckFileAccessRules
2
2
  {
3
3
  param($path, $identity, $rules)
4
4
 
5
- $result = $false
6
- $accessRules = (Get-Acl $path).access | Where-Object {$_.AccessControlType -eq 'Allow' -and $_.IdentityReference -eq $identity }
7
- if ($accessRules) {
8
- $match = $accessRules.FileSystemRights.ToString() -Split (', ') | ?{$rules -contains $_}
9
- $result = $match -ne $null -or $match.length -gt 0
10
- }
11
- $result
5
+ $accessRules = @((Get-Acl $path).access | Where-Object {$_.AccessControlType -eq 'Allow' -and $_.IdentityReference -eq $identity })
6
+ $match = @($accessRules | Where-Object {($_.FileSystemRights.ToString().Split(',') | % {$_.trim()} | ? {$rules -contains $_}) -ne $null})
7
+ $match.count -gt 0
12
8
  }
@@ -6,7 +6,7 @@ function IsPortListening
6
6
  foreach ($ipaddress in $networkIPs)
7
7
  {
8
8
  $matchExpression = ("$ipaddress" + ":" + $portNumber)
9
- if ($protocol) { $matchExpression = ($protocol.toUpper() + "\s+$matchExpression") }
9
+ if ($protocol) { $matchExpression = ($protocol.toUpper() + "\s+$matchExpression") }
10
10
  if ($netstatOutput -match $matchExpression) { return $true }
11
11
  }
12
12
  $false
@@ -192,7 +192,9 @@ module Serverspec
192
192
  when :type_binary
193
193
  byte_array = [property[:value]].pack('H*').bytes.to_a
194
194
  "([byte[]] #{byte_array.join(',')})"
195
- when:type_dword, :type_qword
195
+ when :type_dword
196
+ [property[:value].scan(/[0-9a-f]{2}/i).reverse.join].pack("H*").unpack("l").first
197
+ when :type_qword
196
198
  property[:value].hex
197
199
  else
198
200
  string_array = property[:value].split("\n").map {|s| "'#{s}'"}.reduce {|acc, s| "#{acc},#{s}"}
@@ -1,3 +1,3 @@
1
1
  module Serverspec
2
- VERSION = "0.10.6"
2
+ VERSION = "0.10.7"
3
3
  end
@@ -75,3 +75,30 @@ describe "script encoding" do
75
75
  script.should == "dABlAHMAdABfAHAAbwB3AGUAcgBzAGgAZQBsAGwAXwBzAGMAcgBpAHAAdAA="
76
76
  end
77
77
  end
78
+
79
+ describe 'script creation' do
80
+ context "powershell command" do
81
+ File.should_receive(:read).with(/test_function1.ps1/).and_return 'function test1'
82
+ command = Backend::PowerShell::Command.new do
83
+ using 'test_function1.ps1'
84
+ exec 'test command'
85
+ end
86
+ script = create_script command
87
+ script.should == <<-eof
88
+ $exitCode = 1
89
+ try {
90
+ function test1
91
+ $success = (test command)
92
+ if ($success -is [Boolean] -and $success) { $exitCode = 0 }
93
+ } catch {
94
+ Write-Output $_.Exception.Message
95
+ }
96
+ Write-Output "Exiting with code: $exitCode"
97
+ exit $exitCode
98
+ eof
99
+ end
100
+
101
+ context 'simple command' do
102
+ create_script('test command').should == 'test command'
103
+ end
104
+ end
data/spec/spec_helper.rb CHANGED
@@ -39,10 +39,7 @@ module Serverspec
39
39
  clz.class_eval do
40
40
  include TestCommandRunner
41
41
  def run_command(cmd)
42
- if RSpec.configuration.os =~ /Windows/
43
- cmd = cmd.script
44
- end
45
- cmd = build_command(cmd)
42
+ cmd = build_command(cmd.to_s)
46
43
  cmd = add_pre_command(cmd)
47
44
  do_run cmd
48
45
  end
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+
3
+ include Serverspec::Helper::Cmd
4
+ RSpec.configure do |c|
5
+ c.os = 'Windows'
6
+ end
7
+
8
+ describe command('test_cmd /test/path/file') do
9
+ let(:stdout) { "test output 1.2.3\r\n" }
10
+ it { should return_stdout("test output 1.2.3") }
11
+ its(:command) { should eq 'test_cmd /test/path/file' }
12
+ end
13
+
14
+ describe 'complete matching of stdout' do
15
+ context command('test_cmd /test/path/file') do
16
+ let(:stdout) { "foocontent-should-be-includedbar\r\n" }
17
+ it { should_not return_stdout('content-should-be-included') }
18
+ end
19
+ end
20
+
21
+ describe 'regexp matching of stdout' do
22
+ context command('test_cmd /test/path/file') do
23
+ let(:stdout) { "test output 1.2.3\r\n" }
24
+ it { should return_stdout(/1\.2\.3/) }
25
+ end
26
+ end
27
+
28
+ describe command('test_cmd /test/path/file') do
29
+ let(:stdout) { "No such file or directory\r\n" }
30
+ it { should return_stderr("No such file or directory") }
31
+ its(:command) { should eq 'test_cmd /test/path/file' }
32
+ end
33
+
34
+ describe 'complete matching of stderr' do
35
+ context command('test_cmd /test/path/file') do
36
+ let(:stdout) { "No such file or directory\r\n" }
37
+ it { should_not return_stdout('file') }
38
+ end
39
+ end
40
+
41
+ describe 'regexp matching of stderr' do
42
+ context command('test_cmd /test/path/file') do
43
+ let(:stdout) { "No such file or directory\r\n" }
44
+ it { should return_stderr(/file/) }
45
+ end
46
+ end
47
+
48
+ describe command('test_cmd /test/path/file') do
49
+ it { should return_exit_status 0 }
50
+ its(:command) { should eq 'test_cmd /test/path/file' }
51
+ end
52
+
53
+ describe command('dir "c:\"') do
54
+ let(:stdout) { <<EOF
55
+ Directory: C:\
56
+
57
+ Mode LastWriteTime Length Name
58
+ ---- ------------- ------ ----
59
+ d-r-- 23/09/2013 10:46 AM Program Files
60
+ d-r-- 23/09/2013 1:21 PM Program Files (x86)
61
+ d---- 17/10/2013 8:46 PM temp
62
+ d-r-- 23/09/2013 11:52 AM Users
63
+ d---- 23/09/2013 1:21 PM Windows
64
+ EOF
65
+ }
66
+
67
+ its(:stdout) { should match /Program Files/ }
68
+ its(:stderr) { should match /Program Files/ }
69
+
70
+ its(:stdout) { should eq stdout }
71
+ end
@@ -22,3 +22,12 @@ end
22
22
  describe service('invalid-daemon') do
23
23
  it { should_not be_running }
24
24
  end
25
+
26
+ describe service('Test service') do
27
+ it "should raise error if trying to check service process controller" do
28
+ expect { should be_running.under('supervisor') }.to raise_error
29
+ end
30
+ it "should raise error if trying to check service monitoring" do
31
+ expect { should_not be_monitored_by('monit') }.to raise_error
32
+ end
33
+ end
@@ -0,0 +1,68 @@
1
+ require 'spec_helper'
2
+
3
+ include Serverspec::Helper::Cmd
4
+ RSpec.configure do |c|
5
+ c.os = 'Windows'
6
+ end
7
+
8
+ describe windows_registry_key('PATH/TO/THE_KEY') do
9
+ it { should exist }
10
+ its(:command) { should == "(Get-Item 'Registry::PATH/TO/THE_KEY') -ne $null" }
11
+ end
12
+
13
+ describe windows_registry_key('PATH/TO/THE_KEY') do
14
+ it { should have_value('Test Value') }
15
+ its(:command) { should == "(Compare-Object (Get-Item 'Registry::PATH/TO/THE_KEY').GetValue('') @('Test Value')) -eq $null" }
16
+ end
17
+
18
+ describe 'Key value types' do
19
+ context 'default type' do
20
+ describe windows_registry_key('PATH/TO/THE_KEY') do
21
+ it { should have_property('TestProperty') }
22
+ its(:command) { should == "(Get-Item 'Registry::PATH/TO/THE_KEY').GetValueKind('TestProperty') -eq 'String'" }
23
+ end
24
+ end
25
+
26
+ {
27
+ :type_string => 'String',
28
+ :type_binary => 'Binary',
29
+ :type_dword => 'DWord',
30
+ :type_qword => 'QWord',
31
+ :type_multistring => 'MultiString',
32
+ :type_expandstring => 'ExpandString'
33
+ }.each do |sym, type|
34
+ context "type #{type}" do
35
+ describe windows_registry_key('PATH/TO/THE_KEY') do
36
+ it { should have_property('TestProperty', sym) }
37
+ its(:command) { should == "(Get-Item 'Registry::PATH/TO/THE_KEY').GetValueKind('TestProperty') -eq '#{type}'" }
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ describe windows_registry_key('PATH/TO/THE_KEY') do
44
+ it { should have_property_value('TestProperty', :type_binary, '12a07b') }
45
+ its(:command) { should == "(Compare-Object (Get-Item 'Registry::PATH/TO/THE_KEY').GetValue('TestProperty') ([byte[]] 18,160,123)) -eq $null" }
46
+ end
47
+
48
+ describe windows_registry_key('PATH/TO/THE_KEY') do
49
+ it { should have_property_value('TestProperty', :type_dword, 'fffffd6c') }
50
+ its(:command) { should == "(Compare-Object (Get-Item 'Registry::PATH/TO/THE_KEY').GetValue('TestProperty') -660) -eq $null" }
51
+ end
52
+
53
+ describe windows_registry_key('PATH/TO/THE_KEY') do
54
+ it { should have_property_value('TestProperty', :type_qword, '1e240') }
55
+ its(:command) { should == "(Compare-Object (Get-Item 'Registry::PATH/TO/THE_KEY').GetValue('TestProperty') 123456) -eq $null" }
56
+ end
57
+
58
+ describe windows_registry_key('PATH/TO/THE_KEY') do
59
+ it {
60
+ value = <<-EOF
61
+ test line1
62
+ test line2
63
+ test line3
64
+ EOF
65
+ should have_property_value('TestProperty', :type_multistring, value)
66
+ }
67
+ its(:command) { should == "(Compare-Object (Get-Item 'Registry::PATH/TO/THE_KEY').GetValue('TestProperty') @('test line1','test line2','test line3')) -eq $null" }
68
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: serverspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.6
4
+ version: 0.10.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gosuke Miyashita
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-16 00:00:00.000000000 Z
11
+ date: 2013-10-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: net-ssh
@@ -95,7 +95,7 @@ files:
95
95
  - LICENSE.txt
96
96
  - README.md
97
97
  - Rakefile
98
- - WindowsSupport.md
98
+ - WINDOWS_SUPPORT.md
99
99
  - bin/serverspec-init
100
100
  - lib/serverspec.rb
101
101
  - lib/serverspec/attributes.rb
@@ -368,11 +368,13 @@ files:
368
368
  - spec/solaris11/zfs_spec.rb
369
369
  - spec/spec_helper.rb
370
370
  - spec/support/powershell_command_runner.rb
371
+ - spec/windows/command_spec.rb
371
372
  - spec/windows/file_spec.rb
372
373
  - spec/windows/group_spec.rb
373
374
  - spec/windows/port_spec.rb
374
375
  - spec/windows/service_spec.rb
375
376
  - spec/windows/user_spec.rb
377
+ - spec/windows/windows_registry_key_spec.rb
376
378
  homepage: http://serverspec.org/
377
379
  licenses:
378
380
  - MIT
@@ -564,8 +566,10 @@ test_files:
564
566
  - spec/solaris11/zfs_spec.rb
565
567
  - spec/spec_helper.rb
566
568
  - spec/support/powershell_command_runner.rb
569
+ - spec/windows/command_spec.rb
567
570
  - spec/windows/file_spec.rb
568
571
  - spec/windows/group_spec.rb
569
572
  - spec/windows/port_spec.rb
570
573
  - spec/windows/service_spec.rb
571
574
  - spec/windows/user_spec.rb
575
+ - spec/windows/windows_registry_key_spec.rb