Improve serve test, add single txt file test

This commit is contained in:
Lucien Greathouse
2019-10-16 16:21:33 -07:00
parent 82678235ab
commit 40540c3637
7 changed files with 198 additions and 118 deletions

View File

@@ -1,4 +1,4 @@
use std::path::{Path, PathBuf}; use std::path::{Path};
use criterion::{criterion_group, criterion_main, BatchSize, Criterion}; use criterion::{criterion_group, criterion_main, BatchSize, Criterion};
use tempfile::{tempdir, TempDir}; use tempfile::{tempdir, TempDir};

View File

@@ -0,0 +1,19 @@
---
source: rojo-test/src/serve_test.rs
expression: read_result
---
sessionId: id-1
messageCursor: 0
instances:
id-2:
Id: id-2
Parent: ~
Name: just-txt
ClassName: StringValue
Properties:
Value:
Type: String
Value: "Hello, world!"
Children: []
Metadata:
ignoreUnknownInstances: false

View File

@@ -0,0 +1,9 @@
---
source: rojo-test/src/serve_test.rs
expression: info
---
sessionId: id-1
serverVersion: 0.6.0-dev
protocolVersion: 3
expectedPlaceIds: ~
rootInstanceId: id-2

View File

@@ -0,0 +1 @@
Hello, world!

View File

@@ -2,4 +2,5 @@
mod build_test; mod build_test;
mod serve_test; mod serve_test;
mod serve_util;
mod util; mod util;

View File

@@ -1,24 +1,12 @@
use std::{ use std::fs;
fs,
path::{Path, PathBuf},
process::Command,
sync::atomic::{AtomicUsize, Ordering},
};
use insta::assert_yaml_snapshot; use insta::assert_yaml_snapshot;
use rbx_dom_weak::RbxId;
use tempfile::{tempdir, TempDir};
use librojo::web_interface::{ReadResponse, ServerInfoResponse}; use crate::serve_util::run_serve_test;
use rojo_insta_ext::RedactionMap;
use crate::util::{
copy_recursive, get_rojo_path, get_serve_tests_path, get_working_dir_path, KillOnDrop,
};
#[test] #[test]
fn empty() { fn empty() {
run_serve_test(|session, mut redactions| { run_serve_test("empty", |session, mut redactions| {
let info = session.get_api_rojo().unwrap(); let info = session.get_api_rojo().unwrap();
let root_id = info.root_instance_id; let root_id = info.root_instance_id;
@@ -37,112 +25,29 @@ fn empty() {
}); });
} }
fn run_serve_test(callback: impl FnOnce(TestServeSession, RedactionMap)) { #[test]
let _ = env_logger::try_init(); fn just_txt() {
run_serve_test("just-txt.txt", |session, mut redactions| {
let info = session.get_api_rojo().unwrap();
let mut settings = insta::Settings::new(); let root_id = info.root_instance_id;
let info = redactions.redacted_yaml(info);
let snapshot_path = Path::new(env!("CARGO_MANIFEST_DIR")).join("serve-test-snapshots"); assert_yaml_snapshot!(info);
settings.set_snapshot_path(snapshot_path);
let mut redactions = RedactionMap::new(); let read_result = session.get_api_read(root_id).unwrap();
redactions.intern_iter(read_result.instances.keys().copied());
let read_result = redactions.redacted_yaml(read_result);
let mut session = TestServeSession::new("empty"); assert_yaml_snapshot!(read_result);
let info = session.wait_to_come_online();
redactions.intern(info.session_id); fs::write(session.path(), "Changed content!").unwrap();
redactions.intern(info.root_instance_id);
settings.bind(move || callback(session, redactions)); // TODO: Directly served files currently don't trigger changed events!
}
// let subscribe_result = session.get_api_subscribe(0).unwrap();
fn get_port_number() -> usize { // let subscribe_result = redactions.redacted_yaml(subscribe_result);
static NEXT_PORT_NUMBER: AtomicUsize = AtomicUsize::new(35103);
// assert_yaml_snapshot!(subscribe_result);
NEXT_PORT_NUMBER.fetch_add(1, Ordering::SeqCst) });
}
struct TestServeSession {
// Drop order is important here: we want the process to be killed before the
// directory it's operating on is destroyed.
rojo_process: KillOnDrop,
_dir: TempDir,
port: usize,
project_path: PathBuf,
}
impl TestServeSession {
pub fn new(name: &str) -> Self {
let serve_test_path = get_serve_tests_path();
let working_dir = get_working_dir_path();
let exe_path = get_rojo_path();
let source_path = serve_test_path.join(name);
let dir = tempdir().expect("Couldn't create temporary directory");
let project_path = dir.path().join(name);
fs::create_dir(&project_path).expect("Couldn't create temporary project subdirectory");
copy_recursive(&source_path, &project_path)
.expect("Couldn't copy project to temporary directory");
let port = get_port_number();
let port_string = port.to_string();
let rojo_process = Command::new(exe_path)
.args(&[
"serve",
project_path.to_str().unwrap(),
"--port",
port_string.as_str(),
])
.current_dir(working_dir)
.spawn()
.expect("Couldn't start Rojo");
TestServeSession {
rojo_process: KillOnDrop(rojo_process),
_dir: dir,
port,
project_path,
}
}
pub fn wait_to_come_online(&mut self) -> ServerInfoResponse {
loop {
match self.rojo_process.0.try_wait() {
Ok(Some(status)) => panic!("Rojo process exited with status {}", status),
Ok(None) => { /* process is still running */ }
Err(err) => panic!("Failed to wait on Rojo process: {}", err),
}
let info = match self.get_api_rojo() {
Ok(info) => info,
Err(err) => {
log::debug!("Server error, retrying: {}", err);
std::thread::sleep(std::time::Duration::from_millis(30));
continue;
}
};
log::info!("Got session info: {:?}", info);
return info;
}
}
pub fn get_api_rojo(&self) -> Result<ServerInfoResponse, reqwest::Error> {
let url = format!("http://localhost:{}/api/rojo", self.port);
let body = reqwest::get(&url)?.text()?;
Ok(serde_json::from_str(&body).expect("Server returned malformed response"))
}
pub fn get_api_read(&self, id: RbxId) -> Result<ReadResponse, reqwest::Error> {
let url = format!("http://localhost:{}/api/read/{}", self.port, id);
let body = reqwest::get(&url)?.text()?;
Ok(serde_json::from_str(&body).expect("Server returned malformed response"))
}
} }

145
rojo-test/src/serve_util.rs Normal file
View File

@@ -0,0 +1,145 @@
use std::{
fs,
path::{Path, PathBuf},
process::Command,
sync::atomic::{AtomicUsize, Ordering},
};
use rbx_dom_weak::RbxId;
use tempfile::{tempdir, TempDir};
use librojo::web_interface::{ReadResponse, ServerInfoResponse, SubscribeResponse};
use rojo_insta_ext::RedactionMap;
use crate::util::{
copy_recursive, get_rojo_path, get_serve_tests_path, get_working_dir_path, KillOnDrop,
};
pub fn run_serve_test(test_name: &str, callback: impl FnOnce(TestServeSession, RedactionMap)) {
let _ = env_logger::try_init();
let mut settings = insta::Settings::new();
let snapshot_path = Path::new(env!("CARGO_MANIFEST_DIR")).join("serve-test-snapshots");
settings.set_snapshot_path(snapshot_path);
let mut redactions = RedactionMap::new();
let mut session = TestServeSession::new(test_name);
let info = session.wait_to_come_online();
redactions.intern(info.session_id);
redactions.intern(info.root_instance_id);
settings.bind(move || callback(session, redactions));
}
fn get_port_number() -> usize {
static NEXT_PORT_NUMBER: AtomicUsize = AtomicUsize::new(35103);
NEXT_PORT_NUMBER.fetch_add(1, Ordering::SeqCst)
}
pub struct TestServeSession {
// Drop order is important here: we want the process to be killed before the
// directory it's operating on is destroyed.
rojo_process: KillOnDrop,
_dir: TempDir,
port: usize,
project_path: PathBuf,
}
impl TestServeSession {
pub fn new(name: &str) -> Self {
let serve_test_path = get_serve_tests_path();
let working_dir = get_working_dir_path();
let exe_path = get_rojo_path();
let source_path = serve_test_path.join(name);
let dir = tempdir().expect("Couldn't create temporary directory");
let project_path = dir.path().join(name);
let source_is_file = fs::metadata(&source_path).unwrap().is_file();
if source_is_file {
fs::copy(&source_path, &project_path).expect("couldn't copy project file");
} else {
fs::create_dir(&project_path).expect("Couldn't create temporary project subdirectory");
copy_recursive(&source_path, &project_path)
.expect("Couldn't copy project to temporary directory");
};
let port = get_port_number();
let port_string = port.to_string();
let rojo_process = Command::new(exe_path)
.args(&[
"serve",
project_path.to_str().unwrap(),
"--port",
port_string.as_str(),
])
.current_dir(working_dir)
.spawn()
.expect("Couldn't start Rojo");
TestServeSession {
rojo_process: KillOnDrop(rojo_process),
_dir: dir,
port,
project_path,
}
}
pub fn path(&self) -> &Path {
&self.project_path
}
pub fn wait_to_come_online(&mut self) -> ServerInfoResponse {
loop {
match self.rojo_process.0.try_wait() {
Ok(Some(status)) => panic!("Rojo process exited with status {}", status),
Ok(None) => { /* process is still running */ }
Err(err) => panic!("Failed to wait on Rojo process: {}", err),
}
let info = match self.get_api_rojo() {
Ok(info) => info,
Err(err) => {
log::debug!("Server error, retrying: {}", err);
std::thread::sleep(std::time::Duration::from_millis(30));
continue;
}
};
log::info!("Got session info: {:?}", info);
return info;
}
}
pub fn get_api_rojo(&self) -> Result<ServerInfoResponse, reqwest::Error> {
let url = format!("http://localhost:{}/api/rojo", self.port);
let body = reqwest::get(&url)?.text()?;
Ok(serde_json::from_str(&body).expect("Server returned malformed response"))
}
pub fn get_api_read(&self, id: RbxId) -> Result<ReadResponse, reqwest::Error> {
let url = format!("http://localhost:{}/api/read/{}", self.port, id);
let body = reqwest::get(&url)?.text()?;
Ok(serde_json::from_str(&body).expect("Server returned malformed response"))
}
pub fn get_api_subscribe(
&self,
cursor: u32,
) -> Result<SubscribeResponse<'static>, reqwest::Error> {
let url = format!("http://localhost:{}/api/subscribe/{}", self.port, cursor);
reqwest::get(&url)?.json()
}
}