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