/*
 * Copyright 2015 Nest Labs, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <gtest/gtest.h>

#include <string>

#include <folly/futures/Future.h>
#include <folly/futures/Promise.h>
#include <folly/futures/InlineExecutor.h>
#include <folly/futures/ManualExecutor.h>

using namespace folly;

/* If a Cancellation is invoked, the continuation shall not be invoked */
TEST(CancellationFutures, basicOperation) {
    unsigned k0 = 0, k1 = 0;

    {
        /* putting in a block so all destructors are called */
        Promise<unsigned> p0, p1;
        InlineExecutor x;
        Cancellation cx0, cx1;

        auto f0 = p0.getFuture()
            .via(&x, cx0)
            .then([&k0] (unsigned v) { k0 = v; });
        auto f1 = p1.getFuture()
            .via(&x, cx1)
            .then([&k1] (unsigned v) { k1 = v; });

        cx0.cancel();

        p0.setValue(7);
        p1.setValue(9);
    }

    EXPECT_EQ(0, k0); /* cancelled */
    EXPECT_EQ(9, k1); /* not cancelled */
}

/* If a Cancellation is invoked, the continuation shall not be invoked
 * The Cancellation is provided via .then call. Using .then makes the code simpler and clearer:
 *      instead of:
 *          f.via(x, cx).then(a);
 *      use:
 *          f.then(x, cx, a);
 */
TEST(CancellationFutures, Then_basicOperation) {
    unsigned k0 = 0, k1 = 0;

    {
        /* putting in a block so all destructors are called */
        Promise<unsigned> p0, p1;
        InlineExecutor x;
        Cancellation cx0, cx1;

        auto f0 = p0.getFuture()
            .then(&x, cx0, [&k0] (unsigned v) { k0 = v; });
        auto f1 = p1.getFuture()
            .then(&x, cx1, [&k1] (unsigned v) { k1 = v; });

        cx0.cancel();

        p0.setValue(7);
        p1.setValue(9);
    }

    EXPECT_EQ(0, k0); /* cancelled */
    EXPECT_EQ(9, k1); /* not cancelled */
}

/* If a Cancellation is invoked, the continuation shall not be invoked
 * The Cancellation is provided via .thenMultiWithExecutor call.
 * Using .thenMultiWithExecutor makes the code simpler and clearer if callbacks chain is used:
 *      instead of:
 *          f.via(x, cx).then(a).then(b).then(c)
 *      use:
 *          f.thenMultiWithExecutor(x, cx, a, b, c);
 */
TEST(CancellationFutures, thenMulti_basicOperation) {
    unsigned k0 = 0, k1 = 0;

    {
        /* putting in a block so all destructors are called */
        Promise<unsigned> p0, p1;
        InlineExecutor x;
        Cancellation cx0, cx1;

        auto f0 = p0.getFuture()
            .thenMultiWithExecutor(&x, cx0, [&k0] (unsigned v) { k0 = v; });

        auto f1 = p1.getFuture()
            .thenMultiWithExecutor(&x, cx1, [] (unsigned v) { return v; }, [&k1] (unsigned v) { k1 = v; });
        cx0.cancel();

        p0.setValue(7);
        p1.setValue(9);
    }

    EXPECT_EQ(0, k0); /* cancelled */
    EXPECT_EQ(9, k1); /* not cancelled */
}

/* Cancellations may be shared among multiple futures */
TEST(CancellationFutures, sharedCancellations) {
    InlineExecutor exe;
    Cancellation cx0, cx1;
    Promise<unsigned> p00, p01, p02, p03, p04;
    Promise<unsigned> p10, p11, p12, p13, p14;
    auto lam_control = [&] { EXPECT_TRUE(true); };
    auto lam_variable = [&] { EXPECT_TRUE(false); };

    p00.getFuture().via(&exe, cx0).then(lam_control);
    p01.getFuture().via(&exe, cx0).then(lam_control);
    p02.getFuture().via(&exe, cx0).then(lam_control);
    p03.getFuture().via(&exe, cx0).then(lam_control);
    p04.getFuture().via(&exe, cx0).then(lam_control);

    p10.getFuture().via(&exe, cx1).then(lam_variable);
    p11.getFuture().via(&exe, cx1).then(lam_variable);
    p12.getFuture().via(&exe, cx1).then(lam_variable);
    p13.getFuture().via(&exe, cx1).then(lam_variable);
    p14.getFuture().via(&exe, cx1).then(lam_variable);

    cx1.cancel();

    p00.setValue(0);
    p01.setValue(1);
    p02.setValue(2);
    p03.setValue(3);
    p04.setValue(4);
    p10.setValue(5);
    p11.setValue(6);
    p12.setValue(7);
    p13.setValue(8);
    p14.setValue(9);
}

/* Cancellations via .then may be shared among multiple futures */
TEST(CancellationFutures, Then_sharedCancellations) {
    InlineExecutor exe;
    Cancellation cx0, cx1;
    Promise<unsigned> p00, p01;
    Promise<unsigned> p10, p11;
    unsigned k00 = 0, k01 = 0, k10 = 0, k11 = 0;

    p00.getFuture().then(&exe, cx0, [&k00](unsigned v) { k00 = v; });
    p01.getFuture().then(&exe, cx0, [&k01](unsigned v) { k01 = v; });
    p10.getFuture().then(&exe, cx1, [&k10](unsigned v) { k10 = v; });
    p11.getFuture().then(&exe, cx1, [&k11](unsigned v) { k11 = v; });

    cx1.cancel();

    p00.setValue(1);
    p01.setValue(2);
    p10.setValue(8);
    p11.setValue(9);

    EXPECT_EQ(1, k00); /* not cancelled */
    EXPECT_EQ(2, k01); /* not cancelled */
    EXPECT_EQ(0, k10); /* cancelled */
    EXPECT_EQ(0, k11); /* cancelled */
}

/* Cancellations via shall protect a dangling Executor* reference */
TEST(CancellationFutures, danglingExecutorPointer) {
    using std::unique_ptr;
    using std::string;

    unique_ptr<ManualExecutor> x(new ManualExecutor);
    Promise<string> p;
    Cancellation cx;
    string v;

    p.getFuture()
        .via(x.get(), cx)
        .then([&] (string s) { v = s; });

    cx.cancel();
    x.reset();

    p.setValue("foo"); // should not segfault

    EXPECT_EQ("", v);
}

/* Cancellations via .then shall protect a dangling Executor* reference */
TEST(CancellationFutures, Then_danglingExecutorPointer) {
    using std::unique_ptr;
    using std::string;

    unique_ptr<ManualExecutor> x(new ManualExecutor);
    Promise<string> p;
    Cancellation cx;
    string v;

    p.getFuture()
        .then(x.get(), cx, [&] (string s) { v = s; });

    cx.cancel();
    x.reset();

    p.setValue("foo"); // should not segfault

    EXPECT_EQ("", v);
}

/* Cancellations shall prevent continuation from executing, even if scheduled on Executor
 *
 * This tests a specific race condition where a Cancellation is:
 *
 * 1. cancelled /after/ being scheduled on the Executor,
 * 2. protecting some other reference (e.g. Object&),
 * 3. it is cancelled before the Object is deleted, and
 * 4. The executor fires the callback /after/ the Object is deleted.
 *
 * When this happens, the future's continuation should /not/ fire.
 */
TEST(CancellationFutures, cancelAfterExecutorAdd)
{
    ManualExecutor x;
    Promise<int> p;
    Cancellation cx;
    int flag0 = 0;
    int flag1 = 0;
    int val = 0;

    p.getFuture()
        .via(&x, cx)
        .then([&] (int i) {
                sleep(1);
                val = i;
            });

    x.add([&] { flag0 = 1; });
    p.setValue(42);
    x.add([&] { flag1 = 1; });

    cx.cancel();

    size_t cbs = x.run();
    EXPECT_EQ(3, cbs);
    EXPECT_EQ(1, flag0);
    EXPECT_EQ(0, val);
    EXPECT_EQ(1, flag1);
}

/* Cancellations via .then shall prevent continuation from executing, even if scheduled on Executor
 *
 * This tests a specific race condition where a Cancellation is:
 *
 * 1. cancelled /after/ being scheduled on the Executor,
 * 2. protecting some other reference (e.g. Object&),
 * 3. it is cancelled before the Object is deleted, and
 * 4. The executor fires the callback /after/ the Object is deleted.
 *
 * When this happens, the future's continuation should /not/ fire.
 */
TEST(CancellationFutures, Then_cancelAfterExecutorAdd)
{
    ManualExecutor x;
    Promise<int> p;
    Cancellation cx;
    int flag0 = 0;
    int flag1 = 0;
    int val = 0;

    p.getFuture()
        .then(&x, cx, [&] (int i) {
                val = i;
            });

    x.add([&] { flag0 = 1; });
    p.setValue(42);
    x.add([&] { flag1 = 1; });

    cx.cancel();

    size_t cbs = x.run();
    EXPECT_EQ(3, cbs);
    EXPECT_EQ(1, flag0);
    EXPECT_EQ(0, val);
    EXPECT_EQ(1, flag1);
}

/* The cancellation shall not affect futures without a continuation */
TEST(CancellationFutures, withoutContinuation) {
    InlineExecutor exe;
    Cancellation cx;
    Promise<unsigned> p;

    auto f = p.getFuture();
    f.via(&exe, cx);

    cx.cancel();
    p.setValue(15);
    unsigned v = f.get();

    EXPECT_EQ(15, v);
}

/* If a Cancellation is activated, if you still have the future (not
 * destructed), you should still be able to retreive the value even
 * though the continuation will not be invoked.
 *
 * NB: If you're using a continuation, it's bad practice to keep/use a
 * reference to the original future.
 */
TEST(CancellationFutures, withContinuation) {
    InlineExecutor exe;
    Cancellation cx;
    Promise<unsigned> p;
    unsigned k = 0;

    auto f0 = p.getFuture();
    auto f1 = f0.via(&exe, cx).then([&] { ++k; });

    cx.cancel();
    p.setValue(29);

    EXPECT_TRUE(f0.isReady());
    ASSERT_TRUE(f0.hasValue());
    unsigned v = f0.get();

    EXPECT_FALSE(f1.isReady());

    EXPECT_EQ(29, v);
    EXPECT_EQ(0, k);
}

/* If a Cancellation via is activated, if you still have the future (not
 * destructed), you should still be able to retreive the value even
 * though the continuation will not be invoked.
 * The cancellation is provided via .then call.
 *
 * NB: If you're using a continuation, it's bad practice to keep/use a
 * reference to the original future.
 */
TEST(CancellationFutures, Then_withContinuation) {
    InlineExecutor exe;
    Cancellation cx;
    Promise<unsigned> p;
    unsigned k = 0;

    auto f0 = p.getFuture();
    auto f1 = f0.then(&exe, cx, [&] { ++k; });

    cx.cancel();
    p.setValue(29);

    EXPECT_TRUE(f0.isReady());
    ASSERT_TRUE(f0.hasValue());
    unsigned v = f0.get();

    EXPECT_FALSE(f1.isReady());

    EXPECT_EQ(29, v);
    EXPECT_EQ(0, k);
}

/* If a Cancellation is activated, values shall not leak
 */
TEST(CancellationFutures, valueLeakCheck) {
    using std::shared_ptr;

    struct my_value {
        unsigned& ctor_count_;
        unsigned& dtor_count_;

        my_value() = delete;

        my_value(unsigned& ctor, unsigned& dtor) :
            ctor_count_(ctor),
            dtor_count_(dtor)
        {
            ++ctor_count_;
        }

        my_value(const my_value& o) :
            ctor_count_(o.ctor_count_),
            dtor_count_(o.dtor_count_)
        {
            ++ctor_count_;
        }

        my_value(my_value&& o) :
            ctor_count_(o.ctor_count_),
            dtor_count_(o.dtor_count_)
        {
            ++ctor_count_;
        }

        ~my_value()
        {
            ++dtor_count_;
        }
    };

    InlineExecutor exe;
    Cancellation cx;
    unsigned ctors = 0, dtors = 0;

    {
        my_value v(ctors, dtors);
        Promise<my_value> p;

        p.getFuture()
            .via(&exe, cx)
            .then([&] { EXPECT_TRUE(false); });

        cx.cancel();

        p.setValue(v);
    }

    EXPECT_LE(1, ctors);
    EXPECT_LE(1, dtors);
    EXPECT_EQ(ctors, dtors);
}

/* If a Cancellation is activated, values shall not leak
 * The Cancellation is provided via .then call.
 */
TEST(CancellationFutures, Then_valueLeakCheck) {
    using std::shared_ptr;

    struct my_value {
        unsigned& ctor_count_;
        unsigned& dtor_count_;

        my_value() = delete;

        my_value(unsigned& ctor, unsigned& dtor) :
            ctor_count_(ctor),
            dtor_count_(dtor)
        {
            ++ctor_count_;
        }

        my_value(const my_value& o) :
            ctor_count_(o.ctor_count_),
            dtor_count_(o.dtor_count_)
        {
            ++ctor_count_;
        }

        my_value(my_value&& o) :
            ctor_count_(o.ctor_count_),
            dtor_count_(o.dtor_count_)
        {
            ++ctor_count_;
        }

        ~my_value()
        {
            ++dtor_count_;
        }
    };

    InlineExecutor exe;
    Cancellation cx;
    unsigned ctors = 0, dtors = 0;

    {
        my_value v(ctors, dtors);
        Promise<my_value> p;

        p.getFuture()
            .then(&exe, cx, [&] { EXPECT_TRUE(false); });

        cx.cancel();

        p.setValue(v);
    }

    EXPECT_LE(1, ctors);
    EXPECT_LE(1, dtors);
    EXPECT_EQ(ctors, dtors);
}

/* If a Cancellation is activated, exceptions shall not leak
 */
TEST(CancellationFutures, exceptionLeakCheck) {
    struct my_exception : public std::exception {
        unsigned& ctor_count_;
        unsigned& dtor_count_;

        my_exception(unsigned& ctor, unsigned& dtor) :
            std::exception(),
            ctor_count_(ctor),
            dtor_count_(dtor)
        {
            ++ctor_count_;
        }

        my_exception(const my_exception& o) :
            std::exception(o),
            ctor_count_(o.ctor_count_),
            dtor_count_(o.dtor_count_)
        {
            ++ctor_count_;
        }

        my_exception(my_exception&& o) :
            std::exception(o),
            ctor_count_(o.ctor_count_),
            dtor_count_(o.dtor_count_)
        {
            ++ctor_count_;
        }

        ~my_exception()
        {
            ++dtor_count_;
        }
    };

    InlineExecutor exe;
    Cancellation cx;
    unsigned ctors = 0, dtors = 0;

    {
        Promise<unsigned> p;

        p.getFuture()
            .via(&exe, cx)
            .then([&] { EXPECT_TRUE(false); });

        cx.cancel();

        p.setException(my_exception(ctors, dtors));
    }

    EXPECT_LE(1, ctors);
    EXPECT_LE(1, dtors);
    EXPECT_EQ(ctors, dtors);
}

/* If a Cancellation is activated, exceptions shall not leak
 * The Cancellation is provided via .then call
 */
TEST(CancellationFutures, Then_exceptionLeakCheck) {
    struct my_exception : public std::exception {
        unsigned& ctor_count_;
        unsigned& dtor_count_;

        my_exception(unsigned& ctor, unsigned& dtor) :
            std::exception(),
            ctor_count_(ctor),
            dtor_count_(dtor)
        {
            ++ctor_count_;
        }

        my_exception(const my_exception& o) :
            std::exception(o),
            ctor_count_(o.ctor_count_),
            dtor_count_(o.dtor_count_)
        {
            ++ctor_count_;
        }

        my_exception(my_exception&& o) :
            std::exception(o),
            ctor_count_(o.ctor_count_),
            dtor_count_(o.dtor_count_)
        {
            ++ctor_count_;
        }

        ~my_exception()
        {
            ++dtor_count_;
        }
    };

    InlineExecutor exe;
    Cancellation cx;
    unsigned ctors = 0, dtors = 0;

    {
        Promise<unsigned> p;

        p.getFuture()
            .then(&exe, cx, [&] { EXPECT_TRUE(false); });

        cx.cancel();

        p.setException(my_exception(ctors, dtors));
    }

    EXPECT_LE(1, ctors);
    EXPECT_LE(1, dtors);
    EXPECT_EQ(ctors, dtors);
}

/* A simple inline executor that supports cancellations */
class SimpleExecutorWithCancellation : public ExecutorWithCancellation
{
public:
    virtual void add(folly::Func f) {
        f();
    }

    void setCancellation(Cancellation cx) override {
        cx_ = std::move(cx);
    }

    Cancellation& getCancellation() override {
        return cx_;
    }

private:
    Cancellation cx_;
};

/* This is the primary expected use-case, using Executor's implicit cancellation */
TEST(CancellationFutures, executorWithCancellationViaOverrideDefaultCx)
{
    /* code copied from "basicOperation" test */
    unsigned k0 = 0, k1 = 0;

    {
        /* putting in a block so all destructors are called */
        Promise<unsigned> p0, p1;
        SimpleExecutorWithCancellation x;

        auto f0 = p0.getFuture()
            .via(&x)
            .then([&k0] (unsigned v) { k0 = v; });
        auto f1 = p1.getFuture()
            .via(&x)
            .then([&k1] (unsigned v) { k1 = v; });

        x.getCancellation().cancel();

        p0.setValue(7);
        p1.setValue(9);
    }

    EXPECT_EQ(0, k0); /* cancelled */
    EXPECT_EQ(0, k1); /* cancelled */
}

/* Using Executor's implicit cancellation
 * The Cancellation is provided via .then call.
 */
TEST(CancellationFutures, executorWithCancellationThenOverrideDefaultCx)
{
    /* code copied from "basicOperation" test */
    unsigned k0 = 0, k1 = 0;

    {
        /* putting in a block so all destructors are called */
        Promise<unsigned> p0, p1;
        SimpleExecutorWithCancellation x;

        auto f0 = p0.getFuture()
            .then(&x, [&k0] (unsigned v) { k0 = v; });
        auto f1 = p1.getFuture()
            .then(&x, [&k1] (unsigned v) { k1 = v; });

        x.getCancellation().cancel();

        p0.setValue(7);
        p1.setValue(9);
    }

    EXPECT_EQ(0, k0); /* cancelled */
    EXPECT_EQ(0, k1); /* cancelled */
}

/* Using Executor's implicit cancellation
 * The Cancellation is provided via .thenMultiWithExecutor call.
 */
TEST(CancellationFutures, executorWithCancellationThenMultiOverrideDefaultCx)
{
    /* code copied from "basicOperation" test */
    unsigned k0 = 0, k1 = 0;

    {
        /* putting in a block so all destructors are called */
        Promise<unsigned> p0, p1;
        SimpleExecutorWithCancellation x;

        auto f0 = p0.getFuture()
            .thenMultiWithExecutor(&x, [&k0] (unsigned v) { k0 = v; });
        auto f1 = p1.getFuture()
            .thenMultiWithExecutor(&x, [] (unsigned v) { return v; }, [&k1](unsigned v) {k1 = v;});

        x.getCancellation().cancel();

        p0.setValue(7);
        p1.setValue(9);
    }

    EXPECT_EQ(0, k0); /* cancelled */
    EXPECT_EQ(0, k1); /* cancelled */
}

TEST(CancellationFutures, executorWithCancellationViaOverrideExplicitCx)
{
    /* code copied from "basicOperation" test */
    unsigned k0 = 0, k1 = 0;

    {
        /* putting in a block so all destructors are called */
        Promise<unsigned> p0, p1;
        SimpleExecutorWithCancellation x;
        Cancellation cx;

        x.setCancellation(cx);

        auto f0 = p0.getFuture()
            .via(&x)
            .then([&k0] (unsigned v) { k0 = v; });
        auto f1 = p1.getFuture()
            .via(&x, cx)
            .then([&k1] (unsigned v) { k1 = v; });

        x.getCancellation().cancel();
        EXPECT_TRUE(cx.is_cancelled());
        EXPECT_TRUE(x.getCancellation().is_cancelled());

        p0.setValue(7);
        p1.setValue(9);
    }

    EXPECT_EQ(0, k0); /* cancelled */
    EXPECT_EQ(0, k1); /* cancelled */
}

TEST(CancellationFutures, executorWithCancellationThenOverrideExplicitCx)
{
    /* code copied from "basicOperation" test */
    unsigned k0 = 0, k1 = 0;

    {
        /* putting in a block so all destructors are called */
        Promise<unsigned> p0, p1;
        SimpleExecutorWithCancellation x;
        Cancellation cx;

        x.setCancellation(cx);

        auto f0 = p0.getFuture()
            .then(&x, [&k0] (unsigned v) { k0 = v; });
        auto f1 = p1.getFuture()
            .then(&x, cx, [&k1] (unsigned v) { k1 = v; });

        x.getCancellation().cancel();
        EXPECT_TRUE(cx.is_cancelled());
        EXPECT_TRUE(x.getCancellation().is_cancelled());

        p0.setValue(7);
        p1.setValue(9);
    }

    EXPECT_EQ(0, k0); /* cancelled */
    EXPECT_EQ(0, k1); /* cancelled */
}

TEST(CancellationFutures, executorWithCancellationThenMultiOverrideExplicitCx)
{
    /* code copied from "basicOperation" test */
    unsigned k0 = 0, k1 = 0, k2 = 0;

    {
        /* putting in a block so all destructors are called */
        Promise<unsigned> p0, p1, p2;
        SimpleExecutorWithCancellation x;
        Cancellation cx, cx1;

        x.setCancellation(cx);

        auto f0 = p0.getFuture()
            .thenMultiWithExecutor(&x, [&k0] (unsigned v) { k0 = v; });
        auto f1 = p1.getFuture()
            .thenMultiWithExecutor(&x, cx, [&k1] (unsigned v) { k1 = v; });
        auto f2 = p2.getFuture()
            .thenMultiWithExecutor(&x, cx1, [] (unsigned v) { return v; }, [&k2] (unsigned v) {k2=v;});

        x.getCancellation().cancel();
        EXPECT_TRUE(cx.is_cancelled());
        EXPECT_TRUE(x.getCancellation().is_cancelled());

        p0.setValue(7);
        p1.setValue(9);
        p2.setValue(11);
    }

    EXPECT_EQ(0, k0); /* cancelled */
    EXPECT_EQ(0, k1); /* cancelled */
    EXPECT_EQ(11, k2); /* cancelled */
}

/* If e is an ExecutorWithCancellation*, .via(e) should be an alias
 * for .via(e, e.getCancellation()).  If we use .via(e, cx) to use a
 * /different/ cancellation, we should prefer that cancellation.
 */
TEST(CancellationFutures, executorWithCancellationDoesntBreakExplicitCx)
{
    /* code copied from "basicOperation" test */
    unsigned k0 = 0, k1 = 0;

    {
        /* putting in a block so all destructors are called */
        Promise<unsigned> p0, p1;
        SimpleExecutorWithCancellation x;
        Cancellation cx0, cx1;

        x.setCancellation(cx0);

        auto f0 = p0.getFuture()
            .via(&x, cx0)
            .then([&k0] (unsigned v) { k0 = v; });
        auto f1 = p1.getFuture()
            .via(&x, cx1)
            .then([&k1] (unsigned v) { k1 = v; });

        cx0.cancel();

        p0.setValue(7);
        p1.setValue(9);
    }

    EXPECT_EQ(0, k0); /* cancelled */
    EXPECT_EQ(9, k1); /* not cancelled */
}

/* If e is an ExecutorWithCancellation*, .then(e) should be an alias
 * for .then(e, e.getCancellation()).  If we use .then(e, cx) to use a
 * /different/ cancellation, we should prefer that cancellation.
 */
TEST(CancellationFutures, Then_executorWithCancellationDoesntBreakExplicitCx)
{
    /* code copied from "basicOperation" test */
    unsigned k0 = 0, k1 = 0;

    {
        /* putting in a block so all destructors are called */
        Promise<unsigned> p0, p1;
        SimpleExecutorWithCancellation x;
        Cancellation cx0, cx1;

        x.setCancellation(cx0);

        auto f0 = p0.getFuture()
            .then(&x, cx0, [&k0] (unsigned v) { k0 = v; });
        auto f1 = p1.getFuture()
            .then(&x, cx1, [&k1] (unsigned v) { k1 = v; });

        cx0.cancel();

        p0.setValue(7);
        p1.setValue(9);
    }

    EXPECT_EQ(0, k0); /* cancelled */
    EXPECT_EQ(9, k1); /* not cancelled */
}

/* If e is an ExecutorWithCancellation*, .thenMultiWithExecutor(e)
 * should be an alias for .thenMultiWithExecutor(e, e.getCancellation()).
 * If we use .thenMultiWithExecutor(e, cx) to use a /different/
 * cancellation, we should prefer that cancellation.
 */
TEST(CancellationFutures, ThenMulti_executorWithCancellationDoesntBreakExplicitCx)
{
    /* code copied from "basicOperation" test */
    unsigned k0 = 0, k1 = 0;

    {
        /* putting in a block so all destructors are called */
        Promise<unsigned> p0, p1;
        SimpleExecutorWithCancellation x;
        Cancellation cx0, cx1;

        x.setCancellation(cx0);

        auto f0 = p0.getFuture()
            .thenMultiWithExecutor(&x, cx0, [&k0] (unsigned v) { k0 = v; });
        auto f1 = p1.getFuture()
            .thenMultiWithExecutor(&x, cx1, [](unsigned v){return v;}, [&k1] (unsigned v) { k1 = v; });

        cx0.cancel();

        p0.setValue(7);
        p1.setValue(9);
    }

    EXPECT_EQ(0, k0); /* cancelled */
    EXPECT_EQ(9, k1); /* not cancelled */
}
