Add ability to override the log alias directory. (#584)
diff --git a/mobly/logger.py b/mobly/logger.py
index fba6b2d..a68398e 100644
--- a/mobly/logger.py
+++ b/mobly/logger.py
@@ -187,29 +187,36 @@
h.close()
-def create_latest_log_alias(actual_path):
+def create_latest_log_alias(actual_path, alias):
"""Creates a symlink to the latest test run logs.
Args:
- actual_path: The source directory where the latest test run's logs are.
+ actual_path: string, the source directory where the latest test run's
+ logs are.
+ alias: string, the name of the directory to contain the latest log
+ files.
"""
- alias_path = os.path.join(os.path.dirname(actual_path), 'latest')
+ alias_path = os.path.join(os.path.dirname(actual_path), alias)
utils.create_alias(actual_path, alias_path)
-def setup_test_logger(log_path, prefix=None, filename=None):
+def setup_test_logger(log_path, prefix=None, alias='latest'):
"""Customizes the root logger for a test run.
Args:
- log_path: Location of the report file.
- prefix: A prefix for each log line in terminal.
- filename: Name of the files. The default is the time the objects
- are requested.
+ log_path: string, the location of the report file.
+ prefix: optional string, a prefix for each log line in terminal.
+ alias: optional string, The name of the alias to use for the latest log
+ directory. If a falsy value is provided, then the alias directory
+ will not be created, which is useful to save storage space when the
+ storage system (e.g. ZIP files) does not properly support
+ shortcut/symlinks.
"""
utils.create_dir(log_path)
_setup_test_logger(log_path, prefix)
logging.info('Test output folder: "%s"', log_path)
- create_latest_log_alias(log_path)
+ if alias:
+ create_latest_log_alias(log_path, alias=alias)
def normalize_log_line_timestamp(log_line_timestamp):
diff --git a/mobly/test_runner.py b/mobly/test_runner.py
index f67dede..65e5149 100644
--- a/mobly/test_runner.py
+++ b/mobly/test_runner.py
@@ -219,16 +219,23 @@
self._log_path = None
@contextlib.contextmanager
- def mobly_logger(self):
+ def mobly_logger(self, alias='latest'):
"""Starts and stops a logging context for a Mobly test run.
+ Args:
+ alias: optional string, the name of the latest log alias directory to
+ create. If a falsy value is specified, then the directory will not
+ be created.
+
Yields:
The host file path where the logs for the test run are stored.
"""
self._start_time = logger.get_log_file_timestamp()
self._log_path = os.path.join(self._log_dir, self._test_bed_name,
self._start_time)
- logger.setup_test_logger(self._log_path, self._test_bed_name)
+ logger.setup_test_logger(self._log_path,
+ self._test_bed_name,
+ alias=alias)
try:
yield self._log_path
finally:
diff --git a/tests/mobly/logger_test.py b/tests/mobly/logger_test.py
index 2adc08a..2e34d46 100755
--- a/tests/mobly/logger_test.py
+++ b/tests/mobly/logger_test.py
@@ -12,8 +12,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import unittest
+import mock
import pytz
+import shutil
+import tempfile
+import unittest
from mobly import logger
@@ -21,10 +24,15 @@
class LoggerTest(unittest.TestCase):
"""Verifies code in mobly.logger module.
"""
+ def setUp(self):
+ self.log_dir = tempfile.mkdtemp()
+
+ def tearDown(self):
+ shutil.rmtree(self.log_dir)
def test_epoch_to_log_line_timestamp(self):
- actual_stamp = logger.epoch_to_log_line_timestamp(
- 1469134262116, time_zone=pytz.utc)
+ actual_stamp = logger.epoch_to_log_line_timestamp(1469134262116,
+ time_zone=pytz.utc)
self.assertEqual("07-21 20:51:02.116", actual_stamp)
def test_is_valid_logline_timestamp(self):
@@ -39,6 +47,31 @@
self.assertFalse(
logger.is_valid_logline_timestamp("------------------"))
+ @mock.patch('mobly.utils.create_alias')
+ def test_create_latest_log_alias(self, mock_create_alias):
+ logger.create_latest_log_alias('fake_path', alias='latest')
+ mock_create_alias.assert_called_once_with('fake_path', 'latest')
+
+ @mock.patch('mobly.logger._setup_test_logger')
+ @mock.patch('mobly.logger.create_latest_log_alias')
+ def test_setup_test_logger_creates_log_alias(self,
+ mock_create_latest_log_alias,
+ mock__setup_test_logger):
+ logger.setup_test_logger(self.log_dir)
+ mock__setup_test_logger.assert_called_once_with(self.log_dir, None)
+ mock_create_latest_log_alias.assert_called_once_with(self.log_dir,
+ alias='latest')
+
+ @mock.patch('mobly.logger._setup_test_logger')
+ @mock.patch('mobly.logger.create_latest_log_alias')
+ def test_setup_test_logger_creates_log_alias_with_custom_value(
+ self, mock_create_latest_log_alias, mock__setup_test_logger):
+ mock_alias = mock.MagicMock()
+ logger.setup_test_logger(self.log_dir, alias=mock_alias)
+
+ mock_create_latest_log_alias.assert_called_once_with(self.log_dir,
+ alias=mock_alias)
+
if __name__ == "__main__":
unittest.main()
diff --git a/tests/mobly/output_test.py b/tests/mobly/output_test.py
index 743c342..6762684 100755
--- a/tests/mobly/output_test.py
+++ b/tests/mobly/output_test.py
@@ -132,6 +132,52 @@
win32file.GetLongPathName(logging.log_path))
self.assertEqual(normalized_shortcut_path, normalized_logger_path)
+ @mock.patch('mobly.utils.create_alias')
+ def test_mobly_logger_with_default_latest_log_alias(
+ self, mock_create_alias):
+ mock_test_config = self.create_mock_test_config(
+ self.base_mock_test_config)
+ tr = test_runner.TestRunner(self.log_dir, self.test_bed_name)
+ with tr.mobly_logger():
+ pass
+ expected_alias_dir = os.path.join(self.log_dir, self.test_bed_name,
+ 'latest')
+ mock_create_alias.assert_called_once_with(logging.log_path,
+ expected_alias_dir)
+
+ @mock.patch('mobly.utils.create_alias')
+ def test_mobly_logger_with_custom_latest_log_alias(self,
+ mock_create_alias):
+ mock_test_config = self.create_mock_test_config(
+ self.base_mock_test_config)
+ tr = test_runner.TestRunner(self.log_dir, self.test_bed_name)
+ with tr.mobly_logger(alias='history'):
+ pass
+ expected_alias_dir = os.path.join(self.log_dir, self.test_bed_name,
+ 'history')
+ mock_create_alias.assert_called_once_with(logging.log_path,
+ expected_alias_dir)
+
+ @mock.patch('mobly.utils.create_alias')
+ def test_mobly_logger_skips_latest_log_alias_when_none(
+ self, mock_create_alias):
+ mock_test_config = self.create_mock_test_config(
+ self.base_mock_test_config)
+ tr = test_runner.TestRunner(self.log_dir, self.test_bed_name)
+ with tr.mobly_logger(alias=None):
+ pass
+ mock_create_alias.asset_not_called()
+
+ @mock.patch('mobly.utils.create_alias')
+ def test_mobly_logger_skips_latest_log_alias_when_empty(
+ self, mock_create_alias):
+ mock_test_config = self.create_mock_test_config(
+ self.base_mock_test_config)
+ tr = test_runner.TestRunner(self.log_dir, self.test_bed_name)
+ with tr.mobly_logger(alias=''):
+ pass
+ mock_create_alias.asset_not_called()
+
def test_logging_before_run(self):
"""Verifies the expected output files from a test run.