Commit e4f2adf25b
Verified · cmc
Layout: unified · split
tests/watch.rs +17 −7
| @@ -152,13 +152,21 @@ fn watching_rebuilds_the_site_when_a_source_file_changes() { | |||
| 152 | let _ = orgo::watch::run(&src_t, &out_t, &BuildOptions::default()); | 152 | let _ = orgo::watch::run(&src_t, &out_t, &BuildOptions::default()); |
| 153 | }); | 153 | }); |
| 154 | 154 | ||
| 155 | // Give the watcher a moment to register before making the change it should see. | 155 | // The edit is repeated rather than made once after a fixed head start. The watcher |
| 156 | std::thread::sleep(Duration::from_millis(300)); | 156 | // registers its OS watches *after* an initial build, and that build loads syntect's |
| 157 | std::fs::write(src.join("index.org"), "#+TITLE: Home\n\nSecond version.\n").unwrap(); | 157 | // syntax set — on a cold CI runner, comfortably longer than any head start worth |
| 158 | 158 | // hard-coding. An edit made before anything is listening produces no event at all, | |
| 159 | let deadline = Instant::now() + Duration::from_secs(20); | 159 | // which looks exactly like a watcher that does not work, and only one of those is a |
| 160 | // defect worth failing a build over. (Found by the first CI run on Linux, where a | ||
| 161 | // 300ms head start was not enough and macOS had never noticed.) | ||
| 162 | let deadline = Instant::now() + Duration::from_secs(30); | ||
| 160 | let mut rebuilt = false; | 163 | let mut rebuilt = false; |
| 164 | let mut wrote_at: Option<Instant> = None; | ||
| 161 | while Instant::now() < deadline { | 165 | while Instant::now() < deadline { |
| 166 | if wrote_at.is_none_or(|t| t.elapsed() >= Duration::from_millis(400)) { | ||
| 167 | std::fs::write(src.join("index.org"), "#+TITLE: Home\n\nSecond version.\n").unwrap(); | ||
| 168 | wrote_at = Some(Instant::now()); | ||
| 169 | } | ||
| 162 | if std::fs::read_to_string(out.join("index.html")) | 170 | if std::fs::read_to_string(out.join("index.html")) |
| 163 | .map(|h| h.contains("Second version.")) | 171 | .map(|h| h.contains("Second version.")) |
| 164 | .unwrap_or(false) | 172 | .unwrap_or(false) |
| @@ -168,7 +176,7 @@ fn watching_rebuilds_the_site_when_a_source_file_changes() { | |||
| 168 | } | 176 | } |
| 169 | std::thread::sleep(Duration::from_millis(50)); | 177 | std::thread::sleep(Duration::from_millis(50)); |
| 170 | } | 178 | } |
| 171 | assert!(rebuilt, "an edit should trigger a rebuild within 20s"); | 179 | assert!(rebuilt, "an edit should trigger a rebuild within 30s"); |
| 172 | 180 | ||
| 173 | // The output lives inside the source, so the rebuild's own writes raised events. If | 181 | // The output lives inside the source, so the rebuild's own writes raised events. If |
| 174 | // those are not filtered out, watch spins forever. | 182 | // those are not filtered out, watch spins forever. |
| @@ -178,8 +186,10 @@ fn watching_rebuilds_the_site_when_a_source_file_changes() { | |||
| 178 | // runaway loop — an assertion on it passes whether or not the filter works, which is | 186 | // runaway loop — an assertion on it passes whether or not the filter works, which is |
| 179 | // exactly what it did before this comment existed. `syntax.css` is rewritten on | 187 | // exactly what it did before this comment existed. `syntax.css` is rewritten on |
| 180 | // every build, so its mtime is a direct record of how many builds have run. | 188 | // every build, so its mtime is a direct record of how many builds have run. |
| 189 | // Long enough for the rebuild from the last repeated write to have landed before the | ||
| 190 | // first reading, or this measures that instead of a feedback loop. | ||
| 181 | let stylesheet = out.join("syntax.css"); | 191 | let stylesheet = out.join("syntax.css"); |
| 182 | std::thread::sleep(Duration::from_millis(700)); | 192 | std::thread::sleep(Duration::from_millis(1500)); |
| 183 | let first = std::fs::metadata(&stylesheet).unwrap().modified().unwrap(); | 193 | let first = std::fs::metadata(&stylesheet).unwrap().modified().unwrap(); |
| 184 | std::thread::sleep(Duration::from_millis(1200)); | 194 | std::thread::sleep(Duration::from_millis(1200)); |
| 185 | let second = std::fs::metadata(&stylesheet).unwrap().modified().unwrap(); | 195 | let second = std::fs::metadata(&stylesheet).unwrap().modified().unwrap(); |