mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 20:47:01 +01:00
Further test improvements (#1166)
This commit is contained in:
parent
df4043cf10
commit
692c0a3978
|
@ -97,3 +97,84 @@ pub(crate) fn qs_test(_args: &TokenStream, item: TokenStream, with_init: bool) -
|
||||||
|
|
||||||
result.into()
|
result.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn idm_test(_args: &TokenStream, item: TokenStream) -> TokenStream {
|
||||||
|
let input: syn::ItemFn = match syn::parse(item.clone()) {
|
||||||
|
Ok(it) => it,
|
||||||
|
Err(e) => return token_stream_with_error(item, e),
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(attr) = input.attrs.iter().find(|attr| attr.path.is_ident("test")) {
|
||||||
|
let msg = "second test attribute is supplied";
|
||||||
|
return token_stream_with_error(item, syn::Error::new_spanned(&attr, msg));
|
||||||
|
};
|
||||||
|
|
||||||
|
if input.sig.asyncness.is_none() {
|
||||||
|
let msg = "the `async` keyword is missing from the function declaration";
|
||||||
|
return token_stream_with_error(item, syn::Error::new_spanned(input.sig.fn_token, msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If type mismatch occurs, the current rustc points to the last statement.
|
||||||
|
let (last_stmt_start_span, _last_stmt_end_span) = {
|
||||||
|
let mut last_stmt = input
|
||||||
|
.block
|
||||||
|
.stmts
|
||||||
|
.last()
|
||||||
|
.map(ToTokens::into_token_stream)
|
||||||
|
.unwrap_or_default()
|
||||||
|
.into_iter();
|
||||||
|
// `Span` on stable Rust has a limitation that only points to the first
|
||||||
|
// token, not the whole tokens. We can work around this limitation by
|
||||||
|
// using the first/last span of the tokens like
|
||||||
|
// `syn::Error::new_spanned` does.
|
||||||
|
let start = last_stmt.next().map_or_else(Span::call_site, |t| t.span());
|
||||||
|
let end = last_stmt.last().map_or(start, |t| t.span());
|
||||||
|
(start, end)
|
||||||
|
};
|
||||||
|
|
||||||
|
let rt = quote_spanned! {last_stmt_start_span=>
|
||||||
|
tokio::runtime::Builder::new_current_thread()
|
||||||
|
};
|
||||||
|
|
||||||
|
let header = quote! {
|
||||||
|
#[::core::prelude::v1::test]
|
||||||
|
};
|
||||||
|
|
||||||
|
let test_fn = &input.sig.ident;
|
||||||
|
let test_driver = Ident::new(&format!("idm_{}", test_fn), input.sig.span());
|
||||||
|
|
||||||
|
// Effectively we are just injecting a real test function around this which we will
|
||||||
|
// call.
|
||||||
|
|
||||||
|
let result = quote! {
|
||||||
|
#input
|
||||||
|
|
||||||
|
#header
|
||||||
|
fn #test_driver() {
|
||||||
|
let body = async {
|
||||||
|
let (test_server, mut idms_delayed) = crate::testkit::setup_idm_test().await;
|
||||||
|
|
||||||
|
#test_fn(&test_server, &mut idms_delayed).await;
|
||||||
|
|
||||||
|
// Any needed teardown?
|
||||||
|
// Make sure there are no errors.
|
||||||
|
let mut idm_read_txn = test_server.proxy_read().await;
|
||||||
|
let verifications = idm_read_txn.qs_read.verify();
|
||||||
|
trace!("Verification result: {:?}", verifications);
|
||||||
|
assert!(verifications.len() == 0);
|
||||||
|
|
||||||
|
idms_delayed.check_is_empty_or_panic();
|
||||||
|
};
|
||||||
|
#[allow(clippy::expect_used, clippy::diverging_sub_expression)]
|
||||||
|
{
|
||||||
|
return #rt
|
||||||
|
.enable_all()
|
||||||
|
.build()
|
||||||
|
.expect("Failed building the Runtime")
|
||||||
|
.block_on(body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
result.into()
|
||||||
|
}
|
||||||
|
|
|
@ -26,3 +26,8 @@ pub fn qs_test(args: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
pub fn qs_test_no_init(args: TokenStream, item: TokenStream) -> TokenStream {
|
pub fn qs_test_no_init(args: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
entry::qs_test(&args, item, false)
|
entry::qs_test(&args, item, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[proc_macro_attribute]
|
||||||
|
pub fn idm_test(args: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
|
entry::idm_test(&args, item)
|
||||||
|
}
|
||||||
|
|
|
@ -1,15 +1,11 @@
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
use async_std::task;
|
|
||||||
use criterion::{
|
use criterion::{
|
||||||
criterion_group, criterion_main, BenchmarkId, Criterion, SamplingMode, Throughput,
|
criterion_group, criterion_main, BenchmarkId, Criterion, SamplingMode, Throughput,
|
||||||
};
|
};
|
||||||
use kanidmd_lib;
|
use kanidmd_lib;
|
||||||
use kanidmd_lib::entry::{Entry, EntryInit, EntryNew};
|
use kanidmd_lib::entry::{Entry, EntryInit, EntryNew};
|
||||||
use kanidmd_lib::entry_init;
|
use kanidmd_lib::entry_init;
|
||||||
use kanidmd_lib::idm::server::{IdmServer, IdmServerDelayed};
|
|
||||||
use kanidmd_lib::macros::run_idm_test_no_logging;
|
|
||||||
use kanidmd_lib::server::QueryServer;
|
|
||||||
use kanidmd_lib::utils::duration_from_epoch_now;
|
use kanidmd_lib::utils::duration_from_epoch_now;
|
||||||
use kanidmd_lib::value::Value;
|
use kanidmd_lib::value::Value;
|
||||||
|
|
||||||
|
@ -28,14 +24,19 @@ pub fn scaling_user_create_single(c: &mut Criterion) {
|
||||||
println!("iters, size -> {:?}, {:?}", iters, size);
|
println!("iters, size -> {:?}, {:?}", iters, size);
|
||||||
|
|
||||||
for _i in 0..iters {
|
for _i in 0..iters {
|
||||||
run_idm_test_no_logging(
|
let mut rt = tokio::runtime::Builder::new_current_thread();
|
||||||
|_qs: &QueryServer, idms: &IdmServer, _idms_delayed: &IdmServerDelayed| {
|
elapsed = rt
|
||||||
let ct = duration_from_epoch_now();
|
.enable_all()
|
||||||
|
.build()
|
||||||
|
.expect("Failed building the Runtime")
|
||||||
|
.block_on(async {
|
||||||
|
let (idms, _idms_delayed) =
|
||||||
|
kanidmd_lib::testkit::setup_idm_test().await;
|
||||||
|
|
||||||
|
let ct = duration_from_epoch_now();
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
for counter in 0..size {
|
for counter in 0..size {
|
||||||
let idms_prox_write = task::block_on(idms.proxy_write_async(ct));
|
let mut idms_prox_write = idms.proxy_write(ct).await;
|
||||||
|
|
||||||
let name = format!("testperson_{}", counter);
|
let name = format!("testperson_{}", counter);
|
||||||
let e1 = entry_init!(
|
let e1 = entry_init!(
|
||||||
("class", Value::new_class("object")),
|
("class", Value::new_class("object")),
|
||||||
|
@ -51,9 +52,8 @@ pub fn scaling_user_create_single(c: &mut Criterion) {
|
||||||
|
|
||||||
idms_prox_write.commit().expect("Must not fail");
|
idms_prox_write.commit().expect("Must not fail");
|
||||||
}
|
}
|
||||||
elapsed = elapsed.checked_add(start.elapsed()).unwrap();
|
elapsed.checked_add(start.elapsed()).unwrap()
|
||||||
},
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
elapsed
|
elapsed
|
||||||
});
|
});
|
||||||
|
@ -92,20 +92,25 @@ pub fn scaling_user_create_batched(c: &mut Criterion) {
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
for _i in 0..iters {
|
for _i in 0..iters {
|
||||||
kanidmd_lib::macros::run_idm_test_no_logging(
|
let mut rt = tokio::runtime::Builder::new_current_thread();
|
||||||
|_qs: &QueryServer, idms: &IdmServer, _idms_delayed: &IdmServerDelayed| {
|
elapsed = rt
|
||||||
let ct = duration_from_epoch_now();
|
.enable_all()
|
||||||
|
.build()
|
||||||
|
.expect("Failed building the Runtime")
|
||||||
|
.block_on(async {
|
||||||
|
let (idms, _idms_delayed) =
|
||||||
|
kanidmd_lib::testkit::setup_idm_test().await;
|
||||||
|
|
||||||
|
let ct = duration_from_epoch_now();
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
|
||||||
let idms_prox_write = task::block_on(idms.proxy_write_async(ct));
|
let mut idms_prox_write = idms.proxy_write(ct).await;
|
||||||
let cr = idms_prox_write.qs_write.internal_create(data.clone());
|
let cr = idms_prox_write.qs_write.internal_create(data.clone());
|
||||||
assert!(cr.is_ok());
|
assert!(cr.is_ok());
|
||||||
|
|
||||||
idms_prox_write.commit().expect("Must not fail");
|
idms_prox_write.commit().expect("Must not fail");
|
||||||
elapsed = elapsed.checked_add(start.elapsed()).unwrap();
|
elapsed.checked_add(start.elapsed()).unwrap()
|
||||||
},
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
elapsed
|
elapsed
|
||||||
});
|
});
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,3 @@
|
||||||
use core::task::{Context, Poll};
|
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -11,8 +10,6 @@ use concread::cowcell::{CowCellReadTxn, CowCellWriteTxn};
|
||||||
use concread::hashmap::HashMap;
|
use concread::hashmap::HashMap;
|
||||||
use concread::CowCell;
|
use concread::CowCell;
|
||||||
use fernet::Fernet;
|
use fernet::Fernet;
|
||||||
// #[cfg(any(test,bench))]
|
|
||||||
use futures::task as futures_task;
|
|
||||||
use hashbrown::HashSet;
|
use hashbrown::HashSet;
|
||||||
use kanidm_proto::v1::{
|
use kanidm_proto::v1::{
|
||||||
ApiToken, BackupCodesView, CredentialStatus, PasswordFeedback, RadiusAuthToken, UatPurpose,
|
ApiToken, BackupCodesView, CredentialStatus, PasswordFeedback, RadiusAuthToken, UatPurpose,
|
||||||
|
@ -343,8 +340,12 @@ impl IdmServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IdmServerDelayed {
|
impl IdmServerDelayed {
|
||||||
// #[cfg(any(test,bench))]
|
// I think we can just make this async in the future?
|
||||||
|
#[cfg(test)]
|
||||||
pub(crate) fn check_is_empty_or_panic(&mut self) {
|
pub(crate) fn check_is_empty_or_panic(&mut self) {
|
||||||
|
use core::task::{Context, Poll};
|
||||||
|
use futures::task as futures_task;
|
||||||
|
|
||||||
let waker = futures_task::noop_waker();
|
let waker = futures_task::noop_waker();
|
||||||
let mut cx = Context::from_waker(&waker);
|
let mut cx = Context::from_waker(&waker);
|
||||||
match self.async_rx.poll_recv(&mut cx) {
|
match self.async_rx.poll_recv(&mut cx) {
|
||||||
|
@ -365,6 +366,9 @@ impl IdmServerDelayed {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) fn try_recv(&mut self) -> Result<DelayedAction, OperationError> {
|
pub(crate) fn try_recv(&mut self) -> Result<DelayedAction, OperationError> {
|
||||||
|
use core::task::{Context, Poll};
|
||||||
|
use futures::task as futures_task;
|
||||||
|
|
||||||
let waker = futures_task::noop_waker();
|
let waker = futures_task::noop_waker();
|
||||||
let mut cx = Context::from_waker(&waker);
|
let mut cx = Context::from_waker(&waker);
|
||||||
match self.async_rx.poll_recv(&mut cx) {
|
match self.async_rx.poll_recv(&mut cx) {
|
||||||
|
|
|
@ -375,98 +375,93 @@ mod tests {
|
||||||
use kanidm_proto::v1::ApiToken;
|
use kanidm_proto::v1::ApiToken;
|
||||||
|
|
||||||
use super::{DestroyApiTokenEvent, GenerateApiTokenEvent};
|
use super::{DestroyApiTokenEvent, GenerateApiTokenEvent};
|
||||||
// use crate::prelude::*;
|
|
||||||
use crate::event::CreateEvent;
|
use crate::event::CreateEvent;
|
||||||
use crate::idm::server::IdmServerTransaction;
|
use crate::idm::server::IdmServerTransaction;
|
||||||
|
use crate::prelude::*;
|
||||||
use async_std::task;
|
|
||||||
|
|
||||||
const TEST_CURRENT_TIME: u64 = 6000;
|
const TEST_CURRENT_TIME: u64 = 6000;
|
||||||
|
|
||||||
#[test]
|
#[idm_test]
|
||||||
fn test_idm_service_account_api_token() {
|
async fn test_idm_service_account_api_token(
|
||||||
run_idm_test!(|_qs: &QueryServer,
|
idms: &IdmServer,
|
||||||
idms: &IdmServer,
|
_idms_delayed: &mut IdmServerDelayed,
|
||||||
_idms_delayed: &mut IdmServerDelayed| {
|
) {
|
||||||
let ct = Duration::from_secs(TEST_CURRENT_TIME);
|
let ct = Duration::from_secs(TEST_CURRENT_TIME);
|
||||||
let past_grc = Duration::from_secs(TEST_CURRENT_TIME + 1) + GRACE_WINDOW;
|
let past_grc = Duration::from_secs(TEST_CURRENT_TIME + 1) + GRACE_WINDOW;
|
||||||
let exp = Duration::from_secs(TEST_CURRENT_TIME + 6000);
|
let exp = Duration::from_secs(TEST_CURRENT_TIME + 6000);
|
||||||
let post_exp = Duration::from_secs(TEST_CURRENT_TIME + 6010);
|
let post_exp = Duration::from_secs(TEST_CURRENT_TIME + 6010);
|
||||||
let mut idms_prox_write = task::block_on(idms.proxy_write(ct));
|
let mut idms_prox_write = idms.proxy_write(ct).await;
|
||||||
|
|
||||||
let testaccount_uuid = Uuid::new_v4();
|
let testaccount_uuid = Uuid::new_v4();
|
||||||
|
|
||||||
let e1 = entry_init!(
|
let e1 = entry_init!(
|
||||||
("class", Value::new_class("object")),
|
("class", Value::new_class("object")),
|
||||||
("class", Value::new_class("account")),
|
("class", Value::new_class("account")),
|
||||||
("class", Value::new_class("service_account")),
|
("class", Value::new_class("service_account")),
|
||||||
("name", Value::new_iname("test_account_only")),
|
("name", Value::new_iname("test_account_only")),
|
||||||
("uuid", Value::new_uuid(testaccount_uuid)),
|
("uuid", Value::new_uuid(testaccount_uuid)),
|
||||||
("description", Value::new_utf8s("testaccount")),
|
("description", Value::new_utf8s("testaccount")),
|
||||||
("displayname", Value::new_utf8s("testaccount"))
|
("displayname", Value::new_utf8s("testaccount"))
|
||||||
);
|
);
|
||||||
|
|
||||||
let ce = CreateEvent::new_internal(vec![e1]);
|
let ce = CreateEvent::new_internal(vec![e1]);
|
||||||
let cr = idms_prox_write.qs_write.create(&ce);
|
let cr = idms_prox_write.qs_write.create(&ce);
|
||||||
assert!(cr.is_ok());
|
assert!(cr.is_ok());
|
||||||
|
|
||||||
let gte = GenerateApiTokenEvent::new_internal(testaccount_uuid, "TestToken", Some(exp));
|
let gte = GenerateApiTokenEvent::new_internal(testaccount_uuid, "TestToken", Some(exp));
|
||||||
|
|
||||||
let api_token = idms_prox_write
|
let api_token = idms_prox_write
|
||||||
.service_account_generate_api_token(>e, ct)
|
.service_account_generate_api_token(>e, ct)
|
||||||
.expect("failed to generate new api token");
|
.expect("failed to generate new api token");
|
||||||
|
|
||||||
trace!(?api_token);
|
trace!(?api_token);
|
||||||
|
|
||||||
// Deserialise it.
|
// Deserialise it.
|
||||||
let apitoken_unverified =
|
let apitoken_unverified =
|
||||||
JwsUnverified::from_str(&api_token).expect("Failed to parse apitoken");
|
JwsUnverified::from_str(&api_token).expect("Failed to parse apitoken");
|
||||||
let apitoken_inner: Jws<ApiToken> = apitoken_unverified
|
let apitoken_inner: Jws<ApiToken> = apitoken_unverified
|
||||||
.validate_embeded()
|
.validate_embeded()
|
||||||
.expect("Embedded jwk not found");
|
.expect("Embedded jwk not found");
|
||||||
let apitoken_inner = apitoken_inner.into_inner();
|
let apitoken_inner = apitoken_inner.into_inner();
|
||||||
|
|
||||||
let ident = idms_prox_write
|
let ident = idms_prox_write
|
||||||
.validate_and_parse_token_to_ident(Some(&api_token), ct)
|
.validate_and_parse_token_to_ident(Some(&api_token), ct)
|
||||||
.expect("Unable to verify api token.");
|
.expect("Unable to verify api token.");
|
||||||
|
|
||||||
assert!(ident.get_uuid() == Some(testaccount_uuid));
|
assert!(ident.get_uuid() == Some(testaccount_uuid));
|
||||||
|
|
||||||
// Woohoo! Okay lets test the other edge cases.
|
// Woohoo! Okay lets test the other edge cases.
|
||||||
|
|
||||||
// Check the expiry
|
// Check the expiry
|
||||||
assert!(
|
assert!(
|
||||||
idms_prox_write
|
idms_prox_write
|
||||||
.validate_and_parse_token_to_ident(Some(&api_token), post_exp)
|
.validate_and_parse_token_to_ident(Some(&api_token), post_exp)
|
||||||
.expect_err("Should not succeed")
|
.expect_err("Should not succeed")
|
||||||
== OperationError::SessionExpired
|
== OperationError::SessionExpired
|
||||||
);
|
);
|
||||||
|
|
||||||
// Delete session
|
// Delete session
|
||||||
let dte = DestroyApiTokenEvent::new_internal(
|
let dte =
|
||||||
apitoken_inner.account_id,
|
DestroyApiTokenEvent::new_internal(apitoken_inner.account_id, apitoken_inner.token_id);
|
||||||
apitoken_inner.token_id,
|
assert!(idms_prox_write
|
||||||
);
|
.service_account_destroy_api_token(&dte)
|
||||||
assert!(idms_prox_write
|
.is_ok());
|
||||||
.service_account_destroy_api_token(&dte)
|
|
||||||
.is_ok());
|
|
||||||
|
|
||||||
// Within gracewindow?
|
// Within gracewindow?
|
||||||
// This is okay, because we are within the gracewindow.
|
// This is okay, because we are within the gracewindow.
|
||||||
let ident = idms_prox_write
|
let ident = idms_prox_write
|
||||||
.validate_and_parse_token_to_ident(Some(&api_token), ct)
|
.validate_and_parse_token_to_ident(Some(&api_token), ct)
|
||||||
.expect("Unable to verify api token.");
|
.expect("Unable to verify api token.");
|
||||||
assert!(ident.get_uuid() == Some(testaccount_uuid));
|
assert!(ident.get_uuid() == Some(testaccount_uuid));
|
||||||
|
|
||||||
// Past gracewindow?
|
// Past gracewindow?
|
||||||
assert!(
|
assert!(
|
||||||
idms_prox_write
|
idms_prox_write
|
||||||
.validate_and_parse_token_to_ident(Some(&api_token), past_grc)
|
.validate_and_parse_token_to_ident(Some(&api_token), past_grc)
|
||||||
.expect_err("Should not succeed")
|
.expect_err("Should not succeed")
|
||||||
== OperationError::SessionExpired
|
== OperationError::SessionExpired
|
||||||
);
|
);
|
||||||
|
|
||||||
assert!(idms_prox_write.commit().is_ok());
|
assert!(idms_prox_write.commit().is_ok());
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,8 +52,7 @@ mod repl;
|
||||||
pub mod schema;
|
pub mod schema;
|
||||||
pub mod server;
|
pub mod server;
|
||||||
pub mod status;
|
pub mod status;
|
||||||
#[cfg(test)]
|
pub mod testkit;
|
||||||
mod testkit;
|
|
||||||
|
|
||||||
/// A prelude of imports that should be imported by all other Kanidm modules to
|
/// A prelude of imports that should be imported by all other Kanidm modules to
|
||||||
/// help make imports cleaner.
|
/// help make imports cleaner.
|
||||||
|
@ -79,6 +78,7 @@ pub mod prelude {
|
||||||
FilterInvalid, FC,
|
FilterInvalid, FC,
|
||||||
};
|
};
|
||||||
pub use crate::identity::{AccessScope, IdentType, Identity, IdentityId};
|
pub use crate::identity::{AccessScope, IdentType, Identity, IdentityId};
|
||||||
|
pub use crate::idm::server::{IdmServer, IdmServerDelayed};
|
||||||
pub use crate::modify::{m_pres, m_purge, m_remove, Modify, ModifyInvalid, ModifyList};
|
pub use crate::modify::{m_pres, m_purge, m_remove, Modify, ModifyInvalid, ModifyList};
|
||||||
pub use crate::server::{
|
pub use crate::server::{
|
||||||
QueryServer, QueryServerReadTransaction, QueryServerTransaction,
|
QueryServer, QueryServerReadTransaction, QueryServerTransaction,
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#[cfg(test)]
|
||||||
macro_rules! setup_test {
|
macro_rules! setup_test {
|
||||||
() => {{
|
() => {{
|
||||||
let _ = sketching::test_init();
|
let _ = sketching::test_init();
|
||||||
|
@ -71,6 +72,7 @@ macro_rules! entry_str_to_account {
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
macro_rules! run_idm_test_inner {
|
macro_rules! run_idm_test_inner {
|
||||||
($test_fn:expr) => {{
|
($test_fn:expr) => {{
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
|
@ -112,18 +114,6 @@ macro_rules! run_idm_test {
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_idm_test_no_logging<F>(mut test_fn: F)
|
|
||||||
where
|
|
||||||
F: FnMut(
|
|
||||||
&crate::server::QueryServer,
|
|
||||||
&crate::idm::server::IdmServer,
|
|
||||||
&crate::idm::server::IdmServerDelayed,
|
|
||||||
),
|
|
||||||
{
|
|
||||||
sketching::test_init();
|
|
||||||
run_idm_test_inner!(test_fn);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test helpers for all plugins.
|
// Test helpers for all plugins.
|
||||||
// #[macro_export]
|
// #[macro_export]
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -1603,6 +1603,7 @@ impl Schema {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(test))]
|
||||||
pub(crate) fn write_blocking(&self) -> SchemaWriteTransaction<'_> {
|
pub(crate) fn write_blocking(&self) -> SchemaWriteTransaction<'_> {
|
||||||
self.write()
|
self.write()
|
||||||
}
|
}
|
||||||
|
|
|
@ -820,7 +820,7 @@ impl<'a> QueryServerReadTransaction<'a> {
|
||||||
// Verify the data content of the server is as expected. This will probably
|
// Verify the data content of the server is as expected. This will probably
|
||||||
// call various functions for validation, including possibly plugin
|
// call various functions for validation, including possibly plugin
|
||||||
// verifications.
|
// verifications.
|
||||||
fn verify(&mut self) -> Vec<Result<(), ConsistencyError>> {
|
pub(crate) fn verify(&mut self) -> Vec<Result<(), ConsistencyError>> {
|
||||||
// If we fail after backend, we need to return NOW because we can't
|
// If we fail after backend, we need to return NOW because we can't
|
||||||
// assert any other faith in the DB states.
|
// assert any other faith in the DB states.
|
||||||
// * backend
|
// * backend
|
||||||
|
|
|
@ -19,3 +19,13 @@ pub async fn setup_test() -> QueryServer {
|
||||||
// Init is called via the proc macro
|
// Init is called via the proc macro
|
||||||
qs
|
qs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn setup_idm_test() -> (IdmServer, IdmServerDelayed) {
|
||||||
|
let qs = setup_test().await;
|
||||||
|
|
||||||
|
qs.initialise_helper(duration_from_epoch_now())
|
||||||
|
.await
|
||||||
|
.expect("init failed!");
|
||||||
|
|
||||||
|
IdmServer::new(qs, "https://idm.example.com").expect("Failed to setup idms")
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue