File tree Expand file tree Collapse file tree 2 files changed +51
-5
lines changed
lib/octocatalog-diff/util
spec/octocatalog-diff/tests/util Expand file tree Collapse file tree 2 files changed +51
-5
lines changed Original file line number Diff line number Diff line change @@ -68,14 +68,27 @@ def self.temp_dir(prefix = 'ocd-', basedir = ENV['OCTOCATALOG_DIFF_TEMPDIR'])
68
68
# If the base directory was not specified, then create a temporary directory, and
69
69
# send the `at_exit` to clean it up at the conclusion.
70
70
the_dir = Dir . mktmpdir ( prefix )
71
- at_exit do
71
+ at_exit { remove_temp_dir ( the_dir ) }
72
+ the_dir
73
+ end
74
+
75
+ # Utility method!
76
+ # Remove a directory recursively that has been used as a temporary directory. This
77
+ # should be called within an `at_exit` handler, and is only intended to be called via the
78
+ # `temp_dir` method above.
79
+ #
80
+ # dir - A String with the directory to remove.
81
+ def self . remove_temp_dir ( dir )
82
+ retries = 0
83
+ while File . directory? ( dir ) && retries < 10
84
+ retries += 1
72
85
begin
73
- FileUtils . remove_entry_secure ( the_dir ) if File . directory? ( the_dir )
74
- rescue Errno ::ENOENT # rubocop:disable Lint/HandleExceptions
75
- # OK if the directory doesn't exist since we're trying to remove it anyway
86
+ FileUtils . remove_entry_secure ( dir )
87
+ rescue Errno ::ENOTEMPTY , Errno ::ENOENT # rubocop:disable Lint/HandleExceptions
88
+ # Errno::ENOTEMPTY will trigger a retry because the directory exists
89
+ # Errno::ENOENT will break the loop because the directory won't exist next time it's checked
76
90
end
77
91
end
78
- the_dir
79
92
end
80
93
end
81
94
end
Original file line number Diff line number Diff line change 109
109
expect { described_class . temp_dir } . to raise_error ( Errno ::ENOENT , /temp_dir: Base dir/ )
110
110
end
111
111
end
112
+
113
+ describe '#remove_temp_dir' do
114
+ let ( :dir ) { '/var/tmp/abcd/efgh/ijkl' }
115
+
116
+ it 'should do nothing if the directory does not exist' do
117
+ allow ( File ) . to receive ( :directory? ) . and_call_original
118
+ allow ( File ) . to receive ( :directory? ) . with ( dir ) . and_return ( false )
119
+ expect ( FileUtils ) . not_to receive ( :remove_entry_secure ) . with ( dir )
120
+ described_class . remove_temp_dir ( dir )
121
+ end
122
+
123
+ it 'should do nothing if Errno::ENOENT is raised due to race conditions' do
124
+ allow ( File ) . to receive ( :directory? ) . and_call_original
125
+ allow ( File ) . to receive ( :directory? ) . with ( dir ) . and_return ( true , false )
126
+ expect ( FileUtils ) . to receive ( :remove_entry_secure ) . with ( dir ) . exactly ( 1 ) . times . and_raise ( Errno ::ENOENT )
127
+ described_class . remove_temp_dir ( dir )
128
+ end
129
+
130
+ it 'should retry if Errno::ENOTEMPTY is raised' do
131
+ allow ( File ) . to receive ( :directory? ) . and_call_original
132
+ allow ( File ) . to receive ( :directory? ) . with ( dir ) . and_return ( true , false )
133
+
134
+ call_count = 0
135
+ allow ( FileUtils ) . to receive ( :remove_entry_secure ) . with ( dir ) do
136
+ call_count += 1
137
+ raise Errno ::ENOTEMPTY if call_count == 1
138
+ raise 'This should not occur' unless call_count == 2
139
+ true
140
+ end
141
+
142
+ described_class . remove_temp_dir ( dir )
143
+ end
144
+ end
112
145
end
You can’t perform that action at this time.
0 commit comments