From ff9e37c9b7e3100c7ab1e01da1293f6ea3bfe999 Mon Sep 17 00:00:00 2001 From: mjsterckx Date: Thu, 13 Oct 2022 23:25:22 +0000 Subject: [PATCH] controller: replaced parse_duration package with custom parser --- Cargo.lock | 70 -------------- controller/Cargo.toml | 1 - controller/src/constants.rs | 98 ++++++++++++++++++++ controller/src/resource_controller/action.rs | 6 +- controller/src/test_controller/action.rs | 4 +- 5 files changed, 103 insertions(+), 76 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ef87daf5..b43a0454 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -764,7 +764,6 @@ dependencies = [ "lazy_static", "log", "model", - "parse_duration", "schemars", "serde", "serde_json", @@ -1725,41 +1724,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" -[[package]] -name = "num" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8536030f9fea7127f841b45bb6243b27255787fb4eb83958aa1ef9d2fdc0c36" -dependencies = [ - "num-bigint", - "num-complex", - "num-integer", - "num-iter", - "num-rational", - "num-traits", -] - -[[package]] -name = "num-bigint" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-complex" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" -dependencies = [ - "autocfg", - "num-traits", -] - [[package]] name = "num-integer" version = "0.1.45" @@ -1770,29 +1734,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-iter" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" -dependencies = [ - "autocfg", - "num-bigint", - "num-integer", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.15" @@ -1945,17 +1886,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "parse_duration" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7037e5e93e0172a5a96874380bf73bc6ecef022e26fa25f2be26864d6b3ba95d" -dependencies = [ - "lazy_static", - "num", - "regex", -] - [[package]] name = "path-absolutize" version = "3.0.13" diff --git a/controller/Cargo.toml b/controller/Cargo.toml index eb513bf8..c0b74e2f 100644 --- a/controller/Cargo.toml +++ b/controller/Cargo.toml @@ -16,7 +16,6 @@ kube-runtime = "0.75" lazy_static = "1" log = "0.4" model = { version = "0.0.2", path = "../model" } -parse_duration = "2.1" schemars = "=0.8.10" serde = { version = "1", features = ["derive"] } serde_json = "1" diff --git a/controller/src/constants.rs b/controller/src/constants.rs index 1963211b..b839377f 100644 --- a/controller/src/constants.rs +++ b/controller/src/constants.rs @@ -1,6 +1,11 @@ +use crate::error::Result; +use anyhow::Context; use kube_runtime::controller::Action; +use std::collections::VecDeque; use std::time::Duration; +const UNITS: [(char, u64); 3] = [('d', 86400), ('h', 3600), ('m', 60)]; + /// Tell the controller to reconcile the object again after some duration. pub(crate) fn requeue() -> Action { Action::requeue(Duration::from_secs(5)) @@ -15,3 +20,96 @@ pub(crate) fn requeue_slow() -> Action { pub(crate) fn no_requeue() -> Action { Action::await_change() } + +/// Parse a Duration string into a Duration object. +pub(crate) fn parse_duration(input: &str) -> Result { + let mut secs: u64 = 0; + let mut duration_string = input; + for unit in UNITS { + let mut vec: VecDeque<&str> = duration_string.split(unit.0).collect(); + if vec.len() > 1 { + secs += vec + .pop_front() + .context("Failed to parse input")? + .parse::()? + * unit.1; + } + duration_string = vec.pop_front().context("Failed to parse input")?; + } + let mut vec: VecDeque<&str> = duration_string.split('s').collect(); + let seconds = vec.pop_front().context("Failed to parse input")?; + if !seconds.is_empty() { + secs += seconds.parse::()?; + } + Ok(Duration::from_secs(secs)) +} + +#[test] +fn all_units() { + let input = "1d2h3m4s"; + assert!( + parse_duration(input).is_ok() + && parse_duration(input).unwrap() == Duration::from_secs(93784) + ) +} + +#[test] +fn some_units() { + let input = "1d3m4s"; + assert!( + parse_duration(input).is_ok() + && parse_duration(input).unwrap() == Duration::from_secs(86584) + ) +} + +#[test] +fn only_seconds() { + let input = "500s"; + assert!( + parse_duration(input).is_ok() && parse_duration(input).unwrap() == Duration::from_secs(500) + ) +} + +#[test] +fn no_seconds() { + let input = "1h5m"; + assert!( + parse_duration(input).is_ok() + && parse_duration(input).unwrap() == Duration::from_secs(3900) + ) +} + +#[test] +fn one_unit() { + let input = "10m"; + assert!( + parse_duration(input).is_ok() && parse_duration(input).unwrap() == Duration::from_secs(600) + ) +} + +#[test] +fn no_units() { + let input = "5123"; + assert!( + parse_duration(input).is_ok() + && parse_duration(input).unwrap() == Duration::from_secs(5123) + ) +} + +#[test] +fn wrong_order() { + let input = "10d5m3h2s"; + assert!(parse_duration(input).is_err()) +} + +#[test] +fn invalid_unit() { + let input = "5y40s"; + assert!(parse_duration(input).is_err()) +} + +#[test] +fn missing_value() { + let input = "5hm4s"; + assert!(parse_duration(input).is_err()) +} diff --git a/controller/src/resource_controller/action.rs b/controller/src/resource_controller/action.rs index b83b18ab..17afa010 100644 --- a/controller/src/resource_controller/action.rs +++ b/controller/src/resource_controller/action.rs @@ -1,3 +1,4 @@ +use crate::constants::parse_duration; use crate::error::Result; use crate::job::{JobState, TEST_START_TIME_LIMIT}; use crate::resource_controller::context::ResourceInterface; @@ -7,7 +8,6 @@ use log::{debug, trace}; use model::clients::{AllowNotFound, CrdClient, TestClient}; use model::constants::{FINALIZER_CREATION_JOB, FINALIZER_MAIN, FINALIZER_RESOURCE}; use model::{CrdExt, DestructionPolicy, ResourceAction, TaskState, TestUserState}; -use parse_duration::parse; /// The action that the controller needs to take in order to reconcile the [`Resource`]. #[derive(Debug, Clone, Eq, PartialEq)] @@ -155,7 +155,7 @@ async fn creation_not_done_action( .agent .timeout .as_ref() - .map(|timeout| parse(timeout).map(|timeout| std_duration > timeout)) + .map(|timeout| parse_duration(timeout).map(|timeout| std_duration > timeout)) .unwrap_or(Ok(false)) .unwrap_or(false) { @@ -299,7 +299,7 @@ async fn destruction_not_done_action( .agent .timeout .as_ref() - .map(|timeout| parse(timeout).map(|timeout| std_duration > timeout)) + .map(|timeout| parse_duration(timeout).map(|timeout| std_duration > timeout)) .unwrap_or(Ok(false)) .unwrap_or(false) { diff --git a/controller/src/test_controller/action.rs b/controller/src/test_controller/action.rs index 7bd28946..4bb7ad3f 100644 --- a/controller/src/test_controller/action.rs +++ b/controller/src/test_controller/action.rs @@ -1,3 +1,4 @@ +use crate::constants::parse_duration; use crate::error::Result; use crate::job::{JobState, TEST_START_TIME_LIMIT}; use crate::test_controller::context::TestInterface; @@ -7,7 +8,6 @@ use log::trace; use model::clients::{CrdClient, HttpStatusCode, StatusCode}; use model::constants::{FINALIZER_MAIN, FINALIZER_TEST_JOB, NAMESPACE}; use model::{CrdExt, Outcome, Resource, ResourceAction, TaskState}; -use parse_duration::parse; use std::fmt::{Display, Formatter}; /// The action that the controller needs to take in order to reconcile the `Test`. @@ -219,7 +219,7 @@ async fn task_not_done_action(t: &TestInterface, is_task_state_running: bool) -> .agent .timeout .as_ref() - .map(|timeout| parse(timeout).map(|timeout| std_duration > timeout)) + .map(|timeout| parse_duration(timeout).map(|timeout| std_duration > timeout)) .unwrap_or(Ok(false)) .unwrap_or(false) {