diff --git a/docker-compose.test.yml b/docker-compose.test.yml new file mode 100644 index 0000000..30d991f --- /dev/null +++ b/docker-compose.test.yml @@ -0,0 +1,13 @@ +version: '3' + +services: + sonic: + image: valeriansaliou/sonic:v1.3.0 + ports: + - 36999:1491 + volumes: + - sonic_data:/var/lib/sonic/store/ + - ./sonic.cfg:/etc/sonic.cfg + +volumes: + sonic_data: \ No newline at end of file diff --git a/sonic.cfg b/sonic.cfg new file mode 100644 index 0000000..3157d59 --- /dev/null +++ b/sonic.cfg @@ -0,0 +1,66 @@ +# Sonic +# Fast, lightweight and schema-less search backend +# Configuration file +# Example: https://github.com/valeriansaliou/sonic/blob/master/config.cfg + + +[server] + +log_level = "error" + + +[channel] + +inet = "0.0.0.0:1491" +tcp_timeout = 300 + +auth_password = "SecretPassword1234" + +[channel.search] + +query_limit_default = 10 +query_limit_maximum = 100 +query_alternates_try = 4 + +suggest_limit_default = 5 +suggest_limit_maximum = 20 + + +[store] + +[store.kv] + +path = "/var/lib/sonic/store/kv/" + +retain_word_objects = 1000 + +[store.kv.pool] + +inactive_after = 1800 + +[store.kv.database] + +flush_after = 900 + +compress = true +parallelism = 2 +max_files = 100 +max_compactions = 1 +max_flushes = 1 +write_buffer = 16384 +write_ahead_log = true + +[store.fst] + +path = "/var/lib/sonic/store/fst/" + +[store.fst.pool] + +inactive_after = 300 + +[store.fst.graph] + +consolidate_after = 180 + +max_size = 2048 +max_words = 250000 diff --git a/tests/common.rs b/tests/common.rs new file mode 100644 index 0000000..60313bf --- /dev/null +++ b/tests/common.rs @@ -0,0 +1,18 @@ +#![allow(dead_code)] + +pub use sonic_channel::*; + +pub const HOST: &str = "localhost:36999"; +pub const PASS: &str = "SecretPassword1234"; + +pub fn ingest_start() -> IngestChannel { + IngestChannel::start(HOST, PASS).expect("The Sonic server must be running") +} + +pub fn search_start() -> SearchChannel { + SearchChannel::start(HOST, PASS).expect("The Sonic server must be running") +} + +pub fn flush_collection(collection: &str) { + ingest_start().flushc(collection).unwrap(); +} diff --git a/tests/push_command.rs b/tests/push_command.rs new file mode 100644 index 0000000..06c35b5 --- /dev/null +++ b/tests/push_command.rs @@ -0,0 +1,17 @@ +mod common; +use common::*; + +const COLLECTION: &str = "Ingest"; +const BUCKET: &str = "Push"; + +#[test] +fn should_push_new_object_to_sonic() { + let ingest_channel = ingest_start(); + + match ingest_channel.push(COLLECTION, BUCKET, "1", "Sweet Teriyaki Beef Skewers") { + Ok(res) => assert!(res), + Err(_) => unreachable!(), + } + + flush_collection(COLLECTION); +} diff --git a/tests/query_command.rs b/tests/query_command.rs new file mode 100644 index 0000000..8aaf57c --- /dev/null +++ b/tests/query_command.rs @@ -0,0 +1,60 @@ +mod common; +use common::*; + +const COLLECTION: &str = "Search"; +const BUCKET: &str = "Query"; + +#[test] +fn should_find_object_by_full_text() { + let title = "Sweet Teriyaki Beef Skewers"; + + let ingest_channel = ingest_start(); + ingest_channel.push(COLLECTION, BUCKET, "1", title).unwrap(); + + let search_channel = search_start(); + match search_channel.query(COLLECTION, BUCKET, title) { + Ok(object_ids) => assert_eq!(object_ids, vec!["1"]), + Err(_) => unreachable!(), + } + + flush_collection(COLLECTION); +} + +#[test] +fn should_find_object_by_parts() { + let title = "Sweet Teriyaki Beef Skewers"; + + let ingest_channel = ingest_start(); + ingest_channel.push(COLLECTION, BUCKET, "1", title).unwrap(); + + let search_channel = search_start(); + + for word in title.split_whitespace() { + match search_channel.query(COLLECTION, BUCKET, word) { + Ok(object_ids) => assert_eq!(object_ids, vec!["1"]), + Err(_) => unreachable!(), + } + } + + flush_collection(COLLECTION); +} + +#[test] +fn should_find_many_objects() { + let ingest_channel = ingest_start(); + ingest_channel + .push(COLLECTION, BUCKET, "1", "Sweet Teriyaki Beef Skewers") + .unwrap(); + ingest_channel + .push(COLLECTION, BUCKET, "2", "Slow Cooker Beef Stew I") + .unwrap(); + ingest_channel + .push(COLLECTION, BUCKET, "3", "Christmas Prime Rib") + .unwrap(); + + let search_channel = search_start(); + match search_channel.query(COLLECTION, BUCKET, "Beef") { + Ok(object_ids) => assert_eq!(object_ids, vec!["2", "1"]), + Err(_) => unreachable!(), + } +}