/** * Copyright © 2018 IBM Corporation * * 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 "policy_find.hpp" #include "policy_table.hpp" #include #include #include using namespace ibm::logging; namespace fs = std::experimental::filesystem; static constexpr auto json = R"( [ { "dtls":[ { "CEID":"ABCD1234", "mod":"", "msg":"Error ABCD1234" } ], "err":"xyz.openbmc_project.Error.Test1" }, { "dtls":[ { "CEID":"XYZ222", "mod":"", "msg":"Error XYZ222" } ], "err":"xyz.openbmc_project.Error.Test2" }, { "dtls":[ { "CEID":"AAAAAA", "mod":"mod1", "msg":"Error AAAAAA" }, { "CEID":"BBBBBB", "mod":"mod2", "msg":"Error BBBBBB" }, { "CEID":"CCCCCC", "mod":"mod3", "msg":"Error CCCCCC" } ], "err":"xyz.openbmc_project.Error.Test3" }, { "dtls":[ { "CEID":"DDDDDDDD", "mod":"I2C", "msg":"Error DDDDDDDD" }, { "CEID":"EEEEEEEE", "mod":"FSI", "msg":"Error EEEEEEEE" } ], "err":"xyz.openbmc_project.Error.Test4" }, { "dtls":[ { "CEID":"FFFFFFFF", "mod":"6D", "msg":"Error FFFFFFFF" } ], "err":"xyz.openbmc_project.Error.Test5" }, { "dtls":[ { "CEID":"GGGGGGGG", "mod":"RAIL_5", "msg":"Error GGGGGGGG" } ], "err":"xyz.openbmc_project.Error.Test6" }, { "dtls":[ { "CEID":"HHHHHHHH", "mod":"INPUT_42", "msg":"Error HHHHHHHH" } ], "err":"xyz.openbmc_project.Error.Test7" } ])"; /** * Helper class to write the above json to a file and then * remove it when the tests are over. */ class PolicyTableTest : public ::testing::Test { protected: virtual void SetUp() { char dir[] = {"./jsonTestXXXXXX"}; jsonDir = mkdtemp(dir); jsonFile = jsonDir / "policy.json"; std::ofstream f{jsonFile}; f << json; } virtual void TearDown() { fs::remove_all(jsonDir); } fs::path jsonDir; fs::path jsonFile; }; /** * Test finding entries in the policy table */ TEST_F(PolicyTableTest, TestTable) { policy::Table policy{jsonFile}; ASSERT_EQ(policy.isLoaded(), true); //////////////////////////////////// // Basic search, no modifier std::string err{"xyz.openbmc_project.Error.Test2"}; std::string mod; auto details = policy.find(err, mod); ASSERT_EQ(static_cast(details), true); if (details) { ASSERT_EQ((*details).get().ceid, "XYZ222"); ASSERT_EQ((*details).get().msg, "Error XYZ222"); } ///////////////////////////////////// // Not found err = "foo"; details = policy.find(err, mod); ASSERT_EQ(static_cast(details), false); ///////////////////////////////////// // Test with a modifier err = "xyz.openbmc_project.Error.Test3"; mod = "mod3"; details = policy.find(err, mod); ASSERT_EQ(static_cast(details), true); if (details) { ASSERT_EQ((*details).get().ceid, "CCCCCC"); ASSERT_EQ((*details).get().msg, "Error CCCCCC"); } } /** * Test policy::find() that uses the data from a property * map to find entries in the policy table. */ TEST_F(PolicyTableTest, TestFinder) { using namespace std::literals::string_literals; policy::Table policy{jsonFile}; ASSERT_EQ(policy.isLoaded(), true); // A basic search with no modifier { DbusPropertyMap testProperties{ {"Message"s, Value{"xyz.openbmc_project.Error.Test1"s}}}; auto values = policy::find(policy, testProperties); ASSERT_EQ(std::get(values), "ABCD1234"); ASSERT_EQ(std::get(values), "Error ABCD1234"); } // Use CALLOUT_INVENTORY_PATH from the AdditionalData property { std::vector ad{"FOO=BAR"s, "CALLOUT_INVENTORY_PATH=mod2"s}; DbusPropertyMap testProperties{ {"Message"s, Value{"xyz.openbmc_project.Error.Test3"s}}, {"AdditionalData"s, ad}}; auto values = policy::find(policy, testProperties); ASSERT_EQ(std::get(values), "BBBBBB"); ASSERT_EQ(std::get(values), "Error BBBBBB"); } // Use an I2C DEVICE_PATH from the AdditionalData property { std::vector ad{"FOO=BAR"s, "CALLOUT_DEVICE_PATH=/some/i2c/path"s}; DbusPropertyMap testProperties{ {"Message"s, Value{"xyz.openbmc_project.Error.Test4"s}}, {"AdditionalData"s, ad}}; auto values = policy::find(policy, testProperties); ASSERT_EQ(std::get(values), "DDDDDDDD"); ASSERT_EQ(std::get(values), "Error DDDDDDDD"); } // Use an FSI DEVICE_PATH from the AdditionalData property { std::vector ad{"FOO=BAR"s, "CALLOUT_DEVICE_PATH=/some/fsi/path"s}; DbusPropertyMap testProperties{ {"Message"s, Value{"xyz.openbmc_project.Error.Test4"s}}, {"AdditionalData"s, ad}}; auto values = policy::find(policy, testProperties); ASSERT_EQ(std::get(values), "EEEEEEEE"); ASSERT_EQ(std::get(values), "Error EEEEEEEE"); } // Use PROCEDURE from the AdditionalData property { std::vector ad{"FOO=BAR"s, "PROCEDURE=109"s}; DbusPropertyMap testProperties{ {"Message"s, Value{"xyz.openbmc_project.Error.Test5"s}}, {"AdditionalData"s, ad}}; auto values = policy::find(policy, testProperties); ASSERT_EQ(std::get(values), "FFFFFFFF"); ASSERT_EQ(std::get(values), "Error FFFFFFFF"); } // Use RAIL_NAME from the AdditionalData property { std::vector ad{"FOO=BAR"s, "RAIL_NAME=RAIL_5"s}; DbusPropertyMap testProperties{ {"Message"s, Value{"xyz.openbmc_project.Error.Test6"s}}, {"AdditionalData"s, ad}}; auto values = policy::find(policy, testProperties); ASSERT_EQ(std::get(values), "GGGGGGGG"); ASSERT_EQ(std::get(values), "Error GGGGGGGG"); } // Use INPUT_NAME from the AdditionalData property { std::vector ad{"FOO=BAR"s, "INPUT_NAME=INPUT_42"s}; DbusPropertyMap testProperties{ {"Message"s, Value{"xyz.openbmc_project.Error.Test7"s}}, {"AdditionalData"s, ad}}; auto values = policy::find(policy, testProperties); ASSERT_EQ(std::get(values), "HHHHHHHH"); ASSERT_EQ(std::get(values), "Error HHHHHHHH"); } // Test not finding an entry. { DbusPropertyMap testProperties{{"Message"s, Value{"hello world"s}}}; auto values = policy::find(policy, testProperties); ASSERT_EQ(std::get(values), policy.defaultEID()); ASSERT_EQ(std::get(values), policy.defaultMsg()); } // Test that strange AdditionalData values don't break anything { std::vector ad{"FOO"s, "INPUT_NAME="s}; DbusPropertyMap testProperties{ {"Message"s, Value{"xyz.openbmc_project.Error.Test7"s}}, {"AdditionalData"s, ad}}; auto values = policy::find(policy, testProperties); ASSERT_EQ(std::get(values), policy.defaultEID()); ASSERT_EQ(std::get(values), policy.defaultMsg()); } }