| 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
|
|
|