// // Created by Bradley Austin Davis on 2016/12/12 // Copyright 2013-2016 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 "TestScriptingInterface.h" #include #include #include #include #include #include #include #include #include #include "Application.h" Q_LOGGING_CATEGORY(trace_test, "trace.test") TestScriptingInterface* TestScriptingInterface::getInstance() { static TestScriptingInterface sharedInstance; return &sharedInstance; } void TestScriptingInterface::quit() { qApp->quit(); } void TestScriptingInterface::waitForTextureIdle() { waitForCondition(0, []()->bool { return (0 == gpu::Context::getTexturePendingGPUTransferCount()); }); } void TestScriptingInterface::waitForDownloadIdle() { waitForCondition(0, []()->bool { return (0 == ResourceCache::getLoadingRequestCount()) && (0 == ResourceCache::getPendingRequestCount()); }); } void TestScriptingInterface::waitForProcessingIdle() { auto statTracker = DependencyManager::get(); waitForCondition(0, [statTracker]()->bool { return (0 == statTracker->getStat("Processing").toInt() && 0 == statTracker->getStat("PendingProcessing").toInt()); }); } void TestScriptingInterface::waitIdle() { // Initial wait for some incoming work QThread::sleep(1); waitForDownloadIdle(); waitForProcessingIdle(); waitForTextureIdle(); } bool TestScriptingInterface::loadTestScene(QString scene) { if (QThread::currentThread() != thread()) { bool result; BLOCKING_INVOKE_METHOD(this, "loadTestScene", Q_RETURN_ARG(bool, result), Q_ARG(QString, scene)); return result; } static const QString TEST_ROOT = "https://raw.githubusercontent.com/highfidelity/hifi_tests/master/"; static const QString TEST_BINARY_ROOT = "https://hifi-public.s3.amazonaws.com/test_scene_data/"; static const QString TEST_SCRIPTS_ROOT = TEST_ROOT + "scripts/"; static const QString TEST_SCENES_ROOT = TEST_ROOT + "scenes/"; DependencyManager::get()->setUrlPrefixOverride("atp:/", TEST_BINARY_ROOT + scene + ".atp/"); auto tree = qApp->getEntities()->getTree(); auto treeIsClient = tree->getIsClient(); // Force the tree to accept the load regardless of permissions tree->setIsClient(false); auto result = tree->readFromURL(TEST_SCENES_ROOT + scene + ".json"); tree->setIsClient(treeIsClient); return result; } bool TestScriptingInterface::startTracing(QString logrules) { if (!logrules.isEmpty()) { QLoggingCategory::setFilterRules(logrules); } if (!DependencyManager::isSet()) { return false; } DependencyManager::get()->startTracing(); return true; } bool TestScriptingInterface::stopTracing(QString filename) { if (!DependencyManager::isSet()) { return false; } auto tracer = DependencyManager::get(); tracer->stopTracing(); tracer->serialize(filename); return true; } void TestScriptingInterface::clear() { qApp->postLambdaEvent([] { qApp->getEntities()->clear(); }); } bool TestScriptingInterface::waitForConnection(qint64 maxWaitMs) { // Wait for any previous connection to die QThread::sleep(1); return waitForCondition(maxWaitMs, []()->bool { return DependencyManager::get()->getDomainHandler().isConnected(); }); } void TestScriptingInterface::wait(int milliseconds) { QThread::msleep(milliseconds); } bool TestScriptingInterface::waitForCondition(qint64 maxWaitMs, std::function condition) { QElapsedTimer elapsed; elapsed.start(); while (!condition()) { if (maxWaitMs > 0 && elapsed.elapsed() > maxWaitMs) { return false; } QThread::msleep(1); } return condition(); } void TestScriptingInterface::startTraceEvent(QString name) { tracing::traceEvent(trace_test(), name, tracing::DurationBegin, ""); } void TestScriptingInterface::endTraceEvent(QString name) { tracing::traceEvent(trace_test(), name, tracing::DurationEnd); } void TestScriptingInterface::savePhysicsSimulationStats(QString originalPath) { QString path = FileUtils::replaceDateTimeTokens(originalPath); path = FileUtils::computeDocumentPath(path); if (!FileUtils::canCreateFile(path)) { return; } qApp->saveNextPhysicsStats(path); } void TestScriptingInterface::profileRange(const QString& name, QScriptValue fn) { PROFILE_RANGE(script, name); fn.call(); } void TestScriptingInterface::clearCaches() { qApp->reloadResourceCaches(); } // Writes a JSON object from javascript to a file void TestScriptingInterface::saveObject(QVariant variant, const QString& filename) { if (_testResultsLocation.isNull()) { return; } QJsonDocument jsonDocument; jsonDocument = QJsonDocument::fromVariant(variant); if (jsonDocument.isNull()) { return; } QByteArray jsonData = jsonDocument.toJson(); // Append trailing slash if needed if (_testResultsLocation.right(1) != "/") { _testResultsLocation += "/"; } QString filepath = QDir::cleanPath(_testResultsLocation + filename); QFile file(filepath); file.open(QFile::WriteOnly); file.write(jsonData); file.close(); }