Skip to content

Commit 6f64720

Browse files
committed
Smoke test for Rust quickstart app #2100
1 parent a862ba9 commit 6f64720

File tree

2 files changed

+89
-1
lines changed

2 files changed

+89
-1
lines changed

smoketests/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
SPACETIME_BIN = STDB_DIR / ("target/debug/spacetime" + exe_suffix)
2323
TEMPLATE_TARGET_DIR = STDB_DIR / "target/_stdbsmoketests"
2424
STDB_CONFIG = TEST_DIR / "config.toml"
25-
25+
MODULES_DIR = STDB_DIR / "modules"
2626
# the contents of files for the base smoketest project template
2727
TEMPLATE_LIB_RS = open(STDB_DIR / "crates/cli/src/subcommands/project/rust/lib._rs").read()
2828
TEMPLATE_CARGO_TOML = open(STDB_DIR / "crates/cli/src/subcommands/project/rust/Cargo._toml").read()

smoketests/tests/quickstart.py

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import logging
2+
import re
3+
import tempfile
4+
from pathlib import Path
5+
6+
from .. import Smoketest, MODULES_DIR, STDB_DIR, run_cmd, TEMPLATE_CARGO_TOML, TEST_DIR
7+
8+
DEPENDENCIES = """
9+
log = "0.4"
10+
hex= "0.4"
11+
"""
12+
sdk_path = (STDB_DIR / "crates/sdk").absolute()
13+
escaped_sdk_path = str(sdk_path).replace('\\', '\\\\\\\\') # double escape for re.sub + toml
14+
DEPENDENCIES_TOML = f'spacetimedb-sdk = {{ path = "{escaped_sdk_path}" }}' + DEPENDENCIES
15+
16+
# The quickstart `main.rs` use a `repl` loop to read user input, so we need to replace it for the smoketest.
17+
TEST = """
18+
fn user_input_direct(ctx: &DbConnection) {
19+
let mut line = String::new();
20+
std::io::stdin().read_line(&mut line).expect("Failed to read from stdin.");
21+
if let Some(name) = line.strip_prefix("/name ") {
22+
ctx.reducers.set_name(name.to_string()).unwrap();
23+
} else {
24+
ctx.reducers.send_message(line).unwrap();
25+
}
26+
std::thread::sleep(std::time::Duration::from_secs(1));
27+
std::process::exit(0);
28+
}
29+
"""
30+
31+
32+
def parse_quickstart():
33+
"""This method is used to parse the documentation of `docs/docs/sdks/rust/quickstart.md`."""
34+
35+
doc_path = STDB_DIR / "docs/docs/sdks/rust" / "quickstart.md"
36+
content = open(doc_path, "r").read()
37+
38+
# Extract all Rust code blocks from the documentation.
39+
# This will replicate the steps in the quickstart guide, so if it fails the quickstart guide is broken.
40+
code_blocks = re.findall(r"```rust\n(.*?)\n```", content, re.DOTALL)
41+
42+
return "\n".join(code_blocks).replace("user_input_loop(&ctx)", "user_input_direct(&ctx)") + "\n" + TEST
43+
44+
45+
class Quickstart(Smoketest):
46+
AUTOPUBLISH = False
47+
MODULE_CODE = ""
48+
49+
def check(self, input_cmd: str, client_path: Path, contains: str):
50+
output = run_cmd("cargo", "run", input=input_cmd, cwd=client_path, capture_stderr=True, text=True)
51+
self.assertIn(contains, output)
52+
53+
def test_quickstart_rs(self):
54+
"""This test is designed to run the quickstart guide for the Rust SDK."""
55+
self.project_path = MODULES_DIR / "quickstart-chat"
56+
self.config_path = self.project_path / "config.toml"
57+
self.publish_module("quickstart-chat", capture_stderr=True, clear=True)
58+
client_path = Path(self.enterClassContext(tempfile.TemporaryDirectory()))
59+
logging.info(f"Generating client code in {client_path}...")
60+
# Create a cargo project structure
61+
run_cmd(
62+
"cargo", "new", "--bin", "quickstart_chat_client",
63+
cwd=client_path, capture_stderr=True
64+
)
65+
client_path = client_path / "quickstart_chat_client"
66+
67+
open(client_path / "Cargo.toml", "a").write(DEPENDENCIES_TOML)
68+
69+
# Replay the quickstart guide steps
70+
main = parse_quickstart()
71+
open(client_path / "src" / "main.rs", "w").write(main)
72+
self.spacetime(
73+
"generate",
74+
"--lang", "rust",
75+
"--out-dir", client_path / "src" / "module_bindings",
76+
"--project-path", self.project_path,
77+
capture_stderr=True
78+
)
79+
logging.info(f"Client code generated in {client_path}.")
80+
run_cmd(
81+
"cargo", "build",
82+
cwd=client_path, capture_stderr=True
83+
)
84+
85+
# Replay the quickstart guide steps for test the client
86+
self.check("", client_path, "connected")
87+
self.check("/name Alice", client_path, "Alice")
88+
self.check("Hello World", client_path, "Hello World")

0 commit comments

Comments
 (0)