Improve Tuner VTS: Generate DVR Record Combos
This CL allows the VTS to read a vendor's configuration file, determine if the given devices could support the DVR Record dataflow, and runs the integration tests with all valid combinations. 2 functions were added to help drive the testing logic. generateRecordCombinations() generates all valid record dataflow configurations, and the integration tests call generateRecordCombinations() to analyze whether to generate these combinations or use the data flow provided by the vendor (if there is one). Additionally, when dynamically configuring DVR_Record, a bug was exposed in the VTS that came about from recycling the function recordSingleFilterTest(). When LnbRecord was initialized with a software frontend, the VTS was looking to the record dataflow's dvr source for input. If record is not hardcoded by the vendor, the VTS would crash. To fix this error, an enum class was added as a parameter to RecordSingleFilterTest() to take into consideration which dataflow (lnbRecord or record [no Lnb]) was calling the function. New behavior is defined to take into account both cases. Also, lnbRecord will not be tested if there are no hardware frontends, as this is not very likely to be configured by vendors. Bug: b/182519645 Test: vts-tradefed run vts --module VtsHalTvTunerTargetTest. Manual tests with different input configuration files. Change-Id: I76c05ca2e33767e4bdcd2072db5144d495d623b0
This commit is contained in:
parent
0c0695379d
commit
9c464f7c5c
3 changed files with 122 additions and 30 deletions
|
@ -260,7 +260,9 @@ void TunerRecordAidlTest::recordSingleFilterTestWithLnb(FilterConfig filterConf,
|
|||
for (auto msgName : lnbRecord.diseqcMsgs) {
|
||||
ASSERT_TRUE(mLnbTests.sendDiseqcMessage(diseqcMsgMap[msgName]));
|
||||
}
|
||||
recordSingleFilterTest(filterConf, frontendConf, dvrConf);
|
||||
if (!frontendConf.isSoftwareFe) {
|
||||
recordSingleFilterTest(filterConf, frontendConf, dvrConf, Dataflow_Context::LNBRECORD);
|
||||
}
|
||||
ASSERT_TRUE(mLnbTests.closeLnb());
|
||||
mLnbId = INVALID_LNB_ID;
|
||||
}
|
||||
|
@ -318,29 +320,47 @@ void TunerRecordAidlTest::attachSingleFilterToRecordDvrTest(FilterConfig filterC
|
|||
}
|
||||
|
||||
void TunerRecordAidlTest::recordSingleFilterTest(FilterConfig filterConf,
|
||||
FrontendConfig frontendConf, DvrConfig dvrConf) {
|
||||
FrontendConfig frontendConf, DvrConfig dvrConf,
|
||||
Dataflow_Context context) {
|
||||
int32_t demuxId;
|
||||
std::shared_ptr<IDemux> demux;
|
||||
ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
|
||||
mDvrTests.setDemux(demux);
|
||||
|
||||
DvrConfig dvrSourceConfig;
|
||||
if (record.hasFrontendConnection) {
|
||||
if (context == Dataflow_Context::RECORD) {
|
||||
if (record.hasFrontendConnection) {
|
||||
int32_t feId;
|
||||
mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
|
||||
ASSERT_TRUE(feId != INVALID_ID);
|
||||
ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
|
||||
ASSERT_TRUE(mFrontendTests.setFrontendCallback());
|
||||
if (frontendConf.isSoftwareFe) {
|
||||
mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[record.dvrSoftwareFeId]);
|
||||
}
|
||||
ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
|
||||
mFrontendTests.setDvrTests(&mDvrTests);
|
||||
} else {
|
||||
dvrSourceConfig = dvrMap[record.dvrSourceId];
|
||||
ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrSourceConfig.type, dvrSourceConfig.bufferSize));
|
||||
ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrSourceConfig.settings));
|
||||
ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor());
|
||||
}
|
||||
} else if (context == Dataflow_Context::LNBRECORD) {
|
||||
// If function arrives here, frontend should not be software, so no need to configure a dvr
|
||||
// source or dvr fe connection that might be used for recording without an Lnb
|
||||
int32_t feId;
|
||||
mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
|
||||
ASSERT_TRUE(feId != INVALID_ID);
|
||||
ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
|
||||
ASSERT_TRUE(mFrontendTests.setFrontendCallback());
|
||||
if (frontendConf.isSoftwareFe) {
|
||||
mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[record.dvrSoftwareFeId]);
|
||||
if (mLnbId != INVALID_LNB_ID) {
|
||||
ASSERT_TRUE(mFrontendTests.setLnb(mLnbId));
|
||||
} else {
|
||||
FAIL();
|
||||
}
|
||||
ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
|
||||
mFrontendTests.setDvrTests(&mDvrTests);
|
||||
} else {
|
||||
dvrSourceConfig = dvrMap[record.dvrSourceId];
|
||||
ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrSourceConfig.type, dvrSourceConfig.bufferSize));
|
||||
ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrSourceConfig.settings));
|
||||
ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor());
|
||||
}
|
||||
|
||||
int64_t filterId;
|
||||
|
@ -360,24 +380,31 @@ void TunerRecordAidlTest::recordSingleFilterTest(FilterConfig filterConf,
|
|||
ASSERT_TRUE(mDvrTests.startDvrRecord());
|
||||
ASSERT_TRUE(mFilterTests.startFilter(filterId));
|
||||
|
||||
if (record.hasFrontendConnection) {
|
||||
if (context == Dataflow_Context::RECORD) {
|
||||
if (record.hasFrontendConnection) {
|
||||
ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
|
||||
} else {
|
||||
// Start DVR Source
|
||||
mDvrTests.startPlaybackInputThread(
|
||||
dvrSourceConfig.playbackInputFile,
|
||||
dvrSourceConfig.settings.get<DvrSettings::Tag::playback>());
|
||||
ASSERT_TRUE(mDvrTests.startDvrPlayback());
|
||||
}
|
||||
} else if (context == Dataflow_Context::LNBRECORD) {
|
||||
ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
|
||||
} else {
|
||||
// Start DVR Source
|
||||
mDvrTests.startPlaybackInputThread(
|
||||
dvrSourceConfig.playbackInputFile,
|
||||
dvrSourceConfig.settings.get<DvrSettings::Tag::playback>());
|
||||
ASSERT_TRUE(mDvrTests.startDvrPlayback());
|
||||
}
|
||||
|
||||
mDvrTests.testRecordOutput();
|
||||
mDvrTests.stopRecordThread();
|
||||
|
||||
if (record.hasFrontendConnection) {
|
||||
if (context == Dataflow_Context::RECORD) {
|
||||
if (record.hasFrontendConnection) {
|
||||
ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
|
||||
} else {
|
||||
mDvrTests.stopPlaybackThread();
|
||||
ASSERT_TRUE(mDvrTests.stopDvrPlayback());
|
||||
}
|
||||
} else if (context == Dataflow_Context::LNBRECORD) {
|
||||
ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
|
||||
} else {
|
||||
mDvrTests.stopPlaybackThread();
|
||||
ASSERT_TRUE(mDvrTests.stopDvrPlayback());
|
||||
}
|
||||
|
||||
ASSERT_TRUE(mFilterTests.stopFilter(filterId));
|
||||
|
@ -386,10 +413,14 @@ void TunerRecordAidlTest::recordSingleFilterTest(FilterConfig filterConf,
|
|||
ASSERT_TRUE(mFilterTests.closeFilter(filterId));
|
||||
mDvrTests.closeDvrRecord();
|
||||
|
||||
if (record.hasFrontendConnection) {
|
||||
if (context == Dataflow_Context::RECORD) {
|
||||
if (record.hasFrontendConnection) {
|
||||
ASSERT_TRUE(mFrontendTests.closeFrontend());
|
||||
} else {
|
||||
mDvrTests.closeDvrPlayback();
|
||||
}
|
||||
} else if (context == Dataflow_Context::LNBRECORD) {
|
||||
ASSERT_TRUE(mFrontendTests.closeFrontend());
|
||||
} else {
|
||||
mDvrTests.closeDvrPlayback();
|
||||
}
|
||||
|
||||
ASSERT_TRUE(mDemuxTests.closeDemux());
|
||||
|
@ -892,8 +923,12 @@ TEST_P(TunerRecordAidlTest, RecordDataFlowWithTsRecordFilterTest) {
|
|||
if (!record.support) {
|
||||
return;
|
||||
}
|
||||
recordSingleFilterTest(filterMap[record.recordFilterId], frontendMap[record.frontendId],
|
||||
dvrMap[record.dvrRecordId]);
|
||||
auto record_configs = generateRecordConfigurations();
|
||||
for (auto& configuration : record_configs) {
|
||||
record = configuration;
|
||||
recordSingleFilterTest(filterMap[record.recordFilterId], frontendMap[record.frontendId],
|
||||
dvrMap[record.dvrRecordId], Dataflow_Context::RECORD);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(TunerRecordAidlTest, AttachFiltersToRecordTest) {
|
||||
|
@ -902,8 +937,13 @@ TEST_P(TunerRecordAidlTest, AttachFiltersToRecordTest) {
|
|||
if (!record.support) {
|
||||
return;
|
||||
}
|
||||
attachSingleFilterToRecordDvrTest(filterMap[record.recordFilterId],
|
||||
frontendMap[record.frontendId], dvrMap[record.dvrRecordId]);
|
||||
auto record_configs = generateRecordConfigurations();
|
||||
for (auto& configuration : record_configs) {
|
||||
record = configuration;
|
||||
attachSingleFilterToRecordDvrTest(filterMap[record.recordFilterId],
|
||||
frontendMap[record.frontendId],
|
||||
dvrMap[record.dvrRecordId]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(TunerRecordAidlTest, LnbRecordDataFlowWithTsRecordFilterTest) {
|
||||
|
|
|
@ -78,6 +78,8 @@ void clearIds() {
|
|||
sectionFilterIds.clear();
|
||||
}
|
||||
|
||||
enum class Dataflow_Context { LNBRECORD, RECORD };
|
||||
|
||||
class TunerLnbAidlTest : public testing::TestWithParam<std::string> {
|
||||
public:
|
||||
virtual void SetUp() override {
|
||||
|
@ -289,7 +291,7 @@ class TunerRecordAidlTest : public testing::TestWithParam<std::string> {
|
|||
void recordSingleFilterTestWithLnb(FilterConfig filterConf, FrontendConfig frontendConf,
|
||||
DvrConfig dvrConf, LnbConfig lnbConf);
|
||||
void recordSingleFilterTest(FilterConfig filterConf, FrontendConfig frontendConf,
|
||||
DvrConfig dvrConf);
|
||||
DvrConfig dvrConf, Dataflow_Context context);
|
||||
|
||||
std::shared_ptr<ITuner> mService;
|
||||
FrontendTests mFrontendTests;
|
||||
|
|
|
@ -407,6 +407,56 @@ static inline vector<TimeFilterHardwareConnections> generateTimeFilterConfigurat
|
|||
return timeFilter_configs;
|
||||
}
|
||||
|
||||
/*
|
||||
* index 0 - frontends
|
||||
* index 1 - record dvrs
|
||||
* index 2 - record filters
|
||||
*/
|
||||
static inline vector<DvrRecordHardwareConnections> generateRecordCombinations() {
|
||||
vector<DvrRecordHardwareConnections> combinations;
|
||||
|
||||
const int frontendIdIndex = 0;
|
||||
const int recordDvrIndex = 1;
|
||||
const int recordFilterIndex = 2;
|
||||
|
||||
vector<vector<string>> deviceIds{frontendIds, recordDvrIds, recordFilterIds};
|
||||
|
||||
auto idCombinations = generateIdCombinations(deviceIds);
|
||||
for (auto& combo : idCombinations) {
|
||||
DvrRecordHardwareConnections mRecord;
|
||||
const string feId = combo[frontendIdIndex];
|
||||
mRecord.hasFrontendConnection = true;
|
||||
if (frontendMap[feId].isSoftwareFe) {
|
||||
// If we have a software frontend, do not include configuration for testing.
|
||||
continue;
|
||||
}
|
||||
mRecord.frontendId = feId;
|
||||
mRecord.support = true;
|
||||
mRecord.dvrSourceId = emptyHardwareId;
|
||||
mRecord.dvrSoftwareFeId = emptyHardwareId;
|
||||
mRecord.recordFilterId = combo[recordFilterIndex];
|
||||
mRecord.dvrRecordId = combo[recordDvrIndex];
|
||||
combinations.push_back(mRecord);
|
||||
}
|
||||
|
||||
return combinations;
|
||||
}
|
||||
|
||||
static inline vector<DvrRecordHardwareConnections> generateRecordConfigurations() {
|
||||
vector<DvrRecordHardwareConnections> record_configs;
|
||||
if (configuredRecord) {
|
||||
ALOGD("Using Record configuration provided.");
|
||||
record_configs = {record};
|
||||
} else {
|
||||
ALOGD("Record not provided. Generating possible combinations. Consider adding it to "
|
||||
"the "
|
||||
"configuration file.");
|
||||
record_configs = generateRecordCombinations();
|
||||
}
|
||||
|
||||
return record_configs;
|
||||
}
|
||||
|
||||
/** Config all the frontends that would be used in the tests */
|
||||
inline void initFrontendConfig() {
|
||||
// The test will use the internal default fe when default fe is connected to any data flow
|
||||
|
|
Loading…
Reference in a new issue