199e66a03SMatt Spinler #include "association_manager.hpp"
299e66a03SMatt Spinler 
399e66a03SMatt Spinler #include <filesystem>
499e66a03SMatt Spinler #include <fstream>
599e66a03SMatt Spinler 
699e66a03SMatt Spinler #include <gtest/gtest.h>
799e66a03SMatt Spinler 
899e66a03SMatt Spinler using namespace phosphor::inventory::manager::associations;
999e66a03SMatt Spinler namespace fs = std::filesystem;
1099e66a03SMatt Spinler 
1199e66a03SMatt Spinler static const auto goodJson = R"(
1299e66a03SMatt Spinler [
1399e66a03SMatt Spinler     {
1499e66a03SMatt Spinler         "path": "system/PS0",
1599e66a03SMatt Spinler         "endpoints":
1699e66a03SMatt Spinler         [
1799e66a03SMatt Spinler             {
1899e66a03SMatt Spinler                 "types":
1999e66a03SMatt Spinler                 {
2099e66a03SMatt Spinler                     "rType": "inventory",
2199e66a03SMatt Spinler                     "fType": "sensors"
2299e66a03SMatt Spinler                 },
2399e66a03SMatt Spinler                 "paths":
2499e66a03SMatt Spinler                 [
2599e66a03SMatt Spinler                     "power/ps0_input_power",
2699e66a03SMatt Spinler                     "voltage/ps0_input_voltage",
2799e66a03SMatt Spinler                     "current/ps0_output_current",
2899e66a03SMatt Spinler                     "voltage/ps0_output_voltage"
2999e66a03SMatt Spinler                 ]
3099e66a03SMatt Spinler             },
3199e66a03SMatt Spinler             {
3299e66a03SMatt Spinler                 "types":
3399e66a03SMatt Spinler                 {
3499e66a03SMatt Spinler                     "rType": "inventory",
3599e66a03SMatt Spinler                     "fType": "fans"
3699e66a03SMatt Spinler                 },
3799e66a03SMatt Spinler                 "paths":
3899e66a03SMatt Spinler                 [
3999e66a03SMatt Spinler                     "fan_tach/ps0_fan"
4099e66a03SMatt Spinler                 ]
4199e66a03SMatt Spinler             }
4299e66a03SMatt Spinler         ]
4399e66a03SMatt Spinler     },
4499e66a03SMatt Spinler     {
4599e66a03SMatt Spinler         "path": "system/fan42",
4699e66a03SMatt Spinler         "endpoints":
4799e66a03SMatt Spinler         [
4899e66a03SMatt Spinler             {
4999e66a03SMatt Spinler                 "types":
5099e66a03SMatt Spinler                 {
5199e66a03SMatt Spinler                     "rType": "inventory",
5299e66a03SMatt Spinler                     "fType": "sensors"
5399e66a03SMatt Spinler                 },
5499e66a03SMatt Spinler                 "paths":
5599e66a03SMatt Spinler                 [
5699e66a03SMatt Spinler                     "fan_tach/fan42"
5799e66a03SMatt Spinler                 ]
5899e66a03SMatt Spinler             },
5999e66a03SMatt Spinler             {
6099e66a03SMatt Spinler                 "types":
6199e66a03SMatt Spinler                 {
6299e66a03SMatt Spinler                     "rType": "inventory",
6399e66a03SMatt Spinler                     "fType": "led"
6499e66a03SMatt Spinler                 },
6599e66a03SMatt Spinler                 "paths":
6699e66a03SMatt Spinler                 [
6799e66a03SMatt Spinler                     "led/fan42"
6899e66a03SMatt Spinler                 ]
6999e66a03SMatt Spinler             }
7099e66a03SMatt Spinler         ]
7199e66a03SMatt Spinler     }
7299e66a03SMatt Spinler ])";
7399e66a03SMatt Spinler 
7499e66a03SMatt Spinler // Malformed JSON
7599e66a03SMatt Spinler static const auto badJson0 = R"(
7699e66a03SMatt Spinler     "hello": world
7799e66a03SMatt Spinler })";
7899e66a03SMatt Spinler 
7999e66a03SMatt Spinler // Uses 'blah' instead of 'paths'
8099e66a03SMatt Spinler static const auto badJson1 = R"(
8199e66a03SMatt Spinler [
8299e66a03SMatt Spinler     {
8399e66a03SMatt Spinler         "blah": "system/PS0",
8499e66a03SMatt Spinler         "endpoints":
8599e66a03SMatt Spinler         [
8699e66a03SMatt Spinler             {
8799e66a03SMatt Spinler                 "types":
8899e66a03SMatt Spinler                 {
8999e66a03SMatt Spinler                     "fType": "inventory",
9099e66a03SMatt Spinler                     "rType": "sensors"
9199e66a03SMatt Spinler                 },
9299e66a03SMatt Spinler                 "paths":
9399e66a03SMatt Spinler                 [
9499e66a03SMatt Spinler                     "ps0_input_power",
9599e66a03SMatt Spinler                 ]
9699e66a03SMatt Spinler             }
9799e66a03SMatt Spinler         ]
9899e66a03SMatt Spinler     }
9999e66a03SMatt Spinler ])";
10099e66a03SMatt Spinler 
10199e66a03SMatt Spinler // Uses 'blah' instead of 'rType'
10299e66a03SMatt Spinler static const auto badJson2 = R"(
10399e66a03SMatt Spinler [
10499e66a03SMatt Spinler     {
10599e66a03SMatt Spinler         "paths": "system/PS0",
10699e66a03SMatt Spinler         "endpoints":
10799e66a03SMatt Spinler         [
10899e66a03SMatt Spinler             {
10999e66a03SMatt Spinler                 "types":
11099e66a03SMatt Spinler                 {
11199e66a03SMatt Spinler                     "blah": "inventory",
11299e66a03SMatt Spinler                     "fType": "sensors"
11399e66a03SMatt Spinler                 },
11499e66a03SMatt Spinler                 "paths":
11599e66a03SMatt Spinler                 [
11699e66a03SMatt Spinler                     "ps0_input_power",
11799e66a03SMatt Spinler                 ]
11899e66a03SMatt Spinler             }
11999e66a03SMatt Spinler         ]
12099e66a03SMatt Spinler     }
12199e66a03SMatt Spinler ])";
12299e66a03SMatt Spinler 
12399e66a03SMatt Spinler // Missing the endpoints/paths array
12499e66a03SMatt Spinler static const auto badJson3 = R"(
12599e66a03SMatt Spinler [
12699e66a03SMatt Spinler     {
12799e66a03SMatt Spinler         "paths": "system/PS0",
12899e66a03SMatt Spinler         "endpoints":
12999e66a03SMatt Spinler         [
13099e66a03SMatt Spinler             {
13199e66a03SMatt Spinler                 "types":
13299e66a03SMatt Spinler                 {
13399e66a03SMatt Spinler                     "rType": "inventory",
13499e66a03SMatt Spinler                     "fType": "sensors"
13599e66a03SMatt Spinler                 }
13699e66a03SMatt Spinler             }
13799e66a03SMatt Spinler         ]
13899e66a03SMatt Spinler     }
13999e66a03SMatt Spinler ])";
14099e66a03SMatt Spinler 
14199e66a03SMatt Spinler class AssocsTest : public ::testing::Test
14299e66a03SMatt Spinler {
14399e66a03SMatt Spinler   protected:
AssocsTest()144*7edafe06SPatrick Williams     AssocsTest() : ::testing::Test(), bus(sdbusplus::bus::new_default()) {}
14599e66a03SMatt Spinler 
14699e66a03SMatt Spinler     fs::path jsonDir;
147563306f6SPatrick Williams     sdbusplus::bus_t bus;
14899e66a03SMatt Spinler 
SetUp()14999e66a03SMatt Spinler     virtual void SetUp()
15099e66a03SMatt Spinler     {
15199e66a03SMatt Spinler         char dir[] = {"assocTestXXXXXX"};
15299e66a03SMatt Spinler         jsonDir = mkdtemp(dir);
15399e66a03SMatt Spinler     }
15499e66a03SMatt Spinler 
TearDown()15599e66a03SMatt Spinler     virtual void TearDown()
15699e66a03SMatt Spinler     {
15799e66a03SMatt Spinler         fs::remove_all(jsonDir);
15899e66a03SMatt Spinler     }
15999e66a03SMatt Spinler 
writeFile(const char * data)16099e66a03SMatt Spinler     std::string writeFile(const char* data)
16199e66a03SMatt Spinler     {
16299e66a03SMatt Spinler         fs::path path = jsonDir / "associations.json";
16399e66a03SMatt Spinler 
16499e66a03SMatt Spinler         std::ofstream f{path};
16599e66a03SMatt Spinler         f << data;
16699e66a03SMatt Spinler         f.close();
16799e66a03SMatt Spinler 
16899e66a03SMatt Spinler         return path;
16999e66a03SMatt Spinler     }
17099e66a03SMatt Spinler };
17199e66a03SMatt Spinler 
TEST_F(AssocsTest,TEST_NO_JSON)17299e66a03SMatt Spinler TEST_F(AssocsTest, TEST_NO_JSON)
17399e66a03SMatt Spinler {
17499e66a03SMatt Spinler     try
17599e66a03SMatt Spinler     {
17699e66a03SMatt Spinler         Manager m{bus};
17799e66a03SMatt Spinler         EXPECT_TRUE(false);
17899e66a03SMatt Spinler     }
1793e2d9641SPatrick Williams     catch (const std::exception& e)
180a83db30eSBrad Bishop     {}
18199e66a03SMatt Spinler }
18299e66a03SMatt Spinler 
TEST_F(AssocsTest,TEST_GOOD_JSON)18399e66a03SMatt Spinler TEST_F(AssocsTest, TEST_GOOD_JSON)
18499e66a03SMatt Spinler {
18599e66a03SMatt Spinler     auto path = writeFile(goodJson);
18699e66a03SMatt Spinler     Manager m(bus, path);
18799e66a03SMatt Spinler 
18899e66a03SMatt Spinler     const auto& a = m.getAssociationsConfig();
18999e66a03SMatt Spinler     EXPECT_EQ(a.size(), 2);
19099e66a03SMatt Spinler 
19199e66a03SMatt Spinler     {
19299e66a03SMatt Spinler         auto x = a.find("/xyz/openbmc_project/inventory/system/PS0");
19399e66a03SMatt Spinler         EXPECT_NE(x, a.end());
19499e66a03SMatt Spinler 
19599e66a03SMatt Spinler         auto& endpoints = x->second;
19699e66a03SMatt Spinler         EXPECT_EQ(endpoints.size(), 2);
19799e66a03SMatt Spinler 
19899e66a03SMatt Spinler         {
19999e66a03SMatt Spinler             auto& types = std::get<0>(endpoints[0]);
20099e66a03SMatt Spinler             EXPECT_EQ(std::get<0>(types), "sensors");
20199e66a03SMatt Spinler             EXPECT_EQ(std::get<1>(types), "inventory");
20299e66a03SMatt Spinler 
20399e66a03SMatt Spinler             auto& paths = std::get<1>(endpoints[0]);
20499e66a03SMatt Spinler             EXPECT_EQ(paths.size(), 4);
20599e66a03SMatt Spinler         }
20699e66a03SMatt Spinler         {
20799e66a03SMatt Spinler             auto& types = std::get<0>(endpoints[1]);
20899e66a03SMatt Spinler             EXPECT_EQ(std::get<0>(types), "fans");
20999e66a03SMatt Spinler             EXPECT_EQ(std::get<1>(types), "inventory");
21099e66a03SMatt Spinler 
21199e66a03SMatt Spinler             auto& paths = std::get<1>(endpoints[1]);
21299e66a03SMatt Spinler             EXPECT_EQ(paths.size(), 1);
21399e66a03SMatt Spinler         }
21499e66a03SMatt Spinler     }
21599e66a03SMatt Spinler     {
21699e66a03SMatt Spinler         auto x = a.find("/xyz/openbmc_project/inventory/system/fan42");
21799e66a03SMatt Spinler         EXPECT_NE(x, a.end());
21899e66a03SMatt Spinler 
21999e66a03SMatt Spinler         auto& endpoints = x->second;
22099e66a03SMatt Spinler         EXPECT_EQ(endpoints.size(), 2);
22199e66a03SMatt Spinler 
22299e66a03SMatt Spinler         {
22399e66a03SMatt Spinler             auto& types = std::get<0>(endpoints[0]);
22499e66a03SMatt Spinler             EXPECT_EQ(std::get<0>(types), "sensors");
22599e66a03SMatt Spinler             EXPECT_EQ(std::get<1>(types), "inventory");
22699e66a03SMatt Spinler 
22799e66a03SMatt Spinler             auto& paths = std::get<1>(endpoints[0]);
22899e66a03SMatt Spinler             EXPECT_EQ(paths.size(), 1);
22999e66a03SMatt Spinler         }
23099e66a03SMatt Spinler         {
23199e66a03SMatt Spinler             auto& types = std::get<0>(endpoints[1]);
23299e66a03SMatt Spinler             EXPECT_EQ(std::get<0>(types), "led");
23399e66a03SMatt Spinler             EXPECT_EQ(std::get<1>(types), "inventory");
23499e66a03SMatt Spinler 
23599e66a03SMatt Spinler             auto& paths = std::get<1>(endpoints[1]);
23699e66a03SMatt Spinler             EXPECT_EQ(paths.size(), 1);
23799e66a03SMatt Spinler         }
23899e66a03SMatt Spinler     }
23999e66a03SMatt Spinler }
24099e66a03SMatt Spinler 
TEST_F(AssocsTest,TEST_BAD_JSON0)24199e66a03SMatt Spinler TEST_F(AssocsTest, TEST_BAD_JSON0)
24299e66a03SMatt Spinler {
24399e66a03SMatt Spinler     auto path = writeFile(badJson0);
24499e66a03SMatt Spinler 
24599e66a03SMatt Spinler     try
24699e66a03SMatt Spinler     {
24799e66a03SMatt Spinler         Manager m(bus, path);
24899e66a03SMatt Spinler 
24999e66a03SMatt Spinler         EXPECT_TRUE(false);
25099e66a03SMatt Spinler     }
2513e2d9641SPatrick Williams     catch (const std::exception& e)
252a83db30eSBrad Bishop     {}
25399e66a03SMatt Spinler }
25499e66a03SMatt Spinler 
TEST_F(AssocsTest,TEST_BAD_JSON1)25599e66a03SMatt Spinler TEST_F(AssocsTest, TEST_BAD_JSON1)
25699e66a03SMatt Spinler {
25799e66a03SMatt Spinler     auto path = writeFile(badJson1);
25899e66a03SMatt Spinler 
25999e66a03SMatt Spinler     try
26099e66a03SMatt Spinler     {
26199e66a03SMatt Spinler         Manager m(bus, path);
26299e66a03SMatt Spinler 
26399e66a03SMatt Spinler         EXPECT_TRUE(false);
26499e66a03SMatt Spinler     }
2653e2d9641SPatrick Williams     catch (const std::exception& e)
266a83db30eSBrad Bishop     {}
26799e66a03SMatt Spinler }
26899e66a03SMatt Spinler 
TEST_F(AssocsTest,TEST_BAD_JSON2)26999e66a03SMatt Spinler TEST_F(AssocsTest, TEST_BAD_JSON2)
27099e66a03SMatt Spinler {
27199e66a03SMatt Spinler     auto path = writeFile(badJson2);
27299e66a03SMatt Spinler 
27399e66a03SMatt Spinler     try
27499e66a03SMatt Spinler     {
27599e66a03SMatt Spinler         Manager m(bus, path);
27699e66a03SMatt Spinler 
27799e66a03SMatt Spinler         EXPECT_TRUE(false);
27899e66a03SMatt Spinler     }
2793e2d9641SPatrick Williams     catch (const std::exception& e)
280a83db30eSBrad Bishop     {}
28199e66a03SMatt Spinler }
28299e66a03SMatt Spinler 
TEST_F(AssocsTest,TEST_BAD_JSON3)28399e66a03SMatt Spinler TEST_F(AssocsTest, TEST_BAD_JSON3)
28499e66a03SMatt Spinler {
28599e66a03SMatt Spinler     auto path = writeFile(badJson3);
28699e66a03SMatt Spinler 
28799e66a03SMatt Spinler     try
28899e66a03SMatt Spinler     {
28999e66a03SMatt Spinler         Manager m(bus, path);
29099e66a03SMatt Spinler 
29199e66a03SMatt Spinler         EXPECT_TRUE(false);
29299e66a03SMatt Spinler     }
2933e2d9641SPatrick Williams     catch (const std::exception& e)
294a83db30eSBrad Bishop     {}
29599e66a03SMatt Spinler }
296