use reqwest::ClientBuilder;
use serde::{Deserialize, Serialize};
use solrstice;
use solrstice::models::SolrResponse;
use solrstice::queries::collection::{create_collection, delete_collection};
use solrstice::queries::config::{delete_config, upload_config};
use solrstice::SolrBasicAuth;
use solrstice::SolrRequestBuilder;
use solrstice::SolrSingleServerHost;
use solrstice::{AsyncSolrCloudClient, Error};
use solrstice::{SolrServerContext, SolrServerContextBuilder};
use std::path::Path;
use std::string::ToString;
use std::time::Duration;
pub struct BaseTestsBuildup {
pub context: SolrServerContext,
pub config_path: String,
pub host: SolrSingleServerHost,
pub auth: Option<SolrBasicAuth>,
}
impl BaseTestsBuildup {
pub async fn new() -> Self {
dotenv::from_filename("../test_setup/.env").ok();
let username = std::env::var("SOLR_USERNAME").unwrap();
let password = std::env::var("SOLR_PASSWORD").unwrap();
let auth = match username.is_empty() {
true => None,
false => Some(SolrBasicAuth::new(
username.as_str(),
Some(password.as_str()),
)),
};
let host = SolrSingleServerHost::new(std::env::var("SOLR_HOST").unwrap().as_str());
let builder = SolrServerContextBuilder::new(host.clone());
let context = if let Some(auth) = auth.clone() {
builder.with_auth(auth).build()
} else {
builder.build()
};
wait_for_solr(&context, Duration::from_secs(30)).await;
BaseTestsBuildup {
context,
config_path: "../test_setup/test_collection".to_string(),
host,
auth,
}
}
}
pub struct ErrrorTestsSetup {
pub http_context: SolrServerContext,
pub https_context: SolrServerContext,
pub config_path: String,
pub http_host: SolrSingleServerHost,
pub https_host: SolrSingleServerHost,
pub auth: Option<SolrBasicAuth>,
}
impl ErrrorTestsSetup {
pub async fn new() -> Self {
dotenv::from_filename("../test_setup/.env").ok();
let username = std::env::var("SOLR_USERNAME").unwrap();
let password = std::env::var("SOLR_PASSWORD").unwrap();
let auth = match username.is_empty() {
true => None,
false => Some(SolrBasicAuth::new(
username.as_str(),
Some(password.as_str()),
)),
};
let http_host = SolrSingleServerHost::new(
std::env::var("ERROR_NGINX_HTTP_HOST")
.unwrap()
.as_str()
.to_string(),
);
let http_context = {
let builder = SolrServerContextBuilder::new(http_host.clone());
if let Some(auth) = auth.clone() {
builder.with_auth(auth).build()
} else {
builder.build()
}
};
wait_for_error_nginx(&http_host.host, Duration::from_secs(30)).await;
let https_host = SolrSingleServerHost::new(
std::env::var("ERROR_NGINX_HTTPS_HOST")
.unwrap()
.as_str()
.to_string(),
);
let https_context = {
let builder = SolrServerContextBuilder::new(https_host.clone()).with_client(
ClientBuilder::new()
.danger_accept_invalid_certs(true)
.build()
.unwrap(),
);
if let Some(auth) = auth.clone() {
builder.with_auth(auth).build()
} else {
builder.build()
}
};
ErrrorTestsSetup {
http_context,
https_context,
config_path: "../test_setup/test_collection".to_string(),
http_host,
https_host,
auth,
}
}
}
pub struct FunctionalityTestsBuildup {
pub context: SolrServerContext,
pub async_client: AsyncSolrCloudClient,
pub config_path: String,
pub basename: String,
pub config_name: String,
pub collection_name: String,
}
impl FunctionalityTestsBuildup {
pub async fn build_up(basename: &str) -> Result<Self, Error> {
dotenv::from_filename("../test_setup/.env").ok();
let host = std::env::var("SOLR_HOST").unwrap();
let config_path = "../test_setup/test_collection".to_string();
let username = std::env::var("SOLR_USERNAME").unwrap();
let password = std::env::var("SOLR_PASSWORD").unwrap();
let auth = match username.is_empty() {
true => {
return Err(Error::Unknown(
"Could not find solr username in tests .env file".to_string(),
))
}
false => SolrBasicAuth::new(username.as_str(), Some(password.as_str())),
};
let config_name = basename.to_owned() + "Config";
let collection_name = basename.to_owned() + "Collection";
let solr_request = SolrServerContextBuilder::new(SolrSingleServerHost::new(host.as_str()))
.with_auth(auth)
.build();
wait_for_solr(&solr_request, Duration::from_secs(30)).await;
let _ = delete_collection(&solr_request, &collection_name).await;
let _ = delete_config(&solr_request, &config_name).await;
upload_config(&solr_request, &config_name, Path::new(&config_path))
.await
.unwrap();
create_collection(&solr_request, &collection_name, &config_name, 1, 1)
.await
.unwrap();
Ok(Self {
context: solr_request.clone(),
async_client: AsyncSolrCloudClient::new(solr_request),
basename: basename.to_string(),
config_path,
collection_name,
config_name,
})
}
pub async fn tear_down(&self) -> Result<(), Error> {
delete_collection(&self.context, &self.collection_name)
.await
.unwrap();
delete_config(&self.context, &self.config_name)
.await
.unwrap();
Ok(())
}
}
#[derive(Deserialize, Serialize, Eq, PartialEq, Debug)]
pub struct City {
pub id: String,
pub city_name: String,
pub population: Vec<Population>,
}
#[derive(Deserialize, Serialize, Eq, PartialEq, Debug)]
pub struct Population {
pub id: String,
pub age: usize,
pub count: usize,
pub interests: Vec<String>,
}
pub fn get_test_data() -> Vec<City> {
let data: Vec<City> =
serde_json::from_reader(std::fs::File::open("../test_setup/test_data.json").unwrap())
.unwrap();
data
}
pub async fn wait_for_solr(context: &SolrServerContext, max_time: Duration) {
let end: std::time::Instant = std::time::Instant::now() + max_time;
while std::time::Instant::now() < end {
let response = SolrRequestBuilder::new(context, "/solr/admin/collections")
.with_query_params(&[("action", "CLUSTERSTATUS")])
.send_get::<SolrResponse>()
.await;
if response.is_ok() {
return;
}
tokio::time::sleep(Duration::from_secs(1)).await;
}
panic!("Solr did not respond within {:?} seconds", max_time);
}
pub async fn wait_for_error_nginx(host: &str, max_time: Duration) {
let end = std::time::Instant::now() + max_time;
while std::time::Instant::now() < end {
let response = reqwest::get(format!("{}/status", host)).await.unwrap();
if response.status().is_success() {
return;
}
tokio::time::sleep(Duration::from_secs(1)).await;
}
}