test(host-cache): changed declarations recompile project.so
HostCacheSourceStamp already edits a module source with a backdated mtime and expects the PCM cache to be rebuilt. Its own header names the real danger, a project.so compiled against declarations that no longer match the process it is loaded into, but it never looked at the project.so. It now records the file's mtime before the edit and expects a newer one after it, with project.cpp untouched, so only the stamp can force the rebuild. Fails without the previous commit: the stamp was the version string alone and the project.so was reused. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
e280c955f7
commit
e985f2724b
1 changed files with 16 additions and 0 deletions
|
|
@ -119,6 +119,17 @@ int main() {
|
||||||
Check(fs::last_write_time(probePcm) == afterCold, "unchanged sources do not rebuild the cache");
|
Check(fs::last_write_time(probePcm) == afterCold, "unchanged sources do not rebuild the cache");
|
||||||
Check(ReadStamp(moduleCacheDir) == firstStamp, "unchanged sources keep the same stamp");
|
Check(ReadStamp(moduleCacheDir) == firstStamp, "unchanged sources keep the same stamp");
|
||||||
|
|
||||||
|
// The compiled project file is the other half of the same hazard: it is
|
||||||
|
// loaded into this process and must have been compiled against the
|
||||||
|
// declarations this process was built from.
|
||||||
|
fs::path projectSo;
|
||||||
|
for (const fs::directory_entry& entry : fs::recursive_directory_iterator(projectDir)) {
|
||||||
|
if (entry.path().filename() == "project.so") projectSo = entry.path();
|
||||||
|
}
|
||||||
|
Check(!projectSo.empty(), "the project file was compiled to a project.so");
|
||||||
|
if (projectSo.empty()) return 1;
|
||||||
|
const fs::file_time_type soBeforeEdit = fs::last_write_time(projectSo);
|
||||||
|
|
||||||
// Now the case the mtime rule cannot see. The edit lands in a module the
|
// Now the case the mtime rule cannot see. The edit lands in a module the
|
||||||
// probe does not name, because the cached PCMs import each other: a change
|
// probe does not name, because the cached PCMs import each other: a change
|
||||||
// anywhere in the set invalidates all of them.
|
// anywhere in the set invalidates all of them.
|
||||||
|
|
@ -139,6 +150,11 @@ int main() {
|
||||||
|
|
||||||
Check(fs::last_write_time(probePcm) > afterCold, "a content change rebuilds the cache even when the source's mtime is older");
|
Check(fs::last_write_time(probePcm) > afterCold, "a content change rebuilds the cache even when the source's mtime is older");
|
||||||
Check(ReadStamp(moduleCacheDir) != firstStamp, "the recorded stamp follows the sources");
|
Check(ReadStamp(moduleCacheDir) != firstStamp, "the recorded stamp follows the sources");
|
||||||
|
// project.cpp itself is untouched, so only the stamp can force this. It
|
||||||
|
// once covered the version string alone (the rest sat behind a NUL in a
|
||||||
|
// format string): a project.so built against a class of another size was
|
||||||
|
// reused and corrupted the heap when it filled one in.
|
||||||
|
Check(fs::last_write_time(projectSo) > soBeforeEdit, "changed declarations recompile project.so even though project.cpp is unchanged");
|
||||||
|
|
||||||
fs::remove_all(scratch, ec);
|
fs::remove_all(scratch, ec);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue