capnproto

FORK: Cap'n Proto serialization/RPC system - core tools and C++ library
git clone https://git.neptards.moe/neptards/capnproto.git
Log | Files | Refs | README | LICENSE

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