cloud_sdk_testkit/
adversarial.rs1use crate::{FixtureBody, FixtureBodyError};
4
5pub const DEFAULT_RESPONSE_LIMIT: usize = 8_388_608;
7
8#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
10pub enum AdversarialKind {
11 MalformedJson,
13 UnknownFields,
15 MissingRequiredFields,
17 OversizedResponse,
19 InvalidPagination,
21 InvalidActionState,
23}
24
25#[derive(Clone, Copy, Debug, Eq, PartialEq)]
27pub struct AdversarialFixture<'a> {
28 kind: AdversarialKind,
29 body: FixtureBody<'a>,
30}
31
32impl<'a> AdversarialFixture<'a> {
33 #[must_use]
35 pub const fn new(kind: AdversarialKind, body: FixtureBody<'a>) -> Self {
36 Self { kind, body }
37 }
38
39 #[must_use]
41 pub const fn kind(self) -> AdversarialKind {
42 self.kind
43 }
44
45 #[must_use]
47 pub const fn body(self) -> FixtureBody<'a> {
48 self.body
49 }
50}
51
52pub fn adversarial_corpus() -> Result<[AdversarialFixture<'static>; 6], FixtureBodyError> {
54 let oversized_len = DEFAULT_RESPONSE_LIMIT
55 .checked_add(1)
56 .ok_or(FixtureBodyError::TooLarge)?;
57 Ok([
58 AdversarialFixture::new(
59 AdversarialKind::MalformedJson,
60 FixtureBody::new(br#"{"error":"#)?,
61 ),
62 AdversarialFixture::new(
63 AdversarialKind::UnknownFields,
64 FixtureBody::new(
65 br#"{"action":{"id":1,"command":"test","status":"running","progress":1,"started":"2026-07-12T12:00:00Z","finished":null,"resources":[],"error":null,"unknown":true},"unknown":true}"#,
66 )?,
67 ),
68 AdversarialFixture::new(
69 AdversarialKind::MissingRequiredFields,
70 FixtureBody::new(br#"{}"#)?,
71 ),
72 AdversarialFixture::new(
73 AdversarialKind::OversizedResponse,
74 FixtureBody::repeated(b' ', oversized_len)?,
75 ),
76 AdversarialFixture::new(
77 AdversarialKind::InvalidPagination,
78 FixtureBody::new(br#"{"meta":{"pagination":{"page":0,"per_page":0,"last_page":0}}}"#)?,
79 ),
80 AdversarialFixture::new(
81 AdversarialKind::InvalidActionState,
82 FixtureBody::new(br#"{"action":{"id":1,"status":"not-a-state","progress":101}}"#)?,
83 ),
84 ])
85}