blackjack/
error.rs

1// Copyright 2024 Ole Kliemann
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::test_spec::{Expr, WaitSpec};
5use display_json::{DebugAsJson, DisplayAsJsonPretty};
6use serde::{Deserialize, Serialize};
7
8#[derive(Debug, thiserror::Error)]
9pub enum Error {
10    #[error("File error: {0}")]
11    FileError(#[from] std::io::Error),
12
13    #[error("String error")]
14    StringError,
15
16    #[error("Path error: {0}")]
17    PathError(std::path::PathBuf),
18
19    #[error("Discovery error: {0:?}")]
20    DiscoveryError(kube::core::GroupVersionKind),
21
22    #[error("Watcher error: {0}")]
23    WatcherError(#[from] kube::runtime::watcher::Error),
24
25    #[error("Command line parse error: {0}")]
26    CommandlineParseError(#[from] shell_words::ParseError),
27
28    #[error("Env substitution error: {0}")]
29    EnvSubstError(#[from] envsubst::Error),
30
31    #[error("Kube error: {0}")]
32    KubeError(#[from] kube::Error),
33
34    #[error("ParseGroupVersionError: {0}")]
35    ParseGroupVersionError(#[from] kube::core::gvk::ParseGroupVersionError),
36
37    #[error("Serialization error: {0}")]
38    SerializationYamlError(#[from] serde_yaml::Error),
39
40    #[error("Serialization error: {0}")]
41    SerializationJsonError(#[from] serde_json::Error),
42
43    #[error("Multiple errors: {0:?}")]
44    MultipleErrors(Vec<Error>),
45
46    #[error("NamespaceExists")]
47    NamespaceExists,
48
49    #[error("Conditions failed: {0}")]
50    ConditionsFailed(TestFailures),
51
52    #[error("Path encoding error")]
53    PathEncodingError,
54
55    #[error("Join error: {0:?}")]
56    JoinError(#[from] tokio::task::JoinError),
57
58    #[error("Interrupted")]
59    SIGINT,
60
61    #[error("Not executed")]
62    NotExecuted,
63
64    #[error("No tests found")]
65    NoTestsFoundError,
66
67    #[error("No UID?!")]
68    NoUidError,
69
70    #[error("Script failed: {0} {1}")]
71    ScriptFailed(String, String),
72
73    #[error("Some tests failed")]
74    SomeTestsFailedError,
75
76    #[error("Other error: {0}")]
77    Other(String),
78}
79
80#[derive(Clone, Serialize, Deserialize, DisplayAsJsonPretty, DebugAsJson)]
81pub struct TestFailure {
82    pub assert_diagnostic: AssertDiagnostic,
83    pub spec: WaitSpec,
84}
85
86#[derive(Debug)]
87pub struct TestFailures(pub Vec<TestFailure>);
88
89pub struct FailedTest {
90    pub test_name: String,
91    pub step_name: String,
92    pub failure: Error,
93}
94
95pub type SucceededTest = String;
96
97pub type TestResult = std::result::Result<SucceededTest, FailedTest>;
98
99#[derive(Clone, DebugAsJson, Serialize, Deserialize)]
100pub struct AssertDiagnostic {
101    pub expr: Expr,
102    pub input: Vec<serde_json::Value>,
103}
104
105impl std::fmt::Display for TestFailures {
106    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
107        for (i, test_failure) in self.0.iter().enumerate() {
108            writeln!(f, "\nFailed condition {}", i + 1)?;
109            writeln!(f, "{test_failure}")?;
110        }
111        Ok(())
112    }
113}
114
115impl std::fmt::Display for AssertDiagnostic {
116    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
117        writeln!(f, "🔴 **Assertion Failed**")?;
118        writeln!(f, "Failed Expression: {}", self.expr)?;
119        writeln!(f, "Input Data:")?;
120        for (i, input) in self.input.iter().enumerate() {
121            writeln!(f, "  {}. {}", i + 1, input)?;
122        }
123        Ok(())
124    }
125}
126
127pub type Result<T> = std::result::Result<T, Error>;