1 /* 2 * Copyright (c) Huawei Technologies Co., Ltd. 2018-2020. All rights reserved. 3 * Description: 实现CPPTest的flag标识设置 4 */ 5 6 #include "gtest/hwext/gtest-tag.h" 7 #include "gtest/hwext/gtest-utils.h" 8 9 namespace testing { 10 namespace ext { 11 12 const TestSizeSet TestSize; 13 const TypeSet G_TYPE; 14 const SizeSet G_SIZE; 15 const RankSet G_RANK; 16 const int G_TESTSIZESHIFT = 24; 17 const int G_TYPESHIFT = 8; 18 const int G_SIZESHIFT = 4; 19 TestFlag(const char * n,const char * d,int m)20 TestFlag::TestFlag(const char* n, const char* d, int m) : name(n), desc(d), mask(m) 21 { 22 eleCount = 0; 23 } 24 element(const char * desc,int hex)25 void TestFlag::element(const char* desc, int hex) 26 { 27 elementMap.insert(pair<int, const char* const>(hex, desc)); 28 } 29 printHelp(const char ** indents) const30 void TestFlag::printHelp(const char** indents) const 31 { 32 map<int, const char*>::const_iterator c_iter; 33 int i = 0; 34 printf("%s--gtest_%s=(", indents[0], naming()); 35 for (c_iter = elementMap.begin(); c_iter != elementMap.end(); c_iter++) { 36 printf("%s%s", (i > 0) ? "|" : "", c_iter->second); 37 i++; 38 } 39 printf(")\n"); 40 printf("%s%s\n", indents[1], description()); 41 } 42 verify(int hex,char * err) const43 bool TestFlag::verify(int hex, char* err) const 44 { 45 // wipe bits not belong to this set 46 int masked = hex&mask; 47 48 map<int, const char*>::const_iterator c_iter; 49 for (c_iter = elementMap.begin(); c_iter != elementMap.end(); c_iter++) { 50 // wipe each bit defined in this set 51 masked &= ~c_iter->first; 52 } 53 54 // masked!=0 means find undefined bit(s) 55 const bool nice = masked == 0; 56 if (!nice&&err != NULL) { 57 sprintf(err, "Illegal %s value '0x%08x'\n", naming(), hex); 58 } 59 60 return nice; 61 } 62 eleForName(const char * name,int & result) const63 bool TestFlag::eleForName(const char* name, int& result) const 64 { 65 if (name == NULL) { 66 // NOTE:: strlen(NULL) will cause seg fault 67 return false; 68 } 69 70 const int result_raw = result; 71 // must set to 0 here, because we will do bit-OR arithmetic later 72 result = 0; 73 // the parameter 'name' may contatin more than one element 74 const char* kCandidateSeps = ",;|/"; 75 char name_cpoy[256]; 76 memset(name_cpoy, 0, 256); 77 memcpy(name_cpoy, name, strlen(name)); 78 79 char * pch; 80 pch = strtok(name_cpoy, kCandidateSeps); 81 while (pch != NULL) 82 { 83 map<int, const char*>::const_iterator c_iter; 84 bool matched = false; 85 // try to matchNaming all the elements 86 for (c_iter = elementMap.begin(); c_iter != elementMap.end(); c_iter++) { 87 const char* ele_name = c_iter->second; 88 const string ele_full_name_string = string(naming()) + "." + ele_name; 89 if (compareStringsByIgnoreCase(pch, ele_name) || compareStringsByIgnoreCase(pch, ele_full_name_string.c_str())) { 90 // set this bit 91 result |= c_iter->first; 92 matched = true; 93 break; 94 } 95 } 96 if (!matched) { 97 fprintf(stderr, "Unrecognized %s value '%s'\n", naming(), pch); 98 // abort the matching, recover result to raw value 99 result = result_raw; 100 return false; 101 } 102 pch = strtok(NULL, kCandidateSeps); 103 } 104 return true; 105 } 106 TestSizeSet()107 TestSizeSet::TestSizeSet() : TestFlag ("testsize", "Select tests by test level hint.", 0xff << G_TESTSIZESHIFT) 108 { 109 element("Level0", Level0); 110 element("Level1", Level1); 111 element("Level2", Level2); 112 element("Level3", Level3); 113 element("Level4", Level4); 114 } 115 TypeSet()116 TypeSet::TypeSet() : TestFlag ("type", "Select testcase by type hint.", 0x0f << G_TYPESHIFT) 117 { 118 element("Function", function); 119 element("Performance", performance); 120 element("Power", power); 121 element("Reliability", reliability); 122 element("Security", security); 123 element("Global", global); 124 element("Compatibility", compatibility); 125 element("User", user); 126 element("Standard", standard); 127 element("Safety", safety); 128 element("Resilience", resilience); 129 } 130 131 SizeSet()132 SizeSet::SizeSet() : TestFlag ("size", "Select testcase by size hint.", 0x0f << G_SIZESHIFT) 133 { 134 element("SmallTest", smallTest); 135 element("MediumTest", mediumTest); 136 element("LargeTest", largeTest); 137 } 138 139 RankSet()140 RankSet::RankSet() : TestFlag("rank", "Select testcase by rank hint.", 0x0f) 141 { 142 element("Level0", level0); 143 element("Level1", level1); 144 element("Level2", level2); 145 element("Level3", level3); 146 element("Level4", level4); 147 } 148 149 static std::vector<const TestFlag*> sets; 150 ensureSetsInit()151 static void ensureSetsInit() { 152 if (sets.size() > 0) { 153 return; 154 } 155 sets.push_back(&TestSize); 156 sets.push_back(&G_TYPE); 157 sets.push_back(&G_SIZE); 158 sets.push_back(&G_RANK); 159 } 160 AllHextTagSets()161 const std::vector<const TestFlag*>& AllHextTagSets() 162 { 163 ensureSetsInit(); 164 return sets; 165 } 166 CheckFlagsLegality(int flags)167 bool CheckFlagsLegality(int flags) 168 { 169 ensureSetsInit(); 170 char buf[256]; 171 for (unsigned int i = 0; i < sets.size(); i++) 172 { 173 const TestFlag* set = sets.at(i); 174 memset(buf, 0, 256); 175 if (!set->verify(flags, buf)) { 176 return false; 177 } 178 } 179 return true; 180 } 181 flagForName(const char * set_name,const char * ele_name,int & result)182 bool flagForName(const char* set_name, const char* ele_name, int& result) { 183 ensureSetsInit(); 184 for (unsigned int i = 0; i < sets.size(); i++) 185 { 186 const TestFlag* set = sets.at(i); 187 if (!compareStringsByIgnoreCase(set_name, set->naming())) { 188 continue; 189 } 190 return set->eleForName(ele_name, result); 191 } 192 fprintf(stderr, "Unrecognized flagset '%s'\n", set_name); 193 return false; 194 } 195 196 } // namespace ext 197 } // namespace testing