Index: util/posix/symbolic_constants_posix_test.cc |
diff --git a/util/posix/symbolic_constants_posix_test.cc b/util/posix/symbolic_constants_posix_test.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..7cceaefd143ef1a340b5fc1d9018f66da117e350 |
--- /dev/null |
+++ b/util/posix/symbolic_constants_posix_test.cc |
@@ -0,0 +1,253 @@ |
+// Copyright 2014 The Crashpad Authors. All rights reserved. |
+// |
+// Licensed under the Apache License, Version 2.0 (the "License"); |
+// you may not use this file except in compliance with the License. |
+// You may obtain a copy of the License at |
+// |
+// http://www.apache.org/licenses/LICENSE-2.0 |
+// |
+// Unless required by applicable law or agreed to in writing, software |
+// distributed under the License is distributed on an "AS IS" BASIS, |
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+// See the License for the specific language governing permissions and |
+// limitations under the License. |
+ |
+#include "util/posix/symbolic_constants_posix.h" |
+ |
+#include <sys/signal.h> |
+ |
+#include "base/basictypes.h" |
+#include "base/strings/string_piece.h" |
+#include "base/strings/stringprintf.h" |
+#include "gtest/gtest.h" |
+ |
+namespace { |
+ |
+using namespace crashpad; |
+ |
+const struct { |
+ int signal; |
+ const char* full_name; |
+ const char* short_name; |
+} kSignalTestData[] = { |
+ {SIGABRT, "SIGABRT", "ABRT"}, |
+ {SIGALRM, "SIGALRM", "ALRM"}, |
+ {SIGBUS, "SIGBUS", "BUS"}, |
+ {SIGCHLD, "SIGCHLD", "CHLD"}, |
+ {SIGCONT, "SIGCONT", "CONT"}, |
+ {SIGFPE, "SIGFPE", "FPE"}, |
+ {SIGHUP, "SIGHUP", "HUP"}, |
+ {SIGILL, "SIGILL", "ILL"}, |
+ {SIGINT, "SIGINT", "INT"}, |
+ {SIGIO, "SIGIO", "IO"}, |
+ {SIGKILL, "SIGKILL", "KILL"}, |
+ {SIGPIPE, "SIGPIPE", "PIPE"}, |
+ {SIGPROF, "SIGPROF", "PROF"}, |
+ {SIGQUIT, "SIGQUIT", "QUIT"}, |
+ {SIGSEGV, "SIGSEGV", "SEGV"}, |
+ {SIGSTOP, "SIGSTOP", "STOP"}, |
+ {SIGSYS, "SIGSYS", "SYS"}, |
+ {SIGTERM, "SIGTERM", "TERM"}, |
+ {SIGTRAP, "SIGTRAP", "TRAP"}, |
+ {SIGTSTP, "SIGTSTP", "TSTP"}, |
+ {SIGTTIN, "SIGTTIN", "TTIN"}, |
+ {SIGTTOU, "SIGTTOU", "TTOU"}, |
+ {SIGURG, "SIGURG", "URG"}, |
+ {SIGUSR1, "SIGUSR1", "USR1"}, |
+ {SIGUSR2, "SIGUSR2", "USR2"}, |
+ {SIGVTALRM, "SIGVTALRM", "VTALRM"}, |
+ {SIGWINCH, "SIGWINCH", "WINCH"}, |
+ {SIGXCPU, "SIGXCPU", "XCPU"}, |
+#if defined(OS_MACOSX) |
+ {SIGEMT, "SIGEMT", "EMT"}, |
+ {SIGINFO, "SIGINFO", "INFO"}, |
+#elif defined(OS_LINUX) |
+ {SIGPWR, "SIGPWR", "PWR"}, |
+ {SIGSTKFLT, "SIGSTKFLT", "STKFLT"}, |
+#endif |
+}; |
+ |
+// If expect is NULL, the conversion is expected to fail. If expect is empty, |
+// the conversion is expected to succeed, but the precise returned string value |
+// is unknown. Otherwise, the conversion is expected to succeed, and expect |
+// contains the precise expected string value to be returned. |
+// |
+// Only set kUseFullName or kUseShortName when calling this. Other options are |
+// exercised directly by this function. |
+void TestSignalToStringOnce(int value, |
+ const char* expect, |
+ SymbolicConstantToStringOptions options) { |
+ std::string actual = SignalToString(value, options | kUnknownIsEmpty); |
+ std::string actual_numeric = |
+ SignalToString(value, options | kUnknownIsNumeric); |
+ if (expect) { |
+ if (expect[0] == '\0') { |
+ EXPECT_FALSE(actual.empty()) << "signal " << value; |
+ } else { |
+ EXPECT_EQ(expect, actual) << "signal " << value; |
+ } |
+ EXPECT_EQ(actual, actual_numeric) << "signal " << value; |
+ } else { |
+ EXPECT_TRUE(actual.empty()) << "signal " << value << ", actual " << actual; |
+ EXPECT_FALSE(actual_numeric.empty()) |
+ << "signal " << value << ", actual_numeric " << actual_numeric; |
+ } |
+} |
+ |
+void TestSignalToString(int value, |
+ const char* expect_full, |
+ const char* expect_short) { |
+ { |
+ SCOPED_TRACE("full_name"); |
+ TestSignalToStringOnce(value, expect_full, kUseFullName); |
+ } |
+ |
+ { |
+ SCOPED_TRACE("short_name"); |
+ TestSignalToStringOnce(value, expect_short, kUseShortName); |
+ } |
+} |
+ |
+TEST(SymbolicConstantsPOSIX, SignalToString) { |
+ for (size_t index = 0; index < arraysize(kSignalTestData); ++index) { |
+ SCOPED_TRACE(base::StringPrintf("index %zu", index)); |
+ TestSignalToString(kSignalTestData[index].signal, |
+ kSignalTestData[index].full_name, |
+ kSignalTestData[index].short_name); |
+ } |
+ |
+#if defined(OS_LINUX) |
+ // NSIG is 64 to account for real-time signals. |
+ const int kSignalCount = 32; |
+#else |
+ const int kSignalCount = NSIG; |
+#endif |
+ |
+ for (int signal = 0; signal < kSignalCount + 8; ++signal) { |
+ SCOPED_TRACE(base::StringPrintf("signal %d", signal)); |
+ if (signal > 0 && signal < kSignalCount) { |
+ TestSignalToString(signal, "", ""); |
+ } else { |
+ TestSignalToString(signal, NULL, NULL); |
+ } |
+ } |
+} |
+ |
+void TestStringToSignal(const base::StringPiece& string, |
+ StringToSymbolicConstantOptions options, |
+ bool expect_result, |
+ int expect_value) { |
+ int actual_value; |
+ bool actual_result = StringToSignal(string, options, &actual_value); |
+ if (expect_result) { |
+ EXPECT_TRUE(actual_result) << "string " << string << ", options " << options |
+ << ", signal " << expect_value; |
+ if (actual_result) { |
+ EXPECT_EQ(expect_value, actual_value) << "string " << string |
+ << ", options " << options; |
+ } |
+ } else { |
+ EXPECT_FALSE(actual_result) << "string " << string << ", options " |
+ << options << ", signal " << actual_value; |
+ } |
+} |
+ |
+TEST(SymbolicConstantsPOSIX, StringToSignal) { |
+ const StringToSymbolicConstantOptions kOptions[] = { |
+ 0, |
+ kAllowFullName, |
+ kAllowShortName, |
+ kAllowFullName | kAllowShortName, |
+ kAllowNumber, |
+ kAllowFullName | kAllowNumber, |
+ kAllowShortName | kAllowNumber, |
+ kAllowFullName | kAllowShortName | kAllowNumber, |
+ }; |
+ |
+ for (size_t option_index = 0; option_index < arraysize(kOptions); |
+ ++option_index) { |
+ SCOPED_TRACE(base::StringPrintf("option_index %zu", option_index)); |
+ StringToSymbolicConstantOptions options = kOptions[option_index]; |
+ for (size_t index = 0; index < arraysize(kSignalTestData); ++index) { |
+ SCOPED_TRACE(base::StringPrintf("index %zu", index)); |
+ int signal = kSignalTestData[index].signal; |
+ { |
+ SCOPED_TRACE("full_name"); |
+ TestStringToSignal(kSignalTestData[index].full_name, |
+ options, |
+ options & kAllowFullName, |
+ signal); |
+ } |
+ { |
+ SCOPED_TRACE("short_name"); |
+ TestStringToSignal(kSignalTestData[index].short_name, |
+ options, |
+ options & kAllowShortName, |
+ signal); |
+ } |
+ { |
+ SCOPED_TRACE("number"); |
+ std::string number_string = base::StringPrintf("%d", signal); |
+ TestStringToSignal( |
+ number_string, options, options & kAllowNumber, signal); |
+ } |
+ } |
+ |
+ const char* const kNegativeTestData[] = { |
+ "SIGHUP ", |
+ " SIGINT", |
+ "QUIT ", |
+ " ILL", |
+ "SIGSIGTRAP", |
+ "SIGABRTRON", |
+ "FPES", |
+ "SIGGARBAGE", |
+ "random", |
+ "", |
+ }; |
+ |
+ for (size_t index = 0; index < arraysize(kNegativeTestData); ++index) { |
+ SCOPED_TRACE(base::StringPrintf("index %zu", index)); |
+ TestStringToSignal(kNegativeTestData[index], options, false, 0); |
+ } |
+ |
+ const struct { |
+ const char* string; |
+ size_t length; |
+ } kNULTestData[] = { |
+#define NUL_TEST_DATA(string) { string, arraysize(string) - 1 } |
+ NUL_TEST_DATA("\0SIGBUS"), |
+ NUL_TEST_DATA("SIG\0BUS"), |
+ NUL_TEST_DATA("SIGB\0US"), |
+ NUL_TEST_DATA("SIGBUS\0"), |
+ NUL_TEST_DATA("\0BUS"), |
+ NUL_TEST_DATA("BUS\0"), |
+ NUL_TEST_DATA("B\0US"), |
+ NUL_TEST_DATA("\0002"), |
+ NUL_TEST_DATA("2\0"), |
+ NUL_TEST_DATA("1\0002"), |
+#undef NUL_TEST_DATA |
+ }; |
+ |
+ for (size_t index = 0; index < arraysize(kNULTestData); ++index) { |
+ SCOPED_TRACE(base::StringPrintf("index %zu", index)); |
+ base::StringPiece string(kNULTestData[index].string, |
+ kNULTestData[index].length); |
+ TestStringToSignal(string, options, false, 0); |
+ } |
+ } |
+ |
+ // Ensure that a NUL is not required at the end of the string. |
+ { |
+ SCOPED_TRACE("trailing_NUL_full"); |
+ TestStringToSignal( |
+ base::StringPiece("SIGBUST", 6), kAllowFullName, true, SIGBUS); |
+ } |
+ { |
+ SCOPED_TRACE("trailing_NUL_short"); |
+ TestStringToSignal( |
+ base::StringPiece("BUST", 3), kAllowShortName, true, SIGBUS); |
+ } |
+} |
+ |
+} // namespace |