PageRenderTime 27ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/suite/audio_quality/lib/src/task/TaskCase.cpp

https://gitlab.com/chprasanna93/platform_cts
C++ | 361 lines | 306 code | 34 blank | 21 comment | 58 complexity | 03d94998676bbc6f8c4331df19f3b0f4 MD5 | raw file
  1. /*
  2. * Copyright (C) 2012 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. #include <sys/types.h>
  17. #include <regex.h>
  18. #include <stdlib.h>
  19. #include <stdio.h>
  20. #include "Log.h"
  21. #include "audio/RemoteAudio.h"
  22. #include "ClientImpl.h"
  23. #include "Report.h"
  24. #include "Settings.h"
  25. #include "StringUtil.h"
  26. #include "task/TaskCase.h"
  27. static const android::String8 STR_NAME("name");
  28. static const android::String8 STR_VERSION("version");
  29. static const android::String8 STR_DESCRIPTION("description");
  30. TaskCase::TaskCase()
  31. : TaskGeneric(TaskGeneric::ETaskCase),
  32. mClient(NULL)
  33. {
  34. const android::String8* list[] = {&STR_NAME, &STR_VERSION, &STR_DESCRIPTION, NULL};
  35. registerSupportedStringAttributes(list);
  36. }
  37. TaskCase::~TaskCase()
  38. {
  39. delete mClient;
  40. }
  41. bool TaskCase::getCaseName(android::String8& name) const
  42. {
  43. if (!findStringAttribute(STR_NAME, name)) {
  44. LOGW("TaskCase no name");
  45. return false;
  46. }
  47. return true;
  48. }
  49. bool TaskCase::addChild(TaskGeneric* child)
  50. {
  51. if ((child->getType() != TaskGeneric::ETaskSetup)
  52. && (child->getType() != TaskGeneric::ETaskAction)
  53. && (child->getType() != TaskGeneric::ETaskSave)) {
  54. LOGE("TestCase::addChild wrong child type %d", child->getType());
  55. return false;
  56. }
  57. return TaskGeneric::addChild(child);
  58. }
  59. template <typename T> bool registerGeneric(
  60. typename std::map<android::String8, T>& map,
  61. const android::String8& name, T& data)
  62. {
  63. typename std::map<android::String8, T>::iterator it;
  64. it = map.find(name);
  65. if (it != map.end()) {
  66. LOGV("registerGeneric key %s already registered", name.string());
  67. return false;
  68. }
  69. LOGD("registerGeneric registered key %s", name.string());
  70. map[name] = data;
  71. return true;
  72. }
  73. template <typename T> bool findGeneric(typename std::map<android::String8, T>& map,
  74. const android::String8& name, T& data)
  75. {
  76. LOGD("findGeneric key %s", name.string());
  77. typename std::map<android::String8, T>::iterator it;
  78. it = map.find(name);
  79. if (it == map.end()) {
  80. return false;
  81. }
  82. data = it->second;
  83. return true;
  84. }
  85. template <typename T> bool updateGeneric(typename std::map<android::String8, T>& map,
  86. const android::String8& name, T& data)
  87. {
  88. LOGD("updateGeneric key %s", name.string());
  89. typename std::map<android::String8, T>::iterator it;
  90. it = map.find(name);
  91. if (it == map.end()) {
  92. return false;
  93. }
  94. it->second = data;
  95. return true;
  96. }
  97. // return all the matches for the given regular expression.
  98. // name string and the data itself is copied.
  99. template <typename T> typename std::list<std::pair<android::String8, T> >* findAllGeneric(
  100. typename std::map<android::String8, T>& map, const char* re)
  101. {
  102. regex_t regex;
  103. if (regcomp(&regex, re, REG_EXTENDED | REG_NOSUB) != 0) {
  104. LOGE("regcomp failed");
  105. return NULL;
  106. }
  107. typename std::map<android::String8, T>::iterator it;
  108. typename std::list<std::pair<android::String8, T> >* list = NULL;
  109. for (it = map.begin(); it != map.end(); it++) {
  110. if (regexec(&regex, it->first, 0, NULL, 0) == 0) {
  111. if (list == NULL) { // create only when found
  112. list = new std::list<std::pair<android::String8, T> >();
  113. if (list == NULL) {
  114. regfree(&regex);
  115. return NULL;
  116. }
  117. }
  118. typename std::pair<android::String8, T> match(it->first, it->second);
  119. list->push_back(match);
  120. }
  121. }
  122. regfree(&regex);
  123. return list;
  124. }
  125. bool TaskCase::registerBuffer(const android::String8& orig, android::sp<Buffer>& buffer)
  126. {
  127. android::String8 translated;
  128. if (!translateVarName(orig, translated)) {
  129. return false;
  130. }
  131. return registerGeneric<android::sp<Buffer> >(mBufferList, translated, buffer);
  132. }
  133. bool TaskCase::updateBuffer(const android::String8& orig, android::sp<Buffer>& buffer)
  134. {
  135. android::String8 translated;
  136. if (!translateVarName(orig, translated)) {
  137. return false;
  138. }
  139. return updateGeneric<android::sp<Buffer> >(mBufferList, translated, buffer);
  140. }
  141. android::sp<Buffer> TaskCase::findBuffer(const android::String8& orig)
  142. {
  143. android::String8 translated;
  144. android::sp<Buffer> result;
  145. if (!translateVarName(orig, translated)) {
  146. return result;
  147. }
  148. findGeneric<android::sp<Buffer> >(mBufferList, translated, result);
  149. return result;
  150. }
  151. std::list<TaskCase::BufferPair>* TaskCase::findAllBuffers(const android::String8& re)
  152. {
  153. android::String8 translated;
  154. if (!translateVarName(re, translated)) {
  155. return NULL;
  156. }
  157. return findAllGeneric<android::sp<Buffer> >(mBufferList, translated.string());
  158. }
  159. bool TaskCase::registerValue(const android::String8& orig, Value& val)
  160. {
  161. android::String8 translated;
  162. if (!translateVarName(orig, translated)) {
  163. return false;
  164. }
  165. LOGD("str %x", translated.string());
  166. return registerGeneric<Value>(mValueList, translated, val);
  167. }
  168. bool TaskCase::updateValue(const android::String8& orig, Value& val)
  169. {
  170. android::String8 translated;
  171. if (!translateVarName(orig, translated)) {
  172. return false;
  173. }
  174. return updateGeneric<Value>(mValueList, translated, val);
  175. }
  176. bool TaskCase::findValue(const android::String8& orig, Value& val)
  177. {
  178. android::String8 translated;
  179. if (!translateVarName(orig, translated)) {
  180. return false;
  181. }
  182. return findGeneric<Value>(mValueList, translated, val);
  183. }
  184. std::list<TaskCase::ValuePair>* TaskCase::findAllValues(const android::String8& re)
  185. {
  186. android::String8 translated;
  187. if (!translateVarName(re, translated)) {
  188. return NULL;
  189. }
  190. return findAllGeneric<Value>(mValueList, translated.string());
  191. }
  192. bool TaskCase::registerIndex(const android::String8& name, int value)
  193. {
  194. return registerGeneric<int>(mIndexList, name, value);
  195. }
  196. bool TaskCase::updateIndex(const android::String8& name, int value)
  197. {
  198. return updateGeneric<int>(mIndexList, name, value);
  199. }
  200. bool TaskCase::findIndex(const android::String8& name, int& val)
  201. {
  202. return findGeneric<int>(mIndexList, name, val);
  203. }
  204. std::list<TaskCase::IndexPair>* TaskCase::findAllIndices(const android::String8& re)
  205. {
  206. android::String8 translated;
  207. if (!translateVarName(re, translated)) {
  208. return NULL;
  209. }
  210. return findAllGeneric<int>(mIndexList, translated.string());
  211. }
  212. bool TaskCase::translateVarName(const android::String8& orig, android::String8& translated)
  213. {
  214. const char* src = orig.string();
  215. const int nmatch = 2;
  216. regmatch_t pmatch[nmatch];
  217. regex_t re;
  218. size_t strStart = 0;
  219. if (regcomp(&re, "[a-z0-9_]*[$]([a-z0-9]+)[_]*", REG_EXTENDED) != 0) {
  220. LOGE("regcomp failed");
  221. return false;
  222. }
  223. bool result = false;
  224. size_t matchStart = 0;
  225. size_t matchEnd = 0;
  226. while (regexec(&re, src, nmatch, pmatch, 0) == 0) {
  227. matchStart = strStart + pmatch[1].rm_so;
  228. matchEnd = strStart + pmatch[1].rm_eo;
  229. translated.append(StringUtil::substr(orig, strStart, pmatch[1].rm_so - 1)); //-1 for $
  230. android::String8 indexName;
  231. indexName.append(StringUtil::substr(orig, matchStart, matchEnd - matchStart));
  232. int val;
  233. if (!findIndex(indexName, val)) {
  234. LOGE("TaskCase::translateVarName no index with name %s", indexName.string());
  235. regfree(&re);
  236. return false;
  237. }
  238. translated.appendFormat("%d", val);
  239. LOGD("match found strStart %d, matchStart %d, matchEnd %d, converted str %s",
  240. strStart, matchStart, matchEnd, translated.string());
  241. src += pmatch[1].rm_eo;
  242. strStart += pmatch[1].rm_eo;
  243. }
  244. if (matchEnd < orig.length()) {
  245. //LOGD("%d %d", matchEnd, orig.length());
  246. translated.append(StringUtil::substr(orig, matchEnd, orig.length() - matchEnd));
  247. }
  248. LOGD("translated str %s to %s", orig.string(), translated.string());
  249. regfree(&re);
  250. return true;
  251. }
  252. android::sp<RemoteAudio>& TaskCase::getRemoteAudio()
  253. {
  254. if (mClient == NULL) {
  255. mClient = new ClientImpl();
  256. ASSERT(mClient->init(Settings::Instance()->getSetting(Settings::EADB)));
  257. }
  258. return mClient->getAudio();
  259. }
  260. void TaskCase::releaseRemoteAudio()
  261. {
  262. delete mClient;
  263. mClient = NULL;
  264. }
  265. void TaskCase::setDetails(const android::String8& details)
  266. {
  267. mDetails = details;
  268. }
  269. const android::String8& TaskCase::getDetails() const
  270. {
  271. return mDetails;
  272. }
  273. TaskGeneric::ExecutionResult TaskCase::run()
  274. {
  275. android::String8 name;
  276. android::String8 version;
  277. //LOGI("str %d, %d", strlen(STR_NAME), strlen(STR_VERSION));
  278. if (!findStringAttribute(STR_NAME, name) || !findStringAttribute(STR_VERSION, version)) {
  279. LOGW("TaskCase::run no name or version information");
  280. }
  281. MSG("== Test case %s version %s started ==", name.string(), version.string());
  282. std::list<TaskGeneric*>::iterator i = getChildren().begin();
  283. std::list<TaskGeneric*>::iterator end = getChildren().end();
  284. TaskGeneric* setup = *i;
  285. i++;
  286. TaskGeneric* action = *i;
  287. i++;
  288. TaskGeneric* save = (i == end)? NULL : *i;
  289. if (save == NULL) {
  290. LOGW("No save stage in test case");
  291. }
  292. bool testPassed = true;
  293. TaskGeneric::ExecutionResult result = setup->run();
  294. TaskGeneric::ExecutionResult resultAction(TaskGeneric::EResultOK);
  295. if (result != TaskGeneric::EResultOK) {
  296. MSG("== setup stage failed %d ==", result);
  297. testPassed = false;
  298. } else {
  299. resultAction = action->run();
  300. if (resultAction != TaskGeneric::EResultPass) {
  301. MSG("== action stage failed %d ==", resultAction);
  302. testPassed = false;
  303. }
  304. // save done even for failure if possible
  305. if (save != NULL) {
  306. result = save->run();
  307. }
  308. if (result != TaskGeneric::EResultOK) {
  309. MSG("== save stage failed %d ==", result);
  310. testPassed = false;
  311. }
  312. }
  313. if (testPassed) {
  314. result = TaskGeneric::EResultPass;
  315. MSG("== Case %s Passed ==", name.string());
  316. Report::Instance()->addCasePassed(this);
  317. } else {
  318. if (resultAction != TaskGeneric::EResultOK) {
  319. result = resultAction;
  320. }
  321. MSG("== Case %s Failed ==", name.string());
  322. Report::Instance()->addCaseFailed(this);
  323. }
  324. // release remote audio for other cases to use
  325. releaseRemoteAudio();
  326. return result;
  327. }