1# Licensed to the Apache Software Foundation (ASF) under one 2# or more contributor license agreements. See the NOTICE file 3# distributed with this work for additional information 4# regarding copyright ownership. The ASF licenses this file 5# to you under the Apache License, Version 2.0 (the 6# "License"); you may not use this file except in compliance 7# with the License. You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, 12# software distributed under the License is distributed on an 13# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14# KIND, either express or implied. See the License for the 15# specific language governing permissions and limitations 16# under the License. 17 18module FileSystemTests 19 private def all_entries 20 selector = Arrow::FileSelector.new 21 selector.base_dir = "" 22 selector.recursive = true 23 infos = @fs.get_file_infos_selector(selector) 24 infos.map {|info| [info.path, info.type.nick.to_sym]}.to_h 25 end 26 27 private def mkpath(path) 28 @fs.create_dir(path, true) 29 end 30 31 private def create_file(path, content=nil) 32 stream = @fs.open_output_stream(path) 33 stream.write(content) if content 34 stream.close 35 end 36 37 private def read_file(path) 38 stream = @fs.open_input_stream(path) 39 size = @fs.get_file_info(path).size 40 bytes = stream.read_bytes(size) 41 stream.close 42 bytes.to_s 43 end 44 45 private def file?(path) 46 info = @fs.get_file_info(path) 47 info.file? 48 rescue Arrow::Error::Io 49 false 50 end 51 52 private def directory?(path) 53 info = @fs.get_file_info(path) 54 info.dir? 55 rescue Arrow::Error::Io 56 false 57 end 58 59 def test_empty 60 assert { all_entries.empty? } 61 end 62 63 def test_create_dir 64 @fs.create_dir("AB/CD/EF", true) # recursive 65 @fs.create_dir("AB/GH", false) # non-recursive 66 assert_equal({ 67 "AB" => :dir, 68 "AB/CD" => :dir, 69 "AB/CD/EF" => :dir, 70 "AB/GH" => :dir 71 }, 72 all_entries) 73 end 74 75 def test_create_dir_with_nonexistent_parent 76 assert_raise(Arrow::Error::Io) do 77 @fs.create_dir("AB/GH/IJ", false) # non-recursive, parent doesn't exist 78 end 79 assert_equal({}, 80 all_entries) 81 end 82 83 def test_create_dir_under_file 84 create_file("empty_file") 85 assert_raise(Arrow::Error::Io) do 86 @fs.create_dir(File.join("empty_file", "XY"), true) 87 end 88 assert_equal({"empty_file" => :file}, 89 all_entries) 90 end 91 92 def test_delete_dir 93 mkpath("AB/CD/EF") 94 mkpath("AB/GH/IJ") 95 create_file("AB/abc") 96 create_file("AB/CD/def") 97 create_file("AB/CD/EF/ghi") 98 99 @fs.delete_dir("AB/CD") 100 @fs.delete_dir("AB/GH/IJ") 101 102 assert_equal({ 103 "AB" => :dir, 104 "AB/GH" => :dir, 105 "AB/abc" => :file 106 }, 107 all_entries) 108 end 109 110 def test_delete_dir_contents 111 mkpath("AB/CD/EF") 112 mkpath("AB/GH/IJ") 113 create_file("AB/abc") 114 create_file("AB/CD/def") 115 create_file("AB/CD/EF/ghi") 116 117 @fs.delete_dir_contents("AB/CD") 118 @fs.delete_dir_contents("AB/GH/IJ") 119 120 assert_equal({ 121 "AB" => :dir, 122 "AB/CD" => :dir, 123 "AB/GH" => :dir, 124 "AB/GH/IJ" => :dir, 125 "AB/abc" => :file 126 }, 127 all_entries) 128 end 129 130 def test_delete_file 131 mkpath("AB") 132 create_file("AB/def") 133 assert { file?("AB/def") } 134 135 @fs.delete_file("AB/def") 136 assert { not file?("AB/def") } 137 end 138 139 def test_delete_files 140 mkpath("AB") 141 create_file("abc") 142 { 143 def: 123, 144 ghi: 456, 145 jkl: 789, 146 mno: 789 147 }.each do |name, content| 148 create_file(File.join("AB", name.to_s), content.to_s) 149 end 150 151 assert_equal({ 152 "AB" => :dir, 153 "AB/def" => :file, 154 "AB/ghi" => :file, 155 "AB/jkl" => :file, 156 "AB/mno" => :file, 157 "abc" => :file 158 }, 159 all_entries) 160 161 @fs.delete_files(["abc", "AB/def"]) 162 assert_equal({ 163 "AB" => :dir, 164 "AB/ghi" => :file, 165 "AB/jkl" => :file, 166 "AB/mno" => :file 167 }, 168 all_entries) 169 end 170 171 def test_move_file 172 mkpath("AB/CD") 173 mkpath("EF") 174 create_file("abc") 175 assert_equal({ 176 "AB" => :dir, 177 "AB/CD" => :dir, 178 "EF" => :dir, 179 "abc" => :file 180 }, 181 all_entries) 182 183 @fs.move("abc", "AB/CD/ghi") 184 assert_equal({ 185 "AB" => :dir, 186 "AB/CD" => :dir, 187 "EF" => :dir, 188 "AB/CD/ghi" => :file 189 }, 190 all_entries) 191 end 192 193 def move_dir_is_supported? 194 true 195 end 196 197 def test_move_dir 198 omit("move_dir is not allowed") unless move_dir_is_supported? 199 200 mkpath("AB/CD") 201 mkpath("EF") 202 assert_equal({ 203 "AB" => :dir, 204 "AB/CD" => :dir, 205 "EF" => :dir 206 }, 207 all_entries) 208 209 @fs.move("AB", "GH") 210 assert_equal({ 211 "EF" => :dir, 212 "GH" => :dir, 213 "GH/CD" => :dir 214 }, 215 all_entries) 216 end 217 218 def test_copy_file 219 mkpath("AB/CD") 220 mkpath("EF") 221 create_file("AB/abc", "data") 222 assert_equal({ 223 "AB" => :dir, 224 "AB/CD" => :dir, 225 "EF" => :dir, 226 "AB/abc" => :file 227 }, 228 all_entries) 229 230 @fs.copy_file("AB/abc", "def") 231 assert_equal({ 232 "AB" => :dir, 233 "AB/CD" => :dir, 234 "EF" => :dir, 235 "AB/abc" => :file, 236 "def" => :file 237 }, 238 all_entries) 239 assert_equal("data", 240 read_file("def")) 241 end 242 243 def test_get_file_info 244 mkpath("AB/CD") 245 create_file("AB/CD/ghi", "some data") 246 247 info = @fs.get_file_info("AB") 248 assert_equal(Arrow::FileType::DIR, 249 info.type) 250 assert_equal("AB", 251 info.base_name) 252 assert_equal(-1, 253 info.size) 254 assert do 255 info.mtime > 0 256 end 257 258 info = @fs.get_file_info("AB/CD/ghi") 259 assert_equal(Arrow::FileType::FILE, 260 info.type) 261 assert_equal("ghi", 262 info.base_name) 263 assert_equal(9, 264 info.size) 265 assert do 266 info.mtime > 0 267 end 268 end 269 270 def test_get_file_infos_paths 271 mkpath("AB/CD") 272 create_file("AB/CD/ghi", "some data") 273 274 infos = @fs.get_file_infos_paths(["AB", "AB/CD/ghi"]) 275 assert_equal({ 276 "AB" => -1, 277 "AB/CD/ghi" => 9 278 }, 279 infos.map {|info| [info.path, info.size]}.to_h) 280 end 281 282 def test_get_file_infos_selector 283 mkpath("AB/CD") 284 create_file("abc", "data") 285 create_file("AB/def", "some data") 286 create_file("AB/CD/ghi", "some other data") 287 288 selector = Arrow::FileSelector.new 289 infos = @fs.get_file_infos_selector(selector) 290 assert_equal({ 291 "AB" => -1, 292 "abc" => 4 293 }, 294 infos.map {|info| [info.path, info.size]}.to_h) 295 296 selector.base_dir = "AB" 297 infos = @fs.get_file_infos_selector(selector) 298 assert_equal({ 299 "AB/CD" => -1, 300 "AB/def" => 9 301 }, 302 infos.map {|info| [info.path, info.size]}.to_h) 303 end 304 305 def test_get_file_infos_selector_with_recursion 306 mkpath("AB/CD") 307 create_file("abc", "data") 308 create_file("AB/def", "some data") 309 create_file("AB/CD/ghi", "some other data") 310 311 selector = Arrow::FileSelector.new 312 selector.recursive = true 313 infos = @fs.get_file_infos_selector(selector) 314 assert_equal({ 315 "AB" => -1, 316 "AB/CD" => -1, 317 "AB/CD/ghi" => 15, 318 "AB/def" => 9, 319 "abc" => 4 320 }, 321 infos.map {|info| [info.path, info.size]}.to_h) 322 end 323 324 def test_open_output_stream 325 assert { not file?("abc") } 326 stream = @fs.open_output_stream("abc") 327 assert_equal(0, stream.tell) 328 stream.write("some ") 329 stream.write("data") 330 stream.close 331 assert { file?("abc") } 332 assert_equal("some data", 333 read_file("abc")) 334 335 stream = @fs.open_output_stream("abc") 336 assert_equal(0, stream.tell) 337 stream.write("other data") 338 stream.close 339 assert { file?("abc") } 340 assert_equal("other data", 341 read_file("abc")) 342 end 343 344 def test_open_append_stream 345 assert { not file?("abc") } 346 stream = @fs.open_append_stream("abc") 347 assert_equal(0, stream.tell) 348 stream.write("some ") 349 stream.close 350 assert { file?("abc") } 351 assert_equal("some ", 352 read_file("abc")) 353 354 stream = @fs.open_append_stream("abc") 355 assert_equal(5, stream.tell) 356 stream.write("data") 357 stream.close 358 assert { file?("abc") } 359 assert_equal("some data", 360 read_file("abc")) 361 end 362 363 def test_open_input_stream 364 mkpath("AB") 365 create_file("AB/abc", "some data") 366 367 stream = @fs.open_input_stream("AB/abc") 368 bytes = stream.read_bytes(4) 369 assert_equal("some", 370 bytes.to_s) 371 stream.close 372 end 373 374 def test_open_input_file 375 create_file("ab", "some data") 376 377 stream = @fs.open_input_file("ab") 378 bytes = stream.read_at_bytes(5, 4) 379 assert_equal("data", 380 bytes.to_s) 381 stream.close 382 end 383end 384