-
Notifications
You must be signed in to change notification settings - Fork 260
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feature: eng 483 trim and fix the tests in shuttle-service (#693)
* tests: update build_crate tests * tests: remove loader tests * feat: cleanup service deps * feat: setup integration tests in runtime * feat: expected panic message for not_shuttle * refactor: simplify dummy provisioner * feat: re-export main and service from runtime
- Loading branch information
Showing
39 changed files
with
261 additions
and
638 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
use std::{ | ||
collections::HashMap, | ||
net::{Ipv4Addr, SocketAddr}, | ||
path::{Path, PathBuf}, | ||
}; | ||
|
||
use anyhow::Result; | ||
use async_trait::async_trait; | ||
use shuttle_proto::{ | ||
provisioner::{ | ||
provisioner_server::{Provisioner, ProvisionerServer}, | ||
DatabaseRequest, DatabaseResponse, | ||
}, | ||
runtime::{self, runtime_client::RuntimeClient}, | ||
}; | ||
use shuttle_service::builder::{build_crate, Runtime}; | ||
use tonic::{ | ||
transport::{Channel, Server}, | ||
Request, Response, Status, | ||
}; | ||
|
||
pub struct TestRuntime { | ||
pub runtime_client: RuntimeClient<Channel>, | ||
pub bin_path: String, | ||
pub service_name: String, | ||
pub runtime_address: SocketAddr, | ||
pub secrets: HashMap<String, String>, | ||
} | ||
|
||
pub async fn spawn_runtime(project_path: String, service_name: &str) -> Result<TestRuntime> { | ||
let provisioner_address = SocketAddr::new( | ||
Ipv4Addr::LOCALHOST.into(), | ||
portpicker::pick_unused_port().unwrap(), | ||
); | ||
let runtime_port = portpicker::pick_unused_port().unwrap(); | ||
let runtime_address = SocketAddr::new(Ipv4Addr::LOCALHOST.into(), runtime_port); | ||
|
||
let (tx, _) = crossbeam_channel::unbounded(); | ||
let runtime = build_crate(Path::new(&project_path), false, tx).await?; | ||
|
||
let secrets: HashMap<String, String> = Default::default(); | ||
|
||
let (is_wasm, bin_path) = match runtime { | ||
Runtime::Next(path) => (true, path), | ||
Runtime::Legacy(path) => (false, path), | ||
}; | ||
|
||
start_provisioner(DummyProvisioner, provisioner_address); | ||
|
||
// TODO: update this to work with shuttle-next projects, see cargo-shuttle local run | ||
let runtime_path = || bin_path.clone(); | ||
|
||
let (_, runtime_client) = runtime::start( | ||
is_wasm, | ||
runtime::StorageManagerType::WorkingDir(PathBuf::from(project_path.clone())), | ||
&format!("http://{}", provisioner_address), | ||
runtime_port, | ||
runtime_path, | ||
) | ||
.await?; | ||
|
||
Ok(TestRuntime { | ||
runtime_client, | ||
bin_path: bin_path | ||
.into_os_string() | ||
.into_string() | ||
.expect("to convert path to string"), | ||
service_name: service_name.to_string(), | ||
runtime_address, | ||
secrets, | ||
}) | ||
} | ||
|
||
/// A dummy provisioner for tests, a provisioner connection is required | ||
/// to start a project runtime. | ||
pub struct DummyProvisioner; | ||
|
||
fn start_provisioner(provisioner: DummyProvisioner, address: SocketAddr) { | ||
tokio::spawn(async move { | ||
Server::builder() | ||
.add_service(ProvisionerServer::new(provisioner)) | ||
.serve(address) | ||
.await | ||
}); | ||
} | ||
|
||
#[async_trait] | ||
impl Provisioner for DummyProvisioner { | ||
async fn provision_database( | ||
&self, | ||
_request: Request<DatabaseRequest>, | ||
) -> Result<Response<DatabaseResponse>, Status> { | ||
panic!("did not expect any runtime test to use dbs") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
use std::time::Duration; | ||
|
||
use shuttle_proto::runtime::{LoadRequest, StartRequest}; | ||
use uuid::Uuid; | ||
|
||
use crate::helpers::{spawn_runtime, TestRuntime}; | ||
|
||
/// This test does panic, but the panic happens in a spawned task inside the project runtime, | ||
/// so we get this output: `thread 'tokio-runtime-worker' panicked at 'panic in bind', src/main.rs:6:9`, | ||
/// but `should_panic(expected = "panic in bind")` doesn't catch it. | ||
#[tokio::test] | ||
#[should_panic(expected = "panic in bind")] | ||
async fn bind_panic() { | ||
let project_path = format!("{}/tests/resources/bind-panic", env!("CARGO_MANIFEST_DIR")); | ||
|
||
let TestRuntime { | ||
bin_path, | ||
service_name, | ||
secrets, | ||
mut runtime_client, | ||
runtime_address, | ||
} = spawn_runtime(project_path, "bind-panic").await.unwrap(); | ||
|
||
let load_request = tonic::Request::new(LoadRequest { | ||
path: bin_path, | ||
service_name, | ||
secrets, | ||
}); | ||
|
||
let _ = runtime_client.load(load_request).await.unwrap(); | ||
|
||
let start_request = StartRequest { | ||
deployment_id: Uuid::default().as_bytes().to_vec(), | ||
ip: runtime_address.to_string(), | ||
}; | ||
|
||
// I also tried this without spawning, but it gave the same result. Panic but it isn't caught. | ||
tokio::spawn(async move { | ||
runtime_client | ||
.start(tonic::Request::new(start_request)) | ||
.await | ||
.unwrap(); | ||
// Give it a second to panic. | ||
tokio::time::sleep(Duration::from_secs(1)).await; | ||
}) | ||
.await | ||
.unwrap(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pub mod helpers; | ||
pub mod loader; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
struct MyService; | ||
|
||
#[shuttle_runtime::async_trait] | ||
impl shuttle_runtime::Service for MyService { | ||
async fn bind(mut self, _: std::net::SocketAddr) -> Result<(), shuttle_runtime::Error> { | ||
panic!("panic in bind"); | ||
} | ||
} | ||
|
||
#[shuttle_runtime::main] | ||
async fn bind_panic() -> Result<MyService, shuttle_runtime::Error> { | ||
Ok(MyService) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.