138 lines
4.9 KiB
Rust
138 lines
4.9 KiB
Rust
#![cfg(not(target_arch = "wasm32"))]
|
|
|
|
use makepad_flow::client::{ClientError, FlowClient};
|
|
use makepad_flow::host::{FlowServer, FlowServerConfig};
|
|
use makepad_flow::templates::{group_rank, TEMPLATES, TEMPLATE_GROUPS};
|
|
use std::collections::BTreeSet;
|
|
use std::path::PathBuf;
|
|
use std::time::{SystemTime, UNIX_EPOCH};
|
|
|
|
struct TempRoot(PathBuf);
|
|
|
|
impl TempRoot {
|
|
fn new() -> Self {
|
|
let nonce = SystemTime::now()
|
|
.duration_since(UNIX_EPOCH)
|
|
.unwrap()
|
|
.as_nanos();
|
|
let path = std::env::temp_dir().join(format!(
|
|
"makepad-flow-host-templates-{}-{nonce}",
|
|
std::process::id()
|
|
));
|
|
std::fs::create_dir_all(&path).unwrap();
|
|
Self(path)
|
|
}
|
|
}
|
|
|
|
impl Drop for TempRoot {
|
|
fn drop(&mut self) {
|
|
let _ = std::fs::remove_dir_all(&self.0);
|
|
}
|
|
}
|
|
|
|
fn recipe_names(dir: &str) -> Vec<String> {
|
|
let dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(dir);
|
|
let mut files: Vec<_> = std::fs::read_dir(dir)
|
|
.unwrap()
|
|
.map(|entry| entry.unwrap().path())
|
|
.filter(|path| path.extension().is_some_and(|extension| extension == "splash"))
|
|
.map(|path| path.file_stem().unwrap().to_str().unwrap().to_string())
|
|
.collect();
|
|
files.sort();
|
|
files
|
|
}
|
|
|
|
#[test]
|
|
fn template_registry_matches_the_recipe_directory() {
|
|
// `recipes/templates` holds the creator pipelines, `recipes/studio` the
|
|
// model presets; every file of either is registered once, and only the
|
|
// studio ones are in the Studio group.
|
|
let registered = |stage: bool| {
|
|
let mut names: Vec<_> = TEMPLATES
|
|
.iter()
|
|
.filter(|template| (template.group == "Studio") == stage)
|
|
.map(|template| template.name.to_string())
|
|
.collect();
|
|
names.sort();
|
|
names
|
|
};
|
|
assert_eq!(registered(false), recipe_names("recipes/templates"));
|
|
assert_eq!(registered(true), recipe_names("recipes/studio"));
|
|
let mut all: Vec<_> = TEMPLATES.iter().map(|template| template.name).collect();
|
|
all.sort();
|
|
all.dedup();
|
|
assert_eq!(all.len(), TEMPLATES.len(), "template names are unique");
|
|
}
|
|
|
|
#[test]
|
|
fn host_lists_and_creates_templates() {
|
|
let root = TempRoot::new();
|
|
let mut config = FlowServerConfig::new(root.0.clone());
|
|
config.log = Box::new(|_| {});
|
|
let server = FlowServer::start(config).unwrap();
|
|
let endpoints = server.endpoints();
|
|
let client_endpoints = makepad_flow::client::Endpoints {
|
|
control: endpoints.control,
|
|
data: endpoints.data,
|
|
};
|
|
let client = FlowClient::connect(client_endpoints, endpoints.token.clone(), None).unwrap();
|
|
|
|
let templates = client.templates().unwrap();
|
|
assert_eq!(templates.len(), TEMPLATES.len());
|
|
let returned: BTreeSet<&str> = templates.iter().map(|template| template.name.as_str()).collect();
|
|
let catalogue: BTreeSet<&str> = TEMPLATES.iter().map(|template| template.name).collect();
|
|
assert_eq!(returned, catalogue);
|
|
assert!(templates.windows(2).all(|pair| {
|
|
group_rank(&pair[0].group) < group_rank(&pair[1].group)
|
|
|| (pair[0].group == pair[1].group && pair[0].name < pair[1].name)
|
|
}));
|
|
assert_eq!(
|
|
templates
|
|
.iter()
|
|
.map(|template| template.group.as_str())
|
|
.collect::<std::collections::HashSet<_>>(),
|
|
TEMPLATE_GROUPS.iter().copied().collect()
|
|
);
|
|
assert!(templates.iter().all(|template| {
|
|
!template.label.is_empty()
|
|
&& !template.brief.is_empty()
|
|
&& !template.inputs.is_empty()
|
|
&& !template.outputs.is_empty()
|
|
}));
|
|
let dream = templates.iter().find(|template| template.name == "dream").unwrap();
|
|
assert_eq!(dream.inputs, [("prompt".to_string(), "text".to_string())]);
|
|
assert_eq!(dream.outputs, [("movie".to_string(), "video".to_string())]);
|
|
let publish = templates
|
|
.iter()
|
|
.find(|template| template.name == "prompt-to-library")
|
|
.unwrap();
|
|
assert_eq!(publish.inputs, [("prompt".to_string(), "text".to_string())]);
|
|
assert_eq!(
|
|
publish.outputs,
|
|
[("published".to_string(), "json".to_string())]
|
|
);
|
|
|
|
let detail = client.template("dream").unwrap();
|
|
assert_eq!(detail.name, "dream");
|
|
assert!(!detail.label.is_empty());
|
|
assert!(!detail.brief.is_empty());
|
|
assert!(detail.source.contains("Flow{"));
|
|
|
|
let created = client.create_from_template("my-dream", "dream").unwrap();
|
|
assert_eq!(created.revision, 1);
|
|
assert_eq!(created.graph.label, "DREAM");
|
|
let flows = client.flows().unwrap();
|
|
let flow = flows.iter().find(|flow| flow.name == "my-dream").unwrap();
|
|
assert_eq!(flow.state, "ok");
|
|
|
|
assert!(matches!(
|
|
client.create_from_template("my-dream", "dream"),
|
|
Err(ClientError::Http { status: 409, .. })
|
|
));
|
|
assert!(matches!(
|
|
client.create_from_template("unknown-template", "not-shipped"),
|
|
Err(ClientError::Http { status: 404, .. })
|
|
));
|
|
|
|
server.shutdown();
|
|
}
|