Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/facett

facett-simview/tests/devserver.rs

//! The dev server over a real socket: the static mount, the job verbs and the Arrow data.

use std::io::{Read as _, Write as _};
use std::net::{TcpListener, TcpStream};
use std::path::PathBuf;
use std::sync::{Arc, Mutex};

use facett_simview::contract;
use facett_simview::devserver::{DevServer, Mount};
use facett_simview::mock::MockServer;

fn http(port: u16, method: &str, target: &str) -> (u16, String, Vec<u8>) {
    let mut s = TcpStream::connect(("127.0.0.1", port)).unwrap();
    write!(s, "{method} {target} HTTP/1.1\r\nHost: x\r\nContent-Length: 0\r\n\r\n").unwrap();
    let mut buf = Vec::new();
    s.read_to_end(&mut buf).unwrap();
    let split = buf.windows(4).position(|w| w == b"\r\n\r\n").unwrap();
    let head = String::from_utf8_lossy(&buf[..split]).to_string();
    let status = head.split_whitespace().nth(1).unwrap().parse().unwrap();
    (status, head, buf[split + 4..].to_vec())
}

#[test]
fn the_dev_server_serves_the_page_and_the_contract() {
    let listener = TcpListener::bind("127.0.0.1:0").unwrap();
    let port = listener.local_addr().unwrap().port();
    let here = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    let server = DevServer {
        mounts: vec![Mount { prefix: String::new(), dir: here.join("tests") }],
        mock: Arc::new(Mutex::new(MockServer::new(300))),
    };
    std::thread::spawn(move || server.serve(listener));

    let (s, head, _) = http(port, "GET", "/sim/");
    assert_eq!(s, 302);
    assert!(head.contains("Location: /sim/?component=simview"), "{head}");
    let (s, head, body) = http(port, "GET", "/sim/devserver.rs");
    assert_eq!(s, 200);
    assert!(String::from_utf8_lossy(&body).contains("the_dev_server_serves_the_page"), "{head}");
    assert_eq!(http(port, "GET", "/sim/../Cargo.toml").0, 400, "nothing climbs out of a mount");

    let (s, _, body) = http(port, "GET", "/sim/api/nodes.arrow?labels=Person&limit=200000");
    assert_eq!(s, 200);
    let persons = contract::decode_nodes(&body).unwrap();
    assert_eq!(persons.len(), 300);
    assert!(persons.iter().all(|p| p.label == "Person" && p.kommun.is_some()));
    let (_, _, body) = http(port, "GET", "/sim/api/edges.arrow?types=BOR_PA&limit=50");
    let edges = contract::decode_edges(&body).unwrap();
    assert_eq!(edges.len(), 50);
    assert!(edges.iter().all(|e| e.etype == "BOR_PA"));
    let (_, _, body) = http(port, "GET", "/sim/api/ego.arrow?id=3");
    assert_eq!(contract::decode_edges(&body).unwrap().len(), 4);
    let (_, _, body) = http(port, "GET", "/sim/api/nodes.arrow?ids=3,301");
    assert_eq!(contract::decode_nodes(&body).unwrap().len(), 2);
    let (_, _, body) = http(port, "GET", "/sim/api/meta.json");
    assert_eq!(contract::Meta::parse(&body).unwrap().persons, 300);

    assert_eq!(http(port, "POST", "/power/falkordb/permutate").0, 202);
    assert_eq!(http(port, "POST", "/power/falkordb/simulate").0, 409, "one job at a time");
    let (s, _, body) = http(port, "GET", "/power");
    assert_eq!(s, 200);
    assert!(contract::Job::parse(&body).unwrap().busy);
    assert_eq!(http(port, "POST", "/power/falkordb/explode").0, 404);
}