1# Copyright 2019 The Chromium OS Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4"""This module provides functions for loading side_effects_config.json. 5""" 6 7import errno 8import os 9 10from google.protobuf import json_format 11 12import common 13from autotest_lib.utils.side_effects.proto import config_pb2 14 15_SIDE_EFFECTS_CONFIG_FILE = 'side_effects_config.json' 16 17 18def load(results_dir): 19 """Load a side_effects_config.json file. 20 21 @param results_dir: The path to the results directory containing the file. 22 23 @returns: a side_effects.Config proto object if side_effects_config.json 24 exists, None otherwise. 25 26 @raises: json_format.ParseError if the content of side_effects_config.json 27 is not valid JSON. 28 """ 29 config_path = os.path.join(results_dir, _SIDE_EFFECTS_CONFIG_FILE) 30 31 if not os.path.exists(config_path): 32 return None 33 34 with open(config_path, 'r') as config_file: 35 content = config_file.read() 36 config = config_pb2.Config() 37 return json_format.Parse(content, config, ignore_unknown_fields=True) 38 39 40def validate_tko(config): 41 """Validate the tko field of the side_effects.Config. 42 43 @param config: A side_effects.Config proto. 44 45 @raises: ValueError if the tko field does not contain all required fields. 46 OSError if one of the required files is missing. 47 """ 48 _check_empty_fields({ 49 'TKO proxy socket': config.tko.proxy_socket, 50 'TKO MySQL user': config.tko.mysql_user, 51 'TKO MySQL password file': config.tko.mysql_password_file 52 }) 53 54 _check_file_existence({ 55 'TKO proxy socket': config.tko.proxy_socket, 56 'TKO MySQL password file': config.tko.mysql_password_file 57 }) 58 59 60def validate_google_storage(config): 61 """Validate the google_storage field of the side_effects.Config. 62 63 @param config: A side_effects.Config proto. 64 65 @raises: ValueError if the tko field does not contain all required fields. 66 OSError if one of the required files is missing. 67 """ 68 _check_empty_fields({ 69 'Google Storage bucket': config.google_storage.bucket, 70 'Google Storage credentials file': 71 config.google_storage.credentials_file 72 }) 73 74 _check_file_existence({ 75 'Google Storage credentials file': 76 config.google_storage.credentials_file 77 }) 78 79 80def _check_empty_fields(fields): 81 """Return a list of missing required TKO-related fields. 82 83 @param fields: A dict mapping string field descriptions to string field 84 values. 85 86 @raises: ValueError if at least one of the field values is empty. 87 """ 88 empty_fields = [] 89 for description, value in fields.items(): 90 if not value: 91 empty_fields.append(description) 92 if empty_fields: 93 raise ValueError('Missing required fields: ' + ', '.join(empty_fields)) 94 95 96def _check_file_existence(files): 97 """Checks that all given files exist. 98 99 @param files: A dict mapping string file descriptions to string file names. 100 101 @raises: OSError if at least one of the files is missing. 102 """ 103 missing_files = [] 104 for description, path in files.items(): 105 if not os.path.exists(path): 106 missing_files.append(description + ': ' + path) 107 if missing_files: 108 raise OSError(errno.ENOENT, os.strerror(errno.ENOENT), 109 ', '.join(missing_files)) 110