blob: b5d9766a6aa575f7290069e970c513a80b32dff0 [file] [log] [blame] [edit]
# Copyright 2020 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 re
from recipe_engine import recipe_api
class LogUtilsApi(recipe_api.RecipeApi):
"""Utilities to collect logs in a generic way."""
def initialize_logs_collection(self, env):
"""Initializes log processing.
The initialization process creates a temp directory and adds it to the
FLUTTER_LOGS_DIR env variable to make it available to the task steps. Task
steps can place any files they want to upload to GCS as public logs.
Args:
env(dict): Env variables dictionary.
"""
# Create a temp folder to keep logs until we can upload them to gcs
# at the end of the execution of the test.
with self.m.step.nest('Initialize logs'):
logs_path = self.m.path['cleanup'].join('flutter_logs_dir')
self.m.file.ensure_directory('Ensure %s' % logs_path, logs_path)
env['FLUTTER_LOGS_DIR'] = logs_path
# Ensure that any test outputs, e.g. timelines/timeline summaries are
# included as logs.
env['FLUTTER_TEST_OUTPUTS_DIR'] = logs_path
# Write a noop file to for the creation of the remote folder estructure
# when there logs folder is empty.
self.m.file.write_text(
'Write noop file', logs_path.join('noop.txt'), '', include_log=False
)
def upload_logs(self, task, type='flutter'):
"""Upload the log files in FLUTTER_LOGS_DIR to GCS.
Args:
task(str): A string with the task name the logs belong to.
"""
git_hash = self.m.buildbucket.gitiles_commit.id
# gitiles_commit is only populated on post-submits.
# UUID is used in LED and try jobs.
uuid = self.m.uuid.random()
invocation_id = git_hash if git_hash else uuid
logs_path = self.m.path['cleanup'].join('flutter_logs_dir')
with self.m.step.nest('process logs'):
self.m.gsutil.upload(
bucket='flutter_logs',
source=logs_path,
dest='%s/%s/%s/%s' % (type, invocation_id, task, uuid),
link_name='archive logs',
args=['-r'],
multithreaded=True,
name='upload logs %s' % invocation_id,
unauthenticated_url=True
)
log_files = self.m.file.glob_paths(
'logs', source=logs_path, pattern='*', test_data=['a.txt']
)
with self.m.step.nest('log links') as presentation:
pattern_str = 'https://storage.googleapis.com/%s/%s/%s/%s/%s/%s'
log_files = self.m.file.listdir(
'List logs path', logs_path, True, test_data=('myfile.txt',)
)
for log_file in log_files:
base_name = self.m.path.basename(log_file)
url = pattern_str % (
'flutter_logs', type, invocation_id, task, uuid, base_name
)
presentation.links[base_name] = url
def upload_test_metrics(self, file_path, task_name, git_hash=None):
"""Retrieve the file from the provided path and store it in gcs.
Upload test metrics only on post-submit. These are metrics about unit test execution time,
and they will be used to shard tests evenly according to their overall execution time.
"""
with self.m.step.nest('store metrics'):
git_hash = self.m.buildbucket.gitiles_commit.id if not git_hash else git_hash
if not git_hash or not self.m.path.exists(file_path):
return
uuid = self.m.uuid.random()
self.m.gsutil.upload(
bucket='flutter_logs',
source=file_path,
dest='flutter/%s/%s/%s' % (git_hash, task_name, uuid),
link_name='archive logs',
args=['-r'],
multithreaded=True,
name='upload logs %s' % git_hash,
unauthenticated_url=True
)
def show_logs_stdout(self, file_path):
"""Outputs to sdout the connect of file_path
:param file_path: str
:return:
"""
if self.m.path.exists(file_path):
self.m.file.read_text('Read log file', file_path)