Skip to content

Commit e575ef6

Browse files
committed
Share specs between File.utime and File.lutime
1 parent 76ad54d commit e575ef6

File tree

3 files changed

+112
-98
lines changed

3 files changed

+112
-98
lines changed

spec/ruby/core/file/lutime_spec.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
require_relative '../../spec_helper'
2+
require_relative 'shared/update_time'
3+
4+
describe "File.lutime" do
5+
it_behaves_like :update_time, :lutime
6+
end
27

38
describe "File.lutime" do
49
platform_is_not :windows do
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
describe :update_time, shared: true do
2+
before :all do
3+
@time_is_float = platform_is :windows
4+
end
5+
6+
before :each do
7+
@atime = Time.now
8+
@mtime = Time.now
9+
@file1 = tmp("specs_file_utime1")
10+
@file2 = tmp("specs_file_utime2")
11+
touch @file1
12+
touch @file2
13+
end
14+
15+
after :each do
16+
rm_r @file1, @file2
17+
end
18+
19+
it "sets the access and modification time of each file" do
20+
File.send(@method, @atime, @mtime, @file1, @file2)
21+
22+
if @time_is_float
23+
File.atime(@file1).should be_close(@atime, 0.0001)
24+
File.mtime(@file1).should be_close(@mtime, 0.0001)
25+
File.atime(@file2).should be_close(@atime, 0.0001)
26+
File.mtime(@file2).should be_close(@mtime, 0.0001)
27+
else
28+
File.atime(@file1).to_i.should be_close(@atime.to_i, TIME_TOLERANCE)
29+
File.mtime(@file1).to_i.should be_close(@mtime.to_i, TIME_TOLERANCE)
30+
File.atime(@file2).to_i.should be_close(@atime.to_i, TIME_TOLERANCE)
31+
File.mtime(@file2).to_i.should be_close(@mtime.to_i, TIME_TOLERANCE)
32+
end
33+
end
34+
35+
it "uses the current times if two nil values are passed" do
36+
tn = Time.now
37+
File.send(@method, nil, nil, @file1, @file2)
38+
39+
if @time_is_float
40+
File.atime(@file1).should be_close(tn, 0.050)
41+
File.mtime(@file1).should be_close(tn, 0.050)
42+
File.atime(@file2).should be_close(tn, 0.050)
43+
File.mtime(@file2).should be_close(tn, 0.050)
44+
else
45+
File.atime(@file1).to_i.should be_close(Time.now.to_i, TIME_TOLERANCE)
46+
File.mtime(@file1).to_i.should be_close(Time.now.to_i, TIME_TOLERANCE)
47+
File.atime(@file2).to_i.should be_close(Time.now.to_i, TIME_TOLERANCE)
48+
File.mtime(@file2).to_i.should be_close(Time.now.to_i, TIME_TOLERANCE)
49+
end
50+
end
51+
52+
it "accepts an object that has a #to_path method" do
53+
File.send(@method, @atime, @mtime, mock_to_path(@file1), mock_to_path(@file2))
54+
end
55+
56+
it "accepts numeric atime and mtime arguments" do
57+
if @time_is_float
58+
File.send(@method, @atime.to_f, @mtime.to_f, @file1, @file2)
59+
60+
File.atime(@file1).should be_close(@atime, 0.0001)
61+
File.mtime(@file1).should be_close(@mtime, 0.0001)
62+
File.atime(@file2).should be_close(@atime, 0.0001)
63+
File.mtime(@file2).should be_close(@mtime, 0.0001)
64+
else
65+
File.send(@method, @atime.to_i, @mtime.to_i, @file1, @file2)
66+
67+
File.atime(@file1).to_i.should be_close(@atime.to_i, TIME_TOLERANCE)
68+
File.mtime(@file1).to_i.should be_close(@mtime.to_i, TIME_TOLERANCE)
69+
File.atime(@file2).to_i.should be_close(@atime.to_i, TIME_TOLERANCE)
70+
File.mtime(@file2).to_i.should be_close(@mtime.to_i, TIME_TOLERANCE)
71+
end
72+
end
73+
74+
it "may set nanosecond precision" do
75+
t = Time.utc(2007, 11, 1, 15, 25, 0, 123456.789r)
76+
File.send(@method, t, t, @file1)
77+
78+
File.atime(@file1).nsec.should.between?(0, 123500000)
79+
File.mtime(@file1).nsec.should.between?(0, 123500000)
80+
end
81+
82+
it "returns the number of filenames in the arguments" do
83+
File.send(@method, @atime.to_f, @mtime.to_f, @file1, @file2).should == 2
84+
end
85+
86+
platform_is :linux do
87+
platform_is wordsize: 64 do
88+
it "allows Time instances in the far future to set mtime and atime (but some filesystems limit it up to 2446-05-10 or 2038-01-19 or 2486-07-02)" do
89+
# https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout#Inode_Timestamps
90+
# "Therefore, timestamps should not overflow until May 2446."
91+
# https://lwn.net/Articles/804382/
92+
# "On-disk timestamps hitting the y2038 limit..."
93+
# The problem seems to be being improved, but currently it actually fails on XFS on RHEL8
94+
# https://rubyci.org/logs/rubyci.s3.amazonaws.com/rhel8/ruby-master/log/20201112T123004Z.fail.html.gz
95+
# Amazon Linux 2023 returns 2486-07-02 in this example
96+
# http://rubyci.s3.amazonaws.com/amazon2023/ruby-master/log/20230322T063004Z.fail.html.gz
97+
time = Time.at(1<<44)
98+
File.send(@method, time, time, @file1)
99+
100+
[559444, 2486, 2446, 2038].should.include? File.atime(@file1).year
101+
[559444, 2486, 2446, 2038].should.include? File.mtime(@file1).year
102+
end
103+
end
104+
end
105+
end

spec/ruby/core/file/utime_spec.rb

Lines changed: 2 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,102 +1,6 @@
11
require_relative '../../spec_helper'
2+
require_relative 'shared/update_time'
23

34
describe "File.utime" do
4-
5-
before :all do
6-
@time_is_float = platform_is :windows
7-
end
8-
9-
before :each do
10-
@atime = Time.now
11-
@mtime = Time.now
12-
@file1 = tmp("specs_file_utime1")
13-
@file2 = tmp("specs_file_utime2")
14-
touch @file1
15-
touch @file2
16-
end
17-
18-
after :each do
19-
rm_r @file1, @file2
20-
end
21-
22-
it "sets the access and modification time of each file" do
23-
File.utime(@atime, @mtime, @file1, @file2)
24-
if @time_is_float
25-
File.atime(@file1).should be_close(@atime, 0.0001)
26-
File.mtime(@file1).should be_close(@mtime, 0.0001)
27-
File.atime(@file2).should be_close(@atime, 0.0001)
28-
File.mtime(@file2).should be_close(@mtime, 0.0001)
29-
else
30-
File.atime(@file1).to_i.should be_close(@atime.to_i, TIME_TOLERANCE)
31-
File.mtime(@file1).to_i.should be_close(@mtime.to_i, TIME_TOLERANCE)
32-
File.atime(@file2).to_i.should be_close(@atime.to_i, TIME_TOLERANCE)
33-
File.mtime(@file2).to_i.should be_close(@mtime.to_i, TIME_TOLERANCE)
34-
end
35-
end
36-
37-
it "uses the current times if two nil values are passed" do
38-
tn = Time.now
39-
File.utime(nil, nil, @file1, @file2)
40-
if @time_is_float
41-
File.atime(@file1).should be_close(tn, 0.050)
42-
File.mtime(@file1).should be_close(tn, 0.050)
43-
File.atime(@file2).should be_close(tn, 0.050)
44-
File.mtime(@file2).should be_close(tn, 0.050)
45-
else
46-
File.atime(@file1).to_i.should be_close(Time.now.to_i, TIME_TOLERANCE)
47-
File.mtime(@file1).to_i.should be_close(Time.now.to_i, TIME_TOLERANCE)
48-
File.atime(@file2).to_i.should be_close(Time.now.to_i, TIME_TOLERANCE)
49-
File.mtime(@file2).to_i.should be_close(Time.now.to_i, TIME_TOLERANCE)
50-
end
51-
end
52-
53-
it "accepts an object that has a #to_path method" do
54-
File.utime(@atime, @mtime, mock_to_path(@file1), mock_to_path(@file2))
55-
end
56-
57-
it "accepts numeric atime and mtime arguments" do
58-
if @time_is_float
59-
File.utime(@atime.to_f, @mtime.to_f, @file1, @file2)
60-
File.atime(@file1).should be_close(@atime, 0.0001)
61-
File.mtime(@file1).should be_close(@mtime, 0.0001)
62-
File.atime(@file2).should be_close(@atime, 0.0001)
63-
File.mtime(@file2).should be_close(@mtime, 0.0001)
64-
else
65-
File.utime(@atime.to_i, @mtime.to_i, @file1, @file2)
66-
File.atime(@file1).to_i.should be_close(@atime.to_i, TIME_TOLERANCE)
67-
File.mtime(@file1).to_i.should be_close(@mtime.to_i, TIME_TOLERANCE)
68-
File.atime(@file2).to_i.should be_close(@atime.to_i, TIME_TOLERANCE)
69-
File.mtime(@file2).to_i.should be_close(@mtime.to_i, TIME_TOLERANCE)
70-
end
71-
end
72-
73-
it "may set nanosecond precision" do
74-
t = Time.utc(2007, 11, 1, 15, 25, 0, 123456.789r)
75-
File.utime(t, t, @file1)
76-
File.atime(@file1).nsec.should.between?(0, 123500000)
77-
File.mtime(@file1).nsec.should.between?(0, 123500000)
78-
end
79-
80-
it "returns the number of filenames in the arguments" do
81-
File.utime(@atime.to_f, @mtime.to_f, @file1, @file2).should == 2
82-
end
83-
84-
platform_is :linux do
85-
platform_is wordsize: 64 do
86-
it "allows Time instances in the far future to set mtime and atime (but some filesystems limit it up to 2446-05-10 or 2038-01-19 or 2486-07-02)" do
87-
# https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout#Inode_Timestamps
88-
# "Therefore, timestamps should not overflow until May 2446."
89-
# https://lwn.net/Articles/804382/
90-
# "On-disk timestamps hitting the y2038 limit..."
91-
# The problem seems to be being improved, but currently it actually fails on XFS on RHEL8
92-
# https://rubyci.org/logs/rubyci.s3.amazonaws.com/rhel8/ruby-master/log/20201112T123004Z.fail.html.gz
93-
# Amazon Linux 2023 returns 2486-07-02 in this example
94-
# http://rubyci.s3.amazonaws.com/amazon2023/ruby-master/log/20230322T063004Z.fail.html.gz
95-
time = Time.at(1<<44)
96-
File.utime(time, time, @file1)
97-
[559444, 2486, 2446, 2038].should.include? File.atime(@file1).year
98-
[559444, 2486, 2446, 2038].should.include? File.mtime(@file1).year
99-
end
100-
end
101-
end
5+
it_behaves_like :update_time, :utime
1026
end

0 commit comments

Comments
 (0)