154 lines
4.4 KiB
Rust
154 lines
4.4 KiB
Rust
use crate::data_build_event::Event;
|
|
use crate::{
|
|
BuildState, DataBuildEvent, EventFilter, WantState,
|
|
};
|
|
use std::error::Error;
|
|
use std::sync::{Arc, RwLock};
|
|
|
|
trait BELStorage {
|
|
fn append_event(&mut self, event: Event) -> Result<u64, Box<dyn Error>>;
|
|
fn list_events(
|
|
&self,
|
|
since_idx: u64,
|
|
filter: EventFilter,
|
|
limit: u64,
|
|
) -> Result<Vec<DataBuildEvent>, Box<dyn Error>>;
|
|
}
|
|
|
|
struct BuildEventLog<B: BELStorage> {
|
|
storage: B,
|
|
state: Arc<RwLock<BuildState>>,
|
|
}
|
|
|
|
impl<B: BELStorage> BuildEventLog<B> {
|
|
fn create(storage: B) -> BuildEventLog<B> {
|
|
BuildEventLog {
|
|
storage,
|
|
state: Arc::new(Default::default()),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<B: BELStorage> BuildEventLog<B> {
|
|
fn append_event(&mut self, event: Event) -> Result<u64, Box<dyn Error>> {
|
|
let idx = self.storage.append_event(event.clone())?;
|
|
self.reduce(event);
|
|
Ok(idx)
|
|
}
|
|
|
|
fn reduce(&mut self, event: Event) {
|
|
match event {
|
|
Event::JobRunBuffer(e) => {}
|
|
Event::JobRunQueue(_) => {}
|
|
Event::JobRunStarted(_) => {}
|
|
Event::JobRunHeartbeat(_) => {}
|
|
Event::JobRunSuccess(_) => {}
|
|
Event::JobRunFailure(_) => {}
|
|
Event::JobRunCancel(_) => {}
|
|
Event::JobRunMissingDeps(_) => {}
|
|
Event::WantCreate(e) => {
|
|
self.state
|
|
.write()
|
|
.expect("couldn't take write lock")
|
|
.wants
|
|
.insert(e.want_id.clone(), WantState { want_id: e.want_id });
|
|
}
|
|
Event::WantCancel(_) => {}
|
|
Event::TaintCreate(_) => {}
|
|
Event::TaintDelete(_) => {}
|
|
}
|
|
}
|
|
}
|
|
|
|
mod tests {
|
|
use crate::build_event_log::{BELStorage, BuildEventLog};
|
|
use crate::data_build_event::Event;
|
|
use crate::{DataBuildEvent, EventFilter, PartitionRef, WantCreateEvent};
|
|
use std::error::Error;
|
|
use std::time::{SystemTime, UNIX_EPOCH};
|
|
|
|
struct TestBELStorage {
|
|
events: Vec<DataBuildEvent>,
|
|
}
|
|
|
|
impl TestBELStorage {
|
|
fn create() -> TestBELStorage {
|
|
TestBELStorage { events: vec![] }
|
|
}
|
|
}
|
|
|
|
impl BELStorage for TestBELStorage {
|
|
fn append_event(&mut self, event: Event) -> Result<u64, Box<dyn Error>> {
|
|
let now = SystemTime::now();
|
|
let duration_since_epoch = now.duration_since(UNIX_EPOCH)
|
|
.expect("Time went backwards");
|
|
|
|
let timestamp = duration_since_epoch.as_nanos() as u64;
|
|
|
|
let dbe = DataBuildEvent {
|
|
timestamp,
|
|
event_id: self.events.len() as u64,
|
|
event: Some(event),
|
|
};
|
|
self.events.push(dbe);
|
|
Ok(self.events.len() as u64)
|
|
}
|
|
|
|
fn list_events(
|
|
&self,
|
|
since_idx: u64,
|
|
filter: EventFilter,
|
|
limit: u64,
|
|
) -> Result<Vec<DataBuildEvent>, Box<dyn Error>> {
|
|
Ok(self.events.clone())
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_hello() {
|
|
assert_eq!(2 + 3, 5);
|
|
}
|
|
|
|
#[test]
|
|
fn test_append_event() {
|
|
let storage = TestBELStorage::create();
|
|
let mut log = BuildEventLog::create(storage);
|
|
// Initial state
|
|
assert_eq!(log.storage.events.len(), 0);
|
|
let want_id = "1234".to_string();
|
|
{
|
|
let state = log.state.read().unwrap();
|
|
assert!(state.wants.get(&want_id).is_none());
|
|
}
|
|
|
|
// Given
|
|
log.append_event(Event::WantCreate(WantCreateEvent {
|
|
want_id: want_id.clone(),
|
|
root_want_id: "123".to_string(),
|
|
parent_want_id: "123".to_string(),
|
|
partitions: vec![PartitionRef {
|
|
r#ref: "".to_string(),
|
|
}],
|
|
data_timestamp: 0,
|
|
ttl_seconds: 1,
|
|
sla_seconds: 1,
|
|
source: None,
|
|
comment: None,
|
|
}))
|
|
.expect("append_event failed");
|
|
|
|
// Assert
|
|
assert_eq!(log.storage.events.len(), 1);
|
|
let state = log.state.read().expect("couldn't take read lock");
|
|
assert!(state.wants.get(&want_id).is_some(), "want_id not found");
|
|
assert_eq!(
|
|
state
|
|
.wants
|
|
.get(&want_id)
|
|
.map(|want| want.want_id.clone())
|
|
.expect("state.wants want_id not found"),
|
|
want_id,
|
|
"want_id not equal",
|
|
);
|
|
}
|
|
}
|