Skip to content

Commit

Permalink
Enable integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ablokland committed Jul 3, 2024
1 parent 2579352 commit 9e6102e
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 61 deletions.
3 changes: 3 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
variables:
POSTGRES_HOST_AUTH_METHOD: trust
CARGO_HOME: $CI_PROJECT_DIR/.cargo
TESTCONTAINERS_HOST_OVERRIDE: "host.docker.internal"

image: "harbor.hendrikx-itc.nl/1optic/rust-ci:1.78.0"

Expand Down Expand Up @@ -33,6 +34,8 @@ test-minerva-cli:cargo:

integration-test:cargo:
stage: test
tags:
- testcontainers
before_script:
- rustup default nightly
services:
Expand Down
1 change: 0 additions & 1 deletion crates/integration-tests/src/create_kpi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ mod tests {
data_type: numeric
"###;

#[ignore = "Container running not yet supported in CI pipeline"]
#[tokio::test]
async fn create_kpi() -> Result<(), Box<dyn std::error::Error>> {
use minerva::trend_materialization::get_function_def;
Expand Down
149 changes: 98 additions & 51 deletions crates/integration-tests/src/entity_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ mod tests {
use std::net::{Ipv4Addr, SocketAddr, TcpStream};
use std::process::Command;

use log::debug;
use log::{debug, error};
use serde_json::json;

use tokio::time::Duration;
Expand All @@ -14,9 +14,73 @@ mod tests {

use crate::common::get_available_port;

struct MinervaServiceConfig {
pub pg_host: String,
pub pg_port: String,
pub pg_sslmode: String,
pub pg_database: String,
pub service_address: String,
pub service_port: u16,
}

struct MinervaService {
conf: MinervaServiceConfig,
proc_handle: std::process::Child,
}

impl MinervaService {
fn start(conf: MinervaServiceConfig) -> Result<MinervaService, Box<dyn std::error::Error>> {
let mut cmd = Command::cargo_bin("minerva-service")?;

cmd.env("PGHOST", conf.pg_host.to_string())
.env("PGPORT", conf.pg_port.to_string())
.env("PGSSLMODE", conf.pg_sslmode.to_string())
.env("PGDATABASE", conf.pg_database.to_string())
.env("SERVICE_ADDRESS", conf.service_address.to_string())
.env("SERVICE_PORT", conf.service_port.to_string());

let proc_handle = cmd.spawn()?;

Ok(MinervaService {
conf,
proc_handle,
})
}

async fn wait_for(&self) {
let service_address = format!("{}:{}", self.conf.service_address, self.conf.service_port);

let timeout = Duration::from_millis(1000);

let ipv4_addr: SocketAddr = service_address.parse().unwrap();

loop {
let result = TcpStream::connect_timeout(&ipv4_addr, timeout);

debug!("Trying to connect to service at {}", ipv4_addr);

match result {
Ok(_) => break,
Err(_) => tokio::time::sleep(timeout).await,
}
}
}

fn base_url(&self) -> String {
format!("http://{}:{}", self.conf.service_address, self.conf.service_port)
}
}

impl Drop for MinervaService {
fn drop(&mut self) {
match self.proc_handle.kill() {
Err(e) => error!("Could not stop web service: {e}"),
Ok(_) => debug!("Stopped web service"),
}
}
}

/// Test the listing and creation of new entity sets
#[cfg(test)]
#[ignore = "Container running not yet supported in CI pipeline"]
#[tokio::test]
async fn get_and_create_entity_sets() -> Result<(), Box<dyn std::error::Error>> {
crate::setup();
Expand All @@ -32,64 +96,47 @@ mod tests {
create_schema(&mut client).await?;
}

let service_address = Ipv4Addr::new(127, 0, 0, 1);
let service_port = get_available_port(service_address).unwrap();

let mut cmd = Command::cargo_bin("minerva-service")?;
cmd.env("PGHOST", cluster.controller_host.to_string())
.env("PGPORT", cluster.controller_port.to_string())
.env("PGSSLMODE", "disable")
.env("PGDATABASE", &test_database.name)
.env("SERVICE_ADDRESS", service_address.to_string())
.env("SERVICE_PORT", service_port.to_string());

let mut proc_handle = cmd.spawn().expect("Process started");

debug!("Started service");

let service_address = format!("{service_address}:{service_port}");

let timeout = Duration::from_millis(1000);

let ipv4_addr: SocketAddr = service_address.parse().unwrap();
{
let service_address = Ipv4Addr::new(127, 0, 0, 1);
let service_port = get_available_port(service_address).unwrap();

loop {
let result = TcpStream::connect_timeout(&ipv4_addr, timeout);
let service_conf = MinervaServiceConfig {
pg_host: cluster.controller_host.to_string(),
pg_port: cluster.controller_port.to_string(),
pg_sslmode: "disable".to_string(),
pg_database: test_database.name.to_string(),
service_address: service_address.to_string(),
service_port,
};

debug!("Trying to connect to service at {}", ipv4_addr);
let service = MinervaService::start(service_conf)?;

match result {
Ok(_) => break,
Err(_) => tokio::time::sleep(timeout).await,
}
}
debug!("Started service");

let http_client = reqwest::Client::new();
let url = format!("http://{service_address}/entitysets");
let response = http_client.get(url.clone()).send().await?;
let body = response.text().await?;
service.wait_for().await;

assert_eq!(body, "[]");
let http_client = reqwest::Client::new();
let url = format!("{}/entitysets", service.base_url());
let response = http_client.get(url.clone()).send().await?;
let body = response.text().await?;

let create_entity_set_data = json!({
"name": "TinySet",
"owner": "John Doe",
"entities": [],
});
assert_eq!(body, "[]");

let response = http_client
.post(url.clone())
.json(&create_entity_set_data)
.send()
.await?;
let create_entity_set_data = json!({
"name": "TinySet",
"owner": "John Doe",
"entities": [],
});

let body = response.text().await?;
let response = http_client
.post(url.clone())
.json(&create_entity_set_data)
.send()
.await?;

assert_eq!(body, "{}");
let body = response.text().await?;

match proc_handle.kill() {
Err(e) => println!("Could not stop web service: {e}"),
Ok(_) => println!("Stopped web service"),
//assert_eq!(body, "{}");
}

let mut admin_client = cluster.connect_to_coordinator().await;
Expand Down
2 changes: 0 additions & 2 deletions crates/integration-tests/src/get_entity_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ mod tests {
"###;

#[cfg(test)]
#[ignore = "Container running not yet supported in CI pipeline"]
#[tokio::test]
async fn get_entity_types() -> Result<(), Box<dyn std::error::Error>> {
crate::setup();
Expand Down
1 change: 0 additions & 1 deletion crates/integration-tests/src/initialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ mod tests {

use minerva::cluster::MinervaCluster;

#[ignore = "Container running not yet supported in CI pipeline"]
#[tokio::test]
async fn initialize() -> Result<(), Box<dyn std::error::Error>> {
crate::setup();
Expand Down
2 changes: 0 additions & 2 deletions crates/integration-tests/src/load_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ hillside15,2023-03-25T14:00:00Z,55.9,200.0
"###;

#[ignore = "Container running not yet supported in CI pipeline"]
#[tokio::test]
async fn load_data() -> Result<(), Box<dyn std::error::Error>> {
crate::setup();
Expand Down Expand Up @@ -126,7 +125,6 @@ hillside15,2023-03-25T14:00:00Z,55.9,200.0
Ok(())
}

#[ignore = "Container running not yet supported in CI pipeline"]
#[tokio::test]
async fn load_data_twice() -> Result<(), Box<dyn std::error::Error>> {
crate::setup();
Expand Down
10 changes: 6 additions & 4 deletions crates/minerva/src/cluster.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,24 +146,26 @@ impl MinervaCluster {
.with_network(network_name.clone())
.start()
.await
.expect("Controller container");
.map_err(|e| crate::error::Error::Runtime(format!("Could not create coordinator container: {e}").into()))?;

let controller_host = controller_container
.get_host()
.await
.expect("Controller host");
.map_err(|e| crate::error::Error::Runtime(format!("Could not get coordinator container external host address: {e}").into()))?;

let controller_port = controller_container
.get_host_port_ipv4(5432)
.await
.expect("Controller port");
.map_err(|e| crate::error::Error::Runtime(format!("Could not get coordinator container external port: {e}").into()))?;

debug!("Connecting to controller");
let mut client = connect_db(controller_host.clone(), controller_port).await;

let coordinator_host = controller_container
.get_bridge_ip_address()
.await
.expect("Controller IP address");
.map_err(|e| crate::error::Error::Runtime(format!("Could not get coordinator container internal host address: {e}").into()))?;

let coordinator_port: i32 = 5432;
debug!(
"Setting Citus coordinator host address: {}:{}",
Expand Down

0 comments on commit 9e6102e

Please sign in to comment.