fix: teardown UAF in Track block cache and headless test/render environment
- Track: new InputDisconnectedEvent trims blocks_/block_array_indexes_ when a block edge is removed outside the Track's own operations (block deletion, undo commands detaching a whole track). Previously blocks_ kept dangling pointers and Project teardown crashed in track_length() (ASan heap-use-after-free in oakengine_timeline_edit / oakengine_sync). The persistent array map is intentionally not rewritten so undo of remove_track can re-attach the clips; replace_block guards the handler with ignore_block_disconnect_ - filefunctions: honor OAK_CONFIG_DIR to redirect the configuration root; QStandardPaths ignores XDG_* on macOS, so the engine tests read the real user config (a stale 0.1.x file) and failed frame-rate assertions. All engine tests now set OAK_CONFIG_DIR to their tmpdir - init test: chdir to the fixture directory before loading project_with_footage.ove so the engine's moved-project footage relocation does not rewrite the stored relative filename - renderworkerpool: do not let the render worker inherit QT_QPA_PLATFORM=offscreen from a headless host process; the worker needs a real platform GL context and exited immediately otherwise, failing oak_cli_transcode
This commit is contained in:
@@ -55,6 +55,15 @@ QString FileFunctions::get_unique_file_identifier(const QString &filename)
|
|||||||
|
|
||||||
QString FileFunctions::get_configuration_location()
|
QString FileFunctions::get_configuration_location()
|
||||||
{
|
{
|
||||||
|
// Tests and tooling can redirect the configuration (and, since most
|
||||||
|
// locations derive from it, the cache/data) root. XDG_* vars only work
|
||||||
|
// on Linux; QStandardPaths ignores them on macOS and Windows.
|
||||||
|
const QByteArray override_dir = qgetenv("OAK_CONFIG_DIR");
|
||||||
|
if (!override_dir.isEmpty()) {
|
||||||
|
QDir(override_dir).mkpath(".");
|
||||||
|
return QString::fromUtf8(override_dir);
|
||||||
|
}
|
||||||
|
|
||||||
if (is_portable()) {
|
if (is_portable()) {
|
||||||
return get_application_path();
|
return get_application_path();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -511,7 +511,9 @@ void Track::replace_block(Block *old, Block *replace)
|
|||||||
int cache_index = blocks_.indexOf(old);
|
int cache_index = blocks_.indexOf(old);
|
||||||
int index_of_old_block = get_array_index_from_cache_index(cache_index);
|
int index_of_old_block = get_array_index_from_cache_index(cache_index);
|
||||||
|
|
||||||
|
ignore_block_disconnect_++;
|
||||||
disconnect_edge(old, NodeInput(this, k_block_input, index_of_old_block));
|
disconnect_edge(old, NodeInput(this, k_block_input, index_of_old_block));
|
||||||
|
ignore_block_disconnect_--;
|
||||||
connect_edge(replace, NodeInput(this, k_block_input, index_of_old_block));
|
connect_edge(replace, NodeInput(this, k_block_input, index_of_old_block));
|
||||||
blocks_.replace(cache_index, replace);
|
blocks_.replace(cache_index, replace);
|
||||||
disconnect(old, &Block::length_changed, this, &Track::block_length_changed);
|
disconnect(old, &Block::length_changed, this, &Track::block_length_changed);
|
||||||
@@ -584,6 +586,37 @@ void Track::InputConnectedEvent(const QString &input, int element, Node *node)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Track::InputDisconnectedEvent(const QString &input, int element,
|
||||||
|
Node *output)
|
||||||
|
{
|
||||||
|
Node::InputDisconnectedEvent(input, element, output);
|
||||||
|
|
||||||
|
// Keep the block cache consistent when a block edge is removed outside
|
||||||
|
// the Track's own mutating operations (e.g. the block is being deleted,
|
||||||
|
// or an undo command is detaching the whole track from the graph).
|
||||||
|
// Without this, blocks_ keeps a dangling pointer and later readers such
|
||||||
|
// as track_length() walk into freed memory.
|
||||||
|
//
|
||||||
|
// Only the volatile cache is trimmed here; the persistent array map is
|
||||||
|
// deliberately left alone so that undo can re-attach the blocks from it
|
||||||
|
// (InputConnectedEvent rebuilds the cache while arraymap_invalid_ is
|
||||||
|
// set).
|
||||||
|
if (input == k_block_input && ignore_block_disconnect_ == 0) {
|
||||||
|
const int index = blocks_.indexOf(static_cast<Block *>(output));
|
||||||
|
if (index != -1) {
|
||||||
|
blocks_.removeAt(index);
|
||||||
|
block_array_indexes_.removeAt(index);
|
||||||
|
arraymap_invalid_ = true;
|
||||||
|
|
||||||
|
Block *previous = (index > 0) ? blocks_.at(index - 1) : nullptr;
|
||||||
|
Block *next = (index < blocks_.size()) ? blocks_.at(index) : nullptr;
|
||||||
|
Block::set_previous_next(previous, next);
|
||||||
|
|
||||||
|
update_in_out_from(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Track::update_in_out_from(int index)
|
void Track::update_in_out_from(int index)
|
||||||
{
|
{
|
||||||
// Find block just before this one to find the last out point
|
// Find block just before this one to find the last out point
|
||||||
|
|||||||
@@ -460,6 +460,8 @@ signals:
|
|||||||
protected:
|
protected:
|
||||||
virtual void InputConnectedEvent(const QString &input, int element,
|
virtual void InputConnectedEvent(const QString &input, int element,
|
||||||
Node *node) override;
|
Node *node) override;
|
||||||
|
virtual void InputDisconnectedEvent(const QString &input, int element,
|
||||||
|
Node *output) override;
|
||||||
virtual void InputValueChangedEvent(const QString &input,
|
virtual void InputValueChangedEvent(const QString &input,
|
||||||
int element) override;
|
int element) override;
|
||||||
|
|
||||||
@@ -501,6 +503,13 @@ private:
|
|||||||
bool arraymap_invalid_;
|
bool arraymap_invalid_;
|
||||||
bool ignore_arraymap_set_;
|
bool ignore_arraymap_set_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Nestable guard suppressing the block-cache maintenance in
|
||||||
|
* InputDisconnectedEvent while the Track itself is rewiring block edges
|
||||||
|
* (e.g. replace_block), where the cache update is handled explicitly.
|
||||||
|
*/
|
||||||
|
int ignore_block_disconnect_ = 0;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void block_length_changed();
|
void block_length_changed();
|
||||||
|
|
||||||
|
|||||||
@@ -1141,6 +1141,17 @@ std::unique_ptr<RenderWorkerPool::PooledWorker> RenderWorkerPool::acquire_worker
|
|||||||
process->setProgram(worker_program_path());
|
process->setProgram(worker_program_path());
|
||||||
process->setArguments({ QStringLiteral("--backend"), gpu_backend_ });
|
process->setArguments({ QStringLiteral("--backend"), gpu_backend_ });
|
||||||
|
|
||||||
|
// The engine defaults QT_QPA_PLATFORM to "offscreen" for headless hosts
|
||||||
|
// (cli/tests), but the worker needs a real platform GL context. Don't let
|
||||||
|
// it inherit the offscreen default from this process.
|
||||||
|
{
|
||||||
|
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
||||||
|
if (qEnvironmentVariable("QT_QPA_PLATFORM") == "offscreen") {
|
||||||
|
env.remove(QStringLiteral("QT_QPA_PLATFORM"));
|
||||||
|
process->setProcessEnvironment(env);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const QString worker_stderr_path =
|
const QString worker_stderr_path =
|
||||||
QDir(QDir::tempPath())
|
QDir(QDir::tempPath())
|
||||||
.filePath(QStringLiteral("oak-render-worker-%1-%2.stderr.log")
|
.filePath(QStringLiteral("oak-render-worker-%1-%2.stderr.log")
|
||||||
|
|||||||
@@ -396,6 +396,7 @@ TEST(OakEngineColor, Main)
|
|||||||
EXPECT_TRUE(setenv("XDG_CONFIG_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_CONFIG_HOME", g_tmpdir, 1) == 0);
|
||||||
EXPECT_TRUE(setenv("XDG_CACHE_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_CACHE_HOME", g_tmpdir, 1) == 0);
|
||||||
EXPECT_TRUE(setenv("XDG_DATA_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_DATA_HOME", g_tmpdir, 1) == 0);
|
||||||
|
EXPECT_TRUE(setenv("OAK_CONFIG_DIR", g_tmpdir, 1) == 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EXPECT_TRUE(oakengine_init(OAKENGINE_INIT_HEADLESS) == OAKENGINE_OK);
|
EXPECT_TRUE(oakengine_init(OAKENGINE_INIT_HEADLESS) == OAKENGINE_OK);
|
||||||
|
|||||||
@@ -922,6 +922,7 @@ TEST(OakEngineEvents, Main)
|
|||||||
EXPECT_TRUE(setenv("XDG_CONFIG_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_CONFIG_HOME", g_tmpdir, 1) == 0);
|
||||||
EXPECT_TRUE(setenv("XDG_CACHE_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_CACHE_HOME", g_tmpdir, 1) == 0);
|
||||||
EXPECT_TRUE(setenv("XDG_DATA_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_DATA_HOME", g_tmpdir, 1) == 0);
|
||||||
|
EXPECT_TRUE(setenv("OAK_CONFIG_DIR", g_tmpdir, 1) == 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EXPECT_TRUE(oakengine_init(OAKENGINE_INIT_HEADLESS) == OAKENGINE_OK);
|
EXPECT_TRUE(oakengine_init(OAKENGINE_INIT_HEADLESS) == OAKENGINE_OK);
|
||||||
|
|||||||
@@ -216,6 +216,7 @@ TEST(OakEngineExport, Main)
|
|||||||
EXPECT_TRUE(setenv("XDG_CONFIG_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_CONFIG_HOME", g_tmpdir, 1) == 0);
|
||||||
EXPECT_TRUE(setenv("XDG_CACHE_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_CACHE_HOME", g_tmpdir, 1) == 0);
|
||||||
EXPECT_TRUE(setenv("XDG_DATA_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_DATA_HOME", g_tmpdir, 1) == 0);
|
||||||
|
EXPECT_TRUE(setenv("OAK_CONFIG_DIR", g_tmpdir, 1) == 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EXPECT_TRUE(oakengine_init(OAKENGINE_INIT_HEADLESS) == OAKENGINE_OK);
|
EXPECT_TRUE(oakengine_init(OAKENGINE_INIT_HEADLESS) == OAKENGINE_OK);
|
||||||
|
|||||||
@@ -888,6 +888,7 @@ TEST(OakEngineFootage, Main)
|
|||||||
EXPECT_TRUE(setenv("XDG_CONFIG_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_CONFIG_HOME", g_tmpdir, 1) == 0);
|
||||||
EXPECT_TRUE(setenv("XDG_CACHE_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_CACHE_HOME", g_tmpdir, 1) == 0);
|
||||||
EXPECT_TRUE(setenv("XDG_DATA_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_DATA_HOME", g_tmpdir, 1) == 0);
|
||||||
|
EXPECT_TRUE(setenv("OAK_CONFIG_DIR", g_tmpdir, 1) == 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EXPECT_TRUE(oakengine_init(OAKENGINE_INIT_HEADLESS) == OAKENGINE_OK);
|
EXPECT_TRUE(oakengine_init(OAKENGINE_INIT_HEADLESS) == OAKENGINE_OK);
|
||||||
|
|||||||
@@ -312,6 +312,14 @@ static void test_footage_fixture(void)
|
|||||||
EXPECT_TRUE(n > 0 && (size_t)n < sizeof(fixture));
|
EXPECT_TRUE(n > 0 && (size_t)n < sizeof(fixture));
|
||||||
EXPECT_TRUE(file_exists(fixture));
|
EXPECT_TRUE(file_exists(fixture));
|
||||||
|
|
||||||
|
// The fixture stores footage as the relative path "demo.mp4". Run the
|
||||||
|
// load from the fixture directory so the engine does not treat the
|
||||||
|
// project as "moved" and rewrite the stored filename to an absolute
|
||||||
|
// path (see EngineCore footage relocation on load).
|
||||||
|
char fixture_dir[4096];
|
||||||
|
snprintf(fixture_dir, sizeof(fixture_dir), "%s/tests", OAK_TEST_SOURCE_DIR);
|
||||||
|
EXPECT_TRUE(chdir(fixture_dir) == 0);
|
||||||
|
|
||||||
OakEngineProject *p = oakengine_project_create();
|
OakEngineProject *p = oakengine_project_create();
|
||||||
EXPECT_TRUE(p != NULL);
|
EXPECT_TRUE(p != NULL);
|
||||||
char err[512];
|
char err[512];
|
||||||
@@ -417,6 +425,7 @@ TEST(OakEngineInit, Main)
|
|||||||
EXPECT_TRUE(setenv("XDG_CONFIG_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_CONFIG_HOME", g_tmpdir, 1) == 0);
|
||||||
EXPECT_TRUE(setenv("XDG_CACHE_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_CACHE_HOME", g_tmpdir, 1) == 0);
|
||||||
EXPECT_TRUE(setenv("XDG_DATA_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_DATA_HOME", g_tmpdir, 1) == 0);
|
||||||
|
EXPECT_TRUE(setenv("OAK_CONFIG_DIR", g_tmpdir, 1) == 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
test_init();
|
test_init();
|
||||||
|
|||||||
@@ -831,6 +831,7 @@ TEST(OakEngineKeyframe, Main)
|
|||||||
EXPECT_TRUE(setenv("XDG_CONFIG_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_CONFIG_HOME", g_tmpdir, 1) == 0);
|
||||||
EXPECT_TRUE(setenv("XDG_CACHE_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_CACHE_HOME", g_tmpdir, 1) == 0);
|
||||||
EXPECT_TRUE(setenv("XDG_DATA_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_DATA_HOME", g_tmpdir, 1) == 0);
|
||||||
|
EXPECT_TRUE(setenv("OAK_CONFIG_DIR", g_tmpdir, 1) == 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EXPECT_TRUE(oakengine_init(OAKENGINE_INIT_HEADLESS) == OAKENGINE_OK);
|
EXPECT_TRUE(oakengine_init(OAKENGINE_INIT_HEADLESS) == OAKENGINE_OK);
|
||||||
|
|||||||
@@ -1050,6 +1050,7 @@ TEST(OakEngineNode, Main)
|
|||||||
EXPECT_TRUE(setenv("XDG_CONFIG_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_CONFIG_HOME", g_tmpdir, 1) == 0);
|
||||||
EXPECT_TRUE(setenv("XDG_CACHE_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_CACHE_HOME", g_tmpdir, 1) == 0);
|
||||||
EXPECT_TRUE(setenv("XDG_DATA_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_DATA_HOME", g_tmpdir, 1) == 0);
|
||||||
|
EXPECT_TRUE(setenv("OAK_CONFIG_DIR", g_tmpdir, 1) == 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EXPECT_TRUE(oakengine_init(OAKENGINE_INIT_HEADLESS) == OAKENGINE_OK);
|
EXPECT_TRUE(oakengine_init(OAKENGINE_INIT_HEADLESS) == OAKENGINE_OK);
|
||||||
|
|||||||
@@ -300,6 +300,7 @@ TEST(OakEnginePlayback, Main)
|
|||||||
EXPECT_TRUE(setenv("XDG_CONFIG_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_CONFIG_HOME", g_tmpdir, 1) == 0);
|
||||||
EXPECT_TRUE(setenv("XDG_CACHE_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_CACHE_HOME", g_tmpdir, 1) == 0);
|
||||||
EXPECT_TRUE(setenv("XDG_DATA_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_DATA_HOME", g_tmpdir, 1) == 0);
|
||||||
|
EXPECT_TRUE(setenv("OAK_CONFIG_DIR", g_tmpdir, 1) == 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// HEADLESS is enough for the validation part and creates the
|
// HEADLESS is enough for the validation part and creates the
|
||||||
|
|||||||
@@ -244,6 +244,7 @@ TEST(OakEnginePreview, Main)
|
|||||||
EXPECT_TRUE(setenv("XDG_CONFIG_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_CONFIG_HOME", g_tmpdir, 1) == 0);
|
||||||
EXPECT_TRUE(setenv("XDG_CACHE_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_CACHE_HOME", g_tmpdir, 1) == 0);
|
||||||
EXPECT_TRUE(setenv("XDG_DATA_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_DATA_HOME", g_tmpdir, 1) == 0);
|
||||||
|
EXPECT_TRUE(setenv("OAK_CONFIG_DIR", g_tmpdir, 1) == 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EXPECT_TRUE(oakengine_init(OAKENGINE_INIT_HEADLESS) == OAKENGINE_OK);
|
EXPECT_TRUE(oakengine_init(OAKENGINE_INIT_HEADLESS) == OAKENGINE_OK);
|
||||||
|
|||||||
@@ -240,6 +240,7 @@ TEST(OakEngineRenderer, Main)
|
|||||||
EXPECT_TRUE(setenv("XDG_CONFIG_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_CONFIG_HOME", g_tmpdir, 1) == 0);
|
||||||
EXPECT_TRUE(setenv("XDG_CACHE_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_CACHE_HOME", g_tmpdir, 1) == 0);
|
||||||
EXPECT_TRUE(setenv("XDG_DATA_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_DATA_HOME", g_tmpdir, 1) == 0);
|
||||||
|
EXPECT_TRUE(setenv("OAK_CONFIG_DIR", g_tmpdir, 1) == 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// HEADLESS is enough for the validation part and creates the offscreen
|
// HEADLESS is enough for the validation part and creates the offscreen
|
||||||
|
|||||||
@@ -212,6 +212,7 @@ TEST(OakEngineSync, Main)
|
|||||||
EXPECT_TRUE(setenv("XDG_CONFIG_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_CONFIG_HOME", g_tmpdir, 1) == 0);
|
||||||
EXPECT_TRUE(setenv("XDG_CACHE_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_CACHE_HOME", g_tmpdir, 1) == 0);
|
||||||
EXPECT_TRUE(setenv("XDG_DATA_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_DATA_HOME", g_tmpdir, 1) == 0);
|
||||||
|
EXPECT_TRUE(setenv("OAK_CONFIG_DIR", g_tmpdir, 1) == 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// HEADLESS is enough for the validation part.
|
// HEADLESS is enough for the validation part.
|
||||||
|
|||||||
@@ -1806,6 +1806,7 @@ TEST(OakEngineTimelineEdit, Main)
|
|||||||
EXPECT_TRUE(setenv("XDG_CONFIG_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_CONFIG_HOME", g_tmpdir, 1) == 0);
|
||||||
EXPECT_TRUE(setenv("XDG_CACHE_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_CACHE_HOME", g_tmpdir, 1) == 0);
|
||||||
EXPECT_TRUE(setenv("XDG_DATA_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_DATA_HOME", g_tmpdir, 1) == 0);
|
||||||
|
EXPECT_TRUE(setenv("OAK_CONFIG_DIR", g_tmpdir, 1) == 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EXPECT_TRUE(oakengine_init(OAKENGINE_INIT_HEADLESS) == OAKENGINE_OK);
|
EXPECT_TRUE(oakengine_init(OAKENGINE_INIT_HEADLESS) == OAKENGINE_OK);
|
||||||
|
|||||||
@@ -250,6 +250,7 @@ TEST(OakEngineTraverse, Main)
|
|||||||
EXPECT_TRUE(setenv("XDG_CONFIG_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_CONFIG_HOME", g_tmpdir, 1) == 0);
|
||||||
EXPECT_TRUE(setenv("XDG_CACHE_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_CACHE_HOME", g_tmpdir, 1) == 0);
|
||||||
EXPECT_TRUE(setenv("XDG_DATA_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_DATA_HOME", g_tmpdir, 1) == 0);
|
||||||
|
EXPECT_TRUE(setenv("OAK_CONFIG_DIR", g_tmpdir, 1) == 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EXPECT_TRUE(oakengine_init(OAKENGINE_INIT_HEADLESS) == OAKENGINE_OK);
|
EXPECT_TRUE(oakengine_init(OAKENGINE_INIT_HEADLESS) == OAKENGINE_OK);
|
||||||
|
|||||||
@@ -552,6 +552,7 @@ TEST(OakEngineViewer, Main)
|
|||||||
EXPECT_TRUE(setenv("XDG_CONFIG_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_CONFIG_HOME", g_tmpdir, 1) == 0);
|
||||||
EXPECT_TRUE(setenv("XDG_CACHE_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_CACHE_HOME", g_tmpdir, 1) == 0);
|
||||||
EXPECT_TRUE(setenv("XDG_DATA_HOME", g_tmpdir, 1) == 0);
|
EXPECT_TRUE(setenv("XDG_DATA_HOME", g_tmpdir, 1) == 0);
|
||||||
|
EXPECT_TRUE(setenv("OAK_CONFIG_DIR", g_tmpdir, 1) == 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EXPECT_TRUE(oakengine_init(OAKENGINE_INIT_HEADLESS) == OAKENGINE_OK);
|
EXPECT_TRUE(oakengine_init(OAKENGINE_INIT_HEADLESS) == OAKENGINE_OK);
|
||||||
|
|||||||
Reference in New Issue
Block a user