[ 
https://issues.apache.org/jira/browse/THRIFT-6194?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Jens Geyer resolved THRIFT-6194.
--------------------------------
    Fix Version/s: 0.25.0
         Assignee: Jens Geyer
       Resolution: Fixed

> ToStringTest leaves the global locale set for the rest of the UnitTests binary
> ------------------------------------------------------------------------------
>
>                 Key: THRIFT-6194
>                 URL: https://issues.apache.org/jira/browse/THRIFT-6194
>             Project: Thrift
>          Issue Type: Bug
>          Components: C++ - Library
>            Reporter: Jens Geyer
>            Assignee: Jens Geyer
>            Priority: Minor
>             Fix For: 0.25.0
>
>          Time Spent: 20m
>  Remaining Estimate: 0h
>
> h2. What happens
> {{lib/cpp/test/ToStringTest.cpp}} has two cases that call 
> {{std::locale::global()}} and never
> restore it:
> {code:cpp}
> BOOST_AUTO_TEST_CASE(locale_en_US_int_to_string) {
>   std::locale::global(std::locale("en_US.UTF-8"));
>   BOOST_CHECK_EQUAL(to_string(1000000), "1000000");
> }
> BOOST_AUTO_TEST_CASE(locale_de_DE_floating_point_to_string) {
>   std::locale::global(std::locale("de_DE.UTF-8"));
>   ...
> }
> {code}
> Setting the global locale is the point of these cases -- they prove 
> {{to_string()}} does _not_
> follow it, which is why {{TToString.h}} imbues a default locale on the 
> streams it builds.
> Leaving it set afterwards is not the point. Every stream constructed later in 
> the same
> {{UnitTests}} binary picks it up, in suites that have nothing to do with this 
> one, and numbers
> formatted through {{std::ostringstream}} then come out with digit grouping.
> h2. Why it is worth fixing
> It has already cost one debugging session. A test in {{THttpBufferBoundTest}} 
> formats a chunk
> size through an {{ostringstream}}:
> {code:cpp}
> std::ostringstream size;
> size << std::hex << 4096;   // expected "1000"
> {code}
> which produced {{1.000}} instead. That is not a hex chunk size, so the HTTP 
> transport under test
> read a completely different stream and the case passed or failed depending on 
> whether it was run
> alone or as part of a full run -- {{ToStringTest}} is disabled by default and 
> only runs when the
> whole binary does.
> An order-dependent test result whose cause lives in an unrelated file is 
> expensive to chase, and
> the next test in this binary that formats a number will hit it again.
> h2. Fix
> A small RAII guard in the test file that saves the previous global locale and 
> restores it on
> scope exit, applied to both cases. The test intent is unchanged -- the locale 
> is still set for
> the duration of each case.
> h2. Verified
> The fix was checked by removing the defensive 
> {{imbue(std::locale::classic())}} that
> {{THttpBufferBoundTest}} had to add for its own protection, and confirming 
> its chunked case then
> passes a full run anyway. Before the fix it failed there and passed in 
> isolation.
> Test-only; no shipped code is affected, which is why this is filed as Minor.
> _Filed with AI assistance (Claude Opus 5); reviewed and filed by Jens Geyer._



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to