This commit is contained in:
William Brown 2019-02-24 14:15:37 +10:00
parent 341f7cd0c5
commit 71f4becd5f
10 changed files with 116 additions and 203 deletions

View file

@ -1,4 +1,3 @@
pub static PURGE_TIMEOUT: u64 = 3600; pub static PURGE_TIMEOUT: u64 = 3600;
pub static UUID_ADMIN: &'static str = "00000000-0000-0000-0000-000000000000"; pub static UUID_ADMIN: &'static str = "00000000-0000-0000-0000-000000000000";
@ -55,7 +54,6 @@ pub static UUID_SCHEMA_CLASS_EXTENSIBLEOBJECT: &'static str =
pub static UUID_SCHEMA_CLASS_RECYCLED: &'static str = "813bb7e3-dadf-413d-acc4-197b03d55a4f"; pub static UUID_SCHEMA_CLASS_RECYCLED: &'static str = "813bb7e3-dadf-413d-acc4-197b03d55a4f";
pub static UUID_SCHEMA_CLASS_TOMBSTONE: &'static str = "848a1224-0c3c-465f-abd0-10a32e21830e"; pub static UUID_SCHEMA_CLASS_TOMBSTONE: &'static str = "848a1224-0c3c-465f-abd0-10a32e21830e";
// system supplementary // system supplementary
pub static UUID_SCHEMA_ATTR_DISPLAYNAME: &'static str = "201bc966-954b-48f5-bf25-99ffed759861"; pub static UUID_SCHEMA_ATTR_DISPLAYNAME: &'static str = "201bc966-954b-48f5-bf25-99ffed759861";
pub static UUID_SCHEMA_ATTR_MAIL: &'static str = "fae94676-720b-461b-9438-bfe8cfd7e6cd"; pub static UUID_SCHEMA_ATTR_MAIL: &'static str = "fae94676-720b-461b-9438-bfe8cfd7e6cd";

View file

@ -1,10 +1,10 @@
// use actix::SystemRunner; // use actix::SystemRunner;
use actix::Actor;
use actix_web::middleware::session::{self, RequestSession}; use actix_web::middleware::session::{self, RequestSession};
use actix_web::{ use actix_web::{
error, http, middleware, App, AsyncResponder, Error, FutureResponse, HttpMessage, HttpRequest, error, http, middleware, App, AsyncResponder, Error, FutureResponse, HttpMessage, HttpRequest,
HttpResponse, Path, Result, State, HttpResponse, Path, Result, State,
}; };
use actix::Actor;
use bytes::BytesMut; use bytes::BytesMut;
use futures::{future, Future, Stream}; use futures::{future, Future, Stream};
@ -14,14 +14,13 @@ use super::config::Configuration;
// SearchResult // SearchResult
use super::event::{AuthEvent, CreateEvent, DeleteEvent, ModifyEvent, SearchEvent}; use super::event::{AuthEvent, CreateEvent, DeleteEvent, ModifyEvent, SearchEvent};
use super::filter::Filter; use super::filter::Filter;
use super::interval::IntervalActor;
use super::log; use super::log;
use super::proto_v1::{ use super::proto_v1::{
AuthRequest, AuthResponse, CreateRequest, DeleteRequest, ModifyRequest, SearchRequest, AuthRequest, AuthResponse, CreateRequest, DeleteRequest, ModifyRequest, SearchRequest,
}; };
use super::interval::IntervalActor;
use super::server; use super::server;
struct AppState { struct AppState {
qe: actix::Addr<server::QueryServer>, qe: actix::Addr<server::QueryServer>,
max_size: usize, max_size: usize,

View file

@ -381,7 +381,9 @@ impl Entry<EntryValid, EntryCommitted> {
pub fn to_tombstone(&self) -> Self { pub fn to_tombstone(&self) -> Self {
// Duplicate this to a tombstone entry. // Duplicate this to a tombstone entry.
let uuid_ava = self.get_ava(&String::from("uuid")).expect("Corrupted entry!"); let uuid_ava = self
.get_ava(&String::from("uuid"))
.expect("Corrupted entry!");
let class_ava = vec!["object".to_string(), "tombstone".to_string()]; let class_ava = vec!["object".to_string(), "tombstone".to_string()];
let mut attrs_new: BTreeMap<String, Vec<String>> = BTreeMap::new(); let mut attrs_new: BTreeMap<String, Vec<String>> = BTreeMap::new();

View file

@ -2,7 +2,7 @@ use super::filter::{Filter, FilterInvalid};
use super::proto_v1::Entry as ProtoEntry; use super::proto_v1::Entry as ProtoEntry;
use super::proto_v1::{ use super::proto_v1::{
AuthRequest, AuthResponse, AuthStatus, CreateRequest, DeleteRequest, ModifyRequest, Response, AuthRequest, AuthResponse, AuthStatus, CreateRequest, DeleteRequest, ModifyRequest, Response,
SearchRequest, SearchResponse, SearchRecycledRequest, ReviveRecycledRequest ReviveRecycledRequest, SearchRecycledRequest, SearchRequest, SearchResponse,
}; };
use actix::prelude::*; use actix::prelude::*;
use entry::{Entry, EntryCommitted, EntryInvalid, EntryNew, EntryValid}; use entry::{Entry, EntryCommitted, EntryInvalid, EntryNew, EntryValid};
@ -73,20 +73,12 @@ impl SearchEvent {
SearchEvent { SearchEvent {
internal: false, internal: false,
filter: Filter::And(vec![ filter: Filter::And(vec![
Filter::AndNot(Box::new( Filter::AndNot(Box::new(Filter::Or(vec![
Filter::Or(vec![ Filter::Eq("class".to_string(), "tombstone".to_string()),
Filter::Eq( Filter::Eq("class".to_string(), "recycled".to_string()),
"class".to_string(), ]))),
"tombstone".to_string(), Filter::from(&request.filter),
), ]),
Filter::Eq(
"class".to_string(),
"recycled".to_string(),
)
])
)),
Filter::from(&request.filter)
]),
class: (), class: (),
} }
} }
@ -102,12 +94,9 @@ impl SearchEvent {
pub fn from_rec_request(request: SearchRecycledRequest) -> Self { pub fn from_rec_request(request: SearchRecycledRequest) -> Self {
SearchEvent { SearchEvent {
filter: Filter::And(vec![ filter: Filter::And(vec![
Filter::Eq( Filter::Eq("class".to_string(), "recycled".to_string()),
"class".to_string(), Filter::from(&request.filter),
"recycled".to_string(), ]),
),
Filter::from(&request.filter)
]),
internal: false, internal: false,
class: (), class: (),
} }
@ -201,20 +190,12 @@ impl DeleteEvent {
pub fn from_request(request: DeleteRequest) -> Self { pub fn from_request(request: DeleteRequest) -> Self {
DeleteEvent { DeleteEvent {
filter: Filter::And(vec![ filter: Filter::And(vec![
Filter::AndNot(Box::new( Filter::AndNot(Box::new(Filter::Or(vec![
Filter::Or(vec![ Filter::Eq("class".to_string(), "tombstone".to_string()),
Filter::Eq( Filter::Eq("class".to_string(), "recycled".to_string()),
"class".to_string(), ]))),
"tombstone".to_string(), Filter::from(&request.filter),
), ]),
Filter::Eq(
"class".to_string(),
"recycled".to_string(),
)
])
)),
Filter::from(&request.filter)
]),
internal: false, internal: false,
} }
} }
@ -250,22 +231,14 @@ impl ModifyEvent {
pub fn from_request(request: ModifyRequest) -> Self { pub fn from_request(request: ModifyRequest) -> Self {
ModifyEvent { ModifyEvent {
filter: Filter::And(vec![ filter: Filter::And(vec![
Filter::AndNot(Box::new( Filter::AndNot(Box::new(Filter::Or(vec![
Filter::Or(vec![ Filter::Eq("class".to_string(), "tombstone".to_string()),
Filter::Eq( Filter::Eq("class".to_string(), "recycled".to_string()),
"class".to_string(), ]))),
"tombstone".to_string(), Filter::from(&request.filter),
), ]),
Filter::Eq(
"class".to_string(),
"recycled".to_string(),
)
])
)),
Filter::from(&request.filter)
]),
modlist: ModifyList::from(&request.modlist), modlist: ModifyList::from(&request.modlist),
internal: false internal: false,
} }
} }
@ -310,7 +283,6 @@ impl AuthResult {
} }
} }
#[derive(Debug)] #[derive(Debug)]
pub struct PurgeEvent {} pub struct PurgeEvent {}
@ -338,12 +310,9 @@ impl ReviveRecycledEvent {
pub fn from_request(request: ReviveRecycledRequest) -> Self { pub fn from_request(request: ReviveRecycledRequest) -> Self {
ReviveRecycledEvent { ReviveRecycledEvent {
filter: Filter::And(vec![ filter: Filter::And(vec![
Filter::Eq( Filter::Eq("class".to_string(), "recycled".to_string()),
"class".to_string(), Filter::from(&request.filter),
"recycled".to_string(), ]),
),
Filter::from(&request.filter)
]),
internal: false, internal: false,
} }
} }

View file

@ -1,10 +1,9 @@
use std::time::Duration;
use actix::prelude::*; use actix::prelude::*;
use std::time::Duration;
use server::QueryServer;
use event::PurgeEvent;
use constants::PURGE_TIMEOUT; use constants::PURGE_TIMEOUT;
use event::PurgeEvent;
use server::QueryServer;
pub struct IntervalActor { pub struct IntervalActor {
// Store any addresses we require // Store any addresses we require
@ -13,9 +12,7 @@ pub struct IntervalActor {
impl IntervalActor { impl IntervalActor {
pub fn new(server: actix::Addr<QueryServer>) -> Self { pub fn new(server: actix::Addr<QueryServer>) -> Self {
IntervalActor { IntervalActor { server: server }
server: server,
}
} }
// Define new events here // Define new events here
@ -35,4 +32,3 @@ impl Actor for IntervalActor {
}); });
} }
} }

View file

@ -1,5 +1,5 @@
use proto_v1::ModifyList as ProtoModifyList;
use proto_v1::Modify as ProtoModify; use proto_v1::Modify as ProtoModify;
use proto_v1::ModifyList as ProtoModifyList;
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub enum Modify { pub enum Modify {
@ -14,15 +14,9 @@ pub enum Modify {
impl Modify { impl Modify {
pub fn from(m: &ProtoModify) -> Self { pub fn from(m: &ProtoModify) -> Self {
match m { match m {
ProtoModify::Present(a, v) => { ProtoModify::Present(a, v) => Modify::Present(a.clone(), v.clone()),
Modify::Present(a.clone(), v.clone()) ProtoModify::Removed(a, v) => Modify::Removed(a.clone(), v.clone()),
} ProtoModify::Purged(a) => Modify::Purged(a.clone()),
ProtoModify::Removed(a, v) => {
Modify::Removed(a.clone(), v.clone())
}
ProtoModify::Purged(a) => {
Modify::Purged(a.clone())
}
} }
} }
} }
@ -54,11 +48,7 @@ impl ModifyList {
// For each ProtoModify, do a from. // For each ProtoModify, do a from.
ModifyList { ModifyList {
mods: ml.mods.iter() mods: ml.mods.iter().map(|pm| Modify::from(pm)).collect(),
.map(|pm| {
Modify::from(pm)
})
.collect()
} }
} }
} }

View file

@ -0,0 +1 @@

View file

@ -27,7 +27,6 @@ pub enum Filter {
AndNot(Box<Filter>), AndNot(Box<Filter>),
} }
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub enum Modify { pub enum Modify {
Present(String, String), Present(String, String),
@ -169,7 +168,6 @@ pub struct AuthResponse {
pub status: AuthStatus, pub status: AuthStatus,
} }
/* Recycle Requests area */ /* Recycle Requests area */
// Only two actions on recycled is possible. Search and Revive. // Only two actions on recycled is possible. Search and Revive.
@ -184,7 +182,6 @@ impl SearchRecycledRequest {
} }
} }
// Need a search response here later. // Need a search response here later.
pub struct ReviveRecycledRequest { pub struct ReviveRecycledRequest {

View file

@ -593,7 +593,9 @@ impl SchemaInner {
SchemaClass { SchemaClass {
name: String::from("extensibleobject"), name: String::from("extensibleobject"),
uuid: Uuid::parse_str(UUID_SCHEMA_CLASS_EXTENSIBLEOBJECT).unwrap(), uuid: Uuid::parse_str(UUID_SCHEMA_CLASS_EXTENSIBLEOBJECT).unwrap(),
description: String::from("A class type that has green hair and turns off all rules ..."), description: String::from(
"A class type that has green hair and turns off all rules ...",
),
systemmay: vec![], systemmay: vec![],
may: vec![], may: vec![],
systemmust: vec![], systemmust: vec![],
@ -781,10 +783,7 @@ impl SchemaInner {
// String::from("gidnumber"), // String::from("gidnumber"),
], ],
may: vec![], may: vec![],
systemmust: vec![ systemmust: vec![String::from("displayname"), String::from("name")],
String::from("displayname"),
String::from("name")
],
must: vec![], must: vec![],
}, },
); );
@ -800,10 +799,7 @@ impl SchemaInner {
// String::from("password"), // String::from("password"),
], ],
may: vec![], may: vec![],
systemmust: vec![ systemmust: vec![String::from("displayname"), String::from("name")],
String::from("displayname"),
String::from("name")
],
must: vec![], must: vec![],
}, },
); );
@ -818,9 +814,7 @@ impl SchemaInner {
// String::from("gidnumber"), // String::from("gidnumber"),
], ],
may: vec![], may: vec![],
systemmust: vec![ systemmust: vec![String::from("name")],
String::from("name"),
],
must: vec![], must: vec![],
}, },
); );

View file

@ -14,11 +14,11 @@ use entry::{Entry, EntryCommitted, EntryInvalid, EntryNew, EntryValid};
use error::{OperationError, SchemaError}; use error::{OperationError, SchemaError};
use event::{ use event::{
AuthEvent, AuthResult, CreateEvent, DeleteEvent, ExistsEvent, ModifyEvent, OpResult, AuthEvent, AuthResult, CreateEvent, DeleteEvent, ExistsEvent, ModifyEvent, OpResult,
SearchEvent, SearchResult, PurgeEvent, ReviveRecycledEvent PurgeEvent, ReviveRecycledEvent, SearchEvent, SearchResult,
}; };
use filter::{Filter, FilterInvalid}; use filter::{Filter, FilterInvalid};
use log::EventLog; use log::EventLog;
use modify::{ModifyList, Modify}; use modify::{Modify, ModifyList};
use plugins::Plugins; use plugins::Plugins;
use schema::{Schema, SchemaReadTransaction, SchemaTransaction, SchemaWriteTransaction}; use schema::{Schema, SchemaReadTransaction, SchemaTransaction, SchemaWriteTransaction};
@ -433,16 +433,11 @@ impl<'a> QueryServerWriteTransaction<'a> {
// delete everything that is a tombstone. // delete everything that is a tombstone.
// Search for tombstones // Search for tombstones
let ts = match self.internal_search( let ts = match self
au, .internal_search(au, Filter::Eq("class".to_string(), "tombstone".to_string()))
Filter::Eq("class".to_string(), "tombstone".to_string()) {
) { Ok(r) => r,
Ok(r) => { Err(e) => return Err(e),
r
}
Err(e) => {
return Err(e)
}
}; };
// TODO: Has an appropriate amount of time/condition past (ie replication events?) // TODO: Has an appropriate amount of time/condition past (ie replication events?)
@ -475,23 +470,16 @@ impl<'a> QueryServerWriteTransaction<'a> {
pub fn purge_recycled(&self, au: &mut AuditScope) -> Result<(), OperationError> { pub fn purge_recycled(&self, au: &mut AuditScope) -> Result<(), OperationError> {
// Send everything that is recycled to tombstone // Send everything that is recycled to tombstone
// Search all recycled // Search all recycled
let rc = match self.internal_search( let rc = match self
au, .internal_search(au, Filter::Eq("class".to_string(), "recycled".to_string()))
Filter::Eq("class".to_string(), "recycled".to_string()) {
) { Ok(r) => r,
Ok(r) => { Err(e) => return Err(e),
r
}
Err(e) => {
return Err(e)
}
}; };
// Modify them to strip all avas except uuid // Modify them to strip all avas except uuid
let tombstone_cand = rc.iter().map(|e| { let tombstone_cand = rc.iter().map(|e| e.to_tombstone()).collect();
e.to_tombstone()
}).collect();
// Backend Modify // Backend Modify
let mut audit_be = AuditScope::new("backend_modify"); let mut audit_be = AuditScope::new("backend_modify");
@ -518,7 +506,11 @@ impl<'a> QueryServerWriteTransaction<'a> {
} }
// Should this take a revive event? // Should this take a revive event?
pub fn revive_recycled(&self, au: &mut AuditScope, re: &ReviveRecycledEvent) -> Result<(), OperationError> { pub fn revive_recycled(
&self,
au: &mut AuditScope,
re: &ReviveRecycledEvent,
) -> Result<(), OperationError> {
// Revive an entry to live. This is a specialised (limited) // Revive an entry to live. This is a specialised (limited)
// modify proxy. // modify proxy.
// //
@ -527,20 +519,13 @@ impl<'a> QueryServerWriteTransaction<'a> {
// create the modify // create the modify
// tl;dr, remove the class=recycled // tl;dr, remove the class=recycled
let modlist = ModifyList::new_list(vec![ let modlist = ModifyList::new_list(vec![Modify::Removed(
Modify::Removed( "class".to_string(),
"class".to_string(), "recycled".to_string(),
"recycled".to_string(), )]);
),
]);
// Now impersonate the modify // Now impersonate the modify
self.impersonate_modify( self.impersonate_modify(au, re.filter.clone(), modlist)
au,
re.filter.clone(),
modlist
)
} }
pub fn modify(&self, au: &mut AuditScope, me: &ModifyEvent) -> Result<(), OperationError> { pub fn modify(&self, au: &mut AuditScope, me: &ModifyEvent) -> Result<(), OperationError> {
@ -879,8 +864,6 @@ impl Actor for QueryServer {
ctx.set_mailbox_capacity(1 << 31); ctx.set_mailbox_capacity(1 << 31);
} }
*/ */
} }
// The server only recieves "Event" structures, which // The server only recieves "Event" structures, which
@ -1043,15 +1026,20 @@ mod tests {
use super::super::be::{Backend, BackendTransaction}; use super::super::be::{Backend, BackendTransaction};
use super::super::entry::{Entry, EntryCommitted, EntryInvalid, EntryNew, EntryValid}; use super::super::entry::{Entry, EntryCommitted, EntryInvalid, EntryNew, EntryValid};
use super::super::error::OperationError; use super::super::error::OperationError;
use super::super::event::{CreateEvent, DeleteEvent, ModifyEvent, SearchEvent, ReviveRecycledEvent}; use super::super::event::{
CreateEvent, DeleteEvent, ModifyEvent, ReviveRecycledEvent, SearchEvent,
};
use super::super::filter::Filter; use super::super::filter::Filter;
use super::super::log; use super::super::log;
use super::super::modify::{Modify, ModifyList}; use super::super::modify::{Modify, ModifyList};
use super::super::proto_v1::Entry as ProtoEntry; use super::super::proto_v1::Entry as ProtoEntry;
use super::super::proto_v1::Filter as ProtoFilter; use super::super::proto_v1::Filter as ProtoFilter;
use super::super::proto_v1::{CreateRequest, SearchRequest, DeleteRequest, ModifyRequest, SearchRecycledRequest, ReviveRecycledRequest};
use super::super::proto_v1::Modify as ProtoModify; use super::super::proto_v1::Modify as ProtoModify;
use super::super::proto_v1::ModifyList as ProtoModifyList; use super::super::proto_v1::ModifyList as ProtoModifyList;
use super::super::proto_v1::{
CreateRequest, DeleteRequest, ModifyRequest, ReviveRecycledRequest, SearchRecycledRequest,
SearchRequest,
};
use super::super::schema::Schema; use super::super::schema::Schema;
use super::super::server::{ use super::super::server::{
QueryServer, QueryServerReadTransaction, QueryServerWriteTransaction, QueryServer, QueryServerReadTransaction, QueryServerWriteTransaction,
@ -1430,29 +1418,21 @@ mod tests {
run_test!(|_log, mut server: QueryServer, audit: &mut AuditScope| { run_test!(|_log, mut server: QueryServer, audit: &mut AuditScope| {
let mut server_txn = server.write(); let mut server_txn = server.write();
let filt_ts = ProtoFilter::Eq( let filt_ts = ProtoFilter::Eq(String::from("class"), String::from("tombstone"));
String::from("class"),
String::from("tombstone")
);
let filt_i_ts = Filter::Eq( let filt_i_ts = Filter::Eq(String::from("class"), String::from("tombstone"));
String::from("class"),
String::from("tombstone")
);
// Create fake external requests. Probably from admin later // Create fake external requests. Probably from admin later
let me_ts = ModifyEvent::from_request( let me_ts = ModifyEvent::from_request(ModifyRequest::new(
ModifyRequest::new( filt_ts.clone(),
filt_ts.clone(), ProtoModifyList::new_list(vec![ProtoModify::Present(
ProtoModifyList::new_list(vec![ String::from("class"),
ProtoModify::Present(String::from("class"), String::from("tombstone")), String::from("tombstone"),
]), )]),
) ));
);
let de_ts = DeleteEvent::from_request(DeleteRequest::new(filt_ts.clone())); let de_ts = DeleteEvent::from_request(DeleteRequest::new(filt_ts.clone()));
let se_ts = SearchEvent::from_request(SearchRequest::new(filt_ts.clone())); let se_ts = SearchEvent::from_request(SearchRequest::new(filt_ts.clone()));
// First, create a tombstone // First, create a tombstone
let e_ts: Entry<EntryInvalid, EntryNew> = serde_json::from_str( let e_ts: Entry<EntryInvalid, EntryNew> = serde_json::from_str(
r#"{ r#"{
@ -1484,7 +1464,9 @@ mod tests {
// Can it be seen (internal search) // Can it be seen (internal search)
// Internal search should see it. // Internal search should see it.
let r2 = server_txn.internal_search(audit, filt_i_ts.clone()).unwrap(); let r2 = server_txn
.internal_search(audit, filt_i_ts.clone())
.unwrap();
assert!(r2.len() == 1); assert!(r2.len() == 1);
// Now purge // Now purge
@ -1505,52 +1487,30 @@ mod tests {
run_test!(|_log, mut server: QueryServer, audit: &mut AuditScope| { run_test!(|_log, mut server: QueryServer, audit: &mut AuditScope| {
let mut server_txn = server.write(); let mut server_txn = server.write();
let filt_rc = ProtoFilter::Eq( let filt_rc = ProtoFilter::Eq(String::from("class"), String::from("recycled"));
String::from("class"),
String::from("recycled")
);
let filt_i_rc = Filter::Eq( let filt_i_rc = Filter::Eq(String::from("class"), String::from("recycled"));
String::from("class"),
String::from("recycled")
);
let filt_i_ts = Filter::Eq( let filt_i_ts = Filter::Eq(String::from("class"), String::from("tombstone"));
String::from("class"),
String::from("tombstone")
);
let filt_i_per = Filter::Eq( let filt_i_per = Filter::Eq(String::from("class"), String::from("person"));
String::from("class"),
String::from("person")
);
// Create fake external requests. Probably from admin later // Create fake external requests. Probably from admin later
let me_rc = ModifyEvent::from_request( let me_rc = ModifyEvent::from_request(ModifyRequest::new(
ModifyRequest::new( filt_rc.clone(),
filt_rc.clone(), ProtoModifyList::new_list(vec![ProtoModify::Present(
ProtoModifyList::new_list(vec![ String::from("class"),
ProtoModify::Present(String::from("class"), String::from("recycled")), String::from("recycled"),
]), )]),
) ));
);
let de_rc = DeleteEvent::from_request(DeleteRequest::new(filt_rc.clone())); let de_rc = DeleteEvent::from_request(DeleteRequest::new(filt_rc.clone()));
let se_rc = SearchEvent::from_request(SearchRequest::new(filt_rc.clone())); let se_rc = SearchEvent::from_request(SearchRequest::new(filt_rc.clone()));
let sre_rc = SearchEvent::from_rec_request( let sre_rc = SearchEvent::from_rec_request(SearchRecycledRequest::new(filt_rc.clone()));
SearchRecycledRequest::new(
filt_rc.clone()
)
);
let rre_rc = ReviveRecycledEvent::from_request( let rre_rc = ReviveRecycledEvent::from_request(ReviveRecycledRequest::new(
ReviveRecycledRequest::new( ProtoFilter::Eq("name".to_string(), "testperson1".to_string()),
ProtoFilter::Eq( ));
"name".to_string(),
"testperson1".to_string(),
)
)
);
// Create some recycled objects // Create some recycled objects
let e1: Entry<EntryInvalid, EntryNew> = serde_json::from_str( let e1: Entry<EntryInvalid, EntryNew> = serde_json::from_str(
@ -1583,7 +1543,6 @@ mod tests {
) )
.unwrap(); .unwrap();
let ce = CreateEvent::from_vec(vec![e1, e2]); let ce = CreateEvent::from_vec(vec![e1, e2]);
let cr = server_txn.create(audit, &ce); let cr = server_txn.create(audit, &ce);
assert!(cr.is_ok()); assert!(cr.is_ok());
@ -1606,7 +1565,9 @@ mod tests {
// Can it be seen (internal search) // Can it be seen (internal search)
// Internal search should see it. // Internal search should see it.
let r2 = server_txn.internal_search(audit, filt_i_rc.clone()).unwrap(); let r2 = server_txn
.internal_search(audit, filt_i_rc.clone())
.unwrap();
assert!(r2.len() == 2); assert!(r2.len() == 2);
// There are now two options // There are now two options
@ -1617,15 +1578,21 @@ mod tests {
assert!(server_txn.purge_recycled(audit).is_ok()); assert!(server_txn.purge_recycled(audit).is_ok());
// Should be no recycled objects. // Should be no recycled objects.
let r3 = server_txn.internal_search(audit, filt_i_rc.clone()).unwrap(); let r3 = server_txn
.internal_search(audit, filt_i_rc.clone())
.unwrap();
assert!(r3.len() == 0); assert!(r3.len() == 0);
// There should be one tombstone // There should be one tombstone
let r4 = server_txn.internal_search(audit, filt_i_ts.clone()).unwrap(); let r4 = server_txn
.internal_search(audit, filt_i_ts.clone())
.unwrap();
assert!(r4.len() == 1); assert!(r4.len() == 1);
// There should be one entry // There should be one entry
let r5 = server_txn.internal_search(audit, filt_i_per.clone()).unwrap(); let r5 = server_txn
.internal_search(audit, filt_i_per.clone())
.unwrap();
assert!(r5.len() == 1); assert!(r5.len() == 1);
assert!(server_txn.commit(audit).is_ok()); assert!(server_txn.commit(audit).is_ok());