110 lines
3.7 KiB
Rust
110 lines
3.7 KiB
Rust
//! 源码 hook 真正执行签名 Python/C 工具;安装回放与失败均保持原始项目文件。
|
|
|
|
use super::{pep517_fixture, python_fixture::Python};
|
|
use dever::compiler::project::dependency::library::lock::receipt::Receipt;
|
|
|
|
#[test]
|
|
fn pep517_native_build_and_exact_install_replay_use_locked_static_dynamic_inputs() {
|
|
let mut fixture = Python::new();
|
|
pep517_fixture::prepare(&mut fixture, "stable");
|
|
fixture.command("add", &["pip:built-native@1.0.0"]).unwrap();
|
|
let lock = fixture.lock();
|
|
assert_eq!(
|
|
lock.libs
|
|
.iter()
|
|
.map(|lib| lib.spec.key())
|
|
.collect::<Vec<_>>(),
|
|
["pip:built-native@1.0.0", "pip:runtime-helper@1.0.0"]
|
|
);
|
|
let receipt = Receipt::parse(&lock.builds[0]).unwrap();
|
|
assert_eq!(
|
|
receipt
|
|
.inputs
|
|
.libs
|
|
.iter()
|
|
.map(|lib| lib.spec.key())
|
|
.collect::<Vec<_>>(),
|
|
["pip:build-helper@1.0.0", "pip:dynamic-helper@1.0.0"]
|
|
);
|
|
assert_eq!(receipt.dynamic_requires, ["dynamic-helper==1.0.0"]);
|
|
let before = snapshot(&fixture);
|
|
let original = fixture
|
|
.store
|
|
.0
|
|
.borrow_mut()
|
|
.remove(&receipt.output.sha256)
|
|
.unwrap();
|
|
fixture.transport.requests.borrow_mut().clear();
|
|
fixture.command("install", &[]).unwrap();
|
|
assert_eq!(fixture.store.0.borrow()[&receipt.output.sha256], original);
|
|
assert!(fixture.transport.requests.borrow().is_empty());
|
|
assert_eq!(snapshot(&fixture), before);
|
|
fixture.command("doctor", &[]).unwrap();
|
|
assert_eq!(snapshot(&fixture), before);
|
|
// 完整冷缓存恢复只下载固定 source/wheel;不请求任何版本 metadata。
|
|
fixture.store.0.borrow_mut().clear();
|
|
fixture.command("install", &[]).unwrap();
|
|
assert!(
|
|
fixture
|
|
.transport
|
|
.requests
|
|
.borrow()
|
|
.iter()
|
|
.all(|url| url.starts_with("https://files.pythonhosted.org/"))
|
|
);
|
|
assert_eq!(fixture.store.0.borrow()[&receipt.output.sha256], original);
|
|
assert_eq!(snapshot(&fixture), before);
|
|
}
|
|
|
|
#[test]
|
|
fn pep517_changed_metadata_and_exit10_preserve_previous_project() {
|
|
for mode in ["mismatch", "exit10"] {
|
|
let mut fixture = Python::new();
|
|
pep517_fixture::prepare(&mut fixture, mode);
|
|
fixture
|
|
.command("add", &["pip:runtime-helper@1.0.0"])
|
|
.unwrap();
|
|
let before = snapshot(&fixture);
|
|
let error = fixture
|
|
.command("add", &["pip:built-native@1.0.0"])
|
|
.unwrap_err();
|
|
assert!(
|
|
error.contains(if mode == "mismatch" {
|
|
"prepared metadata"
|
|
} else {
|
|
"expected PEP517 exit10"
|
|
}),
|
|
"{error}"
|
|
);
|
|
assert_eq!(snapshot(&fixture), before);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn pep517_nonreproducible_replay_preserves_lock_and_does_not_publish_replacement() {
|
|
let mut fixture = Python::new();
|
|
pep517_fixture::prepare(&mut fixture, "unstable");
|
|
fixture.command("add", &["pip:built-native@1.0.0"]).unwrap();
|
|
let lock = fixture.lock();
|
|
let receipt = Receipt::parse(&lock.builds[0]).unwrap();
|
|
fixture.store.0.borrow_mut().remove(&receipt.output.sha256);
|
|
let before = snapshot(&fixture);
|
|
let cache = fixture.store.0.borrow().clone();
|
|
assert!(
|
|
fixture
|
|
.command("install", &[])
|
|
.unwrap_err()
|
|
.contains("not byte reproducible")
|
|
);
|
|
assert_eq!(snapshot(&fixture), before);
|
|
assert_eq!(*fixture.store.0.borrow(), cache);
|
|
}
|
|
|
|
fn snapshot(fixture: &Python) -> [Vec<u8>; 2] {
|
|
let root = &fixture.fixture.directory.0;
|
|
[
|
|
std::fs::read(root.join("config/setting.json")).unwrap(),
|
|
std::fs::read(root.join("dever.lock")).unwrap(),
|
|
]
|
|
}
|