Revert "Floating-point exception observer for unit tests"
This reverts commit 3fb3939896f6270d48aff34eee2946bd7661bd63. Reason for revert: Downstream projects failures. Original change's description: > Floating-point exception observer for unit tests > > This CL adds a simple tool that let a unit test fail if a floating > point exception occurs. It is possible to focus on specific exceptions. > Note that FloatingPointExceptionObserver is only effective in debug > mode. For this reason, the related unit tests only run in debug mode. > Plus, due to some platform-specific limitations, not all the floating > point exceptions are available on Android. > > Bug: webrtc:8948 > Change-Id: I0956e27f2f3aa68771dd647169fba7968ccbd771 > Reviewed-on: https://webrtc-review.googlesource.com/58097 > Commit-Queue: Alessio Bazzica <alessiob@webrtc.org> > Reviewed-by: Patrik Höglund <phoglund@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#22768} TBR=phoglund@webrtc.org,alessiob@webrtc.org,kwiberg@webrtc.org Change-Id: I0fd3d114ab4a348fd46339e98273e19c1ac1c6dc No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:8948 Reviewed-on: https://webrtc-review.googlesource.com/67380 Reviewed-by: Alessio Bazzica <alessiob@webrtc.org> Commit-Queue: Alessio Bazzica <alessiob@webrtc.org> Cr-Commit-Position: refs/heads/master@{#22769}
This commit is contained in:

committed by
Commit Bot

parent
3fb3939896
commit
e3d522dd6b
@ -207,17 +207,6 @@ rtc_source_set("test_support") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rtc_include_tests) {
|
if (rtc_include_tests) {
|
||||||
rtc_source_set("floating_point_except_observer") {
|
|
||||||
testonly = true
|
|
||||||
sources = [
|
|
||||||
"fpe_observer.h",
|
|
||||||
]
|
|
||||||
deps = [
|
|
||||||
":test_support",
|
|
||||||
"../rtc_base:rtc_base_approved",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
rtc_source_set("test_main") {
|
rtc_source_set("test_main") {
|
||||||
visibility = [ "*" ]
|
visibility = [ "*" ]
|
||||||
testonly = true
|
testonly = true
|
||||||
@ -328,10 +317,8 @@ if (rtc_include_tests) {
|
|||||||
rtc_test("test_support_unittests") {
|
rtc_test("test_support_unittests") {
|
||||||
deps = [
|
deps = [
|
||||||
":fileutils",
|
":fileutils",
|
||||||
":floating_point_except_observer",
|
|
||||||
":perf_test",
|
":perf_test",
|
||||||
":rtp_test_utils",
|
":rtp_test_utils",
|
||||||
":test_support",
|
|
||||||
"../api:video_frame_api",
|
"../api:video_frame_api",
|
||||||
"../api:video_frame_api_i420",
|
"../api:video_frame_api_i420",
|
||||||
"../call:call_interfaces",
|
"../call:call_interfaces",
|
||||||
@ -342,7 +329,6 @@ if (rtc_include_tests) {
|
|||||||
"../system_wrappers",
|
"../system_wrappers",
|
||||||
]
|
]
|
||||||
sources = [
|
sources = [
|
||||||
"fpe_observer_unittest.cc",
|
|
||||||
"frame_generator_unittest.cc",
|
"frame_generator_unittest.cc",
|
||||||
"rtp_file_reader_unittest.cc",
|
"rtp_file_reader_unittest.cc",
|
||||||
"rtp_file_writer_unittest.cc",
|
"rtp_file_writer_unittest.cc",
|
||||||
|
@ -1,60 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE file in the root of the source
|
|
||||||
* tree. An additional intellectual property rights grant can be found
|
|
||||||
* in the file PATENTS. All contributing project authors may
|
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef TEST_FPE_OBSERVER_H_
|
|
||||||
#define TEST_FPE_OBSERVER_H_
|
|
||||||
|
|
||||||
#include <cfenv>
|
|
||||||
#include "test/gtest.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
|
||||||
namespace test {
|
|
||||||
|
|
||||||
// Class that let a unit test fail if floating point exceptions are signaled.
|
|
||||||
// Usage:
|
|
||||||
// {
|
|
||||||
// FloatingPointExceptionObserver fpe_observer;
|
|
||||||
// ...
|
|
||||||
// }
|
|
||||||
class FloatingPointExceptionObserver {
|
|
||||||
public:
|
|
||||||
FloatingPointExceptionObserver(int mask = FE_DIVBYZERO | FE_INVALID |
|
|
||||||
FE_OVERFLOW | FE_UNDERFLOW)
|
|
||||||
: mask_(mask) {
|
|
||||||
#ifdef NDEBUG
|
|
||||||
EXPECT_LE(0, mask_); // Avoid compile time errors in release mode.
|
|
||||||
#else
|
|
||||||
EXPECT_EQ(0, std::feclearexcept(mask_));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
~FloatingPointExceptionObserver() {
|
|
||||||
#ifndef NDEBUG
|
|
||||||
const int occurred = std::fetestexcept(mask_);
|
|
||||||
EXPECT_FALSE(occurred & FE_INVALID)
|
|
||||||
<< "Domain error occurred in a floating-point operation.";
|
|
||||||
EXPECT_FALSE(occurred & FE_DIVBYZERO) << "Division by zero.";
|
|
||||||
EXPECT_FALSE(occurred & FE_OVERFLOW)
|
|
||||||
<< "The result of a floating-point operation was too large.";
|
|
||||||
EXPECT_FALSE(occurred & FE_UNDERFLOW)
|
|
||||||
<< "The result of a floating-point operation was subnormal with a loss "
|
|
||||||
<< "of precision.";
|
|
||||||
EXPECT_FALSE(occurred & FE_INEXACT)
|
|
||||||
<< "Inexact result: rounding during a floating-point operation.";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const int mask_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace test
|
|
||||||
} // namespace webrtc
|
|
||||||
|
|
||||||
#endif // TEST_FPE_OBSERVER_H_
|
|
@ -1,138 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE file in the root of the source
|
|
||||||
* tree. An additional intellectual property rights grant can be found
|
|
||||||
* in the file PATENTS. All contributing project authors may
|
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
#include <iostream>
|
|
||||||
#include <limits>
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "rtc_base/logging.h"
|
|
||||||
#include "test/fpe_observer.h"
|
|
||||||
#include "test/gtest.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
|
||||||
namespace test {
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
std::map<int, std::string> GetExceptionCodes() {
|
|
||||||
static const std::map<int, std::string> codes = {
|
|
||||||
{FE_INVALID, "FE_INVALID"},
|
|
||||||
// TODO(bugs.webrtc.org/8948): Some floating point exceptions are not signaled
|
|
||||||
// on Android.
|
|
||||||
#ifndef WEBRTC_ANDROID
|
|
||||||
{FE_DIVBYZERO, "FE_DIVBYZERO"}, {FE_OVERFLOW, "FE_OVERFLOW"},
|
|
||||||
{FE_UNDERFLOW, "FE_UNDERFLOW"},
|
|
||||||
#endif
|
|
||||||
{FE_INEXACT, "FE_INEXACT"},
|
|
||||||
};
|
|
||||||
return codes;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define helper functions as a trick to trigger floating point exceptions at
|
|
||||||
// run-time.
|
|
||||||
float MinusOne() {
|
|
||||||
return -std::cos(0.f);
|
|
||||||
}
|
|
||||||
|
|
||||||
float PlusOne() {
|
|
||||||
return std::cos(0.f);
|
|
||||||
}
|
|
||||||
|
|
||||||
float PlusTwo() {
|
|
||||||
return 2.f * std::cos(0.f);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Triggers one or more exception according to the |trigger| mask while
|
|
||||||
// observing the floating point exceptions defined in the |observe| mask.
|
|
||||||
void TriggerObserveFloatingPointExceptions(int trigger, int observe) {
|
|
||||||
FloatingPointExceptionObserver fpe_observer(observe);
|
|
||||||
float tmp = 0.f;
|
|
||||||
if (trigger & FE_INVALID)
|
|
||||||
tmp = std::sqrt(MinusOne());
|
|
||||||
if (trigger & FE_DIVBYZERO)
|
|
||||||
tmp = 1.f / (MinusOne() + PlusOne());
|
|
||||||
if (trigger & FE_OVERFLOW)
|
|
||||||
tmp = std::numeric_limits<float>::max() * PlusTwo();
|
|
||||||
if (trigger & FE_UNDERFLOW) {
|
|
||||||
// TODO(bugs.webrtc.org/8948): Check why FE_UNDERFLOW is not triggered with
|
|
||||||
// <float>.
|
|
||||||
tmp = std::numeric_limits<double>::min() / PlusTwo();
|
|
||||||
}
|
|
||||||
if (trigger & FE_INEXACT) {
|
|
||||||
tmp = std::sqrt(2.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
TEST(FloatingPointExceptionObserverTest, CheckTestConstants) {
|
|
||||||
// Check that the constants used in the test suite behave as expected.
|
|
||||||
ASSERT_EQ(0.f, MinusOne() + PlusOne());
|
|
||||||
#ifndef WEBRTC_ANDROID
|
|
||||||
// Check that all the floating point exceptions are exercised.
|
|
||||||
int all_flags = 0;
|
|
||||||
for (const auto v : GetExceptionCodes()) {
|
|
||||||
RTC_LOG(LS_INFO) << v.second << " = " << v.first;
|
|
||||||
all_flags |= v.first;
|
|
||||||
}
|
|
||||||
#ifdef WEBRTC_MAC
|
|
||||||
#ifndef FE_UNNORMAL
|
|
||||||
#define FE_UNNORMAL 2
|
|
||||||
#endif
|
|
||||||
all_flags |= FE_UNNORMAL; // Non standard OS specific flag.
|
|
||||||
#endif
|
|
||||||
ASSERT_EQ(FE_ALL_EXCEPT, all_flags);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef NDEBUG
|
|
||||||
#define MAYBE_CheckNoFalsePositives DISABLED_CheckNoFalsePositives
|
|
||||||
#define MAYBE_CheckNoFalseNegatives DISABLED_CheckNoFalseNegatives
|
|
||||||
#else
|
|
||||||
#define MAYBE_CheckNoFalsePositives CheckNoFalsePositives
|
|
||||||
#define MAYBE_CheckNoFalseNegatives CheckNoFalseNegatives
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// The floating point exception observer only works in debug mode.
|
|
||||||
// Trigger each single floating point exception while observing all the other
|
|
||||||
// exceptions. It must not fail.
|
|
||||||
TEST(FloatingPointExceptionObserverTest, MAYBE_CheckNoFalsePositives) {
|
|
||||||
for (const auto exception_code : GetExceptionCodes()) {
|
|
||||||
SCOPED_TRACE(exception_code.second);
|
|
||||||
const int trigger = exception_code.first;
|
|
||||||
int observe = FE_ALL_EXCEPT & ~trigger;
|
|
||||||
// Over/underflows also trigger FE_INEXACT; hence, ignore FE_INEXACT (which
|
|
||||||
// would be a false positive).
|
|
||||||
if (trigger & (FE_OVERFLOW | FE_UNDERFLOW))
|
|
||||||
observe &= ~FE_INEXACT;
|
|
||||||
TriggerObserveFloatingPointExceptions(trigger, observe);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trigger each single floating point exception while observing it. Check that
|
|
||||||
// this fails.
|
|
||||||
TEST(FloatingPointExceptionObserverTest, MAYBE_CheckNoFalseNegatives) {
|
|
||||||
for (const auto exception_code : GetExceptionCodes()) {
|
|
||||||
SCOPED_TRACE(exception_code.second);
|
|
||||||
const int trigger = exception_code.first;
|
|
||||||
#ifdef WEBRTC_ANDROID
|
|
||||||
// TODO(bugs.webrtc.org/8948): FE_INEXACT is not triggered on Android.
|
|
||||||
if (trigger == FE_INEXACT)
|
|
||||||
continue;
|
|
||||||
#endif
|
|
||||||
EXPECT_NONFATAL_FAILURE(
|
|
||||||
TriggerObserveFloatingPointExceptions(trigger, trigger), "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace test
|
|
||||||
} // namespace webrtc
|
|
Reference in New Issue
Block a user