/suite/audio_quality/lib/src/task/TaskCase.cpp
C++ | 361 lines | 306 code | 34 blank | 21 comment | 58 complexity | 03d94998676bbc6f8c4331df19f3b0f4 MD5 | raw file
- /*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * 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 <sys/types.h>
- #include <regex.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include "Log.h"
- #include "audio/RemoteAudio.h"
- #include "ClientImpl.h"
- #include "Report.h"
- #include "Settings.h"
- #include "StringUtil.h"
- #include "task/TaskCase.h"
- static const android::String8 STR_NAME("name");
- static const android::String8 STR_VERSION("version");
- static const android::String8 STR_DESCRIPTION("description");
- TaskCase::TaskCase()
- : TaskGeneric(TaskGeneric::ETaskCase),
- mClient(NULL)
- {
- const android::String8* list[] = {&STR_NAME, &STR_VERSION, &STR_DESCRIPTION, NULL};
- registerSupportedStringAttributes(list);
- }
- TaskCase::~TaskCase()
- {
- delete mClient;
- }
- bool TaskCase::getCaseName(android::String8& name) const
- {
- if (!findStringAttribute(STR_NAME, name)) {
- LOGW("TaskCase no name");
- return false;
- }
- return true;
- }
- bool TaskCase::addChild(TaskGeneric* child)
- {
- if ((child->getType() != TaskGeneric::ETaskSetup)
- && (child->getType() != TaskGeneric::ETaskAction)
- && (child->getType() != TaskGeneric::ETaskSave)) {
- LOGE("TestCase::addChild wrong child type %d", child->getType());
- return false;
- }
- return TaskGeneric::addChild(child);
- }
- template <typename T> bool registerGeneric(
- typename std::map<android::String8, T>& map,
- const android::String8& name, T& data)
- {
- typename std::map<android::String8, T>::iterator it;
- it = map.find(name);
- if (it != map.end()) {
- LOGV("registerGeneric key %s already registered", name.string());
- return false;
- }
- LOGD("registerGeneric registered key %s", name.string());
- map[name] = data;
- return true;
- }
- template <typename T> bool findGeneric(typename std::map<android::String8, T>& map,
- const android::String8& name, T& data)
- {
- LOGD("findGeneric key %s", name.string());
- typename std::map<android::String8, T>::iterator it;
- it = map.find(name);
- if (it == map.end()) {
- return false;
- }
- data = it->second;
- return true;
- }
- template <typename T> bool updateGeneric(typename std::map<android::String8, T>& map,
- const android::String8& name, T& data)
- {
- LOGD("updateGeneric key %s", name.string());
- typename std::map<android::String8, T>::iterator it;
- it = map.find(name);
- if (it == map.end()) {
- return false;
- }
- it->second = data;
- return true;
- }
- // return all the matches for the given regular expression.
- // name string and the data itself is copied.
- template <typename T> typename std::list<std::pair<android::String8, T> >* findAllGeneric(
- typename std::map<android::String8, T>& map, const char* re)
- {
- regex_t regex;
- if (regcomp(®ex, re, REG_EXTENDED | REG_NOSUB) != 0) {
- LOGE("regcomp failed");
- return NULL;
- }
- typename std::map<android::String8, T>::iterator it;
- typename std::list<std::pair<android::String8, T> >* list = NULL;
- for (it = map.begin(); it != map.end(); it++) {
- if (regexec(®ex, it->first, 0, NULL, 0) == 0) {
- if (list == NULL) { // create only when found
- list = new std::list<std::pair<android::String8, T> >();
- if (list == NULL) {
- regfree(®ex);
- return NULL;
- }
- }
- typename std::pair<android::String8, T> match(it->first, it->second);
- list->push_back(match);
- }
- }
- regfree(®ex);
- return list;
- }
- bool TaskCase::registerBuffer(const android::String8& orig, android::sp<Buffer>& buffer)
- {
- android::String8 translated;
- if (!translateVarName(orig, translated)) {
- return false;
- }
- return registerGeneric<android::sp<Buffer> >(mBufferList, translated, buffer);
- }
- bool TaskCase::updateBuffer(const android::String8& orig, android::sp<Buffer>& buffer)
- {
- android::String8 translated;
- if (!translateVarName(orig, translated)) {
- return false;
- }
- return updateGeneric<android::sp<Buffer> >(mBufferList, translated, buffer);
- }
- android::sp<Buffer> TaskCase::findBuffer(const android::String8& orig)
- {
- android::String8 translated;
- android::sp<Buffer> result;
- if (!translateVarName(orig, translated)) {
- return result;
- }
- findGeneric<android::sp<Buffer> >(mBufferList, translated, result);
- return result;
- }
- std::list<TaskCase::BufferPair>* TaskCase::findAllBuffers(const android::String8& re)
- {
- android::String8 translated;
- if (!translateVarName(re, translated)) {
- return NULL;
- }
- return findAllGeneric<android::sp<Buffer> >(mBufferList, translated.string());
- }
- bool TaskCase::registerValue(const android::String8& orig, Value& val)
- {
- android::String8 translated;
- if (!translateVarName(orig, translated)) {
- return false;
- }
- LOGD("str %x", translated.string());
- return registerGeneric<Value>(mValueList, translated, val);
- }
- bool TaskCase::updateValue(const android::String8& orig, Value& val)
- {
- android::String8 translated;
- if (!translateVarName(orig, translated)) {
- return false;
- }
- return updateGeneric<Value>(mValueList, translated, val);
- }
- bool TaskCase::findValue(const android::String8& orig, Value& val)
- {
- android::String8 translated;
- if (!translateVarName(orig, translated)) {
- return false;
- }
- return findGeneric<Value>(mValueList, translated, val);
- }
- std::list<TaskCase::ValuePair>* TaskCase::findAllValues(const android::String8& re)
- {
- android::String8 translated;
- if (!translateVarName(re, translated)) {
- return NULL;
- }
- return findAllGeneric<Value>(mValueList, translated.string());
- }
- bool TaskCase::registerIndex(const android::String8& name, int value)
- {
- return registerGeneric<int>(mIndexList, name, value);
- }
- bool TaskCase::updateIndex(const android::String8& name, int value)
- {
- return updateGeneric<int>(mIndexList, name, value);
- }
- bool TaskCase::findIndex(const android::String8& name, int& val)
- {
- return findGeneric<int>(mIndexList, name, val);
- }
- std::list<TaskCase::IndexPair>* TaskCase::findAllIndices(const android::String8& re)
- {
- android::String8 translated;
- if (!translateVarName(re, translated)) {
- return NULL;
- }
- return findAllGeneric<int>(mIndexList, translated.string());
- }
- bool TaskCase::translateVarName(const android::String8& orig, android::String8& translated)
- {
- const char* src = orig.string();
- const int nmatch = 2;
- regmatch_t pmatch[nmatch];
- regex_t re;
- size_t strStart = 0;
- if (regcomp(&re, "[a-z0-9_]*[$]([a-z0-9]+)[_]*", REG_EXTENDED) != 0) {
- LOGE("regcomp failed");
- return false;
- }
- bool result = false;
- size_t matchStart = 0;
- size_t matchEnd = 0;
- while (regexec(&re, src, nmatch, pmatch, 0) == 0) {
- matchStart = strStart + pmatch[1].rm_so;
- matchEnd = strStart + pmatch[1].rm_eo;
- translated.append(StringUtil::substr(orig, strStart, pmatch[1].rm_so - 1)); //-1 for $
- android::String8 indexName;
- indexName.append(StringUtil::substr(orig, matchStart, matchEnd - matchStart));
- int val;
- if (!findIndex(indexName, val)) {
- LOGE("TaskCase::translateVarName no index with name %s", indexName.string());
- regfree(&re);
- return false;
- }
- translated.appendFormat("%d", val);
- LOGD("match found strStart %d, matchStart %d, matchEnd %d, converted str %s",
- strStart, matchStart, matchEnd, translated.string());
- src += pmatch[1].rm_eo;
- strStart += pmatch[1].rm_eo;
- }
- if (matchEnd < orig.length()) {
- //LOGD("%d %d", matchEnd, orig.length());
- translated.append(StringUtil::substr(orig, matchEnd, orig.length() - matchEnd));
- }
- LOGD("translated str %s to %s", orig.string(), translated.string());
- regfree(&re);
- return true;
- }
- android::sp<RemoteAudio>& TaskCase::getRemoteAudio()
- {
- if (mClient == NULL) {
- mClient = new ClientImpl();
- ASSERT(mClient->init(Settings::Instance()->getSetting(Settings::EADB)));
- }
- return mClient->getAudio();
- }
- void TaskCase::releaseRemoteAudio()
- {
- delete mClient;
- mClient = NULL;
- }
- void TaskCase::setDetails(const android::String8& details)
- {
- mDetails = details;
- }
- const android::String8& TaskCase::getDetails() const
- {
- return mDetails;
- }
- TaskGeneric::ExecutionResult TaskCase::run()
- {
- android::String8 name;
- android::String8 version;
- //LOGI("str %d, %d", strlen(STR_NAME), strlen(STR_VERSION));
- if (!findStringAttribute(STR_NAME, name) || !findStringAttribute(STR_VERSION, version)) {
- LOGW("TaskCase::run no name or version information");
- }
- MSG("== Test case %s version %s started ==", name.string(), version.string());
- std::list<TaskGeneric*>::iterator i = getChildren().begin();
- std::list<TaskGeneric*>::iterator end = getChildren().end();
- TaskGeneric* setup = *i;
- i++;
- TaskGeneric* action = *i;
- i++;
- TaskGeneric* save = (i == end)? NULL : *i;
- if (save == NULL) {
- LOGW("No save stage in test case");
- }
- bool testPassed = true;
- TaskGeneric::ExecutionResult result = setup->run();
- TaskGeneric::ExecutionResult resultAction(TaskGeneric::EResultOK);
- if (result != TaskGeneric::EResultOK) {
- MSG("== setup stage failed %d ==", result);
- testPassed = false;
- } else {
- resultAction = action->run();
- if (resultAction != TaskGeneric::EResultPass) {
- MSG("== action stage failed %d ==", resultAction);
- testPassed = false;
- }
- // save done even for failure if possible
- if (save != NULL) {
- result = save->run();
- }
- if (result != TaskGeneric::EResultOK) {
- MSG("== save stage failed %d ==", result);
- testPassed = false;
- }
- }
- if (testPassed) {
- result = TaskGeneric::EResultPass;
- MSG("== Case %s Passed ==", name.string());
- Report::Instance()->addCasePassed(this);
- } else {
- if (resultAction != TaskGeneric::EResultOK) {
- result = resultAction;
- }
- MSG("== Case %s Failed ==", name.string());
- Report::Instance()->addCaseFailed(this);
- }
- // release remote audio for other cases to use
- releaseRemoteAudio();
- return result;
- }