1 |
commit: 7b8f57335c43054fe4008b7401d6ac2b3f710c1a |
2 |
Author: Zac Medico <zmedico <AT> gentoo <DOT> org> |
3 |
AuthorDate: Wed Nov 6 08:03:36 2019 +0000 |
4 |
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> |
5 |
CommitDate: Wed Nov 6 20:05:27 2019 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=7b8f5733 |
7 |
|
8 |
FileCopier: capture exceptions |
9 |
|
10 |
Use ForkExecutor to capture exceptions instead of showing |
11 |
a full traceback. FileCopier callers will now be responsible |
12 |
for displaying relevant exception messages. |
13 |
|
14 |
Bug: https://bugs.gentoo.org/699400 |
15 |
Signed-off-by: Zac Medico <zmedico <AT> gentoo.org> |
16 |
|
17 |
lib/portage/tests/util/test_file_copier.py | 44 ++++++++++++++++++++++++++++++ |
18 |
lib/portage/util/_async/FileCopier.py | 16 ++++++----- |
19 |
2 files changed, 53 insertions(+), 7 deletions(-) |
20 |
|
21 |
diff --git a/lib/portage/tests/util/test_file_copier.py b/lib/portage/tests/util/test_file_copier.py |
22 |
new file mode 100644 |
23 |
index 000000000..01dfba494 |
24 |
--- /dev/null |
25 |
+++ b/lib/portage/tests/util/test_file_copier.py |
26 |
@@ -0,0 +1,44 @@ |
27 |
+# Copyright 2019 Gentoo Authors |
28 |
+# Distributed under the terms of the GNU General Public License v2 |
29 |
+ |
30 |
+import errno |
31 |
+import os |
32 |
+import shutil |
33 |
+import tempfile |
34 |
+ |
35 |
+from portage.tests import TestCase |
36 |
+from portage.util._async.FileCopier import FileCopier |
37 |
+from portage.util._eventloop.global_event_loop import global_event_loop |
38 |
+ |
39 |
+ |
40 |
+class FileCopierTestCase(TestCase): |
41 |
+ |
42 |
+ def testFileCopier(self): |
43 |
+ loop = global_event_loop() |
44 |
+ tempdir = tempfile.mkdtemp() |
45 |
+ try: |
46 |
+ |
47 |
+ # regular successful copy |
48 |
+ src_path = os.path.join(tempdir, 'src') |
49 |
+ dest_path = os.path.join(tempdir, 'dest') |
50 |
+ content = b'foo' |
51 |
+ with open(src_path, 'wb') as f: |
52 |
+ f.write(content) |
53 |
+ copier = FileCopier(src_path=src_path, dest_path=dest_path, scheduler=loop) |
54 |
+ copier.start() |
55 |
+ loop.run_until_complete(copier.async_wait()) |
56 |
+ self.assertEqual(copier.returncode, 0) |
57 |
+ copier.future.result() |
58 |
+ with open(dest_path, 'rb') as f: |
59 |
+ self.assertEqual(f.read(), content) |
60 |
+ |
61 |
+ # failure due to nonexistent src_path |
62 |
+ src_path = os.path.join(tempdir, 'does-not-exist') |
63 |
+ copier = FileCopier(src_path=src_path, dest_path=dest_path, scheduler=loop) |
64 |
+ copier.start() |
65 |
+ loop.run_until_complete(copier.async_wait()) |
66 |
+ self.assertEqual(copier.returncode, 1) |
67 |
+ self.assertEqual(copier.future.exception().errno, errno.ENOENT) |
68 |
+ self.assertEqual(copier.future.exception().filename, src_path.encode('utf8')) |
69 |
+ finally: |
70 |
+ shutil.rmtree(tempdir) |
71 |
|
72 |
diff --git a/lib/portage/util/_async/FileCopier.py b/lib/portage/util/_async/FileCopier.py |
73 |
index 27e5ab4c0..3a0be4b63 100644 |
74 |
--- a/lib/portage/util/_async/FileCopier.py |
75 |
+++ b/lib/portage/util/_async/FileCopier.py |
76 |
@@ -1,17 +1,19 @@ |
77 |
-# Copyright 2013 Gentoo Foundation |
78 |
+# Copyright 2013-2019 Gentoo Authors |
79 |
# Distributed under the terms of the GNU General Public License v2 |
80 |
|
81 |
-from portage import os |
82 |
from portage import shutil |
83 |
-from portage.util._async.ForkProcess import ForkProcess |
84 |
+from portage.util.futures import asyncio |
85 |
+from portage.util.futures.executor.fork import ForkExecutor |
86 |
+from portage.util._async.AsyncTaskFuture import AsyncTaskFuture |
87 |
|
88 |
-class FileCopier(ForkProcess): |
89 |
+class FileCopier(AsyncTaskFuture): |
90 |
""" |
91 |
Asynchronously copy a file. |
92 |
""" |
93 |
|
94 |
__slots__ = ('src_path', 'dest_path') |
95 |
|
96 |
- def _run(self): |
97 |
- shutil.copy(self.src_path, self.dest_path) |
98 |
- return os.EX_OK |
99 |
+ def _start(self): |
100 |
+ self.future = asyncio.ensure_future(self.scheduler.run_in_executor(ForkExecutor(loop=self.scheduler), |
101 |
+ shutil.copy, self.src_path, self.dest_path)) |
102 |
+ super(FileCopier, self)._start() |