Skip to content

Commit

Permalink
feat: validate schedule input
Browse files Browse the repository at this point in the history
  • Loading branch information
kasbuunk committed Dec 13, 2024
1 parent d8802bd commit fb043e4
Show file tree
Hide file tree
Showing 5 changed files with 343 additions and 11 deletions.
4 changes: 2 additions & 2 deletions src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ use chrono::prelude::*;
use mockall::{automock, mock, predicate::*};
use uuid::Uuid;

use crate::model::{Message, MetricEvent, Schedule, Transmission};
use crate::model::{Message, MetricEvent, Schedule, ScheduleError, Transmission};

#[cfg_attr(test, automock)]
#[async_trait]
pub trait Scheduler: Send + Sync {
async fn schedule(&self, schedule: Schedule, message: Message) -> Result<Uuid, Box<dyn Error>>;
async fn schedule(&self, schedule: Schedule, message: Message) -> Result<Uuid, ScheduleError>;
}

#[cfg_attr(test, automock)]
Expand Down
9 changes: 9 additions & 0 deletions src/grpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,15 @@ impl proto::transmit_server::Transmit for GrpcServer {
transmission_id: id.to_string(),
}))
}
Err(ScheduleError::AgedSchedule) => Err(Status::invalid_argument(
"aged schedule; provide a timestamp in the future",
)),
Err(ScheduleError::TooShortInterval) => Err(Status::invalid_argument(
"too short interval; provide a greater duration between transmissions",
)),
Err(ScheduleError::NatsInvalidSubject) => Err(Status::invalid_argument(
"provided nats subject not allowed",
)),
Err(err) => {
error!("Failed to schedule message: {err}");

Expand Down
21 changes: 21 additions & 0 deletions src/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ mod tests {

let mut now = MockNow::new();
let mut sequence_now = Sequence::new();

// Expect call for validation.
now.expect_now()
.once()
.in_sequence(&mut sequence_now)
.returning(move || timestamp_now);

for process_listen_iteration in process_listen_iterations.clone() {
now.expect_now()
.once()
Expand Down Expand Up @@ -136,6 +143,13 @@ mod tests {

let mut now = MockNow::new();
let mut sequence_now = Sequence::new();

// Expect call for validation.
now.expect_now()
.once()
.in_sequence(&mut sequence_now)
.returning(move || timestamp_now);

for process_listen_iteration in process_listen_iterations.clone() {
now.expect_now()
.once()
Expand Down Expand Up @@ -234,6 +248,13 @@ mod tests {

let mut now = MockNow::new();
let mut sequence_now = Sequence::new();

// Expect call for validation.
now.expect_now()
.once()
.in_sequence(&mut sequence_now)
.returning(move || timestamp_now);

for process_listen_iteration in process_listen_iterations.clone() {
now.expect_now()
.once()
Expand Down
46 changes: 45 additions & 1 deletion src/model.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::error::Error;
use std::fmt;
use std::str::FromStr;
use std::time;

Expand Down Expand Up @@ -98,7 +99,7 @@ impl Schedule {

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
pub struct Delayed {
transmit_at: DateTime<Utc>,
pub transmit_at: DateTime<Utc>,
}

impl Delayed {
Expand Down Expand Up @@ -221,6 +222,49 @@ pub enum Iterate {
Times(u32),
}

#[derive(Debug)]
pub enum ScheduleError {
AgedSchedule,
TooShortInterval,
NatsInvalidSubject,
Other(Box<dyn Error>),
}

impl fmt::Display for ScheduleError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ScheduleError::AgedSchedule => {
write!(f, "first transmission should not be in the past")
}
ScheduleError::TooShortInterval => write!(f, "interval must be sufficiently large"),
ScheduleError::NatsInvalidSubject => {
write!(f, "subject not allowed")
}
ScheduleError::Other(err) => write!(f, "err: {}", err),
}
}
}

impl PartialEq for ScheduleError {
fn eq(&self, other: &Self) -> bool {
match self {
ScheduleError::AgedSchedule => match other {
ScheduleError::AgedSchedule => true,
_ => false,
},
ScheduleError::TooShortInterval => match other {
ScheduleError::TooShortInterval => true,
_ => false,
},
ScheduleError::NatsInvalidSubject => match other {
ScheduleError::NatsInvalidSubject => true,
_ => false,
},
_ => false,
}
}
}

#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub enum MetricEvent {
Scheduled(bool),
Expand Down
Loading

0 comments on commit fb043e4

Please sign in to comment.