r-train 0.9.1

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.
Files changed (77) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +45 -0
  4. data/.travis.yml +12 -0
  5. data/Gemfile +22 -0
  6. data/LICENSE +201 -0
  7. data/README.md +137 -0
  8. data/Rakefile +39 -0
  9. data/lib/train.rb +100 -0
  10. data/lib/train/errors.rb +23 -0
  11. data/lib/train/extras.rb +15 -0
  12. data/lib/train/extras/command_wrapper.rb +105 -0
  13. data/lib/train/extras/file_common.rb +131 -0
  14. data/lib/train/extras/linux_file.rb +74 -0
  15. data/lib/train/extras/linux_lsb.rb +60 -0
  16. data/lib/train/extras/os_common.rb +131 -0
  17. data/lib/train/extras/os_detect_darwin.rb +32 -0
  18. data/lib/train/extras/os_detect_linux.rb +126 -0
  19. data/lib/train/extras/os_detect_unix.rb +77 -0
  20. data/lib/train/extras/os_detect_windows.rb +73 -0
  21. data/lib/train/extras/stat.rb +92 -0
  22. data/lib/train/extras/windows_file.rb +85 -0
  23. data/lib/train/options.rb +80 -0
  24. data/lib/train/plugins.rb +40 -0
  25. data/lib/train/plugins/base_connection.rb +86 -0
  26. data/lib/train/plugins/transport.rb +49 -0
  27. data/lib/train/transports/docker.rb +102 -0
  28. data/lib/train/transports/local.rb +52 -0
  29. data/lib/train/transports/local_file.rb +77 -0
  30. data/lib/train/transports/local_os.rb +51 -0
  31. data/lib/train/transports/mock.rb +125 -0
  32. data/lib/train/transports/ssh.rb +163 -0
  33. data/lib/train/transports/ssh_connection.rb +216 -0
  34. data/lib/train/transports/winrm.rb +187 -0
  35. data/lib/train/transports/winrm_connection.rb +258 -0
  36. data/lib/train/version.rb +7 -0
  37. data/test/integration/.kitchen.yml +43 -0
  38. data/test/integration/Berksfile +3 -0
  39. data/test/integration/bootstrap.sh +17 -0
  40. data/test/integration/chefignore +1 -0
  41. data/test/integration/cookbooks/test/metadata.rb +1 -0
  42. data/test/integration/cookbooks/test/recipes/default.rb +101 -0
  43. data/test/integration/docker_run.rb +153 -0
  44. data/test/integration/docker_test.rb +24 -0
  45. data/test/integration/docker_test_container.rb +24 -0
  46. data/test/integration/helper.rb +58 -0
  47. data/test/integration/sudo/nopasswd.rb +16 -0
  48. data/test/integration/sudo/passwd.rb +21 -0
  49. data/test/integration/sudo/run_as.rb +12 -0
  50. data/test/integration/test-runner.yaml +24 -0
  51. data/test/integration/test_local.rb +19 -0
  52. data/test/integration/test_ssh.rb +24 -0
  53. data/test/integration/tests/path_block_device_test.rb +74 -0
  54. data/test/integration/tests/path_character_device_test.rb +74 -0
  55. data/test/integration/tests/path_file_test.rb +79 -0
  56. data/test/integration/tests/path_folder_test.rb +88 -0
  57. data/test/integration/tests/path_missing_test.rb +77 -0
  58. data/test/integration/tests/path_pipe_test.rb +78 -0
  59. data/test/integration/tests/path_symlink_test.rb +83 -0
  60. data/test/integration/tests/run_command_test.rb +28 -0
  61. data/test/unit/extras/command_wrapper_test.rb +41 -0
  62. data/test/unit/extras/file_common_test.rb +133 -0
  63. data/test/unit/extras/linux_file_test.rb +98 -0
  64. data/test/unit/extras/os_common_test.rb +258 -0
  65. data/test/unit/extras/stat_test.rb +105 -0
  66. data/test/unit/helper.rb +6 -0
  67. data/test/unit/plugins/connection_test.rb +44 -0
  68. data/test/unit/plugins/transport_test.rb +111 -0
  69. data/test/unit/plugins_test.rb +22 -0
  70. data/test/unit/train_test.rb +132 -0
  71. data/test/unit/transports/local_file_test.rb +112 -0
  72. data/test/unit/transports/local_test.rb +73 -0
  73. data/test/unit/transports/mock_test.rb +76 -0
  74. data/test/unit/transports/ssh_test.rb +95 -0
  75. data/test/unit/version_test.rb +8 -0
  76. data/train.gemspec +32 -0
  77. metadata +299 -0
@@ -0,0 +1,77 @@
1
+ # encoding: utf-8
2
+
3
+ describe 'file interface' do
4
+ let(:backend) { get_backend.call }
5
+
6
+ describe 'a path that doesnt exist' do
7
+ let(:file) {
8
+ backend.file('/do_not_create_this_path_please_or_my_tests_will_fail')
9
+ }
10
+
11
+ it 'does not exist' do
12
+ file.exist?.must_equal(false)
13
+ end
14
+
15
+ it 'is not a file' do
16
+ file.file?.must_equal(false)
17
+ end
18
+
19
+ it 'has type nil' do
20
+ file.type.must_be_nil
21
+ end
22
+
23
+ it 'has no content' do
24
+ file.content.must_be_nil
25
+ end
26
+
27
+ it 'has no owner' do
28
+ file.owner.must_be_nil
29
+ end
30
+
31
+ it 'has no group' do
32
+ file.group.must_be_nil
33
+ end
34
+
35
+ it 'has mode nil' do
36
+ file.mode.must_be_nil
37
+ end
38
+
39
+ it 'checks mode? nil' do
40
+ file.mode?(nil).must_equal(true)
41
+ end
42
+
43
+ it 'has no link_path' do
44
+ file.link_path.must_be_nil
45
+ end
46
+
47
+ it 'has an md5sum' do
48
+ file.md5sum.must_be_nil
49
+ end
50
+
51
+ it 'has an sha256sum' do
52
+ file.sha256sum.must_be_nil
53
+ end
54
+
55
+ it 'has a modified time' do
56
+ file.mtime.must_be_nil
57
+ end
58
+
59
+ it 'has inode size' do
60
+ # Must be around 11 Bytes, +- 4
61
+ file.size.must_be_nil
62
+ end
63
+
64
+ it 'has no selinux_label' do
65
+ file.selinux_label.must_be_nil
66
+ end
67
+
68
+ it 'has no product_version' do
69
+ file.product_version.must_be_nil
70
+ end
71
+
72
+ it 'has no file_version' do
73
+ file.file_version.must_be_nil
74
+ end
75
+
76
+ end
77
+ end
@@ -0,0 +1,78 @@
1
+ # encoding: utf-8
2
+
3
+ describe 'file interface' do
4
+ let(:backend) { get_backend.call }
5
+
6
+ describe 'pipe / fifo' do
7
+ let(:file) { backend.file('/tmp/pipe') }
8
+
9
+ it 'exists' do
10
+ file.exist?.must_equal(true)
11
+ end
12
+
13
+ it 'is a pipe' do
14
+ file.pipe?.must_equal(true)
15
+ end
16
+
17
+ it 'has type :pipe' do
18
+ file.type.must_equal(:pipe)
19
+ end
20
+
21
+ # # TODO add back content
22
+ # it 'has no content' do
23
+ # file.content.must_be_nil
24
+ # end
25
+
26
+ it 'has owner name root' do
27
+ file.owner.must_equal('root')
28
+ end
29
+
30
+ it 'has group name' do
31
+ file.group.must_equal(Test.root_group(backend.os))
32
+ end
33
+
34
+ it 'has mode 0644' do
35
+ file.mode.must_equal(00644)
36
+ end
37
+
38
+ it 'checks mode? 0644' do
39
+ file.mode?(00644).must_equal(true)
40
+ end
41
+
42
+ it 'has no link_path' do
43
+ file.link_path.must_be_nil
44
+ end
45
+
46
+ # # TODO add back content
47
+ # it 'has no md5sum' do
48
+ # file.md5sum.must_be_nil
49
+ # end
50
+ #
51
+ # # TODO add back content
52
+ # it 'has no sha256sum' do
53
+ # file.sha256sum.must_be_nil
54
+ # end
55
+
56
+ it 'has a modified time' do
57
+ file.mtime.must_be_close_to(Time.now.to_i - Test.mtime/2, Test.mtime)
58
+ end
59
+
60
+ it 'has inode size of 0' do
61
+ file.size.must_equal(0)
62
+ end
63
+
64
+ it 'has selinux label handling' do
65
+ res = Test.selinux_label(backend, file.path)
66
+ file.selinux_label.must_equal(res)
67
+ end
68
+
69
+
70
+ it 'has no product_version' do
71
+ file.product_version.must_equal(nil)
72
+ end
73
+
74
+ it 'has no file_version' do
75
+ file.file_version.must_equal(nil)
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,83 @@
1
+ # encoding: utf-8
2
+
3
+ describe 'file interface' do
4
+ let(:backend) { get_backend.call }
5
+
6
+ describe 'symlink file' do
7
+ let(:file) { backend.file('/tmp/symlink') }
8
+
9
+ it 'exists' do
10
+ file.exist?.must_equal(true)
11
+ end
12
+
13
+ it 'is a symlink' do
14
+ file.symlink?.must_equal(true)
15
+ end
16
+
17
+ it 'is pointing to a file' do
18
+ file.file?.must_equal(true)
19
+ end
20
+
21
+ it 'is not pointing to a folder' do
22
+ file.directory?.must_equal(false)
23
+ end
24
+
25
+ it 'has type :symlink' do
26
+ file.type.must_equal(:symlink)
27
+ end
28
+
29
+ it 'has content' do
30
+ file.content.must_equal('hello world')
31
+ end
32
+
33
+ it 'has owner name root' do
34
+ file.owner.must_equal('root')
35
+ end
36
+
37
+ it 'has group name' do
38
+ file.group.must_equal(Test.root_group(backend.os))
39
+ end
40
+
41
+ it 'has mode 0777' do
42
+ file.mode.must_equal(00777)
43
+ end
44
+
45
+ it 'checks mode? 0777' do
46
+ file.mode?(00777).must_equal(true)
47
+ end
48
+
49
+ it 'has link_path' do
50
+ file.link_path.must_equal('/tmp/file')
51
+ end
52
+
53
+ it 'has an md5sum' do
54
+ file.md5sum.must_equal('5eb63bbbe01eeed093cb22bb8f5acdc3')
55
+ end
56
+
57
+ it 'has an sha256sum' do
58
+ file.sha256sum.must_equal('b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9')
59
+ end
60
+
61
+ it 'has a modified time' do
62
+ file.mtime.must_be_close_to(Time.now.to_i - Test.mtime/2, Test.mtime)
63
+ end
64
+
65
+ it 'has size' do
66
+ # Must be around 11 Bytes, +- 4
67
+ file.size.must_be_close_to(11, 4)
68
+ end
69
+
70
+ it 'has selinux label handling' do
71
+ res = Test.selinux_label(backend, file.path)
72
+ file.selinux_label.must_equal(res)
73
+ end
74
+
75
+ it 'has no product_version' do
76
+ file.product_version.must_equal(nil)
77
+ end
78
+
79
+ it 'has no file_version' do
80
+ file.file_version.must_equal(nil)
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+
3
+ describe 'run_command' do
4
+ let(:backend) { get_backend.call() }
5
+
6
+ it 'can echo commands' do
7
+ res = backend.run_command('echo hello world')
8
+ res.stdout.must_equal("hello world\n")
9
+ res.stderr.must_equal('')
10
+ res.exit_status.must_equal(0)
11
+ end
12
+
13
+ it 'can echo commands to stderr' do
14
+ # TODO: Specinfra often fails on this test.
15
+ # Fix and re-enable it.
16
+ res = backend.run_command('>&2 echo hello world')
17
+ res.stdout.must_equal('')
18
+ res.stderr.must_equal("hello world\n")
19
+ res.exit_status.must_equal(0)
20
+ end
21
+
22
+ it 'prints a correct exit status' do
23
+ res = backend.run_command('exit 123')
24
+ res.stdout.must_equal('')
25
+ res.stderr.must_equal('')
26
+ res.exit_status.must_equal(123)
27
+ end
28
+ end
@@ -0,0 +1,41 @@
1
+ # encoding: utf-8
2
+ # author: Dominik Richter
3
+ # author: Christoph Hartmann
4
+
5
+ require 'helper'
6
+ require 'train/transports/mock'
7
+ require 'train/extras'
8
+ require 'base64'
9
+
10
+ describe 'linux command' do
11
+ let(:cls) { Train::Extras::LinuxCommand }
12
+ let(:cmd) { rand.to_s }
13
+ let(:backend) {
14
+ backend = Train::Transports::Mock.new.connection
15
+ backend.mock_os({ family: 'linux' })
16
+ backend
17
+ }
18
+
19
+ it 'wraps commands in sudo' do
20
+ lc = cls.new(backend, { sudo: true })
21
+ lc.run(cmd).must_equal "sudo #{cmd}"
22
+ end
23
+
24
+ it 'doesnt wrap commands in sudo if user == root' do
25
+ lc = cls.new(backend, { sudo: true, user: 'root' })
26
+ lc.run(cmd).must_equal cmd
27
+ end
28
+
29
+ it 'wraps commands in sudo with all options' do
30
+ opts = rand.to_s
31
+ lc = cls.new(backend, { sudo: true, sudo_options: opts })
32
+ lc.run(cmd).must_equal "sudo #{opts} #{cmd}"
33
+ end
34
+
35
+ it 'runs commands in sudo with password' do
36
+ pw = rand.to_s
37
+ lc = cls.new(backend, { sudo: true, sudo_password: pw })
38
+ bpw = Base64.strict_encode64(pw + "\n")
39
+ lc.run(cmd).must_equal "echo #{bpw} | base64 -d | sudo -S #{cmd}"
40
+ end
41
+ end
@@ -0,0 +1,133 @@
1
+ # encoding: utf-8
2
+ require 'helper'
3
+ require 'securerandom'
4
+ require 'train/extras/file_common'
5
+
6
+ describe 'file common' do
7
+ let(:cls) { Train::Extras::FileCommon }
8
+
9
+ def mockup(stubs)
10
+ Class.new(cls) do
11
+ stubs.each do |k,v|
12
+ define_method k.to_sym do
13
+ v
14
+ end
15
+ end
16
+ end.new
17
+ end
18
+
19
+ it 'has the default type of unknown' do
20
+ cls.new.type.must_equal :unknown
21
+ end
22
+
23
+ it 'calculates md5sum from content' do
24
+ content = 'hello world'
25
+ cls.new.stub :content, content do |i|
26
+ i.md5sum.must_equal '5eb63bbbe01eeed093cb22bb8f5acdc3'
27
+ end
28
+ end
29
+
30
+ it 'sets md5sum of nil content to nil' do
31
+ cls.new.stub :content, nil do |i|
32
+ i.md5sum.must_be_nil
33
+ end
34
+ end
35
+
36
+ it 'calculates md5sum from content' do
37
+ content = 'hello world'
38
+ cls.new.stub :content, content do |i|
39
+ i.sha256sum.must_equal 'b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9'
40
+ end
41
+ end
42
+
43
+ it 'sets sha256sum of nil content to nil' do
44
+ cls.new.stub :content, nil do |i|
45
+ i.sha256sum.must_be_nil
46
+ end
47
+ end
48
+
49
+ describe 'type' do
50
+ it 'recognized type == file' do
51
+ fc = mockup(type: :file)
52
+ fc.file?.must_equal true
53
+ end
54
+
55
+ it 'recognized type == block_device' do
56
+ fc = mockup(type: :block_device)
57
+ fc.block_device?.must_equal true
58
+ end
59
+
60
+ it 'recognized type == character_device' do
61
+ fc = mockup(type: :character_device)
62
+ fc.character_device?.must_equal true
63
+ end
64
+
65
+ it 'recognized type == socket' do
66
+ fc = mockup(type: :socket)
67
+ fc.socket?.must_equal true
68
+ end
69
+
70
+ it 'recognized type == directory' do
71
+ fc = mockup(type: :directory)
72
+ fc.directory?.must_equal true
73
+ end
74
+
75
+ it 'recognized type == pipe' do
76
+ fc = mockup(type: :pipe)
77
+ fc.pipe?.must_equal true
78
+ end
79
+
80
+ it 'recognized type == symlink' do
81
+ fc = mockup(type: :symlink)
82
+ fc.symlink?.must_equal true
83
+ end
84
+ end
85
+
86
+ describe 'version' do
87
+ it 'recognized wrong version' do
88
+ fc = mockup(product_version: rand, file_version: rand)
89
+ fc.version?(rand).must_equal false
90
+ end
91
+
92
+ it 'recognized product_version' do
93
+ x = rand
94
+ fc = mockup(product_version: x, file_version: rand)
95
+ fc.version?(x).must_equal true
96
+ end
97
+
98
+ it 'recognized file_version' do
99
+ x = rand
100
+ fc = mockup(product_version: rand, file_version: x)
101
+ fc.version?(x).must_equal true
102
+ end
103
+ end
104
+
105
+ describe 'unix_mode_mask' do
106
+
107
+ let(:fc) { mockup(type: :file) }
108
+
109
+ it 'check owner mode calculation' do
110
+ fc.unix_mode_mask('owner', 'x').must_equal 0100
111
+ fc.unix_mode_mask('owner', 'w').must_equal 0200
112
+ fc.unix_mode_mask('owner', 'r').must_equal 0400
113
+ end
114
+
115
+ it 'check group mode calculation' do
116
+ fc.unix_mode_mask('group', 'x').must_equal 0010
117
+ fc.unix_mode_mask('group', 'w').must_equal 0020
118
+ fc.unix_mode_mask('group', 'r').must_equal 0040
119
+ end
120
+
121
+ it 'check other mode calculation' do
122
+ fc.unix_mode_mask('other', 'x').must_equal 0001
123
+ fc.unix_mode_mask('other', 'w').must_equal 0002
124
+ fc.unix_mode_mask('other', 'r').must_equal 0004
125
+ end
126
+
127
+ it 'check all mode calculation' do
128
+ fc.unix_mode_mask('all', 'x').must_equal 0111
129
+ fc.unix_mode_mask('all', 'w').must_equal 0222
130
+ fc.unix_mode_mask('all', 'r').must_equal 0444
131
+ end
132
+ end
133
+ end