Skip to content

Commit

Permalink
fix: speed up cairo-runner and cairo-tester in starklings (shramee#26)
Browse files Browse the repository at this point in the history
* fix: speed up cairo-runner and cairo-tester in starklings

* fix: CI

* refactor: use rust function instead of CLI invoke

* docs: revert changes to readme

---------

Co-authored-by: Shramee Srivastav <[email protected]>
  • Loading branch information
enitrat and shramee committed Feb 19, 2023
1 parent 65bd2a9 commit af3b90c
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 78 deletions.
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ name = "starklings"
path = "src/main.rs"

[[bin]]
name = "cairo-runner"
path = "src/cairo-runner.rs"
name = "starklings-runner"
path = "src/starklings_runner.rs"

[[bin]]
name = "cairo-tester"
path = "src/cairo-tester.rs"
name = "starklings-tester"
path = "src/starklings_tester.rs"
2 changes: 1 addition & 1 deletion info.toml
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ name = "arrays3"
path = "exercises/arrays/arrays3.cairo"
mode = "test"
hint = """
The test fails because you are trying to access an element that is out of bounds!
The test fails because you are trying to access an element that is out of bounds!
By using array.pop_front(), we remove the first element from the array, so the index of the last element is no longer 2.
Without changing the index accessed, how can we make the test pass? Is there a method that returns an option that could help us?
"""
Expand Down
10 changes: 1 addition & 9 deletions src/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,4 @@ thiserror = "1.0.32"
[dev-dependencies]
assert_cmd = "0.11.0"
predicates = "1.0.1"
glob = "0.3.0"

[[bin]]
name = "starklings"
path = "main.rs"

[[bin]]
name = "cairo-runner"
path = "cairo-runner.rs"
glob = "0.3.0"
31 changes: 18 additions & 13 deletions src/exercise.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ use std::fmt::{self, Display, Formatter};
use std::fs::{remove_file, File};
use std::io::Read;
use std::path::PathBuf;
use std::process::{self, Command};
use std::process::{self};
use crate::starklings_runner::{Args as RunnerArgs,run_cairo_program};
use crate::starklings_tester::{Args as TesterArgs ,test_cairo_program};

const I_AM_DONE_REGEX: &str = r"(?m)^\s*///?\s*I\s+AM\s+NOT\s+DONE";
const CONTEXT: usize = 2;
Expand Down Expand Up @@ -89,20 +91,23 @@ impl Drop for FileHandle {
}

impl Exercise {
pub fn run_cairo(&self) -> std::process::Output {
let cmd = Command::new("cargo")
.args(&["run", "-q", "--bin", "cairo-runner", "--"])
.args(&["--path", self.path.to_str().unwrap()])
.output();
cmd.expect("Failed to run 'compile' command.")
pub fn run_cairo(&self) -> anyhow::Result<String> {
run_cairo_program(&RunnerArgs{
path: self.path.to_str().unwrap().parse()?,
available_gas: None,
print_full_memory: false,
})

}

pub fn test_cairo(&self) -> std::process::Output {
let cmd = Command::new("cargo")
.args(&["run", "-q", "--bin", "cairo-tester", "--"])
.args(&["--path", self.path.to_str().unwrap()])
.output();
cmd.expect("Failed to run 'test' command.")
pub fn test_cairo(&self) -> anyhow::Result<String> {
test_cairo_program(&TesterArgs{
path: self.path.to_str().unwrap().parse()?,
filter: "".to_string(),
include_ignored: false,
ignored: false,
starknet: false,
})
}

pub fn state(&self) -> State {
Expand Down
3 changes: 2 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ use std::time::Duration;

#[macro_use]
mod ui;

mod exercise;
mod project;
mod run;
mod verify;
mod starklings_tester;
mod starklings_runner;

// In sync with crate version
const VERSION: &str = "5.3.0";
Expand Down
18 changes: 10 additions & 8 deletions src/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,17 @@ fn run_cairo(exercise: &Exercise) -> Result<(), ()> {
progress_bar.enable_steady_tick(100);
let output = exercise.run_cairo();

if output.stderr.len() > 0 {
if let Some(error) = output.as_ref().err(){
progress_bar.finish_and_clear();
println!("Err");
println!("{}", String::from_utf8(output.stderr).unwrap());
println!("{}", error.to_string());

println!("Normal");
println!("{}", String::from_utf8(output.stdout).unwrap());
println!("{}", error.to_string());
Err(())
} else {
println!("{}", String::from_utf8(output.stdout).unwrap());
let message = output.unwrap();
println!("{}", message);
success!("Successfully ran {}", exercise);
Ok(())
}
Expand All @@ -61,16 +62,17 @@ fn test_cairo(exercise: &Exercise) -> Result<(), ()> {
progress_bar.enable_steady_tick(100);
let output = exercise.test_cairo();

if output.stderr.len() > 0 {
if let Some(error) = output.as_ref().err(){
progress_bar.finish_and_clear();
println!("Err");
println!("{}", String::from_utf8(output.stderr).unwrap());
println!("{}", error.to_string());

println!("Normal");
println!("{}", String::from_utf8(output.stdout).unwrap());
println!("{}", error.to_string());
Err(())
} else {
println!("{}", String::from_utf8(output.stdout).unwrap());
let message = output.unwrap();
println!("{}", message);
success!("Successfully ran {}", exercise);
Ok(())
}
Expand Down
38 changes: 18 additions & 20 deletions src/cairo-runner.rs → src/starklings_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,29 @@ const CORELIB_DIR_NAME: &str = "corelib";
/// Exits with 0/1 if the input is formatted correctly/incorrectly.
#[derive(Parser, Debug)]
#[clap(version, verbatim_doc_comment)]
struct Args {
pub struct Args {
/// The file to compile and run.
#[arg(short, long)]
path: String,
pub path: String,
/// In cases where gas is available, the amount of provided gas.
#[arg(long)]
available_gas: Option<usize>,
pub available_gas: Option<usize>,
/// Whether to print the memory.
#[arg(long, default_value_t = false)]
print_full_memory: bool,
pub print_full_memory: bool,
}

fn main() -> anyhow::Result<()> {
let args = Args::parse();
let res = run_cairo_program(&args);
if let Err(e) = res {
eprintln!("{}", e);
std::process::exit(1);
}
Ok(())
}

pub fn run_cairo_program(args: &Args) -> anyhow::Result<String> {
let mut db = RootDatabase::default();
let mut corelib_dir = std::env::current_exe()
.unwrap_or_else(|e| panic!("Problem getting the executable path: {e:?}"));
Expand All @@ -49,6 +57,8 @@ fn main() -> anyhow::Result<()> {
anyhow::bail!("failed to compile: {}", args.path);
}

let mut ret_string = String::new();

let sierra_program = db
.get_sierra_program(main_crate_ids)
.to_option()
Expand All @@ -63,24 +73,12 @@ fn main() -> anyhow::Result<()> {
.with_context(|| "Failed to run the function.")?;
match result.value {
cairo_lang_runner::RunResultValue::Success(values) => {
println!("Run completed successfully, returning {values:?}")
ret_string.push_str(format!("Run completed successfully, returning {values:?}").as_str())
}
cairo_lang_runner::RunResultValue::Panic(values) => {
println!("Run panicked with err values: {values:?}")
ret_string.push_str(format!("Run panicked with err values: {values:?}").as_str());
}
}
if let Some(gas) = result.gas_counter {
println!("Remaining gas: {gas}");
}
if args.print_full_memory {
print!("Full memory: [");
for cell in &result.memory {
match cell {
None => print!("_, "),
Some(value) => print!("{value}, "),
}
}
println!("]");
}
Ok(())
println!("{ret_string}");
Ok(ret_string)
}
30 changes: 19 additions & 11 deletions src/cairo-tester.rs → src/starklings_tester.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,22 +39,22 @@ const CORELIB_DIR_NAME: &str = "corelib";
/// Exits with 0/1 if the input is formatted correctly/incorrectly.
#[derive(Parser, Debug)]
#[clap(version, verbatim_doc_comment)]
struct Args {
pub struct Args {
/// The path to compile and run its tests.
#[arg(short, long)]
path: String,
pub path: String,
/// The filter for the tests, running only tests containing the filter string.
#[arg(short, long, default_value_t = String::default())]
filter: String,
pub filter: String,
/// Should we run ignored tests as well.
#[arg(long, default_value_t = false)]
include_ignored: bool,
pub include_ignored: bool,
/// Should we run only the ignored tests.
#[arg(long, default_value_t = false)]
ignored: bool,
pub ignored: bool,
/// Should we add the starknet plugin to run the tests.
#[arg(long, default_value_t = false)]
starknet: bool,
pub starknet: bool,
}

/// The status of a ran test.
Expand All @@ -66,8 +66,16 @@ enum TestStatus {

fn main() -> anyhow::Result<()> {
let args = Args::parse();
let res = test_cairo_program(&args);
if let Err(e) = res {
eprintln!("{}", e);
std::process::exit(1);
}
Ok(())
}

// TODO(orizi): Use `get_default_plugins` and just update the config plugin.
pub fn test_cairo_program(args: &Args) -> anyhow::Result<String> {
// TODO(orizi): Use `get_default_plugins` and just update the config plugin.
let mut plugins: Vec<Arc<dyn SemanticPlugin>> = vec![
Arc::new(DerivePlugin {}),
Arc::new(PanicablePlugin {}),
Expand Down Expand Up @@ -115,7 +123,7 @@ fn main() -> anyhow::Result<()> {
FunctionLongId {
function: ConcreteFunction {
generic_function: GenericFunctionId::Free(test.func_id),
generic_args: vec![]
generic_args: vec![],
}
}
.debug(db)
Expand All @@ -139,7 +147,7 @@ fn main() -> anyhow::Result<()> {
failed.len(),
ignored.len()
).as_str());
Ok(())
Ok(result_string)
} else {
result_string.push_str(format!("failures:").as_str());
for (failure, run_result) in failed.iter().zip_eq(failed_run_results) {
Expand Down Expand Up @@ -169,7 +177,7 @@ fn main() -> anyhow::Result<()> {
passed.len(),
failed.len(),
ignored.len()
);
)
}
}

Expand Down Expand Up @@ -237,7 +245,7 @@ fn run_tests(
}
TestStatus::Ignore => (&mut summary.ignored, "ignored".bright_yellow()),
};
println!("test {name} ... {status_str}",);
println!("test {name} ... {status_str}", );
res_type.push(name);
});
wrapped_summary.into_inner().unwrap()
Expand Down
22 changes: 11 additions & 11 deletions src/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ fn compile_and_run_interactively(exercise: &Exercise) -> Result<bool, ()> {

Ok(prompt_for_completion(
exercise,
Some(String::from_utf8(run_state.stdout).unwrap()),
Some(run_state)
))
}

Expand All @@ -65,7 +65,7 @@ fn compile_and_test_interactively(exercise: &Exercise) -> Result<bool, ()> {

Ok(prompt_for_completion(
exercise,
Some(String::from_utf8(run_state.stdout).unwrap()),
Some(run_state),
))
}

Expand All @@ -74,19 +74,19 @@ fn compile_and_test_interactively(exercise: &Exercise) -> Result<bool, ()> {
fn compile_and_run_cairo<'a, 'b>(
exercise: &'a Exercise,
progress_bar: &'b ProgressBar,
) -> Result<std::process::Output, ()> {
) -> Result<String, ()> {
let compilation_result = exercise.run_cairo();

if compilation_result.stderr.len() > 0 {
if let Some(error) = compilation_result.as_ref().err() {
progress_bar.finish_and_clear();
warn!(
"Compiling of {} failed! Please try again. Here's the output:",
exercise
);
println!("{}", String::from_utf8(compilation_result.stderr).unwrap());
println!("{}", error.to_string());
Err(())
} else {
Ok(compilation_result)
Ok(compilation_result.unwrap())
}
}

Expand All @@ -95,19 +95,19 @@ fn compile_and_run_cairo<'a, 'b>(
fn compile_and_test_cairo<'a, 'b>(
exercise: &'a Exercise,
progress_bar: &'b ProgressBar,
) -> Result<std::process::Output, ()> {
) -> Result<String, ()> {
let compilation_result = exercise.test_cairo();

if compilation_result.stderr.len() > 0 {
if let Some(error) = compilation_result.as_ref().err() {
progress_bar.finish_and_clear();
warn!(
"Test of {} failed! Please try again. Here's the output:",
"Testing of {} failed! Please try again. Here's the output:",
exercise
);
println!("{}", String::from_utf8(compilation_result.stderr).unwrap());
println!("{}", error.to_string());
Err(())
} else {
Ok(compilation_result)
Ok(compilation_result.unwrap())
}
}

Expand Down
1 change: 1 addition & 0 deletions tests/integration_tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use assert_cmd::prelude::*;
use glob::glob;

use std::fs::File;
use std::io::Read;
use std::process::Command;
Expand Down

0 comments on commit af3b90c

Please sign in to comment.