Merge lp:~sylvain-pineau/checkbox-core/bug983035 into lp:checkbox-core

Proposed by Sylvain Pineau
Status: Needs review
Proposed branch: lp:~sylvain-pineau/checkbox-core/bug983035
Merge into: lp:checkbox-core
Diff against target: 775 lines (+147/-184)
16 files modified
checkbox/daemon/pidentry.py (+3/-3)
checkbox/daemon/server.py (+8/-3)
checkbox/io/fifo.py (+5/-4)
checkbox/io/pipe.py (+7/-5)
checkbox/io/watchdog.py (+4/-4)
checkbox/journal/multi.py (+3/-3)
checkbox/journal/reader.py (+2/-2)
checkbox/journal/tests/test_reader.py (+2/-2)
checkbox/journal/tests/test_writer.py (+2/-2)
checkbox/journal/writer.py (+21/-22)
checkbox/lib/fifo.py (+25/-10)
checkbox/lib/file.py (+19/-77)
checkbox/lib/tests/test_fifo.py (+3/-7)
checkbox/lib/tests/test_file.py (+38/-35)
checkbox/runner/manager.py (+3/-3)
checkbox/runner/starter.py (+2/-2)
To merge this branch: bzr merge lp:~sylvain-pineau/checkbox-core/bug983035
Reviewer Review Type Date Requested Status
Marc Tardif Needs Fixing
Sylvain Pineau (community) Needs Resubmitting
Review via email: mp+103270@code.launchpad.net

Description of the change

This MR replaces the file wrapper class with a new one that inherits of io.fileIO.
Classes depending on the old file interface have been updated as well.

To post a comment you must log in.
Revision history for this message
Marc Tardif (cr3) wrote :

Excellent work looking info fileobject.c! I just commented on the bug linked to this branch a couple minutes ago, do you think we should add more methods to this story?

review: Needs Information
15. By Marc Tardif

Merged from javier.collado's staticmethods branch.

16. By Marc Tardif

Preliminary submit and shadowd components.

17. By Marc Tardif

Merged from javier.collado's package-docstrings branch.

Revision history for this message
Sylvain Pineau (sylvain-pineau) wrote :

A new proposal based this time on io.FileIO

review: Needs Resubmitting
18. By Sylvain Pineau

merge trunk recent updates

19. By Sylvain Pineau

File class now inherits from io.FileIO

Revision history for this message
Sylvain Pineau (sylvain-pineau) wrote :

io.FileIO is now used as a base class to checkbox.lib.file

review: Needs Resubmitting
20. By Sylvain Pineau

Fix classes that now depends on the new File/io.FileIO class

Revision history for this message
Sylvain Pineau (sylvain-pineau) wrote :

I've fixed classes that used the old file interface to match the new way we built file objects.

review: Needs Resubmitting
21. By Sylvain Pineau

fix reamining calls to File.create_from*

22. By Sylvain Pineau

Remove unused import of File in watchdog.py

Revision history for this message
Marc Tardif (cr3) wrote :

Nice work, I'm very pleased about removing the create_from_* class methods and using None instead of an empty File instance! First, I don't think this logic is the same as before:

324 - if (self._user_enable
325 - and not self._openPath(path, self._file, lock=self._lock)):
326 + self._file = self._openPath(path, lock=self._lock)
327 + if (self._user_enable and not self._file):

Before, _openPath was only called if _user_enable is True. Now, _openPath is always called. Second, I think this code is a bit ambiguous because self._writer is not expected to be boolean:

141 + return self._writer == True

Even though your code probably works, I think it's more obvious to say something like: return self._writer is not None. Last, but not least, what would you think about changing Fifo.create_fifo to just be a function, instead of a class method, that would return a reader and writer tuple?

review: Needs Fixing
23. By Sylvain Pineau

Fix a call to _openPath in writer.py and rewrite the returned boolean of connect and listen functions in pipe.py

24. By Sylvain Pineau

Revert Fifo.create_fifo into a function instead of a class method returning a reader and writer tuple

Revision history for this message
Sylvain Pineau (sylvain-pineau) wrote :

Thanks for the review, I've made the suggested changes, both in code and tests.

review: Needs Resubmitting
Revision history for this message
Marc Tardif (cr3) wrote :

This code will raise an AttributeError when calling the close() method on a None object:

394 + file = create_file(fd, mode)
395 + if not file:
396 + file.close()

By removing the decorators in checkbox.lib.file, the file object no longer contains the errno attribute used like this in checkbox.daemon.pidentry for example:

  elif buffer is None \
       and file.errno != errno.EWOULDBLOCK \
       and file.errno != errno.EAGAIN:
      logging.info("Read failed for pid %d: %d", pipe_fd, file.errno)
      return False

A quick grep returned other places where file.errno is used. We might either want to reintroduce the previous decorators, but that still won't work in places like in checkbox.journal.multi where errno will be called on a None object. How would you address this problem?

By the way, I really like this unit test which clearly shows that the new behavior of fifo_create is much more elegant:

- read_file = File()
- write_file = File()
-
- self.assertTrue(fifo_create(self.path, read_file, write_file))
- self.assertNotEquals(read_file.fileno(), -1)
- self.assertNotEquals(write_file.fileno(), -1)
+ reader, writer = fifo_create(self.path)
+ self.assertNotEquals(reader.fileno(), -1)
+ self.assertNotEquals(writer.fileno(), -1)

review: Needs Fixing
Revision history for this message
Marc Tardif (cr3) wrote :

I just thought of a solution to solve the problem of having create_file somehow return an errno: instead of returning None when an error occurs, we could return the negative errno:

  file = create_file(path)
  if file < 0:
    logging.error("Failed to open file '%s'; errno = %d", path, -file)

This will work when create_file returns an actual object, so the code is safe. The only problem is that the value assigned to file is either an object or a negative integer. This might sound strange but it's not that much diffferent from returning None. For example, both a negative integer and None will raise an AttributeError when attempting to call file.read() when create_file fails. What do you think?

Revision history for this message
Sylvain Pineau (sylvain-pineau) wrote :

It's probably the best we can do to keep the calling code quite simple.

I was thinking to reintroduce the errno attribute to the File class, if the file object creation fails, returns the class and check for the errno. Given that the application if not threaded, it could be reliable:

class File(io.FileIO):

    __slots__ = (
        "errno",
        )

    def __init__(self, *args, **kwargs):
        super(File, self).__init__(*args, **kwargs)
        self.errno = 0

[...]

def create_file(*args, **kwargs):
    try:
        return File(*args, **kwargs)
    except (EnvironmentError, ValueError), error:
        f = File
        f.errno = error.errno
        return f

Even if I prefer your proposal, what do you think of mine ?

Unmerged revisions

24. By Sylvain Pineau

Revert Fifo.create_fifo into a function instead of a class method returning a reader and writer tuple

23. By Sylvain Pineau

Fix a call to _openPath in writer.py and rewrite the returned boolean of connect and listen functions in pipe.py

22. By Sylvain Pineau

Remove unused import of File in watchdog.py

21. By Sylvain Pineau

fix reamining calls to File.create_from*

20. By Sylvain Pineau

Fix classes that now depends on the new File/io.FileIO class

19. By Sylvain Pineau

File class now inherits from io.FileIO

18. By Sylvain Pineau

merge trunk recent updates

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'checkbox/daemon/pidentry.py'
2--- checkbox/daemon/pidentry.py 2012-04-23 19:36:19 +0000
3+++ checkbox/daemon/pidentry.py 2012-05-02 10:18:20 +0000
4@@ -26,7 +26,7 @@
5 import logging
6
7 from checkbox.lib.file import (
8- File,
9+ create_file,
10 fd_close,
11 )
12
13@@ -78,7 +78,7 @@
14 max_read_bytes = (
15 self.max_pipe_buffer - len(self.pipe_buffer[pipe_index]))
16
17- file = File.create_from_fd(pipe_fd, "r")
18+ file = create_file(pipe_fd, "r")
19 buffer = file.read(max_read_bytes)
20 if buffer:
21 self.pipe_buffer[pipe_index] += buffer
22@@ -100,7 +100,7 @@
23 data_left = buffer[self.stdin_offset:]
24 total_len = len(buffer)
25
26- file = File.create_from_fd(pipe_fd, "w")
27+ file = create_file(pipe_fd, "w")
28 bytes_written = file.write(data_left)
29
30 else:
31
32=== modified file 'checkbox/daemon/server.py'
33--- checkbox/daemon/server.py 2012-04-23 19:36:19 +0000
34+++ checkbox/daemon/server.py 2012-05-02 10:18:20 +0000
35@@ -52,7 +52,12 @@
36 from time import time
37
38 from checkbox.lib.enum import Enum
39-from checkbox.lib.file import File, fd_close, fd_get_flags, fd_set_flags
40+from checkbox.lib.file import (
41+ create_file,
42+ fd_close,
43+ fd_get_flags,
44+ fd_set_flags,
45+ )
46 from checkbox.lib.sigset import Sigset
47 from checkbox.lib.stat import Stat
48
49@@ -653,14 +658,14 @@
50 if size < 0:
51 raise Exception("Invalid size: %d" % size)
52
53- pipe_file = File.create_from_fd(pipe_end, "r")
54+ pipe_file = create_file(pipe_end, "r")
55 return pipe_file.read(size)
56
57 def writePipe(self, pipe_end, buffer):
58 if not buffer:
59 raise Exception("Invalid buffer, empty")
60
61- pipe_file = File.create_from_fd(pipe_end, "w")
62+ pipe_file = create_file(pipe_end, "w")
63 return pipe_file.write(buffer)
64
65 def closeFd(self, fd):
66
67=== modified file 'checkbox/io/fifo.py'
68--- checkbox/io/fifo.py 2012-04-24 22:43:09 +0000
69+++ checkbox/io/fifo.py 2012-05-02 10:18:20 +0000
70@@ -33,7 +33,7 @@
71 fifo_create,
72 )
73 from checkbox.lib.file import (
74- File,
75+ create_file,
76 fd_open,
77 fd_get_flags,
78 fd_set_flags
79@@ -78,7 +78,7 @@
80 self._pid = 0
81 self._serial_number = -1
82
83- self._dummy = File()
84+ self._dummy = None
85 self._state = FifoState.VIRGIN
86
87 def __del__(self):
88@@ -267,7 +267,8 @@
89
90 def _openReader(self, path):
91 # Keep dummy writer open so that reader never receives EOF
92- if not fifo_create(path, self._reader, self._dummy):
93+ self._reader, self._dummy = fifo_create(path)
94+ if not self._reader or not self._dummy:
95 logging.info("Failed to set fifo path at %s", path)
96 return False
97
98@@ -289,7 +290,7 @@
99 if fd_set_flags(write_fd, flags) < 0:
100 return False
101
102- self._writer.initialize_from_fd(write_fd, "w")
103+ self._writer = create_file(write_fd, "w")
104
105 return True
106
107
108=== modified file 'checkbox/io/pipe.py'
109--- checkbox/io/pipe.py 2012-04-23 19:36:19 +0000
110+++ checkbox/io/pipe.py 2012-05-02 10:18:20 +0000
111@@ -24,7 +24,7 @@
112
113 import logging
114
115-from checkbox.lib.file import File
116+from checkbox.lib.file import create_file
117
118 from checkbox.io.selector import (
119 Selector,
120@@ -54,8 +54,8 @@
121 super(Pipe, self).__init__()
122 self._fd = None
123 self._bytes = ""
124- self._reader = File()
125- self._writer = File()
126+ self._reader = None
127+ self._writer = None
128 self._watchdog_client = None
129 self._watchdog_server = None
130
131@@ -71,11 +71,13 @@
132
133 def connect(self, fd):
134 self._fd = fd
135- return self._writer.initialize_from_fd(fd, "w") == 0
136+ self._writer = create_file(fd, "w")
137+ return self._writer is not None
138
139 def listen(self, fd):
140 self._fd = fd
141- return self._reader.initialize_from_fd(fd, "r") == 0
142+ self._reader = create_file(fd, "r")
143+ return self._reader is not None
144
145 def handleIncomingMessage(self):
146 """Receive messages from the reader and buffer them.
147
148=== modified file 'checkbox/io/watchdog.py'
149--- checkbox/io/watchdog.py 2012-04-23 19:36:19 +0000
150+++ checkbox/io/watchdog.py 2012-05-02 10:18:20 +0000
151@@ -28,7 +28,6 @@
152
153 from checkbox.lib.fifo import fifo_create
154 from checkbox.lib.file import (
155- File,
156 fd_open,
157 fd_close,
158 )
159@@ -88,8 +87,8 @@
160
161 def __init__(self):
162 self._path = None
163- self._reader = File()
164- self._writer = File()
165+ self._reader = None
166+ self._writer = None
167
168 def __del__(self):
169 self.reset()
170@@ -108,7 +107,8 @@
171 return False
172
173 path += WATCHDOG_SUFFIX
174- if not fifo_create(path, self._reader, self._writer):
175+ self._reader, self._writer = fifo_create(path)
176+ if not self._reader or not self._writer:
177 logging.info("Failed to set watched fifo path at %s", path)
178 return False
179
180
181=== modified file 'checkbox/journal/multi.py'
182--- checkbox/journal/multi.py 2012-04-24 13:23:07 +0000
183+++ checkbox/journal/multi.py 2012-05-02 10:18:20 +0000
184@@ -30,7 +30,7 @@
185
186 from checkbox.lib.directory import Directory
187 from checkbox.lib.file import (
188- File,
189+ create_file,
190 fd_open,
191 fd_close,
192 )
193@@ -74,7 +74,7 @@
194
195 :param filename: Filename to read.
196 """
197- file = File.create_from_path(filename, "r")
198+ file = create_file(filename, "r")
199 if not file:
200 logging.debug(
201 "Failed to open '%s' with errno %d", filename, file.errno)
202@@ -184,7 +184,7 @@
203 if directory:
204 submit_filename = os.path.join(directory, submit_filename)
205
206- file = File.create_from_path(submit_filename, "r")
207+ file = create_file(submit_filename, "r")
208 if not file:
209 logging.debug(
210 "Failed to open '%s' with errno %d",
211
212=== modified file 'checkbox/journal/reader.py'
213--- checkbox/journal/reader.py 2012-04-23 19:36:19 +0000
214+++ checkbox/journal/reader.py 2012-05-02 10:18:20 +0000
215@@ -31,7 +31,7 @@
216 from checkbox.lib import param
217 from checkbox.lib.enum import Enum
218 from checkbox.lib.file import (
219- File,
220+ create_file,
221 fd_open,
222 fd_close,
223 )
224@@ -644,7 +644,7 @@
225 return EventOutcome.READ_ERROR
226
227 try:
228- self._file = File.create_from_fd(self._fd, "r")
229+ self._file = create_file(self._fd, "r")
230 except OSError:
231 self._closeJournalFile(True)
232 return EventOutcome.READ_ERROR
233
234=== modified file 'checkbox/journal/tests/test_reader.py'
235--- checkbox/journal/tests/test_reader.py 2012-04-23 19:36:19 +0000
236+++ checkbox/journal/tests/test_reader.py 2012-05-02 10:18:20 +0000
237@@ -26,7 +26,7 @@
238
239 from tempfile import mkstemp
240
241-from checkbox.lib.file import File
242+from checkbox.lib.file import create_file
243
244 from checkbox.journal.event import (
245 Event,
246@@ -45,7 +45,7 @@
247
248 def setUp(self):
249 (fd, self.path) = mkstemp()
250- self.file = File.create_from_fd(fd)
251+ self.file = create_file(fd)
252
253 os.environ["EVENT_JOURNAL"] = self.path
254
255
256=== modified file 'checkbox/journal/tests/test_writer.py'
257--- checkbox/journal/tests/test_writer.py 2012-04-23 19:36:19 +0000
258+++ checkbox/journal/tests/test_writer.py 2012-05-02 10:18:20 +0000
259@@ -27,7 +27,7 @@
260 from tempfile import mkstemp
261 from StringIO import StringIO
262
263-from checkbox.lib.file import File
264+from checkbox.lib.file import create_file
265
266 from checkbox.journal.event import (
267 Event,
268@@ -40,7 +40,7 @@
269
270 def setUp(self):
271 (fd, self.path) = mkstemp()
272- self.file = File.create_from_fd(fd)
273+ self.file = create_file(fd)
274
275 os.environ["EVENT_JOURNAL"] = self.path
276
277
278=== modified file 'checkbox/journal/writer.py'
279--- checkbox/journal/writer.py 2012-04-23 19:36:19 +0000
280+++ checkbox/journal/writer.py 2012-05-02 10:18:20 +0000
281@@ -34,7 +34,7 @@
282 )
283 from checkbox.lib.file import (
284 FILE_NULL,
285- File,
286+ create_file,
287 fd_open,
288 fd_close,
289 )
290@@ -96,13 +96,13 @@
291
292 self._user_enable = True
293 self._path = ""
294- self._file = File()
295+ self._file = None
296 self._lock = Lock()
297 self._enable_fsync = True
298 self._enable_locking = True
299
300 self._global_path = ""
301- self._global_file = File()
302+ self._global_file = None
303 self._global_lock = Lock()
304 self._global_stat = None
305
306@@ -186,12 +186,13 @@
307 self._path = path
308
309 # Reset local resources
310- self._file.reset()
311+ self._file = None
312 self._lock.reset()
313
314- if (self._user_enable
315- and not self._openPath(path, self._file, lock=self._lock)):
316- return False
317+ if self._user_enable:
318+ self._file = self._openPath(path, lock=self._lock)
319+ if not self._file:
320+ return False
321
322 return self.initialize()
323
324@@ -200,13 +201,14 @@
325 self._global_lock.reset()
326
327 if self._global_file:
328- self._global_file.reset()
329+ self._global_file = None
330
331 if not self._global_path:
332 return True
333
334- if not self._openPath(
335- self._global_path, self._global_file, lock=self._global_lock):
336+ self._global_file = self._openPath(
337+ self._global_path, lock=self._global_lock)
338+ if not self._global_file:
339 return False
340
341 stat = Stat()
342@@ -290,7 +292,7 @@
343 # Rotate the journal
344
345 # Read the old header, use it to write an updated one
346- file = File.create_from_path(self._global_path, "r")
347+ file = create_file(self._global_path, "r")
348 if not file:
349 logging.debug("Failed to open '%s'", self._global_path)
350
351@@ -311,12 +313,11 @@
352
353 header_reader.num_events = events
354
355- file.reset()
356-
357 header_reader.size = current_filesize
358
359 # Craft a header writer object from the header reader
360- if not self._openPath(self._global_path, file, False):
361+ file = self._openPath(self._global_path, False)
362+ if not file:
363 logging.debug(
364 "Failed to open '%s' for header rewrite", self._global_path)
365
366@@ -381,7 +382,7 @@
367 return True
368
369 # Reset global resources
370- self._global_file.reset()
371+ self._global_file = None
372 self._global_lock.reset()
373 self._global_stat = None
374
375@@ -430,9 +431,8 @@
376
377 return True
378
379- def _openPath(self, path, file, append=True, lock=None):
380+ def _openPath(self, path, append=True, lock=None):
381 if path and path == FILE_NULL:
382- file.reset()
383 if lock is not None:
384 lock.reset()
385 return True
386@@ -446,16 +446,15 @@
387 return False
388
389 mode = "a" if append else "w"
390- try:
391- file.initialize_from_fd(fd, mode)
392- except OSError:
393- fd_close(fd)
394+ file = create_file(fd, mode)
395+ if not file:
396+ file.close()
397 return False
398
399 if lock is not None:
400 lock.initialize(fd, file)
401
402- return True
403+ return file
404
405 def writeEvent(self, event):
406 """Write an event to the journal file.
407
408=== modified file 'checkbox/lib/fifo.py'
409--- checkbox/lib/fifo.py 2012-04-23 19:36:19 +0000
410+++ checkbox/lib/fifo.py 2012-05-02 10:18:20 +0000
411@@ -30,13 +30,18 @@
412 from checkbox.lib.file import (
413 fd_open,
414 fd_close,
415+ create_file,
416 )
417
418
419 FIFO_BUF = 512
420
421
422-def fifo_create(path, reader, writer):
423+def fifo_create(path):
424+ reader = None
425+ writer = None
426+ uninitialized_fh = reader, writer
427+
428 # Check that fifo doesn't exist
429 if os.path.exists(path):
430 os.unlink(path)
431@@ -46,13 +51,18 @@
432 os.mkfifo(path, 0600)
433 except OSError, error:
434 logging.info("Failed to create fifo %s: %d", path, error.errno)
435- return False
436+ return uninitialized_fh
437
438 # Open read side of the fifo initially in non-blocking mode
439 read_fd = fd_open(path, os.O_RDONLY | os.O_NONBLOCK)
440 if read_fd == -1:
441 logging.info("Failed to open read-only %s", path)
442- return False
443+ return uninitialized_fh
444+ reader = create_file(read_fd, "r")
445+ if not reader:
446+ logging.info("Failed to initialize file descriptors.")
447+ fd_close(read_fd)
448+ return uninitialized_fh
449
450 # Set the fifo back to blocking mode
451 flags = fcntl.fcntl(read_fd, fcntl.F_GETFL)
452@@ -63,14 +73,19 @@
453 if write_fd == -1:
454 logging.info("Failed to open write-only %s", path)
455 fd_close(read_fd)
456- return False
457-
458- if (reader.initialize_from_fd(read_fd, "r") or
459- writer.initialize_from_fd(write_fd, "w")):
460+ return uninitialized_fh
461+ writer = create_file(write_fd, "w")
462+ if not writer:
463 logging.info("Failed to initialize file descriptors.")
464 fd_close(write_fd)
465- fd_close(read_fd)
466- return False
467+ reader.close()
468+ return uninitialized_fh
469+
470+ if (not reader.readable() or not writer.writable()):
471+ logging.info("Failed to initialize file descriptors.")
472+ writer.close()
473+ reader.close()
474+ return uninitialized_fh
475
476 # Everything worked
477- return True
478+ return reader, writer
479
480=== modified file 'checkbox/lib/file.py'
481--- checkbox/lib/file.py 2012-04-23 19:36:19 +0000
482+++ checkbox/lib/file.py 2012-05-02 10:18:20 +0000
483@@ -21,6 +21,7 @@
484 __all__ = [
485 "FILE_NULL",
486 "File",
487+ "create_file",
488 "fd_open",
489 "fd_close",
490 "fd_get_flags",
491@@ -28,92 +29,33 @@
492 ]
493
494 import os
495+import io
496 import fcntl
497
498-from checkbox.lib.decorators import CheckException
499-
500
501 FILE_NULL = "/dev/null"
502
503
504-class CheckError(CheckException):
505-
506- def onError(self, error):
507- self._instance.errno = error.errno
508-
509-
510-def check_error(default=None):
511-
512- def wrapper(func):
513- return CheckError(func, default, EnvironmentError)
514-
515- return wrapper
516-
517-
518-class File:
519-
520- __slots__ = (
521- "info",
522- "errno",
523- )
524-
525- def __init__(self):
526- self.info = None
527- self.errno = 0
528-
529- @classmethod
530- def create_from_path(cls, *args, **kwargs):
531- file = cls()
532- file.initialize_from_path(*args, **kwargs)
533-
534- return file
535-
536- @classmethod
537- def create_from_fd(cls, *args, **kwargs):
538- file = cls()
539- file.initialize_from_fd(*args, **kwargs)
540-
541- return file
542-
543- @check_error(-1)
544- def initialize_from_path(self, *args, **kwargs):
545- self.info = open(*args, **kwargs)
546- return 0
547-
548- @check_error(-1)
549- def initialize_from_fd(self, *args, **kwargs):
550- self.info = os.fdopen(*args, **kwargs)
551- return 0
552-
553- def copy_from(self, other):
554- self.info = other.info
555-
556- def reset(self):
557- self.info = None
558- self.errno = 0
559-
560- @check_error(None)
561+class File(io.FileIO):
562+
563 def read(self, size):
564- # Return something useful
565- return os.read(self.info.fileno(), size)
566+ try:
567+ return super(File, self).read(size)
568+ except (EnvironmentError, ValueError):
569+ return None
570
571- @check_error(-1)
572 def write(self, buffer):
573- # Return something useful
574- return os.write(self.info.fileno(), buffer)
575-
576- @check_error(None)
577- def __getattr__(self, name):
578- return getattr(self.info, name)
579-
580- def __setattr__(self, name, value):
581- if name in File.__slots__:
582- return super(File, self).__setattr__(name, value)
583-
584- return setattr(self.info, name, value)
585-
586- def __nonzero__(self):
587- return self.info is not None
588+ try:
589+ return super(File, self).write(buffer)
590+ except (EnvironmentError, ValueError):
591+ return -1
592+
593+
594+def create_file(*args, **kwargs):
595+ try:
596+ return File(*args, **kwargs)
597+ except (EnvironmentError, ValueError):
598+ return None
599
600
601 def fd_open(path, flag, *args, **kwargs):
602
603=== modified file 'checkbox/lib/tests/test_fifo.py'
604--- checkbox/lib/tests/test_fifo.py 2012-04-23 19:36:19 +0000
605+++ checkbox/lib/tests/test_fifo.py 2012-05-02 10:18:20 +0000
606@@ -26,7 +26,6 @@
607 from unittest import TestCase
608
609 from checkbox.lib.fifo import fifo_create
610-from checkbox.lib.file import File
611
612
613 class TestFifo(TestCase):
614@@ -39,9 +38,6 @@
615 os.unlink(self.path)
616
617 def test_fifo_create(self):
618- read_file = File()
619- write_file = File()
620-
621- self.assertTrue(fifo_create(self.path, read_file, write_file))
622- self.assertNotEquals(read_file.fileno(), -1)
623- self.assertNotEquals(write_file.fileno(), -1)
624+ reader, writer = fifo_create(self.path)
625+ self.assertNotEquals(reader.fileno(), -1)
626+ self.assertNotEquals(writer.fileno(), -1)
627
628=== modified file 'checkbox/lib/tests/test_file.py'
629--- checkbox/lib/tests/test_file.py 2012-04-23 19:36:19 +0000
630+++ checkbox/lib/tests/test_file.py 2012-05-02 10:18:20 +0000
631@@ -21,6 +21,7 @@
632 __all__ = []
633
634 import os
635+from io import (SEEK_SET, SEEK_CUR)
636
637 from unittest import TestCase
638
639@@ -30,7 +31,7 @@
640 )
641
642 from checkbox.lib.file import (
643- File,
644+ create_file,
645 fd_open,
646 fd_close,
647 )
648@@ -46,40 +47,15 @@
649 if os.path.exists(self.path):
650 os.unlink(self.path)
651
652- def test_init(self):
653- file = File()
654- self.assertFalse(file)
655-
656- def test_create_from_path(self):
657- file = File.create_from_path(self.path)
658- self.assertEquals(file.errno, 0)
659- self.assertTrue(file)
660-
661- file = File.create_from_path(self.temp)
662- self.assertEquals(file.errno, 2)
663- self.assertFalse(file)
664-
665- def test_initialize_from_fd(self):
666- file = File.create_from_fd(self.fd)
667- self.assertEquals(file.errno, 0)
668- self.assertTrue(file)
669-
670- file = File.create_from_fd(-1)
671- self.assertEquals(file.errno, 9)
672- self.assertFalse(file)
673-
674- def test_reset(self):
675- file = File.create_from_path(self.path)
676- self.assertTrue(file)
677-
678- file.reset()
679- self.assertFalse(file)
680-
681- file = File.create_from_path(self.temp)
682- self.assertEquals(file.errno, 2)
683-
684- file.reset()
685- self.assertEquals(file.errno, 0)
686+ def test_create_file(self):
687+ file = create_file(self.path)
688+ self.assertTrue(file)
689+
690+ file = create_file(self.temp)
691+ self.assertFalse(file)
692+
693+ file = create_file(0xFFFF)
694+ self.assertFalse(file)
695
696 def test_fd_open(self):
697 fd = fd_open(self.path, os.O_RDONLY)
698@@ -94,3 +70,30 @@
699
700 ret = fd_close(-1)
701 self.assertEquals(ret, -1)
702+
703+ def test_tell_seek(self):
704+ file = create_file(self.fd, 'w')
705+ self.assertTrue(file)
706+
707+ self.assertEquals(file.tell(), 0)
708+ pos = file.write('ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890')
709+ self.assertEquals(pos, 36)
710+ self.assertEquals(file.tell(), 36)
711+ file.close()
712+
713+ file = create_file(self.path)
714+ self.assertTrue(file)
715+
716+ self.assertEquals(file.tell(), 0)
717+ str = file.read(4)
718+ self.assertEquals(str, 'ABCD')
719+ self.assertEquals(file.tell(), 4)
720+
721+ file.seek(14, SEEK_CUR)
722+ self.assertEquals(file.tell(), 18)
723+
724+ os.lseek(file.fileno(), 28, SEEK_SET)
725+ self.assertEquals(file.tell(), 28)
726+ str = file.read(1)
727+ self.assertEquals(str, '3')
728+ self.assertEquals(file.tell(), 29)
729
730=== modified file 'checkbox/runner/manager.py'
731--- checkbox/runner/manager.py 2012-04-23 19:36:19 +0000
732+++ checkbox/runner/manager.py 2012-05-02 10:18:20 +0000
733@@ -26,7 +26,7 @@
734 import logging
735
736 from checkbox.lib import param
737-from checkbox.lib.file import File
738+from checkbox.lib.file import create_file
739
740 from checkbox.daemon.server import server
741
742@@ -214,9 +214,9 @@
743
744 if self._output_record_is_stdout:
745 logging.info("Will write output record to STDOUT")
746- file = File.create_from_fd(1)
747+ file = create_file(1)
748 else:
749- file = File.create_from_path(self._output_record_path, "a")
750+ file = create_file(self._output_record_path, "a")
751 if not file:
752 logging.info(
753 "Failed to open output record '%s': %s",
754
755=== modified file 'checkbox/runner/starter.py'
756--- checkbox/runner/starter.py 2012-04-23 19:36:19 +0000
757+++ checkbox/runner/starter.py 2012-05-02 10:18:20 +0000
758@@ -30,7 +30,7 @@
759
760 from checkbox.lib import param
761 from checkbox.lib.enum import Enum
762-from checkbox.lib.file import File
763+from checkbox.lib.file import create_file
764
765 from checkbox.daemon.server import (
766 server,
767@@ -190,7 +190,7 @@
768 self._execute_directory, "%d.recover" % server.pid)
769
770 tmp_path = "%s.tmp" % self._recovery_path
771- tmp_file = File.create_from_path(tmp_path, "w")
772+ tmp_file = create_file(tmp_path, "w")
773 if not tmp_file:
774 logging.info("Failed to open recovery file %s", tmp_path)
775 return

Subscribers

People subscribed via source and target branches

to all changes: