Make core serialized enum shapes exhaustive
This commit is contained in:
parent
5376aa90f9
commit
77ba5319ce
2 changed files with 319 additions and 0 deletions
|
|
@ -699,6 +699,8 @@ mod credentials;
|
|||
mod documents;
|
||||
#[path = "schema_records/encoding.rs"]
|
||||
mod encoding;
|
||||
#[path = "schema_records/enum_shapes.rs"]
|
||||
mod enum_shapes;
|
||||
#[path = "schema_records/participant_transitions.rs"]
|
||||
mod participant_transitions;
|
||||
#[path = "schema_records/process_evidence.rs"]
|
||||
|
|
|
|||
317
crates/lazaret-core/tests/schema_records/enum_shapes.rs
Normal file
317
crates/lazaret-core/tests/schema_records/enum_shapes.rs
Normal file
|
|
@ -0,0 +1,317 @@
|
|||
use super::*;
|
||||
|
||||
macro_rules! enum_corpus {
|
||||
($digest:expr, $type:ty, { $($pattern:pat => $value:expr),+ $(,)? }) => {{
|
||||
let values: Vec<$type> = vec![$($value),+];
|
||||
let mut tags = HashSet::new();
|
||||
for value in values {
|
||||
let tag = match &value {
|
||||
$($pattern => stringify!($pattern)),+
|
||||
};
|
||||
assert!(tags.insert(tag));
|
||||
let encoded = postcard::to_stdvec(&value).unwrap();
|
||||
$digest.update(stringify!($type).len().to_be_bytes());
|
||||
$digest.update(stringify!($type).as_bytes());
|
||||
$digest.update(tag.len().to_be_bytes());
|
||||
$digest.update(tag.as_bytes());
|
||||
$digest.update(encoded.len().to_be_bytes());
|
||||
$digest.update(encoded);
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
fn lifecycle_corpus(digest: &mut Sha256) {
|
||||
enum_corpus!(digest, DurableDecision, {
|
||||
DurableDecision::None => DurableDecision::None,
|
||||
DurableDecision::Preparing => DurableDecision::Preparing,
|
||||
DurableDecision::Published => DurableDecision::Published,
|
||||
DurableDecision::Clean => DurableDecision::Clean,
|
||||
});
|
||||
enum_corpus!(digest, ParticipantRole, {
|
||||
ParticipantRole::PreparedLower => ParticipantRole::PreparedLower,
|
||||
ParticipantRole::StateAnchor => ParticipantRole::StateAnchor,
|
||||
ParticipantRole::GitRouting => ParticipantRole::GitRouting,
|
||||
ParticipantRole::Network => ParticipantRole::Network,
|
||||
ParticipantRole::Helper => ParticipantRole::Helper,
|
||||
ParticipantRole::Sandbox => ParticipantRole::Sandbox,
|
||||
ParticipantRole::Publication => ParticipantRole::Publication,
|
||||
});
|
||||
enum_corpus!(digest, ParticipantState, {
|
||||
ParticipantState::Intent => ParticipantState::Intent,
|
||||
ParticipantState::LeaseHeld => ParticipantState::LeaseHeld,
|
||||
ParticipantState::Prepared => ParticipantState::Prepared,
|
||||
ParticipantState::Committed => ParticipantState::Committed,
|
||||
ParticipantState::ReleaseIntent => ParticipantState::ReleaseIntent,
|
||||
ParticipantState::Clean => ParticipantState::Clean,
|
||||
});
|
||||
enum_corpus!(digest, PersistedHostProcessOwnership, {
|
||||
PersistedHostProcessOwnership::Unassigned => PersistedHostProcessOwnership::unassigned(),
|
||||
PersistedHostProcessOwnership::Staged(_) => PersistedHostProcessOwnership::staged(process(1)),
|
||||
PersistedHostProcessOwnership::Committed(_) => PersistedHostProcessOwnership::committed(process(2)),
|
||||
});
|
||||
enum_corpus!(digest, ProcessOwnershipMessageVersion, {
|
||||
ProcessOwnershipMessageVersion::V1 => ProcessOwnershipMessageVersion::V1,
|
||||
});
|
||||
enum_corpus!(digest, SessionPhase, {
|
||||
SessionPhase::New => SessionPhase::New,
|
||||
SessionPhase::Waiting => SessionPhase::Waiting,
|
||||
SessionPhase::Registering => SessionPhase::Registering,
|
||||
SessionPhase::Attached => SessionPhase::Attached,
|
||||
SessionPhase::Prompting => SessionPhase::Prompting,
|
||||
SessionPhase::HostExecuting => SessionPhase::HostExecuting,
|
||||
SessionPhase::Closed => SessionPhase::Closed,
|
||||
SessionPhase::Failed => SessionPhase::Failed,
|
||||
});
|
||||
enum_corpus!(digest, SessionTerminalState, {
|
||||
SessionTerminalState::Intent => SessionTerminalState::Intent,
|
||||
SessionTerminalState::Running => SessionTerminalState::Running,
|
||||
SessionTerminalState::ReleaseIntent => SessionTerminalState::ReleaseIntent,
|
||||
SessionTerminalState::Clean => SessionTerminalState::Clean,
|
||||
});
|
||||
}
|
||||
|
||||
fn ownership_slot_corpus(digest: &mut Sha256) {
|
||||
enum_corpus!(digest, HostProcessOwnershipSlot, {
|
||||
HostProcessOwnershipSlot::SandboxHostCoordinator => HostProcessOwnershipSlot::SandboxHostCoordinator,
|
||||
HostProcessOwnershipSlot::SandboxRuntimeSupervisor => HostProcessOwnershipSlot::SandboxRuntimeSupervisor,
|
||||
HostProcessOwnershipSlot::SandboxAttachedRunsc => HostProcessOwnershipSlot::SandboxAttachedRunsc,
|
||||
HostProcessOwnershipSlot::StateAnchorDaemon => HostProcessOwnershipSlot::StateAnchorDaemon,
|
||||
HostProcessOwnershipSlot::GitRoutingDaemon => HostProcessOwnershipSlot::GitRoutingDaemon,
|
||||
HostProcessOwnershipSlot::NetworkRuntimeSupervisor => HostProcessOwnershipSlot::NetworkRuntimeSupervisor,
|
||||
HostProcessOwnershipSlot::HelperConnectivityHelper => HostProcessOwnershipSlot::HelperConnectivityHelper,
|
||||
HostProcessOwnershipSlot::HelperRuntimeSupervisor => HostProcessOwnershipSlot::HelperRuntimeSupervisor,
|
||||
HostProcessOwnershipSlot::SessionTerminalHostCoordinator(_) => HostProcessOwnershipSlot::SessionTerminalHostCoordinator(session_id()),
|
||||
HostProcessOwnershipSlot::SessionTerminalExecClient(_) => HostProcessOwnershipSlot::SessionTerminalExecClient(session_id()),
|
||||
HostProcessOwnershipSlot::EscalationHostProcess(_) => HostProcessOwnershipSlot::EscalationHostProcess(RequestId::new(opaque(3))),
|
||||
});
|
||||
enum_corpus!(digest, ParticipantOwnership, {
|
||||
ParticipantOwnership::PreparedLower(_) => ParticipantOwnership::empty(ParticipantRole::PreparedLower),
|
||||
ParticipantOwnership::StateAnchor(_) => ParticipantOwnership::empty(ParticipantRole::StateAnchor),
|
||||
ParticipantOwnership::GitRouting(_) => ParticipantOwnership::empty(ParticipantRole::GitRouting),
|
||||
ParticipantOwnership::Network(_) => ParticipantOwnership::empty(ParticipantRole::Network),
|
||||
ParticipantOwnership::Helper(_) => ParticipantOwnership::empty(ParticipantRole::Helper),
|
||||
ParticipantOwnership::Sandbox(_) => ParticipantOwnership::empty(ParticipantRole::Sandbox),
|
||||
ParticipantOwnership::Publication(_) => ParticipantOwnership::empty(ParticipantRole::Publication),
|
||||
});
|
||||
}
|
||||
|
||||
fn terminal_value(seed: u8) -> TerminalOutput {
|
||||
TerminalOutput {
|
||||
session_id: session_id(),
|
||||
bytes: vec![seed],
|
||||
}
|
||||
}
|
||||
|
||||
fn terminal_corpus(digest: &mut Sha256) {
|
||||
let resize = TerminalResize {
|
||||
session_id: session_id(),
|
||||
rows: NonZeroU16::new(24).unwrap(),
|
||||
columns: NonZeroU16::new(80).unwrap(),
|
||||
pixel_width: 640,
|
||||
pixel_height: 480,
|
||||
};
|
||||
enum_corpus!(digest, TerminalSignalKind, {
|
||||
TerminalSignalKind::Interrupt => TerminalSignalKind::Interrupt,
|
||||
TerminalSignalKind::Quit => TerminalSignalKind::Quit,
|
||||
TerminalSignalKind::Suspend => TerminalSignalKind::Suspend,
|
||||
});
|
||||
enum_corpus!(digest, SessionTerminalEvent, {
|
||||
SessionTerminalEvent::Input(_) => SessionTerminalEvent::Input(TerminalInput { session_id: session_id(), bytes: vec![1] }),
|
||||
SessionTerminalEvent::Resize(_) => SessionTerminalEvent::Resize(resize),
|
||||
SessionTerminalEvent::Signal(_) => SessionTerminalEvent::Signal(TerminalSignal { session_id: session_id(), signal: TerminalSignalKind::Interrupt }),
|
||||
SessionTerminalEvent::Close(_) => SessionTerminalEvent::Close(SessionClose { session_id: session_id() }),
|
||||
});
|
||||
enum_corpus!(digest, SessionExitOutcome, {
|
||||
SessionExitOutcome::Exited => SessionExitOutcome::Exited,
|
||||
SessionExitOutcome::Terminated => SessionExitOutcome::Terminated,
|
||||
SessionExitOutcome::RuntimeLost => SessionExitOutcome::RuntimeLost,
|
||||
});
|
||||
enum_corpus!(digest, SessionTerminalMessage, {
|
||||
SessionTerminalMessage::Output(_) => SessionTerminalMessage::Output(terminal_value(2)),
|
||||
SessionTerminalMessage::Exit(_) => SessionTerminalMessage::Exit(SessionExit::exited(session_id(), 3)),
|
||||
});
|
||||
enum_corpus!(digest, InteractiveSessionEvent, {
|
||||
InteractiveSessionEvent::Terminal(_) => InteractiveSessionEvent::Terminal(SessionTerminalEvent::Resize(resize)),
|
||||
InteractiveSessionEvent::PromptDecision { .. } => InteractiveSessionEvent::PromptDecision { session_id: session_id(), signed_decision: vec![4] },
|
||||
InteractiveSessionEvent::Poll { .. } => InteractiveSessionEvent::Poll { session_id: session_id() },
|
||||
});
|
||||
}
|
||||
|
||||
fn session_message_corpus(digest: &mut Sha256) {
|
||||
let prompt = TerminalPrompt {
|
||||
session_id: session_id(),
|
||||
request_id: RequestId::new(opaque(5)),
|
||||
request_sha256: RequestDigest::new(opaque(6)),
|
||||
agent_profile: "trusted".into(),
|
||||
command_argv: vec![b"tool".to_vec()],
|
||||
justification: "needed".into(),
|
||||
};
|
||||
enum_corpus!(digest, InteractiveSessionMessage, {
|
||||
InteractiveSessionMessage::Terminal(_) => InteractiveSessionMessage::Terminal(SessionTerminalMessage::Output(terminal_value(7))),
|
||||
InteractiveSessionMessage::Prompt(_) => InteractiveSessionMessage::Prompt(prompt),
|
||||
});
|
||||
enum_corpus!(digest, NonInteractiveSessionMessage, {
|
||||
NonInteractiveSessionMessage::Stdout(_) => NonInteractiveSessionMessage::Stdout(NonInteractiveOutput { session_id: session_id(), bytes: vec![8] }),
|
||||
NonInteractiveSessionMessage::Stderr(_) => NonInteractiveSessionMessage::Stderr(NonInteractiveOutput { session_id: session_id(), bytes: vec![9] }),
|
||||
NonInteractiveSessionMessage::Exit(_) => NonInteractiveSessionMessage::Exit(SessionExit::runtime_lost(session_id())),
|
||||
});
|
||||
}
|
||||
|
||||
fn enrollment_request() -> ClientEnrollmentRequest {
|
||||
ClientEnrollmentRequest {
|
||||
protocol_version: ProtocolVersion::V1,
|
||||
generation_identity: generation_identity(),
|
||||
cli_id: ClientId::new(opaque(10)),
|
||||
certificate_signing_request_der: vec![11],
|
||||
}
|
||||
}
|
||||
|
||||
fn enrollment_response() -> ClientEnrollmentResponse {
|
||||
ClientEnrollmentResponse {
|
||||
protocol_version: ProtocolVersion::V1,
|
||||
credential: TlsCredential::client_cli(
|
||||
generation_identity(),
|
||||
ClientId::new(opaque(10)),
|
||||
vec![12],
|
||||
CertificateDigest::new(opaque(13)),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn registration_request() -> SessionRegistrationRequest {
|
||||
SessionRegistrationRequest {
|
||||
protocol_version: ProtocolVersion::V1,
|
||||
session_binding: session_binding(),
|
||||
}
|
||||
}
|
||||
|
||||
fn registration_response() -> SessionRegistrationResponse {
|
||||
SessionRegistrationResponse {
|
||||
protocol_version: ProtocolVersion::V1,
|
||||
session_capability: session_capability(),
|
||||
}
|
||||
}
|
||||
|
||||
fn control_corpus(digest: &mut Sha256) {
|
||||
let resize = TerminalResize {
|
||||
session_id: session_id(),
|
||||
rows: NonZeroU16::new(24).unwrap(),
|
||||
columns: NonZeroU16::new(80).unwrap(),
|
||||
pixel_width: 0,
|
||||
pixel_height: 0,
|
||||
};
|
||||
enum_corpus!(digest, ControlRequest, {
|
||||
ControlRequest::Enroll(_) => ControlRequest::Enroll(enrollment_request()),
|
||||
ControlRequest::Register(_) => ControlRequest::Register(registration_request()),
|
||||
ControlRequest::Execute(_) => ControlRequest::Execute(NonInteractiveSessionRequest { protocol_version: ProtocolVersion::V1, session_id: session_id(), argv: vec![b"tool".to_vec()] }),
|
||||
ControlRequest::ExecuteInteractive(_) => ControlRequest::ExecuteInteractive(InteractiveSessionRequest { protocol_version: ProtocolVersion::V1, session_id: session_id(), argv: vec![b"tool".to_vec()], initial_size: resize }),
|
||||
});
|
||||
enum_corpus!(digest, ControlResponse, {
|
||||
ControlResponse::Enrolled(_) => ControlResponse::Enrolled(enrollment_response()),
|
||||
ControlResponse::Registered(_) => ControlResponse::Registered(registration_response()),
|
||||
});
|
||||
}
|
||||
|
||||
fn credential_corpus(digest: &mut Sha256) {
|
||||
enum_corpus!(digest, ProtocolVersion, {
|
||||
ProtocolVersion::V1 => ProtocolVersion::V1,
|
||||
});
|
||||
enum_corpus!(digest, TlsRole, {
|
||||
TlsRole::SessionCoordinator => TlsRole::SessionCoordinator,
|
||||
TlsRole::ClientCli => TlsRole::ClientCli,
|
||||
});
|
||||
enum_corpus!(digest, TlsSubjectId, {
|
||||
TlsSubjectId::SessionCoordinator(_) => TlsSubjectId::SessionCoordinator(coordinator_id()),
|
||||
TlsSubjectId::ClientCli(_) => TlsSubjectId::ClientCli(ClientId::new(opaque(14))),
|
||||
});
|
||||
enum_corpus!(digest, ProtocolCredentialRole, {
|
||||
ProtocolCredentialRole::SessionCoordinator => ProtocolCredentialRole::SessionCoordinator,
|
||||
ProtocolCredentialRole::AgentSandbox => ProtocolCredentialRole::AgentSandbox,
|
||||
});
|
||||
enum_corpus!(digest, ProtocolSubjectId, {
|
||||
ProtocolSubjectId::SessionCoordinator(_) => ProtocolSubjectId::SessionCoordinator(coordinator_id()),
|
||||
ProtocolSubjectId::AgentSandbox(_) => ProtocolSubjectId::AgentSandbox(sandbox_id()),
|
||||
});
|
||||
enum_corpus!(digest, DeveloperDecisionKind, {
|
||||
DeveloperDecisionKind::Approve => DeveloperDecisionKind::Approve,
|
||||
DeveloperDecisionKind::Deny => DeveloperDecisionKind::Deny,
|
||||
});
|
||||
enum_corpus!(digest, EscalationOutcome, {
|
||||
EscalationOutcome::Completed => EscalationOutcome::Completed,
|
||||
EscalationOutcome::Denied => EscalationOutcome::Denied,
|
||||
EscalationOutcome::TimedOut => EscalationOutcome::TimedOut,
|
||||
EscalationOutcome::Cancelled => EscalationOutcome::Cancelled,
|
||||
EscalationOutcome::Failed => EscalationOutcome::Failed,
|
||||
});
|
||||
enum_corpus!(digest, ResultStream, {
|
||||
ResultStream::Stdout => ResultStream::Stdout,
|
||||
ResultStream::Stderr => ResultStream::Stderr,
|
||||
});
|
||||
}
|
||||
|
||||
fn network_corpus(digest: &mut Sha256) {
|
||||
enum_corpus!(digest, AddressFamily, {
|
||||
AddressFamily::Ipv4 => AddressFamily::Ipv4,
|
||||
AddressFamily::Ipv6 => AddressFamily::Ipv6,
|
||||
});
|
||||
enum_corpus!(digest, AddressFamilyDispositionValue, {
|
||||
AddressFamilyDispositionValue::Enabled => AddressFamilyDispositionValue::Enabled,
|
||||
AddressFamilyDispositionValue::Disabled => AddressFamilyDispositionValue::Disabled,
|
||||
});
|
||||
enum_corpus!(digest, IpAddress, {
|
||||
IpAddress::V4(_) => IpAddress::V4([1, 2, 3, 4]),
|
||||
IpAddress::V6(_) => IpAddress::V6([5; 16]),
|
||||
});
|
||||
enum_corpus!(digest, PolicyAction, {
|
||||
PolicyAction::Allow => PolicyAction::Allow,
|
||||
PolicyAction::Deny => PolicyAction::Deny,
|
||||
});
|
||||
enum_corpus!(digest, PolicyDelivery, {
|
||||
PolicyDelivery::SealedMemfd => PolicyDelivery::SealedMemfd,
|
||||
});
|
||||
}
|
||||
|
||||
fn storage_configuration_waiter_corpus(digest: &mut Sha256) {
|
||||
enum_corpus!(digest, ArtifactState, {
|
||||
ArtifactState::Available => ArtifactState::Available,
|
||||
ArtifactState::Reclaiming => ArtifactState::Reclaiming,
|
||||
});
|
||||
enum_corpus!(digest, PrepareStageState, {
|
||||
PrepareStageState::Intent => PrepareStageState::Intent,
|
||||
PrepareStageState::Owned => PrepareStageState::Owned,
|
||||
});
|
||||
enum_corpus!(digest, VolumeKind, {
|
||||
VolumeKind::File => VolumeKind::File,
|
||||
VolumeKind::Directory => VolumeKind::Directory,
|
||||
});
|
||||
enum_corpus!(digest, VolumeAccess, {
|
||||
VolumeAccess::ReadOnly => VolumeAccess::ReadOnly,
|
||||
VolumeAccess::ReadWrite => VolumeAccess::ReadWrite,
|
||||
});
|
||||
enum_corpus!(digest, BootstrapWaitOutcome, {
|
||||
BootstrapWaitOutcome::Waiting => BootstrapWaitOutcome::Waiting,
|
||||
BootstrapWaitOutcome::Published => BootstrapWaitOutcome::Published,
|
||||
BootstrapWaitOutcome::Failed => BootstrapWaitOutcome::Failed,
|
||||
BootstrapWaitOutcome::Refused => BootstrapWaitOutcome::Refused,
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn every_serialized_enum_variant_has_fixed_shape_evidence() {
|
||||
let mut digest = Sha256::new();
|
||||
lifecycle_corpus(&mut digest);
|
||||
ownership_slot_corpus(&mut digest);
|
||||
terminal_corpus(&mut digest);
|
||||
session_message_corpus(&mut digest);
|
||||
control_corpus(&mut digest);
|
||||
credential_corpus(&mut digest);
|
||||
network_corpus(&mut digest);
|
||||
storage_configuration_waiter_corpus(&mut digest);
|
||||
assert_eq!(
|
||||
digest.finalize().as_slice(),
|
||||
[
|
||||
91, 180, 216, 8, 22, 13, 86, 141, 24, 220, 203, 225, 25, 175, 149, 91, 254, 88, 90,
|
||||
142, 176, 169, 45, 94, 24, 209, 70, 185, 116, 120, 58, 128,
|
||||
]
|
||||
);
|
||||
}
|
||||
Loading…
Reference in a new issue