Fixed tests
This commit is contained in:
@@ -35,7 +35,7 @@ pub mod set;
|
||||
|
||||
pub const INBOX_ID: u32 = 0;
|
||||
pub const TRASH_ID: u32 = 1;
|
||||
pub const JUNK_ID: u32 = 1;
|
||||
pub const JUNK_ID: u32 = 2;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct UidMailbox {
|
||||
|
||||
@@ -32,7 +32,7 @@ jemallocator = "0.5.0"
|
||||
|
||||
[features]
|
||||
#default = ["sqlite", "foundationdb", "postgres", "mysql", "rocks", "elastic", "s3", "redis"]
|
||||
default = ["rocks"]
|
||||
default = ["sqlite", "foundationdb", "postgres", "mysql", "rocks", "elastic", "s3", "redis"]
|
||||
sqlite = ["store/sqlite"]
|
||||
foundationdb = ["store/foundation"]
|
||||
postgres = ["store/postgres"]
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
use rusqlite::{params, OptionalExtension, TransactionBehavior};
|
||||
|
||||
use crate::{
|
||||
write::{Batch, Operation, ValueOp},
|
||||
write::{Batch, BitmapClass, Operation, ValueClass, ValueOp},
|
||||
BitmapKey, IndexKey, Key, LogKey, ValueKey,
|
||||
};
|
||||
|
||||
@@ -95,6 +95,26 @@ impl SqliteStore {
|
||||
table
|
||||
))?
|
||||
.execute([&key, value])?;
|
||||
|
||||
if matches!(class, ValueClass::ReservedId) {
|
||||
// Make sure the reserved id is not already in use
|
||||
let key = BitmapKey {
|
||||
account_id,
|
||||
collection,
|
||||
class: BitmapClass::DocumentIds,
|
||||
block_num: document_id,
|
||||
}
|
||||
.serialize(0);
|
||||
if trx
|
||||
.prepare_cached("SELECT 1 FROM b WHERE k = ?")?
|
||||
.query_row([&key], |_| Ok(true))
|
||||
.optional()?
|
||||
.unwrap_or(false)
|
||||
{
|
||||
trx.rollback()?;
|
||||
return Err(crate::Error::AssertValueFailed);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
trx.prepare_cached(&format!("DELETE FROM {} WHERE k = ?", table))?
|
||||
.execute([&key])?;
|
||||
@@ -171,6 +191,7 @@ impl SqliteStore {
|
||||
.optional()?
|
||||
.unwrap_or_else(|| assert_value.is_none());
|
||||
if !matches {
|
||||
trx.rollback()?;
|
||||
return Err(crate::Error::AssertValueFailed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ resolver = "2"
|
||||
|
||||
[features]
|
||||
#default = ["sqlite", "foundationdb", "postgres", "mysql", "rocks", "elastic", "s3", "redis"]
|
||||
default = ["rocks"]
|
||||
default = ["sqlite", "foundationdb", "postgres", "mysql", "rocks", "elastic", "s3", "redis"]
|
||||
sqlite = ["store/sqlite"]
|
||||
foundationdb = ["store/foundation"]
|
||||
postgres = ["store/postgres"]
|
||||
|
||||
@@ -43,6 +43,22 @@ use tokio_rustls::TlsAcceptor;
|
||||
use crate::store::TempDir;
|
||||
|
||||
const CONFIG: &str = r#"
|
||||
[directory."rocksdb"]
|
||||
type = "internal"
|
||||
store = "rocksdb"
|
||||
|
||||
[directory."rocksdb".options]
|
||||
catch-all = true
|
||||
subaddressing = true
|
||||
|
||||
[directory."foundationdb"]
|
||||
type = "internal"
|
||||
store = "foundationdb"
|
||||
|
||||
[directory."foundationdb".options]
|
||||
catch-all = true
|
||||
subaddressing = true
|
||||
|
||||
[directory."sqlite"]
|
||||
type = "sql"
|
||||
store = "sqlite"
|
||||
@@ -288,7 +304,9 @@ impl DirectoryTest {
|
||||
let mut config_file = CONFIG.replace("{TMP}", &temp_dir.path.to_string_lossy());
|
||||
if id_store.is_some() {
|
||||
// Disable foundationdb store for SQL tests (the fdb select api version can only be run once per process)
|
||||
config_file = config_file.replace("foundationdb", "ignore");
|
||||
config_file = config_file
|
||||
.replace("type = \"foundationdb\"", "type = \"ignore\"")
|
||||
.replace("store = \"foundationdb\"", "disable = true");
|
||||
}
|
||||
let config = utils::config::Config::new(&config_file).unwrap();
|
||||
let stores = config.parse_stores().await.unwrap();
|
||||
|
||||
@@ -325,7 +325,7 @@ impl DirectoryStore {
|
||||
),
|
||||
"INSERT INTO accounts (name, secret, type) VALUES ('admin', 'secret', 'admin')",
|
||||
] {
|
||||
let query = if matches!(self.store, LookupStore::Store(Store::MySQL(_))) {
|
||||
let query = if self.is_mysql() {
|
||||
query.replace("TEXT", "VARCHAR(255)")
|
||||
} else {
|
||||
query.to_string()
|
||||
@@ -346,12 +346,12 @@ impl DirectoryStore {
|
||||
};
|
||||
self.store
|
||||
.query::<usize>(
|
||||
if matches!(self.store, LookupStore::Store(Store::PostgreSQL(_))) {
|
||||
if self.is_postgresql() {
|
||||
concat!(
|
||||
"INSERT INTO accounts (name, secret, description, ",
|
||||
"type, active) VALUES ($1, $2, $3, $4, true) ON CONFLICT (name) DO NOTHING"
|
||||
)
|
||||
} else if matches!(self.store, LookupStore::Store(Store::MySQL(_))) {
|
||||
} else if self.is_mysql() {
|
||||
concat!(
|
||||
"INSERT IGNORE INTO accounts (name, secret, description, ",
|
||||
"type, active) VALUES (?, ?, ?, ?, true)"
|
||||
@@ -381,12 +381,12 @@ impl DirectoryStore {
|
||||
pub async fn create_test_group(&self, login: &str, name: &str) {
|
||||
self.store
|
||||
.query::<usize>(
|
||||
if matches!(self.store, LookupStore::Store(Store::PostgreSQL(_))) {
|
||||
if self.is_postgresql() {
|
||||
concat!(
|
||||
"INSERT INTO accounts (name, description, ",
|
||||
"type, active) VALUES ($1, $2, $3, $4) ON CONFLICT (name) DO NOTHING"
|
||||
)
|
||||
} else if matches!(self.store, LookupStore::Store(Store::MySQL(_))) {
|
||||
} else if self.is_mysql() {
|
||||
concat!(
|
||||
"INSERT IGNORE INTO accounts (name, description, ",
|
||||
"type, active) VALUES (?, ?, ?, ?)"
|
||||
@@ -411,9 +411,9 @@ impl DirectoryStore {
|
||||
pub async fn link_test_address(&self, login: &str, address: &str, typ: &str) {
|
||||
self.store
|
||||
.query::<usize>(
|
||||
if matches!(self.store, LookupStore::Store(Store::PostgreSQL(_))) {
|
||||
if self.is_postgresql() {
|
||||
"INSERT INTO emails (name, address, type) VALUES ($1, $2, $3) ON CONFLICT (name, address) DO NOTHING"
|
||||
} else if matches!(self.store, LookupStore::Store(Store::MySQL(_))) {
|
||||
} else if self.is_mysql() {
|
||||
"INSERT IGNORE INTO emails (name, address, type) VALUES (?, ?, ?)"
|
||||
} else {
|
||||
"INSERT OR IGNORE INTO emails (name, address, type) VALUES (?, ?, ?)"
|
||||
@@ -427,7 +427,7 @@ impl DirectoryStore {
|
||||
pub async fn set_test_quota(&self, login: &str, quota: u32) {
|
||||
self.store
|
||||
.query::<usize>(
|
||||
if matches!(self.store, LookupStore::Store(Store::PostgreSQL(_))) {
|
||||
if self.is_postgresql() {
|
||||
"UPDATE accounts SET quota = $1 where name = $2"
|
||||
} else {
|
||||
"UPDATE accounts SET quota = ? where name = ?"
|
||||
@@ -441,7 +441,7 @@ impl DirectoryStore {
|
||||
pub async fn add_to_group(&self, login: &str, group: &str) {
|
||||
self.store
|
||||
.query::<usize>(
|
||||
if matches!(self.store, LookupStore::Store(Store::PostgreSQL(_))) {
|
||||
if self.is_postgresql() {
|
||||
"INSERT INTO group_members (name, member_of) VALUES ($1, $2)"
|
||||
} else {
|
||||
"INSERT INTO group_members (name, member_of) VALUES (?, ?)"
|
||||
@@ -455,7 +455,7 @@ impl DirectoryStore {
|
||||
pub async fn remove_from_group(&self, login: &str, group: &str) {
|
||||
self.store
|
||||
.query::<usize>(
|
||||
if matches!(self.store, LookupStore::Store(Store::PostgreSQL(_))) {
|
||||
if self.is_postgresql() {
|
||||
"DELETE FROM group_members WHERE name = $1 AND member_of = $2"
|
||||
} else {
|
||||
"DELETE FROM group_members WHERE name = ? AND member_of = ?"
|
||||
@@ -469,7 +469,7 @@ impl DirectoryStore {
|
||||
pub async fn remove_test_alias(&self, login: &str, alias: &str) {
|
||||
self.store
|
||||
.query::<usize>(
|
||||
if matches!(self.store, LookupStore::Store(Store::PostgreSQL(_))) {
|
||||
if self.is_postgresql() {
|
||||
"DELETE FROM emails WHERE name = $1 AND address = $2"
|
||||
} else {
|
||||
"DELETE FROM emails WHERE name = ? AND address = ?"
|
||||
@@ -479,4 +479,38 @@ impl DirectoryStore {
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn is_mysql(&self) -> bool {
|
||||
#[cfg(feature = "mysql")]
|
||||
{
|
||||
matches!(self.store, LookupStore::Store(Store::MySQL(_)))
|
||||
}
|
||||
#[cfg(not(feature = "mysql"))]
|
||||
{
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn is_postgresql(&self) -> bool {
|
||||
#[cfg(feature = "postgres")]
|
||||
{
|
||||
matches!(self.store, LookupStore::Store(Store::PostgreSQL(_)))
|
||||
}
|
||||
#[cfg(not(feature = "postgres"))]
|
||||
{
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn is_sqlite(&self) -> bool {
|
||||
#[cfg(feature = "sqlite")]
|
||||
{
|
||||
matches!(self.store, LookupStore::Store(Store::SQLite(_)))
|
||||
}
|
||||
#[cfg(not(feature = "sqlite"))]
|
||||
{
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,6 +164,7 @@ url = "https://localhost:9200"
|
||||
user = "elastic"
|
||||
password = "RtQ-Lu6+o4rxx=XJplVJ"
|
||||
allow-invalid-certs = true
|
||||
disable = true # Elastic is disabled by default
|
||||
|
||||
[certificate.default]
|
||||
cert = "file://{CERT}"
|
||||
@@ -286,10 +287,8 @@ pub async fn jmap_tests() {
|
||||
delete,
|
||||
)
|
||||
.await;
|
||||
//assert_is_empty(params.server.clone()).await;
|
||||
|
||||
let coco = 1;
|
||||
/*email_query::test(&mut params, delete).await;
|
||||
email_query::test(&mut params, delete).await;
|
||||
email_get::test(&mut params).await;
|
||||
email_set::test(&mut params).await;
|
||||
email_parse::test(&mut params).await;
|
||||
@@ -300,7 +299,7 @@ pub async fn jmap_tests() {
|
||||
thread_get::test(&mut params).await;
|
||||
thread_merge::test(&mut params).await;
|
||||
mailbox::test(&mut params).await;
|
||||
delivery::test(&mut params).await;*/
|
||||
delivery::test(&mut params).await;
|
||||
auth_acl::test(&mut params).await;
|
||||
auth_limits::test(&mut params).await;
|
||||
auth_oauth::test(&mut params).await;
|
||||
|
||||
@@ -38,9 +38,9 @@ pub async fn blob_tests() {
|
||||
Config::new(&CONFIG.replace("{TMP}", temp_dir.path.as_path().to_str().unwrap())).unwrap();
|
||||
let stores = config.parse_stores().await.unwrap();
|
||||
|
||||
for (store_id, blob_store) in stores.blob_stores {
|
||||
for (store_id, blob_store) in &stores.blob_stores {
|
||||
println!("Testing blob store {}...", store_id);
|
||||
test_store(blob_store).await;
|
||||
test_store(blob_store.clone()).await;
|
||||
}
|
||||
|
||||
for (store_id, store) in stores.stores {
|
||||
|
||||
@@ -39,15 +39,25 @@ pub async fn lookup_tests() {
|
||||
store.destroy().await;
|
||||
}
|
||||
|
||||
// Test value expiry
|
||||
// Test key
|
||||
let key = "xyz".as_bytes().to_vec();
|
||||
assert_eq!(
|
||||
LookupValue::None,
|
||||
store
|
||||
.key_get::<String>(LookupKey::Key(key.clone()))
|
||||
.await
|
||||
.unwrap()
|
||||
);
|
||||
store
|
||||
.key_set(
|
||||
key.clone(),
|
||||
LookupValue::Value {
|
||||
value: "world".to_string().into_bytes(),
|
||||
expires: 0,
|
||||
},
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
store.purge_expired().await.unwrap();
|
||||
assert!(matches!(store
|
||||
.key_get::<String>(LookupKey::Key(key.clone()))
|
||||
.await
|
||||
.unwrap(), LookupValue::Value { value,.. } if value == "world"));
|
||||
|
||||
// Test value expiry
|
||||
store
|
||||
.key_set(
|
||||
key.clone(),
|
||||
@@ -76,23 +86,6 @@ pub async fn lookup_tests() {
|
||||
store.assert_is_empty(store.clone().into()).await;
|
||||
}
|
||||
|
||||
// Test key
|
||||
store
|
||||
.key_set(
|
||||
key.clone(),
|
||||
LookupValue::Value {
|
||||
value: "world".to_string().into_bytes(),
|
||||
expires: 0,
|
||||
},
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
store.purge_expired().await.unwrap();
|
||||
assert!(matches!(store
|
||||
.key_get::<String>(LookupKey::Key(key.clone()))
|
||||
.await
|
||||
.unwrap(), LookupValue::Value { value,.. } if value == "world"));
|
||||
|
||||
// Test counter
|
||||
let key = "abc".as_bytes().to_vec();
|
||||
store
|
||||
|
||||
Reference in New Issue
Block a user