|
13 | 13 | # See the License for the specific language governing permissions and |
14 | 14 | # limitations under the License. |
15 | 15 |
|
| 16 | +import json |
| 17 | +import os |
16 | 18 | import tempfile |
17 | 19 | from unittest import mock |
18 | 20 |
|
@@ -153,6 +155,71 @@ def test_describe_running(docker_scheduler, docker_executor): |
153 | 155 | assert len(response.roles) == 1 |
154 | 156 |
|
155 | 157 |
|
| 158 | +def test_describe_failed(docker_scheduler, docker_executor): |
| 159 | + with ( |
| 160 | + mock.patch.object(DockerJobRequest, "load") as mock_load, |
| 161 | + mock.patch.object(DockerContainer, "get_container") as mock_get_container, |
| 162 | + mock.patch.object(PersistentDockerScheduler, "_get_app_state") as mock_get_app_state, |
| 163 | + ): |
| 164 | + container = DockerContainer( |
| 165 | + name="test_role", |
| 166 | + command=["test"], |
| 167 | + executor=docker_executor, |
| 168 | + extra_env={}, |
| 169 | + ) |
| 170 | + req = DockerJobRequest( |
| 171 | + id="test_session___test_role___test_container_id", |
| 172 | + executor=docker_executor, |
| 173 | + containers=[container], |
| 174 | + ) |
| 175 | + mock_load.return_value = req |
| 176 | + mock_get_container.return_value = container |
| 177 | + mock_get_app_state.return_value = None |
| 178 | + status_file = os.path.join(req.executor.job_dir, f"status_{req.containers[0].name}.out") |
| 179 | + |
| 180 | + with open(status_file, "w") as f: |
| 181 | + f.write(json.dumps({"exit_code": 1})) |
| 182 | + |
| 183 | + response = docker_scheduler.describe(req.id) |
| 184 | + assert response is not None |
| 185 | + assert response.app_id == req.id |
| 186 | + assert "FAILED" in str(response.state) |
| 187 | + assert len(response.roles) == 1 |
| 188 | + |
| 189 | + |
| 190 | +@pytest.mark.xfail |
| 191 | +def test_describe_failure_not_detected(docker_scheduler, docker_executor): |
| 192 | + with ( |
| 193 | + mock.patch.object(DockerJobRequest, "load") as mock_load, |
| 194 | + mock.patch.object(DockerContainer, "get_container") as mock_get_container, |
| 195 | + mock.patch.object(PersistentDockerScheduler, "_get_app_state") as mock_get_app_state, |
| 196 | + ): |
| 197 | + container = DockerContainer( |
| 198 | + name="test_role", |
| 199 | + command=["test"], |
| 200 | + executor=docker_executor, |
| 201 | + extra_env={}, |
| 202 | + ) |
| 203 | + req = DockerJobRequest( |
| 204 | + id="test_session___test_role___test_container_id", |
| 205 | + executor=docker_executor, |
| 206 | + containers=[container], |
| 207 | + ) |
| 208 | + mock_load.return_value = req |
| 209 | + mock_get_container.return_value = container |
| 210 | + mock_get_app_state.return_value = None |
| 211 | + status_file = os.path.join(req.executor.job_dir, f"status_{req.containers[0].name}.out") |
| 212 | + |
| 213 | + with open(status_file, "w") as f: |
| 214 | + f.write(json.dumps({"exit_code": 1})) |
| 215 | + |
| 216 | + response = docker_scheduler.describe(req.id) |
| 217 | + assert response is not None |
| 218 | + assert response.app_id == req.id |
| 219 | + assert "SUCCEEDED" in str(response.state) |
| 220 | + assert len(response.roles) == 1 |
| 221 | + |
| 222 | + |
156 | 223 | def test_save_and_get_job_dirs(): |
157 | 224 | with tempfile.TemporaryDirectory() as temp_dir: |
158 | 225 | from nemo_run.config import set_nemorun_home |
|
0 commit comments