trainml 0.5.8__tar.gz → 0.5.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {trainml-0.5.8 → trainml-0.5.9}/PKG-INFO +1 -1
- trainml-0.5.9/tests/integration/projects/conftest.py +8 -0
- {trainml-0.5.8/tests/integration → trainml-0.5.9/tests/integration/projects}/test_projects_integration.py +0 -6
- trainml-0.5.9/tests/integration/projects/test_projects_keys_integration.py +43 -0
- trainml-0.5.9/tests/integration/projects/test_projects_secrets_integration.py +44 -0
- trainml-0.5.9/tests/unit/cloudbender/__init__.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/conftest.py +72 -2
- trainml-0.5.9/tests/unit/projects/__init__.py +0 -0
- trainml-0.5.9/tests/unit/projects/test_project_data_connectors_unit.py +102 -0
- trainml-0.5.9/tests/unit/projects/test_project_datastores_unit.py +96 -0
- trainml-0.5.9/tests/unit/projects/test_project_keys_unit.py +96 -0
- trainml-0.5.9/tests/unit/projects/test_project_secrets_unit.py +101 -0
- trainml-0.5.9/tests/unit/projects/test_project_services_unit.py +102 -0
- trainml-0.5.9/tests/unit/projects/test_projects_unit.py +128 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/__init__.py +1 -1
- trainml-0.5.8/trainml/cli/project.py → trainml-0.5.9/trainml/cli/project/__init__.py +4 -0
- trainml-0.5.9/trainml/cli/project/key.py +124 -0
- trainml-0.5.9/trainml/cli/project/secret.py +71 -0
- trainml-0.5.9/trainml/projects/__init__.py +3 -0
- trainml-0.5.9/trainml/projects/data_connectors.py +63 -0
- trainml-0.5.9/trainml/projects/datastores.py +58 -0
- trainml-0.5.9/trainml/projects/keys.py +71 -0
- trainml-0.5.9/trainml/projects/projects.py +83 -0
- trainml-0.5.9/trainml/projects/secrets.py +70 -0
- trainml-0.5.9/trainml/projects/services.py +63 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml.egg-info/PKG-INFO +1 -1
- {trainml-0.5.8 → trainml-0.5.9}/trainml.egg-info/SOURCES.txt +25 -7
- trainml-0.5.8/tests/unit/test_projects_unit.py +0 -320
- trainml-0.5.8/trainml/projects.py +0 -228
- {trainml-0.5.8 → trainml-0.5.9}/LICENSE +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/README.md +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/examples/__init__.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/examples/create_dataset_and_training_job.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/examples/local_storage.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/examples/training_inference_pipeline.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/pyproject.toml +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/setup.cfg +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/setup.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/integration/__init__.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/integration/cloudbender/__init__.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/integration/cloudbender/test_providers_integration.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/integration/conftest.py +0 -0
- {trainml-0.5.8/tests/unit → trainml-0.5.9/tests/integration/projects}/__init__.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/integration/test_checkpoints_integration.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/integration/test_datasets_integration.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/integration/test_environments_integration.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/integration/test_gpu_types_integration.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/integration/test_jobs_integration.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/integration/test_models_integration.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/integration/test_volumes_integration.py +0 -0
- {trainml-0.5.8/tests/unit/cli → trainml-0.5.9/tests/unit}/__init__.py +0 -0
- {trainml-0.5.8/tests/unit/cli/cloudbender → trainml-0.5.9/tests/unit/cli}/__init__.py +0 -0
- {trainml-0.5.8/tests/unit → trainml-0.5.9/tests/unit/cli}/cloudbender/__init__.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/cli/cloudbender/test_cli_datastore_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/cli/cloudbender/test_cli_device_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/cli/cloudbender/test_cli_node_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/cli/cloudbender/test_cli_provider_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/cli/cloudbender/test_cli_region_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/cli/cloudbender/test_cli_service_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/cli/conftest.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/cli/test_cli_checkpoint_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/cli/test_cli_datasets_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/cli/test_cli_environment_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/cli/test_cli_gpu_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/cli/test_cli_job_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/cli/test_cli_model_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/cli/test_cli_project_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/cli/test_cli_volume_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/cloudbender/test_data_connectors_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/cloudbender/test_datastores_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/cloudbender/test_device_configs_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/cloudbender/test_devices_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/cloudbender/test_nodes_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/cloudbender/test_providers_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/cloudbender/test_regions_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/cloudbender/test_services_unit.py +0 -0
- /trainml-0.5.8/tests/unit/test_auth.py → /trainml-0.5.9/tests/unit/test_auth_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/test_checkpoints_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/test_connections_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/test_datasets_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/test_environments_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/test_exceptions.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/test_gpu_types_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/test_jobs_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/test_models_unit.py +0 -0
- /trainml-0.5.8/tests/unit/test_trainml.py → /trainml-0.5.9/tests/unit/test_trainml_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/tests/unit/test_volumes_unit.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/__main__.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/auth.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/checkpoints.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/cli/__init__.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/cli/checkpoint.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/cli/cloudbender/__init__.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/cli/cloudbender/data_connector.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/cli/cloudbender/datastore.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/cli/cloudbender/device.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/cli/cloudbender/node.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/cli/cloudbender/provider.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/cli/cloudbender/region.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/cli/cloudbender/service.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/cli/connection.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/cli/dataset.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/cli/environment.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/cli/gpu.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/cli/job/__init__.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/cli/job/create.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/cli/model.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/cli/volume.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/cloudbender/__init__.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/cloudbender/cloudbender.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/cloudbender/data_connectors.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/cloudbender/datastores.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/cloudbender/device_configs.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/cloudbender/devices.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/cloudbender/nodes.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/cloudbender/providers.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/cloudbender/regions.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/cloudbender/services.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/connections.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/datasets.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/environments.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/exceptions.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/gpu_types.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/jobs.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/models.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/trainml.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml/volumes.py +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml.egg-info/dependency_links.txt +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml.egg-info/entry_points.txt +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml.egg-info/requires.txt +0 -0
- {trainml-0.5.8 → trainml-0.5.9}/trainml.egg-info/top_level.txt +0 -0
|
@@ -9,12 +9,6 @@ pytestmark = [mark.sdk, mark.integration, mark.projects]
|
|
|
9
9
|
@mark.create
|
|
10
10
|
@mark.asyncio
|
|
11
11
|
class GetProjectsTests:
|
|
12
|
-
@fixture(scope="class")
|
|
13
|
-
async def project(self, trainml):
|
|
14
|
-
project = await trainml.projects.create(name="New Project", copy_keys=False)
|
|
15
|
-
yield project
|
|
16
|
-
await project.remove()
|
|
17
|
-
|
|
18
12
|
async def test_get_projects(self, trainml):
|
|
19
13
|
projects = await trainml.projects.list()
|
|
20
14
|
assert len(projects) > 0
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import sys
|
|
3
|
+
import asyncio
|
|
4
|
+
from pytest import mark, fixture
|
|
5
|
+
|
|
6
|
+
pytestmark = [mark.sdk, mark.integration, mark.projects]
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@mark.create
|
|
10
|
+
@mark.asyncio
|
|
11
|
+
class ProjectKeysTests:
|
|
12
|
+
@fixture(scope="class")
|
|
13
|
+
async def project_key(self, project):
|
|
14
|
+
project_key = await project.keys.put(
|
|
15
|
+
type="aws", key_id="ASFHALKF", secret="IUHKLHKAHF"
|
|
16
|
+
)
|
|
17
|
+
yield project_key
|
|
18
|
+
await project.keys.remove(type="aws")
|
|
19
|
+
|
|
20
|
+
async def test_list_project_keys(self, project, project_key):
|
|
21
|
+
keys = await project.keys.list()
|
|
22
|
+
assert len(keys) > 0
|
|
23
|
+
|
|
24
|
+
async def test_project_key_properties(self, project, project_key):
|
|
25
|
+
assert isinstance(project_key.project_uuid, str)
|
|
26
|
+
assert isinstance(project_key.type, str)
|
|
27
|
+
assert isinstance(project_key.key_id, str)
|
|
28
|
+
assert project_key.type == "aws"
|
|
29
|
+
assert project.id == project_key.project_uuid
|
|
30
|
+
|
|
31
|
+
async def test_project_key_str(self, project_key):
|
|
32
|
+
string = str(project_key)
|
|
33
|
+
regex = r"^{.*\"type\": \"" + project_key.type + r"\".*}$"
|
|
34
|
+
assert isinstance(string, str)
|
|
35
|
+
assert re.match(regex, string)
|
|
36
|
+
|
|
37
|
+
async def test_project_key_repr(self, project_key):
|
|
38
|
+
string = repr(project_key)
|
|
39
|
+
regex = (
|
|
40
|
+
r"^ProjectKey\( trainml , \*\*{.*'type': '" + project_key.type + r"'.*}\)$"
|
|
41
|
+
)
|
|
42
|
+
assert isinstance(string, str)
|
|
43
|
+
assert re.match(regex, string)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import sys
|
|
3
|
+
import asyncio
|
|
4
|
+
from pytest import mark, fixture
|
|
5
|
+
|
|
6
|
+
pytestmark = [mark.sdk, mark.integration, mark.projects]
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@mark.create
|
|
10
|
+
@mark.asyncio
|
|
11
|
+
class ProjectSecretsTests:
|
|
12
|
+
@fixture(scope="class")
|
|
13
|
+
async def project_secret(self, project):
|
|
14
|
+
project_secret = await project.secrets.put(
|
|
15
|
+
name="secret_value", value="IUHKLHKAHF"
|
|
16
|
+
)
|
|
17
|
+
yield project_secret
|
|
18
|
+
await project.secrets.remove(name="secret_value")
|
|
19
|
+
|
|
20
|
+
async def test_list_project_keys(self, project, project_secret):
|
|
21
|
+
secrets = await project.secrets.list()
|
|
22
|
+
assert len(secrets) > 0
|
|
23
|
+
|
|
24
|
+
async def test_project_secret_properties(self, project, project_secret):
|
|
25
|
+
assert isinstance(project_secret.project_uuid, str)
|
|
26
|
+
assert isinstance(project_secret.name, str)
|
|
27
|
+
assert project_secret.name == "secret_value"
|
|
28
|
+
assert project.id == project_secret.project_uuid
|
|
29
|
+
|
|
30
|
+
async def test_project_secret_str(self, project_secret):
|
|
31
|
+
string = str(project_secret)
|
|
32
|
+
regex = r"^{.*\"name\": \"" + project_secret.name + r"\".*}$"
|
|
33
|
+
assert isinstance(string, str)
|
|
34
|
+
assert re.match(regex, string)
|
|
35
|
+
|
|
36
|
+
async def test_project_secret_repr(self, project_secret):
|
|
37
|
+
string = repr(project_secret)
|
|
38
|
+
regex = (
|
|
39
|
+
r"^ProjectSecret\( trainml , \*\*{.*'name': '"
|
|
40
|
+
+ project_secret.name
|
|
41
|
+
+ r"'.*}\)$"
|
|
42
|
+
)
|
|
43
|
+
assert isinstance(string, str)
|
|
44
|
+
assert re.match(regex, string)
|
|
File without changes
|
|
@@ -16,9 +16,11 @@ from trainml.connections import Connections
|
|
|
16
16
|
from trainml.projects import (
|
|
17
17
|
Projects,
|
|
18
18
|
Project,
|
|
19
|
-
ProjectDatastore,
|
|
20
|
-
ProjectService,
|
|
21
19
|
)
|
|
20
|
+
from trainml.projects.datastores import ProjectDatastore
|
|
21
|
+
from trainml.projects.services import ProjectService
|
|
22
|
+
from trainml.projects.data_connectors import ProjectDataConnector
|
|
23
|
+
|
|
22
24
|
from trainml.cloudbender import Cloudbender
|
|
23
25
|
from trainml.cloudbender.providers import Provider, Providers
|
|
24
26
|
from trainml.cloudbender.regions import Region, Regions
|
|
@@ -26,6 +28,7 @@ from trainml.cloudbender.nodes import Node, Nodes
|
|
|
26
28
|
from trainml.cloudbender.devices import Device, Devices
|
|
27
29
|
from trainml.cloudbender.datastores import Datastore, Datastores
|
|
28
30
|
from trainml.cloudbender.services import Service, Services
|
|
31
|
+
from trainml.cloudbender.data_connectors import DataConnector, DataConnectors
|
|
29
32
|
from trainml.cloudbender.device_configs import DeviceConfig, DeviceConfigs
|
|
30
33
|
|
|
31
34
|
|
|
@@ -948,6 +951,68 @@ def mock_project_services():
|
|
|
948
951
|
]
|
|
949
952
|
|
|
950
953
|
|
|
954
|
+
@fixture(scope="session")
|
|
955
|
+
def mock_data_connectors():
|
|
956
|
+
trainml = Mock()
|
|
957
|
+
yield [
|
|
958
|
+
DataConnector(
|
|
959
|
+
trainml,
|
|
960
|
+
**{
|
|
961
|
+
"provider_uuid": "prov-id-1",
|
|
962
|
+
"region_uuid": "reg-id-1",
|
|
963
|
+
"connector_id": "con-id-1",
|
|
964
|
+
"type": "custom",
|
|
965
|
+
"name": "On-Prem Connection A",
|
|
966
|
+
"protocol": "TCP",
|
|
967
|
+
"port_range": "8000-8099",
|
|
968
|
+
"cidr": "10.0.3.0/24",
|
|
969
|
+
},
|
|
970
|
+
),
|
|
971
|
+
DataConnector(
|
|
972
|
+
trainml,
|
|
973
|
+
**{
|
|
974
|
+
"provider_uuid": "prov-id-2",
|
|
975
|
+
"region_uuid": "reg-id-2",
|
|
976
|
+
"connector_id": "con-id-2",
|
|
977
|
+
"type": "custom",
|
|
978
|
+
"name": "Cloud Connection B",
|
|
979
|
+
"protocol": "UDP",
|
|
980
|
+
"port_range": "5000",
|
|
981
|
+
"cidr": "10.0.2.0/24",
|
|
982
|
+
},
|
|
983
|
+
),
|
|
984
|
+
]
|
|
985
|
+
|
|
986
|
+
|
|
987
|
+
@fixture(
|
|
988
|
+
scope="session",
|
|
989
|
+
)
|
|
990
|
+
def mock_project_data_connectors():
|
|
991
|
+
trainml = Mock()
|
|
992
|
+
yield [
|
|
993
|
+
ProjectDataConnector(
|
|
994
|
+
trainml,
|
|
995
|
+
**{
|
|
996
|
+
"project_uuid": "proj-id-1",
|
|
997
|
+
"region_uuid": "reg-id-1",
|
|
998
|
+
"id": "con-id-1",
|
|
999
|
+
"type": "custom",
|
|
1000
|
+
"name": "On-Prem Connection A",
|
|
1001
|
+
},
|
|
1002
|
+
),
|
|
1003
|
+
ProjectDataConnector(
|
|
1004
|
+
trainml,
|
|
1005
|
+
**{
|
|
1006
|
+
"project_uuid": "proj-id-1",
|
|
1007
|
+
"region_uuid": "reg-id-2",
|
|
1008
|
+
"id": "con-id-2",
|
|
1009
|
+
"type": "custom",
|
|
1010
|
+
"name": "Cloud Connection B",
|
|
1011
|
+
},
|
|
1012
|
+
),
|
|
1013
|
+
]
|
|
1014
|
+
|
|
1015
|
+
|
|
951
1016
|
@fixture(scope="session")
|
|
952
1017
|
def mock_device_configs():
|
|
953
1018
|
trainml = Mock()
|
|
@@ -991,6 +1056,7 @@ def mock_trainml(
|
|
|
991
1056
|
mock_devices,
|
|
992
1057
|
mock_datastores,
|
|
993
1058
|
mock_services,
|
|
1059
|
+
mock_data_connectors,
|
|
994
1060
|
mock_device_configs,
|
|
995
1061
|
):
|
|
996
1062
|
trainml = create_autospec(TrainML)
|
|
@@ -1030,6 +1096,10 @@ def mock_trainml(
|
|
|
1030
1096
|
trainml.cloudbender.datastores.list = AsyncMock(return_value=mock_datastores)
|
|
1031
1097
|
trainml.cloudbender.services = create_autospec(Services)
|
|
1032
1098
|
trainml.cloudbender.services.list = AsyncMock(return_value=mock_services)
|
|
1099
|
+
trainml.cloudbender.data_connectors = create_autospec(DataConnectors)
|
|
1100
|
+
trainml.cloudbender.data_connectors.list = AsyncMock(
|
|
1101
|
+
return_value=mock_data_connectors
|
|
1102
|
+
)
|
|
1033
1103
|
trainml.cloudbender.device_configs = create_autospec(DeviceConfigs)
|
|
1034
1104
|
trainml.cloudbender.device_configs.list = AsyncMock(
|
|
1035
1105
|
return_value=mock_device_configs
|
|
File without changes
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import json
|
|
3
|
+
import logging
|
|
4
|
+
from unittest.mock import AsyncMock, patch
|
|
5
|
+
from pytest import mark, fixture, raises
|
|
6
|
+
from aiohttp import WSMessage, WSMsgType
|
|
7
|
+
|
|
8
|
+
import trainml.projects.data_connectors as specimen
|
|
9
|
+
from trainml.exceptions import (
|
|
10
|
+
ApiError,
|
|
11
|
+
SpecificationError,
|
|
12
|
+
TrainMLException,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
pytestmark = [mark.sdk, mark.unit, mark.projects]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@fixture
|
|
19
|
+
def project_data_connectors(mock_trainml):
|
|
20
|
+
yield specimen.ProjectDataConnectors(mock_trainml, project_id="1")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@fixture
|
|
24
|
+
def project_data_connector(mock_trainml):
|
|
25
|
+
yield specimen.ProjectDataConnector(
|
|
26
|
+
mock_trainml,
|
|
27
|
+
id="ds-id-1",
|
|
28
|
+
name="connector 1",
|
|
29
|
+
project_uuid="proj-id-1",
|
|
30
|
+
type="custom",
|
|
31
|
+
region_uuid="reg-id-1",
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class ProjectDataConnectorsTests:
|
|
36
|
+
@mark.asyncio
|
|
37
|
+
async def test_project_data_connectors_refresh(
|
|
38
|
+
self, project_data_connectors, mock_trainml
|
|
39
|
+
):
|
|
40
|
+
api_response = dict()
|
|
41
|
+
mock_trainml._query = AsyncMock(return_value=api_response)
|
|
42
|
+
await project_data_connectors.refresh()
|
|
43
|
+
mock_trainml._query.assert_called_once_with(
|
|
44
|
+
"/project/1/data_connectors", "PATCH"
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
@mark.asyncio
|
|
48
|
+
async def test_project_data_connectors_list(
|
|
49
|
+
self, project_data_connectors, mock_trainml
|
|
50
|
+
):
|
|
51
|
+
api_response = [
|
|
52
|
+
{
|
|
53
|
+
"project_uuid": "proj-id-1",
|
|
54
|
+
"region_uuid": "reg-id-1",
|
|
55
|
+
"id": "store-id-1",
|
|
56
|
+
"type": "custom",
|
|
57
|
+
"name": "On-Prem Connection A",
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"project_uuid": "proj-id-1",
|
|
61
|
+
"region_uuid": "reg-id-2",
|
|
62
|
+
"id": "store-id-2",
|
|
63
|
+
"type": "custom",
|
|
64
|
+
"name": "Cloud Connection B",
|
|
65
|
+
},
|
|
66
|
+
]
|
|
67
|
+
mock_trainml._query = AsyncMock(return_value=api_response)
|
|
68
|
+
resp = await project_data_connectors.list()
|
|
69
|
+
mock_trainml._query.assert_called_once_with(
|
|
70
|
+
"/project/1/data_connectors", "GET", dict()
|
|
71
|
+
)
|
|
72
|
+
assert len(resp) == 2
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class ProjectDataConnectorTests:
|
|
76
|
+
def test_project_data_connector_properties(self, project_data_connector):
|
|
77
|
+
assert isinstance(project_data_connector.id, str)
|
|
78
|
+
assert isinstance(project_data_connector.name, str)
|
|
79
|
+
assert isinstance(project_data_connector.project_uuid, str)
|
|
80
|
+
assert isinstance(project_data_connector.type, str)
|
|
81
|
+
assert isinstance(project_data_connector.region_uuid, str)
|
|
82
|
+
|
|
83
|
+
def test_project_data_connector_str(self, project_data_connector):
|
|
84
|
+
string = str(project_data_connector)
|
|
85
|
+
regex = r"^{.*\"id\": \"" + project_data_connector.id + r"\".*}$"
|
|
86
|
+
assert isinstance(string, str)
|
|
87
|
+
assert re.match(regex, string)
|
|
88
|
+
|
|
89
|
+
def test_project_data_connector_repr(self, project_data_connector):
|
|
90
|
+
string = repr(project_data_connector)
|
|
91
|
+
regex = (
|
|
92
|
+
r"^ProjectDataConnector\( trainml , \*\*{.*'id': '"
|
|
93
|
+
+ project_data_connector.id
|
|
94
|
+
+ r"'.*}\)$"
|
|
95
|
+
)
|
|
96
|
+
assert isinstance(string, str)
|
|
97
|
+
assert re.match(regex, string)
|
|
98
|
+
|
|
99
|
+
def test_project_data_connector_bool(self, project_data_connector, mock_trainml):
|
|
100
|
+
empty_project_data_connector = specimen.ProjectDataConnector(mock_trainml)
|
|
101
|
+
assert bool(project_data_connector)
|
|
102
|
+
assert not bool(empty_project_data_connector)
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import json
|
|
3
|
+
import logging
|
|
4
|
+
from unittest.mock import AsyncMock, patch
|
|
5
|
+
from pytest import mark, fixture, raises
|
|
6
|
+
from aiohttp import WSMessage, WSMsgType
|
|
7
|
+
|
|
8
|
+
import trainml.projects.datastores as specimen
|
|
9
|
+
from trainml.exceptions import (
|
|
10
|
+
ApiError,
|
|
11
|
+
SpecificationError,
|
|
12
|
+
TrainMLException,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
pytestmark = [mark.sdk, mark.unit, mark.projects]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@fixture
|
|
19
|
+
def project_datastores(mock_trainml):
|
|
20
|
+
yield specimen.ProjectDatastores(mock_trainml, project_id="1")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@fixture
|
|
24
|
+
def project_datastore(mock_trainml):
|
|
25
|
+
yield specimen.ProjectDatastore(
|
|
26
|
+
mock_trainml,
|
|
27
|
+
id="ds-id-1",
|
|
28
|
+
name="datastore 1",
|
|
29
|
+
project_uuid="proj-id-1",
|
|
30
|
+
type="nfs",
|
|
31
|
+
region_uuid="reg-id-1",
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class ProjectDatastoresTests:
|
|
36
|
+
@mark.asyncio
|
|
37
|
+
async def test_project_datastores_refresh(self, project_datastores, mock_trainml):
|
|
38
|
+
api_response = dict()
|
|
39
|
+
mock_trainml._query = AsyncMock(return_value=api_response)
|
|
40
|
+
await project_datastores.refresh()
|
|
41
|
+
mock_trainml._query.assert_called_once_with("/project/1/datastores", "PATCH")
|
|
42
|
+
|
|
43
|
+
@mark.asyncio
|
|
44
|
+
async def test_project_datastores_list(self, project_datastores, mock_trainml):
|
|
45
|
+
api_response = [
|
|
46
|
+
{
|
|
47
|
+
"project_uuid": "proj-id-1",
|
|
48
|
+
"region_uuid": "reg-id-1",
|
|
49
|
+
"id": "store-id-1",
|
|
50
|
+
"type": "nfs",
|
|
51
|
+
"name": "On-prem NFS",
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"project_uuid": "proj-id-1",
|
|
55
|
+
"region_uuid": "reg-id-2",
|
|
56
|
+
"id": "store-id-2",
|
|
57
|
+
"type": "smb",
|
|
58
|
+
"name": "GCP Samba",
|
|
59
|
+
},
|
|
60
|
+
]
|
|
61
|
+
mock_trainml._query = AsyncMock(return_value=api_response)
|
|
62
|
+
resp = await project_datastores.list()
|
|
63
|
+
mock_trainml._query.assert_called_once_with(
|
|
64
|
+
"/project/1/datastores", "GET", dict()
|
|
65
|
+
)
|
|
66
|
+
assert len(resp) == 2
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class ProjectDatastoreTests:
|
|
70
|
+
def test_project_datastore_properties(self, project_datastore):
|
|
71
|
+
assert isinstance(project_datastore.id, str)
|
|
72
|
+
assert isinstance(project_datastore.name, str)
|
|
73
|
+
assert isinstance(project_datastore.project_uuid, str)
|
|
74
|
+
assert isinstance(project_datastore.type, str)
|
|
75
|
+
assert isinstance(project_datastore.region_uuid, str)
|
|
76
|
+
|
|
77
|
+
def test_project_datastore_str(self, project_datastore):
|
|
78
|
+
string = str(project_datastore)
|
|
79
|
+
regex = r"^{.*\"id\": \"" + project_datastore.id + r"\".*}$"
|
|
80
|
+
assert isinstance(string, str)
|
|
81
|
+
assert re.match(regex, string)
|
|
82
|
+
|
|
83
|
+
def test_project_datastore_repr(self, project_datastore):
|
|
84
|
+
string = repr(project_datastore)
|
|
85
|
+
regex = (
|
|
86
|
+
r"^ProjectDatastore\( trainml , \*\*{.*'id': '"
|
|
87
|
+
+ project_datastore.id
|
|
88
|
+
+ r"'.*}\)$"
|
|
89
|
+
)
|
|
90
|
+
assert isinstance(string, str)
|
|
91
|
+
assert re.match(regex, string)
|
|
92
|
+
|
|
93
|
+
def test_project_datastore_bool(self, project_datastore, mock_trainml):
|
|
94
|
+
empty_project_datastore = specimen.ProjectDatastore(mock_trainml)
|
|
95
|
+
assert bool(project_datastore)
|
|
96
|
+
assert not bool(empty_project_datastore)
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import json
|
|
3
|
+
import logging
|
|
4
|
+
from unittest.mock import AsyncMock, patch
|
|
5
|
+
from pytest import mark, fixture, raises
|
|
6
|
+
from aiohttp import WSMessage, WSMsgType
|
|
7
|
+
|
|
8
|
+
import trainml.projects.keys as specimen
|
|
9
|
+
from trainml.exceptions import (
|
|
10
|
+
ApiError,
|
|
11
|
+
SpecificationError,
|
|
12
|
+
TrainMLException,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
pytestmark = [mark.sdk, mark.unit, mark.projects]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@fixture
|
|
19
|
+
def project_keys(mock_trainml):
|
|
20
|
+
yield specimen.ProjectKeys(mock_trainml, project_id="1")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@fixture
|
|
24
|
+
def project_key(mock_trainml):
|
|
25
|
+
yield specimen.ProjectKey(
|
|
26
|
+
mock_trainml, project_uuid="proj-id-1", type="aws", key_id="AIYHGFSDLK"
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ProjectKeysTests:
|
|
31
|
+
@mark.asyncio
|
|
32
|
+
async def test_project_keys_list(self, project_keys, mock_trainml):
|
|
33
|
+
api_response = [
|
|
34
|
+
{"project_uuid": "proj-id-1", "type": "aws", "key_id": "AIYHGFSDLK"},
|
|
35
|
+
{"project_uuid": "proj-id-1", "type": "gcp", "key_id": "credentials.json"},
|
|
36
|
+
]
|
|
37
|
+
mock_trainml._query = AsyncMock(return_value=api_response)
|
|
38
|
+
resp = await project_keys.list()
|
|
39
|
+
mock_trainml._query.assert_called_once_with("/project/1/keys", "GET", dict())
|
|
40
|
+
assert len(resp) == 2
|
|
41
|
+
|
|
42
|
+
@mark.asyncio
|
|
43
|
+
async def test_remove_project_key(
|
|
44
|
+
self,
|
|
45
|
+
project_keys,
|
|
46
|
+
mock_trainml,
|
|
47
|
+
):
|
|
48
|
+
api_response = dict()
|
|
49
|
+
mock_trainml._query = AsyncMock(return_value=api_response)
|
|
50
|
+
await project_keys.remove("aws")
|
|
51
|
+
mock_trainml._query.assert_called_once_with(
|
|
52
|
+
"/project/1/key/aws", "DELETE", dict()
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
@mark.asyncio
|
|
56
|
+
async def test_put_project_key(self, project_keys, mock_trainml):
|
|
57
|
+
requested_config = dict(type="aws", key_id="AIUDHADA", secret="ASKHJSLKF")
|
|
58
|
+
expected_payload = dict(key_id="AIUDHADA", secret="ASKHJSLKF")
|
|
59
|
+
api_response = {
|
|
60
|
+
"project_uuid": "project-id-1",
|
|
61
|
+
"type": "aws",
|
|
62
|
+
"key_id": "AIUDHADA",
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
mock_trainml._query = AsyncMock(return_value=api_response)
|
|
66
|
+
response = await project_keys.put(**requested_config)
|
|
67
|
+
mock_trainml._query.assert_called_once_with(
|
|
68
|
+
"/project/1/key/aws", "PUT", None, expected_payload
|
|
69
|
+
)
|
|
70
|
+
assert response.type == "aws"
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class ProjectKeyTests:
|
|
74
|
+
def test_project_key_properties(self, project_key):
|
|
75
|
+
assert isinstance(project_key.type, str)
|
|
76
|
+
assert isinstance(project_key.key_id, str)
|
|
77
|
+
assert isinstance(project_key.project_uuid, str)
|
|
78
|
+
|
|
79
|
+
def test_project_key_str(self, project_key):
|
|
80
|
+
string = str(project_key)
|
|
81
|
+
regex = r"^{.*\"type\": \"" + project_key.type + r"\".*}$"
|
|
82
|
+
assert isinstance(string, str)
|
|
83
|
+
assert re.match(regex, string)
|
|
84
|
+
|
|
85
|
+
def test_project_key_repr(self, project_key):
|
|
86
|
+
string = repr(project_key)
|
|
87
|
+
regex = (
|
|
88
|
+
r"^ProjectKey\( trainml , \*\*{.*'type': '" + project_key.type + r"'.*}\)$"
|
|
89
|
+
)
|
|
90
|
+
assert isinstance(string, str)
|
|
91
|
+
assert re.match(regex, string)
|
|
92
|
+
|
|
93
|
+
def test_project_key_bool(self, project_key, mock_trainml):
|
|
94
|
+
empty_project_key = specimen.ProjectKey(mock_trainml)
|
|
95
|
+
assert bool(project_key)
|
|
96
|
+
assert not bool(empty_project_key)
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import json
|
|
3
|
+
import logging
|
|
4
|
+
from unittest.mock import AsyncMock, patch
|
|
5
|
+
from pytest import mark, fixture, raises
|
|
6
|
+
from aiohttp import WSMessage, WSMsgType
|
|
7
|
+
|
|
8
|
+
import trainml.projects.secrets as specimen
|
|
9
|
+
from trainml.exceptions import (
|
|
10
|
+
ApiError,
|
|
11
|
+
SpecificationError,
|
|
12
|
+
TrainMLException,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
pytestmark = [mark.sdk, mark.unit, mark.projects]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@fixture
|
|
19
|
+
def project_secrets(mock_trainml):
|
|
20
|
+
yield specimen.ProjectSecrets(mock_trainml, project_id="1")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@fixture
|
|
24
|
+
def project_service(mock_trainml):
|
|
25
|
+
yield specimen.ProjectSecret(
|
|
26
|
+
mock_trainml,
|
|
27
|
+
project_uuid="proj-id-1",
|
|
28
|
+
name="secret_value",
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class ProjectSecretsTests:
|
|
33
|
+
@mark.asyncio
|
|
34
|
+
async def test_project_secrets_list(self, project_secrets, mock_trainml):
|
|
35
|
+
api_response = [
|
|
36
|
+
{
|
|
37
|
+
"project_uuid": "proj-id-1",
|
|
38
|
+
"name": "secret_value",
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"project_uuid": "proj-id-1",
|
|
42
|
+
"name": "secret_value_2",
|
|
43
|
+
},
|
|
44
|
+
]
|
|
45
|
+
mock_trainml._query = AsyncMock(return_value=api_response)
|
|
46
|
+
resp = await project_secrets.list()
|
|
47
|
+
mock_trainml._query.assert_called_once_with("/project/1/secrets", "GET", dict())
|
|
48
|
+
assert len(resp) == 2
|
|
49
|
+
|
|
50
|
+
@mark.asyncio
|
|
51
|
+
async def test_remove_project_secret(
|
|
52
|
+
self,
|
|
53
|
+
project_secrets,
|
|
54
|
+
mock_trainml,
|
|
55
|
+
):
|
|
56
|
+
api_response = dict()
|
|
57
|
+
mock_trainml._query = AsyncMock(return_value=api_response)
|
|
58
|
+
await project_secrets.remove("secret_value")
|
|
59
|
+
mock_trainml._query.assert_called_once_with(
|
|
60
|
+
"/project/1/secret/secret_value", "DELETE", dict()
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
@mark.asyncio
|
|
64
|
+
async def test_put_project_secret(self, project_secrets, mock_trainml):
|
|
65
|
+
requested_config = dict(name="secret_value", value="ASKHJSLKF")
|
|
66
|
+
expected_payload = dict(value="ASKHJSLKF")
|
|
67
|
+
api_response = {"project_uuid": "project-id-1", "name": "secret_value"}
|
|
68
|
+
|
|
69
|
+
mock_trainml._query = AsyncMock(return_value=api_response)
|
|
70
|
+
response = await project_secrets.put(**requested_config)
|
|
71
|
+
mock_trainml._query.assert_called_once_with(
|
|
72
|
+
"/project/1/secret/secret_value", "PUT", None, expected_payload
|
|
73
|
+
)
|
|
74
|
+
assert response.name == "secret_value"
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class ProjectSecretTests:
|
|
78
|
+
def test_project_service_properties(self, project_service):
|
|
79
|
+
assert isinstance(project_service.name, str)
|
|
80
|
+
assert isinstance(project_service.project_uuid, str)
|
|
81
|
+
|
|
82
|
+
def test_project_service_str(self, project_service):
|
|
83
|
+
string = str(project_service)
|
|
84
|
+
regex = r"^{.*\"name\": \"" + project_service.name + r"\".*}$"
|
|
85
|
+
assert isinstance(string, str)
|
|
86
|
+
assert re.match(regex, string)
|
|
87
|
+
|
|
88
|
+
def test_project_service_repr(self, project_service):
|
|
89
|
+
string = repr(project_service)
|
|
90
|
+
regex = (
|
|
91
|
+
r"^ProjectSecret\( trainml , \*\*{.*'name': '"
|
|
92
|
+
+ project_service.name
|
|
93
|
+
+ r"'.*}\)$"
|
|
94
|
+
)
|
|
95
|
+
assert isinstance(string, str)
|
|
96
|
+
assert re.match(regex, string)
|
|
97
|
+
|
|
98
|
+
def test_project_service_bool(self, project_service, mock_trainml):
|
|
99
|
+
empty_project_service = specimen.ProjectSecret(mock_trainml)
|
|
100
|
+
assert bool(project_service)
|
|
101
|
+
assert not bool(empty_project_service)
|