stop leaking TZ between unit tests
authorPhilipp Gesang <philipp.gesang@intra2net.com>
Fri, 5 Apr 2019 06:51:25 +0000 (08:51 +0200)
committerPhilipp Gesang <philipp.gesang@intra2net.com>
Fri, 5 Apr 2019 06:51:29 +0000 (08:51 +0200)
So apparently boost/unit_test does not restore the original
environment for each test. Do that ourselves then for the TZ
variable which is needed for certain tests.

Also enable UTC in more helpers that leave it unspecified in
formatting. Till now those were relying on the UTC set in a
previous test. Ew!

test/test_timefunc.cpp

index 827d128..96b8337 100644 (file)
@@ -32,6 +32,7 @@ on this file might be covered by the GNU General Public License.
 
 #include <unistd.h>
 #include <set>
+#include <iostream>
 
 using namespace std;
 using namespace I2n;
@@ -42,6 +43,7 @@ class TestTimeFuncFixture
 protected:
    typedef std::list< std::string > StringList;
    std::set<std::string>  used_check_files;
+   std::string tz; /* save and restore TZ from envp */
 
    std::string get_check_file_path(std::string tag)
    {
@@ -67,14 +69,43 @@ protected:
       used_check_files.clear();
    } // eo remove_check_files
 
+   void set_utc (void)
+   {
+        errno = 0;
+        if (setenv ("TZ", "UTC", 1) == -1)
+        {
+            std::cerr
+                << "error setting environment 'TZ': [" << this->tz << "]"
+                << std::endl
+                ;
+            return;
+        }
+
+        tzset ();
+   }
+
 public:
     TestTimeFuncFixture()
+        : tz (secure_getenv ("TZ") ?: "")
     {
     }
 
     ~TestTimeFuncFixture()
     {
         remove_check_files();
+
+        errno = 0;
+        if (setenv ("TZ", this->tz.c_str (), 1) == -1)
+        {
+            std::cerr
+                << "error cleaning up environment 'TZ': [" << this->tz << "]"
+                << std::endl
+                ;
+        }
+        else
+        {
+            tzset();
+        }
     }
 };
 
@@ -1050,8 +1081,7 @@ BOOST_AUTO_TEST_SUITE(Clock)
          * brr, the old formatters use localtime without a way to opt out of
          * it!
          */
-        setenv ("TZ", "UTC", 1);
-        tzset();
+        this->set_utc ();
         boost::optional<std::string> s = t.format_full_time ();
 
         BOOST_CHECK_EQUAL("11.11.2018 11:11", *s);
@@ -1070,6 +1100,8 @@ BOOST_AUTO_TEST_SUITE(Clock)
         const std::string in1 ("0001-01-01T00:00:00Z+0000");
         const std::string in2 ("2018-11-11T11:11:11Z+0000");
 
+        this->set_utc ();
+
         boost::optional<I2n::clock::Time> t1 = I2n::clock::time_of_iso8601 (in1);
         boost::optional<I2n::clock::Time> t2 = I2n::clock::time_of_iso8601 (in2);
 
@@ -1089,6 +1121,8 @@ BOOST_AUTO_TEST_SUITE(Clock)
         const std::string in1 ("-0001-01-01T00:00:00Z+0000");
         const std::string in2 ("-2018-11-11T11:11:11Z+0000");
 
+        this->set_utc ();
+
         boost::optional<I2n::clock::Time> t1 = I2n::clock::time_of_iso8601 (in1);
         boost::optional<I2n::clock::Time> t2 = I2n::clock::time_of_iso8601 (in2);
 
@@ -1108,8 +1142,7 @@ BOOST_AUTO_TEST_SUITE(Clock)
         const std::string in1 ("2018-11-11T11:11:11");
         const std::string in2 ("2018-11-11");
 
-        setenv ("TZ", "UTC", 1);
-        tzset();
+        this->set_utc ();
 
         boost::optional<I2n::clock::Time> t1 =
             I2n::clock::time_of_iso8601 (in1, true, true, false);
@@ -1132,6 +1165,8 @@ BOOST_AUTO_TEST_SUITE(Clock)
         const std::string timeless ("11:11:11");
         boost::optional<I2n::clock::Time> untimely = boost::none;
 
+        this->set_utc ();
+
         untimely = I2n::clock::time_of_iso8601 (timeless, false, true, false);
 
 # if LONG_BIT == 32