Improve tests

* Don’t forget to CI the thread-local support;
* Clean up some tests;
* Properly pass thorugh the target to use for the test helper.
This commit is contained in:
Simonas Kazlauskas
2020-08-22 06:42:11 +03:00
committed by Simonas Kazlauskas
parent adbc5bebba
commit 95c792bfba
8 changed files with 131 additions and 96 deletions
+6
View File
@@ -26,6 +26,9 @@ jobs:
profile: minimal
components: clippy
default: true
- name: Set LIBLOADING_TEST_NIGHTLY
run: echo "::set-env name=LIBLOADING_TEST_NIGHTLY::1"
if: ${{ matrix.rust_toolchain == 'nightly' }}
- name: Update
uses: actions-rs/cargo@v1
with:
@@ -70,6 +73,9 @@ jobs:
- i686-pc-windows-gnu
steps:
- uses: actions/checkout@v2
- name: Set LIBLOADING_TEST_NIGHTLY
run: echo "::set-env name=LIBLOADING_TEST_NIGHTLY::1"
if: ${{ matrix.rust_toolchain == 'nightly' }}
- name: Add MSYS2 to the PATH
run: echo "::add-path::c:/msys64/bin"
- name: Add 32-bit mingw-w64 to the PATH
+7
View File
@@ -61,4 +61,11 @@ fn main() {
::std::process::exit(0xfd);
}
}
// For tests
println!(
"cargo:rustc-env=LIBLOADING_TEST_TARGET={}",
std::env::var("TARGET").expect("$TARGET is not set")
);
println!("cargo:rerun-if-env-changed=LIBLOADING_TEST_NIGHTLY");
}
-21
View File
@@ -128,24 +128,3 @@ impl std::fmt::Display for Error {
}
}
}
#[cfg(test)]
mod tests {
#[test]
fn error_send() {
fn assert_send<T: Send>() {}
assert_send::<super::Error>();
}
#[test]
fn error_sync() {
fn assert_sync<T: Sync>() {}
assert_sync::<super::Error>();
}
#[test]
fn error_display() {
fn assert_display<T: std::fmt::Display>() {}
assert_display::<super::Error>();
}
}
-8
View File
@@ -406,11 +406,3 @@ struct DlInfo {
dli_sname: *const raw::c_char,
dli_saddr: *mut raw::c_void
}
#[cfg(test)]
mod tests {
#[test]
fn this() {
super::Library::this();
}
}
-47
View File
@@ -348,50 +348,3 @@ where F: FnOnce() -> Option<T> {
}
})
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn works_getlasterror() {
let lib = Library::new("kernel32.dll").unwrap();
let gle: Symbol<unsafe extern "system" fn() -> DWORD> = unsafe {
lib.get(b"GetLastError").unwrap()
};
unsafe {
errhandlingapi::SetLastError(42);
assert_eq!(errhandlingapi::GetLastError(), gle())
}
}
#[test]
fn works_getlasterror0() {
let lib = Library::new("kernel32.dll").unwrap();
let gle: Symbol<unsafe extern "system" fn() -> DWORD> = unsafe {
lib.get(b"GetLastError\0").unwrap()
};
unsafe {
errhandlingapi::SetLastError(42);
assert_eq!(errhandlingapi::GetLastError(), gle())
}
}
#[test]
fn library_this_get() {
use std::sync::atomic::{AtomicBool, Ordering};
static VARIABLE: AtomicBool = AtomicBool::new();
#[no_mangle]
extern "C" fn library_this_get_test_fn() {
VARIABLE.store(true, Ordering::SeqCst);
}
let lib = Library::this().expect("this library");
let test_fn: Symbol<unsafe extern "C" fn()> = unsafe {
lib.get(b"library_this_get_test_fn\0").expect("get symbol");
};
assert_eq!(VARIABLE.load(Ordering::SeqCst), false);
test_fn();
assert_eq!(VARIABLE.load(Ordering::SeqCst), true);
}
}
+4 -4
View File
@@ -1,7 +1,7 @@
//! This is a separate file containing helpers for tests of this library. It is built into a
//! dynamic library by the build.rs script.
#![crate_type="dylib"] // FIXME: should become a cdylib in due time
#![cfg_attr(test_nightly, feature(thread_local))]
#![crate_type="cdylib"]
#![cfg_attr(thread_local, feature(thread_local))]
#[no_mangle]
pub static mut TEST_STATIC_U32: u32 = 0;
@@ -9,7 +9,7 @@ pub static mut TEST_STATIC_U32: u32 = 0;
#[no_mangle]
pub static mut TEST_STATIC_PTR: *mut () = 0 as *mut _;
#[cfg(test_nightly)]
#[cfg(thread_local)]
#[thread_local]
#[no_mangle]
pub static mut TEST_THREAD_LOCAL: u32 = 0;
@@ -42,7 +42,7 @@ pub unsafe extern "C" fn test_check_static_ptr() -> bool {
TEST_STATIC_PTR == (&mut TEST_STATIC_PTR as *mut *mut _ as *mut _)
}
#[cfg(test_nightly)]
#[cfg(thread_local)]
#[no_mangle]
pub unsafe extern "C" fn test_get_thread_local() -> u32 {
TEST_THREAD_LOCAL
+97 -16
View File
@@ -1,19 +1,28 @@
#[cfg(windows)]
extern crate winapi;
extern crate libloading;
use libloading::{Symbol, Library};
const LIBPATH: &'static str = concat!(env!("OUT_DIR"), "/libtest_helpers.dll");
const LIBPATH: &'static str = concat!(env!("OUT_DIR"), "/libtest_helpers.module");
fn make_helpers() {
static ONCE: ::std::sync::Once = ::std::sync::Once::new();
ONCE.call_once(|| {
let mut outpath = String::from(if let Some(od) = option_env!("OUT_DIR") { od } else { return });
let rustc = option_env!("RUSTC").unwrap_or_else(|| { "rustc".into() });
outpath.push_str(&"/libtest_helpers.dll"); // extension for windows required, POSIX does not care.
let _ = ::std::process::Command::new(rustc)
let mut cmd = ::std::process::Command::new(rustc);
cmd
.arg("src/test_helpers.rs")
.arg("-o")
.arg(outpath)
.arg("-O")
.arg(LIBPATH)
.arg("--target")
.arg(env!("LIBLOADING_TEST_TARGET"))
.arg("-O");
if std::env::var_os("LIBLOADING_TEST_NIGHTLY").is_some() {
cmd.arg("--cfg").arg("thread_local");
}
cmd
.output()
.expect("could not compile the test helpers!");
});
@@ -137,19 +146,91 @@ fn test_static_ptr() {
}
#[cfg(any(windows, target_os="linux"))]
#[cfg(test_nightly)]
#[test]
fn test_tls_static() {
make_helpers();
let lib = Library::new(LIBPATH).unwrap();
unsafe {
let var: Symbol<*mut u32> = lib.get(b"TEST_THREAD_LOCAL\0").unwrap();
**var = 84;
let help: Symbol<unsafe extern fn() -> u32> = lib.get(b"test_get_thread_local\0").unwrap();
assert_eq!(84, help());
if std::env::var_os("LIBLOADING_TEST_NIGHTLY").is_some() {
unsafe {
let var: Symbol<*mut u32> = lib.get(b"TEST_THREAD_LOCAL\0").unwrap();
**var = 84;
let help: Symbol<unsafe extern fn() -> u32> = lib.get(b"test_get_thread_local\0").unwrap();
assert_eq!(84, help());
}
::std::thread::spawn(move || unsafe {
let help: Symbol<unsafe extern fn() -> u32> = lib.get(b"test_get_thread_local\0").unwrap();
assert_eq!(0, help());
}).join().unwrap();
} else {
unsafe {
assert!(lib.get::<Symbol<*mut u32>>(b"TEST_THREAD_LOCAL\0").is_err());
}
}
}
#[cfg(unix)]
#[test]
fn library_this_get() {
use libloading::os::unix::Library;
make_helpers();
let _lib = Library::new(LIBPATH).unwrap();
let this = Library::this();
// SAFE: functions are never called
unsafe {
// Library we loaded in `_lib` (should be RTLD_LOCAL).
// FIXME: inconsistent behaviour between macos and other posix systems
// assert!(this.get::<unsafe extern "C" fn()>(b"test_identity_u32").is_err());
// Something obscure from libc...
assert!(this.get::<unsafe extern "C" fn()>(b"freopen").is_ok());
}
}
#[cfg(windows)]
#[test]
fn library_this() {
use libloading::os::windows::Library;
make_helpers();
let _lib = Library::new(LIBPATH).unwrap();
let this = Library::this().expect("this library");
// SAFE: functions are never called
unsafe {
// Library we loaded in `_lib`.
assert!(this.get::<unsafe extern "C" fn()>(b"test_identity_u32").is_err());
// Something "obscure" from kernel32...
assert!(this.get::<unsafe extern "C" fn()>(b"GetLastError").is_err());
}
}
#[cfg(windows)]
#[test]
fn works_getlasterror() {
use winapi::um::errhandlingapi;
use winapi::shared::minwindef::DWORD;
use libloading::os::windows::{Library, Symbol};
let lib = Library::new("kernel32.dll").unwrap();
let gle: Symbol<unsafe extern "system" fn() -> DWORD> = unsafe {
lib.get(b"GetLastError").unwrap()
};
unsafe {
errhandlingapi::SetLastError(42);
assert_eq!(errhandlingapi::GetLastError(), gle())
}
}
#[cfg(windows)]
#[test]
fn works_getlasterror0() {
use winapi::um::errhandlingapi;
use winapi::shared::minwindef::DWORD;
use libloading::os::windows::{Library, Symbol};
let lib = Library::new("kernel32.dll").unwrap();
let gle: Symbol<unsafe extern "system" fn() -> DWORD> = unsafe {
lib.get(b"GetLastError\0").unwrap()
};
unsafe {
errhandlingapi::SetLastError(42);
assert_eq!(errhandlingapi::GetLastError(), gle())
}
::std::thread::spawn(move || unsafe {
let help: Symbol<unsafe extern fn() -> u32> = lib.get(b"test_get_thread_local\0").unwrap();
assert_eq!(0, help());
}).join().unwrap();
}
+17
View File
@@ -4,6 +4,23 @@ extern crate libloading;
fn assert_send<T: Send>() {}
#[cfg(test)]
fn assert_sync<T: Sync>() {}
#[cfg(test)]
fn assert_display<T: std::fmt::Display>() {}
#[test]
fn check_error_send() {
assert_send::<libloading::Error>();
}
#[test]
fn check_error_sync() {
assert_sync::<libloading::Error>();
}
#[test]
fn check_error_display() {
assert_display::<libloading::Error>();
}
#[test]
fn check_library_send() {