eio 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/.gitignore +8 -0
  2. data/COPYING +502 -0
  3. data/LICENSE +16 -0
  4. data/README.rdoc +201 -0
  5. data/Rakefile +48 -0
  6. data/bench/eventmachine.rb +134 -0
  7. data/eio.gemspec +17 -0
  8. data/ext/eio/eio_ext.c +1447 -0
  9. data/ext/eio/extconf.rb +11 -0
  10. data/ext/libeio/CVS/Entries +13 -0
  11. data/ext/libeio/CVS/Repository +1 -0
  12. data/ext/libeio/CVS/Root +1 -0
  13. data/ext/libeio/Changes +40 -0
  14. data/ext/libeio/LICENSE +36 -0
  15. data/ext/libeio/Makefile +692 -0
  16. data/ext/libeio/Makefile.am +15 -0
  17. data/ext/libeio/Makefile.in +692 -0
  18. data/ext/libeio/aclocal.m4 +8937 -0
  19. data/ext/libeio/autogen.sh +3 -0
  20. data/ext/libeio/autom4te.cache/output.0 +13871 -0
  21. data/ext/libeio/autom4te.cache/output.1 +13867 -0
  22. data/ext/libeio/autom4te.cache/requests +275 -0
  23. data/ext/libeio/autom4te.cache/traces.0 +2384 -0
  24. data/ext/libeio/autom4te.cache/traces.1 +621 -0
  25. data/ext/libeio/config.guess +1501 -0
  26. data/ext/libeio/config.h +122 -0
  27. data/ext/libeio/config.h.in +121 -0
  28. data/ext/libeio/config.status +2035 -0
  29. data/ext/libeio/config.sub +1705 -0
  30. data/ext/libeio/configure +13867 -0
  31. data/ext/libeio/configure.ac +22 -0
  32. data/ext/libeio/demo.c +194 -0
  33. data/ext/libeio/eio.3 +3428 -0
  34. data/ext/libeio/eio.c +2075 -0
  35. data/ext/libeio/eio.h +336 -0
  36. data/ext/libeio/eio.pod +303 -0
  37. data/ext/libeio/install-sh +520 -0
  38. data/ext/libeio/libeio.m4 +156 -0
  39. data/ext/libeio/libtool +8890 -0
  40. data/ext/libeio/ltmain.sh +8406 -0
  41. data/ext/libeio/missing +376 -0
  42. data/ext/libeio/stamp-h1 +1 -0
  43. data/ext/libeio/xthread.h +168 -0
  44. data/lib/eio.rb +9 -0
  45. data/lib/eio/eventmachine.rb +24 -0
  46. data/lib/eio/middleware.rb +21 -0
  47. data/test/test_eio.rb +1161 -0
  48. data/test/test_eventmachine.rb +23 -0
  49. data/test/test_middleware.rb +20 -0
  50. metadata +148 -0
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+
3
+ require 'eio_ext'
4
+
5
+ module EIO
6
+ VERSION = '0.1'
7
+
8
+ autoload :Middleware, 'eio/middleware'
9
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+
3
+ require 'eio'
4
+ require 'eventmachine'
5
+
6
+ # The Eventmachine handler watches the read end of a pipe which wakes up the event loop whenever there's
7
+ # results to process. This is entirely driven from libeio which writes a char to the write end of the pipe
8
+ # to wake up the loop. The EIO.poll callback will fire as many times as it needs to as we don't read data # from the pipe through the reactor. A separate callback invoked by libeio will read the char and clear
9
+ # it's readable state.
10
+
11
+ module EM::EioHandler
12
+ def notify_readable
13
+ EIO.poll
14
+ end
15
+ end
16
+
17
+ module EIO
18
+
19
+ # Registers the read end of a pipe with Eventmachine which wakes up the event loop whenever there's
20
+ # results to process.
21
+ def self.eventmachine_handler
22
+ EM.watch(EIO.fd, EM::EioHandler){ |c| c.notify_readable = true }
23
+ end
24
+ end
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+
3
+ require 'eio'
4
+
5
+ # The call to EIO.wait blocks until callbacks for all completed requests have been invoked. This workflow
6
+ # is comparable to a 100m race with each line representing a libeio request and EIO.wait being the
7
+ # finishing line / completion barrier. Each I/O operation may be scheduled on a different core and will
8
+ # complete in parallel, proportional to the slowest request, with some minor overhead to boot.
9
+
10
+ class EIO::Middleware
11
+ def initialize(app, opts = {})
12
+ @app = app
13
+ @options = opts
14
+ end
15
+
16
+ def call(env)
17
+ ret = @app.call(env)
18
+ EIO.wait # flush the libeio request queue (blocks until all requests have been processed)
19
+ ret
20
+ end
21
+ end
@@ -0,0 +1,1161 @@
1
+ # encoding: utf-8
2
+
3
+ require 'test/unit'
4
+ require 'eio'
5
+ require 'fileutils' #19
6
+
7
+ TMP = File.expand_path(File.join(File.dirname(__FILE__), '..', 'tmp'))
8
+ SANDBOX = File.join(TMP, 'sandbox')
9
+ FileUtils.rm_rf SANDBOX
10
+ FileUtils.mkdir_p SANDBOX
11
+
12
+ class TestEio < Test::Unit::TestCase
13
+ def test_poll
14
+ assert_equal 0, EIO.poll
15
+ end
16
+
17
+ def test_version
18
+ assert_equal "0.1", EIO::VERSION
19
+ end
20
+
21
+ def test_main_thread_only
22
+ assert_raises ThreadError do
23
+ Thread.new do
24
+ EIO.open(__FILE__) do |fd|
25
+ end
26
+ end.value
27
+ EIO.wait
28
+ end
29
+ end
30
+
31
+ def test_fd
32
+ assert_instance_of Fixnum, EIO.fd
33
+ end
34
+
35
+ def test_constants
36
+ assert_equal(-4, EIO::PRI_MIN)
37
+ assert_equal 4, EIO::PRI_MAX
38
+ assert_equal 0, EIO::PRI_DEFAULT
39
+ end
40
+
41
+ def test_requests
42
+ assert_equal 0, EIO.requests
43
+ end
44
+
45
+ def test_ready
46
+ assert_equal 0, EIO.ready
47
+ end
48
+
49
+ def test_pending
50
+ assert_equal 0, EIO.pending
51
+ end
52
+
53
+ def test_threads
54
+ assert_equal 3, EIO.threads
55
+ end
56
+
57
+ def test_set_max_poll_time
58
+ assert_equal 1, EIO.max_poll_time = 1
59
+ assert_equal 0.1, EIO.max_poll_time = 0.1
60
+ end
61
+
62
+ def test_set_max_poll_reqs
63
+ assert_equal 1, EIO.max_poll_reqs = 1
64
+ end
65
+
66
+ def test_set_min_parallel
67
+ assert_equal 3, EIO.min_parallel = 3
68
+ end
69
+
70
+ def test_set_max_parallel
71
+ assert_equal 3, EIO.max_parallel = 3
72
+ end
73
+
74
+ def test_set_max_idle
75
+ assert_equal 1, EIO.max_idle = 1
76
+ end
77
+
78
+ def test_set_idle_timeout
79
+ assert_equal 1, EIO.idle_timeout = 1
80
+ end
81
+
82
+ def test_no_callbacks
83
+ descriptor = nil
84
+ EIO.open(__FILE__) do |fd|
85
+ descriptor = fd
86
+ EIO.close(fd)
87
+ end
88
+ EIO.wait
89
+ assert_raises(Errno::EBADF){ IO.new(descriptor) }
90
+ end
91
+
92
+ def test_args
93
+ assert_raises(TypeError){ EIO.open(1) }
94
+ assert_raises(TypeError){ EIO.open(__FILE__, EIO::RDONLY, 0, "") }
95
+ EIO.wait
96
+ end
97
+
98
+ # OPEN
99
+
100
+ def test_open_invalid_path
101
+ assert_raises Errno::ENOENT do
102
+ EIO.open('/non/existent/path'){|fd| }
103
+ EIO.wait
104
+ end
105
+ end
106
+
107
+ def test_open_invalid_flags
108
+ assert_raises TypeError do
109
+ EIO.open(__FILE__, :invalid)
110
+ end
111
+ end
112
+
113
+ def test_open_invalid_mode
114
+ assert_raises TypeError do
115
+ EIO.open(__FILE__, EIO::RDONLY, :invalid)
116
+ end
117
+ end
118
+
119
+ def test_open_close
120
+ closed, descriptor = false, nil
121
+ EIO.open(__FILE__) do |fd|
122
+ descriptor = fd
123
+ EIO.close(fd){ closed = true }
124
+ end
125
+ EIO.wait
126
+ assert closed
127
+ assert_raises(Errno::EBADF){ IO.new(descriptor) }
128
+ end
129
+
130
+ def test_open_sync
131
+ fd = EIO.open(__FILE__)
132
+ assert_instance_of Fixnum, fd
133
+ EIO.close(fd)
134
+ assert_raises(Errno::EBADF){ IO.new(fd) }
135
+ end
136
+
137
+ def test_open_close_with_proc_cb
138
+ closed = false
139
+ ccb = Proc.new{ closed = true }
140
+ cb = Proc.new do |fd|
141
+ EIO.close(fd, &ccb)
142
+ end
143
+ EIO.open(__FILE__, &cb)
144
+ EIO.wait
145
+ assert closed
146
+ end
147
+
148
+ # CLOSE
149
+
150
+ def test_close_non_numeric_fd
151
+ assert_raises TypeError do
152
+ EIO.close :symbol
153
+ end
154
+ end
155
+
156
+ def test_close_bad_fd
157
+ assert_raises Errno::EBADF do
158
+ EIO.close(900)
159
+ EIO.wait
160
+ end
161
+ end
162
+
163
+ def test_close_sync
164
+ descriptor = nil
165
+ EIO.open(__FILE__) do |fd|
166
+ descriptor = fd
167
+ EIO.close(fd)
168
+ end
169
+ EIO.wait
170
+ assert_raises(Errno::EBADF){ IO.new(descriptor) }
171
+ end
172
+
173
+ # FSYNC
174
+
175
+ def test_fsync_non_numeric_fd
176
+ assert_raises TypeError do
177
+ EIO.fsync :symbol
178
+ end
179
+ end
180
+
181
+ def test_fsync_bad_fd
182
+ assert_raises Errno::EBADF do
183
+ EIO.fsync(900)
184
+ end
185
+ end
186
+
187
+ def test_fsync
188
+ file = File.join(SANDBOX, 'test_fsync.txt')
189
+ buf = "sadklj32oiej23or23"
190
+ fsynced = false
191
+ EIO.open(file, EIO::RDWR | EIO::CREAT) do |fd|
192
+ EIO.write(fd, buf)
193
+ EIO.fsync(fd) do
194
+ assert_equal buf, IO.read(file)
195
+ fsynced = true
196
+ EIO.close(fd) do
197
+ EIO.unlink(file)
198
+ end
199
+ end
200
+ end
201
+ EIO.wait
202
+ assert fsynced
203
+ end
204
+
205
+ def test_fsync_sync
206
+ file = File.join(SANDBOX, 'test_fsync.txt')
207
+ buf = "sadklj32oiej23or23"
208
+ EIO.open(file, EIO::RDWR | EIO::CREAT) do |fd|
209
+ EIO.write(fd, buf)
210
+ EIO.fsync(fd)
211
+ assert_equal buf, IO.read(file)
212
+ EIO.close(fd) do
213
+ EIO.unlink(file)
214
+ end
215
+ end
216
+ EIO.wait
217
+ end
218
+
219
+ # FDATASYNC
220
+
221
+ def test_fdatasync_non_numeric_fd
222
+ assert_raises TypeError do
223
+ EIO.fdatasync :symbol
224
+ end
225
+ end
226
+
227
+ def test_fdatasync_bad_fd
228
+ assert_raises Errno::EBADF do
229
+ EIO.fdatasync(900)
230
+ end
231
+ end
232
+
233
+ def test_fdatasync
234
+ file = File.join(SANDBOX, 'test_fdatasync.txt')
235
+ buf = "sadklj32oiej23or23"
236
+ fsynced = false
237
+ EIO.open(file, EIO::RDWR | EIO::CREAT) do |fd|
238
+ EIO.write(fd, buf)
239
+ EIO.fdatasync(fd) do
240
+ assert_equal buf, IO.read(file)
241
+ fsynced = true
242
+ EIO.close(fd) do
243
+ EIO.unlink(file)
244
+ end
245
+ end
246
+ end
247
+ EIO.wait
248
+ assert fsynced
249
+ end
250
+
251
+ def test_fdatasync_sync
252
+ file = File.join(SANDBOX, 'test_fdatasync.txt')
253
+ buf = "sadklj32oiej23or23"
254
+ EIO.open(file, EIO::RDWR | EIO::CREAT) do |fd|
255
+ EIO.write(fd, buf)
256
+ EIO.fdatasync(fd)
257
+ assert_equal buf, IO.read(file)
258
+ EIO.close(fd) do
259
+ EIO.unlink(file)
260
+ end
261
+ end
262
+ EIO.wait
263
+ end
264
+
265
+ # READ
266
+
267
+ def test_read
268
+ expected = "# encoding: utf-8\n\n"
269
+ data = nil
270
+ EIO.open(__FILE__) do |fd|
271
+ EIO.read(fd, 19) do |buf|
272
+ data = buf
273
+ EIO.close(fd)
274
+ end
275
+ end
276
+ EIO.wait
277
+ assert_equal expected, data
278
+ end
279
+
280
+ def test_read_sync
281
+ expected = "# encoding: utf-8\n\n"
282
+ EIO.open(__FILE__) do |fd|
283
+ assert_equal expected, EIO.read(fd, 19)
284
+ EIO.close(fd)
285
+ end
286
+ EIO.wait
287
+ end
288
+
289
+ def test_read_with_offset
290
+ expected = "equire "
291
+ data = nil
292
+ EIO.open(__FILE__) do |fd|
293
+ EIO.read(fd, 7, 20) do |buf|
294
+ data = buf
295
+ EIO.close(fd)
296
+ end
297
+ end
298
+ EIO.wait
299
+ assert_equal expected, data
300
+ end
301
+
302
+ def test_read_sync_with_offset
303
+ expected = "equire "
304
+ EIO.open(__FILE__) do |fd|
305
+ assert_equal expected, EIO.read(fd, 7, 20)
306
+ EIO.close(fd)
307
+ end
308
+ EIO.wait
309
+ end
310
+
311
+ def test_read_bad_fd
312
+ assert_raises Errno::EBADF do
313
+ EIO.read(200) do |buf|
314
+ end
315
+ EIO.wait
316
+ end
317
+ end
318
+
319
+ def test_read_invalid_length
320
+ assert_raises TypeError do
321
+ EIO.open(__FILE__) do |fd|
322
+ EIO.read(fd, :invalid)
323
+ EIO.close(fd)
324
+ end
325
+ EIO.wait
326
+ end
327
+ end
328
+
329
+ def test_read_invalid_offset
330
+ assert_raises TypeError do
331
+ EIO.open(__FILE__) do |fd|
332
+ EIO.read(fd, 10, :invalid)
333
+ EIO.close(fd)
334
+ end
335
+ EIO.wait
336
+ end
337
+ end
338
+
339
+ def test_read_zero_length
340
+ data = nil
341
+ EIO.open(__FILE__) do |fd|
342
+ EIO.read(fd, 0) do |buf|
343
+ data = buf
344
+ EIO.close(fd)
345
+ end
346
+ end
347
+ EIO.wait
348
+ assert_equal 1024, data.size
349
+ end
350
+
351
+ # READAHEAD
352
+
353
+ def test_readahead
354
+ readahead = false
355
+ EIO.open(__FILE__) do |fd|
356
+ EIO.readahead(fd, 100) do
357
+ readahead = true
358
+ EIO.close(fd)
359
+ end
360
+ end
361
+ EIO.wait
362
+ assert readahead
363
+ end
364
+
365
+ def test_readahead_bad_fd
366
+ assert_raises Errno::EBADF do
367
+ EIO.readahead(200)
368
+ end
369
+ end
370
+
371
+ def test_readahead_invalid_length
372
+ assert_raises TypeError do
373
+ EIO.open(__FILE__) do |fd|
374
+ EIO.readahead(fd, :invalid) do
375
+ EIO.close(fd)
376
+ end
377
+ end
378
+ EIO.wait
379
+ end
380
+ end
381
+
382
+ def test_readahead_invalid_offset
383
+ assert_raises TypeError do
384
+ EIO.open(__FILE__) do |fd|
385
+ EIO.readahead(fd, 100, :invalid) do
386
+ EIO.close(fd)
387
+ end
388
+ end
389
+ EIO.wait
390
+ end
391
+ end
392
+
393
+ def test_readahead_sync
394
+ EIO.open(__FILE__) do |fd|
395
+ assert_equal 0, EIO.readahead(fd, 100)
396
+ EIO.close(fd)
397
+ end
398
+ EIO.wait
399
+ end
400
+
401
+ # WRITE
402
+
403
+ def test_write_bad_fd
404
+ assert_raises Errno::EBADF do
405
+ EIO.open(__FILE__) do |fd|
406
+ EIO.close(fd)
407
+ EIO.write(200, 'buffer')
408
+ end
409
+ EIO.wait
410
+ end
411
+ end
412
+
413
+ def test_write_not_string_buffer
414
+ assert_raises TypeError do
415
+ EIO.open(__FILE__) do |fd|
416
+ EIO.write(fd, :symbol)
417
+ end
418
+ EIO.wait
419
+ end
420
+ end
421
+
422
+ def test_write
423
+ file = File.join(SANDBOX, 'test_write.txt')
424
+ buf = "sadklj32oiej23or23"
425
+ descriptor = nil
426
+ EIO.open(file, EIO::RDWR | EIO::CREAT) do |fd|
427
+ descriptor = fd
428
+ EIO.write(fd, buf) do |written|
429
+ assert_equal written, buf.size
430
+ EIO.read(fd) do |data|
431
+ assert_equal data, buf
432
+ EIO.close(fd)
433
+ EIO.unlink(file)
434
+ end
435
+ end
436
+ end
437
+ EIO.wait
438
+ assert_raises(Errno::EBADF){ IO.new(descriptor) }
439
+ end
440
+
441
+ def test_write_sync
442
+ file = File.join(SANDBOX, 'test_write_sync.txt')
443
+ buf = "sadklj32oiej23or23"
444
+ EIO.open(file, EIO::RDWR | EIO::CREAT) do |fd|
445
+ assert_equal EIO.write(fd, buf), buf.size
446
+ EIO.read(fd) do |data|
447
+ assert_equal data, buf
448
+ EIO.close(fd)
449
+ EIO.unlink(file)
450
+ end
451
+ end
452
+ EIO.wait
453
+ end
454
+
455
+ def test_write_partial
456
+ file = File.join(SANDBOX, 'test_write_partial.txt')
457
+ buf = "sadklj32oiej23or23"
458
+ EIO.open(file, EIO::RDWR | EIO::CREAT) do |fd|
459
+ EIO.write(fd, buf, 4, 0) do |written|
460
+ assert_equal 4, written
461
+ EIO.read(fd) do |data|
462
+ assert_equal "sadk", IO.read(file)
463
+ assert_equal "sadk", data
464
+ EIO.close(fd)
465
+ EIO.unlink(file)
466
+ end
467
+ end
468
+ end
469
+ EIO.wait
470
+ end
471
+
472
+ def test_write_partial_sync
473
+ file = File.join(SANDBOX, 'test_write_partial_sync.txt')
474
+ buf = "sadklj32oiej23or23"
475
+ EIO.open(file, EIO::RDWR | EIO::CREAT) do |fd|
476
+ assert_equal 4, EIO.write(fd, buf, 4, 0)
477
+ EIO.read(fd) do |data|
478
+ assert_equal "sadk", IO.read(file)
479
+ assert_equal "sadk", data
480
+ EIO.close(fd)
481
+ EIO.unlink(file)
482
+ end
483
+ end
484
+ EIO.wait
485
+ end
486
+
487
+ # SENDFILE
488
+
489
+ def test_sendfile_bad_fd
490
+ assert_raises Errno::EBADF do
491
+ EIO.sendfile(300, 400, 0, 8)
492
+ end
493
+ end
494
+
495
+ def test_sendfile_invalid_length
496
+ file_out = File.join(SANDBOX, 'test_sendfile_out.txt')
497
+ file_in = File.join(SANDBOX, 'test_sendfile_in.txt')
498
+ assert_raises TypeError do
499
+ EIO.open(file_out, EIO::RDWR | EIO::CREAT) do |fd_in|
500
+ EIO.open(file_in, EIO::RDWR | EIO::CREAT) do |fd_out|
501
+ EIO.sendfile(fd_out, fd_in, :symbol) do |written|
502
+ end
503
+ end
504
+ end
505
+ EIO.wait
506
+ end
507
+ end
508
+
509
+ def test_sendfile_invalid_offset
510
+ file_out = File.join(SANDBOX, 'test_sendfile_out.txt')
511
+ file_in = File.join(SANDBOX, 'test_sendfile_in.txt')
512
+ assert_raises TypeError do
513
+ EIO.open(file_out, EIO::RDWR | EIO::CREAT) do |fd_in|
514
+ EIO.open(file_in, EIO::RDWR | EIO::CREAT) do |fd_out|
515
+ EIO.sendfile(fd_out, fd_in, 0, :symbol) do |written|
516
+ end
517
+ end
518
+ end
519
+ EIO.wait
520
+ end
521
+ end
522
+
523
+ def test_sendfile
524
+ file_out = File.join(SANDBOX, 'test_sendfile_out.txt')
525
+ file_in = File.join(SANDBOX, 'test_sendfile_in.txt')
526
+ File.open(file_out, "w+"){|f| f << "sendfile" }
527
+ EIO.open(file_out) do |fd_in|
528
+ EIO.open(file_in, EIO::RDWR | EIO::CREAT) do |fd_out|
529
+ EIO.sendfile(fd_out, fd_in, 0, 8) do |written|
530
+ assert_equal 8, written
531
+ EIO.close(fd_out)
532
+ EIO.close(fd_in)
533
+ EIO.unlink(file_in)
534
+ EIO.unlink(file_out)
535
+ end
536
+ end
537
+ end
538
+ EIO.wait
539
+ end
540
+
541
+ def test_sendfile_sync
542
+ file_out = File.join(SANDBOX, 'test_sendfile_out.txt')
543
+ file_in = File.join(SANDBOX, 'test_sendfile_in.txt')
544
+ File.open(file_out, "w+"){|f| f << "sendfile" }
545
+ EIO.open(file_out) do |fd_in|
546
+ EIO.open(file_in, EIO::RDWR | EIO::CREAT) do |fd_out|
547
+ assert_equal 8, EIO.sendfile(fd_out, fd_in, 0, 8)
548
+ EIO.close(fd_out)
549
+ EIO.close(fd_in)
550
+ EIO.unlink(file_in)
551
+ EIO.unlink(file_out)
552
+ end
553
+ end
554
+ EIO.wait
555
+ end
556
+
557
+ # READDIR
558
+
559
+ def test_readdir_not_a_string
560
+ assert_raises TypeError do
561
+ EIO.readdir(:symbol) do |entries|
562
+ end
563
+ end
564
+ end
565
+
566
+ def test_readdir_invalid_path
567
+ assert_raises Errno::ENOENT do
568
+ EIO.readdir('/invalid/path') do |entries|
569
+ end
570
+ EIO.wait
571
+ end
572
+ end
573
+
574
+ def test_readdir
575
+ EIO.readdir(TMP) do |entries|
576
+ assert entries.include?("sandbox")
577
+ end
578
+ EIO.wait
579
+ end
580
+
581
+ def test_readdir_sync
582
+ assert EIO.readdir(TMP).include?("sandbox")
583
+ end
584
+
585
+ # STAT
586
+
587
+ def test_stat_not_a_string
588
+ assert_raises TypeError do
589
+ EIO.stat(:symbol) do |stat|
590
+ end
591
+ end
592
+ end
593
+
594
+ def test_stat_invalid_path
595
+ assert_raises Errno::ENOENT do
596
+ EIO.stat('/invalid/path') do |stat|
597
+ end
598
+ EIO.wait
599
+ end
600
+ end
601
+
602
+ def test_stat
603
+ EIO.stat(__FILE__) do |s|
604
+ assert_instance_of File::Stat, s
605
+ assert_equal 'file', s.ftype
606
+ end
607
+ EIO.wait
608
+ end
609
+
610
+ def test_stat_sync
611
+ s = EIO.stat(__FILE__)
612
+ assert_instance_of File::Stat, s
613
+ assert_equal 'file', s.ftype
614
+ end
615
+
616
+ # MKDIR
617
+
618
+ def test_mkdir_not_a_string
619
+ assert_raises TypeError do
620
+ EIO.mkdir(:symbol)
621
+ end
622
+ end
623
+
624
+ def test_mkdir_invalid_mode
625
+ path = File.join(SANDBOX, 'test_mkdir_invalid')
626
+ assert_raises TypeError do
627
+ EIO.mkdir(path, :invalid)
628
+ end
629
+ end
630
+
631
+ def test_mkdir_rmdir
632
+ path = File.join(SANDBOX, 'test_mkdir')
633
+ EIO.mkdir(path) do
634
+ assert File.directory?(path)
635
+ EIO.rmdir(path) do
636
+ assert !File.directory?(path)
637
+ end
638
+ end
639
+ EIO.wait
640
+ end
641
+
642
+ def test_mkdir_rmdir_sync
643
+ path = File.join(SANDBOX, 'test_mkdir')
644
+ EIO.mkdir(path)
645
+ assert File.directory?(path)
646
+ EIO.rmdir(path)
647
+ assert !File.directory?(path)
648
+ end
649
+
650
+ # RMDIR
651
+
652
+ def test_rmdir_not_a_string
653
+ assert_raises TypeError do
654
+ EIO.rmdir(:symbol)
655
+ end
656
+ end
657
+
658
+ def test_rmdir_nonexistent_path
659
+ assert_raises Errno::ENOENT do
660
+ EIO.rmdir('/invalid/path') do
661
+ end
662
+ EIO.wait
663
+ end
664
+ end
665
+
666
+ # UNLINK
667
+
668
+ def test_unlink_nonexistent_path
669
+ assert_raises Errno::ENOENT do
670
+ EIO.unlink('/invalid/path/file.txt')
671
+ EIO.wait
672
+ end
673
+ end
674
+
675
+ def test_unlink_not_a_string
676
+ assert_raises TypeError do
677
+ EIO.unlink(:symbol)
678
+ end
679
+ end
680
+
681
+ def test_unlink
682
+ file = File.join(SANDBOX, 'test_unlink.txt')
683
+ File.new(file, EIO::CREAT).close
684
+ EIO.unlink(file) do
685
+ assert !File.exist?(file)
686
+ end
687
+ EIO.wait
688
+ end
689
+
690
+ def test_unlink_sync
691
+ file = File.join(SANDBOX, 'test_unlink.txt')
692
+ File.new(file, EIO::CREAT).close
693
+ EIO.unlink(file)
694
+ assert !File.exist?(file)
695
+ EIO.wait
696
+ end
697
+
698
+ # READLINK
699
+
700
+ def test_readlink_invalid
701
+ assert_raises Errno::ENOENT do
702
+ EIO.readlink('/nonexistent/path') do |path|
703
+ end
704
+ EIO.wait
705
+ end
706
+ end
707
+
708
+ def test_readlink_not_a_link
709
+ assert_raises Errno::EINVAL do
710
+ EIO.readlink(__FILE__) do |path|
711
+ end
712
+ EIO.wait
713
+ end
714
+ end
715
+
716
+ def test_readlink_not_a_string
717
+ assert_raises TypeError do
718
+ EIO.readlink(:symbol)
719
+ end
720
+ end
721
+
722
+ def test_readlink
723
+ file = File.join(SANDBOX, 'test_readlink.txt')
724
+ symlinked = File.join(SANDBOX, 'test_readlinked.txt')
725
+ File.open(file, "w+"){|f| f << "readlink" }
726
+ EIO.symlink(file, symlinked) do
727
+ assert File.exist?(symlinked)
728
+ EIO.readlink(symlinked) do |path|
729
+ assert_equal file, path
730
+ EIO.unlink(symlinked) do
731
+ EIO.unlink(file)
732
+ end
733
+ end
734
+ end
735
+ EIO.wait
736
+ end
737
+
738
+ def test_readlink_sync
739
+ file = File.join(SANDBOX, 'test_readlink.txt')
740
+ symlinked = File.join(SANDBOX, 'test_readlinked.txt')
741
+ File.open(file, "w+"){|f| f << "readlink" }
742
+ EIO.symlink(file, symlinked) do
743
+ assert File.exist?(symlinked)
744
+ assert_equal file, EIO.readlink(symlinked)
745
+ EIO.unlink(symlinked) do
746
+ EIO.unlink(file)
747
+ end
748
+ end
749
+ EIO.wait
750
+ end
751
+
752
+ # RENAME
753
+
754
+ def test_rename_not_strings
755
+ assert_raises TypeError do
756
+ EIO.rename(:a, :b)
757
+ end
758
+ end
759
+
760
+ def test_rename_invalid_paths
761
+ assert_raises Errno::ENOENT do
762
+ EIO.rename('/invalid/path', '/other/invalid/path')
763
+ EIO.wait
764
+ end
765
+ end
766
+
767
+ def test_rename
768
+ file = File.join(SANDBOX, 'test_rename.txt')
769
+ renamed_file = File.join(SANDBOX, 'test_renamed.txt')
770
+ File.new(file, EIO::CREAT).close
771
+ EIO.rename(file, renamed_file) do
772
+ assert !File.exist?(file)
773
+ assert File.exist?(renamed_file)
774
+ EIO.unlink(renamed_file)
775
+ end
776
+ EIO.wait
777
+ end
778
+
779
+ def test_rename_sync
780
+ file = File.join(SANDBOX, 'test_rename.txt')
781
+ renamed_file = File.join(SANDBOX, 'test_renamed.txt')
782
+ File.new(file, EIO::CREAT).close
783
+ EIO.rename(file, renamed_file)
784
+ assert !File.exist?(file)
785
+ assert File.exist?(renamed_file)
786
+ EIO.unlink(renamed_file)
787
+ EIO.wait
788
+ end
789
+
790
+ # CHMOD
791
+
792
+ def test_chmod_invalid_path
793
+ assert_raises Errno::ENOENT do
794
+ EIO.chmod('/invalid/path', 0644) do
795
+ end
796
+ EIO.wait
797
+ end
798
+ end
799
+
800
+ def test_chmod_invalid_mode
801
+ assert_raises TypeError do
802
+ EIO.chmod(__FILE__, :invalid) do
803
+ end
804
+ end
805
+ end
806
+
807
+ def test_chmod_not_a_string_path
808
+ assert_raises TypeError do
809
+ EIO.chmod(:symbol, 0644) do
810
+ end
811
+ end
812
+ end
813
+
814
+ def test_chmod
815
+ file = File.join(SANDBOX, 'test_chmod.txt')
816
+ File.new(file, EIO::CREAT).close
817
+ EIO.chmod(file, 0644) do
818
+ # XXX expects "100644"
819
+ assert_equal 33188, File.stat(file).mode
820
+ EIO.unlink(file)
821
+ end
822
+ EIO.wait
823
+ end
824
+
825
+ def test_chmod_sync
826
+ file = File.join(SANDBOX, 'test_chmod.txt')
827
+ File.new(file, EIO::CREAT).close
828
+ EIO.chmod(file, 0644)
829
+ # XXX expects "100644"
830
+ assert_equal 33188, File.stat(file).mode
831
+ EIO.unlink(file)
832
+ EIO.wait
833
+ end
834
+
835
+ # FCHMOD
836
+
837
+ def test_fchmod_invalid_fd
838
+ assert_raises Errno::EBADF do
839
+ EIO.fchmod(200, 0644) do
840
+ end
841
+ EIO.wait
842
+ end
843
+ end
844
+
845
+ def test_fchmod_invalid_mode
846
+ assert_raises TypeError do
847
+ EIO.open(__FILE__) do |fd|
848
+ EIO.fchmod(fd, :invalid) do
849
+ end
850
+ end
851
+ EIO.wait
852
+ end
853
+ end
854
+
855
+ def test_fchmod
856
+ file = File.join(SANDBOX, 'test_fchmod.txt')
857
+ EIO.open(file, EIO::CREAT) do |fd|
858
+ EIO.fchmod(fd, 0644) do
859
+ # XXX expects "100644"
860
+ assert_equal 33188, File.stat(file).mode
861
+ EIO.unlink(file) do
862
+ EIO.close(fd)
863
+ end
864
+ end
865
+ end
866
+ EIO.wait
867
+ end
868
+
869
+ def test_fchmod_sync
870
+ file = File.join(SANDBOX, 'test_fchmod.txt')
871
+ EIO.open(file, EIO::CREAT) do |fd|
872
+ EIO.fchmod(fd, 0644)
873
+ # XXX expects "100644"
874
+ assert_equal 33188, File.stat(file).mode
875
+ EIO.unlink(file) do
876
+ EIO.close(fd)
877
+ end
878
+ end
879
+ EIO.wait
880
+ end
881
+
882
+ # TRUNCATE
883
+
884
+ def test_truncate_invalid_path
885
+ assert_raises Errno::ENOENT do
886
+ EIO.truncate('/invalid/path', 0) do
887
+ end
888
+ EIO.wait
889
+ end
890
+ end
891
+
892
+ def test_truncate_invalid_offset
893
+ assert_raises TypeError do
894
+ EIO.truncate(__FILE__, :invalid) do
895
+ end
896
+ end
897
+ end
898
+
899
+ def test_truncate
900
+ file = File.join(SANDBOX, 'test_truncate.txt')
901
+ File.open(file, "w+"){|f| f << "truncate" }
902
+ EIO.truncate(file) do
903
+ assert_equal 0, File.size(file)
904
+ EIO.unlink(file)
905
+ end
906
+ EIO.wait
907
+ end
908
+
909
+ def test_truncate_sync
910
+ file = File.join(SANDBOX, 'test_truncate.txt')
911
+ File.open(file, "w+"){|f| f << "truncate" }
912
+ EIO.truncate(file)
913
+ assert_equal 0, File.size(file)
914
+ EIO.unlink(file)
915
+ end
916
+
917
+ # FTRUNCATE
918
+
919
+ def test_ftruncate_invalid_fd
920
+ assert_raises Errno::EBADF do
921
+ EIO.ftruncate(200, 0) do
922
+ end
923
+ EIO.wait
924
+ end
925
+ end
926
+
927
+ def test_ftruncate_invalid_offset
928
+ assert_raises TypeError do
929
+ EIO.open(__FILE__) do |fd|
930
+ EIO.ftruncate(fd, :invalid) do
931
+ end
932
+ end
933
+ EIO.wait
934
+ end
935
+ end
936
+
937
+ def test_ftruncate
938
+ file = File.join(SANDBOX, 'test_ftruncate.txt')
939
+ EIO.open(file, EIO::RDWR | EIO::CREAT) do |fd|
940
+ EIO.ftruncate(fd) do
941
+ assert_equal 0, File.size(file)
942
+ EIO.unlink(file) do
943
+ EIO.close(fd)
944
+ end
945
+ end
946
+ end
947
+ EIO.wait
948
+ end
949
+
950
+ def test_ftruncate_sync
951
+ file = File.join(SANDBOX, 'test_ftruncate.txt')
952
+ EIO.open(file, EIO::RDWR | EIO::CREAT) do |fd|
953
+ EIO.ftruncate(fd)
954
+ assert_equal 0, File.size(file)
955
+ EIO.unlink(file) do
956
+ EIO.close(fd)
957
+ end
958
+ end
959
+ EIO.wait
960
+ end
961
+
962
+ # CHOWN
963
+
964
+ def test_chown_invalid_path
965
+ assert_raises Errno::ENOENT do
966
+ EIO.chown('/invalid/path') do
967
+ end
968
+ EIO.wait
969
+ end
970
+ end
971
+
972
+ def test_chown_not_a_string
973
+ assert_raises TypeError do
974
+ EIO.chown(:symbol)
975
+ end
976
+ end
977
+
978
+ def test_chown_invalid_perms
979
+ assert_raises TypeError do
980
+ EIO.chown(__FILE__, :a, :b)
981
+ end
982
+ end
983
+
984
+ def test_chown
985
+ file = File.join(SANDBOX, 'test_chown.txt')
986
+ File.new(file, EIO::CREAT).close
987
+ EIO.chown(file) do
988
+ assert_equal 502, File.stat(file).uid
989
+ assert_equal 502, File.stat(file).gid
990
+ EIO.unlink(file)
991
+ end
992
+ EIO.wait
993
+ end
994
+
995
+ def test_chown_sync
996
+ file = File.join(SANDBOX, 'test_chown.txt')
997
+ File.new(file, EIO::CREAT).close
998
+ EIO.chown(file)
999
+ assert_equal 502, File.stat(file).uid
1000
+ assert_equal 502, File.stat(file).gid
1001
+ EIO.unlink(file)
1002
+ EIO.wait
1003
+ end
1004
+
1005
+ # FCHOWN
1006
+
1007
+ def test_fchown_bad_fd
1008
+ assert_raises Errno::EBADF do
1009
+ EIO.fchown(200) do
1010
+ end
1011
+ EIO.wait
1012
+ end
1013
+ end
1014
+
1015
+ def test_fchown_invalid_perms
1016
+ assert_raises TypeError do
1017
+ EIO.open(__FILE__) do |fd|
1018
+ EIO.fchown(fd, :a, :b)
1019
+ end
1020
+ EIO.wait
1021
+ end
1022
+ end
1023
+
1024
+ def test_fchown
1025
+ file = File.join(SANDBOX, 'test_fchown.txt')
1026
+ EIO.open(file, EIO::CREAT) do |fd|
1027
+ EIO.fchown(fd) do
1028
+ assert_equal 502, File.stat(file).uid
1029
+ assert_equal 502, File.stat(file).gid
1030
+ EIO.unlink(file) do
1031
+ EIO.close(fd)
1032
+ end
1033
+ end
1034
+ end
1035
+ EIO.wait
1036
+ end
1037
+
1038
+ def test_fchown_sync
1039
+ file = File.join(SANDBOX, 'test_fchown.txt')
1040
+ EIO.open(file, EIO::CREAT) do |fd|
1041
+ EIO.fchown(fd)
1042
+ assert_equal 502, File.stat(file).uid
1043
+ assert_equal 502, File.stat(file).gid
1044
+ EIO.unlink(file) do
1045
+ EIO.close(fd)
1046
+ end
1047
+ end
1048
+ EIO.wait
1049
+ end
1050
+
1051
+ # LINK
1052
+
1053
+ def test_link_invalid_paths
1054
+ assert_raises Errno::ENOENT do
1055
+ EIO.link('/invalid/path/a', '/invalid/path/b')
1056
+ EIO.wait
1057
+ end
1058
+ end
1059
+
1060
+ def test_link_not_strings
1061
+ assert_raises TypeError do
1062
+ EIO.link(:a, :b)
1063
+ end
1064
+ end
1065
+
1066
+ def test_link
1067
+ file = File.join(SANDBOX, 'test_link.txt')
1068
+ linked = File.join(SANDBOX, 'test_linked.txt')
1069
+ File.open(file, "w+"){|f| f << "link" }
1070
+ EIO.link(file, linked) do
1071
+ assert File.exist?(linked)
1072
+ assert_equal "link", IO.read(linked)
1073
+ EIO.unlink(linked) do
1074
+ EIO.unlink(file)
1075
+ end
1076
+ end
1077
+ EIO.wait
1078
+ end
1079
+
1080
+ def test_link_sync
1081
+ file = File.join(SANDBOX, 'test_link.txt')
1082
+ linked = File.join(SANDBOX, 'test_linked.txt')
1083
+ File.open(file, "w+"){|f| f << "link" }
1084
+ EIO.link(file, linked)
1085
+ assert File.exist?(linked)
1086
+ assert_equal "link", IO.read(linked)
1087
+ EIO.unlink(linked) do
1088
+ EIO.unlink(file)
1089
+ end
1090
+ EIO.wait
1091
+ end
1092
+
1093
+ # SYMLINK
1094
+
1095
+ def test_symlink_invalid_paths
1096
+ assert_raises Errno::ENOENT do
1097
+ EIO.symlink('/invalid/path/a', '/invalid/path/b')
1098
+ EIO.wait
1099
+ end
1100
+ end
1101
+
1102
+ def test_symlink_not_strings
1103
+ assert_raises TypeError do
1104
+ EIO.symlink(:a, :b)
1105
+ end
1106
+ end
1107
+
1108
+ def test_symlink
1109
+ file = File.join(SANDBOX, 'test_symlink.txt')
1110
+ symlinked = File.join(SANDBOX, 'test_symlinked.txt')
1111
+ File.open(file, "w+"){|f| f << "symlink" }
1112
+ EIO.symlink(file, symlinked) do
1113
+ assert File.exist?(symlinked)
1114
+ assert_equal "symlink", IO.read(symlinked)
1115
+ EIO.unlink(symlinked) do
1116
+ EIO.unlink(file)
1117
+ end
1118
+ end
1119
+ EIO.wait
1120
+ end
1121
+
1122
+ def test_symlink_sync
1123
+ file = File.join(SANDBOX, 'test_symlink.txt')
1124
+ symlinked = File.join(SANDBOX, 'test_symlinked.txt')
1125
+ File.open(file, "w+"){|f| f << "symlink" }
1126
+ EIO.symlink(file, symlinked)
1127
+ assert File.exist?(symlinked)
1128
+ assert_equal "symlink", IO.read(symlinked)
1129
+ EIO.unlink(symlinked) do
1130
+ EIO.unlink(file)
1131
+ end
1132
+ EIO.wait
1133
+ end
1134
+
1135
+ def test_request
1136
+ req = EIO.open(__FILE__) do |fd|
1137
+ EIO.close(fd)
1138
+ end
1139
+ EIO.wait
1140
+ assert_instance_of EIO::Request, req
1141
+ assert_equal 0, req.errno
1142
+ assert_equal EIO::Request::OPEN, req.type
1143
+ assert_equal EIO::PRI_DEFAULT, req.priority
1144
+ end
1145
+
1146
+ def test_cancel_request
1147
+ cancelled = true
1148
+ EIO.open(__FILE__) do |fd|
1149
+ cancelled = false
1150
+ end.cancel
1151
+ EIO.wait
1152
+ assert cancelled
1153
+ end
1154
+
1155
+ def test_complete
1156
+ req = EIO.open(__FILE__) do |fd|
1157
+ end
1158
+ EIO.wait
1159
+ assert req.complete?
1160
+ end
1161
+ end