blob: efb9340d031cc5040bd306e5f2b9d11be9645c5a [file] [log] [blame]
Mike Frysingerf1ba7ad2022-09-12 05:42:57 -04001# Copyright 2019 The ChromiumOS Authors
Alex Klein69339cc2019-07-22 14:08:35 -06002# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
Alex Klein2008aee2019-08-20 16:25:27 -06005"""API config object and related helper functionality."""
Alex Klein69339cc2019-07-22 14:08:35 -06006
Alex Kleind815ca62020-01-10 12:21:30 -07007from chromite.api.gen.chromite.api import build_api_config_pb2
8
9
10class Error(Exception):
Alex Klein1699fab2022-09-08 08:46:06 -060011 """Base error class for the module."""
Alex Kleind815ca62020-01-10 12:21:30 -070012
13
14class UnknownCallTypeEnumValue(Error):
Alex Klein1699fab2022-09-08 08:46:06 -060015 """Thrown when the call type enum value in proto is not configured here."""
Alex Kleind815ca62020-01-10 12:21:30 -070016
Alex Klein69339cc2019-07-22 14:08:35 -060017
Alex Klein2008aee2019-08-20 16:25:27 -060018class ApiConfig(object):
Alex Klein1699fab2022-09-08 08:46:06 -060019 """API Config class."""
Alex Klein69339cc2019-07-22 14:08:35 -060020
Alex Klein1699fab2022-09-08 08:46:06 -060021 # Call type constants.
22 CALL_TYPE_EXECUTE = 1
23 CALL_TYPE_VALIDATE_ONLY = 2
24 CALL_TYPE_MOCK_SUCCESS = 3
25 CALL_TYPE_MOCK_FAILURE = 4
26 CALL_TYPE_MOCK_INVALID = 5
Alex Kleind815ca62020-01-10 12:21:30 -070027
Alex Klein1699fab2022-09-08 08:46:06 -060028 # Maps the proto enum to the type constants.
29 TYPE_ENUM_MAP = {
30 build_api_config_pb2.CALL_TYPE_NONE: CALL_TYPE_EXECUTE,
31 build_api_config_pb2.CALL_TYPE_EXECUTE: CALL_TYPE_EXECUTE,
32 build_api_config_pb2.CALL_TYPE_VALIDATE_ONLY: CALL_TYPE_VALIDATE_ONLY,
33 build_api_config_pb2.CALL_TYPE_MOCK_SUCCESS: CALL_TYPE_MOCK_SUCCESS,
34 build_api_config_pb2.CALL_TYPE_MOCK_FAILURE: CALL_TYPE_MOCK_FAILURE,
35 build_api_config_pb2.CALL_TYPE_MOCK_INVALID: CALL_TYPE_MOCK_INVALID,
36 }
Alex Kleind815ca62020-01-10 12:21:30 -070037
Alex Klein1699fab2022-09-08 08:46:06 -060038 # Maps the type constants to the proto enums.
39 ENUM_TYPE_MAP = {
40 CALL_TYPE_EXECUTE: build_api_config_pb2.CALL_TYPE_EXECUTE,
41 CALL_TYPE_VALIDATE_ONLY: build_api_config_pb2.CALL_TYPE_VALIDATE_ONLY,
42 CALL_TYPE_MOCK_SUCCESS: build_api_config_pb2.CALL_TYPE_MOCK_SUCCESS,
43 CALL_TYPE_MOCK_FAILURE: build_api_config_pb2.CALL_TYPE_MOCK_FAILURE,
44 CALL_TYPE_MOCK_INVALID: build_api_config_pb2.CALL_TYPE_MOCK_INVALID,
45 }
Alex Kleind815ca62020-01-10 12:21:30 -070046
Alex Klein1699fab2022-09-08 08:46:06 -060047 # The valid call types.
48 _VALID_CALL_TYPES = tuple(ENUM_TYPE_MAP.keys())
Alex Klein2008aee2019-08-20 16:25:27 -060049
Alex Klein1699fab2022-09-08 08:46:06 -060050 def __init__(self, call_type=CALL_TYPE_EXECUTE, log_path=None):
51 assert call_type in self._VALID_CALL_TYPES
52 self._call_type = call_type
53 # Explicit `or None` to simplify proto default empty string.
54 self.log_path = log_path or None
Alex Klein2008aee2019-08-20 16:25:27 -060055
Alex Klein1699fab2022-09-08 08:46:06 -060056 def __eq__(self, other):
57 if self.__class__ is other.__class__:
58 return self.__dict__ == other.__dict__
Alex Klein2008aee2019-08-20 16:25:27 -060059
Alex Klein1699fab2022-09-08 08:46:06 -060060 return NotImplemented
Alex Klein2008aee2019-08-20 16:25:27 -060061
Alex Klein1699fab2022-09-08 08:46:06 -060062 __hash__ = NotImplemented
Alex Kleind815ca62020-01-10 12:21:30 -070063
Alex Klein1699fab2022-09-08 08:46:06 -060064 @property
65 def do_validation(self):
66 # We skip validation for all mock calls, so do validation when it's
67 # anything but a mocked call.
68 return not (self.mock_call or self.mock_error or self.mock_invalid)
Alex Kleind815ca62020-01-10 12:21:30 -070069
Alex Klein1699fab2022-09-08 08:46:06 -060070 @property
71 def validate_only(self):
72 return self._call_type == self.CALL_TYPE_VALIDATE_ONLY
Alex Kleind815ca62020-01-10 12:21:30 -070073
Alex Klein1699fab2022-09-08 08:46:06 -060074 @property
75 def mock_call(self):
76 return self._call_type == self.CALL_TYPE_MOCK_SUCCESS
Alex Kleind815ca62020-01-10 12:21:30 -070077
Alex Klein1699fab2022-09-08 08:46:06 -060078 @property
79 def mock_error(self):
80 return self._call_type == self.CALL_TYPE_MOCK_FAILURE
Alex Kleind815ca62020-01-10 12:21:30 -070081
Alex Klein1699fab2022-09-08 08:46:06 -060082 @property
83 def mock_invalid(self):
84 return self._call_type == self.CALL_TYPE_MOCK_INVALID
Alex Kleind1e9e5c2020-12-14 12:32:32 -070085
Alex Klein1699fab2022-09-08 08:46:06 -060086 @property
87 def run_endpoint(self) -> bool:
88 """Run the endpoint when none of the special calls are invoked."""
89 return (
90 not self.validate_only
91 and not self.mock_call
92 and not self.mock_error
93 and not self.mock_invalid
94 )
Alex Kleind815ca62020-01-10 12:21:30 -070095
Alex Klein1699fab2022-09-08 08:46:06 -060096 def get_proto(
97 self, for_inside_execution: bool = True
98 ) -> build_api_config_pb2.BuildApiConfig:
99 """Get the config as a proto.
Alex Kleind815ca62020-01-10 12:21:30 -0700100
Alex Klein1699fab2022-09-08 08:46:06 -0600101 Args:
102 for_inside_execution: Allows avoiding propagating configs that are
103 irrelevant for the build api process executed inside the chroot.
104 Enabled by default.
105 """
106 config = build_api_config_pb2.BuildApiConfig()
107 config.call_type = self.ENUM_TYPE_MAP[self._call_type]
Alex Kleind815ca62020-01-10 12:21:30 -0700108
Alex Klein1699fab2022-09-08 08:46:06 -0600109 if not for_inside_execution:
110 # Add values not needed when reexecuting.
111 config.log_path = self.log_path
112
113 return config
Alex Kleind815ca62020-01-10 12:21:30 -0700114
115
Miriam Polzeraab64a92021-08-17 11:26:37 +0200116def build_config_from_proto(
Alex Klein1699fab2022-09-08 08:46:06 -0600117 config_proto: build_api_config_pb2.BuildApiConfig,
118) -> ApiConfig:
119 """Build an ApiConfig instance from a BuildApiConfig message.
Alex Kleind815ca62020-01-10 12:21:30 -0700120
Alex Klein1699fab2022-09-08 08:46:06 -0600121 Args:
122 config_proto: The proto config.
123 """
Alex Kleind815ca62020-01-10 12:21:30 -0700124
Alex Klein1699fab2022-09-08 08:46:06 -0600125 if config_proto.call_type not in ApiConfig.TYPE_ENUM_MAP:
126 raise UnknownCallTypeEnumValue(
127 "The given protobuf call_type value is not "
128 "configured in api_config."
129 )
130 return ApiConfig(
131 call_type=ApiConfig.TYPE_ENUM_MAP[config_proto.call_type],
132 log_path=config_proto.log_path,
133 )
Alex Klein69339cc2019-07-22 14:08:35 -0600134
135
136class ApiConfigMixin(object):
Alex Klein1699fab2022-09-08 08:46:06 -0600137 """Mixin to add an API Config factory properties.
Alex Klein69339cc2019-07-22 14:08:35 -0600138
Alex Klein1699fab2022-09-08 08:46:06 -0600139 This is meant to be used for tests to make these configs more uniform across
140 all the tests since there's very little to change anyway.
141 """
Alex Klein69339cc2019-07-22 14:08:35 -0600142
Alex Klein1699fab2022-09-08 08:46:06 -0600143 @property
144 def api_config(self):
145 return ApiConfig()
Alex Klein69339cc2019-07-22 14:08:35 -0600146
Alex Klein1699fab2022-09-08 08:46:06 -0600147 @property
148 def validate_only_config(self):
149 return ApiConfig(call_type=ApiConfig.CALL_TYPE_VALIDATE_ONLY)
Alex Klein2008aee2019-08-20 16:25:27 -0600150
Alex Klein1699fab2022-09-08 08:46:06 -0600151 @property
152 def no_validate_config(self):
153 return self.mock_call_config
Alex Klein2008aee2019-08-20 16:25:27 -0600154
Alex Klein1699fab2022-09-08 08:46:06 -0600155 @property
156 def mock_call_config(self):
157 return ApiConfig(call_type=ApiConfig.CALL_TYPE_MOCK_SUCCESS)
Alex Klein2008aee2019-08-20 16:25:27 -0600158
Alex Klein1699fab2022-09-08 08:46:06 -0600159 @property
160 def mock_error_config(self):
161 return ApiConfig(call_type=ApiConfig.CALL_TYPE_MOCK_FAILURE)