eio 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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