]> git.proxmox.com Git - ceph.git/blob - ceph/src/arrow/cpp/src/arrow/status_test.cc
import quincy 17.2.0
[ceph.git] / ceph / src / arrow / cpp / src / arrow / status_test.cc
1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements. See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership. The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License. You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing,
12 // software distributed under the License is distributed on an
13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, either express or implied. See the License for the
15 // specific language governing permissions and limitations
16 // under the License.
17
18 #include <sstream>
19
20 #include <gmock/gmock-matchers.h>
21 #include <gtest/gtest.h>
22
23 #include "arrow/status.h"
24 #include "arrow/testing/gtest_util.h"
25 #include "arrow/testing/matchers.h"
26
27 namespace arrow {
28
29 namespace {
30
31 class TestStatusDetail : public StatusDetail {
32 public:
33 const char* type_id() const override { return "type_id"; }
34 std::string ToString() const override { return "a specific detail message"; }
35 };
36
37 } // namespace
38
39 TEST(StatusTest, TestCodeAndMessage) {
40 Status ok = Status::OK();
41 ASSERT_EQ(StatusCode::OK, ok.code());
42 Status file_error = Status::IOError("file error");
43 ASSERT_EQ(StatusCode::IOError, file_error.code());
44 ASSERT_EQ("file error", file_error.message());
45 }
46
47 TEST(StatusTest, TestToString) {
48 Status file_error = Status::IOError("file error");
49 ASSERT_EQ("IOError: file error", file_error.ToString());
50
51 std::stringstream ss;
52 ss << file_error;
53 ASSERT_EQ(file_error.ToString(), ss.str());
54 }
55
56 TEST(StatusTest, TestToStringWithDetail) {
57 Status status(StatusCode::IOError, "summary", std::make_shared<TestStatusDetail>());
58 ASSERT_EQ("IOError: summary. Detail: a specific detail message", status.ToString());
59
60 std::stringstream ss;
61 ss << status;
62 ASSERT_EQ(status.ToString(), ss.str());
63 }
64
65 TEST(StatusTest, TestWithDetail) {
66 Status status(StatusCode::IOError, "summary");
67 auto detail = std::make_shared<TestStatusDetail>();
68 Status new_status = status.WithDetail(detail);
69
70 ASSERT_EQ(new_status.code(), status.code());
71 ASSERT_EQ(new_status.message(), status.message());
72 ASSERT_EQ(new_status.detail(), detail);
73 }
74
75 TEST(StatusTest, AndStatus) {
76 Status a = Status::OK();
77 Status b = Status::OK();
78 Status c = Status::Invalid("invalid value");
79 Status d = Status::IOError("file error");
80
81 Status res;
82 res = a & b;
83 ASSERT_TRUE(res.ok());
84 res = a & c;
85 ASSERT_TRUE(res.IsInvalid());
86 res = d & c;
87 ASSERT_TRUE(res.IsIOError());
88
89 res = Status::OK();
90 res &= c;
91 ASSERT_TRUE(res.IsInvalid());
92 res &= d;
93 ASSERT_TRUE(res.IsInvalid());
94
95 // With rvalues
96 res = Status::OK() & Status::Invalid("foo");
97 ASSERT_TRUE(res.IsInvalid());
98 res = Status::Invalid("foo") & Status::OK();
99 ASSERT_TRUE(res.IsInvalid());
100 res = Status::Invalid("foo") & Status::IOError("bar");
101 ASSERT_TRUE(res.IsInvalid());
102
103 res = Status::OK();
104 res &= Status::OK();
105 ASSERT_TRUE(res.ok());
106 res &= Status::Invalid("foo");
107 ASSERT_TRUE(res.IsInvalid());
108 res &= Status::IOError("bar");
109 ASSERT_TRUE(res.IsInvalid());
110 }
111
112 TEST(StatusTest, TestEquality) {
113 ASSERT_EQ(Status(), Status::OK());
114 ASSERT_EQ(Status::Invalid("error"), Status::Invalid("error"));
115
116 ASSERT_NE(Status::Invalid("error"), Status::OK());
117 ASSERT_NE(Status::Invalid("error"), Status::Invalid("other error"));
118 }
119
120 TEST(StatusTest, MatcherExamples) {
121 EXPECT_THAT(Status::Invalid("arbitrary error"), Raises(StatusCode::Invalid));
122
123 EXPECT_THAT(Status::Invalid("arbitrary error"),
124 Raises(StatusCode::Invalid, testing::HasSubstr("arbitrary")));
125
126 // message doesn't match, so no match
127 EXPECT_THAT(
128 Status::Invalid("arbitrary error"),
129 testing::Not(Raises(StatusCode::Invalid, testing::HasSubstr("reasonable"))));
130
131 // different error code, so no match
132 EXPECT_THAT(Status::TypeError("arbitrary error"),
133 testing::Not(Raises(StatusCode::Invalid)));
134
135 // not an error, so no match
136 EXPECT_THAT(Status::OK(), testing::Not(Raises(StatusCode::Invalid)));
137 }
138
139 TEST(StatusTest, MatcherDescriptions) {
140 testing::Matcher<Status> matcher = Raises(StatusCode::Invalid);
141
142 {
143 std::stringstream ss;
144 matcher.DescribeTo(&ss);
145 EXPECT_THAT(ss.str(), testing::StrEq("raises StatusCode::Invalid"));
146 }
147
148 {
149 std::stringstream ss;
150 matcher.DescribeNegationTo(&ss);
151 EXPECT_THAT(ss.str(), testing::StrEq("does not raise StatusCode::Invalid"));
152 }
153 }
154
155 TEST(StatusTest, MessageMatcherDescriptions) {
156 testing::Matcher<Status> matcher =
157 Raises(StatusCode::Invalid, testing::HasSubstr("arbitrary"));
158
159 {
160 std::stringstream ss;
161 matcher.DescribeTo(&ss);
162 EXPECT_THAT(
163 ss.str(),
164 testing::StrEq(
165 "raises StatusCode::Invalid and message has substring \"arbitrary\""));
166 }
167
168 {
169 std::stringstream ss;
170 matcher.DescribeNegationTo(&ss);
171 EXPECT_THAT(ss.str(), testing::StrEq("does not raise StatusCode::Invalid or message "
172 "has no substring \"arbitrary\""));
173 }
174 }
175
176 TEST(StatusTest, MatcherExplanations) {
177 testing::Matcher<Status> matcher = Raises(StatusCode::Invalid);
178
179 {
180 testing::StringMatchResultListener listener;
181 EXPECT_TRUE(matcher.MatchAndExplain(Status::Invalid("XXX"), &listener));
182 EXPECT_THAT(listener.str(), testing::StrEq("whose value \"Invalid: XXX\" matches"));
183 }
184
185 {
186 testing::StringMatchResultListener listener;
187 EXPECT_FALSE(matcher.MatchAndExplain(Status::OK(), &listener));
188 EXPECT_THAT(listener.str(), testing::StrEq("whose value \"OK\" doesn't match"));
189 }
190
191 {
192 testing::StringMatchResultListener listener;
193 EXPECT_FALSE(matcher.MatchAndExplain(Status::TypeError("XXX"), &listener));
194 EXPECT_THAT(listener.str(),
195 testing::StrEq("whose value \"Type error: XXX\" doesn't match"));
196 }
197 }
198
199 TEST(StatusTest, TestDetailEquality) {
200 const auto status_with_detail =
201 arrow::Status(StatusCode::IOError, "", std::make_shared<TestStatusDetail>());
202 const auto status_with_detail2 =
203 arrow::Status(StatusCode::IOError, "", std::make_shared<TestStatusDetail>());
204 const auto status_without_detail = arrow::Status::IOError("");
205
206 ASSERT_EQ(*status_with_detail.detail(), *status_with_detail2.detail());
207 ASSERT_EQ(status_with_detail, status_with_detail2);
208 ASSERT_NE(status_with_detail, status_without_detail);
209 ASSERT_NE(status_without_detail, status_with_detail);
210 }
211
212 } // namespace arrow