Skip to content

Commit d3b03b9

Browse files
authored
Merge pull request #146 from chef/chris-rock/alpine-stat
use stat -c for alpine linux
2 parents 560b159 + 0fe0868 commit d3b03b9

File tree

3 files changed

+58
-32
lines changed

3 files changed

+58
-32
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,12 @@ We perform `unit`, `integration` and `windows` tests.
101101
* `integration` tests run against VMs and docker containers
102102
* `windows` tests that run on appveyor for windows integration tests
103103

104+
## Mac/Linux
105+
106+
```
107+
bundle exec ruby -W -Ilib:test/unit test/unit/extras/stat_test.rb
108+
```
109+
104110
## Windows
105111

106112
```

lib/train/extras/stat.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,8 @@ def self.stat(shell_escaped_path, backend, follow_symlink)
3434

3535
def self.linux_stat(shell_escaped_path, backend, follow_symlink)
3636
lstat = follow_symlink ? ' -L' : ''
37-
format = backend.os.esx? ? '-c' : '--printf'
37+
format = (backend.os.esx? || backend.os[:name] == 'alpine') ? '-c' : '--printf'
3838
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'")
39-
4039
# ignore the exit_code: it is != 0 if selinux labels are not supported
4140
# on the system.
4241

test/unit/extras/stat_test.rb

Lines changed: 51 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# encoding: utf-8
22
require 'helper'
33
require 'train/extras'
4+
require 'train/transports/mock'
45

56
describe 'stat' do
67
let(:cls) { Train::Extras::Stat }
@@ -42,27 +43,22 @@
4243
end
4344

4445
describe 'linux stat' do
45-
let(:backend) { Minitest::Mock.new }
46+
let(:backend) {
47+
mock = Train::Transports::Mock.new(verbose: true).connection
48+
mock.mock_os({ name: 'ubuntu', family: 'debian', release: '15.04', arch: 'x86_64' })
49+
mock.commands = {
50+
"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),
51+
"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),
52+
}
53+
mock
54+
}
4655

4756
it 'ignores wrong stat results' do
48-
res = Minitest::Mock.new
49-
os = Minitest::Mock.new
50-
res.expect :stdout, ''
51-
os.expect :esx?, false
52-
backend.expect :os, os
53-
backend.expect :run_command, res, [String]
5457
cls.linux_stat('/path', backend, false).must_equal({})
5558
end
5659

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

7975
describe 'esx stat' do
80-
let(:backend) { Minitest::Mock.new }
76+
let(:backend) {
77+
mock = Train::Transports::Mock.new(verbose: true).connection
78+
mock.mock_os({ name: 'vmkernel', family: 'esx', release: '5' })
79+
mock.commands = {
80+
"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),
81+
"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),
82+
}
83+
mock
84+
}
8185

8286
it 'ignores wrong stat results' do
83-
res = Minitest::Mock.new
84-
os = Minitest::Mock.new
85-
res.expect :stdout, ''
86-
os.expect :esx?, true
87-
backend.expect :os, os
88-
backend.expect :run_command, res, [String]
8987
cls.linux_stat('/path', backend, false).must_equal({})
9088
end
9189

9290
it 'reads correct stat results' do
93-
res = Minitest::Mock.new
94-
os = Minitest::Mock.new
95-
# 43ff is 41777; linux_stat strips the 4
96-
res.expect :stdout, "360\n43ff\nroot\n0\nrootz\n1\n1444520846\n1444522445\nC"
97-
os.expect :esx?, true
98-
backend.expect :os, os
99-
backend.expect :run_command, res, [String]
100-
cls.linux_stat('/path', backend, false).must_equal({
91+
cls.linux_stat('/path-stat', backend, false).must_equal({
92+
type: :directory,
93+
mode: 01777,
94+
owner: 'root',
95+
uid: 0,
96+
group: 'rootz',
97+
gid: 1,
98+
mtime: 1444522445,
99+
size: 360,
100+
selinux_label: nil,
101+
})
102+
end
103+
end
104+
105+
describe 'alpine stat' do
106+
let(:backend) {
107+
mock = Train::Transports::Mock.new(verbose: true).connection
108+
mock.mock_os({ name: 'alpine', family: 'alpine', release: nil })
109+
mock.commands = {
110+
"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),
111+
"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),
112+
}
113+
mock
114+
}
115+
116+
it 'ignores wrong stat results' do
117+
cls.linux_stat('/path', backend, false).must_equal({})
118+
end
119+
120+
it 'reads correct stat results' do
121+
cls.linux_stat('/path-stat', backend, false).must_equal({
101122
type: :directory,
102123
mode: 01777,
103124
owner: 'root',

0 commit comments

Comments
 (0)