1 #include "helpers.hpp" 2 #include "utils/dbus_path_utils.hpp" 3 #include "utils/make_id_name.hpp" 4 #include "utils/string_utils.hpp" 5 6 #include <sdbusplus/exception.hpp> 7 8 #include <gmock/gmock.h> 9 10 using namespace testing; 11 using namespace std::literals::string_literals; 12 using namespace utils::string_utils; 13 14 class ScenarioBase : public Test 15 { 16 public: 17 std::string_view defaultName = "defName"; 18 std::vector<std::string> conflicts; 19 }; 20 21 class ScenarioNameProvided : public ScenarioBase 22 { 23 public: 24 auto makeIdName(std::string_view id, std::string_view name) const 25 { 26 return utils::makeIdName(id, name, defaultName, conflicts); 27 } 28 }; 29 30 TEST_F(ScenarioNameProvided, throwsWhenProvidedNameIsTooLong) 31 { 32 EXPECT_THROW(this->makeIdName("", getTooLongName()), 33 sdbusplus::exception::SdBusError); 34 } 35 36 class TestMakeIdNameNameProvided : public ScenarioNameProvided 37 {}; 38 39 TEST_F(TestMakeIdNameNameProvided, usesIdWhenProvided) 40 { 41 const std::string name = "name"; 42 43 EXPECT_THAT(this->makeIdName("id0", name), Eq(std::pair{"id0"s, name})); 44 EXPECT_THAT(this->makeIdName("prefix/id2", name), 45 Eq(std::pair{"prefix/id2"s, name})); 46 } 47 48 TEST_F(TestMakeIdNameNameProvided, usedDefaultWhenNothingProvided) 49 { 50 this->defaultName = "def"; 51 52 EXPECT_THAT(this->makeIdName("", ""), Eq(std::pair{"def"s, "def"s})); 53 EXPECT_THAT(this->makeIdName("abc/", ""), 54 Eq(std::pair{"abc/def"s, "def"s})); 55 } 56 57 TEST_F(TestMakeIdNameNameProvided, usedDefaultWhenNameContainsNoIdChars) 58 { 59 this->defaultName = "def"; 60 const std::string name = " !"; 61 62 EXPECT_THAT(this->makeIdName("", name), Eq(std::pair{"def"s, name})); 63 EXPECT_THAT(this->makeIdName("prefix/", name), 64 Eq(std::pair{"prefix/def"s, name})); 65 } 66 67 class ScenarioNameNotProvided : public ScenarioBase 68 { 69 public: 70 auto makeIdName(std::string_view id, std::string_view name) const 71 { 72 return utils::makeIdName(id, "", name, conflicts); 73 } 74 }; 75 76 class TestMakeIdNameNameNotProvided : public ScenarioNameNotProvided 77 {}; 78 79 TEST_F(TestMakeIdNameNameNotProvided, usesIdAsNameWhenProvided) 80 { 81 EXPECT_THAT(this->makeIdName("id0", defaultName), 82 Eq(std::pair{"id0"s, "id0"s})); 83 EXPECT_THAT(this->makeIdName("prefix/id2", defaultName), 84 Eq(std::pair{"prefix/id2"s, "id2"s})); 85 } 86 87 template <class Scenario> 88 class TestMakeIdName : public Scenario 89 {}; 90 91 using TestScenarios = 92 ::testing::Types<ScenarioNameProvided, ScenarioNameNotProvided>; 93 TYPED_TEST_SUITE(TestMakeIdName, TestScenarios); 94 95 TYPED_TEST(TestMakeIdName, throwsWhenProvidedIdContainsIncorrectCharacters) 96 { 97 EXPECT_THROW(this->makeIdName("Id%@%!@%!%()%fooo/Id", "name"), 98 sdbusplus::exception::SdBusError); 99 EXPECT_THROW(this->makeIdName("Id/Id%@%!@%!%()%fooo", "name"), 100 sdbusplus::exception::SdBusError); 101 EXPECT_THROW(this->makeIdName("/123", "trigger"), 102 sdbusplus::exception::SdBusError); 103 EXPECT_THROW(this->makeIdName("/123/", "trigger"), 104 sdbusplus::exception::SdBusError); 105 } 106 107 TYPED_TEST(TestMakeIdName, throwsWhenProvidedIdContainsTooLongSegment) 108 { 109 std::string longPrefix = getTooLongPrefix(); 110 std::string longSuffix = getTooLongId(); 111 EXPECT_THROW(this->makeIdName(longPrefix + "/", "name"), 112 sdbusplus::exception::SdBusError); 113 EXPECT_THROW(this->makeIdName(longPrefix + "/Id", "name"), 114 sdbusplus::exception::SdBusError); 115 EXPECT_THROW(this->makeIdName(longPrefix + "/" + longSuffix, "name"), 116 sdbusplus::exception::SdBusError); 117 EXPECT_THROW(this->makeIdName("Prefix/" + longSuffix, "name"), 118 sdbusplus::exception::SdBusError); 119 EXPECT_THROW(this->makeIdName(longSuffix, "name"), 120 sdbusplus::exception::SdBusError); 121 } 122 123 TYPED_TEST(TestMakeIdName, throwsWhenProvidedIdOrPrefixTooLong) 124 { 125 EXPECT_THROW(this->makeIdName(getTooLongId(), "name"), 126 sdbusplus::exception::SdBusError); 127 EXPECT_THROW(this->makeIdName(getTooLongPrefix() + "/Id", "name"), 128 sdbusplus::exception::SdBusError); 129 EXPECT_THROW(this->makeIdName("Prefix/" + getTooLongId(), "trigger"), 130 sdbusplus::exception::SdBusError); 131 } 132 133 TYPED_TEST(TestMakeIdName, throwsWhenIdContainsMoreThanOneSlash) 134 { 135 EXPECT_THROW(this->makeIdName("/12/", "name"), 136 sdbusplus::exception::SdBusError); 137 EXPECT_THROW(this->makeIdName("12//", "name"), 138 sdbusplus::exception::SdBusError); 139 EXPECT_THROW(this->makeIdName("12//123", "name"), 140 sdbusplus::exception::SdBusError); 141 EXPECT_THROW(this->makeIdName("12/12/123", "name"), 142 sdbusplus::exception::SdBusError); 143 } 144 145 TYPED_TEST(TestMakeIdName, usesNameWhenThereAreConflicts) 146 { 147 this->conflicts = {"trigger"}; 148 EXPECT_THAT(this->makeIdName("", "trigger"), 149 Eq(std::pair{"trigger0"s, "trigger"s})); 150 151 this->conflicts = {"trigger", "trigger0"}; 152 EXPECT_THAT(this->makeIdName("", "trigger"), 153 Eq(std::pair{"trigger1"s, "trigger"s})); 154 155 this->conflicts = {getMaxId()}; 156 std::string expectedId = getMaxId(); 157 expectedId[expectedId.length() - 1] = '0'; 158 EXPECT_THAT(this->makeIdName("", getMaxId()), 159 Eq(std::pair{expectedId, getMaxId()})); 160 } 161 162 TYPED_TEST(TestMakeIdName, throwsWhenProvidedIdIsTaken) 163 { 164 this->conflicts = {"id", "prefix/id"}; 165 166 EXPECT_THROW(this->makeIdName("id", "name"), 167 sdbusplus::exception::SdBusError); 168 EXPECT_THROW(this->makeIdName("prefix/id", "name"), 169 sdbusplus::exception::SdBusError); 170 } 171 172 TYPED_TEST(TestMakeIdName, usesNameWhenIdNotProvided) 173 { 174 EXPECT_THAT(this->makeIdName("", "name"), Eq(std::pair{"name"s, "name"s})); 175 EXPECT_THAT(this->makeIdName("abc/", "name"), 176 Eq(std::pair{"abc/name"s, "name"s})); 177 EXPECT_THAT(this->makeIdName("123/", "name"), 178 Eq(std::pair{"123/name"s, "name"s})); 179 } 180 181 TYPED_TEST(TestMakeIdName, usesNameWithoutInvalidCharactersWhenIdNotProvided) 182 { 183 EXPECT_THAT(this->makeIdName("", "n#a$/m@e"), 184 Eq(std::pair{"name"s, "n#a$/m@e"s})); 185 EXPECT_THAT(this->makeIdName("", "n!^aŹ/me"), 186 Eq(std::pair{"name"s, "n!^aŹ/me"s})); 187 EXPECT_THAT(this->makeIdName("p/", "n!^aŹ/m*(e"), 188 Eq(std::pair{"p/name"s, "n!^aŹ/m*(e"s})); 189 } 190