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 errors::InvalidArgument); 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 errors::InvalidArgument); 99 EXPECT_THROW(this->makeIdName("Id/Id%@%!@%!%()%fooo", "name"), 100 errors::InvalidArgument); 101 EXPECT_THROW(this->makeIdName("/123", "trigger"), errors::InvalidArgument); 102 EXPECT_THROW(this->makeIdName("/123/", "trigger"), errors::InvalidArgument); 103 } 104 105 TYPED_TEST(TestMakeIdName, throwsWhenProvidedIdContainsTooLongSegment) 106 { 107 std::string longPrefix = getTooLongPrefix(); 108 std::string longSuffix = getTooLongId(); 109 EXPECT_THROW(this->makeIdName(longPrefix + "/", "name"), 110 errors::InvalidArgument); 111 EXPECT_THROW(this->makeIdName(longPrefix + "/Id", "name"), 112 errors::InvalidArgument); 113 EXPECT_THROW(this->makeIdName(longPrefix + "/" + longSuffix, "name"), 114 errors::InvalidArgument); 115 EXPECT_THROW(this->makeIdName("Prefix/" + longSuffix, "name"), 116 errors::InvalidArgument); 117 EXPECT_THROW(this->makeIdName(longSuffix, "name"), errors::InvalidArgument); 118 } 119 120 TYPED_TEST(TestMakeIdName, throwsWhenProvidedIdOrPrefixTooLong) 121 { 122 EXPECT_THROW(this->makeIdName(getTooLongId(), "name"), 123 errors::InvalidArgument); 124 EXPECT_THROW(this->makeIdName(getTooLongPrefix() + "/Id", "name"), 125 errors::InvalidArgument); 126 EXPECT_THROW(this->makeIdName("Prefix/" + getTooLongId(), "trigger"), 127 errors::InvalidArgument); 128 } 129 130 TYPED_TEST(TestMakeIdName, throwsWhenIdContainsMoreThanOneSlash) 131 { 132 EXPECT_THROW(this->makeIdName("/12/", "name"), errors::InvalidArgument); 133 EXPECT_THROW(this->makeIdName("12//", "name"), errors::InvalidArgument); 134 EXPECT_THROW(this->makeIdName("12//123", "name"), errors::InvalidArgument); 135 EXPECT_THROW(this->makeIdName("12/12/123", "name"), 136 errors::InvalidArgument); 137 } 138 139 TYPED_TEST(TestMakeIdName, usesNameWhenThereAreConflicts) 140 { 141 this->conflicts = {"trigger"}; 142 EXPECT_THAT(this->makeIdName("", "trigger"), 143 Eq(std::pair{"trigger0"s, "trigger"s})); 144 145 this->conflicts = {"trigger", "trigger0"}; 146 EXPECT_THAT(this->makeIdName("", "trigger"), 147 Eq(std::pair{"trigger1"s, "trigger"s})); 148 149 this->conflicts = {getMaxId()}; 150 std::string expectedId = getMaxId(); 151 expectedId[expectedId.length() - 1] = '0'; 152 EXPECT_THAT(this->makeIdName("", getMaxId()), 153 Eq(std::pair{expectedId, getMaxId()})); 154 } 155 156 TYPED_TEST(TestMakeIdName, throwsWhenProvidedIdIsTaken) 157 { 158 this->conflicts = {"id", "prefix/id"}; 159 160 EXPECT_THROW(this->makeIdName("id", "name"), 161 sdbusplus::exception::SdBusError); 162 EXPECT_THROW(this->makeIdName("prefix/id", "name"), 163 sdbusplus::exception::SdBusError); 164 } 165 166 TYPED_TEST(TestMakeIdName, usesNameWhenIdNotProvided) 167 { 168 EXPECT_THAT(this->makeIdName("", "name"), Eq(std::pair{"name"s, "name"s})); 169 EXPECT_THAT(this->makeIdName("abc/", "name"), 170 Eq(std::pair{"abc/name"s, "name"s})); 171 EXPECT_THAT(this->makeIdName("123/", "name"), 172 Eq(std::pair{"123/name"s, "name"s})); 173 } 174 175 TYPED_TEST(TestMakeIdName, usesNameWithoutInvalidCharactersWhenIdNotProvided) 176 { 177 EXPECT_THAT(this->makeIdName("", "n#a$/m@e"), 178 Eq(std::pair{"name"s, "n#a$/m@e"s})); 179 EXPECT_THAT(this->makeIdName("", "n!^aŹ/me"), 180 Eq(std::pair{"name"s, "n!^aŹ/me"s})); 181 EXPECT_THAT(this->makeIdName("p/", "n!^aŹ/m*(e"), 182 Eq(std::pair{"p/name"s, "n!^aŹ/m*(e"s})); 183 } 184