Skip to content

Commit

Permalink
#5977: Fix flaky unit test now that signal emission is no longer sync…
Browse files Browse the repository at this point in the history
…hronised
  • Loading branch information
codereader committed Jul 8, 2022
1 parent b967f34 commit 1810e73
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 1 deletion.
7 changes: 6 additions & 1 deletion test/DeclManager.cpp
Expand Up @@ -2,6 +2,7 @@

#include "ideclmanager.h"
#include "testutil/TemporaryFile.h"
#include "testutil/ThreadUtils.h"

namespace test
{
Expand Down Expand Up @@ -287,9 +288,11 @@ TEST_F(DeclManagerTest, DeclsReloadedSignalAfterInitialParse)
// Parse this folder, it contains decls of type testdecl and testdecl2 in the .decl files
GlobalDeclarationManager().registerDeclFolder(decl::Type::Material, "testdecls", ".decl");

// Force the thread to be finished
// Force the threads to be finished
GlobalDeclarationManager().foreachDeclaration(decl::Type::Material, [](const decl::IDeclaration::Ptr&) {});

EXPECT_TRUE(algorithm::waitUntil([&]() { return materialSignalFired; })) << "Time out waiting for the flag";

EXPECT_TRUE(materialSignalFired) << "Material signal should have fired by the time parsing has finished";
EXPECT_FALSE(modelSignalFired) << "Model-type Signal should not have been fired";
}
Expand Down Expand Up @@ -324,6 +327,8 @@ TEST_F(DeclManagerTest, DeclsReloadedSignals)

GlobalDeclarationManager().reloadDeclarations();

EXPECT_TRUE(algorithm::waitUntil([&]() { return materialsReloadedFired; })) << "Time out waiting for the flag";

EXPECT_TRUE(materialsReloadingFired) << "Material signal should have fired before reloadDecls";
EXPECT_TRUE(modelsReloadingFired) << "Model signal should have fired before reloadDecls";
EXPECT_TRUE(materialsReloadedFired) << "Material signal should have fired after reloadDecls";
Expand Down
38 changes: 38 additions & 0 deletions test/testutil/ThreadUtils.h
@@ -0,0 +1,38 @@
#pragma once

#include <chrono>
#include <functional>
#include <thread>

namespace test
{

namespace algorithm
{

// Waits until the given condition is met, but no longer than the given amount of milliseconds
// Returns true if the stop condition has been met before the timeout, false otherwise
inline bool waitUntil(std::function<bool()> stopCondition, std::size_t maxMillisecondsToWait = 30000)
{
using namespace std::chrono_literals;
auto startTime = std::chrono::steady_clock::now();

while (!stopCondition())
{
std::this_thread::sleep_for(10ms);

auto timeSinceStart = std::chrono::steady_clock::now() - startTime;
auto millisecondsPassed = std::chrono::duration_cast<std::chrono::milliseconds>(timeSinceStart);

if (millisecondsPassed.count() > maxMillisecondsToWait)
{
return false;
}
}

return true;
}

}

}
1 change: 1 addition & 0 deletions tools/msvc/Tests/Tests.vcxproj
Expand Up @@ -81,6 +81,7 @@
<ClInclude Include="..\..\..\test\testutil\FileSelectionHelper.h" />
<ClInclude Include="..\..\..\test\testutil\TestObjectRenderer.h" />
<ClInclude Include="..\..\..\test\testutil\TestSyncObjectProvider.h" />
<ClInclude Include="..\..\..\test\testutil\ThreadUtils.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\test\Basic.cpp" />
Expand Down
3 changes: 3 additions & 0 deletions tools/msvc/Tests/Tests.vcxproj.filters
Expand Up @@ -116,6 +116,9 @@
<ClInclude Include="..\..\..\test\algorithm\FileUtils.h">
<Filter>algorithm</Filter>
</ClInclude>
<ClInclude Include="..\..\..\test\testutil\ThreadUtils.h">
<Filter>testutil</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="algorithm">
Expand Down

0 comments on commit 1810e73

Please sign in to comment.