Mercurial > hg > CbC > CbC_llvm
comparison unittests/Support/ErrorTest.cpp @ 148:63bd29f05246
merged
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 14 Aug 2019 19:46:37 +0900 |
parents | c2174574ed3a |
children |
comparison
equal
deleted
inserted
replaced
146:3fc4d5c3e21e | 148:63bd29f05246 |
---|---|
1 //===----- unittests/ErrorTest.cpp - Error.h tests ------------------------===// | 1 //===----- unittests/ErrorTest.cpp - Error.h tests ------------------------===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 // | 4 // See https://llvm.org/LICENSE.txt for license information. |
5 // This file is distributed under the University of Illinois Open Source | 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 // License. See LICENSE.TXT for details. | |
7 // | 6 // |
8 //===----------------------------------------------------------------------===// | 7 //===----------------------------------------------------------------------===// |
9 | 8 |
10 #include "llvm/Support/Error.h" | 9 #include "llvm/Support/Error.h" |
10 #include "llvm-c/Error.h" | |
11 | 11 |
12 #include "llvm/ADT/Twine.h" | 12 #include "llvm/ADT/Twine.h" |
13 #include "llvm/Support/Errc.h" | 13 #include "llvm/Support/Errc.h" |
14 #include "llvm/Support/ErrorHandling.h" | 14 #include "llvm/Support/ErrorHandling.h" |
15 #include "llvm/Support/ManagedStatic.h" | |
15 #include "llvm/Testing/Support/Error.h" | 16 #include "llvm/Testing/Support/Error.h" |
16 #include "gtest/gtest-spi.h" | 17 #include "gtest/gtest-spi.h" |
17 #include "gtest/gtest.h" | 18 #include "gtest/gtest.h" |
18 #include <memory> | 19 #include <memory> |
19 | 20 |
30 // Get the info attached to this error. | 31 // Get the info attached to this error. |
31 int getInfo() const { return Info; } | 32 int getInfo() const { return Info; } |
32 | 33 |
33 // Log this error to a stream. | 34 // Log this error to a stream. |
34 void log(raw_ostream &OS) const override { | 35 void log(raw_ostream &OS) const override { |
35 OS << "CustomError { " << getInfo() << "}"; | 36 OS << "CustomError {" << getInfo() << "}"; |
36 } | 37 } |
37 | 38 |
38 std::error_code convertToErrorCode() const override { | 39 std::error_code convertToErrorCode() const override { |
39 llvm_unreachable("CustomError doesn't support ECError conversion"); | 40 llvm_unreachable("CustomError doesn't support ECError conversion"); |
40 } | 41 } |
101 TEST(Error, CheckedSuccess) { | 102 TEST(Error, CheckedSuccess) { |
102 Error E = Error::success(); | 103 Error E = Error::success(); |
103 EXPECT_FALSE(E) << "Unexpected error while testing Error 'Success'"; | 104 EXPECT_FALSE(E) << "Unexpected error while testing Error 'Success'"; |
104 } | 105 } |
105 | 106 |
106 // Test that unchecked succes values cause an abort. | 107 // Test that unchecked success values cause an abort. |
107 #if LLVM_ENABLE_ABI_BREAKING_CHECKS | 108 #if LLVM_ENABLE_ABI_BREAKING_CHECKS |
108 TEST(Error, UncheckedSuccess) { | 109 TEST(Error, UncheckedSuccess) { |
109 EXPECT_DEATH({ Error E = Error::success(); }, | 110 EXPECT_DEATH({ Error E = Error::success(); }, |
110 "Program aborted due to an unhandled Error:") | 111 "Program aborted due to an unhandled Error:") |
111 << "Unchecked Error Succes value did not cause abort()"; | 112 << "Unchecked Error Succes value did not cause abort()"; |
430 } | 431 } |
431 | 432 |
432 TEST(Error, StringError) { | 433 TEST(Error, StringError) { |
433 std::string Msg; | 434 std::string Msg; |
434 raw_string_ostream S(Msg); | 435 raw_string_ostream S(Msg); |
435 logAllUnhandledErrors(make_error<StringError>("foo" + Twine(42), | 436 logAllUnhandledErrors( |
436 inconvertibleErrorCode()), | 437 make_error<StringError>("foo" + Twine(42), inconvertibleErrorCode()), S); |
437 S, ""); | |
438 EXPECT_EQ(S.str(), "foo42\n") << "Unexpected StringError log result"; | 438 EXPECT_EQ(S.str(), "foo42\n") << "Unexpected StringError log result"; |
439 | 439 |
440 auto EC = | 440 auto EC = |
441 errorToErrorCode(make_error<StringError>("", errc::invalid_argument)); | 441 errorToErrorCode(make_error<StringError>("", errc::invalid_argument)); |
442 EXPECT_EQ(EC, errc::invalid_argument) | 442 EXPECT_EQ(EC, errc::invalid_argument) |
443 << "Failed to convert StringError to error_code."; | 443 << "Failed to convert StringError to error_code."; |
444 } | |
445 | |
446 TEST(Error, createStringError) { | |
447 static const char *Bar = "bar"; | |
448 static const std::error_code EC = errc::invalid_argument; | |
449 std::string Msg; | |
450 raw_string_ostream S(Msg); | |
451 logAllUnhandledErrors(createStringError(EC, "foo%s%d0x%" PRIx8, Bar, 1, 0xff), | |
452 S); | |
453 EXPECT_EQ(S.str(), "foobar10xff\n") | |
454 << "Unexpected createStringError() log result"; | |
455 | |
456 S.flush(); | |
457 Msg.clear(); | |
458 logAllUnhandledErrors(createStringError(EC, Bar), S); | |
459 EXPECT_EQ(S.str(), "bar\n") | |
460 << "Unexpected createStringError() (overloaded) log result"; | |
461 | |
462 S.flush(); | |
463 Msg.clear(); | |
464 auto Res = errorToErrorCode(createStringError(EC, "foo%s", Bar)); | |
465 EXPECT_EQ(Res, EC) | |
466 << "Failed to convert createStringError() result to error_code."; | |
444 } | 467 } |
445 | 468 |
446 // Test that the ExitOnError utility works as expected. | 469 // Test that the ExitOnError utility works as expected. |
447 TEST(Error, ExitOnError) { | 470 TEST(Error, ExitOnError) { |
448 ExitOnError ExitOnErr; | 471 ExitOnError ExitOnErr; |
700 // Test that error messages work. | 723 // Test that error messages work. |
701 TEST(Error, ErrorMessage) { | 724 TEST(Error, ErrorMessage) { |
702 EXPECT_EQ(toString(Error::success()).compare(""), 0); | 725 EXPECT_EQ(toString(Error::success()).compare(""), 0); |
703 | 726 |
704 Error E1 = make_error<CustomError>(0); | 727 Error E1 = make_error<CustomError>(0); |
705 EXPECT_EQ(toString(std::move(E1)).compare("CustomError { 0}"), 0); | 728 EXPECT_EQ(toString(std::move(E1)).compare("CustomError {0}"), 0); |
706 | 729 |
707 Error E2 = make_error<CustomError>(0); | 730 Error E2 = make_error<CustomError>(0); |
708 handleAllErrors(std::move(E2), [](const CustomError &CE) { | 731 handleAllErrors(std::move(E2), [](const CustomError &CE) { |
709 EXPECT_EQ(CE.message().compare("CustomError { 0}"), 0); | 732 EXPECT_EQ(CE.message().compare("CustomError {0}"), 0); |
710 }); | 733 }); |
711 | 734 |
712 Error E3 = joinErrors(make_error<CustomError>(0), make_error<CustomError>(1)); | 735 Error E3 = joinErrors(make_error<CustomError>(0), make_error<CustomError>(1)); |
713 EXPECT_EQ(toString(std::move(E3)) | 736 EXPECT_EQ(toString(std::move(E3)) |
714 .compare("CustomError { 0}\n" | 737 .compare("CustomError {0}\n" |
715 "CustomError { 1}"), | 738 "CustomError {1}"), |
716 0); | 739 0); |
740 } | |
741 | |
742 TEST(Error, Stream) { | |
743 { | |
744 Error OK = Error::success(); | |
745 std::string Buf; | |
746 llvm::raw_string_ostream S(Buf); | |
747 S << OK; | |
748 EXPECT_EQ("success", S.str()); | |
749 consumeError(std::move(OK)); | |
750 } | |
751 { | |
752 Error E1 = make_error<CustomError>(0); | |
753 std::string Buf; | |
754 llvm::raw_string_ostream S(Buf); | |
755 S << E1; | |
756 EXPECT_EQ("CustomError {0}", S.str()); | |
757 consumeError(std::move(E1)); | |
758 } | |
717 } | 759 } |
718 | 760 |
719 TEST(Error, ErrorMatchers) { | 761 TEST(Error, ErrorMatchers) { |
720 EXPECT_THAT_ERROR(Error::success(), Succeeded()); | 762 EXPECT_THAT_ERROR(Error::success(), Succeeded()); |
721 EXPECT_NONFATAL_FAILURE( | 763 EXPECT_NONFATAL_FAILURE( |
722 EXPECT_THAT_ERROR(make_error<CustomError>(0), Succeeded()), | 764 EXPECT_THAT_ERROR(make_error<CustomError>(0), Succeeded()), |
723 "Expected: succeeded\n Actual: failed (CustomError { 0})"); | 765 "Expected: succeeded\n Actual: failed (CustomError {0})"); |
724 | 766 |
725 EXPECT_THAT_ERROR(make_error<CustomError>(0), Failed()); | 767 EXPECT_THAT_ERROR(make_error<CustomError>(0), Failed()); |
726 EXPECT_NONFATAL_FAILURE(EXPECT_THAT_ERROR(Error::success(), Failed()), | 768 EXPECT_NONFATAL_FAILURE(EXPECT_THAT_ERROR(Error::success(), Failed()), |
727 "Expected: failed\n Actual: succeeded"); | 769 "Expected: failed\n Actual: succeeded"); |
728 | 770 |
771 EXPECT_THAT_ERROR(make_error<CustomError>(0), Failed<CustomError>()); | |
772 EXPECT_NONFATAL_FAILURE( | |
773 EXPECT_THAT_ERROR(Error::success(), Failed<CustomError>()), | |
774 "Expected: failed with Error of given type\n Actual: succeeded"); | |
775 EXPECT_NONFATAL_FAILURE( | |
776 EXPECT_THAT_ERROR(make_error<CustomError>(0), Failed<CustomSubError>()), | |
777 "Error was not of given type"); | |
778 EXPECT_NONFATAL_FAILURE( | |
779 EXPECT_THAT_ERROR( | |
780 joinErrors(make_error<CustomError>(0), make_error<CustomError>(1)), | |
781 Failed<CustomError>()), | |
782 "multiple errors"); | |
783 | |
784 EXPECT_THAT_ERROR( | |
785 make_error<CustomError>(0), | |
786 Failed<CustomError>(testing::Property(&CustomError::getInfo, 0))); | |
787 EXPECT_NONFATAL_FAILURE( | |
788 EXPECT_THAT_ERROR( | |
789 make_error<CustomError>(0), | |
790 Failed<CustomError>(testing::Property(&CustomError::getInfo, 1))), | |
791 "Expected: failed with Error of given type and the error is an object " | |
792 "whose given property is equal to 1\n" | |
793 " Actual: failed (CustomError {0})"); | |
794 EXPECT_THAT_ERROR(make_error<CustomError>(0), Failed<ErrorInfoBase>()); | |
795 | |
729 EXPECT_THAT_EXPECTED(Expected<int>(0), Succeeded()); | 796 EXPECT_THAT_EXPECTED(Expected<int>(0), Succeeded()); |
730 EXPECT_NONFATAL_FAILURE( | 797 EXPECT_NONFATAL_FAILURE( |
731 EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)), | 798 EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)), |
732 Succeeded()), | 799 Succeeded()), |
733 "Expected: succeeded\n Actual: failed (CustomError { 0})"); | 800 "Expected: succeeded\n Actual: failed (CustomError {0})"); |
734 | 801 |
735 EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)), Failed()); | 802 EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)), Failed()); |
736 EXPECT_NONFATAL_FAILURE( | 803 EXPECT_NONFATAL_FAILURE( |
737 EXPECT_THAT_EXPECTED(Expected<int>(0), Failed()), | 804 EXPECT_THAT_EXPECTED(Expected<int>(0), Failed()), |
738 "Expected: failed\n Actual: succeeded with value 0"); | 805 "Expected: failed\n Actual: succeeded with value 0"); |
740 EXPECT_THAT_EXPECTED(Expected<int>(0), HasValue(0)); | 807 EXPECT_THAT_EXPECTED(Expected<int>(0), HasValue(0)); |
741 EXPECT_NONFATAL_FAILURE( | 808 EXPECT_NONFATAL_FAILURE( |
742 EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)), | 809 EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)), |
743 HasValue(0)), | 810 HasValue(0)), |
744 "Expected: succeeded with value (is equal to 0)\n" | 811 "Expected: succeeded with value (is equal to 0)\n" |
745 " Actual: failed (CustomError { 0})"); | 812 " Actual: failed (CustomError {0})"); |
746 EXPECT_NONFATAL_FAILURE( | 813 EXPECT_NONFATAL_FAILURE( |
747 EXPECT_THAT_EXPECTED(Expected<int>(1), HasValue(0)), | 814 EXPECT_THAT_EXPECTED(Expected<int>(1), HasValue(0)), |
748 "Expected: succeeded with value (is equal to 0)\n" | 815 "Expected: succeeded with value (is equal to 0)\n" |
749 " Actual: succeeded with value 1, (isn't equal to 0)"); | 816 " Actual: succeeded with value 1, (isn't equal to 0)"); |
750 | 817 |
760 " Actual: succeeded with value 0, (isn't > 1)"); | 827 " Actual: succeeded with value 0, (isn't > 1)"); |
761 EXPECT_NONFATAL_FAILURE( | 828 EXPECT_NONFATAL_FAILURE( |
762 EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)), | 829 EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)), |
763 HasValue(testing::Gt(1))), | 830 HasValue(testing::Gt(1))), |
764 "Expected: succeeded with value (is > 1)\n" | 831 "Expected: succeeded with value (is > 1)\n" |
765 " Actual: failed (CustomError { 0})"); | 832 " Actual: failed (CustomError {0})"); |
766 } | 833 } |
834 | |
835 TEST(Error, C_API) { | |
836 EXPECT_THAT_ERROR(unwrap(wrap(Error::success())), Succeeded()) | |
837 << "Failed to round-trip Error success value via C API"; | |
838 EXPECT_THAT_ERROR(unwrap(wrap(make_error<CustomError>(0))), | |
839 Failed<CustomError>()) | |
840 << "Failed to round-trip Error failure value via C API"; | |
841 | |
842 auto Err = | |
843 wrap(make_error<StringError>("test message", inconvertibleErrorCode())); | |
844 EXPECT_EQ(LLVMGetErrorTypeId(Err), LLVMGetStringErrorTypeId()) | |
845 << "Failed to match error type ids via C API"; | |
846 char *ErrMsg = LLVMGetErrorMessage(Err); | |
847 EXPECT_STREQ(ErrMsg, "test message") | |
848 << "Failed to roundtrip StringError error message via C API"; | |
849 LLVMDisposeErrorMessage(ErrMsg); | |
850 | |
851 bool GotCSE = false; | |
852 bool GotCE = false; | |
853 handleAllErrors( | |
854 unwrap(wrap(joinErrors(make_error<CustomSubError>(42, 7), | |
855 make_error<CustomError>(42)))), | |
856 [&](CustomSubError &CSE) { | |
857 GotCSE = true; | |
858 }, | |
859 [&](CustomError &CE) { | |
860 GotCE = true; | |
861 }); | |
862 EXPECT_TRUE(GotCSE) << "Failed to round-trip ErrorList via C API"; | |
863 EXPECT_TRUE(GotCE) << "Failed to round-trip ErrorList via C API"; | |
864 } | |
865 | |
866 TEST(Error, FileErrorTest) { | |
867 #if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST | |
868 EXPECT_DEATH( | |
869 { | |
870 Error S = Error::success(); | |
871 consumeError(createFileError("file.bin", std::move(S))); | |
872 }, | |
873 ""); | |
874 #endif | |
875 // Not allowed, would fail at compile-time | |
876 //consumeError(createFileError("file.bin", ErrorSuccess())); | |
877 | |
878 Error E1 = make_error<CustomError>(1); | |
879 Error FE1 = createFileError("file.bin", std::move(E1)); | |
880 EXPECT_EQ(toString(std::move(FE1)).compare("'file.bin': CustomError {1}"), 0); | |
881 | |
882 Error E2 = make_error<CustomError>(2); | |
883 Error FE2 = createFileError("file.bin", std::move(E2)); | |
884 handleAllErrors(std::move(FE2), [](const FileError &F) { | |
885 EXPECT_EQ(F.message().compare("'file.bin': CustomError {2}"), 0); | |
886 }); | |
887 | |
888 Error E3 = make_error<CustomError>(3); | |
889 Error FE3 = createFileError("file.bin", std::move(E3)); | |
890 auto E31 = handleErrors(std::move(FE3), [](std::unique_ptr<FileError> F) { | |
891 return F->takeError(); | |
892 }); | |
893 handleAllErrors(std::move(E31), [](const CustomError &C) { | |
894 EXPECT_EQ(C.message().compare("CustomError {3}"), 0); | |
895 }); | |
896 | |
897 Error FE4 = | |
898 joinErrors(createFileError("file.bin", make_error<CustomError>(41)), | |
899 createFileError("file2.bin", make_error<CustomError>(42))); | |
900 EXPECT_EQ(toString(std::move(FE4)) | |
901 .compare("'file.bin': CustomError {41}\n" | |
902 "'file2.bin': CustomError {42}"), | |
903 0); | |
904 } | |
905 | |
906 enum class test_error_code { | |
907 unspecified = 1, | |
908 error_1, | |
909 error_2, | |
910 }; | |
767 | 911 |
768 } // end anon namespace | 912 } // end anon namespace |
913 | |
914 namespace std { | |
915 template <> | |
916 struct is_error_code_enum<test_error_code> : std::true_type {}; | |
917 } // namespace std | |
918 | |
919 namespace { | |
920 | |
921 const std::error_category &TErrorCategory(); | |
922 | |
923 inline std::error_code make_error_code(test_error_code E) { | |
924 return std::error_code(static_cast<int>(E), TErrorCategory()); | |
925 } | |
926 | |
927 class TestDebugError : public ErrorInfo<TestDebugError, StringError> { | |
928 public: | |
929 using ErrorInfo<TestDebugError, StringError >::ErrorInfo; // inherit constructors | |
930 TestDebugError(const Twine &S) : ErrorInfo(S, test_error_code::unspecified) {} | |
931 static char ID; | |
932 }; | |
933 | |
934 class TestErrorCategory : public std::error_category { | |
935 public: | |
936 const char *name() const noexcept override { return "error"; } | |
937 std::string message(int Condition) const override { | |
938 switch (static_cast<test_error_code>(Condition)) { | |
939 case test_error_code::unspecified: | |
940 return "An unknown error has occurred."; | |
941 case test_error_code::error_1: | |
942 return "Error 1."; | |
943 case test_error_code::error_2: | |
944 return "Error 2."; | |
945 } | |
946 llvm_unreachable("Unrecognized test_error_code"); | |
947 } | |
948 }; | |
949 | |
950 static llvm::ManagedStatic<TestErrorCategory> TestErrCategory; | |
951 const std::error_category &TErrorCategory() { return *TestErrCategory; } | |
952 | |
953 char TestDebugError::ID; | |
954 | |
955 TEST(Error, SubtypeStringErrorTest) { | |
956 auto E1 = make_error<TestDebugError>(test_error_code::error_1); | |
957 EXPECT_EQ(toString(std::move(E1)).compare("Error 1."), 0); | |
958 | |
959 auto E2 = make_error<TestDebugError>(test_error_code::error_1, | |
960 "Detailed information"); | |
961 EXPECT_EQ(toString(std::move(E2)).compare("Error 1. Detailed information"), | |
962 0); | |
963 | |
964 auto E3 = make_error<TestDebugError>(test_error_code::error_2); | |
965 handleAllErrors(std::move(E3), [](const TestDebugError &F) { | |
966 EXPECT_EQ(F.message().compare("Error 2."), 0); | |
967 }); | |
968 | |
969 auto E4 = joinErrors(make_error<TestDebugError>(test_error_code::error_1, | |
970 "Detailed information"), | |
971 make_error<TestDebugError>(test_error_code::error_2)); | |
972 EXPECT_EQ(toString(std::move(E4)) | |
973 .compare("Error 1. Detailed information\n" | |
974 "Error 2."), | |
975 0); | |
976 } | |
977 | |
978 } // namespace |