petri_artifacts_common/lib.rs
1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! `petri` test artifact declarations used by all petri-based tests, no matter
5//! what VMM backend is being used.
6
7#![forbid(unsafe_code)]
8
9/// Artifact declarations
10pub mod artifacts {
11 use petri_artifacts_core::declare_artifacts;
12
13 declare_artifacts! {
14 /// Pipette windows x86_64 executable
15 PIPETTE_WINDOWS_X64,
16 /// Pipette linux x86_64 executable
17 PIPETTE_LINUX_X64,
18 /// Pipette windows aarch64 executable
19 PIPETTE_WINDOWS_AARCH64,
20 /// Pipette linux aarch64 executable
21 PIPETTE_LINUX_AARCH64,
22 /// Directory to put petri test logs in
23 TEST_LOG_DIRECTORY,
24 }
25}
26
27/// Artifact tag trait declarations
28pub mod tags {
29 use petri_artifacts_core::ArtifactId;
30
31 /// A coarse-grained label used to differentiate between different OS
32 /// environments.
33 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
34 #[expect(missing_docs)] // Self-describing names.
35 pub enum OsFlavor {
36 Windows,
37 Linux,
38 FreeBsd,
39 Uefi,
40 }
41
42 /// The machine architecture supported by the artifact or VM.
43 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
44 #[expect(missing_docs)] // Self describing names
45 pub enum MachineArch {
46 X86_64,
47 Aarch64,
48 }
49
50 impl MachineArch {
51 /// Returns the host's architecture.
52 pub fn host() -> Self {
53 // xtask-fmt allow-target-arch oneoff-petri-host-arch
54 if cfg!(target_arch = "x86_64") {
55 Self::X86_64
56 }
57 // xtask-fmt allow-target-arch oneoff-petri-host-arch
58 else if cfg!(target_arch = "aarch64") {
59 Self::Aarch64
60 } else {
61 panic!("unsupported host architecture")
62 }
63 }
64 }
65
66 /// Quirks needed to boot a guest.
67 #[derive(Default, Clone, Debug)]
68 pub struct GuestQuirksInner {
69 /// How long to wait after the shutdown IC reports ready before sending
70 /// the shutdown command.
71 ///
72 /// This is necessary because some guests will ignore shutdown requests
73 /// that arrive too early in the boot process.
74 pub hyperv_shutdown_ic_sleep: Option<std::time::Duration>,
75 /// Some guests reboot automatically soon after first boot.
76 pub initial_reboot: Option<InitialRebootCondition>,
77 }
78
79 /// Some guests may automatically reboot only in certain configurations
80 #[derive(Clone, Copy, Debug)]
81 pub enum InitialRebootCondition {
82 /// This guest always reboots on this VMM.
83 Always,
84 /// This guest only reboots when the TPM is enabled.
85 WithTpm,
86 }
87
88 /// Quirks needed to boot a guest, allowing for differences based on backend
89 #[derive(Default, Clone, Debug)]
90 pub struct GuestQuirks {
91 /// Quirks when running in OpenVMM
92 pub openvmm: GuestQuirksInner,
93 /// Quirks when running in Hyper-V
94 pub hyperv: GuestQuirksInner,
95 }
96
97 impl GuestQuirks {
98 /// Use the same quirks for all backends
99 pub fn for_all_backends(quirks: GuestQuirksInner) -> GuestQuirks {
100 GuestQuirks {
101 openvmm: quirks.clone(),
102 hyperv: quirks,
103 }
104 }
105 }
106
107 /// Artifact is a OpenHCL IGVM file
108 pub trait IsOpenhclIgvm: IsLoadable + ArtifactId {}
109
110 /// Artifact is a bootable test VHD file
111 pub trait IsTestVhd: ArtifactId {
112 /// What [`OsFlavor`] this image boots into.
113 const OS_FLAVOR: OsFlavor;
114
115 /// What [`MachineArch`] this image supports.
116 const ARCH: MachineArch;
117
118 /// Declare any "quirks" needed to boot the image.
119 fn quirks() -> GuestQuirks {
120 GuestQuirks::default()
121 }
122 }
123
124 /// Artifact is a bootable test ISO file
125 pub trait IsTestIso: ArtifactId {
126 /// What [`OsFlavor`] this image boots into.
127 const OS_FLAVOR: OsFlavor;
128
129 /// What [`MachineArch`] this image supports.
130 const ARCH: MachineArch;
131
132 /// Declare any "quirks" needed to boot the image.
133 fn quirks() -> GuestQuirks {
134 GuestQuirks::default()
135 }
136 }
137
138 /// Artifact is a binary that can be loaded into a VM
139 pub trait IsLoadable: ArtifactId {
140 /// What [`MachineArch`] this artifact supports.
141 const ARCH: MachineArch;
142 }
143
144 /// Artifact is a test VMGS file
145 pub trait IsTestVmgs: ArtifactId {}
146
147 /// Artifact is a VmgsTool binary
148 pub trait IsVmgsTool: ArtifactId {}
149}