1#
2# Copyright (C) 2017 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#      http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16import logging
17import os
18
19from vts.proto import VtsReportMessage_pb2 as ReportMsg
20from vts.runners.host import keys
21from vts.utils.python.reporting import report_file_utils
22from vts.utils.python.systrace import systrace_controller
23from vts.utils.python.web import feature_utils
24
25
26class LogUploadingFeature(feature_utils.Feature):
27    """Feature object for log uploading functionality.
28
29    Attributes:
30        enabled: boolean, True if log uploading is enabled, False otherwise.
31        web: (optional) WebFeature, object storing web feature util for test run.
32        _report_file_util: report file util object for uploading logs to distant.
33        _report_file_util_gcs: report file util object for uploading logs to gcs.
34    """
35
36    _TOGGLE_PARAM = keys.ConfigKeys.IKEY_ENABLE_LOG_UPLOADING
37    _REQUIRED_PARAMS = [
38        keys.ConfigKeys.IKEY_ANDROID_DEVICE,
39    ]
40    _OPTIONAL_PARAMS = [
41        keys.ConfigKeys.KEY_TESTBED_NAME,
42        keys.ConfigKeys.IKEY_LOG_UPLOADING_USE_DATE_DIRECTORY,
43        keys.ConfigKeys.IKEY_LOG_UPLOADING_PATH,
44        keys.ConfigKeys.IKEY_LOG_UPLOADING_URL_PREFIX,
45        keys.ConfigKeys.IKEY_LOG_UPLOADING_GCS_BUCKET_NAME,
46        keys.ConfigKeys.IKEY_SERVICE_JSON_PATH
47    ]
48
49    def __init__(self, user_params, web=None):
50        """Initializes the log uploading feature.
51
52        Args:
53            user_params: A dictionary from parameter name (String) to parameter value.
54            web: (optional) WebFeature, object storing web feature util for test run
55        """
56        self.ParseParameters(
57            toggle_param_name=self._TOGGLE_PARAM,
58            required_param_names=self._REQUIRED_PARAMS,
59            optional_param_names=self._OPTIONAL_PARAMS,
60            user_params=user_params)
61        self.web = web
62
63        if self.enabled:
64            logging.info("Log uploading is enabled")
65        else:
66            logging.debug("Log uploading is disabled")
67            return
68
69        if all(hasattr(self, attr) for attr in [
70                    keys.ConfigKeys.IKEY_LOG_UPLOADING_GCS_BUCKET_NAME,
71                    keys.ConfigKeys.IKEY_SERVICE_JSON_PATH]):
72            gcs_bucket_name = getattr(
73                self, keys.ConfigKeys.IKEY_LOG_UPLOADING_GCS_BUCKET_NAME)
74            gcs_url_prefix = "https://storage.cloud.google.com/" + gcs_bucket_name + "/"
75            self._report_file_util_gcs = report_file_utils.ReportFileUtil(
76                flatten_source_dir=True,
77                use_destination_date_dir=getattr(
78                    self,
79                    keys.ConfigKeys.IKEY_LOG_UPLOADING_USE_DATE_DIRECTORY,
80                    True),
81                destination_dir=gcs_bucket_name,
82                url_prefix=gcs_url_prefix,
83                gcs_key_path=getattr(self,
84                                     keys.ConfigKeys.IKEY_SERVICE_JSON_PATH))
85
86        if hasattr(self, keys.ConfigKeys.IKEY_LOG_UPLOADING_PATH):
87            self._report_file_util = report_file_utils.ReportFileUtil(
88                flatten_source_dir=True,
89                use_destination_date_dir=getattr(
90                    self,
91                    keys.ConfigKeys.IKEY_LOG_UPLOADING_USE_DATE_DIRECTORY,
92                    True),
93                destination_dir=getattr(
94                    self, keys.ConfigKeys.IKEY_LOG_UPLOADING_PATH),
95                url_prefix=getattr(
96                    self, keys.ConfigKeys.IKEY_LOG_UPLOADING_URL_PREFIX, None))
97
98    def UploadLogs(self, prefix=None, dryrun=False):
99        """Save test logs and add log urls to report message.
100
101        Args:
102            prefix: string, file name prefix. Will be auto-generated if not provided.
103            dryrun: bool, whether to perform a dry run that attaches
104                    destination URLs to result message only. if True,
105                    log files will not be actually uploaded.
106        """
107        if not self.enabled:
108            return
109
110        if not prefix:
111            prefix = '%s_%s_' % (
112                getattr(self, keys.ConfigKeys.KEY_TESTBED_NAME, ''),
113                self.web.report_msg.start_timestamp)
114
115        def path_filter(path):
116            '''filter to exclude proto files in log uploading'''
117            return not path.endswith('_proto.msg')
118
119        for object_name in ['_report_file_util_gcs', '_report_file_util']:
120            if hasattr(self, object_name):
121                report_file_util = getattr(self, object_name)
122                urls = report_file_util.SaveReportsFromDirectory(
123                    source_dir=logging.log_path,
124                    file_name_prefix=prefix,
125                    file_path_filters=path_filter,
126                    dryrun=dryrun)
127                if urls is None:
128                    logging.error('Error happened when saving logs.')
129                elif self.web and self.web.enabled:
130                    self.web.AddLogUrls(urls)