Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
 
Fix async eldritch functions crashing golem/imix. (#148)
  • Loading branch information
hulto authored Mar 16, 2023
1 parent 57d40b6 commit b211899
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 33 deletions.
8 changes: 8 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ jobs:
key: ${{ runner.os }}-imix-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-imix-cargo-
- if: matrix.os == 'windows-latest'
run: start-process -filepath powershell -ArgumentList '/c','Set-MpPreference -DisableRealtimeMonitoring $true' -verb RunAs
name: 👾 Disable defender
shell: powershell
- name: 🔨 Build
run: cd implants/imix && cargo build --verbose
- name: 🔎 Run tests
Expand All @@ -79,6 +83,10 @@ jobs:
key: ${{ runner.os }}-eldritch-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-eldritch-cargo-
- if: matrix.os == 'windows-latest'
run: start-process -filepath powershell -ArgumentList '/c','Set-MpPreference -DisableRealtimeMonitoring $true' -verb RunAs
name: 👾 Disable defender
shell: powershell
- name: 🔨 Build
run: cd implants/eldritch && cargo build --verbose
- name: 🔎 Run tests
Expand Down
23 changes: 21 additions & 2 deletions implants/eldritch/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub fn get_eldritch() -> anyhow::Result<Globals> {
}

pub fn eldritch_run(tome_filename: String, tome_contents: String, tome_parameters: Option<String>) -> anyhow::Result<String> {
// Boilder plate
let ast: AstModule;
match AstModule::parse(
&tome_filename,
Expand All @@ -41,7 +42,7 @@ pub fn eldritch_run(tome_filename: String, tome_contents: String, tome_parameter

let tome_params_str: String = match tome_parameters {
Some(param_string) => param_string,
None => "".to_string(),
None => "{}".to_string(),
};

let globals = get_eldritch()?;
Expand All @@ -50,7 +51,7 @@ pub fn eldritch_run(tome_filename: String, tome_contents: String, tome_parameter

let res: SmallMap<Value, Value> = SmallMap::new();
let mut input_params: Dict = Dict::new(res);

let parsed: serde_json::Value = serde_json::from_str(&tome_params_str)?;
let param_map: serde_json::Map<String, serde_json::Value> = match parsed.as_object() {
Some(tmp_param_map) => tmp_param_map.clone(),
Expand Down Expand Up @@ -110,10 +111,13 @@ pub fn eldritch_run(tome_filename: String, tome_contents: String, tome_parameter

#[cfg(test)]
mod tests {
use std::thread;

use super::*;
use starlark::environment::{GlobalsBuilder};
use starlark::{starlark_module};
use starlark::assert::Assert;
use tempfile::NamedTempFile;

use super::file::FileLibrary;
use super::process::ProcessLibrary;
Expand Down Expand Up @@ -191,4 +195,19 @@ input_params
Ok(())
}

#[tokio::test]
async fn test_library_async() -> anyhow::Result<()> {
// just using a temp file for its path
let tmp_file = NamedTempFile::new()?;
let path = String::from(tmp_file.path().to_str().unwrap()).clone().replace("\\", "\\\\");
let test_content = format!(r#"
file.download("https://www.google.com/", "{path}")
"#);
let test_res = thread::spawn(|| { eldritch_run("test.tome".to_string(), test_content, None) });
let test_val = test_res.join();

assert!(tmp_file.as_file().metadata().unwrap().len() > 5);

Ok(())
}
}
45 changes: 18 additions & 27 deletions implants/golem/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,14 @@ extern crate golem;
extern crate eldritch;

use clap::{Command, Arg};
use tokio::task;
use std::fs;
use std::process;
use std::thread;

use eldritch::{eldritch_run};

mod inter;


async fn run(tome_path: String) -> anyhow::Result<String> {
// Read a tome script
let tome_contents = fs::read_to_string(tome_path.clone())?;
// Execute a tome script
eldritch_run(tome_path, tome_contents, None)
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
let matches = Command::new("golem")
Expand All @@ -37,31 +29,32 @@ async fn main() -> anyhow::Result<()> {
// Queue async tasks
let mut all_tome_futures: Vec<(String, _)> = vec![];
for tome in tome_files {
let tome_execution_task = run(tome.to_string());
let tmp_row = (tome.to_string(), task::spawn(tome_execution_task));
let tome_path = tome.to_string().clone();
let tome_contents = fs::read_to_string(tome_path.clone())?;
let tmp_row = (tome.to_string(), thread::spawn(|| { eldritch_run(tome_path, tome_contents, None) }));
all_tome_futures.push(tmp_row)
}


let mut error_code = 0;
// Collect results and do error handling
let mut result: Vec<String> = Vec::new();
for tome_task in all_tome_futures {
// Get the name of the file from our tuple.
let tome_name: String = tome_task.0;
match tome_task.1.await {
// Match on task results.
Ok(res) => match res {
Ok(task_res) => result.push(task_res),
Err(task_err) => {
eprintln!("[TASK ERROR] {tome_name}: {task_err}");
error_code = 1;
}
},

Err(err) => {
eprintln!("[ERROR] {tome_name}: {err}");
// Join our
let tome_result_thread_join = match tome_task.1.join() {
Ok(local_thread_join_res) => local_thread_join_res,
Err(_) => {
error_code = 1;
Err(anyhow::anyhow!("An error occured waiting for the tome thread to complete while executing {tome_name}."))
},
};

match tome_result_thread_join {
Ok(local_tome_result) => result.push(local_tome_result),
Err(task_error) => {
error_code = 1;
eprintln!("[TASK ERROR] {tome_name}: {task_error}");
}
}
}
if result.len() > 0 {
Expand All @@ -73,5 +66,3 @@ async fn main() -> anyhow::Result<()> {
}
Ok(())
}


18 changes: 16 additions & 2 deletions implants/golem/tests/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ fn test_golem_main_file_not_found() -> anyhow::Result<()> {
cmd.arg("nonexistentdir/run.tome");
cmd.assert()
.failure()
.stderr(predicate::str::contains("[TASK ERROR] nonexistentdir/run.tome: No such file or directory (os error 2)"));
.stderr(predicate::str::contains("Error: No such file or directory"));

Ok(())
}
Expand Down Expand Up @@ -53,7 +53,21 @@ fn test_golem_main_basic_eldritch_non_interactive() -> anyhow::Result<()> {
cmd.arg("working_dir/tomes/eldritch_test.tome");
cmd.assert()
.success()
.stdout(predicate::str::contains("[\"[\\\"append\\\", \\\"copy\\\", \\\"download\\\", \\\"exists\\\", \\\"hash\\\", \\\"is_dir\\\", \\\"is_file\\\", \\\"mkdir\\\", \\\"read\\\", \\\"remove\\\", \\\"rename\\\", \\\"replace\\\", \\\"replace_all\\\", \\\"timestomp\\\", \\\"write\\\"]\"]"));
.stdout(predicate::str::contains(r#"[\"append\", \"compress\""#));

Ok(())
}


// Test running `./golem ./working_dir/tomes/eldritch_test.tome`
#[test]
fn test_golem_main_basic_async() -> anyhow::Result<()> {
let mut cmd = Command::cargo_bin("golem")?;

cmd.arg("working_dir/tomes/download_test.tome");
cmd.assert()
.success()
.stderr(predicate::str::contains(r#"OKAY!"#));

Ok(())
}
Expand Down
2 changes: 2 additions & 0 deletions implants/golem/working_dir/tomes/download_test.tome
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
file.download("https://github.com/KCarretto/realm/releases/download/v0.0.1/imix-linux-x64","/tmp/abc")
print("OKAY!")
7 changes: 6 additions & 1 deletion implants/imix/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::thread;
use std::{collections::HashMap, fs};
use std::fs::File;
use std::io::Write;
Expand Down Expand Up @@ -40,7 +41,11 @@ async fn handle_exec_tome(task: GraphQLTask) -> Result<(String,String)> {
let tome_contents = task_job.tome.eldritch;

// Execute a tome script
let res = eldritch_run(tome_name, tome_contents, task_job.tome.parameters);
let res = match thread::spawn(|| { eldritch_run(tome_name, tome_contents, task_job.tome.parameters) }).join() {
Ok(local_thread_res) => local_thread_res,
Err(_) => todo!(),
};

match res {
Ok(tome_output) => Ok((tome_output, "".to_string())),
Err(tome_error) => Ok(("".to_string(), tome_error.to_string())),
Expand Down
2 changes: 1 addition & 1 deletion tests/create_file_dll/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ extern "system" fn DllMain(
pub fn demo_init() {
unsafe { consoleapi::AllocConsole() };
for (key, value) in env::vars_os() {
println!("{key:?}: {value:?}");
// println!("{key:?}: {value:?}");
if key == "LIBTESTFILE" {
let mut file = File::create(value).unwrap();
let _ = file.write_all(b"Hello, world!");
Expand Down

0 comments on commit b211899

Please sign in to comment.