strerror_test.cc (2766B)
1 // Copyright 2020 The Abseil Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "absl/base/internal/strerror.h" 16 17 #include <atomic> 18 #include <cerrno> 19 #include <cstdio> 20 #include <cstring> 21 #include <string> 22 #include <thread> // NOLINT(build/c++11) 23 #include <vector> 24 25 #include "gmock/gmock.h" 26 #include "gtest/gtest.h" 27 #include "absl/strings/match.h" 28 29 namespace { 30 using ::testing::AnyOf; 31 using ::testing::Eq; 32 33 TEST(StrErrorTest, ValidErrorCode) { 34 errno = ERANGE; 35 EXPECT_THAT(absl::base_internal::StrError(EDOM), Eq(strerror(EDOM))); 36 EXPECT_THAT(errno, Eq(ERANGE)); 37 } 38 39 TEST(StrErrorTest, InvalidErrorCode) { 40 errno = ERANGE; 41 EXPECT_THAT(absl::base_internal::StrError(-1), 42 AnyOf(Eq("No error information"), Eq("Unknown error -1"))); 43 EXPECT_THAT(errno, Eq(ERANGE)); 44 } 45 46 TEST(StrErrorTest, MultipleThreads) { 47 // In this test, we will start up 2 threads and have each one call 48 // StrError 1000 times, each time with a different errnum. We 49 // expect that StrError(errnum) will return a string equal to the 50 // one returned by strerror(errnum), if the code is known. Since 51 // strerror is known to be thread-hostile, collect all the expected 52 // strings up front. 53 const int kNumCodes = 1000; 54 std::vector<std::string> expected_strings(kNumCodes); 55 for (int i = 0; i < kNumCodes; ++i) { 56 expected_strings[i] = strerror(i); 57 } 58 59 std::atomic_int counter(0); 60 auto thread_fun = [&]() { 61 for (int i = 0; i < kNumCodes; ++i) { 62 ++counter; 63 errno = ERANGE; 64 const std::string value = absl::base_internal::StrError(i); 65 // EXPECT_* could change errno. Stash it first. 66 int check_err = errno; 67 EXPECT_THAT(check_err, Eq(ERANGE)); 68 // Only the GNU implementation is guaranteed to provide the 69 // string "Unknown error nnn". POSIX doesn't say anything. 70 if (!absl::StartsWith(value, "Unknown error ")) { 71 EXPECT_THAT(value, Eq(expected_strings[i])); 72 } 73 } 74 }; 75 76 const int kNumThreads = 100; 77 std::vector<std::thread> threads; 78 for (int i = 0; i < kNumThreads; ++i) { 79 threads.push_back(std::thread(thread_fun)); 80 } 81 for (auto& thread : threads) { 82 thread.join(); 83 } 84 85 EXPECT_THAT(counter, Eq(kNumThreads * kNumCodes)); 86 } 87 88 } // namespace