gmicloud 0.1.0__py3-none-any.whl

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.
@@ -0,0 +1,274 @@
1
+ import unittest
2
+ from unittest.mock import patch
3
+ from gmicloud._internal._manager._artifact_manager import ArtifactManager
4
+ from gmicloud._internal._client._iam_client import IAMClient
5
+ from gmicloud._internal._models import *
6
+ from gmicloud._internal._enums import BuildStatus
7
+
8
+
9
+ class TestArtifactManager(unittest.TestCase):
10
+
11
+ def setUp(self):
12
+ self.mock_user_id = "test_user_id"
13
+ self.mock_token = "test_token"
14
+
15
+ self.iam_client = IAMClient(client_id="test_client_id", email="test_email", password="test_password")
16
+ self.iam_client._user_id = self.mock_user_id
17
+ self.iam_client._access_token = self.mock_token
18
+
19
+ self.artifact_manager = ArtifactManager(self.iam_client)
20
+
21
+ @patch('gmicloud._internal._client._artifact_client.ArtifactClient.get_artifact')
22
+ def test_get_artifact_returns_artifact(self, mock_get_artifact):
23
+ mock_get_artifact.return_value = Artifact(artifact_id="1")
24
+ artifact = self.artifact_manager.get_artifact("1")
25
+ self.assertEqual(artifact.artifact_id, "1")
26
+
27
+ @patch('gmicloud._internal._client._artifact_client.ArtifactClient.get_artifact')
28
+ def test_get_artifact_raises_error_for_invalid_artifact_id(self, mock_get_artifact):
29
+ with self.assertRaises(ValueError) as context:
30
+ self.artifact_manager.get_artifact("")
31
+ self.assertTrue("Artifact ID is required and cannot be empty." in str(context.exception))
32
+
33
+ @patch('gmicloud._internal._client._artifact_client.ArtifactClient.get_artifact')
34
+ def test_get_artifact_raises_error_for_nonexistent_artifact(self, mock_get_artifact):
35
+ mock_get_artifact.side_effect = Exception("Artifact not found")
36
+ with self.assertRaises(Exception) as context:
37
+ self.artifact_manager.get_artifact("nonexistent_id")
38
+ self.assertTrue("Artifact not found" in str(context.exception))
39
+
40
+ @patch('gmicloud._internal._client._artifact_client.ArtifactClient.get_all_artifacts')
41
+ def test_get_all_artifacts(self, mock_get_all_artifacts):
42
+ mock_dict = {
43
+ 'artifact_id': 'test',
44
+ 'artifact_data': {
45
+ 'artifact_type': 'DockerImage',
46
+ 'artifact_link': 'link',
47
+ 'build_status': 'SUCCESS',
48
+ 'build_error': '',
49
+ 'build_id': 'test',
50
+ 'build_file_name': '',
51
+ 'create_at': '2024-12-25T03:20:39.820623326Z',
52
+ 'update_at': '2024-12-25T03:36:25.483679194Z',
53
+ 'status': ''
54
+ },
55
+ 'artifact_metadata': {
56
+ 'user_id': 'test',
57
+ 'artifact_name': 'name',
58
+ 'artifact_description': 'description',
59
+ 'artifact_tags': ['tags', 'test']
60
+ },
61
+ 'big_files_metadata': None
62
+ }
63
+ mock_get_all_artifacts.return_value = [Artifact(**mock_dict)]
64
+
65
+ artifacts = self.artifact_manager.get_all_artifacts()
66
+ self.assertEqual(len(artifacts), 1)
67
+
68
+ @patch('gmicloud._internal._client._artifact_client.ArtifactClient.create_artifact')
69
+ def test_create_artifact(self, mock_create_artifact):
70
+ mock_response = CreateArtifactResponse(artifact_id="test_artifact_id", upload_link="mock_link")
71
+ mock_create_artifact.return_value = mock_response
72
+
73
+ response = self.artifact_manager.create_artifact("artifact_name")
74
+ self.assertEqual(response.artifact_id, "test_artifact_id")
75
+
76
+ @patch("gmicloud._internal._client._file_upload_client.FileUploadClient.upload_small_file")
77
+ @patch('gmicloud._internal._client._artifact_client.ArtifactClient.create_artifact')
78
+ def test_create_artifact_with_file(self, mock_create_artifact, mock_upload_small_file):
79
+ upload_link = "http://upload-link"
80
+ artifact_file_path = "./testdata/test.zip"
81
+
82
+ mock_response = CreateArtifactResponse(artifact_id="test_artifact_id", upload_link=upload_link)
83
+ mock_create_artifact.return_value = mock_response
84
+
85
+ artifact_id = self.artifact_manager.create_artifact_with_file(
86
+ artifact_name="artifact_name",
87
+ artifact_file_path=artifact_file_path,
88
+ )
89
+ self.assertEqual(artifact_id, "test_artifact_id")
90
+ mock_upload_small_file.assert_called_once_with(upload_link, artifact_file_path, "application/zip")
91
+
92
+ def test_create_artifact_with_file_raises_error_for_invalid_file_type(self):
93
+ with self.assertRaises(ValueError) as context:
94
+ self.artifact_manager.create_artifact_with_file("artifact_name", "./testdata/test.txt")
95
+ self.assertTrue("File type must be application/zip." in str(context.exception))
96
+
97
+ def test_create_artifact_with_file_raises_file_not_found_error(self):
98
+ with self.assertRaises(FileNotFoundError) as context:
99
+ self.artifact_manager.create_artifact_with_file("artifact_name", "./testdata/nonexistent.zip")
100
+ self.assertTrue("File not found: ./testdata/nonexistent.zip" in str(context.exception))
101
+
102
+ @patch('gmicloud._internal._client._artifact_client.ArtifactClient.create_artifact_from_template')
103
+ def test_create_artifact_from_template_creates_artifact(self, mock_create_artifact_from_template):
104
+ mock_create_artifact_from_template.return_value = CreateArtifactFromTemplateResponse(artifact_id="1",
105
+ status="success")
106
+ artifact_template_id = "template123"
107
+ response = self.artifact_manager.create_artifact_from_template(artifact_template_id)
108
+ self.assertEqual(response.artifact_id, "1")
109
+
110
+ @patch('gmicloud._internal._client._artifact_client.ArtifactClient.create_artifact_from_template')
111
+ def test_create_artifact_from_template_raises_error_for_invalid_template_id(self,
112
+ mock_create_artifact_from_template):
113
+ with self.assertRaises(ValueError) as context:
114
+ self.artifact_manager.create_artifact_from_template("")
115
+ self.assertTrue("Artifact template ID is required and cannot be empty." in str(context.exception))
116
+
117
+ @patch('gmicloud._internal._client._artifact_client.ArtifactClient.create_artifact_from_template')
118
+ def test_create_artifact_from_template_raises_error_for_nonexistent_template(self,
119
+ mock_create_artifact_from_template):
120
+ mock_create_artifact_from_template.side_effect = Exception("Template not found")
121
+ with self.assertRaises(Exception) as context:
122
+ self.artifact_manager.create_artifact_from_template("nonexistent_template_id")
123
+ self.assertTrue("Template not found" in str(context.exception))
124
+
125
+ @patch('gmicloud._internal._client._artifact_client.ArtifactClient.create_artifact')
126
+ @patch('gmicloud._internal._client._artifact_client.ArtifactClient.get_bigfile_upload_url')
127
+ @patch('gmicloud._internal._client._file_upload_client.FileUploadClient.upload_small_file')
128
+ @patch('gmicloud._internal._client._file_upload_client.FileUploadClient.upload_large_file')
129
+ def test_create_artifact_with_model_files(self, mock_upload_large_file, mock_upload_small_file,
130
+ mock_get_bigfile_upload_url, mock_create_artifact):
131
+ upload_link = "http://upload-link"
132
+ bigfile_upload_link = "http://bigfile-upload-link"
133
+ artifact_file_path = "./testdata/test.zip"
134
+ model_file_path = "./testdata/model.zip"
135
+
136
+ mock_create_artifact.return_value = CreateArtifactResponse(artifact_id="1", upload_link=upload_link)
137
+ mock_get_bigfile_upload_url.return_value = GetBigFileUploadUrlResponse(artifact_id="1",
138
+ upload_link=bigfile_upload_link)
139
+
140
+ artifact_id = self.artifact_manager.create_artifact_with_model_files(artifact_name="artifact_name",
141
+ artifact_file_path=artifact_file_path,
142
+ model_file_paths=[model_file_path])
143
+ self.assertEqual(artifact_id, "1")
144
+ mock_upload_small_file.assert_called_once_with(upload_link, artifact_file_path, "application/zip")
145
+ mock_upload_large_file.assert_called_once_with(bigfile_upload_link, model_file_path)
146
+
147
+ @patch('gmicloud._internal._client._artifact_client.ArtifactClient.create_artifact')
148
+ @patch('gmicloud._internal._client._file_upload_client.FileUploadClient.upload_small_file')
149
+ def test_create_artifact_with_model_files_raises_file_not_found_error_for_model_file(self, mock_create_artifact,
150
+ mock_upload_small_file):
151
+ upload_link = "http://upload-link"
152
+ artifact_file_path = "./testdata/test.zip"
153
+ model_file_path = "./testdata/nonexistent.zip"
154
+
155
+ mock_create_artifact.return_value = CreateArtifactResponse(artifact_id="1", upload_link=upload_link)
156
+
157
+ with self.assertRaises(FileNotFoundError) as context:
158
+ self.artifact_manager.create_artifact_with_model_files(artifact_name="artifact_name",
159
+ artifact_file_path=artifact_file_path,
160
+ model_file_paths=[model_file_path])
161
+ self.assertTrue(f"File not found: {model_file_path}" in str(context.exception))
162
+
163
+ @patch('gmicloud._internal._client._artifact_client.ArtifactClient.rebuild_artifact')
164
+ def test_rebuild_artifact_rebuilds_successfully(self, mock_rebuild_artifact):
165
+ mock_rebuild_artifact.return_value = RebuildArtifactResponse(artifact_id="1", build_status=BuildStatus.SUCCESS)
166
+ response = self.artifact_manager.rebuild_artifact("1")
167
+ self.assertEqual(response.artifact_id, "1")
168
+
169
+ @patch('gmicloud._internal._client._artifact_client.ArtifactClient.rebuild_artifact')
170
+ def test_rebuild_artifact_raises_error_for_invalid_artifact_id(self, mock_rebuild_artifact):
171
+ with self.assertRaises(ValueError) as context:
172
+ self.artifact_manager.rebuild_artifact("")
173
+ self.assertTrue("Artifact ID is required and cannot be empty." in str(context.exception))
174
+
175
+ @patch('gmicloud._internal._client._artifact_client.ArtifactClient.rebuild_artifact')
176
+ def test_rebuild_artifact_raises_error_for_nonexistent_artifact(self, mock_rebuild_artifact):
177
+ mock_rebuild_artifact.side_effect = Exception("Artifact not found")
178
+ with self.assertRaises(Exception) as context:
179
+ self.artifact_manager.rebuild_artifact("nonexistent_id")
180
+ self.assertTrue("Artifact not found" in str(context.exception))
181
+
182
+ @patch('gmicloud._internal._client._artifact_client.ArtifactClient.delete_artifact')
183
+ def test_delete_artifact_deletes_successfully(self, mock_delete_artifact):
184
+ mock_delete_artifact.return_value = DeleteArtifactResponse(artifact_id="1")
185
+ response = self.artifact_manager.delete_artifact("1")
186
+ self.assertEqual(response.artifact_id, "1")
187
+
188
+ @patch('gmicloud._internal._client._artifact_client.ArtifactClient.delete_artifact')
189
+ def test_delete_artifact_raises_error_for_invalid_artifact_id(self, mock_delete_artifact):
190
+ with self.assertRaises(ValueError) as context:
191
+ self.artifact_manager.delete_artifact("")
192
+ self.assertTrue("Artifact ID is required and cannot be empty." in str(context.exception))
193
+
194
+ @patch('gmicloud._internal._client._artifact_client.ArtifactClient.delete_artifact')
195
+ def test_delete_artifact_raises_error_for_nonexistent_artifact(self, mock_delete_artifact):
196
+ mock_delete_artifact.side_effect = Exception("Artifact not found")
197
+ with self.assertRaises(Exception) as context:
198
+ self.artifact_manager.delete_artifact("nonexistent_id")
199
+ self.assertTrue("Artifact not found" in str(context.exception))
200
+
201
+ @patch('gmicloud._internal._client._artifact_client.ArtifactClient.get_bigfile_upload_url')
202
+ def test_get_bigfile_upload_url_returns_upload_link(self, mock_get_bigfile_upload_url):
203
+ upload_link = "http://upload-link"
204
+ model_file_path = "./testdata/model.zip"
205
+
206
+ mock_get_bigfile_upload_url.return_value = GetBigFileUploadUrlResponse(artifact_id="1", upload_link=upload_link)
207
+ upload_link = self.artifact_manager.get_bigfile_upload_url("1", model_file_path)
208
+ self.assertEqual(upload_link, upload_link)
209
+
210
+ @patch('gmicloud._internal._client._artifact_client.ArtifactClient.get_bigfile_upload_url')
211
+ def test_get_bigfile_upload_url_raises_error_for_invalid_artifact_id(self, mock_get_bigfile_upload_url):
212
+ with self.assertRaises(ValueError) as context:
213
+ self.artifact_manager.get_bigfile_upload_url("", "./testdata/test.zip")
214
+ self.assertTrue("Artifact ID is required and cannot be empty." in str(context.exception))
215
+
216
+ @patch('gmicloud._internal._client._artifact_client.ArtifactClient.get_bigfile_upload_url')
217
+ def test_get_bigfile_upload_url_raises_error_for_invalid_file_path(self, mock_get_bigfile_upload_url):
218
+ with self.assertRaises(ValueError) as context:
219
+ self.artifact_manager.get_bigfile_upload_url("1", "")
220
+ self.assertTrue("File path is required and cannot be empty." in str(context.exception))
221
+
222
+ @patch('gmicloud._internal._client._artifact_client.ArtifactClient.get_bigfile_upload_url')
223
+ def test_get_bigfile_upload_url_raises_error_for_nonexistent_file(self, mock_get_bigfile_upload_url):
224
+ with self.assertRaises(FileNotFoundError) as context:
225
+ self.artifact_manager.get_bigfile_upload_url("1", "./testdata/nonexistent.zip")
226
+ self.assertTrue("File not found: ./testdata/nonexistent.zip" in str(context.exception))
227
+
228
+ @patch('gmicloud._internal._client._artifact_client.ArtifactClient.delete_bigfile')
229
+ def test_delete_bigfile_deletes_successfully(self, mock_delete_bigfile):
230
+ mock_delete_bigfile.return_value = DeleteBigfileResponse(artifact_id="1", file_name="file.txt",
231
+ status="success")
232
+ response = self.artifact_manager.delete_bigfile("1", "file.txt")
233
+ self.assertEqual(response, "success")
234
+
235
+ @patch('gmicloud._internal._client._artifact_client.ArtifactClient.delete_bigfile')
236
+ def test_delete_bigfile_raises_error_for_invalid_artifact_id(self, mock_delete_bigfile):
237
+ with self.assertRaises(ValueError) as context:
238
+ self.artifact_manager.delete_bigfile("", "file.txt")
239
+ self.assertTrue("Artifact ID is required and cannot be empty." in str(context.exception))
240
+
241
+ @patch('gmicloud._internal._client._artifact_client.ArtifactClient.delete_bigfile')
242
+ def test_delete_bigfile_raises_error_for_invalid_file_name(self, mock_delete_bigfile):
243
+ with self.assertRaises(ValueError) as context:
244
+ self.artifact_manager.delete_bigfile("1", "")
245
+ self.assertTrue("File name is required and cannot be empty." in str(context.exception))
246
+
247
+ @patch('gmicloud._internal._client._artifact_client.ArtifactClient.delete_bigfile')
248
+ def test_delete_bigfile_raises_error_for_nonexistent_artifact(self, mock_delete_bigfile):
249
+ mock_delete_bigfile.side_effect = Exception("Artifact not found")
250
+ with self.assertRaises(Exception) as context:
251
+ self.artifact_manager.delete_bigfile("nonexistent_id", "file.txt")
252
+ self.assertTrue("Artifact not found" in str(context.exception))
253
+
254
+ @patch('gmicloud._internal._client._artifact_client.ArtifactClient.get_artifact_templates')
255
+ def test_get_artifact_templates_returns_templates(self, mock_get_artifact_templates):
256
+ mock_get_artifact_templates.return_value = GetArtifactTemplatesResponse(
257
+ artifact_templates=[ArtifactTemplate(artifact_template_id="1", artifact_name="Template1")])
258
+ templates = self.artifact_manager.get_artifact_templates()
259
+ self.assertEqual(len(templates), 1)
260
+ self.assertEqual(templates[0].artifact_template_id, "1")
261
+ self.assertEqual(templates[0].artifact_name, "Template1")
262
+
263
+ @patch('gmicloud._internal._client._artifact_client.ArtifactClient.get_artifact_templates')
264
+ def test_get_artifact_templates_returns_empty_list_when_no_templates(self, mock_get_artifact_templates):
265
+ mock_get_artifact_templates.return_value = GetArtifactTemplatesResponse(artifact_templates=[])
266
+ templates = self.artifact_manager.get_artifact_templates()
267
+ self.assertEqual(len(templates), 0)
268
+
269
+ @patch('gmicloud._internal._client._artifact_client.ArtifactClient.get_artifact_templates')
270
+ def test_get_artifact_templates_raises_error_on_failure(self, mock_get_artifact_templates):
271
+ mock_get_artifact_templates.side_effect = Exception("Failed to fetch templates")
272
+ with self.assertRaises(Exception) as context:
273
+ self.artifact_manager.get_artifact_templates()
274
+ self.assertTrue("Failed to fetch templates" in str(context.exception))
@@ -0,0 +1,207 @@
1
+ import unittest
2
+ from unittest.mock import MagicMock, patch, Mock
3
+ from gmicloud._internal._manager._task_manager import TaskManager
4
+ from gmicloud._internal._client._iam_client import IAMClient
5
+ from gmicloud._internal._models import *
6
+
7
+
8
+ class TestTaskManager(unittest.TestCase):
9
+
10
+ def setUp(self):
11
+ self.mock_user_id = "test_user_id"
12
+ self.mock_token = "test_token"
13
+
14
+ self.iam_client = IAMClient(client_id="test_client_id", email="test_email", password="test_password")
15
+ self.iam_client._user_id = self.mock_user_id
16
+ self.iam_client._access_token = self.mock_token
17
+ self.task_manager = TaskManager(self.iam_client)
18
+
19
+ @patch('gmicloud._internal._client._task_client.TaskClient.get_task')
20
+ def test_get_task_returns_task_successfully(self, mock_get_task):
21
+ mock_get_task.return_value = Task(task_id="1")
22
+ task = self.task_manager.get_task("1")
23
+ self.assertEqual(task.task_id, "1")
24
+
25
+ @patch('gmicloud._internal._client._task_client.TaskClient.get_task')
26
+ def test_get_task_raises_error_for_invalid_task_id(self, mock_get_task):
27
+ with self.assertRaises(ValueError) as context:
28
+ self.task_manager.get_task("")
29
+ self.assertTrue("Task ID is required and cannot be empty." in str(context.exception))
30
+
31
+ @patch('gmicloud._internal._client._task_client.TaskClient.get_task')
32
+ def test_get_task_raises_error_for_nonexistent_task(self, mock_get_task):
33
+ mock_get_task.side_effect = Exception("Task not found")
34
+ with self.assertRaises(Exception) as context:
35
+ self.task_manager.get_task("nonexistent_id")
36
+ self.assertTrue("Task not found" in str(context.exception))
37
+
38
+ @patch('gmicloud._internal._client._task_client.TaskClient.get_all_tasks')
39
+ def test_get_all_tasks_returns_list_of_tasks(self, mock_get_all_tasks):
40
+ mock_dict = {
41
+ 'task_id': 'test',
42
+ 'owner': {
43
+ 'user_id': 'test',
44
+ 'group_id': 'current_group_id',
45
+ 'service_account_id': 'current_sa_id'
46
+ },
47
+ 'config': {
48
+ 'ray_task_config': {
49
+ 'ray_version': 'latest-py311-gpu',
50
+ 'ray_cluster_image': '',
51
+ 'file_path': 'serve',
52
+ 'deployment_name': 'app',
53
+ 'artifact_id': 'test',
54
+ 'replica_resource': {
55
+ 'cpu': 6,
56
+ 'ram_gb': 64,
57
+ 'gpu': 2,
58
+ 'gpu_name': ''
59
+ },
60
+ 'volume_mounts': None
61
+ },
62
+ 'task_scheduling': {
63
+ 'scheduling_oneoff': {
64
+ 'trigger_timestamp': 0,
65
+ 'min_replicas': 0,
66
+ 'max_replicas': 0
67
+ },
68
+ 'scheduling_daily': {
69
+ 'triggers': None
70
+ }
71
+ },
72
+ 'create_timestamp': 1734951094,
73
+ 'last_update_timestamp': 1734975798
74
+ },
75
+ 'task_status': '',
76
+ 'readiness_status': '',
77
+ 'info': {
78
+ 'endpoint_status': 'ready',
79
+ 'endpoint': 'api.GMICOULD.ai/INFERENCEENGINE/c49bfbc9-3'
80
+ }
81
+ }
82
+ mock_get_all_tasks.return_value = MagicMock(tasks=[Task(**mock_dict)])
83
+ tasks = self.task_manager.get_all_tasks()
84
+ self.assertEqual(len(tasks), 1)
85
+ self.assertEqual(tasks[0].task_id, "test")
86
+
87
+ @patch('gmicloud._internal._client._task_client.TaskClient.get_all_tasks')
88
+ def test_get_all_tasks_handles_empty_list(self, mock_get_all_tasks):
89
+ mock_get_all_tasks.return_value = MagicMock(tasks=[])
90
+ tasks = self.task_manager.get_all_tasks()
91
+ self.assertEqual(len(tasks), 0)
92
+
93
+ @patch('gmicloud._internal._client._task_client.TaskClient.create_task')
94
+ def test_create_task_raises_error_for_none_task(self, mock_create_task):
95
+ with self.assertRaises(ValueError) as context:
96
+ self.task_manager.create_task(None)
97
+ self.assertTrue("Task object is required and cannot be None." in str(context.exception))
98
+
99
+ @patch('gmicloud._internal._client._task_client.TaskClient.create_task')
100
+ def test_create_task_from_file_creates_task(self, mock_create_task):
101
+ self.task_manager.create_task_from_file("1", "./testdata/one-off_task.json", int(datetime.now().timestamp()))
102
+ mock_create_task.assert_called_once()
103
+
104
+ @patch('gmicloud._internal._client._task_client.TaskClient.create_task')
105
+ def test_create_task_from_file_raises_error_for_invalid_file(self, mock_create_task):
106
+ with self.assertRaises(ValueError) as context:
107
+ self.task_manager.create_task_from_file("1", "./testdata/one-off_task_err.json")
108
+ self.assertTrue("Failed to parse Task from file" in str(context.exception))
109
+
110
+ @patch('gmicloud._internal._client._task_client.TaskClient.update_task_schedule')
111
+ def test_update_task_schedule_raises_error_for_none_task(self, mock_update_task_schedule):
112
+ with self.assertRaises(ValueError) as context:
113
+ self.task_manager.update_task_schedule(None)
114
+ self.assertTrue("Task object is required and cannot be None." in str(context.exception))
115
+
116
+ @patch('gmicloud._internal._client._task_client.TaskClient.update_task_schedule')
117
+ def test_update_task_schedule_from_file_updates_schedule(self, mock_update_task_schedule):
118
+ self.task_manager.update_task_schedule_from_file("1", "1", "./testdata/daily_task.json")
119
+ mock_update_task_schedule.assert_called_once()
120
+
121
+ @patch('gmicloud._internal._client._task_client.TaskClient.update_task_schedule')
122
+ def test_update_task_schedule_from_file_raises_error_for_invalid_file(self, mock_update_task_schedule):
123
+ with self.assertRaises(ValueError) as context:
124
+ self.task_manager.update_task_schedule_from_file("1", "1", "./testdata/one-off_task_err.json")
125
+ self.assertTrue("Failed to parse Task from file" in str(context.exception))
126
+
127
+ @patch('gmicloud._internal._client._task_client.TaskClient.start_task')
128
+ def test_start_task_starts_successfully(self, mock_start_task):
129
+ mock_start_task.return_value = None
130
+ self.task_manager.start_task("1")
131
+ mock_start_task.assert_called_once_with("1")
132
+
133
+ @patch('gmicloud._internal._client._task_client.TaskClient.start_task')
134
+ def test_start_task_raises_error_for_invalid_task_id(self, mock_start_task):
135
+ with self.assertRaises(ValueError) as context:
136
+ self.task_manager.start_task("")
137
+ self.assertTrue("Task ID is required and cannot be empty." in str(context.exception))
138
+
139
+ @patch('gmicloud._internal._client._task_client.TaskClient.start_task')
140
+ def test_start_task_raises_error_for_nonexistent_task(self, mock_start_task):
141
+ mock_start_task.side_effect = Exception("Task not found")
142
+ with self.assertRaises(Exception) as context:
143
+ self.task_manager.start_task("nonexistent_id")
144
+ self.assertTrue("Task not found" in str(context.exception))
145
+
146
+ @patch('gmicloud._internal._client._task_client.TaskClient.stop_task')
147
+ def test_stop_task_stops_successfully(self, mock_stop_task):
148
+ mock_stop_task.return_value = None
149
+ self.task_manager.stop_task("1")
150
+ mock_stop_task.assert_called_once_with("1")
151
+
152
+ @patch('gmicloud._internal._client._task_client.TaskClient.stop_task')
153
+ def test_stop_task_raises_error_for_invalid_task_id(self, mock_stop_task):
154
+ with self.assertRaises(ValueError) as context:
155
+ self.task_manager.stop_task("")
156
+ self.assertTrue("Task ID is required and cannot be empty." in str(context.exception))
157
+
158
+ @patch('gmicloud._internal._client._task_client.TaskClient.stop_task')
159
+ def test_stop_task_raises_error_for_nonexistent_task(self, mock_stop_task):
160
+ mock_stop_task.side_effect = Exception("Task not found")
161
+ with self.assertRaises(Exception) as context:
162
+ self.task_manager.stop_task("nonexistent_id")
163
+ self.assertTrue("Task not found" in str(context.exception))
164
+
165
+ @patch('gmicloud._internal._client._task_client.TaskClient.get_usage_data')
166
+ def test_get_usage_data_returns_data_successfully(self, mock_get_usage_data):
167
+ mock_get_usage_data.return_value = GetUsageDataResponse(usage_data=[Usage(replica_count=1)])
168
+ response = self.task_manager.get_usage_data("2023-01-01T00:00:00Z", "2023-01-31T23:59:59Z")
169
+ self.assertEqual(response.usage_data[0].replica_count, 1)
170
+
171
+ @patch('gmicloud._internal._client._task_client.TaskClient.get_usage_data')
172
+ def test_get_usage_data_raises_error_for_invalid_start_timestamp(self, mock_get_usage_data):
173
+ with self.assertRaises(ValueError) as context:
174
+ self.task_manager.get_usage_data("", "2023-01-31T23:59:59Z")
175
+ self.assertTrue("Start timestamp is required and cannot be empty." in str(context.exception))
176
+
177
+ @patch('gmicloud._internal._client._task_client.TaskClient.get_usage_data')
178
+ def test_get_usage_data_raises_error_for_invalid_end_timestamp(self, mock_get_usage_data):
179
+ with self.assertRaises(ValueError) as context:
180
+ self.task_manager.get_usage_data("2023-01-01T00:00:00Z", "")
181
+ self.assertTrue("End timestamp is required and cannot be empty." in str(context.exception))
182
+
183
+ @patch('gmicloud._internal._client._task_client.TaskClient.get_usage_data')
184
+ def test_get_usage_data_raises_error_on_failure(self, mock_get_usage_data):
185
+ mock_get_usage_data.side_effect = Exception("Failed to fetch usage data")
186
+ with self.assertRaises(Exception) as context:
187
+ self.task_manager.get_usage_data("2023-01-01T00:00:00Z", "2023-01-31T23:59:59Z")
188
+ self.assertTrue("Failed to fetch usage data" in str(context.exception))
189
+
190
+ @patch('gmicloud._internal._client._task_client.TaskClient.archive_task')
191
+ def test_archive_task_archives_successfully(self, mock_archive_task):
192
+ mock_archive_task.return_value = None
193
+ self.task_manager.archive_task("1")
194
+ mock_archive_task.assert_called_once_with("1")
195
+
196
+ @patch('gmicloud._internal._client._task_client.TaskClient.archive_task')
197
+ def test_archive_task_raises_error_for_invalid_task_id(self, mock_archive_task):
198
+ with self.assertRaises(ValueError) as context:
199
+ self.task_manager.archive_task("")
200
+ self.assertTrue("Task ID is required and cannot be empty." in str(context.exception))
201
+
202
+ @patch('gmicloud._internal._client._task_client.TaskClient.archive_task')
203
+ def test_archive_task_raises_error_for_nonexistent_task(self, mock_archive_task):
204
+ mock_archive_task.side_effect = Exception("Task not found")
205
+ with self.assertRaises(Exception) as context:
206
+ self.task_manager.archive_task("nonexistent_id")
207
+ self.assertTrue("Task not found" in str(context.exception))