From b2a1a7762dd0bd569f3ca063f08a32445375c4cd Mon Sep 17 00:00:00 2001 From: Hasso Date: Mon, 6 Apr 2026 16:42:19 -0500 Subject: [PATCH 01/15] Add native test projects to the solution --- FieldWorks.sln | 114 ++++++++++++++++++++++++++++--------------------- 1 file changed, 65 insertions(+), 49 deletions(-) diff --git a/FieldWorks.sln b/FieldWorks.sln index 4aff9ba74d..12b0c003cf 100644 --- a/FieldWorks.sln +++ b/FieldWorks.sln @@ -216,7 +216,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "xWorksTests", "Src\xWorks\x EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Generic", "Src\Generic\Generic.vcxproj", "{7F6B25EE-CD22-4E4C-898D-A0F846E6E9D4}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Kernel", "Src\Kernel\Kernel.vcxproj", "{6396B488-4D34-48B2-8639-EEB90707405B}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FwKernel", "Src\Kernel\Kernel.vcxproj", "{6396B488-4D34-48B2-8639-EEB90707405B}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "views", "Src\views\views.vcxproj", "{C86CA2EB-81B5-4411-B5B7-E983314E02DA}" EndProject @@ -276,6 +276,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ToneParsFLExDll", "Src\Util EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DisambiguateInFLExDBTests", "Src\Utilities\pcpatrflex\DisambiguateInFLExDB\DisambiguateInFLExDBTests\DisambiguateInFLExDBTests.csproj", "{1D9F7F7D-F4DE-43DC-9E1D-9D0E512D1CB6}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestViews", "Src\views\Test\TestViews.vcxproj", "{1D4CC42D-BC16-4EC3-A89B-173798828F56}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestGeneric", "Src\Generic\Test\TestGeneric.vcxproj", "{C644C392-FB14-4DF1-9989-897E182D3849}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Bounds|x64 = Bounds|x64 @@ -991,6 +995,54 @@ Global {5DB1CEDA-B7AA-4594-9CE0-6D3A6F5763DF}.Debug|x64.Build.0 = Debug|x64 {5DB1CEDA-B7AA-4594-9CE0-6D3A6F5763DF}.Release|x64.ActiveCfg = Release|x64 {5DB1CEDA-B7AA-4594-9CE0-6D3A6F5763DF}.Release|x64.Build.0 = Release|x64 + {996498A3-06F1-4B1B-B83F-15648DD8F514}.Bounds|x64.ActiveCfg = Debug|x64 + {996498A3-06F1-4B1B-B83F-15648DD8F514}.Bounds|x64.Build.0 = Debug|x64 + {996498A3-06F1-4B1B-B83F-15648DD8F514}.Debug|x64.ActiveCfg = Debug|x64 + {996498A3-06F1-4B1B-B83F-15648DD8F514}.Debug|x64.Build.0 = Debug|x64 + {996498A3-06F1-4B1B-B83F-15648DD8F514}.Release|x64.ActiveCfg = Release|x64 + {996498A3-06F1-4B1B-B83F-15648DD8F514}.Release|x64.Build.0 = Release|x64 + {ECEC3C09-019A-4B31-B72A-C4A22DE88E84}.Bounds|x64.ActiveCfg = Debug|x64 + {ECEC3C09-019A-4B31-B72A-C4A22DE88E84}.Bounds|x64.Build.0 = Debug|x64 + {ECEC3C09-019A-4B31-B72A-C4A22DE88E84}.Debug|x64.ActiveCfg = Debug|x64 + {ECEC3C09-019A-4B31-B72A-C4A22DE88E84}.Debug|x64.Build.0 = Debug|x64 + {ECEC3C09-019A-4B31-B72A-C4A22DE88E84}.Release|x64.ActiveCfg = Release|x64 + {ECEC3C09-019A-4B31-B72A-C4A22DE88E84}.Release|x64.Build.0 = Release|x64 + {98A04BE3-5CDA-4616-9396-E40B33CC9256}.Bounds|x64.ActiveCfg = Debug|x64 + {98A04BE3-5CDA-4616-9396-E40B33CC9256}.Bounds|x64.Build.0 = Debug|x64 + {98A04BE3-5CDA-4616-9396-E40B33CC9256}.Debug|x64.ActiveCfg = Debug|x64 + {98A04BE3-5CDA-4616-9396-E40B33CC9256}.Debug|x64.Build.0 = Debug|x64 + {98A04BE3-5CDA-4616-9396-E40B33CC9256}.Release|x64.ActiveCfg = Release|x64 + {98A04BE3-5CDA-4616-9396-E40B33CC9256}.Release|x64.Build.0 = Release|x64 + {B4CDC940-DDA7-4EEC-87A6-8441CF47EE7E}.Bounds|x64.ActiveCfg = Debug|x64 + {B4CDC940-DDA7-4EEC-87A6-8441CF47EE7E}.Bounds|x64.Build.0 = Debug|x64 + {B4CDC940-DDA7-4EEC-87A6-8441CF47EE7E}.Debug|x64.ActiveCfg = Debug|x64 + {B4CDC940-DDA7-4EEC-87A6-8441CF47EE7E}.Debug|x64.Build.0 = Debug|x64 + {B4CDC940-DDA7-4EEC-87A6-8441CF47EE7E}.Release|x64.ActiveCfg = Release|x64 + {B4CDC940-DDA7-4EEC-87A6-8441CF47EE7E}.Release|x64.Build.0 = Release|x64 + {2C57CEB5-40DE-4229-89B8-BADE30687815}.Bounds|x64.ActiveCfg = Debug|x64 + {2C57CEB5-40DE-4229-89B8-BADE30687815}.Bounds|x64.Build.0 = Debug|x64 + {2C57CEB5-40DE-4229-89B8-BADE30687815}.Debug|x64.ActiveCfg = Debug|x64 + {2C57CEB5-40DE-4229-89B8-BADE30687815}.Debug|x64.Build.0 = Debug|x64 + {2C57CEB5-40DE-4229-89B8-BADE30687815}.Release|x64.ActiveCfg = Release|x64 + {2C57CEB5-40DE-4229-89B8-BADE30687815}.Release|x64.Build.0 = Release|x64 + {0EDB239B-A523-4259-9123-EBA3B7E0139F}.Bounds|x64.ActiveCfg = Debug|x64 + {0EDB239B-A523-4259-9123-EBA3B7E0139F}.Bounds|x64.Build.0 = Debug|x64 + {0EDB239B-A523-4259-9123-EBA3B7E0139F}.Debug|x64.ActiveCfg = Debug|x64 + {0EDB239B-A523-4259-9123-EBA3B7E0139F}.Debug|x64.Build.0 = Debug|x64 + {0EDB239B-A523-4259-9123-EBA3B7E0139F}.Release|x64.ActiveCfg = Release|x64 + {0EDB239B-A523-4259-9123-EBA3B7E0139F}.Release|x64.Build.0 = Release|x64 + {AF29BF64-3F6E-4CD9-BC70-AFB68F563173}.Bounds|x64.ActiveCfg = Debug|x64 + {AF29BF64-3F6E-4CD9-BC70-AFB68F563173}.Bounds|x64.Build.0 = Debug|x64 + {AF29BF64-3F6E-4CD9-BC70-AFB68F563173}.Debug|x64.ActiveCfg = Debug|x64 + {AF29BF64-3F6E-4CD9-BC70-AFB68F563173}.Debug|x64.Build.0 = Debug|x64 + {AF29BF64-3F6E-4CD9-BC70-AFB68F563173}.Release|x64.ActiveCfg = Release|x64 + {AF29BF64-3F6E-4CD9-BC70-AFB68F563173}.Release|x64.Build.0 = Release|x64 + {91219E68-FF1D-4DED-BB06-3A6AF46C0419}.Bounds|x64.ActiveCfg = Debug|x64 + {91219E68-FF1D-4DED-BB06-3A6AF46C0419}.Bounds|x64.Build.0 = Debug|x64 + {91219E68-FF1D-4DED-BB06-3A6AF46C0419}.Debug|x64.ActiveCfg = Debug|x64 + {91219E68-FF1D-4DED-BB06-3A6AF46C0419}.Debug|x64.Build.0 = Debug|x64 + {91219E68-FF1D-4DED-BB06-3A6AF46C0419}.Release|x64.ActiveCfg = Release|x64 + {91219E68-FF1D-4DED-BB06-3A6AF46C0419}.Release|x64.Build.0 = Release|x64 {6A3359E7-E3DA-4CF6-B6F8-C6A4E8D9800B}.Bounds|x64.ActiveCfg = Debug|x64 {6A3359E7-E3DA-4CF6-B6F8-C6A4E8D9800B}.Bounds|x64.Build.0 = Debug|x64 {6A3359E7-E3DA-4CF6-B6F8-C6A4E8D9800B}.Debug|x64.ActiveCfg = Debug|x64 @@ -1045,54 +1097,18 @@ Global {1D9F7F7D-F4DE-43DC-9E1D-9D0E512D1CB6}.Debug|x64.Build.0 = Debug|x64 {1D9F7F7D-F4DE-43DC-9E1D-9D0E512D1CB6}.Release|x64.ActiveCfg = Release|x64 {1D9F7F7D-F4DE-43DC-9E1D-9D0E512D1CB6}.Release|x64.Build.0 = Release|x64 - {996498A3-06F1-4B1B-B83F-15648DD8F514}.Bounds|x64.ActiveCfg = Debug|x64 - {996498A3-06F1-4B1B-B83F-15648DD8F514}.Bounds|x64.Build.0 = Debug|x64 - {996498A3-06F1-4B1B-B83F-15648DD8F514}.Debug|x64.ActiveCfg = Debug|x64 - {996498A3-06F1-4B1B-B83F-15648DD8F514}.Debug|x64.Build.0 = Debug|x64 - {996498A3-06F1-4B1B-B83F-15648DD8F514}.Release|x64.ActiveCfg = Release|x64 - {996498A3-06F1-4B1B-B83F-15648DD8F514}.Release|x64.Build.0 = Release|x64 - {ECEC3C09-019A-4B31-B72A-C4A22DE88E84}.Bounds|x64.ActiveCfg = Debug|x64 - {ECEC3C09-019A-4B31-B72A-C4A22DE88E84}.Bounds|x64.Build.0 = Debug|x64 - {ECEC3C09-019A-4B31-B72A-C4A22DE88E84}.Debug|x64.ActiveCfg = Debug|x64 - {ECEC3C09-019A-4B31-B72A-C4A22DE88E84}.Debug|x64.Build.0 = Debug|x64 - {ECEC3C09-019A-4B31-B72A-C4A22DE88E84}.Release|x64.ActiveCfg = Release|x64 - {ECEC3C09-019A-4B31-B72A-C4A22DE88E84}.Release|x64.Build.0 = Release|x64 - {98A04BE3-5CDA-4616-9396-E40B33CC9256}.Bounds|x64.ActiveCfg = Debug|x64 - {98A04BE3-5CDA-4616-9396-E40B33CC9256}.Bounds|x64.Build.0 = Debug|x64 - {98A04BE3-5CDA-4616-9396-E40B33CC9256}.Debug|x64.ActiveCfg = Debug|x64 - {98A04BE3-5CDA-4616-9396-E40B33CC9256}.Debug|x64.Build.0 = Debug|x64 - {98A04BE3-5CDA-4616-9396-E40B33CC9256}.Release|x64.ActiveCfg = Release|x64 - {98A04BE3-5CDA-4616-9396-E40B33CC9256}.Release|x64.Build.0 = Release|x64 - {B4CDC940-DDA7-4EEC-87A6-8441CF47EE7E}.Bounds|x64.ActiveCfg = Debug|x64 - {B4CDC940-DDA7-4EEC-87A6-8441CF47EE7E}.Bounds|x64.Build.0 = Debug|x64 - {B4CDC940-DDA7-4EEC-87A6-8441CF47EE7E}.Debug|x64.ActiveCfg = Debug|x64 - {B4CDC940-DDA7-4EEC-87A6-8441CF47EE7E}.Debug|x64.Build.0 = Debug|x64 - {B4CDC940-DDA7-4EEC-87A6-8441CF47EE7E}.Release|x64.ActiveCfg = Release|x64 - {B4CDC940-DDA7-4EEC-87A6-8441CF47EE7E}.Release|x64.Build.0 = Release|x64 - {2C57CEB5-40DE-4229-89B8-BADE30687815}.Bounds|x64.ActiveCfg = Debug|x64 - {2C57CEB5-40DE-4229-89B8-BADE30687815}.Bounds|x64.Build.0 = Debug|x64 - {2C57CEB5-40DE-4229-89B8-BADE30687815}.Debug|x64.ActiveCfg = Debug|x64 - {2C57CEB5-40DE-4229-89B8-BADE30687815}.Debug|x64.Build.0 = Debug|x64 - {2C57CEB5-40DE-4229-89B8-BADE30687815}.Release|x64.ActiveCfg = Release|x64 - {2C57CEB5-40DE-4229-89B8-BADE30687815}.Release|x64.Build.0 = Release|x64 - {0EDB239B-A523-4259-9123-EBA3B7E0139F}.Bounds|x64.ActiveCfg = Debug|x64 - {0EDB239B-A523-4259-9123-EBA3B7E0139F}.Bounds|x64.Build.0 = Debug|x64 - {0EDB239B-A523-4259-9123-EBA3B7E0139F}.Debug|x64.ActiveCfg = Debug|x64 - {0EDB239B-A523-4259-9123-EBA3B7E0139F}.Debug|x64.Build.0 = Debug|x64 - {0EDB239B-A523-4259-9123-EBA3B7E0139F}.Release|x64.ActiveCfg = Release|x64 - {0EDB239B-A523-4259-9123-EBA3B7E0139F}.Release|x64.Build.0 = Release|x64 - {AF29BF64-3F6E-4CD9-BC70-AFB68F563173}.Bounds|x64.ActiveCfg = Debug|x64 - {AF29BF64-3F6E-4CD9-BC70-AFB68F563173}.Bounds|x64.Build.0 = Debug|x64 - {AF29BF64-3F6E-4CD9-BC70-AFB68F563173}.Debug|x64.ActiveCfg = Debug|x64 - {AF29BF64-3F6E-4CD9-BC70-AFB68F563173}.Debug|x64.Build.0 = Debug|x64 - {AF29BF64-3F6E-4CD9-BC70-AFB68F563173}.Release|x64.ActiveCfg = Release|x64 - {AF29BF64-3F6E-4CD9-BC70-AFB68F563173}.Release|x64.Build.0 = Release|x64 - {91219E68-FF1D-4DED-BB06-3A6AF46C0419}.Bounds|x64.ActiveCfg = Debug|x64 - {91219E68-FF1D-4DED-BB06-3A6AF46C0419}.Bounds|x64.Build.0 = Debug|x64 - {91219E68-FF1D-4DED-BB06-3A6AF46C0419}.Debug|x64.ActiveCfg = Debug|x64 - {91219E68-FF1D-4DED-BB06-3A6AF46C0419}.Debug|x64.Build.0 = Debug|x64 - {91219E68-FF1D-4DED-BB06-3A6AF46C0419}.Release|x64.ActiveCfg = Release|x64 - {91219E68-FF1D-4DED-BB06-3A6AF46C0419}.Release|x64.Build.0 = Release|x64 + {1D4CC42D-BC16-4EC3-A89B-173798828F56}.Bounds|x64.ActiveCfg = Debug|x64 + {1D4CC42D-BC16-4EC3-A89B-173798828F56}.Bounds|x64.Build.0 = Debug|x64 + {1D4CC42D-BC16-4EC3-A89B-173798828F56}.Debug|x64.ActiveCfg = Debug|x64 + {1D4CC42D-BC16-4EC3-A89B-173798828F56}.Debug|x64.Build.0 = Debug|x64 + {1D4CC42D-BC16-4EC3-A89B-173798828F56}.Release|x64.ActiveCfg = Release|x64 + {1D4CC42D-BC16-4EC3-A89B-173798828F56}.Release|x64.Build.0 = Release|x64 + {C644C392-FB14-4DF1-9989-897E182D3849}.Bounds|x64.ActiveCfg = Debug|x64 + {C644C392-FB14-4DF1-9989-897E182D3849}.Bounds|x64.Build.0 = Debug|x64 + {C644C392-FB14-4DF1-9989-897E182D3849}.Debug|x64.ActiveCfg = Debug|x64 + {C644C392-FB14-4DF1-9989-897E182D3849}.Debug|x64.Build.0 = Debug|x64 + {C644C392-FB14-4DF1-9989-897E182D3849}.Release|x64.ActiveCfg = Release|x64 + {C644C392-FB14-4DF1-9989-897E182D3849}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 9629455dac286a3b0127e9173466a74dd347b3bc Mon Sep 17 00:00:00 2001 From: Hasso Date: Mon, 6 Apr 2026 16:46:55 -0500 Subject: [PATCH 02/15] Clean up commented code in TestUtil.h --- Src/Generic/Test/TestUtil.h | 81 +------------------------------------ 1 file changed, 1 insertion(+), 80 deletions(-) diff --git a/Src/Generic/Test/TestUtil.h b/Src/Generic/Test/TestUtil.h index 8160b3f14e..367184ffa3 100644 --- a/Src/Generic/Test/TestUtil.h +++ b/Src/Generic/Test/TestUtil.h @@ -1,5 +1,5 @@ /*--------------------------------------------------------------------*//*:Ignore this sentence. -Copyright (c) 2003-2013 SIL International +Copyright (c) 2003-2026 SIL International This software is licensed under the LGPL, version 2.1 or later (http://www.gnu.org/licenses/lgpl-2.1.html) @@ -100,85 +100,6 @@ namespace TestGenericLib //GetFullPathName(const achar * psz, StrAnsi & staPath) // ... -// Clipboard is entirely handled in C# now -// void GetClipboardFormat(CLIPFORMAT cf, StrUni stuNFC) -// { -// // TODO-Linux: Clipboard not supported in C++ -//#ifdef WIN32 -// FORMATETC format; -// STGMEDIUM medium; -// -// HRESULT hr; -// IDataObjectPtr qdobj; -// for (int i = 0; i < 10; i++) // try up to 20 times. -// { -// hr = ::OleGetClipboard(&qdobj); -// if (SUCCEEDED(hr)) -// break; -// ::Sleep(100); -// } -// CheckHr(hr); -// -// format.cfFormat = static_cast(cf); -// format.ptd = NULL; -// format.dwAspect = DVASPECT_CONTENT; -// format.lindex = -1; -// format.tymed = TYMED_HGLOBAL; -// -// hr = qdobj->GetData(&format, &medium); -// if (hr == S_OK) -// { -// StrUni stu; -// if (medium.tymed == TYMED_HGLOBAL && medium.hGlobal) -// { -// const char * pszClip; -// const wchar * pwszClip; -// switch(cf) -// { -// case CF_OEMTEXT: -// case CF_TEXT: -// pszClip = (const char *)::GlobalLock(medium.hGlobal); -// stu = pszClip; -// break; -// -// case CF_UNICODETEXT: -// default: -// pwszClip = (const wchar *)::GlobalLock(medium.hGlobal); -// stu = pwszClip; -// } -// ::GlobalUnlock(medium.hGlobal); -// } -// ::ReleaseStgMedium(&medium); -// unitpp::assert_true("Clipboard data normalized correctly in some format", -// stu.Equals(stuNFC.Chars(), stuNFC.Length())); -// } -// else -// unitpp::assert_true("GetData failed in GetClipboardFormat", 0); -//#endif -// } -// -// void testGetDataNormalized() -// { -// // TODO-Linux: Clipboard not supported in C++ -//#ifdef WIN32 -// StrUni stuIn = L"Te\x0301sting"; -// StrUni stuNFC = L"T\x00e9sting"; -// IDataObjectPtr qdobj; -// StringDataObject::Create(const_cast(stuIn.Chars()), &qdobj); -// if (::OleSetClipboard(qdobj) == S_OK) -// { -// ModuleEntry::SetClipboard(qdobj); -// } -// qdobj.Clear(); // Let go of our connection to the clipboard; seems to make tests at least more reliable. -// -// GetClipboardFormat(CF_UNICODETEXT, stuNFC); -// GetClipboardFormat(CF_OEMTEXT, stuNFC); -// GetClipboardFormat(CF_TEXT, stuNFC); -// -// ::OleSetClipboard(NULL); // reset the clipboard {release the object} -//#endif -// } - public: TestUtil(); }; From 2dab8674b6766d7862593a3cb8264fd426852d29 Mon Sep 17 00:00:00 2001 From: Hasso Date: Mon, 6 Apr 2026 16:47:15 -0500 Subject: [PATCH 03/15] TEST native test reporting --- Src/Generic/Test/TestUtil.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Src/Generic/Test/TestUtil.h b/Src/Generic/Test/TestUtil.h index 367184ffa3..482fd8b6ff 100644 --- a/Src/Generic/Test/TestUtil.h +++ b/Src/Generic/Test/TestUtil.h @@ -21,6 +21,10 @@ namespace TestGenericLib { class TestUtil : public unitpp::suite { + void testFailure() + { + unitpp::assert_fail("Oh, what fun it is to type in a one-line failing test, hey!"); + } void testGetPrimeNear() { uint u; From 8ad91f37c673ecb519a1bbf81f6a2b6e3d8b5133 Mon Sep 17 00:00:00 2001 From: Hasso Date: Mon, 6 Apr 2026 17:20:28 -0500 Subject: [PATCH 04/15] Run native tests every time --- test.ps1 | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/test.ps1 b/test.ps1 index 7ec8ec875a..e0e6ced55c 100644 --- a/test.ps1 +++ b/test.ps1 @@ -140,7 +140,7 @@ try { # Native Tests Dispatch # ============================================================================= - if ($Native) { + #if ($Native) { $cppScript = Join-Path $PSScriptRoot "Build/scripts/Invoke-CppTest.ps1" if (-not (Test-Path $cppScript)) { Write-Host "[ERROR] Native test script not found at $cppScript" -ForegroundColor Red @@ -174,8 +174,8 @@ try { } } $script:testExitCode = $overallExitCode - return - } + # return + #} # ============================================================================= # Build (unless -NoBuild) @@ -445,7 +445,10 @@ try { $ErrorActionPreference = 'Continue' try { & $vstestPath $vstestArgs 2>&1 | Tee-Object -Variable testOutput - $script:testExitCode = $LASTEXITCODE + # Don't overwrite a non-zero exit code from native tests with a zero exit code from these tests. + if ($LASTEXITCODE -ne 0) { + $script:testExitCode = $LASTEXITCODE + } } finally { $ErrorActionPreference = $previousEap From a1fb9ee1218291a08b5c3da90a559795d7724912 Mon Sep 17 00:00:00 2001 From: Hasso Date: Tue, 7 Apr 2026 16:55:57 -0500 Subject: [PATCH 05/15] Run native tests from the same GHA --- .github/workflows/CI-native.yml | 83 --------------------------------- .github/workflows/CI.yml | 18 ++++--- 2 files changed, 12 insertions(+), 89 deletions(-) delete mode 100644 .github/workflows/CI-native.yml diff --git a/.github/workflows/CI-native.yml b/.github/workflows/CI-native.yml deleted file mode 100644 index 6c77c9a10a..0000000000 --- a/.github/workflows/CI-native.yml +++ /dev/null @@ -1,83 +0,0 @@ -name: Flex CI Native -on: - push: - branches: ["release/**", "main", "feature/PubSub"] - paths: - - 'Src/**/*.cpp' - - 'Src/**/*.h' - - 'Src/**/*.hpp' - - 'Src/**/*.cc' - - 'Src/**/*.ixx' - - 'Src/**/*.def' - - 'Src/**/*.vcxproj' - - 'Src/**/*.vcxproj.filters' - - 'Src/**/*.mak' - - 'Lib/**/*.cpp' - - 'Lib/**/*.h' - - 'Lib/**/*.hpp' - - 'Lib/**/*.cc' - - 'Lib/**/*.ixx' - - 'Lib/**/*.def' - - 'Build/Src/NativeBuild/**' - - 'Build/scripts/Invoke-CppTest.ps1' - - 'test.ps1' - pull_request: - branches: ["release/**", "main", "feature/PubSub"] - paths: - - 'Src/**/*.cpp' - - 'Src/**/*.h' - - 'Src/**/*.hpp' - - 'Src/**/*.cc' - - 'Src/**/*.ixx' - - 'Src/**/*.def' - - 'Src/**/*.vcxproj' - - 'Src/**/*.vcxproj.filters' - - 'Src/**/*.mak' - - 'Lib/**/*.cpp' - - 'Lib/**/*.h' - - 'Lib/**/*.hpp' - - 'Lib/**/*.cc' - - 'Lib/**/*.ixx' - - 'Lib/**/*.def' - - 'Build/Src/NativeBuild/**' - - 'Build/scripts/Invoke-CppTest.ps1' - - 'test.ps1' - workflow_dispatch: - -permissions: - contents: read - checks: write - -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - -jobs: - native_build_and_test: - name: Build Debug and run native tests - runs-on: windows-latest - steps: - - name: Checkout Files - uses: actions/checkout@v6 - id: checkout - - - name: Build and run native tests - id: native_test - shell: powershell - run: | - .\test.ps1 -Configuration Debug -Native - if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } - - - name: Summarize native test results - if: ${{ always() }} - shell: powershell - run: | - .\Build\Agent\Summarize-NativeTestResults.ps1 -Configuration Debug - - - uses: actions/upload-artifact@v7 - if: ${{ !cancelled() && failure() }} - with: - name: native-build-logs - path: | - ./*.log - ./Output/**/*.log diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 2ef7b55d3c..1ffb096725 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -16,28 +16,34 @@ concurrency: jobs: debug_build_and_test: - name: Build Debug and run managed tests + name: Build Debug and run native and managed tests runs-on: windows-latest steps: - name: Checkout Files uses: actions/checkout@v6 id: checkout - - name: Build managed (with tests) - id: managed_build + - name: Build (with tests) + id: build_with_tests shell: powershell run: | .\build.ps1 -Configuration Debug -BuildTests if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } - - name: Run managed tests - id: managed_test + - name: Run native and managed tests + id: run_tests shell: powershell run: | .\test.ps1 -Configuration Debug -NoBuild -TestFilter 'TestCategory!=LongRunning&TestCategory!=ByHand&TestCategory!=SmokeTest&TestCategory!=DesktopRequired' if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } - - name: Upload TRX test results + - name: Summarize native test results + if: ${{ always() }} + shell: powershell + run: | + .\Build\Agent\Summarize-NativeTestResults.ps1 -Configuration Debug + + - name: Upload TRX managed test results if: ${{ !cancelled() }} uses: actions/upload-artifact@v7 with: From fceec0845669d6b28e4b1a82eaf60728e11ec04b Mon Sep 17 00:00:00 2001 From: Hasso Date: Wed, 8 Apr 2026 11:19:12 -0500 Subject: [PATCH 06/15] Revert "Run native tests from the same GHA" This reverts commit a1fb9ee1218291a08b5c3da90a559795d7724912. --- .github/workflows/CI-native.yml | 83 +++++++++++++++++++++++++++++++++ .github/workflows/CI.yml | 18 +++---- 2 files changed, 89 insertions(+), 12 deletions(-) create mode 100644 .github/workflows/CI-native.yml diff --git a/.github/workflows/CI-native.yml b/.github/workflows/CI-native.yml new file mode 100644 index 0000000000..6c77c9a10a --- /dev/null +++ b/.github/workflows/CI-native.yml @@ -0,0 +1,83 @@ +name: Flex CI Native +on: + push: + branches: ["release/**", "main", "feature/PubSub"] + paths: + - 'Src/**/*.cpp' + - 'Src/**/*.h' + - 'Src/**/*.hpp' + - 'Src/**/*.cc' + - 'Src/**/*.ixx' + - 'Src/**/*.def' + - 'Src/**/*.vcxproj' + - 'Src/**/*.vcxproj.filters' + - 'Src/**/*.mak' + - 'Lib/**/*.cpp' + - 'Lib/**/*.h' + - 'Lib/**/*.hpp' + - 'Lib/**/*.cc' + - 'Lib/**/*.ixx' + - 'Lib/**/*.def' + - 'Build/Src/NativeBuild/**' + - 'Build/scripts/Invoke-CppTest.ps1' + - 'test.ps1' + pull_request: + branches: ["release/**", "main", "feature/PubSub"] + paths: + - 'Src/**/*.cpp' + - 'Src/**/*.h' + - 'Src/**/*.hpp' + - 'Src/**/*.cc' + - 'Src/**/*.ixx' + - 'Src/**/*.def' + - 'Src/**/*.vcxproj' + - 'Src/**/*.vcxproj.filters' + - 'Src/**/*.mak' + - 'Lib/**/*.cpp' + - 'Lib/**/*.h' + - 'Lib/**/*.hpp' + - 'Lib/**/*.cc' + - 'Lib/**/*.ixx' + - 'Lib/**/*.def' + - 'Build/Src/NativeBuild/**' + - 'Build/scripts/Invoke-CppTest.ps1' + - 'test.ps1' + workflow_dispatch: + +permissions: + contents: read + checks: write + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + native_build_and_test: + name: Build Debug and run native tests + runs-on: windows-latest + steps: + - name: Checkout Files + uses: actions/checkout@v6 + id: checkout + + - name: Build and run native tests + id: native_test + shell: powershell + run: | + .\test.ps1 -Configuration Debug -Native + if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } + + - name: Summarize native test results + if: ${{ always() }} + shell: powershell + run: | + .\Build\Agent\Summarize-NativeTestResults.ps1 -Configuration Debug + + - uses: actions/upload-artifact@v7 + if: ${{ !cancelled() && failure() }} + with: + name: native-build-logs + path: | + ./*.log + ./Output/**/*.log diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 1ffb096725..2ef7b55d3c 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -16,34 +16,28 @@ concurrency: jobs: debug_build_and_test: - name: Build Debug and run native and managed tests + name: Build Debug and run managed tests runs-on: windows-latest steps: - name: Checkout Files uses: actions/checkout@v6 id: checkout - - name: Build (with tests) - id: build_with_tests + - name: Build managed (with tests) + id: managed_build shell: powershell run: | .\build.ps1 -Configuration Debug -BuildTests if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } - - name: Run native and managed tests - id: run_tests + - name: Run managed tests + id: managed_test shell: powershell run: | .\test.ps1 -Configuration Debug -NoBuild -TestFilter 'TestCategory!=LongRunning&TestCategory!=ByHand&TestCategory!=SmokeTest&TestCategory!=DesktopRequired' if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } - - name: Summarize native test results - if: ${{ always() }} - shell: powershell - run: | - .\Build\Agent\Summarize-NativeTestResults.ps1 -Configuration Debug - - - name: Upload TRX managed test results + - name: Upload TRX test results if: ${{ !cancelled() }} uses: actions/upload-artifact@v7 with: From 9284bb27d99a47e4673c3b0de01e9b41210e8058 Mon Sep 17 00:00:00 2001 From: Hasso Date: Wed, 8 Apr 2026 11:50:22 -0500 Subject: [PATCH 07/15] Filter tests --- .github/workflows/CI-native.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CI-native.yml b/.github/workflows/CI-native.yml index 6c77c9a10a..121ef15060 100644 --- a/.github/workflows/CI-native.yml +++ b/.github/workflows/CI-native.yml @@ -65,7 +65,7 @@ jobs: id: native_test shell: powershell run: | - .\test.ps1 -Configuration Debug -Native + .\test.ps1 -Configuration Debug -TestFilter 'TestCategory!=LongRunning&TestCategory!=ByHand&TestCategory!=SmokeTest&TestCategory!=DesktopRequired' if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } - name: Summarize native test results From be8be0c56f831a746a3b6a5c6d9fd4c5c534de92 Mon Sep 17 00:00:00 2001 From: Hasso Date: Thu, 9 Apr 2026 11:52:19 -0500 Subject: [PATCH 08/15] Include native failures in the failure summary --- test.ps1 | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/test.ps1 b/test.ps1 index e0e6ced55c..7068d0ccda 100644 --- a/test.ps1 +++ b/test.ps1 @@ -26,6 +26,12 @@ Test output verbosity: q[uiet], m[inimal], n[ormal], d[etailed]. Default is 'normal'. +.PARAMETER NoNative + Skip running native C++ tests. Run only managed tests. + +.PARAMETER NativeOnly + Run only native C++ tests, skipping managed tests. + .PARAMETER StartedBy Optional actor label written to worktree lock metadata (for example: user or agent). Defaults to FW_BUILD_STARTED_BY if set; otherwise 'unknown'. @@ -62,7 +68,8 @@ param( [switch]$ListTests, [ValidateSet('quiet', 'minimal', 'normal', 'detailed', 'q', 'm', 'n', 'd')] [string]$Verbosity = "normal", - [switch]$Native, + [switch]$NoNative, + [switch]$NativeOnly, [switch]$SkipDependencyCheck, [switch]$SkipWorktreeLock, [ValidateSet('user', 'agent', 'unknown')] @@ -140,7 +147,8 @@ try { # Native Tests Dispatch # ============================================================================= - #if ($Native) { + $script:nativeErrorMessages = @() + if (-not $NoNative) { $cppScript = Join-Path $PSScriptRoot "Build/scripts/Invoke-CppTest.ps1" if (-not (Test-Path $cppScript)) { Write-Host "[ERROR] Native test script not found at $cppScript" -ForegroundColor Red @@ -170,12 +178,17 @@ try { & $cppScript -Action $action -TestProject $proj -Configuration $Configuration if ($LASTEXITCODE -ne 0) { $overallExitCode = $LASTEXITCODE - Write-Host "[ERROR] $proj failed with exit code $LASTEXITCODE" -ForegroundColor Red + $message = "$proj failed with exit code $LASTEXITCODE" + $script:nativeErrorMessages += $message + Write-Host "[ERROR] $message" -ForegroundColor Red } } $script:testExitCode = $overallExitCode - # return - #} + + if ($NativeOnly) { + return + } + } # ============================================================================= # Build (unless -NoBuild) @@ -539,6 +552,14 @@ if ($testExitCode -ne 0 -and (Test-Path $vstestLogPath)) { Write-Host "" Write-Host "========== FAILURE SUMMARY ==========" -ForegroundColor Red + if ($script:nativeErrorMessages.Count -gt 0) { + Write-Host "Native test failures:" -ForegroundColor Red + foreach ($msg in $script:nativeErrorMessages) { + Write-Host " $msg" -ForegroundColor Red + } + Write-Host "=====================================" -ForegroundColor Red + } + $logLines = Get-Content $vstestLogPath $failedTests = @() for ($i = 0; $i -lt $logLines.Count; $i++) { @@ -575,7 +596,10 @@ if ($testExitCode -ne 0 -and (Test-Path $vstestLogPath)) { } Write-Host "=====================================" -ForegroundColor Red - Write-Host " Full log: $vstestLogPath" -ForegroundColor Gray + Write-Host " Full log for managed tests: $vstestLogPath" -ForegroundColor Gray + if (-not $NoNative) { + Write-Host " Native test logs for each suite are in the same folder." -ForegroundColor Gray + } } if ($testExitCode -eq 0) { From db07d78f9cd971abc321be2aaf96f710d30d027f Mon Sep 17 00:00:00 2001 From: Hasso Date: Thu, 9 Apr 2026 13:32:53 -0500 Subject: [PATCH 09/15] Run all tests in one place --- .github/workflows/CI.yml | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 2ef7b55d3c..9cf651e9fe 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -16,28 +16,27 @@ concurrency: jobs: debug_build_and_test: - name: Build Debug and run managed tests + name: Build Debug and run all tests runs-on: windows-latest steps: - name: Checkout Files uses: actions/checkout@v6 id: checkout - - name: Build managed (with tests) - id: managed_build + - name: Build and run tests + id: test shell: powershell run: | - .\build.ps1 -Configuration Debug -BuildTests + .\test.ps1 -Configuration Debug -TestFilter 'TestCategory!=LongRunning&TestCategory!=ByHand&TestCategory!=SmokeTest&TestCategory!=DesktopRequired' if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } - - name: Run managed tests - id: managed_test + - name: Summarize native test results + if: ${{ always() }} shell: powershell run: | - .\test.ps1 -Configuration Debug -NoBuild -TestFilter 'TestCategory!=LongRunning&TestCategory!=ByHand&TestCategory!=SmokeTest&TestCategory!=DesktopRequired' - if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } + .\Build\Agent\Summarize-NativeTestResults.ps1 -Configuration Debug - - name: Upload TRX test results + - name: Upload TRX test results (managed) if: ${{ !cancelled() }} uses: actions/upload-artifact@v7 with: From 1001a581906c2d119e0eef0c29678d4f224af5a6 Mon Sep 17 00:00:00 2001 From: Hasso Date: Thu, 9 Apr 2026 13:59:29 -0500 Subject: [PATCH 10/15] Fix path to native tests in summary message (Finding and passing the actual path would be a lot of work, since the native suites are actually called by a different script.) --- test.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.ps1 b/test.ps1 index 7068d0ccda..1305a9b277 100644 --- a/test.ps1 +++ b/test.ps1 @@ -598,7 +598,7 @@ if ($testExitCode -ne 0 -and (Test-Path $vstestLogPath)) { Write-Host "=====================================" -ForegroundColor Red Write-Host " Full log for managed tests: $vstestLogPath" -ForegroundColor Gray if (-not $NoNative) { - Write-Host " Native test logs for each suite are in the same folder." -ForegroundColor Gray + Write-Host " Logs for each native test suite should be in the directory above (Output\$Configuration)." -ForegroundColor Gray } } From 8247a50a0b0bb7319991c5cf86a0f8296581d75f Mon Sep 17 00:00:00 2001 From: Hasso Date: Mon, 9 Mar 2026 11:07:07 -0500 Subject: [PATCH 11/15] test tests --- Src/CacheLight/CacheLightTests/MetaDataCacheTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/CacheLight/CacheLightTests/MetaDataCacheTests.cs b/Src/CacheLight/CacheLightTests/MetaDataCacheTests.cs index f946bf945d..5d6c6bbe3f 100644 --- a/Src/CacheLight/CacheLightTests/MetaDataCacheTests.cs +++ b/Src/CacheLight/CacheLightTests/MetaDataCacheTests.cs @@ -362,7 +362,7 @@ public class MetaDataCacheFieldAccessTests : MetaDataCacheBase [Test] public void GetDstClsNameTest() { - Assert.That(m_metaDataCache.GetDstClsName(59005), Is.EqualTo("ClassL"), "Wrong class name"); + Assert.Fail("just checking"); } /// From e11b85ab94c9df585e2c24b4b6484af8619aeba5 Mon Sep 17 00:00:00 2001 From: Hasso Date: Fri, 10 Apr 2026 11:27:30 -0500 Subject: [PATCH 12/15] Param to skip build tasks (default to skip?) Building build tasks doesn't work when the DLL is locked, as has been the case often on my machine this week. REVIEW: would it be better to default to not building if they exist already, since they rarely change? --- build.ps1 | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/build.ps1 b/build.ps1 index a7181b885a..85ead263d6 100644 --- a/build.ps1 +++ b/build.ps1 @@ -57,6 +57,15 @@ Useful for CI/agent scenarios where you want to see recent output without piping. The full output is still written to LogFile if specified. +.PARAMETER SkipRestore + Skips restoring NuGet packages + +.PARAMETER SkipBuildTasks + Skips building FwBuildTasks. + +.PARAMETER SkipNative + Skips building native C++ components. Use this for faster iterations when making purely managed code changes. + .PARAMETER BuildInstaller If set, builds the installer via Build/InstallerBuild.proj after the main build. This automatically enables -BuildAdditionalApps unless explicitly disabled. @@ -151,6 +160,7 @@ param( [string]$LogFile, [int]$TailLines, [switch]$SkipRestore, + [switch]$SkipBuildTasks, [switch]$SkipNative, [switch]$BuildInstaller, [switch]$BuildPatch, @@ -511,12 +521,14 @@ try { } # Bootstrap: Build FwBuildTasks first (required by SetupInclude.targets) - $fwBuildTasksOutputDir = Join-Path $PSScriptRoot "BuildTools/FwBuildTasks/$Configuration/" - Invoke-MSBuild ` - -Arguments @('Build/Src/FwBuildTasks/FwBuildTasks.csproj', '/t:Restore;Build', "/p:Configuration=$Configuration", "/p:Platform=$Platform", ` - "/p:FwBuildTasksOutputPath=$fwBuildTasksOutputDir", "/p:SkipFwBuildTasksAssemblyCheck=true", "/p:SkipFwBuildTasksUsingTask=true", "/p:SkipGenerateFwTargets=true", ` - "/p:SkipSetupTargets=true", "/v:quiet", "/nologo") ` - -Description 'FwBuildTasks (Bootstrap)' + if (-not $SkipBuildTasks) { + $fwBuildTasksOutputDir = Join-Path $PSScriptRoot "BuildTools/FwBuildTasks/$Configuration/" + Invoke-MSBuild ` + -Arguments @('Build/Src/FwBuildTasks/FwBuildTasks.csproj', '/t:Restore;Build', "/p:Configuration=$Configuration", "/p:Platform=$Platform", ` + "/p:FwBuildTasksOutputPath=$fwBuildTasksOutputDir", "/p:SkipFwBuildTasksAssemblyCheck=true", "/p:SkipFwBuildTasksUsingTask=true", "/p:SkipGenerateFwTargets=true", ` + "/p:SkipSetupTargets=true", "/v:quiet", "/nologo") ` + -Description 'FwBuildTasks (Bootstrap)' + } if (-not (Test-Path $fwTasksSourcePath)) { throw "Failed to build FwBuildTasks. Expected $fwTasksSourcePath to exist." From 4dee30286a86f5fcc315c8131be09b685f5f7766 Mon Sep 17 00:00:00 2001 From: Hasso Date: Fri, 10 Apr 2026 12:08:02 -0500 Subject: [PATCH 13/15] Copilot's stab at building tests Claude Haiku 4.5. I think I would change how the targets are conditioned. --- Build/Src/NativeBuild/NativeBuild.csproj | 2 +- Build/mkall.targets | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/Build/Src/NativeBuild/NativeBuild.csproj b/Build/Src/NativeBuild/NativeBuild.csproj index 5ace008eea..74577aaef1 100644 --- a/Build/Src/NativeBuild/NativeBuild.csproj +++ b/Build/Src/NativeBuild/NativeBuild.csproj @@ -68,7 +68,7 @@ - + diff --git a/Build/mkall.targets b/Build/mkall.targets index 4b77f4f212..de462a1b84 100644 --- a/Build/mkall.targets +++ b/Build/mkall.targets @@ -22,7 +22,26 @@ + + + + + + + + + + + + + + + + + + + From ad081b7efb06d574ffa6c5daa7a9fb1b45e4b704 Mon Sep 17 00:00:00 2001 From: Hasso Date: Fri, 10 Apr 2026 13:56:00 -0500 Subject: [PATCH 14/15] my test build cleanup --- Build/mkall.targets | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/Build/mkall.targets b/Build/mkall.targets index de462a1b84..56d34f406f 100644 --- a/Build/mkall.targets +++ b/Build/mkall.targets @@ -22,15 +22,9 @@ - - - - - + - - - + From 3bf69affdbf37cabd64e209f3920156409fce50d Mon Sep 17 00:00:00 2001 From: Hasso Date: Fri, 10 Apr 2026 14:22:25 -0500 Subject: [PATCH 15/15] Build and run in separate steps (again) --- .github/workflows/CI.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 9cf651e9fe..439c926c59 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -16,18 +16,25 @@ concurrency: jobs: debug_build_and_test: - name: Build Debug and run all tests + name: Build Debug and run tests runs-on: windows-latest steps: - name: Checkout Files uses: actions/checkout@v6 id: checkout + - name: Build with tests + id: build + shell: powershell + run: | + .\build.ps1 -Configuration Debug -BuildTests + if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } + - name: Build and run tests id: test shell: powershell run: | - .\test.ps1 -Configuration Debug -TestFilter 'TestCategory!=LongRunning&TestCategory!=ByHand&TestCategory!=SmokeTest&TestCategory!=DesktopRequired' + .\test.ps1 -Configuration Debug -NoBuild -TestFilter 'TestCategory!=LongRunning&TestCategory!=ByHand&TestCategory!=SmokeTest&TestCategory!=DesktopRequired' if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } - name: Summarize native test results