feat: add Fleet operations view
This commit is contained in:
1 parent
c6d01df31c
commit
786a1ab910
12 files changed
+1062
-148
No files matched your search
@@ -45,6 +45,21 @@ def inventory_row(**overrides):
|
||||
"created_at": now,
|
||||
"updated_at": now,
|
||||
"tags": [],
|
||||
"site_name": None,
|
||||
"room_name": None,
|
||||
"location_position_id": None,
|
||||
"rack_label": None,
|
||||
"shelf_label": None,
|
||||
"position_label": None,
|
||||
"position_index": None,
|
||||
"observed_at": None,
|
||||
"hashrate_ths": None,
|
||||
"power_w": None,
|
||||
"chip_temp_max_c": None,
|
||||
"hash_stable": None,
|
||||
"active_repair_id": None,
|
||||
"active_repair_status": None,
|
||||
"active_repair_reason": None,
|
||||
}
|
||||
row.update(overrides)
|
||||
return row
|
||||
@@ -56,6 +71,7 @@ class FakeInventoryRepository:
|
||||
self.created_values = None
|
||||
self.asset_id_history = []
|
||||
self.update_error = None
|
||||
self.search_kwargs = None
|
||||
|
||||
@contextmanager
|
||||
def transaction(self):
|
||||
@@ -89,6 +105,7 @@ class FakeInventoryRepository:
|
||||
return list(self.rows.values())[offset : offset + limit]
|
||||
|
||||
def search_miners(self, **kwargs):
|
||||
self.search_kwargs = kwargs
|
||||
rows = list(self.rows.values())
|
||||
lifecycle = kwargs.get("lifecycle_status")
|
||||
if lifecycle:
|
||||
@@ -416,6 +433,54 @@ class InventoryServiceTests(unittest.TestCase):
|
||||
)
|
||||
self.assertEqual(self.repository.asset_id_history, [])
|
||||
|
||||
def test_fleet_projection_mapping_and_filter_forwarding(self):
|
||||
miner_id = uuid4()
|
||||
repair_id = uuid4()
|
||||
site_id = uuid4()
|
||||
row = inventory_row(
|
||||
id=miner_id,
|
||||
miner_sn="MINER-SN",
|
||||
site_id=site_id,
|
||||
site_name="North Site",
|
||||
observed_at=datetime.now(timezone.utc),
|
||||
hashrate_ths=0.0,
|
||||
power_w=0.0,
|
||||
chip_temp_max_c=0.0,
|
||||
hash_stable=False,
|
||||
active_repair_id=repair_id,
|
||||
active_repair_status="IN_PROGRESS",
|
||||
active_repair_reason="Hashboard diagnostics",
|
||||
)
|
||||
self.repository.rows[miner_id] = row
|
||||
filters = InventorySearchFilters(
|
||||
model=" M50 ", runtime_status="offline", repair="active",
|
||||
operational_state="repair", problems=True, site_id=site_id,
|
||||
limit=25, offset=0,
|
||||
)
|
||||
|
||||
result = self.service.search_miners(
|
||||
filters, include_location_details=True
|
||||
)[0]
|
||||
|
||||
self.assertEqual(result.miner_sn, "MINER-SN")
|
||||
self.assertEqual(result.hashrate_ths, 0.0)
|
||||
self.assertEqual(result.power_w, 0.0)
|
||||
self.assertEqual(result.chip_temp_max_c, 0.0)
|
||||
self.assertFalse(result.hash_stable)
|
||||
self.assertEqual(result.active_repair.id, repair_id)
|
||||
self.assertEqual(self.repository.search_kwargs["model"], "M50")
|
||||
self.assertEqual(self.repository.search_kwargs["site_id"], site_id)
|
||||
self.assertTrue(self.repository.search_kwargs["include_location_details"])
|
||||
|
||||
def test_location_filter_without_projection_is_rejected(self):
|
||||
with self.assertRaisesRegex(
|
||||
InventoryValidationError, "Location filters require"
|
||||
):
|
||||
self.service.search_miners(
|
||||
InventorySearchFilters(site_id=uuid4())
|
||||
)
|
||||
self.assertIsNone(self.repository.search_kwargs)
|
||||
|
||||
def test_search_validation_precedes_repository(self):
|
||||
with self.assertRaises(InventoryValidationError):
|
||||
self.service.search_miners(
|
||||
@@ -485,6 +550,22 @@ class InventoryRepositoryIntegrationTests(unittest.TestCase):
|
||||
miner_id,
|
||||
)
|
||||
|
||||
fleet = self.repository.search_miners(
|
||||
model="M50",
|
||||
runtime_status="unknown",
|
||||
operational_state="unknown",
|
||||
problems=True,
|
||||
include_location_details=True,
|
||||
)
|
||||
self.assertEqual(fleet[0]["id"], miner_id)
|
||||
self.assertEqual(fleet[0]["miner_sn"], "MINER-001")
|
||||
self.assertIsNone(fleet[0]["observed_at"])
|
||||
self.assertIsNone(fleet[0]["location_position_id"])
|
||||
self.assertEqual(
|
||||
self.repository.list_location_filter_options(),
|
||||
{"sites": [], "rooms": []},
|
||||
)
|
||||
|
||||
updated = self.repository.update_miner(
|
||||
miner_id,
|
||||
{"lifecycle_status": "spare", "notes": "Bench stock"},
|
||||
|
||||
Reference in new issue
Block a user