rtc_error_unittest.cc (8130B)
1 /* 2 * Copyright 2017 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "api/rtc_error.h" 12 13 #include <string> 14 #include <utility> 15 16 #include "absl/strings/str_cat.h" 17 #include "absl/strings/string_view.h" 18 #include "rtc_base/checks.h" 19 #include "test/gtest.h" 20 21 namespace webrtc { 22 namespace { 23 24 constexpr int kDefaultMoveOnlyIntValue = 0xbadf00d; 25 26 // Class that has no copy constructor, ensuring that RTCErrorOr can 27 struct MoveOnlyInt { 28 MoveOnlyInt() {} 29 explicit MoveOnlyInt(int value) : value(value) {} 30 MoveOnlyInt(const MoveOnlyInt& other) = delete; 31 MoveOnlyInt& operator=(const MoveOnlyInt& other) = delete; 32 MoveOnlyInt(MoveOnlyInt&& other) : value(other.value) {} 33 MoveOnlyInt& operator=(MoveOnlyInt&& other) { 34 value = other.value; 35 return *this; 36 } 37 38 int value = kDefaultMoveOnlyIntValue; 39 }; 40 41 // Same as above. Used to test conversion from RTCErrorOr<A> to RTCErrorOr<B> 42 // when A can be converted to B. 43 struct MoveOnlyInt2 { 44 MoveOnlyInt2() {} 45 explicit MoveOnlyInt2(int value) : value(value) {} 46 MoveOnlyInt2(const MoveOnlyInt2& other) = delete; 47 MoveOnlyInt2& operator=(const MoveOnlyInt2& other) = delete; 48 MoveOnlyInt2(MoveOnlyInt2&& other) : value(other.value) {} 49 MoveOnlyInt2& operator=(MoveOnlyInt2&& other) { 50 value = other.value; 51 return *this; 52 } 53 54 explicit MoveOnlyInt2(MoveOnlyInt&& other) : value(other.value) {} 55 MoveOnlyInt2& operator=(MoveOnlyInt&& other) { 56 value = other.value; 57 return *this; 58 } 59 60 int value = kDefaultMoveOnlyIntValue; 61 }; 62 63 // Test that the default constructor creates a "no error" error. 64 TEST(RTCErrorTest, DefaultConstructor) { 65 RTCError e; 66 EXPECT_EQ(e.type(), RTCErrorType::NONE); 67 EXPECT_STREQ(e.message(), ""); 68 EXPECT_TRUE(e.ok()); 69 } 70 71 TEST(RTCErrorTest, NormalConstructors) { 72 RTCError a(RTCErrorType::INVALID_PARAMETER); 73 EXPECT_EQ(a.type(), RTCErrorType::INVALID_PARAMETER); 74 EXPECT_STREQ(a.message(), ""); 75 76 // Constructor that takes const char* message. 77 RTCError b(RTCErrorType::UNSUPPORTED_PARAMETER, "foobar"); 78 EXPECT_EQ(b.type(), RTCErrorType::UNSUPPORTED_PARAMETER); 79 EXPECT_STREQ(b.message(), "foobar"); 80 81 // Constructor that takes absl::string_view message. 82 RTCError c(RTCErrorType::SYNTAX_ERROR, absl::string_view("baz")); 83 EXPECT_EQ(c.type(), RTCErrorType::SYNTAX_ERROR); 84 EXPECT_STREQ(c.message(), "baz"); 85 86 // Constructor that takes std::string message. 87 RTCError d(RTCErrorType::INVALID_RANGE, std::string("new")); 88 EXPECT_EQ(d.type(), RTCErrorType::INVALID_RANGE); 89 EXPECT_STREQ(d.message(), "new"); 90 } 91 92 TEST(RTCErrorTest, MoveConstructor) { 93 // Static string. 94 RTCError a(RTCErrorType::INVALID_PARAMETER, "foo"); 95 RTCError b(std::move(a)); 96 EXPECT_EQ(b.type(), RTCErrorType::INVALID_PARAMETER); 97 EXPECT_STREQ(b.message(), "foo"); 98 99 // Non-static string. 100 RTCError c(RTCErrorType::UNSUPPORTED_PARAMETER, std::string("bar")); 101 RTCError d(std::move(c)); 102 EXPECT_EQ(d.type(), RTCErrorType::UNSUPPORTED_PARAMETER); 103 EXPECT_STREQ(d.message(), "bar"); 104 } 105 106 TEST(RTCErrorTest, MoveAssignment) { 107 // Try all combinations of "is static string"/"is non-static string" moves. 108 RTCError e(RTCErrorType::INVALID_PARAMETER, "foo"); 109 110 e = RTCError(RTCErrorType::UNSUPPORTED_PARAMETER, "bar"); 111 EXPECT_EQ(e.type(), RTCErrorType::UNSUPPORTED_PARAMETER); 112 EXPECT_STREQ(e.message(), "bar"); 113 114 e = RTCError(RTCErrorType::SYNTAX_ERROR, absl::string_view("baz")); 115 EXPECT_STREQ(e.message(), "baz"); 116 117 e = RTCError(RTCErrorType::SYNTAX_ERROR, std::string("another")); 118 EXPECT_STREQ(e.message(), "another"); 119 } 120 121 // Test that the error returned by RTCError::OK() is a "no error" error. 122 TEST(RTCErrorTest, OKConstant) { 123 RTCError ok = RTCError::OK(); 124 EXPECT_EQ(ok.type(), RTCErrorType::NONE); 125 EXPECT_STREQ(ok.message(), ""); 126 EXPECT_TRUE(ok.ok()); 127 } 128 129 // Test that "error.ok()" behaves as expected. 130 TEST(RTCErrorTest, OkMethod) { 131 RTCError success; 132 RTCError failure(RTCErrorType::INTERNAL_ERROR); 133 EXPECT_TRUE(success.ok()); 134 EXPECT_FALSE(failure.ok()); 135 } 136 137 // Test that a message can be set using either static const strings or 138 // std::strings. 139 TEST(RTCErrorTest, SetMessage) { 140 RTCError e; 141 e.set_message("foo"); 142 EXPECT_STREQ(e.message(), "foo"); 143 144 e.set_message(absl::string_view("bar")); 145 EXPECT_STREQ(e.message(), "bar"); 146 147 e.set_message(std::string("string")); 148 EXPECT_STREQ(e.message(), "string"); 149 } 150 151 TEST(RTCErrorTest, Stringify) { 152 RTCError e(RTCErrorType::INVALID_PARAMETER, "foo"); 153 EXPECT_EQ(absl::StrCat(e), "INVALID_PARAMETER with message: \"foo\""); 154 } 155 156 // Test that the default constructor creates an "INTERNAL_ERROR". 157 TEST(RTCErrorOrTest, DefaultConstructor) { 158 RTCErrorOr<MoveOnlyInt> e; 159 EXPECT_EQ(e.error().type(), RTCErrorType::INTERNAL_ERROR); 160 } 161 162 // Test that an RTCErrorOr can be implicitly constructed from a value. 163 TEST(RTCErrorOrTest, ImplicitValueConstructor) { 164 RTCErrorOr<MoveOnlyInt> e = [] { return MoveOnlyInt(100); }(); 165 EXPECT_EQ(e.value().value, 100); 166 } 167 168 // Test that an RTCErrorOr can be implicitly constructed from an RTCError. 169 TEST(RTCErrorOrTest, ImplicitErrorConstructor) { 170 RTCErrorOr<MoveOnlyInt> e = [] { 171 return RTCError(RTCErrorType::SYNTAX_ERROR); 172 }(); 173 EXPECT_EQ(e.error().type(), RTCErrorType::SYNTAX_ERROR); 174 } 175 176 TEST(RTCErrorOrTest, MoveConstructor) { 177 RTCErrorOr<MoveOnlyInt> a(MoveOnlyInt(5)); 178 RTCErrorOr<MoveOnlyInt> b(std::move(a)); 179 EXPECT_EQ(b.value().value, 5); 180 } 181 182 TEST(RTCErrorOrTest, MoveAssignment) { 183 RTCErrorOr<MoveOnlyInt> a(MoveOnlyInt(5)); 184 RTCErrorOr<MoveOnlyInt> b(MoveOnlyInt(10)); 185 a = std::move(b); 186 EXPECT_EQ(a.value().value, 10); 187 } 188 189 TEST(RTCErrorOrTest, ConversionConstructor) { 190 RTCErrorOr<MoveOnlyInt> a(MoveOnlyInt(1)); 191 RTCErrorOr<MoveOnlyInt2> b(std::move(a)); 192 } 193 194 TEST(RTCErrorOrTest, ConversionAssignment) { 195 RTCErrorOr<MoveOnlyInt> a(MoveOnlyInt(5)); 196 RTCErrorOr<MoveOnlyInt2> b(MoveOnlyInt2(10)); 197 b = std::move(a); 198 EXPECT_EQ(b.value().value, 5); 199 } 200 201 TEST(RTCErrorOrTest, OkMethod) { 202 RTCErrorOr<int> success(1337); 203 RTCErrorOr<int> error = RTCError(RTCErrorType::INTERNAL_ERROR); 204 EXPECT_TRUE(success.ok()); 205 EXPECT_FALSE(error.ok()); 206 } 207 208 TEST(RTCErrorOrTest, MoveError) { 209 RTCErrorOr<int> e({RTCErrorType::SYNTAX_ERROR, "message"}); 210 RTCError err = e.MoveError(); 211 EXPECT_EQ(err.type(), RTCErrorType::SYNTAX_ERROR); 212 EXPECT_STREQ(err.message(), "message"); 213 } 214 215 TEST(RTCErrorOrTest, MoveValue) { 216 RTCErrorOr<MoveOnlyInt> e(MoveOnlyInt(88)); 217 MoveOnlyInt value = e.MoveValue(); 218 EXPECT_EQ(value.value, 88); 219 } 220 221 TEST(RTCErrorOrTest, StringifyWithUnprintableValue) { 222 RTCErrorOr<MoveOnlyInt> e(MoveOnlyInt(1337)); 223 EXPECT_EQ(absl::StrCat(e), "OK"); 224 } 225 226 TEST(RTCErrorOrTest, StringifyWithStringValue) { 227 RTCErrorOr<absl::string_view> e("foo"); 228 EXPECT_EQ(absl::StrCat(e), "OK with value: foo"); 229 } 230 231 TEST(RTCErrorOrTest, StringifyWithPrintableValue) { 232 RTCErrorOr<int> e(1337); 233 EXPECT_EQ(absl::StrCat(e), "OK with value: 1337"); 234 } 235 236 TEST(RTCErrorOrTest, StringifyWithError) { 237 RTCErrorOr<int> e({RTCErrorType::SYNTAX_ERROR, "message"}); 238 EXPECT_EQ(absl::StrCat(e), "SYNTAX_ERROR with message: \"message\""); 239 } 240 241 // Death tests. 242 // Disabled on Android because death tests misbehave on Android, see 243 // base/test/gtest_util.h. 244 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) 245 246 TEST(RTCErrorOrDeathTest, ConstructWithOkError) { 247 RTCErrorOr<int> err; 248 EXPECT_DEATH(err = RTCError::OK(), ""); 249 } 250 251 TEST(RTCErrorOrDeathTest, DereferenceErrorValue) { 252 RTCErrorOr<int> error = RTCError(RTCErrorType::INTERNAL_ERROR); 253 EXPECT_DEATH(error.value(), ""); 254 } 255 256 TEST(RTCErrorOrDeathTest, MoveErrorValue) { 257 RTCErrorOr<int> error = RTCError(RTCErrorType::INTERNAL_ERROR); 258 EXPECT_DEATH(error.MoveValue(), ""); 259 } 260 261 #endif // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) 262 263 } // namespace 264 } // namespace webrtc