Skip to content

Commit

Permalink
controller: replaced parse_duration package with custom parser
Browse files Browse the repository at this point in the history
  • Loading branch information
mjsterckx committed Oct 15, 2022
1 parent bdcffc9 commit ff9e37c
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 76 deletions.
70 changes: 0 additions & 70 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion controller/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
98 changes: 98 additions & 0 deletions controller/src/constants.rs
Original file line number Diff line number Diff line change
@@ -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))
Expand All @@ -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<Duration> {
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::<u64>()?
* 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::<u64>()?;
}
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())
}
6 changes: 3 additions & 3 deletions controller/src/resource_controller/action.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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)]
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
{
Expand Down
4 changes: 2 additions & 2 deletions controller/src/test_controller/action.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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`.
Expand Down Expand Up @@ -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)
{
Expand Down

0 comments on commit ff9e37c

Please sign in to comment.