@@ -153,6 +153,9 @@ impl VendorClass {
153153
154154#[ cfg( test) ]
155155mod tests {
156+ use carbide_test_support:: Outcome :: * ;
157+ use carbide_test_support:: { Case , check_cases, value_scenarios} ;
158+
156159 use super :: * ;
157160
158161 impl VendorClass {
@@ -169,86 +172,183 @@ mod tests {
169172 }
170173 }
171174
172- #[ test]
173- fn it_is_pxe_capable ( ) {
174- let vc: VendorClass = "PXEClient:Arch:00007:UNDI:003000" . parse ( ) . unwrap ( ) ;
175- assert ! ( !vc. is_netboot( ) ) ;
176-
177- let vc: VendorClass = "iDRAC" . parse ( ) . unwrap ( ) ;
178- assert ! ( !vc. is_netboot( ) ) ;
179-
180- let vc: VendorClass = "PXEClient" . parse ( ) . unwrap ( ) ;
181- assert ! ( !vc. is_netboot( ) ) ;
182- }
183-
184- #[ test]
185- fn is_it_arm_non_uefi ( ) {
186- let vc: VendorClass = "nvidia-bluefield-dpu aarch64" . parse ( ) . unwrap ( ) ;
187- assert ! ( vc. arm( ) ) ;
188-
189- let vc: VendorClass = "BF2Client" . parse ( ) . unwrap ( ) ;
190- assert ! ( vc. arm( ) ) ;
175+ /// The full boot-relevant classification a parsed vendor class resolves to:
176+ /// architecture (`arm`/`x64`), whether it asks for HTTP `netboot`, and whether
177+ /// it is a `modern` (netboot ARM-UEFI) client.
178+ #[ derive( Debug , PartialEq ) ]
179+ struct Classification {
180+ arm : bool ,
181+ x64 : bool ,
182+ netboot : bool ,
183+ modern : bool ,
191184 }
192185
193- #[ test]
194- fn is_it_arm ( ) {
195- let vc: VendorClass = "PXEClient:Arch:00011:UNDI:003000" . parse ( ) . unwrap ( ) ;
196- assert ! ( vc. arm( ) ) ;
197- }
198-
199- #[ test]
200- fn is_it_not_modern ( ) {
201- let vc: VendorClass = "PXEClient:Arch:00007:UNDI:003000" . parse ( ) . unwrap ( ) ;
202- assert ! ( !vc. is_it_modern( ) ) ;
186+ impl Classification {
187+ fn of ( vc : & VendorClass ) -> Self {
188+ Self {
189+ arm : vc. arm ( ) ,
190+ x64 : vc. x64 ( ) ,
191+ netboot : vc. is_netboot ( ) ,
192+ modern : vc. is_it_modern ( ) ,
193+ }
194+ }
203195 }
204196
197+ /// Every vendor-class string we recognize, pinned to its full classification.
198+ /// One row per input -- a `PXEClient` x64 UEFI, an OS-form `aarch64` DPU, an
199+ /// `HTTPClient` netboot, a bare BMC id -- so a parse covers all four predicates
200+ /// at once instead of one assertion apiece.
205201 #[ test]
206- fn is_it_modern ( ) {
207- let vc: VendorClass = "HTTPClient:Arch:00011:UNDI:003000" . parse ( ) . unwrap ( ) ;
208- assert ! ( vc. is_it_modern( ) ) ;
202+ fn classifies_each_vendor_class ( ) {
203+ check_cases (
204+ [
205+ Case {
206+ scenario : "x64 UEFI PXEClient" ,
207+ input : "PXEClient:Arch:00007:UNDI:003000" ,
208+ expect : Yields ( Classification {
209+ arm : false ,
210+ x64 : true ,
211+ netboot : false ,
212+ modern : false ,
213+ } ) ,
214+ } ,
215+ Case {
216+ scenario : "Dell iDRAC BMC (x64)" ,
217+ input : "iDRAC" ,
218+ expect : Yields ( Classification {
219+ arm : false ,
220+ x64 : true ,
221+ netboot : false ,
222+ modern : false ,
223+ } ) ,
224+ } ,
225+ Case {
226+ scenario : "bare PXEClient iPXE response (arm)" ,
227+ input : "PXEClient" ,
228+ expect : Yields ( Classification {
229+ arm : true ,
230+ x64 : false ,
231+ netboot : false ,
232+ modern : false ,
233+ } ) ,
234+ } ,
235+ Case {
236+ scenario : "OS-form aarch64 DPU" ,
237+ input : "nvidia-bluefield-dpu aarch64" ,
238+ expect : Yields ( Classification {
239+ arm : true ,
240+ x64 : false ,
241+ netboot : false ,
242+ modern : false ,
243+ } ) ,
244+ } ,
245+ Case {
246+ scenario : "legacy BF2 card" ,
247+ input : "BF2Client" ,
248+ expect : Yields ( Classification {
249+ arm : true ,
250+ x64 : false ,
251+ netboot : false ,
252+ modern : false ,
253+ } ) ,
254+ } ,
255+ Case {
256+ scenario : "ARM UEFI PXEClient (not netboot)" ,
257+ input : "PXEClient:Arch:00011:UNDI:003000" ,
258+ expect : Yields ( Classification {
259+ arm : true ,
260+ x64 : false ,
261+ netboot : false ,
262+ modern : false ,
263+ } ) ,
264+ } ,
265+ Case {
266+ scenario : "ARM UEFI HTTPClient is modern netboot" ,
267+ input : "HTTPClient:Arch:00011:UNDI:003000" ,
268+ expect : Yields ( Classification {
269+ arm : true ,
270+ x64 : false ,
271+ netboot : true ,
272+ modern : true ,
273+ } ) ,
274+ } ,
275+ Case {
276+ scenario : "x64 HTTPClient netboots but is not modern" ,
277+ input : "HTTPClient:Arch:00016:UNDI:003001" ,
278+ expect : Yields ( Classification {
279+ arm : false ,
280+ x64 : true ,
281+ netboot : true ,
282+ modern : false ,
283+ } ) ,
284+ } ,
285+ ] ,
286+ |input| {
287+ input
288+ . parse :: < VendorClass > ( )
289+ . map ( |vc| Classification :: of ( & vc) )
290+ . map_err ( |_| "parse failed" )
291+ } ,
292+ ) ;
209293 }
210294
295+ /// The human-readable `VendorClass` `Display`: `"<arch> (<netboot|basic>)"`.
211296 #[ test]
212- fn it_is_netboot_capable ( ) {
213- let vc: VendorClass = "HTTPClient:Arch:00016:UNDI:003001" . parse ( ) . unwrap ( ) ;
214- assert ! ( vc. is_netboot( ) ) ;
215- }
297+ fn formats_vendor_class_display ( ) {
298+ value_scenarios ! ( run = |input: & str | input. parse:: <VendorClass >( ) . unwrap( ) . to_string( ) ;
299+ "basic (non-netboot) clients" {
300+ "NothingClient:Arch:00011:UNDI:X" => "ARM 64-bit UEFI (basic)" . to_string( ) ,
301+ "NVIDIA/BF/OOB" => "ARM 64-bit UEFI (basic)" . to_string( ) ,
302+ "NVIDIA/BF/BMC" => "ARM 64-bit UEFI (basic)" . to_string( ) ,
303+ "PXEClient:Arch:00000:UNDI:003000" => "x86 BIOS (basic)" . to_string( ) ,
304+ }
216305
217- #[ test]
218- fn it_is_netboot_and_not_arm ( ) {
219- let vc: VendorClass = "HTTPClient:Arch:00016:UNDI:003001" . parse ( ) . unwrap ( ) ;
220- assert ! ( vc. is_netboot( ) ) ;
221- assert ! ( vc. x64( ) ) ;
306+ "netboot clients" {
307+ "HTTPClient:Arch:00011:UNDI:003000" => "ARM 64-bit UEFI (netboot)" . to_string( ) ,
308+ }
309+ ) ;
222310 }
223311
312+ /// `MachineArchitecture::from_str` maps DHCP option-93 architecture codes (base
313+ /// 10, as the long vendor class spells them) to an architecture. It never errors
314+ /// -- an unrecognized or non-numeric code resolves to `Unknown` so we still vend
315+ /// an address. Exercised directly here rather than only through `VendorClass`.
224316 #[ test]
225- fn it_handles_basic_for_all_clients ( ) {
226- let vc : Result < VendorClass , VendorClassParseError > =
227- "NothingClient:Arch:00011:UNDI:X" . parse ( ) ;
228- assert_eq ! ( vc . unwrap ( ) . to_string ( ) , "ARM 64-bit UEFI (basic)" ) ;
229- }
317+ fn maps_architecture_codes ( ) {
318+ value_scenarios ! ( run = |input : & str | MachineArchitecture :: from_str ( input ) . unwrap ( ) ;
319+ "x86 BIOS" {
320+ "00000" => MachineArchitecture :: BiosX86 ,
321+ }
230322
231- #[ test]
232- fn it_formats_the_parser_armuefi_netboot ( ) {
233- let vc: VendorClass = "HTTPClient:Arch:00011:UNDI:003000" . parse ( ) . unwrap ( ) ;
234- assert_eq ! ( vc. to_string( ) , "ARM 64-bit UEFI (netboot)" ) ;
235- }
323+ "x64 UEFI" {
324+ "00007" => MachineArchitecture :: EfiX64 ,
325+ "00016" => MachineArchitecture :: EfiX64 ,
326+ }
236327
237- # [ test ]
238- fn it_detects_nvidia_bf_oob_as_arm ( ) {
239- let vc : VendorClass = "NVIDIA/BF/OOB" . parse ( ) . unwrap ( ) ;
240- assert_eq ! ( vc . to_string ( ) , "ARM 64-bit UEFI (basic)" ) ;
241- }
328+ "ARM 64-bit" {
329+ "00011" => MachineArchitecture :: Arm64 ,
330+ "00019" => MachineArchitecture :: Arm64 ,
331+ "aarch64" => MachineArchitecture :: Arm64 ,
332+ }
242333
243- #[ test]
244- fn it_detects_nvidia_bf_bmc_as_arm ( ) {
245- let vc: VendorClass = "NVIDIA/BF/BMC" . parse ( ) . unwrap ( ) ;
246- assert_eq ! ( vc. to_string( ) , "ARM 64-bit UEFI (basic)" ) ;
334+ "unknown" {
335+ "00042" => MachineArchitecture :: Unknown ,
336+ "not-a-number" => MachineArchitecture :: Unknown ,
337+ }
338+ ) ;
247339 }
248340
341+ /// The `MachineArchitecture` `Display` strings, which the `VendorClass` `Display`
342+ /// is built from.
249343 #[ test]
250- fn it_formats_the_parser_legacypxe ( ) {
251- let vc: VendorClass = "PXEClient:Arch:00000:UNDI:003000" . parse ( ) . unwrap ( ) ;
252- assert_eq ! ( vc. to_string( ) , "x86 BIOS (basic)" ) ;
344+ fn formats_architecture_display ( ) {
345+ value_scenarios ! ( run = |arch: MachineArchitecture | arch. to_string( ) ;
346+ "architecture labels" {
347+ MachineArchitecture :: Arm64 => "ARM 64-bit UEFI" . to_string( ) ,
348+ MachineArchitecture :: EfiX64 => "x64 UEFI" . to_string( ) ,
349+ MachineArchitecture :: BiosX86 => "x86 BIOS" . to_string( ) ,
350+ MachineArchitecture :: Unknown => "Unknown" . to_string( ) ,
351+ }
352+ ) ;
253353 }
254354}
0 commit comments