Files
oak-editor/crates/oakplugin/tests/common/mod.rs
T
Mike-Solar 18ff60f147 feat(engine): clip move, clip effect_input, mandatory static FFmpeg
- oakengine_sequence_move_clip implemented for real (oaktimeline
  TrackMoveBlockCommand; fixes the graph-ownership/gap-anchor/ripple
  trim bugs the stub was hiding); same-track via the frozen C ABI,
  cross-track supported by the module command
- oaknode clip blocks now declare a tex_in texture input and set
  effect_input to it, so timeline clips can host effect chains; facade
  test covers effect insert/remove on a real clip
- oakffmpeg-link: FFMPEG_DIR is now mandatory with a clear panic (a
  Homebrew upgrade left the system ffmpeg .pc pointing at a deleted
  dav1d Cellar path, breaking links); reads a git-ignored workspace
  .env for IDEs that cannot inject env vars (RustRover); links the C++
  stdlib for C++ codec libs (svt-av1)
- oakengine re-exports oaknode so tests share one crate instance;
  it_node uses the direct instance's value type where it calls the
  module FFI (the --workspace dev-dependency feature split builds
  oaknode twice)
2026-08-11 23:04:48 +08:00

104 lines
3.9 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Oak Video Editor - Non-Linear Video Editor
// Copyright (C) 2026 Oak Team
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//! 测试公共件:最小测试插件定位、快照/golden 文件路径、夹具。
//!
//! 最小测试插件(cbits/oak_test_plugin.cbuild.rs 编译为共享库,
//! 运行时装配成 oak-test-plugin.ofx.bundle):filter 上下文、
//! Double 参数 gain、双 clipSource/Output)。插件未构建时相关
//! 用例经 [`skip`] 提前返回。
//! 测试桩在库内(bridge::render::stub`--features test-stubs`):
//! 全链路像素路径可在 cargo test 跑通;真实链路在 standalone
//! ctest。本文档的 run 命令见 crate README。
use std::path::PathBuf;
/// 构建系统注入插件路径的环境变量名。
pub const TEST_PLUGIN_ENV: &str = "OAK_TEST_PLUGIN_DIR";
/// 测试插件 bundle 的绝对路径(由构建系统经环境变量注入;
/// 未注入时用 build.rs 编的共享库现场装配 bundle 目录;均不可用
/// 时返回 None,调用方 skip)。
pub fn test_plugin_dir() -> Option<PathBuf> {
if let Some(p) = std::env::var_os(TEST_PLUGIN_ENV) {
return Some(PathBuf::from(p));
}
static BUNDLE: std::sync::OnceLock<Option<PathBuf>> = std::sync::OnceLock::new();
BUNDLE
.get_or_init(|| {
let out = PathBuf::from(env!("OUT_DIR"));
let lib = if cfg!(target_os = "macos") {
out.join("oak_test_plugin.dylib")
} else {
out.join("oak_test_plugin.so")
};
if !lib.is_file() {
return None;
}
let bundle = std::env::temp_dir()
.join(format!("oak-test-plugin-{}", std::process::id()))
.join("oak-test-plugin.ofx.bundle");
let platform = if cfg!(target_os = "macos") {
"MacOS"
} else {
"Linux-x86-64"
};
let bin_dir = bundle.join("Contents").join(platform);
std::fs::create_dir_all(&bin_dir).ok()?;
let target = bin_dir.join("plugin");
if !target.exists() {
std::fs::copy(&lib, &target).ok()?;
}
Some(bundle)
})
.clone()
}
/// 测试插件 bundle 的父目录(host_scan 的入参)。
pub fn test_plugin_scan_dir() -> Option<PathBuf> {
let bundle = test_plugin_dir()?;
let parent = bundle.parent()?;
// scan_path 会 canonicalizebundle 在临时目录下,直接给父目录。
Some(parent.to_path_buf())
}
/// golden master 目录(tests/ofx/)。描述符快照 JSON 与 EXR 帧都在这。
pub fn golden_dir() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/ofx")
}
/// 当前平台是否有 GPUGL golden 用例的门:无 GPU 一律 skip)。
///
/// 第 1 期无 GL 用例:显式环境变量开启(GL 验收需人工本机确认,
/// CI 一律跳过)。
pub fn gpu_available() -> bool {
std::env::var_os("OAK_GPU_TESTS").is_some()
}
/// 通用 skip 宏的函数形态:前置条件不满足时打印原因并提前返回。
/// cargo 没有 GTEST_SKIP,约定为 `return`,并在输出里打印 SKIP。)
pub fn skip(reason: &str) {
println!("SKIP: {reason}");
}
/// 宿主单例测试串行化:同一二进制的测试并行跑会互相踩
/// init/shutdown/scan(进程单例无锁);所有触碰宿主面的用例经它。
pub fn with_host(f: impl FnOnce()) {
static LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(());
let _g = LOCK.lock().unwrap_or_else(|e| e.into_inner());
f();
}