test-util.h (11731B)
1 // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors 2 // Licensed under the MIT License: 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a copy 5 // of this software and associated documentation files (the "Software"), to deal 6 // in the Software without restriction, including without limitation the rights 7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 // copies of the Software, and to permit persons to whom the Software is 9 // furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 // THE SOFTWARE. 21 22 #pragma once 23 24 #include <capnp/test.capnp.h> 25 #include <iostream> 26 #include "blob.h" 27 #include <kj/compat/gtest.h> 28 29 #if !CAPNP_LITE 30 #include "dynamic.h" 31 #include <kj/io.h> 32 #endif // !CAPNP_LITE 33 34 CAPNP_BEGIN_HEADER 35 36 // TODO(cleanup): Auto-generate stringification functions for union discriminants. 37 namespace capnproto_test { 38 namespace capnp { 39 namespace test { 40 inline kj::String KJ_STRINGIFY(TestUnion::Union0::Which which) { 41 return kj::str(static_cast<uint16_t>(which)); 42 } 43 inline kj::String KJ_STRINGIFY(TestUnion::Union1::Which which) { 44 return kj::str(static_cast<uint16_t>(which)); 45 } 46 inline kj::String KJ_STRINGIFY(TestUnion::Union2::Which which) { 47 return kj::str(static_cast<uint16_t>(which)); 48 } 49 inline kj::String KJ_STRINGIFY(TestUnion::Union3::Which which) { 50 return kj::str(static_cast<uint16_t>(which)); 51 } 52 inline kj::String KJ_STRINGIFY(TestUnnamedUnion::Which which) { 53 return kj::str(static_cast<uint16_t>(which)); 54 } 55 inline kj::String KJ_STRINGIFY(TestGroups::Groups::Which which) { 56 return kj::str(static_cast<uint16_t>(which)); 57 } 58 inline kj::String KJ_STRINGIFY(TestInterleavedGroups::Group1::Which which) { 59 return kj::str(static_cast<uint16_t>(which)); 60 } 61 } // namespace test 62 } // namespace capnp 63 } // namespace capnproto_test 64 65 namespace capnp { 66 namespace _ { // private 67 68 inline Data::Reader data(const char* str) { 69 return Data::Reader(reinterpret_cast<const byte*>(str), strlen(str)); 70 } 71 72 namespace test = capnproto_test::capnp::test; 73 74 // We don't use "using namespace" to pull these in because then things would still compile 75 // correctly if they were generated in the global namespace. 76 using ::capnproto_test::capnp::test::TestAllTypes; 77 using ::capnproto_test::capnp::test::TestDefaults; 78 using ::capnproto_test::capnp::test::TestEnum; 79 using ::capnproto_test::capnp::test::TestUnion; 80 using ::capnproto_test::capnp::test::TestUnionDefaults; 81 using ::capnproto_test::capnp::test::TestNestedTypes; 82 using ::capnproto_test::capnp::test::TestUsing; 83 using ::capnproto_test::capnp::test::TestListDefaults; 84 85 void initTestMessage(TestAllTypes::Builder builder); 86 void initTestMessage(TestDefaults::Builder builder); 87 void initTestMessage(TestListDefaults::Builder builder); 88 89 void checkTestMessage(TestAllTypes::Builder builder); 90 void checkTestMessage(TestDefaults::Builder builder); 91 void checkTestMessage(TestListDefaults::Builder builder); 92 93 void checkTestMessage(TestAllTypes::Reader reader); 94 void checkTestMessage(TestDefaults::Reader reader); 95 void checkTestMessage(TestListDefaults::Reader reader); 96 97 void checkTestMessageAllZero(TestAllTypes::Builder builder); 98 void checkTestMessageAllZero(TestAllTypes::Reader reader); 99 100 #if !CAPNP_LITE 101 void initDynamicTestMessage(DynamicStruct::Builder builder); 102 void initDynamicTestLists(DynamicStruct::Builder builder); 103 void checkDynamicTestMessage(DynamicStruct::Builder builder); 104 void checkDynamicTestLists(DynamicStruct::Builder builder); 105 void checkDynamicTestMessage(DynamicStruct::Reader reader); 106 void checkDynamicTestLists(DynamicStruct::Reader reader); 107 void checkDynamicTestMessageAllZero(DynamicStruct::Builder builder); 108 void checkDynamicTestMessageAllZero(DynamicStruct::Reader reader); 109 #endif // !CAPNP_LITE 110 111 template <typename T> 112 inline void checkElement(T a, T b) { 113 EXPECT_EQ(a, b); 114 } 115 116 template <> 117 inline void checkElement<float>(float a, float b) { 118 EXPECT_FLOAT_EQ(a, b); 119 } 120 121 template <> 122 inline void checkElement<double>(double a, double b) { 123 EXPECT_DOUBLE_EQ(a, b); 124 } 125 126 template <typename T, typename L = typename T::Reads> 127 void checkList(T reader, std::initializer_list<decltype(reader[0])> expected) { 128 ASSERT_EQ(expected.size(), reader.size()); 129 for (uint i = 0; i < expected.size(); i++) { 130 checkElement<decltype(reader[0])>(expected.begin()[i], reader[i]); 131 } 132 } 133 134 template <typename T, typename L = typename T::Builds, bool = false> 135 void checkList(T reader, std::initializer_list<decltype(typename L::Reader()[0])> expected) { 136 ASSERT_EQ(expected.size(), reader.size()); 137 for (uint i = 0; i < expected.size(); i++) { 138 checkElement<decltype(typename L::Reader()[0])>(expected.begin()[i], reader[i]); 139 } 140 } 141 142 inline void checkList(List<test::TestOldVersion>::Reader reader, 143 std::initializer_list<int64_t> expectedData, 144 std::initializer_list<Text::Reader> expectedPointers) { 145 ASSERT_EQ(expectedData.size(), reader.size()); 146 for (uint i = 0; i < expectedData.size(); i++) { 147 EXPECT_EQ(expectedData.begin()[i], reader[i].getOld1()); 148 EXPECT_EQ(expectedPointers.begin()[i], reader[i].getOld2()); 149 } 150 } 151 152 // Hack because as<>() is a template-parameter-dependent lookup everywhere below... 153 #define as template as 154 155 template <typename T> void expectPrimitiveEq(T a, T b) { EXPECT_EQ(a, b); } 156 inline void expectPrimitiveEq(float a, float b) { EXPECT_FLOAT_EQ(a, b); } 157 inline void expectPrimitiveEq(double a, double b) { EXPECT_DOUBLE_EQ(a, b); } 158 inline void expectPrimitiveEq(Text::Reader a, Text::Builder b) { EXPECT_EQ(a, b); } 159 inline void expectPrimitiveEq(Data::Reader a, Data::Builder b) { EXPECT_EQ(a, b); } 160 161 #if !CAPNP_LITE 162 template <typename Element, typename T> 163 void checkList(T reader, std::initializer_list<ReaderFor<Element>> expected) { 164 auto list = reader.as<DynamicList>(); 165 ASSERT_EQ(expected.size(), list.size()); 166 for (uint i = 0; i < expected.size(); i++) { 167 expectPrimitiveEq(expected.begin()[i], list[i].as<Element>()); 168 } 169 170 auto typed = reader.as<List<Element>>(); 171 ASSERT_EQ(expected.size(), typed.size()); 172 for (uint i = 0; i < expected.size(); i++) { 173 expectPrimitiveEq(expected.begin()[i], typed[i]); 174 } 175 } 176 #endif // !CAPNP_LITE 177 178 #undef as 179 180 // ======================================================================================= 181 // Interface implementations. 182 183 #if !CAPNP_LITE 184 185 class TestInterfaceImpl final: public test::TestInterface::Server { 186 public: 187 TestInterfaceImpl(int& callCount); 188 189 kj::Promise<void> foo(FooContext context) override; 190 191 kj::Promise<void> baz(BazContext context) override; 192 193 private: 194 int& callCount; 195 }; 196 197 class TestExtendsImpl final: public test::TestExtends2::Server { 198 public: 199 TestExtendsImpl(int& callCount); 200 201 kj::Promise<void> foo(FooContext context) override; 202 203 kj::Promise<void> grault(GraultContext context) override; 204 205 private: 206 int& callCount; 207 }; 208 209 class TestPipelineImpl final: public test::TestPipeline::Server { 210 public: 211 TestPipelineImpl(int& callCount); 212 213 kj::Promise<void> getCap(GetCapContext context) override; 214 kj::Promise<void> getAnyCap(GetAnyCapContext context) override; 215 kj::Promise<void> getCapPipelineOnly(GetCapPipelineOnlyContext context) override; 216 217 private: 218 int& callCount; 219 }; 220 221 class TestCallOrderImpl final: public test::TestCallOrder::Server { 222 public: 223 kj::Promise<void> getCallSequence(GetCallSequenceContext context) override; 224 225 uint getCount() { return count; } 226 227 private: 228 uint count = 0; 229 }; 230 231 class TestTailCallerImpl final: public test::TestTailCaller::Server { 232 public: 233 TestTailCallerImpl(int& callCount); 234 235 kj::Promise<void> foo(FooContext context) override; 236 237 private: 238 int& callCount; 239 }; 240 241 class TestTailCalleeImpl final: public test::TestTailCallee::Server { 242 public: 243 TestTailCalleeImpl(int& callCount); 244 245 kj::Promise<void> foo(FooContext context) override; 246 247 private: 248 int& callCount; 249 }; 250 251 class TestMoreStuffImpl final: public test::TestMoreStuff::Server { 252 public: 253 TestMoreStuffImpl(int& callCount, int& handleCount); 254 255 kj::Promise<void> getCallSequence(GetCallSequenceContext context) override; 256 257 kj::Promise<void> callFoo(CallFooContext context) override; 258 259 kj::Promise<void> callFooWhenResolved(CallFooWhenResolvedContext context) override; 260 261 kj::Promise<void> neverReturn(NeverReturnContext context) override; 262 263 kj::Promise<void> hold(HoldContext context) override; 264 265 kj::Promise<void> callHeld(CallHeldContext context) override; 266 267 kj::Promise<void> getHeld(GetHeldContext context) override; 268 269 kj::Promise<void> echo(EchoContext context) override; 270 271 kj::Promise<void> expectCancel(ExpectCancelContext context) override; 272 273 kj::Promise<void> getHandle(GetHandleContext context) override; 274 275 kj::Promise<void> getNull(GetNullContext context) override; 276 277 kj::Promise<void> getEnormousString(GetEnormousStringContext context) override; 278 279 kj::Promise<void> writeToFd(WriteToFdContext context) override; 280 281 kj::Promise<void> throwException(ThrowExceptionContext context) override; 282 283 kj::Promise<void> throwRemoteException(ThrowRemoteExceptionContext context) override; 284 285 private: 286 int& callCount; 287 int& handleCount; 288 test::TestInterface::Client clientToHold = nullptr; 289 290 kj::Promise<void> loop(uint depth, test::TestInterface::Client cap, ExpectCancelContext context); 291 }; 292 293 class TestCapDestructor final: public test::TestInterface::Server { 294 // Implementation of TestInterface that notifies when it is destroyed. 295 296 public: 297 TestCapDestructor(kj::Own<kj::PromiseFulfiller<void>>&& fulfiller) 298 : fulfiller(kj::mv(fulfiller)), impl(dummy) {} 299 300 ~TestCapDestructor() { 301 fulfiller->fulfill(); 302 } 303 304 kj::Promise<void> foo(FooContext context) { 305 return impl.foo(context); 306 } 307 308 private: 309 kj::Own<kj::PromiseFulfiller<void>> fulfiller; 310 int dummy = 0; 311 TestInterfaceImpl impl; 312 }; 313 314 class TestFdCap final: public test::TestInterface::Server { 315 // Implementation of TestInterface that wraps a file descriptor. 316 317 public: 318 TestFdCap(kj::AutoCloseFd fd): fd(kj::mv(fd)) {} 319 320 kj::Maybe<int> getFd() override { return fd.get(); } 321 322 private: 323 kj::AutoCloseFd fd; 324 }; 325 326 class TestStreamingImpl final: public test::TestStreaming::Server { 327 public: 328 uint iSum = 0; 329 uint jSum = 0; 330 kj::Maybe<kj::Own<kj::PromiseFulfiller<void>>> fulfiller; 331 bool jShouldThrow = false; 332 333 kj::Promise<void> doStreamI(DoStreamIContext context) override { 334 iSum += context.getParams().getI(); 335 auto paf = kj::newPromiseAndFulfiller<void>(); 336 fulfiller = kj::mv(paf.fulfiller); 337 return kj::mv(paf.promise); 338 } 339 340 kj::Promise<void> doStreamJ(DoStreamJContext context) override { 341 context.allowCancellation(); 342 jSum += context.getParams().getJ(); 343 344 if (jShouldThrow) { 345 KJ_FAIL_ASSERT("throw requested") { break; } 346 return kj::READY_NOW; 347 } 348 349 auto paf = kj::newPromiseAndFulfiller<void>(); 350 fulfiller = kj::mv(paf.fulfiller); 351 return kj::mv(paf.promise); 352 } 353 354 kj::Promise<void> finishStream(FinishStreamContext context) override { 355 auto results = context.getResults(); 356 results.setTotalI(iSum); 357 results.setTotalJ(jSum); 358 return kj::READY_NOW; 359 } 360 }; 361 362 #endif // !CAPNP_LITE 363 364 } // namespace _ (private) 365 } // namespace capnp 366 367 CAPNP_END_HEADER