Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 28 additions & 6 deletions stdlib/src/web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,8 +402,19 @@ impl StdlibRegistry {
return Ok(RuntimeValue::Str("Server already running".to_string()));
}
SERVER_RUNNING.store(true, Ordering::SeqCst);
let server =
Mutex::new(tiny_http::Server::http(format!("0.0.0.0:{}", port)).unwrap());
let server = match tiny_http::Server::http(format!("0.0.0.0:{}", port)) {
Ok(s) => Mutex::new(s),
Err(e) => {
SERVER_RUNNING.store(false, Ordering::SeqCst);
return Err(RuntimeError::new(
techscript_runtime::error::RuntimeErrorKind::InvalidOperation(
format!("Failed to start server: {}", e),
),
None,
None,
));
}
};
thread::spawn(move || {
while SERVER_RUNNING.load(Ordering::SeqCst) {
if let Ok(mut req) = server.lock().unwrap().recv() {
Expand All @@ -413,7 +424,7 @@ impl StdlibRegistry {
&b"Content-Type"[..],
&b"text/html; charset=utf-8"[..],
)
.unwrap(),
.expect("valid header"),
);
let _ = req.respond(r);
}
Expand Down Expand Up @@ -470,8 +481,19 @@ impl StdlibRegistry {
return Ok(RuntimeValue::Str("Server already running".to_string()));
}
SERVER_RUNNING.store(true, Ordering::SeqCst);
let server =
Mutex::new(tiny_http::Server::http(format!("0.0.0.0:{}", port)).unwrap());
let server = match tiny_http::Server::http(format!("0.0.0.0:{}", port)) {
Ok(s) => Mutex::new(s),
Err(e) => {
SERVER_RUNNING.store(false, Ordering::SeqCst);
return Err(RuntimeError::new(
techscript_runtime::error::RuntimeErrorKind::InvalidOperation(
format!("Failed to start server: {}", e),
),
None,
None,
));
}
};
thread::spawn(move || {
while SERVER_RUNNING.load(Ordering::SeqCst) {
if let Ok(mut req) = server.lock().unwrap().recv() {
Expand All @@ -481,7 +503,7 @@ impl StdlibRegistry {
&b"Content-Type"[..],
&b"text/html; charset=utf-8"[..],
)
.unwrap(),
.expect("valid header"),
);
let _ = req.respond(r);
}
Expand Down
63 changes: 26 additions & 37 deletions stdlib/tests/stdlib_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,6 @@ fn test_regex_operations() {
#[test]
fn test_web_module() {
use std::net::TcpListener;
use std::panic;

let registry = StdlibRegistry::new();
let web = registry.get_module("std.web").unwrap();
Expand All @@ -433,50 +432,40 @@ fn test_web_module() {
let listener = TcpListener::bind("0.0.0.0:0").unwrap();
let port = listener.local_addr().unwrap().port();

// Test panic on `start` when port is in use
let start_result = panic::catch_unwind(panic::AssertUnwindSafe(|| {
let mut caps = HashSet::new();
caps.insert(Capability::Network);
let mut ctx2 = RuntimeContext::new(RuntimeConfig {
strict_mode: false,
max_recursion_depth: 1000,
enable_assertions: true,
capabilities: caps,
});
let _ = start.call(
&mut ctx2,
vec![
RuntimeValue::Int(port as i64),
RuntimeValue::Str("<h1>Test</h1>".to_string()),
],
);
}));
// Test that `start` returns an error when port is in use
let start_result = start.call(
&mut ctx,
vec![
RuntimeValue::Int(port as i64),
RuntimeValue::Str("<h1>Test</h1>".to_string()),
],
);

assert!(
start_result.is_err(),
"Expected `start` to panic due to port already in use"
"Expected `start` to return an error due to port already in use"
);
assert!(
start_result
.unwrap_err()
.message
.contains("Failed to start server"),
"Expected error message to mention failure to start server"
);

// Make sure we stop the server and cleanup the global bool in case of weirdness,
// although the panic meant it wasn't started fully, but `SERVER_RUNNING` is true.
let _ = stop.call(&mut ctx, vec![]).unwrap();

// Test panic on `serve` when port is in use
let serve_result = panic::catch_unwind(panic::AssertUnwindSafe(|| {
let mut caps = HashSet::new();
caps.insert(Capability::Network);
let mut ctx3 = RuntimeContext::new(RuntimeConfig {
strict_mode: false,
max_recursion_depth: 1000,
enable_assertions: true,
capabilities: caps,
});
let _ = serve.call(&mut ctx3, vec![RuntimeValue::Int(port as i64)]);
}));
// Test that `serve` returns an error when port is in use
let serve_result = serve.call(&mut ctx, vec![RuntimeValue::Int(port as i64)]);

assert!(
serve_result.is_err(),
"Expected `serve` to panic due to port already in use"
"Expected `serve` to return an error due to port already in use"
);
assert!(
serve_result
.unwrap_err()
.message
.contains("Failed to start server"),
"Expected error message to mention failure to start server"
);

// Reset `SERVER_RUNNING` so other tests aren't affected
Expand Down
Loading