From 3f7c1403e7c9a021dfaf2cd42136853c858579f8 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Mon, 10 Sep 2018 15:01:01 -0700 Subject: [PATCH] First version of scheduled tests. --- tools/auto-tester/src/TestRunner.cpp | 148 ++++++++++---- tools/auto-tester/src/TestRunner.h | 32 ++- tools/auto-tester/src/ui/AutoTester.cpp | 36 +++- tools/auto-tester/src/ui/AutoTester.h | 3 + tools/auto-tester/src/ui/AutoTester.ui | 252 +++++++++++++++++++++++- 5 files changed, 418 insertions(+), 53 deletions(-) diff --git a/tools/auto-tester/src/TestRunner.cpp b/tools/auto-tester/src/TestRunner.cpp index 4075defb6f..e40e9a0986 100644 --- a/tools/auto-tester/src/TestRunner.cpp +++ b/tools/auto-tester/src/TestRunner.cpp @@ -21,17 +21,58 @@ extern AutoTester* autoTester; #include #endif -TestRunner::TestRunner(QObject* parent) : QObject(parent) { +TestRunner::TestRunner(std::vector dayCheckboxes, + std::vector timeEditCheckboxes, + std::vector timeEdits, + QLabel* workingFolderLabel, + QObject* parent) : + QObject(parent) +{ + _dayCheckboxes = dayCheckboxes; + _timeEditCheckboxes = timeEditCheckboxes; + _timeEdits = timeEdits; + _workingFolderLabel = workingFolderLabel; +} + +TestRunner::~TestRunner() { + disconnect(_timer, SIGNAL(timeout()), this, SLOT(checkTime())); +} + +void TestRunner::setWorkingFolder() { + // Everything will be written to this folder + QString previousSelection = _workingFolder; + QString parent = previousSelection.left(previousSelection.lastIndexOf('/')); + if (!parent.isNull() && parent.right(1) != "/") { + parent += "/"; + } + + _workingFolder = QFileDialog::getExistingDirectory(nullptr, "Please select a temporary folder for installation", parent, + QFileDialog::ShowDirsOnly); + + // If user canceled then restore previous selection and return + if (_workingFolder == "") { + _workingFolder = previousSelection; + return; + } + + _installationFolder = _workingFolder + "/High Fidelity"; + + autoTester->enableRunTabControls(); + _workingFolderLabel->setText(QDir::toNativeSeparators(_workingFolder)); + + // The time is checked every 30 seconds for automatic test start + _timer = new QTimer(this); + connect(_timer, SIGNAL(timeout()), this, SLOT(checkTime())); + _timer->start(30 * 1000); //time specified in ms } void TestRunner::run() { + _automatedTestIsRunning = true; + // Initial setup _branch = autoTester->getSelectedBranch(); _user = autoTester->getSelectedUser(); - // Everything will be written to this folder - selectTemporaryFolder(); - // This will be restored at the end of the tests saveExistingHighFidelityAppDataFolder(); @@ -42,7 +83,7 @@ void TestRunner::run() { QStringList filenames; filenames << INSTALLER_FILENAME << BUILD_XML_FILENAME; - autoTester->downloadFiles(urls, _tempFolder, filenames, (void*)this); + autoTester->downloadFiles(urls, _workingFolder, filenames, (void*)this); // `installerDownloadComplete` will run after download has completed } @@ -69,7 +110,7 @@ void TestRunner::runInstaller() { // To allow installation, the installer is run using the `system` command QStringList arguments{ QStringList() << QString("/S") << QString("/D=") + QDir::toNativeSeparators(_installationFolder) }; - QString installerFullPath = _tempFolder + "/" + INSTALLER_FILENAME; + QString installerFullPath = _workingFolder + "/" + INSTALLER_FILENAME; QString commandLine = QDir::toNativeSeparators(installerFullPath) + " /S /D=" + QDir::toNativeSeparators(_installationFolder); @@ -96,35 +137,8 @@ void TestRunner::saveExistingHighFidelityAppDataFolder() { copyFolder(QDir::currentPath() + "/AppDataHighFidelity", _appDataFolder.path()); } -void TestRunner::restoreHighFidelityAppDataFolder() { - _appDataFolder.removeRecursively(); - - if (_savedAppDataFolder != QDir()) { - _appDataFolder.rename(_savedAppDataFolder.path(), _appDataFolder.path()); - } -} - -void TestRunner::selectTemporaryFolder() { - QString previousSelection = _tempFolder; - QString parent = previousSelection.left(previousSelection.lastIndexOf('/')); - if (!parent.isNull() && parent.right(1) != "/") { - parent += "/"; - } - - _tempFolder = QFileDialog::getExistingDirectory(nullptr, "Please select a temporary folder for installation", parent, - QFileDialog::ShowDirsOnly); - - // If user canceled then restore previous selection and return - if (_tempFolder == "") { - _tempFolder = previousSelection; - return; - } - - _installationFolder = _tempFolder + "/High Fidelity"; -} - void TestRunner::createSnapshotFolder() { - _snapshotFolder = _tempFolder + "/" + SNAPSHOT_FOLDER_NAME; + _snapshotFolder = _workingFolder + "/" + SNAPSHOT_FOLDER_NAME; // Just delete all PNGs from the folder if it already exists if (QDir(_snapshotFolder).exists()) { @@ -145,7 +159,10 @@ void TestRunner::createSnapshotFolder() { void TestRunner::killProcesses() { #ifdef Q_OS_WIN try { - QStringList processesToKill = QStringList() << "interface.exe" << "assignment-client.exe" << "domain-server.exe" << "server-console.exe"; + QStringList processesToKill = QStringList() << "interface.exe" + << "assignment-client.exe" + << "domain-server.exe" + << "server-console.exe"; // Loop until all pending processes to kill have actually died QStringList pendingProcessesToKill; @@ -167,12 +184,12 @@ void TestRunner::killProcesses() { // Kill any task in the list do { - foreach (QString process, processesToKill) - if (QString(processEntry32.szExeFile) == process) { - QString commandLine = "taskkill /im " + process + " /f >nul"; - system(commandLine.toStdString().c_str()); - pendingProcessesToKill << process; - } + foreach (QString process, processesToKill) + if (QString(processEntry32.szExeFile) == process) { + QString commandLine = "taskkill /im " + process + " /f >nul"; + system(commandLine.toStdString().c_str()); + pendingProcessesToKill << process; + } } while (Process32Next(processSnapHandle, &processEntry32)); QThread::sleep(2); @@ -200,7 +217,7 @@ void TestRunner::startLocalServerProcesses() { system(commandLine.toStdString().c_str()); #endif // Give server processes time to stabilize - QThread::sleep(8); + QThread::sleep(12); } void TestRunner::runInterfaceWithTestScript() { @@ -221,12 +238,14 @@ void TestRunner::evaluateResults() { void TestRunner::automaticTestRunEvaluationComplete(QString zippedFolder) { addBuildNumberToResults(zippedFolder); restoreHighFidelityAppDataFolder(); + + _automatedTestIsRunning = false; } void TestRunner::addBuildNumberToResults(QString zippedFolderName) { try { QDomDocument domDocument; - QString filename{ _tempFolder + "/" + BUILD_XML_FILENAME }; + QString filename{ _workingFolder + "/" + BUILD_XML_FILENAME }; QFile file(filename); if (!file.open(QIODevice::ReadOnly) || !domDocument.setContent(&file)) { throw QString("Could not open " + filename); @@ -290,6 +309,14 @@ void TestRunner::addBuildNumberToResults(QString zippedFolderName) { } } +void TestRunner::restoreHighFidelityAppDataFolder() { + _appDataFolder.removeRecursively(); + + if (_savedAppDataFolder != QDir()) { + _appDataFolder.rename(_savedAppDataFolder.path(), _appDataFolder.path()); + } +} + // Copies a folder recursively void TestRunner::copyFolder(const QString& source, const QString& destination) { try { @@ -321,3 +348,38 @@ void TestRunner::copyFolder(const QString& source, const QString& destination) { exit(-1); } } + +void TestRunner::checkTime() { + // No processing is done if a test is running + if (_automatedTestIsRunning) { + return; + } + + QDateTime now = QDateTime::currentDateTime(); + + // Check day of week + if (!_dayCheckboxes.at(now.date().dayOfWeek() - 1)->isChecked()) { + return; + } + + // Check the time + bool timeToRun{ false }; + QTime time = now.time(); + int h = time.hour(); + int m = time.minute(); + + for (int i = 0; i < std::min(_timeEditCheckboxes.size(), _timeEdits.size()); ++i) { + bool is = _timeEditCheckboxes[i]->isChecked(); + int hh = _timeEdits[i]->time().hour(); + int mm = _timeEdits[i]->time().minute(); + if (_timeEditCheckboxes[i]->isChecked() && (_timeEdits[i]->time().hour() == now.time().hour()) && + (_timeEdits[i]->time().minute() == now.time().minute())) { + timeToRun = true; + break; + } + } + + if (timeToRun) { + run(); + } +} \ No newline at end of file diff --git a/tools/auto-tester/src/TestRunner.h b/tools/auto-tester/src/TestRunner.h index 7b4e8c901a..605d56c88d 100644 --- a/tools/auto-tester/src/TestRunner.h +++ b/tools/auto-tester/src/TestRunner.h @@ -11,24 +11,36 @@ #ifndef hifi_testRunner_h #define hifi_testRunner_h -#include +#include #include +#include +#include #include +#include +#include #include "Downloader.h" class TestRunner : public QObject { Q_OBJECT public: - explicit TestRunner(QObject* parent = 0); + explicit TestRunner(std::vector dayCheckboxes, + std::vector timeEditCheckboxes, + std::vector timeEdits, + QLabel* workingFolderLabel, + QObject* parent = 0); + ~TestRunner(); + + void setWorkingFolder(); void run(); + void installerDownloadComplete(); void runInstaller(); void saveExistingHighFidelityAppDataFolder(); void restoreHighFidelityAppDataFolder(); - void selectTemporaryFolder(); + void createSnapshotFolder(); void killProcesses(); void startLocalServerProcesses(); @@ -39,11 +51,16 @@ public: void copyFolder(const QString& source, const QString& destination); +private slots: + void checkTime(); + private: + bool _automatedTestIsRunning{ false }; + QDir _appDataFolder; QDir _savedAppDataFolder; - QString _tempFolder; + QString _workingFolder; QString _snapshotFolder; QString _installationFolder; @@ -61,6 +78,13 @@ private: QString _branch; QString _user; + + std::vector _dayCheckboxes; + std::vector _timeEditCheckboxes; + std::vector _timeEdits; + QLabel* _workingFolderLabel; + + QTimer* _timer; }; #endif // hifi_testRunner_h \ No newline at end of file diff --git a/tools/auto-tester/src/ui/AutoTester.cpp b/tools/auto-tester/src/ui/AutoTester.cpp index 3c8be24f69..951ee1acd7 100644 --- a/tools/auto-tester/src/ui/AutoTester.cpp +++ b/tools/auto-tester/src/ui/AutoTester.cpp @@ -32,13 +32,35 @@ AutoTester::AutoTester(QWidget* parent) : QMainWindow(parent) { #ifndef Q_OS_WIN _ui.tabWidget->removeTab(1); #endif - //// Coming soon... + //// Coming soon to an auto-tester near you... //// _helpWindow.textBrowser->setText() } void AutoTester::setup() { _test = new Test(_ui.progressBar, _ui.checkBoxInteractiveMode); - _testRunner = new TestRunner(); + + std::vector dayCheckboxes; + dayCheckboxes.emplace_back(_ui.mondayCheckBox); + dayCheckboxes.emplace_back(_ui.tuesdayCheckBox); + dayCheckboxes.emplace_back(_ui.wednesdayCheckBox); + dayCheckboxes.emplace_back(_ui.thursdayCheckBox); + dayCheckboxes.emplace_back(_ui.fridayCheckBox); + dayCheckboxes.emplace_back(_ui.saturdayCheckBox); + dayCheckboxes.emplace_back(_ui.sundayCheckBox); + + std::vector timeEditCheckboxes; + timeEditCheckboxes.emplace_back(_ui.timeEdit1checkBox); + timeEditCheckboxes.emplace_back(_ui.timeEdit2checkBox); + timeEditCheckboxes.emplace_back(_ui.timeEdit3checkBox); + timeEditCheckboxes.emplace_back(_ui.timeEdit4checkBox); + + std::vector timeEdits; + timeEdits.emplace_back(_ui.timeEdit1); + timeEdits.emplace_back(_ui.timeEdit2); + timeEdits.emplace_back(_ui.timeEdit3); + timeEdits.emplace_back(_ui.timeEdit4); + + _testRunner = new TestRunner(dayCheckboxes, timeEditCheckboxes, timeEdits, _ui.workingFolderLabel); } void AutoTester::startTestsEvaluation(const bool isRunningFromCommandLine, @@ -103,6 +125,16 @@ void AutoTester::on_createTestRailRunButton_clicked() { _test->createTestRailRun(); } +void AutoTester::on_setWorkingFolderButton_clicked() { + _testRunner->setWorkingFolder(); +} + +void AutoTester::enableRunTabControls() { + _ui.runNowButton->setEnabled(true); + _ui.daysGroupBox->setEnabled(true); + _ui.timesGroupBox->setEnabled(true); +} + void AutoTester::on_runNowButton_clicked() { _testRunner->run(); } diff --git a/tools/auto-tester/src/ui/AutoTester.h b/tools/auto-tester/src/ui/AutoTester.h index 6c8641fa49..8ef238d953 100644 --- a/tools/auto-tester/src/ui/AutoTester.h +++ b/tools/auto-tester/src/ui/AutoTester.h @@ -47,6 +47,8 @@ public: void setBranchText(const QString& branch); QString getSelectedBranch(); + void enableRunTabControls(); + private slots: void on_tabWidget_currentChanged(int index); @@ -66,6 +68,7 @@ private slots: void on_createTestRailTestCasesButton_clicked(); void on_createTestRailRunButton_clicked(); + void on_setWorkingFolderButton_clicked(); void on_runNowButton_clicked(); void on_updateTestRailRunResultsButton_clicked(); diff --git a/tools/auto-tester/src/ui/AutoTester.ui b/tools/auto-tester/src/ui/AutoTester.ui index 8c95bba7d1..bc8fa27af6 100644 --- a/tools/auto-tester/src/ui/AutoTester.ui +++ b/tools/auto-tester/src/ui/AutoTester.ui @@ -43,7 +43,7 @@ - 1 + 2 @@ -190,11 +190,14 @@ Run + + false + - 200 - 200 - 93 + 10 + 70 + 161 28 @@ -202,6 +205,247 @@ Run now + + + false + + + + 20 + 150 + 91 + 241 + + + + Days + + + + + 10 + 210 + 80 + 17 + + + + Sunday + + + + + + 10 + 90 + 80 + 17 + + + + Wednesday + + + + + + 10 + 60 + 80 + 17 + + + + Tuesday + + + + + + 10 + 120 + 80 + 17 + + + + Thursday + + + + + + 10 + 150 + 80 + 17 + + + + Friday + + + + + + 10 + 180 + 80 + 17 + + + + Saturday + + + + + + 10 + 30 + 80 + 17 + + + + Monday + + + + + + false + + + + 130 + 150 + 181 + 191 + + + + Times + + + + + 30 + 20 + 118 + 22 + + + + + + + 30 + 60 + 118 + 22 + + + + + + + 30 + 100 + 118 + 22 + + + + + + + 30 + 140 + 118 + 22 + + + + + + + 10 + 23 + 21 + 17 + + + + + + + + + + 10 + 63 + 21 + 17 + + + + + + + + + + 10 + 103 + 21 + 17 + + + + + + + + + + 10 + 143 + 21 + 17 + + + + + + + + + + + 10 + 20 + 161 + 28 + + + + Set Working Folder + + + + + + 190 + 20 + 321 + 31 + + + + ####### + +