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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -2
- data/lib/train.rb +1 -0
- data/lib/train/errors.rb +6 -0
- data/lib/train/extras.rb +0 -1
- data/lib/train/platforms.rb +82 -0
- data/lib/train/platforms/common.rb +34 -0
- data/lib/train/platforms/detect.rb +12 -0
- data/lib/train/platforms/detect/helpers/os_common.rb +56 -0
- data/lib/train/platforms/detect/helpers/os_linux.rb +75 -0
- data/lib/train/{extras/os_detect_windows.rb → platforms/detect/helpers/os_windows.rb} +3 -10
- data/lib/train/platforms/detect/scanner.rb +84 -0
- data/lib/train/platforms/detect/specifications/os.rb +480 -0
- data/lib/train/platforms/family.rb +26 -0
- data/lib/train/platforms/platform.rb +80 -0
- data/lib/train/plugins/base_connection.rb +75 -27
- data/lib/train/transports/docker.rb +17 -28
- data/lib/train/transports/local.rb +21 -22
- data/lib/train/transports/mock.rb +44 -30
- data/lib/train/transports/ssh_connection.rb +55 -67
- data/lib/train/transports/winrm_connection.rb +16 -26
- data/lib/train/version.rb +1 -1
- data/test/unit/file/remote/linux_test.rb +2 -2
- data/test/unit/platforms/detect/os_common_test.rb +85 -0
- data/test/unit/platforms/detect/os_linux_test.rb +124 -0
- data/test/unit/{extras/os_detect_windows_test.rb → platforms/detect/os_windows_test.rb} +5 -2
- data/test/unit/platforms/detect/scanner_test.rb +61 -0
- data/test/unit/platforms/family_test.rb +32 -0
- data/test/unit/platforms/os_detect_test.rb +175 -0
- data/test/unit/{extras/os_common_test.rb → platforms/platform_test.rb} +103 -18
- data/test/unit/platforms/platforms_test.rb +42 -0
- data/test/unit/plugins/connection_test.rb +106 -8
- data/test/unit/transports/local_test.rb +20 -15
- data/test/unit/transports/mock_test.rb +16 -6
- data/test/unit/transports/ssh_test.rb +17 -15
- metadata +28 -19
- data/lib/train/extras/linux_lsb.rb +0 -60
- data/lib/train/extras/os_common.rb +0 -151
- data/lib/train/extras/os_detect_arista_eos.rb +0 -34
- data/lib/train/extras/os_detect_darwin.rb +0 -40
- data/lib/train/extras/os_detect_esx.rb +0 -22
- data/lib/train/extras/os_detect_linux.rb +0 -164
- data/lib/train/extras/os_detect_openvms.rb +0 -29
- data/lib/train/extras/os_detect_unix.rb +0 -106
- data/lib/train/extras/uname.rb +0 -28
- data/lib/train/transports/local_os.rb +0 -51
- data/test/unit/extras/os_detect_linux_test.rb +0 -230
| @@ -55,67 +55,6 @@ class Train::Transports::SSH | |
| 55 55 | 
             
                  @session = nil
         | 
| 56 56 | 
             
                end
         | 
| 57 57 |  | 
| 58 | 
            -
                def os
         | 
| 59 | 
            -
                  @os ||= OS.new(self)
         | 
| 60 | 
            -
                end
         | 
| 61 | 
            -
             | 
| 62 | 
            -
                def file(path)
         | 
| 63 | 
            -
                  @files[path] ||= \
         | 
| 64 | 
            -
                    if os.aix?
         | 
| 65 | 
            -
                      Train::File::Remote::Aix.new(self, path)
         | 
| 66 | 
            -
                    elsif os.solaris?
         | 
| 67 | 
            -
                      Train::File::Remote::Unix.new(self, path)
         | 
| 68 | 
            -
                    elsif os[:name] == 'qnx'
         | 
| 69 | 
            -
                      Train::File::Remote::Qnx.new(self, path)
         | 
| 70 | 
            -
                    else
         | 
| 71 | 
            -
                      Train::File::Remote::Linux.new(self, path)
         | 
| 72 | 
            -
                    end
         | 
| 73 | 
            -
                end
         | 
| 74 | 
            -
             | 
| 75 | 
            -
                # (see Base::Connection#run_command)
         | 
| 76 | 
            -
                def run_command(cmd)
         | 
| 77 | 
            -
                  stdout = stderr = ''
         | 
| 78 | 
            -
                  exit_status = nil
         | 
| 79 | 
            -
                  cmd.dup.force_encoding('binary') if cmd.respond_to?(:force_encoding)
         | 
| 80 | 
            -
                  logger.debug("[SSH] #{self} (#{cmd})")
         | 
| 81 | 
            -
             | 
| 82 | 
            -
                  session.open_channel do |channel|
         | 
| 83 | 
            -
                    # wrap commands if that is configured
         | 
| 84 | 
            -
                    cmd = @cmd_wrapper.run(cmd) unless @cmd_wrapper.nil?
         | 
| 85 | 
            -
             | 
| 86 | 
            -
                    if @transport_options[:pty]
         | 
| 87 | 
            -
                      channel.request_pty do |_ch, success|
         | 
| 88 | 
            -
                        fail Train::Transports::SSHPTYFailed, 'Requesting PTY failed' unless success
         | 
| 89 | 
            -
                      end
         | 
| 90 | 
            -
                    end
         | 
| 91 | 
            -
             | 
| 92 | 
            -
                    channel.exec(cmd) do |_, success|
         | 
| 93 | 
            -
                      abort 'Couldn\'t execute command on SSH.' unless success
         | 
| 94 | 
            -
             | 
| 95 | 
            -
                      channel.on_data do |_, data|
         | 
| 96 | 
            -
                        stdout += data
         | 
| 97 | 
            -
                      end
         | 
| 98 | 
            -
             | 
| 99 | 
            -
                      channel.on_extended_data do |_, _type, data|
         | 
| 100 | 
            -
                        stderr += data
         | 
| 101 | 
            -
                      end
         | 
| 102 | 
            -
             | 
| 103 | 
            -
                      channel.on_request('exit-status') do |_, data|
         | 
| 104 | 
            -
                        exit_status = data.read_long
         | 
| 105 | 
            -
                      end
         | 
| 106 | 
            -
             | 
| 107 | 
            -
                      channel.on_request('exit-signal') do |_, data|
         | 
| 108 | 
            -
                        exit_status = data.read_long
         | 
| 109 | 
            -
                      end
         | 
| 110 | 
            -
                    end
         | 
| 111 | 
            -
                  end
         | 
| 112 | 
            -
                  @session.loop
         | 
| 113 | 
            -
             | 
| 114 | 
            -
                  CommandResult.new(stdout, stderr, exit_status)
         | 
| 115 | 
            -
                rescue Net::SSH::Exception => ex
         | 
| 116 | 
            -
                  raise Train::Transports::SSHFailed, "SSH command failed (#{ex.message})"
         | 
| 117 | 
            -
                end
         | 
| 118 | 
            -
             | 
| 119 58 | 
             
                # (see Base::Connection#login_command)
         | 
| 120 59 | 
             
                def login_command
         | 
| 121 60 | 
             
                  level = logger.debug? ? 'VERBOSE' : 'ERROR'
         | 
| @@ -225,6 +164,61 @@ class Train::Transports::SSH | |
| 225 164 | 
             
                  retry
         | 
| 226 165 | 
             
                end
         | 
| 227 166 |  | 
| 167 | 
            +
                def file_via_connection(path)
         | 
| 168 | 
            +
                  if os.aix?
         | 
| 169 | 
            +
                    Train::File::Remote::Aix.new(self, path)
         | 
| 170 | 
            +
                  elsif os.solaris?
         | 
| 171 | 
            +
                    Train::File::Remote::Unix.new(self, path)
         | 
| 172 | 
            +
                  elsif os[:name] == 'qnx'
         | 
| 173 | 
            +
                    Train::File::Remote::Qnx.new(self, path)
         | 
| 174 | 
            +
                  else
         | 
| 175 | 
            +
                    Train::File::Remote::Linux.new(self, path)
         | 
| 176 | 
            +
                  end
         | 
| 177 | 
            +
                end
         | 
| 178 | 
            +
             | 
| 179 | 
            +
                def run_command_via_connection(cmd)
         | 
| 180 | 
            +
                  stdout = stderr = ''
         | 
| 181 | 
            +
                  exit_status = nil
         | 
| 182 | 
            +
                  cmd.dup.force_encoding('binary') if cmd.respond_to?(:force_encoding)
         | 
| 183 | 
            +
                  logger.debug("[SSH] #{self} (#{cmd})")
         | 
| 184 | 
            +
             | 
| 185 | 
            +
                  session.open_channel do |channel|
         | 
| 186 | 
            +
                    # wrap commands if that is configured
         | 
| 187 | 
            +
                    cmd = @cmd_wrapper.run(cmd) unless @cmd_wrapper.nil?
         | 
| 188 | 
            +
             | 
| 189 | 
            +
                    if @transport_options[:pty]
         | 
| 190 | 
            +
                      channel.request_pty do |_ch, success|
         | 
| 191 | 
            +
                        fail Train::Transports::SSHPTYFailed, 'Requesting PTY failed' unless success
         | 
| 192 | 
            +
                      end
         | 
| 193 | 
            +
                    end
         | 
| 194 | 
            +
             | 
| 195 | 
            +
                    channel.exec(cmd) do |_, success|
         | 
| 196 | 
            +
                      abort 'Couldn\'t execute command on SSH.' unless success
         | 
| 197 | 
            +
             | 
| 198 | 
            +
                      channel.on_data do |_, data|
         | 
| 199 | 
            +
                        stdout += data
         | 
| 200 | 
            +
                      end
         | 
| 201 | 
            +
             | 
| 202 | 
            +
                      channel.on_extended_data do |_, _type, data|
         | 
| 203 | 
            +
                        stderr += data
         | 
| 204 | 
            +
                      end
         | 
| 205 | 
            +
             | 
| 206 | 
            +
                      channel.on_request('exit-status') do |_, data|
         | 
| 207 | 
            +
                        exit_status = data.read_long
         | 
| 208 | 
            +
                      end
         | 
| 209 | 
            +
             | 
| 210 | 
            +
                      channel.on_request('exit-signal') do |_, data|
         | 
| 211 | 
            +
                        exit_status = data.read_long
         | 
| 212 | 
            +
                      end
         | 
| 213 | 
            +
                    end
         | 
| 214 | 
            +
                  end
         | 
| 215 | 
            +
                  @session.loop
         | 
| 216 | 
            +
             | 
| 217 | 
            +
                  CommandResult.new(stdout, stderr, exit_status)
         | 
| 218 | 
            +
                rescue Net::SSH::Exception => ex
         | 
| 219 | 
            +
                  raise Train::Transports::SSHFailed, "SSH command failed (#{ex.message})"
         | 
| 220 | 
            +
                end
         | 
| 221 | 
            +
             | 
| 228 222 | 
             
                # Returns a connection session, or establishes one when invoked the
         | 
| 229 223 | 
             
                # first time.
         | 
| 230 224 | 
             
                #
         | 
| @@ -247,11 +241,5 @@ class Train::Transports::SSH | |
| 247 241 | 
             
                  options_to_print[:password] = '<hidden>' if options_to_print.key?(:password)
         | 
| 248 242 | 
             
                  "#{@username}@#{@hostname}<#{options_to_print.inspect}>"
         | 
| 249 243 | 
             
                end
         | 
| 250 | 
            -
             | 
| 251 | 
            -
                class OS < OSCommon
         | 
| 252 | 
            -
                  def initialize(backend)
         | 
| 253 | 
            -
                    super(backend)
         | 
| 254 | 
            -
                  end
         | 
| 255 | 
            -
                end
         | 
| 256 244 | 
             
              end
         | 
| 257 245 | 
             
            end
         | 
| @@ -46,26 +46,6 @@ class Train::Transports::WinRM | |
| 46 46 | 
             
                  @session = nil
         | 
| 47 47 | 
             
                end
         | 
| 48 48 |  | 
| 49 | 
            -
                def os
         | 
| 50 | 
            -
                  @os ||= OS.new(self)
         | 
| 51 | 
            -
                end
         | 
| 52 | 
            -
             | 
| 53 | 
            -
                def file(path)
         | 
| 54 | 
            -
                  @files[path] ||= Train::File::Remote::Windows.new(self, path)
         | 
| 55 | 
            -
                end
         | 
| 56 | 
            -
             | 
| 57 | 
            -
                def run_command(command)
         | 
| 58 | 
            -
                  return if command.nil?
         | 
| 59 | 
            -
                  logger.debug("[WinRM] #{self} (#{command})")
         | 
| 60 | 
            -
                  out = ''
         | 
| 61 | 
            -
             | 
| 62 | 
            -
                  response = session.run(command) do |stdout, _|
         | 
| 63 | 
            -
                    out << stdout if stdout
         | 
| 64 | 
            -
                  end
         | 
| 65 | 
            -
             | 
| 66 | 
            -
                  CommandResult.new(out, response.stderr, response.exitcode)
         | 
| 67 | 
            -
                end
         | 
| 68 | 
            -
             | 
| 69 49 | 
             
                # (see Base::Connection#login_command)
         | 
| 70 50 | 
             
                def login_command
         | 
| 71 51 | 
             
                  case RbConfig::CONFIG['host_os']
         | 
| @@ -111,6 +91,22 @@ class Train::Transports::WinRM | |
| 111 91 |  | 
| 112 92 | 
             
                PING_COMMAND = "Write-Host '[WinRM] Established\n'".freeze
         | 
| 113 93 |  | 
| 94 | 
            +
                def file_via_connection(path)
         | 
| 95 | 
            +
                  Train::File::Remote::Windows.new(self, path)
         | 
| 96 | 
            +
                end
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                def run_command_via_connection(command)
         | 
| 99 | 
            +
                  return if command.nil?
         | 
| 100 | 
            +
                  logger.debug("[WinRM] #{self} (#{command})")
         | 
| 101 | 
            +
                  out = ''
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                  response = session.run(command) do |stdout, _|
         | 
| 104 | 
            +
                    out << stdout if stdout
         | 
| 105 | 
            +
                  end
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                  CommandResult.new(out, response.stderr, response.exitcode)
         | 
| 108 | 
            +
                end
         | 
| 109 | 
            +
             | 
| 114 110 | 
             
                # Create a local RDP document and return it
         | 
| 115 111 | 
             
                #
         | 
| 116 112 | 
             
                # @param opts [Hash] configuration options
         | 
| @@ -193,11 +189,5 @@ class Train::Transports::WinRM | |
| 193 189 | 
             
                  options_to_print[:password] = '<hidden>' if options_to_print.key?(:password)
         | 
| 194 190 | 
             
                  "#{@username}@#{@hostname}<#{options_to_print.inspect}>"
         | 
| 195 191 | 
             
                end
         | 
| 196 | 
            -
             | 
| 197 | 
            -
                class OS < OSCommon
         | 
| 198 | 
            -
                  def initialize(backend)
         | 
| 199 | 
            -
                    super(backend, { family: 'windows' })
         | 
| 200 | 
            -
                  end
         | 
| 201 | 
            -
                end
         | 
| 202 192 | 
             
              end
         | 
| 203 193 | 
             
            end
         | 
    
        data/lib/train/version.rb
    CHANGED
    
    
| @@ -7,14 +7,14 @@ describe Train::File::Remote::Linux do | |
| 7 7 | 
             
              let(:cls) { Train::File::Remote::Linux }
         | 
| 8 8 | 
             
              let(:backend) {
         | 
| 9 9 | 
             
                backend = Train::Transports::Mock.new.connection
         | 
| 10 | 
            -
                backend.mock_os({  | 
| 10 | 
            +
                backend.mock_os({ name: 'linux', family: 'unix' })
         | 
| 11 11 | 
             
                backend
         | 
| 12 12 | 
             
              }  
         | 
| 13 13 |  | 
| 14 14 | 
             
              def mock_stat(args, out, err = '', code = 0)
         | 
| 15 15 | 
             
                backend.mock_command(
         | 
| 16 16 | 
             
                  "stat #{args} 2>/dev/null --printf '%s\n%f\n%U\n%u\n%G\n%g\n%X\n%Y\n%C'",
         | 
| 17 | 
            -
                  out, err, code | 
| 17 | 
            +
                  out, err, code
         | 
| 18 18 | 
             
                )
         | 
| 19 19 | 
             
              end
         | 
| 20 20 |  | 
| @@ -0,0 +1,85 @@ | |
| 1 | 
            +
            # encoding: utf-8
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'helper'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            class OsDetectLinuxTester
         | 
| 6 | 
            +
              attr_reader :platform
         | 
| 7 | 
            +
              include Train::Platforms::Detect::Helpers::OSCommon
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              def initialize
         | 
| 10 | 
            +
                @platform = {}
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
            end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            describe 'os_common' do
         | 
| 15 | 
            +
              let(:detector) { OsDetectLinuxTester.new }
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              describe 'winrm? check' do
         | 
| 18 | 
            +
                it 'return winrm? true' do
         | 
| 19 | 
            +
                  require 'train/transports/winrm'
         | 
| 20 | 
            +
                  be = Train::Transports::WinRM::Connection.new(nil)
         | 
| 21 | 
            +
                  detector.instance_variable_set(:@backend, be)
         | 
| 22 | 
            +
                  detector.winrm?.must_equal(true)
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                it 'return winrm? false' do
         | 
| 26 | 
            +
                  be = mock('Backend')
         | 
| 27 | 
            +
                  detector.instance_variable_set(:@backend, be)
         | 
| 28 | 
            +
                  detector.winrm?.must_equal(false)
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              describe 'unix file contents' do
         | 
| 33 | 
            +
                it 'return new file contents' do
         | 
| 34 | 
            +
                  be = mock('Backend')
         | 
| 35 | 
            +
                  output = mock('Output', exit_status: 0)
         | 
| 36 | 
            +
                  output.expects(:stdout).returns('test')
         | 
| 37 | 
            +
                  be.stubs(:run_command).with('test -f /etc/fstab && cat /etc/fstab').returns(output)
         | 
| 38 | 
            +
                  detector.instance_variable_set(:@backend, be)
         | 
| 39 | 
            +
                  detector.instance_variable_set(:@files, {})
         | 
| 40 | 
            +
                  detector.unix_file_contents('/etc/fstab').must_equal('test')
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                it 'return new file contents cached' do
         | 
| 44 | 
            +
                  be = mock('Backend')
         | 
| 45 | 
            +
                  detector.instance_variable_set(:@backend, be)
         | 
| 46 | 
            +
                  detector.instance_variable_set(:@files, { '/etc/profile' => 'test' })
         | 
| 47 | 
            +
                  detector.unix_file_contents('/etc/profile').must_equal('test')
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
              end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
              describe 'unix file exist?' do
         | 
| 52 | 
            +
                it 'file does exist' do
         | 
| 53 | 
            +
                  be = mock('Backend')
         | 
| 54 | 
            +
                  be.stubs(:run_command).with('test -f /etc/test').returns(mock('Output', exit_status: 0))
         | 
| 55 | 
            +
                  detector.instance_variable_set(:@backend, be)
         | 
| 56 | 
            +
                  detector.unix_file_exist?('/etc/test').must_equal(true)
         | 
| 57 | 
            +
                end
         | 
| 58 | 
            +
              end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
              describe '#detect_linux_arch' do
         | 
| 61 | 
            +
                it 'uname m call' do
         | 
| 62 | 
            +
                  be = mock('Backend')
         | 
| 63 | 
            +
                  be.stubs(:run_command).with('uname -m').returns(mock('Output', stdout: "x86_64\n"))
         | 
| 64 | 
            +
                  detector.instance_variable_set(:@backend, be)
         | 
| 65 | 
            +
                  detector.instance_variable_set(:@uname, {})
         | 
| 66 | 
            +
                  detector.unix_uname_m.must_equal('x86_64')
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                it 'uname s call' do
         | 
| 70 | 
            +
                  be = mock('Backend')
         | 
| 71 | 
            +
                  be.stubs(:run_command).with('uname -s').returns(mock('Output', stdout: "linux"))
         | 
| 72 | 
            +
                  detector.instance_variable_set(:@backend, be)
         | 
| 73 | 
            +
                  detector.instance_variable_set(:@uname, {})
         | 
| 74 | 
            +
                  detector.unix_uname_s.must_equal('linux')
         | 
| 75 | 
            +
                end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                it 'uname r call' do
         | 
| 78 | 
            +
                  be = mock('Backend')
         | 
| 79 | 
            +
                  be.stubs(:run_command).with('uname -r').returns(mock('Output', stdout: "17.0.0\n"))
         | 
| 80 | 
            +
                  detector.instance_variable_set(:@backend, be)
         | 
| 81 | 
            +
                  detector.instance_variable_set(:@uname, {})
         | 
| 82 | 
            +
                  detector.unix_uname_r.must_equal('17.0.0')
         | 
| 83 | 
            +
                end
         | 
| 84 | 
            +
              end
         | 
| 85 | 
            +
            end
         | 
| @@ -0,0 +1,124 @@ | |
| 1 | 
            +
            # encoding: utf-8
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'helper'
         | 
| 4 | 
            +
            require 'train/transports/mock'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            class OsDetectLinuxTester
         | 
| 7 | 
            +
              include Train::Platforms::Detect::Helpers::OSCommon
         | 
| 8 | 
            +
            end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            describe 'os_linux' do
         | 
| 11 | 
            +
              let(:detector) { OsDetectLinuxTester.new }
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              describe 'redhatish_platform cleaner' do
         | 
| 14 | 
            +
                it 'normal redhat' do
         | 
| 15 | 
            +
                  detector.redhatish_platform('Red Hattter').must_equal('redhat')
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                it 'custom redhat' do
         | 
| 19 | 
            +
                  detector.redhatish_platform('Centos Pro 11').must_equal('centos')
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              describe 'redhatish_version cleaner' do
         | 
| 24 | 
            +
                it 'normal rawhide' do
         | 
| 25 | 
            +
                  detector.redhatish_version('18 (Rawhide) Pro').must_equal('18 (rawhide)')
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                it 'normal linux' do
         | 
| 29 | 
            +
                  detector.redhatish_version('derived from Ubuntu Linux 11').must_equal('11')
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
              describe 'lsb parse' do
         | 
| 34 | 
            +
                it 'lsb config' do
         | 
| 35 | 
            +
                  lsb = "DISTRIB_ID=Ubuntu\nDISTRIB_RELEASE=14.06\nDISTRIB_CODENAME=xenial"
         | 
| 36 | 
            +
                  expect = { :id=>'Ubuntu', :release=>'14.06', :codename=>'xenial' }
         | 
| 37 | 
            +
                  detector.lsb_config(lsb).must_equal(expect)
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                it 'lsb releasel' do
         | 
| 41 | 
            +
                  lsb = "Distributor ID: Ubuntu\nRelease: 14.06\nCodename: xenial"
         | 
| 42 | 
            +
                  expect = { :id=>'Ubuntu', :release=>'14.06', :codename=>'xenial' }
         | 
| 43 | 
            +
                  detector.lsb_release(lsb).must_equal(expect)
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
              end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
              describe '#linux_os_release' do
         | 
| 48 | 
            +
                describe 'when no os-release data is available' do
         | 
| 49 | 
            +
                  it 'returns nil' do
         | 
| 50 | 
            +
                    detector.expects(:unix_file_contents).with('/etc/os-release').returns(nil)
         | 
| 51 | 
            +
                    detector.linux_os_release.must_be_nil
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
              end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
              describe 'when os-release data exists with no CISCO_RELEASE_INFO' do
         | 
| 57 | 
            +
                let(:os_release) { { 'KEY1' => 'VALUE1' } }
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                it 'returns a correct hash' do
         | 
| 60 | 
            +
                  detector.expects(:unix_file_contents).with('/etc/os-release').returns('os-release data')
         | 
| 61 | 
            +
                  detector.expects(:parse_os_release_info).with('os-release data').returns(os_release)
         | 
| 62 | 
            +
                  detector.linux_os_release['KEY1'].must_equal('VALUE1')
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
              end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
              describe 'when os-release data exists with CISCO_RELEASE_INFO' do
         | 
| 67 | 
            +
                let(:os_release)    { { 'KEY1' => 'VALUE1', 'CISCO_RELEASE_INFO' => 'cisco_file' } }
         | 
| 68 | 
            +
                let(:cisco_release) { { 'KEY1' => 'NEWVALUE1', 'KEY2' => 'VALUE2' } }
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                it 'returns a correct hash' do
         | 
| 71 | 
            +
                  detector.expects(:unix_file_contents).with('/etc/os-release').returns('os-release data')
         | 
| 72 | 
            +
                  detector.expects(:unix_file_contents).with('cisco_file').returns('cisco data')
         | 
| 73 | 
            +
                  detector.expects(:parse_os_release_info).with('os-release data').returns(os_release)
         | 
| 74 | 
            +
                  detector.expects(:parse_os_release_info).with('cisco data').returns(cisco_release)
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                  os_info = detector.linux_os_release
         | 
| 77 | 
            +
                  os_info['KEY1'].must_equal('NEWVALUE1')
         | 
| 78 | 
            +
                  os_info['KEY2'].must_equal('VALUE2')
         | 
| 79 | 
            +
                end
         | 
| 80 | 
            +
              end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
              describe '#parse_os_release_info' do
         | 
| 83 | 
            +
                describe 'when nil is supplied' do
         | 
| 84 | 
            +
                  it 'returns an empty hash' do
         | 
| 85 | 
            +
                    detector.parse_os_release_info(nil).must_equal({})
         | 
| 86 | 
            +
                  end
         | 
| 87 | 
            +
                end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                describe 'when unexpectedly-formatted data is supplied' do
         | 
| 90 | 
            +
                  let(:data) do
         | 
| 91 | 
            +
                    <<-EOL
         | 
| 92 | 
            +
            blah blah
         | 
| 93 | 
            +
            no good data here
         | 
| 94 | 
            +
                    EOL
         | 
| 95 | 
            +
                  end
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                  it 'returns an empty hash' do
         | 
| 98 | 
            +
                    detector.parse_os_release_info(nil).must_equal({})
         | 
| 99 | 
            +
                  end
         | 
| 100 | 
            +
                end
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                describe 'when properly-formatted data is supplied' do
         | 
| 103 | 
            +
                  let(:data) do
         | 
| 104 | 
            +
                    <<-EOL
         | 
| 105 | 
            +
            KEY1=value1
         | 
| 106 | 
            +
            KEY2=
         | 
| 107 | 
            +
            KEY3=value3
         | 
| 108 | 
            +
            KEY4="value4 with spaces"
         | 
| 109 | 
            +
            KEY5="value5 with a = sign"
         | 
| 110 | 
            +
                    EOL
         | 
| 111 | 
            +
                  end
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                  it 'parses the data correctly' do
         | 
| 114 | 
            +
                    parsed_data = detector.parse_os_release_info(data)
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                    parsed_data['KEY1'].must_equal('value1')
         | 
| 117 | 
            +
                    parsed_data.key?('KEY2').must_equal(false)
         | 
| 118 | 
            +
                    parsed_data['KEY3'].must_equal('value3')
         | 
| 119 | 
            +
                    parsed_data['KEY4'].must_equal('value4 with spaces')
         | 
| 120 | 
            +
                    parsed_data['KEY5'].must_equal('value5 with a = sign')
         | 
| 121 | 
            +
                  end
         | 
| 122 | 
            +
                end
         | 
| 123 | 
            +
              end
         | 
| 124 | 
            +
            end
         | 
| @@ -1,8 +1,11 @@ | |
| 1 | 
            -
             | 
| 1 | 
            +
            # encoding: utf-8
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'helper'
         | 
| 4 | 
            +
            require 'train/transports/mock'
         | 
| 2 5 |  | 
| 3 6 | 
             
            class OsDetectWindowsTester
         | 
| 4 7 | 
             
              attr_reader :platform, :backend
         | 
| 5 | 
            -
              include Train:: | 
| 8 | 
            +
              include Train::Platforms::Detect::Helpers::Windows
         | 
| 6 9 |  | 
| 7 10 | 
             
              def initialize
         | 
| 8 11 | 
             
                @platform = {}
         |