-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a test suite for programs using libgc + rustgc
- Loading branch information
1 parent
70ae093
commit 17cf277
Showing
4 changed files
with
132 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
use std::{env, path::PathBuf, process::Command}; | ||
|
||
use lang_tester::LangTester; | ||
use tempfile::TempDir; | ||
|
||
fn deps_path() -> String { | ||
let mut path = PathBuf::new(); | ||
path.push(env::var("CARGO_MANIFEST_DIR").unwrap()); | ||
path.push("target"); | ||
#[cfg(debug_assertions)] | ||
path.push("debug"); | ||
#[cfg(not(debug_assertions))] | ||
path.push("release"); | ||
path.push("deps"); | ||
|
||
path.to_str().unwrap().to_owned() | ||
} | ||
|
||
fn main() { | ||
let rustc = env::var("RUSTGC").expect("RUSTGC environment var not specified"); | ||
// We grab the rlibs from `target/<debug | release>/` but in order | ||
// for them to exist here, they must have been moved from `deps/`. | ||
// Simply running `cargo test` will not do this, instead, we must | ||
// ensure that `cargo build` has been run before running the tests. | ||
|
||
#[cfg(debug_assertions)] | ||
let build_mode = "--debug"; | ||
#[cfg(not(debug_assertions))] | ||
let build_mode = "--release"; | ||
|
||
Command::new("cargo") | ||
.args(&["build", build_mode]) | ||
.env("RUSTC", &rustc.as_str()) | ||
.output() | ||
.expect("Failed to build libs"); | ||
|
||
let tempdir = TempDir::new().unwrap(); | ||
LangTester::new() | ||
.test_dir("gc_tests/tests") | ||
.test_file_filter(|p| p.extension().unwrap().to_str().unwrap() == "rs") | ||
.test_extract(|s| { | ||
Some( | ||
s.lines() | ||
.take_while(|l| l.starts_with("//")) | ||
.map(|l| &l[2..]) | ||
.collect::<Vec<_>>() | ||
.join("\n"), | ||
) | ||
}) | ||
.test_cmds(move |p| { | ||
let mut exe = PathBuf::new(); | ||
exe.push(&tempdir); | ||
exe.push(p.file_stem().unwrap()); | ||
|
||
let mut compiler = Command::new(&rustc); | ||
compiler.args(&[ | ||
"-L", | ||
deps_path().as_str(), | ||
p.to_str().unwrap(), | ||
"-o", | ||
exe.to_str().unwrap(), | ||
]); | ||
|
||
vec![("Compiler", compiler), ("Run-time", Command::new(exe))] | ||
}) | ||
.run(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// Run-time: | ||
// status: success | ||
#![feature(rustc_private)] | ||
|
||
extern crate libgc; | ||
|
||
use std::alloc::GcAllocator; | ||
use std::{thread, time}; | ||
use std::sync::atomic::{AtomicBool, Ordering}; | ||
use libgc::Gc; | ||
|
||
#[global_allocator] | ||
static ALLOCATOR: GcAllocator = GcAllocator; | ||
|
||
struct PanicOnDrop(String); | ||
|
||
impl Drop for PanicOnDrop { | ||
fn drop(&mut self) { | ||
eprintln!("Finalizer called. Object erroneously collected"); | ||
} | ||
|
||
} | ||
|
||
static mut NO_CHILD_EXISTS: AtomicBool = AtomicBool::new(true); | ||
|
||
fn main() { | ||
for _ in 1..10 { | ||
thread::spawn(child); | ||
} | ||
|
||
while(unsafe { NO_CHILD_EXISTS.load(Ordering::SeqCst) }) {}; | ||
|
||
// This should collect no garbage, because the call stacks of each child | ||
// thread should be scanned for roots. | ||
GcAllocator::force_gc(); | ||
|
||
// If there's a problem, a finalizer will print to stderr. Lets wait an | ||
// appropriate amount of time for this to happen. | ||
thread::sleep(time::Duration::from_millis(10)); | ||
} | ||
|
||
fn child() { | ||
unsafe { NO_CHILD_EXISTS.store(false, Ordering::SeqCst)}; | ||
let gc = Gc::new(String::from("Hello world!")); | ||
|
||
// Wait a bit before dying, ensuring that the thread stays alive long enough | ||
// cross the force_gc call. | ||
thread::sleep(time::Duration::from_millis(10)); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters