WIP - downloading Installer (APK)

This commit is contained in:
NissimHadar 2019-01-25 11:30:43 -08:00
parent 50e7adf32c
commit 1c1b34c3aa
9 changed files with 247 additions and 171 deletions

View file

@ -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);
}

View file

@ -51,7 +51,6 @@ public:
void enableRunTabControls();
void updateStatusLabel(const QString& status);
void appendLogWindow(const QString& message);
private slots:

View file

@ -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;
}

View file

@ -11,23 +11,47 @@
#ifndef hifi_testRunner_h
#define hifi_testRunner_h
#include <QCheckBox>
#include <QLabel>
#include <QLineEdit>
#include <QObject>
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 {

View file

@ -21,16 +21,20 @@
#include "Nitpick.h"
extern Nitpick* nitpick;
TestRunnerDesktop::TestRunnerDesktop(std::vector<QCheckBox*> dayCheckboxes,
std::vector<QCheckBox*> timeEditCheckboxes,
std::vector<QTimeEdit*> timeEdits,
QLabel* workingFolderLabel,
QCheckBox* runServerless,
QCheckBox* runLatest,
QLineEdit* url,
QPushButton* runNow,
QObject* parent) :
QObject(parent) {
TestRunnerDesktop::TestRunnerDesktop(
std::vector<QCheckBox*> dayCheckboxes,
std::vector<QCheckBox*> timeEditCheckboxes,
std::vector<QTimeEdit*> 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<QCheckBox*> 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);
}
}

View file

@ -11,10 +11,8 @@
#ifndef hifi_testRunnerDesktop_h
#define hifi_testRunnerDesktop_h
#include <QCheckBox>
#include <QDir>
#include <QLabel>
#include <QLineEdit>
#include <QObject>
#include <QPushButton>
#include <QThread>
@ -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<QCheckBox*> dayCheckboxes,
std::vector<QCheckBox*> timeEditCheckboxes,
std::vector<QTimeEdit*> timeEdits,
QLabel* workingFolderLabel,
QCheckBox* runServerless,
QCheckBox* runLatest,
QLineEdit* url,
QPushButton* runNow,
QObject* parent = 0);
explicit TestRunnerDesktop(
std::vector<QCheckBox*> dayCheckboxes,
std::vector<QCheckBox*> timeEditCheckboxes,
std::vector<QTimeEdit*> 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<QTimeEdit*> _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 {

View file

@ -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());

View file

@ -12,7 +12,6 @@
#define hifi_testRunnerMobile_h
#include <QLabel>
#include <QLineEdit>
#include <QObject>
#include <QPushButton>
@ -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;
};

View file

@ -469,7 +469,7 @@
<string>Status:</string>
</property>
</widget>
<widget class="QLabel" name="statusLabel">
<widget class="QLabel" name="statusLabelOnDesktop">
<property name="geometry">
<rect>
<x>350</x>
@ -683,6 +683,32 @@
<string>Download APK</string>
</property>
</widget>
<widget class="QLabel" name="workingFolderLabel_4">
<property name="geometry">
<rect>
<x>290</x>
<y>20</y>
<width>41</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>Status:</string>
</property>
</widget>
<widget class="QLabel" name="statusLabelOnMobile">
<property name="geometry">
<rect>
<x>340</x>
<y>20</y>
<width>271</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>#######</string>
</property>
</widget>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">