Skip to content

Commit

Permalink
Merge pull request #146 from chef/chris-rock/alpine-stat
Browse files Browse the repository at this point in the history
use stat -c for alpine linux
  • Loading branch information
stevendanna authored Sep 5, 2016
2 parents 560b159 + 0fe0868 commit d3b03b9
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 32 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,12 @@ We perform `unit`, `integration` and `windows` tests.
* `integration` tests run against VMs and docker containers
* `windows` tests that run on appveyor for windows integration tests

## Mac/Linux

```
bundle exec ruby -W -Ilib:test/unit test/unit/extras/stat_test.rb
```

## Windows

```
Expand Down
3 changes: 1 addition & 2 deletions lib/train/extras/stat.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,8 @@ def self.stat(shell_escaped_path, backend, follow_symlink)

def self.linux_stat(shell_escaped_path, backend, follow_symlink)
lstat = follow_symlink ? ' -L' : ''
format = backend.os.esx? ? '-c' : '--printf'
format = (backend.os.esx? || backend.os[:name] == 'alpine') ? '-c' : '--printf'
res = backend.run_command("stat#{lstat} #{shell_escaped_path} 2>/dev/null #{format} '%s\n%f\n%U\n%u\n%G\n%g\n%X\n%Y\n%C'")

# ignore the exit_code: it is != 0 if selinux labels are not supported
# on the system.

Expand Down
81 changes: 51 additions & 30 deletions test/unit/extras/stat_test.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# encoding: utf-8
require 'helper'
require 'train/extras'
require 'train/transports/mock'

describe 'stat' do
let(:cls) { Train::Extras::Stat }
Expand Down Expand Up @@ -42,27 +43,22 @@
end

describe 'linux stat' do
let(:backend) { Minitest::Mock.new }
let(:backend) {
mock = Train::Transports::Mock.new(verbose: true).connection
mock.mock_os({ name: 'ubuntu', family: 'debian', release: '15.04', arch: 'x86_64' })
mock.commands = {
"stat /path 2>/dev/null --printf '%s\n%f\n%U\n%u\n%G\n%g\n%X\n%Y\n%C'" => mock.mock_command('', '', '', 0),
"stat /path-stat 2>/dev/null --printf '%s\n%f\n%U\n%u\n%G\n%g\n%X\n%Y\n%C'" => mock.mock_command('', "360\n43ff\nroot\n0\nrootz\n1\n1444520846\n1444522445\n?", '', 0),
}
mock
}

it 'ignores wrong stat results' do
res = Minitest::Mock.new
os = Minitest::Mock.new
res.expect :stdout, ''
os.expect :esx?, false
backend.expect :os, os
backend.expect :run_command, res, [String]
cls.linux_stat('/path', backend, false).must_equal({})
end

it 'reads correct stat results' do
res = Minitest::Mock.new
os = Minitest::Mock.new
# 43ff is 41777; linux_stat strips the 4
res.expect :stdout, "360\n43ff\nroot\n0\nrootz\n1\n1444520846\n1444522445\n?"
os.expect :esx?, false
backend.expect :os, os
backend.expect :run_command, res, [String]
cls.linux_stat('/path', backend, false).must_equal({
cls.linux_stat('/path-stat', backend, false).must_equal({
type: :directory,
mode: 01777,
owner: 'root',
Expand All @@ -77,27 +73,52 @@
end

describe 'esx stat' do
let(:backend) { Minitest::Mock.new }
let(:backend) {
mock = Train::Transports::Mock.new(verbose: true).connection
mock.mock_os({ name: 'vmkernel', family: 'esx', release: '5' })
mock.commands = {
"stat /path 2>/dev/null -c '%s\n%f\n%U\n%u\n%G\n%g\n%X\n%Y\n%C'" => mock.mock_command('', '', '', 0),
"stat /path-stat 2>/dev/null -c '%s\n%f\n%U\n%u\n%G\n%g\n%X\n%Y\n%C'" => mock.mock_command('', "360\n43ff\nroot\n0\nrootz\n1\n1444520846\n1444522445\n?", '', 0),
}
mock
}

it 'ignores wrong stat results' do
res = Minitest::Mock.new
os = Minitest::Mock.new
res.expect :stdout, ''
os.expect :esx?, true
backend.expect :os, os
backend.expect :run_command, res, [String]
cls.linux_stat('/path', backend, false).must_equal({})
end

it 'reads correct stat results' do
res = Minitest::Mock.new
os = Minitest::Mock.new
# 43ff is 41777; linux_stat strips the 4
res.expect :stdout, "360\n43ff\nroot\n0\nrootz\n1\n1444520846\n1444522445\nC"
os.expect :esx?, true
backend.expect :os, os
backend.expect :run_command, res, [String]
cls.linux_stat('/path', backend, false).must_equal({
cls.linux_stat('/path-stat', backend, false).must_equal({
type: :directory,
mode: 01777,
owner: 'root',
uid: 0,
group: 'rootz',
gid: 1,
mtime: 1444522445,
size: 360,
selinux_label: nil,
})
end
end

describe 'alpine stat' do
let(:backend) {
mock = Train::Transports::Mock.new(verbose: true).connection
mock.mock_os({ name: 'alpine', family: 'alpine', release: nil })
mock.commands = {
"stat /path 2>/dev/null -c '%s\n%f\n%U\n%u\n%G\n%g\n%X\n%Y\n%C'" => mock.mock_command('', '', '', 0),
"stat /path-stat 2>/dev/null -c '%s\n%f\n%U\n%u\n%G\n%g\n%X\n%Y\n%C'" => mock.mock_command('', "360\n43ff\nroot\n0\nrootz\n1\n1444520846\n1444522445\n?", '', 0),
}
mock
}

it 'ignores wrong stat results' do
cls.linux_stat('/path', backend, false).must_equal({})
end

it 'reads correct stat results' do
cls.linux_stat('/path-stat', backend, false).must_equal({
type: :directory,
mode: 01777,
owner: 'root',
Expand Down

0 comments on commit d3b03b9

Please sign in to comment.