Skip to content

Enable invariant globalization mode to remove ICU dependency#146

Merged
BrettKinny merged 1 commit intomainfrom
claude/check-globalization-features-5rZvW
Feb 14, 2026
Merged

Enable invariant globalization mode to remove ICU dependency#146
BrettKinny merged 1 commit intomainfrom
claude/check-globalization-features-5rZvW

Conversation

@BrettKinny
Copy link
Collaborator

Summary

This PR removes the runtime dependency on ICU (International Components for Unicode) libraries by enabling .NET's invariant globalization mode. This simplifies deployment and eliminates the need for platform-specific library installation steps.

Key Changes

  • Added <InvariantGlobalization>true</InvariantGlobalization> to all three project files:
    • Opcilloscope.csproj (main application)
    • Opcilloscope.TestServer.csproj (test server)
    • Opcilloscope.Tests.csproj (test project)
  • Removed ICU library installation instructions from README.md (Debian/Ubuntu and Fedora/RHEL specific steps)
  • Removed ICU library installation step from CI/CD pipeline (.github/workflows/ci.yml)

Implementation Details

By enabling invariant globalization mode, the application will use the invariant culture for all globalization operations rather than relying on system-provided ICU libraries. This is a common approach for applications that don't require locale-specific formatting or collation, reducing deployment complexity and improving portability across different Linux distributions.

https://claude.ai/code/session_01FJHaXGtwgSBicEuLMHpvVg

The app uses only culture-invariant operations (ordinal string
comparisons, fixed format strings, ISO 8601 timestamps), so full
ICU/globalization support is unnecessary. Setting
InvariantGlobalization=true in all .csproj files eliminates the
runtime dependency on libicu, simplifying Linux deployment.

https://claude.ai/code/session_01FJHaXGtwgSBicEuLMHpvVg
@claude
Copy link

claude bot commented Feb 14, 2026

Code Review

Summary

This PR enables invariant globalization mode to remove the ICU library dependency. While the goal is excellent (simplifying deployment), there are critical test failures that must be addressed before merging.


🔴 Critical Issues

1. OPC Foundation Server SDK Incompatibility

All integration tests fail with the following error when the test server attempts to start:

Opc.Ua.ServiceResultException : [80020000] 'Unexpected error starting application'
at Opc.Ua.Server.StandardServer.StartApplicationAsync(ApplicationConfiguration configuration, CancellationToken cancellationToken)

Impact: 93 out of 523 tests fail (all integration tests that require the test server).

Root cause: The OPC Foundation's OPCFoundation.NetStandard.Opc.Ua.Server library appears to be incompatible with InvariantGlobalization=true. The server component likely uses culture-specific operations internally that aren't available in invariant mode.

Recommendation:

  • Remove <InvariantGlobalization>true</InvariantGlobalization> from test projects only:
    • Tests/Opcilloscope.TestServer/Opcilloscope.TestServer.csproj
    • Tests/Opcilloscope.Tests/Opcilloscope.Tests.csproj
  • Keep it in the main Opcilloscope.csproj (the client application)
  • The client SDK works fine with invariant globalization, but the server SDK does not

2. Flaky Test - CsvRecordingManagerTests.RecordValue_WritesValueToFile

This test passes in isolation but fails intermittently when run with the full suite. This appears to be a pre-existing timing/isolation issue unrelated to this PR, but should be noted.


✅ What Works Well

  1. Code quality: All changes are minimal and focused
  2. DateTime formatting: The application correctly uses culture-invariant format strings:
    • "yyyy-MM-ddTHH:mm:ss.fff" (ISO 8601)
    • "yyyyMMdd_HHmmss" for filenames
  3. String comparisons: Proper use of StringComparison.OrdinalIgnoreCase throughout
  4. Client compatibility: The main application (OPC UA client) works perfectly with invariant globalization
  5. Documentation: README and CI workflow updates are appropriate

📋 Testing Results

Non-integration tests: ✅ 429/430 passed (1 flaky test)
Integration tests: ❌ 0/93 passed (server startup failure)
Total: ❌ 430/523 passed


🔧 Recommended Fix

diff --git a/Tests/Opcilloscope.TestServer/Opcilloscope.TestServer.csproj b/Tests/Opcilloscope.TestServer/Opcilloscope.TestServer.csproj
index 7b0dbb8..b85e40c 100644
--- a/Tests/Opcilloscope.TestServer/Opcilloscope.TestServer.csproj
+++ b/Tests/Opcilloscope.TestServer/Opcilloscope.TestServer.csproj
@@ -7,7 +7,6 @@
     <Nullable>enable</Nullable>
     <RootNamespace>Opcilloscope.TestServer</RootNamespace>
     <AssemblyName>Opcilloscope.TestServer</AssemblyName>
-    <InvariantGlobalization>true</InvariantGlobalization>
   </PropertyGroup>
 
diff --git a/Tests/Opcilloscope.Tests/Opcilloscope.Tests.csproj b/Tests/Opcilloscope.Tests/Opcilloscope.Tests.csproj
index b2e5c40..9f27636 100644
--- a/Tests/Opcilloscope.Tests/Opcilloscope.Tests.csproj
+++ b/Tests/Opcilloscope.Tests/Opcilloscope.Tests.csproj
@@ -7,7 +7,6 @@
 
     <IsPackable>false</IsPackable>
     <IsTestProject>true</IsTestProject>
-    <InvariantGlobalization>true</InvariantGlobalization>
   </PropertyGroup>

This approach:

  • ✅ Keeps the deployment simplification for end users (main app has no ICU dependency)
  • ✅ Allows integration tests to run (test server can use full globalization)
  • ✅ Test projects don't get deployed to end users anyway

🔍 Additional Considerations

Security: ✅ No security concerns
Performance: ✅ Invariant globalization may slightly improve startup time
Best practices: ✅ Proper use of culture-invariant operations throughout codebase
Breaking changes: ✅ None for end users (application behavior unchanged)


Verdict

Request changes: The test failures must be fixed before merging. The suggested fix (removing InvariantGlobalization from test projects only) maintains all the deployment benefits while ensuring tests pass.

Once tests are green, this will be an excellent improvement to the project! 🚀

@BrettKinny BrettKinny merged commit 3e65144 into main Feb 14, 2026
1 of 2 checks passed
@BrettKinny BrettKinny deleted the claude/check-globalization-features-5rZvW branch February 14, 2026 09:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants