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