summaryrefslogtreecommitdiff
path: root/src/components/utils/test
diff options
context:
space:
mode:
authorJustin Dickow <jjdickow@gmail.com>2015-02-20 09:11:18 -0500
committerJustin Dickow <jjdickow@gmail.com>2015-02-20 09:11:18 -0500
commita7c5d752cb75485baa0ded5226335d0f8eb10321 (patch)
treefbfd9251ada2cdcd5cf6a03a79887d08f6b496d7 /src/components/utils/test
parentb2b2233d866f102d3de339afa8ccaf37d3cf2570 (diff)
downloadsmartdevicelink-SynchronizationCommit.tar.gz
Bug Fixes and ImprovementsSynchronizationCommit
Fix Empty perform iteration request Fix type of name from string to enum SendLocation implemented on HTML5 HMI Fixed PI response on VR rejection due to high priority. Fix Apps not responsive/not able to start app/apps remain listed on SYNC even after USB disconnect Mobile API change and processing capabilities Change perform interaction request conditions. Fix SDL must always start 3sec timer before resuming the HMILevel of the app Remove redundant StartSavePersistentDataTimer() call. Change wrong predicate name to right. Added stream request handling feature Made streaming timeout in media manager configurable Put navi app in LIMITED in case of phone call Handling of audio state for applications Add stop streaming timeout into ini file Implement HMILevel resumption for job-1 Fix result code ABORTED when interrupts it by Voice recognition activation Fix incorrect value parameter unexpectedDisconnect in BCOnAppUnregistered Fix SDL send BC.OnAppUnregistered with "unexpectedDisconnect" set to "true" in case received from HMI OnExitAllApplications {"reason":"MASTER_RESET"} Fix Update ini file for iAP1 support Current working directory added to image path Fix helpers to make it workable with more then 2 parameters DCHECK() for ManageMobileCommand() replaced with log message because the latter returns false in some regular situations (e.g. TOO_MANY_PENDING_REQUESTS, see SDLAQ-CRS-10) Remove connection after closing. Signed-off-by: Justin Dickow <jjdickow@gmail.com>
Diffstat (limited to 'src/components/utils/test')
-rw-r--r--src/components/utils/test/CMakeLists.txt75
-rw-r--r--src/components/utils/test/async_runner_test.cc140
-rw-r--r--src/components/utils/test/auto_trace_test.cc101
-rw-r--r--src/components/utils/test/back_trace_test.cc53
-rw-r--r--src/components/utils/test/bitstream_test.cc230
-rw-r--r--src/components/utils/test/conditional_variable_test.cc132
-rw-r--r--src/components/utils/test/data_accessor_test.cc140
-rw-r--r--src/components/utils/test/date_time_test.cc318
-rw-r--r--src/components/utils/test/file_system_test.cc1166
-rw-r--r--src/components/utils/test/lock_posix_test.cc123
-rw-r--r--src/components/utils/test/log4cxx.properties11
-rw-r--r--src/components/utils/test/log_message_loop_thread_test.cc96
-rw-r--r--src/components/utils/test/message_queue_test.cc169
-rw-r--r--src/components/utils/test/messagemeter_test.cc2
-rw-r--r--src/components/utils/test/posix_thread_test.cc312
-rw-r--r--src/components/utils/test/resource_usage_test.cc100
-rw-r--r--src/components/utils/test/rwlock_posix_test.cc143
-rw-r--r--src/components/utils/test/signals_linux_test.cc55
-rw-r--r--src/components/utils/test/singleton_test.cc189
-rw-r--r--src/components/utils/test/stl_utils_test.cc106
-rw-r--r--src/components/utils/test/system_test.cc125
-rwxr-xr-xsrc/components/utils/test/testscript.sh5
-rw-r--r--src/components/utils/test/thread_validator_test.cc53
-rw-r--r--src/components/utils/test/timer_thread_test.cc158
24 files changed, 3885 insertions, 117 deletions
diff --git a/src/components/utils/test/CMakeLists.txt b/src/components/utils/test/CMakeLists.txt
index a9ed5acda..377b7dba7 100644
--- a/src/components/utils/test/CMakeLists.txt
+++ b/src/components/utils/test/CMakeLists.txt
@@ -1,17 +1,80 @@
+# Copyright (c) 2015, Ford Motor Company
+# 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 the Ford Motor Company 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 HOLDER 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.
+
+if(BUILD_TESTS)
+
include_directories (
${CMAKE_SOURCE_DIR}/src/3rd_party-static/gmock-1.7.0/include
- ${CMAKE_SOURCE_DIR}/src/3rd_party-static/gmock-1.7.0/gtest/include)
+ ${CMAKE_SOURCE_DIR}/src/3rd_party-static/gmock-1.7.0/gtest/include
+ ${COMPONENTS_DIR}/include/utils
+ )
set(testSources
main.cc
+ messagemeter_test.cc
file_system_test.cc
- date_time_test.cc)
+ date_time_test.cc
+ system_test.cc
+ signals_linux_test.cc
+ thread_validator_test.cc
+ conditional_variable_test.cc
+ message_queue_test.cc
+ resource_usage_test.cc
+ bitstream_test.cc
+ data_accessor_test.cc
+ lock_posix_test.cc
+ singleton_test.cc
+ #posix_thread_test.cc
+ stl_utils_test.cc
+ timer_thread_test.cc
+ rwlock_posix_test.cc
+ async_runner_test.cc
+)
+
+if (ENABLE_LOG)
+ list(APPEND testSources auto_trace_test.cc)
+ list(APPEND testSources log_message_loop_thread_test.cc)
+endif()
+
+if (BUILD_BACKTRACE_SUPPORT)
+ list(APPEND testSources back_trace_test.cc)
+endif()
set(testLibraries
gmock
- gtest
- Utils)
+ Utils
+)
+
+file(COPY testscript.sh DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+file(COPY log4cxx.properties DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
-add_executable(utils_test ${testSources})
-target_link_libraries(utils_test ${testLibraries})
+create_test("utils_test" "${testSources}" "${testLibraries}")
+endif()
diff --git a/src/components/utils/test/async_runner_test.cc b/src/components/utils/test/async_runner_test.cc
new file mode 100644
index 000000000..38606c15a
--- /dev/null
+++ b/src/components/utils/test/async_runner_test.cc
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * 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 the Ford Motor Company 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 HOLDER 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.
+ */
+
+#include <stdlib.h>
+#include <ctime>
+#include "lock.h"
+#include "threads/async_runner.h"
+#include "utils/conditional_variable.h"
+
+#include "gtest/gtest.h"
+
+namespace test {
+namespace components {
+namespace utils {
+
+using namespace sync_primitives;
+using namespace threads;
+
+namespace {
+uint32_t check_value = 0;
+}
+
+// ThreadDelegate successor
+class TestThreadDelegate : public ThreadDelegate {
+ public:
+ void threadMain() {
+ ++check_value;
+ }
+};
+
+class AsyncRunnerTest : public ::testing::Test {
+ public:
+ AsyncRunnerTest()
+ : kDelegatesNum_(1),
+ asr_pt_(NULL) {
+ CreateAsyncRunner();
+ CreateThreadsArray();
+ }
+
+ ~AsyncRunnerTest() {
+ DeleteAsyncRunner();
+ DeleteThreadsArray();
+ }
+
+ protected:
+ Lock test_lock_;
+ uint32_t kDelegatesNum_;
+ ConditionalVariable cond_var_;
+ TestThreadDelegate **delegates_;
+ AsyncRunner *asr_pt_;
+
+ void CreateThreadsArray() {
+ srand(std::time(NULL));
+ kDelegatesNum_ = (rand() % 20 + 1);
+ delegates_ = new TestThreadDelegate*[kDelegatesNum_];
+ }
+
+ void DeleteThreadsArray() {
+ delete[] delegates_;
+ }
+
+ void CreateAsyncRunner() {
+ asr_pt_ = new AsyncRunner("test");
+ }
+ void DeleteAsyncRunner() {
+ delete asr_pt_;
+ }
+};
+
+TEST_F(AsyncRunnerTest, ASyncRunManyDelegates_ExpectSuccessfulAllDelegatesRun) {
+ AutoLock lock(test_lock_);
+ // Clear global value before test
+ check_value = 0;
+ // Create Delegates and run
+ for (unsigned int i = 0; i < kDelegatesNum_; ++i) {
+ delegates_[i] = new TestThreadDelegate();
+ asr_pt_->AsyncRun(delegates_[i]);
+ }
+ // Wait for 2 secs. Give this time to delegates to be run
+ cond_var_.WaitFor(lock, 2000);
+ // Expect all delegates run successfully
+ EXPECT_EQ(kDelegatesNum_, check_value);
+}
+
+TEST_F(AsyncRunnerTest, RunManyDelegatesAndStop_ExpectSuccessfulDelegatesStop) {
+ AutoLock lock(test_lock_);
+ // Clear global value before test
+ check_value = 0;
+ // Create Delegates
+ for (unsigned int i = 0; i < kDelegatesNum_; ++i) {
+ delegates_[i] = new TestThreadDelegate();
+ }
+ // Wait for 2 secs
+ cond_var_.WaitFor(lock, 2000);
+ // Run created delegates
+ for (unsigned int i = 0; i < kDelegatesNum_; ++i) {
+ if (kDelegatesNum_ > 1) {
+ if (i == kDelegatesNum_ / 2) {
+ asr_pt_->Stop();
+ }
+ }
+ asr_pt_->AsyncRun(delegates_[i]);
+ }
+ // Expect 3 delegates run successlully. The other stopped.
+ EXPECT_EQ(kDelegatesNum_ / 2, check_value);
+}
+
+} // namespace utils
+} // namespace components
+} // namespace test
+
diff --git a/src/components/utils/test/auto_trace_test.cc b/src/components/utils/test/auto_trace_test.cc
new file mode 100644
index 000000000..71e0f4376
--- /dev/null
+++ b/src/components/utils/test/auto_trace_test.cc
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * 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 the Ford Motor Company 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 HOLDER 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.
+ */
+
+#include "gtest/gtest.h"
+#include "utils/auto_trace.h"
+#include "logger.h"
+#include <fstream>
+
+namespace test {
+namespace components {
+namespace utils {
+
+using namespace ::logger;
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "AutoTraceTestLog");
+
+void Preconditions() {
+ //delete file with previous logs
+ const char* file_name = "AutoTraceTestLogFile.log";
+ std::remove(file_name);
+}
+
+void InitLogger() {
+ INIT_LOGGER("log4cxx.properties");
+}
+
+void CreateDeleteAutoTrace(const std::string & testlog) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, testlog);
+}
+
+bool CheckTraceInFile(const std::string & testlog) {
+
+ bool isLogFound = false;
+ std::string line;
+
+ std::ifstream file_log("AutoTraceTestLogFile.log");
+
+ if (file_log.is_open()) {
+ while (getline(file_log, line)) {
+ std::size_t found = line.find(testlog);
+ std::size_t founddebug = line.find("DEBUG");
+ if ((found != std::string::npos) && (founddebug != std::string::npos)) {
+ isLogFound = true;
+ break;
+ }
+ }
+ file_log.close();
+ } else {
+ std::cout << "file cannot be opened \n";
+ }
+ return isLogFound;
+}
+
+void DeinitLogger() {
+ DEINIT_LOGGER();
+}
+
+TEST(AutoTraceTest, Basic) {
+ const std::string testlog =
+ "Test trace is working!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";
+ Preconditions();
+ InitLogger();
+ CreateDeleteAutoTrace(testlog);
+ DeinitLogger();
+
+ ASSERT_TRUE(CheckTraceInFile(testlog));
+}
+
+} // namespace utils
+} // namespace components
+} // namespace test
diff --git a/src/components/utils/test/back_trace_test.cc b/src/components/utils/test/back_trace_test.cc
new file mode 100644
index 000000000..12d5df81f
--- /dev/null
+++ b/src/components/utils/test/back_trace_test.cc
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * 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 the Ford Motor Company 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 HOLDER 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.
+ */
+
+#include "gtest/gtest.h"
+#include "utils/back_trace.h"
+
+namespace test {
+namespace components {
+namespace utils {
+
+using namespace ::utils;
+
+TEST(BackTraceTest, CallStackShouldNotBeEmpty) {
+
+ //arrange
+ Backtrace newtrace = Backtrace();
+ std::vector < std::string > symbols = newtrace.CallStack();
+ //assert
+ ASSERT_FALSE(symbols.empty());
+}
+
+} // namespace utils
+} // namespace components
+} // namespace test
diff --git a/src/components/utils/test/bitstream_test.cc b/src/components/utils/test/bitstream_test.cc
new file mode 100644
index 000000000..07a80bde0
--- /dev/null
+++ b/src/components/utils/test/bitstream_test.cc
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * 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 the Ford Motor Company 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 HOLDER 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.
+ */
+
+#include <unistd.h>
+#include "gtest/gtest.h"
+#include "utils/macro.h"
+#include "utils/bitstream.h"
+
+namespace test {
+namespace components {
+namespace utils {
+
+using ::utils::BitStream;
+
+TEST(BitstreamTest, CreateBitstream_WithDataWithDatasize_BitStreamIsGood) {
+
+ //arrange
+ uint8_t data = 10;
+ size_t bits = 2;
+ BitStream bs(&data, bits);
+
+ //assert
+ EXPECT_TRUE(bs.IsGood());
+}
+
+TEST(BitstreamTest, ExtractBitstreamInUint8_ExtractAllData_BitStreamIsGoodDataExtractedCorrectly) {
+
+ //arrange
+ uint8_t data = 10;
+ size_t bits = 2;
+ BitStream bs(&data, bits);
+
+ uint8_t extract_data = 0;
+ Extract(&bs, &extract_data);
+
+ //assert
+ EXPECT_TRUE(bs.IsGood());
+
+ EXPECT_EQ(data, extract_data);
+}
+
+TEST(BitstreamTest, ExtractBitstreamInUint8_WithDataWithZeroSize_BitStreamIsBad) {
+
+ //arrange
+ uint8_t data = 10;
+ size_t bits = 0;
+ BitStream bs(&data, bits);
+
+ uint8_t extract_data = 0;
+ Extract(&bs, &extract_data);
+
+ //assert
+ EXPECT_TRUE(bs.IsBad());
+}
+
+TEST(BitstreamTest, ExtractBitstreamInUint32_WithDatasizeEq4_BitStreamIsGoodDataExtractedCorrectly) {
+
+ //arrange
+ uint8_t data = 10;
+ size_t bits = 4;
+ BitStream bs(&data, bits);
+
+ uint32_t extract_data = 0;
+ Extract(&bs, &extract_data);
+
+ //assert
+ EXPECT_TRUE(bs.IsGood());
+
+}
+
+TEST(BitstreamTest, ExtractBitstreamInUint32_DatasizeLess4_BitStreamIsBad) {
+
+ //arrange
+ uint8_t data = 10;
+ size_t bits = 3;
+ BitStream bs(&data, bits);
+
+ uint32_t extract_data = 0;
+ Extract(&bs, &extract_data);
+
+ //assert
+ EXPECT_TRUE(bs.IsBad());
+
+}
+
+TEST(BitstreamTest, ExtractFullBitstream_WithDataWithDatasize_BitStreamIsGood) {
+
+ //arrange
+ uint8_t data = 10;
+ size_t bits = 8;
+ BitStream bs(&data, bits);
+
+ uint8_t extract_data = 0;
+
+ Extract(&bs, &extract_data, bits);
+
+ //assert
+ EXPECT_TRUE(bs.IsGood());
+
+ EXPECT_EQ(data, extract_data);
+}
+
+TEST(BitstreamTest, ExtractBitstreamInString_WithDataWithDatasize_BitStreamIsGood) {
+
+ //arrange
+ uint8_t data = 10;
+ size_t bits = 2;
+ BitStream bs(&data, bits);
+
+ std::string strdata = "";
+ size_t length = strdata.length();
+
+ Extract(&bs, &strdata, length);
+
+ //assert
+ EXPECT_TRUE(bs.IsGood());
+}
+
+TEST(BitstreamTest, CreateBitstream_NoDataZeroDatasize_BitStreamIsGood) {
+
+ //arrange
+ uint8_t *data = NULL;
+ size_t bits = 0;
+ BitStream bs(data, bits);
+
+ //assert
+ EXPECT_TRUE(bs.IsGood());
+}
+
+TEST(BitstreamTest, CreateBitstream_NoDataWithUpperboundDataSize_BitStreamIsGood) {
+
+ //arrange
+ uint8_t *data = NULL;
+ size_t bits = 65535;
+ BitStream bs(data, bits);
+
+ //assert
+ EXPECT_TRUE(bs.IsGood());
+}
+
+TEST(BitstreamTest, CreateBitstream_WithUpperboundDataWithLessDataSize_BitStreamIsGood) {
+
+ //arrange
+ uint8_t data = 255;
+ size_t bits = sizeof(char);
+ BitStream bs(&data, bits);
+
+ //assert
+ EXPECT_TRUE(bs.IsGood());
+}
+
+TEST(BitstreamTest, ExtractBitstream_WithUpperboundDataWithLessDataSize_BitStreamIsGood) {
+
+ //arrange
+ uint8_t data = 255;
+ size_t bits = sizeof(char);
+ BitStream bs(&data, bits);
+
+ uint8_t extract_data = 0;
+ Extract(&bs, &extract_data, bits);
+
+ //assert
+ EXPECT_TRUE(bs.IsGood());
+}
+
+TEST(BitstreamTest, ExtractBitstream_WithUpperboundDataWithZeroDataSize_BitStreamIsGood) {
+
+ //arrange
+ uint8_t data = 255;
+ size_t bits = 0;
+ BitStream bs(&data, bits);
+
+ uint8_t extract_data = 0;
+ Extract(&bs, &extract_data, bits);
+
+ //assert
+ EXPECT_TRUE(bs.IsGood());
+}
+
+TEST(BitstreamTest, ExtractBitstream_WithDataMarkedBad_ExpectIsBad) {
+
+ //arrange
+ uint8_t data = 255;
+ size_t bits = sizeof(int);
+ BitStream bs(&data, bits);
+ //assert
+ EXPECT_TRUE(bs.IsGood());
+ //act
+ bs.MarkBad();
+
+ //assert
+ EXPECT_TRUE(bs.IsBad());
+ //act
+ Extract(&bs, &data, bits);
+ //arrange
+ EXPECT_TRUE(bs.IsBad());
+}
+
+} // namespace utils
+} // namespace components
+} // namespace test
diff --git a/src/components/utils/test/conditional_variable_test.cc b/src/components/utils/test/conditional_variable_test.cc
new file mode 100644
index 000000000..a898732ff
--- /dev/null
+++ b/src/components/utils/test/conditional_variable_test.cc
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * 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 the Ford Motor Company 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 HOLDER 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.
+ */
+
+#include <pthread.h>
+#include <iostream>
+
+#include "lock.h"
+#include "macro.h"
+
+#include "gtest/gtest.h"
+#include "utils/conditional_variable.h"
+
+namespace test {
+namespace components {
+namespace utils {
+
+class ConditionalVariableTest : public ::testing::Test {
+ public:
+ ConditionalVariableTest()
+ : test_value_("initialized"),
+ counter_(0) {
+ }
+ void check_counter();
+ void task_one();
+
+ static void* check_counter_helper(void *context) {
+ (reinterpret_cast<ConditionalVariableTest *>(context))->check_counter();
+ return NULL;
+ }
+
+ static void* task_one_helper(void *context) {
+ (reinterpret_cast<ConditionalVariableTest *>(context))->task_one();
+ return NULL;
+ }
+ protected:
+ std::string test_value_;
+ sync_primitives::ConditionalVariable cond_var_;
+ sync_primitives::Lock test_mutex_;
+ unsigned counter_;
+};
+
+// Defines threads behaviour which depends on counter value
+void ConditionalVariableTest::check_counter() {
+ sync_primitives::AutoLock test_lock(test_mutex_);
+ if (counter_ <= 1) {
+ counter_++;
+ cond_var_.Wait(test_mutex_); // Mutex unlock & Thread sleeps until Notification
+ }
+ else if(counter_ == 2) { // Checking for equal 2 in this specific case. Because we were waiting for 2 threads to be finished
+ cond_var_.Broadcast(); // Notify All threads waiting on conditional variable
+ }
+}
+
+// Tasks for threads to begin with
+void ConditionalVariableTest::task_one() {
+ sync_primitives::AutoLock test_lock(test_mutex_);
+ test_value_ = "changed by thread 1";
+ cond_var_.NotifyOne(); // Notify At least one thread waiting on conditional variable
+ test_value_ = "changed again by thread 1";
+}
+
+TEST_F(ConditionalVariableTest, CheckNotifyOne_OneThreadNotified_ExpectSuccessful) {
+ pthread_t thread1;
+ sync_primitives::AutoLock test_lock(test_mutex_);
+ test_value_ = "changed by main thread";
+ const bool thread_created = pthread_create(&thread1,
+ NULL,
+ &ConditionalVariableTest::task_one_helper,
+ this);
+ ASSERT_FALSE(thread_created) << "thread1 is not created!";
+ test_value_ = "changed twice by main thread";
+ cond_var_.WaitFor(test_lock, 2000);
+ std::string last_value("changed again by thread 1");
+ EXPECT_EQ(last_value, test_value_);
+}
+
+TEST_F(ConditionalVariableTest, CheckBroadcast_AllThreadsNotified_ExpectSuccessful) {
+ pthread_t thread1;
+ pthread_t thread2;
+ bool thread_created = pthread_create(&thread1,
+ NULL,
+ &ConditionalVariableTest::check_counter_helper,
+ this);
+ ASSERT_FALSE(thread_created) << "thread1 is not created!";
+ thread_created = pthread_create(&thread2,
+ NULL,
+ &ConditionalVariableTest::check_counter_helper,
+ this);
+ ASSERT_FALSE(thread_created) << "thread2 is not created!";
+ check_counter();
+ EXPECT_EQ(2u, counter_);
+}
+
+TEST_F(ConditionalVariableTest, CheckWaitForWithTimeout1sec_ThreadBlockedForTimeout_ExpectSuccessfulWakeUp) {
+ sync_primitives::AutoLock test_lock(test_mutex_);
+ sync_primitives::ConditionalVariable::WaitStatus wait_st = cond_var_.WaitFor(test_lock, 1000);
+ EXPECT_EQ(sync_primitives::ConditionalVariable::kTimeout, wait_st);
+}
+
+} // namespace utils
+} // namespace components
+} // namespace test
+
diff --git a/src/components/utils/test/data_accessor_test.cc b/src/components/utils/test/data_accessor_test.cc
new file mode 100644
index 000000000..105ec8517
--- /dev/null
+++ b/src/components/utils/test/data_accessor_test.cc
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * 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 the Ford Motor Company 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 HOLDER 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.
+ */
+
+#include "gtest/gtest.h"
+#include "utils/data_accessor.h"
+#include "utils/lock.h"
+
+namespace test {
+namespace components {
+namespace utils {
+
+TEST(DataAccessorTest, CreateDataAccessor) {
+
+ //arrange
+ int test_value = 10;
+ sync_primitives::Lock testSet_lock_;
+ DataAccessor<int> testdata(test_value, testSet_lock_);
+ int data_from_testdata = testdata.GetData();
+
+ //assert
+ EXPECT_EQ(test_value, data_from_testdata);
+}
+
+TEST(DataAccessorTest, CreateDataAccessor_MutexIsLocked_CannotLockItAgain) {
+
+ //arrange
+ int test_value = 10;
+ sync_primitives::Lock testSet_lock_;
+ DataAccessor<int> testdata(test_value, testSet_lock_);
+
+ //assert
+ EXPECT_FALSE(testSet_lock_.Try());
+}
+
+TEST(DataAccessorTest, CopyDataAccessor_GetDataFromDataAccessors) {
+
+ //arrange
+ int test_value = 10;
+ sync_primitives::Lock testSet_lock_;
+ DataAccessor<int> testdata(test_value, testSet_lock_);
+ DataAccessor<int> testdata_copy(testdata);
+
+ int data_from_testdata = testdata.GetData();
+ int data_from_testdata_copy = testdata_copy.GetData();
+
+ //assert
+ EXPECT_EQ(data_from_testdata, data_from_testdata_copy);
+
+ EXPECT_FALSE(testSet_lock_.Try());
+}
+
+TEST(DataAccessorTest,ChangedDataInDataAccessor_ChangeData_DataInDataAccessorIsChanged) {
+
+ //arrange
+ int test_value = 10;
+ sync_primitives::Lock testSet_lock_;
+ DataAccessor<int> testdata(test_value, testSet_lock_);
+ test_value = 0;
+
+ int data_from_testdata_after_change = testdata.GetData();
+
+ //assert
+ EXPECT_EQ(test_value, data_from_testdata_after_change);
+}
+
+TEST(DataAccessorTest, DeleteDataAccessor_CreatedOneDeleteOneThread_MutexIsUnlocked) {
+
+ //arrange
+ int test_value = 10;
+ sync_primitives::Lock testSet_lock_;
+ {
+ DataAccessor<int> testdata(test_value, testSet_lock_);
+
+ //assert
+ EXPECT_FALSE(testSet_lock_.Try());
+ }
+ //assert
+
+ EXPECT_TRUE(testSet_lock_.Try());
+
+ testSet_lock_.Release();
+
+}
+
+TEST(DataAccessorTest, DeleteDataAccessor_CreatedThreadAndCopyDeleteBothThreads_MutexIsUnlocked) {
+
+ //arrange
+ int test_value = 10;
+ sync_primitives::Lock testSet_lock_;
+ {
+ DataAccessor<int> testdata(test_value, testSet_lock_);
+ {
+ DataAccessor<int> testdata_copy(testdata);
+
+ //assert
+ EXPECT_FALSE(testSet_lock_.Try());
+ }
+ //assert
+ EXPECT_FALSE(testSet_lock_.Try());
+
+ }
+
+ //assert
+ EXPECT_TRUE(testSet_lock_.Try());
+ testSet_lock_.Release();
+
+}
+
+} // namespace utils
+} // namespace components
+} // namespace test
diff --git a/src/components/utils/test/date_time_test.cc b/src/components/utils/test/date_time_test.cc
index ddcf679a1..b437bdc17 100644
--- a/src/components/utils/test/date_time_test.cc
+++ b/src/components/utils/test/date_time_test.cc
@@ -1,126 +1,326 @@
/*
-* Copyright (c) 2014, Ford Motor Company
-* 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 the Ford Motor Company 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 HOLDER 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.
-*/
-
-#include <unistd.h>
+ * Copyright (c) 2015, Ford Motor Company
+ * 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 the Ford Motor Company 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 HOLDER 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.
+ */
#include "gtest/gtest.h"
-#include "gmock/gmock.h"
-
#include "utils/date_time.h"
-namespace test {
-namespace components {
-namespace utils {
+namespace test {
+namespace components {
+namespace utils {
+using namespace date_time;
TEST(DateTimeTest, GetCurrentTime) {
+
+ //arrange
const TimevalStruct time1 = date_time::DateTime::getCurrentTime();
+
+ //assert
ASSERT_NE(0, time1.tv_sec);
ASSERT_GE(time1.tv_usec, 0);
+ //act
const TimevalStruct time2 = date_time::DateTime::getCurrentTime();
+
+ //assert
ASSERT_NE(0, time2.tv_sec);
ASSERT_GE(time2.tv_usec, 0);
- ASSERT_GE(time2.tv_sec, time1.tv_sec);
+ ASSERT_GE(time2.tv_sec, time1.tv_sec);
+}
+
+TEST(DateTimeTest, GetSecs) {
+ //arrange
+ TimevalStruct time;
+ time.tv_sec = 1;
+ time.tv_usec = 2 * date_time::DateTime::MICROSECONDS_IN_MILLISECONDS;
+
+ //assert
+ ASSERT_EQ(1, date_time::DateTime::getSecs(time));
}
TEST(DateTimeTest, GetmSecs) {
+ //arrange
TimevalStruct time;
- time.tv_sec = 1;
+ time.tv_sec = 1;
time.tv_usec = 2 * date_time::DateTime::MICROSECONDS_IN_MILLISECONDS;
- ASSERT_EQ(time.tv_sec * date_time::DateTime::MILLISECONDS_IN_SECOND +
- time.tv_usec / date_time::DateTime::MICROSECONDS_IN_MILLISECONDS,
- date_time::DateTime::getmSecs(time));
+ int64_t expect_value = time.tv_sec
+ * date_time::DateTime::MILLISECONDS_IN_SECOND
+ + time.tv_usec / date_time::DateTime::MICROSECONDS_IN_MILLISECONDS;
+ //assert
+ ASSERT_EQ(expect_value, date_time::DateTime::getmSecs(time));
}
TEST(DateTimeTest, GetuSecs) {
+ //arrange
TimevalStruct time;
- time.tv_sec = 3;
+ time.tv_sec = 3;
time.tv_usec = 4;
- ASSERT_EQ(time.tv_sec * date_time::DateTime::MILLISECONDS_IN_SECOND *
- date_time::DateTime::MICROSECONDS_IN_MILLISECONDS + time.tv_usec,
- date_time::DateTime::getuSecs(time));
+ int64_t expect_value = time.tv_sec
+ * date_time::DateTime::MILLISECONDS_IN_SECOND
+ * date_time::DateTime::MICROSECONDS_IN_MILLISECONDS + time.tv_usec;
+ //assert
+ ASSERT_EQ(expect_value, date_time::DateTime::getuSecs(time));
}
TEST(DateTimeTest, GetuSecsmSecs) {
+ //arrange
TimevalStruct time;
- time.tv_sec = 5;
+ time.tv_sec = 5;
time.tv_usec = 6;
- ASSERT_EQ( date_time::DateTime::getmSecs(time),
- date_time::DateTime::getuSecs(time) / date_time::DateTime::MICROSECONDS_IN_MILLISECONDS);
+ int64_t expect_value = date_time::DateTime::getuSecs(time)
+ / date_time::DateTime::MICROSECONDS_IN_MILLISECONDS;
+
+ //assert
+ ASSERT_EQ(expect_value, date_time::DateTime::getmSecs(time));
}
TEST(DateTimeTest, CalculateTimeSpan) {
+ //arrange
const TimevalStruct time = date_time::DateTime::getCurrentTime();
const uint32_t sleep_time_mSec = 10;
usleep(sleep_time_mSec * date_time::DateTime::MICROSECONDS_IN_MILLISECONDS);
- ASSERT_GE(date_time::DateTime::calculateTimeSpan(time),
- sleep_time_mSec);
+ //assert
+ ASSERT_GE(date_time::DateTime::calculateTimeSpan(time), sleep_time_mSec);
}
TEST(DateTimeTest, CalculateTimeDiff) {
+
+ //arrange
TimevalStruct time1;
- time1.tv_sec = 1;
+ time1.tv_sec = 1;
time1.tv_usec = 2 * date_time::DateTime::MICROSECONDS_IN_MILLISECONDS;
TimevalStruct time2;
- time2.tv_sec = 3;
+ time2.tv_sec = 3;
time2.tv_usec = 4 * date_time::DateTime::MICROSECONDS_IN_MILLISECONDS;
//time2 to time1
TimevalStruct diff1;
- diff1.tv_sec = time2.tv_sec - time1.tv_sec;
+ diff1.tv_sec = time2.tv_sec - time1.tv_sec;
diff1.tv_usec = time2.tv_usec - time1.tv_usec;
const int64_t mSecDiff = static_cast<int64_t>(diff1.tv_sec) * 1000
+ diff1.tv_usec / 1000;
- ASSERT_EQ(mSecDiff,
- date_time::DateTime::calculateTimeDiff(time2, time1));
+ //assert
+ ASSERT_EQ(mSecDiff, date_time::DateTime::calculateTimeDiff(time2, time1));
//time1 to time2
TimevalStruct diff2;
- diff2.tv_sec = time1.tv_sec - time2.tv_sec;
+ diff2.tv_sec = time1.tv_sec - time2.tv_sec;
diff2.tv_usec = time1.tv_usec - time2.tv_usec;
const int64_t mSecDiff2 = -(static_cast<int64_t>(diff2.tv_sec) * 1000
+ diff2.tv_usec / 1000);
- ASSERT_EQ(mSecDiff2,
- date_time::DateTime::calculateTimeDiff(time1, time2));
+ //assert
+ ASSERT_EQ(mSecDiff2, date_time::DateTime::calculateTimeDiff(time1, time2));
+}
+
+TEST(DateTimeTest, CalculateEqualTimeDiff) {
+ TimevalStruct time1;
+ time1.tv_sec = 1;
+ time1.tv_usec = 2 * date_time::DateTime::MICROSECONDS_IN_MILLISECONDS;
+
+ TimevalStruct time2;
+ time2.tv_sec = 1;
+ time2.tv_usec = 2 * date_time::DateTime::MICROSECONDS_IN_MILLISECONDS;
+
+ ASSERT_EQ(0, date_time::DateTime::calculateTimeDiff(time2, time1));
+ ASSERT_EQ(0, date_time::DateTime::calculateTimeDiff(time1, time2));
+}
+
+TEST(DateTimeTest, compareTime) {
+
+ //arrange
+ TimevalStruct time1;
+ time1.tv_sec = 1;
+ time1.tv_usec = 2 * date_time::DateTime::MICROSECONDS_IN_MILLISECONDS;
+
+ TimevalStruct time2;
+ time2.tv_sec = 2;
+ time2.tv_usec = 4 * date_time::DateTime::MICROSECONDS_IN_MILLISECONDS;
+
+ //assert
+ ASSERT_EQ(LESS, date_time::DateTime::compareTime(time1, time2));
+ ASSERT_EQ(GREATER, date_time::DateTime::compareTime(time2, time1));
+ ASSERT_NE(EQUAL, date_time::DateTime::compareTime(time2, time1));
+
+ //act
+ TimevalStruct time3 = date_time::DateTime::Sub(time2, time1);
+
+ //assert
+ ASSERT_EQ(EQUAL, date_time::DateTime::compareTime(time1, time3));
+}
+
+//TODO(VVeremjova) APPLINK-11051 Missing convertation microseconds in seconds
+
+TEST(DateTimeTest, DISABLED_GetSecs_UsecConvertedInSec) {
+ //arrange
+ TimevalStruct time1;
+ time1.tv_sec = 0;
+ time1.tv_usec = date_time::DateTime::MICROSECONDS_IN_SECOND;
+
+ //assert
+ ASSERT_EQ(1, date_time::DateTime::getSecs(time1));
+}
+
+TEST(DateTimeTest, DISABLED_compareTime_UsecConvertedInSec) {
+ //arrange
+ TimevalStruct time1;
+ time1.tv_sec = 1;
+ time1.tv_usec = 0;
+
+ TimevalStruct time2;
+ time2.tv_sec = 0;
+ time2.tv_usec = date_time::DateTime::MICROSECONDS_IN_SECOND;
+
+ //assert
+ ASSERT_EQ(1, date_time::DateTime::getSecs(time1));
+ ASSERT_EQ(1, date_time::DateTime::getSecs(time2));
+ ASSERT_EQ(EQUAL, date_time::DateTime::compareTime(time1, time2));
+}
+
+TEST(DateTimeTest, DISABLED_compareEqualTime_UsecConvertedInSec) {
+ //arrange
+ TimevalStruct time1;
+ time1.tv_sec = 1;
+ time1.tv_usec = 0;
+
+ TimevalStruct time2;
+ time2.tv_sec = 0;
+ time2.tv_usec = date_time::DateTime::MICROSECONDS_IN_SECOND;
+
+ //assert
+ ASSERT_TRUE(date_time::DateTime::Equal(time1, time2));
+}
+
+TEST(DateTimeTest, DISABLED_compareLessTime_UsecConvertedInSec) {
+ //arrange
+ TimevalStruct time1;
+ time1.tv_sec = 1;
+ time1.tv_usec = 0;
+
+ TimevalStruct time2;
+ time2.tv_sec = 0;
+ time2.tv_usec = 2 * date_time::DateTime::MICROSECONDS_IN_SECOND;
+
+ //assert
+ ASSERT_TRUE(date_time::DateTime::Less(time1, time2));
+}
+
+TEST(DateTimeTest, DISABLED_compareGreaterTime_UsecConvertedInSec) {
+ //arrange
+ TimevalStruct time1;
+ time1.tv_sec = 1;
+ time1.tv_usec = 0;
+
+ TimevalStruct time2;
+ time2.tv_sec = 0;
+ time2.tv_usec = 2 * date_time::DateTime::MICROSECONDS_IN_SECOND;
+
+ //assert
+ ASSERT_TRUE(date_time::DateTime::Greater(time2, time1));
+}
+
+TEST(DateTimeTest, DISABLED_CalculateTimeSub_UsecConvertedInSec) {
+ //arrange
+ TimevalStruct time1;
+ time1.tv_sec = 1;
+ time1.tv_usec = 0;
+
+ TimevalStruct time2;
+ time2.tv_sec = 0;
+ time2.tv_usec = 2 * date_time::DateTime::MICROSECONDS_IN_SECOND;
+
+ TimevalStruct time3 = date_time::DateTime::Sub(time2, time1);
+
+ //assert
+ ASSERT_EQ(EQUAL, date_time::DateTime::compareTime(time1, time3));
+}
+
+TEST(DateTimeTest, DISABLED_CalculateTimeDiff_UsecConvertedInSec) {
+ //arrange
+ TimevalStruct time1;
+ time1.tv_sec = 2;
+ time1.tv_usec = 5 * date_time::DateTime::MICROSECONDS_IN_SECOND;
+
+ TimevalStruct time2;
+ time2.tv_sec = 3;
+ time2.tv_usec = 1 * date_time::DateTime::MICROSECONDS_IN_SECOND;
+
+ //assert
+ ASSERT_EQ(3000, date_time::DateTime::calculateTimeDiff(time2, time1));
+ ASSERT_EQ(3000, date_time::DateTime::calculateTimeDiff(time1, time2));
+}
+
+TEST(DateTimeTest, DISABLED_CalculateEqualTimeDiff_UsecConvertedInSec) {
+ //arrange
+ TimevalStruct time1;
+ time1.tv_sec = 2;
+ time1.tv_usec = 2 * date_time::DateTime::MICROSECONDS_IN_SECOND;
+
+ TimevalStruct time2;
+ time2.tv_sec = 3;
+ time2.tv_usec = 1 * date_time::DateTime::MICROSECONDS_IN_SECOND;
+
+ //assert
+ ASSERT_EQ(0, date_time::DateTime::calculateTimeDiff(time2, time1));
+ ASSERT_EQ(0, date_time::DateTime::calculateTimeDiff(time1, time2));
+}
+
+TEST(DateTimeTest, DISABLED_CalculateEqualTimeSub_UsecConvertedInSec) {
+ //arrange
+ TimevalStruct time1;
+ time1.tv_sec = 3;
+ time1.tv_usec = 0;
+
+ TimevalStruct time2;
+ time2.tv_sec = 2;
+ time2.tv_usec = 1 * date_time::DateTime::MICROSECONDS_IN_SECOND;
+
+ TimevalStruct time3 = date_time::DateTime::Sub(time2, time1);
+ TimevalStruct time4 = date_time::DateTime::Sub(time1, time2);
+
+ TimevalStruct time_expected;
+ time_expected.tv_sec = 0;
+
+ //assert
+ ASSERT_EQ(EQUAL, date_time::DateTime::compareTime(time_expected, time3));
+ ASSERT_EQ(EQUAL, date_time::DateTime::compareTime(time_expected, time4));
}
} // namespace utils
diff --git a/src/components/utils/test/file_system_test.cc b/src/components/utils/test/file_system_test.cc
index abf09735b..54a662c51 100644
--- a/src/components/utils/test/file_system_test.cc
+++ b/src/components/utils/test/file_system_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Ford Motor Company
+ * Copyright (c) 2015, Ford Motor Company
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,82 +30,1146 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include "gmock/gmock.h"
+#include <algorithm>
+#include <fstream>
+#include "gtest/gtest.h"
#include "utils/file_system.h"
-namespace test {
-namespace components {
-namespace utils {
+namespace test {
+namespace components {
+namespace utils {
-TEST(FileSystemTest, CommonFileSystemTest) {
- // Directory creation
- ASSERT_FALSE(file_system::DirectoryExists("./Test directory"));
+using namespace file_system;
- file_system::CreateDirectory("./Test directory");
+TEST(FileSystemTest, CreateDeleteDirectory) {
- ASSERT_TRUE(file_system::DirectoryExists("./Test directory"));
+ ASSERT_FALSE(DirectoryExists("./Test directory"));
+ // Directory creation
+ CreateDirectory("./Test directory");
- ASSERT_TRUE(file_system::IsDirectory("./Test directory"));
+ EXPECT_TRUE(DirectoryExists("./Test directory"));
+ EXPECT_TRUE(IsDirectory("./Test directory"));
+ // Directory removing
+ EXPECT_TRUE(RemoveDirectory("./Test directory", false));
+ EXPECT_FALSE(DirectoryExists("./Test directory"));
+}
+
+TEST(FileSystemTest, CreateDirectoryTwice) {
+ ASSERT_FALSE(DirectoryExists("./Test directory"));
+ // Directory creation
+ CreateDirectory("./Test directory");
+
+ EXPECT_TRUE(DirectoryExists("./Test directory"));
+ EXPECT_TRUE(IsDirectory("./Test directory"));
+
+ // Create directory second time
+ CreateDirectory("./Test directory");
+ EXPECT_TRUE(DirectoryExists("./Test directory"));
+
+ // Directory removing
+ EXPECT_TRUE(RemoveDirectory("./Test directory", false));
+ //try delete directory again
+ EXPECT_FALSE(RemoveDirectory("./Test directory", false));
+ EXPECT_FALSE(DirectoryExists("./Test directory"));
+}
+
+TEST(FileSystemTest,DeleteDirectoryRecursively) {
+ ASSERT_FALSE(DirectoryExists("./Test directory"));
+ // Create directories
+ CreateDirectory("./Test directory");
+ CreateDirectory("./Test directory/Test directory 2");
+
+ // Create file inside directory
+ EXPECT_TRUE(CreateFile("./Test directory/test file"));
+
+ EXPECT_FALSE(RemoveDirectory("./Test directory", false));
+ EXPECT_TRUE(DirectoryExists("./Test directory"));
+ EXPECT_TRUE(IsDirectory("./Test directory"));
+
+ EXPECT_TRUE(RemoveDirectory("./Test directory", true));
+ EXPECT_FALSE(DirectoryExists("./Test directory"));
+}
+
+TEST(FileSystemTest, CreateDirectoryRecursivelyDeleteRecursively) {
+ ASSERT_FALSE(DirectoryExists("./Test directory"));
+ // Create directories recursively
+ CreateDirectoryRecursively(
+ "./Test directory/Test directory 2/Test directory 3");
+
+ EXPECT_TRUE(DirectoryExists("./Test directory"));
+ EXPECT_TRUE(IsDirectory("./Test directory"));
+
+ EXPECT_TRUE(DirectoryExists("./Test directory/Test directory 2"));
+ EXPECT_TRUE(IsDirectory("./Test directory/Test directory 2"));
+
+ EXPECT_TRUE(
+ DirectoryExists("./Test directory/Test directory 2/Test directory 3"));
+ EXPECT_TRUE(
+ IsDirectory("./Test directory/Test directory 2/Test directory 3"));
+
+ // Delete recursively
+ EXPECT_TRUE(RemoveDirectory("./Test directory", true));
+ EXPECT_FALSE(DirectoryExists("./Test directory"));
+ EXPECT_FALSE(DirectoryExists("./Test directory/Test directory 2"));
+ EXPECT_FALSE(
+ DirectoryExists("./Test directory/Test directory 2/Test directory 3"));
+}
+
+TEST(FileSystemTest, TwiceCreateDirectoryRecursivelyDeleteRecursivelyOnce) {
+ ASSERT_FALSE(DirectoryExists("./Test directory"));
+ // Create directories recursively
+ EXPECT_TRUE(
+ CreateDirectoryRecursively(
+ "./Test directory/Test directory 2/Test directory 3"));
+
+ // Check that all directories are created
+ EXPECT_TRUE(DirectoryExists("./Test directory"));
+ EXPECT_TRUE(IsDirectory("./Test directory"));
+
+ EXPECT_TRUE(DirectoryExists("./Test directory/Test directory 2"));
+ EXPECT_TRUE(IsDirectory("./Test directory/Test directory 2"));
+
+ EXPECT_TRUE(
+ DirectoryExists("./Test directory/Test directory 2/Test directory 3"));
+ EXPECT_TRUE(
+ IsDirectory("./Test directory/Test directory 2/Test directory 3"));
+
+ // Create directories recursively second time
+ EXPECT_TRUE(
+ CreateDirectoryRecursively(
+ "./Test directory/Test directory 2/Test directory 3"));
+
+ EXPECT_TRUE(DirectoryExists("./Test directory"));
+
+ EXPECT_TRUE(DirectoryExists("./Test directory/Test directory 2"));
+
+ EXPECT_TRUE(
+ DirectoryExists("./Test directory/Test directory 2/Test directory 3"));
+
+ // Delete recursively
+ EXPECT_TRUE(RemoveDirectory("./Test directory", true));
+ EXPECT_FALSE(DirectoryExists("./Test directory"));
+ // Delete recursively again is impossible
+ EXPECT_FALSE(RemoveDirectory("./Test directory", true));
+
+ EXPECT_FALSE(DirectoryExists("./Test directory"));
+ EXPECT_FALSE(DirectoryExists("./Test directory/Test directory 2"));
+ EXPECT_FALSE(
+ DirectoryExists("./Test directory/Test directory 2/Test directory 3"));
+}
+
+TEST(FileSystemTest, CreateDeleteFile) {
+ ASSERT_FALSE(FileExists("./test file"));
// File creation
- ASSERT_FALSE(file_system::FileExists("./Test directory/test file"));
+ EXPECT_TRUE(CreateFile("./test file"));
+ EXPECT_FALSE(IsDirectory("./test file"));
- std::vector<unsigned char> data;
- data.push_back('t');
- data.push_back('e');
- data.push_back('s');
- data.push_back('t');
+ // Delete file
+ EXPECT_TRUE(DeleteFile("./test file"));
+ //try delete file again
+ EXPECT_FALSE(DeleteFile("./test file"));
+ EXPECT_FALSE(FileExists("./test file"));
+}
+
+TEST(FileSystemTest, CheckIsDirectory) {
+ ASSERT_FALSE(DirectoryExists("./Test directory"));
+ // Create directory and check that IsDirectory=true
+ CreateDirectory("./Test directory");
+ EXPECT_TRUE(IsDirectory("./Test directory"));
+
+ // Delete directory and check, that IsDirectory=false
+ EXPECT_TRUE(RemoveDirectory("./Test directory", false));
+ EXPECT_FALSE(DirectoryExists("./Test directory"));
+ EXPECT_FALSE(IsDirectory("./Test directory"));
+
+ // Create file and check that IsDirectory=false
+ ASSERT_FALSE(FileExists("./test file"));
+ EXPECT_TRUE(CreateFile("./test file"));
+ EXPECT_FALSE(IsDirectory("./test file"));
+
+ // Delete file and check that IsDirectory=false
+ EXPECT_TRUE(DeleteFile("./test file"));
+ EXPECT_FALSE(FileExists("./test file"));
+ EXPECT_FALSE(IsDirectory("./test file"));
+}
- ASSERT_TRUE(file_system::Write("./Test directory/test file", data));
+TEST(FileSystemTest, CreateFileTwice) {
+ ASSERT_FALSE(FileExists("./test file"));
- ASSERT_TRUE(file_system::FileExists("./Test directory/test file"));
+ // Create file first time
+ EXPECT_TRUE(CreateFile("./test file"));
+ EXPECT_TRUE(FileExists("./test file"));
- ASSERT_FALSE(file_system::IsDirectory("./Test directory/test file"));
+ // Create file second time
+ EXPECT_TRUE(CreateFile("./test file"));
+ EXPECT_TRUE(FileExists("./test file"));
+
+ // Delete file
+ EXPECT_TRUE(DeleteFile("./test file"));
+ EXPECT_FALSE(FileExists("./test file"));
+}
+
+TEST(FileSystemTest, CreateOpenCloseFileStream) {
+ ASSERT_FALSE(FileExists("./test file"));
+
+ // Create and open file
+ std::ofstream* test_file = Open("./test file");
+ EXPECT_TRUE(test_file->is_open());
+ Close(test_file);
+ EXPECT_FALSE(test_file->is_open());
+ delete test_file;
+
+ EXPECT_TRUE(FileExists("./test file"));
+
+ EXPECT_TRUE(DeleteFile("./test file"));
+ EXPECT_FALSE(FileExists("./test file"));
+}
+
+TEST(FileSystemTest, CreateAndOpenFileStreamTwice) {
+ ASSERT_FALSE(FileExists("./test file"));
+
+ // Create and open file
+ std::ofstream* test_file = Open("./test file");
+ EXPECT_TRUE(test_file->is_open());
+ Close(test_file);
+ EXPECT_FALSE(test_file->is_open());
+ delete test_file;
+
+ EXPECT_TRUE(FileExists("./test file"));
+
+ // Create file second time
+ EXPECT_TRUE(CreateFile("./test file"));
+
+ EXPECT_TRUE(DeleteFile("./test file"));
+ EXPECT_FALSE(FileExists("./test file"));
+}
+
+TEST(FileSystemTest, OpenFileWriteInFileStream) {
+ ASSERT_FALSE(FileExists("./test file"));
+
+ // Create and open file
+ std::ofstream* test_file = Open("./test file");
+ EXPECT_TRUE(test_file->is_open());
+
+ // Write data in file
+ uint32_t data_size = 4;
+ uint8_t* data = new uint8_t[data_size];
+ for (uint i = 0; i < data_size; ++i) {
+ data[i] = i;
+ }
+ EXPECT_TRUE(Write(test_file, data, data_size));
+ Close(test_file);
+ EXPECT_FALSE(test_file->is_open());
+ delete test_file;
// Read data from file
- std::vector<unsigned char> result;
+ std::vector < uint8_t > result;
+ EXPECT_TRUE(ReadBinaryFile("./test file", result));
+ EXPECT_FALSE(result.empty());
+
+// Check data
+ for (uint i = 0; i < data_size; ++i) {
+ EXPECT_EQ(data[i], result[i]);
+ }
+ delete data;
- ASSERT_TRUE(file_system::ReadBinaryFile("./Test directory/test file",
- result));
- ASSERT_FALSE(result.empty());
+ // Delete file
+ EXPECT_TRUE(DeleteFile("./test file"));
+ EXPECT_FALSE(FileExists("./test file"));
+}
- // list files
- ASSERT_TRUE(file_system::Write("./Test directory/test file 2", data));
+TEST(FileSystemTest, CannotWriteInClosedFileStream) {
+ ASSERT_FALSE(FileExists("./test file"));
- std::vector<std::string> list;
- list = file_system::ListFiles("./Test directory");
+ // Create and open file
+ std::ofstream* test_file = Open("./test file");
+ EXPECT_TRUE(test_file->is_open());
+ Close(test_file);
+ EXPECT_FALSE(test_file->is_open());
- ASSERT_FALSE(list.empty());
- std::sort(list.begin(), list.end());
- ASSERT_EQ("test file", list[0]);
- ASSERT_EQ("test file 2", list[1]);
+ // Write data in file
+ uint32_t data_size = 4;
+ uint8_t* data = new uint8_t[data_size];
+ for (uint i = 0; i < data_size; ++i) {
+ data[i] = i;
+ }
+ EXPECT_TRUE(Write(test_file, data, data_size));
+
+ delete data;
+ delete test_file;
+
+ // Read data from file
+ std::vector < uint8_t > result;
+ EXPECT_TRUE(ReadBinaryFile("./test file", result));
+ EXPECT_TRUE(result.empty());
// Delete file
- ASSERT_TRUE(file_system::FileExists("./Test directory/test file 2"));
- ASSERT_TRUE(file_system::DeleteFile("./Test directory/test file 2"));
- ASSERT_FALSE(file_system::FileExists("./Test directory/test file 2"));
+ EXPECT_TRUE(DeleteFile("./test file"));
+ EXPECT_FALSE(FileExists("./test file"));
+}
+
+TEST(FileSystemTest, CreateWriteInFileStream_CreateFileAgain_FileRewritten) {
+ ASSERT_FALSE(FileExists("./test file"));
+
+ // Create and open file
+ std::ofstream* test_file = Open("./test file");
+ EXPECT_TRUE(test_file->is_open());
- // Delete empty directory
- file_system::CreateDirectory("./Test directory/Empty directory");
+ // Write data in file
+ uint32_t data_size = 4;
+ uint8_t* data = new uint8_t[data_size];
+ for (uint i = 0; i < data_size; ++i) {
+ data[i] = i;
+ }
+ EXPECT_TRUE(Write(test_file, data, data_size));
- ASSERT_TRUE(file_system::DirectoryExists(
- "./Test directory/Empty directory"));
- ASSERT_TRUE(file_system::RemoveDirectory(
- "./Test directory/Empty directory", false));
- ASSERT_FALSE(file_system::DirectoryExists(
- "./Test directory/Empty directory"));
+ Close(test_file);
+ delete test_file;
- ASSERT_FALSE(file_system::RemoveDirectory("./Test directory", false));
- ASSERT_TRUE(file_system::DirectoryExists("./Test directory"));
+ std::vector < uint8_t > result;
+ EXPECT_TRUE(ReadBinaryFile("./test file", result));
+ EXPECT_FALSE(result.empty());
- // Delete directory recursively
- file_system::CreateDirectory("./Test directory/Test directory 2");
- ASSERT_TRUE(file_system::Write(
- "./Test directory/Test directory 2/test file 2", data));
- ASSERT_TRUE(file_system::RemoveDirectory("./Test directory", true));
+ delete data;
+ EXPECT_TRUE(CreateFile("./test file"));
- ASSERT_FALSE(file_system::DirectoryExists("./Test directory"));
+ // Now file is empty
+ EXPECT_TRUE(ReadBinaryFile("./test file", result));
+ EXPECT_TRUE(result.empty());
+
+ EXPECT_TRUE(DeleteFile("./test file"));
+ EXPECT_FALSE(FileExists("./test file"));
}
+
+TEST(FileSystemTest, CreateFileStream_WriteInFile_FileStreamNotClosed) {
+ ASSERT_FALSE(FileExists("./test file"));
+
+ // Create and open file
+ std::ofstream* test_file = Open("./test file");
+ EXPECT_TRUE(test_file->is_open());
+
+ // Write data in file
+ uint32_t data_size = 4;
+ std::vector < uint8_t > data;
+ for (uint i = 0; i < data_size; ++i) {
+ data.push_back(i);
+ }
+ // Write data in file
+ EXPECT_TRUE(Write("./test file", data));
+ EXPECT_TRUE(test_file->is_open());
+
+ // Close filestream
+ Close(test_file);
+ delete test_file;
+
+ std::vector < uint8_t > result;
+ EXPECT_TRUE(ReadBinaryFile("./test file", result));
+ EXPECT_FALSE(result.empty());
+
+ EXPECT_TRUE(DeleteFile("./test file"));
+ EXPECT_FALSE(FileExists("./test file"));
+}
+
+TEST(FileSystemTest, CreateFileStream_WriteInFileWriteInFileStream_FileIncludeLastData) {
+ ASSERT_FALSE(FileExists("./test file"));
+
+ // Create and open file
+ std::ofstream* test_file = Open("./test file");
+ EXPECT_TRUE(test_file->is_open());
+
+ // Write data in file
+ uint32_t data_size = 4;
+ std::vector < uint8_t > data;
+ for (uint i = 0; i < data_size; ++i) {
+ data.push_back(i);
+ }
+ // Write data in file
+ EXPECT_TRUE(Write("./test file", data));
+
+ EXPECT_TRUE(test_file->is_open());
+
+ // Write in filestream
+ uint8_t* data_2 = new uint8_t[data_size];
+ for (uint i = 0; i < data_size; ++i) {
+ data_2[i] = i + data_size;
+ }
+ EXPECT_TRUE(Write(test_file, data_2, data_size));
+ // Close filestream
+ Close(test_file);
+
+ delete test_file;
+ std::vector < uint8_t > result;
+ EXPECT_TRUE(ReadBinaryFile("./test file", result));
+ EXPECT_FALSE(result.empty());
+
+ // Check data
+ EXPECT_EQ(result.size(), data_size);
+ for (uint i = 0; i < data_size; ++i) {
+ EXPECT_NE(data[i], result[i]);
+ EXPECT_EQ(data_2[i], result[i]);
+ }
+
+ delete data_2;
+
+ EXPECT_TRUE(DeleteFile("./test file"));
+ EXPECT_FALSE(FileExists("./test file"));
+}
+
+TEST(FileSystemTest, WriteInFilestreamTwice_FileRewritten) {
+ ASSERT_FALSE(FileExists("./test file"));
+
+ // Create and open file
+ std::ofstream* test_file = Open("./test file");
+ EXPECT_TRUE(test_file->is_open());
+
+ // Open file second time
+ std::ofstream* test_file_2 = Open("./test file");
+ EXPECT_TRUE(test_file_2->is_open());
+
+ uint32_t data_size = 4;
+ uint8_t* data = new uint8_t[data_size];
+ for (uint i = 0; i < data_size; ++i) {
+ data[i] = i;
+ }
+ uint8_t* data_2 = new uint8_t[data_size];
+ for (uint i = 0; i < data_size; ++i) {
+ data_2[i] = i + 4;
+ }
+
+ // Write data in file
+ EXPECT_TRUE(Write(test_file, data, data_size));
+
+ EXPECT_TRUE(Write(test_file_2, data_2, data_size));
+
+ Close(test_file);
+ Close(test_file_2);
+
+ EXPECT_FALSE(test_file->is_open());
+ EXPECT_FALSE(test_file_2->is_open());
+
+ delete test_file;
+ delete test_file_2;
+ // Check file
+ std::vector < uint8_t > result;
+ EXPECT_TRUE(ReadBinaryFile("./test file", result));
+ EXPECT_FALSE(result.empty());
+ // Check data
+ for (uint i = 0; i < data_size; ++i) {
+ EXPECT_NE(data[i], result[i]);
+ EXPECT_EQ(data_2[i], result[i]);
+ }
+
+ delete data;
+ delete data_2;
+
+ EXPECT_TRUE(DeleteFile("./test file"));
+ EXPECT_FALSE(FileExists("./test file"));
+}
+
+TEST(FileSystemTest, WriteInFilestreamConsequentially_FileRewritten) {
+ ASSERT_FALSE(FileExists("./test file"));
+
+ // Create and open file
+ std::ofstream* test_file = Open("./test file");
+ EXPECT_TRUE(test_file->is_open());
+
+ uint32_t data_size = 4;
+ uint8_t* data = new uint8_t[data_size];
+ for (uint i = 0; i < data_size; ++i) {
+ data[i] = i;
+ }
+
+ // Write data in file
+ EXPECT_TRUE(Write(test_file, data, data_size));
+
+ Close(test_file);
+ EXPECT_FALSE(test_file->is_open());
+
+ // Open file second time
+ std::ofstream* test_file_2 = Open("./test file");
+ EXPECT_TRUE(test_file_2->is_open());
+
+ // Write second time
+ uint8_t* data_2 = new uint8_t[data_size];
+ for (uint i = 0; i < data_size; ++i) {
+ data_2[i] = i + 4;
+ }
+ EXPECT_TRUE(Write(test_file_2, data_2, data_size));
+
+ Close(test_file_2);
+ EXPECT_FALSE(test_file_2->is_open());
+
+ delete test_file;
+ delete test_file_2;
+ // Check file
+ std::vector < uint8_t > result;
+ EXPECT_TRUE(ReadBinaryFile("./test file", result));
+ EXPECT_FALSE(result.empty());
+
+ // Check data
+ EXPECT_EQ(result.size(), data_size);
+ for (uint i = 0; i < data_size; ++i) {
+ EXPECT_NE(data[i], result[i]);
+ EXPECT_EQ(data_2[i], result[i]);
+ }
+
+ delete data;
+ delete data_2;
+
+ EXPECT_TRUE(DeleteFile("./test file"));
+ EXPECT_FALSE(FileExists("./test file"));
+}
+
+TEST(FileSystemTest, CreateFileTwiceWriteInFileTwice) {
+ ASSERT_FALSE(FileExists("./test file"));
+
+ // Create and open file
+ EXPECT_TRUE(CreateFile("./test file"));
+ EXPECT_TRUE(FileExists("./test file"));
+
+ uint32_t data_size = 4;
+ std::vector < uint8_t > data;
+ for (uint i = 0; i < data_size; ++i) {
+ data.push_back(i);
+ }
+
+ // Write data in file
+ EXPECT_TRUE(Write("./test file", data));
+ // Create file second time
+ EXPECT_TRUE(CreateFile("./test file"));
+ EXPECT_TRUE(CreateFile("./test file"));
+
+ std::vector < uint8_t > data_2;
+ for (uint i = 0; i < data_size; ++i) {
+ data_2.push_back(i + data_size);
+ }
+
+ // Write data in file
+ EXPECT_TRUE(Write("./test file", data_2));
+
+ // Check file
+ std::vector < uint8_t > result;
+ EXPECT_TRUE(ReadBinaryFile("./test file", result));
+ EXPECT_FALSE(result.empty());
+
+ EXPECT_EQ(data_2, result);
+ EXPECT_EQ(result.size(), data_size);
+ // Check data
+ for (uint i = 0; i < data_size; ++i) {
+ EXPECT_NE(data[i], result[i]);
+ EXPECT_EQ(data_2[i], result[i]);
+ }
+
+ EXPECT_TRUE(DeleteFile("./test file"));
+ EXPECT_FALSE(FileExists("./test file"));
+}
+
+TEST(FileSystemTest, WriteInFileTwiceFileRewritten) {
+ ASSERT_FALSE(FileExists("./test file"));
+
+ // Create and open file
+ EXPECT_TRUE(CreateFile("./test file"));
+ EXPECT_TRUE(FileExists("./test file"));
+
+ // Write data in file
+ uint32_t data_size = 4;
+ std::vector < uint8_t > data;
+ for (uint i = 0; i < data_size; ++i) {
+ data.push_back(i);
+ }
+ EXPECT_TRUE(Write("./test file", data));
+
+ // Write data to file again
+ std::vector < uint8_t > data_2;
+ for (uint i = 0; i < data_size; ++i) {
+ data_2.push_back(i + data_size);
+ }
+ EXPECT_TRUE(Write("./test file", data_2));
+
+ // Check file
+ std::vector < uint8_t > result;
+ EXPECT_TRUE(ReadBinaryFile("./test file", result));
+ EXPECT_FALSE(result.empty());
+
+ // Check data
+ EXPECT_EQ(data_size, result.size());
+ for (uint i = 0; i < data_size; ++i) {
+ EXPECT_NE(data[i], result[i]);
+ EXPECT_EQ(data_2[i], result[i]);
+ }
+
+ EXPECT_TRUE(DeleteFile("./test file"));
+ EXPECT_FALSE(FileExists("./test file"));
+}
+
+TEST(FileSystemTest, WriteDataInTheEndOfFile) {
+ ASSERT_FALSE(FileExists("./test file"));
+
+ EXPECT_TRUE(CreateFile("./test file"));
+ EXPECT_TRUE(FileExists("./test file"));
+
+ int32_t data_size = 4;
+ std::vector < uint8_t > data;
+ for (int i = 0; i < data_size; ++i) {
+ data.push_back(i);
+ }
+
+ // Write data in file
+ EXPECT_TRUE(Write("./test file", data));
+
+ // Write in file second time
+ std::vector < uint8_t > data_2;
+ for (int i = 0; i < data_size; ++i) {
+ data_2.push_back(i + data_size);
+ }
+
+ // Write data in file
+ EXPECT_TRUE(Write("./test file", data_2, std::ios_base::app));
+
+ // Check file
+ std::vector < uint8_t > result;
+ EXPECT_TRUE(ReadBinaryFile("./test file", result));
+ EXPECT_FALSE(result.empty());
+
+ std::vector < uint8_t > data_check;
+ for (int i = 0; i < 2 * data_size; ++i) {
+ data_check.push_back(i);
+ }
+
+ // Check data
+ EXPECT_EQ(data_check.size(), result.size());
+ for (int i = 0; i < 2 * data_size; ++i) {
+ EXPECT_EQ(data_check[i], result[i]);
+ }
+
+ EXPECT_TRUE(DeleteFile("./test file"));
+ EXPECT_FALSE(FileExists("./test file"));
+}
+
+TEST(FileSystemTest, WriteInFileStream_WriteInFileInTheEndOfFile_FileIncludeBothData) {
+ ASSERT_FALSE(FileExists("./test file"));
+
+ // Create and open file
+ std::ofstream* test_file = Open("./test file");
+ EXPECT_TRUE(test_file->is_open());
+
+ // Write data in file
+ uint32_t data_size = 4;
+ std::vector < uint8_t > data;
+ for (uint i = 0; i < data_size; ++i) {
+ data.push_back(i);
+ }
+ // Write data in file
+ EXPECT_TRUE(Write("./test file", data));
+ EXPECT_TRUE(test_file->is_open());
+
+ // Close filestream
+ Close(test_file);
+
+ delete test_file;
+ // Write in file second time
+ std::vector < uint8_t > data_2;
+ for (uint i = 0; i < data_size; ++i) {
+ data_2.push_back(i + data_size);
+ }
+
+ // Write data in file
+ EXPECT_TRUE(Write("./test file", data_2, std::ios_base::app));
+
+ // Check file
+ std::vector < uint8_t > result;
+ EXPECT_TRUE(ReadBinaryFile("./test file", result));
+ EXPECT_FALSE(result.empty());
+
+ std::vector < uint8_t > data_check;
+ for (uint i = 0; i < 2 * data_size; ++i) {
+ data_check.push_back(i);
+ }
+
+ // Check data
+ EXPECT_EQ(data_check.size(), result.size());
+ for (uint i = 0; i < 2 * data_size; ++i) {
+ EXPECT_EQ(data_check[i], result[i]);
+ }
+
+ EXPECT_TRUE(DeleteFile("./test file"));
+ EXPECT_FALSE(FileExists("./test file"));
+}
+
+TEST(FileSystemTest, OpenFileStreamForRead_WriteInFileStream) {
+ ASSERT_FALSE(FileExists("./test file"));
+ // File creation
+ EXPECT_TRUE(CreateFile("./test file"));
+ std::ofstream* test_file = Open("./test file", std::ios_base::in);
+ EXPECT_TRUE(test_file->is_open());
+
+ // Write data in file
+ uint32_t data_size = 4;
+ uint8_t* data = new uint8_t[data_size];
+ for (uint i = 0; i < data_size; ++i) {
+ data[i] = i;
+ }
+
+ EXPECT_TRUE(Write(test_file, data, data_size));
+
+ Close(test_file);
+ EXPECT_FALSE(test_file->is_open());
+
+ // Read data from file
+ std::vector < uint8_t > result;
+ EXPECT_TRUE(ReadBinaryFile("./test file", result));
+ EXPECT_FALSE(result.empty());
+
+ // Check data
+ for (uint i = 0; i < data_size; ++i) {
+ EXPECT_EQ(data[i], result[i]);
+ }
+
+ delete data;
+ delete test_file;
+
+ EXPECT_TRUE(FileExists("./test file"));
+
+ EXPECT_TRUE(DeleteFile("./test file"));
+ EXPECT_FALSE(FileExists("./test file"));
+}
+
+TEST(FileSystemTest, WriteFileNotExists) {
+ ASSERT_FALSE(FileExists("./test file"));
+
+ unsigned char tmp[] = { 't', 'e', 's', 't' };
+ std::vector<unsigned char> data(tmp, tmp + 4);
+ EXPECT_TRUE(Write("./test file", data));
+ // File now exists
+ ASSERT_TRUE(FileExists("./test file"));
+ EXPECT_TRUE(DeleteFile("./test file"));
+ EXPECT_FALSE(FileExists("./test file"));
+}
+
+TEST(FileSystemTest, WriteFileReadFile) {
+ ASSERT_FALSE(FileExists("./test file"));
+ EXPECT_TRUE(CreateFile("./test file"));
+
+ unsigned char tmp[] = { 't', 'e', 's', 't' };
+ std::vector<unsigned char> data(tmp, tmp + 4);
+ EXPECT_TRUE(Write("./test file", data));
+
+ // Read data from file
+ std::string result;
+ std::string check = "test";
+ EXPECT_TRUE(ReadFile("./test file", result));
+ EXPECT_NE(0, result.size());
+ EXPECT_EQ(check, result);
+
+ EXPECT_TRUE(DeleteFile("./test file"));
+ EXPECT_FALSE(FileExists("./test file"));
+}
+
+TEST(FileSystemTest, WriteBinaryDataReadBinaryFile) {
+ ASSERT_FALSE(FileExists("./test file"));
+ EXPECT_TRUE(CreateFile("./test file"));
+
+ uint8_t tmp[] = { 1, 2, 3, 4};
+ std::vector<uint8_t> data(tmp, tmp + 4);
+ EXPECT_TRUE(WriteBinaryFile("./test file", data));
+
+ // Read data from file
+ std::vector < uint8_t > result;
+ EXPECT_TRUE(ReadBinaryFile("./test file", result));
+ EXPECT_FALSE(result.empty());
+ EXPECT_EQ(data, result);
+
+ EXPECT_TRUE(DeleteFile("./test file"));
+}
+
+TEST(FileSystemTest, WriteBinaryDataTwice_FileRewritten) {
+ ASSERT_FALSE(FileExists("./test file"));
+
+ EXPECT_TRUE(CreateFile("./test file"));
+ EXPECT_TRUE(FileExists("./test file"));
+
+ int32_t data_size = 4;
+ std::vector < uint8_t > data;
+ for (int i = 0; i < data_size; ++i) {
+ data.push_back(i);
+ }
+ // Write data in file
+ EXPECT_TRUE(WriteBinaryFile("./test file", data));
+
+ // Write in file second time
+ std::vector < uint8_t > data_2;
+ for (int i = 0; i < data_size; ++i) {
+ data_2.push_back(i + data_size);
+ }
+
+ // Write data in file
+ EXPECT_TRUE(WriteBinaryFile("./test file", data_2));
+
+ // Check file
+ std::vector < uint8_t > result;
+ EXPECT_TRUE(ReadBinaryFile("./test file", result));
+ EXPECT_FALSE(result.empty());
+
+ // Check data
+ EXPECT_EQ(data_2.size(), result.size());
+ for (int i = 0; i < data_size; ++i) {
+ EXPECT_EQ(data_2[i], result[i]);
+ }
+
+ EXPECT_TRUE(DeleteFile("./test file"));
+ EXPECT_FALSE(FileExists("./test file"));
+}
+
+TEST(FileSystemTest, WriteBinaryDataFileNotExists) {
+ ASSERT_FALSE(FileExists("./test file"));
+
+ int32_t data_size = 4;
+ std::vector < uint8_t > data;
+ for (int i = 0; i < data_size; ++i) {
+ data.push_back(i);
+ }
+
+ EXPECT_TRUE(WriteBinaryFile("./test file", data));
+ ASSERT_TRUE(FileExists("./test file"));
+ EXPECT_TRUE(DeleteFile("./test file"));
+ EXPECT_FALSE(FileExists("./test file"));
+}
+
+TEST(FileSystemTest, WriteDataAsBinaryData) {
+ ASSERT_FALSE(FileExists("./test file"));
+
+ unsigned char tmp[] = { 't', 'e', 's', 't' };
+ std::vector<unsigned char> data(tmp, tmp + 4);
+ EXPECT_TRUE(WriteBinaryFile("./test file", data));
+ ASSERT_TRUE(FileExists("./test file"));
+
+ // Check file
+ std::vector < uint8_t > result;
+ EXPECT_TRUE(ReadBinaryFile("./test file", result));
+ EXPECT_FALSE(result.empty());
+
+ EXPECT_EQ(data.size(), result.size());
+
+ for (uint i = 0; i < result.size(); ++i) {
+ EXPECT_EQ(data[i], result[i]);
+ }
+
+ EXPECT_TRUE(DeleteFile("./test file"));
+ EXPECT_FALSE(FileExists("./test file"));
+}
+
+TEST(FileSystemTest, WriteEmptyData) {
+ ASSERT_FALSE(FileExists("./test file"));
+
+ std::vector<unsigned char> data;
+ EXPECT_TRUE(Write("./test file", data));
+ ASSERT_TRUE(FileExists("./test file"));
+
+ // Check file
+ std::vector < uint8_t > result;
+ EXPECT_TRUE(ReadBinaryFile("./test file", result));
+ EXPECT_TRUE(result.empty());
+
+ EXPECT_TRUE(DeleteFile("./test file"));
+ EXPECT_FALSE(FileExists("./test file"));
+}
+
+TEST(FileSystemTest, WriteEmptyDataAsBinaryData) {
+ ASSERT_FALSE(FileExists("./test file"));
+
+ // Write empty data
+ std::vector<unsigned char> data;
+ EXPECT_TRUE(WriteBinaryFile("./test file", data));
+ ASSERT_TRUE(FileExists("./test file"));
+
+ // Check file
+ std::vector < uint8_t > result;
+ EXPECT_TRUE(ReadBinaryFile("./test file", result));
+ EXPECT_TRUE(result.empty());
+
+ EXPECT_TRUE(DeleteFile("./test file"));
+ EXPECT_FALSE(FileExists("./test file"));
+}
+
+TEST(FileSystemTest, WriteBinaryData_WriteDataInTheEndOfFile) {
+ ASSERT_FALSE(FileExists("./test file"));
+
+ // Write binary file
+ unsigned char tmp[] = { 't', 'e', 's', 't' };
+ std::vector<unsigned char> data(tmp, tmp + 4);
+ EXPECT_TRUE(WriteBinaryFile("./test file", data));
+ ASSERT_TRUE(FileExists("./test file"));
+
+ // Write in file second time
+ int32_t data_size = 4;
+ std::vector < uint8_t > data_2;
+ for (int i = 0; i < data_size; ++i) {
+ data_2.push_back(i);
+ }
+
+ // Write data in file
+ EXPECT_TRUE(Write("./test file", data_2, std::ios_base::app));
+
+ // Check file
+ std::vector < uint8_t > result;
+ EXPECT_TRUE(ReadBinaryFile("./test file", result));
+ EXPECT_FALSE(result.empty());
+
+ // Prepare data for check
+ data.insert(data.end(), data_2.begin(), data_2.end());
+
+ // Compare data
+ EXPECT_EQ(data.size(), result.size());
+ for (uint i = 0; i < result.size(); ++i) {
+ EXPECT_EQ(data[i], result[i]);
+ }
+
+ EXPECT_TRUE(DeleteFile("./test file"));
+ EXPECT_FALSE(FileExists("./test file"));
+}
+
+TEST(FileSystemTest, CreateFile_WriteDataWithFlagOpenForReading) {
+ ASSERT_FALSE(FileExists("./test file"));
+ EXPECT_TRUE(CreateFile("./test file"));
+ // Write data in file
+ int32_t data_size = 4;
+ std::vector < uint8_t > data;
+ for (int i = 0; i < data_size; ++i) {
+ data.push_back(i);
+ }
+ EXPECT_TRUE(Write("./test file", data, std::ios_base::in));
+ EXPECT_TRUE(FileExists("./test file"));
+
+ // Check file
+ std::vector < uint8_t > result;
+ EXPECT_TRUE(ReadBinaryFile("./test file", result));
+ EXPECT_FALSE(result.empty());
+
+ // Compare data
+ EXPECT_EQ(data.size(), result.size());
+ for (uint i = 0; i < result.size(); ++i) {
+ EXPECT_EQ(data[i], result[i]);
+ }
+
+ EXPECT_TRUE(DeleteFile("./test file"));
+ EXPECT_FALSE(FileExists("./test file"));
+}
+
+TEST(FileSystemTest, FileDoesNotCreated_WriteFileWithFlagOpenForReadingIsImpossible) {
+ ASSERT_FALSE(FileExists("./test file"));
+
+ // Write data in file is impossible
+ int32_t data_size = 4;
+ std::vector < uint8_t > data;
+ for (int i = 0; i < data_size; ++i) {
+ data.push_back(i);
+ }
+ EXPECT_FALSE(Write("./test file", data, std::ios_base::in));
+ EXPECT_FALSE(FileExists("./test file"));
+}
+
+TEST(FileSystemTest, WriteFileGetSize) {
+ ASSERT_FALSE(FileExists("./test file"));
+ EXPECT_TRUE(CreateFile("./test file"));
+ EXPECT_EQ(0, FileSize("./test file"));
+
+ unsigned char tmp[] = { 't', 'e', 's', 't' };
+ std::vector<unsigned char> data(tmp, tmp + 4);
+ EXPECT_TRUE(Write("./test file", data));
+
+ EXPECT_NE(0, FileSize("./test file"));
+
+ EXPECT_TRUE(DeleteFile("./test file"));
+ EXPECT_FALSE(FileExists("./test file"));
+}
+
+TEST(FileSystemTest, CreateFileCheckDefaultAccess) {
+ // File creation
+ ASSERT_FALSE(FileExists("./test file"));
+ EXPECT_TRUE(CreateFile("./test file"));
+
+ // Check accesses
+ EXPECT_TRUE(IsAccessible("./test file", R_OK));
+ EXPECT_TRUE(IsAccessible("./test file", W_OK));
+ EXPECT_TRUE(IsReadingAllowed("./test file"));
+ EXPECT_TRUE(IsWritingAllowed("./test file"));
+
+ EXPECT_TRUE(DeleteFile("./test file"));
+ EXPECT_FALSE(FileExists("./test file"));
+}
+
+TEST(FileSystemTest, GetFileModificationTime) {
+ ASSERT_FALSE(FileExists("./test file"));
+
+ EXPECT_TRUE(CreateFile("./test file"));
+
+ uint64_t modif_time = GetFileModificationTime("./test file");
+ EXPECT_LE(0, modif_time);
+
+ std::vector < uint8_t > data(1, 1);
+ EXPECT_TRUE(WriteBinaryFile("./test file", data));
+
+ EXPECT_LE(0, GetFileModificationTime("./test file"));
+ EXPECT_LE(modif_time, GetFileModificationTime("./test file"));
+
+ EXPECT_TRUE(DeleteFile("./test file"));
+ EXPECT_FALSE(FileExists("./test file"));
+
+}
+
+TEST(FileSystemTest, ListFiles) {
+ ASSERT_FALSE(DirectoryExists("./Test directory"));
+ CreateDirectory("./Test directory");
+
+ std::vector < std::string > list;
+ list = ListFiles("./Test directory");
+ EXPECT_TRUE(list.empty());
+
+ EXPECT_TRUE(CreateFile("./Test directory/test file"));
+ EXPECT_TRUE(CreateFile("./Test directory/test file 2"));
+
+ list = ListFiles("./Test directory");
+ EXPECT_FALSE(list.empty());
+
+ std::sort(list.begin(), list.end());
+ EXPECT_EQ("test file", list[0]);
+ EXPECT_EQ("test file 2", list[1]);
+
+ EXPECT_TRUE(RemoveDirectory("./Test directory", true));
+ EXPECT_FALSE(DirectoryExists("./Test directory"));
+
+ EXPECT_FALSE(FileExists("./Test directory/test file"));
+ EXPECT_FALSE(FileExists("./Test directory/test file 2"));
+}
+
+TEST(FileSystemTest, ListFilesIncludeSubdirectory) {
+ ASSERT_FALSE(DirectoryExists("./Test directory"));
+ CreateDirectoryRecursively("./Test directory/Test directory 2/");
+
+ std::vector < std::string > list;
+ list = ListFiles("./Test directory");
+ EXPECT_FALSE(list.empty());
+ EXPECT_EQ(1, list.size());
+ EXPECT_EQ("Test directory 2", list[0]);
+
+ EXPECT_TRUE(RemoveDirectory("./Test directory", true));
+ EXPECT_FALSE(DirectoryExists("./Test directory"));
+}
+
+TEST(FileSystemTest, ListFilesDoesNotIncludeFilesInSubdirectory) {
+ ASSERT_FALSE(DirectoryExists("./Test directory"));
+ CreateDirectoryRecursively("./Test directory/Test directory 2/");
+
+ std::vector < std::string > list;
+ list = ListFiles("./Test directory");
+ EXPECT_FALSE(list.empty());
+
+ EXPECT_TRUE(CreateFile("./Test directory/Test directory 2/test file"));
+ EXPECT_TRUE(CreateFile("./Test directory/Test directory 2/test file 2"));
+
+ list = ListFiles("./Test directory");
+ EXPECT_FALSE(list.empty());
+
+ std::sort(list.begin(), list.end());
+ EXPECT_EQ("Test directory 2", list[0]);
+ EXPECT_EQ(1, list.size());
+
+ EXPECT_TRUE(RemoveDirectory("./Test directory", true));
+ EXPECT_FALSE(DirectoryExists("./Test directory"));
+}
+
+TEST(FileSystemTest, GetAvailableDiskSpace) {
+
+ // Get available disk space before directory with file creaction and after
+ uint64_t available_space = GetAvailableDiskSpace(".");
+ EXPECT_NE(0, available_space);
+ ASSERT_FALSE(DirectoryExists("./Test directory"));
+ CreateDirectory("./Test directory");
+
+ unsigned char tmp[] = { 't', 'e', 's', 't' };
+ std::vector<unsigned char> data(tmp, tmp + 4);
+ EXPECT_TRUE(Write("./Test directory/test file", data));
+
+ EXPECT_GE(available_space, GetAvailableDiskSpace("."));
+ EXPECT_TRUE(RemoveDirectory("./Test directory"));
+ EXPECT_FALSE(DirectoryExists("./Test directory"));
+}
+
+TEST(FileSystemTest, ConvertPathForURL) {
+ std::string path = "./Test directory";
+ EXPECT_NE(path, ConvertPathForURL(path));
+ std::string path_brackets = "./Test_directory_with(brackets)";
+ EXPECT_NE(path_brackets, ConvertPathForURL(path));
+ std::string another_path = "./Test_directory/new_directory_without_spaces";
+ EXPECT_EQ(another_path, ConvertPathForURL(another_path));
+}
+
+TEST(FileSystemTest, DirectorySize) {
+ ASSERT_FALSE(DirectoryExists("./Test directory"));
+ CreateDirectory("./Test directory");
+ EXPECT_TRUE(DirectoryExists("./Test directory"));
+ // Get size of empty directory
+ EXPECT_EQ(0, DirectorySize("./Test directory"));
+ EXPECT_TRUE(CreateFile("./Test directory/test file"));
+
+ // Get size of nonempty directory with empty file
+ EXPECT_EQ(0, DirectorySize("./Test directory"));
+
+ unsigned char tmp[] = { 't', 'e', 's', 't' };
+ std::vector<unsigned char> data(tmp, tmp + 4);
+
+ EXPECT_TRUE(Write("./Test directory/test file", data));
+ // Get size of nonempty directory with nonempty file
+ EXPECT_NE(0, DirectorySize("./Test directory"));
+
+ EXPECT_TRUE(DeleteFile("./Test directory/test file"));
+ EXPECT_EQ(0, DirectorySize("./Test directory"));
+ EXPECT_TRUE(RemoveDirectory("./Test directory"));
+ EXPECT_FALSE(DirectoryExists("./Test directory"));
+}
+
+TEST(FileSystemTest, DeleteAllContentInDirectory) {
+ ASSERT_FALSE(DirectoryExists("./Test directory"));
+ CreateDirectory("./Test directory");
+
+ // Create files in directory
+ EXPECT_TRUE(CreateFile("./Test directory/test file"));
+ EXPECT_TRUE(CreateFile("./Test directory/test file 2"));
+
+ EXPECT_TRUE(FileExists("./Test directory/test file"));
+ EXPECT_TRUE(FileExists("./Test directory/test file 2"));
+
+ EXPECT_TRUE(DirectoryExists("./Test directory"));
+
+ // Create subdirectories
+ CreateDirectoryRecursively(
+ "./Test directory/Test directory 2/Test directory 3");
+
+ EXPECT_TRUE(DirectoryExists("./Test directory/Test directory 2"));
+ EXPECT_TRUE(
+ DirectoryExists("./Test directory/Test directory 2/Test directory 3"));
+
+ remove_directory_content("./Test directory");
+
+ // Directory does not include files and subdirectories
+ EXPECT_FALSE(FileExists("./Test directory/test file"));
+ EXPECT_FALSE(FileExists("./Test directory/test file 2"));
+
+ EXPECT_FALSE(
+ DirectoryExists("./Test directory/Test directory 2/Test directory 3"));
+ EXPECT_FALSE(DirectoryExists("./Test directory/Test directory 2"));
+
+ std::vector < std::string > list;
+ list = ListFiles("./Test directory");
+ EXPECT_TRUE(list.empty());
+
+ EXPECT_TRUE(DirectoryExists("./Test directory"));
+
+ EXPECT_TRUE(RemoveDirectory("./Test directory", true));
+ EXPECT_FALSE(DirectoryExists("./Test directory"));
+}
+
} // namespace utils
} // namespace components
} // namespace test
diff --git a/src/components/utils/test/lock_posix_test.cc b/src/components/utils/test/lock_posix_test.cc
new file mode 100644
index 000000000..9b0d9533b
--- /dev/null
+++ b/src/components/utils/test/lock_posix_test.cc
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * 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 the Ford Motor Company 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 HOLDER 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.
+ */
+
+#include "gtest/gtest.h"
+#include "utils/lock.h"
+
+namespace test {
+namespace components {
+namespace utils {
+
+using sync_primitives::Lock;
+
+TEST(LockPosixTest, DefaultCtorTest_ExpectNonRecursiveMutexCreated) {
+ // Create Lock object
+ Lock test_mutex;
+ // Lock mutex
+ test_mutex.Acquire();
+ // Check if created mutex is non-recursive
+ EXPECT_FALSE(test_mutex.Try());
+ // Release mutex before destroy
+ test_mutex.Release();
+}
+
+TEST(LockPosixTest, CtorTestWithFalseArgument_ExpectNonRecursiveMutexCreated) {
+ // Create Lock object
+ Lock test_mutex(false);
+ // Lock mutex
+ test_mutex.Acquire();
+ // Check if created mutex is non-recursive
+ EXPECT_FALSE(test_mutex.Try());
+ // Release mutex before destroy
+ test_mutex.Release();
+}
+
+TEST(LockPosixTest, CtorTestWithTrueArgument_ExpectRecursiveMutexCreated) {
+ // Create Lock object
+ Lock test_mutex(true);
+ // Lock mutex
+ test_mutex.Acquire();
+ // Check if created mutex is recursive
+ EXPECT_TRUE(test_mutex.Try());
+ // Release mutex before destroy
+ test_mutex.Release();
+ test_mutex.Release();
+}
+
+TEST(LockPosixTest, AcquireMutex_ExpectMutexLocked) {
+ // Create Lock object (non-recursive mutex)
+ Lock test_mutex;
+ // Lock mutex
+ test_mutex.Acquire();
+ // Try to lock it again. If locked expect false
+ EXPECT_FALSE(test_mutex.Try());
+ test_mutex.Release();
+}
+
+TEST(LockPosixTest, ReleaseMutex_ExpectMutexReleased) {
+ // Create Lock object (non-recursive mutex)
+ Lock test_mutex;
+ // Lock mutex
+ test_mutex.Acquire();
+ // Release mutex
+ test_mutex.Release();
+ // Try to lock it again. If released expect true
+ EXPECT_TRUE(test_mutex.Try());
+ test_mutex.Release();
+}
+
+TEST(LockPosixTest, TryLockNonRecursiveMutex_ExpectMutexNotLockedTwice) {
+ // Create Lock object (non-recursive mutex)
+ Lock test_mutex;
+ // Lock mutex
+ test_mutex.Try();
+ // Try to lock it again. If locked expect false
+ EXPECT_FALSE(test_mutex.Try());
+ test_mutex.Release();
+}
+
+TEST(LockPosixTest, TryLockRecursiveMutex_ExpectMutexLockedTwice) {
+ // Create Lock object (recursive mutex)
+ Lock test_mutex(true);
+ // Lock mutex
+ test_mutex.Try();
+ // Try to lock it again. Expect true and internal counter increase
+ EXPECT_TRUE(test_mutex.Try());
+ // Release mutex twice as was locked twice.
+ // Every Release() will decrement internal counter
+ test_mutex.Release();
+ test_mutex.Release();
+}
+
+} // namespace utils
+} // namespace components
+} // namespace test
diff --git a/src/components/utils/test/log4cxx.properties b/src/components/utils/test/log4cxx.properties
new file mode 100644
index 000000000..0ba34d0ad
--- /dev/null
+++ b/src/components/utils/test/log4cxx.properties
@@ -0,0 +1,11 @@
+log4j.appender.AutoTraceTestLogFile=org.apache.log4j.FileAppender
+log4j.appender.AutoTraceTestLogFile.File=AutoTraceTestLogFile.log
+log4j.appender.AutoTraceTestLogFile.append=true
+log4j.appender.AutoTraceTestLogFile.DatePattern='.' yyyy-MM-dd HH-mm
+log4j.appender.AutoTraceTestLogFile.ImmediateFlush=true
+log4j.appender.AutoTraceTestLogFile.layout=org.apache.log4j.PatternLayout
+log4j.appender.AutoTraceTestLogFile.layout.ConversionPattern=%-5p [%d{dd MMM yyyy HH:mm:ss,SSS}][%c] %F:%L %M: %m%n
+
+
+# All SmartDeviceLinkCore logs
+log4j.rootLogger=ALL, AutoTraceTestLogFile \ No newline at end of file
diff --git a/src/components/utils/test/log_message_loop_thread_test.cc b/src/components/utils/test/log_message_loop_thread_test.cc
new file mode 100644
index 000000000..789bf62f4
--- /dev/null
+++ b/src/components/utils/test/log_message_loop_thread_test.cc
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * 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 the Ford Motor Company 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 HOLDER 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.
+ */
+
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+#include "utils/log_message_loop_thread.h"
+#include "utils/logger_status.h"
+
+namespace test {
+namespace components {
+namespace utils {
+
+using namespace ::logger;
+using ::testing::_;
+
+TEST(LogMessageLoopThread,CreateLogMessageSingleton) {
+ //if logger_status is LoggerThreadNotCreated or LoggerThreadCreated,
+ // creation of singleton will be impossible
+ logger::logger_status = CreatingLoggerThread;
+
+ LogMessageLoopThread *instance_1 = LogMessageLoopThread::instance();
+ LogMessageLoopThread *instance_2 = LogMessageLoopThread::instance();
+
+ //assert
+ EXPECT_EQ(instance_1, instance_2);
+
+ LogMessageLoopThread::destroy();
+
+ EXPECT_FALSE(LogMessageLoopThread::exists());
+ logger::logger_status = LoggerThreadNotCreated;
+}
+
+TEST(LogMessageLoopThread, DestroyLogMessage_loggerStatusDeletingLogger) {
+ logger::logger_status = CreatingLoggerThread;
+ LogMessageLoopThread::instance();
+
+ //assert
+ EXPECT_EQ(CreatingLoggerThread, logger::logger_status);
+
+ //act
+ LogMessageLoopThread::destroy();
+
+ //assert
+ EXPECT_EQ(DeletingLoggerThread, logger::logger_status);
+
+ logger::logger_status = LoggerThreadNotCreated;
+}
+
+class MockLogMessageTest : public LogMessageHandler {
+ public:
+ MOCK_CONST_METHOD1(Handle, void(const LogMessage message));
+};
+
+TEST(LogMessageLoopThread, HandleNeverCalled) {
+ logger::logger_status = CreatingLoggerThread;
+
+ MockLogMessageTest mmock;
+ EXPECT_CALL(mmock,Handle(_)).Times(0);
+ LogMessageLoopThread::instance();
+
+ LogMessageLoopThread::destroy();
+ logger::logger_status = LoggerThreadNotCreated;
+}
+
+} // namespace utils
+} // namespace components
+} // namespace test
diff --git a/src/components/utils/test/message_queue_test.cc b/src/components/utils/test/message_queue_test.cc
new file mode 100644
index 000000000..fbae7a9e5
--- /dev/null
+++ b/src/components/utils/test/message_queue_test.cc
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * 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 the Ford Motor Company 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 HOLDER 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.
+ */
+
+#include <unistd.h>
+#include "gtest/gtest.h"
+#include "utils/message_queue.h"
+
+namespace test {
+namespace components {
+namespace utils {
+
+using ::utils::MessageQueue;
+
+class MessageQueueTest : public testing::Test {
+ public:
+ MessageQueueTest()
+ : test_val_1("Hello,"),
+ test_val_2("Beautiful "),
+ test_val_3("World!"),
+ test_line(""),
+ check_value(false) {
+ }
+ void add_one_element_to_queue();
+ void extract_from_queue();
+ void add_three_elements_to_queue();
+ void ShutDownQueue();
+
+ static void* add_one_element_to_queue_helper(void *context);
+ static void* extract_from_queue_helper(void *context);
+ static void* add_three_elements_to_queue_helper(void *context);
+ static void* ShutDownQueue_helper(void *context);
+
+ protected:
+ MessageQueue<std::string> test_queue;
+ std::string test_val_1;
+ std::string test_val_2;
+ std::string test_val_3;
+ std::string test_line;
+ bool check_value;
+};
+
+// Thread function - adds 1 element1 to the queue
+void MessageQueueTest::add_one_element_to_queue() {
+ test_queue.push(test_val_1);
+ pthread_exit(NULL);
+}
+
+// Thread function - removes 1 element from beginning of queue
+void MessageQueueTest::extract_from_queue() {
+ test_queue.wait();
+ test_line = test_queue.pop();
+ pthread_exit(NULL);
+}
+
+// Thread function - adds 3 elements to the queue
+void MessageQueueTest::add_three_elements_to_queue() {
+ test_queue.push(test_val_1);
+ test_queue.push(test_val_2);
+ test_queue.push(test_val_3);
+ pthread_exit(NULL);
+}
+
+// Thread function - adds 3 elements to the queue
+void MessageQueueTest::ShutDownQueue() {
+ check_value = true;
+ test_queue.Shutdown();
+ pthread_exit(NULL);
+}
+
+void* MessageQueueTest::add_one_element_to_queue_helper(void *context) {
+ (reinterpret_cast<MessageQueueTest *>(context))->add_one_element_to_queue();
+ return NULL;
+}
+void* MessageQueueTest::extract_from_queue_helper(void *context) {
+ (reinterpret_cast<MessageQueueTest *>(context))->extract_from_queue();
+ return NULL;
+}
+void* MessageQueueTest::add_three_elements_to_queue_helper(void *context) {
+ (reinterpret_cast<MessageQueueTest *>(context))->add_three_elements_to_queue();
+ return NULL;
+}
+void* MessageQueueTest::ShutDownQueue_helper(void *context) {
+ (reinterpret_cast<MessageQueueTest *>(context))->ShutDownQueue();
+ return NULL;
+}
+
+TEST_F(MessageQueueTest, DefaultCtorTest_ExpectEmptyQueueCreated) {
+ bool test_value = true;
+ // Check if the queue is empty
+ ASSERT_EQ(test_value, test_queue.empty());
+}
+
+TEST_F(MessageQueueTest, MessageQueuePushThreeElementsTest_ExpectThreeElementsAdded) {
+ pthread_t thread1;
+ pthread_create(&thread1, NULL, &MessageQueueTest::add_three_elements_to_queue_helper, this);
+ pthread_join(thread1, NULL);
+ // check if 3 elements were added successfully
+ ASSERT_EQ(3u, test_queue.size());
+}
+
+TEST_F(MessageQueueTest, NotEmptyMessageQueueResetTest_ExpectEmptyQueue) {
+ // Adding some elements to queue
+ test_queue.push(test_val_1);
+ test_queue.push(test_val_2);
+ test_queue.push(test_val_3);
+ // Resetting queue
+ test_queue.Reset();
+ // Check if queue is empty
+ ASSERT_TRUE(test_queue.empty());
+ // Check the size of queue after reset
+ ASSERT_EQ(0u, test_queue.size());
+}
+
+TEST_F(MessageQueueTest, MessageQueuePopOneElementTest_ExpectOneElementRemovedFromQueue) {
+ pthread_t thread1;
+ pthread_t thread2;
+ // Creating threads with thread function mentioned above
+ pthread_create(&thread1, NULL, &MessageQueueTest::add_one_element_to_queue_helper, this);
+ pthread_create(&thread2, NULL, &MessageQueueTest::extract_from_queue_helper, this);
+ // Primary thread waits until thread 2 to be finished
+ pthread_join(thread2, NULL);
+ // Check if first element was removed successfully
+ ASSERT_EQ(test_val_1, test_line);
+ // Check the size of queue after 1 element was removed
+ ASSERT_EQ(0u, test_queue.size());
+}
+
+TEST_F(MessageQueueTest, MessageQueueShutdownTest_ExpectMessageQueueWillBeShutDown) {
+ pthread_t thread1;
+ // Creating thread with thread function mentioned above
+ pthread_create(&thread1, NULL, &MessageQueueTest::ShutDownQueue_helper, this);
+ // Primary thread sleeps until thread1 will make queue shutdown
+ test_queue.wait();
+ check_value = true;
+ ASSERT_TRUE(check_value);
+}
+
+} // namespace utils
+} // namespace components
+} // namespace test
diff --git a/src/components/utils/test/messagemeter_test.cc b/src/components/utils/test/messagemeter_test.cc
index 45375e4ed..6c13ab345 100644
--- a/src/components/utils/test/messagemeter_test.cc
+++ b/src/components/utils/test/messagemeter_test.cc
@@ -79,7 +79,7 @@ class MessageMeterTest: public ::testing::TestWithParam<TimePair> {
void TearDown() OVERRIDE {
}
::utils::MessageMeter<int> meter;
- TimevalStruct time_range {0, 0};
+ TimevalStruct time_range = {0, 0};
int64_t time_range_msecs;
int usecs;
int id1, id2, id3;
diff --git a/src/components/utils/test/posix_thread_test.cc b/src/components/utils/test/posix_thread_test.cc
new file mode 100644
index 000000000..d597f036d
--- /dev/null
+++ b/src/components/utils/test/posix_thread_test.cc
@@ -0,0 +1,312 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * 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 the Ford Motor Company 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 HOLDER 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.
+ */
+
+#include "gtest/gtest.h"
+#include "utils/lock.h"
+#include "threads/thread.h"
+
+namespace test {
+namespace components {
+namespace utils {
+
+using namespace sync_primitives;
+using namespace threads;
+
+// TODO(AByzhynar): Change this to use Gtest class to create all variables for every TEST_F
+// TODO(AByzhynar): Add multithreading tests
+
+namespace {
+const uint32_t MAX_SIZE = 20;
+const size_t MyStackSize = 32768;
+const char *threadName("test thread");
+const std::string test_thread_name("THREAD");
+sync_primitives::ConditionalVariable cond_var_;
+sync_primitives::Lock test_mutex_;
+};
+
+// ThreadDelegate successor
+class TestThreadDelegate : public threads::ThreadDelegate {
+ public:
+ TestThreadDelegate()
+ : check_value_(false) {
+ }
+ void threadMain() {
+ AutoLock test_lock(test_mutex_);
+ check_value_ = true;
+ cond_var_.NotifyOne();
+ }
+
+ bool check_value() const {
+ return check_value_;
+ }
+ private:
+ bool check_value_;
+};
+
+TEST(PosixThreadTest, CreateThread_ExpectThreadCreated) {
+ // Arrange
+ threads::Thread *thread = NULL;
+ TestThreadDelegate *threadDelegate = new TestThreadDelegate();
+ // Create thread
+ ASSERT_NO_THROW(thread = CreateThread(threadName, threadDelegate));
+ EXPECT_TRUE(thread != NULL);
+ EXPECT_EQ(thread, threadDelegate->thread());
+ EXPECT_EQ(thread->delegate(), threadDelegate);
+ DeleteThread(thread);
+ delete threadDelegate;
+ // Check Delegate Dtor worked successfully
+ EXPECT_EQ(NULL, thread->delegate());
+}
+
+TEST(PosixThreadTest, CheckCreatedThreadName_ExpectCorrectName) {
+ // Arrange
+ threads::Thread *thread = NULL;
+ threads::ThreadDelegate *threadDelegate = new TestThreadDelegate();
+ // Create thread
+ ASSERT_NO_THROW(thread = CreateThread(threadName, threadDelegate));
+ // Check thread was created with correct name
+ EXPECT_EQ(threadName, thread->name());
+ DeleteThread(thread);
+ delete threadDelegate;
+ EXPECT_EQ(NULL, thread->delegate());
+}
+
+TEST(PosixThreadTest, CheckCreatedThreadNameChangeToLongName_ExpectThreadNameReduced) {
+ // Arrange
+ threads::Thread *thread = NULL;
+ TestThreadDelegate *threadDelegate = new TestThreadDelegate();
+ AutoLock test_lock(test_mutex_);
+ // Create thread
+ ASSERT_NO_THROW(thread = CreateThread(threadName, threadDelegate));
+ thread->start(threads::ThreadOptions(threads::Thread::kMinStackSize));
+ // Rename started thread. Name will be cut to 15 symbols + '\0'
+ // This is the limit in current POSIX thread implementation
+ thread->SetNameForId(thread->thread_handle(),
+ std::string("new thread with changed name"));
+ // Name must be large enough to keep 16 symbols. Read previous comment
+ char name[MAX_SIZE];
+ int result = pthread_getname_np(thread->thread_handle(), name, sizeof(name));
+ if (!result)
+ EXPECT_EQ(std::string("new thread with"), std::string(name));
+ cond_var_.WaitFor(test_lock, 10000);
+ EXPECT_TRUE(threadDelegate->check_value());
+ DeleteThread(thread);
+ delete threadDelegate;
+ EXPECT_EQ(NULL, thread->delegate());
+}
+
+TEST(PosixThreadTest, StartCreatedThreadWithOptionsJoinableAndMyStackSize_ExpectMyStackSizeStackAndJoinableThreadStarted) {
+ // Arrange
+ threads::Thread *thread = NULL;
+ TestThreadDelegate *threadDelegate = new TestThreadDelegate();
+ AutoLock test_lock(test_mutex_);
+ // Create thread
+ ASSERT_NO_THROW(thread = CreateThread(threadName, threadDelegate));
+ // Start thread with following options (Stack size = 32768 & thread is joinable)
+ thread->start(threads::ThreadOptions(MyStackSize));
+ // Check thread is joinable
+ EXPECT_TRUE(thread->is_joinable());
+ // Check thread stack size is 32768
+ EXPECT_EQ(MyStackSize, thread->stack_size());
+ cond_var_.WaitFor(test_lock, 10000);
+ EXPECT_TRUE(threadDelegate->check_value());
+ DeleteThread(thread);
+ delete threadDelegate;
+ EXPECT_EQ(NULL, thread->delegate());
+}
+
+TEST(PosixThreadTest, StartCreatedThreadWithDefaultOptions_ExpectZeroStackAndJoinableThreadStarted) {
+ // Arrange
+ threads::Thread *thread = NULL;
+ TestThreadDelegate *threadDelegate = new TestThreadDelegate();
+ AutoLock test_lock(test_mutex_);
+ // Create thread
+ ASSERT_NO_THROW(thread = CreateThread(threadName, threadDelegate));
+ // Start thread with default options (Stack size = 0 & thread is joinable)
+ thread->start(threads::ThreadOptions());
+ // Check thread is joinable
+ EXPECT_TRUE(thread->is_joinable());
+ // Check thread stack size is minimum value. Stack can not be 0
+ EXPECT_EQ(Thread::kMinStackSize, thread->stack_size());
+ cond_var_.WaitFor(test_lock, 10000);
+ EXPECT_TRUE(threadDelegate->check_value());
+ DeleteThread(thread);
+ delete threadDelegate;
+ EXPECT_EQ(NULL, thread->delegate());
+}
+
+TEST(PosixThreadTest, StartThreadWithZeroStackAndDetached_ExpectMinimumStackAndDetachedThreadStarted) {
+ // Arrange
+ threads::Thread *thread = NULL;
+ TestThreadDelegate *threadDelegate = new TestThreadDelegate();
+ AutoLock test_lock(test_mutex_);
+ // Create thread
+ ASSERT_NO_THROW(thread = CreateThread(threadName, threadDelegate));
+ // Start thread with default options (Stack size = 0 & thread is detached)
+ thread->start(threads::ThreadOptions(0, false));
+ // Check thread is detached
+ EXPECT_FALSE(thread->is_joinable());
+ // Check thread stack size is 0
+ EXPECT_EQ(Thread::kMinStackSize, thread->stack_size());
+ cond_var_.WaitFor(test_lock, 10000);
+ EXPECT_TRUE(threadDelegate->check_value());
+ DeleteThread(thread);
+ delete threadDelegate;
+ EXPECT_EQ(NULL, thread->delegate());
+}
+
+TEST(PosixThreadTest, DISABLED_CheckCreatedThreadNameChangeToEmpty_ExpectThreadNameChangedToEmpty) {
+ // Arrange
+ threads::Thread *thread = NULL;
+ TestThreadDelegate *threadDelegate = new TestThreadDelegate();
+ AutoLock test_lock(test_mutex_);
+ // Create thread
+ ASSERT_NO_THROW(thread = CreateThread(threadName, threadDelegate));
+ thread->start(threads::ThreadOptions(threads::Thread::kMinStackSize));
+ // Rename started thread. Name will be cut to 15 symbols + '\0'
+ // This is the limit in current POSIX thread implementation
+ thread->SetNameForId(thread->thread_handle(), std::string(""));
+ // Name must be large enough to keep 16 symbols. Read previous comment
+ char name[MAX_SIZE];
+ int result = pthread_getname_np(thread->thread_handle(), name, sizeof(name));
+ if (!result) {
+ EXPECT_EQ(std::string(""), std::string(name));
+ }
+ cond_var_.WaitFor(test_lock, 10000);
+ EXPECT_TRUE(threadDelegate->check_value());
+ DeleteThread(thread);
+ delete threadDelegate;
+ EXPECT_EQ(NULL, thread->delegate());
+}
+
+TEST(PosixThreadTest, CheckCreatedThreadNameChangeToShortName_ExpectThreadNameChangedToShort) {
+ // Arrange
+ threads::Thread *thread = NULL;
+ TestThreadDelegate *threadDelegate = new TestThreadDelegate();
+ AutoLock test_lock(test_mutex_);
+ // Create thread
+ ASSERT_NO_THROW(thread = CreateThread(threadName, threadDelegate));
+ // Start created thread
+ thread->start(threads::ThreadOptions(threads::Thread::kMinStackSize));
+ // Rename started thread. Name will be cut to 15 symbols + '\0'
+ // This is the limit in current POSIX thread implementation
+ thread->SetNameForId(thread->thread_handle(), test_thread_name);
+ // Name must be large enough to keep 16 symbols. Read previous comment
+ char name[MAX_SIZE];
+ int result = pthread_getname_np(thread->thread_handle(), name, sizeof(name));
+ if (!result) {
+ EXPECT_EQ(test_thread_name, std::string(name));
+ }
+ cond_var_.WaitFor(test_lock, 10000);
+ EXPECT_TRUE(threadDelegate->check_value());
+ DeleteThread(thread);
+ delete threadDelegate;
+ EXPECT_EQ(NULL, thread->delegate());
+}
+
+TEST(PosixThreadTest, StartThread_ExpectThreadStarted) {
+ // Arrange
+ threads::Thread *thread = NULL;
+ TestThreadDelegate *threadDelegate = new TestThreadDelegate();
+ AutoLock test_lock(test_mutex_);
+ // Create thread
+ ASSERT_NO_THROW(thread = CreateThread(threadName, threadDelegate));
+ // Start created thread
+ EXPECT_TRUE(thread->start(threads::ThreadOptions(threads::Thread::kMinStackSize)));
+ cond_var_.WaitFor(test_lock, 10000);
+ EXPECT_TRUE(threadDelegate->check_value());
+ DeleteThread(thread);
+ delete threadDelegate;
+ EXPECT_EQ(NULL, thread->delegate());
+}
+
+TEST(PosixThreadTest, StartOneThreadTwice_ExpectTheSameThreadStartedTwice) {
+ // Arrange
+ PlatformThreadHandle thread1_id;
+ PlatformThreadHandle thread2_id;
+ threads::Thread *thread = NULL;
+ TestThreadDelegate *threadDelegate = new TestThreadDelegate();
+ AutoLock test_lock(test_mutex_);
+ // Create thread
+ ASSERT_NO_THROW(thread = CreateThread(threadName, threadDelegate));
+ // Start created thread
+ EXPECT_TRUE(thread->start(threads::ThreadOptions(threads::Thread::kMinStackSize)));
+ thread1_id = thread->CurrentId();
+ thread->stop();
+ // Try to start thread again
+ EXPECT_TRUE(thread->start(threads::ThreadOptions(threads::Thread::kMinStackSize)));
+ thread2_id = thread->CurrentId();
+ EXPECT_EQ(thread1_id, thread2_id);
+ cond_var_.WaitFor(test_lock, 10000);
+ EXPECT_TRUE(threadDelegate->check_value());
+ DeleteThread(thread);
+ delete threadDelegate;
+ EXPECT_EQ(NULL, thread->delegate());
+}
+
+TEST(PosixThreadTest, StartOneThreadAgainAfterRename_ExpectRenamedThreadStarted) {
+ // Arrange
+ PlatformThreadHandle thread1_id;
+ PlatformThreadHandle thread2_id;
+ threads::Thread *thread = NULL;
+ TestThreadDelegate *threadDelegate = new TestThreadDelegate();
+ AutoLock test_lock(test_mutex_);
+ // Create thread
+ ASSERT_NO_THROW(thread = CreateThread(threadName, threadDelegate));
+ // Start created thread
+ EXPECT_TRUE(thread->start(threads::ThreadOptions(threads::Thread::kMinStackSize)));
+ thread1_id = thread->CurrentId();
+ // Rename started thread. Name will be cut to 15 symbols + '\0'
+ // This is the limit in current POSIX thread implementation
+ thread->SetNameForId(thread->thread_handle(), test_thread_name);
+ // Name must be large enough to keep 16 symbols. Read previous comment
+ char name[MAX_SIZE];
+ int result = pthread_getname_np(thread->thread_handle(), name, sizeof(name));
+ if (!result)
+ EXPECT_EQ(test_thread_name, std::string(name));
+ // Stop thread
+ thread->stop();
+ EXPECT_TRUE(thread->start(threads::ThreadOptions(threads::Thread::kMinStackSize)));
+ thread2_id = thread->CurrentId();
+ // Expect the same thread started with the the same name
+ EXPECT_EQ(test_thread_name, std::string(name));
+ EXPECT_EQ(thread1_id, thread2_id);
+ cond_var_.WaitFor(test_lock, 10000);
+ EXPECT_TRUE(threadDelegate->check_value());
+ DeleteThread(thread);
+ delete threadDelegate;
+ EXPECT_EQ(NULL, thread->delegate());
+}
+
+} // namespace utils
+} // namespace components
+} // namespace test
diff --git a/src/components/utils/test/resource_usage_test.cc b/src/components/utils/test/resource_usage_test.cc
new file mode 100644
index 000000000..c10bbea86
--- /dev/null
+++ b/src/components/utils/test/resource_usage_test.cc
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * 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 the Ford Motor Company 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 HOLDER 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.
+ */
+
+#include <unistd.h>
+#include "gtest/gtest.h"
+#include "utils/macro.h"
+
+#include "utils/resource_usage.h"
+#include "utils/file_system.h"
+
+namespace utils {
+
+class ResourceUsagePrivateTest : public ::testing::Test {
+ protected:
+ Resources res;
+};
+
+TEST_F(ResourceUsagePrivateTest, ReadStatFileTest) {
+ std::string proc_buf;
+ EXPECT_TRUE(res.ReadStatFile(proc_buf));
+}
+
+TEST_F(ResourceUsagePrivateTest, GetProcInfoTest) {
+ Resources::PidStats pid_stat;
+ EXPECT_TRUE(res.GetProcInfo(pid_stat));
+}
+
+TEST_F(ResourceUsagePrivateTest, GetMemInfoTest) {
+ Resources::MemInfo mem_info;
+ EXPECT_TRUE(res.GetMemInfo(mem_info));
+}
+
+TEST_F(ResourceUsagePrivateTest, GetStatPathTest_FileExists) {
+ //arrange
+ std::string filename = res.GetStatPath();
+ //assert
+ EXPECT_TRUE(file_system::FileExists(filename));
+}
+
+TEST_F(ResourceUsagePrivateTest, GetStatPathTest_ReadFile) {
+ //arrange
+ std::string filename = res.GetStatPath();
+ std::string output;
+ //assert
+ EXPECT_TRUE(file_system::ReadFile(filename, output));
+
+}
+TEST_F(ResourceUsagePrivateTest, GetProcPathTest) {
+ ///arrange
+ std::string fd = res.GetProcPath();
+ std::string filename = res.GetStatPath();
+ //assert
+ EXPECT_EQ(filename, fd + "/stat");
+}
+}
+
+namespace test {
+namespace components {
+namespace utils {
+using namespace ::utils;
+
+TEST(ResourceUsageTest, SuccesfulGrabResources) {
+ ResourseUsage* resources = Resources::getCurrentResourseUsage();
+ EXPECT_TRUE(resources != NULL);
+ delete resources;
+
+}
+
+} // namespace utils
+} // namespace components
+} // namespace test
diff --git a/src/components/utils/test/rwlock_posix_test.cc b/src/components/utils/test/rwlock_posix_test.cc
new file mode 100644
index 000000000..779b57ff3
--- /dev/null
+++ b/src/components/utils/test/rwlock_posix_test.cc
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * 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 the Ford Motor Company 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 HOLDER 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.
+ */
+
+#include "gtest/gtest.h"
+#include "utils/rwlock.h"
+
+namespace test {
+namespace components {
+namespace utils {
+
+using sync_primitives::RWLock;
+
+class RWlockTest : public ::testing::Test {
+ public:
+ void ThreadsDispatcher(void* (*func)(void*)) {
+ for (uint8_t i = 0; i < kNum_threads_; ++i) {
+ bool thread_created = (pthread_create(&thread[i], NULL, func, this) == 0);
+ ASSERT_TRUE(thread_created);
+ }
+ for (uint8_t i = 0; i < kNum_threads_; ++i) {
+ pthread_join(thread[i], NULL);
+ }
+ }
+
+ void ReadLock() {
+ EXPECT_TRUE(test_rwlock.AcquireForReading());
+ EXPECT_TRUE(test_rwlock.Release());
+ }
+
+ void ExpectReadLockFail() {
+ bool temp = test_rwlock.TryAcquireForReading();
+ EXPECT_FALSE(temp);
+ if (temp) {
+ test_rwlock.Release();
+ }
+ }
+
+ void ExpectWriteLockFail() {
+ bool temp = test_rwlock.TryAcquireForWriting();
+ EXPECT_FALSE(temp);
+ if (temp) {
+ test_rwlock.Release();
+ }
+ }
+
+ static void* ReadLock_helper(void *context) {
+ RWlockTest *temp = reinterpret_cast<RWlockTest *>(context);
+ temp->ReadLock();
+ return NULL;
+ }
+
+ static void* TryReadLock_helper(void *context) {
+ RWlockTest *temp = reinterpret_cast<RWlockTest *>(context);
+ temp->ExpectReadLockFail();
+ return NULL;
+ }
+
+ static void* TryWriteLock_helper(void *context) {
+ RWlockTest *temp = reinterpret_cast<RWlockTest *>(context);
+ temp->ExpectWriteLockFail();
+ return NULL;
+ }
+
+ protected:
+ RWLock test_rwlock;
+ enum { kNum_threads_ = 5 };
+ pthread_t thread[kNum_threads_];
+};
+
+TEST_F(RWlockTest, AcquireForReading_ExpectAccessForReading) {
+ // Lock rw lock for reading
+ EXPECT_TRUE(test_rwlock.AcquireForReading());
+ // Try to lock rw lock for reading again
+ EXPECT_TRUE(test_rwlock.AcquireForReading());
+ // Creating kNumThreads threads, starting them with callback function, waits until all of them finished
+ ThreadsDispatcher(&RWlockTest::ReadLock_helper);
+ // Releasing RW locks
+ EXPECT_TRUE(test_rwlock.Release());
+ EXPECT_TRUE(test_rwlock.Release());
+}
+
+TEST_F(RWlockTest, AcquireForReading_ExpectNoAccessForWriting) {
+ // Lock rw lock for reading
+ EXPECT_TRUE(test_rwlock.AcquireForReading());
+ // Try to lock rw lock for writing
+ EXPECT_FALSE(test_rwlock.TryAcquireForWriting());
+ // Creating kNumThreads threads, starting them with callback function, waits until all of them finished
+ ThreadsDispatcher(&RWlockTest::TryWriteLock_helper);
+ EXPECT_TRUE(test_rwlock.Release());
+}
+
+TEST_F(RWlockTest, AcquireForWriting_ExpectNoAccessForReading) {
+ // Lock rw lock for writing
+ EXPECT_TRUE(test_rwlock.AcquireForWriting());
+ // Try to lock rw lock for reading
+ EXPECT_FALSE(test_rwlock.TryAcquireForReading());
+ // Creating kNumThreads threads, starting them with callback function, waits until all of them finished
+ ThreadsDispatcher(&RWlockTest::TryReadLock_helper);
+ EXPECT_TRUE(test_rwlock.Release());
+}
+
+TEST_F(RWlockTest, AcquireForWriting_ExpectNoMoreAccessForWriting) {
+ // Lock rw lock for writing
+ EXPECT_TRUE(test_rwlock.AcquireForWriting());
+ // Try to lock rw lock for reading
+ EXPECT_FALSE(test_rwlock.TryAcquireForWriting());
+ // Creating kNumThreads threads, starting them with callback function, waits until all of them finished
+ ThreadsDispatcher(&RWlockTest::TryWriteLock_helper);
+ EXPECT_TRUE(test_rwlock.Release());
+}
+
+} // namespace utils
+} // namespace components
+} // namespace test
diff --git a/src/components/utils/test/signals_linux_test.cc b/src/components/utils/test/signals_linux_test.cc
new file mode 100644
index 000000000..263f240ec
--- /dev/null
+++ b/src/components/utils/test/signals_linux_test.cc
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * 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 the Ford Motor Company 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 HOLDER 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.
+ */
+
+#include <unistd.h>
+#include <assert.h>
+#include "gtest/gtest.h"
+#include "utils/signals.h"
+
+namespace test {
+namespace components {
+namespace utils {
+
+void handler(int sig) {
+}
+
+TEST(SignalsLinuxTest, SubscribeToTerminateSignal_Positive) {
+ ASSERT_TRUE(::utils::SubscribeToTerminateSignal(handler));
+}
+
+TEST(SignalsLinuxTest, SubscribeToFaultSignal_Positive) {
+ ASSERT_TRUE(::utils::SubscribeToFaultSignal(handler));
+}
+
+} // namespace utils
+} // namespace components
+} // namespace test
diff --git a/src/components/utils/test/singleton_test.cc b/src/components/utils/test/singleton_test.cc
new file mode 100644
index 000000000..8a9e6b31e
--- /dev/null
+++ b/src/components/utils/test/singleton_test.cc
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * 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 the Ford Motor Company 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 HOLDER 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.
+ */
+
+#include "gtest/gtest.h"
+#include "utils/singleton.h"
+#include <pthread.h>
+
+namespace test {
+namespace components {
+namespace utils {
+
+using ::utils::Singleton;
+
+class SingletonTest : public ::utils::Singleton<SingletonTest> {
+ public:
+
+ void SetValue(int value) {
+ test_value = value;
+ }
+ int GetValue() {
+ return test_value;
+ }
+
+ FRIEND_BASE_SINGLETON_CLASS (SingletonTest);
+ private:
+ int test_value;
+};
+
+TEST(SingletonTest, CreateAndDestroySingleton) {
+ //assert
+ ASSERT_EQ(SingletonTest::instance(), SingletonTest::instance());
+ ASSERT_EQ(0, SingletonTest::instance()->GetValue());
+ ASSERT_TRUE(SingletonTest::exists());
+ SingletonTest::instance()->SetValue(5);
+ ASSERT_EQ(5, SingletonTest::instance()->GetValue());
+
+ //act
+ SingletonTest::destroy();
+
+ //assert
+ ASSERT_FALSE(SingletonTest::exists());
+}
+
+TEST(SingletonTest, DestroySingletonTwice) {
+ //assert
+ ASSERT_EQ(0, SingletonTest::instance()->GetValue());
+ ASSERT_TRUE(SingletonTest::exists());
+
+ //act
+ SingletonTest::destroy();
+ //assert
+ ASSERT_FALSE(SingletonTest::exists());
+
+ //act
+ SingletonTest::destroy();
+ //assert
+ ASSERT_FALSE(SingletonTest::exists());
+}
+
+TEST(SingletonTest, DeleteSingletonCreateAnother) {
+ //arrange
+ SingletonTest::instance()->SetValue(10);
+ //assert
+ ASSERT_TRUE(SingletonTest::exists());
+ ASSERT_EQ(10, SingletonTest::instance()->GetValue());
+ //act
+ SingletonTest::destroy();
+ //assert
+ ASSERT_FALSE(SingletonTest::exists());
+
+ //act
+ SingletonTest::instance();
+
+ //assert
+ ASSERT_EQ(0, SingletonTest::instance()->GetValue());
+ ASSERT_TRUE(SingletonTest::exists());
+ SingletonTest::destroy();
+}
+
+void* func_pthread1(void*) {
+ SingletonTest* singleton_in_other_thread = SingletonTest::instance();
+ pthread_exit(singleton_in_other_thread);
+ return NULL;
+}
+
+void* func_pthread2(void * value) {
+ SingletonTest * instance = reinterpret_cast<SingletonTest *>(value);
+ instance->destroy();
+ pthread_exit (NULL);
+ return NULL;
+}
+
+TEST(SingletonTest, CreateSingletonInDifferentThreads) {
+ //arrange
+ SingletonTest::instance();
+ ASSERT_TRUE(SingletonTest::exists());
+
+ pthread_t thread1;
+ pthread_create(&thread1, NULL, func_pthread1, NULL);
+
+ void *instance2;
+ pthread_join(thread1, &instance2);
+ SingletonTest * instance_2 = reinterpret_cast<SingletonTest *>(instance2);
+
+ //assert
+ ASSERT_EQ(SingletonTest::instance(), instance_2);
+
+ //act
+ SingletonTest::destroy();
+ //assert
+ ASSERT_FALSE(SingletonTest::exists());
+}
+
+TEST(SingletonTest, CreateDeleteSingletonInDifferentThreads) {
+ //arrange
+ pthread_t thread1;
+ pthread_create(&thread1, NULL, func_pthread1, NULL);
+
+ pthread_t thread2;
+ pthread_create(&thread2, NULL, func_pthread1, NULL);
+
+ void *instance1;
+ pthread_join(thread1, &instance1);
+ SingletonTest * instance_1 = reinterpret_cast<SingletonTest *>(instance1);
+
+ void *instance2;
+ pthread_join(thread2, &instance2);
+ SingletonTest * instance_2 = reinterpret_cast<SingletonTest *>(instance2);
+
+ //assert
+ ASSERT_TRUE(instance_1->exists());
+ ASSERT_TRUE(instance_2->exists());
+
+ ASSERT_EQ(instance_1, instance_2);
+
+ //act
+ SingletonTest::destroy();
+
+ //assert
+ ASSERT_FALSE(instance_1->exists());
+ ASSERT_FALSE(instance_2->exists());
+}
+
+TEST(SingletonTest, DeleteSingletonInDifferentThread) {
+ //arrange
+ SingletonTest::instance();
+ ASSERT_TRUE(SingletonTest::exists());
+
+ pthread_t thread1;
+ pthread_create(&thread1, NULL, func_pthread2, SingletonTest::instance());
+
+ pthread_join(thread1, NULL);
+
+ //assert
+ ASSERT_FALSE(SingletonTest::exists());
+}
+
+} // namespace utils
+} // namespace components
+} // namespace test
diff --git a/src/components/utils/test/stl_utils_test.cc b/src/components/utils/test/stl_utils_test.cc
new file mode 100644
index 000000000..62c6d9404
--- /dev/null
+++ b/src/components/utils/test/stl_utils_test.cc
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * 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 the Ford Motor Company 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 HOLDER 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.
+ */
+
+#include "gtest/gtest.h"
+#include "utils/stl_utils.h"
+
+namespace test {
+namespace components {
+namespace utils {
+
+using ::utils::StlCollectionDeleter;
+using ::utils::StlMapDeleter;
+
+class TestObject {
+ public:
+ ~TestObject() {
+ }
+};
+
+typedef std::map<int, TestObject*> TestMap;
+typedef std::vector<TestObject*> TestVector;
+
+TEST(StlDeleter, DestructMapWithOneElement) {
+ TestMap test_map;
+ test_map[1] = new TestObject();
+
+ EXPECT_EQ(1, test_map.size());
+ {
+ StlMapDeleter<TestMap> test_list_deleter_(&test_map);
+ }
+ EXPECT_EQ(1, test_map.size());
+ EXPECT_EQ(NULL, test_map[1]);
+}
+
+TEST(StlDeleter, DestructMapWithSeveralElements) {
+ TestMap test_map;
+ test_map[1] = new TestObject();
+ test_map[2] = new TestObject();
+
+ EXPECT_EQ(2, test_map.size());
+ {
+ StlMapDeleter<TestMap> test_list_deleter_(&test_map);
+ }
+ EXPECT_EQ(2, test_map.size());
+ EXPECT_EQ(NULL, test_map[1]);
+ EXPECT_EQ(NULL, test_map[2]);
+}
+
+TEST(StlDeleter, DestructVectorWithOneElement) {
+ TestVector test_vector;
+ test_vector.push_back(new TestObject());
+
+ EXPECT_EQ(1, test_vector.size());
+ {
+ StlCollectionDeleter<TestVector> test_list_deleter_(&test_vector);
+ }
+ EXPECT_EQ(1, test_vector.size());
+ EXPECT_EQ(NULL, test_vector[0]);
+}
+
+TEST(StlDeleter, DestructVectorWithSeveralElements) {
+ TestVector test_vector;
+ test_vector.push_back(new TestObject());
+ test_vector.push_back(new TestObject());
+
+ EXPECT_EQ(2, test_vector.size());
+ {
+ StlCollectionDeleter<TestVector> test_list_deleter_(&test_vector);
+ }
+ EXPECT_EQ(2, test_vector.size());
+ EXPECT_EQ(NULL, test_vector[0]);
+ EXPECT_EQ(NULL, test_vector[1]);
+}
+
+} // namespace utils
+} // namespace components
+} // namespace test
diff --git a/src/components/utils/test/system_test.cc b/src/components/utils/test/system_test.cc
new file mode 100644
index 000000000..42307998b
--- /dev/null
+++ b/src/components/utils/test/system_test.cc
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * 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 the Ford Motor Company 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 HOLDER 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.
+ */
+
+#include "gmock/gmock.h"
+#include "utils/system.h"
+
+namespace test {
+namespace components {
+namespace utils {
+
+using namespace ::utils;
+
+TEST(SystemTest, Constructor_WithCommandName_ExpectArgsStored) {
+ // Command creation without any arguments
+ const std::string test_command("ls");
+ System object(test_command);
+
+ // Check if the object was created with correct command
+ ASSERT_EQ(object.command(), test_command);
+ int vec_size = object.argv().size();
+ ASSERT_EQ(vec_size, 1);
+}
+
+TEST(SystemTest, Constructor_WithFileNameCommandName_ExpectArgsStored) {
+ // Command creation with 1 argument
+ const std::string test_command("ls");
+ const std::string test_list_args("-la");
+ System object(test_command, test_list_args);
+
+ // Check if the object was created with correct command
+ ASSERT_EQ(object.command(), test_command);
+
+ // Check if actual number of arguments arec correct
+ int vec_size = object.argv().size();
+ ASSERT_EQ(vec_size, 1); // Correct number of arguments is 1
+
+}
+
+TEST(SystemTest, AddTwoArgsToCommand_ExpectTwoArgsAdded) {
+ const std::string test_command("echo");
+ const char* args[] = {"-e", "\b"};
+ System object(test_command);
+
+ // Adding arguments
+ object.Add(args[0]);
+ object.Add(args[1]);
+
+ // Check if actual number of arguments equal args stored in object
+ int vec_size = object.argv().size();
+ ASSERT_EQ(vec_size, 3); // Correct number of arguments is 3
+}
+
+TEST(SystemTest, AddTwoArgsToCommand_CheckOrder_ExpectOrderCorrect) {
+ const std::string test_command("echo");
+ const char* args[] = {"-e", "\b"};
+ System object(test_command);
+
+ // Adding arguments
+ object.Add(args[0]);
+ object.Add(args[1]);
+
+ // Check if the object was appended by correct arguments in correct order
+ EXPECT_STREQ(object.argv()[1].c_str(), args[0]);
+ EXPECT_STREQ(object.argv()[2].c_str(), args[1]);
+}
+
+
+
+TEST(SystemTest, SynchronousInvokeWithExistingCommand_ExpectSuccessfull) {
+ const std::string test_command("./testscript.sh");
+ System object(test_command);
+
+ // Check if Execute() method is working properly with synchronous command invoke
+ ASSERT_TRUE(object.Execute(true));
+}
+
+TEST(SystemTest, SynchronousInvokeWithEmptyCommand_IncorrectCommand_ExpectFailed) {
+ const std::string test_command(""); // any incorrect command
+ System object(test_command);
+
+ // Check if Execute() method will fail with not correct command (synchronous command invoke)
+ ASSERT_FALSE(object.Execute(true));
+}
+
+TEST(SystemTest, ASynchronousInvokeEmptyCommand_InvokeSuccessfull) {
+ const std::string test_command(""); // Possible to put here any command (existing or incorrect)
+ const std::string test_list_args("anything"); // as command will never be executed from child process
+ System object(test_command, test_list_args); // as parrent process does not wait for child process to be finished
+
+ // Check if Execute() method is working properly with asynchronous command invoke
+ ASSERT_TRUE(object.Execute());
+}
+
+} // namespace utils
+} // namespace components
+} // namespace test
diff --git a/src/components/utils/test/testscript.sh b/src/components/utils/test/testscript.sh
new file mode 100755
index 000000000..c42d8e78b
--- /dev/null
+++ b/src/components/utils/test/testscript.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+echo "Hello, Ford "
+
+
+
diff --git a/src/components/utils/test/thread_validator_test.cc b/src/components/utils/test/thread_validator_test.cc
new file mode 100644
index 000000000..16d9d1287
--- /dev/null
+++ b/src/components/utils/test/thread_validator_test.cc
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * 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 the Ford Motor Company 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 HOLDER 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.
+ */
+
+#include <unistd.h>
+
+#include "gtest/gtest.h"
+
+#include "utils/threads/thread_validator.h"
+
+namespace test {
+namespace components {
+namespace utils {
+
+using namespace ::threads;
+
+TEST(ThreadValidatorTest, CompareID_CurrentThreadAndPthread_AreEqual) {
+ SingleThreadSimpleValidator object;
+ ASSERT_EQ(object.creation_thread_id(), pthread_self());
+
+}
+
+} // namespace utils
+} // namespace components
+} // namespace test
diff --git a/src/components/utils/test/timer_thread_test.cc b/src/components/utils/test/timer_thread_test.cc
new file mode 100644
index 000000000..be25e03b7
--- /dev/null
+++ b/src/components/utils/test/timer_thread_test.cc
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * 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 the Ford Motor Company 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 HOLDER 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.
+ */
+
+#include <pthread.h>
+#include <iostream>
+
+#include "lock.h"
+#include "macro.h"
+
+#include "gtest/gtest.h"
+#include "utils/conditional_variable.h"
+#include "utils/timer_thread.h"
+
+namespace test {
+namespace components {
+namespace utils {
+
+using namespace timer;
+using namespace sync_primitives;
+
+class TimerThreadTest : public ::testing::Test {
+ public:
+ TimerThreadTest()
+ : check_val(0),
+ val1(3),
+ val2(4),
+ wait_val(3000) {
+ }
+
+ void function() {
+ AutoLock alock(lock_);
+ ++check_val;
+ condvar_.NotifyOne();
+ }
+
+ protected:
+ uint32_t check_val;
+ Lock lock_;
+ ConditionalVariable condvar_;
+ const uint32_t val1;
+ const uint32_t val2;
+ const uint32_t wait_val;
+};
+
+TEST_F(TimerThreadTest, StartTimerThreadWithTimeoutOneSec_ExpectSuccessfullInvokeCallbackFuncOnTimeout) {
+ // Create Timer with TimerDeleagate
+ TimerThread<TimerThreadTest> timer("Test", this, &TimerThreadTest::function,
+ false);
+ AutoLock alock(lock_);
+ EXPECT_EQ(0, check_val);
+ // Start timer with 1 second timeout
+ timer.start(1);
+ condvar_.WaitFor(alock, wait_val);
+ EXPECT_EQ(1, check_val);
+}
+
+TEST_F(TimerThreadTest, StartTimerThreadWithTimeoutOneSecInLoop_ExpectSuccessfullInvokeCallbackFuncOnEveryTimeout) {
+ // Create Timer with TimerLooperDeleagate
+ TimerThread<TimerThreadTest> timer("Test", this, &TimerThreadTest::function,
+ true);
+ AutoLock alock(lock_);
+ EXPECT_EQ(0, check_val);
+ // Start timer with 1 second timeout
+ timer.start(1);
+ while (check_val < val2) {
+ condvar_.WaitFor(alock, wait_val);
+ }
+ // Check callback function was called 4 times
+ EXPECT_EQ(val2, check_val);
+}
+
+TEST_F(TimerThreadTest, StopStartedTimerThreadWithTimeoutOneSecInLoop_ExpectSuccessfullStop) {
+ // Create Timer with TimerLooperDeleagate
+ TimerThread<TimerThreadTest> timer("Test", this, &TimerThreadTest::function,
+ true);
+ AutoLock alock(lock_);
+ EXPECT_EQ(0, check_val);
+ // Start timer with 1 second timeout
+ timer.start(1);
+ // Stop timer on 3rd second
+ while (check_val < val2) {
+ if (check_val == val1) {
+ timer.stop();
+ break;
+ }
+ condvar_.WaitFor(alock, wait_val);
+ }
+ EXPECT_EQ(val1, check_val);
+}
+
+TEST_F(TimerThreadTest, ChangeTimeoutForStartedTimerThreadWithTimeoutOneSecInLoop_ExpectSuccessfullStop) {
+ // Create Timer with TimerLooperDeleagate
+ TimerThread<TimerThreadTest> timer("Test", this, &TimerThreadTest::function,
+ true);
+ AutoLock alock(lock_);
+ EXPECT_EQ(0, check_val);
+ // Start timer with 1 second timeout
+ timer.start(1);
+ // Change timer timeout on 3rd second
+ while (check_val < val2) {
+ if (check_val == val1) {
+ timer.updateTimeOut(2);
+ }
+ condvar_.WaitFor(alock, wait_val);
+ }
+ EXPECT_EQ(val2, check_val);
+}
+
+TEST_F(TimerThreadTest, CheckStartedTimerIsRunning_ExpectTrue) {
+ // Create Timer with TimerLooperDeleagate
+ TimerThread<TimerThreadTest> timer("Test", this, &TimerThreadTest::function,
+ true);
+ AutoLock alock(lock_);
+ EXPECT_EQ(0, check_val);
+ // Start timer with 1 second timeout
+ timer.start(1);
+ // Change timer timeout on 3rd second
+ while (check_val < val1) {
+ condvar_.WaitFor(alock, wait_val);
+ // Check start is running
+ EXPECT_TRUE(timer.isRunning());
+ }
+ EXPECT_EQ(val1, check_val);
+}
+
+} // namespace utils
+} // namespace components
+} // namespace test
+