Initial Dever 0.0.1
This commit is contained in:
commit
81233d098c
1479 files changed
+163782
No files matched your search
@@ -0,0 +1,257 @@
|
||||
//! 真实 wheel、回环元数据及命令发布回归,不以字符串匹配代替完整闭包与文件校验。
|
||||
|
||||
use super::python_fixture::{Python, wheel, zip};
|
||||
use dever::compiler::project::dependency::{
|
||||
Lock,
|
||||
library::{self, python},
|
||||
};
|
||||
use dever::compiler::toolchain::BuildTarget;
|
||||
|
||||
#[test]
|
||||
fn python_resolves_wheel_metadata_extras_markers_and_backtracks() {
|
||||
let mut fixture = Python::new();
|
||||
fixture.transport.release("alpha", "1.0.0", "Requires-Dist: common>=1,<3\nRequires-Dist: helper; extra == 'test'\nProvides-Extra: test\nRequires-Dist: windows-only; sys_platform == 'win32'\n");
|
||||
fixture
|
||||
.transport
|
||||
.release("common", "2.0.0", "Requires-Dist: helper>=2\n");
|
||||
fixture
|
||||
.transport
|
||||
.release("common", "1.0.0", "Requires-Dist: helper<2\n");
|
||||
fixture.transport.release("helper", "1.0.0", "");
|
||||
fixture.transport.release("helper", "2.0.0", "");
|
||||
fixture
|
||||
.command("add", &["pip:alpha[test]@1.0.0", "pip:helper@1.0.0"])
|
||||
.unwrap();
|
||||
let lock = fixture.lock();
|
||||
assert_eq!(
|
||||
lock.libs
|
||||
.iter()
|
||||
.map(|lib| lib.spec.key())
|
||||
.collect::<Vec<_>>(),
|
||||
[
|
||||
"pip:alpha[test]@1.0.0",
|
||||
"pip:common@1.0.0",
|
||||
"pip:helper@1.0.0"
|
||||
]
|
||||
);
|
||||
assert!(
|
||||
fixture
|
||||
.transport
|
||||
.requests
|
||||
.borrow()
|
||||
.iter()
|
||||
.all(|url| !url.contains("wrong-registry-summary") && !url.contains("windows-only"))
|
||||
);
|
||||
let metadata = fixture.runtime();
|
||||
let runtime = library::runtime::load(
|
||||
&fixture.signed,
|
||||
"pip",
|
||||
BuildTarget::host().unwrap(),
|
||||
&metadata.pack,
|
||||
)
|
||||
.unwrap();
|
||||
for lib in &lock.libs {
|
||||
let files = python::install(
|
||||
lib,
|
||||
&fixture.store.0.borrow()[&lib.artifacts[0].sha256],
|
||||
&runtime.manifest,
|
||||
&lock.libs,
|
||||
)
|
||||
.unwrap();
|
||||
assert!(files.keys().any(|path| path.ends_with("__init__.py")));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn selected_update_preserves_other_roots_and_exact_install_never_resolves() {
|
||||
let mut fixture = Python::new();
|
||||
for (name, version) in [("alpha", "1.0.0"), ("alpha", "2.0.0"), ("beta", "1.0.0")] {
|
||||
fixture.transport.release(name, version, "");
|
||||
}
|
||||
fixture
|
||||
.command("add", &["pip:alpha@1.0.0", "pip:beta@1.0.0"])
|
||||
.unwrap();
|
||||
fixture.command("update", &["pip:alpha@2.0.0"]).unwrap();
|
||||
let lock = fixture.lock();
|
||||
assert_eq!(
|
||||
lock.libs
|
||||
.iter()
|
||||
.map(|lib| lib.spec.key())
|
||||
.collect::<Vec<_>>(),
|
||||
["pip:alpha@2.0.0", "pip:beta@1.0.0"]
|
||||
);
|
||||
let root = &fixture.fixture.directory.0;
|
||||
let before = [
|
||||
std::fs::read(root.join("config/setting.json")).unwrap(),
|
||||
std::fs::read(root.join("dever.lock")).unwrap(),
|
||||
];
|
||||
fixture.store.0.borrow_mut().clear();
|
||||
fixture.transport.requests.borrow_mut().clear();
|
||||
fixture.command("install", &[]).unwrap();
|
||||
assert_eq!(fixture.transport.requests.borrow().len(), 2);
|
||||
assert!(
|
||||
fixture
|
||||
.transport
|
||||
.requests
|
||||
.borrow()
|
||||
.iter()
|
||||
.all(|url| url.starts_with("https://files.pythonhosted.org/"))
|
||||
);
|
||||
assert_eq!(fixture.store.0.borrow().len(), 2);
|
||||
fixture.transport.requests.borrow_mut().clear();
|
||||
let cache = fixture.store.0.borrow().clone();
|
||||
for action in ["install", "doctor"] {
|
||||
fixture.store.1.borrow_mut().clear();
|
||||
fixture.command(action, &[]).unwrap();
|
||||
let reads = fixture.store.1.borrow();
|
||||
let read_bytes = reads.iter().map(|(_, bytes)| bytes).sum::<usize>();
|
||||
eprintln!(
|
||||
"cache {action}: reads={} bytes={read_bytes} fixtures={:?}",
|
||||
reads.len(),
|
||||
cache.keys().collect::<Vec<_>>()
|
||||
);
|
||||
assert_eq!(reads.len(), cache.len());
|
||||
assert_eq!(read_bytes, cache.values().map(Vec::len).sum::<usize>());
|
||||
for hash in cache.keys() {
|
||||
assert_eq!(reads.iter().filter(|(key, _)| key == hash).count(), 1);
|
||||
}
|
||||
}
|
||||
assert_eq!(*fixture.store.0.borrow(), cache);
|
||||
assert!(fixture.transport.requests.borrow().is_empty());
|
||||
assert_eq!(
|
||||
before,
|
||||
[
|
||||
std::fs::read(root.join("config/setting.json")).unwrap(),
|
||||
std::fs::read(root.join("dever.lock")).unwrap()
|
||||
]
|
||||
);
|
||||
let hash = cache.keys().next().unwrap();
|
||||
for damaged in [vec![0; cache[hash].len()], vec![]] {
|
||||
fixture.store.0.borrow_mut().insert(hash.clone(), damaged);
|
||||
for action in ["install", "doctor"] {
|
||||
assert!(
|
||||
fixture
|
||||
.command(action, &[])
|
||||
.unwrap_err()
|
||||
.contains("digest or length")
|
||||
);
|
||||
assert!(fixture.transport.requests.borrow().is_empty());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn failed_resolution_and_tampered_restore_leave_project_and_cache_unchanged() {
|
||||
let mut fixture = Python::new();
|
||||
fixture.transport.release("alpha", "1.0.0", "");
|
||||
fixture
|
||||
.transport
|
||||
.release("broken", "1.0.0", "Requires-Dist: alpha<1\n");
|
||||
fixture.command("add", &["pip:alpha@1.0.0"]).unwrap();
|
||||
let root = &fixture.fixture.directory.0;
|
||||
let before = [
|
||||
std::fs::read(root.join("config/setting.json")).unwrap(),
|
||||
std::fs::read(root.join("dever.lock")).unwrap(),
|
||||
];
|
||||
assert!(
|
||||
fixture
|
||||
.command("add", &["pip:broken@1.0.0"])
|
||||
.unwrap_err()
|
||||
.contains("conflict")
|
||||
);
|
||||
let source = fixture.lock().libs[0].artifacts[0]
|
||||
.source
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.locator
|
||||
.clone();
|
||||
fixture.transport.files.insert(source, b"tampered".to_vec());
|
||||
fixture.store.0.borrow_mut().clear();
|
||||
assert!(
|
||||
fixture
|
||||
.command("install", &[])
|
||||
.unwrap_err()
|
||||
.contains("digest")
|
||||
);
|
||||
assert!(fixture.store.0.borrow().is_empty());
|
||||
assert_eq!(
|
||||
before,
|
||||
[
|
||||
std::fs::read(root.join("config/setting.json")).unwrap(),
|
||||
std::fs::read(root.join("dever.lock")).unwrap()
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn wheel_record_rejects_mutation_omission_duplicate_and_weak_hash() {
|
||||
let fixture = Python::new();
|
||||
let bytes = wheel("alpha", "1.0.0", "");
|
||||
let lib = serde_json::from_value(serde_json::json!({"spec":{"ecosystem":"pip","name":"alpha","version":"1.0.0"},"dependencies":[],"runtime":fixture.runtime().pack,"artifacts":[],"schema":"pypi-wheel-v1"})).unwrap();
|
||||
let runtime = library::runtime::load(
|
||||
&fixture.signed,
|
||||
"pip",
|
||||
BuildTarget::host().unwrap(),
|
||||
&fixture.runtime().pack,
|
||||
)
|
||||
.unwrap();
|
||||
let original = library::archive::files(&bytes, true).unwrap();
|
||||
python::install(&lib, &bytes, &runtime.manifest, &[]).unwrap();
|
||||
let record = "alpha-1.0.0.dist-info/RECORD";
|
||||
for mode in 0..4 {
|
||||
let mut files = original.clone();
|
||||
match mode {
|
||||
0 => {
|
||||
files.insert("alpha/__init__.py".into(), b"VALUE = 43\n".to_vec());
|
||||
}
|
||||
1 => {
|
||||
files.insert("alpha/extra.py".into(), b"unlisted".to_vec());
|
||||
}
|
||||
2 => {
|
||||
let duplicate = files[record].clone();
|
||||
files.get_mut(record).unwrap().extend_from_slice(&duplicate);
|
||||
}
|
||||
_ => {
|
||||
let text = String::from_utf8(files[record].clone())
|
||||
.unwrap()
|
||||
.replace("sha256=", "md5=");
|
||||
files.insert(record.into(), text.into_bytes());
|
||||
}
|
||||
}
|
||||
assert!(
|
||||
python::install(&lib, &zip(files), &runtime.manifest, &[]).is_err(),
|
||||
"accepted mode {mode}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn python_resolver_failure_does_not_mutate_input_lock() {
|
||||
let mut fixture = Python::new();
|
||||
fixture
|
||||
.transport
|
||||
.release("alpha", "1.0.0", "Requires-Dist: missing>=1\n");
|
||||
let mut lock = Lock::new(vec![]);
|
||||
let before = lock.encode().unwrap();
|
||||
let result = python::resolve(
|
||||
&["pip:alpha@1.0.0".parse().unwrap()],
|
||||
BuildTarget::host().unwrap(),
|
||||
&fixture.runtime(),
|
||||
&fixture.transport,
|
||||
&fixture.store,
|
||||
&mut lock,
|
||||
);
|
||||
assert!(result.is_err());
|
||||
assert_eq!(lock.encode().unwrap(), before);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn self_requirements_are_checked_without_a_spurious_locked_edge() {
|
||||
let mut fixture = Python::new();
|
||||
fixture
|
||||
.transport
|
||||
.release("alpha", "1.0.0", "Requires-Dist: alpha>=1\n");
|
||||
fixture.command("add", &["pip:alpha@1.0.0"]).unwrap();
|
||||
assert!(fixture.lock().libs[0].dependencies.is_empty());
|
||||
fixture.command("doctor", &[]).unwrap();
|
||||
}
|
||||
Reference in new issue
Block a user