add xml report
- add getDeviceInfo command to get information from client
- rename ModelBuilderTest test case xml (all.xml gone)
- reduce buffer size for AudioTrack if data size is small
- add -s option
- generate XML report similar to CtsVerifier and zip the result.
Change-Id: Ic28e0234cfdb848ba1a2f91cc57f15bfdefafd87
diff --git a/suite/audio_quality/lib/include/GenericFactory.h b/suite/audio_quality/lib/include/GenericFactory.h
index 243a744..9f74b7f 100644
--- a/suite/audio_quality/lib/include/GenericFactory.h
+++ b/suite/audio_quality/lib/include/GenericFactory.h
@@ -18,8 +18,8 @@
#define CTSAUDIO_GENERIC_FACTORY_H
#include "task/TaskGeneric.h"
+#include "ClientInterface.h"
-class ClientInterface;
/**
* Factory methods for all abstract classes
diff --git a/suite/audio_quality/lib/include/Log.h b/suite/audio_quality/lib/include/Log.h
index 2b75bc2..e3e803c 100644
--- a/suite/audio_quality/lib/include/Log.h
+++ b/suite/audio_quality/lib/include/Log.h
@@ -59,6 +59,8 @@
#define LOGD(x...) do { Log::Instance()->printf(Log::ELogD, x); } while(0)
#define LOGV(x...) do { Log::Instance()->printf(Log::ELogV, x); } while(0)
+#define MSG(x...) do { Log::Instance()->printf(Log::ELogW, x); } while(0)
+
#define ASSERT(cond) if(!(cond)) { Log::Instance()->printf(Log::ELogE, \
"assertion failed %s %d", __FILE__, __LINE__); \
Log::Finalize(); \
diff --git a/suite/audio_quality/lib/include/Report.h b/suite/audio_quality/lib/include/Report.h
index 67a0572..248f4b9 100644
--- a/suite/audio_quality/lib/include/Report.h
+++ b/suite/audio_quality/lib/include/Report.h
@@ -37,13 +37,14 @@
void addCasePassed(const android::String8& name);
void addCaseFailed(const android::String8& name);
- void printf(const char* fmt, ...);
+
private:
Report();
~Report();
bool init(const char* dirName);
- void writeSummary();
+ void writeReport();
+ void printf(const char* fmt, ...);
private:
static Report* mInstance;
diff --git a/suite/audio_quality/lib/include/Settings.h b/suite/audio_quality/lib/include/Settings.h
index 5cdcd7a..a8cfea5 100644
--- a/suite/audio_quality/lib/include/Settings.h
+++ b/suite/audio_quality/lib/include/Settings.h
@@ -25,13 +25,18 @@
static Settings* Instance();
static void Finalize();
enum SettingType {
- EADB
+ EADB = 0, // adb device serial number
+ EREPORT_TIME = 1,
+ EREPORT_FILE = 2,
+ EDEVICE_INFO = 3,
+ ETEST_XML = 4, // name of test description xml
+ EMAX_SETTINGS = 4 // not real setting
};
void addSetting(SettingType type, const android::String8 setting);
const android::String8& getSetting(SettingType type);
private:
static Settings* mInstance;
- android::String8 mAdbSetting;
+ android::String8 mSettings[EMAX_SETTINGS + 1];
};
diff --git a/suite/audio_quality/lib/include/audio/AudioProtocol.h b/suite/audio_quality/lib/include/audio/AudioProtocol.h
index 83ba922..01e8507 100644
--- a/suite/audio_quality/lib/include/audio/AudioProtocol.h
+++ b/suite/audio_quality/lib/include/audio/AudioProtocol.h
@@ -37,6 +37,7 @@
uint32_t mVolume;
uint32_t mId;
android::sp<Buffer> mBuffer;
+ void* mExtra; // extra data for whatever purpose
};
class AudioProtocol {
@@ -48,7 +49,8 @@
ECmdStopPlayback = 0x12340003,
ECmdStartRecording = 0x12340004,
ECmdStopRecording = 0x12340005,
- ECmdLast = 0x12340006, // not actual command
+ ECmdGetDeviceInfo = 0x12340006,
+ ECmdLast = 0x12340007, // not actual command
};
static const uint32_t REPLY_HEADER_SIZE = 12;
@@ -140,7 +142,13 @@
virtual ~CmdStopRecording() {};
};
+class CmdGetDeviceInfo: public AudioProtocol {
+public:
+ CmdGetDeviceInfo(ClientSocket& socket)
+ : AudioProtocol(socket, ECmdGetDeviceInfo) {};
+ virtual ~CmdGetDeviceInfo() {};
-
+ virtual bool handleReply(const uint32_t* data, AudioParam* param);
+};
#endif // CTSAUDIO_AUDIOPROTOCOL_H
diff --git a/suite/audio_quality/lib/include/audio/RemoteAudio.h b/suite/audio_quality/lib/include/audio/RemoteAudio.h
index 4c587e6..26647c4 100644
--- a/suite/audio_quality/lib/include/audio/RemoteAudio.h
+++ b/suite/audio_quality/lib/include/audio/RemoteAudio.h
@@ -21,6 +21,7 @@
#include <map>
#include <utils/Looper.h>
+#include <utils/String8.h>
#include <utils/StrongPointer.h>
#include <utils/threads.h>
@@ -56,6 +57,8 @@
android::sp<Buffer>& buffer);
bool waitForRecordingCompletion();
void stopRecording();
+
+ bool getDeviceInfo(android::String8& data);
/** should be called before RemoteAudio is destroyed */
void release();
@@ -139,6 +142,7 @@
android::sp<android::MessageHandler> mDownloadHandler;
android::sp<android::MessageHandler> mPlaybackHandler;
android::sp<android::MessageHandler> mRecordingHandler;
+ android::sp<android::MessageHandler> mDeviceInfoHandler;
AudioProtocol* mCmds[AudioProtocol::ECmdLast - AudioProtocol::ECmdStart];
int mDownloadId;
diff --git a/suite/audio_quality/lib/src/FileUtil.cpp b/suite/audio_quality/lib/src/FileUtil.cpp
index e40b7e3..8c8ea7e 100644
--- a/suite/audio_quality/lib/src/FileUtil.cpp
+++ b/suite/audio_quality/lib/src/FileUtil.cpp
@@ -19,6 +19,7 @@
#include <errno.h>
#include "Log.h"
+#include "Settings.h"
#include "StringUtil.h"
#include "FileUtil.h"
@@ -54,9 +55,14 @@
_LOGD_("mkdir of topdir failed, error %d", errno);
return false;
}
+ android::String8 reportTime;
+ if (reportTime.appendFormat("%04d_%02d_%02d_%02d_%02d_%02d", tm->tm_year + 1900,
+ tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec) != 0) {
+ return false;
+ }
+ Settings::Instance()->addSetting(Settings::EREPORT_TIME, reportTime);
android::String8 path;
- if (path.appendFormat("%s/%04d_%02d_%02d_%02d_%02d_%02d", reportTopDir,tm->tm_year + 1900,
- tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec) != 0) {
+ if (path.appendFormat("%s/%s", reportTopDir, reportTime.string()) != 0) {
return false;
}
result = mkdir(path.string(), S_IRWXU);
diff --git a/suite/audio_quality/lib/src/Report.cpp b/suite/audio_quality/lib/src/Report.cpp
index b487836..e6a248c 100644
--- a/suite/audio_quality/lib/src/Report.cpp
+++ b/suite/audio_quality/lib/src/Report.cpp
@@ -15,6 +15,7 @@
*/
#include "Log.h"
+#include "Settings.h"
#include "StringUtil.h"
#include "Report.h"
@@ -43,7 +44,7 @@
Report::~Report()
{
- writeSummary();
+ writeReport();
}
bool Report::init(const char* dirName)
@@ -52,9 +53,10 @@
return true;
}
android::String8 report;
- if (report.appendFormat("%s/report.txt", dirName) != 0) {
+ if (report.appendFormat("%s/report.xml", dirName) != 0) {
return false;
}
+ Settings::Instance()->addSetting(Settings::EREPORT_FILE, report);
return FileUtil::init(report.string());
}
@@ -76,17 +78,24 @@
mFailedCases.push_back(name);
}
-void Report::writeSummary()
+void Report::writeReport()
{
- printf("= Test cases executed: %d, passed: %d, failed: %d =",
- mPassedCases.size() + mFailedCases.size(), mPassedCases.size(), mFailedCases.size());
- printf("= Failed cases =");
+ printf("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>");
+ printf("<audio-test-results-report report-version=\"1\" creation-time=\"%s\">",
+ Settings::Instance()->getSetting(Settings::EREPORT_TIME).string());
+ printf(" <verifier-info version-name=\"1\" version-code=\"1\" />");
+ printf(" <device-info>");
+ printf(" %s", Settings::Instance()->getSetting(Settings::EDEVICE_INFO).string());
+ printf(" </device-info>");
+ printf(" <audio-test-results xml=\"%s\">",
+ Settings::Instance()->getSetting(Settings::ETEST_XML).string());
std::list<android::String8>::iterator it;
for (it = mFailedCases.begin(); it != mFailedCases.end(); it++) {
- printf("* %s", it->string());
+ printf(" <test title=\"%s\" result=\"fail\" />", it->string());
}
- printf("= Passed cases =");
for (it = mPassedCases.begin(); it != mPassedCases.end(); it++) {
- printf("* %s", it->string());
+ printf(" <test title=\"%s\" result=\"pass\" />", it->string());
}
+ printf(" </audio-test-results>");
+ printf("</audio-test-results-report>");
}
diff --git a/suite/audio_quality/lib/src/Settings.cpp b/suite/audio_quality/lib/src/Settings.cpp
index 4f78fe4..42dd30e 100644
--- a/suite/audio_quality/lib/src/Settings.cpp
+++ b/suite/audio_quality/lib/src/Settings.cpp
@@ -36,23 +36,11 @@
void Settings::addSetting(SettingType type, const android::String8 setting)
{
- // TODO key, string can be better if there are large number of settings
- switch(type) {
- case EADB:
- mAdbSetting = setting;
- default:
- ASSERT(false);
- }
+ mSettings[type] = setting;
}
const android::String8& Settings::getSetting(SettingType type)
{
- switch(type) {
- case EADB:
- return mAdbSetting;
- default:
- ASSERT(false);
- }
- return mAdbSetting; // just for removing compiler warning, will not reach here
+ return mSettings[type];
}
diff --git a/suite/audio_quality/lib/src/audio/AudioProtocol.cpp b/suite/audio_quality/lib/src/audio/AudioProtocol.cpp
index bf1ca22..c3457f5 100644
--- a/suite/audio_quality/lib/src/audio/AudioProtocol.cpp
+++ b/suite/audio_quality/lib/src/audio/AudioProtocol.cpp
@@ -19,6 +19,7 @@
#include <sys/socket.h>
#include <utils/StrongPointer.h>
+#include <utils/UniquePtr.h>
#include "audio/Buffer.h"
#include "Log.h"
@@ -171,6 +172,26 @@
return true;
}
+bool CmdGetDeviceInfo::handleReply(const uint32_t* data, AudioParam* param)
+{
+ if (!checkHeaderId(data, ECmdGetDeviceInfo)) {
+ return false;
+ }
+ if (data[1] != 0) { // no endian change for 0
+ LOGE("error in reply %d", ntohl(data[1]));
+ return false;
+ }
+ int len = ntohl(data[2]);
+ UniquePtr<char, DefaultDelete<char[]> > infoString(new char[len + 1]);
+ if (!readData(infoString.get(), len)) {
+ return false;
+ }
+ (infoString.get())[len] = 0;
+ LOGI("received data %s from device", infoString.get());
+ android::String8* string = reinterpret_cast<android::String8*>(param->mExtra);
+ string->setTo(infoString.get(), len);
+ return true;
+}
diff --git a/suite/audio_quality/lib/src/audio/RemoteAudio.cpp b/suite/audio_quality/lib/src/audio/RemoteAudio.cpp
index bb9474b..1156173 100644
--- a/suite/audio_quality/lib/src/audio/RemoteAudio.cpp
+++ b/suite/audio_quality/lib/src/audio/RemoteAudio.cpp
@@ -32,6 +32,7 @@
mDownloadHandler(new CommandHandler(*this, (int)AudioProtocol::ECmdDownload)),
mPlaybackHandler(new CommandHandler(*this, (int)AudioProtocol::ECmdStartPlayback)),
mRecordingHandler(new CommandHandler(*this, (int)AudioProtocol::ECmdStartRecording)),
+ mDeviceInfoHandler(new CommandHandler(*this, (int)AudioProtocol::ECmdGetDeviceInfo)),
mDownloadId(0)
{
mCmds[AudioProtocol::ECmdDownload - AudioProtocol::ECmdStart] = new CmdDownload(socket);
@@ -43,6 +44,8 @@
new CmdStartRecording(socket);
mCmds[AudioProtocol::ECmdStopRecording - AudioProtocol::ECmdStart] =
new CmdStopRecording(socket);
+ mCmds[AudioProtocol::ECmdGetDeviceInfo - AudioProtocol::ECmdStart] =
+ new CmdGetDeviceInfo(socket);
}
RemoteAudio::~RemoteAudio()
@@ -104,7 +107,6 @@
if (!AudioProtocol::handleReplyHeader(mSocket, data, id)) {
return false;
}
- AudioParam* param = NULL;
CommandHandler* handler = NULL;
if (id == AudioProtocol::ECmdDownload) {
handler = reinterpret_cast<CommandHandler*>(mDownloadHandler.get());
@@ -112,6 +114,11 @@
handler = reinterpret_cast<CommandHandler*>(mPlaybackHandler.get());
} else if (id == AudioProtocol::ECmdStartRecording) {
handler = reinterpret_cast<CommandHandler*>(mRecordingHandler.get());
+ } else if (id == AudioProtocol::ECmdGetDeviceInfo) {
+ handler = reinterpret_cast<CommandHandler*>(mDeviceInfoHandler.get());
+ }
+ AudioParam* param = NULL;
+ if (handler != NULL) {
param = &(handler->getParam());
}
bool result = mCmds[id - AudioProtocol::ECmdStart]->handleReply(data, param);
@@ -148,6 +155,7 @@
bool RemoteAudio::waitForCompletion(android::sp<android::MessageHandler>& command, int timeInMSec)
{
+ LOGV("waitForCompletion %d", timeInMSec);
return toCommandHandler(command)->timedWait(timeInMSec);
}
@@ -190,12 +198,13 @@
CommandHandler* handler = reinterpret_cast<CommandHandler*>(mDownloadHandler.get());
id = mDownloadId;
mDownloadId++;
+ handler->mStateLock.lock();
handler->getParam().mId = id;
handler->getParam().mBuffer = buffer;
- sendCommand(mDownloadHandler);
- handler->mStateLock.lock();
handler->mNotifyOnReply = true;
handler->mStateLock.unlock();
+ sendCommand(mDownloadHandler);
+
// assume 1Mbps ==> 1000 bits per msec ==> 125 bytes per msec
int maxWaitTime = CLIENT_WAIT_TIMEOUT_MSEC + buffer->getSize() / 125;
// client blocked until reply comes from DUT
@@ -299,6 +308,23 @@
doStop(mRecordingHandler, AudioProtocol::ECmdStopRecording);
}
+bool RemoteAudio::getDeviceInfo(android::String8& data)
+{
+ CommandHandler* handler = reinterpret_cast<CommandHandler*>(mDeviceInfoHandler.get());
+ handler->mStateLock.lock();
+ handler->mNotifyOnReply = true;
+ handler->getParam().mExtra = &data;
+ handler->mStateLock.unlock();
+ sendCommand(mDeviceInfoHandler);
+
+ // client blocked until reply comes from DUT
+ if (!waitForCompletion(mDeviceInfoHandler, CLIENT_WAIT_TIMEOUT_MSEC)) {
+ LOGE("timeout");
+ return false;
+ }
+ return handler->mResult;
+}
+
/** should be called before RemoteAudio is destroyed */
void RemoteAudio::release()
{
@@ -322,11 +348,13 @@
case AudioProtocol::ECmdStopPlayback:
case AudioProtocol::ECmdStartRecording:
case AudioProtocol::ECmdStopRecording:
+ case AudioProtocol::ECmdGetDeviceInfo:
{
mResult = (mThread.mCmds[message.what - AudioProtocol::ECmdStart]) \
->sendCommand(mParam);
- // no post for download. Client blocked until reply comes with time-out
- if (message.what != AudioProtocol::ECmdDownload) {
+ // no post for download and getdeviceinfo. Client blocked until reply comes with time-out
+ if ((message.what != AudioProtocol::ECmdDownload) &&
+ (message.what != AudioProtocol::ECmdGetDeviceInfo) ) {
mClientWait.post();
}
diff --git a/suite/audio_quality/lib/src/task/TaskBatch.cpp b/suite/audio_quality/lib/src/task/TaskBatch.cpp
index f8c77fe..70499fc 100644
--- a/suite/audio_quality/lib/src/task/TaskBatch.cpp
+++ b/suite/audio_quality/lib/src/task/TaskBatch.cpp
@@ -58,10 +58,10 @@
if (!findStringAttribute(STR_NAME, name) || !findStringAttribute(STR_VERSION, version)) {
LOGW("TaskBatch::run no name or version information");
}
- Report::Instance()->printf("= Test batch %s version %s started. =", name.string(),
+ MSG("= Test batch %s version %s started. =", name.string(),
version.string());
bool result = TaskGeneric::forEachChild(runAlways, NULL);
- Report::Instance()->printf("= Finished Test batch =");
+ MSG("= Finished Test batch =");
return TaskGeneric::EResultOK;
}
diff --git a/suite/audio_quality/lib/src/task/TaskCase.cpp b/suite/audio_quality/lib/src/task/TaskCase.cpp
index 9cbc6c8..c92e71b 100644
--- a/suite/audio_quality/lib/src/task/TaskCase.cpp
+++ b/suite/audio_quality/lib/src/task/TaskCase.cpp
@@ -300,8 +300,7 @@
if (!findStringAttribute(STR_NAME, name) || !findStringAttribute(STR_VERSION, version)) {
LOGW("TaskCase::run no name or version information");
}
- Report::Instance()->printf("== Test case %s version %s started ==", name.string(),
- version.string());
+ 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;
@@ -316,12 +315,12 @@
TaskGeneric::ExecutionResult result = setup->run();
TaskGeneric::ExecutionResult resultAction(TaskGeneric::EResultOK);
if (result != TaskGeneric::EResultOK) {
- Report::Instance()->printf("== setup stage failed %d ==", result);
+ MSG("== setup stage failed %d ==", result);
testPassed = false;
} else {
resultAction = action->run();
if (resultAction != TaskGeneric::EResultPass) {
- Report::Instance()->printf("== action stage failed %d ==", resultAction);
+ MSG("== action stage failed %d ==", resultAction);
testPassed = false;
}
// save done even for failure if possible
@@ -329,19 +328,19 @@
result = save->run();
}
if (result != TaskGeneric::EResultOK) {
- Report::Instance()->printf("== save stage failed %d ==", result);
+ MSG("== save stage failed %d ==", result);
testPassed = false;
}
}
if (testPassed) {
result = TaskGeneric::EResultPass;
- Report::Instance()->printf("== Case %s Passed ==", name.string());
+ MSG("== Case %s Passed ==", name.string());
Report::Instance()->addCasePassed(name);
} else {
if (resultAction != TaskGeneric::EResultOK) {
result = resultAction;
}
- Report::Instance()->printf("== Case %s Failed ==", name.string());
+ MSG("== Case %s Failed ==", name.string());
Report::Instance()->addCaseFailed(name);
}
// release remote audio for other cases to use
diff --git a/suite/audio_quality/lib/src/task/TaskSave.cpp b/suite/audio_quality/lib/src/task/TaskSave.cpp
index d62b846..8938c1e 100644
--- a/suite/audio_quality/lib/src/task/TaskSave.cpp
+++ b/suite/audio_quality/lib/src/task/TaskSave.cpp
@@ -110,7 +110,7 @@
LOGE("alloc failed");
return false;
}
- Report::Instance()->printf("=== Values stored ===");
+ MSG("=== Values stored ===");
for (size_t i = 0; i < listp->size(); i++) {
UniquePtr<std::list<TaskCase::ValuePair> > values(
getTestCase()->findAllValues((*listp)[i]));
@@ -123,11 +123,9 @@
std::list<TaskCase::ValuePair>::iterator end = values->end();
for (; it != end; it++) {
if (it->second.getType() == TaskCase::Value::ETypeDouble) {
- Report::Instance()->printf(" %s: %f", it->first.string(),
- it->second.getDouble());
+ MSG(" %s: %f", it->first.string(), it->second.getDouble());
} else { //64bit int
- Report::Instance()->printf(" %s: %lld", it->first.string(),
- it->second.getInt64());
+ MSG(" %s: %lld", it->first.string(), it->second.getInt64());
}
}
}