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

capability-test.c++ (43281B)


      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 #include "schema.capnp.h"
     23 
     24 #ifdef CAPNP_CAPABILITY_H_INCLUDED
     25 #error "schema.capnp should not depend on capability.h, because it contains no interfaces."
     26 #endif
     27 
     28 #include <capnp/test.capnp.h>
     29 
     30 #ifndef CAPNP_CAPABILITY_H_INCLUDED
     31 #error "test.capnp did not include capability.h."
     32 #endif
     33 
     34 #include "capability.h"
     35 #include "test-util.h"
     36 #include <kj/debug.h>
     37 #include <kj/compat/gtest.h>
     38 
     39 namespace capnp {
     40 namespace _ {
     41 namespace {
     42 
     43 TEST(Capability, Basic) {
     44   kj::EventLoop loop;
     45   kj::WaitScope waitScope(loop);
     46 
     47   int callCount = 0;
     48   test::TestInterface::Client client(kj::heap<TestInterfaceImpl>(callCount));
     49 
     50   auto request1 = client.fooRequest();
     51   request1.setI(123);
     52   request1.setJ(true);
     53   auto promise1 = request1.send();
     54 
     55   auto request2 = client.bazRequest();
     56   initTestMessage(request2.initS());
     57   auto promise2 = request2.send();
     58 
     59   bool barFailed = false;
     60   auto request3 = client.barRequest();
     61   auto promise3 = request3.send().then(
     62       [](Response<test::TestInterface::BarResults>&& response) {
     63         ADD_FAILURE() << "Expected bar() call to fail.";
     64       }, [&](kj::Exception&& e) {
     65         EXPECT_EQ(kj::Exception::Type::UNIMPLEMENTED, e.getType());
     66         barFailed = true;
     67       });
     68 
     69   EXPECT_EQ(0, callCount);
     70 
     71   auto response1 = promise1.wait(waitScope);
     72 
     73   EXPECT_EQ("foo", response1.getX());
     74 
     75   auto response2 = promise2.wait(waitScope);
     76 
     77   promise3.wait(waitScope);
     78 
     79   EXPECT_EQ(2, callCount);
     80   EXPECT_TRUE(barFailed);
     81 }
     82 
     83 TEST(Capability, CapabilityList) {
     84   kj::EventLoop loop;
     85   kj::WaitScope waitScope(loop);
     86 
     87   MallocMessageBuilder builder;
     88   auto root = builder.initRoot<test::TestListOfAny>();
     89   auto initCapList = root.initCapList(2);
     90 
     91   int callCount0 = 0;
     92   int callCount1 = 0;
     93   initCapList.set(0, kj::heap<TestInterfaceImpl>(callCount0));
     94   initCapList.set(1, kj::heap<TestInterfaceImpl>(callCount1));
     95 
     96   auto capList = root.getCapList();
     97   auto cap0 = capList[0].castAs<test::TestInterface>();
     98   auto cap1 = capList[1].castAs<test::TestInterface>();
     99 
    100   EXPECT_EQ(2u, root.getCapList().size());
    101 
    102   auto request0 = cap0.fooRequest();
    103   request0.setI(123);
    104   request0.setJ(true);
    105   EXPECT_EQ("foo", request0.send().wait(waitScope).getX());
    106 
    107   auto request1 = cap1.fooRequest();
    108   request1.setI(123);
    109   request1.setJ(true);
    110   EXPECT_EQ("foo", request1.send().wait(waitScope).getX());
    111 
    112   EXPECT_EQ(1, callCount0);
    113   EXPECT_EQ(1, callCount1);
    114 }
    115 
    116 TEST(Capability, Inheritance) {
    117   kj::EventLoop loop;
    118   kj::WaitScope waitScope(loop);
    119 
    120   int callCount = 0;
    121   test::TestExtends::Client client1(kj::heap<TestExtendsImpl>(callCount));
    122   test::TestInterface::Client client2 = client1;
    123   auto client = client2.castAs<test::TestExtends>();
    124 
    125   auto request1 = client.fooRequest();
    126   request1.setI(321);
    127   auto promise1 = request1.send();
    128 
    129   auto request2 = client.graultRequest();
    130   auto promise2 = request2.send();
    131 
    132   EXPECT_EQ(0, callCount);
    133 
    134   auto response2 = promise2.wait(waitScope);
    135 
    136   checkTestMessage(response2);
    137 
    138   auto response1 = promise1.wait(waitScope);
    139 
    140   EXPECT_EQ("bar", response1.getX());
    141 
    142   EXPECT_EQ(2, callCount);
    143 }
    144 
    145 TEST(Capability, Pipelining) {
    146   kj::EventLoop loop;
    147   kj::WaitScope waitScope(loop);
    148 
    149   int callCount = 0;
    150   int chainedCallCount = 0;
    151   test::TestPipeline::Client client(kj::heap<TestPipelineImpl>(callCount));
    152 
    153   auto request = client.getCapRequest();
    154   request.setN(234);
    155   request.setInCap(test::TestInterface::Client(kj::heap<TestInterfaceImpl>(chainedCallCount)));
    156 
    157   auto promise = request.send();
    158 
    159   auto pipelineRequest = promise.getOutBox().getCap().fooRequest();
    160   pipelineRequest.setI(321);
    161   auto pipelinePromise = pipelineRequest.send();
    162 
    163   auto pipelineRequest2 = promise.getOutBox().getCap().castAs<test::TestExtends>().graultRequest();
    164   auto pipelinePromise2 = pipelineRequest2.send();
    165 
    166   promise = nullptr;  // Just to be annoying, drop the original promise.
    167 
    168   EXPECT_EQ(0, callCount);
    169   EXPECT_EQ(0, chainedCallCount);
    170 
    171   auto response = pipelinePromise.wait(waitScope);
    172   EXPECT_EQ("bar", response.getX());
    173 
    174   auto response2 = pipelinePromise2.wait(waitScope);
    175   checkTestMessage(response2);
    176 
    177   EXPECT_EQ(3, callCount);
    178   EXPECT_EQ(1, chainedCallCount);
    179 }
    180 
    181 KJ_TEST("use pipeline after dropping response") {
    182   kj::EventLoop loop;
    183   kj::WaitScope waitScope(loop);
    184 
    185   int callCount = 0;
    186   int chainedCallCount = 0;
    187   test::TestPipeline::Client client(kj::heap<TestPipelineImpl>(callCount));
    188 
    189   auto request = client.getCapRequest();
    190   request.setN(234);
    191   request.setInCap(test::TestInterface::Client(kj::heap<TestInterfaceImpl>(chainedCallCount)));
    192 
    193   auto promise = request.send();
    194   test::TestPipeline::GetCapResults::Pipeline pipeline = kj::mv(promise);
    195 
    196   {
    197     auto response = promise.wait(waitScope);
    198     KJ_EXPECT(response.getS() == "bar");
    199   }
    200 
    201   auto pipelineRequest = pipeline.getOutBox().getCap().fooRequest();
    202   pipelineRequest.setI(321);
    203   auto pipelinePromise = pipelineRequest.send();
    204 
    205   auto pipelineRequest2 = pipeline.getOutBox().getCap().castAs<test::TestExtends>().graultRequest();
    206   auto pipelinePromise2 = pipelineRequest2.send();
    207 
    208   auto response = pipelinePromise.wait(waitScope);
    209   EXPECT_EQ("bar", response.getX());
    210 
    211   auto response2 = pipelinePromise2.wait(waitScope);
    212   checkTestMessage(response2);
    213 
    214   EXPECT_EQ(3, callCount);
    215   EXPECT_EQ(1, chainedCallCount);
    216 }
    217 
    218 KJ_TEST("context.setPipeline") {
    219   kj::EventLoop loop;
    220   kj::WaitScope waitScope(loop);
    221 
    222   int callCount = 0;
    223   test::TestPipeline::Client client(kj::heap<TestPipelineImpl>(callCount));
    224 
    225   auto promise = client.getCapPipelineOnlyRequest().send();
    226 
    227   auto pipelineRequest = promise.getOutBox().getCap().fooRequest();
    228   pipelineRequest.setI(321);
    229   auto pipelinePromise = pipelineRequest.send();
    230 
    231   auto pipelineRequest2 = promise.getOutBox().getCap().castAs<test::TestExtends>().graultRequest();
    232   auto pipelinePromise2 = pipelineRequest2.send();
    233 
    234   EXPECT_EQ(0, callCount);
    235 
    236   auto response = pipelinePromise.wait(waitScope);
    237   EXPECT_EQ("bar", response.getX());
    238 
    239   auto response2 = pipelinePromise2.wait(waitScope);
    240   checkTestMessage(response2);
    241 
    242   EXPECT_EQ(3, callCount);
    243 
    244   // The original promise never completed.
    245   KJ_EXPECT(!promise.poll(waitScope));
    246 }
    247 
    248 TEST(Capability, TailCall) {
    249   kj::EventLoop loop;
    250   kj::WaitScope waitScope(loop);
    251 
    252   int calleeCallCount = 0;
    253   int callerCallCount = 0;
    254 
    255   test::TestTailCallee::Client callee(kj::heap<TestTailCalleeImpl>(calleeCallCount));
    256   test::TestTailCaller::Client caller(kj::heap<TestTailCallerImpl>(callerCallCount));
    257 
    258   auto request = caller.fooRequest();
    259   request.setI(456);
    260   request.setCallee(callee);
    261 
    262   auto promise = request.send();
    263 
    264   auto dependentCall0 = promise.getC().getCallSequenceRequest().send();
    265 
    266   auto response = promise.wait(waitScope);
    267   EXPECT_EQ(456, response.getI());
    268   EXPECT_EQ(456, response.getI());
    269 
    270   auto dependentCall1 = promise.getC().getCallSequenceRequest().send();
    271 
    272   auto dependentCall2 = response.getC().getCallSequenceRequest().send();
    273 
    274   EXPECT_EQ(0, dependentCall0.wait(waitScope).getN());
    275   EXPECT_EQ(1, dependentCall1.wait(waitScope).getN());
    276   EXPECT_EQ(2, dependentCall2.wait(waitScope).getN());
    277 
    278   EXPECT_EQ(1, calleeCallCount);
    279   EXPECT_EQ(1, callerCallCount);
    280 }
    281 
    282 TEST(Capability, AsyncCancelation) {
    283   // Tests allowCancellation().
    284 
    285   kj::EventLoop loop;
    286   kj::WaitScope waitScope(loop);
    287 
    288   auto paf = kj::newPromiseAndFulfiller<void>();
    289   bool destroyed = false;
    290   auto destructionPromise = paf.promise.then([&]() { destroyed = true; }).eagerlyEvaluate(nullptr);
    291 
    292   int callCount = 0;
    293   int handleCount = 0;
    294 
    295   test::TestMoreStuff::Client client(kj::heap<TestMoreStuffImpl>(callCount, handleCount));
    296 
    297   kj::Promise<void> promise = nullptr;
    298 
    299   bool returned = false;
    300   {
    301     auto request = client.expectCancelRequest();
    302     request.setCap(test::TestInterface::Client(kj::heap<TestCapDestructor>(kj::mv(paf.fulfiller))));
    303     promise = request.send().then(
    304         [&](Response<test::TestMoreStuff::ExpectCancelResults>&& response) {
    305       returned = true;
    306     }).eagerlyEvaluate(nullptr);
    307   }
    308   kj::evalLater([]() {}).wait(waitScope);
    309   kj::evalLater([]() {}).wait(waitScope);
    310 
    311   // We can detect that the method was canceled because it will drop the cap.
    312   EXPECT_FALSE(destroyed);
    313   EXPECT_FALSE(returned);
    314 
    315   promise = nullptr;  // request cancellation
    316   destructionPromise.wait(waitScope);
    317 
    318   EXPECT_TRUE(destroyed);
    319   EXPECT_FALSE(returned);
    320 }
    321 
    322 // =======================================================================================
    323 
    324 TEST(Capability, DynamicClient) {
    325   kj::EventLoop loop;
    326   kj::WaitScope waitScope(loop);
    327 
    328   int callCount = 0;
    329   DynamicCapability::Client client =
    330       test::TestInterface::Client(kj::heap<TestInterfaceImpl>(callCount));
    331 
    332   auto request1 = client.newRequest("foo");
    333   request1.set("i", 123);
    334   request1.set("j", true);
    335   auto promise1 = request1.send();
    336 
    337   auto request2 = client.newRequest("baz");
    338   initDynamicTestMessage(request2.init("s").as<DynamicStruct>());
    339   auto promise2 = request2.send();
    340 
    341   bool barFailed = false;
    342   auto request3 = client.newRequest("bar");
    343   auto promise3 = request3.send().then(
    344       [](Response<DynamicStruct>&& response) {
    345         ADD_FAILURE() << "Expected bar() call to fail.";
    346       }, [&](kj::Exception&& e) {
    347         EXPECT_EQ(kj::Exception::Type::UNIMPLEMENTED, e.getType());
    348         barFailed = true;
    349       });
    350 
    351   EXPECT_EQ(0, callCount);
    352 
    353   auto response1 = promise1.wait(waitScope);
    354 
    355   EXPECT_EQ("foo", response1.get("x").as<Text>());
    356 
    357   auto response2 = promise2.wait(waitScope);
    358 
    359   promise3.wait(waitScope);
    360 
    361   EXPECT_EQ(2, callCount);
    362   EXPECT_TRUE(barFailed);
    363 }
    364 
    365 TEST(Capability, DynamicClientInheritance) {
    366   kj::EventLoop loop;
    367   kj::WaitScope waitScope(loop);
    368 
    369   int callCount = 0;
    370 
    371   DynamicCapability::Client client1 =
    372       test::TestExtends::Client(kj::heap<TestExtendsImpl>(callCount));
    373   EXPECT_EQ(Schema::from<test::TestExtends>(), client1.getSchema());
    374   EXPECT_NE(Schema::from<test::TestInterface>(), client1.getSchema());
    375 
    376   DynamicCapability::Client client2 = client1.upcast(Schema::from<test::TestInterface>());
    377   EXPECT_EQ(Schema::from<test::TestInterface>(), client2.getSchema());
    378 
    379   EXPECT_ANY_THROW(client2.upcast(Schema::from<test::TestExtends>()));
    380   auto client = client2.castAs<DynamicCapability>(Schema::from<test::TestExtends>());
    381 
    382   auto request1 = client.newRequest("foo");
    383   request1.set("i", 321);
    384   auto promise1 = request1.send();
    385 
    386   auto request2 = client.newRequest("grault");
    387   auto promise2 = request2.send();
    388 
    389   EXPECT_EQ(0, callCount);
    390 
    391   auto response2 = promise2.wait(waitScope);
    392 
    393   checkDynamicTestMessage(response2.as<DynamicStruct>());
    394 
    395   auto response1 = promise1.wait(waitScope);
    396 
    397   EXPECT_EQ("bar", response1.get("x").as<Text>());
    398 
    399   EXPECT_EQ(2, callCount);
    400 }
    401 
    402 TEST(Capability, DynamicClientPipelining) {
    403   kj::EventLoop loop;
    404   kj::WaitScope waitScope(loop);
    405 
    406   int callCount = 0;
    407   int chainedCallCount = 0;
    408   DynamicCapability::Client client =
    409       test::TestPipeline::Client(kj::heap<TestPipelineImpl>(callCount));
    410 
    411   auto request = client.newRequest("getCap");
    412   request.set("n", 234);
    413   request.set("inCap", test::TestInterface::Client(kj::heap<TestInterfaceImpl>(chainedCallCount)));
    414 
    415   auto promise = request.send();
    416 
    417   auto outCap = promise.get("outBox").releaseAs<DynamicStruct>()
    418                        .get("cap").releaseAs<DynamicCapability>();
    419   auto pipelineRequest = outCap.newRequest("foo");
    420   pipelineRequest.set("i", 321);
    421   auto pipelinePromise = pipelineRequest.send();
    422 
    423   auto pipelineRequest2 = outCap.castAs<test::TestExtends>().graultRequest();
    424   auto pipelinePromise2 = pipelineRequest2.send();
    425 
    426   promise = nullptr;  // Just to be annoying, drop the original promise.
    427 
    428   EXPECT_EQ(0, callCount);
    429   EXPECT_EQ(0, chainedCallCount);
    430 
    431   auto response = pipelinePromise.wait(waitScope);
    432   EXPECT_EQ("bar", response.get("x").as<Text>());
    433 
    434   auto response2 = pipelinePromise2.wait(waitScope);
    435   checkTestMessage(response2);
    436 
    437   EXPECT_EQ(3, callCount);
    438   EXPECT_EQ(1, chainedCallCount);
    439 }
    440 
    441 TEST(Capability, DynamicClientPipelineAnyCap) {
    442   kj::EventLoop loop;
    443   kj::WaitScope waitScope(loop);
    444 
    445   int callCount = 0;
    446   int chainedCallCount = 0;
    447   DynamicCapability::Client client =
    448       test::TestPipeline::Client(kj::heap<TestPipelineImpl>(callCount));
    449 
    450   auto request = client.newRequest("getAnyCap");
    451   request.set("n", 234);
    452   request.set("inCap", test::TestInterface::Client(kj::heap<TestInterfaceImpl>(chainedCallCount)));
    453 
    454   auto promise = request.send();
    455 
    456   auto outAnyCap = promise.get("outBox").releaseAs<DynamicStruct>()
    457                           .get("cap").releaseAs<DynamicCapability>();
    458 
    459   EXPECT_EQ(Schema::from<Capability>(), outAnyCap.getSchema());
    460   auto outCap = outAnyCap.castAs<DynamicCapability>(Schema::from<test::TestInterface>());
    461 
    462   auto pipelineRequest = outCap.newRequest("foo");
    463   pipelineRequest.set("i", 321);
    464   auto pipelinePromise = pipelineRequest.send();
    465 
    466   auto pipelineRequest2 = outCap.castAs<test::TestExtends>().graultRequest();
    467   auto pipelinePromise2 = pipelineRequest2.send();
    468 
    469   promise = nullptr;  // Just to be annoying, drop the original promise.
    470 
    471   EXPECT_EQ(0, callCount);
    472   EXPECT_EQ(0, chainedCallCount);
    473 
    474   auto response = pipelinePromise.wait(waitScope);
    475   EXPECT_EQ("bar", response.get("x").as<Text>());
    476 
    477   auto response2 = pipelinePromise2.wait(waitScope);
    478   checkTestMessage(response2);
    479 
    480   EXPECT_EQ(3, callCount);
    481   EXPECT_EQ(1, chainedCallCount);
    482 }
    483 
    484 // =======================================================================================
    485 
    486 class TestInterfaceDynamicImpl final: public DynamicCapability::Server {
    487 public:
    488   TestInterfaceDynamicImpl(int& callCount)
    489       : DynamicCapability::Server(Schema::from<test::TestInterface>()),
    490         callCount(callCount) {}
    491 
    492   int& callCount;
    493 
    494   kj::Promise<void> call(InterfaceSchema::Method method,
    495                          CallContext<DynamicStruct, DynamicStruct> context) {
    496     auto methodName = method.getProto().getName();
    497     if (methodName == "foo") {
    498       ++callCount;
    499       auto params = context.getParams();
    500       EXPECT_EQ(123, params.get("i").as<int>());
    501       EXPECT_TRUE(params.get("j").as<bool>());
    502       context.getResults().set("x", "foo");
    503       return kj::READY_NOW;
    504     } else if (methodName == "baz") {
    505       ++callCount;
    506       auto params = context.getParams();
    507       checkDynamicTestMessage(params.get("s").as<DynamicStruct>());
    508       context.releaseParams();
    509       EXPECT_ANY_THROW(context.getParams());
    510       return kj::READY_NOW;
    511     } else {
    512       KJ_UNIMPLEMENTED("Method not implemented", methodName) { break; }
    513       return kj::READY_NOW;
    514     }
    515   }
    516 };
    517 
    518 TEST(Capability, DynamicServer) {
    519   kj::EventLoop loop;
    520   kj::WaitScope waitScope(loop);
    521 
    522   int callCount = 0;
    523   test::TestInterface::Client client =
    524       DynamicCapability::Client(kj::heap<TestInterfaceDynamicImpl>(callCount))
    525           .castAs<test::TestInterface>();
    526 
    527   auto request1 = client.fooRequest();
    528   request1.setI(123);
    529   request1.setJ(true);
    530   auto promise1 = request1.send();
    531 
    532   auto request2 = client.bazRequest();
    533   initTestMessage(request2.initS());
    534   auto promise2 = request2.send();
    535 
    536   bool barFailed = false;
    537   auto request3 = client.barRequest();
    538   auto promise3 = request3.send().then(
    539       [](Response<test::TestInterface::BarResults>&& response) {
    540         ADD_FAILURE() << "Expected bar() call to fail.";
    541       }, [&](kj::Exception&& e) {
    542         EXPECT_EQ(kj::Exception::Type::UNIMPLEMENTED, e.getType());
    543         barFailed = true;
    544       });
    545 
    546   EXPECT_EQ(0, callCount);
    547 
    548   auto response1 = promise1.wait(waitScope);
    549 
    550   EXPECT_EQ("foo", response1.getX());
    551 
    552   auto response2 = promise2.wait(waitScope);
    553 
    554   promise3.wait(waitScope);
    555 
    556   EXPECT_EQ(2, callCount);
    557   EXPECT_TRUE(barFailed);
    558 }
    559 
    560 class TestExtendsDynamicImpl final: public DynamicCapability::Server {
    561 public:
    562   TestExtendsDynamicImpl(int& callCount)
    563       : DynamicCapability::Server(Schema::from<test::TestExtends>()),
    564         callCount(callCount) {}
    565 
    566   int& callCount;
    567 
    568   kj::Promise<void> call(InterfaceSchema::Method method,
    569                          CallContext<DynamicStruct, DynamicStruct> context) {
    570     auto methodName = method.getProto().getName();
    571     if (methodName == "foo") {
    572       ++callCount;
    573       auto params = context.getParams();
    574       EXPECT_EQ(321, params.get("i").as<int>());
    575       EXPECT_FALSE(params.get("j").as<bool>());
    576       context.getResults().set("x", "bar");
    577       return kj::READY_NOW;
    578     } else if (methodName == "grault") {
    579       ++callCount;
    580       context.releaseParams();
    581       initDynamicTestMessage(context.getResults());
    582       return kj::READY_NOW;
    583     } else {
    584       KJ_FAIL_ASSERT("Method not implemented", methodName);
    585     }
    586   }
    587 };
    588 
    589 TEST(Capability, DynamicServerInheritance) {
    590   kj::EventLoop loop;
    591   kj::WaitScope waitScope(loop);
    592 
    593   int callCount = 0;
    594   test::TestExtends::Client client1 =
    595       DynamicCapability::Client(kj::heap<TestExtendsDynamicImpl>(callCount))
    596           .castAs<test::TestExtends>();
    597   test::TestInterface::Client client2 = client1;
    598   auto client = client2.castAs<test::TestExtends>();
    599 
    600   auto request1 = client.fooRequest();
    601   request1.setI(321);
    602   auto promise1 = request1.send();
    603 
    604   auto request2 = client.graultRequest();
    605   auto promise2 = request2.send();
    606 
    607   EXPECT_EQ(0, callCount);
    608 
    609   auto response2 = promise2.wait(waitScope);
    610 
    611   checkTestMessage(response2);
    612 
    613   auto response1 = promise1.wait(waitScope);
    614 
    615   EXPECT_EQ("bar", response1.getX());
    616 
    617   EXPECT_EQ(2, callCount);
    618 }
    619 
    620 class TestPipelineDynamicImpl final: public DynamicCapability::Server {
    621 public:
    622   TestPipelineDynamicImpl(int& callCount)
    623       : DynamicCapability::Server(Schema::from<test::TestPipeline>()),
    624         callCount(callCount) {}
    625 
    626   int& callCount;
    627 
    628   kj::Promise<void> call(InterfaceSchema::Method method,
    629                          CallContext<DynamicStruct, DynamicStruct> context) {
    630     auto methodName = method.getProto().getName();
    631     if (methodName == "getCap") {
    632       ++callCount;
    633 
    634       auto params = context.getParams();
    635       EXPECT_EQ(234, params.get("n").as<uint32_t>());
    636 
    637       auto cap = params.get("inCap").as<DynamicCapability>();
    638       context.releaseParams();
    639 
    640       auto request = cap.newRequest("foo");
    641       request.set("i", 123);
    642       request.set("j", true);
    643 
    644       return request.send().then(
    645           [this,KJ_CPCAP(context)](capnp::Response<DynamicStruct>&& response) mutable {
    646             EXPECT_EQ("foo", response.get("x").as<Text>());
    647 
    648             auto result = context.getResults();
    649             result.set("s", "bar");
    650 
    651             auto box = result.init("outBox").as<DynamicStruct>();
    652 
    653             // Too lazy to write a whole separate test for each of these cases...  so just make
    654             // sure they both compile here, and only actually test the latter.
    655             box.set("cap", kj::heap<TestExtendsDynamicImpl>(callCount));
    656 #if __GNUG__ && !__clang__ && __GNUG__ == 4 && __GNUC_MINOR__ == 9
    657             // The last line in this block tickles a bug in Debian G++ 4.9.2 that is not present
    658             // in 4.8.x nor in 4.9.4:
    659             //     https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=781060
    660             //
    661             // Unfortunately 4.9.2 is present on many Debian Jessie systems..
    662             //
    663             // For the moment, we can get away with skipping the last line as the previous line
    664             // will set things up in a way that allows the test to complete successfully.
    665             return;
    666 #endif
    667             box.set("cap", kj::heap<TestExtendsImpl>(callCount));
    668           });
    669     } else {
    670       KJ_FAIL_ASSERT("Method not implemented", methodName);
    671     }
    672   }
    673 };
    674 
    675 TEST(Capability, DynamicServerPipelining) {
    676   kj::EventLoop loop;
    677   kj::WaitScope waitScope(loop);
    678 
    679   int callCount = 0;
    680   int chainedCallCount = 0;
    681   test::TestPipeline::Client client =
    682       DynamicCapability::Client(kj::heap<TestPipelineDynamicImpl>(callCount))
    683           .castAs<test::TestPipeline>();
    684 
    685   auto request = client.getCapRequest();
    686   request.setN(234);
    687   request.setInCap(test::TestInterface::Client(kj::heap<TestInterfaceImpl>(chainedCallCount)));
    688 
    689   auto promise = request.send();
    690 
    691   auto pipelineRequest = promise.getOutBox().getCap().fooRequest();
    692   pipelineRequest.setI(321);
    693   auto pipelinePromise = pipelineRequest.send();
    694 
    695   auto pipelineRequest2 = promise.getOutBox().getCap().castAs<test::TestExtends>().graultRequest();
    696   auto pipelinePromise2 = pipelineRequest2.send();
    697 
    698   promise = nullptr;  // Just to be annoying, drop the original promise.
    699 
    700   EXPECT_EQ(0, callCount);
    701   EXPECT_EQ(0, chainedCallCount);
    702 
    703   auto response = pipelinePromise.wait(waitScope);
    704   EXPECT_EQ("bar", response.getX());
    705 
    706   auto response2 = pipelinePromise2.wait(waitScope);
    707   checkTestMessage(response2);
    708 
    709   EXPECT_EQ(3, callCount);
    710   EXPECT_EQ(1, chainedCallCount);
    711 }
    712 
    713 class TestTailCallerDynamicImpl final: public DynamicCapability::Server {
    714 public:
    715   TestTailCallerDynamicImpl(int& callCount)
    716       : DynamicCapability::Server(Schema::from<test::TestTailCaller>()),
    717         callCount(callCount) {}
    718 
    719   int& callCount;
    720 
    721   kj::Promise<void> call(InterfaceSchema::Method method,
    722                          CallContext<DynamicStruct, DynamicStruct> context) {
    723     auto methodName = method.getProto().getName();
    724     if (methodName == "foo") {
    725       ++callCount;
    726 
    727       auto params = context.getParams();
    728       auto tailRequest = params.get("callee").as<DynamicCapability>().newRequest("foo");
    729       tailRequest.set("i", params.get("i"));
    730       tailRequest.set("t", "from TestTailCaller");
    731       return context.tailCall(kj::mv(tailRequest));
    732     } else {
    733       KJ_FAIL_ASSERT("Method not implemented", methodName);
    734     }
    735   }
    736 };
    737 
    738 TEST(Capability, DynamicServerTailCall) {
    739   kj::EventLoop loop;
    740   kj::WaitScope waitScope(loop);
    741 
    742   int calleeCallCount = 0;
    743   int callerCallCount = 0;
    744 
    745   test::TestTailCallee::Client callee(kj::heap<TestTailCalleeImpl>(calleeCallCount));
    746   test::TestTailCaller::Client caller =
    747       DynamicCapability::Client(kj::heap<TestTailCallerDynamicImpl>(callerCallCount))
    748           .castAs<test::TestTailCaller>();
    749 
    750   auto request = caller.fooRequest();
    751   request.setI(456);
    752   request.setCallee(callee);
    753 
    754   auto promise = request.send();
    755 
    756   auto dependentCall0 = promise.getC().getCallSequenceRequest().send();
    757 
    758   auto response = promise.wait(waitScope);
    759   EXPECT_EQ(456, response.getI());
    760   EXPECT_EQ(456, response.getI());
    761 
    762   auto dependentCall1 = promise.getC().getCallSequenceRequest().send();
    763 
    764   auto dependentCall2 = response.getC().getCallSequenceRequest().send();
    765 
    766   EXPECT_EQ(0, dependentCall0.wait(waitScope).getN());
    767   EXPECT_EQ(1, dependentCall1.wait(waitScope).getN());
    768   EXPECT_EQ(2, dependentCall2.wait(waitScope).getN());
    769 
    770   EXPECT_EQ(1, calleeCallCount);
    771   EXPECT_EQ(1, callerCallCount);
    772 }
    773 
    774 // =======================================================================================
    775 
    776 void verifyClient(test::TestInterface::Client client, const int& callCount,
    777                   kj::WaitScope& waitScope) {
    778   int origCount = callCount;
    779   auto request = client.fooRequest();
    780   request.setI(123);
    781   request.setJ(true);
    782   auto response = request.send().wait(waitScope);
    783   EXPECT_EQ("foo", response.getX());
    784   EXPECT_EQ(origCount + 1, callCount);
    785 }
    786 
    787 void verifyClient(DynamicCapability::Client client, const int& callCount,
    788                   kj::WaitScope& waitScope) {
    789   int origCount = callCount;
    790   auto request = client.newRequest("foo");
    791   request.set("i", 123);
    792   request.set("j", true);
    793   auto response = request.send().wait(waitScope);
    794   EXPECT_EQ("foo", response.get("x").as<Text>());
    795   EXPECT_EQ(origCount + 1, callCount);
    796 }
    797 
    798 TEST(Capability, AnyPointersAndOrphans) {
    799   kj::EventLoop loop;
    800   kj::WaitScope waitScope(loop);
    801 
    802   int callCount1 = 0;
    803   int callCount2 = 0;
    804 
    805   // We use a TestPipeline instance here merely as a way to conveniently obtain an imbued message
    806   // instance.
    807   test::TestPipeline::Client baseClient(nullptr);
    808   test::TestInterface::Client client1(kj::heap<TestInterfaceImpl>(callCount1));
    809   test::TestInterface::Client client2(kj::heap<TestInterfaceImpl>(callCount2));
    810 
    811   auto request = baseClient.testPointersRequest();
    812   request.setCap(client1);
    813 
    814   EXPECT_TRUE(request.hasCap());
    815 
    816   Orphan<test::TestInterface> orphan = request.disownCap();
    817   EXPECT_FALSE(orphan == nullptr);
    818 
    819   EXPECT_FALSE(request.hasCap());
    820 
    821   verifyClient(orphan.get(), callCount1, waitScope);
    822   verifyClient(orphan.getReader(), callCount1, waitScope);
    823 
    824   request.getObj().adopt(kj::mv(orphan));
    825   EXPECT_TRUE(orphan == nullptr);
    826 
    827   verifyClient(request.getObj().getAs<test::TestInterface>(), callCount1, waitScope);
    828   verifyClient(request.asReader().getObj().getAs<test::TestInterface>(), callCount1, waitScope);
    829   verifyClient(request.getObj().getAs<DynamicCapability>(
    830       Schema::from<test::TestInterface>()), callCount1, waitScope);
    831   verifyClient(request.asReader().getObj().getAs<DynamicCapability>(
    832       Schema::from<test::TestInterface>()), callCount1, waitScope);
    833 
    834   request.getObj().clear();
    835   EXPECT_FALSE(request.hasObj());
    836 
    837   request.getObj().setAs<test::TestInterface>(client2);
    838   verifyClient(request.getObj().getAs<test::TestInterface>(), callCount2, waitScope);
    839 
    840   Orphan<DynamicCapability> dynamicOrphan = request.getObj().disownAs<DynamicCapability>(
    841       Schema::from<test::TestInterface>());
    842   verifyClient(dynamicOrphan.get(), callCount2, waitScope);
    843   verifyClient(dynamicOrphan.getReader(), callCount2, waitScope);
    844 
    845   Orphan<DynamicValue> dynamicValueOrphan = kj::mv(dynamicOrphan);
    846   verifyClient(dynamicValueOrphan.get().as<DynamicCapability>(), callCount2, waitScope);
    847 
    848   orphan = dynamicValueOrphan.releaseAs<test::TestInterface>();
    849   EXPECT_FALSE(orphan == nullptr);
    850   verifyClient(orphan.get(), callCount2, waitScope);
    851 
    852   request.adoptCap(kj::mv(orphan));
    853   EXPECT_TRUE(orphan == nullptr);
    854 
    855   verifyClient(request.getCap(), callCount2, waitScope);
    856 
    857   Orphan<DynamicCapability> dynamicOrphan2 = request.disownCap();
    858   verifyClient(dynamicOrphan2.get(), callCount2, waitScope);
    859   verifyClient(dynamicOrphan2.getReader(), callCount2, waitScope);
    860 }
    861 
    862 TEST(Capability, Lists) {
    863   kj::EventLoop loop;
    864   kj::WaitScope waitScope(loop);
    865 
    866   int callCount1 = 0;
    867   int callCount2 = 0;
    868   int callCount3 = 0;
    869   test::TestPipeline::Client baseClient(kj::heap<TestPipelineImpl>(callCount1));
    870   test::TestInterface::Client client1(kj::heap<TestInterfaceImpl>(callCount1));
    871   test::TestInterface::Client client2(kj::heap<TestInterfaceImpl>(callCount2));
    872   test::TestInterface::Client client3(kj::heap<TestInterfaceImpl>(callCount3));
    873 
    874   auto request = baseClient.testPointersRequest();
    875 
    876   auto list = request.initList(3);
    877   list.set(0, client1);
    878   list.set(1, client2);
    879   list.set(2, client3);
    880 
    881   verifyClient(list[0], callCount1, waitScope);
    882   verifyClient(list[1], callCount2, waitScope);
    883   verifyClient(list[2], callCount3, waitScope);
    884 
    885   auto listReader = request.asReader().getList();
    886   verifyClient(listReader[0], callCount1, waitScope);
    887   verifyClient(listReader[1], callCount2, waitScope);
    888   verifyClient(listReader[2], callCount3, waitScope);
    889 
    890   auto dynamicList = toDynamic(list);
    891   verifyClient(dynamicList[0].as<DynamicCapability>(), callCount1, waitScope);
    892   verifyClient(dynamicList[1].as<DynamicCapability>(), callCount2, waitScope);
    893   verifyClient(dynamicList[2].as<DynamicCapability>(), callCount3, waitScope);
    894 
    895   auto dynamicListReader = toDynamic(listReader);
    896   verifyClient(dynamicListReader[0].as<DynamicCapability>(), callCount1, waitScope);
    897   verifyClient(dynamicListReader[1].as<DynamicCapability>(), callCount2, waitScope);
    898   verifyClient(dynamicListReader[2].as<DynamicCapability>(), callCount3, waitScope);
    899 }
    900 
    901 TEST(Capability, KeywordMethods) {
    902   // Verify that keywords are only munged where necessary.
    903 
    904   kj::EventLoop loop;
    905   kj::WaitScope waitScope(loop);
    906   bool called = false;
    907 
    908   class TestKeywordMethodsImpl final: public test::TestKeywordMethods::Server {
    909   public:
    910     TestKeywordMethodsImpl(bool& called): called(called) {}
    911 
    912     kj::Promise<void> delete_(DeleteContext context) override {
    913       called = true;
    914       return kj::READY_NOW;
    915     }
    916 
    917   private:
    918     bool& called;
    919   };
    920 
    921   test::TestKeywordMethods::Client client = kj::heap<TestKeywordMethodsImpl>(called);
    922   client.deleteRequest().send().wait(waitScope);
    923 
    924   EXPECT_TRUE(called);
    925 }
    926 
    927 TEST(Capability, Generics) {
    928   kj::EventLoop loop;
    929   kj::WaitScope waitScope(loop);
    930 
    931   typedef test::TestGenerics<TestAllTypes>::Interface<List<uint32_t>> Interface;
    932   Interface::Client client = nullptr;
    933 
    934   auto request = client.callRequest();
    935   request.setBaz("hello");
    936   initTestMessage(request.initInnerBound().initFoo());
    937   initTestMessage(request.initInnerUnbound().getFoo().initAs<TestAllTypes>());
    938 
    939   auto promise = request.send().then([](capnp::Response<Interface::CallResults>&& response) {
    940     // This doesn't actually execute; we're just checking that it compiles.
    941     List<uint32_t>::Reader qux = response.getQux();
    942     qux.size();
    943     checkTestMessage(response.getGen().getFoo());
    944   }, [](kj::Exception&& e) {
    945     // Ignore exception (which we'll always get because we're calling a null capability).
    946   });
    947 
    948   promise.wait(waitScope);
    949 
    950   // Check that asGeneric<>() compiles.
    951   test::TestGenerics<TestAllTypes>::Interface<>::Client castClient = client.asGeneric<>();
    952   test::TestGenerics<TestAllTypes>::Interface<TestAllTypes>::Client castClient2 =
    953       client.asGeneric<TestAllTypes>();
    954   test::TestGenerics<>::Interface<List<uint32_t>>::Client castClient3 = client.asTestGenericsGeneric<>();
    955 }
    956 
    957 TEST(Capability, Generics2) {
    958   MallocMessageBuilder builder;
    959   auto root = builder.getRoot<test::TestUseGenerics>();
    960 
    961   root.initCap().setFoo(test::TestInterface::Client(nullptr));
    962 }
    963 
    964 TEST(Capability, ImplicitParams) {
    965   kj::EventLoop loop;
    966   kj::WaitScope waitScope(loop);
    967 
    968   typedef test::TestImplicitMethodParams Interface;
    969   Interface::Client client = nullptr;
    970 
    971   capnp::Request<Interface::CallParams<Text, TestAllTypes>,
    972                  test::TestGenerics<Text, TestAllTypes>> request =
    973       client.callRequest<Text, TestAllTypes>();
    974   request.setFoo("hello");
    975   initTestMessage(request.initBar());
    976 
    977   auto promise = request.send()
    978       .then([](capnp::Response<test::TestGenerics<Text, TestAllTypes>>&& response) {
    979     // This doesn't actually execute; we're just checking that it compiles.
    980     Text::Reader text = response.getFoo();
    981     text.size();
    982     checkTestMessage(response.getRev().getFoo());
    983   }, [](kj::Exception&& e) {});
    984 
    985   promise.wait(waitScope);
    986 }
    987 
    988 TEST(Capability, CapabilityServerSet) {
    989   kj::EventLoop loop;
    990   kj::WaitScope waitScope(loop);
    991 
    992   CapabilityServerSet<test::TestInterface> set1, set2;
    993 
    994   int callCount = 0;
    995   test::TestInterface::Client clientStandalone(kj::heap<TestInterfaceImpl>(callCount));
    996   test::TestInterface::Client clientNull = nullptr;
    997 
    998   auto ownServer1 = kj::heap<TestInterfaceImpl>(callCount);
    999   auto& server1 = *ownServer1;
   1000   test::TestInterface::Client client1 = set1.add(kj::mv(ownServer1));
   1001 
   1002   auto ownServer2 = kj::heap<TestInterfaceImpl>(callCount);
   1003   auto& server2 = *ownServer2;
   1004   test::TestInterface::Client client2 = set2.add(kj::mv(ownServer2));
   1005 
   1006   // Getting the local server using the correct set works.
   1007   EXPECT_EQ(&server1, &KJ_ASSERT_NONNULL(set1.getLocalServer(client1).wait(waitScope)));
   1008   EXPECT_EQ(&server2, &KJ_ASSERT_NONNULL(set2.getLocalServer(client2).wait(waitScope)));
   1009 
   1010   // Getting the local server using the wrong set doesn't work.
   1011   EXPECT_TRUE(set1.getLocalServer(client2).wait(waitScope) == nullptr);
   1012   EXPECT_TRUE(set2.getLocalServer(client1).wait(waitScope) == nullptr);
   1013   EXPECT_TRUE(set1.getLocalServer(clientStandalone).wait(waitScope) == nullptr);
   1014   EXPECT_TRUE(set1.getLocalServer(clientNull).wait(waitScope) == nullptr);
   1015 
   1016   // A promise client waits to be resolved.
   1017   auto paf = kj::newPromiseAndFulfiller<test::TestInterface::Client>();
   1018   test::TestInterface::Client clientPromise = kj::mv(paf.promise);
   1019 
   1020   auto errorPaf = kj::newPromiseAndFulfiller<test::TestInterface::Client>();
   1021   test::TestInterface::Client errorPromise = kj::mv(errorPaf.promise);
   1022 
   1023   bool resolved1 = false, resolved2 = false, resolved3 = false;
   1024   auto promise1 = set1.getLocalServer(clientPromise)
   1025       .then([&](kj::Maybe<test::TestInterface::Server&> server) {
   1026     resolved1 = true;
   1027     EXPECT_EQ(&server1, &KJ_ASSERT_NONNULL(server));
   1028   });
   1029   auto promise2 = set2.getLocalServer(clientPromise)
   1030       .then([&](kj::Maybe<test::TestInterface::Server&> server) {
   1031     resolved2 = true;
   1032     EXPECT_TRUE(server == nullptr);
   1033   });
   1034   auto promise3 = set1.getLocalServer(errorPromise)
   1035       .then([&](kj::Maybe<test::TestInterface::Server&> server) {
   1036     KJ_FAIL_EXPECT("getLocalServer() on error promise should have thrown");
   1037   }, [&](kj::Exception&& e) {
   1038     resolved3 = true;
   1039     KJ_EXPECT(e.getDescription().endsWith("foo"), e.getDescription());
   1040   });
   1041 
   1042   kj::evalLater([](){}).wait(waitScope);
   1043   kj::evalLater([](){}).wait(waitScope);
   1044   kj::evalLater([](){}).wait(waitScope);
   1045   kj::evalLater([](){}).wait(waitScope);
   1046 
   1047   EXPECT_FALSE(resolved1);
   1048   EXPECT_FALSE(resolved2);
   1049   EXPECT_FALSE(resolved3);
   1050 
   1051   paf.fulfiller->fulfill(kj::cp(client1));
   1052   errorPaf.fulfiller->reject(KJ_EXCEPTION(FAILED, "foo"));
   1053 
   1054   promise1.wait(waitScope);
   1055   promise2.wait(waitScope);
   1056   promise3.wait(waitScope);
   1057 
   1058   EXPECT_TRUE(resolved1);
   1059   EXPECT_TRUE(resolved2);
   1060   EXPECT_TRUE(resolved3);
   1061 }
   1062 
   1063 class TestThisCap final: public test::TestInterface::Server {
   1064 public:
   1065   TestThisCap(int& callCount): callCount(callCount) {}
   1066   ~TestThisCap() noexcept(false) { callCount = -1; }
   1067 
   1068   test::TestInterface::Client getSelf() {
   1069     return thisCap();
   1070   }
   1071 
   1072 protected:
   1073   kj::Promise<void> bar(BarContext context) {
   1074     ++callCount;
   1075     return kj::READY_NOW;
   1076   }
   1077 
   1078 private:
   1079   int& callCount;
   1080 };
   1081 
   1082 TEST(Capability, ThisCap) {
   1083   int callCount = 0;
   1084   kj::EventLoop loop;
   1085   kj::WaitScope waitScope(loop);
   1086 
   1087   auto server = kj::heap<TestThisCap>(callCount);
   1088   TestThisCap* serverPtr = server;
   1089 
   1090   test::TestInterface::Client client = kj::mv(server);
   1091   client.barRequest().send().wait(waitScope);
   1092   EXPECT_EQ(1, callCount);
   1093 
   1094   test::TestInterface::Client client2 = serverPtr->getSelf();
   1095   EXPECT_EQ(1, callCount);
   1096   client2.barRequest().send().wait(waitScope);
   1097   EXPECT_EQ(2, callCount);
   1098 
   1099   client = nullptr;
   1100 
   1101   EXPECT_EQ(2, callCount);
   1102   client2.barRequest().send().wait(waitScope);
   1103   EXPECT_EQ(3, callCount);
   1104 
   1105   client2 = nullptr;
   1106 
   1107   EXPECT_EQ(-1, callCount);
   1108 }
   1109 
   1110 TEST(Capability, TransferCap) {
   1111   kj::EventLoop loop;
   1112   kj::WaitScope waitScope(loop);
   1113 
   1114   MallocMessageBuilder message;
   1115   auto root = message.initRoot<test::TestTransferCap>();
   1116 
   1117   auto orphan = message.getOrphanage().newOrphan<test::TestTransferCap::Element>();
   1118   auto e = orphan.get();
   1119   e.setText("foo");
   1120   e.setCap(KJ_EXCEPTION(FAILED, "whatever"));
   1121 
   1122   root.initList(1).adoptWithCaveats(0, kj::mv(orphan));
   1123 
   1124   // This line used to throw due to capability pointers being incorrectly transferred.
   1125   auto cap = root.getList()[0].getCap();
   1126 
   1127   cap.whenResolved().then([]() {
   1128     KJ_FAIL_EXPECT("didn't throw?");
   1129   }, [](kj::Exception&&) {
   1130     // success
   1131   }).wait(waitScope);
   1132 }
   1133 
   1134 KJ_TEST("Promise<RemotePromise<T>> automatically reduces to RemotePromise<T>") {
   1135   kj::EventLoop loop;
   1136   kj::WaitScope waitScope(loop);
   1137 
   1138   int callCount = 0;
   1139   test::TestInterface::Client client(kj::heap<TestInterfaceImpl>(callCount));
   1140 
   1141   RemotePromise<test::TestInterface::FooResults> promise = kj::evalLater([&]() {
   1142     auto request = client.fooRequest();
   1143     request.setI(123);
   1144     request.setJ(true);
   1145     return request.send();
   1146   });
   1147 
   1148   EXPECT_EQ(0, callCount);
   1149   auto response = promise.wait(waitScope);
   1150   EXPECT_EQ("foo", response.getX());
   1151   EXPECT_EQ(1, callCount);
   1152 }
   1153 
   1154 KJ_TEST("Promise<RemotePromise<T>> automatically reduces to RemotePromise<T> with pipelining") {
   1155   kj::EventLoop loop;
   1156   kj::WaitScope waitScope(loop);
   1157 
   1158   int callCount = 0;
   1159   int chainedCallCount = 0;
   1160   test::TestPipeline::Client client(kj::heap<TestPipelineImpl>(callCount));
   1161 
   1162   auto promise = kj::evalLater([&]() {
   1163     auto request = client.getCapRequest();
   1164     request.setN(234);
   1165     request.setInCap(test::TestInterface::Client(kj::heap<TestInterfaceImpl>(chainedCallCount)));
   1166     return request.send();
   1167   });
   1168 
   1169   auto pipelineRequest = promise.getOutBox().getCap().fooRequest();
   1170   pipelineRequest.setI(321);
   1171   auto pipelinePromise = pipelineRequest.send();
   1172 
   1173   EXPECT_EQ(0, callCount);
   1174   EXPECT_EQ(0, chainedCallCount);
   1175 
   1176   auto response = pipelinePromise.wait(waitScope);
   1177   EXPECT_EQ("bar", response.getX());
   1178 
   1179   EXPECT_EQ(2, callCount);
   1180   EXPECT_EQ(1, chainedCallCount);
   1181 }
   1182 
   1183 KJ_TEST("clone() with caps") {
   1184   int dummy = 0;
   1185   MallocMessageBuilder builder(2048);
   1186   auto root = builder.getRoot<AnyPointer>().initAs<List<test::TestInterface>>(3);
   1187   root.set(0, kj::heap<TestInterfaceImpl>(dummy));
   1188   root.set(1, kj::heap<TestInterfaceImpl>(dummy));
   1189   root.set(2, kj::heap<TestInterfaceImpl>(dummy));
   1190 
   1191   auto copyPtr = clone(root.asReader());
   1192   auto& copy = *copyPtr;
   1193 
   1194   KJ_ASSERT(copy.size() == 3);
   1195   KJ_EXPECT(ClientHook::from(copy[0]).get() == ClientHook::from(root[0]).get());
   1196   KJ_EXPECT(ClientHook::from(copy[1]).get() == ClientHook::from(root[1]).get());
   1197   KJ_EXPECT(ClientHook::from(copy[2]).get() == ClientHook::from(root[2]).get());
   1198 
   1199   KJ_EXPECT(ClientHook::from(copy[0]).get() != ClientHook::from(root[1]).get());
   1200   KJ_EXPECT(ClientHook::from(copy[1]).get() != ClientHook::from(root[2]).get());
   1201   KJ_EXPECT(ClientHook::from(copy[2]).get() != ClientHook::from(root[0]).get());
   1202 }
   1203 
   1204 KJ_TEST("Streaming calls block subsequent calls") {
   1205   kj::EventLoop loop;
   1206   kj::WaitScope waitScope(loop);
   1207 
   1208   auto ownServer = kj::heap<TestStreamingImpl>();
   1209   auto& server = *ownServer;
   1210   test::TestStreaming::Client cap = kj::mv(ownServer);
   1211 
   1212   kj::Promise<void> promise1 = nullptr, promise2 = nullptr, promise3 = nullptr;
   1213 
   1214   {
   1215     auto req = cap.doStreamIRequest();
   1216     req.setI(123);
   1217     promise1 = req.send();
   1218   }
   1219 
   1220   {
   1221     auto req = cap.doStreamJRequest();
   1222     req.setJ(321);
   1223     promise2 = req.send();
   1224   }
   1225 
   1226   {
   1227     auto req = cap.doStreamIRequest();
   1228     req.setI(456);
   1229     promise3 = req.send();
   1230   }
   1231 
   1232   auto promise4 = cap.finishStreamRequest().send();
   1233 
   1234   KJ_EXPECT(server.iSum == 0);
   1235   KJ_EXPECT(server.jSum == 0);
   1236 
   1237   KJ_EXPECT(!promise1.poll(waitScope));
   1238   KJ_EXPECT(!promise2.poll(waitScope));
   1239   KJ_EXPECT(!promise3.poll(waitScope));
   1240   KJ_EXPECT(!promise4.poll(waitScope));
   1241 
   1242   KJ_EXPECT(server.iSum == 123);
   1243   KJ_EXPECT(server.jSum == 0);
   1244 
   1245   KJ_ASSERT_NONNULL(server.fulfiller)->fulfill();
   1246 
   1247   KJ_EXPECT(promise1.poll(waitScope));
   1248   KJ_EXPECT(!promise2.poll(waitScope));
   1249   KJ_EXPECT(!promise3.poll(waitScope));
   1250   KJ_EXPECT(!promise4.poll(waitScope));
   1251 
   1252   KJ_EXPECT(server.iSum == 123);
   1253   KJ_EXPECT(server.jSum == 321);
   1254 
   1255   KJ_ASSERT_NONNULL(server.fulfiller)->fulfill();
   1256 
   1257   KJ_EXPECT(promise1.poll(waitScope));
   1258   KJ_EXPECT(promise2.poll(waitScope));
   1259   KJ_EXPECT(!promise3.poll(waitScope));
   1260   KJ_EXPECT(!promise4.poll(waitScope));
   1261 
   1262   KJ_EXPECT(server.iSum == 579);
   1263   KJ_EXPECT(server.jSum == 321);
   1264 
   1265   KJ_ASSERT_NONNULL(server.fulfiller)->fulfill();
   1266 
   1267   KJ_EXPECT(promise1.poll(waitScope));
   1268   KJ_EXPECT(promise2.poll(waitScope));
   1269   KJ_EXPECT(promise3.poll(waitScope));
   1270   KJ_EXPECT(promise4.poll(waitScope));
   1271 
   1272   auto result = promise4.wait(waitScope);
   1273   KJ_EXPECT(result.getTotalI() == 579);
   1274   KJ_EXPECT(result.getTotalJ() == 321);
   1275 }
   1276 
   1277 KJ_TEST("Streaming calls can be canceled") {
   1278   kj::EventLoop loop;
   1279   kj::WaitScope waitScope(loop);
   1280 
   1281   auto ownServer = kj::heap<TestStreamingImpl>();
   1282   auto& server = *ownServer;
   1283   test::TestStreaming::Client cap = kj::mv(ownServer);
   1284 
   1285   kj::Promise<void> promise1 = nullptr, promise2 = nullptr, promise3 = nullptr;
   1286 
   1287   {
   1288     auto req = cap.doStreamIRequest();
   1289     req.setI(123);
   1290     promise1 = req.send();
   1291   }
   1292 
   1293   {
   1294     auto req = cap.doStreamJRequest();
   1295     req.setJ(321);
   1296     promise2 = req.send();
   1297   }
   1298 
   1299   {
   1300     auto req = cap.doStreamIRequest();
   1301     req.setI(456);
   1302     promise3 = req.send();
   1303   }
   1304 
   1305   auto promise4 = cap.finishStreamRequest().send();
   1306 
   1307   // Cancel the streaming calls.
   1308   promise1 = nullptr;
   1309   promise2 = nullptr;
   1310   promise3 = nullptr;
   1311 
   1312   KJ_EXPECT(server.iSum == 0);
   1313   KJ_EXPECT(server.jSum == 0);
   1314 
   1315   KJ_EXPECT(!promise4.poll(waitScope));
   1316 
   1317   KJ_EXPECT(server.iSum == 123);
   1318   KJ_EXPECT(server.jSum == 0);
   1319 
   1320   KJ_ASSERT_NONNULL(server.fulfiller)->fulfill();
   1321 
   1322   KJ_EXPECT(!promise4.poll(waitScope));
   1323 
   1324   // The call to doStreamJ() opted into cancellation so the next call to doStreamI() happens
   1325   // immediately.
   1326   KJ_EXPECT(server.iSum == 579);
   1327   KJ_EXPECT(server.jSum == 321);
   1328 
   1329   KJ_ASSERT_NONNULL(server.fulfiller)->fulfill();
   1330 
   1331   KJ_EXPECT(promise4.poll(waitScope));
   1332 
   1333   auto result = promise4.wait(waitScope);
   1334   KJ_EXPECT(result.getTotalI() == 579);
   1335   KJ_EXPECT(result.getTotalJ() == 321);
   1336 }
   1337 
   1338 KJ_TEST("Streaming call throwing cascades to following calls") {
   1339   kj::EventLoop loop;
   1340   kj::WaitScope waitScope(loop);
   1341 
   1342   auto ownServer = kj::heap<TestStreamingImpl>();
   1343   auto& server = *ownServer;
   1344   test::TestStreaming::Client cap = kj::mv(ownServer);
   1345 
   1346   server.jShouldThrow = true;
   1347 
   1348   kj::Promise<void> promise1 = nullptr, promise2 = nullptr, promise3 = nullptr;
   1349 
   1350   {
   1351     auto req = cap.doStreamIRequest();
   1352     req.setI(123);
   1353     promise1 = req.send();
   1354   }
   1355 
   1356   {
   1357     auto req = cap.doStreamJRequest();
   1358     req.setJ(321);
   1359     promise2 = req.send();
   1360   }
   1361 
   1362   {
   1363     auto req = cap.doStreamIRequest();
   1364     req.setI(456);
   1365     promise3 = req.send();
   1366   }
   1367 
   1368   auto promise4 = cap.finishStreamRequest().send();
   1369 
   1370   KJ_EXPECT(server.iSum == 0);
   1371   KJ_EXPECT(server.jSum == 0);
   1372 
   1373   KJ_EXPECT(!promise1.poll(waitScope));
   1374   KJ_EXPECT(!promise2.poll(waitScope));
   1375   KJ_EXPECT(!promise3.poll(waitScope));
   1376   KJ_EXPECT(!promise4.poll(waitScope));
   1377 
   1378   KJ_EXPECT(server.iSum == 123);
   1379   KJ_EXPECT(server.jSum == 0);
   1380 
   1381   KJ_ASSERT_NONNULL(server.fulfiller)->fulfill();
   1382 
   1383   KJ_EXPECT(promise1.poll(waitScope));
   1384   KJ_EXPECT(promise2.poll(waitScope));
   1385   KJ_EXPECT(promise3.poll(waitScope));
   1386   KJ_EXPECT(promise4.poll(waitScope));
   1387 
   1388   KJ_EXPECT(server.iSum == 123);
   1389   KJ_EXPECT(server.jSum == 321);
   1390 
   1391   KJ_EXPECT_THROW_RECOVERABLE_MESSAGE("throw requested", promise2.wait(waitScope));
   1392   KJ_EXPECT_THROW_RECOVERABLE_MESSAGE("throw requested", promise3.wait(waitScope));
   1393   KJ_EXPECT_THROW_RECOVERABLE_MESSAGE("throw requested", promise4.ignoreResult().wait(waitScope));
   1394 }
   1395 
   1396 }  // namespace
   1397 }  // namespace _
   1398 }  // namespace capnp