blob: e04cbf9419f7c35d2f34be644106462c71bf2b7f [file] [log] [blame]
Alex Klein69339cc2019-07-22 14:08:35 -06001# 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
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):
11 """Base error class for the module."""
12
13
14class UnknownCallTypeEnumValue(Error):
15 """Thrown when the call type enum value in proto is not configured here."""
16
Alex Klein69339cc2019-07-22 14:08:35 -060017
Alex Klein2008aee2019-08-20 16:25:27 -060018class ApiConfig(object):
19 """API Config class."""
Alex Kleind815ca62020-01-10 12:21:30 -070020 # Call type constants.
21 CALL_TYPE_EXECUTE = 1
22 CALL_TYPE_VALIDATE_ONLY = 2
23 CALL_TYPE_MOCK_SUCCESS = 3
24 CALL_TYPE_MOCK_FAILURE = 4
25 CALL_TYPE_MOCK_INVALID = 5
Alex Klein69339cc2019-07-22 14:08:35 -060026
Alex Kleind815ca62020-01-10 12:21:30 -070027 # Maps the proto enum to the type constants.
28 TYPE_ENUM_MAP = {
29 build_api_config_pb2.CALL_TYPE_NONE: CALL_TYPE_EXECUTE,
30 build_api_config_pb2.CALL_TYPE_EXECUTE: CALL_TYPE_EXECUTE,
31 build_api_config_pb2.CALL_TYPE_VALIDATE_ONLY: CALL_TYPE_VALIDATE_ONLY,
32 build_api_config_pb2.CALL_TYPE_MOCK_SUCCESS: CALL_TYPE_MOCK_SUCCESS,
33 build_api_config_pb2.CALL_TYPE_MOCK_FAILURE: CALL_TYPE_MOCK_FAILURE,
34 build_api_config_pb2.CALL_TYPE_MOCK_INVALID: CALL_TYPE_MOCK_INVALID,
35 }
36
37 # Maps the type constants to the proto enums.
38 ENUM_TYPE_MAP = {
39 CALL_TYPE_EXECUTE: build_api_config_pb2.CALL_TYPE_EXECUTE,
40 CALL_TYPE_VALIDATE_ONLY: build_api_config_pb2.CALL_TYPE_VALIDATE_ONLY,
41 CALL_TYPE_MOCK_SUCCESS: build_api_config_pb2.CALL_TYPE_MOCK_SUCCESS,
42 CALL_TYPE_MOCK_FAILURE: build_api_config_pb2.CALL_TYPE_MOCK_FAILURE,
43 CALL_TYPE_MOCK_INVALID: build_api_config_pb2.CALL_TYPE_MOCK_INVALID,
44 }
45
46 # The valid call types.
47 _VALID_CALL_TYPES = tuple(ENUM_TYPE_MAP.keys())
48
49 def __init__(self, call_type=CALL_TYPE_EXECUTE, log_path=None):
50 assert call_type in self._VALID_CALL_TYPES
51 self._call_type = call_type
52 # Explicit `or None` to simplify proto default empty string.
53 self.log_path = log_path or None
Alex Klein2008aee2019-08-20 16:25:27 -060054
55 def __eq__(self, other):
56 if self.__class__ is other.__class__:
Alex Kleind815ca62020-01-10 12:21:30 -070057 return self.__dict__ == other.__dict__
Alex Klein2008aee2019-08-20 16:25:27 -060058
59 return NotImplemented
60
61 __hash__ = NotImplemented
62
63 @property
64 def do_validation(self):
Alex Kleind815ca62020-01-10 12:21:30 -070065 # We skip validation for all mock calls, so do validation when it's
66 # anything but a mocked call.
67 return not (self.mock_call or self.mock_error or self.mock_invalid)
68
69 @property
70 def validate_only(self):
71 return self._call_type == self.CALL_TYPE_VALIDATE_ONLY
72
73 @property
74 def mock_call(self):
75 return self._call_type == self.CALL_TYPE_MOCK_SUCCESS
76
77 @property
78 def mock_error(self):
79 return self._call_type == self.CALL_TYPE_MOCK_FAILURE
80
81 @property
82 def mock_invalid(self):
83 return self._call_type == self.CALL_TYPE_MOCK_INVALID
84
Alex Kleind1e9e5c2020-12-14 12:32:32 -070085 @property
86 def run_endpoint(self) -> bool:
87 """Run the endpoint when none of the special calls are invoked."""
88 return (not self.validate_only and not self.mock_call and
89 not self.mock_error and not self.mock_invalid)
90
Miriam Polzeraab64a92021-08-17 11:26:37 +020091 def get_proto(
92 self,
93 for_inside_execution: bool = True
94 ) -> build_api_config_pb2.BuildApiConfig:
Alex Kleind815ca62020-01-10 12:21:30 -070095 """Get the config as a proto.
96
97 Args:
Miriam Polzeraab64a92021-08-17 11:26:37 +020098 for_inside_execution: Allows avoiding propagating configs that are
Alex Kleind815ca62020-01-10 12:21:30 -070099 irrelevant for the build api process executed inside the chroot.
100 Enabled by default.
Alex Kleind815ca62020-01-10 12:21:30 -0700101 """
102 config = build_api_config_pb2.BuildApiConfig()
103 config.call_type = self.ENUM_TYPE_MAP[self._call_type]
104
105 if not for_inside_execution:
106 # Add values not needed when reexecuting.
107 config.log_path = self.log_path
108
109 return config
110
111
Miriam Polzeraab64a92021-08-17 11:26:37 +0200112def build_config_from_proto(
113 config_proto: build_api_config_pb2.BuildApiConfig) -> ApiConfig:
Alex Kleind815ca62020-01-10 12:21:30 -0700114 """Build an ApiConfig instance from a BuildApiConfig message.
115
116 Args:
Miriam Polzeraab64a92021-08-17 11:26:37 +0200117 config_proto: The proto config.
Alex Kleind815ca62020-01-10 12:21:30 -0700118 """
Alex Kleind815ca62020-01-10 12:21:30 -0700119
120 if config_proto.call_type not in ApiConfig.TYPE_ENUM_MAP:
121 raise UnknownCallTypeEnumValue('The given protobuf call_type value is not '
122 'configured in api_config.')
Miriam Polzeraab64a92021-08-17 11:26:37 +0200123 return ApiConfig(
124 call_type=ApiConfig.TYPE_ENUM_MAP[config_proto.call_type],
125 log_path=config_proto.log_path)
Alex Klein69339cc2019-07-22 14:08:35 -0600126
127
128class ApiConfigMixin(object):
129 """Mixin to add an API Config factory properties.
130
131 This is meant to be used for tests to make these configs more uniform across
Alex Kleine191ed62020-02-27 15:59:55 -0700132 all the tests since there's very little to change anyway.
Alex Klein69339cc2019-07-22 14:08:35 -0600133 """
134
135 @property
136 def api_config(self):
Alex Klein2008aee2019-08-20 16:25:27 -0600137 return ApiConfig()
Alex Klein69339cc2019-07-22 14:08:35 -0600138
139 @property
140 def validate_only_config(self):
Alex Kleind815ca62020-01-10 12:21:30 -0700141 return ApiConfig(call_type=ApiConfig.CALL_TYPE_VALIDATE_ONLY)
Alex Klein2008aee2019-08-20 16:25:27 -0600142
143 @property
144 def no_validate_config(self):
145 return self.mock_call_config
146
147 @property
148 def mock_call_config(self):
Alex Kleind815ca62020-01-10 12:21:30 -0700149 return ApiConfig(call_type=ApiConfig.CALL_TYPE_MOCK_SUCCESS)
Alex Klein2008aee2019-08-20 16:25:27 -0600150
151 @property
152 def mock_error_config(self):
Alex Kleind815ca62020-01-10 12:21:30 -0700153 return ApiConfig(call_type=ApiConfig.CALL_TYPE_MOCK_FAILURE)