From 0b7e06498083395beaeb5098033419350f9db1ea Mon Sep 17 00:00:00 2001 From: Sergio <77530549+sergi0g@users.noreply.github.com> Date: Sat, 16 Nov 2024 14:58:16 +0200 Subject: [PATCH] Update sort_update_vec function, fix lints and enable testing in CI --- .github/workflows/ci.yml | 3 + src/check.rs | 12 ++- src/structs/image.rs | 2 +- src/utils/sort_update_vec.rs | 182 ++++++++++++++++++++++++----------- 4 files changed, 137 insertions(+), 62 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0351d88..06412d3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,6 +28,9 @@ jobs: - name: Build run: ./build.sh cargo build --verbose + - name: Test + run: cargo test + build-image: runs-on: ubuntu-latest steps: diff --git a/src/check.rs b/src/check.rs index 4150a17..d60beae 100644 --- a/src/check.rs +++ b/src/check.rs @@ -16,8 +16,12 @@ pub async fn get_updates(references: &Option>, config: &Config) -> V let mut images = get_images_from_docker_daemon(config, references).await; let extra_images = match references { Some(refs) => { - let image_refs: FxHashSet<&String> = images.iter().map(|image| &image.reference).collect(); - let extra = refs.iter().filter(|&reference| !image_refs.contains(reference)).collect::>(); + let image_refs: FxHashSet<&String> = + images.iter().map(|image| &image.reference).collect(); + let extra = refs + .iter() + .filter(|&reference| !image_refs.contains(reference)) + .collect::>(); let mut handles = Vec::with_capacity(extra.len()); for reference in extra { @@ -25,8 +29,8 @@ pub async fn get_updates(references: &Option>, config: &Config) -> V handles.push(future) } Some(join_all(handles).await) - }, - None => None + } + None => None, }; if let Some(extra_imgs) = extra_images { images.extend_from_slice(&extra_imgs); diff --git a/src/structs/image.rs b/src/structs/image.rs index 1da2c9a..c451d9d 100644 --- a/src/structs/image.rs +++ b/src/structs/image.rs @@ -75,7 +75,7 @@ impl Image { /// Creates and populates the fields of an Image object based on a reference. If the tag is not recognized as a version string, exits the program with an error. pub async fn from_reference(reference: &str) -> Self { - let (registry, repository, tag) = split(&reference); + let (registry, repository, tag) = split(reference); let version_tag = Version::from_tag(&tag); match version_tag { Some(version) => Self { diff --git a/src/utils/sort_update_vec.rs b/src/utils/sort_update_vec.rs index a55781c..1f86517 100644 --- a/src/utils/sort_update_vec.rs +++ b/src/utils/sort_update_vec.rs @@ -2,7 +2,7 @@ use std::cmp::Ordering; use crate::structs::image::Image; -/// Sorts the update vector alphabetically and where Some(true) > Some(false) > None +/// Sorts the update vector alphabetically and by Status pub fn sort_image_vec(updates: &[Image]) -> Vec { let mut sorted_updates = updates.to_vec(); sorted_updates.sort_by(|a, b| { @@ -18,76 +18,53 @@ pub fn sort_image_vec(updates: &[Image]) -> Vec { #[cfg(test)] mod tests { - use crate::structs::image::DigestInfo; + use crate::structs::{ + image::{DigestInfo, VersionInfo}, + version::Version, + }; use super::*; /// Test the `sort_update_vec` function - /// TODO: test versioning as well + /// We test for sorting based on status (Major > Minor > Patch > Digest > Up to date > Unknown) and that references are sorted alphabetically. #[test] fn test_ordering() { // Create test objects - let update_available_1 = Image { - reference: "busybox".to_string(), - digest_info: Some(DigestInfo { - local_digests: vec!["some_digest".to_string(), "some_other_digest".to_string()], - remote_digest: Some("latest_digest".to_string()), - }), - ..Default::default() - }; - let update_available_2 = Image { - reference: "library/alpine".to_string(), - digest_info: Some(DigestInfo { - local_digests: vec!["some_digest".to_string(), "some_other_digest".to_string()], - remote_digest: Some("latest_digest".to_string()), - }), - ..Default::default() - }; - let up_to_date_1 = Image { - reference: "docker:dind".to_string(), - digest_info: Some(DigestInfo { - local_digests: vec![ - "some_digest".to_string(), - "some_other_digest".to_string(), - "latest_digest".to_string(), - ], - remote_digest: Some("latest_digest".to_string()), - }), - ..Default::default() - }; - let up_to_date_2 = Image { - reference: "ghcr.io/sergi0g/cup".to_string(), - digest_info: Some(DigestInfo { - local_digests: vec![ - "some_digest".to_string(), - "some_other_digest".to_string(), - "latest_digest".to_string(), - ], - remote_digest: Some("latest_digest".to_string()), - }), - ..Default::default() - }; - let unknown_1 = Image { - reference: "fake_registry.com/fake/image".to_string(), - error: Some("whoops".to_string()), - ..Default::default() - }; - let unknown_2 = Image { - reference: "private_registry.io/private/image".to_string(), - error: Some("whoops".to_string()), - ..Default::default() - }; + let major_update_1 = create_major_update("redis:6.2"); // We're ignoring the tag we passed here, that is tested in version.rs + let major_update_2 = create_major_update("traefik:v3.0"); + let minor_update_1 = create_minor_update("mysql:8.0"); + let minor_update_2 = create_minor_update("rust:1.80.1-alpine"); + let patch_update_1 = create_patch_update("node:20"); + let patch_update_2 = create_patch_update("valkey/valkey:7.2-alpine"); + let digest_update_1 = create_digest_update("busybox"); + let digest_update_2 = create_digest_update("library/alpine"); + let up_to_date_1 = create_up_to_date("docker:dind"); + let up_to_date_2 = create_up_to_date("ghcr.io/sergi0g/cup"); + let unknown_1 = create_unknown("fake_registry.com/fake/image"); + let unknown_2 = create_unknown("private_registry.io/private/image"); let input_vec = vec![ + major_update_2.clone(), unknown_2.clone(), + minor_update_2.clone(), + patch_update_2.clone(), up_to_date_1.clone(), unknown_1.clone(), - update_available_2.clone(), - update_available_1.clone(), + patch_update_1.clone(), + digest_update_2.clone(), + minor_update_1.clone(), + major_update_1.clone(), + digest_update_1.clone(), up_to_date_2.clone(), ]; let expected_vec = vec![ - update_available_1, - update_available_2, + major_update_1, + major_update_2, + minor_update_1, + minor_update_2, + patch_update_1, + patch_update_2, + digest_update_1, + digest_update_2, up_to_date_1, up_to_date_2, unknown_1, @@ -100,4 +77,95 @@ mod tests { // Check results assert_eq!(sorted_vec, expected_vec); } + + fn create_unknown(reference: &str) -> Image { + Image { + reference: reference.to_string(), + error: Some("whoops".to_string()), + ..Default::default() + } + } + + fn create_up_to_date(reference: &str) -> Image { + Image { + reference: reference.to_string(), + digest_info: Some(DigestInfo { + local_digests: vec![ + "some_digest".to_string(), + "some_other_digest".to_string(), + "latest_digest".to_string(), + ], + remote_digest: Some("latest_digest".to_string()), + }), + ..Default::default() + } + } + + fn create_digest_update(reference: &str) -> Image { + Image { + reference: reference.to_string(), + digest_info: Some(DigestInfo { + local_digests: vec!["some_digest".to_string(), "some_other_digest".to_string()], + remote_digest: Some("latest_digest".to_string()), + }), + ..Default::default() + } + } + + fn create_patch_update(reference: &str) -> Image { + Image { + reference: reference.to_string(), + version_info: Some(VersionInfo { + current_tag: Version { + major: 19, + minor: Some(42), + patch: Some(999), + }, + latest_remote_tag: Some(Version { + major: 19, + minor: Some(42), + patch: Some(1000), + }), + }), + ..Default::default() + } + } + + fn create_minor_update(reference: &str) -> Image { + Image { + reference: reference.to_string(), + version_info: Some(VersionInfo { + current_tag: Version { + major: 19, + minor: Some(42), + patch: Some(45), + }, + latest_remote_tag: Some(Version { + major: 19, + minor: Some(47), + patch: Some(2), + }), + }), + ..Default::default() + } + } + + fn create_major_update(reference: &str) -> Image { + Image { + reference: reference.to_string(), + version_info: Some(VersionInfo { + current_tag: Version { + major: 17, + minor: Some(42), + patch: None, + }, + latest_remote_tag: Some(Version { + major: 19, + minor: Some(0), + patch: None, + }), + }), + ..Default::default() + } + } }