Skip to content

Commit 1b716f6

Browse files
committed
Auto merge of #6599 - Eh2406:more-tests, r=dwijnand
Tweeks to proptests This is some small tweaks to the prop test configuration and adds an additional test. Most of the diff is whitespace.
2 parents e185111 + d9e6360 commit 1b716f6

File tree

2 files changed

+131
-71
lines changed

2 files changed

+131
-71
lines changed

tests/testsuite/resolve.rs

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,11 @@ use crate::support::project;
88
use crate::support::registry::Package;
99
use crate::support::resolver::{
1010
assert_contains, assert_same, dep, dep_kind, dep_loc, dep_req, loc_names, names, pkg, pkg_dep,
11-
pkg_id, pkg_loc, registry, registry_strategy, resolve, resolve_and_validated,
11+
pkg_id, pkg_loc, registry, registry_strategy, remove_dep, resolve, resolve_and_validated,
1212
resolve_with_config, PrettyPrintRegistry, ToDep, ToPkgId,
1313
};
1414

15-
use proptest::collection::vec;
16-
use proptest::prelude::*;
17-
use proptest::*;
15+
use proptest::{prelude::*, *};
1816

1917
/// NOTE: proptest is a form of fuzz testing. It generates random input and makes shore that
2018
/// certain universal truths are upheld. Therefore, it can pass when there is a problem,
@@ -25,20 +23,15 @@ use proptest::*;
2523
/// and if you did not change the resolver then feel free to retry without concern.
2624
proptest! {
2725
#![proptest_config(ProptestConfig {
28-
// Note that this is a little low in terms of cases we'd like to test,
29-
// but this number affects how long this function takes. It can be
30-
// increased locally to execute more tests and try to find more bugs,
31-
// but for now it's semi-low to run in a small-ish amount of time on CI
32-
// and locally.
33-
cases: 256,
3426
max_shrink_iters:
3527
if env::var("CI").is_ok() || !atty::is(atty::Stream::Stderr) {
3628
// This attempts to make sure that CI will fail fast,
3729
0
3830
} else {
3931
// but that local builds will give a small clear test case.
40-
ProptestConfig::default().max_shrink_iters
32+
std::u32::MAX
4133
},
34+
result_cache: prop::test_runner::basic_result_cache,
4235
.. ProptestConfig::default()
4336
})]
4437

@@ -110,11 +103,53 @@ proptest! {
110103
}
111104
}
112105

106+
/// NOTE: if you think this test has failed spuriously see the note at the top of this macro.
107+
#[test]
108+
fn removing_a_dep_cant_brake(
109+
PrettyPrintRegistry(input) in registry_strategy(50, 20, 60),
110+
indexs_to_remove in collection::vec((any::<prop::sample::Index>(), any::<prop::sample::Index>()), ..10)
111+
) {
112+
let reg = registry(input.clone());
113+
let mut removed_input = input.clone();
114+
for (summery_idx, dep_idx) in indexs_to_remove {
115+
if removed_input.len() > 0 {
116+
let summery_idx = summery_idx.index(removed_input.len());
117+
let deps = removed_input[summery_idx].dependencies();
118+
if deps.len() > 0 {
119+
let new = remove_dep(&removed_input[summery_idx], dep_idx.index(deps.len()));
120+
removed_input[summery_idx] = new;
121+
}
122+
}
123+
}
124+
let removed_reg = registry(removed_input);
125+
// there is only a small chance that eny one
126+
// crate will be interesting.
127+
// So we try some of the most complicated.
128+
for this in input.iter().rev().take(10) {
129+
if resolve(
130+
&pkg_id("root"),
131+
vec![dep_req(&this.name(), &format!("={}", this.version()))],
132+
&reg,
133+
).is_ok() {
134+
prop_assert!(
135+
resolve(
136+
&pkg_id("root"),
137+
vec![dep_req(&this.name(), &format!("={}", this.version()))],
138+
&removed_reg,
139+
).is_ok(),
140+
"full index worked for `{} = \"={}\"` but removing some deps broke it!",
141+
this.name(),
142+
this.version(),
143+
)
144+
}
145+
}
146+
}
147+
113148
/// NOTE: if you think this test has failed spuriously see the note at the top of this macro.
114149
#[test]
115150
fn limited_independence_of_irrelevant_alternatives(
116151
PrettyPrintRegistry(input) in registry_strategy(50, 20, 60),
117-
indexs_to_unpublish in vec(any::<prop::sample::Index>(), 10)
152+
indexs_to_unpublish in collection::vec(any::<prop::sample::Index>(), ..10)
118153
) {
119154
let reg = registry(input.clone());
120155
// there is only a small chance that eny one

tests/testsuite/support/resolver.rs

Lines changed: 84 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,20 @@ pub fn pkg_loc(name: &str, loc: &str) -> Summary {
230230
.unwrap()
231231
}
232232

233+
pub fn remove_dep(sum: &Summary, ind: usize) -> Summary {
234+
let mut deps = sum.dependencies().to_vec();
235+
deps.remove(ind);
236+
// note: more things will need to be copied over in the future, but it works for now.
237+
Summary::new(
238+
sum.package_id(),
239+
deps,
240+
&BTreeMap::<String, Vec<String>>::new(),
241+
sum.links().map(|a| a.as_str()),
242+
sum.namespaced_features(),
243+
)
244+
.unwrap()
245+
}
246+
233247
pub fn dep(name: &str) -> Dependency {
234248
dep_req(name, "*")
235249
}
@@ -400,67 +414,78 @@ pub fn registry_strategy(
400414

401415
let list_of_raw_dependency = vec(raw_dependency, ..=max_deps);
402416

403-
(list_of_crates_with_versions, list_of_raw_dependency).prop_map(
404-
|(crate_vers_by_name, raw_dependencies)| {
405-
let list_of_pkgid: Vec<_> = crate_vers_by_name
406-
.iter()
407-
.flat_map(|(name, vers)| vers.iter().map(move |x| ((name.as_str(), &x.0), x.1)))
408-
.collect();
409-
let len_all_pkgid = list_of_pkgid.len();
410-
let mut dependency_by_pkgid = vec![vec![]; len_all_pkgid];
411-
for (a, b, (c, d), k) in raw_dependencies {
412-
let (a, b) = order_index(a, b, len_all_pkgid);
413-
let ((dep_name, _), _) = list_of_pkgid[a];
414-
if (list_of_pkgid[b].0).0 == dep_name {
415-
continue;
416-
}
417-
let s = &crate_vers_by_name[dep_name];
418-
let s_last_index = s.len() - 1;
419-
let (c, d) = order_index(c, d, s.len());
420-
421-
dependency_by_pkgid[b].push(dep_req_kind(
422-
&dep_name,
423-
&if c == 0 && d == s_last_index {
424-
"*".to_string()
425-
} else if c == 0 {
426-
format!("<={}", s[d].0)
427-
} else if d == s_last_index {
428-
format!(">={}", s[c].0)
429-
} else if c == d {
430-
format!("={}", s[c].0)
431-
} else {
432-
format!(">={}, <={}", s[c].0, s[d].0)
433-
},
434-
match k {
435-
0 => Kind::Normal,
436-
1 => Kind::Build,
437-
// => Kind::Development, // Development has not impact so don't gen
438-
_ => panic!("bad index for Kind"),
439-
},
440-
))
441-
}
417+
// By default a package depends only on other packages that have a smaller name,
418+
// this helps make sure that all things in the resulting index are DAGs.
419+
// If this is true then the DAG is maintained with grater instead.
420+
let reverse_alphabetical = any::<bool>().no_shrink();
442421

443-
PrettyPrintRegistry(
444-
list_of_pkgid
445-
.into_iter()
446-
.zip(dependency_by_pkgid.into_iter())
447-
.map(|(((name, ver), allow_deps), deps)| {
448-
pkg_dep(
449-
(name, ver).to_pkgid(),
450-
if !allow_deps {
451-
vec![dep_req("bad", "*")]
452-
} else {
453-
let mut deps = deps;
454-
deps.sort_by_key(|d| d.name_in_toml());
455-
deps.dedup_by_key(|d| d.name_in_toml());
456-
deps
457-
},
458-
)
459-
})
460-
.collect(),
461-
)
462-
},
422+
(
423+
list_of_crates_with_versions,
424+
list_of_raw_dependency,
425+
reverse_alphabetical,
463426
)
427+
.prop_map(
428+
|(crate_vers_by_name, raw_dependencies, reverse_alphabetical)| {
429+
let list_of_pkgid: Vec<_> = crate_vers_by_name
430+
.iter()
431+
.flat_map(|(name, vers)| vers.iter().map(move |x| ((name.as_str(), &x.0), x.1)))
432+
.collect();
433+
let len_all_pkgid = list_of_pkgid.len();
434+
let mut dependency_by_pkgid = vec![vec![]; len_all_pkgid];
435+
for (a, b, (c, d), k) in raw_dependencies {
436+
let (a, b) = order_index(a, b, len_all_pkgid);
437+
let (a, b) = if reverse_alphabetical { (b, a) } else { (a, b) };
438+
let ((dep_name, _), _) = list_of_pkgid[a];
439+
if (list_of_pkgid[b].0).0 == dep_name {
440+
continue;
441+
}
442+
let s = &crate_vers_by_name[dep_name];
443+
let s_last_index = s.len() - 1;
444+
let (c, d) = order_index(c, d, s.len());
445+
446+
dependency_by_pkgid[b].push(dep_req_kind(
447+
&dep_name,
448+
&if c == 0 && d == s_last_index {
449+
"*".to_string()
450+
} else if c == 0 {
451+
format!("<={}", s[d].0)
452+
} else if d == s_last_index {
453+
format!(">={}", s[c].0)
454+
} else if c == d {
455+
format!("={}", s[c].0)
456+
} else {
457+
format!(">={}, <={}", s[c].0, s[d].0)
458+
},
459+
match k {
460+
0 => Kind::Normal,
461+
1 => Kind::Build,
462+
// => Kind::Development, // Development has not impact so don't gen
463+
_ => panic!("bad index for Kind"),
464+
},
465+
))
466+
}
467+
468+
PrettyPrintRegistry(
469+
list_of_pkgid
470+
.into_iter()
471+
.zip(dependency_by_pkgid.into_iter())
472+
.map(|(((name, ver), allow_deps), deps)| {
473+
pkg_dep(
474+
(name, ver).to_pkgid(),
475+
if !allow_deps {
476+
vec![dep_req("bad", "*")]
477+
} else {
478+
let mut deps = deps;
479+
deps.sort_by_key(|d| d.name_in_toml());
480+
deps.dedup_by_key(|d| d.name_in_toml());
481+
deps
482+
},
483+
)
484+
})
485+
.collect(),
486+
)
487+
},
488+
)
464489
}
465490

466491
/// This test is to test the generator to ensure

0 commit comments

Comments
 (0)