Skip to content
This repository was archived by the owner on Jan 23, 2026. It is now read-only.

Commit 616f718

Browse files
committed
Use new set_instance_state
1 parent af21f4b commit 616f718

3 files changed

Lines changed: 21 additions & 91 deletions

File tree

packages/jumpstarter-driver-corellium/jumpstarter_driver_corellium/corellium/api.py

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -103,26 +103,20 @@ def create_instance(self, name: str, project: Project, device: Device, os_versio
103103

104104
return Instance(**data)
105105

106-
def get_instance(self, instance_ref: str) -> Optional[Instance]:
106+
async def get_instance(self, instance_ref: str) -> Optional[Instance]:
107107
"""
108108
Retrieve an existing instance by its name.
109109
110110
Return None if it does not exist.
111111
"""
112-
try:
113-
res = self.req.get(f"{self.baseurl}/v1/instances")
114-
data = res.json()
115-
res.raise_for_status()
116-
except requests.exceptions.RequestException as e:
117-
raise CorelliumApiException(data.get("error", str(e))) from e
118-
119-
for instance in data:
120-
if instance["name"] == instance_ref or instance["id"] == instance_ref:
121-
return Instance(id=instance["id"], state=instance["state"])
112+
instances = await self.api.v1_get_instances()
113+
for instance in instances:
114+
if instance.name == instance_ref or instance.id == instance_ref:
115+
return instance
122116

123117
return None
124118

125-
def set_instance_state(self, instance: Instance, instance_state: str) -> None:
119+
async def set_instance_state(self, instance: Instance, instance_state: str) -> None:
126120
"""
127121
Set the virtual instance state from corellium.
128122
@@ -138,16 +132,11 @@ def set_instance_state(self, instance: Instance, instance_state: str) -> None:
138132
- rebooting
139133
- error
140134
"""
141-
data = {"state": instance_state}
142-
143-
try:
144-
res = self.req.put(f"{self.baseurl}/v1/instances/{instance.id}/state", json=data)
145-
data = res.json() if res.status_code != 204 else None
146-
res.raise_for_status()
147-
except requests.exceptions.RequestException as e:
148-
msgerr = data if data is not None else str(e)
149135

150-
raise CorelliumApiException(msgerr) from e
136+
await self.api.v1_set_instance_state(
137+
instance.id,
138+
corellium_api.V1SetStateBody(state=instance_state),
139+
)
151140

152141
async def destroy_instance(self, instance: Instance) -> None:
153142
"""

packages/jumpstarter-driver-corellium/jumpstarter_driver_corellium/driver.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
"""
44

55
import os
6-
import time
76
from collections.abc import AsyncGenerator
87
from dataclasses import dataclass, field
98
from datetime import datetime, timedelta
109
from typing import Dict, Optional
1110

11+
from anyio import sleep
1212
from jumpstarter_driver_power.driver import PowerReading, VirtualPowerInterface
1313

1414
from .corellium.api import ApiClient
@@ -122,7 +122,7 @@ def get_timeout_opts(self) -> Dict[str, int]:
122122
"interval": os.environ.get("CORELLIUM_API_INTERVAL", 5),
123123
}
124124

125-
def wait_instance(self, current: Instance, desired: Optional[Instance]):
125+
async def wait_instance(self, current: Instance, desired: Optional[Instance]):
126126
"""
127127
Wait for `current` instance to reach the same state as the `desired` instance.
128128
@@ -135,11 +135,11 @@ def wait_instance(self, current: Instance, desired: Optional[Instance]):
135135
if counter >= opts["retries"]:
136136
raise ValueError(f"Instance took too long to be reach the desired state: {current}")
137137

138-
if self.parent.api.get_instance(current.id) == desired:
138+
if await self.parent.api.get_instance(current.id) == desired:
139139
break
140140

141141
counter += 1
142-
time.sleep(opts["interval"])
142+
await sleep(opts["interval"])
143143

144144
@export
145145
async def on(self) -> None:
@@ -164,9 +164,9 @@ async def on(self) -> None:
164164
self.logger.info(f"Using device spec: {device.name}")
165165

166166
# retrieve an existing instance first
167-
instance = self.parent.api.get_instance(self.parent.device_name)
167+
instance = await self.parent.api.get_instance(self.parent.device_name)
168168
if instance:
169-
self.parent.api.set_instance_state(instance, "on")
169+
await self.parent.api.set_instance_state(instance, "on")
170170
# create a new one otherwise
171171
else:
172172
opts = {}
@@ -177,7 +177,7 @@ async def on(self) -> None:
177177
instance = self.parent.api.create_instance(self.parent.device_name, project, device, **opts)
178178
self.logger.info(f"Instance: {self.parent.device_name} (ID: {instance.id})")
179179

180-
self.wait_instance(instance, Instance(id=instance.id, state="on"))
180+
await self.wait_instance(instance, Instance(id=instance.id, state="on"))
181181

182182
@export
183183
async def off(self, destroy: bool = False) -> None:
@@ -190,16 +190,16 @@ async def off(self, destroy: bool = False) -> None:
190190
raise ValueError(f"Unable to fetch project: {self.parent.project_id}")
191191

192192
# get instance and fail if instance does not exist
193-
instance = self.parent.api.get_instance(self.parent.device_name)
193+
instance = await self.parent.api.get_instance(self.parent.device_name)
194194
if instance is None:
195195
raise ValueError("Instance does not exist")
196196

197-
self.parent.api.set_instance_state(instance, "off")
198-
self.wait_instance(instance, Instance(id=instance.id, state="off"))
197+
await self.parent.api.set_instance_state(instance, "off")
198+
await self.wait_instance(instance, Instance(id=instance.id, state="off"))
199199

200200
if destroy:
201201
await self.parent.api.destroy_instance(instance)
202-
self.wait_instance(instance, None)
202+
await self.wait_instance(instance, None)
203203

204204
@export
205205
def read(self) -> AsyncGenerator[PowerReading, None]:

packages/jumpstarter-driver-corellium/jumpstarter_driver_corellium/driver_test.py

Lines changed: 0 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import pytest
44

5-
from .corellium.exceptions import CorelliumApiException
65
from .corellium.types import Device, Instance, Project, Session
76
from .driver import Corellium, CorelliumPower
87
from jumpstarter.common import exceptions as jmp_exceptions
@@ -99,34 +98,6 @@ async def test_driver_power_on_ok(monkeypatch):
9998
await power.on()
10099

101100

102-
@pytest.mark.parametrize(
103-
"mock_data",
104-
[
105-
({"login": {"side_effect": CorelliumApiException("login error")}}),
106-
({"get_project": {"return_value": None}}),
107-
({"get_instance": {"return_value": None}}),
108-
({"create_instance": {"side_effect": CorelliumApiException("create error")}}),
109-
],
110-
)
111-
async def test_driver_power_on_error(monkeypatch, mock_data):
112-
monkeypatch.setenv("CORELLIUM_API_HOST", "api-host")
113-
monkeypatch.setenv("CORELLIUM_API_TOKEN", "api-token")
114-
115-
project = Project("1", "Default Project")
116-
instance = Instance(id="7f4f241c-821f-4219-905f-c3b50b0db5dd", state="on")
117-
root = Corellium(project_id="1", device_name="jmp", device_flavor="kronos", device_os="1.0")
118-
power = CorelliumPower(parent=root)
119-
120-
with pytest.raises((CorelliumApiException, ValueError)):
121-
with (
122-
patch.object(root._api, "login", **mock_data.get("login", {"return_value": None})),
123-
patch.object(root._api, "get_project", **mock_data.get("get_project", {"return_value": project})),
124-
patch.object(root._api, "get_instance", **mock_data.get("get_instance", {"return_value": instance})),
125-
patch.object(root._api, "create_instance", **mock_data.get("create_instance", {"return_value": instance})),
126-
):
127-
await power.off()
128-
129-
130101
async def test_driver_power_off_ok(monkeypatch):
131102
monkeypatch.setenv("CORELLIUM_API_HOST", "api-host")
132103
monkeypatch.setenv("CORELLIUM_API_TOKEN", "api-token")
@@ -143,33 +114,3 @@ async def test_driver_power_off_ok(monkeypatch):
143114
patch.object(root._api, "get_instance", side_effect=[instance, Instance(id=instance.id, state="off")]),
144115
):
145116
await power.off()
146-
147-
148-
@pytest.mark.parametrize(
149-
"mock_data",
150-
[
151-
({"login": {"side_effect": CorelliumApiException("login error")}}),
152-
({"get_project": {"return_value": None}}),
153-
({"get_instance": {"return_value": None}}),
154-
({"destroy_instance": {"side_effect": CorelliumApiException("destroy error")}}),
155-
],
156-
)
157-
async def test_driver_power_off_error(monkeypatch, mock_data):
158-
monkeypatch.setenv("CORELLIUM_API_HOST", "api-host")
159-
monkeypatch.setenv("CORELLIUM_API_TOKEN", "api-token")
160-
161-
project = Project("1", "Default Project")
162-
instance = Instance(id="7f4f241c-821f-4219-905f-c3b50b0db5dd", state="on")
163-
root = Corellium(project_id="1", device_name="jmp", device_flavor="kronos", device_os="1.0")
164-
power = CorelliumPower(parent=root)
165-
166-
with pytest.raises((CorelliumApiException, ValueError)):
167-
with (
168-
patch.object(root._api, "login", **mock_data.get("login", {"return_value": None})),
169-
patch.object(root._api, "get_project", **mock_data.get("get_project", {"return_value": project})),
170-
patch.object(root._api, "get_instance", **mock_data.get("get_instance", {"side_effect": [instance, None]})),
171-
patch.object(
172-
root._api, "destroy_instance", **mock_data.get("destroy_instance", {"return_value": instance})
173-
),
174-
):
175-
await power.off()

0 commit comments

Comments
 (0)