summaryrefslogtreecommitdiffstats
path: root/QA
diff options
context:
space:
mode:
Diffstat (limited to 'QA')
-rw-r--r--QA/Checker/CppUnitTestResultPrinter.cpp150
-rw-r--r--QA/Checker/CppUnitTestResultPrinter.h58
-rw-r--r--QA/Checker/IO.cpp86
-rw-r--r--QA/Checker/IO.h6
-rw-r--r--QA/Checker/SConscript33
-rw-r--r--QA/Checker/checker.cpp214
-rwxr-xr-xQA/CrossDistributionTest/VagrantCrossDistributionTest.py90
-rw-r--r--QA/CrossDistributionTest/playbook.yml33
-rw-r--r--QA/SConscript6
-rw-r--r--QA/UnitTest/SConscript49
-rw-r--r--QA/UnitTest/template/FooTest.cpp26
11 files changed, 578 insertions, 173 deletions
diff --git a/QA/Checker/CppUnitTestResultPrinter.cpp b/QA/Checker/CppUnitTestResultPrinter.cpp
new file mode 100644
index 0000000..75eea72
--- /dev/null
+++ b/QA/Checker/CppUnitTestResultPrinter.cpp
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+ // Copyright 2005, Google Inc.
+ // All rights reserved.
+ //
+ // Redistribution and use in source and binary forms, with or without
+ // modification, are permitted provided that the following conditions are
+ // met:
+ //
+ // * Redistributions of source code must retain the above copyright
+ // notice, this list of conditions and the following disclaimer.
+ // * Redistributions in binary form must reproduce the above
+ // copyright notice, this list of conditions and the following disclaimer
+ // in the documentation and/or other materials provided with the
+ // distribution.
+ // * Neither the name of Google Inc. nor the names of its
+ // contributors may be used to endorse or promote products derived from
+ // this software without specific prior written permission.
+ //
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ //
+ // Author: wan@google.com (Zhanyong Wan)
+ //
+ // The Google C++ Testing Framework (Google Test)
+
+#include <QA/Checker/CppUnitTestResultPrinter.h>
+
+namespace testing {
+
+ namespace internal {
+ enum GTestColor {
+ COLOR_DEFAULT,
+ COLOR_RED,
+ COLOR_GREEN,
+ COLOR_YELLOW
+ };
+ void ColoredPrintf(GTestColor color, const char* fmt, ...);
+ }
+
+using namespace internal;
+
+static std::string plural(const std::string msg1, const std::string msg2, int n) {
+ if (n == 1) {
+ return msg1;
+ }
+ return msg2;
+}
+
+static std::string PrintTestPartResultToString(const TestPartResult& testPartResult) {
+ return (Message() << internal::FormatFileLocation(testPartResult.file_name(), testPartResult.line_number())
+ << " " << (testPartResult.type() == TestPartResult::Type::kSuccess ? "Success" : "Failure") << std::endl << testPartResult.message()).GetString();
+}
+
+void CppUnitTestResultPrinter::OnTestIterationStart(const UnitTest& unitTest, int iteration) {
+ if (GTEST_FLAG(repeat) != 1) {
+ std::cout << std::endl << "Repeating all tests (iteration" << iteration + 1 << ") . . ." << std::endl << std::endl;
+ }
+ const char* const filter = GTEST_FLAG(filter).c_str();
+ if (!String::CStringEquals(filter, "*")) {
+ ColoredPrintf(COLOR_YELLOW, "Note: %s filter = %s\n", GTEST_NAME_, filter);
+ }
+ if (GTEST_FLAG(shuffle)) {
+ ColoredPrintf(COLOR_YELLOW, "Note: Randomizing tests' orders with a seed of %d .\n", unitTest.random_seed());
+ }
+ ColoredPrintf(COLOR_GREEN, "[==========] ");
+ std::cout << "Running " << unitTest.test_to_run_count() << " " << plural("test", "tests", unitTest.test_to_run_count());
+ std::cout << " from " << unitTest.test_case_to_run_count() << " " << plural("test case", "test cases", unitTest.test_case_to_run_count()) << "." << std::endl;
+ std::cout.flush();
+}
+
+void CppUnitTestResultPrinter::OnTestPartResult(const TestPartResult& testPartResult) {
+ if (testPartResult.failed()) {
+ assertionsFailures_ << PrintTestPartResultToString(testPartResult) << std::endl;
+ }
+}
+
+void CppUnitTestResultPrinter::OnTestEnd(const TestInfo& testInfo) {
+ if (testInfo.result()->Passed()) {
+ ColoredPrintf(COLOR_GREEN, ".");
+ }
+ else {
+ ColoredPrintf(COLOR_RED, "F");
+ testFailures_ << std::endl << testInfo.name() << "." << testInfo.test_case_name() << std::endl << assertionsFailures_.rdbuf();
+ assertionsFailures_.clear();
+ }
+}
+
+void CppUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unitTest, int) {
+ ColoredPrintf(COLOR_GREEN, "\n[==========] ");
+ std::cout << unitTest.test_to_run_count() << " " << plural("test", "tests", unitTest.test_to_run_count()) << " from " << unitTest.test_case_to_run_count() << " " << plural("test case", "test cases", unitTest.test_case_to_run_count()) << " ran. ";
+ if (GTEST_FLAG(print_time)) {
+ std::cout << "(" << StreamableToString(unitTest.elapsed_time()).c_str() << " ms total)";
+ }
+ ColoredPrintf(COLOR_GREEN, "\n[ PASSED ] ");
+ std::cout << unitTest.successful_test_count() << " " << plural("test", "tests", unitTest.successful_test_count()) << "." << std::endl;
+
+ int num_failures = unitTest.failed_test_count();
+ if (!unitTest.Passed()) {
+ ColoredPrintf(COLOR_RED, "[ FAILED ] ");
+ std::cout << unitTest.failed_test_count() << " " << plural("test", "tests", unitTest.failed_test_count()) << ", listed below:" << std::endl;
+ PrintFailedTests(unitTest);
+ std::cout << std::endl << num_failures << " FAILED " << plural("TEST", "TESTS", num_failures) << std::endl;
+ }
+ int num_disabled = unitTest.reportable_disabled_test_count();
+ if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) {
+ if (!num_failures) {
+ std::cout << std::endl;
+ }
+ std::cout << num_disabled << " " << plural("test", "tests", num_disabled) << " were disabled." << std::endl << std::endl;
+ }
+ std::cout << testFailures_.rdbuf();
+ std::cout.flush();
+}
+
+// Internal helper for printing the list of failed tests.
+void CppUnitTestResultPrinter::PrintFailedTests(const UnitTest& unitTest) {
+ if (unitTest.failed_test_count() == 0) {
+ return;
+ }
+ for (int i = 0; i < unitTest.total_test_case_count(); ++i) {
+ const TestCase& testCase = *unitTest.GetTestCase(i);
+ if (!testCase.should_run() || (testCase.failed_test_count() == 0)) {
+ continue;
+ }
+ for (int j = 0; j < testCase.total_test_count(); ++j) {
+ const TestInfo& testInfo = *testCase.GetTestInfo(j);
+ if (!testInfo.should_run() || testInfo.result()->Passed()) {
+ continue;
+ }
+ ColoredPrintf(COLOR_RED, "[ FAILED ] ");
+ std::cout << testCase.name() << "." << testInfo.name() << std::endl;
+ }
+ }
+}
+
+}
diff --git a/QA/Checker/CppUnitTestResultPrinter.h b/QA/Checker/CppUnitTestResultPrinter.h
new file mode 100644
index 0000000..8e09243
--- /dev/null
+++ b/QA/Checker/CppUnitTestResultPrinter.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+ // Copyright 2005, Google Inc.
+ // All rights reserved.
+ //
+ // Redistribution and use in source and binary forms, with or without
+ // modification, are permitted provided that the following conditions are
+ // met:
+ //
+ // * Redistributions of source code must retain the above copyright
+ // notice, this list of conditions and the following disclaimer.
+ // * Redistributions in binary form must reproduce the above
+ // copyright notice, this list of conditions and the following disclaimer
+ // in the documentation and/or other materials provided with the
+ // distribution.
+ // * Neither the name of Google Inc. nor the names of its
+ // contributors may be used to endorse or promote products derived from
+ // this software without specific prior written permission.
+ //
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ //
+ // Author: wan@google.com (Zhanyong Wan)
+ //
+ // The Google C++ Testing Framework (Google Test)
+
+#pragma once
+
+#include <gtest/gtest.h>
+
+namespace testing {
+
+ //CppUnitTestResultPrinter is based on PrettyUnitTestResultPrinter from the google test suite
+ class CppUnitTestResultPrinter : public ::testing::EmptyTestEventListener {
+ public:
+ virtual void OnTestIterationStart(const ::testing::UnitTest& unitTest, int iteration);
+ virtual void OnTestPartResult(const ::testing::TestPartResult& testPartResult);
+ virtual void OnTestEnd(const ::testing::TestInfo& test_info);
+ virtual void OnTestIterationEnd(const ::testing::UnitTest& unitTest, int);
+ private:
+ static void PrintFailedTests(const ::testing::UnitTest& unitTest);
+ std::stringstream assertionsFailures_;
+ std::stringstream testFailures_;
+ };
+}
diff --git a/QA/Checker/IO.cpp b/QA/Checker/IO.cpp
index 41fe5d3..4b43635 100644
--- a/QA/Checker/IO.cpp
+++ b/QA/Checker/IO.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#include <QA/Checker/IO.h>
@@ -10,56 +10,56 @@
#include <iostream>
std::ostream& operator<<(std::ostream& os, const Swift::ByteArray& s) {
- std::ios::fmtflags oldFlags = os.flags();
- os << std::hex;
- for (Swift::ByteArray::const_iterator i = s.begin(); i != s.end(); ++i) {
- if (*i >= 32 && *i < 127) {
- os << *i;
- }
- else {
- os << "\\x" << static_cast<unsigned int>(static_cast<unsigned char>(*i));
- }
- }
- os << std::endl;
- os.flags(oldFlags);
- return os;
+ std::ios::fmtflags oldFlags = os.flags();
+ os << std::hex;
+ for (unsigned char i : s) {
+ if (i >= 32 && i < 127) {
+ os << i;
+ }
+ else {
+ os << "\\x" << static_cast<unsigned int>(static_cast<unsigned char>(i));
+ }
+ }
+ os << std::endl;
+ os.flags(oldFlags);
+ return os;
}
std::ostream& operator<<(std::ostream& os, const Swift::SafeByteArray& s) {
- std::ios::fmtflags oldFlags = os.flags();
- os << std::hex;
- for (Swift::SafeByteArray::const_iterator i = s.begin(); i != s.end(); ++i) {
- if (*i >= 32 && *i < 127) {
- os << *i;
- }
- else {
- os << "\\x" << static_cast<unsigned int>(static_cast<unsigned char>(*i));
- }
- }
- os << std::endl;
- os.flags(oldFlags);
- return os;
+ std::ios::fmtflags oldFlags = os.flags();
+ os << std::hex;
+ for (unsigned char i : s) {
+ if (i >= 32 && i < 127) {
+ os << i;
+ }
+ else {
+ os << "\\x" << static_cast<unsigned int>(static_cast<unsigned char>(i));
+ }
+ }
+ os << std::endl;
+ os.flags(oldFlags);
+ return os;
}
std::ostream& operator<<(std::ostream& os, const std::vector<int>& s) {
- for (std::vector<int>::const_iterator i = s.begin(); i != s.end(); ++i) {
- os << *i << " ";
- }
- os << std::endl;
- return os;
+ for (int i : s) {
+ os << i << " ";
+ }
+ os << std::endl;
+ return os;
}
std::ostream& operator<<(std::ostream& os, const std::vector<size_t>& s) {
- for (std::vector<size_t>::const_iterator i = s.begin(); i != s.end(); ++i) {
- os << *i << " ";
- }
- os << std::endl;
- return os;
+ for (size_t i : s) {
+ os << i << " ";
+ }
+ os << std::endl;
+ return os;
}
bool operator==(const Swift::ByteArray& a, const Swift::ByteArray& b) {
- if (a.size() != b.size()) {
- return false;
- }
- return std::equal(a.begin(), a.end(), b.begin());
+ if (a.size() != b.size()) {
+ return false;
+ }
+ return std::equal(a.begin(), a.end(), b.begin());
}
diff --git a/QA/Checker/IO.h b/QA/Checker/IO.h
index 3e40f7e..90f985a 100644
--- a/QA/Checker/IO.h
+++ b/QA/Checker/IO.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
diff --git a/QA/Checker/SConscript b/QA/Checker/SConscript
index d180af2..70458f0 100644
--- a/QA/Checker/SConscript
+++ b/QA/Checker/SConscript
@@ -1,17 +1,24 @@
+import os
+
Import("env")
if env["TEST"] :
- if env["SCONS_STAGE"] == "flags" :
- env["CHECKER_FLAGS"] = {
- "CPPPATH" : ["#/3rdParty/HippoMocks"],
- "LIBS": ["Checker"],
- "LIBPATH": [Dir(".")],
- "LINKFLAGS": ["/SUBSYSTEM:CONSOLE"] if env["PLATFORM"] == "win32" else []
- }
+ if env["SCONS_STAGE"] == "flags" :
+ env["CHECKER_FLAGS"] = {
+ "LIBS": ["Checker"],
+ "LIBPATH": [Dir(".")],
+ "LINKFLAGS": env["PLATFORM"] == "win32" and ["/SUBSYSTEM:CONSOLE"] or []
+ }
+
+ if os.path.basename(env["CC"]).startswith(("clang", "gcc")):
+ env["CHECKER_FLAGS"]["CPPFLAGS"] = ["-isystem" + Dir("#/3rdParty/HippoMocks").abspath]
+ else :
+ env["CHECKER_FLAGS"]["CPPPATH"] = ["#/3rdParty/HippoMocks"]
- if env["SCONS_STAGE"] == "build" :
- checker_env = env.Clone()
- checker_env.UseFlags(env["SWIFTEN_FLAGS"])
- checker_env.UseFlags(env["BOOST_FLAGS"])
- checker_env.UseFlags(env["CPPUNIT_FLAGS"])
- checker_env.Library("Checker", ["checker.cpp", "IO.cpp"])
+ if env["SCONS_STAGE"] == "build" :
+ checker_env = env.Clone()
+ checker_env.UseFlags(env["SWIFTEN_FLAGS"])
+ checker_env.UseFlags(env["BOOST_FLAGS"])
+ checker_env.UseFlags(env["CPPUNIT_FLAGS"])
+ checker_env.UseFlags(env["GOOGLETEST_FLAGS"])
+ checker_env.Library("Checker", ["checker.cpp", "IO.cpp", "CppUnitTestResultPrinter.cpp"])
diff --git a/QA/Checker/checker.cpp b/QA/Checker/checker.cpp
index 1ec8892..4d6a90e 100644
--- a/QA/Checker/checker.cpp
+++ b/QA/Checker/checker.cpp
@@ -1,86 +1,150 @@
/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010-2019 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
+#include <cstdlib>
+#include <fstream>
#include <string>
-#include <cppunit/ui/text/TestRunner.h>
-#include <cppunit/extensions/TestFactoryRegistry.h>
-#include <cppunit/XmlOutputter.h>
-#include <cppunit/TextTestResult.h>
+#include <sstream>
+
+#include <boost/algorithm/string/predicate.hpp>
+
+#include <gtest/gtest.h>
+#include <QA/Checker/CppUnitTestResultPrinter.h>
+
#include <cppunit/BriefTestProgressListener.h>
-#include <cppunit/TextTestProgressListener.h>
#include <cppunit/TextOutputter.h>
+#include <cppunit/TextTestProgressListener.h>
+#include <cppunit/TextTestResult.h>
+#include <cppunit/XmlOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
#include <Swiften/Base/Log.h>
+using Swift::Log;
+
int main(int argc, char* argv[]) {
- bool verbose = false;
- bool outputXML = false;
-
- Swift::Log::setLogLevel(Swift::Log::error);
-
- // Parse parameters
- std::vector<std::string> testsToRun;
- for (int i = 1; i < argc; ++i) {
- std::string param(argv[i]);
- if (param == "--verbose") {
- verbose = true;
- }
- else if (param == "--xml") {
- outputXML = true;
- }
- else if (param == "--debug") {
- Swift::Log::setLogLevel(Swift::Log::debug);
- }
- else {
- testsToRun.push_back(param);
- }
- }
- if (testsToRun.empty()) {
- testsToRun.push_back("");
- }
-
- // Set up the listeners
- CppUnit::TestResult controller;
-
- CppUnit::TestResultCollector result;
- controller.addListener(&result);
-
- CppUnit::TextTestProgressListener progressListener;
- CppUnit::BriefTestProgressListener verboseListener;
- if (!outputXML) {
- if (verbose) {
- controller.addListener(&verboseListener);
- }
- else {
- controller.addListener(&progressListener);
- }
- }
-
- // Run the tests
- CppUnit::TestRunner runner;
- runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
- for (std::vector<std::string>::const_iterator i = testsToRun.begin(); i != testsToRun.end(); ++i) {
- try {
- runner.run(controller, *i);
- }
- catch (const std::exception& e) {
- std::cerr << "Error: " << e.what() << std::endl;
- return -1;
- }
- }
-
- // Output the results
- if (outputXML) {
- CppUnit::XmlOutputter outputter(&result, std::cout);
- outputter.write();
- }
- else {
- CppUnit::TextOutputter outputter(&result, std::cerr);
- outputter.write();
- }
-
- return result.wasSuccessful() ? 0 : 1;
+ bool verbose = false;
+ bool outputXML = false;
+
+ Log::setLogLevel(Swift::Log::error);
+
+ // Parse parameters
+ std::vector<std::string> testsToRun;
+ for (int i = 1; i < argc; ++i) {
+ std::string param(argv[i]);
+ if (param == "--verbose") {
+ verbose = true;
+ }
+ else if (param == "--xml") {
+ outputXML = true;
+ }
+ else if (param == "--debug") {
+ Swift::Log::setLogLevel(Swift::Log::debug);
+ }
+ else if (boost::starts_with(param, "--")) {
+ continue;
+ }
+ else {
+ testsToRun.push_back(param);
+ }
+ }
+
+ if (testsToRun.empty()) {
+ testsToRun.push_back("");
+ }
+
+ // generate output filenames for XML test output
+ std::string gtestOutputFilename;
+ std::string cppunitOutputFilename;
+
+ if (outputXML) {
+ auto programName = std::string(argv[0]);
+
+ std::stringstream outFileStringStreamGTest("");
+ outFileStringStreamGTest << "xml:" << programName << "-report.gtest.xml";
+ gtestOutputFilename = outFileStringStreamGTest.str();
+
+ std::stringstream outFileStringStreamCppUnit("");
+ outFileStringStreamCppUnit << programName << "-report.cppunit.xml";
+ cppunitOutputFilename = outFileStringStreamCppUnit.str();
+ }
+
+ if (outputXML && (std::getenv("GTEST_OUTPUT") == nullptr)) {
+ ::testing::GTEST_FLAG(output) = gtestOutputFilename;
+ }
+
+ // Google Test might throw an exception in an anonymous namespace. Exiting
+ // due to uncaught execption is fine here.
+ // coverity[fun_call_w_exception]
+ ::testing::InitGoogleTest(&argc, argv);
+
+ // Set up the listeners
+ CppUnit::TestResult controller;
+
+ CppUnit::TestResultCollector result;
+ controller.addListener(&result);
+
+ CppUnit::TextTestProgressListener progressListener;
+ CppUnit::BriefTestProgressListener verboseListener;
+ if (!outputXML) {
+ if (verbose) {
+ controller.addListener(&verboseListener);
+ }
+ else {
+ controller.addListener(&progressListener);
+ }
+ }
+
+ // Run the tests
+ CppUnit::TestRunner runner;
+ runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
+ for (std::vector<std::string>::const_iterator i = testsToRun.begin(); i != testsToRun.end(); ++i) {
+ try {
+ runner.run(controller, *i);
+ }
+ catch (const std::exception& e) {
+ std::cerr << "Error: " << e.what() << std::endl;
+ return -1;
+ }
+ }
+
+ // Output the results
+ if (outputXML) {
+ std::ofstream cppUnitXUnitOutputFile;
+ cppUnitXUnitOutputFile.open(cppunitOutputFilename, std::ofstream::out | std::ofstream::trunc);
+ if (cppUnitXUnitOutputFile.is_open()) {
+ CppUnit::XmlOutputter outputter(&result, cppUnitXUnitOutputFile);
+ outputter.write();
+ }
+ else {
+ std::cerr << "Failed to overwrite " << cppunitOutputFilename << " output file." << std::endl;
+ return 1;
+ }
+ }
+ else {
+ CppUnit::TextOutputter outputter(&result, std::cerr);
+ outputter.write();
+ }
+
+ auto googleTestWasSuccessful = false;
+ try {
+ if (!verbose) {
+ testing::UnitTest& unitTest = *testing::UnitTest::GetInstance();
+ testing::TestEventListeners& listeners = unitTest.listeners();
+ delete listeners.Release(listeners.default_result_printer());
+ listeners.Append(new testing::CppUnitTestResultPrinter);
+ }
+ googleTestWasSuccessful = RUN_ALL_TESTS() == 0 ? true : false;
+ } catch (const ::testing::internal::GoogleTestFailureException& e) {
+ googleTestWasSuccessful = false;
+ SWIFT_LOG(error) << "GoogleTestFailureException was thrown: " << e.what();
+ }
+
+ auto cppUnitWasSuccessful = result.wasSuccessful() ? true : false;
+
+ return (googleTestWasSuccessful && cppUnitWasSuccessful) ? 0 : 1;
}
diff --git a/QA/CrossDistributionTest/VagrantCrossDistributionTest.py b/QA/CrossDistributionTest/VagrantCrossDistributionTest.py
new file mode 100755
index 0000000..3530fe5
--- /dev/null
+++ b/QA/CrossDistributionTest/VagrantCrossDistributionTest.py
@@ -0,0 +1,90 @@
+#!/usr/bin/env python
+
+# Required Python libraries:
+#
+# pip install python-vagrant tqdm
+#
+# Purpose of this script:
+#
+# This script tests
+# a) InstallSwiftDependencies.sh installs all required packages for Swift and Swiften on system and
+# b) all Swift projects build successfully on the system and their tests pass.
+
+from tqdm import tqdm
+from time import sleep
+import sys
+import vagrant
+
+testSystems = [
+ "bento/ubuntu-16.04",
+ "bento/ubuntu-15.04",
+ "bento/debian-8.5",
+ "bento/opensuse-leap-42.1",
+ "bento/fedora-24",
+ "Sabayon/spinbase-amd64"
+]
+
+progressBar = tqdm(testSystems)
+
+successfulSystems = []
+failedSystems = []
+
+for testSystem in progressBar :
+ v = vagrant.Vagrant(quiet_stdout=False)
+ try :
+ progressBar.set_description("create Vagrantfile for %s" % testSystem)
+ with open('Vagrantfile', 'w') as vagrantfile :
+ vagrantfile.write("""
+Vagrant.configure("2") do |config|
+ config.vm.box = "%s"
+
+ config.ssh.insert_key = false
+
+ config.vm.provider "virtualbox" do |v|
+ v.memory = 4096
+ v.cpus = 2
+ end
+
+ # This is needed because Fedora only comes with Python 3 and Ansible needs Python 2
+ # on the target system for some features.
+ if config.vm.box.include? "fedora"
+ config.vm.provision "shell", inline: "sudo dnf install -y python2 python2-dnf libselinux-python"
+ end
+
+ if config.vm.box.include? "Sabayon"
+ config.vm.provision "shell", inline: "sudo equo update && sudo env ACCEPT_LICENSE=* equo install dev-vcs/git sys-apps/lsb-release"
+ end
+
+ config.vm.synced_folder "../..", "/home/vagrant/swift-host", type: "rsync"
+ config.vm.synced_folder ".", "/vagrant", type: "rsync"
+
+ config.vm.provision "ansible" do |ansible|
+ #ansible.verbose = "vvv"
+ ansible.playbook = "playbook.yml"
+ end
+end""" % testSystem)
+
+ progressBar.set_description("vagrant up")
+ v.up(testSystem, provision=True )
+
+ progressBar.set_description("start building swift on %s" % testSystem)
+ # unset QTDIR is needed, because Fedora 24 sets QTDIR to Qt 3, even though Qt 5 is installed.
+ # SCons will pick up the Qt installation from QTDIR if QTDIR is set.
+ v._call_vagrant_command(["ssh", "-c", "cd /home/vagrant/swift && unset QTDIR && ./scons test=unit -j 2"])
+
+ progressBar.set_description("vagrant destory %s" % testSystem)
+ v.destroy()
+ successfulSystems.append(testSystem)
+ except :
+ e = sys.exc_info()[0]
+ print("Exception: %s" % e)
+ progressBar.set_description("vagrant destory %s" % testSystem)
+ v.destroy()
+ failedSystems.append(testSystem)
+
+for system in successfulSystems:
+ print("SUCCESS: %s" % system)
+for system in failedSystems:
+ print("FAILED: %s" % system)
+
+exit(len(failedSystems)) \ No newline at end of file
diff --git a/QA/CrossDistributionTest/playbook.yml b/QA/CrossDistributionTest/playbook.yml
new file mode 100644
index 0000000..aa4b8f5
--- /dev/null
+++ b/QA/CrossDistributionTest/playbook.yml
@@ -0,0 +1,33 @@
+- hosts: all
+ tasks:
+ - name: Install required packages via apt
+ apt: name=git state=latest update_cache=yes
+ become: true
+ when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu'
+ - name: Install required packages via dnf
+ dnf: name={{item}} state=latest
+ with_items:
+ - git
+ - redhat-lsb
+ become: true
+ when: ansible_distribution == 'CentOS' or ansible_distribution == 'Red Hat Enterprise Linux' or ansible_distribution == 'RedHat' or ansible_distribution == 'Fedora'
+ - name: 'Install required packages via zypper'
+ zypper: name={{item}} state=latest
+ with_items:
+ - git-core
+ - lsb-release
+ become: true
+ when: ansible_distribution == 'openSUSE Leap'
+ - name: Clone git from host working directory
+ git: repo=/home/vagrant/swift-host dest=/home/vagrant/swift
+
+ - name: 'Install Swift dependencies for openSUSE Leap'
+ shell: ./BuildTools/InstallSwiftDependencies.sh --non-interactive chdir=/home/vagrant/swift
+ become: true
+ when: ansible_distribution == 'openSUSE Leap'
+ - name: 'Install Swift dependencies'
+ environment:
+ ACCEPT_LICENSE: '*'
+ shell: yes | ./BuildTools/InstallSwiftDependencies.sh chdir=/home/vagrant/swift
+ become: true
+ when: ansible_distribution != 'openSUSE Leap'
diff --git a/QA/SConscript b/QA/SConscript
index 5c626e3..b4125cf 100644
--- a/QA/SConscript
+++ b/QA/SConscript
@@ -1,4 +1,4 @@
SConscript(dirs = [
- "Checker",
- "UnitTest"
- ])
+ "Checker",
+ "UnitTest"
+ ])
diff --git a/QA/UnitTest/SConscript b/QA/UnitTest/SConscript
index 53c38f5..5c19432 100644
--- a/QA/UnitTest/SConscript
+++ b/QA/UnitTest/SConscript
@@ -3,26 +3,29 @@ import os
Import("env")
if env["TEST"] :
- if env["SCONS_STAGE"] == "flags" :
- env["UNITTEST_SOURCES"] = []
- env["UNITTEST_OBJECTS"] = []
- if env["SCONS_STAGE"] == "build" :
- myenv = env.Clone()
- myenv.UseFlags(env.get("CHECKER_FLAGS",""))
- myenv.UseFlags(env.get("SLIMBER_FLAGS",""))
- myenv.UseFlags(env.get("SWIFT_CONTROLLERS_FLAGS",""))
- myenv.UseFlags(env.get("SWIFTOOLS_FLAGS",""))
- myenv.UseFlags(env.get("LIMBER_FLAGS",""))
- myenv.UseFlags(env.get("SWIFTEN_FLAGS",""))
- myenv.UseFlags(env.get("CPPUNIT_FLAGS",""))
- myenv.UseFlags(env.get("SWIFTEN_DEP_FLAGS", ""))
- if env.get("HAVE_LIBXML") :
- myenv.Append(CPPDEFINES = ["HAVE_LIBXML"])
- if env.get("HAVE_EXPAT") :
- myenv.Append(CPPDEFINES = ["HAVE_EXPAT"])
- if env["TEST_CREATE_LIBRARIES"] :
- lib = myenv.StaticLibrary("Swift_UnitTests", env["UNITTEST_SOURCES"] + env["UNITTEST_OBJECTS"])
- myenv.Program("checker", lib)
- else :
- checker = myenv.Program("checker", env["UNITTEST_SOURCES"] + env["UNITTEST_OBJECTS"])
- myenv.Test(checker, is_checker = True) \ No newline at end of file
+ if env["SCONS_STAGE"] == "flags" :
+ env["UNITTEST_SOURCES"] = []
+ env["UNITTEST_OBJECTS"] = []
+ if env["SCONS_STAGE"] == "build" :
+ myenv = env.Clone()
+ myenv.UseFlags(env.get("CHECKER_FLAGS",""))
+ myenv.UseFlags(env.get("INJECTED_UNITTEST_FLAGS","")) # So things that piggy-back our build system can piggy-back our test system too
+ myenv.UseFlags(env.get("SLIMBER_FLAGS",""))
+ myenv.UseFlags(env.get("SWIFT_CONTROLLERS_FLAGS",""))
+ myenv.UseFlags(env.get("SWIFTOOLS_FLAGS",""))
+ myenv.UseFlags(env.get("LIMBER_FLAGS",""))
+ myenv.UseFlags(env.get("SWIFTEN_FLAGS",""))
+ myenv.UseFlags(env.get("CPPUNIT_FLAGS",""))
+ myenv.UseFlags(env.get("GOOGLETEST_FLAGS", ""))
+ myenv.UseFlags(env.get("SWIFTEN_DEP_FLAGS", ""))
+ myenv.UseFlags(env.get("SWIFT_QTUI_TEST_FLAGS", ""))
+ if env.get("HAVE_LIBXML") :
+ myenv.Append(CPPDEFINES = ["HAVE_LIBXML"])
+ if env.get("HAVE_EXPAT") :
+ myenv.Append(CPPDEFINES = ["HAVE_EXPAT"])
+ if env["TEST_CREATE_LIBRARIES"] :
+ lib = myenv.StaticLibrary("Swift_UnitTests", env["UNITTEST_SOURCES"] + env["UNITTEST_OBJECTS"])
+ myenv.Program("checker", lib)
+ else :
+ checker = myenv.Program("checker", env["UNITTEST_SOURCES"] + env["UNITTEST_OBJECTS"])
+ myenv.Test(checker, is_checker = True)
diff --git a/QA/UnitTest/template/FooTest.cpp b/QA/UnitTest/template/FooTest.cpp
index 7619ad1..adddb5b 100644
--- a/QA/UnitTest/template/FooTest.cpp
+++ b/QA/UnitTest/template/FooTest.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#include <cppunit/extensions/HelperMacros.h>
@@ -10,19 +10,19 @@
using namespace Swift;
class FooTest : public CppUnit::TestFixture {
- CPPUNIT_TEST_SUITE(FooTest);
- CPPUNIT_TEST(testBar);
- CPPUNIT_TEST_SUITE_END();
+ CPPUNIT_TEST_SUITE(FooTest);
+ CPPUNIT_TEST(testBar);
+ CPPUNIT_TEST_SUITE_END();
- public:
- void setUp() {
- }
+ public:
+ void setUp() {
+ }
- void tearDown() {
- }
+ void tearDown() {
+ }
- void testBar() {
- }
+ void testBar() {
+ }
};
CPPUNIT_TEST_SUITE_REGISTRATION(FooTest);