# HG changeset patch # User Yuya Nishihara # Date 1571037319 -32400 # Node ID 8d432d3a2d7c2ba332a03e58367efeeb65bcd843 # Parent 434d7a3e92e3465161572768577c0f9ac4a98ef5 rust-cpython: prepare for writing tests that require libpython What I wanted is to disable the "cpython/extension-module" feature while building tests executable, but that seems not doable. Instead, this patch adds new features dedicated for tests. The make rule is extracted so that we can easily run cargo tests. Added a minimal test of ref-sharing as an example. More tests will follow. diff -r 434d7a3e92e3 -r 8d432d3a2d7c Makefile --- a/Makefile Sat Oct 05 10:21:34 2019 -0400 +++ b/Makefile Mon Oct 14 16:15:19 2019 +0900 @@ -113,7 +113,7 @@ tests: # Run Rust tests if cargo is installed if command -v $(CARGO) >/dev/null 2>&1; then \ - cd $(HGROOT)/rust/hg-cpython && $(CARGO) test --quiet --all; \ + $(MAKE) rust-tests; \ fi cd tests && $(PYTHON) run-tests.py $(TESTFLAGS) @@ -127,6 +127,13 @@ $(MAKE) -f $(HGROOT)/contrib/Makefile.python PYTHONVER=$* PREFIX=$(HGPYTHONS)/$* python ) cd tests && $(HGPYTHONS)/$*/bin/python run-tests.py $(TESTFLAGS) +rust-tests: py_feature = $(shell $(PYTHON) -c \ + 'import sys; print(["python27-bin", "python3-bin"][sys.version_info[0] >= 3])') +rust-tests: + cd $(HGROOT)/rust/hg-cpython \ + && $(CARGO) test --quiet --all \ + --no-default-features --features "$(py_feature)" + check-code: hg manifest | xargs python contrib/check-code.py @@ -248,6 +255,7 @@ .PHONY: help all local build doc cleanbutpackages clean install install-bin \ install-doc install-home install-home-bin install-home-doc \ - dist dist-notests check tests check-code format-c update-pot \ + dist dist-notests check tests rust-tests check-code format-c \ + update-pot \ $(packaging_targets) \ osx diff -r 434d7a3e92e3 -r 8d432d3a2d7c rust/hg-cpython/Cargo.toml --- a/rust/hg-cpython/Cargo.toml Sat Oct 05 10:21:34 2019 -0400 +++ b/rust/hg-cpython/Cargo.toml Mon Oct 14 16:15:19 2019 +0900 @@ -11,9 +11,14 @@ [features] default = ["python27"] +# Features to build an extension module: python27 = ["cpython/python27-sys", "cpython/extension-module-2-7"] +python3 = ["cpython/python3-sys", "cpython/extension-module"] -python3 = ["cpython/python3-sys", "cpython/extension-module"] +# Enable one of these features to build a test executable linked to libpython: +# e.g. cargo test --no-default-features --features python27-bin +python27-bin = ["cpython/python27-sys"] +python3-bin = ["cpython/python3-sys"] [dependencies] hg-core = { path = "../hg-core" } diff -r 434d7a3e92e3 -r 8d432d3a2d7c rust/hg-cpython/src/lib.rs --- a/rust/hg-cpython/src/lib.rs Sat Oct 05 10:21:34 2019 -0400 +++ b/rust/hg-cpython/src/lib.rs Mon Oct 14 16:15:19 2019 +0900 @@ -72,3 +72,10 @@ )?; Ok(()) }); + +#[cfg(not(any(feature = "python27-bin", feature = "python3-bin")))] +#[test] +#[ignore] +fn libpython_must_be_linked_to_run_tests() { + // stub function to tell that some tests wouldn't run +} diff -r 434d7a3e92e3 -r 8d432d3a2d7c rust/hg-cpython/src/ref_sharing.rs --- a/rust/hg-cpython/src/ref_sharing.rs Sat Oct 05 10:21:34 2019 -0400 +++ b/rust/hg-cpython/src/ref_sharing.rs Mon Oct 14 16:15:19 2019 +0900 @@ -490,3 +490,34 @@ } }; } + +#[cfg(test)] +#[cfg(any(feature = "python27-bin", feature = "python3-bin"))] +mod test { + use super::*; + use cpython::{GILGuard, Python}; + + py_class!(class Owner |py| { + data string: PySharedRefCell; + }); + py_shared_ref!(Owner, String, string, string_shared); + + fn prepare_env() -> (GILGuard, Owner) { + let gil = Python::acquire_gil(); + let py = gil.python(); + let owner = + Owner::create_instance(py, PySharedRefCell::new("new".to_owned())) + .unwrap(); + (gil, owner) + } + + #[test] + fn test_borrow_mut_while_leaked() { + let (gil, owner) = prepare_env(); + let py = gil.python(); + assert!(owner.string_shared(py).borrow_mut().is_ok()); + let _leaked = owner.string_shared(py).leak_immutable().unwrap(); + // TODO: will be allowed + assert!(owner.string_shared(py).borrow_mut().is_err()); + } +}