@@ -97,6 +97,78 @@ TEST(BmiCache, PopulateThenStageRoundTrip) {
9797 EXPECT_EQ (body, " OBJ-A" );
9898}
9999
100+ TEST (BmiCache, StageIntoDoesNotTouchIdenticalOutputs) {
101+ Tmp t;
102+ auto home = t.path / " home" ;
103+ auto project = t.path / " proj" / " target" ;
104+ std::filesystem::create_directories (project / " gcm.cache" );
105+ std::filesystem::create_directories (project / " obj" );
106+
107+ writeFile (project / " gcm.cache" / " mcpplibs.cmdline.gcm" , " GCM-A" );
108+ writeFile (project / " obj" / " cmdline.m.o" , " OBJ-A" );
109+
110+ DepArtifacts arts {
111+ .gcmFiles = { " mcpplibs.cmdline.gcm" },
112+ .objFiles = { " cmdline.m.o" },
113+ };
114+
115+ auto k = makeKey (home);
116+ ASSERT_TRUE (populate_from (k, project, arts));
117+
118+ auto staged = stage_into (k, project);
119+ ASSERT_TRUE (staged) << staged.error ();
120+ auto gcmTime = std::filesystem::last_write_time (project / " gcm.cache" / " mcpplibs.cmdline.gcm" );
121+ auto objTime = std::filesystem::last_write_time (project / " obj" / " cmdline.m.o" );
122+
123+ auto stagedAgain = stage_into (k, project);
124+ ASSERT_TRUE (stagedAgain) << stagedAgain.error ();
125+ EXPECT_EQ (std::filesystem::last_write_time (project / " gcm.cache" / " mcpplibs.cmdline.gcm" ), gcmTime);
126+ EXPECT_EQ (std::filesystem::last_write_time (project / " obj" / " cmdline.m.o" ), objTime);
127+ }
128+
129+ TEST (BmiCache, StageIntoDoesNotOverwriteExistingOutputs) {
130+ Tmp t;
131+ auto home = t.path / " home" ;
132+ auto cacheProject = t.path / " cache-proj" / " target" ;
133+ auto project = t.path / " proj" / " target" ;
134+ std::filesystem::create_directories (cacheProject / " gcm.cache" );
135+ std::filesystem::create_directories (cacheProject / " obj" );
136+ std::filesystem::create_directories (project / " gcm.cache" );
137+ std::filesystem::create_directories (project / " obj" );
138+
139+ writeFile (cacheProject / " gcm.cache" / " mcpplibs.cmdline.gcm" , " CACHE-GCM" );
140+ writeFile (cacheProject / " obj" / " cmdline.m.o" , " CACHE-OBJ" );
141+
142+ DepArtifacts arts {
143+ .gcmFiles = { " mcpplibs.cmdline.gcm" },
144+ .objFiles = { " cmdline.m.o" },
145+ };
146+
147+ auto k = makeKey (home);
148+ ASSERT_TRUE (populate_from (k, cacheProject, arts));
149+
150+ writeFile (project / " gcm.cache" / " mcpplibs.cmdline.gcm" , " PROJECT-GCM" );
151+ writeFile (project / " obj" / " cmdline.m.o" , " PROJECT-OBJ" );
152+ auto gcmTime = std::filesystem::last_write_time (project / " gcm.cache" / " mcpplibs.cmdline.gcm" );
153+ auto objTime = std::filesystem::last_write_time (project / " obj" / " cmdline.m.o" );
154+
155+ auto staged = stage_into (k, project);
156+ ASSERT_TRUE (staged) << staged.error ();
157+
158+ {
159+ std::ifstream is (project / " gcm.cache" / " mcpplibs.cmdline.gcm" );
160+ std::string body ((std::istreambuf_iterator<char >(is)), {});
161+ EXPECT_EQ (body, " PROJECT-GCM" );
162+ }
163+ {
164+ std::ifstream is (project / " obj" / " cmdline.m.o" );
165+ std::string body ((std::istreambuf_iterator<char >(is)), {});
166+ EXPECT_EQ (body, " PROJECT-OBJ" );
167+ }
168+ EXPECT_EQ (std::filesystem::last_write_time (project / " gcm.cache" / " mcpplibs.cmdline.gcm" ), gcmTime);
169+ EXPECT_EQ (std::filesystem::last_write_time (project / " obj" / " cmdline.m.o" ), objTime);
170+ }
171+
100172TEST (BmiCache, IsCachedFalseWhenSentinelExistsButFileMissing) {
101173 Tmp t;
102174 auto home = t.path / " home" ;
0 commit comments