Skip to content

Commit

Permalink
Make moorc able to run moot tests. Add some configuration knobs to moot.
Browse files Browse the repository at this point in the history
  • Loading branch information
rdaum committed Feb 17, 2025
1 parent d0f23e6 commit 5ebdea7
Show file tree
Hide file tree
Showing 9 changed files with 318 additions and 46 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 18 additions & 24 deletions crates/compiler/src/objdef.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ pub enum ObjDefParseError {
BadAttributeType(VarType),
}

fn parse_boolean_literal(pair: pest::iterators::Pair<Rule>) -> Result<bool, ObjDefParseError> {
fn parse_boolean_literal(pair: Pair<Rule>) -> Result<bool, ObjDefParseError> {
let str = pair.as_str();
match str.to_lowercase().as_str() {
"true" => Ok(true),
Expand All @@ -110,7 +110,7 @@ fn parse_boolean_literal(pair: pest::iterators::Pair<Rule>) -> Result<bool, ObjD
}
fn parse_literal_list(
context: &mut ObjFileContext,
pairs: pest::iterators::Pairs<Rule>,
pairs: Pairs<Rule>,
) -> Result<Var, ObjDefParseError> {
let mut list = vec![];
for pair in pairs {
Expand All @@ -122,7 +122,7 @@ fn parse_literal_list(

fn parse_literal_map(
context: &mut ObjFileContext,
pairs: pest::iterators::Pairs<Rule>,
pairs: Pairs<Rule>,
) -> Result<Var, ObjDefParseError> {
let mut elements = vec![];
for r in pairs {
Expand All @@ -139,10 +139,7 @@ fn parse_literal_map(
Ok(v_map(&pairs))
}

fn parse_literal(
context: &mut ObjFileContext,
pair: pest::iterators::Pair<Rule>,
) -> Result<Var, ObjDefParseError> {
fn parse_literal(context: &mut ObjFileContext, pair: Pair<Rule>) -> Result<Var, ObjDefParseError> {
match pair.as_rule() {
Rule::atom => {
let pair = pair.into_inner().next().unwrap();
Expand Down Expand Up @@ -224,7 +221,7 @@ fn parse_literal(
}
}

fn parse_object_literal(pair: pest::iterators::Pair<Rule>) -> Result<Obj, ObjDefParseError> {
fn parse_object_literal(pair: Pair<Rule>) -> Result<Obj, ObjDefParseError> {
match pair.as_rule() {
Rule::object => {
let ostr = &pair.as_str()[1..];
Expand All @@ -238,15 +235,15 @@ fn parse_object_literal(pair: pest::iterators::Pair<Rule>) -> Result<Obj, ObjDef
}
}

fn parse_string_literal(pair: pest::iterators::Pair<Rule>) -> Result<String, ObjDefParseError> {
fn parse_string_literal(pair: Pair<Rule>) -> Result<String, ObjDefParseError> {
let string = pair.as_str();
let parsed = unquote_str(string).map_err(ObjDefParseError::VerbCompileError)?;
let parsed = unquote_str(string).map_err(VerbCompileError)?;
Ok(parsed)
}

fn parse_literal_atom(
context: &mut ObjFileContext,
pair: pest::iterators::Pair<Rule>,
pair: Pair<Rule>,
) -> Result<Var, ObjDefParseError> {
match pair.as_rule() {
Rule::object => {
Expand All @@ -262,7 +259,7 @@ fn parse_literal_atom(
pair.as_str()
))
})
.map_err(ObjDefParseError::VerbCompileError)?,
.map_err(VerbCompileError)?,
)),
Rule::float => Ok(v_float(
pair.as_str()
Expand All @@ -273,7 +270,7 @@ fn parse_literal_atom(
pair.as_str()
))
})
.map_err(ObjDefParseError::VerbCompileError)?,
.map_err(VerbCompileError)?,
)),
Rule::string => {
let str = parse_string_literal(pair)?;
Expand Down Expand Up @@ -329,15 +326,13 @@ pub fn compile_object_definitions(
LineColLocation::Span(begin, end) => (begin, Some(end)),
};

return Err(ObjDefParseError::VerbCompileError(
CompileError::ParseError {
line,
column,
end_line_col,
context: e.line().to_string(),
message: e.variant.message().to_string(),
},
));
return Err(VerbCompileError(CompileError::ParseError {
line,
column,
end_line_col,
context: e.line().to_string(),
message: e.variant.message().to_string(),
}));
}
};

Expand Down Expand Up @@ -724,8 +719,7 @@ fn parse_verb_decl(
let program = match verb_body.as_rule() {
Rule::verb_statements => {
let inner = verb_body.into_inner();
compile_tree(inner, compile_options.clone())
.map_err(ObjDefParseError::VerbCompileError)?
compile_tree(inner, compile_options.clone()).map_err(VerbCompileError)?
}
_ => {
panic!("Expected verb body, got {:?}", verb_body);
Expand Down
6 changes: 4 additions & 2 deletions crates/kernel/testsuite/moot_suite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use moor_kernel::{
},
SchedulerClient,
};
use moor_moot::{execute_moot_test, MootRunner};
use moor_moot::{execute_moot_test, MootOptions, MootRunner};
use moor_values::{v_none, Obj, Var};

mod common;
Expand Down Expand Up @@ -111,7 +111,7 @@ impl MootRunner for SchedulerMootRunner {
fn test_with_db(path: &Path) {
test(create_db(), path);
}
test_each_file::test_each_path! { in "./crates/kernel/testsuite/moot" as txdb => test_with_db }
test_each_file::test_each_path! { in "./crates/kernel/testsuite/moot" as moot_run => test_with_db }

struct NoopSessionFactory {}
impl SessionFactory for NoopSessionFactory {
Expand Down Expand Up @@ -143,8 +143,10 @@ fn test(db: Box<dyn Database>, path: &Path) {
.spawn(move || scheduler.run(session_factory.clone()))
.expect("Failed to spawn scheduler");

let options = MootOptions::default();
execute_moot_test(
SchedulerMootRunner::new(scheduler_client.clone(), Arc::new(NoopClientSession::new())),
&options,
path,
|| Ok(()),
);
Expand Down
4 changes: 3 additions & 1 deletion crates/telnet-host/tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
// this program. If not, see <https://www.gnu.org/licenses/>.
//

use moor_moot::{telnet::ManagedChild, test_db_path};
use moor_moot::{telnet::ManagedChild, test_db_path, MootOptions};
use serial_test::serial;
use std::net::TcpListener;
use std::{
Expand Down Expand Up @@ -144,8 +144,10 @@ fn test_moot_with_telnet_host<P: AsRef<Path>>(moot_file: P) {
telnet_host_clone.lock().unwrap().assert_running()
};

let moot_options = MootOptions::default();
execute_moot_test(
TelnetMootRunner::new(port),
&moot_options,
&PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("tests/moot")
.join(moot_file)
Expand Down
67 changes: 57 additions & 10 deletions crates/testing/moot/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ pub const NONPROGRAMMER: Obj = Obj::mk_id(5);
#[allow(dead_code)]
static LOGGING_INIT: Once = Once::new();
#[allow(dead_code)]
fn init_logging() {
fn init_logging(options: &MootOptions) {
if !options.init_logging {
return;
}
LOGGING_INIT.call_once(|| {
let main_subscriber = tracing_subscriber::fmt()
.compact()
Expand All @@ -46,8 +49,7 @@ fn init_logging() {
.with_max_level(tracing::Level::WARN)
.with_test_writer()
.finish();
tracing::subscriber::set_global_default(main_subscriber)
.expect("Unable to configure logging");
tracing::subscriber::set_global_default(main_subscriber).ok();
});
}
/// Look up the path to Test.db from any crate under the `moor` workspace
Expand All @@ -67,24 +69,69 @@ pub trait MootRunner {
fn none(&self) -> Self::Value;
}

pub struct MootOptions {
/// Whether logging needs to be initialized, or if the host process has already initialized
/// logging
init_logging: bool,
wizard_object: Obj,
programmer_object: Obj,
nonprogrammer_object: Obj,
}

impl MootOptions {
pub fn default() -> Self {
Self {
init_logging: false,
wizard_object: WIZARD,
programmer_object: PROGRAMMER,
nonprogrammer_object: NONPROGRAMMER,
}
}

Check warning on line 89 in crates/testing/moot/src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy

method `default` can be confused for the standard trait method `std::default::Default::default`

warning: method `default` can be confused for the standard trait method `std::default::Default::default` --> crates/testing/moot/src/lib.rs:82:5 | 82 | / pub fn default() -> Self { 83 | | Self { 84 | | init_logging: false, 85 | | wizard_object: WIZARD, ... | 88 | | } 89 | | } | |_____^ | = help: consider implementing the trait `std::default::Default` or choosing a less ambiguous method name = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#should_implement_trait = note: `#[warn(clippy::should_implement_trait)]` on by default

pub fn new() -> Self {
Self::default()
}

Check warning on line 93 in crates/testing/moot/src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy

you should consider adding a `Default` implementation for `MootOptions`

warning: you should consider adding a `Default` implementation for `MootOptions` --> crates/testing/moot/src/lib.rs:91:5 | 91 | / pub fn new() -> Self { 92 | | Self::default() 93 | | } | |_____^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#new_without_default = note: `#[warn(clippy::new_without_default)]` on by default help: try adding this | 81 + impl Default for MootOptions { 82 + fn default() -> Self { 83 + Self::new() 84 + } 85 + } |

pub fn init_logging(mut self, yesno: bool) -> Self {
self.init_logging = yesno;
self
}

pub fn wizard_object(mut self, wizard_object: Obj) -> Self {
self.wizard_object = wizard_object;
self
}

pub fn programmer_object(mut self, programmer_object: Obj) -> Self {
self.programmer_object = programmer_object;
self
}

pub fn nonprogrammer_object(mut self, nonprogrammer_object: Obj) -> Self {
self.nonprogrammer_object = nonprogrammer_object;
self
}
}

pub fn execute_moot_test<R: MootRunner, F: Fn() -> eyre::Result<()>>(
mut runner: R,
options: &MootOptions,
path: &Path,
validate_state: F,
) {
init_logging();
init_logging(&options);

Check warning on line 122 in crates/testing/moot/src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy

this expression creates a reference which is immediately dereferenced by the compiler

warning: this expression creates a reference which is immediately dereferenced by the compiler --> crates/testing/moot/src/lib.rs:122:18 | 122 | init_logging(&options); | ^^^^^^^^ help: change this to: `options` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow = note: `#[warn(clippy::needless_borrow)]` on by default
eprintln!("Test definition: {}", path.display());

let test = std::fs::read_to_string(path)
.wrap_err(format!("{}", path.display()))
.unwrap();

let mut player = WIZARD;
let mut player = options.wizard_object.clone();
for span in parser::parse(&test).context("parse").unwrap() {
eprintln!("{:?}", span);
match &span.expr {
MootBlock::ChangePlayer(change) => {
player = handle_change_player(change.name)
player = handle_change_player(&options, change.name)

Check warning on line 134 in crates/testing/moot/src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy

this expression creates a reference which is immediately dereferenced by the compiler

warning: this expression creates a reference which is immediately dereferenced by the compiler --> crates/testing/moot/src/lib.rs:134:47 | 134 | player = handle_change_player(&options, change.name) | ^^^^^^^^ help: change this to: `options` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow
.context("handle_change_player")
.unwrap();
}
Expand All @@ -104,11 +151,11 @@ pub fn execute_moot_test<R: MootRunner, F: Fn() -> eyre::Result<()>>(
}
}

fn handle_change_player(name: &str) -> eyre::Result<Obj> {
fn handle_change_player(options: &MootOptions, name: &str) -> eyre::Result<Obj> {
Ok(match name {
"wizard" => WIZARD,
"programmer" => PROGRAMMER,
"nonprogrammer" => NONPROGRAMMER,
"wizard" => options.wizard_object.clone(),
"programmer" => options.programmer_object.clone(),
"nonprogrammer" => options.nonprogrammer_object.clone(),
_ => return Err(eyre!("Unknown player: {}", name)),
})
}
Expand Down
12 changes: 10 additions & 2 deletions crates/testing/moot/tests/moot_lmoo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ use std::{
sync::{Arc, Mutex},
};

use moor_moot::{execute_moot_test, telnet::ManagedChild, telnet::TelnetMootRunner, test_db_path};
use moor_moot::{
execute_moot_test, telnet::ManagedChild, telnet::TelnetMootRunner, test_db_path, MootOptions,
};

fn moo_path() -> PathBuf {
env::var("MOOT_MOO_PATH")
Expand Down Expand Up @@ -67,7 +69,13 @@ fn test_moo(path: &Path) {
let moo_clone = moo.clone();
let validate_state = move || moo_clone.lock().unwrap().assert_running();

execute_moot_test(TelnetMootRunner::new(moo_port()), path, validate_state);
let moot_options = MootOptions::default();
execute_moot_test(
TelnetMootRunner::new(moo_port()),
&moot_options,
path,
validate_state,
);

drop(moo);
}
Expand Down
4 changes: 2 additions & 2 deletions tools/moorc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,18 @@ rust-version.workspace = true
description = "A tool for importing, compiling, and exporting mooR cores without running the full daemon"

[dependencies]
moor-compiler = { path = "../../crates/compiler" }
moor-db = { path = "../../crates/db" }
moor-kernel = { path = "../../crates/kernel" }
moor-values = { path = "../../crates/common" }
moor-daemon = { path = "../../crates/daemon" }
moor-moot = { path = "../../crates/testing/moot" }

## Command line arguments parsing.
clap.workspace = true
clap_derive.workspace = true

# General.
bincode.workspace = true
bytes.workspace = true
color-eyre.workspace = true
eyre.workspace = true
semver.workspace = true
Expand Down
Loading

0 comments on commit 5ebdea7

Please sign in to comment.