Skip to content

Commit 042ece7

Browse files
author
lif
committed
wip: start adding test that will eventually validate behavior of responding to TimedOut answers from nexus
1 parent 4f44109 commit 042ece7

File tree

2 files changed

+114
-15
lines changed

2 files changed

+114
-15
lines changed

openapi/nexus-internal.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@
514514
"/instances/{instance_id}/creation-success": {
515515
"put": {
516516
"summary": "Asynchronously report the successful result of certain instance_put calls",
517-
"description": "(such as the potentially long-running one made during instance creation)",
517+
"description": "(such as the potentially long-running one made during instance creation). If Nexus has already marked the instance as failed, this returns `TimedOut` so the sled-agent making the request knows to terminate the instance.",
518518
"operationId": "cpapi_handle_instance_put_success",
519519
"parameters": [
520520
{

sled-agent/src/instance.rs

Lines changed: 113 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1470,7 +1470,33 @@ mod tests {
14701470
) -> Instance {
14711471
let id = Uuid::new_v4();
14721472
let propolis_id = Uuid::new_v4();
1473+
14731474
let ticket = InstanceTicket::new_without_manager_for_test(id);
1475+
1476+
let initial_state =
1477+
fake_instance_initial_state(propolis_id, propolis_addr);
1478+
1479+
let services = fake_instance_manager_services(
1480+
logctx,
1481+
storage_handle,
1482+
nexus_client_with_resolver,
1483+
);
1484+
1485+
Instance::new(
1486+
logctx.log.new(o!("component" => "Instance")),
1487+
id,
1488+
propolis_id,
1489+
ticket,
1490+
initial_state,
1491+
services,
1492+
)
1493+
.unwrap()
1494+
}
1495+
1496+
fn fake_instance_initial_state(
1497+
propolis_id: Uuid,
1498+
propolis_addr: SocketAddr,
1499+
) -> InstanceInitialState {
14741500
let hardware = InstanceHardware {
14751501
properties: InstanceProperties {
14761502
ncpus: InstanceCpuCount(1),
@@ -1495,7 +1521,7 @@ mod tests {
14951521
cloud_init_bytes: None,
14961522
};
14971523

1498-
let initial_state = InstanceInitialState {
1524+
InstanceInitialState {
14991525
hardware,
15001526
instance_runtime: InstanceRuntimeState {
15011527
propolis_id: Some(propolis_id),
@@ -1510,8 +1536,14 @@ mod tests {
15101536
time_updated: Default::default(),
15111537
},
15121538
propolis_addr,
1513-
};
1539+
}
1540+
}
15141541

1542+
fn fake_instance_manager_services(
1543+
logctx: &LogContext,
1544+
storage_handle: StorageHandle,
1545+
nexus_client_with_resolver: NexusClientWithResolver,
1546+
) -> InstanceManagerServices {
15151547
let vnic_allocator =
15161548
VnicAllocator::new("Foo", Etherstub("mystub".to_string()));
15171549
let port_manager = PortManager::new(
@@ -1526,24 +1558,14 @@ mod tests {
15261558
cleanup_context,
15271559
);
15281560

1529-
let services = InstanceManagerServices {
1561+
InstanceManagerServices {
15301562
nexus_client: nexus_client_with_resolver,
15311563
vnic_allocator,
15321564
port_manager,
15331565
storage: storage_handle,
15341566
zone_bundler,
15351567
zone_builder_factory: ZoneBuilderFactory::fake(),
1536-
};
1537-
1538-
Instance::new(
1539-
logctx.log.new(o!("component" => "Instance")),
1540-
id,
1541-
propolis_id,
1542-
ticket,
1543-
initial_state,
1544-
services,
1545-
)
1546-
.unwrap()
1568+
}
15471569
}
15481570

15491571
#[tokio::test]
@@ -1724,4 +1746,81 @@ mod tests {
17241746

17251747
logctx.cleanup_successful();
17261748
}
1749+
1750+
#[tokio::test]
1751+
async fn test_instance_manager_creation_nexus_timeout() {
1752+
let logctx = omicron_test_utils::dev::test_setup_log(
1753+
"test_instance_manager_creation_nexus_timeout",
1754+
);
1755+
1756+
let storage_handle = fake_storage_manager_with_u2().await;
1757+
1758+
let (nexus_client, nexus_server, state_rx) = fake_nexus_server(&logctx);
1759+
1760+
let (_dns_server, resolver, _dns_config_dir) =
1761+
timeout(TIMEOUT_DURATION, dns_server(&logctx, &nexus_server))
1762+
.await
1763+
.expect("timed out making DNS server and Resolver");
1764+
1765+
let nexus_client_with_resolver =
1766+
NexusClientWithResolver::new_with_client(nexus_client, resolver);
1767+
1768+
let InstanceManagerServices {
1769+
nexus_client,
1770+
vnic_allocator: _,
1771+
port_manager,
1772+
storage,
1773+
zone_bundler,
1774+
zone_builder_factory,
1775+
} = fake_instance_manager_services(
1776+
&logctx,
1777+
storage_handle,
1778+
nexus_client_with_resolver,
1779+
);
1780+
1781+
let etherstub = Etherstub("mystub".to_string());
1782+
1783+
let mgr = crate::instance_manager::InstanceManager::new(
1784+
logctx.log.new(o!("component" => "InstanceManager")),
1785+
nexus_client,
1786+
etherstub,
1787+
port_manager,
1788+
storage,
1789+
zone_bundler,
1790+
zone_builder_factory,
1791+
)
1792+
.unwrap();
1793+
1794+
let (propolis_server, _propolis_client) =
1795+
propolis_mock_server(&logctx.log);
1796+
let propolis_addr = propolis_server.local_addr();
1797+
1798+
// automock'd things used during this test
1799+
let _mock_vnic_contexts = mock_vnic_contexts();
1800+
let _mock_zone_contexts = mock_zone_contexts();
1801+
1802+
let instance_id = Uuid::new_v4();
1803+
let propolis_id = Uuid::new_v4();
1804+
let InstanceInitialState {
1805+
hardware,
1806+
instance_runtime,
1807+
vmm_runtime,
1808+
propolis_addr,
1809+
} = fake_instance_initial_state(propolis_id, propolis_addr);
1810+
1811+
mgr.ensure_registered(
1812+
instance_id,
1813+
propolis_id,
1814+
hardware,
1815+
instance_runtime,
1816+
vmm_runtime,
1817+
propolis_addr,
1818+
)
1819+
.await
1820+
.unwrap();
1821+
1822+
todo!();
1823+
1824+
logctx.cleanup_successful();
1825+
}
17271826
}

0 commit comments

Comments
 (0)