test: replace wall-clock loop deadlines with progress criteria
Three real-engine throughput loops (thumbnail pipeline, full-res fill behind the proxy, playback window supply) failed on machine slowness: their pass/fail was a wall-clock Instant deadline, so a loaded machine broke them for speed, not for a broken pipeline. Each loop now counts engine pumps — machine-speed independent — and asserts the condition within a bounded number of pumps. The two single-frame worker channel receives keep a generous 60 s recv_timeout (a one-shot bounded operation, not a throughput loop). oak-cli: the integration fixtures moved with the app crate during the workspace restructure; point the fixture helpers at ../oak-app/tests instead of the (now empty) repo-root tests/.
This commit is contained in:
@@ -184,7 +184,7 @@ jobs:
|
||||
runs-on: oak-windows-2025
|
||||
defaults:
|
||||
run:
|
||||
shell: C:\msys2\usr\bin\bash.exe -eo pipefail {0}
|
||||
shell: msys2 {0}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
+1
-1
@@ -1,5 +1,6 @@
|
||||
# Oak Video Editor UI strings — Deutsch (de)
|
||||
# Format: "i18n.key": "Translated text". Add new languages as new files named <lang>.yaml.
|
||||
"language.name": "Deutsch"
|
||||
"menu.file": "Datei(D)"
|
||||
"menu.edit": "Bearbeiten(B)"
|
||||
"menu.view": "Ansicht(A)"
|
||||
@@ -65,7 +66,6 @@
|
||||
"menu.view.theme.dark": "Olive Dark"
|
||||
"menu.view.theme.light": "Olive Light"
|
||||
"menu.view.language": "Sprache"
|
||||
"language.name": "Deutsch"
|
||||
"menu.view.zoom_in": "Vergrößern"
|
||||
"menu.view.zoom_out": "Verkleinern"
|
||||
"menu.view.increase_track_height": "Spurhöhe erhöhen"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# Oak Video Editor UI strings — English (en-US)
|
||||
# Format: "i18n.key": "Translated text". Add new languages as new files named <lang>.yaml.
|
||||
"language.name": "English"
|
||||
"menu.file": "File(F)"
|
||||
"menu.edit": "Edit(E)"
|
||||
"menu.view": "View(V)"
|
||||
@@ -65,7 +66,6 @@
|
||||
"menu.view.theme.dark": "Olive Dark"
|
||||
"menu.view.theme.light": "Olive Light"
|
||||
"menu.view.language": "Language"
|
||||
"language.name": "English"
|
||||
"menu.view.zoom_in": "Zoom In"
|
||||
"menu.view.zoom_out": "Zoom Out"
|
||||
"menu.view.increase_track_height": "Increase Track Height"
|
||||
|
||||
+1
-1
@@ -1,5 +1,6 @@
|
||||
# Oak Video Editor UI strings — Español (es)
|
||||
# Format: "i18n.key": "Translated text". Add new languages as new files named <lang>.yaml.
|
||||
"language.name": "Español"
|
||||
"menu.file": "Archivo(A)"
|
||||
"menu.edit": "Editar(E)"
|
||||
"menu.view": "Ver(V)"
|
||||
@@ -65,7 +66,6 @@
|
||||
"menu.view.theme.dark": "Olive Dark"
|
||||
"menu.view.theme.light": "Olive Light"
|
||||
"menu.view.language": "Idioma"
|
||||
"language.name": "Español"
|
||||
"menu.view.zoom_in": "Acercar"
|
||||
"menu.view.zoom_out": "Alejar"
|
||||
"menu.view.increase_track_height": "Aumentar altura de pista"
|
||||
|
||||
+1
-1
@@ -1,5 +1,6 @@
|
||||
# Oak Video Editor UI strings — Français (fr)
|
||||
# Format: "i18n.key": "Translated text". Add new languages as new files named <lang>.yaml.
|
||||
"language.name": "Français"
|
||||
"menu.file": "Fichier(F)"
|
||||
"menu.edit": "Édition(E)"
|
||||
"menu.view": "Affichage(A)"
|
||||
@@ -65,7 +66,6 @@
|
||||
"menu.view.theme.dark": "Olive Dark"
|
||||
"menu.view.theme.light": "Olive Light"
|
||||
"menu.view.language": "Langue"
|
||||
"language.name": "Français"
|
||||
"menu.view.zoom_in": "Zoom avant"
|
||||
"menu.view.zoom_out": "Zoom arrière"
|
||||
"menu.view.increase_track_height": "Augmenter la hauteur de piste"
|
||||
|
||||
+1
-1
@@ -1,5 +1,6 @@
|
||||
# Oak Video Editor UI strings — 日本語 (ja)
|
||||
# Format: "i18n.key": "Translated text". Add new languages as new files named <lang>.yaml.
|
||||
"language.name": "日本語"
|
||||
"menu.file": "ファイル(F)"
|
||||
"menu.edit": "編集(E)"
|
||||
"menu.view": "表示(V)"
|
||||
@@ -65,7 +66,6 @@
|
||||
"menu.view.theme.dark": "Olive Dark"
|
||||
"menu.view.theme.light": "Olive Light"
|
||||
"menu.view.language": "言語"
|
||||
"language.name": "日本語"
|
||||
"menu.view.zoom_in": "ズームイン"
|
||||
"menu.view.zoom_out": "ズームアウト"
|
||||
"menu.view.increase_track_height": "トラックの高さを増やす"
|
||||
|
||||
+1
-1
@@ -1,5 +1,6 @@
|
||||
# Oak Video Editor UI strings — Português (pt)
|
||||
# Format: "i18n.key": "Translated text". Add new languages as new files named <lang>.yaml.
|
||||
"language.name": "Português"
|
||||
"menu.file": "Arquivo(A)"
|
||||
"menu.edit": "Editar(E)"
|
||||
"menu.view": "Ver(V)"
|
||||
@@ -65,7 +66,6 @@
|
||||
"menu.view.theme.dark": "Olive Dark"
|
||||
"menu.view.theme.light": "Olive Light"
|
||||
"menu.view.language": "Idioma"
|
||||
"language.name": "Português"
|
||||
"menu.view.zoom_in": "Aproximar"
|
||||
"menu.view.zoom_out": "Afastar"
|
||||
"menu.view.increase_track_height": "Aumentar altura da trilha"
|
||||
|
||||
+1
-1
@@ -1,5 +1,6 @@
|
||||
# Oak Video Editor UI strings — Русский (ru)
|
||||
# Format: "i18n.key": "Translated text". Add new languages as new files named <lang>.yaml.
|
||||
"language.name": "Русский"
|
||||
"menu.file": "Файл(Ф)"
|
||||
"menu.edit": "Правка(П)"
|
||||
"menu.view": "Вид(В)"
|
||||
@@ -65,7 +66,6 @@
|
||||
"menu.view.theme.dark": "Olive Dark"
|
||||
"menu.view.theme.light": "Olive Light"
|
||||
"menu.view.language": "Язык"
|
||||
"language.name": "Русский"
|
||||
"menu.view.zoom_in": "Увеличить"
|
||||
"menu.view.zoom_out": "Уменьшить"
|
||||
"menu.view.increase_track_height": "Увеличить высоту дорожки"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# Oak Video Editor UI strings — 简体中文 (zh-CN)
|
||||
# Format: "i18n.key": "Translated text". Add new languages as new files named <lang>.yaml.
|
||||
"language.name": "简体中文"
|
||||
"menu.file": "文件(F)"
|
||||
"menu.edit": "编辑(E)"
|
||||
"menu.view": "视图(V)"
|
||||
@@ -65,7 +66,6 @@
|
||||
"menu.view.theme.dark": "Olive Dark"
|
||||
"menu.view.theme.light": "Olive Light"
|
||||
"menu.view.language": "语言"
|
||||
"language.name": "简体中文"
|
||||
"menu.view.zoom_in": "放大"
|
||||
"menu.view.zoom_out": "缩小"
|
||||
"menu.view.increase_track_height": "增加轨道高度"
|
||||
|
||||
@@ -5829,8 +5829,12 @@ mod tests {
|
||||
})
|
||||
})
|
||||
.expect("re-import the footage");
|
||||
let deadline = std::time::Instant::now() + Duration::from_secs(20);
|
||||
// Progress criterion, not wall time: the worker's async thumbnail
|
||||
// installs after a bounded number of engine pumps (a wall-clock
|
||||
// cap would fail on slow machines for machine speed).
|
||||
let mut pumps = 0usize;
|
||||
loop {
|
||||
pumps += 1;
|
||||
let thumbnail = cx.read(|app| {
|
||||
engine
|
||||
.read(app)
|
||||
@@ -5847,8 +5851,8 @@ mod tests {
|
||||
break;
|
||||
}
|
||||
assert!(
|
||||
std::time::Instant::now() < deadline,
|
||||
"the entry eventually carries a thumbnail path"
|
||||
pumps < 5000,
|
||||
"the entry eventually carries a thumbnail path (after {pumps} pumps)"
|
||||
);
|
||||
cx.update(|app| engine.update(app, |engine, _cx| engine.drain_thumbnails()));
|
||||
std::thread::sleep(Duration::from_millis(10));
|
||||
@@ -6318,7 +6322,7 @@ mod tests {
|
||||
std::thread::spawn(move || RealEngine::full_res_worker(request, tx));
|
||||
|
||||
let event = rx
|
||||
.recv_timeout(Duration::from_secs(20))
|
||||
.recv_timeout(Duration::from_secs(60))
|
||||
.expect("the worker delivers the frame after the project drop");
|
||||
let bytes = event.image.as_bytes(0).expect("one frame");
|
||||
assert_eq!(bytes.len(), 64 * 64 * 4, "full-res geometry");
|
||||
@@ -6488,7 +6492,7 @@ mod tests {
|
||||
std::thread::spawn(move || RealEngine::full_res_worker(request, tx));
|
||||
|
||||
let event = rx
|
||||
.recv_timeout(Duration::from_secs(20))
|
||||
.recv_timeout(Duration::from_secs(60))
|
||||
.expect("the worker delivers the full-res frame");
|
||||
assert_eq!(event.monitor, Monitor::Program);
|
||||
assert_eq!(event.frame, 0);
|
||||
@@ -6543,9 +6547,12 @@ mod tests {
|
||||
|
||||
// Drive the tick loop until the background fill lands and replaces
|
||||
// the proxy in the display path.
|
||||
// Progress criterion, not wall time: the fill lands after a bounded
|
||||
// number of engine pumps (machine-speed independent).
|
||||
let full_len = (width * height * 4) as usize;
|
||||
let deadline = std::time::Instant::now() + Duration::from_secs(20);
|
||||
let mut pumps = 0usize;
|
||||
loop {
|
||||
pumps += 1;
|
||||
cx.update(|app| engine.update(app, |engine, cx| engine.tick(cx)));
|
||||
let len = cx.read(|app| {
|
||||
engine
|
||||
@@ -6559,8 +6566,8 @@ mod tests {
|
||||
break;
|
||||
}
|
||||
assert!(
|
||||
std::time::Instant::now() < deadline,
|
||||
"the full-res fill lands within the deadline (got {len} bytes)"
|
||||
pumps < 5000,
|
||||
"the full-res fill lands after a bounded number of pumps (got {len} bytes after {pumps})"
|
||||
);
|
||||
std::thread::sleep(Duration::from_millis(10));
|
||||
}
|
||||
@@ -6858,10 +6865,11 @@ mod tests {
|
||||
|
||||
// Start playback and drive the tick loop: the window must fill.
|
||||
cx.update(|app| engine.update(app, |engine, cx| engine.play(Monitor::Program, cx)));
|
||||
let deadline = std::time::Instant::now() + Duration::from_secs(30);
|
||||
let mut filled = 0usize;
|
||||
let mut hit = false;
|
||||
let mut pumps = 0usize;
|
||||
loop {
|
||||
pumps += 1;
|
||||
cx.update(|app| engine.update(app, |engine, cx| engine.tick(cx)));
|
||||
let (slots, submitted) = cx.read(|app| {
|
||||
let engine = engine.read(app);
|
||||
@@ -6882,8 +6890,8 @@ mod tests {
|
||||
break;
|
||||
}
|
||||
assert!(
|
||||
std::time::Instant::now() < deadline,
|
||||
"the playback window must supply playhead frames (peak cached {filled}, submitted {submitted})"
|
||||
pumps < 5000,
|
||||
"the playback window must supply playhead frames (peak cached {filled}, submitted {submitted}, after {pumps} pumps)"
|
||||
);
|
||||
std::thread::sleep(Duration::from_millis(10));
|
||||
}
|
||||
|
||||
@@ -42,17 +42,17 @@ fn bin() -> &'static str {
|
||||
|
||||
/// The fixture `.ove` file (relative to the workspace root).
|
||||
fn fixture_project() -> PathBuf {
|
||||
// The fixtures live with the app crate (moved there in the workspace
|
||||
// restructure); oak-cli sits one level below oak-app.
|
||||
Path::new(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("../..")
|
||||
.join("tests")
|
||||
.join("../oak-app/tests")
|
||||
.join("project_with_footage.ove")
|
||||
}
|
||||
|
||||
/// The real media fixture.
|
||||
fn fixture_media() -> PathBuf {
|
||||
Path::new(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("../..")
|
||||
.join("tests")
|
||||
.join("../oak-app/tests")
|
||||
.join("demo.mp4")
|
||||
}
|
||||
|
||||
@@ -60,8 +60,7 @@ fn fixture_media() -> PathBuf {
|
||||
/// no audio — fast end-to-end transcode coverage.
|
||||
fn fixture_image() -> PathBuf {
|
||||
Path::new(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("../..")
|
||||
.join("tests")
|
||||
.join("../oak-app/tests")
|
||||
.join("img.png")
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user