Coverage for mlos_bench/mlos_bench/environments/remote/saas_env.py: 42%
38 statements
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-20 00:44 +0000
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-20 00:44 +0000
1#
2# Copyright (c) Microsoft Corporation.
3# Licensed under the MIT License.
4#
5"""Cloud-based (configurable) SaaS environment."""
7import logging
8from typing import Optional
10from mlos_bench.environments.base_environment import Environment
11from mlos_bench.services.base_service import Service
12from mlos_bench.services.types.host_ops_type import SupportsHostOps
13from mlos_bench.services.types.remote_config_type import SupportsRemoteConfig
14from mlos_bench.tunables.tunable_groups import TunableGroups
16_LOG = logging.getLogger(__name__)
19class SaaSEnv(Environment):
20 """Cloud-based (configurable) SaaS environment."""
22 def __init__( # pylint: disable=too-many-arguments
23 self,
24 *,
25 name: str,
26 config: dict,
27 global_config: Optional[dict] = None,
28 tunables: Optional[TunableGroups] = None,
29 service: Optional[Service] = None,
30 ):
31 """
32 Create a new environment for (configurable) cloud-based SaaS instance.
34 Parameters
35 ----------
36 name: str
37 Human-readable name of the environment.
38 config : dict
39 Free-format dictionary that contains the benchmark environment
40 configuration. Each config must have at least the "tunable_params"
41 and the "const_args" sections.
42 global_config : dict
43 Free-format dictionary of global parameters (e.g., security credentials)
44 to be mixed in into the "const_args" section of the local config.
45 tunables : TunableGroups
46 A collection of tunable parameters for *all* environments.
47 service: Service
48 An optional service object
49 (e.g., providing methods to configure the remote service).
50 """
51 super().__init__(
52 name=name,
53 config=config,
54 global_config=global_config,
55 tunables=tunables,
56 service=service,
57 )
59 assert self._service is not None and isinstance(
60 self._service, SupportsHostOps
61 ), "RemoteEnv requires a service that supports host operations"
62 self._host_service: SupportsHostOps = self._service
64 assert self._service is not None and isinstance(
65 self._service, SupportsRemoteConfig
66 ), "SaaSEnv requires a service that supports remote host configuration API"
67 self._config_service: SupportsRemoteConfig = self._service
69 def setup(self, tunables: TunableGroups, global_config: Optional[dict] = None) -> bool:
70 """
71 Update the configuration of a remote SaaS instance.
73 Parameters
74 ----------
75 tunables : TunableGroups
76 A collection of groups of tunable parameters along with the
77 parameters' values.
78 global_config : dict
79 Free-format dictionary of global parameters of the environment
80 that are not used in the optimization process.
82 Returns
83 -------
84 is_success : bool
85 True if operation is successful, false otherwise.
86 """
87 _LOG.info("SaaS set up: %s :: %s", self, tunables)
88 if not super().setup(tunables, global_config):
89 return False
91 (status, _) = self._config_service.configure(
92 self._params,
93 self._tunable_params.get_param_values(),
94 )
95 if not status.is_succeeded():
96 return False
98 (status, res) = self._config_service.is_config_pending(self._params)
99 if not status.is_succeeded():
100 return False
102 # Azure Flex DB instances currently require a VM reboot after reconfiguration.
103 if res.get("isConfigPendingRestart") or res.get("isConfigPendingReboot"):
104 _LOG.info("Restarting: %s", self)
105 (status, params) = self._host_service.restart_host(self._params)
106 if status.is_pending():
107 (status, _) = self._host_service.wait_host_operation(params)
108 if not status.is_succeeded():
109 return False
111 _LOG.info("Wait to restart: %s", self)
112 (status, params) = self._host_service.start_host(self._params)
113 if status.is_pending():
114 (status, _) = self._host_service.wait_host_operation(params)
116 self._is_ready = status.is_succeeded()
117 return self._is_ready