| # -*- coding: utf-8 -*- |
| # Copyright 2019 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Unittests for goma_lib.py""" |
| |
| from __future__ import print_function |
| |
| import datetime |
| import getpass |
| import gzip |
| import json |
| import os |
| import sys |
| import time |
| |
| from chromite.lib import cros_build_lib |
| from chromite.lib import cros_test_lib |
| from chromite.lib import goma_lib |
| from chromite.lib import osutils |
| |
| |
| assert sys.version_info >= (3, 6), 'This module requires Python 3.6+' |
| |
| |
| class TestLogsArchiver(cros_test_lib.MockTempDirTestCase): |
| """Tests for goma_lib.LogsArchiver.""" |
| |
| def setUp(self): |
| self.goma_log_dir = os.path.join(self.tempdir, 'goma_log_dir') |
| osutils.SafeMakedirs(self.goma_log_dir) |
| self.dest_dir = os.path.join(self.tempdir, 'destination_dir') |
| osutils.SafeMakedirs(self.dest_dir) |
| |
| def _CreateFile(self, name): |
| """Creates a basic file, such as a stats or counterz file. |
| |
| Args: |
| name (str): Filename |
| """ |
| osutils.WriteFile(os.path.join(self.goma_log_dir, name), 'File: ' + name) |
| |
| def _CreateLogFile(self, name, timestamp): |
| """Creates a log file for testing. |
| |
| Args: |
| name (str): Log file name. |
| timestamp (datetime): timestamp that is written to the file. |
| """ |
| path = os.path.join( |
| self.goma_log_dir, |
| '%s.host.log.INFO.%s' % (name, timestamp.strftime('%Y%m%d-%H%M%S.%f'))) |
| osutils.WriteFile( |
| path, |
| timestamp.strftime('Log file created at: %Y/%m/%d %H:%M:%S')) |
| |
| def testArchive(self): |
| """Test successful archive of goma logs without stats/counterz specified.""" |
| self._CreateLogFile( |
| 'compiler_proxy', datetime.datetime(2017, 4, 26, 12, 0, 0)) |
| self._CreateLogFile( |
| 'compiler_proxy-subproc', datetime.datetime(2017, 4, 26, 12, 0, 0)) |
| self._CreateLogFile( |
| 'gomacc', datetime.datetime(2017, 4, 26, 12, 1, 0)) |
| self._CreateLogFile( |
| 'gomacc', datetime.datetime(2017, 4, 26, 12, 2, 0)) |
| |
| archiver = goma_lib.LogsArchiver(self.goma_log_dir, dest_dir=self.dest_dir) |
| archiver_tuple = archiver.Archive() |
| |
| # Verify that no stats/counterz was returned in the tuple. |
| self.assertFalse(archiver_tuple.counterz_file) |
| self.assertFalse(archiver_tuple.stats_file) |
| |
| archived_files = os.listdir(self.dest_dir) |
| |
| # Verify that the list of files returned matched what we find in the |
| # dest_dir. |
| self.assertCountEqual(archiver_tuple.log_files, archived_files) |
| |
| self.assertCountEqual( |
| archived_files, |
| ['compiler_proxy.host.log.INFO.20170426-120000.000000.gz', |
| 'gomacc.host.log.INFO.20170426-120100.000000.tar.gz', |
| 'compiler_proxy-subproc.host.log.INFO.20170426-120000.000000.gz']) |
| |
| def testArchiveWithStatsAndCounterz(self): |
| """Test successful archive of goma logs with stats and counterz.""" |
| self._CreateLogFile( |
| 'compiler_proxy', datetime.datetime(2017, 4, 26, 12, 0, 0)) |
| self._CreateLogFile( |
| 'compiler_proxy-subproc', datetime.datetime(2017, 4, 26, 12, 0, 0)) |
| self._CreateLogFile( |
| 'gomacc', datetime.datetime(2017, 4, 26, 12, 1, 0)) |
| self._CreateLogFile( |
| 'gomacc', datetime.datetime(2017, 4, 26, 12, 2, 0)) |
| self._CreateFile('stats.binaryproto') |
| self._CreateFile('counterz.binaryproto') |
| |
| archiver = goma_lib.LogsArchiver(self.goma_log_dir, dest_dir=self.dest_dir, |
| stats_file='stats.binaryproto', |
| counterz_file='counterz.binaryproto') |
| archiver_tuple = archiver.Archive() |
| |
| self.assertCountEqual( |
| archiver_tuple.log_files, |
| ['compiler_proxy.host.log.INFO.20170426-120000.000000.gz', |
| 'gomacc.host.log.INFO.20170426-120100.000000.tar.gz', |
| 'compiler_proxy-subproc.host.log.INFO.20170426-120000.000000.gz']) |
| self.assertEqual(archiver_tuple.stats_file, 'stats.binaryproto') |
| self.assertEqual(archiver_tuple.counterz_file, 'counterz.binaryproto') |
| |
| def testArchiveWithStatsAndMissingCounterz(self): |
| """Test successful archive of goma logs with stats and counterz.""" |
| self._CreateLogFile( |
| 'compiler_proxy', datetime.datetime(2017, 4, 26, 12, 0, 0)) |
| self._CreateLogFile( |
| 'compiler_proxy-subproc', datetime.datetime(2017, 4, 26, 12, 0, 0)) |
| self._CreateLogFile( |
| 'gomacc', datetime.datetime(2017, 4, 26, 12, 1, 0)) |
| self._CreateLogFile( |
| 'gomacc', datetime.datetime(2017, 4, 26, 12, 2, 0)) |
| self._CreateFile('stats.binaryproto') |
| |
| archiver = goma_lib.LogsArchiver(self.goma_log_dir, dest_dir=self.dest_dir, |
| stats_file='stats.binaryproto', |
| counterz_file='counterz.binaryproto') |
| # Because counterz.binaryproto does not exist, verify it is not returned |
| # as one of the files archived. |
| archiver_tuple = archiver.Archive() |
| self.assertFalse(archiver_tuple.counterz_file) |
| self.assertEqual(archiver_tuple.stats_file, 'stats.binaryproto') |
| self.assertCountEqual( |
| archiver_tuple.log_files, |
| ['compiler_proxy.host.log.INFO.20170426-120000.000000.gz', |
| 'gomacc.host.log.INFO.20170426-120100.000000.tar.gz', |
| 'compiler_proxy-subproc.host.log.INFO.20170426-120000.000000.gz']) |
| |
| def testNinjaLogArchive(self): |
| """Test successful archive of ninja logs.""" |
| self._CreateLogFile( |
| 'compiler_proxy', datetime.datetime(2017, 8, 21, 12, 0, 0)) |
| self._CreateLogFile( |
| 'compiler_proxy-subproc', datetime.datetime(2017, 8, 21, 12, 0, 0)) |
| |
| ninja_log_path = os.path.join(self.goma_log_dir, 'ninja_log') |
| osutils.WriteFile(ninja_log_path, 'Ninja Log Content\n') |
| timestamp = datetime.datetime(2017, 8, 21, 12, 0, 0) |
| mtime = time.mktime(timestamp.timetuple()) |
| os.utime(ninja_log_path, ((time.time(), mtime))) |
| |
| osutils.WriteFile( |
| os.path.join(self.goma_log_dir, 'ninja_command'), 'ninja_command') |
| osutils.WriteFile( |
| os.path.join(self.goma_log_dir, 'ninja_cwd'), 'ninja_cwd') |
| osutils.WriteFile( |
| os.path.join(self.goma_log_dir, 'ninja_env'), |
| 'key1=value1\0key2=value2\0') |
| osutils.WriteFile( |
| os.path.join(self.goma_log_dir, 'ninja_exit'), '0') |
| |
| archiver = goma_lib.LogsArchiver(self.goma_log_dir, dest_dir=self.dest_dir) |
| archived_tuple = archiver.Archive() |
| |
| username = getpass.getuser() |
| pid = os.getpid() |
| hostname = cros_build_lib.GetHostName() |
| ninjalog_filename = 'ninja_log.%s.%s.20170821-120000.%d.gz' % ( |
| username, hostname, pid) |
| # Verify the archived files in the dest_dir |
| archived_files = os.listdir(self.dest_dir) |
| self.assertCountEqual( |
| archived_files, |
| [ninjalog_filename, |
| 'compiler_proxy-subproc.host.log.INFO.20170821-120000.000000.gz', |
| 'compiler_proxy.host.log.INFO.20170821-120000.000000.gz']) |
| # Verify the archived_tuple result. |
| self.assertFalse(archived_tuple.counterz_file) |
| self.assertFalse(archived_tuple.stats_file) |
| self.assertCountEqual( |
| archived_tuple.log_files, |
| ['compiler_proxy.host.log.INFO.20170821-120000.000000.gz', |
| 'compiler_proxy-subproc.host.log.INFO.20170821-120000.000000.gz', |
| ninjalog_filename]) |
| |
| |
| # Verify content of ninja_log file. |
| ninjalog_path = os.path.join(self.dest_dir, ninjalog_filename) |
| |
| with gzip.open(ninjalog_path, 'rt') as gzip_file: |
| ninja_log_content = gzip_file.read() |
| |
| content, eof, metadata_json = ninja_log_content.split('\n', 3) |
| self.assertEqual('Ninja Log Content', content) |
| self.assertEqual('# end of ninja log', eof) |
| metadata = json.loads(metadata_json) |
| self.assertEqual( |
| metadata, |
| { |
| 'platform': 'chromeos', |
| 'cmdline': ['ninja_command'], |
| 'cwd': 'ninja_cwd', |
| 'exit': 0, |
| 'env': {'key1': 'value1', 'key2': 'value2'}, |
| 'compiler_proxy_info': |
| 'compiler_proxy.host.log.INFO.20170821-120000.000000' |
| }) |