train 0.29.2 → 0.30.0

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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -2
  3. data/lib/train.rb +1 -0
  4. data/lib/train/errors.rb +6 -0
  5. data/lib/train/extras.rb +0 -1
  6. data/lib/train/platforms.rb +82 -0
  7. data/lib/train/platforms/common.rb +34 -0
  8. data/lib/train/platforms/detect.rb +12 -0
  9. data/lib/train/platforms/detect/helpers/os_common.rb +56 -0
  10. data/lib/train/platforms/detect/helpers/os_linux.rb +75 -0
  11. data/lib/train/{extras/os_detect_windows.rb → platforms/detect/helpers/os_windows.rb} +3 -10
  12. data/lib/train/platforms/detect/scanner.rb +84 -0
  13. data/lib/train/platforms/detect/specifications/os.rb +480 -0
  14. data/lib/train/platforms/family.rb +26 -0
  15. data/lib/train/platforms/platform.rb +80 -0
  16. data/lib/train/plugins/base_connection.rb +75 -27
  17. data/lib/train/transports/docker.rb +17 -28
  18. data/lib/train/transports/local.rb +21 -22
  19. data/lib/train/transports/mock.rb +44 -30
  20. data/lib/train/transports/ssh_connection.rb +55 -67
  21. data/lib/train/transports/winrm_connection.rb +16 -26
  22. data/lib/train/version.rb +1 -1
  23. data/test/unit/file/remote/linux_test.rb +2 -2
  24. data/test/unit/platforms/detect/os_common_test.rb +85 -0
  25. data/test/unit/platforms/detect/os_linux_test.rb +124 -0
  26. data/test/unit/{extras/os_detect_windows_test.rb → platforms/detect/os_windows_test.rb} +5 -2
  27. data/test/unit/platforms/detect/scanner_test.rb +61 -0
  28. data/test/unit/platforms/family_test.rb +32 -0
  29. data/test/unit/platforms/os_detect_test.rb +175 -0
  30. data/test/unit/{extras/os_common_test.rb → platforms/platform_test.rb} +103 -18
  31. data/test/unit/platforms/platforms_test.rb +42 -0
  32. data/test/unit/plugins/connection_test.rb +106 -8
  33. data/test/unit/transports/local_test.rb +20 -15
  34. data/test/unit/transports/mock_test.rb +16 -6
  35. data/test/unit/transports/ssh_test.rb +17 -15
  36. metadata +28 -19
  37. data/lib/train/extras/linux_lsb.rb +0 -60
  38. data/lib/train/extras/os_common.rb +0 -151
  39. data/lib/train/extras/os_detect_arista_eos.rb +0 -34
  40. data/lib/train/extras/os_detect_darwin.rb +0 -40
  41. data/lib/train/extras/os_detect_esx.rb +0 -22
  42. data/lib/train/extras/os_detect_linux.rb +0 -164
  43. data/lib/train/extras/os_detect_openvms.rb +0 -29
  44. data/lib/train/extras/os_detect_unix.rb +0 -106
  45. data/lib/train/extras/uname.rb +0 -28
  46. data/lib/train/transports/local_os.rb +0 -51
  47. data/test/unit/extras/os_detect_linux_test.rb +0 -230
@@ -0,0 +1,61 @@
1
+ # encoding: utf-8
2
+
3
+ require 'helper'
4
+ require 'train/platforms/detect/scanner'
5
+ require 'train/transports/mock'
6
+
7
+ describe 'scanner' do
8
+ let(:backend) { Train::Transports::Mock::Connection.new }
9
+ let(:scanner) { Train::Platforms::Detect::Scanner.new(backend) }
10
+
11
+ describe 'scan family children' do
12
+ it 'return child' do
13
+ family = Train::Platforms.family('linux')
14
+ scanner.scan_family_children(family).name.must_equal('linux')
15
+ scanner.instance_variable_get(:@family_hierarchy).must_equal(['linux'])
16
+ end
17
+
18
+ it 'return nil' do
19
+ family = Train::Platforms.family('fake-fam')
20
+ scanner.scan_family_children(family).must_be_nil
21
+ scanner.instance_variable_get(:@family_hierarchy).must_be_empty
22
+ end
23
+ end
24
+
25
+ describe 'check condition' do
26
+ it 'return true equal' do
27
+ scanner.instance_variable_set(:@platform, { arch: 'x86_64' })
28
+ scanner.check_condition({ arch: '= x86_64' }).must_equal(true)
29
+ end
30
+
31
+ it 'return true greater then' do
32
+ scanner.instance_variable_set(:@platform, { release: '8.2' })
33
+ scanner.check_condition({ release: '>= 7' }).must_equal(true)
34
+ end
35
+
36
+ it 'return false greater then' do
37
+ scanner.instance_variable_set(:@platform, { release: '2.2' })
38
+ scanner.check_condition({ release: '> 7' }).must_equal(false)
39
+ end
40
+ end
41
+
42
+ describe 'get platform' do
43
+ it 'return empty platform' do
44
+ plat = Train::Platforms.name('linux')
45
+ plat = scanner.get_platform(plat)
46
+ plat.platform.must_equal({})
47
+ plat.backend.must_equal(backend)
48
+ plat.family_hierarchy.must_equal([])
49
+ end
50
+
51
+ it 'return full platform' do
52
+ scanner.instance_variable_set(:@platform, { family: 'linux' })
53
+ scanner.instance_variable_set(:@family_hierarchy, [ 'linux', 'unix' ])
54
+ plat = Train::Platforms.name('linux')
55
+ plat = scanner.get_platform(plat)
56
+ plat.platform.must_equal({ family: 'linux' })
57
+ plat.backend.must_equal(backend)
58
+ plat.family_hierarchy.must_equal([ 'linux', 'unix' ])
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+
3
+ require 'helper'
4
+
5
+ describe 'platform family' do
6
+ def mock_family(x)
7
+ Train::Platforms.families[x] = nil if x == 'mock'
8
+ Train::Platforms.family(x)
9
+ end
10
+
11
+ it 'set family title' do
12
+ plat = mock_family('mock')
13
+ plat.title.must_equal('Mock Family')
14
+ plat.title('The Best Mock Family')
15
+ plat.title.must_equal('The Best Mock Family')
16
+ end
17
+
18
+ it 'set family in a family' do
19
+ plat = mock_family('family1')
20
+ plat.in_family('family2')
21
+ plat.families.keys[0].name.must_equal('family2')
22
+
23
+ plat = mock_family('family2')
24
+ plat.children.keys[0].name.must_equal('family1')
25
+ end
26
+
27
+ it 'set family in a family with condition' do
28
+ plat = Train::Platforms.family('family4', arch: '= x68_64').in_family('family5')
29
+ plat.families.keys[0].name.must_equal('family5')
30
+ plat.families.values[0].must_equal({ arch: '= x68_64' })
31
+ end
32
+ end
@@ -0,0 +1,175 @@
1
+ # encoding: utf-8
2
+ require 'helper'
3
+ require 'train/transports/mock'
4
+
5
+ class OsDetectLinuxTester
6
+ include Train::Platforms::Detect::Helpers::OSCommon
7
+ end
8
+
9
+ describe 'os_detect' do
10
+ let(:detector) { OsDetectLinuxTester.new }
11
+
12
+ def scan_with_files(uname, files)
13
+ mock = Train::Transports::Mock::Connection.new
14
+ mock.mock_command('uname -s', uname)
15
+ mock.mock_command('uname -r', 'test-release')
16
+ files.each do |path, data|
17
+ mock.mock_command("test -f #{path}")
18
+ mock.mock_command("test -f #{path} && cat #{path}", data)
19
+ end
20
+ Train::Platforms::Detect.scan(mock)
21
+ end
22
+
23
+ ## Detect all linux distros
24
+ describe '/etc/enterprise-release' do
25
+ it 'sets the correct family/release for oracle' do
26
+ path = '/etc/enterprise-release'
27
+ platform = scan_with_files('linux', { path => 'release 7' })
28
+
29
+ platform[:name].must_equal('oracle')
30
+ platform[:family].must_equal('redhat')
31
+ platform[:release].must_equal('7')
32
+ end
33
+ end
34
+
35
+ describe '/etc/redhat-release' do
36
+ describe 'and /etc/os-release' do
37
+ it 'sets the correct family, name, and release on centos' do
38
+ files = {
39
+ '/etc/redhat-release' => "CentOS Linux release 7.2.1511 (Core) \n",
40
+ '/etc/os-release' => "NAME=\"CentOS Linux\"\nVERSION=\"7 (Core)\"\nID=\"centos\"\nID_LIKE=\"rhel fedora\"\n",
41
+ }
42
+ platform = scan_with_files('linux', files)
43
+ platform[:name].must_equal('centos')
44
+ platform[:family].must_equal('redhat')
45
+ platform[:release].must_equal('7.2.1511')
46
+ end
47
+ end
48
+ end
49
+
50
+ describe 'darwin' do
51
+ describe 'mac_os_x' do
52
+ it 'sets the correct family, name, and release on os_x' do
53
+ files = {
54
+ '/System/Library/CoreServices/SystemVersion.plist' => '<string>Mac OS X</string>',
55
+ }
56
+ platform = scan_with_files('darwin', files)
57
+ platform[:name].must_equal('mac_os_x')
58
+ platform[:family].must_equal('darwin')
59
+ platform[:release].must_equal('test-release')
60
+ end
61
+ end
62
+
63
+ describe 'generic darwin' do
64
+ it 'sets the correct family, name, and release on darwin' do
65
+ files = {
66
+ '/usr/bin/sw_vers' => "ProductVersion: 17.0.1\nBuildVersion: alpha.x1",
67
+ }
68
+ platform = scan_with_files('darwin', files)
69
+ platform[:name].must_equal('darwin')
70
+ platform[:family].must_equal('darwin')
71
+ platform[:release].must_equal('17.0.1')
72
+ platform[:build].must_equal('alpha.x1')
73
+ end
74
+ end
75
+ end
76
+
77
+ describe '/etc/debian_version' do
78
+ def debian_scan(id, version)
79
+ lsb_release = "DISTRIB_ID=#{id}\nDISTRIB_RELEASE=#{version}"
80
+ files = {
81
+ '/etc/lsb-release' => lsb_release,
82
+ '/etc/debian_version' => 'data',
83
+ }
84
+ scan_with_files('linux', files)
85
+ end
86
+
87
+ describe 'ubuntu' do
88
+ it 'sets the correct family/release for ubuntu' do
89
+ platform = debian_scan('ubuntu', '16.04')
90
+
91
+ platform[:name].must_equal('ubuntu')
92
+ platform[:family].must_equal('debian')
93
+ platform[:release].must_equal('16.04')
94
+ end
95
+ end
96
+
97
+ describe 'linuxmint' do
98
+ it 'sets the correct family/release for linuxmint' do
99
+ platform = debian_scan('linuxmint', '12')
100
+
101
+ platform[:name].must_equal('linuxmint')
102
+ platform[:family].must_equal('debian')
103
+ platform[:release].must_equal('12')
104
+ end
105
+ end
106
+
107
+ describe 'raspbian' do
108
+ it 'sets the correct family/release for raspbian ' do
109
+ files = {
110
+ '/usr/bin/raspi-config' => 'data',
111
+ '/etc/debian_version' => '13.6',
112
+ }
113
+ platform = scan_with_files('linux', files)
114
+
115
+ platform[:name].must_equal('raspbian')
116
+ platform[:family].must_equal('debian')
117
+ platform[:release].must_equal('13.6')
118
+ end
119
+ end
120
+
121
+ describe 'everything else' do
122
+ it 'sets the correct family/release for debian ' do
123
+ platform = debian_scan('some_debian', '12.99')
124
+
125
+ platform[:name].must_equal('debian')
126
+ platform[:family].must_equal('debian')
127
+ platform[:release].must_equal('12.99')
128
+ end
129
+ end
130
+ end
131
+
132
+ describe '/etc/coreos/update.conf' do
133
+ it 'sets the correct family/release for coreos' do
134
+ lsb_release = "DISTRIB_ID=Container Linux by CoreOS\nDISTRIB_RELEASE=27.9"
135
+ files = {
136
+ '/etc/lsb-release' => lsb_release,
137
+ '/etc/coreos/update.conf' => 'data',
138
+ }
139
+ platform = scan_with_files('linux', files)
140
+
141
+ platform[:name].must_equal('coreos')
142
+ platform[:family].must_equal('linux')
143
+ platform[:release].must_equal('27.9')
144
+ end
145
+ end
146
+
147
+ describe '/etc/os-release' do
148
+ describe 'when not on a wrlinux build' do
149
+ it 'fail back to genaric linux' do
150
+ os_release = "ID_LIKE=cisco-unkwown\nVERSION=unknown"
151
+ files = {
152
+ '/etc/os-release' => os_release,
153
+ }
154
+ platform = scan_with_files('linux', files)
155
+
156
+ platform[:name].must_equal('linux')
157
+ platform[:family].must_equal('linux')
158
+ end
159
+ end
160
+
161
+ describe 'when on a wrlinux build' do
162
+ it 'sets the correct family/release for wrlinux' do
163
+ os_release = "ID_LIKE=cisco-wrlinux\nVERSION=cisco123"
164
+ files = {
165
+ '/etc/os-release' => os_release,
166
+ }
167
+ platform = scan_with_files('linux', files)
168
+
169
+ platform[:name].must_equal('wrlinux')
170
+ platform[:family].must_equal('redhat')
171
+ platform[:release].must_equal('cisco123')
172
+ end
173
+ end
174
+ end
175
+ end
@@ -1,30 +1,102 @@
1
1
  # encoding: utf-8
2
- # author: Dominik Richter
3
- # author: Christoph Hartmann
4
2
 
5
3
  require 'helper'
6
- require 'train/extras'
7
4
 
8
- describe 'os common plugin' do
9
- let(:cls) {
10
- Class.new(Train::Extras::OSCommon) do
11
- def detect_family; end
5
+ describe 'platform' do
6
+ def mock_platform(x)
7
+ plat = Train::Platforms.name(x)
8
+ plat.family_hierarchy = mock_os_hierarchy(plat).flatten
9
+ plat.platform[:family] = plat.family_hierarchy[0]
10
+ plat.add_platform_methods
11
+ plat
12
+ end
13
+
14
+ def mock_platform_family(x)
15
+ Train::Platforms.list[x] = nil if x == 'mock'
16
+ plat = Train::Platforms.name(x).in_family(x)
17
+ plat.family_hierarchy = mock_os_hierarchy(plat).flatten
18
+ plat.platform[:family] = plat.family_hierarchy[0]
19
+ plat.add_platform_methods
20
+ plat
21
+ end
22
+
23
+ def mock_os_hierarchy(plat)
24
+ plat.families.each_with_object([]) do |(k, _v), memo|
25
+ memo << k.name
26
+ memo << mock_os_hierarchy(k) unless k.families.empty?
12
27
  end
13
- }
28
+ end
14
29
 
15
- def mock_platform(x)
16
- cls.new(nil, { family: x })
30
+ it 'set platform title' do
31
+ plat = mock_platform_family('mock')
32
+ plat.title.must_equal('Mock')
33
+ plat.title('The Best Mock')
34
+ plat.title.must_equal('The Best Mock')
35
+ end
36
+
37
+ it 'set name and name override' do
38
+ plat = mock_platform_family('mock')
39
+ plat.name.must_equal('mock')
40
+ plat[:name].must_equal('mock')
41
+ plat.platform[:name] = 'mock2020'
42
+ plat.name.must_equal('mock2020')
43
+ plat[:name].must_equal('mock2020')
44
+ end
45
+
46
+ it 'check families' do
47
+ plat = mock_platform_family('mock')
48
+ plat.families.keys[0].name.must_equal('mock')
49
+ end
50
+
51
+ it 'check families with condition' do
52
+ Train::Platforms.list['mock'] = nil
53
+ plat = Train::Platforms.name('mock', arch: '= x86_64').in_family('linux')
54
+ plat.families.keys[0].name.must_equal('linux')
55
+ plat.families.values[0].must_equal({ arch: '= x86_64' })
56
+ end
57
+
58
+ it 'return direct families' do
59
+ plat = mock_platform_family('mock')
60
+ plat.in_family('mock2')
61
+ plat.in_family('mock3')
62
+ plat.direct_families.must_equal(["mock", "mock2", "mock3"])
63
+ end
64
+
65
+ it 'return to_hash' do
66
+ plat = mock_platform_family('mock')
67
+ plat.to_hash.must_equal({ family: "mock" })
68
+ end
69
+
70
+ it 'return unknown release' do
71
+ plat = mock_platform_family('mock')
72
+ plat[:release].must_equal('unknown')
73
+ end
74
+
75
+ it 'return name?' do
76
+ plat = Train::Platforms.name('windows_rc1')
77
+ defined?(plat.windows_rc1?).must_be_nil
78
+ plat.add_platform_methods
79
+ plat.windows_rc1?.must_equal(true)
80
+ end
81
+
82
+ it 'add platform methods' do
83
+ Train::Platforms.list['mock'] = nil
84
+ plat = Train::Platforms.name('mock').in_family('linux')
85
+ defined?(plat.linux?).must_be_nil
86
+ plat.family_hierarchy = mock_os_hierarchy(plat).flatten
87
+ plat.add_platform_methods
88
+ plat.linux?.must_equal(true)
17
89
  end
18
90
 
19
91
  it 'provides a method to access platform data' do
20
- family = rand
21
- os = mock_platform(family)
92
+ family = 'test-os'
93
+ os = mock_platform_family(family)
22
94
  os[:family].must_equal family
23
95
  end
24
96
 
25
97
  it 'provides an accessor for the full hash' do
26
- x = rand.to_s
27
- os = mock_platform(x)
98
+ x = 'test-os'
99
+ os = mock_platform_family(x)
28
100
  os.to_hash.must_equal({ family: x })
29
101
  end
30
102
 
@@ -68,7 +140,7 @@ describe 'os common plugin' do
68
140
  describe 'with platform set to amazon' do
69
141
  let(:os) { mock_platform('amazon') }
70
142
  it { os.fedora?.must_equal(false) }
71
- it { os.redhat?.must_equal(false) }
143
+ it { os.redhat?.must_equal(true) }
72
144
  it { os.debian?.must_equal(false) }
73
145
  it { os.suse?.must_equal(false) }
74
146
  it { os.linux?.must_equal(true) }
@@ -278,10 +350,10 @@ describe 'os common plugin' do
278
350
  end
279
351
 
280
352
  describe 'with platform set to esx' do
281
- let(:os) { mock_platform('esx') }
353
+ let(:os) { mock_platform('vmkernel') }
282
354
  it { os.solaris?.must_equal(false) }
283
355
  it { os.linux?.must_equal(false) }
284
- it {os[:family].must_equal('esx')}
356
+ it { os[:family].must_equal('esx') }
285
357
  it { os.unix?.must_equal(false) }
286
358
  it { os.esx?.must_equal(true) }
287
359
  end
@@ -290,10 +362,23 @@ describe 'os common plugin' do
290
362
  let(:os) { mock_platform('darwin') }
291
363
  it { os.solaris?.must_equal(false) }
292
364
  it { os.linux?.must_equal(false) }
293
- it {os[:family].must_equal('darwin')}
365
+ it { os[:family].must_equal('darwin') }
366
+ it { os.bsd?.must_equal(true) }
367
+ it { os.darwin?.must_equal(true) }
294
368
  it { os.unix?.must_equal(true) }
295
369
  it { os.bsd?.must_equal(true) }
296
370
  it { os.esx?.must_equal(false) }
297
371
  end
298
372
 
373
+ describe 'with platform set to mac_os_x' do
374
+ let(:os) { mock_platform('mac_os_x') }
375
+ it { os.solaris?.must_equal(false) }
376
+ it { os.linux?.must_equal(false) }
377
+ it { os[:family].must_equal('darwin') }
378
+ it { os.bsd?.must_equal(true) }
379
+ it { os.darwin?.must_equal(true) }
380
+ it { os.unix?.must_equal(true) }
381
+ it { os.bsd?.must_equal(true) }
382
+ it { os.esx?.must_equal(false) }
383
+ end
299
384
  end
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+
3
+ require 'helper'
4
+
5
+ describe 'platforms' do
6
+
7
+ it 'create platform' do
8
+ Train::Platforms.list['mock'] = nil
9
+ plat = Train::Platforms.name('mock')
10
+ Train::Platforms.name('mock').in_family('test')
11
+ Train::Platforms.name('mock').detect { true }
12
+ plat.title.must_equal('Mock')
13
+ plat.detect.call.must_equal(true)
14
+ plat.families.keys[0].name.must_equal('test')
15
+ end
16
+
17
+ it 'create family' do
18
+ Train::Platforms.families['mock'] = nil
19
+ fam = Train::Platforms.family('mock')
20
+ Train::Platforms.family('mock').in_family('test')
21
+ Train::Platforms.family('mock').detect { true }
22
+ fam.title.must_equal('Mock Family')
23
+ fam.detect.call.must_equal(true)
24
+ fam.families.keys[0].name.must_equal('test')
25
+ end
26
+
27
+ it 'return top platforms empty' do
28
+ Train::Platforms.stubs(:list).returns({})
29
+ Train::Platforms.stubs(:families).returns({})
30
+ top = Train::Platforms.top_platforms
31
+ top.count.must_equal(0)
32
+ end
33
+
34
+ it 'return top platforms with data' do
35
+ plat = Train::Platforms.name('linux')
36
+ plat.stubs(:families).returns({})
37
+ Train::Platforms.stubs(:list).returns({ 'linux' => plat })
38
+ Train::Platforms.stubs(:families).returns({})
39
+ top = Train::Platforms.top_platforms
40
+ top.count.must_equal(1)
41
+ end
42
+ end