Chromium Code Reviews| Index: build/android/pylib/base/output_manager.py |
| diff --git a/build/android/pylib/base/output_manager.py b/build/android/pylib/base/output_manager.py |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..fe5359fd4d9ab30c9e426bc7201129a65aace1f5 |
| --- /dev/null |
| +++ b/build/android/pylib/base/output_manager.py |
| @@ -0,0 +1,102 @@ |
| +# Copyright 2017 The Chromium Authors. All rights reserved. |
| +# Use of this source code is governed by a BSD-style license that can be |
| +# found in the LICENSE file. |
| + |
| +import logging |
| +import os |
| + |
| +from devil.utils import reraiser_thread |
| + |
| + |
| +class Datatype(object): |
| + HTML = 'html' |
| + IMAGE = 'image' |
| + TEXT = 'text' |
| + |
| + |
| +class OutputManager(object): |
| + |
| + def __init__(self): |
| + """OutputManager Constructor. |
| + |
| + This class provides a simple interface to save test output. Subclasses |
| + of this will allow users to save test results in the cloud or locally. |
| + """ |
| + self._allow_upload = False |
| + self._thread_group = None |
| + |
| + def ArchiveAndDeleteFile( |
| + self, in_filename, out_filename, out_subdir, datatype=Datatype.TEXT): |
| + """Context manager used to archive file contents asynchonously. |
|
jbudorick
2017/07/19 22:45:09
This doesn't appear to be a context manager any mo
mikecase (-- gone --)
2017/07/26 21:21:37
Done
|
| + |
| + Example Usage. |
| + |
| + try: |
| + // Create non-temporary File. Upload is done asynchonously. |
| + file = ... |
| + file.write(...) |
| + finally: |
| + output_manager.ArchiveAndDeleteFile() |
|
jbudorick
2017/07/19 22:45:09
This example doesn't pass any arguments to Archive
mikecase (-- gone --)
2017/07/26 21:21:37
Done
|
| + |
| + Args: |
|
jbudorick
2017/07/19 22:45:09
in_filename?
mikecase (-- gone --)
2017/07/26 21:21:37
Done
|
| + out_filename: Name for saved file. |
| + out_subdir: Directory to save |out_file| in. |
| + datatype: Datatype of file. |
| + |
| + Yields: |
|
jbudorick
2017/07/19 22:45:09
nit: Returns, not Yields
mikecase (-- gone --)
2017/07/26 21:21:37
Yeah, I changed the implementation a bunch. Seems
|
| + A tuple (filename, link). Filename is a file you write to and link is a |
| + URL to where the contents of the file will end up. |
| + """ |
| + assert self._allow_upload, 'Must run |SetUp| before attempting to upload!' |
|
jbudorick
2017/07/19 22:45:09
Do this w/ an explicit exception rather than an as
mikecase (-- gone --)
2017/07/26 21:21:37
Done
|
| + |
| + job = self._CreateArchiveJob( |
| + in_filename, out_filename, out_subdir, datatype) |
| + |
| + if job is None: |
| + return '' |
| + |
| + def archive(): |
| + try: |
| + job.Archive() |
| + finally: |
| + os.remove(in_filename) |
| + |
| + thread = reraiser_thread.ReraiserThread(func=archive) |
| + thread.start() |
| + self._thread_group.Add(thread) |
| + return job.Link() |
| + |
| + def _CreateArchiveJob(self, in_filepath, out_filename, out_subdir, datatype): |
| + """Returns an instance of Job that actually uploads/saves the file.""" |
| + raise NotImplementedError |
| + |
| + def SetUp(self): |
| + self._allow_upload = True |
| + self._thread_group = reraiser_thread.ReraiserThreadGroup() |
| + |
| + def TearDown(self): |
| + self._allow_upload = False |
| + logging.info('Finishing archiving output.') |
| + self._thread_group.JoinAll() |
| + |
| + def __enter__(self): |
| + self.SetUp() |
| + return self |
| + |
| + def __exit__(self, _exc_type, _exc_val, _exc_tb): |
| + self.TearDown() |
| + |
| + |
| +class Job(object): |
| + |
| + def __init__(self, in_filepath, out_filename, out_subdir, datatype): |
| + self._in_filepath = in_filepath |
| + self._out_filename = out_filename |
| + self._out_subdir = out_subdir |
| + self._datatype = datatype |
| + |
| + def Link(self): |
| + raise NotImplementedError |
| + |
| + def Archive(self): |
| + raise NotImplementedError |