16c97b3acSDean Michael Berris //===- llvm/unittest/XRay/GraphTest.cpp - XRay Graph unit tests -*- C++ -*-===//
26c97b3acSDean Michael Berris //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66c97b3acSDean Michael Berris //
76c97b3acSDean Michael Berris //===----------------------------------------------------------------------===//
86c97b3acSDean Michael Berris
96c97b3acSDean Michael Berris #include "llvm/XRay/Graph.h"
106c97b3acSDean Michael Berris #include "gtest/gtest.h"
116c97b3acSDean Michael Berris #include <iostream>
126c97b3acSDean Michael Berris #include <set>
136c97b3acSDean Michael Berris #include <type_traits>
146c97b3acSDean Michael Berris
156c97b3acSDean Michael Berris using namespace llvm;
166c97b3acSDean Michael Berris using namespace xray;
176c97b3acSDean Michael Berris
186c97b3acSDean Michael Berris namespace {
19b5600b58SDean Michael Berris struct VAttr {
206c97b3acSDean Michael Berris unsigned VA;
216c97b3acSDean Michael Berris };
22b5600b58SDean Michael Berris struct EAttr {
236c97b3acSDean Michael Berris unsigned EA;
246c97b3acSDean Michael Berris };
25b5600b58SDean Michael Berris typedef Graph<VAttr, EAttr, unsigned> GraphT;
266c97b3acSDean Michael Berris typedef typename GraphT::VertexIdentifier VI;
276c97b3acSDean Michael Berris typedef typename GraphT::EdgeIdentifier EI;
286c97b3acSDean Michael Berris
296c97b3acSDean Michael Berris // Test Fixture
306c97b3acSDean Michael Berris template <typename T> class GraphTest : public testing::Test {
316c97b3acSDean Michael Berris protected:
326c97b3acSDean Michael Berris T Graph = getTestGraph();
336c97b3acSDean Michael Berris
346c97b3acSDean Michael Berris private:
getTestGraph()356c97b3acSDean Michael Berris static T getTestGraph() {
366c97b3acSDean Michael Berris using std::make_pair;
371bd6123bSJustin Lebar std::remove_const_t<T> G;
38b5600b58SDean Michael Berris G.insert(make_pair(1u, VAttr({3u})));
39b5600b58SDean Michael Berris G.insert(make_pair(2u, VAttr({5u})));
40b5600b58SDean Michael Berris G.insert(make_pair(3u, VAttr({7u})));
41b5600b58SDean Michael Berris G.insert(make_pair(4u, VAttr({11u})));
42b5600b58SDean Michael Berris G.insert(make_pair(5u, VAttr({13u})));
43b5600b58SDean Michael Berris G.insert(make_pair(6u, VAttr({17u})));
446c97b3acSDean Michael Berris
45b5600b58SDean Michael Berris G.insert(std::make_pair(EI(1u, 2u), EAttr({3u * 5u})));
46b5600b58SDean Michael Berris G.insert(std::make_pair(EI(2u, 3u), EAttr({5u * 7u})));
47b5600b58SDean Michael Berris G.insert(std::make_pair(EI(6u, 3u), EAttr({2u * 7u * 17u})));
48b5600b58SDean Michael Berris G.insert(std::make_pair(EI(4u, 6u), EAttr({11u * 17u})));
49b5600b58SDean Michael Berris G.insert(std::make_pair(EI(2u, 4u), EAttr({5u * 11u})));
50b5600b58SDean Michael Berris G.insert(std::make_pair(EI(2u, 5u), EAttr({5u * 13u})));
51b5600b58SDean Michael Berris G.insert(std::make_pair(EI(4u, 5u), EAttr({11u * 13u})));
526c97b3acSDean Michael Berris
536c97b3acSDean Michael Berris return G;
546c97b3acSDean Michael Berris }
556c97b3acSDean Michael Berris };
566c97b3acSDean Michael Berris
576c97b3acSDean Michael Berris typedef ::testing::Types<GraphT, const GraphT> GraphTestTypes;
586c97b3acSDean Michael Berris
596c97b3acSDean Michael Berris using VVT = typename GraphT::VertexValueType;
606c97b3acSDean Michael Berris using EVT = typename GraphT::EdgeValueType;
616c97b3acSDean Michael Berris
62*05de4b41SBenjamin Kramer TYPED_TEST_SUITE(GraphTest, GraphTestTypes, );
636c97b3acSDean Michael Berris
graphVertexTester(T & G)646c97b3acSDean Michael Berris template <typename T> void graphVertexTester(T &G) {
656c97b3acSDean Michael Berris std::set<unsigned> V({1u, 2u, 3u, 4u, 5u, 6u});
666c97b3acSDean Michael Berris std::vector<unsigned> VA({0u, 3u, 5u, 7u, 11u, 13u, 17u});
676c97b3acSDean Michael Berris
686c97b3acSDean Michael Berris EXPECT_EQ(V.size(), G.vertices().size());
696c97b3acSDean Michael Berris EXPECT_FALSE(G.vertices().empty());
706c97b3acSDean Michael Berris for (unsigned u : V) {
716c97b3acSDean Michael Berris auto EVV = G.at(u);
726c97b3acSDean Michael Berris ASSERT_TRUE(!!EVV);
736c97b3acSDean Michael Berris EXPECT_EQ(1u, G.count(u));
746c97b3acSDean Michael Berris EXPECT_EQ(VA[u], EVV->VA);
756c97b3acSDean Michael Berris EXPECT_NE(G.vertices().end(),
766c97b3acSDean Michael Berris std::find_if(G.vertices().begin(), G.vertices().end(),
776c97b3acSDean Michael Berris [&](const VVT &VV) { return VV.first == u; }));
786c97b3acSDean Michael Berris consumeError(EVV.takeError());
796c97b3acSDean Michael Berris }
806c97b3acSDean Michael Berris
816c97b3acSDean Michael Berris for (auto &VVT : G.vertices()) {
826c97b3acSDean Michael Berris EXPECT_EQ(1u, V.count(VVT.first));
836c97b3acSDean Michael Berris EXPECT_EQ(VA[VVT.first], VVT.second.VA);
846c97b3acSDean Michael Berris }
856c97b3acSDean Michael Berris }
866c97b3acSDean Michael Berris
graphEdgeTester(T & G)876c97b3acSDean Michael Berris template <typename T> void graphEdgeTester(T &G) {
886c97b3acSDean Michael Berris std::set<unsigned> V({1u, 2u, 3u, 4u, 5u, 6u});
896c97b3acSDean Michael Berris
906c97b3acSDean Michael Berris std::set<std::pair<unsigned, unsigned>> E(
916c97b3acSDean Michael Berris {{1u, 2u}, {2u, 3u}, {6u, 3u}, {4u, 6u}, {2u, 4u}, {2u, 5u}, {4u, 5u}});
926c97b3acSDean Michael Berris std::vector<unsigned> VA({0u, 3u, 5u, 7u, 11u, 13u, 17u});
936c97b3acSDean Michael Berris
946c97b3acSDean Michael Berris EXPECT_EQ(E.size(), G.edges().size());
956c97b3acSDean Michael Berris EXPECT_FALSE(G.edges().empty());
966c97b3acSDean Michael Berris for (std::pair<unsigned, unsigned> u : E) {
976c97b3acSDean Michael Berris auto EEV = G.at(u);
986c97b3acSDean Michael Berris ASSERT_TRUE(!!EEV);
996c97b3acSDean Michael Berris EXPECT_EQ(1u, G.count(u));
1006c97b3acSDean Michael Berris EXPECT_EQ(VA[u.first] * VA[u.second] * ((u.first > u.second) ? 2 : 1),
1016c97b3acSDean Michael Berris EEV->EA);
1026c97b3acSDean Michael Berris auto Pred = [&](const EVT &EV) { return EV.first == u; };
1036c97b3acSDean Michael Berris EXPECT_NE(G.edges().end(),
1046c97b3acSDean Michael Berris std::find_if(G.edges().begin(), G.edges().end(), Pred));
1056c97b3acSDean Michael Berris consumeError(EEV.takeError());
1066c97b3acSDean Michael Berris }
1076c97b3acSDean Michael Berris
1086c97b3acSDean Michael Berris for (auto &EV : G.edges()) {
1096c97b3acSDean Michael Berris EXPECT_EQ(1u, E.count(EV.first));
1106c97b3acSDean Michael Berris EXPECT_EQ(VA[EV.first.first] * VA[EV.first.second] *
1116c97b3acSDean Michael Berris ((EV.first.first > EV.first.second) ? 2 : 1),
1126c97b3acSDean Michael Berris EV.second.EA);
1136c97b3acSDean Michael Berris const auto &IE = G.inEdges(EV.first.second);
1146c97b3acSDean Michael Berris const auto &OE = G.outEdges(EV.first.first);
1156c97b3acSDean Michael Berris EXPECT_NE(IE.size(), 0u);
1166c97b3acSDean Michael Berris EXPECT_NE(OE.size(), 0u);
1176c97b3acSDean Michael Berris EXPECT_NE(IE.begin(), IE.end());
1186c97b3acSDean Michael Berris EXPECT_NE(OE.begin(), OE.end());
1196c97b3acSDean Michael Berris {
1206c97b3acSDean Michael Berris auto It = std::find_if(
1216c97b3acSDean Michael Berris G.inEdges(EV.first.second).begin(), G.inEdges(EV.first.second).end(),
1226c97b3acSDean Michael Berris [&](const EVT &EVI) { return EVI.first == EV.first; });
1236c97b3acSDean Michael Berris EXPECT_NE(G.inEdges(EV.first.second).end(), It);
1246c97b3acSDean Michael Berris }
1256c97b3acSDean Michael Berris {
1266c97b3acSDean Michael Berris auto It = std::find_if(
1276c97b3acSDean Michael Berris G.inEdges(EV.first.first).begin(), G.inEdges(EV.first.first).end(),
1286c97b3acSDean Michael Berris [&](const EVT &EVI) { return EVI.first == EV.first; });
1296c97b3acSDean Michael Berris EXPECT_EQ(G.inEdges(EV.first.first).end(), It);
1306c97b3acSDean Michael Berris }
1316c97b3acSDean Michael Berris {
1326c97b3acSDean Michael Berris auto It =
1336c97b3acSDean Michael Berris std::find_if(G.outEdges(EV.first.second).begin(),
1346c97b3acSDean Michael Berris G.outEdges(EV.first.second).end(),
1356c97b3acSDean Michael Berris [&](const EVT &EVI) { return EVI.first == EV.first; });
1366c97b3acSDean Michael Berris EXPECT_EQ(G.outEdges(EV.first.second).end(), It);
1376c97b3acSDean Michael Berris }
1386c97b3acSDean Michael Berris {
1396c97b3acSDean Michael Berris auto It = std::find_if(
1406c97b3acSDean Michael Berris G.outEdges(EV.first.first).begin(), G.outEdges(EV.first.first).end(),
1416c97b3acSDean Michael Berris [&](const EVT &EVI) { return EVI.first == EV.first; });
1426c97b3acSDean Michael Berris EXPECT_NE(G.outEdges(EV.first.first).end(), It);
1436c97b3acSDean Michael Berris }
1446c97b3acSDean Michael Berris }
1456c97b3acSDean Michael Berris }
1466c97b3acSDean Michael Berris
TYPED_TEST(GraphTest,TestGraphEdge)1476c97b3acSDean Michael Berris TYPED_TEST(GraphTest, TestGraphEdge) {
1486c97b3acSDean Michael Berris auto &G = this->Graph;
1496c97b3acSDean Michael Berris
1506c97b3acSDean Michael Berris graphEdgeTester(G);
1516c97b3acSDean Michael Berris }
1526c97b3acSDean Michael Berris
TYPED_TEST(GraphTest,TestGraphVertex)1536c97b3acSDean Michael Berris TYPED_TEST(GraphTest, TestGraphVertex) {
1546c97b3acSDean Michael Berris auto &G = this->Graph;
1556c97b3acSDean Michael Berris
1566c97b3acSDean Michael Berris graphVertexTester(G);
1576c97b3acSDean Michael Berris }
1586c97b3acSDean Michael Berris
TYPED_TEST(GraphTest,TestCopyConstructor)1596c97b3acSDean Michael Berris TYPED_TEST(GraphTest, TestCopyConstructor) {
1606c97b3acSDean Michael Berris TypeParam G(this->Graph);
1616c97b3acSDean Michael Berris
1626c97b3acSDean Michael Berris graphEdgeTester(G);
1636c97b3acSDean Michael Berris graphVertexTester(G);
1646c97b3acSDean Michael Berris }
1656c97b3acSDean Michael Berris
TYPED_TEST(GraphTest,TestCopyAssign)1666c97b3acSDean Michael Berris TYPED_TEST(GraphTest, TestCopyAssign) {
1676c97b3acSDean Michael Berris TypeParam G = this->Graph;
1686c97b3acSDean Michael Berris
1696c97b3acSDean Michael Berris graphEdgeTester(G);
1706c97b3acSDean Michael Berris graphVertexTester(G);
1716c97b3acSDean Michael Berris }
1726c97b3acSDean Michael Berris
TYPED_TEST(GraphTest,TestMoveConstructor)1736c97b3acSDean Michael Berris TYPED_TEST(GraphTest, TestMoveConstructor) {
1746c97b3acSDean Michael Berris TypeParam G(std::move(this->Graph));
1756c97b3acSDean Michael Berris
1766c97b3acSDean Michael Berris graphEdgeTester(G);
1776c97b3acSDean Michael Berris graphVertexTester(G);
1786c97b3acSDean Michael Berris }
1796c97b3acSDean Michael Berris
1806c97b3acSDean Michael Berris // Tests the incremental Construction of a graph
TEST(GraphTest,TestConstruction)1816c97b3acSDean Michael Berris TEST(GraphTest, TestConstruction) {
1826c97b3acSDean Michael Berris GraphT MG;
1836c97b3acSDean Michael Berris const GraphT &G = MG;
1846c97b3acSDean Michael Berris EXPECT_EQ(0u, G.count(0u));
1856c97b3acSDean Michael Berris EXPECT_EQ(0u, G.count({0u, 1u}));
1866c97b3acSDean Michael Berris auto VE = G.at(0);
1876c97b3acSDean Michael Berris auto EE = G.at({0, 0});
1886c97b3acSDean Michael Berris EXPECT_FALSE(VE); // G.at[0] returns an error
1896c97b3acSDean Michael Berris EXPECT_FALSE(EE); // G.at[{0,0}] returns an error
1906c97b3acSDean Michael Berris consumeError(VE.takeError());
1916c97b3acSDean Michael Berris consumeError(EE.takeError());
1926c97b3acSDean Michael Berris EXPECT_TRUE(G.vertices().empty());
1936c97b3acSDean Michael Berris EXPECT_TRUE(G.edges().empty());
1946c97b3acSDean Michael Berris EXPECT_EQ(G.vertices().begin(), G.vertices().end());
1956c97b3acSDean Michael Berris EXPECT_EQ(G.edges().begin(), G.edges().end());
1966c97b3acSDean Michael Berris }
1976c97b3acSDean Michael Berris
TEST(GraphTest,TestiVertexAccessOperator)1986c97b3acSDean Michael Berris TEST(GraphTest, TestiVertexAccessOperator) {
1996c97b3acSDean Michael Berris GraphT MG;
2006c97b3acSDean Michael Berris const GraphT &G = MG;
2016c97b3acSDean Michael Berris
2026c97b3acSDean Michael Berris MG[0u] = {1u};
2036c97b3acSDean Michael Berris EXPECT_EQ(1u, MG[0u].VA);
2046c97b3acSDean Michael Berris EXPECT_EQ(1u, G.count(0u));
2056c97b3acSDean Michael Berris EXPECT_EQ(0u, G.count(1u));
2066c97b3acSDean Michael Berris EXPECT_EQ(1u, MG[0u].VA);
2076c97b3acSDean Michael Berris auto T = G.at(0u);
2086c97b3acSDean Michael Berris EXPECT_TRUE(!!T);
2096c97b3acSDean Michael Berris EXPECT_EQ(1u, T->VA);
2106c97b3acSDean Michael Berris
2116c97b3acSDean Michael Berris EXPECT_EQ(1u, G.vertices().size());
2126c97b3acSDean Michael Berris EXPECT_EQ(0u, G.edges().size());
2136c97b3acSDean Michael Berris EXPECT_FALSE(G.vertices().empty());
2146c97b3acSDean Michael Berris EXPECT_TRUE(G.edges().empty());
2156c97b3acSDean Michael Berris EXPECT_NE(G.vertices().begin(), G.vertices().end());
2166c97b3acSDean Michael Berris EXPECT_EQ(G.edges().begin(), G.edges().end());
2176c97b3acSDean Michael Berris EXPECT_EQ(1u, G.vertices().begin()->second.VA);
2186c97b3acSDean Michael Berris EXPECT_EQ(0u, G.vertices().begin()->first);
2196c97b3acSDean Michael Berris EXPECT_EQ(0u, G.outEdges(0u).size());
2206c97b3acSDean Michael Berris EXPECT_TRUE(G.outEdges(0u).empty());
2216c97b3acSDean Michael Berris EXPECT_EQ(G.outEdges(0u).begin(), G.outEdges(0u).end());
2226c97b3acSDean Michael Berris EXPECT_EQ(0u, G.inEdges(0u).size());
2236c97b3acSDean Michael Berris EXPECT_TRUE(G.inEdges(0u).empty());
2246c97b3acSDean Michael Berris EXPECT_EQ(G.inEdges(0u).begin(), G.inEdges(0u).end());
2256c97b3acSDean Michael Berris }
2266c97b3acSDean Michael Berris
TEST(GraphTest,TestEdgeAccessOperator)2276c97b3acSDean Michael Berris TEST(GraphTest, TestEdgeAccessOperator) {
2286c97b3acSDean Michael Berris GraphT MG;
2296c97b3acSDean Michael Berris const GraphT &G = MG;
2306c97b3acSDean Michael Berris
2316c97b3acSDean Michael Berris MG[{0u, 0u}] = {2u};
2326c97b3acSDean Michael Berris EI EdgeIdent({0u, 0u});
2336c97b3acSDean Michael Berris EXPECT_EQ(2u, MG[EdgeIdent].EA);
2346c97b3acSDean Michael Berris EXPECT_EQ(1u, G.count({0u, 0u}));
2356c97b3acSDean Michael Berris EXPECT_EQ(0u, G.count({0u, 1u}));
2366c97b3acSDean Michael Berris EXPECT_EQ(1u, G.count(0u));
2376c97b3acSDean Michael Berris EXPECT_NE(1u, G.count(1u));
2386c97b3acSDean Michael Berris auto T = G.at({0u, 0u});
2396c97b3acSDean Michael Berris EXPECT_TRUE(T && T->EA == 2u);
2406c97b3acSDean Michael Berris EXPECT_EQ(1u, G.edges().size());
2416c97b3acSDean Michael Berris EXPECT_EQ(1u, G.vertices().size());
2426c97b3acSDean Michael Berris EXPECT_FALSE(G.edges().empty());
2436c97b3acSDean Michael Berris EXPECT_FALSE(G.vertices().empty());
2446c97b3acSDean Michael Berris EXPECT_NE(G.edges().begin(), G.edges().end());
2456c97b3acSDean Michael Berris EXPECT_EQ(EI(0u, 0u), G.edges().begin()->first);
2466c97b3acSDean Michael Berris EXPECT_EQ(2u, G.edges().begin()->second.EA);
2476c97b3acSDean Michael Berris EXPECT_EQ(1u, G.outEdges(0u).size());
2486c97b3acSDean Michael Berris EXPECT_FALSE(G.outEdges(0u).empty());
2496c97b3acSDean Michael Berris EXPECT_NE(G.outEdges(0u).begin(), G.outEdges(0u).end());
2506c97b3acSDean Michael Berris EXPECT_EQ(EI(0u, 0u), G.outEdges(0u).begin()->first);
2516c97b3acSDean Michael Berris EXPECT_EQ(2u, G.outEdges(0u).begin()->second.EA);
2526c97b3acSDean Michael Berris EXPECT_EQ(++(G.outEdges(0u).begin()), G.outEdges(0u).end());
2536c97b3acSDean Michael Berris EXPECT_EQ(1u, G.inEdges(0u).size());
2546c97b3acSDean Michael Berris EXPECT_FALSE(G.inEdges(0u).empty());
2556c97b3acSDean Michael Berris EXPECT_NE(G.inEdges(0u).begin(), G.inEdges(0u).end());
2566c97b3acSDean Michael Berris EXPECT_EQ(EI(0u, 0u), G.inEdges(0u).begin()->first);
2576c97b3acSDean Michael Berris EXPECT_EQ(2u, G.inEdges(0u).begin()->second.EA);
2586c97b3acSDean Michael Berris EXPECT_EQ(++(G.inEdges(0u).begin()), G.inEdges(0u).end());
2596c97b3acSDean Michael Berris }
2606c97b3acSDean Michael Berris }
261