From e9084fef1de60dd08ffbf3697e9bd1fdaa33d01e Mon Sep 17 00:00:00 2001 From: Viktor Gsteiger Date: Mon, 8 Jan 2024 10:12:45 -0800 Subject: [PATCH 1/3] Add validation for function name (#38) Close #37 --- .../client/multi_x_serverless_function.py | 8 ++++++++ .../client/test_multi_x_serverless_function.py | 18 +++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/multi_x_serverless/deployment/client/multi_x_serverless_function.py b/multi_x_serverless/deployment/client/multi_x_serverless_function.py index b140d413..7ab7ea33 100644 --- a/multi_x_serverless/deployment/client/multi_x_serverless_function.py +++ b/multi_x_serverless/deployment/client/multi_x_serverless_function.py @@ -19,6 +19,14 @@ def __init__( self.entry_point = entry_point self.handler = function_callable.__name__ self.regions_and_providers = regions_and_providers if len(regions_and_providers) > 0 else None + self.validate_function_name() + + def validate_function_name(self) -> None: + """ + Validate the function name. + """ + if ":" in self.name: + raise ValueError("Function name cannot contain ':'") def is_waiting_for_predecessors(self) -> bool: """ diff --git a/multi_x_serverless/tests/deployment/client/test_multi_x_serverless_function.py b/multi_x_serverless/tests/deployment/client/test_multi_x_serverless_function.py index 14b6f438..7e898705 100644 --- a/multi_x_serverless/tests/deployment/client/test_multi_x_serverless_function.py +++ b/multi_x_serverless/tests/deployment/client/test_multi_x_serverless_function.py @@ -36,7 +36,6 @@ def function(x): name = "test_function" entry_point = True regions_and_providers = {} - providers = [] function_obj = MultiXServerlessFunction(function, name, entry_point, regions_and_providers) @@ -48,3 +47,20 @@ def function(x): function_obj = MultiXServerlessFunction(function, name, entry_point, regions_and_providers) self.assertTrue(function_obj.is_waiting_for_predecessors()) + + def test_validate_function_name(self): + def function(x): + return x + + name = "test_function" + entry_point = True + regions_and_providers = {} + + function_obj = MultiXServerlessFunction(function, name, entry_point, regions_and_providers) + + function_obj.validate_function_name() + + function_obj.name = "test:function" + + with self.assertRaises(ValueError): + function_obj.validate_function_name() From 1e87ceab62ddadad392e2ab4126c93594b528d54 Mon Sep 17 00:00:00 2001 From: vgsteiger Date: Mon, 8 Jan 2024 20:48:09 -0800 Subject: [PATCH 2/3] Update pytest coverage command --- .github/workflows/workflow.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workflow.yaml b/.github/workflows/workflow.yaml index aea49356..4d844a38 100644 --- a/.github/workflows/workflow.yaml +++ b/.github/workflows/workflow.yaml @@ -42,7 +42,7 @@ jobs: uses: ./.github/actions/poetry - name: Run tests run: | - poetry run pytest --cache-clear --cov=multi_x_serverless multi_x_serverless/ > pytest-coverage.txt + poetry run pytest --cov-reset --cache-clear > pytest-coverage.txt - name: Comment coverage uses: coroo/pytest-coverage-commentator@v1.0.2 From c6f345a7f30b8a781efe6aab7ff1a5dd0a8182d5 Mon Sep 17 00:00:00 2001 From: Viktor Gsteiger Date: Tue, 9 Jan 2024 11:50:46 -0800 Subject: [PATCH 3/3] Change Home Regions and other Regions Config to Objects (#43) * Refactor enum names and update provider regions * Update region configuration in app.py --- README.md | 13 ++++++++ benchmarks/image_processing/app.py | 14 ++++++-- benchmarks/regression_tuning/app.py | 14 ++++++-- benchmarks/text_2_speech_censoring/app.py | 14 ++++++-- docs/design.md | 7 +++- .../deployment/client/cli/config_schema.py | 11 +++++-- .../template/.multi-x-serverless/config.yml | 12 +++++-- .../deployment/client/cli/template/app.py | 14 ++++++-- .../deployment/client/config.py | 14 +------- .../deployment/client/deploy/executor.py | 4 +-- .../client/deploy/models/function.py | 32 +++++++++---------- .../client/deploy/models/remote_state.py | 4 +-- .../client/deploy/models/workflow.py | 2 +- multi_x_serverless/deployment/client/enums.py | 2 +- .../client/factories/cli_factory.py | 18 +++++------ .../client/factories/remote_client_factory.py | 12 +++---- .../client/remote_client/remote_client.py | 8 ----- .../tests/deployment/client/test_config.py | 8 ++--- .../test_multi_x_serverless_function.py | 14 ++++++-- .../test_multi_x_serverless_workflow.py | 28 +++++++++++++--- 20 files changed, 160 insertions(+), 85 deletions(-) diff --git a/README.md b/README.md index bf964f06..adada477 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,19 @@ We are working with poetry, so you need to install it first. pip install poetry ``` +Alternatively if this doesn't work you will need to install poetry on Linux with: + +```bash +apt install python3-poetry +``` + +Or you need to reinstall poetry: + +```bash +curl -sSL https://install.python-poetry.org | python3 - +poetry self update +``` + Then, install the dependencies: ```bash diff --git a/benchmarks/image_processing/app.py b/benchmarks/image_processing/app.py index f53e6e0d..aae40832 100644 --- a/benchmarks/image_processing/app.py +++ b/benchmarks/image_processing/app.py @@ -15,8 +15,18 @@ name="GetInput", entry_point=True, regions_and_providers={ - "only_regions": [["aws", "us-east-1"], ["aws", "us-east-2"], ["aws", "us-west-1"], ["aws", "us-west-2"]], - "forbidden_regions": None, + "only_regions": [ + { + "provider": "aws", + "region": "us-east-1", + } + ], + "forbidden_regions": [ + { + "provider": "aws", + "region": "us-east-2", + } + ], "providers": [ { "name": "aws", diff --git a/benchmarks/regression_tuning/app.py b/benchmarks/regression_tuning/app.py index 8d6f79fa..0cd07f41 100644 --- a/benchmarks/regression_tuning/app.py +++ b/benchmarks/regression_tuning/app.py @@ -21,8 +21,18 @@ name="GetInput", entry_point=True, regions_and_providers={ - "only_regions": [["aws", "us-east-1"], ["aws", "us-east-2"], ["aws", "us-west-1"], ["aws", "us-west-2"]], - "forbidden_regions": None, + "only_regions": [ + { + "provider": "aws", + "region": "us-east-1", + } + ], + "forbidden_regions": [ + { + "provider": "aws", + "region": "us-east-2", + } + ], "providers": [ { "name": "aws", diff --git a/benchmarks/text_2_speech_censoring/app.py b/benchmarks/text_2_speech_censoring/app.py index 5b751887..69f5daa8 100644 --- a/benchmarks/text_2_speech_censoring/app.py +++ b/benchmarks/text_2_speech_censoring/app.py @@ -20,8 +20,18 @@ name="GetInput", entry_point=True, regions_and_providers={ - "only_regions": [["aws", "us-east-1"], ["aws", "us-east-2"], ["aws", "us-west-1"], ["aws", "us-west-2"]], - "forbidden_regions": None, + "only_regions": [ + { + "provider": "aws", + "region": "us-east-1", + } + ], + "forbidden_regions": [ + { + "provider": "aws", + "region": "us-east-2", + } + ], "providers": [ { "name": "aws", diff --git a/docs/design.md b/docs/design.md index bcac7a5c..6cf52ade 100644 --- a/docs/design.md +++ b/docs/design.md @@ -79,7 +79,12 @@ workflow = MultiXServerlessWorkflow("workflow_name") name="function_name", entry_point=True, regions_and_providers={ - "only_regions": [["aws", "us-east-1"], ["aws", "us-east-2"], ["aws", "us-west-1"], ["aws", "us-west-2"]], + "only_regions": [ + { + "provider": "aws", + "region": "us-east-1", + } + ], "forbidden_regions": None, }, providers=[ diff --git a/multi_x_serverless/deployment/client/cli/config_schema.py b/multi_x_serverless/deployment/client/cli/config_schema.py index ad77bc39..1fe26957 100644 --- a/multi_x_serverless/deployment/client/cli/config_schema.py +++ b/multi_x_serverless/deployment/client/cli/config_schema.py @@ -23,9 +23,14 @@ def validate_config(cls: Any, values: Any) -> Any: # pylint: disable=no-self-ar return values +class ProviderRegion(BaseModel): + provider: str = Field(..., title="The name of the provider") + region: str = Field(..., title="The name of the region") + + class RegionAndProviders(BaseModel): - only_regions: Optional[List[List[str]]] = Field(None, title="List of regions to deploy to") - forbidden_regions: Optional[List[List[str]]] = Field(None, title="List of regions to not deploy to") + only_regions: Optional[List[ProviderRegion]] = Field(None, title="List of regions to deploy to") + forbidden_regions: Optional[List[ProviderRegion]] = Field(None, title="List of regions to not deploy to") providers: List[Provider] = Field(..., title="List of possible providers with their configurations") @@ -33,5 +38,5 @@ class ConfigSchema(BaseModel): workflow_name: str = Field(..., title="The name of the workflow") environment_variables: List[EnvironmentVariable] = Field(..., title="List of environment variables") iam_policy_file: str = Field(..., title="The IAM policy file") - home_regions: List[List[str]] = Field(..., title="List of home regions") + home_regions: List[ProviderRegion] = Field(..., title="List of home regions") regions_and_providers: RegionAndProviders = Field(..., title="List of regions and providers") diff --git a/multi_x_serverless/deployment/client/cli/template/.multi-x-serverless/config.yml b/multi_x_serverless/deployment/client/cli/template/.multi-x-serverless/config.yml index e1448edd..aed30b62 100644 --- a/multi_x_serverless/deployment/client/cli/template/.multi-x-serverless/config.yml +++ b/multi_x_serverless/deployment/client/cli/template/.multi-x-serverless/config.yml @@ -3,7 +3,9 @@ environment_variables: - name: "ENV_VAR_1" value: "value_1" iam_policy_file: "iam_policy.json" -home_regions: [["aws", us-west-2"]] # Regions are defined as "provider:region" (e.g. aws:us-west-2) +home_regions: + - provider: "aws" + region: "us-east-1" estimated_invocations_per_month: 1000000 constraints: hard_resource_constraints: # None for none @@ -25,8 +27,12 @@ constraints: - runtime - carbon regions_and_providers: # Either the user specify only allowed regions (which will override everything else) - only_regions: null # Only check other conditions if this is None, else will restrict to ONLY those regions - forbidden_regions: null + only_regions: + - provider: "aws" + region: "us-east-1" + forbidden_regions: + - provider: "aws" + region: "us-east-2" providers: - name: "aws" config: diff --git a/multi_x_serverless/deployment/client/cli/template/app.py b/multi_x_serverless/deployment/client/cli/template/app.py index 750b05a0..3fada0c1 100644 --- a/multi_x_serverless/deployment/client/cli/template/app.py +++ b/multi_x_serverless/deployment/client/cli/template/app.py @@ -9,8 +9,18 @@ name="First-Function", entry_point=True, regions_and_providers={ - "only_regions": [["aws", "us-east-1"]], - "forbidden_regions": [["aws", "us-east-2"]], + "only_regions": [ + { + "provider": "aws", + "region": "us-east-1", + } + ], + "forbidden_regions": [ + { + "provider": "aws", + "region": "us-east-2", + } + ], "providers": [ { "name": "aws", diff --git a/multi_x_serverless/deployment/client/config.py b/multi_x_serverless/deployment/client/config.py index f3fd3834..170142ef 100644 --- a/multi_x_serverless/deployment/client/config.py +++ b/multi_x_serverless/deployment/client/config.py @@ -52,19 +52,7 @@ def environment_variables(self) -> dict[str, Any]: return env_variables @property - def home_regions(self) -> list[tuple[str, str]]: - if "home_regions_tuple" in self.project_config: - return self.project_config["home_regions_tuple"] - home_regions: list[list[str]] = self._lookup("home_regions") - if home_regions is None: - return [] - home_regions_tuple = [tuple(home_region[0:2]) for home_region in home_regions] - self.project_config["home_regions_tuple"] = home_regions_tuple - return home_regions_tuple # type: ignore - # somehow mypy thinks this is a list of tuples with one or more elements - - @property - def home_regions_json(self) -> list[list[str]]: + def home_regions(self) -> list[dict[str, str]]: return self._lookup("home_regions") @property diff --git a/multi_x_serverless/deployment/client/deploy/executor.py b/multi_x_serverless/deployment/client/deploy/executor.py index 8b70224a..c42a66fb 100644 --- a/multi_x_serverless/deployment/client/deploy/executor.py +++ b/multi_x_serverless/deployment/client/deploy/executor.py @@ -18,8 +18,8 @@ def __init__(self, config: Config) -> None: def execute(self, deployment_plan: DeploymentPlan) -> None: for home_region, instructions in deployment_plan.instructions.items(): - endpoint, region = home_region.split(":") - client = self._remote_client_factory.get_remote_client(endpoint, region) + provider, region = home_region.split(":") + client = self._remote_client_factory.get_remote_client(provider, region) for instruction in instructions: getattr(self, f"_do_{instruction.__class__.__name__.lower()}", self._default_handler)( instruction, diff --git a/multi_x_serverless/deployment/client/deploy/models/function.py b/multi_x_serverless/deployment/client/deploy/models/function.py index ae6e5971..643ee668 100644 --- a/multi_x_serverless/deployment/client/deploy/models/function.py +++ b/multi_x_serverless/deployment/client/deploy/models/function.py @@ -9,7 +9,7 @@ from multi_x_serverless.deployment.client.deploy.models.remote_state import RemoteState from multi_x_serverless.deployment.client.deploy.models.resource import Resource from multi_x_serverless.deployment.client.deploy.models.variable import Variable -from multi_x_serverless.deployment.client.enums import Endpoint +from multi_x_serverless.deployment.client.enums import Provider class Function(Resource): # pylint: disable=too-many-instance-attributes @@ -22,7 +22,7 @@ def __init__( environment_variables: dict[str, str], handler: str, runtime: str, - home_regions: list[tuple[str, str]], + home_regions: list[dict[str, str]], providers: list[dict], ) -> None: super().__init__(name, "function") @@ -50,12 +50,12 @@ def __repr__(self) -> str: Providers: {self.providers} """ - def initialise_remote_states(self, home_regions: list[tuple[str, str]]) -> None: + def initialise_remote_states(self, home_regions: list[dict[str, str]]) -> None: for home_region in home_regions: - endpoint, region = home_region - if endpoint not in self._remote_states: - self._remote_states[endpoint] = {} - self._remote_states[endpoint][region] = RemoteState(endpoint=endpoint, region=region) + provider, region = home_region["provider"], home_region["region"] + if provider not in self._remote_states: + self._remote_states[provider] = {} + self._remote_states[provider][region] = RemoteState(provider=provider, region=region) def dependencies(self) -> Sequence[Resource]: resources: list[Resource] = [self.role, self.deployment_package] @@ -64,21 +64,21 @@ def dependencies(self) -> Sequence[Resource]: def get_deployment_instructions(self) -> dict[str, list[Instruction]]: instructions: dict[str, list[Instruction]] = {} for home_region in self.home_regions: - endpoint, region = home_region - if endpoint == Endpoint.AWS.value: + provider, region = home_region["provider"], home_region["region"] + if provider == Provider.AWS.value: instruction = self.get_deployment_instructions_aws(region) - elif endpoint == Endpoint.GCP.value: + elif provider == Provider.GCP.value: instruction = self.get_deployment_instructions_gcp(region) else: - raise RuntimeError(f"Unknown endpoint {endpoint}") - instructions[f"{endpoint}:{region}"] = instruction + raise RuntimeError(f"Unknown provider {provider}") + instructions[f"{provider}:{region}"] = instruction return instructions def _get_memory_and_timeout(self) -> tuple[int, int]: memory = 128 timeout = 3 for provider in self.providers: - if provider["name"] == Endpoint.AWS.value: + if provider["name"] == Provider.AWS.value: if "memory" in provider: memory = provider["memory"] if "timeout" in provider: @@ -117,7 +117,7 @@ def get_deployment_instructions_aws(self, region: str) -> list[Instruction]: if policy is None: raise RuntimeError(f"Lambda policy could not be read, check the path ({self.role.policy})") policy = json.dumps(json.loads(policy)) - if not self._remote_states[Endpoint.AWS.value][region].resource_exists(self.role): + if not self._remote_states[Provider.AWS.value][region].resource_exists(self.role): instructions.extend( [ APICall( @@ -164,7 +164,7 @@ def get_deployment_instructions_aws(self, region: str) -> list[Instruction]: with open(self.deployment_package.filename, "rb") as f: zip_contents = f.read() function_varname = f"{self.name}_lambda_arn_{region}" - if not self._remote_states[Endpoint.AWS.value][region].resource_exists(self): + if not self._remote_states[Provider.AWS.value][region].resource_exists(self): instructions.extend( [ APICall( @@ -253,4 +253,4 @@ def get_sns_topic_instruction_for_region(self, region: str, output_var: str) -> ) def get_deployment_instructions_gcp(self, region: str) -> list[Instruction]: # pylint: disable=unused-argument - return [] + raise NotImplementedError() diff --git a/multi_x_serverless/deployment/client/deploy/models/remote_state.py b/multi_x_serverless/deployment/client/deploy/models/remote_state.py index b58c3708..03011de6 100644 --- a/multi_x_serverless/deployment/client/deploy/models/remote_state.py +++ b/multi_x_serverless/deployment/client/deploy/models/remote_state.py @@ -3,8 +3,8 @@ class RemoteState: - def __init__(self, endpoint: str, region: str) -> None: - self._client = RemoteClientFactory().get_remote_client(endpoint, region) + def __init__(self, provider: str, region: str) -> None: + self._client = RemoteClientFactory().get_remote_client(provider, region) def resource_exists(self, resource: Resource) -> bool: return self._client.resource_exists(resource) diff --git a/multi_x_serverless/deployment/client/deploy/models/workflow.py b/multi_x_serverless/deployment/client/deploy/models/workflow.py index 0d6646ef..1cfef0ce 100644 --- a/multi_x_serverless/deployment/client/deploy/models/workflow.py +++ b/multi_x_serverless/deployment/client/deploy/models/workflow.py @@ -63,7 +63,7 @@ def get_description(self) -> WorkflowConfig: raise RuntimeError("Error in workflow config creation, given config is None, this should not happen") workflow_description = { "instances": [function_instance.to_json() for function_instance in self._functions], - "start_hops": self._config.home_regions_json, + "start_hops": self._config.home_regions, # TODO (#27): Implement and incorporate Free Tier considerations into data_sources "estimated_invocations_per_month": self._config.estimated_invocations_per_month, "constraints": self._config.constraints, diff --git a/multi_x_serverless/deployment/client/enums.py b/multi_x_serverless/deployment/client/enums.py index 6d476b33..3cc4b5e1 100644 --- a/multi_x_serverless/deployment/client/enums.py +++ b/multi_x_serverless/deployment/client/enums.py @@ -1,6 +1,6 @@ from enum import Enum -class Endpoint(Enum): +class Provider(Enum): AWS = "aws" GCP = "gcp" diff --git a/multi_x_serverless/deployment/client/factories/cli_factory.py b/multi_x_serverless/deployment/client/factories/cli_factory.py index 40c3ad5c..d5843638 100644 --- a/multi_x_serverless/deployment/client/factories/cli_factory.py +++ b/multi_x_serverless/deployment/client/factories/cli_factory.py @@ -14,7 +14,7 @@ create_default_deployer, create_deletion_deployer, ) -from multi_x_serverless.deployment.client.enums import Endpoint +from multi_x_serverless.deployment.client.enums import Provider from multi_x_serverless.deployment.client.multi_x_serverless_workflow import MultiXServerlessWorkflow @@ -72,24 +72,24 @@ def __validate_only_regions_and_providers(self, project_config: dict) -> None: if "providers" not in project_config["regions_and_providers"]: raise RuntimeError("at least one provider must be defined in regions_and_providers") if "only_regions" in project_config["regions_and_providers"]: - possible_endpoints = [endpoint.value for endpoint in Endpoint] - defined_endpoints = [ + possible_providers = [provider.value for provider in Provider] + defined_providers = [ provider["name"] for provider in project_config["regions_and_providers"]["providers"] - if provider["name"] in possible_endpoints + if provider["name"] in possible_providers ] only_regions = project_config["regions_and_providers"]["only_regions"] if not only_regions: only_regions = [] if only_regions and not isinstance(only_regions, list): raise RuntimeError("only_regions must be a list") - for region in only_regions: - if not isinstance(region, str): + for provider_region in only_regions: + if not isinstance(provider_region, dict): raise RuntimeError("only_regions must be a list of strings") - provider = region[0] - if provider not in Endpoint.__members__: + provider = provider_region["provider"] + if provider not in Provider.__members__: raise RuntimeError(f"Provider {provider} is not supported") - if provider not in defined_endpoints: + if provider not in defined_providers: raise RuntimeError(f"Provider {provider} is not defined in providers") def load_workflow_app(self) -> MultiXServerlessWorkflow: diff --git a/multi_x_serverless/deployment/client/factories/remote_client_factory.py b/multi_x_serverless/deployment/client/factories/remote_client_factory.py index 8d9f846b..71a88e13 100644 --- a/multi_x_serverless/deployment/client/factories/remote_client_factory.py +++ b/multi_x_serverless/deployment/client/factories/remote_client_factory.py @@ -1,13 +1,13 @@ -from multi_x_serverless.deployment.client.enums import Endpoint +from multi_x_serverless.deployment.client.enums import Provider from multi_x_serverless.deployment.client.remote_client.aws_remote_client import AWSRemoteClient from multi_x_serverless.deployment.client.remote_client.remote_client import RemoteClient class RemoteClientFactory: - def get_remote_client(self, endpoint: str, region: str) -> RemoteClient: - endpoint_enum = Endpoint(endpoint) - if endpoint_enum == Endpoint.AWS: + def get_remote_client(self, provider: str, region: str) -> RemoteClient: + provider_enum = Provider(provider) + if provider_enum == Provider.AWS: return AWSRemoteClient(region) - if endpoint_enum == Endpoint.GCP: + if provider_enum == Provider.GCP: raise NotImplementedError() - raise RuntimeError(f"Unknown endpoint {endpoint}") + raise RuntimeError(f"Unknown provider {provider}") diff --git a/multi_x_serverless/deployment/client/remote_client/remote_client.py b/multi_x_serverless/deployment/client/remote_client/remote_client.py index 3e840efd..3eee4363 100644 --- a/multi_x_serverless/deployment/client/remote_client/remote_client.py +++ b/multi_x_serverless/deployment/client/remote_client/remote_client.py @@ -19,18 +19,10 @@ def create_function( ) -> str: raise NotImplementedError() - @abstractmethod - def get_iam_role(self, role_name: str) -> str: - raise NotImplementedError() - @abstractmethod def resource_exists(self, resource: Resource) -> bool: raise NotImplementedError() - @abstractmethod - def get_lambda_function(self, function_name: str) -> dict[str, Any]: - raise NotImplementedError() - @abstractmethod def create_role(self, role_name: str, policy: str, trust_policy: dict) -> str: raise NotImplementedError() diff --git a/multi_x_serverless/tests/deployment/client/test_config.py b/multi_x_serverless/tests/deployment/client/test_config.py index 99831109..6fc58efe 100644 --- a/multi_x_serverless/tests/deployment/client/test_config.py +++ b/multi_x_serverless/tests/deployment/client/test_config.py @@ -25,12 +25,8 @@ def test_environment_variables(self): self.assertEqual(self.config.environment_variables, {"ENV": "test"}) def test_home_regions(self): - self.config.project_config["home_regions"] = [["aws", "us-west-2"]] - self.assertEqual(self.config.home_regions, [("aws", "us-west-2")]) - - def test_home_regions_json(self): - self.config.project_config["home_regions"] = [["aws", "us-west-2"]] - self.assertEqual(self.config.home_regions_json, [["aws", "us-west-2"]]) + self.config.project_config["home_regions"] = [{"provider": "aws", "region": "us-west-2"}] + self.assertEqual(self.config.home_regions, [{"provider": "aws", "region": "us-west-2"}]) def test_estimated_invocations_per_month(self): self.config.project_config["estimated_invocations_per_month"] = 1000 diff --git a/multi_x_serverless/tests/deployment/client/test_multi_x_serverless_function.py b/multi_x_serverless/tests/deployment/client/test_multi_x_serverless_function.py index 7e898705..a60ffad2 100644 --- a/multi_x_serverless/tests/deployment/client/test_multi_x_serverless_function.py +++ b/multi_x_serverless/tests/deployment/client/test_multi_x_serverless_function.py @@ -16,8 +16,18 @@ def function(x): entry_point = True providers = [{"name": "aws", "config": {"timeout": 60, "memory": 128}}] regions_and_providers = { - "only_regions": [["aws", "us-east-1"]], - "forbidden_regions": [["aws", "us-east-2"]], + "only_regions": [ + { + "provider": "aws", + "region": "us-east-1", + } + ], + "forbidden_regions": [ + { + "provider": "aws", + "region": "us-east-2", + } + ], "providers": providers, } diff --git a/multi_x_serverless/tests/deployment/client/test_multi_x_serverless_workflow.py b/multi_x_serverless/tests/deployment/client/test_multi_x_serverless_workflow.py index cead008a..8444bb80 100644 --- a/multi_x_serverless/tests/deployment/client/test_multi_x_serverless_workflow.py +++ b/multi_x_serverless/tests/deployment/client/test_multi_x_serverless_workflow.py @@ -26,8 +26,18 @@ def test_serverless_function(self): name="test_func", entry_point=True, regions_and_providers={ - "only_regions": [["aws", "us-east-1"]], - "forbidden_regions": [["aws", "us-east-2"]], + "only_regions": [ + { + "provider": "aws", + "region": "us-east-1", + } + ], + "forbidden_regions": [ + { + "provider": "aws", + "region": "us-east-2", + } + ], "providers": [ { "name": "aws", @@ -52,8 +62,18 @@ def test_func(payload): "test_func", True, { - "only_regions": [["aws", "us-east-1"]], - "forbidden_regions": [["aws", "us-east-2"]], + "only_regions": [ + { + "provider": "aws", + "region": "us-east-1", + } + ], + "forbidden_regions": [ + { + "provider": "aws", + "region": "us-east-2", + } + ], "providers": [ { "name": "aws",