xref: /aosp_15_r20/external/grpc-grpc/test/core/promise/try_seq_test.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 // Copyright 2021 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "src/core/lib/promise/try_seq.h"
16 
17 #include <stdlib.h>
18 
19 #include <string>
20 #include <vector>
21 
22 #include "gtest/gtest.h"
23 
24 namespace grpc_core {
25 
26 struct AbslStatusTraits {
27   template <typename T>
28   using Promise = std::function<Poll<absl::StatusOr<T>>()>;
29 
30   template <typename T>
instant_okgrpc_core::AbslStatusTraits31   static Promise<T> instant_ok(T x) {
32     return [x] { return absl::StatusOr<T>(x); };
33   }
34 
instant_ok_statusgrpc_core::AbslStatusTraits35   static auto instant_ok_status() {
36     return [] { return absl::OkStatus(); };
37   }
38 
39   template <typename T>
instant_failgrpc_core::AbslStatusTraits40   static Promise<T> instant_fail() {
41     return [] { return absl::StatusOr<T>(); };
42   }
43 
44   template <typename T>
instant_crashgrpc_core::AbslStatusTraits45   static Poll<absl::StatusOr<T>> instant_crash() {
46     abort();
47   }
48 
49   template <typename T>
okgrpc_core::AbslStatusTraits50   static Poll<absl::StatusOr<T>> ok(T x) {
51     return absl::StatusOr<T>(x);
52   }
53 
ok_statusgrpc_core::AbslStatusTraits54   static Poll<absl::Status> ok_status() { return absl::OkStatus(); }
55 
56   template <typename T>
failgrpc_core::AbslStatusTraits57   static Poll<absl::StatusOr<T>> fail() {
58     return absl::StatusOr<T>();
59   }
60 
61   template <typename T>
pendinggrpc_core::AbslStatusTraits62   static Promise<T> pending() {
63     return []() -> Poll<absl::StatusOr<T>> { return Pending(); };
64   }
65 };
66 
67 struct ValueOrFailureTraits {
68   template <typename T>
69   using Promise = std::function<Poll<ValueOrFailure<T>>()>;
70 
71   template <typename T>
instant_okgrpc_core::ValueOrFailureTraits72   static Promise<T> instant_ok(T x) {
73     return [x] { return ValueOrFailure<T>(x); };
74   }
75 
instant_ok_statusgrpc_core::ValueOrFailureTraits76   static auto instant_ok_status() {
77     return [] { return StatusFlag(true); };
78   }
79 
80   template <typename T>
instant_failgrpc_core::ValueOrFailureTraits81   static Promise<T> instant_fail() {
82     return [] { return Failure{}; };
83   }
84 
85   template <typename T>
instant_crashgrpc_core::ValueOrFailureTraits86   static Poll<ValueOrFailure<T>> instant_crash() {
87     abort();
88   }
89 
90   template <typename T>
okgrpc_core::ValueOrFailureTraits91   static Poll<ValueOrFailure<T>> ok(T x) {
92     return ValueOrFailure<T>(x);
93   }
94 
ok_statusgrpc_core::ValueOrFailureTraits95   static Poll<StatusFlag> ok_status() { return Success{}; }
96 
97   template <typename T>
failgrpc_core::ValueOrFailureTraits98   static Poll<ValueOrFailure<T>> fail() {
99     return Failure{};
100   }
101 
102   template <typename T>
pendinggrpc_core::ValueOrFailureTraits103   static Promise<T> pending() {
104     return []() -> Poll<ValueOrFailure<T>> { return Pending(); };
105   }
106 };
107 
108 template <typename T>
109 class TrySeqTest : public ::testing::Test {};
110 
111 using Traits = ::testing::Types<AbslStatusTraits, ValueOrFailureTraits>;
112 TYPED_TEST_SUITE(TrySeqTest, Traits);
113 
TYPED_TEST(TrySeqTest,SucceedAndThen)114 TYPED_TEST(TrySeqTest, SucceedAndThen) {
115   EXPECT_EQ(TrySeq(TypeParam::instant_ok(1),
116                    [](int i) { return TypeParam::instant_ok(i + 1); })(),
117             TypeParam::ok(2));
118 }
119 
TYPED_TEST(TrySeqTest,SucceedDirectlyAndThenDirectly)120 TYPED_TEST(TrySeqTest, SucceedDirectlyAndThenDirectly) {
121   EXPECT_EQ(
122       TrySeq([] { return 1; }, [](int i) { return [i]() { return i + 1; }; })(),
123       Poll<absl::StatusOr<int>>(2));
124 }
125 
TYPED_TEST(TrySeqTest,SucceedAndThenChangeType)126 TYPED_TEST(TrySeqTest, SucceedAndThenChangeType) {
127   EXPECT_EQ(
128       TrySeq(TypeParam::instant_ok(42),
129              [](int i) { return TypeParam::instant_ok(std::to_string(i)); })(),
130       TypeParam::ok(std::string("42")));
131 }
132 
TYPED_TEST(TrySeqTest,FailAndThen)133 TYPED_TEST(TrySeqTest, FailAndThen) {
134   EXPECT_EQ(
135       TrySeq(TypeParam::template instant_fail<int>(),
136              [](int) { return TypeParam::template instant_crash<double>(); })(),
137       TypeParam::template fail<double>());
138 }
139 
TYPED_TEST(TrySeqTest,RawSucceedAndThen)140 TYPED_TEST(TrySeqTest, RawSucceedAndThen) {
141   EXPECT_EQ(TrySeq(TypeParam::instant_ok_status(),
142                    [] { return TypeParam::instant_ok_status(); })(),
143             TypeParam::ok_status());
144 }
145 
TYPED_TEST(TrySeqTest,RawFailAndThen)146 TYPED_TEST(TrySeqTest, RawFailAndThen) {
147   EXPECT_EQ(TrySeq([] { return absl::CancelledError(); },
148                    []() { return []() -> Poll<absl::Status> { abort(); }; })(),
149             Poll<absl::Status>(absl::CancelledError()));
150 }
151 
TYPED_TEST(TrySeqTest,RawSucceedAndThenValue)152 TYPED_TEST(TrySeqTest, RawSucceedAndThenValue) {
153   EXPECT_EQ(TrySeq([] { return absl::OkStatus(); },
154                    [] { return []() { return absl::StatusOr<int>(42); }; })(),
155             Poll<absl::StatusOr<int>>(absl::StatusOr<int>(42)));
156 }
157 
TEST(TrySeqIterTest,Ok)158 TEST(TrySeqIterTest, Ok) {
159   std::vector<int> v{1, 2, 3, 4, 5};
160   EXPECT_EQ(TrySeqIter(v.begin(), v.end(), 0,
161                        [](int elem, int accum) {
162                          return [elem, accum]() -> absl::StatusOr<int> {
163                            return elem + accum;
164                          };
165                        })(),
166             Poll<absl::StatusOr<int>>(15));
167 }
168 
TEST(TrySeqIterTest,ErrorAt3)169 TEST(TrySeqIterTest, ErrorAt3) {
170   std::vector<int> v{1, 2, 3, 4, 5};
171   EXPECT_EQ(TrySeqIter(v.begin(), v.end(), 0,
172                        [](int elem, int accum) {
173                          return [elem, accum]() -> absl::StatusOr<int> {
174                            if (elem < 3) {
175                              return elem + accum;
176                            }
177                            if (elem == 3) {
178                              return absl::CancelledError();
179                            }
180                            abort();  // unreachable
181                          };
182                        })(),
183             Poll<absl::StatusOr<int>>(absl::CancelledError()));
184 }
185 
186 }  // namespace grpc_core
187 
main(int argc,char ** argv)188 int main(int argc, char** argv) {
189   ::testing::InitGoogleTest(&argc, argv);
190   return RUN_ALL_TESTS();
191 }
192