Commit dd071b28 authored by qinsoon's avatar qinsoon

putting pytest into Rust cargo test

(not completely done)
parent 638f4413
**/target/*
**/__pycache__/*
emit/*
**/temp/*
Cargo.lock
*.log
*.DS_Store
......
use testutil::get_test_clang_path;
use testutil::exec;
use ast::ir::MuName;
use runtime;
use compiler::backend;
use std::path::PathBuf;
use std::process::Command;
fn link_executable_internal (files: Vec<PathBuf>, out: PathBuf) -> PathBuf {
let mut gcc = Command::new(get_test_clang_path());
for file in files {
println!("link with {:?}", file.as_path());
gcc.arg(file.as_path());
}
println!("output as {:?}", out.as_path());
if cfg!(target_os = "linux") {
gcc.arg("-lrt");
gcc.arg("-ldl");
gcc.arg("-lpthread");
}
// so we can find symbols in itself
gcc.arg("-rdynamic");
gcc.arg("-o");
gcc.arg(out.as_os_str());
assert!(exec(gcc).status.success());
out
}
fn link_dylib_internal (files: Vec<PathBuf>, out: PathBuf) -> PathBuf {
let mut object_files : Vec<PathBuf> = vec![];
for file in files {
let mut gcc = Command::new(get_test_clang_path());
gcc.arg("-c");
gcc.arg("-fpic");
let mut out = file.clone();
out.set_extension("o");
gcc.arg(file.as_os_str());
gcc.arg("-o");
gcc.arg(out.as_os_str());
object_files.push(out);
exec(gcc);
}
let mut gcc = Command::new(get_test_clang_path());
gcc.arg("-shared");
gcc.arg("-Wl");
gcc.arg("-undefined");
gcc.arg("dynamic_lookup");
for obj in object_files {
gcc.arg(obj.as_os_str());
}
gcc.arg("-o");
gcc.arg(out.as_os_str());
exec(gcc);
out
}
fn get_path_for_mu_func (f: MuName) -> PathBuf {
let mut ret = PathBuf::from(backend::AOT_EMIT_DIR);
ret.push(f);
ret.set_extension("s");
ret
}
fn get_path_for_mu_context () -> PathBuf {
let mut ret = PathBuf::from(backend::AOT_EMIT_DIR);
ret.push(backend::AOT_EMIT_CONTEXT_FILE);
ret
}
pub fn link_primordial (funcs: Vec<MuName>, out: &str) -> PathBuf {
let emit_dir = PathBuf::from(backend::AOT_EMIT_DIR);
let files : Vec<PathBuf> = {
use std::fs;
let mut ret = vec![];
// all interested mu funcs
for func in funcs {
ret.push(get_path_for_mu_func(func));
}
// mu context
ret.push(get_path_for_mu_context());
// copy primoridal entry
let source = PathBuf::from(runtime::PRIMORDIAL_ENTRY);
let mut dest = PathBuf::from(backend::AOT_EMIT_DIR);
dest.push("main.c");
fs::copy(source.as_path(), dest.as_path()).unwrap();
// include the primordial C main
ret.push(dest);
// include mu static lib
let libmu = PathBuf::from("target/debug/libmu.a");
ret.push(libmu);
ret
};
let mut out_path = emit_dir.clone();
out_path.push(out);
link_executable_internal(files, out_path)
}
pub fn execute(executable: PathBuf) {
let run = Command::new(executable.as_os_str());
assert!(exec(run).status.success());
}
pub fn link_dylib (funcs: Vec<MuName>, out: &str) -> PathBuf {
let files = {
let mut ret = vec![];
for func in funcs {
ret.push(get_path_for_mu_func(func));
}
ret.push(get_path_for_mu_context());
ret
};
let mut out_path = PathBuf::from(backend::AOT_EMIT_DIR);
out_path.push(out);
link_dylib_internal(files, out_path)
}
\ No newline at end of file
extern crate libloading;
use testutil::get_test_clang_path;
use testutil::exec;
use std::path::Path;
use std::path::PathBuf;
use std::process::Command;
pub fn compile_run_c_test(test_file_path: &'static str) -> PathBuf {
let mut src = Path::new("tests/test_jit").to_path_buf();
src.push(test_file_path);
let output = {
use std::fs;
let temp = Path::new("tests/test_jit/temp");
fs::create_dir_all(temp);
let mut ret = temp.to_path_buf();
ret.push(src.file_stem().unwrap());
ret
};
// compile the C test
let mut cc = Command::new(get_test_clang_path());
cc.arg("-std=c99");
cc.arg("-Isrc/vm/api");
cc.arg("-Ltarget/debug");
cc.arg("-lmu");
// src
cc.arg(src.as_os_str());
// output
cc.arg("-o");
cc.arg(output.as_os_str());
exec(cc);
// run the executable
let test = Command::new(output.as_os_str());
let test_out = exec(test);
Path::new(&String::from_utf8(test_out.stdout).unwrap()).to_path_buf()
}
\ No newline at end of file
......@@ -7,169 +7,31 @@ use ast::ir::*;
use vm::*;
use std::sync::Arc;
pub mod aot {
use ast::ir::MuName;
use runtime;
use compiler::backend;
use std::path::PathBuf;
use std::process::Command;
use std::process::Output;
use std::process::Command;
use std::process::Output;
fn get_test_clang_path() -> String {
use std::env;
pub mod aot;
pub mod c_api;
match env::var("CLANG_FOR_AOT") {
Ok(val) => val,
Err(_) => "clang".to_string()
}
}
fn exec (mut cmd: Command) -> Output {
println!("executing: {:?}", cmd);
let output = cmd.output().expect("failed to execute");
println!("---out---");
println!("{}", String::from_utf8_lossy(&output.stdout));
println!("---err---");
println!("{}", String::from_utf8_lossy(&output.stderr));
output
}
fn link_executable_internal (files: Vec<PathBuf>, out: PathBuf) -> PathBuf {
let mut gcc = Command::new(get_test_clang_path());
for file in files {
println!("link with {:?}", file.as_path());
gcc.arg(file.as_path());
}
println!("output as {:?}", out.as_path());
if cfg!(target_os = "linux") {
gcc.arg("-lrt");
gcc.arg("-ldl");
gcc.arg("-lpthread");
}
// so we can find symbols in itself
gcc.arg("-rdynamic");
gcc.arg("-o");
gcc.arg(out.as_os_str());
assert!(exec(gcc).status.success());
out
}
fn link_dylib_internal (files: Vec<PathBuf>, out: PathBuf) -> PathBuf {
let mut object_files : Vec<PathBuf> = vec![];
for file in files {
let mut gcc = Command::new(get_test_clang_path());
gcc.arg("-c");
gcc.arg("-fpic");
let mut out = file.clone();
out.set_extension("o");
gcc.arg(file.as_os_str());
gcc.arg("-o");
gcc.arg(out.as_os_str());
object_files.push(out);
exec(gcc);
}
let mut gcc = Command::new(get_test_clang_path());
gcc.arg("-shared");
gcc.arg("-Wl");
gcc.arg("-undefined");
gcc.arg("dynamic_lookup");
for obj in object_files {
gcc.arg(obj.as_os_str());
}
gcc.arg("-o");
gcc.arg(out.as_os_str());
exec(gcc);
out
}
pub fn get_test_clang_path() -> String {
use std::env;
fn get_path_for_mu_func (f: MuName) -> PathBuf {
let mut ret = PathBuf::from(backend::AOT_EMIT_DIR);
ret.push(f);
ret.set_extension("s");
ret
}
fn get_path_for_mu_context () -> PathBuf {
let mut ret = PathBuf::from(backend::AOT_EMIT_DIR);
ret.push(backend::AOT_EMIT_CONTEXT_FILE);
ret
match env::var("CLANG_FOR_AOT") {
Ok(val) => val,
Err(_) => "clang".to_string()
}
}
pub fn link_primordial (funcs: Vec<MuName>, out: &str) -> PathBuf {
let emit_dir = PathBuf::from(backend::AOT_EMIT_DIR);
let files : Vec<PathBuf> = {
use std::fs;
let mut ret = vec![];
// all interested mu funcs
for func in funcs {
ret.push(get_path_for_mu_func(func));
}
// mu context
ret.push(get_path_for_mu_context());
// copy primoridal entry
let source = PathBuf::from(runtime::PRIMORDIAL_ENTRY);
let mut dest = PathBuf::from(backend::AOT_EMIT_DIR);
dest.push("main.c");
fs::copy(source.as_path(), dest.as_path()).unwrap();
// include the primordial C main
ret.push(dest);
// include mu static lib
let libmu = PathBuf::from("target/debug/libmu.a");
ret.push(libmu);
ret
};
let mut out_path = emit_dir.clone();
out_path.push(out);
link_executable_internal(files, out_path)
}
pub fn execute(executable: PathBuf) {
let run = Command::new(executable.as_os_str());
assert!(exec(run).status.success());
}
pub fn link_dylib (funcs: Vec<MuName>, out: &str) -> PathBuf {
let files = {
let mut ret = vec![];
for func in funcs {
ret.push(get_path_for_mu_func(func));
}
ret.push(get_path_for_mu_context());
ret
};
pub fn exec (mut cmd: Command) -> Output {
println!("executing: {:?}", cmd);
let output = cmd.output().expect("failed to execute");
let mut out_path = PathBuf::from(backend::AOT_EMIT_DIR);
out_path.push(out);
println!("---out---");
println!("{}", String::from_utf8_lossy(&output.stdout));
println!("---err---");
println!("{}", String::from_utf8_lossy(&output.stderr));
link_dylib_internal(files, out_path)
}
output
}
pub fn compile_fnc<'a>(fnc_name: &'static str, build_fnc: &'a Fn() -> VM) -> ll::Library {
......
......@@ -9,6 +9,7 @@ mod test_ir;
mod test_compiler;
mod test_runtime;
mod test_api;
mod test_jit;
mod common {
use std::fmt;
......
extern crate libloading;
use mu::testutil::c_api::compile_run_c_test;
mod test_binops;
mod test_cmpops;
#[test]
fn test_constant_function() {
let dylib_path = compile_run_c_test("suite/test_constfunc.c");
let lib = libloading::Library::new(dylib_path.as_os_str()).unwrap();
unsafe {
let func : libloading::Symbol<unsafe extern fn() -> i32> = lib.get(b"test_fnc").unwrap();
assert!(func() == 0);
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment