Skip to content

Commit dcaa633

Browse files
committed
Add unit tests for enroll-netdev entrypoint
1 parent bd863ee commit dcaa633

1 file changed

Lines changed: 188 additions & 0 deletions

File tree

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
import logging
2+
from types import SimpleNamespace
3+
from unittest.mock import MagicMock
4+
from unittest.mock import call
5+
6+
from understack_workflows import ironic_node
7+
from understack_workflows.ironic.client import IronicClient
8+
from understack_workflows.main import enroll_netdev
9+
10+
11+
def make_ironic_client():
12+
fake_client = MagicMock()
13+
node = SimpleNamespace(uuid="node-123")
14+
fake_client.node.create.return_value = node
15+
fake_client.port.create.side_effect = [
16+
SimpleNamespace(uuid="port-1"),
17+
SimpleNamespace(uuid="port-2"),
18+
]
19+
return fake_client, node
20+
21+
22+
def test_enroll_creates_node_ports_logs_and_makes_available(mocker, caplog):
23+
caplog.set_level(logging.INFO)
24+
fake_ironic, node = make_ironic_client()
25+
mocker.patch(
26+
"understack_workflows.ironic.client.get_ironic_client",
27+
return_value=fake_ironic,
28+
)
29+
30+
enroll_netdev.enroll(
31+
name="leaf01",
32+
physical_network="f20-1-network",
33+
port1_mac="00:11:22:33:44:55",
34+
port1_switch="spine01.example.net",
35+
port1_intf="Ethernet1/1",
36+
port2_mac="00:11:22:33:44:66",
37+
port2_switch="spine02.example.net",
38+
port2_intf="Ethernet1/2",
39+
resource_class=None,
40+
)
41+
42+
fake_ironic.node.create.assert_called_once_with(
43+
automated_clean=False,
44+
driver="netdev",
45+
name="leaf01",
46+
resource_class="generic",
47+
)
48+
fake_ironic.port.create.assert_has_calls(
49+
[
50+
call(
51+
address="00:11:22:33:44:55",
52+
category="network",
53+
local_link_connection={
54+
"switch_id": "00:00:00:00:00:00",
55+
"switch_info": "spine01.example.net",
56+
"port_id": "Ethernet1/1",
57+
},
58+
name="leaf01:port1",
59+
node_uuid=node.uuid,
60+
physical_network="f20-1-network",
61+
),
62+
call(
63+
address="00:11:22:33:44:66",
64+
category="network",
65+
local_link_connection={
66+
"switch_id": "00:00:00:00:00:00",
67+
"switch_info": "spine02.example.net",
68+
"port_id": "Ethernet1/2",
69+
},
70+
name="leaf01:port2",
71+
node_uuid=node.uuid,
72+
physical_network="f20-1-network",
73+
),
74+
]
75+
)
76+
fake_ironic.node.set_provision_state.assert_has_calls(
77+
[
78+
call(
79+
node.uuid,
80+
"manage",
81+
cleansteps=None,
82+
runbook=None,
83+
disable_ramdisk=None,
84+
),
85+
call(
86+
node.uuid,
87+
"provide",
88+
cleansteps=None,
89+
runbook=None,
90+
disable_ramdisk=None,
91+
),
92+
]
93+
)
94+
fake_ironic.node.wait_for_provision_state.assert_has_calls(
95+
[
96+
call(
97+
node.uuid,
98+
"manageable",
99+
timeout=ironic_node.NODE_STATE_TIMEOUT_SECS,
100+
),
101+
call(
102+
node.uuid,
103+
"available",
104+
timeout=ironic_node.NODE_STATE_TIMEOUT_SECS,
105+
),
106+
]
107+
)
108+
assert "Starting enroll-netdev workflow name=leaf01" in caplog.text
109+
assert "Created netdev Ironic node name=leaf01 uuid=node-123" in caplog.text
110+
assert "[node:node-123] Created baremetal port name=leaf01:port1" in caplog.text
111+
assert "[node:node-123] Node is available" in caplog.text
112+
113+
114+
def test_enroll_records_external_cmdb_id_and_custom_resource_class(mocker):
115+
fake_ironic, _ = make_ironic_client()
116+
mocker.patch(
117+
"understack_workflows.ironic.client.get_ironic_client",
118+
return_value=fake_ironic,
119+
)
120+
121+
enroll_netdev.enroll(
122+
name="leaf01",
123+
physical_network="f20-1-network",
124+
port1_mac="00:11:22:33:44:55",
125+
port1_switch="spine01.example.net",
126+
port1_intf="Ethernet1/1",
127+
port2_mac="00:11:22:33:44:66",
128+
port2_switch="spine02.example.net",
129+
port2_intf="Ethernet1/2",
130+
external_cmdb_id="cmdb-1",
131+
resource_class="switch",
132+
)
133+
134+
fake_ironic.node.create.assert_called_once_with(
135+
automated_clean=False,
136+
driver="netdev",
137+
name="leaf01",
138+
resource_class="switch",
139+
extra={"external_cmdb_id": "cmdb-1"},
140+
)
141+
142+
143+
def test_argument_parser_defaults_resource_class_to_generic():
144+
args = enroll_netdev.argument_parser().parse_args(
145+
[
146+
"--name",
147+
"leaf01",
148+
"--physical-network",
149+
"f20-1-network",
150+
"--port1-mac",
151+
"00:11:22:33:44:55",
152+
"--port1-switch",
153+
"spine01.example.net",
154+
"--port1-intf",
155+
"Ethernet1/1",
156+
"--port2-mac",
157+
"00:11:22:33:44:66",
158+
"--port2-switch",
159+
"spine02.example.net",
160+
"--port2-intf",
161+
"Ethernet1/2",
162+
]
163+
)
164+
165+
assert args.resource_class == "generic"
166+
assert args.external_cmdb_id == ""
167+
168+
169+
def test_create_port_allows_category_when_client_whitelist_is_old(mocker):
170+
fake_ironic = MagicMock()
171+
fake_ironic.port._creation_attributes = ["address"]
172+
mocker.patch(
173+
"understack_workflows.ironic.client.get_ironic_client",
174+
return_value=fake_ironic,
175+
)
176+
177+
IronicClient().create_port(
178+
{
179+
"address": "00:11:22:33:44:55",
180+
"category": "network",
181+
}
182+
)
183+
184+
assert "category" in fake_ironic.port._creation_attributes
185+
fake_ironic.port.create.assert_called_once_with(
186+
address="00:11:22:33:44:55",
187+
category="network",
188+
)

0 commit comments

Comments
 (0)