Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 7b06315

Browse files
authored
Merge pull request rust-lang#1661 from Kobzol/cargo-lock-check
Check that `Cargo.lock` doesn't change
2 parents fe06474 + f462af2 commit 7b06315

File tree

3 files changed

+60
-1
lines changed

3 files changed

+60
-1
lines changed

collector/src/compile/execute/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::compile::benchmark::profile::Profile;
55
use crate::compile::benchmark::scenario::Scenario;
66
use crate::compile::benchmark::BenchmarkName;
77
use crate::toolchain::Toolchain;
8+
use crate::utils::fs::EnsureImmutableFile;
89
use crate::{async_command_output, command_output, utils};
910
use anyhow::Context;
1011
use bencher::Bencher;
@@ -203,6 +204,12 @@ impl<'a> CargoProcess<'a> {
203204
);
204205

205206
loop {
207+
// Make sure that Cargo.lock isn't changed by the build
208+
let _guard = EnsureImmutableFile::new(
209+
&self.cwd.join("Cargo.lock"),
210+
self.processor_name.0.clone(),
211+
)?;
212+
206213
// Get the subcommand. If it's not `rustc` it must should be a
207214
// subcommand that itself invokes `rustc` (so that the `FAKE_RUSTC`
208215
// machinery works).
@@ -316,6 +323,7 @@ impl<'a> CargoProcess<'a> {
316323

317324
let cmd = tokio::process::Command::from(cmd);
318325
let output = async_command_output(cmd).await?;
326+
319327
if let Some((ref mut processor, scenario, scenario_str, patch)) = self.processor_etc {
320328
let data = ProcessOutputData {
321329
name: self.processor_name.clone(),

collector/src/runtime/benchmark.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::runtime_group_step_name;
22
use crate::toolchain::Toolchain;
3+
use crate::utils::fs::EnsureImmutableFile;
34
use anyhow::Context;
45
use benchlib::benchmark::passes_filter;
56
use cargo_metadata::Message;
@@ -195,6 +196,14 @@ pub fn prepare_runtime_benchmark_suite(
195196

196197
let target_dir = temp_dir.as_ref().map(|d| d.path());
197198

199+
// Make sure that Cargo.lock isn't changed by the build if we're running in isolated mode
200+
let _guard = match isolation_mode {
201+
CargoIsolationMode::Cached => None,
202+
CargoIsolationMode::Isolated => Some(EnsureImmutableFile::new(
203+
&benchmark_crate.path.join("Cargo.lock"),
204+
benchmark_crate.name.clone(),
205+
)?),
206+
};
198207
let result = start_cargo_build(toolchain, &benchmark_crate.path, target_dir, &opts)
199208
.with_context(|| {
200209
anyhow::anyhow!("Cannot start compilation of {}", benchmark_crate.name)

collector/src/utils/fs.rs

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use anyhow::Context;
2+
use std::collections::hash_map::DefaultHasher;
23
use std::ffi::OsStr;
34
use std::fs;
4-
use std::path::{Component, Path};
5+
use std::hash::{Hash, Hasher};
6+
use std::path::{Component, Path, PathBuf};
57
use std::process::Command;
68

79
#[cfg(windows)]
@@ -142,6 +144,46 @@ pub fn robocopy(
142144
Ok(())
143145
}
144146

147+
/// Loads contents of a file and hashes it when it is created.
148+
/// It then asserts that when it is dropped, the file still has the same contents.
149+
#[must_use = "EnsureImmutableFile acts like a guard, consider keeping it alive until something can happen with the file"]
150+
pub struct EnsureImmutableFile {
151+
path: PathBuf,
152+
hash: u64,
153+
name: String,
154+
}
155+
156+
impl EnsureImmutableFile {
157+
pub fn new(path: &Path, name: String) -> anyhow::Result<Self> {
158+
let hash = Self::hash(path)?;
159+
Ok(Self {
160+
path: path.to_path_buf(),
161+
hash,
162+
name,
163+
})
164+
}
165+
166+
fn hash(path: &Path) -> anyhow::Result<u64> {
167+
let contents = fs::read(path)?;
168+
let mut hasher = DefaultHasher::new();
169+
contents.hash(&mut hasher);
170+
Ok(hasher.finish())
171+
}
172+
}
173+
174+
impl Drop for EnsureImmutableFile {
175+
fn drop(&mut self) {
176+
let hash = Self::hash(&self.path).expect("Cannot hash file");
177+
assert_eq!(
178+
self.hash,
179+
hash,
180+
"{} ({}) has changed during a build",
181+
self.path.display(),
182+
self.name
183+
);
184+
}
185+
}
186+
145187
#[cfg(test)]
146188
mod tests {
147189
use super::get_file_count_and_size;

0 commit comments

Comments
 (0)