fiber.test.cc revision 13465
113465Sgabeblack@google.com/*
213465Sgabeblack@google.com * Copyright 2018 Google, Inc.
313465Sgabeblack@google.com *
413465Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
513465Sgabeblack@google.com * modification, are permitted provided that the following conditions are
613465Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
713465Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
813465Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
913465Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
1013465Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
1113465Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
1213465Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
1313465Sgabeblack@google.com * this software without specific prior written permission.
1413465Sgabeblack@google.com *
1513465Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1613465Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1713465Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1813465Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1913465Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2013465Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2113465Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2213465Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2313465Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2413465Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2513465Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2613465Sgabeblack@google.com *
2713465Sgabeblack@google.com * Authors: Gabe Black
2813465Sgabeblack@google.com */
2913465Sgabeblack@google.com
3013465Sgabeblack@google.com#include <gtest/gtest.h>
3113465Sgabeblack@google.com
3213465Sgabeblack@google.com#include <initializer_list>
3313465Sgabeblack@google.com#include <iostream>
3413465Sgabeblack@google.com#include <vector>
3513465Sgabeblack@google.com
3613465Sgabeblack@google.com#include "base/fiber.hh"
3713465Sgabeblack@google.com
3813465Sgabeblack@google.comclass TestFiber : public Fiber
3913465Sgabeblack@google.com{
4013465Sgabeblack@google.com  public:
4113465Sgabeblack@google.com    const char *name;
4213465Sgabeblack@google.com    std::vector<Fiber *> next;
4313465Sgabeblack@google.com
4413465Sgabeblack@google.com    TestFiber(const char *name, std::initializer_list<Fiber *> l);
4513465Sgabeblack@google.com
4613465Sgabeblack@google.com    void checkExpected();
4713465Sgabeblack@google.com    void main();
4813465Sgabeblack@google.com};
4913465Sgabeblack@google.com
5013465Sgabeblack@google.comextern TestFiber a;
5113465Sgabeblack@google.comextern TestFiber b;
5213465Sgabeblack@google.comextern TestFiber c;
5313465Sgabeblack@google.com
5413465Sgabeblack@google.comTestFiber a("A", { &b, &a, Fiber::primaryFiber(), &b, &c });
5513465Sgabeblack@google.comTestFiber b("B", { &a, &c });
5613465Sgabeblack@google.comTestFiber c("C", { &a, Fiber::primaryFiber(), Fiber::primaryFiber() });
5713465Sgabeblack@google.com
5813465Sgabeblack@google.comstd::vector<TestFiber *>::iterator expectedIt;
5913465Sgabeblack@google.comstd::vector<TestFiber *> expected({
6013465Sgabeblack@google.com    &a, &b, &a, &a, /* main Fiber, */
6113465Sgabeblack@google.com    &a, &b, &c, &a, &c,
6213465Sgabeblack@google.com    /* main Fiber, */ &c, &c
6313465Sgabeblack@google.com});
6413465Sgabeblack@google.com
6513465Sgabeblack@google.comTestFiber::TestFiber(
6613465Sgabeblack@google.com        const char *name, std::initializer_list<Fiber *> l) :
6713465Sgabeblack@google.com    name(name), next(l)
6813465Sgabeblack@google.com{}
6913465Sgabeblack@google.com
7013465Sgabeblack@google.comvoid
7113465Sgabeblack@google.comTestFiber::checkExpected()
7213465Sgabeblack@google.com{
7313465Sgabeblack@google.com    ASSERT_NE(expectedIt, expected.end());
7413465Sgabeblack@google.com    TestFiber *e = *expectedIt++;
7513465Sgabeblack@google.com    EXPECT_EQ(e, this) << "Expected " << e->name << ", got " << name;
7613465Sgabeblack@google.com}
7713465Sgabeblack@google.com
7813465Sgabeblack@google.comvoid
7913465Sgabeblack@google.comTestFiber::main()
8013465Sgabeblack@google.com{
8113465Sgabeblack@google.com    checkExpected();
8213465Sgabeblack@google.com    for (auto &n : next) {
8313465Sgabeblack@google.com        n->run();
8413465Sgabeblack@google.com        checkExpected();
8513465Sgabeblack@google.com    }
8613465Sgabeblack@google.com}
8713465Sgabeblack@google.com
8813465Sgabeblack@google.comTEST(Fiber, Switching)
8913465Sgabeblack@google.com{
9013465Sgabeblack@google.com    expectedIt = expected.begin();
9113465Sgabeblack@google.com
9213465Sgabeblack@google.com    a.run();
9313465Sgabeblack@google.com    EXPECT_EQ(expectedIt - expected.begin(), 4);
9413465Sgabeblack@google.com
9513465Sgabeblack@google.com    a.run();
9613465Sgabeblack@google.com    EXPECT_EQ(expectedIt - expected.begin(), 9);
9713465Sgabeblack@google.com
9813465Sgabeblack@google.com    c.run();
9913465Sgabeblack@google.com    EXPECT_EQ(expectedIt - expected.begin(), 10);
10013465Sgabeblack@google.com
10113465Sgabeblack@google.com    EXPECT_FALSE(a.finished());
10213465Sgabeblack@google.com    EXPECT_FALSE(b.finished());
10313465Sgabeblack@google.com    EXPECT_FALSE(c.finished());
10413465Sgabeblack@google.com
10513465Sgabeblack@google.com    c.run();
10613465Sgabeblack@google.com    EXPECT_EQ(expected.end(), expectedIt) <<
10713465Sgabeblack@google.com        "Didn't exactly use up the expected Fiber sequence";
10813465Sgabeblack@google.com
10913465Sgabeblack@google.com    EXPECT_TRUE(c.finished());
11013465Sgabeblack@google.com}
11113465Sgabeblack@google.com
11213465Sgabeblack@google.comint currentIndex = 0;
11313465Sgabeblack@google.com
11413465Sgabeblack@google.comclass LinkedFiber : public Fiber
11513465Sgabeblack@google.com{
11613465Sgabeblack@google.com  public:
11713465Sgabeblack@google.com    const int index;
11813465Sgabeblack@google.com    LinkedFiber(Fiber *link, int index) : Fiber(link), index(index) {}
11913465Sgabeblack@google.com
12013465Sgabeblack@google.com    void
12113465Sgabeblack@google.com    main()
12213465Sgabeblack@google.com    {
12313465Sgabeblack@google.com        EXPECT_EQ(currentIndex, index);
12413465Sgabeblack@google.com        currentIndex++;
12513465Sgabeblack@google.com    }
12613465Sgabeblack@google.com};
12713465Sgabeblack@google.com
12813465Sgabeblack@google.comTEST(Fiber, Linked)
12913465Sgabeblack@google.com{
13013465Sgabeblack@google.com    currentIndex = 0;
13113465Sgabeblack@google.com
13213465Sgabeblack@google.com    LinkedFiber lf3(Fiber::primaryFiber(), 3);
13313465Sgabeblack@google.com    LinkedFiber lf2(&lf3, 2);
13413465Sgabeblack@google.com    LinkedFiber lf1(&lf2, 1);
13513465Sgabeblack@google.com    LinkedFiber lf0(&lf1, 0);
13613465Sgabeblack@google.com
13713465Sgabeblack@google.com    lf0.run();
13813465Sgabeblack@google.com
13913465Sgabeblack@google.com    EXPECT_EQ(currentIndex, 4);
14013465Sgabeblack@google.com}
141