Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Unified Diff: build/android/pylib/base/output_manager.py

Issue 2933993002: Add local results details pages.
Patch Set: Add --local-output arg which enables local results detail pages. Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..4a757da22b1a85a7234677a156a34930d01fe405
--- /dev/null
+++ b/build/android/pylib/base/output_manager.py
@@ -0,0 +1,110 @@
+# 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
jbudorick 2017/08/10 16:27:37 nit: maybe allow_save or allow_archive, since this
+ self._thread_group = None
+
+ def ArchiveAndDeleteFile(
+ self, in_filepath, out_filename, out_subdir, datatype=Datatype.TEXT):
+ """Archive file contents asynchonously and then deletes file.
+
+ Example Usage.
+
+ try:
+ // Create non-temporary File. Upload is done asynchonously.
+ file = ...
+ file.write(...)
+ finally:
+ output_manager.ArchiveAndDeleteFile(...)
+
+ Args:
+ in_filepath: Path for file you want to archive.
+ out_filename: Name for saved file.
+ out_subdir: Directory to save |out_file| in.
+ datatype: Datatype of file.
+
+ Returns:
+ A link to where the contents of the file will be archived.
+ """
+ if not self._allow_upload:
+ raise Exception('Must run |SetUp| before attempting to upload!')
+
+ job = self._CreateArchiveJob(
+ in_filepath, out_filename, out_subdir, datatype)
+
+ if job is None:
+ return ''
+
+ def archive():
+ try:
+ job.Archive()
+ finally:
+ os.remove(in_filepath)
+
+ 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):
+ """Returns location of archived file.
+
+ Note that this function will almost certainly be used before the file
+ has finished being archived. Therefore, this needs to know the exact
+ location of the archived file before it is archived.
+ """
+ raise NotImplementedError
+
+ def Archive(self):
+ """Archives file."""
+ raise NotImplementedError

Powered by Google App Engine
This is Rietveld 408576698