/**************************************************************************** ** ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Autotester project. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "testprofile.h" #include "test.h" #include #define PARALLEL_TESTS 15 /************************************************************************************************** **************************************************************************************************/ TestProfile::TestProfile(const QString &name) : QObject(), profileName(name), profileState(Saved), runState(NotRunning), currentTestToRun(0), currentParallelTestToRun(0), runningTestCount(0), stopRun(false) { QThreadPool::globalInstance()->setMaxThreadCount(PARALLEL_TESTS); } /************************************************************************************************** **************************************************************************************************/ TestProfile::~TestProfile() { foreach (Test* test, tests.values()) delete test; foreach(Test* test, unsavedAddedTests) delete test; } /************************************************************************************************** **************************************************************************************************/ void TestProfile::addTest(Test *test) { if (!test) return; if (unsavedRemovedTests.contains(test->name())) unsavedRemovedTests.removeAll(test->name()); if (tests.contains(test->name()) || unsavedAddedTests.contains(test->name())) return; unsavedAddedTests.insert(test->name(), test); if (profileState == Saved) { profileState = Unsaved; emit stateChanged(profileState); } } /************************************************************************************************** **************************************************************************************************/ void TestProfile::removeTest(const QString &testName) { if (tests.contains(testName)) { unsavedRemovedTests.append(testName); } else if (unsavedAddedTests.contains(testName)) { delete unsavedAddedTests[testName]; unsavedAddedTests.remove(testName); } if (profileState == Saved) { profileState = Unsaved; emit stateChanged(profileState); } } /************************************************************************************************** **************************************************************************************************/ void TestProfile::run(Test *test) { if (runState != NotRunning || !test->isAvailable()) return; runState = Running; emit runningStateChanged(); testsToRun.clear(); parallelTestsToRun.clear(); testsToRun.insert(test->name(), test); foreach (Test* test, testsToRun.values()) test->reset(); currentTestToRun = 0; currentParallelTestToRun = 0; runNextTest(); } /************************************************************************************************** **************************************************************************************************/ void TestProfile::run() { runState = Running; emit runningStateChanged(); testsToRun.clear(); parallelTestsToRun.clear(); QList toRun = tests.values() + unsavedAddedTests.values(); foreach (Test *test, toRun) { if (test->isAvailable() && !unsavedRemovedTests.contains(test->name())) { if (test->runInParallel()) { parallelTestsToRun.insert(test->name(), test); } else { testsToRun.insert(test->name(), test); } } } foreach (Test* test, testsToRun.values()) test->reset(); foreach (Test* test, parallelTestsToRun.values()) test->reset(); currentTestToRun = 0; currentParallelTestToRun = 0; runNextTest(); } /************************************************************************************************** **************************************************************************************************/ void TestProfile::cancelRun(bool cancelOnlyCurrentTest) { stopRun = !cancelOnlyCurrentTest; if (currentTestToRun - 1 >= 0) testsToRun.values().at(currentTestToRun - 1)->cancelRun(); if (stopRun) { foreach (Test *test, tests) { if (test->status() == Test::Building || test->status() == Test::Running) test->cancelRun(); } } } /************************************************************************************************** **************************************************************************************************/ void TestProfile::runNextTest() { if (((currentTestToRun >= testsToRun.count() && currentParallelTestToRun >= parallelTestsToRun.count()) || stopRun) && runningTestCount == 0) { stopRun = false; runState = NotRunning; emit runningStateChanged(); return; } if (stopRun) return; while ((testsToRun.count() > currentTestToRun || parallelTestsToRun.count() > currentParallelTestToRun) && runningTestCount < PARALLEL_TESTS) { Test *test = 0; if (parallelTestsToRun.count() > currentParallelTestToRun) { test = parallelTestsToRun.values().at(currentParallelTestToRun); currentParallelTestToRun++; } else if (testsToRun.count() > currentTestToRun) { if (runningTestCount != 0) return; // We can't run in parallel with another test test = testsToRun.values().at(currentTestToRun); currentTestToRun++; } else { return; } connect(test, SIGNAL(statusChanged(Test::TestStatus)), this, SLOT(onRunningTestStatusChanged(Test::TestStatus))); runningTestCount++; QtConcurrent::run(test, &Test::run); } } /************************************************************************************************** **************************************************************************************************/ void TestProfile::onRunningTestStatusChanged(Test::TestStatus status) { Q_UNUSED(status); Test *test = qobject_cast(sender()); if (!test) return; if (test->status() != Test::Building && test->status() != Test::Running) { disconnect(test, SIGNAL(statusChanged(Test::TestStatus)), this, SLOT(onRunningTestStatusChanged(Test::TestStatus))); runningTestCount--; runNextTest(); } } /************************************************************************************************** **************************************************************************************************/ void TestProfile::save() { foreach (Test *test, unsavedAddedTests.values()) tests.insert(test->name(), test); unsavedAddedTests.clear(); foreach (const QString &test, unsavedRemovedTests) { delete tests[test]; tests.remove(test); } unsavedRemovedTests.clear(); profileState = Saved; emit stateChanged(profileState); } /************************************************************************************************** **************************************************************************************************/ void TestProfile::restore() { foreach(Test* test, unsavedAddedTests) delete test; unsavedAddedTests.clear(); unsavedRemovedTests.clear(); profileState = Saved; emit stateChanged(profileState); } void TestProfile::setVariant(const QString& var) { buildVariant = var; }