overte/tools/nitpick/src/TestRunner.cpp
2019-03-01 12:32:55 -08:00

199 lines
6.3 KiB
C++

//
// TestRunner.cpp
//
// Created by Nissim Hadar on 23 Jan 2019.
// Copyright 2013 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "TestRunner.h"
#include <QFileDialog>
#include "Nitpick.h"
extern Nitpick* nitpick;
TestRunner::TestRunner(
QLabel* workingFolderLabel,
QLabel* statusLabel,
QCheckBox* usePreviousInstallationCheckBox,
QCheckBox* runLatest,
QLineEdit* url,
QCheckBox* runFullSuite,
QLineEdit* scriptURL
) {
_workingFolderLabel = workingFolderLabel;
_statusLabel = statusLabel;
_usePreviousInstallationCheckBox = usePreviousInstallationCheckBox;
_runLatest = runLatest;
_url = url;
_runFullSuite = runFullSuite;
_scriptURL = scriptURL;
_downloader = new Downloader();
}
void TestRunner::setWorkingFolder(QLabel* workingFolderLabel) {
// 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 working folder for temporary files", parent,
QFileDialog::ShowDirsOnly);
// If user canceled then restore previous selection and return
if (_workingFolder == "") {
_workingFolder = previousSelection;
return;
}
workingFolderLabel->setText(QDir::toNativeSeparators(_workingFolder));
// This file is used for debug purposes.
_logFile.setFileName(_workingFolder + "/log.txt");
}
void TestRunner::downloadBuildXml(void* caller) {
// Download the latest High Fidelity build XML.
// Note that this is not needed for PR builds (or whenever `Run Latest` is unchecked)
// It is still downloaded, to simplify the flow
buildXMLDownloaded = false;
QStringList urls;
QStringList filenames;
urls << DEV_BUILD_XML_URL;
filenames << DEV_BUILD_XML_FILENAME;
_downloader->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 TestRunner::appendLog(const QString& message) {
if (!_logFile.open(QIODevice::Append | QIODevice::Text)) {
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__),
"Could not open the log file");
exit(-1);
}
_logFile.write(message.toStdString().c_str());
_logFile.write("\n");
_logFile.close();
nitpick->appendLogWindow(message);
}
void Worker::setCommandLine(const QString& commandLine) {
_commandLine = commandLine;
}
int Worker::runCommand() {
int result = system(_commandLine.toStdString().c_str());
emit commandComplete();
return result;
}