From de8768181631c6d961ce0e4dacb50c2ed02abc36 Mon Sep 17 00:00:00 2001 From: Jack Wills <32690432+mrjackwills@users.noreply.github.com> Date: Thu, 1 Aug 2024 14:46:58 +0000 Subject: [PATCH] feat: unhealthy status, closes #43 Highlight an unhealthy container in Orange, and display "! running" as the state, refactor: Move dev Docker files to docker directory --- .github/screenshot_01.png | Bin 57914 -> 42007 bytes README.md | 4 +- docker/Dockerfile.unhealthy | 17 ++ .../docker-compose.yml | 15 ++ src/app_data/container_state.rs | 169 ++++++++++++++---- src/app_data/mod.rs | 61 ++++--- src/docker_data/mod.rs | 12 +- src/exec.rs | 9 +- src/main.rs | 7 +- src/ui/draw_blocks.rs | 75 +++++++- src/ui/mod.rs | 2 + 11 files changed, 291 insertions(+), 80 deletions(-) create mode 100644 docker/Dockerfile.unhealthy rename docker-compose.yml => docker/docker-compose.yml (73%) diff --git a/.github/screenshot_01.png b/.github/screenshot_01.png index 8355605508df97f9122917033a25fb140f0089b8..0a199b6dd9f58341200623a966c67f36e0037167 100644 GIT binary patch literal 42007 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 RGc#6qDnHG&F8uA>X>O#P}!}rRA_rR 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 NQC3Z+MC!HQ{{Suplpp{A literal 57914 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%0Dy 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 diff --git a/README.md b/README.md index 216972e..cefc768 100644 --- a/README.md +++ b/README.md @@ -168,10 +168,10 @@ cargo test Run some example docker images -using docker-compose.yml; +using docker/docker-compose.yml; ```shell -docker compose -f docker-compose.yml up -d +docker compose -f ./docker/docker-compose.yml up -d ``` or individually diff --git a/docker/Dockerfile.unhealthy b/docker/Dockerfile.unhealthy new file mode 100644 index 0000000..34835d0 --- /dev/null +++ b/docker/Dockerfile.unhealthy @@ -0,0 +1,17 @@ +# Use an official lightweight image as a base +FROM alpine:latest + +# Install a simple utility (e.g., curl) to run as a health check +RUN apk --no-cache add curl + +# Create a dummy file that we will use in our health check +RUN touch /tmp/healthy + +# Define a simple health check +HEALTHCHECK --interval=5s --timeout=3s --retries=3 \ + CMD [ ! -f /tmp/healthy ] || exit 1 + +# Start a basic loop that keeps the container running +CMD ["sh", "-c", "while :; do echo 'Container is running but will be unhealthy'; sleep 30; done"] + +# docker build -t unhealthy-container . -f Dockerfile.unhealthy; docker run -d --name unhealthy unhealthy-container \ No newline at end of file diff --git a/docker-compose.yml b/docker/docker-compose.yml similarity index 73% rename from docker-compose.yml rename to docker/docker-compose.yml index 9ccaf49..2b4c1ea 100644 --- a/docker-compose.yml +++ b/docker/docker-compose.yml @@ -39,5 +39,20 @@ services: resources: limits: memory: 512M + some_container: + container_name: some_container + image: some_container + build: + context: . + dockerfile: Dockerfile.unhealthy + ipc: private + restart: always + networks: + - oxker-example-net + deploy: + resources: + limits: + memory: 128M + diff --git a/src/app_data/container_state.rs b/src/app_data/container_state.rs index 600f152..7eccb32 100644 --- a/src/app_data/container_state.rs +++ b/src/app_data/container_state.rs @@ -10,6 +10,8 @@ use ratatui::{ widgets::{ListItem, ListState}, }; +use crate::ui::ORANGE; + use super::Header; const ONE_KB: f64 = 1000.0; @@ -48,6 +50,9 @@ impl PartialOrd for ContainerId { } } +pub trait Contains { + fn contains(&self, input: &str) -> bool; +} /// ContainerName and ContainerImage are simple structs, used so can implement custom fmt functions to them macro_rules! unit_struct { ($name:ident) => { @@ -67,7 +72,7 @@ macro_rules! unit_struct { } } - impl$name { + impl $name { pub fn get(&self) -> &str { self.0.as_str() } @@ -75,26 +80,20 @@ macro_rules! unit_struct { pub fn set(&mut self, value: String) { self.0 = value; } + } - pub fn contains(&self, term: &str) -> bool { - self.0.to_lowercase().contains(term) + impl Contains for $name { + fn contains(&self, input: &str) -> bool { + self.0.to_lowercase().contains(input) } } impl std::fmt::Display for $name { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { if self.0.chars().count() >= 30 { - write!( - f, - "{}…", - self.0.chars().take(29).collect::() - ) + write!(f, "{}…", self.0.chars().take(29).collect::()) } else { - write!( - f, - "{}", - self.0 - ) + write!(f, "{}", self.0) } } } @@ -211,62 +210,108 @@ impl StatefulList { } } -/// States of the container +/// Store the containers status in a struct, so can then check for healthy/unhealthy status +/// It's usually something like "Up 1 hour", "Exited (0) 10 hours ago", "Up 10 minutes (unhealthy)" +#[derive(Debug, Clone, Eq, PartialEq, PartialOrd)] +pub struct ContainerStatus(String); + +impl From for ContainerStatus { + fn from(value: String) -> Self { + Self(value) + } +} + +impl ContainerStatus { + /// Check if a container is unhealthy + pub fn unhealthy(&self) -> bool { + self.contains("(unhealthy)") + } + + /// Get a reference to the source string + pub const fn get(&self) -> &String { + &self.0 + } +} + +impl Contains for ContainerStatus { + /// Check if the state contains a specific string + fn contains(&self, item: &str) -> bool { + self.0.to_lowercase().contains(item) + } +} + +/// By default a container's running status will be healthy #[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd)] +pub enum RunningState { + Healthy, + Unhealthy, +} +/// States of the container +#[derive(Debug, Clone, Copy, Eq, PartialEq)] pub enum State { Dead, Exited, Paused, Removing, Restarting, - Running, + Running(RunningState), Unknown, } impl State { pub const fn is_alive(self) -> bool { - matches!(self, Self::Running) + matches!(self, Self::Running(_)) } pub const fn get_color(self) -> Color { match self { Self::Paused => Color::Yellow, Self::Removing => Color::LightRed, Self::Restarting => Color::LightGreen, - Self::Running => Color::Green, + Self::Running(RunningState::Healthy) => Color::Green, + Self::Running(RunningState::Unhealthy) => ORANGE, _ => Color::Red, } } /// Dirty way to create order for the state, rather than impl Ord pub const fn order(self) -> u8 { match self { - Self::Running => 0, - Self::Paused => 1, - Self::Restarting => 2, - Self::Removing => 3, - Self::Exited => 4, - Self::Dead => 5, - Self::Unknown => 6, + Self::Running(RunningState::Healthy) => 0, + Self::Running(RunningState::Unhealthy) => 1, + Self::Paused => 2, + Self::Restarting => 3, + Self::Removing => 4, + Self::Exited => 5, + Self::Dead => 6, + Self::Unknown => 7, } } } -impl From<&str> for State { - fn from(input: &str) -> Self { +/// Need status, to check if container is unhealthy or not +impl From<(&str, &ContainerStatus)> for State { + fn from((input, status): (&str, &ContainerStatus)) -> Self { match input { "dead" => Self::Dead, "exited" => Self::Exited, "paused" => Self::Paused, "removing" => Self::Removing, "restarting" => Self::Restarting, - "running" => Self::Running, + "running" => { + if status.unhealthy() { + Self::Running(RunningState::Unhealthy) + } else { + Self::Running(RunningState::Healthy) + } + } _ => Self::Unknown, } } } -impl From> for State { - fn from(input: Option) -> Self { - input.map_or(Self::Unknown, |input| Self::from(input.as_str())) +/// Again, need status, to check if container is unhealthy or not +impl From<(Option, &ContainerStatus)> for State { + fn from((input, status): (Option, &ContainerStatus)) -> Self { + input.map_or(Self::Unknown, |input| Self::from((input.as_str(), status))) } } @@ -278,7 +323,8 @@ impl fmt::Display for State { Self::Paused => "॥ paused", Self::Removing => "removing", Self::Restarting => "↻ restarting", - Self::Running => "✓ running", + Self::Running(RunningState::Healthy) => "✓ running", + Self::Running(RunningState::Unhealthy) => "! running", Self::Unknown => "? unknown", }; write!(f, "{disp}") @@ -314,7 +360,7 @@ impl DockerControls { State::Dead | State::Exited => vec![Self::Start, Self::Restart, Self::Delete], State::Paused => vec![Self::Resume, Self::Stop, Self::Delete], State::Restarting => vec![Self::Stop, Self::Delete], - State::Running => vec![Self::Pause, Self::Restart, Self::Stop, Self::Delete], + State::Running(_) => vec![Self::Pause, Self::Restart, Self::Stop, Self::Delete], _ => vec![Self::Delete], } } @@ -543,7 +589,7 @@ pub struct ContainerItem { pub ports: Vec, pub rx: ByteStats, pub state: State, - pub status: String, + pub status: ContainerStatus, pub tx: ByteStats, } @@ -572,7 +618,7 @@ impl ContainerItem { name: String, ports: Vec, state: State, - status: String, + status: ContainerStatus, ) -> Self { let mut docker_controls = StatefulList::new(DockerControls::gen_vec(state)); docker_controls.start(); @@ -686,11 +732,11 @@ mod tests { use ratatui::widgets::ListItem; use crate::{ - app_data::{ContainerImage, Logs}, + app_data::{ContainerImage, Logs, RunningState}, ui::log_sanitizer, }; - use super::{ByteStats, ContainerName, CpuStats, LogsTz}; + use super::{ByteStats, ContainerName, ContainerStatus, CpuStats, LogsTz, State}; #[test] /// Display CpuStats as a string @@ -774,4 +820,55 @@ mod tests { assert_eq!(logs.logs.items.len(), 2); } + + #[test] + /// check ContainerStatus unhealthy state + fn test_container_state_unhealthy() { + let input = ContainerStatus::from("Up 1 hour".to_owned()); + + assert!(!input.unhealthy()); + + let input = ContainerStatus::from("Up 1 hour (unhealthy)".to_owned()); + + assert!(input.unhealthy()); + } + + #[test] + /// Generate container State from a &str and &ContainerStatus + fn test_container_status_unhealthy() { + let healthy = ContainerStatus::from("Up 1 hour".to_owned()); + let unhealthy = ContainerStatus::from("Up 1 hour (unhealthy)".to_owned()); + + // Running and healthy + let input = State::from(("running", &healthy)); + assert_eq!(input, State::Running(RunningState::Healthy)); + + // Running and unhealthy + let input = State::from(("running", &unhealthy)); + assert_eq!(input, State::Running(RunningState::Unhealthy)); + + // Dead + let input = State::from(("dead", &healthy)); + assert_eq!(input, State::Dead); + + // Exited + let input = State::from(("exited", &healthy)); + assert_eq!(input, State::Exited); + + // Paused + let input = State::from(("paused", &healthy)); + assert_eq!(input, State::Paused); + + // Removing + let input = State::from(("removing", &healthy)); + assert_eq!(input, State::Removing); + + // Restarting + let input = State::from(("restarting", &healthy)); + assert_eq!(input, State::Restarting); + + // Unknown + let input = State::from(("oxker", &healthy)); + assert_eq!(input, State::Unknown); + } } diff --git a/src/app_data/mod.rs b/src/app_data/mod.rs index 002a09b..51027b3 100644 --- a/src/app_data/mod.rs +++ b/src/app_data/mod.rs @@ -179,11 +179,11 @@ impl AppData { FilterBy::All => { container.name.contains(&term) || container.image.contains(&term) - || container.status.to_lowercase().contains(&term) + || container.status.contains(&term) } FilterBy::Image => container.image.contains(&term), FilterBy::Name => container.name.contains(&term), - FilterBy::Status => container.status.to_lowercase().contains(&term), + FilterBy::Status => container.status.contains(&term), } }) } @@ -335,7 +335,8 @@ impl AppData { Header::Status => item_ord .0 .status - .cmp(&item_ord.1.status) + .get() + .cmp(item_ord.1.status.get()) .then_with(|| item_ord.0.name.get().cmp(item_ord.1.name.get())), Header::Cpu => item_ord .0 @@ -727,7 +728,7 @@ impl AppData { columns.net_rx.1 = columns.net_rx.1.max(count(&container.rx.to_string())); columns.net_tx.1 = columns.net_tx.1.max(count(&container.tx.to_string())); columns.state.1 = columns.state.1.max(count(&container.state.to_string())); - columns.status.1 = columns.status.1.max(count(&container.status)); + columns.status.1 = columns.status.1.max(count(container.status.get())); } } columns @@ -836,12 +837,13 @@ impl AppData { .as_ref() .map_or(false, |i| i.starts_with(ENTRY_POINT)); - let state = State::from(i.state.as_ref().map_or("dead", |z| z)); - let status = i - .status - .as_ref() - .map_or(String::new(), std::clone::Clone::clone); + let status = ContainerStatus::from( + i.status + .as_ref() + .map_or(String::new(), std::clone::Clone::clone), + ); + let state = State::from((i.state.as_ref().map_or("dead", |z| z), &status)); let image = i .image .as_ref() @@ -983,7 +985,7 @@ mod tests { i.state = State::Exited; } if let Some(i) = app_data.get_container_by_id(&ContainerId::from("2")) { - i.state = State::Running; + i.state = State::Running(RunningState::Healthy); } if let Some(i) = app_data.get_container_by_id(&ContainerId::from("3")) { i.state = State::Paused; @@ -1017,11 +1019,12 @@ mod tests { assert_eq!(result, &containers); if let Some(i) = app_data.get_container_by_id(&ContainerId::from("2")) { - "Exited (0) 10 minutes ago".clone_into(&mut i.status); + ContainerStatus::from("Exited (0) 10 minutes ago".to_owned()).clone_into(&mut i.status); } if let Some(i) = app_data.get_container_by_id(&ContainerId::from("3")) { - "Up 2 hours (Paused)".clone_into(&mut i.status); + // "Up 2 hours (Paused)".clone_into(&mut i.status); + ContainerStatus::from("Up 2 hours (Paused)".to_owned()).clone_into(&mut i.status); } // Sort by status @@ -1342,7 +1345,7 @@ mod tests { result, Some(( ContainerId::from("1"), - State::Running, + State::Running(RunningState::Healthy), "container_1".to_owned() )) ); @@ -1356,7 +1359,7 @@ mod tests { result, Some(( ContainerId::from("1"), - State::Running, + State::Running(RunningState::Healthy), "container_1".to_owned() )) ); @@ -1384,7 +1387,7 @@ mod tests { result, Some(( ContainerId::from("2"), - State::Running, + State::Running(RunningState::Healthy), "container_2".to_owned() )) ); @@ -1409,7 +1412,7 @@ mod tests { result, Some(( ContainerId::from("3"), - State::Running, + State::Running(RunningState::Healthy), "container_3".to_owned() )) ); @@ -1423,7 +1426,7 @@ mod tests { result, Some(( ContainerId::from("3"), - State::Running, + State::Running(RunningState::Healthy), "container_3".to_owned() )) ); @@ -1504,7 +1507,7 @@ mod tests { result, Some(( ContainerId::from("3"), - State::Running, + State::Running(RunningState::Healthy), "container_3".to_owned() )) ); @@ -1594,7 +1597,7 @@ mod tests { "container_1".to_owned(), vec![], state, - "Up 1 hour".to_owned(), + ContainerStatus::from("Up 1 hour".to_owned()), ) }; let mut app_data = gen_appdata(&[gen_item_state(state)]); @@ -1635,7 +1638,7 @@ mod tests { &mut vec![DockerControls::Stop, DockerControls::Delete], ); test_state( - State::Running, + State::Running(RunningState::Healthy), &mut vec![ DockerControls::Pause, DockerControls::Restart, @@ -1671,7 +1674,6 @@ mod tests { assert_eq!(post_len, 1); // Can insert checks against the current filter term - // todo!("fix me"); assert!(app_data.can_insert(&containers[1])); assert!(!app_data.can_insert(&containers[0])); assert!(!app_data.can_insert(&containers[2])); @@ -1710,7 +1712,7 @@ mod tests { /// Data is filtered correctly by status fn test_app_data_filter_by_status() { let (_, mut containers) = gen_containers(); - "Exited".clone_into(&mut containers[0].status); + ContainerStatus::from("Exited".to_owned()).clone_into(&mut containers[0].status); let mut app_data = gen_appdata(&containers); assert!(app_data.get_filter_term().is_none()); @@ -1738,7 +1740,7 @@ mod tests { /// Data is filtered correctly by all fn test_app_data_filter_by_all() { let (_, mut containers) = gen_containers(); - "Exited".clone_into(&mut containers[0].status); + ContainerStatus::from("Exited".to_owned()).clone_into(&mut containers[0].status); let mut app_data = gen_appdata(&containers); assert!(app_data.get_filter_term().is_none()); @@ -1767,7 +1769,7 @@ mod tests { /// Data is filtered correctly after various next() and previous() commands fn test_app_data_filter_prev() { let (_, mut containers) = gen_containers(); - "Exited".clone_into(&mut containers[0].status); + ContainerStatus::from("Exited".to_owned()).clone_into(&mut containers[0].status); let mut app_data = gen_appdata(&containers); assert!(app_data.get_filter_term().is_none()); @@ -2067,12 +2069,12 @@ mod tests { ( vec![(0.0, 1.1), (1.0, 1.2)], CpuStats::new(1.2), - State::Running + State::Running(RunningState::Healthy), ), ( vec![(0.0, 1.0), (1.0, 2.0)], ByteStats::new(2), - State::Running + State::Running(RunningState::Healthy), ) )) ); @@ -2188,7 +2190,7 @@ mod tests { public: None } ], - State::Running + State::Running(RunningState::Healthy), )) ); @@ -2197,7 +2199,10 @@ mod tests { app_data.containers.items[0].ports = vec![]; let result = app_data.get_selected_ports(); - assert_eq!(result, Some((vec![], State::Running))); + assert_eq!( + result, + Some((vec![], State::Running(RunningState::Healthy))) + ); } // ************** // diff --git a/src/docker_data/mod.rs b/src/docker_data/mod.rs index be3e05f..307d058 100644 --- a/src/docker_data/mod.rs +++ b/src/docker_data/mod.rs @@ -22,7 +22,7 @@ use tokio::{ use uuid::Uuid; use crate::{ - app_data::{AppData, ContainerId, DockerControls, State}, + app_data::{AppData, ContainerId, ContainerStatus, DockerControls, State}, app_error::AppError, parse_args::CliArgs, ui::{GuiState, Status}, @@ -236,7 +236,15 @@ impl DockerData { output .into_iter() .filter_map(|i| { - i.id.map(|id| (State::from(i.state), ContainerId::from(id.as_str()))) + i.id.map(|id| { + ( + State::from(( + i.state, + &ContainerStatus::from(i.status.map_or_else(String::new, |i| i)), + )), + ContainerId::from(id.as_str()), + ) + }) }) .collect::>() } diff --git a/src/exec.rs b/src/exec.rs index 2f3a9d2..1c3468e 100644 --- a/src/exec.rs +++ b/src/exec.rs @@ -18,7 +18,7 @@ use tokio::{ use tokio_util::sync::CancellationToken; use crate::{ - app_data::{AppData, ContainerId, State}, + app_data::{AppData, ContainerId, RunningState, State}, app_error::AppError, }; @@ -162,7 +162,12 @@ impl ExecMode { let container = app_data.lock().get_selected_container_id_state_name(); if let Some((id, state, _)) = container { - if state == State::Running { + if [ + State::Running(RunningState::Healthy), + State::Running(RunningState::Unhealthy), + ] + .contains(&state) + { if tty_readable() && !use_cli { if let Ok(exec) = docker .create_exec( diff --git a/src/main.rs b/src/main.rs index aeff8a4..aa5c2cd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -176,7 +176,8 @@ mod tests { use crate::{ app_data::{ - AppData, ContainerId, ContainerItem, ContainerPorts, Filter, State, StatefulList, + AppData, ContainerId, ContainerItem, ContainerPorts, ContainerStatus, Filter, + RunningState, State, StatefulList, }, parse_args::CliArgs, }; @@ -208,8 +209,8 @@ mod tests { private: u16::try_from(index).unwrap_or(1) + 8000, public: None, }], - State::Running, - format!("Up {index} hour"), + State::Running(RunningState::Healthy), + ContainerStatus::from(format!("Up {index} hour")), ) } diff --git a/src/ui/draw_blocks.rs b/src/ui/draw_blocks.rs index e193375..d98e5ee 100644 --- a/src/ui/draw_blocks.rs +++ b/src/ui/draw_blocks.rs @@ -21,7 +21,7 @@ use crate::{ use super::{ gui_state::{BoxLocation, DeleteButton, Region}, - FrameData, Status, + FrameData, Status, ORANGE, }; use super::{GuiState, SelectablePanel}; @@ -39,7 +39,6 @@ const NAME: &str = env!("CARGO_PKG_NAME"); const VERSION: &str = env!("CARGO_PKG_VERSION"); const REPO: &str = env!("CARGO_PKG_REPOSITORY"); const DESCRIPTION: &str = env!("CARGO_PKG_DESCRIPTION"); -const ORANGE: Color = Color::Rgb(255, 178, 36); const MARGIN: &str = " "; const RIGHT_ARROW: &str = "▶ "; const CIRCLE: &str = "⚪ "; @@ -163,7 +162,7 @@ fn format_containers<'a>(i: &ContainerItem, widths: &Columns) -> Line<'a> { Span::styled( format!( "{: "no ports", + State::Running(_) | State::Paused | State::Restarting => "no ports", _ => "", }; let paragraph = Paragraph::new(Span::from(text).add_modifier(Modifier::BOLD)) @@ -383,7 +382,7 @@ fn make_chart<'a, T: Stats + Display>( ) -> Chart<'a> { let title_color = state.get_color(); let label_color = match state { - State::Running => ORANGE, + State::Running(_) => ORANGE, _ => state.get_color(), }; Chart::new(dataset) @@ -1081,8 +1080,8 @@ mod tests { use crate::{ app_data::{ - AppData, ContainerId, ContainerImage, ContainerName, ContainerPorts, Header, - SortedOrder, State, StatefulList, + AppData, ContainerId, ContainerImage, ContainerName, ContainerPorts, ContainerStatus, + Header, SortedOrder, State, StatefulList, }, app_error::AppError, tests::{gen_appdata, gen_container_summary, gen_containers}, @@ -1782,6 +1781,68 @@ mod tests { } } + #[test] + /// When container state is unknown, correct colors displayed + fn test_draw_blocks_containers_unhealthy() { + let (w, h) = (130, 6); + let mut setup = test_setup(w, h, true, true); + + let status = ContainerStatus::from("Up 1 hour (unhealthy)".to_owned()); + setup.app_data.lock().containers.items[0].state = State::from(("running", &status)); + setup.app_data.lock().containers.items[0].status = status; + + let expected= [ + "╭ Containers 1/3 ────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮", + "│⚪ container_1 ! running Up 1 hour (unhealthy) 00.00% 0.00 kB / 0.00 kB 1 image_1 0.00 kB 0.00 kB │", + "│ container_2 ✓ running Up 2 hour 00.00% 0.00 kB / 0.00 kB 2 image_2 0.00 kB 0.00 kB │", + "│ container_3 ✓ running Up 3 hour 00.00% 0.00 kB / 0.00 kB 3 image_3 0.00 kB 0.00 kB │", + "│ │", + "╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯" + ]; + let fd = FrameData::from((setup.app_data.lock(), setup.gui_state.lock())); + + setup + .terminal + .draw(|f| { + super::containers(&setup.app_data, setup.area, f, &fd, &setup.gui_state); + }) + .unwrap(); + + for (row_index, result_row) in get_result(&setup, w) { + let expected_row = expected_to_vec(&expected, row_index); + for (result_cell_index, result_cell) in result_row.iter().enumerate() { + assert_eq!(result_cell.symbol(), expected_row[result_cell_index]); + match (row_index, result_cell_index) { + // border + (0 | 5, _) | (1..=4, 0 | 129) => { + assert_eq!(result_cell.fg, Color::LightCyan); + } + // name, id, image column + (1..=3, 4..=17 | 83..=103) => { + assert_eq!(result_cell.fg, Color::Blue); + } + // state, status, cpu, memory column of the first row + (1, 18..=82) => { + assert_eq!(result_cell.fg, ORANGE); + } + // state, status, cpu, memory column + (2..=3, 18..=82) => { + assert_eq!(result_cell.fg, Color::Green); + } + // rx column + (1..=3, 104..=113) => { + assert_eq!(result_cell.fg, Color::Rgb(255, 233, 193)); + } + // tx column + (1..=3, 114..=123) => { + assert_eq!(result_cell.fg, Color::Rgb(205, 140, 140)); + } + _ => assert_eq!(result_cell.fg, Color::Reset), + } + } + } + } + #[test] /// When container state is unknown, correct colors displayed fn test_draw_blocks_containers_unknown() { diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 9fca730..99023f8 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -32,6 +32,8 @@ use crate::{ input_handler::InputMessages, }; +pub const ORANGE: ratatui::style::Color = ratatui::style::Color::Rgb(255, 178, 36); + pub struct Ui { app_data: Arc>, gui_state: Arc>,