Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tests: confirm that stopped projects delete successfully #1435

Merged
merged 2 commits into from Nov 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 15 additions & 0 deletions gateway/src/api/latest.rs
Expand Up @@ -1393,6 +1393,21 @@ pub mod tests {
);
}

#[test_context(TestProject)]
#[tokio::test]
async fn api_delete_project_that_is_stopped(project: &mut TestProject) {
// Run two health checks to get the project to go into idle mode
project.run_health_check().await;
project.run_health_check().await;

project.wait_for_state(project::State::Stopped).await;

assert_eq!(
project.router_call(Method::DELETE, "/delete").await,
StatusCode::OK
);
}

#[test_context(TestProject)]
#[tokio::test]
async fn api_delete_project_that_is_destroyed(project: &mut TestProject) {
Expand Down
44 changes: 34 additions & 10 deletions gateway/src/lib.rs
Expand Up @@ -286,7 +286,7 @@ pub mod tests {
use sqlx::sqlite::SqliteConnectOptions;
use sqlx::{query, SqlitePool};
use test_context::AsyncTestContext;
use tokio::sync::mpsc::channel;
use tokio::sync::mpsc::{channel, Sender};
use tokio::time::sleep;
use tower::Service;

Expand All @@ -296,6 +296,7 @@ pub mod tests {
use crate::project::Project;
use crate::proxy::UserServiceBuilder;
use crate::service::{ContainerSettings, GatewayService, MIGRATIONS};
use crate::task::BoxedTask;
use crate::worker::Worker;
use crate::DockerContext;

Expand Down Expand Up @@ -649,8 +650,8 @@ pub mod tests {
}
}

/// Create a router to make API calls against. Also starts up a worker to create actual Docker containers for all requests
pub async fn router(&self) -> Router {
/// Create a service and sender to handle tasks. Also starts up a worker to create actual Docker containers for all requests
pub async fn service(&self) -> (Arc<GatewayService>, Sender<BoxedTask>) {
let service = Arc::new(GatewayService::init(self.args(), self.pool(), "".into()).await);
let worker = Worker::new();

Expand All @@ -676,6 +677,11 @@ pub mod tests {
// Allow the spawns to start
tokio::time::sleep(Duration::from_secs(1)).await;

(service, sender)
}

/// Create a router to make API calls against
pub fn router(&self, service: Arc<GatewayService>, sender: Sender<BoxedTask>) -> Router {
ApiBuilder::new()
.with_service(Arc::clone(&service))
.with_sender(sender)
Expand Down Expand Up @@ -767,7 +773,9 @@ pub mod tests {
router: Router,
authorization: Authorization<Bearer>,
project_name: String,
world: World,
pool: SqlitePool,
service: Arc<GatewayService>,
sender: Sender<BoxedTask>,
}

impl TestProject {
Expand Down Expand Up @@ -985,28 +993,42 @@ pub mod tests {
/// Puts the project in a new state
pub async fn update_state(&self, state: Project) {
let TestProject {
project_name,
world,
..
project_name, pool, ..
} = self;

let state = sqlx::types::Json(state);

query("UPDATE projects SET project_state = ?1 WHERE project_name = ?2")
.bind(&state)
.bind(project_name)
.execute(&world.pool)
.execute(pool)
.await
.expect("test to update project state");
}

/// Run one iteration of health checks for this project
pub async fn run_health_check(&self) {
let handle = self
.service
.new_task()
.project(self.project_name.parse().unwrap())
.send(&self.sender)
.await
.expect("to send one ambulance task");

// We wait for the check to be done before moving on
handle.await
}
}

#[async_trait]
impl AsyncTestContext for TestProject {
async fn setup() -> Self {
let world = World::new().await;

let mut router = world.router().await;
let (service, sender) = world.service().await;

let mut router = world.router(service.clone(), sender.clone());
let authorization = world.create_authorization_bearer("neo");
let project_name = "matrix";

Expand All @@ -1030,7 +1052,9 @@ pub mod tests {
authorization,
project_name: project_name.to_string(),
router,
world,
pool: world.pool(),
service,
sender,
};

this.wait_for_state(project::State::Ready).await;
Expand Down