From 1c1b34c3aa9cbdf37287a4be2309d4889a518e45 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Fri, 25 Jan 2019 11:30:43 -0800 Subject: [PATCH] WIP - downloading Installer (APK) --- tools/nitpick/src/Nitpick.cpp | 17 +-- tools/nitpick/src/Nitpick.h | 1 - tools/nitpick/src/TestRunner.cpp | 103 +++++++++++++++++- tools/nitpick/src/TestRunner.h | 24 ++++ tools/nitpick/src/TestRunnerDesktop.cpp | 139 ++++-------------------- tools/nitpick/src/TestRunnerDesktop.h | 46 +++----- tools/nitpick/src/TestRunnerMobile.cpp | 43 +++++++- tools/nitpick/src/TestRunnerMobile.h | 17 +-- tools/nitpick/ui/Nitpick.ui | 28 ++++- 9 files changed, 247 insertions(+), 171 deletions(-) diff --git a/tools/nitpick/src/Nitpick.cpp b/tools/nitpick/src/Nitpick.cpp index ccbb2da762..6db107b9a7 100644 --- a/tools/nitpick/src/Nitpick.cpp +++ b/tools/nitpick/src/Nitpick.cpp @@ -35,8 +35,10 @@ Nitpick::Nitpick(QWidget* parent) : QMainWindow(parent) { _ui.tabWidget->removeTab(1); #endif - _ui.statusLabel->setText(""); - _ui.plainTextEdit->setReadOnly(true); + _ui.statusLabelOnDesktop->setText(""); + _ui.statusLabelOnMobile->setText(""); + + _ui.plainTextEdit->setReadOnly(true); setWindowTitle("Nitpick - v2.0.1"); } @@ -96,7 +98,8 @@ void Nitpick::setup() { _ui.checkBoxServerless, _ui.runLatestOnDesktopCheckBox, _ui.urlOnDesktopLineEdit, - _ui.runNowPushbutton + _ui.runNowPushbutton, + _ui.statusLabelOnDesktop ); if (_testRunnerMobile) { @@ -108,7 +111,9 @@ void Nitpick::setup() { _ui.pullFolderPushbutton, _ui.detectedDeviceLabel, _ui.folderLineEdit, - _ui.downloadAPKPushbutton + _ui.downloadAPKPushbutton, + _ui.runLatestOnMobileCheckBox, + _ui.urlOnMobileLineEdit ); } @@ -335,10 +340,6 @@ QString Nitpick::getSelectedBranch() { return _ui.branchLineEdit->text(); } -void Nitpick::updateStatusLabel(const QString& status) { - _ui.statusLabel->setText(status); -} - void Nitpick::appendLogWindow(const QString& message) { _ui.plainTextEdit->appendPlainText(message); } diff --git a/tools/nitpick/src/Nitpick.h b/tools/nitpick/src/Nitpick.h index 18916a1f03..f54754de2e 100644 --- a/tools/nitpick/src/Nitpick.h +++ b/tools/nitpick/src/Nitpick.h @@ -51,7 +51,6 @@ public: void enableRunTabControls(); - void updateStatusLabel(const QString& status); void appendLogWindow(const QString& message); private slots: diff --git a/tools/nitpick/src/TestRunner.cpp b/tools/nitpick/src/TestRunner.cpp index 3089b59e2c..6d3a3e1b84 100644 --- a/tools/nitpick/src/TestRunner.cpp +++ b/tools/nitpick/src/TestRunner.cpp @@ -49,6 +49,108 @@ void TestRunner::downloadBuildXml(void* caller) { nitpick->downloadFiles(urls, _workingFolder, filenames, caller); } +void TestRunner::parseBuildInformation() { + try { + QDomDocument domDocument; + QString filename{ _workingFolder + "/" + DEV_BUILD_XML_FILENAME }; + QFile file(filename); + if (!file.open(QIODevice::ReadOnly) || !domDocument.setContent(&file)) { + throw QString("Could not open " + filename); + } + + QString platformOfInterest; +#ifdef Q_OS_WIN + platformOfInterest = "windows"; +#elif defined(Q_OS_MAC) + platformOfInterest = "mac"; +#endif + + QDomElement element = domDocument.documentElement(); + + // Verify first element is "projects" + if (element.tagName() != "projects") { + throw("File seems to be in wrong format"); + } + + element = element.firstChild().toElement(); + if (element.tagName() != "project") { + throw("File seems to be in wrong format"); + } + + if (element.attribute("name") != "interface") { + throw("File is not from 'interface' build"); + } + + // Now loop over the platforms, looking for ours + bool platformFound{ false }; + element = element.firstChild().toElement(); + while (!element.isNull()) { + if (element.attribute("name") == platformOfInterest) { + platformFound = true; + break; + } + element = element.nextSibling().toElement(); + } + + if (!platformFound) { + throw("File seems to be in wrong format - platform " + platformOfInterest + " not found"); + } + + element = element.firstChild().toElement(); + if (element.tagName() != "build") { + throw("File seems to be in wrong format"); + } + + // Next element should be the version + element = element.firstChild().toElement(); + if (element.tagName() != "version") { + throw("File seems to be in wrong format"); + } + + // Add the build number to the end of the filename + _buildInformation.build = element.text(); + + // First sibling should be stable_version + element = element.nextSibling().toElement(); + if (element.tagName() != "stable_version") { + throw("File seems to be in wrong format"); + } + + // Next sibling should be url + element = element.nextSibling().toElement(); + if (element.tagName() != "url") { + throw("File seems to be in wrong format"); + } + _buildInformation.url = element.text(); + + } + catch (QString errorMessage) { + QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), errorMessage); + exit(-1); + } + catch (...) { + QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "unknown error"); + exit(-1); + } +} + +QString TestRunner::getInstallerNameFromURL(const QString& url) { + // An example URL: https://deployment.highfidelity.com/jobs/pr-build/label%3Dwindows/13023/HighFidelity-Beta-Interface-PR14006-be76c43.exe + // On Mac, replace `exe` with `dmg` + try { + QStringList urlParts = url.split("/"); + return urlParts[urlParts.size() - 1]; + } + catch (QString errorMessage) { + QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), errorMessage); + exit(-1); + } + catch (...) { + QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "unknown error"); + exit(-1); + } +} + void Worker::setCommandLine(const QString& commandLine) { _commandLine = commandLine; } @@ -58,4 +160,3 @@ int Worker::runCommand() { emit commandComplete(); return result; } - diff --git a/tools/nitpick/src/TestRunner.h b/tools/nitpick/src/TestRunner.h index 40f8a7d95a..0453bcf491 100644 --- a/tools/nitpick/src/TestRunner.h +++ b/tools/nitpick/src/TestRunner.h @@ -11,23 +11,47 @@ #ifndef hifi_testRunner_h #define hifi_testRunner_h +#include #include +#include #include class Worker; +class BuildInformation { +public: + QString build; + QString url; +}; + class TestRunner { public: void setWorkingFolder(QLabel* workingFolderLabel); void downloadBuildXml(void* caller); + void parseBuildInformation(); + QString getInstallerNameFromURL(const QString& url); protected: + QLabel* _workingFolderLabel; + QLabel* _statusLabel; + QLineEdit* _url; + QCheckBox* _runLatest; + QString _workingFolder; const QString DEV_BUILD_XML_URL{ "https://highfidelity.com/dev-builds.xml" }; const QString DEV_BUILD_XML_FILENAME{ "dev-builds.xml" }; bool buildXMLDownloaded; + BuildInformation _buildInformation; + +#ifdef Q_OS_WIN + const QString INSTALLER_FILENAME_LATEST{ "HighFidelity-Beta-latest-dev.exe" }; +#elif defined(Q_OS_MAC) + const QString INSTALLER_FILENAME_LATEST{ "HighFidelity-Beta-latest-dev.dmg" }; +#else + const QString INSTALLER_FILENAME_LATEST{ "" }; +#endif }; class Worker : public QObject { diff --git a/tools/nitpick/src/TestRunnerDesktop.cpp b/tools/nitpick/src/TestRunnerDesktop.cpp index 6ddf452b0a..eb371f7e85 100644 --- a/tools/nitpick/src/TestRunnerDesktop.cpp +++ b/tools/nitpick/src/TestRunnerDesktop.cpp @@ -21,16 +21,20 @@ #include "Nitpick.h" extern Nitpick* nitpick; -TestRunnerDesktop::TestRunnerDesktop(std::vector dayCheckboxes, - std::vector timeEditCheckboxes, - std::vector timeEdits, - QLabel* workingFolderLabel, - QCheckBox* runServerless, - QCheckBox* runLatest, - QLineEdit* url, - QPushButton* runNow, - QObject* parent) : - QObject(parent) { +TestRunnerDesktop::TestRunnerDesktop( + std::vector dayCheckboxes, + std::vector timeEditCheckboxes, + std::vector timeEdits, + QLabel* workingFolderLabel, + QCheckBox* runServerless, + QCheckBox* runLatest, + QLineEdit* url, + QPushButton* runNow, + QLabel* statusLabel, + + QObject* parent +) : QObject(parent) +{ _dayCheckboxes = dayCheckboxes; _timeEditCheckboxes = timeEditCheckboxes; _timeEdits = timeEdits; @@ -39,6 +43,7 @@ TestRunnerDesktop::TestRunnerDesktop(std::vector dayCheckboxes, _runLatest = runLatest; _url = url; _runNow = runNow; + _statusLabel = statusLabel; _installerThread = new QThread(); _installerWorker = new InstallerWorker(); @@ -176,7 +181,7 @@ void TestRunnerDesktop::run() { // This will be restored at the end of the tests saveExistingHighFidelityAppDataFolder(); - updateStatusLabel("Downloading Build XML"); + _statusLabel->setText("Downloading Build XML"); downloadBuildXml((void*)this); // `downloadComplete` will run after download has completed @@ -204,7 +209,7 @@ void TestRunnerDesktop::downloadComplete() { filenames << _installerFilename; } - updateStatusLabel("Downloading installer"); + _statusLabel->setText("Downloading installer"); nitpick->downloadFiles(urls, _workingFolder, filenames, (void*)this); @@ -216,7 +221,7 @@ void TestRunnerDesktop::downloadComplete() { QString("%1").arg(_testStartDateTime.time().minute(), 2, 10, QChar('0')) + ", on " + _testStartDateTime.date().toString("ddd, MMM d, yyyy")); - updateStatusLabel("Installing"); + _statusLabel->setText("Installing"); // Kill any existing processes that would interfere with installation killProcesses(); @@ -278,7 +283,7 @@ void TestRunnerDesktop::installationComplete() { createSnapshotFolder(); - updateStatusLabel("Running tests"); + _statusLabel->setText("Running tests"); if (!_runServerless->isChecked()) { startLocalServerProcesses(); @@ -547,7 +552,7 @@ void TestRunnerDesktop::interfaceExecutionComplete() { } void TestRunnerDesktop::evaluateResults() { - updateStatusLabel("Evaluating results"); + _statusLabel->setText("Evaluating results"); nitpick->startTestsEvaluation(false, true, _snapshotFolder, _branch, _user); } @@ -555,7 +560,7 @@ void TestRunnerDesktop::automaticTestRunEvaluationComplete(QString zippedFolder, addBuildNumberToResults(zippedFolder); restoreHighFidelityAppDataFolder(); - updateStatusLabel("Testing complete"); + _statusLabel->setText("Testing complete"); QDateTime currentDateTime = QDateTime::currentDateTime(); @@ -656,10 +661,6 @@ void TestRunnerDesktop::checkTime() { } } -void TestRunnerDesktop::updateStatusLabel(const QString& message) { - nitpick->updateStatusLabel(message); -} - void TestRunnerDesktop::appendLog(const QString& message) { if (!_logFile.open(QIODevice::Append | QIODevice::Text)) { QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), @@ -674,21 +675,6 @@ void TestRunnerDesktop::appendLog(const QString& message) { nitpick->appendLogWindow(message); } -QString TestRunnerDesktop::getInstallerNameFromURL(const QString& url) { - // An example URL: https://deployment.highfidelity.com/jobs/pr-build/label%3Dwindows/13023/HighFidelity-Beta-Interface-PR14006-be76c43.exe - // On Mac, replace `exe` with `dmg` - try { - QStringList urlParts = url.split("/"); - return urlParts[urlParts.size() - 1]; - } catch (QString errorMessage) { - QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), errorMessage); - exit(-1); - } catch (...) { - QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "unknown error"); - exit(-1); - } -} - QString TestRunnerDesktop::getPRNumberFromURL(const QString& url) { try { QStringList urlParts = url.split("/"); @@ -709,86 +695,3 @@ QString TestRunnerDesktop::getPRNumberFromURL(const QString& url) { exit(-1); } } - -void TestRunnerDesktop::parseBuildInformation() { - try { - QDomDocument domDocument; - QString filename{ _workingFolder + "/" + DEV_BUILD_XML_FILENAME }; - QFile file(filename); - if (!file.open(QIODevice::ReadOnly) || !domDocument.setContent(&file)) { - throw QString("Could not open " + filename); - } - - QString platformOfInterest; -#ifdef Q_OS_WIN - platformOfInterest = "windows"; -#elif defined(Q_OS_MAC) - platformOfInterest = "mac"; -#endif - - QDomElement element = domDocument.documentElement(); - - // Verify first element is "projects" - if (element.tagName() != "projects") { - throw("File seems to be in wrong format"); - } - - element = element.firstChild().toElement(); - if (element.tagName() != "project") { - throw("File seems to be in wrong format"); - } - - if (element.attribute("name") != "interface") { - throw("File is not from 'interface' build"); - } - - // Now loop over the platforms, looking for ours - bool platformFound{ false }; - element = element.firstChild().toElement(); - while (!element.isNull()) { - if (element.attribute("name") == platformOfInterest) { - platformFound = true; - break; - } - element = element.nextSibling().toElement(); - } - - if (!platformFound) { - throw("File seems to be in wrong format - platform " + platformOfInterest + " not found"); - } - - element = element.firstChild().toElement(); - if (element.tagName() != "build") { - throw("File seems to be in wrong format"); - } - - // Next element should be the version - element = element.firstChild().toElement(); - if (element.tagName() != "version") { - throw("File seems to be in wrong format"); - } - - // Add the build number to the end of the filename - _buildInformation.build = element.text(); - - // First sibling should be stable_version - element = element.nextSibling().toElement(); - if (element.tagName() != "stable_version") { - throw("File seems to be in wrong format"); - } - - // Next sibling should be url - element = element.nextSibling().toElement(); - if (element.tagName() != "url") { - throw("File seems to be in wrong format"); - } - _buildInformation.url = element.text(); - - } catch (QString errorMessage) { - QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), errorMessage); - exit(-1); - } catch (...) { - QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "unknown error"); - exit(-1); - } -} diff --git a/tools/nitpick/src/TestRunnerDesktop.h b/tools/nitpick/src/TestRunnerDesktop.h index 467162da9f..83551cef0e 100644 --- a/tools/nitpick/src/TestRunnerDesktop.h +++ b/tools/nitpick/src/TestRunnerDesktop.h @@ -11,10 +11,8 @@ #ifndef hifi_testRunnerDesktop_h #define hifi_testRunnerDesktop_h -#include #include #include -#include #include #include #include @@ -23,27 +21,25 @@ #include "TestRunner.h" -class BuildInformation { -public: - QString build; - QString url; -}; - class InterfaceWorker; class InstallerWorker; class TestRunnerDesktop : public QObject, public TestRunner { Q_OBJECT public: - explicit TestRunnerDesktop(std::vector dayCheckboxes, - std::vector timeEditCheckboxes, - std::vector timeEdits, - QLabel* workingFolderLabel, - QCheckBox* runServerless, - QCheckBox* runLatest, - QLineEdit* url, - QPushButton* runNow, - QObject* parent = 0); + explicit TestRunnerDesktop( + std::vector dayCheckboxes, + std::vector timeEditCheckboxes, + std::vector timeEdits, + QLabel* workingFolderLabel, + QCheckBox* runServerless, + QCheckBox* runLatest, + QLineEdit* url, + QPushButton* runNow, + QLabel* statusLabel, + + QObject* parent = 0 + ); ~TestRunnerDesktop(); @@ -71,14 +67,10 @@ public: void copyFolder(const QString& source, const QString& destination); - void updateStatusLabel(const QString& message); void appendLog(const QString& message); - QString getInstallerNameFromURL(const QString& url); QString getPRNumberFromURL(const QString& url); - void parseBuildInformation(); - private slots: void checkTime(); void installationComplete(); @@ -92,14 +84,6 @@ signals: private: bool _automatedTestIsRunning{ false }; -#ifdef Q_OS_WIN - const QString INSTALLER_FILENAME_LATEST{ "HighFidelity-Beta-latest-dev.exe" }; -#elif defined(Q_OS_MAC) - const QString INSTALLER_FILENAME_LATEST{ "HighFidelity-Beta-latest-dev.dmg" }; -#else - const QString INSTALLER_FILENAME_LATEST{ "" }; -#endif - QString _installerURL; QString _installerFilename; @@ -120,8 +104,6 @@ private: std::vector _timeEdits; QLabel* _workingFolderLabel; QCheckBox* _runServerless; - QCheckBox* _runLatest; - QLineEdit* _url; QPushButton* _runNow; QTimer* _timer; @@ -134,8 +116,6 @@ private: InstallerWorker* _installerWorker; InterfaceWorker* _interfaceWorker; - - BuildInformation _buildInformation; }; class InstallerWorker : public Worker { diff --git a/tools/nitpick/src/TestRunnerMobile.cpp b/tools/nitpick/src/TestRunnerMobile.cpp index a269c15b26..85aaeec609 100644 --- a/tools/nitpick/src/TestRunnerMobile.cpp +++ b/tools/nitpick/src/TestRunnerMobile.cpp @@ -23,6 +23,9 @@ TestRunnerMobile::TestRunnerMobile( QLabel* detectedDeviceLabel, QLineEdit *folderLineEdit, QPushButton* downloadAPKPushbutton, + QCheckBox* runLatest, + QLineEdit* url, + QObject* parent ) : QObject(parent) { @@ -32,6 +35,8 @@ TestRunnerMobile::TestRunnerMobile( _detectedDeviceLabel = detectedDeviceLabel; _folderLineEdit = folderLineEdit; _downloadAPKPushbutton = downloadAPKPushbutton; + _runLatest = runLatest; + _url = url; folderLineEdit->setText("/sdcard/DCIM/TEST"); } @@ -111,10 +116,44 @@ void TestRunnerMobile::downloadComplete() { // Download of Build XML has completed buildXMLDownloaded = true; - // Download the High Fidelity APK - int df = 546; + // Download the High Fidelity installer + QStringList urls; + QStringList filenames; + if (_runLatest->isChecked()) { + parseBuildInformation(); + + _installerFilename = INSTALLER_FILENAME_LATEST; + + urls << _buildInformation.url; + filenames << _installerFilename; + } else { + QString urlText = _url->text(); + urls << urlText; + _installerFilename = getInstallerNameFromURL(urlText); + filenames << _installerFilename; + } + + _statusLabel->setText("Downloading installer"); + + //// nitpick->downloadFiles(urls, _workingFolder, filenames, (void*)this); + + // `downloadComplete` will run again after download has completed + + } else { + // Download of Installer has completed +//// appendLog(QString("Tests started at ") + QString::number(_testStartDateTime.time().hour()) + ":" + +//// QString("%1").arg(_testStartDateTime.time().minute(), 2, 10, QChar('0')) + ", on " + +//// _testStartDateTime.date().toString("ddd, MMM d, yyyy")); + + _statusLabel->setText("Installing"); + + // Kill any existing processes that would interfere with installation +//// killProcesses(); + +//// runInstaller(); } } + void TestRunnerMobile::pullFolder() { QString command = _adbCommand + " pull " + _folderLineEdit->text() + " " + _workingFolder + " >" + _workingFolder + "/pullOutput.txt"; system(command.toStdString().c_str()); diff --git a/tools/nitpick/src/TestRunnerMobile.h b/tools/nitpick/src/TestRunnerMobile.h index f0d79ae177..8d08eda191 100644 --- a/tools/nitpick/src/TestRunnerMobile.h +++ b/tools/nitpick/src/TestRunnerMobile.h @@ -12,7 +12,6 @@ #define hifi_testRunnerMobile_h #include -#include #include #include @@ -22,12 +21,15 @@ class TestRunnerMobile : public QObject, public TestRunner { Q_OBJECT public: explicit TestRunnerMobile( - QLabel* workingFolderLabel, - QPushButton *connectDeviceButton, - QPushButton *pullFolderButton, - QLabel* detectedDeviceLabel, - QLineEdit* folderLineEdit, + QLabel* workingFolderLabel, + QPushButton *connectDeviceButton, + QPushButton *pullFolderButton, + QLabel* detectedDeviceLabel, + QLineEdit *folderLineEdit, QPushButton* downloadAPKPushbutton, + QCheckBox* runLatest, + QLineEdit* url, + QObject* parent = 0 ); ~TestRunnerMobile(); @@ -39,7 +41,6 @@ public: void pullFolder(); private: - QLabel* _workingFolderLabel; QPushButton* _connectDeviceButton; QPushButton* _pullFolderButton; QLabel* _detectedDeviceLabel; @@ -53,6 +54,8 @@ private: const QString _adbExe{ "adb" }; #endif + QString _installerFilename; + QString _adbCommand; }; diff --git a/tools/nitpick/ui/Nitpick.ui b/tools/nitpick/ui/Nitpick.ui index 78d9e8613e..1fa2b3f9d7 100644 --- a/tools/nitpick/ui/Nitpick.ui +++ b/tools/nitpick/ui/Nitpick.ui @@ -469,7 +469,7 @@ Status: - + 350 @@ -683,6 +683,32 @@ Download APK + + + + 290 + 20 + 41 + 31 + + + + Status: + + + + + + 340 + 20 + 271 + 31 + + + + ####### + +