Move test framework from wrt-commons to security-tests 89/25089/18
authorMarcin Niesluchowski <m.niesluchow@samsung.com>
Mon, 28 Jul 2014 08:49:13 +0000 (10:49 +0200)
committerMarcin Niesluchowski <m.niesluchow@samsung.com>
Thu, 7 Aug 2014 15:39:12 +0000 (17:39 +0200)
Change-Id: If185e7401ded389f40d1a07e610c5d999ff152c1

53 files changed:
packaging/security-tests.spec
tests/CMakeLists.txt
tests/common/CMakeLists.txt
tests/common/tests_common.cpp
tests/cynara-tests/CMakeLists.txt
tests/cynara-tests/test_cases.cpp
tests/framework/config.cmake [new file with mode: 0644]
tests/framework/include/dpl/abstract_input.h [new file with mode: 0644]
tests/framework/include/dpl/abstract_input_output.h [new file with mode: 0644]
tests/framework/include/dpl/abstract_output.h [new file with mode: 0644]
tests/framework/include/dpl/assert.h [new file with mode: 0644]
tests/framework/include/dpl/atomic.h [new file with mode: 0644]
tests/framework/include/dpl/availability.h [new file with mode: 0644]
tests/framework/include/dpl/binary_queue.h [new file with mode: 0644]
tests/framework/include/dpl/colors.h [new file with mode: 0644]
tests/framework/include/dpl/exception.h [new file with mode: 0644]
tests/framework/include/dpl/log/abstract_log_provider.h [new file with mode: 0644]
tests/framework/include/dpl/log/dlog_log_provider.h [new file with mode: 0644]
tests/framework/include/dpl/log/log.h [new file with mode: 0644]
tests/framework/include/dpl/log/old_style_log_provider.h [new file with mode: 0644]
tests/framework/include/dpl/log/secure_log.h [new file with mode: 0644]
tests/framework/include/dpl/noncopyable.h [new file with mode: 0644]
tests/framework/include/dpl/noreturn.h [new file with mode: 0644]
tests/framework/include/dpl/scoped_fclose.h [new file with mode: 0644]
tests/framework/include/dpl/scoped_free.h [new file with mode: 0644]
tests/framework/include/dpl/scoped_resource.h [new file with mode: 0644]
tests/framework/include/dpl/singleton.h [new file with mode: 0644]
tests/framework/include/dpl/singleton_impl.h [new file with mode: 0644]
tests/framework/include/dpl/singleton_safe_impl.h [new file with mode: 0644]
tests/framework/include/dpl/test/test_results_collector.h [new file with mode: 0644]
tests/framework/include/dpl/test/test_runner.h [new file with mode: 0644]
tests/framework/include/dpl/test/test_runner_child.h [new file with mode: 0644]
tests/framework/include/dpl/test/test_runner_multiprocess.h [new file with mode: 0644]
tests/framework/src/abstract_log_provider.cpp [new file with mode: 0644]
tests/framework/src/assert.cpp [new file with mode: 0644]
tests/framework/src/atomic.cpp [new file with mode: 0644]
tests/framework/src/binary_queue.cpp [new file with mode: 0644]
tests/framework/src/colors.cpp [new file with mode: 0644]
tests/framework/src/dlog_log_provider.cpp [new file with mode: 0644]
tests/framework/src/exception.cpp [new file with mode: 0644]
tests/framework/src/log.cpp [new file with mode: 0644]
tests/framework/src/noncopyable.cpp [new file with mode: 0644]
tests/framework/src/old_style_log_provider.cpp [new file with mode: 0644]
tests/framework/src/singleton.cpp [new file with mode: 0644]
tests/framework/src/test_results_collector.cpp [new file with mode: 0644]
tests/framework/src/test_runner.cpp [new file with mode: 0644]
tests/framework/src/test_runner_child.cpp [new file with mode: 0644]
tests/framework/src/test_runner_multiprocess.cpp [new file with mode: 0644]
tests/libprivilege-control-tests/CMakeLists.txt
tests/libsmack-tests/CMakeLists.txt
tests/security-manager-tests/CMakeLists.txt
tests/security-server-tests/CMakeLists.txt
tests/security-server-tests/security_server_measurer_API_speed.cpp

index b9b6d6d..6d41ea2 100644 (file)
@@ -12,10 +12,12 @@ BuildRequires: pkgconfig(libsmack)
 BuildRequires: pkgconfig(libprivilege-control)
 BuildRequires: pkgconfig(security-server)
 BuildRequires: pkgconfig(security-manager)
-BuildRequires: pkgconfig(dpl-test-efl)
 BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(glib-2.0)
 BuildRequires: pkgconfig(dbus-1)
 BuildRequires: pkgconfig(dbus-glib-1)
+BuildRequires: pkgconfig(libpcrecpp)
+BuildRequires: pkgconfig(libxml-2.0)
 BuildRequires: pkgconfig(libiri)
 BuildRequires: pkgconfig(sqlite3)
 BuildRequires: pkgconfig(cynara-admin)
index db4ee57..9606a41 100644 (file)
 #    limitations under the License.
 #
 
+INCLUDE(FindPkgConfig)
+
+PKG_CHECK_MODULES(SYS_FRAMEWORK_TEST
+    REQUIRED
+    libxml-2.0
+    libpcrecpp
+    libiri
+    )
+
+PKG_CHECK_MODULES(SYS_FRAMEWORK_TEST_OTHER
+    REQUIRED
+    glib-2.0
+    dlog
+    )
+
+ADD_DEFINITIONS(${SYS_FRAMEWORK_TEST_OTHER_CFLAGS})
+
+include(framework/config.cmake)
+
+SET(DPL_FRAMEWORK_TEST_LIBRARY "dpl-test-framework")
+
+INCLUDE_DIRECTORIES(SYSTEM
+    ${SYS_FRAMEWORK_TEST_OTHER_INCLUDE_DIRS}
+    ${DPL_FRAMEWORK_TEST_INCLUDE_DIR}
+    )
+
+ADD_LIBRARY(${DPL_FRAMEWORK_TEST_LIBRARY} ${DPL_FRAMEWORK_TEST_SOURCES})
+
+TARGET_LINK_LIBRARIES(${DPL_FRAMEWORK_TEST_LIBRARY}
+    ${SYS_FRAMEWORK_TEST_OTHER_LIBRARIES}
+    ${SYS_FRAMEWORK_TEST_LIBRARIES}
+    )
+
 INSTALL(FILES ${PROJECT_SOURCE_DIR}/tests/security-tests.sh
     DESTINATION bin
     PERMISSIONS OWNER_READ
@@ -59,6 +92,7 @@ INSTALL(FILES
                 WORLD_EXECUTE
     )
 
+
 ADD_SUBDIRECTORY(common)
 ADD_SUBDIRECTORY(libprivilege-control-tests)
 ADD_SUBDIRECTORY(libsmack-tests)
index bf079e0..85d4ac1 100644 (file)
@@ -4,7 +4,6 @@ SET(COMMON_TARGET_TEST "tests-common")
 #dependencies
 PKG_CHECK_MODULES(COMMON_TARGET_DEP
     libsmack
-    dpl-test-efl
     dbus-1
     dbus-glib-1
     sqlite3
@@ -29,12 +28,16 @@ SET(COMMON_TARGET_TEST_SOURCES
 #system and local includes
 INCLUDE_DIRECTORIES(SYSTEM ${COMMON_TARGET_DEP_INCLUDE_DIRS})
 
-INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/tests/common)
+INCLUDE_DIRECTORIES(
+    ${PROJECT_SOURCE_DIR}/tests/framework/include
+    ${PROJECT_SOURCE_DIR}/tests/common
+    )
 
 
 #output OBJECT format
 ADD_LIBRARY(${COMMON_TARGET_TEST} ${COMMON_TARGET_TEST_SOURCES})
 
-TARGET_LINK_LIBRARIES(${COMMON_TARGET_TEST} ${COMMON_TARGET_DEP_LIBRARIES})
+TARGET_LINK_LIBRARIES(${COMMON_TARGET_TEST} ${COMMON_TARGET_DEP_LIBRARIES}
+    dpl-test-framework)
 
 INSTALL (FILES ${PROJECT_SOURCE_DIR}/tests/common/security-tests.conf DESTINATION /etc/dbus-1/system.d)
index e55ec75..555b8b5 100644 (file)
@@ -26,6 +26,7 @@
 #include <grp.h>
 #include <errno.h>
 #include <vector>
+#include <algorithm>
 
 int DB::Transaction::db_result = PC_OPERATION_SUCCESS;
 
index 9093003..8f69835 100644 (file)
@@ -5,7 +5,6 @@ SET(CYNARA_TARGET_TEST "cynara-test")
 
 PKG_CHECK_MODULES(CYNARA_TARGET_DEP
     REQUIRED
-    dpl-test-efl
     libprivilege-control
     cynara-admin
     cynara-client
@@ -41,6 +40,7 @@ ADD_EXECUTABLE(${CYNARA_TARGET_TEST} ${CYNARA_TARGET_TEST_SOURCES})
 #linker directories
 TARGET_LINK_LIBRARIES(${CYNARA_TARGET_TEST}
     ${CYNARA_TARGET_DEP_LIBRARIES}
+    dpl-test-framework
     tests-common
     )
 
index c61e632..aeeed20 100644 (file)
@@ -22,6 +22,7 @@
  * @brief       Tests for libcynara-client and libcynara-admin
  */
 
+#include <dpl/exception.h>
 #include <tests_common.h>
 #include <cynara_test_client.h>
 #include <cynara_test_admin.h>
diff --git a/tests/framework/config.cmake b/tests/framework/config.cmake
new file mode 100644 (file)
index 0000000..4ec039a
--- /dev/null
@@ -0,0 +1,42 @@
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+#    Licensed under the Apache License, Version 2.0 (the "License");
+#    you may not use this file except in compliance with the License.
+#    You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+#
+#
+# @file        config.cmake
+# @author      Lukasz Marek (l.marek@samsung.com)
+# @version     1.0
+# @brief
+#
+
+SET(DPL_FRAMEWORK_TEST_SOURCES
+    ${PROJECT_SOURCE_DIR}/tests/framework/src/assert.cpp
+    ${PROJECT_SOURCE_DIR}/tests/framework/src/atomic.cpp
+    ${PROJECT_SOURCE_DIR}/tests/framework/src/binary_queue.cpp
+    ${PROJECT_SOURCE_DIR}/tests/framework/src/colors.cpp
+    ${PROJECT_SOURCE_DIR}/tests/framework/src/exception.cpp
+    ${PROJECT_SOURCE_DIR}/tests/framework/src/noncopyable.cpp
+    ${PROJECT_SOURCE_DIR}/tests/framework/src/singleton.cpp
+    ${PROJECT_SOURCE_DIR}/tests/framework/src/abstract_log_provider.cpp
+    ${PROJECT_SOURCE_DIR}/tests/framework/src/dlog_log_provider.cpp
+    ${PROJECT_SOURCE_DIR}/tests/framework/src/log.cpp
+    ${PROJECT_SOURCE_DIR}/tests/framework/src/old_style_log_provider.cpp
+    ${PROJECT_SOURCE_DIR}/tests/framework/src/test_results_collector.cpp
+    ${PROJECT_SOURCE_DIR}/tests/framework/src/test_runner_child.cpp
+    ${PROJECT_SOURCE_DIR}/tests/framework/src/test_runner.cpp
+    ${PROJECT_SOURCE_DIR}/tests/framework/src/test_runner_multiprocess.cpp
+)
+
+SET(DPL_FRAMEWORK_TEST_INCLUDE_DIR
+    ${PROJECT_SOURCE_DIR}/tests/framework/include
+)
diff --git a/tests/framework/include/dpl/abstract_input.h b/tests/framework/include/dpl/abstract_input.h
new file mode 100644 (file)
index 0000000..8c0e16a
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        abstract_input.h
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the header file of abstract input
+ */
+#ifndef DPL_ABSTRACT_INPUT_H
+#define DPL_ABSTRACT_INPUT_H
+
+#include <dpl/exception.h>
+#include <memory>
+
+namespace DPL {
+class BinaryQueue;
+typedef std::auto_ptr<BinaryQueue> BinaryQueueAutoPtr;
+
+class AbstractInput
+{
+  public:
+    class Exception
+    {
+      public:
+        DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+        DECLARE_EXCEPTION_TYPE(Base, ReadFailed)
+    };
+
+  public:
+    virtual ~AbstractInput() {}
+
+    /**
+     * Read binary data from input
+     * If no data is available method returns NULL buffer.
+     * In case connection was successfuly close, method returns empty buffer
+     *
+     * @param[in] size Maximum number of bytes to read from input
+     * @return Buffer containing read bytes
+     * @throw  ReadFailed
+     */
+    virtual BinaryQueueAutoPtr Read(size_t size) = 0;
+};
+} // namespace DPL
+
+#endif // DPL_ABSTRACT_INPUT_H
diff --git a/tests/framework/include/dpl/abstract_input_output.h b/tests/framework/include/dpl/abstract_input_output.h
new file mode 100644 (file)
index 0000000..153d5c4
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        abstract_output.h
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the header file of abstract output
+ */
+#ifndef DPL_ABSTRACT_INPUT_OUTPUT_H
+#define DPL_ABSTRACT_INPUT_OUTPUT_H
+
+#include <dpl/abstract_input.h>
+#include <dpl/abstract_output.h>
+
+namespace DPL {
+class AbstractInputOutput :
+    public AbstractInput,
+    public AbstractOutput
+{
+  public:
+    virtual ~AbstractInputOutput() {}
+};
+} // namespace DPL
+
+#endif // DPL_ABSTRACT_INPUT_OUTPUT_H
diff --git a/tests/framework/include/dpl/abstract_output.h b/tests/framework/include/dpl/abstract_output.h
new file mode 100644 (file)
index 0000000..56c86fb
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        abstract_output.h
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the header file of abstract output
+ */
+#ifndef DPL_ABSTRACT_OUTPUT_H
+#define DPL_ABSTRACT_OUTPUT_H
+
+#include <dpl/exception.h>
+#include <memory>
+
+namespace DPL {
+class BinaryQueue;
+typedef std::auto_ptr<BinaryQueue> BinaryQueueAutoPtr;
+
+class AbstractOutput
+{
+  public:
+    class Exception
+    {
+      public:
+        DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+        DECLARE_EXCEPTION_TYPE(Base, WriteFailed)
+    };
+
+  public:
+    virtual ~AbstractOutput() {}
+
+    /**
+     * Write binary data to output
+     * If output is blocked, Write returns zero, if instance is a type of
+     * WaitableAbstractOutput one can wait for writability then
+     *
+     * @param[in] buffer Input buffer with data to be written
+     * @param[in] bufferSize Maximum number of bytes to write from buffer
+     * @return Number of bytes success successfuly written or zero if output is
+     * blocked
+     * @throw WriteFailed
+     */
+    virtual size_t Write(const BinaryQueue &buffer, size_t bufferSize) = 0;
+};
+} // namespace DPL
+
+#endif // DPL_ABSTRACT_OUTPUT_H
diff --git a/tests/framework/include/dpl/assert.h b/tests/framework/include/dpl/assert.h
new file mode 100644 (file)
index 0000000..59331a0
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        assert.h
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of assert
+ */
+#ifndef DPL_ASSERT_H
+#define DPL_ASSERT_H
+
+#include <dpl/noreturn.h>
+
+namespace DPL {
+// Assertion handler procedure
+// Do not call directly
+// Always use Assert macro
+DPL_NORETURN void AssertProc(const char *condition,
+                             const char *file,
+                             int line,
+                             const char *function);
+} // namespace DPL
+
+#define Assert(Condition) do { if (!(Condition)) { DPL::AssertProc(#Condition, \
+                                                                   __FILE__, \
+                                                                   __LINE__, \
+                                                                   __FUNCTION__); \
+                               } } while (0)
+
+#endif // DPL_ASSERT_H
diff --git a/tests/framework/include/dpl/atomic.h b/tests/framework/include/dpl/atomic.h
new file mode 100644 (file)
index 0000000..50c4a1a
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        atomic.h
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the header file of atomic
+ */
+#ifndef DPL_ATOMIC_H
+#define DPL_ATOMIC_H
+
+#pragma GCC system_header
+#include <glib.h>
+
+namespace DPL {
+class Atomic
+{
+  public:
+    typedef gint ValueType;
+
+  private:
+    volatile ValueType m_value;
+
+  public:
+    Atomic(ValueType value = static_cast<ValueType>(0));
+
+    ValueType ExchangeAndAdd(ValueType value);
+    bool CompareAndExchange(ValueType oldValue, ValueType newValue);
+    bool operator--();
+    void operator++();
+
+    operator ValueType() const;
+};
+} // namespace DPL
+
+#endif // DPL_ATOMIC_H
diff --git a/tests/framework/include/dpl/availability.h b/tests/framework/include/dpl/availability.h
new file mode 100644 (file)
index 0000000..0813892
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        availability.h
+ * @author      Jihoon Chung (jihoon.chung@samsung.com)
+ * @version     1.0
+ */
+#ifndef DPL_AVAILABILITY_H
+#define DPL_AVAILABILITY_H
+
+#define DPL_DEPRECATED __attribute__((deprecated))
+#define DPL_DEPRECATED_WITH_MESSAGE(msg) __attribute__((deprecated(msg)))
+
+#define DPL_UNUSED __attribute__((unused))
+#define DPL_UNUSED_PARAM(variable) (void)variable
+
+#endif // DPL_AVAILABILITY_H
diff --git a/tests/framework/include/dpl/binary_queue.h b/tests/framework/include/dpl/binary_queue.h
new file mode 100644 (file)
index 0000000..f4fa278
--- /dev/null
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        binary_queue.h
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the header file of binary queue
+ */
+#ifndef DPL_BINARY_QUEUE_H
+#define DPL_BINARY_QUEUE_H
+
+#include <dpl/abstract_input_output.h>
+#include <dpl/exception.h>
+#include <dpl/noncopyable.h>
+#include <memory>
+#include <list>
+
+namespace DPL {
+/**
+ * Binary stream implemented as constant size bucket list
+ *
+ * @todo Add optimized implementation for FlattenConsume
+ */
+class BinaryQueue :
+    public AbstractInputOutput
+{
+  public:
+    class Exception
+    {
+      public:
+        DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+        DECLARE_EXCEPTION_TYPE(Base, OutOfData)
+    };
+
+    typedef void (*BufferDeleter)(const void *buffer, size_t bufferSize,
+                                  void *userParam);
+    static void BufferDeleterFree(const void *buffer,
+                                  size_t bufferSize,
+                                  void *userParam);
+
+    class BucketVisitor
+    {
+      public:
+        /**
+         * Destructor
+         */
+        virtual ~BucketVisitor();
+
+        /**
+         * Visit bucket
+         *
+         * @return none
+         * @param[in] buffer Constant pointer to bucket data buffer
+         * @param[in] bufferSize Number of bytes in bucket
+         */
+        virtual void OnVisitBucket(const void *buffer, size_t bufferSize) = 0;
+    };
+
+  private:
+    struct Bucket :
+        private Noncopyable
+    {
+        const void *buffer;
+        const void *ptr;
+        size_t size;
+        size_t left;
+
+        BufferDeleter deleter;
+        void *param;
+
+        Bucket(const void *buffer,
+               size_t bufferSize,
+               BufferDeleter deleter,
+               void *userParam);
+        virtual ~Bucket();
+    };
+
+    typedef std::list<Bucket *> BucketList;
+    BucketList m_buckets;
+    size_t m_size;
+
+    static void DeleteBucket(Bucket *bucket);
+
+    class BucketVisitorCall
+    {
+      private:
+        BucketVisitor *m_visitor;
+
+      public:
+        BucketVisitorCall(BucketVisitor *visitor);
+        virtual ~BucketVisitorCall();
+
+        void operator()(Bucket *bucket) const;
+    };
+
+  public:
+    /**
+     * Construct empty binary queue
+     */
+    BinaryQueue();
+
+    /**
+     * Construct binary queue via bare copy of other binary queue
+     *
+     * @param[in] other Other binary queue to copy from
+     * @warning One cannot assume that bucket structure is preserved during copy
+     */
+    BinaryQueue(const BinaryQueue &other);
+
+    /**
+     * Destructor
+     */
+    virtual ~BinaryQueue();
+
+    /**
+     * Construct binary queue via bare copy of other binary queue
+     *
+     * @param[in] other Other binary queue to copy from
+     * @warning One cannot assume that bucket structure is preserved during copy
+     */
+    const BinaryQueue &operator=(const BinaryQueue &other);
+
+    /**
+     * Append copy of @a bufferSize bytes from memory pointed by @a buffer
+     * to the end of binary queue. Uses default deleter based on free.
+     *
+     * @return none
+     * @param[in] buffer Pointer to buffer to copy data from
+     * @param[in] bufferSize Number of bytes to copy
+     * @exception std::bad_alloc Cannot allocate memory to hold additional data
+     * @see BinaryQueue::BufferDeleterFree
+     */
+    void AppendCopy(const void *buffer, size_t bufferSize);
+
+    /**
+     * Append @a bufferSize bytes from memory pointed by @a buffer
+     * to the end of binary queue. Uses custom provided deleter.
+     * Responsibility for deleting provided buffer is transfered to BinaryQueue.
+     *
+     * @return none
+     * @param[in] buffer Pointer to data buffer
+     * @param[in] bufferSize Number of bytes available in buffer
+     * @param[in] deleter Pointer to deleter procedure used to free provided
+     * buffer
+     * @param[in] userParam User parameter passed to deleter routine
+     * @exception std::bad_alloc Cannot allocate memory to hold additional data
+     */
+    void AppendUnmanaged(
+        const void *buffer,
+        size_t bufferSize,
+        BufferDeleter deleter =
+            &BinaryQueue::BufferDeleterFree,
+        void *userParam = NULL);
+
+    /**
+     * Append copy of other binary queue to the end of this binary queue
+     *
+     * @return none
+     * @param[in] other Constant reference to other binary queue to copy data
+     * from
+     * @exception std::bad_alloc Cannot allocate memory to hold additional data
+     * @warning One cannot assume that bucket structure is preserved during copy
+     */
+    void AppendCopyFrom(const BinaryQueue &other);
+
+    /**
+     * Move bytes from other binary queue to the end of this binary queue.
+     * This also removes all bytes from other binary queue.
+     * This method is designed to be as fast as possible (only pointer swaps)
+     * and is suggested over making copies of binary queues.
+     * Bucket structure is preserved after operation.
+     *
+     * @return none
+     * @param[in] other Reference to other binary queue to move data from
+     * @exception std::bad_alloc Cannot allocate memory to hold additional data
+     */
+    void AppendMoveFrom(BinaryQueue &other);
+
+    /**
+     * Append copy of binary queue to the end of other binary queue
+     *
+     * @return none
+     * @param[in] other Constant reference to other binary queue to copy data to
+     * @exception std::bad_alloc Cannot allocate memory to hold additional data
+     * @warning One cannot assume that bucket structure is preserved during copy
+     */
+    void AppendCopyTo(BinaryQueue &other) const;
+
+    /**
+     * Move bytes from binary queue to the end of other binary queue.
+     * This also removes all bytes from binary queue.
+     * This method is designed to be as fast as possible (only pointer swaps)
+     * and is suggested over making copies of binary queues.
+     * Bucket structure is preserved after operation.
+     *
+     * @return none
+     * @param[in] other Reference to other binary queue to move data to
+     * @exception std::bad_alloc Cannot allocate memory to hold additional data
+     */
+    void AppendMoveTo(BinaryQueue &other);
+
+    /**
+     * Retrieve total size of all data contained in binary queue
+     *
+     * @return Number of bytes in binary queue
+     */
+    size_t Size() const;
+
+    /**
+     * Remove all data from binary queue
+     *
+     * @return none
+     */
+    void Clear();
+
+    /**
+     * Check if binary queue is empty
+     *
+     * @return true if binary queue is empty, false otherwise
+     */
+    bool Empty() const;
+
+    /**
+     * Remove @a size bytes from beginning of binary queue
+     *
+     * @return none
+     * @param[in] size Number of bytes to remove
+     * @exception BinaryQueue::Exception::OutOfData Number of bytes is larger
+     *            than available bytes in binary queue
+     */
+    void Consume(size_t size);
+
+    /**
+     * Retrieve @a bufferSize bytes from beginning of binary queue and copy them
+     * to user supplied buffer
+     *
+     * @return none
+     * @param[in] buffer Pointer to user buffer to receive bytes
+     * @param[in] bufferSize Size of user buffer pointed by @a buffer
+     * @exception BinaryQueue::Exception::OutOfData Number of bytes to flatten
+     *            is larger than available bytes in binary queue
+     */
+    void Flatten(void *buffer, size_t bufferSize) const;
+
+    /**
+     * Retrieve @a bufferSize bytes from beginning of binary queue, copy them
+     * to user supplied buffer, and remove from binary queue
+     *
+     * @return none
+     * @param[in] buffer Pointer to user buffer to receive bytes
+     * @param[in] bufferSize Size of user buffer pointed by @a buffer
+     * @exception BinaryQueue::Exception::OutOfData Number of bytes to flatten
+     *            is larger than available bytes in binary queue
+     */
+    void FlattenConsume(void *buffer, size_t bufferSize);
+
+    /**
+     * Visit each buffer with data using visitor object
+     *
+     * @return none
+     * @param[in] visitor Pointer to bucket visitor
+     * @see BinaryQueue::BucketVisitor
+     */
+    void VisitBuckets(BucketVisitor *visitor) const;
+
+    /**
+     * IAbstractInput interface
+     */
+    virtual BinaryQueueAutoPtr Read(size_t size);
+
+    /**
+     * IAbstractOutput interface
+     */
+    virtual size_t Write(const BinaryQueue &buffer, size_t bufferSize);
+};
+
+/**
+ * Binary queue auto pointer
+ */
+typedef std::auto_ptr<BinaryQueue> BinaryQueueAutoPtr;
+} // namespace DPL
+
+#endif // DPL_BINARY_QUEUE_H
diff --git a/tests/framework/include/dpl/colors.h b/tests/framework/include/dpl/colors.h
new file mode 100644 (file)
index 0000000..c7cfd53
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        colors.h
+ * @author      Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version     1.0
+ * @brief       Some constants with definition of colors for Console
+ *              and html output
+ */
+
+#ifndef DPL_COLORS_H
+#define DPL_COLORS_H
+
+namespace DPL {
+namespace Colors {
+namespace Text {
+extern const char* BOLD_GREEN_BEGIN;
+extern const char* BOLD_GREEN_END;
+extern const char* PURPLE_BEGIN;
+extern const char* PURPLE_END;
+extern const char* RED_BEGIN;
+extern const char* RED_END;
+extern const char* GREEN_BEGIN;
+extern const char* GREEN_END;
+extern const char* CYAN_BEGIN;
+extern const char* CYAN_END;
+extern const char* BOLD_RED_BEGIN;
+extern const char* BOLD_RED_END;
+extern const char* BOLD_YELLOW_BEGIN;
+extern const char* BOLD_YELLOW_END;
+extern const char* BOLD_GOLD_BEGIN;
+extern const char* BOLD_GOLD_END;
+extern const char* BOLD_WHITE_BEGIN;
+extern const char* BOLD_WHITE_END;
+} //namespace Text
+
+namespace Html {
+extern const char* BOLD_GREEN_BEGIN;
+extern const char* BOLD_GREEN_END;
+extern const char* PURPLE_BEGIN;
+extern const char* PURPLE_END;
+extern const char* RED_BEGIN;
+extern const char* RED_END;
+extern const char* GREEN_BEGIN;
+extern const char* GREEN_END;
+extern const char* CYAN_BEGIN;
+extern const char* CYAN_END;
+extern const char* BOLD_RED_BEGIN;
+extern const char* BOLD_RED_END;
+extern const char* BOLD_YELLOW_BEGIN;
+extern const char* BOLD_YELLOW_END;
+extern const char* BOLD_GOLD_BEGIN;
+extern const char* BOLD_GOLD_END;
+extern const char* BOLD_WHITE_BEGIN;
+extern const char* BOLD_WHITE_END;
+} //namespace Html
+} //namespace Colors
+} //namespace DPL
+
+#endif /* DPL_COLORS_H */
diff --git a/tests/framework/include/dpl/exception.h b/tests/framework/include/dpl/exception.h
new file mode 100644 (file)
index 0000000..cdbdc53
--- /dev/null
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file    exception.h
+ * @author  Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief   Header file for base exception
+ */
+#ifndef DPL_EXCEPTION_H
+#define DPL_EXCEPTION_H
+
+#include <string>
+#include <cstring>
+#include <cstdio>
+#include <exception>
+#include <cstdlib>
+#include <sstream>
+
+namespace DPL {
+void LogUnhandledException(const std::string &str);
+void LogUnhandledException(const std::string &str,
+                           const char *filename,
+                           int line,
+                           const char *function);
+}
+
+namespace DPL {
+class Exception
+{
+  private:
+    static unsigned int m_exceptionCount;
+    static Exception* m_lastException;
+    static void (*m_terminateHandler)();
+
+    static void AddRef(Exception* exception)
+    {
+        if (!m_exceptionCount) {
+            m_terminateHandler = std::set_terminate(&TerminateHandler);
+        }
+
+        ++m_exceptionCount;
+        m_lastException = exception;
+    }
+
+    static void UnRef(Exception* e)
+    {
+        if (m_lastException == e) {
+            m_lastException = NULL;
+        }
+
+        --m_exceptionCount;
+
+        if (!m_exceptionCount) {
+            std::set_terminate(m_terminateHandler);
+            m_terminateHandler = NULL;
+        }
+    }
+
+    static void TerminateHandler()
+    {
+        if (m_lastException != NULL) {
+            DisplayKnownException(*m_lastException);
+            abort();
+        } else {
+            DisplayUnknownException();
+            abort();
+        }
+    }
+
+    Exception *m_reason;
+    std::string m_path;
+    std::string m_function;
+    int m_line;
+
+  protected:
+    std::string m_message;
+    std::string m_className;
+
+  public:
+    static std::string KnownExceptionToString(const Exception &e)
+    {
+        std::ostringstream message;
+        message <<
+        "\033[1;5;31m\n=== Unhandled DPL exception occurred ===\033[m\n\n";
+        message << "\033[1;33mException trace:\033[m\n\n";
+        message << e.DumpToString();
+        message << "\033[1;31m\n=== Will now abort ===\033[m\n";
+
+        return message.str();
+    }
+
+    static std::string UnknownExceptionToString()
+    {
+        std::ostringstream message;
+        message <<
+        "\033[1;5;31m\n=== Unhandled non-DPL exception occurred ===\033[m\n\n";
+        message << "\033[1;31m\n=== Will now abort ===\033[m\n";
+
+        return message.str();
+    }
+
+    static void DisplayKnownException(const Exception& e)
+    {
+        LogUnhandledException(KnownExceptionToString(e).c_str());
+    }
+
+    static void DisplayUnknownException()
+    {
+        LogUnhandledException(UnknownExceptionToString().c_str());
+    }
+
+    Exception(const Exception &other)
+    {
+        // Deep copy
+        if (other.m_reason != NULL) {
+            m_reason = new Exception(*other.m_reason);
+        } else {
+            m_reason = NULL;
+        }
+
+        m_message = other.m_message;
+        m_path = other.m_path;
+        m_function = other.m_function;
+        m_line = other.m_line;
+
+        m_className = other.m_className;
+
+        AddRef(this);
+    }
+
+    const Exception &operator =(const Exception &other)
+    {
+        if (this == &other) {
+            return *this;
+        }
+
+        // Deep copy
+        if (other.m_reason != NULL) {
+            m_reason = new Exception(*other.m_reason);
+        } else {
+            m_reason = NULL;
+        }
+
+        m_message = other.m_message;
+        m_path = other.m_path;
+        m_function = other.m_function;
+        m_line = other.m_line;
+
+        m_className = other.m_className;
+
+        AddRef(this);
+
+        return *this;
+    }
+
+    Exception(const char *path,
+              const char *function,
+              int line,
+              const std::string &message) :
+        m_reason(NULL),
+        m_path(path),
+        m_function(function),
+        m_line(line),
+        m_message(message)
+    {
+        AddRef(this);
+    }
+
+    Exception(const char *path,
+              const char *function,
+              int line,
+              const Exception &reason,
+              const std::string &message) :
+        m_reason(new Exception(reason)),
+        m_path(path),
+        m_function(function),
+        m_line(line),
+        m_message(message)
+    {
+        AddRef(this);
+    }
+
+    virtual ~Exception() throw()
+    {
+        if (m_reason != NULL) {
+            delete m_reason;
+            m_reason = NULL;
+        }
+
+        UnRef(this);
+    }
+
+    void Dump() const
+    {
+        // Show reason first
+        if (m_reason != NULL) {
+            m_reason->Dump();
+        }
+
+        // Afterward, dump exception
+        const char *file = strchr(m_path.c_str(), '/');
+
+        if (file == NULL) {
+            file = m_path.c_str();
+        } else {
+            ++file;
+        }
+
+        printf("\033[0;36m[%s:%i]\033[m %s() \033[4;35m%s\033[m: %s\033[m\n",
+               file, m_line,
+               m_function.c_str(),
+               m_className.c_str(),
+               m_message.empty() ? "<EMPTY>" : m_message.c_str());
+    }
+
+    std::string DumpToString() const
+    {
+        std::string ret;
+        if (m_reason != NULL) {
+            ret = m_reason->DumpToString();
+        }
+
+        const char *file = strchr(m_path.c_str(), '/');
+
+        if (file == NULL) {
+            file = m_path.c_str();
+        } else {
+            ++file;
+        }
+
+        char buf[1024];
+        snprintf(buf,
+                 sizeof(buf),
+                 "\033[0;36m[%s:%i]\033[m %s() \033[4;35m%s\033[m: %s\033[m\n",
+                 file,
+                 m_line,
+                 m_function.c_str(),
+                 m_className.c_str(),
+                 m_message.empty() ? "<EMPTY>" : m_message.c_str());
+
+        buf[sizeof(buf) - 1] = '\n';
+        ret += buf;
+
+        return ret;
+    }
+
+    Exception *GetReason() const
+    {
+        return m_reason;
+    }
+
+    std::string GetPath() const
+    {
+        return m_path;
+    }
+
+    std::string GetFunction() const
+    {
+        return m_function;
+    }
+
+    int GetLine() const
+    {
+        return m_line;
+    }
+
+    std::string GetMessage() const
+    {
+        return m_message;
+    }
+
+    std::string GetClassName() const
+    {
+        return m_className;
+    }
+};
+} // namespace DPL
+
+#define Try try
+
+#define Throw(ClassName) \
+    throw ClassName(__FILE__, __FUNCTION__, __LINE__)
+
+#define ThrowMsg(ClassName, Message)                                                 \
+    do                                                                               \
+    {                                                                                \
+        std::ostringstream dplLoggingStream;                                         \
+        dplLoggingStream << Message;                                                 \
+        throw ClassName(__FILE__, __FUNCTION__, __LINE__, dplLoggingStream.str());   \
+    } while (0)
+
+#define ReThrow(ClassName) \
+    throw ClassName(__FILE__, __FUNCTION__, __LINE__, _rethrown_exception)
+
+#define ReThrowMsg(ClassName, Message) \
+    throw ClassName(__FILE__, \
+                    __FUNCTION__, \
+                    __LINE__, \
+                    _rethrown_exception, \
+                    Message)
+
+#define Catch(ClassName) \
+    catch (const ClassName &_rethrown_exception)
+
+#define DECLARE_EXCEPTION_TYPE(BaseClass, Class)                                                                                          \
+    class Class :                                                                                                                                 \
+        public BaseClass                                                                                                                \
+    {                                                                                                                                     \
+      public:                                                                                                                               \
+        Class(const char *path, \
+              const char *function, \
+              int line, \
+              const std::string & message = std::string()) :                                                                                                                             \
+            BaseClass(path, function, line, message)                                                                                    \
+        {                                                                                                                                 \
+            BaseClass::m_className = #Class;                                                                                              \
+        }                                                                                                                                 \
+                                                                                                                                          \
+        Class(const char *path, \
+              const char *function, \
+              int line, \
+              const DPL::Exception & reason, \
+              const std::string & message = std::string()) :                                                                                                                             \
+            BaseClass(path, function, line, reason, message)                                                                            \
+        {                                                                                                                                 \
+            BaseClass::m_className = #Class;                                                                                              \
+        }                                                                                                                                 \
+    };
+
+#define UNHANDLED_EXCEPTION_HANDLER_BEGIN try
+
+#define UNHANDLED_EXCEPTION_HANDLER_END                                                                   \
+    catch (const DPL::Exception &exception)                                                               \
+    {                                                                                                     \
+        std::ostringstream msg;                                                                           \
+        msg << DPL::Exception::KnownExceptionToString(exception);                                         \
+        DPL::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__);                          \
+        abort();                                                                                          \
+    }                                                                                                     \
+    catch (std::exception& e)                                                                             \
+    {                                                                                                     \
+        std::ostringstream msg;                                                                           \
+        msg << e.what();                                                                                  \
+        msg << "\n";                                                                                      \
+        msg << DPL::Exception::UnknownExceptionToString();                                                \
+        DPL::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__);                          \
+        abort();                                                                                          \
+    }                                                                                                     \
+    catch (...)                                                                                           \
+    {                                                                                                     \
+        std::ostringstream msg;                                                                           \
+        msg << DPL::Exception::UnknownExceptionToString();                                                \
+        DPL::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__);                          \
+        abort();                                                                                          \
+    }
+
+namespace DPL {
+namespace CommonException {
+/**
+ * Internal exception definitions
+ *
+ * These should normally not happen.
+ * Usually, exception trace with internal error includes
+ * important messages.
+ */
+DECLARE_EXCEPTION_TYPE(Exception, InternalError) ///< Unexpected error from
+                                                 // underlying libraries or
+                                                 // kernel
+}
+}
+
+#endif // DPL_EXCEPTION_H
diff --git a/tests/framework/include/dpl/log/abstract_log_provider.h b/tests/framework/include/dpl/log/abstract_log_provider.h
new file mode 100644 (file)
index 0000000..62fa050
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        abstract_log_provider.h
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of abstract log provider
+ */
+#ifndef DPL_ABSTRACT_LOG_PROVIDER_H
+#define DPL_ABSTRACT_LOG_PROVIDER_H
+
+namespace DPL {
+namespace Log {
+class AbstractLogProvider
+{
+  public:
+    virtual ~AbstractLogProvider() {}
+
+    virtual void Debug(const char *message,
+                       const char *fileName,
+                       int line,
+                       const char *function) = 0;
+    virtual void Info(const char *message,
+                      const char *fileName,
+                      int line,
+                      const char *function) = 0;
+    virtual void Warning(const char *message,
+                         const char *fileName,
+                         int line,
+                         const char *function) = 0;
+    virtual void Error(const char *message,
+                       const char *fileName,
+                       int line,
+                       const char *function) = 0;
+    virtual void Pedantic(const char *message,
+                          const char *fileName,
+                          int line,
+                          const char *function) = 0;
+
+  protected:
+    static const char *LocateSourceFileName(const char *filename);
+};
+}
+} // namespace DPL
+
+#endif // DPL_ABSTRACT_LOG_PROVIDER_H
diff --git a/tests/framework/include/dpl/log/dlog_log_provider.h b/tests/framework/include/dpl/log/dlog_log_provider.h
new file mode 100644 (file)
index 0000000..1dd4c2d
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        dlog_log_provider.h
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of DLOG log provider
+ */
+#ifndef DPL_DLOG_LOG_PROVIDER_H
+#define DPL_DLOG_LOG_PROVIDER_H
+
+#include <dpl/log/abstract_log_provider.h>
+#include <dpl/scoped_free.h>
+#include <string>
+
+namespace DPL {
+namespace Log {
+class DLOGLogProvider :
+    public AbstractLogProvider
+{
+  private:
+    DPL::ScopedFree<char> m_tag;
+
+    static std::string FormatMessage(const char *message,
+                                     const char *filename,
+                                     int line,
+                                     const char *function);
+
+  public:
+    DLOGLogProvider();
+    virtual ~DLOGLogProvider();
+
+    virtual void Debug(const char *message,
+                       const char *fileName,
+                       int line,
+                       const char *function);
+    virtual void Info(const char *message,
+                      const char *fileName,
+                      int line,
+                      const char *function);
+    virtual void Warning(const char *message,
+                         const char *fileName,
+                         int line,
+                         const char *function);
+    virtual void Error(const char *message,
+                       const char *fileName,
+                       int line,
+                       const char *function);
+    virtual void Pedantic(const char *message,
+                          const char *fileName,
+                          int line,
+                          const char *function);
+
+    // Set global Tag according to DLOG
+    void SetTag(const char *tag);
+};
+}
+} // namespace DPL
+
+#endif // DPL_DLOG_LOG_PROVIDER_H
diff --git a/tests/framework/include/dpl/log/log.h b/tests/framework/include/dpl/log/log.h
new file mode 100644 (file)
index 0000000..d4d95ed
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        log.h
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of log system
+ */
+#ifndef DPL_LOG_H
+#define DPL_LOG_H
+
+#include <dpl/singleton.h>
+#include <dpl/noncopyable.h>
+#include <dpl/log/abstract_log_provider.h>
+#include <dpl/log/dlog_log_provider.h>
+#include <dpl/log/old_style_log_provider.h>
+#include <sstream>
+#include <list>
+
+namespace DPL {
+namespace Log {
+/**
+ * DPL log system
+ *
+ * To switch logs into old style, export
+ * DPL_USE_OLD_STYLE_LOGS before application start
+ */
+class LogSystem :
+    private Noncopyable
+{
+  private:
+    typedef std::list<AbstractLogProvider *> AbstractLogProviderPtrList;
+    AbstractLogProviderPtrList m_providers;
+
+    DLOGLogProvider *m_dlogProvider;
+    OldStyleLogProvider *m_oldStyleProvider;
+
+    bool m_isLoggingEnabled;
+
+  public:
+    bool IsLoggingEnabled() const;
+    LogSystem();
+    virtual ~LogSystem();
+
+    /**
+     * Log debug message
+     */
+    void Debug(const char *message,
+               const char *filename,
+               int line,
+               const char *function);
+
+    /**
+     * Log info message
+     */
+    void Info(const char *message,
+              const char *filename,
+              int line,
+              const char *function);
+
+    /**
+     * Log warning message
+     */
+    void Warning(const char *message,
+                 const char *filename,
+                 int line,
+                 const char *function);
+
+    /**
+     * Log error message
+     */
+    void Error(const char *message,
+               const char *filename,
+               int line,
+               const char *function);
+
+    /**
+     * Log pedantic message
+     */
+    void Pedantic(const char *message,
+                  const char *filename,
+                  int line,
+                  const char *function);
+
+    /**
+     * Set default's DLOG provider Tag
+     */
+    void SetTag(const char *tag);
+
+    /**
+     * Add abstract provider to providers list
+     *
+     * @notice Ownership is transfered to LogSystem and deleted upon exit
+     */
+    void AddProvider(AbstractLogProvider *provider);
+
+    /**
+     * Remove abstract provider from providers list
+     */
+    void RemoveProvider(AbstractLogProvider *provider);
+};
+
+/*
+ * Replacement low overhead null logging class
+ */
+class NullStream
+{
+  public:
+    NullStream() {}
+
+    template <typename T>
+    NullStream& operator<<(const T&)
+    {
+        return *this;
+    }
+};
+
+/**
+ * Log system singleton
+ */
+typedef Singleton<LogSystem> LogSystemSingleton;
+}
+} // namespace DPL
+
+//
+// Log support
+//
+//
+
+#ifdef DPL_LOGS_ENABLED
+    #define DPL_MACRO_FOR_LOGGING(message, function)                           \
+    do                                                                     \
+    {                                                                      \
+        if (DPL::Log::LogSystemSingleton::Instance().IsLoggingEnabled())   \
+        {                                                                  \
+            std::ostringstream platformLog;                                \
+            platformLog << message;                                        \
+            DPL::Log::LogSystemSingleton::Instance().function(             \
+                platformLog.str().c_str(),                                 \
+                __FILE__, __LINE__, __FUNCTION__);                         \
+        }                                                                  \
+    } while (0)
+#else
+/* avoid warnings about unused variables */
+    #define DPL_MACRO_FOR_LOGGING(message, function)                           \
+    do {                                                                   \
+        DPL::Log::NullStream ns;                                           \
+        ns << message;                                                     \
+    } while (0)
+#endif
+
+#define  LogDebug(message) DPL_MACRO_FOR_LOGGING(message, Debug)
+#define  LogInfo(message) DPL_MACRO_FOR_LOGGING(message, Info)
+#define  LogWarning(message) DPL_MACRO_FOR_LOGGING(message, Warning)
+#define  LogError(message) DPL_MACRO_FOR_LOGGING(message, Error)
+#define  LogPedantic(message) DPL_MACRO_FOR_LOGGING(message, Pedantic)
+
+#endif // DPL_LOG_H
diff --git a/tests/framework/include/dpl/log/old_style_log_provider.h b/tests/framework/include/dpl/log/old_style_log_provider.h
new file mode 100644 (file)
index 0000000..70e308a
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        old_style_log_provider.h
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of old style log provider
+ */
+#ifndef DPL_OLD_STYLE_LOG_PROVIDER_H
+#define DPL_OLD_STYLE_LOG_PROVIDER_H
+
+#include <dpl/log/abstract_log_provider.h>
+#include <string>
+
+namespace DPL {
+namespace Log {
+class OldStyleLogProvider :
+    public AbstractLogProvider
+{
+  private:
+    bool m_showDebug;
+    bool m_showInfo;
+    bool m_showWarning;
+    bool m_showError;
+    bool m_showPedantic;
+    bool m_printStdErr;
+
+    static std::string FormatMessage(const char *message,
+                                     const char *filename,
+                                     int line,
+                                     const char *function);
+
+  public:
+    OldStyleLogProvider(bool showDebug,
+                        bool showInfo,
+                        bool showWarning,
+                        bool showError,
+                        bool showPedantic);
+    OldStyleLogProvider(bool showDebug,
+                        bool showInfo,
+                        bool showWarning,
+                        bool showError,
+                        bool showPedantic,
+                        bool printStdErr);
+    virtual ~OldStyleLogProvider() {}
+
+    virtual void Debug(const char *message,
+                       const char *fileName,
+                       int line,
+                       const char *function);
+    virtual void Info(const char *message,
+                      const char *fileName,
+                      int line,
+                      const char *function);
+    virtual void Warning(const char *message,
+                         const char *fileName,
+                         int line,
+                         const char *function);
+    virtual void Error(const char *message,
+                       const char *fileName,
+                       int line,
+                       const char *function);
+    virtual void Pedantic(const char *message,
+                          const char *fileName,
+                          int line,
+                          const char *function);
+};
+}
+} // namespace DPL
+
+#endif // DPL_OLD_STYLE_LOG_PROVIDER_H
diff --git a/tests/framework/include/dpl/log/secure_log.h b/tests/framework/include/dpl/log/secure_log.h
new file mode 100644 (file)
index 0000000..d8a0750
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/**
+ * @file       secure_log.h
+ * @author     Jihoon Chung(jihoon.chung@samsung.com)
+ * @version    0.1
+ * @brief
+ */
+
+#ifndef DPL_SECURE_LOG_H
+#define DPL_SECURE_LOG_H
+
+#include <dlog.h>
+
+#define COLOR_ERROR   "\e[1;31m"
+#define COLOR_WARNING "\e[2;31m"
+#define COLOR_END     "\e[0m"
+#define COLOR_TAG     "\e[0m"
+
+// default TAG
+#undef LOG_TAG
+#define LOG_TAG "WRT_UNDEFINED"
+
+#ifdef WRT_LOG
+#undef LOG_TAG
+#define LOG_TAG "WRT"
+#undef COLOR_TAG
+#define COLOR_TAG "\e[1;32m"
+#endif
+
+#ifdef WRT_BUNDLE_LOG
+#undef LOG_TAG
+#define LOG_TAG "WRT_BUNDLE"
+#undef COLOR_TAG
+#define COLOR_TAG "\e[1;34m"
+#endif
+
+#ifdef WRT_PLUGINS_COMMON_LOG
+#undef LOG_TAG
+#define LOG_TAG "WRT_PLUGINS/COMMON"
+#undef COLOR_TAG
+#define COLOR_TAG "\e[1;36m"
+#endif
+
+#ifdef WRT_PLUGINS_WIDGET_LOG
+#undef LOG_TAG
+#define LOG_TAG "WRT_PLUGINS/WIDGET"
+#undef COLOR_TAG
+#define COLOR_TAG "\e[1;35m"
+#endif
+
+#ifdef WRT_INSTALLER_LOG
+#undef LOG_TAG
+#define LOG_TAG "WRT_INSTALLER"
+#undef COLOR_TAG
+#define COLOR_TAG "\e[1;32m"
+#endif
+
+#ifndef SECURE_SLOGD
+#define SECURE_SLOGD(fmt, arg...) SLOGD(fmt,##arg)
+#endif
+
+#ifndef SECURE_SLOGW
+#define SECURE_SLOGW(fmt, arg...) SLOGW(fmt,##arg)
+#endif
+
+#ifndef SECURE_SLOGE
+#define SECURE_SLOGE(fmt, arg...) SLOGE(fmt,##arg)
+#endif
+
+#define _D(fmt, arg ...) SECURE_SLOGD(COLOR_TAG fmt COLOR_END,##arg)
+#define _W(fmt, arg ...) SECURE_SLOGW(COLOR_WARNING fmt COLOR_END,##arg)
+#define _E(fmt, arg ...) SECURE_SLOGE(COLOR_ERROR fmt COLOR_END,##arg)
+
+#endif // DPL_SECURE_LOG_H
+
diff --git a/tests/framework/include/dpl/noncopyable.h b/tests/framework/include/dpl/noncopyable.h
new file mode 100644 (file)
index 0000000..98d57dd
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        noncopyable
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of noncopyable
+ */
+#ifndef DPL_NONCOPYABLE_H
+#define DPL_NONCOPYABLE_H
+
+namespace DPL {
+class Noncopyable
+{
+  private:
+    Noncopyable(const Noncopyable &);
+    const Noncopyable &operator=(const Noncopyable &);
+
+  public:
+    Noncopyable();
+    virtual ~Noncopyable();
+};
+} // namespace DPL
+
+#endif // DPL_NONCOPYABLE_H
diff --git a/tests/framework/include/dpl/noreturn.h b/tests/framework/include/dpl/noreturn.h
new file mode 100644 (file)
index 0000000..93845b7
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        noreturn.h
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of noreturn
+ */
+#ifndef DPL_NORETURN_H
+#define DPL_NORETURN_H
+
+#define DPL_NORETURN __attribute__((__noreturn__))
+
+#endif // DPL_NORETURN_H
diff --git a/tests/framework/include/dpl/scoped_fclose.h b/tests/framework/include/dpl/scoped_fclose.h
new file mode 100644 (file)
index 0000000..e8deb15
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*!
+ * @file        scoped_fclose.h
+ * @author      Piotr Marcinkiewicz (p.marcinkiew@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of scoped fclose RAII
+ */
+#ifndef DPL_SCOPED_FCLOSE_H
+#define DPL_SCOPED_FCLOSE_H
+
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <cerrno>
+#include <cstdio>
+#include <string>
+#include <dpl/log/log.h>
+#include <dpl/scoped_resource.h>
+
+namespace DPL {
+struct ScopedFClosePolicy
+{
+    typedef FILE* Type;
+    static Type NullValue()
+    {
+        return NULL;
+    }
+    static void Destroy(Type file)
+    {
+        if (file != NULL) {
+            // Try to flush first
+            if (TEMP_FAILURE_RETRY(fflush(file)) != 0) {
+                std::string errString = strerror(errno);
+                LogPedantic("Failed to fflush scoped fclose error: "
+                            << errString);
+            }
+
+            // fclose cannot be retried, try to close once
+            if (fclose(file) != 0) {
+                std::string errString = strerror(errno);
+                LogPedantic("Failed scoped fclose error: " << errString);
+            }
+        }
+    }
+};
+
+class ScopedFClose : public ScopedResource<ScopedFClosePolicy>
+{
+    typedef ScopedFClosePolicy Policy;
+    typedef ScopedResource<Policy> BaseType;
+
+  public:
+    explicit ScopedFClose(FILE* argFileStream = Policy::NullValue()) :
+        BaseType(argFileStream)
+    {}
+};
+} // namespace DPL
+
+#endif // DPL_SCOPED_FCLOSE_H
diff --git a/tests/framework/include/dpl/scoped_free.h b/tests/framework/include/dpl/scoped_free.h
new file mode 100644 (file)
index 0000000..7bebe39
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*!
+ * @file        scoped_free.h
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of scoped free RAII
+ */
+
+#ifndef DPL_SCOPED_FREE_H
+#define DPL_SCOPED_FREE_H
+
+#include <malloc.h>
+#include <cstddef>
+
+#include <dpl/scoped_resource.h>
+
+namespace DPL {
+template<typename Class>
+struct ScopedFreePolicy
+{
+    typedef Class* Type;
+    static Type NullValue()
+    {
+        return NULL;
+    }
+    static void Destroy(Type ptr)
+    {
+        free(ptr);
+    }
+};
+
+template<typename Memory>
+class ScopedFree : public ScopedResource<ScopedFreePolicy<Memory> >
+{
+    typedef ScopedFreePolicy<Memory> Policy;
+    typedef ScopedResource<Policy> BaseType;
+
+  public:
+    explicit ScopedFree(Memory *ptr = Policy::NullValue()) : BaseType(ptr) { }
+};
+} // namespace DPL
+
+#endif // DPL_SCOPED_FREE_H
diff --git a/tests/framework/include/dpl/scoped_resource.h b/tests/framework/include/dpl/scoped_resource.h
new file mode 100644 (file)
index 0000000..63287da
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        scoped_resource.h
+ * @author      Piotr Marcinkiewicz (p.marcinkiew@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of scoped resource pattern
+ */
+#ifndef DPL_SCOPED_RESOURCE_H
+#define DPL_SCOPED_RESOURCE_H
+
+#include <dpl/noncopyable.h>
+
+namespace DPL {
+template<typename ClassPolicy>
+class ScopedResource :
+    private Noncopyable
+{
+  public:
+    typedef typename ClassPolicy::Type ValueType;
+    typedef ScopedResource<ClassPolicy> ThisType;
+
+  protected:
+    ValueType m_value;
+
+  public:
+    explicit ScopedResource(ValueType value) : m_value(value) { }
+
+    ~ScopedResource()
+    {
+        ClassPolicy::Destroy(m_value);
+    }
+
+    ValueType Get() const
+    {
+        return m_value;
+    }
+
+    void Reset(ValueType value = ClassPolicy::NullValue())
+    {
+        ClassPolicy::Destroy(m_value);
+        m_value = value;
+    }
+
+    ValueType Release()
+    {
+        ValueType value = m_value;
+        m_value = ClassPolicy::NullValue();
+        return value;
+    }
+    typedef ValueType ThisType::*UnknownBoolType;
+
+    operator UnknownBoolType() const
+    {
+        return m_value == ClassPolicy::NullValue() ?
+               0 : //0 is valid here because it converts to false
+               &ThisType::m_value; //it converts to true
+    }
+
+    bool operator !() const
+    {
+        return m_value == ClassPolicy::NullValue();
+    }
+};
+} // namespace DPL
+
+#endif // DPL_SCOPED_RESOURCE_H
diff --git a/tests/framework/include/dpl/singleton.h b/tests/framework/include/dpl/singleton.h
new file mode 100644 (file)
index 0000000..fc118d5
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        singleton.h
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of singleton
+ */
+#ifndef DPL_SINGLETON_H
+#define DPL_SINGLETON_H
+
+#include <dpl/assert.h>
+
+namespace DPL {
+template<typename Class>
+class Singleton :
+    private Class
+{
+    //
+    // Note:
+    //
+    // To remove posibility of instantiating directly Class,
+    // make Class' default constructor protected
+    //
+
+  private:
+    Singleton()
+    {}
+
+    static Singleton &InternalInstance();
+
+  public:
+    virtual ~Singleton()
+    {}
+
+    static Class &Instance();
+};
+} // namespace DPL
+
+#endif // DPL_SINGLETON_H
diff --git a/tests/framework/include/dpl/singleton_impl.h b/tests/framework/include/dpl/singleton_impl.h
new file mode 100644 (file)
index 0000000..12dbf32
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        singleton_impl.h
+ * @author      Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of singleton
+ */
+#ifndef DPL_SINGLETON_IMPL_H
+#define DPL_SINGLETON_IMPL_H
+
+/*
+ * WARNING!
+ *
+ * If some singleton's implementation uses another singletons implementation,
+ * those templates make the second singleton a dubleton. Be warned. Try to use
+ * singleton_safe_impl.h if possible.
+ */
+
+namespace DPL {
+template<typename Class>
+Singleton<Class>& Singleton<Class>::InternalInstance()
+{
+    static Singleton<Class> instance;
+    return instance;
+}
+
+template<typename Class>
+Class &Singleton<Class>::Instance()
+{
+    Singleton<Class>& instance = Singleton<Class>::InternalInstance();
+    return instance;
+}
+} // namespace DPL
+
+#define IMPLEMENT_SINGLETON(Type)                                           \
+    template DPL::Singleton<Type>&DPL::Singleton<Type>::InternalInstance();    \
+    template Type & DPL::Singleton<Type>::Instance();                            \
+
+#endif // DPL_SINGLETON_IMPL_H
diff --git a/tests/framework/include/dpl/singleton_safe_impl.h b/tests/framework/include/dpl/singleton_safe_impl.h
new file mode 100644 (file)
index 0000000..c8923b7
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        singleton_safe_impl.h
+ * @author      Tomasz Swierczek (t.swierczek@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of singleton
+ */
+#ifndef DPL_SINGLETON_SAFE_IMPL_H
+#define DPL_SINGLETON_SAFE_IMPL_H
+
+#define IMPLEMENT_SAFE_SINGLETON(Class)                                        \
+    namespace DPL {                                                                \
+    template<>                                                                     \
+    Singleton<Class>&Singleton<Class>::InternalInstance()                         \
+    {                                                                              \
+        static Singleton<Class> instance;                                          \
+        return instance;                                                           \
+    }                                                                              \
+                                                                               \
+    template<>                                                                     \
+    Class & Singleton<Class>::Instance()                                            \
+    {                                                                              \
+        Singleton<Class>& instance = Singleton<Class>::InternalInstance();         \
+        return instance;                                                           \
+    }                                                                              \
+                                                                               \
+    template Singleton<Class>&Singleton<Class>::InternalInstance();               \
+    template Class & Singleton<Class>::Instance();                                  \
+    } // namespace DPL
+
+#endif // DPL_SINGLETON_SAFE_IMPL_H
diff --git a/tests/framework/include/dpl/test/test_results_collector.h b/tests/framework/include/dpl/test/test_results_collector.h
new file mode 100644 (file)
index 0000000..cb29921
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        test_results_collector.h
+ * @author      Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version     1.0
+ * @brief       Header file with declaration of TestResultsCollectorBase
+ */
+
+#ifndef DPL_TEST_RESULTS_COLLECTOR_H
+#define DPL_TEST_RESULTS_COLLECTOR_H
+
+#include <dpl/noncopyable.h>
+#include <vector>
+#include <list>
+#include <map>
+#include <chrono>
+#include <string>
+#include <memory>
+
+namespace DPL {
+namespace Test {
+class TestResultsCollectorBase;
+typedef std::shared_ptr<TestResultsCollectorBase>
+TestResultsCollectorBasePtr;
+
+class TestResultsCollectorBase :
+    private DPL::Noncopyable
+{
+  public:
+    typedef TestResultsCollectorBase* (*CollectorConstructorFunc)();
+    typedef std::list<std::string> TestCaseIdList;
+    struct FailStatus
+    {
+        enum Type
+        {
+            NONE,
+            FAILED,
+            IGNORED,
+            INTERNAL
+        };
+    };
+
+    virtual ~TestResultsCollectorBase() {}
+
+    virtual bool Configure()
+    {
+        return true;
+    }
+    virtual void Start() { }
+    virtual void Finish() { }
+    virtual void CollectCurrentTestGroupName(const std::string& /*groupName*/)
+    {}
+
+    virtual void CollectTestsCasesList(const TestCaseIdList& /*list*/) {}
+    virtual void CollectResult(const std::string& id,
+                               const std::string& description,
+                               const FailStatus::Type status = FailStatus::NONE,
+                               const std::string& reason = "",
+                               const bool& isPerformanceTest = false,
+                               const std::chrono::system_clock::duration& performanceTime = std::chrono::microseconds::zero(),
+                               const std::chrono::system_clock::duration& performanceMaxTime = std::chrono::microseconds::zero()) = 0;
+    virtual std::string CollectorSpecificHelp() const
+    {
+        return "";
+    }
+    virtual bool ParseCollectorSpecificArg (const std::string& /*arg*/)
+    {
+        return false;
+    }
+
+    static TestResultsCollectorBase* Create(const std::string& name);
+    static void RegisterCollectorConstructor(
+        const std::string& name,
+        CollectorConstructorFunc
+        constructor);
+    static std::vector<std::string> GetCollectorsNames();
+
+  private:
+    typedef std::map<std::string, CollectorConstructorFunc> ConstructorsMap;
+    static ConstructorsMap m_constructorsMap;
+};
+}
+}
+
+#endif /* DPL_TEST_RESULTS_COLLECTOR_H */
diff --git a/tests/framework/include/dpl/test/test_runner.h b/tests/framework/include/dpl/test/test_runner.h
new file mode 100644 (file)
index 0000000..4893ee5
--- /dev/null
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        test_runner.h
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @author      Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version     1.0
+ * @brief       This file is the header file of test runner
+ */
+#ifndef DPL_TEST_RUNNER_H
+#define DPL_TEST_RUNNER_H
+
+#include <dpl/singleton.h>
+#include <dpl/availability.h>
+#include <dpl/atomic.h>
+#include <dpl/test/test_results_collector.h>
+#include <sstream>
+#include <string>
+#include <vector>
+#include <chrono>
+#include <list>
+#include <set>
+#include <map>
+
+namespace DPL {
+namespace Test {
+class TestRunner
+{
+    typedef std::map<std::string, TestResultsCollectorBasePtr>
+    TestResultsCollectors;
+    TestResultsCollectors m_collectors;
+
+    std::string m_startTestId;
+    bool m_runIgnored;
+
+  public:
+    TestRunner() :
+        m_currentTestCase(NULL)
+      , m_terminate(false)
+      , m_allowChildLogs(false)
+    {}
+
+    void beginPerformanceTestTime(std::chrono::system_clock::duration maxTimeInMicroseconds);
+    void endPerformanceTestTime();
+    void getCurrentTestCasePerformanceResult(bool& isPerformanceTest,
+                                             std::chrono::system_clock::duration& result,
+                                             std::chrono::system_clock::duration& resultMax);
+    void setCurrentTestCasePerformanceResult(bool isPerformanceTest,
+                                             std::chrono::system_clock::duration result,
+                                             std::chrono::system_clock::duration resultMax);
+
+    typedef void (*TestCase)();
+
+  private:
+    struct TestCaseStruct
+    {
+        std::string name;
+        TestCase proc;
+
+        bool m_isPerformanceTest;
+        std::chrono::system_clock::time_point m_performanceTestStartTime;
+        std::chrono::system_clock::duration m_performanceTestDurationTime;
+        std::chrono::system_clock::duration m_performanceMaxTime;
+
+        bool operator <(const TestCaseStruct &other) const
+        {
+            return name < other.name;
+        }
+
+        bool operator ==(const TestCaseStruct &other) const
+        {
+            return name == other.name;
+        }
+
+        TestCaseStruct(const std::string &n, TestCase p) :
+            name(n),
+            proc(p),
+            m_isPerformanceTest(false)
+        {}
+    };
+
+    typedef std::list<TestCaseStruct> TestCaseStructList;
+    typedef std::map<std::string, TestCaseStructList> TestCaseGroupMap;
+    TestCaseGroupMap m_testGroups;
+
+    TestCaseStruct * m_currentTestCase;
+
+    typedef std::set<std::string> SelectedTestNameSet;
+    SelectedTestNameSet m_selectedTestNamesSet;
+    typedef std::set<std::string> SelectedTestGroupSet;
+    SelectedTestGroupSet m_selectedTestGroupSet;
+    std::string m_currentGroup;
+
+    DPL::Atomic m_totalAssertions;
+
+    // Terminate without any logs.
+    // Some test requires to call fork function.
+    // Child process must not produce any logs and should die quietly.
+    bool m_terminate;
+    bool m_allowChildLogs;
+
+    void Banner();
+    void InvalidArgs(const std::string& message = "Invalid arguments!");
+    void Usage();
+
+    bool filterGroupsByXmls(const std::vector<std::string> & files);
+    bool filterByXML(std::map<std::string, bool> & casesMap);
+    void normalizeXMLTag(std::string& str, const std::string& testcase);
+
+    enum Status { FAILED, IGNORED, PASS };
+
+    Status RunTestCase(const TestCaseStruct& testCase);
+
+    void setCurrentTestCase(TestCaseStruct* testCase);
+    TestCaseStruct *getCurrentTestCase();
+
+    void RunTests();
+
+    void CollectResult(const std::string& id,
+                       const std::string& description,
+                       const TestResultsCollectorBase::FailStatus::Type status
+                           = TestResultsCollectorBase::FailStatus::NONE,
+                       const std::string& reason = std::string(),
+                       const bool& isPerformanceTest = false,
+                       const std::chrono::system_clock::duration& performanceTime = std::chrono::microseconds::zero(),
+                       const std::chrono::system_clock::duration& performanceMaxTime = std::chrono::microseconds::zero());
+
+  public:
+    class TestFailed
+    {
+      private:
+        std::string m_message;
+
+      public:
+        TestFailed()
+        {}
+
+        //! \brief Failed test message creator
+        //!
+        //! \param[in] aTest string for tested expression
+        //! \param[in] aFile source file name
+        //! \param[in] aLine source file line
+        //! \param[in] aMessage error message
+        TestFailed(const char* aTest,
+                   const char* aFile,
+                   int aLine,
+                   const std::string &aMessage);
+
+        TestFailed(const std::string &message);
+
+        std::string GetMessage() const
+        {
+            return m_message;
+        }
+    };
+
+    class Ignored
+    {
+      private:
+        std::string m_message;
+
+      public:
+        Ignored()
+        {}
+
+        Ignored(const std::string &message) :
+            m_message(message)
+        {}
+
+        std::string GetMessage() const
+        {
+            return m_message;
+        }
+    };
+
+    void MarkAssertion();
+
+    void RegisterTest(const char *testName, TestCase proc);
+    void InitGroup(const char* name);
+
+    int ExecTestRunner(int argc, char *argv[]);
+    typedef std::vector<std::string> ArgsList;
+    int ExecTestRunner(ArgsList args);
+    bool getRunIgnored() const;
+    // The runner will terminate as soon as possible (after current test).
+    void Terminate();
+    bool GetAllowChildLogs();
+};
+
+typedef DPL::Singleton<TestRunner> TestRunnerSingleton;
+}
+} // namespace DPL
+
+#define RUNNER_TEST_GROUP_INIT(GroupName)                                \
+    static int Static##GroupName##Init()                                 \
+    {                                                                    \
+        DPL::Test::TestRunnerSingleton::Instance().InitGroup(#GroupName); \
+        return 0;                                                        \
+    }                                                                    \
+    const int DPL_UNUSED Static##GroupName##InitVar =                   \
+        Static##GroupName##Init();
+
+#define RUNNER_TEST(Proc)                                                \
+    void Proc();                                                         \
+    static int Static##Proc##Init()                                      \
+    {                                                                    \
+        DPL::Test::TestRunnerSingleton::Instance().RegisterTest(#Proc, &Proc); \
+        return 0;                                                        \
+    }                                                                    \
+    const int DPL_UNUSED Static##Proc##InitVar = Static##Proc##Init();  \
+    void Proc()
+
+//! \brief Returns base name for path
+
+#define RUNNER_ASSERT_MSG(test, message)                                               \
+    do                                                                                     \
+    {                                                                                      \
+        DPL::Test::TestRunnerSingleton::Instance().MarkAssertion();                        \
+                                                                                       \
+        if (!(test))                                                                       \
+        {                                                                                  \
+            std::ostringstream assertMsg;                                                  \
+            assertMsg << message;                                                          \
+            throw DPL::Test::TestRunner::TestFailed(#test, \
+                                                    __FILE__, \
+                                                    __LINE__, \
+                                                    assertMsg.str()); \
+        }                                                                                  \
+    } while (0)
+
+#define RUNNER_ASSERT(test) RUNNER_ASSERT_MSG(test, "")
+
+#define RUNNER_FAIL RUNNER_ASSERT(false)
+
+#define RUNNER_IGNORED_MSG(message) do { std::ostringstream assertMsg; \
+                                         assertMsg << message; \
+                                         throw DPL::Test::TestRunner::Ignored( \
+                                                   assertMsg.str()); \
+} while (0)
+
+/*
+ * Use these macros to do the time measurement. The first macro will start time measurement,
+ * the second will gather the result. These macros can be used only once per test-case.
+ * The result of time measurement will be displayed only if the test will pass.
+ * Notice that these macros will work only if will be used in parent process. If these
+ * macros will be used in child process then there will be no time measure results printed.
+ * This macro in multiprocess tests has effect only if used in parent process. This macro
+ * used in child process in multiprocess test has no effect.
+ * The precision of measurement is 1 microsecond - the smallest time value that can be
+ * measured is 0.000001s.
+ * The time measure results will be printed only specific output format:
+ *     - text
+ *     - html
+ *     - xml
+ *     - csv
+ * In TAP format performance result will not be displayed.
+ */
+#define RUNNER_PERF_TEST_BEGIN(maxTime)                                        \
+    do {                                                                       \
+        DPL::Test::TestRunnerSingleton::Instance().beginPerformanceTestTime(   \
+                std::chrono::microseconds{static_cast<long long int>(maxTime*1000000.0)}); \
+    } while (0)
+
+#define RUNNER_PERF_TEST_END()                                                \
+    do {                                                                      \
+        DPL::Test::TestRunnerSingleton::Instance().endPerformanceTestTime();  \
+    } while (0)
+
+#endif // DPL_TEST_RUNNER_H
diff --git a/tests/framework/include/dpl/test/test_runner_child.h b/tests/framework/include/dpl/test/test_runner_child.h
new file mode 100644 (file)
index 0000000..d1e4b1c
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        test_runner_child.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       This file is the header file of test runner
+ */
+#ifndef DPL_TEST_RUNNER_CHILD_H
+#define DPL_TEST_RUNNER_CHILD_H
+
+#include <dpl/test/test_runner.h>
+
+namespace DPL {
+namespace Test {
+
+class PipeWrapper : DPL::Noncopyable
+{
+  public:
+    enum Usage {
+        READONLY,
+        WRITEONLY
+    };
+
+    enum Status {
+        SUCCESS,
+        TIMEOUT,
+        ERROR
+    };
+
+    PipeWrapper();
+
+    bool isReady();
+
+    void setUsage(Usage usage);
+
+    virtual ~PipeWrapper();
+
+    Status send(int code, std::string &message);
+    Status sendTime(int code,
+                    std::chrono::system_clock::duration time,
+                    std::chrono::system_clock::duration timeMax);
+
+    Status receive(int &code,
+                   int &msgType,
+                   std::string &data,
+                   std::chrono::system_clock::duration &time,
+                   std::chrono::system_clock::duration &timeMax,
+                   time_t deadline);
+
+    void closeAll();
+
+  protected:
+
+    std::string toBinaryString(int data);
+    std::string toBinaryString(std::chrono::system_clock::duration data);
+
+    void closeHelp(int desc);
+
+    Status writeHelp(const void *buffer, int size);
+
+    Status readHelp(void *buf, int size, time_t deadline);
+
+    static const int PIPE_CLOSED = -1;
+
+    int m_pipefd[2];
+};
+
+void RunChildProc(TestRunner::TestCase procChild);
+} // namespace Test
+} // namespace DPL
+
+#define RUNNER_CHILD_TEST(Proc)                                                      \
+    void Proc();                                                                     \
+    void Proc##Child();                                                              \
+    static int Static##Proc##Init()                                                  \
+    {                                                                                \
+        DPL::Test::TestRunnerSingleton::Instance().RegisterTest(#Proc, &Proc);       \
+        return 0;                                                                    \
+    }                                                                                \
+    const int DPL_UNUSED Static##Proc##InitVar = Static##Proc##Init();               \
+    void Proc(){                                                                     \
+        DPL::Test::RunChildProc(&Proc##Child);                                       \
+    }                                                                                \
+    void Proc##Child()
+
+#endif // DPL_TEST_RUNNER_CHILD_H
diff --git a/tests/framework/include/dpl/test/test_runner_multiprocess.h b/tests/framework/include/dpl/test/test_runner_multiprocess.h
new file mode 100644 (file)
index 0000000..279b5ef
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        test_runner_multiprocess.h
+ * @author      Marcin Niesluchowski (m.niesluchow@samsung.com)
+ * @version     1.0
+ * @brief       This file is the header file of multiprocess test runner
+ */
+#ifndef DPL_TEST_RUNNER_MULTIPROCESS_H
+#define DPL_TEST_RUNNER_MULTIPROCESS_H
+
+#include <dpl/test/test_runner_child.h>
+
+namespace DPL {
+namespace Test {
+
+class SimplePipeWrapper :
+        public PipeWrapper
+{
+  public:
+    SimplePipeWrapper();
+
+    virtual ~SimplePipeWrapper();
+
+    Status send(std::string &message);
+    Status receive(std::string &data, bool &empty, time_t deadline);
+};
+
+void RunMultiProc(TestRunner::TestCase procMulti);
+} // namespace Test
+} // namespace DPL
+
+#define RUNNER_MULTIPROCESS_TEST(Proc)                                               \
+    void Proc();                                                                     \
+    void Proc##Multi();                                                              \
+    static int Static##Proc##Init()                                                  \
+    {                                                                                \
+        DPL::Test::TestRunnerSingleton::Instance().RegisterTest(#Proc, &Proc);       \
+        return 0;                                                                    \
+    }                                                                                \
+    const int DPL_UNUSED Static##Proc##InitVar = Static##Proc##Init();               \
+    void Proc(){                                                                     \
+        DPL::Test::RunMultiProc(&Proc##Multi);                                       \
+    }                                                                                \
+    void Proc##Multi()
+
+#endif // DPL_TEST_RUNNER_MULTIPROCESS_H
diff --git a/tests/framework/src/abstract_log_provider.cpp b/tests/framework/src/abstract_log_provider.cpp
new file mode 100644 (file)
index 0000000..a03f8a0
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        abstract_log_provider.cpp
+ * @author      Pawel Sikorski (p.sikorski@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of abstract log provider
+ */
+#include <stddef.h>
+#include <dpl/log/abstract_log_provider.h>
+#include <cstring>
+
+namespace DPL {
+namespace Log {
+const char *AbstractLogProvider::LocateSourceFileName(const char *filename)
+{
+    const char *ptr = strrchr(filename, '/');
+    return ptr != NULL ? ptr + 1 : filename;
+}
+}
+}
diff --git a/tests/framework/src/assert.cpp b/tests/framework/src/assert.cpp
new file mode 100644 (file)
index 0000000..636a7cf
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        assert.cpp
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of assert
+ */
+#include <stddef.h>
+#include <dpl/assert.h>
+#include <dpl/colors.h>
+#include <dpl/exception.h>
+#include <dpl/log/log.h>
+#include <cstdlib>
+
+namespace DPL {
+void AssertProc(const char *condition,
+                const char *file,
+                int line,
+                const char *function)
+{
+#define INTERNAL_LOG(message)                                          \
+    do                                                                 \
+    {                                                                  \
+        std::ostringstream platformLog;                                \
+        platformLog << message;                                        \
+        DPL::Log::LogSystemSingleton::Instance().Pedantic(             \
+            platformLog.str().c_str(),                                 \
+            __FILE__, __LINE__, __FUNCTION__);                         \
+    } \
+    while (0)
+
+    // Try to log failed assertion to log system
+    Try
+    {
+        INTERNAL_LOG(
+            "################################################################################");
+        INTERNAL_LOG(
+            "###                          DPL assertion failed!                           ###");
+        INTERNAL_LOG(
+            "################################################################################");
+        INTERNAL_LOG("### Condition: " << condition);
+        INTERNAL_LOG("### File: " << file);
+        INTERNAL_LOG("### Line: " << line);
+        INTERNAL_LOG("### Function: " << function);
+        INTERNAL_LOG(
+            "################################################################################");
+    } catch (Exception) {
+        // Just ignore possible double errors
+    }
+
+    // Fail with c-library abort
+    abort();
+}
+} // namespace DPL
diff --git a/tests/framework/src/atomic.cpp b/tests/framework/src/atomic.cpp
new file mode 100644 (file)
index 0000000..2f50074
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        atomic.cpp
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of atomic
+ */
+#include <stddef.h>
+#include <dpl/atomic.h>
+
+namespace DPL {
+Atomic::Atomic(ValueType value) :
+    m_value(value)
+{}
+
+Atomic::ValueType Atomic::ExchangeAndAdd(ValueType value)
+{
+    return g_atomic_int_add(const_cast<gint* >(&m_value), value);
+}
+
+bool Atomic::CompareAndExchange(ValueType oldValue, ValueType newValue)
+{
+    return g_atomic_int_compare_and_exchange(const_cast<gint* >(&m_value),
+                                             oldValue,
+                                             newValue);
+}
+
+bool Atomic::operator--()
+{
+    return g_atomic_int_dec_and_test(const_cast<gint* >(&m_value)) != TRUE;
+}
+
+void Atomic::operator++()
+{
+    g_atomic_int_inc(const_cast<gint* >(&m_value));
+}
+
+Atomic::operator ValueType() const
+{
+    return g_atomic_int_get(const_cast<gint* >(&m_value));
+}
+} // namespace DPL
diff --git a/tests/framework/src/binary_queue.cpp b/tests/framework/src/binary_queue.cpp
new file mode 100644 (file)
index 0000000..2234c8f
--- /dev/null
@@ -0,0 +1,312 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        binary_queue.cpp
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of binary queue
+ */
+#include <stddef.h>
+#include <dpl/binary_queue.h>
+#include <dpl/assert.h>
+#include <dpl/scoped_free.h>
+#include <algorithm>
+#include <malloc.h>
+#include <cstring>
+#include <new>
+
+namespace DPL {
+BinaryQueue::BinaryQueue() :
+    m_size(0)
+{}
+
+BinaryQueue::BinaryQueue(const BinaryQueue &other) :
+    m_size(0)
+{
+    AppendCopyFrom(other);
+}
+
+BinaryQueue::~BinaryQueue()
+{
+    // Remove all remainig buckets
+    Clear();
+}
+
+const BinaryQueue &BinaryQueue::operator=(const BinaryQueue &other)
+{
+    if (this != &other) {
+        Clear();
+        AppendCopyFrom(other);
+    }
+
+    return *this;
+}
+
+void BinaryQueue::AppendCopyFrom(const BinaryQueue &other)
+{
+    // To speed things up, always copy as one bucket
+    void *bufferCopy = malloc(other.m_size);
+
+    if (bufferCopy == NULL) {
+        throw std::bad_alloc();
+    }
+
+    try {
+        other.Flatten(bufferCopy, other.m_size);
+        AppendUnmanaged(bufferCopy, other.m_size, &BufferDeleterFree, NULL);
+    } catch (const std::bad_alloc &) {
+        // Free allocated memory
+        free(bufferCopy);
+        throw;
+    }
+}
+
+void BinaryQueue::AppendMoveFrom(BinaryQueue &other)
+{
+    // Copy all buckets
+    std::copy(other.m_buckets.begin(),
+              other.m_buckets.end(), std::back_inserter(m_buckets));
+    m_size += other.m_size;
+
+    // Clear other, but do not free memory
+    other.m_buckets.clear();
+    other.m_size = 0;
+}
+
+void BinaryQueue::AppendCopyTo(BinaryQueue &other) const
+{
+    other.AppendCopyFrom(*this);
+}
+
+void BinaryQueue::AppendMoveTo(BinaryQueue &other)
+{
+    other.AppendMoveFrom(*this);
+}
+
+void BinaryQueue::Clear()
+{
+    std::for_each(m_buckets.begin(), m_buckets.end(), &DeleteBucket);
+    m_buckets.clear();
+    m_size = 0;
+}
+
+void BinaryQueue::AppendCopy(const void* buffer, size_t bufferSize)
+{
+    // Create data copy with malloc/free
+    void *bufferCopy = malloc(bufferSize);
+
+    // Check if allocation succeded
+    if (bufferCopy == NULL) {
+        throw std::bad_alloc();
+    }
+
+    // Copy user data
+    memcpy(bufferCopy, buffer, bufferSize);
+
+    try {
+        // Try to append new bucket
+        AppendUnmanaged(bufferCopy, bufferSize, &BufferDeleterFree, NULL);
+    } catch (const std::bad_alloc &) {
+        // Free allocated memory
+        free(bufferCopy);
+        throw;
+    }
+}
+
+void BinaryQueue::AppendUnmanaged(const void* buffer,
+                                  size_t bufferSize,
+                                  BufferDeleter deleter,
+                                  void* userParam)
+{
+    // Do not attach empty buckets
+    if (bufferSize == 0) {
+        deleter(buffer, bufferSize, userParam);
+        return;
+    }
+
+    // Just add new bucket with selected deleter
+    m_buckets.push_back(new Bucket(buffer, bufferSize, deleter, userParam));
+
+    // Increase total queue size
+    m_size += bufferSize;
+}
+
+size_t BinaryQueue::Size() const
+{
+    return m_size;
+}
+
+bool BinaryQueue::Empty() const
+{
+    return m_size == 0;
+}
+
+void BinaryQueue::Consume(size_t size)
+{
+    // Check parameters
+    if (size > m_size) {
+        Throw(Exception::OutOfData);
+    }
+
+    size_t bytesLeft = size;
+
+    // Consume data and/or remove buckets
+    while (bytesLeft > 0) {
+        // Get consume size
+        size_t count = std::min(bytesLeft, m_buckets.front()->left);
+
+        m_buckets.front()->ptr =
+            static_cast<const char *>(m_buckets.front()->ptr) + count;
+        m_buckets.front()->left -= count;
+        bytesLeft -= count;
+        m_size -= count;
+
+        if (m_buckets.front()->left == 0) {
+            DeleteBucket(m_buckets.front());
+            m_buckets.pop_front();
+        }
+    }
+}
+
+void BinaryQueue::Flatten(void *buffer, size_t bufferSize) const
+{
+    // Check parameters
+    if (bufferSize == 0) {
+        return;
+    }
+
+    if (bufferSize > m_size) {
+        Throw(Exception::OutOfData);
+    }
+
+    size_t bytesLeft = bufferSize;
+    void *ptr = buffer;
+    BucketList::const_iterator bucketIterator = m_buckets.begin();
+    Assert(m_buckets.end() != bucketIterator);
+
+    // Flatten data
+    while (bytesLeft > 0) {
+        // Get consume size
+        size_t count = std::min(bytesLeft, (*bucketIterator)->left);
+
+        // Copy data to user pointer
+        memcpy(ptr, (*bucketIterator)->ptr, count);
+
+        // Update flattened bytes count
+        bytesLeft -= count;
+        ptr = static_cast<char *>(ptr) + count;
+
+        // Take next bucket
+        ++bucketIterator;
+    }
+}
+
+void BinaryQueue::FlattenConsume(void *buffer, size_t bufferSize)
+{
+    // FIXME: Optimize
+    Flatten(buffer, bufferSize);
+    Consume(bufferSize);
+}
+
+void BinaryQueue::DeleteBucket(BinaryQueue::Bucket *bucket)
+{
+    delete bucket;
+}
+
+void BinaryQueue::BufferDeleterFree(const void* data,
+                                    size_t dataSize,
+                                    void* userParam)
+{
+    (void)dataSize;
+    (void)userParam;
+
+    // Default free deleter
+    free(const_cast<void *>(data));
+}
+
+BinaryQueue::Bucket::Bucket(const void* data,
+                            size_t dataSize,
+                            BufferDeleter dataDeleter,
+                            void* userParam) :
+    buffer(data),
+    ptr(data),
+    size(dataSize),
+    left(dataSize),
+    deleter(dataDeleter),
+    param(userParam)
+{
+    Assert(data != NULL);
+    Assert(deleter != NULL);
+}
+
+BinaryQueue::Bucket::~Bucket()
+{
+    // Invoke deleter on bucket data
+    deleter(buffer, size, param);
+}
+
+BinaryQueue::BucketVisitor::~BucketVisitor()
+{}
+
+BinaryQueue::BucketVisitorCall::BucketVisitorCall(BucketVisitor *visitor) :
+    m_visitor(visitor)
+{}
+
+BinaryQueue::BucketVisitorCall::~BucketVisitorCall()
+{}
+
+void BinaryQueue::BucketVisitorCall::operator()(Bucket *bucket) const
+{
+    m_visitor->OnVisitBucket(bucket->ptr, bucket->left);
+}
+
+void BinaryQueue::VisitBuckets(BucketVisitor *visitor) const
+{
+    Assert(visitor != NULL);
+
+    // Visit all buckets
+    std::for_each(m_buckets.begin(), m_buckets.end(), BucketVisitorCall(visitor));
+}
+
+BinaryQueueAutoPtr BinaryQueue::Read(size_t size)
+{
+    // Simulate input stream
+    size_t available = std::min(size, m_size);
+
+    ScopedFree<void> bufferCopy(malloc(available));
+
+    if (!bufferCopy) {
+        throw std::bad_alloc();
+    }
+
+    BinaryQueueAutoPtr result(new BinaryQueue());
+
+    Flatten(bufferCopy.Get(), available);
+    result->AppendUnmanaged(
+        bufferCopy.Get(), available, &BufferDeleterFree, NULL);
+    bufferCopy.Release();
+    Consume(available);
+
+    return result;
+}
+
+size_t BinaryQueue::Write(const BinaryQueue &buffer, size_t bufferSize)
+{
+    // Simulate output stream
+    AppendCopyFrom(buffer);
+    return bufferSize;
+}
+} // namespace DPL
diff --git a/tests/framework/src/colors.cpp b/tests/framework/src/colors.cpp
new file mode 100644 (file)
index 0000000..0b2fcd4
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        colors.cpp
+ * @author      Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version     1.0
+ * @brief       Some constants with definition of colors for Console
+ *              and html output
+ */
+#include <stddef.h>
+#include <dpl/colors.h>
+
+namespace DPL {
+namespace Colors {
+namespace Text {
+const char* BOLD_GREEN_BEGIN = "\033[1;32m";
+const char* BOLD_GREEN_END = "\033[m";
+const char* RED_BEGIN = "\033[0;31m";
+const char* RED_END = "\033[m";
+const char* PURPLE_BEGIN = "\033[0;35m";
+const char* PURPLE_END = "\033[m";
+const char* GREEN_BEGIN = "\033[0;32m";
+const char* GREEN_END = "\033[m";
+const char* CYAN_BEGIN = "\033[0;36m";
+const char* CYAN_END = "\033[m";
+const char* BOLD_RED_BEGIN = "\033[1;31m";
+const char* BOLD_RED_END = "\033[m";
+const char* BOLD_YELLOW_BEGIN = "\033[1;33m";
+const char* BOLD_YELLOW_END = "\033[m";
+const char* BOLD_GOLD_BEGIN = "\033[0;33m";
+const char* BOLD_GOLD_END = "\033[m";
+const char* BOLD_WHITE_BEGIN = "\033[1;37m";
+const char* BOLD_WHITE_END = "\033[m";
+} //namespace Text
+
+namespace Html {
+const char* BOLD_GREEN_BEGIN = "<font color=\"green\"><b>";
+const char* BOLD_GREEN_END = "</b></font>";
+const char* PURPLE_BEGIN = "<font color=\"purple\"><b>";
+const char* PURPLE_END = "</b></font>";
+const char* RED_BEGIN = "<font color=\"red\"><b>";
+const char* RED_END = "</b></font>";
+const char* GREEN_BEGIN = "<font color=\"green\">";
+const char* GREEN_END = "</font>";
+const char* CYAN_BEGIN = "<font color=\"cyan\">";
+const char* CYAN_END = "</font>";
+const char* BOLD_RED_BEGIN = "<font color=\"red\"><b>";
+const char* BOLD_RED_END = "</b></font>";
+const char* BOLD_YELLOW_BEGIN = "<font color=\"yellow\"><b>";
+const char* BOLD_YELLOW_END = "</b></font>";
+const char* BOLD_GOLD_BEGIN = "<font color=\"gold\"><b>";
+const char* BOLD_GOLD_END = "</b></font>";
+const char* BOLD_WHITE_BEGIN = "<font color=\"white\"><b>";
+const char* BOLD_WHITE_END = "</b></font>";
+} //namespace Html
+} //namespace Colors
+} //namespace DPL
diff --git a/tests/framework/src/dlog_log_provider.cpp b/tests/framework/src/dlog_log_provider.cpp
new file mode 100644 (file)
index 0000000..573ee89
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        dlog_log_provider.cpp
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of DLOG log provider
+ */
+#include <stddef.h>
+#include <dpl/log/dlog_log_provider.h>
+#include <cstring>
+#include <sstream>
+#include <dlog.h>
+
+namespace DPL {
+namespace Log {
+std::string DLOGLogProvider::FormatMessage(const char *message,
+                                           const char *filename,
+                                           int line,
+                                           const char *function)
+{
+    std::ostringstream val;
+
+    val << std::string("[") <<
+    LocateSourceFileName(filename) << std::string(":") << line <<
+    std::string("] ") << function << std::string("(): ") << message;
+
+    return val.str();
+}
+
+DLOGLogProvider::DLOGLogProvider()
+{}
+
+DLOGLogProvider::~DLOGLogProvider()
+{}
+
+void DLOGLogProvider::SetTag(const char *tag)
+{
+    m_tag.Reset(strdup(tag));
+}
+
+void DLOGLogProvider::Debug(const char *message,
+                            const char *filename,
+                            int line,
+                            const char *function)
+{
+#ifdef SECURE_LOG
+    SECURE_LOG(LOG_DEBUG, m_tag.Get(), "%s",
+        FormatMessage(message, filename, line, function).c_str());
+#else
+    LOG(LOG_DEBUG, m_tag.Get(), "%s",
+        FormatMessage(message, filename, line, function).c_str());
+#endif
+}
+
+void DLOGLogProvider::Info(const char *message,
+                           const char *filename,
+                           int line,
+                           const char *function)
+{
+#ifdef SECURE_LOG
+    SECURE_LOG(LOG_INFO, m_tag.Get(), "%s",
+        FormatMessage(message, filename, line, function).c_str());
+#else
+    LOG(LOG_INFO, m_tag.Get(), "%s",
+        FormatMessage(message, filename, line, function).c_str());
+#endif
+}
+
+void DLOGLogProvider::Warning(const char *message,
+                              const char *filename,
+                              int line,
+                              const char *function)
+{
+#ifdef SECURE_LOG
+    SECURE_LOG(LOG_WARN, m_tag.Get(), "%s",
+        FormatMessage(message, filename, line, function).c_str());
+#else
+    LOG(LOG_WARN, m_tag.Get(), "%s",
+        FormatMessage(message, filename, line, function).c_str());
+#endif
+}
+
+void DLOGLogProvider::Error(const char *message,
+                            const char *filename,
+                            int line,
+                            const char *function)
+{
+#ifdef SECURE_LOG
+    SECURE_LOG(LOG_ERROR, m_tag.Get(), "%s",
+        FormatMessage(message, filename, line, function).c_str());
+#else
+    LOG(LOG_ERROR, m_tag.Get(), "%s",
+        FormatMessage(message, filename, line, function).c_str());
+#endif
+}
+
+void DLOGLogProvider::Pedantic(const char *message,
+                               const char *filename,
+                               int line,
+                               const char *function)
+{
+#ifdef SECURE_LOG
+    SECURE_LOG(LOG_DEBUG, "DPL", "%s", FormatMessage(message,
+                                              filename,
+                                              line,
+                                              function).c_str());
+#else
+    LOG(LOG_DEBUG, "DPL", "%s", FormatMessage(message,
+                                              filename,
+                                              line,
+                                              function).c_str());
+#endif
+}
+}
+} // namespace DPL
diff --git a/tests/framework/src/exception.cpp b/tests/framework/src/exception.cpp
new file mode 100644 (file)
index 0000000..d3673e6
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        exception.cpp
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation of exception system
+ */
+#include <stddef.h>
+#include <dpl/exception.h>
+#include <dpl/log/log.h>
+#include <cstdio>
+
+namespace DPL {
+Exception* Exception::m_lastException = NULL;
+unsigned int Exception::m_exceptionCount = 0;
+void (*Exception::m_terminateHandler)() = NULL;
+
+void LogUnhandledException(const std::string &str)
+{
+    // Logging to console
+    printf("%s\n", str.c_str());
+
+    // Logging to dlog
+    LogPedantic(str);
+}
+
+void LogUnhandledException(const std::string &str,
+                           const char *filename,
+                           int line,
+                           const char *function)
+{
+    // Logging to console
+    std::ostringstream msg;
+    msg << "\033[1;5;31m\n=== [" << filename << ":" << line << "] " <<
+    function << " ===\033[m";
+    msg << str;
+    printf("%s\n", msg.str().c_str());
+
+    // Logging to dlog
+    DPL::Log::LogSystemSingleton::Instance().Error(
+        str.c_str(), filename, line, function);
+}
+} // namespace DPL
diff --git a/tests/framework/src/log.cpp b/tests/framework/src/log.cpp
new file mode 100644 (file)
index 0000000..5e155bf
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        log.cpp
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of log system
+ */
+#include <stddef.h>
+#include <string.h>
+
+#include <dpl/log/log.h>
+#include <dpl/singleton_impl.h>
+
+IMPLEMENT_SINGLETON(DPL::Log::LogSystem)
+
+namespace DPL {
+namespace Log {
+namespace // anonymous
+{
+const char *OLD_STYLE_LOGS_ENV_NAME = "DPL_USE_OLD_STYLE_LOGS";
+const char *OLD_STYLE_PEDANTIC_LOGS_ENV_NAME =
+    "DPL_USE_OLD_STYLE_PEDANTIC_LOGS";
+const char *OLD_STYLE_LOGS_MASK_ENV_NAME = "DPL_USE_OLD_STYLE_LOGS_MASK";
+const char *DPL_LOG_OFF = "DPL_LOG_OFF";
+} // namespace anonymous
+
+bool LogSystem::IsLoggingEnabled() const
+{
+    return m_isLoggingEnabled;
+}
+
+LogSystem::LogSystem() :
+    m_dlogProvider(NULL),
+    m_oldStyleProvider(NULL),
+    m_isLoggingEnabled(!getenv(DPL_LOG_OFF))
+{
+    bool oldStyleLogs = false;
+    bool oldStyleDebugLogs = true;
+    bool oldStyleInfoLogs = true;
+    bool oldStyleWarningLogs = true;
+    bool oldStyleErrorLogs = true;
+    bool oldStylePedanticLogs = false;
+
+    // Check environment settings about pedantic logs
+    const char *value = getenv(OLD_STYLE_LOGS_ENV_NAME);
+
+    if (value != NULL && !strcmp(value, "1")) {
+        oldStyleLogs = true;
+    }
+
+    value = getenv(OLD_STYLE_PEDANTIC_LOGS_ENV_NAME);
+
+    if (value != NULL && !strcmp(value, "1")) {
+        oldStylePedanticLogs = true;
+    }
+
+    value = getenv(OLD_STYLE_LOGS_MASK_ENV_NAME);
+
+    if (value != NULL) {
+        size_t len = strlen(value);
+
+        if (len >= 1) {
+            if (value[0] == '0') {
+                oldStyleDebugLogs = false;
+            } else if (value[0] == '1') {
+                oldStyleDebugLogs = true;
+            }
+        }
+
+        if (len >= 2) {
+            if (value[1] == '0') {
+                oldStyleInfoLogs = false;
+            } else if (value[1] == '1') {
+                oldStyleInfoLogs = true;
+            }
+        }
+
+        if (len >= 3) {
+            if (value[2] == '0') {
+                oldStyleWarningLogs = false;
+            } else if (value[2] == '1') {
+                oldStyleWarningLogs = true;
+            }
+        }
+
+        if (len >= 4) {
+            if (value[3] == '0') {
+                oldStyleErrorLogs = false;
+            } else if (value[3] == '1') {
+                oldStyleErrorLogs = true;
+            }
+        }
+    }
+
+    // Setup default DLOG and old style logging
+    if (oldStyleLogs) {
+        // Old style
+        m_oldStyleProvider = new OldStyleLogProvider(oldStyleDebugLogs,
+                                                     oldStyleInfoLogs,
+                                                     oldStyleWarningLogs,
+                                                     oldStyleErrorLogs,
+                                                     oldStylePedanticLogs);
+        AddProvider(m_oldStyleProvider);
+    } else {
+        // DLOG
+        m_dlogProvider = new DLOGLogProvider();
+        AddProvider(m_dlogProvider);
+    }
+}
+
+LogSystem::~LogSystem()
+{
+    // Delete all providers
+    for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin();
+         iterator != m_providers.end();
+         ++iterator)
+    {
+        delete *iterator;
+    }
+
+    m_providers.clear();
+
+    // And even default providers
+    m_dlogProvider = NULL;
+    m_oldStyleProvider = NULL;
+}
+
+void LogSystem::SetTag(const char* tag)
+{
+    if (m_dlogProvider != NULL) {
+        m_dlogProvider->SetTag(tag);
+    }
+}
+
+void LogSystem::AddProvider(AbstractLogProvider *provider)
+{
+    m_providers.push_back(provider);
+}
+
+void LogSystem::RemoveProvider(AbstractLogProvider *provider)
+{
+    m_providers.remove(provider);
+}
+
+void LogSystem::Debug(const char *message,
+                      const char *filename,
+                      int line,
+                      const char *function)
+{
+    for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin();
+         iterator != m_providers.end();
+         ++iterator)
+    {
+        (*iterator)->Debug(message, filename, line, function);
+    }
+}
+
+void LogSystem::Info(const char *message,
+                     const char *filename,
+                     int line,
+                     const char *function)
+{
+    for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin();
+         iterator != m_providers.end();
+         ++iterator)
+    {
+        (*iterator)->Info(message, filename, line, function);
+    }
+}
+
+void LogSystem::Warning(const char *message,
+                        const char *filename,
+                        int line,
+                        const char *function)
+{
+    for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin();
+         iterator != m_providers.end();
+         ++iterator)
+    {
+        (*iterator)->Warning(message, filename, line, function);
+    }
+}
+
+void LogSystem::Error(const char *message,
+                      const char *filename,
+                      int line,
+                      const char *function)
+{
+    for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin();
+         iterator != m_providers.end();
+         ++iterator)
+    {
+        (*iterator)->Error(message, filename, line, function);
+    }
+}
+
+void LogSystem::Pedantic(const char *message,
+                         const char *filename,
+                         int line,
+                         const char *function)
+{
+    for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin();
+         iterator != m_providers.end();
+         ++iterator)
+    {
+        (*iterator)->Pedantic(message, filename, line, function);
+    }
+}
+}
+} // namespace DPL
diff --git a/tests/framework/src/noncopyable.cpp b/tests/framework/src/noncopyable.cpp
new file mode 100644 (file)
index 0000000..9453655
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        noncopyable.cpp
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of noncopyable
+ */
+#include <stddef.h>
+#include <dpl/noncopyable.h>
+
+namespace DPL {
+Noncopyable::Noncopyable()
+{}
+
+Noncopyable::~Noncopyable()
+{}
+} // namespace DPL
diff --git a/tests/framework/src/old_style_log_provider.cpp b/tests/framework/src/old_style_log_provider.cpp
new file mode 100644 (file)
index 0000000..b8060dd
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        old_style_log_provider.cpp
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of old style log provider
+ */
+#include <stddef.h>
+#include <dpl/log/old_style_log_provider.h>
+#include <dpl/colors.h>
+#include <cstdio>
+#include <cstring>
+#include <sstream>
+#include <sys/time.h>
+#include <unistd.h>
+
+namespace DPL {
+namespace Log {
+namespace // anonymous
+{
+using namespace DPL::Colors::Text;
+const char *DEBUG_BEGIN = GREEN_BEGIN;
+const char *DEBUG_END = GREEN_END;
+const char *INFO_BEGIN = CYAN_BEGIN;
+const char *INFO_END = CYAN_END;
+const char *ERROR_BEGIN = RED_BEGIN;
+const char *ERROR_END = RED_END;
+const char *WARNING_BEGIN = BOLD_GOLD_BEGIN;
+const char *WARNING_END = BOLD_GOLD_END;
+const char *PEDANTIC_BEGIN = PURPLE_BEGIN;
+const char *PEDANTIC_END = PURPLE_END;
+
+std::string GetFormattedTime()
+{
+    timeval tv;
+    tm localNowTime;
+
+    gettimeofday(&tv, NULL);
+    localtime_r(&tv.tv_sec, &localNowTime);
+
+    char format[64];
+    snprintf(format,
+             sizeof(format),
+             "%02i:%02i:%02i.%03i",
+             localNowTime.tm_hour,
+             localNowTime.tm_min,
+             localNowTime.tm_sec,
+             static_cast<int>(tv.tv_usec / 1000));
+    return format;
+}
+} // namespace anonymous
+
+std::string OldStyleLogProvider::FormatMessage(const char *message,
+                                               const char *filename,
+                                               int line,
+                                               const char *function)
+{
+    std::ostringstream val;
+
+    val << std::string("[") << GetFormattedTime() << std::string("] [") <<
+    static_cast<unsigned long>(pthread_self()) << "/" <<
+    static_cast<int>(getpid()) << std::string("] [") <<
+    LocateSourceFileName(filename) << std::string(":") << line <<
+    std::string("] ") << function << std::string("(): ") << message;
+
+    return val.str();
+}
+
+OldStyleLogProvider::OldStyleLogProvider(bool showDebug,
+                                         bool showInfo,
+                                         bool showWarning,
+                                         bool showError,
+                                         bool showPedantic) :
+    m_showDebug(showDebug),
+    m_showInfo(showInfo),
+    m_showWarning(showWarning),
+    m_showError(showError),
+    m_showPedantic(showPedantic),
+    m_printStdErr(false)
+{}
+
+OldStyleLogProvider::OldStyleLogProvider(bool showDebug,
+                                         bool showInfo,
+                                         bool showWarning,
+                                         bool showError,
+                                         bool showPedantic,
+                                         bool printStdErr) :
+    m_showDebug(showDebug),
+    m_showInfo(showInfo),
+    m_showWarning(showWarning),
+    m_showError(showError),
+    m_showPedantic(showPedantic),
+    m_printStdErr(printStdErr)
+{}
+
+void OldStyleLogProvider::Debug(const char *message,
+                                const char *filename,
+                                int line,
+                                const char *function)
+{
+    if (m_showDebug) {
+        if (m_printStdErr) {
+            fprintf(stderr, "%s%s%s\n", DEBUG_BEGIN,
+                    FormatMessage(message, filename, line,
+                        function).c_str(), DEBUG_END);
+        } else {
+            fprintf(stdout, "%s%s%s\n", DEBUG_BEGIN,
+                    FormatMessage(message, filename, line,
+                        function).c_str(), DEBUG_END);
+        }
+    }
+}
+
+void OldStyleLogProvider::Info(const char *message,
+                               const char *filename,
+                               int line,
+                               const char *function)
+{
+    if (m_showInfo) {
+        if (m_printStdErr) {
+            fprintf(stderr, "%s%s%s\n", INFO_BEGIN,
+                    FormatMessage(message, filename, line,
+                        function).c_str(), INFO_END);
+        } else {
+            fprintf(stdout, "%s%s%s\n", INFO_BEGIN,
+                    FormatMessage(message, filename, line,
+                        function).c_str(), INFO_END);
+        }
+    }
+}
+
+void OldStyleLogProvider::Warning(const char *message,
+                                  const char *filename,
+                                  int line,
+                                  const char *function)
+{
+    if (m_showWarning) {
+        if (m_printStdErr) {
+            fprintf(stderr, "%s%s%s\n", WARNING_BEGIN,
+                    FormatMessage(message, filename, line,
+                        function).c_str(), WARNING_END);
+        } else {
+            fprintf(stdout, "%s%s%s\n", WARNING_BEGIN,
+                    FormatMessage(message, filename, line,
+                        function).c_str(), WARNING_END);
+        }
+    }
+}
+
+void OldStyleLogProvider::Error(const char *message,
+                                const char *filename,
+                                int line,
+                                const char *function)
+{
+    if (m_showError) {
+        if (m_printStdErr) {
+            fprintf(stderr, "%s%s%s\n", ERROR_BEGIN,
+                    FormatMessage(message, filename, line,
+                        function).c_str(), ERROR_END);
+        } else {
+            fprintf(stdout, "%s%s%s\n", ERROR_BEGIN,
+                    FormatMessage(message, filename, line,
+                        function).c_str(), ERROR_END);
+        }
+    }
+}
+
+void OldStyleLogProvider::Pedantic(const char *message,
+                                   const char *filename,
+                                   int line,
+                                   const char *function)
+{
+    if (m_showPedantic) {
+        if (m_printStdErr) {
+            fprintf(stderr, "%s%s%s\n", PEDANTIC_BEGIN,
+                    FormatMessage(message, filename, line,
+                        function).c_str(), PEDANTIC_END);
+        } else {
+            fprintf(stdout, "%s%s%s\n", PEDANTIC_BEGIN,
+                    FormatMessage(message, filename, line,
+                        function).c_str(), PEDANTIC_END);
+        }
+    }
+}
+}
+} // namespace DPL
diff --git a/tests/framework/src/singleton.cpp b/tests/framework/src/singleton.cpp
new file mode 100644 (file)
index 0000000..54abd52
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        singleton.cpp
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of singleton
+ */
+#include <stddef.h>
+#include <dpl/singleton.h>
+
+//
+// Note:
+//
+// The file here is left blank to enable precompilation
+// of templates in corresponding header file.
+// Do not remove this file.
+//
diff --git a/tests/framework/src/test_results_collector.cpp b/tests/framework/src/test_results_collector.cpp
new file mode 100644 (file)
index 0000000..e42f60e
--- /dev/null
@@ -0,0 +1,1081 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        test_results_collector.h
+ * @author      Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version     1.0
+ * @brief       Implementation file some concrete TestResulstsCollector
+ */
+#include <cstddef>
+#include <dpl/test/test_results_collector.h>
+#include <dpl/availability.h>
+#include <dpl/colors.h>
+#include <dpl/assert.h>
+#include <dpl/scoped_fclose.h>
+#include <dpl/exception.h>
+
+#include <string>
+#include <string.h>
+#include <errno.h>
+#include <cstdio>
+#include <fstream>
+#include <sstream>
+#include <cstdlib>
+
+#define GREEN_RESULT_OK "[%s%s%s]\n", BOLD_GREEN_BEGIN, "   OK   ", \
+    BOLD_GREEN_END
+#define GREEN_RESULT_OK_TIME "[%s%s%s] [elapsed: %0.3fms]\n", BOLD_GREEN_BEGIN, \
+    "   OK   ", BOLD_GREEN_END
+#define GREEN_RESULT_OK_TIME_MAX(elapsed, max) \
+    "[%s%s%s] %s[elapsed: %0.3fms, expected < %0.3fms]%s\n", BOLD_GREEN_BEGIN, \
+    "   OK   ", BOLD_GREEN_END, BOLD_GREEN_BEGIN, elapsed, max, BOLD_GREEN_END
+#define GREEN_RESULT_OK_TIME_TOO_LONG(elapsed, max) \
+    "[%s%s%s] %s[elapsed: %0.3fms, expected < %0.3fms]%s\n", BOLD_GREEN_BEGIN, \
+    "   OK   ", BOLD_GREEN_END, BOLD_RED_BEGIN, elapsed, max, BOLD_RED_END
+
+namespace { /* anonymous namespace */
+// Get duration as a fraction of millisecond (max precision is 1 microsecond)
+double get_milliseconds (const std::chrono::system_clock::duration& performanceTime)
+{
+    return (static_cast<double>(std::chrono::duration_cast<std::chrono::microseconds>
+            (performanceTime).count()))/1000.0;
+}
+} /* anonymous namespace */
+
+namespace DPL {
+namespace Test {
+namespace {
+const char *DEFAULT_HTML_FILE_NAME = "index.html";
+const char *DEFAULT_TAP_FILE_NAME = "results.tap";
+const char *DEFAULT_XML_FILE_NAME = "results.xml";
+
+bool ParseCollectorFileArg(const std::string &arg, std::string &filename)
+{
+    const std::string argname = "--file=";
+    if (arg.find(argname) == 0 ) {
+        filename = arg.substr(argname.size());
+        return true;
+    }
+    return false;
+}
+
+class Statistic
+{
+  public:
+    Statistic() :
+        m_failed(0),
+        m_ignored(0),
+        m_passed(0),
+        m_count(0)
+    {}
+
+    void AddTest(TestResultsCollectorBase::FailStatus::Type type)
+    {
+        ++m_count;
+        switch (type) {
+        case TestResultsCollectorBase::FailStatus::INTERNAL:
+        case TestResultsCollectorBase::FailStatus::FAILED:   ++m_failed;
+            break;
+        case TestResultsCollectorBase::FailStatus::IGNORED:  ++m_ignored;
+            break;
+        case TestResultsCollectorBase::FailStatus::NONE:     ++m_passed;
+            break;
+        default:
+            Assert(false && "Bad FailStatus");
+        }
+    }
+
+    std::size_t GetTotal() const
+    {
+        return m_count;
+    }
+    std::size_t GetPassed() const
+    {
+        return m_passed;
+    }
+    std::size_t GetSuccesed() const
+    {
+        return m_passed;
+    }
+    std::size_t GetFailed() const
+    {
+        return m_failed;
+    }
+    std::size_t GetIgnored() const
+    {
+        return m_ignored;
+    }
+    float GetPassedOrIgnoredPercend() const
+    {
+        float passIgnoredPercent =
+            100.0f * (static_cast<float>(m_passed)
+                      + static_cast<float>(m_ignored))
+            / static_cast<float>(m_count);
+        return passIgnoredPercent;
+    }
+
+  private:
+    std::size_t m_failed;
+    std::size_t m_ignored;
+    std::size_t m_passed;
+    std::size_t m_count;
+};
+
+class ConsoleCollector :
+    public TestResultsCollectorBase
+{
+  public:
+    static TestResultsCollectorBase* Constructor();
+
+  private:
+    ConsoleCollector() {}
+
+    virtual void CollectCurrentTestGroupName(const std::string& name)
+    {
+        printf("Starting group %s\n", name.c_str());
+        m_currentGroup = name;
+    }
+
+    virtual void Finish()
+    {
+        using namespace DPL::Colors::Text;
+
+        // Show result
+        for (auto &group : m_groupsStats) {
+            PrintStats(group.first, group.second);
+        }
+        PrintStats("All tests together", m_stats);
+    }
+
+    virtual void CollectResult(const std::string& id,
+                               const std::string& /*description*/,
+                               const FailStatus::Type status = FailStatus::NONE,
+                               const std::string& reason = "",
+                               const bool& isPerformanceTest = true,
+                               const std::chrono::system_clock::duration& performanceTime = std::chrono::microseconds::zero(),
+                               const std::chrono::system_clock::duration& performanceMaxTime = std::chrono::microseconds::zero())
+    {
+        using namespace DPL::Colors::Text;
+        std::string tmp = "'" + id + "' ...";
+
+        printf("Running test case %-60s", tmp.c_str());
+        switch (status) {
+        case TestResultsCollectorBase::FailStatus::NONE:
+            if (isPerformanceTest) {
+                if (performanceMaxTime <= std::chrono::microseconds::zero()) {
+                    printf(GREEN_RESULT_OK_TIME,
+                            get_milliseconds(performanceTime));
+                    break;
+                }
+                else {
+                    if (performanceTime > performanceMaxTime)
+                        printf(GREEN_RESULT_OK_TIME_TOO_LONG(
+                                get_milliseconds(performanceTime),
+                                get_milliseconds(performanceMaxTime)));
+                    else
+                        printf(GREEN_RESULT_OK_TIME_MAX(
+                                get_milliseconds(performanceTime),
+                                get_milliseconds(performanceMaxTime)));
+                    break;
+                }
+            }
+            printf(GREEN_RESULT_OK);
+            break;
+        case TestResultsCollectorBase::FailStatus::FAILED:
+            PrintfErrorMessage(" FAILED ", reason, true);
+            break;
+        case TestResultsCollectorBase::FailStatus::IGNORED:
+            PrintfIgnoredMessage("Ignored ", reason, true);
+            break;
+        case TestResultsCollectorBase::FailStatus::INTERNAL:
+            PrintfErrorMessage("INTERNAL", reason, true);
+            break;
+        default:
+            Assert(false && "Bad status");
+        }
+        m_stats.AddTest(status);
+        m_groupsStats[m_currentGroup].AddTest(status);
+    }
+
+    void PrintfErrorMessage(const char* type,
+                            const std::string& message,
+                            bool verbosity)
+    {
+        using namespace DPL::Colors::Text;
+        if (verbosity) {
+            printf("[%s%s%s] %s%s%s\n",
+                   BOLD_RED_BEGIN,
+                   type,
+                   BOLD_RED_END,
+                   BOLD_YELLOW_BEGIN,
+                   message.c_str(),
+                   BOLD_YELLOW_END);
+        } else {
+            printf("[%s%s%s]\n",
+                   BOLD_RED_BEGIN,
+                   type,
+                   BOLD_RED_END);
+        }
+    }
+
+    void PrintfIgnoredMessage(const char* type,
+                              const std::string& message,
+                              bool verbosity)
+    {
+        using namespace DPL::Colors::Text;
+        if (verbosity) {
+            printf("[%s%s%s] %s%s%s\n",
+                   CYAN_BEGIN,
+                   type,
+                   CYAN_END,
+                   BOLD_GOLD_BEGIN,
+                   message.c_str(),
+                   BOLD_GOLD_END);
+        } else {
+            printf("[%s%s%s]\n",
+                   CYAN_BEGIN,
+                   type,
+                   CYAN_END);
+        }
+    }
+
+    void PrintStats(const std::string& title, const Statistic& stats)
+    {
+        using namespace DPL::Colors::Text;
+        printf("\n%sResults [%s]: %s\n", BOLD_GREEN_BEGIN,
+               title.c_str(), BOLD_GREEN_END);
+        printf("%s%s%3zu%s\n",
+               CYAN_BEGIN,
+               "Total tests:            ",
+               stats.GetTotal(),
+               CYAN_END);
+        printf("  %s%s%3zu%s\n",
+               CYAN_BEGIN,
+               "Succeeded:            ",
+               stats.GetPassed(),
+               CYAN_END);
+        printf("  %s%s%3zu%s\n",
+               CYAN_BEGIN,
+               "Failed:               ",
+               stats.GetFailed(),
+               CYAN_END);
+        printf("  %s%s%3zu%s\n",
+               CYAN_BEGIN,
+               "Ignored:              ",
+               stats.GetIgnored(),
+               CYAN_END);
+    }
+
+    Statistic m_stats;
+    std::map<std::string, Statistic> m_groupsStats;
+    std::string m_currentGroup;
+};
+
+TestResultsCollectorBase* ConsoleCollector::Constructor()
+{
+    return new ConsoleCollector();
+}
+
+class HtmlCollector :
+    public TestResultsCollectorBase
+{
+  public:
+    static TestResultsCollectorBase* Constructor();
+
+  private:
+    HtmlCollector() : m_filename(DEFAULT_HTML_FILE_NAME) {}
+
+    virtual void CollectCurrentTestGroupName(const std::string& name)
+    {
+        fprintf(m_fp.Get(), "<b>Starting group %s", name.c_str());
+        m_currentGroup = name;
+    }
+
+    virtual bool Configure()
+    {
+        m_fp.Reset(fopen(m_filename.c_str(), "w"));
+        if (!m_fp) {
+            LogPedantic("Could not open file " << m_filename << " for writing");
+            return false;
+        }
+        return true;
+    }
+    virtual std::string CollectorSpecificHelp() const
+    {
+        return "--file=<filename> - name of file for output\n"
+               "                    default - index.html\n";
+    }
+
+    virtual void Start()
+    {
+        Assert(!!m_fp && "File handle must not be null");
+        fprintf(m_fp.Get(),
+                "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0"
+                "Transitional//EN\" "
+                "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\""
+                ">\n");
+        fprintf(m_fp.Get(),
+                "<html xmlns=\"http://www.w3.org/1999/xhtml\" "
+                "lang=\"en\" dir=\"ltr\">\n");
+        fprintf(m_fp.Get(), "<body style=\"background-color: black;\">\n");
+        fprintf(m_fp.Get(), "<pre>\n");
+        fprintf(m_fp.Get(), "<font color=\"white\">\n");
+    }
+
+    virtual void Finish()
+    {
+        using namespace DPL::Colors::Html;
+        // Show result
+        for (auto &group : m_groupsStats) {
+            PrintStats(group.first, group.second);
+        }
+        PrintStats("All tests together", m_stats);
+        fprintf(m_fp.Get(), "</font>\n");
+        fprintf(m_fp.Get(), "</pre>\n");
+        fprintf(m_fp.Get(), "</body>\n");
+        fprintf(m_fp.Get(), "</html>\n");
+    }
+
+    virtual bool ParseCollectorSpecificArg(const std::string& arg)
+    {
+        return ParseCollectorFileArg(arg, m_filename);
+    }
+
+    virtual void CollectResult(const std::string& id,
+                               const std::string& /*description*/,
+                               const FailStatus::Type status = FailStatus::NONE,
+                               const std::string& reason = "",
+                               const bool& isPerformanceTest = false,
+                               const std::chrono::system_clock::duration& performanceTime = std::chrono::microseconds::zero(),
+                               const std::chrono::system_clock::duration& performanceMaxTime = std::chrono::microseconds::zero())
+    {
+        using namespace DPL::Colors::Html;
+        std::string tmp = "'" + id + "' ...";
+
+        fprintf(m_fp.Get(), "Running test case %-100s", tmp.c_str());
+        switch (status) {
+        case TestResultsCollectorBase::FailStatus::NONE:
+            if (isPerformanceTest) {
+                if (performanceMaxTime <= std::chrono::microseconds::zero()) {
+                    fprintf(m_fp.Get(), GREEN_RESULT_OK_TIME,
+                            get_milliseconds(performanceTime));
+                    break;
+                } else {
+                    if (performanceTime > performanceMaxTime)
+                        fprintf(m_fp.Get(), GREEN_RESULT_OK_TIME_TOO_LONG(
+                                get_milliseconds(performanceTime),
+                                get_milliseconds(performanceMaxTime)));
+                    else
+                        fprintf(m_fp.Get(), GREEN_RESULT_OK_TIME_MAX(
+                                get_milliseconds(performanceTime),
+                                get_milliseconds(performanceMaxTime)));
+                    break;
+                }
+            }
+            fprintf(m_fp.Get(), GREEN_RESULT_OK);
+            break;
+        case TestResultsCollectorBase::FailStatus::FAILED:
+            PrintfErrorMessage(" FAILED ", reason, true);
+            break;
+        case TestResultsCollectorBase::FailStatus::IGNORED:
+            PrintfIgnoredMessage("Ignored ", reason, true);
+            break;
+        case TestResultsCollectorBase::FailStatus::INTERNAL:
+            PrintfErrorMessage("INTERNAL", reason, true);
+            break;
+        default:
+            Assert(false && "Bad status");
+        }
+        m_groupsStats[m_currentGroup].AddTest(status);
+        m_stats.AddTest(status);
+    }
+
+    void PrintfErrorMessage(const char* type,
+                            const std::string& message,
+                            bool verbosity)
+    {
+        using namespace DPL::Colors::Html;
+        if (verbosity) {
+            fprintf(m_fp.Get(),
+                    "[%s%s%s] %s%s%s\n",
+                    BOLD_RED_BEGIN,
+                    type,
+                    BOLD_RED_END,
+                    BOLD_YELLOW_BEGIN,
+                    message.c_str(),
+                    BOLD_YELLOW_END);
+        } else {
+            fprintf(m_fp.Get(),
+                    "[%s%s%s]\n",
+                    BOLD_RED_BEGIN,
+                    type,
+                    BOLD_RED_END);
+        }
+    }
+
+    void PrintfIgnoredMessage(const char* type,
+                              const std::string& message,
+                              bool verbosity)
+    {
+        using namespace DPL::Colors::Html;
+
+        if (verbosity) {
+            fprintf(m_fp.Get(),
+                    "[%s%s%s] %s%s%s\n",
+                    CYAN_BEGIN,
+                    type,
+                    CYAN_END,
+                    BOLD_GOLD_BEGIN,
+                    message.c_str(),
+                    BOLD_GOLD_END);
+        } else {
+            fprintf(m_fp.Get(),
+                    "[%s%s%s]\n",
+                    CYAN_BEGIN,
+                    type,
+                    CYAN_END);
+        }
+    }
+
+    void PrintStats(const std::string& name, const Statistic& stats)
+    {
+        using namespace DPL::Colors::Html;
+        fprintf(
+            m_fp.Get(), "\n%sResults [%s]:%s\n", BOLD_GREEN_BEGIN,
+            name.c_str(), BOLD_GREEN_END);
+        fprintf(
+            m_fp.Get(), "%s%s%3zu%s\n", CYAN_BEGIN,
+            "Total tests:            ", stats.GetTotal(), CYAN_END);
+        fprintf(
+            m_fp.Get(), "  %s%s%3zu%s\n", CYAN_BEGIN,
+            "Succeeded:            ", stats.GetPassed(), CYAN_END);
+        fprintf(
+            m_fp.Get(), "  %s%s%3zu%s\n", CYAN_BEGIN,
+            "Failed:               ", stats.GetFailed(), CYAN_END);
+        fprintf(
+            m_fp.Get(), "  %s%s%3zu%s\n", CYAN_BEGIN,
+            "Ignored:              ", stats.GetIgnored(), CYAN_END);
+    }
+
+    std::string m_filename;
+    ScopedFClose m_fp;
+    Statistic m_stats;
+    std::string m_currentGroup;
+    std::map<std::string, Statistic> m_groupsStats;
+};
+
+TestResultsCollectorBase* HtmlCollector::Constructor()
+{
+    return new HtmlCollector();
+}
+
+class XmlCollector :
+    public TestResultsCollectorBase
+{
+  public:
+    static TestResultsCollectorBase* Constructor();
+
+  private:
+    XmlCollector() : m_filename(DEFAULT_XML_FILE_NAME) {}
+
+    virtual void CollectCurrentTestGroupName(const std::string& name)
+    {
+        std::size_t pos = GetCurrentGroupPosition();
+        if (std::string::npos != pos) {
+            GroupFinish(pos);
+            FlushOutput();
+            m_stats = Statistic();
+        }
+
+        pos = m_outputBuffer.find("</testsuites>");
+        if (std::string::npos == pos) {
+            ThrowMsg(DPL::Exception, "Could not find test suites closing tag");
+        }
+        GroupStart(pos, name);
+    }
+
+    void GroupStart(const std::size_t pos, const std::string& name)
+    {
+        std::stringstream groupHeader;
+        groupHeader << "\n\t<testsuite";
+        groupHeader << " name=\"" << EscapeSpecialCharacters(name) << "\"";
+        groupHeader << R"( tests="1")"; // include SegFault
+        groupHeader << R"( failures="1")"; // include SegFault
+        groupHeader << R"( skipped="0")";
+        groupHeader << ">";
+
+        groupHeader << "\n\t\t<testcase name=\"unknown\" status=\"FAILED\">";
+        groupHeader <<
+        "\n\t\t\t<failure type=\"FAILED\" message=\"segmentation fault\"/>";
+        groupHeader << "\n\t\t</testcase>";
+
+        groupHeader << "\n\t</testsuite>";
+
+        m_outputBuffer.insert(pos - 1, groupHeader.str());
+    }
+
+    virtual bool Configure()
+    {
+        m_fp.Reset(fopen(m_filename.c_str(), "w"));
+        if (!m_fp) {
+            LogPedantic("Could not open file " << m_filename << " for writing");
+            return false;
+        }
+        return true;
+    }
+
+    virtual std::string CollectorSpecificHelp() const
+    {
+        return "--file=<filename> - name of file for output\n"
+               "                    default - results.xml\n";
+    }
+
+    virtual void Start()
+    {
+        Assert(!!m_fp && "File handle must not be null");
+        m_outputBuffer.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
+        m_outputBuffer.append("<testsuites>\n</testsuites>");
+        FlushOutput();
+    }
+
+    virtual void Finish()
+    {
+        std::size_t pos = GetCurrentGroupPosition();
+        if (std::string::npos != pos) {
+            GroupFinish(pos);
+            FlushOutput();
+        }
+    }
+
+    virtual bool ParseCollectorSpecificArg(const std::string& arg)
+    {
+        return ParseCollectorFileArg(arg, m_filename);
+    }
+
+    virtual void CollectResult(const std::string& id,
+                               const std::string& /*description*/,
+                               const FailStatus::Type status = FailStatus::NONE,
+                               const std::string& reason = "",
+                               const bool& isPerformanceTest = false,
+                               const std::chrono::system_clock::duration& performanceTime = std::chrono::microseconds::zero(),
+                               const std::chrono::system_clock::duration& performanceMaxTime = std::chrono::microseconds::zero())
+    {
+        m_resultBuffer.erase();
+        m_resultBuffer.append("\t\t<testcase name=\"");
+        m_resultBuffer.append(EscapeSpecialCharacters(id));
+        m_resultBuffer.append("\"");
+        switch (status) {
+        case TestResultsCollectorBase::FailStatus::NONE:
+            if (isPerformanceTest) {
+                if (performanceMaxTime <= std::chrono::microseconds::zero()) {
+                    m_resultBuffer.append(" status=\"OK\" time=\"");
+                    std::ostringstream ostr;
+                    ostr << performanceTime.count();
+                    m_resultBuffer.append(ostr.str());
+                    m_resultBuffer.append("\"/>\n");
+                    break;
+                } else {
+                    m_resultBuffer.append(" status=\"OK\" time=\"");
+                    std::ostringstream ostr;
+                    ostr << performanceTime.count();
+                    m_resultBuffer.append(ostr.str());
+                    m_resultBuffer.append("\" time_expected=\"");
+                    ostr.str("");
+                    ostr << performanceMaxTime.count();
+                    m_resultBuffer.append(ostr.str());
+                    m_resultBuffer.append("\"/>\n");
+                    break;
+                }
+            }
+            m_resultBuffer.append(" status=\"OK\"/>\n");
+            break;
+        case TestResultsCollectorBase::FailStatus::FAILED:
+            m_resultBuffer.append(" status=\"FAILED\">\n");
+            PrintfErrorMessage("FAILED", EscapeSpecialCharacters(reason), true);
+            m_resultBuffer.append("\t\t</testcase>\n");
+            break;
+        case TestResultsCollectorBase::FailStatus::IGNORED:
+            m_resultBuffer.append(" status=\"Ignored\">\n");
+            PrintfIgnoredMessage("Ignored", EscapeSpecialCharacters(
+                                     reason), true);
+            m_resultBuffer.append("\t\t</testcase>\n");
+            break;
+        case TestResultsCollectorBase::FailStatus::INTERNAL:
+            m_resultBuffer.append(" status=\"FAILED\">\n");
+            PrintfErrorMessage("INTERNAL", EscapeSpecialCharacters(
+                                   reason), true);
+            m_resultBuffer.append("\t\t</testcase>");
+            break;
+        default:
+            Assert(false && "Bad status");
+        }
+        std::size_t group_pos = GetCurrentGroupPosition();
+        if (std::string::npos == group_pos) {
+            ThrowMsg(DPL::Exception, "No current group set");
+        }
+
+        std::size_t last_case_pos = m_outputBuffer.find(
+                "<testcase name=\"unknown\"",
+                group_pos);
+        if (std::string::npos == last_case_pos) {
+            ThrowMsg(DPL::Exception, "Could not find SegFault test case");
+        }
+        m_outputBuffer.insert(last_case_pos - 2, m_resultBuffer);
+
+        m_stats.AddTest(status);
+
+        UpdateGroupHeader(group_pos,
+                          m_stats.GetTotal() + 1, // include SegFault
+                          m_stats.GetFailed() + 1, // include SegFault
+                          m_stats.GetIgnored());
+        FlushOutput();
+    }
+
+    std::size_t GetCurrentGroupPosition() const
+    {
+        return m_outputBuffer.rfind("<testsuite ");
+    }
+
+    void UpdateGroupHeader(const std::size_t groupPosition,
+                           const unsigned int tests,
+                           const unsigned int failures,
+                           const unsigned int skipped)
+    {
+        UpdateElementAttribute(groupPosition, "tests", UIntToString(tests));
+        UpdateElementAttribute(groupPosition, "failures", UIntToString(failures));
+        UpdateElementAttribute(groupPosition, "skipped", UIntToString(skipped));
+    }
+
+    void UpdateElementAttribute(const std::size_t elementPosition,
+                                const std::string& name,
+                                const std::string& value)
+    {
+        std::string pattern = name + "=\"";
+
+        std::size_t start = m_outputBuffer.find(pattern, elementPosition);
+        if (std::string::npos == start) {
+            ThrowMsg(DPL::Exception,
+                     "Could not find attribute " << name << " beginning");
+        }
+
+        std::size_t end = m_outputBuffer.find("\"", start + pattern.length());
+        if (std::string::npos == end) {
+            ThrowMsg(DPL::Exception,
+                     "Could not find attribute " << name << " end");
+        }
+
+        m_outputBuffer.replace(start + pattern.length(),
+                               end - start - pattern.length(),
+                               value);
+    }
+
+    std::string UIntToString(const unsigned int value)
+    {
+        std::stringstream result;
+        result << value;
+        return result.str();
+    }
+
+    void GroupFinish(const std::size_t groupPosition)
+    {
+        std::size_t segFaultStart =
+            m_outputBuffer.find("<testcase name=\"unknown\"", groupPosition);
+        if (std::string::npos == segFaultStart) {
+            ThrowMsg(DPL::Exception,
+                     "Could not find SegFault test case start position");
+        }
+        segFaultStart -= 2; // to erase tabs
+
+        std::string closeTag = "</testcase>";
+        std::size_t segFaultEnd = m_outputBuffer.find(closeTag, segFaultStart);
+        if (std::string::npos == segFaultEnd) {
+            ThrowMsg(DPL::Exception,
+                     "Could not find SegFault test case end position");
+        }
+        segFaultEnd += closeTag.length() + 1; // to erase new line
+
+        m_outputBuffer.erase(segFaultStart, segFaultEnd - segFaultStart);
+
+        UpdateGroupHeader(groupPosition,
+                          m_stats.GetTotal(),
+                          m_stats.GetFailed(),
+                          m_stats.GetIgnored());
+    }
+
+    void FlushOutput()
+    {
+        int fd = fileno(m_fp.Get());
+        if (-1 == fd) {
+            const char* errStr = strerror(errno);
+            ThrowMsg(DPL::Exception, errStr);
+        }
+
+        if (-1 == TEMP_FAILURE_RETRY(ftruncate(fd, 0L))) {
+            const char* errStr = strerror(errno);
+            ThrowMsg(DPL::Exception, errStr);
+        }
+
+        if (-1 == TEMP_FAILURE_RETRY(fseek(m_fp.Get(), 0L, SEEK_SET))) {
+            const char* errStr = strerror(errno);
+            ThrowMsg(DPL::Exception, errStr);
+        }
+
+        if (m_outputBuffer.size() !=
+            fwrite(m_outputBuffer.c_str(), 1, m_outputBuffer.size(),
+                   m_fp.Get()))
+        {
+            const char* errStr = strerror(errno);
+            ThrowMsg(DPL::Exception, errStr);
+        }
+
+        if (-1 == TEMP_FAILURE_RETRY(fflush(m_fp.Get()))) {
+            const char* errStr = strerror(errno);
+            ThrowMsg(DPL::Exception, errStr);
+        }
+    }
+
+    void PrintfErrorMessage(const char* type,
+                            const std::string& message,
+                            bool verbosity)
+    {
+        if (verbosity) {
+            m_resultBuffer.append("\t\t\t<failure type=\"");
+            m_resultBuffer.append(EscapeSpecialCharacters(type));
+            m_resultBuffer.append("\" message=\"");
+            m_resultBuffer.append(EscapeSpecialCharacters(message));
+            m_resultBuffer.append("\"/>\n");
+        } else {
+            m_resultBuffer.append("\t\t\t<failure type=\"");
+            m_resultBuffer.append(EscapeSpecialCharacters(type));
+            m_resultBuffer.append("\"/>\n");
+        }
+    }
+
+    void PrintfIgnoredMessage(const char* type,
+                              const std::string& message,
+                              bool verbosity)
+    {
+        if (verbosity) {
+            m_resultBuffer.append("\t\t\t<skipped type=\"");
+            m_resultBuffer.append(EscapeSpecialCharacters(type));
+            m_resultBuffer.append("\" message=\"");
+            m_resultBuffer.append(EscapeSpecialCharacters(message));
+            m_resultBuffer.append("\"/>\n");
+        } else {
+            m_resultBuffer.append("\t\t\t<skipped type=\"");
+            m_resultBuffer.append(EscapeSpecialCharacters(type));
+            m_resultBuffer.append("\"/>\n");
+        }
+    }
+
+    std::string EscapeSpecialCharacters(std::string s)
+    {
+        for (unsigned int i = 0; i < s.size();) {
+            switch (s[i]) {
+            case '"':
+                s.erase(i, 1);
+                s.insert(i, "&quot;");
+                i += 6;
+                break;
+
+            case '&':
+                s.erase(i, 1);
+                s.insert(i, "&amp;");
+                i += 5;
+                break;
+
+            case '<':
+                s.erase(i, 1);
+                s.insert(i, "&lt;");
+                i += 4;
+                break;
+
+            case '>':
+                s.erase(i, 1);
+                s.insert(i, "&gt;");
+                i += 4;
+                break;
+
+            case '\'':
+                s.erase(i, 1);
+                s.insert(i, "&#39;");
+                i += 5;
+                break;
+            default:
+                ++i;
+                break;
+            }
+        }
+        return s;
+    }
+
+    std::string m_filename;
+    ScopedFClose m_fp;
+    Statistic m_stats;
+    std::string m_outputBuffer;
+    std::string m_resultBuffer;
+};
+
+TestResultsCollectorBase* XmlCollector::Constructor()
+{
+    return new XmlCollector();
+}
+
+class CSVCollector :
+    public TestResultsCollectorBase
+{
+  public:
+    static TestResultsCollectorBase* Constructor();
+
+  private:
+    CSVCollector() {}
+
+    virtual void Start()
+    {
+        printf("GROUP;ID;RESULT;REASON;ELAPSED [s];EXPECTED [s]\n");
+    }
+
+    virtual void CollectCurrentTestGroupName(const std::string& name)
+    {
+        m_currentGroup = name;
+    }
+
+    virtual void CollectResult(const std::string& id,
+                               const std::string& /*description*/,
+                               const FailStatus::Type status = FailStatus::NONE,
+                               const std::string& reason = "",
+                               const bool& isPerformanceTest = false,
+                               const std::chrono::system_clock::duration& performanceTime = std::chrono::microseconds::zero(),
+                               const std::chrono::system_clock::duration& performanceMaxTime = std::chrono::microseconds::zero())
+    {
+        std::string statusMsg = "";
+        switch (status) {
+        case TestResultsCollectorBase::FailStatus::NONE:
+            statusMsg = "OK";
+            if (isPerformanceTest) {
+                statusMsg.append(";;");
+                std::ostringstream ostr;
+                ostr << performanceTime.count();
+                statusMsg.append(ostr.str());
+                if (performanceMaxTime <= std::chrono::microseconds::zero()) {
+                    statusMsg.append(";");
+                    ostr.str("");
+                    ostr << performanceMaxTime.count();
+                    statusMsg.append(ostr.str());
+                }
+            }
+            break;
+        case TestResultsCollectorBase::FailStatus::FAILED: statusMsg = "FAILED";
+            break;
+        case TestResultsCollectorBase::FailStatus::IGNORED: statusMsg =
+            "IGNORED";
+            break;
+        case TestResultsCollectorBase::FailStatus::INTERNAL: statusMsg =
+            "FAILED";
+            break;
+        default:
+            Assert(false && "Bad status");
+        }
+        printf("%s;%s;%s;%s\n",
+               m_currentGroup.c_str(),
+               id.c_str(),
+               statusMsg.c_str(),
+               reason.c_str());
+    }
+
+    std::string m_currentGroup;
+};
+
+TestResultsCollectorBase* CSVCollector::Constructor()
+{
+    return new CSVCollector();
+}
+}
+
+class TAPCollector :
+    public TestResultsCollectorBase
+{
+  public:
+    static TestResultsCollectorBase* Constructor();
+
+  private:
+    TAPCollector() : m_filename(DEFAULT_TAP_FILE_NAME)  {}
+
+    virtual bool Configure()
+    {
+        m_output.open(m_filename.c_str(), std::ios_base::trunc);
+        if (m_output.fail()) {
+            LogError("Can't open output file: " << m_filename);
+            return false;
+        }
+        return true;
+    }
+    virtual std::string CollectorSpecificHelp() const
+    {
+        std::string retVal = "--file=<filename> - name of file for output\n"
+                             "                    default - ";
+        retVal += DEFAULT_TAP_FILE_NAME;
+        retVal += "\n";
+        return retVal;
+    }
+
+    virtual void Start()
+    {
+        Assert(m_output.good() && "Output file must be opened.");
+        m_output << "TAP version 13" << std::endl;
+        m_testIndex = 0;
+    }
+
+    virtual void Finish()
+    {
+        m_output << "1.." << m_testIndex << std::endl;
+        m_output << m_collectedData.rdbuf();
+        m_output.close();
+    }
+
+    virtual bool ParseCollectorSpecificArg(const std::string& arg)
+    {
+        return ParseCollectorFileArg(arg, m_filename);
+    }
+
+    virtual void CollectResult(const std::string& id,
+                               const std::string& description,
+                               const FailStatus::Type status = FailStatus::NONE,
+                               const std::string& reason = "",
+                               const bool& isPerformanceTest = false,
+                               const std::chrono::system_clock::duration& performanceTime = std::chrono::microseconds::zero(),
+                               const std::chrono::system_clock::duration& performanceMaxTime = std::chrono::microseconds::zero())
+    {
+        /* Remove unused variable warning */
+        DPL_UNUSED_PARAM(isPerformanceTest);
+        DPL_UNUSED_PARAM(performanceTime);
+        DPL_UNUSED_PARAM(performanceMaxTime);
+
+        m_testIndex++;
+        switch (status) {
+        case TestResultsCollectorBase::FailStatus::NONE:
+            LogBasicTAP(true, id, description);
+            endTAPLine();
+            break;
+        case TestResultsCollectorBase::FailStatus::FAILED:
+            LogBasicTAP(false, id, description);
+            endTAPLine();
+            break;
+        case TestResultsCollectorBase::FailStatus::IGNORED:
+            LogBasicTAP(true, id, description);
+            m_collectedData << " # skip " << reason;
+            endTAPLine();
+            break;
+        case TestResultsCollectorBase::FailStatus::INTERNAL:
+            LogBasicTAP(true, id, description);
+            endTAPLine();
+            m_collectedData << "    ---" << std::endl;
+            m_collectedData << "    message: " << reason << std::endl;
+            m_collectedData << "    severity: Internal" << std::endl;
+            m_collectedData << "    ..." << std::endl;
+            break;
+        default:
+            Assert(false && "Bad status");
+        }
+    }
+
+    void LogBasicTAP(bool isOK, const std::string& id,
+                     const std::string& description)
+    {
+        if (!isOK) {
+            m_collectedData << "not ";
+        }
+        m_collectedData << "ok " << m_testIndex << " [" <<
+        id << "] " << description;
+    }
+
+    void endTAPLine()
+    {
+        m_collectedData << std::endl;
+    }
+
+    std::string m_filename;
+    std::stringstream m_collectedData;
+    std::ofstream m_output;
+    int m_testIndex;
+};
+
+TestResultsCollectorBase* TAPCollector::Constructor()
+{
+    return new TAPCollector();
+}
+
+void TestResultsCollectorBase::RegisterCollectorConstructor(
+    const std::string& name,
+    TestResultsCollectorBase::CollectorConstructorFunc func)
+{
+    Assert(m_constructorsMap.find(name) == m_constructorsMap.end());
+    m_constructorsMap[name] = func;
+}
+
+TestResultsCollectorBase* TestResultsCollectorBase::Create(
+    const std::string& name)
+{
+    ConstructorsMap::iterator found = m_constructorsMap.find(name);
+    if (found != m_constructorsMap.end()) {
+        return found->second();
+    } else {
+        return NULL;
+    }
+}
+
+std::vector<std::string> TestResultsCollectorBase::GetCollectorsNames()
+{
+    std::vector<std::string> list;
+    for (auto &constructor : m_constructorsMap)
+    {
+        list.push_back(constructor.first);
+    }
+    return list;
+}
+
+TestResultsCollectorBase::ConstructorsMap TestResultsCollectorBase::
+    m_constructorsMap;
+
+namespace {
+static int RegisterCollectorConstructors();
+static const int RegisterHelperVariable = RegisterCollectorConstructors();
+int RegisterCollectorConstructors()
+{
+    (void)RegisterHelperVariable;
+
+    TestResultsCollectorBase::RegisterCollectorConstructor(
+        "text",
+        &ConsoleCollector::Constructor);
+    TestResultsCollectorBase::RegisterCollectorConstructor(
+        "html",
+        &HtmlCollector::Constructor);
+    TestResultsCollectorBase::RegisterCollectorConstructor(
+        "csv",
+        &CSVCollector::Constructor);
+    TestResultsCollectorBase::RegisterCollectorConstructor(
+        "tap",
+        &TAPCollector::Constructor);
+    TestResultsCollectorBase::RegisterCollectorConstructor(
+        "xml",
+        &XmlCollector::Constructor);
+
+    return 0;
+}
+}
+}
+}
+#undef GREEN_RESULT_OK
diff --git a/tests/framework/src/test_runner.cpp b/tests/framework/src/test_runner.cpp
new file mode 100644 (file)
index 0000000..ee316e2
--- /dev/null
@@ -0,0 +1,767 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        test_runner.cpp
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @author      Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of test runner
+ */
+#include <stddef.h>
+#include <dpl/test/test_runner.h>
+#include <dpl/test/test_results_collector.h>
+#include <dpl/exception.h>
+#include <dpl/scoped_free.h>
+#include <dpl/log/log.h>
+#include <dpl/colors.h>
+#include <pcrecpp.h>
+#include <algorithm>
+#include <cstdio>
+#include <memory.h>
+#include <libgen.h>
+#include <cstring>
+#include <cstdlib>
+
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+#include <dpl/singleton_impl.h>
+IMPLEMENT_SINGLETON(DPL::Test::TestRunner)
+
+namespace {
+
+std::string getXMLNode(xmlNodePtr node)
+{
+    std::string ret;
+    xmlChar * value = xmlNodeGetContent(node);
+    ret = std::string(reinterpret_cast<char*>(value));
+    xmlFree(value);
+    return ret;
+}
+
+}
+
+
+namespace DPL {
+namespace Test {
+namespace // anonymous
+{
+std::string BaseName(std::string aPath)
+{
+    ScopedFree<char> path(strdup(aPath.c_str()));
+    if (NULL == path.Get()) {
+        throw std::bad_alloc();
+    }
+    char* baseName = basename(path.Get());
+    std::string retValue = baseName;
+    return retValue;
+}
+} // namespace anonymous
+
+//! \brief Failed test message creator
+//!
+//! \param[in] aTest string for tested expression
+//! \param[in] aFile source file name
+//! \param[in] aLine source file line
+//! \param[in] aMessage error message
+TestRunner::TestFailed::TestFailed(const char* aTest,
+                                   const char* aFile,
+                                   int aLine,
+                                   const std::string &aMessage)
+{
+    std::ostringstream assertMsg;
+    assertMsg << "[" << BaseName(aFile) << ":" << aLine
+              << "] Assertion failed ("
+              << aTest << ") " << aMessage;
+    m_message = assertMsg.str();
+}
+
+TestRunner::TestFailed::TestFailed(const std::string &message)
+{
+    m_message = message;
+}
+
+void TestRunner::RegisterTest(const char *testName, TestCase proc)
+{
+    m_testGroups[m_currentGroup].push_back(TestCaseStruct(testName, proc));
+}
+
+void TestRunner::InitGroup(const char* name)
+{
+    m_currentGroup = name;
+}
+
+void TestRunner::normalizeXMLTag(std::string& str, const std::string& testcase)
+{
+    //Add testcase if missing
+    std::string::size_type pos = str.find(testcase);
+    if(pos != 0)
+    {
+        str = testcase + "_" + str;
+    }
+
+    //dpl test runner cannot have '-' character in name so it have to be replaced
+    // for TCT case to make comparision works
+    std::replace(str.begin(), str.end(), '-', '_');
+}
+
+bool TestRunner::filterGroupsByXmls(const std::vector<std::string> & files)
+{
+    DECLARE_EXCEPTION_TYPE(DPL::Exception, XMLError)
+
+    const std::string idPath = "/test_definition/suite/set/testcase/@id";
+
+    bool success = true;
+    std::map<std::string, bool> casesMap;
+
+    std::string testsuite;
+    if(!m_testGroups.empty())
+    {
+        for(TestCaseGroupMap::const_iterator cit = m_testGroups.begin(); cit != m_testGroups.end(); ++cit)
+        {
+            if(!cit->second.empty())
+            {
+                for(TestCaseStructList::const_iterator cj = cit->second.begin(); cj != cit->second.end(); ++cj)
+                {
+                    std::string name = cj->name;
+                    std::string::size_type st = name.find('_');
+                    if(st != std::string::npos)
+                    {
+                        name = name.substr(0, st);
+                        testsuite = name;
+                        break;
+                    }
+                }
+                if(!testsuite.empty()) break;
+            }
+        }
+    }
+
+    xmlInitParser();
+    LIBXML_TEST_VERSION
+    xmlXPathInit();
+
+    Try
+    {
+        for (const std::string &file : files)
+        {
+            xmlDocPtr doc;
+            xmlXPathContextPtr xpathCtx;
+
+            doc = xmlReadFile(file.c_str(), NULL, 0);
+            if (doc == NULL) {
+                ThrowMsg(XMLError, "File Problem");
+            } else {
+                //context
+                xpathCtx = xmlXPathNewContext(doc);
+                if (xpathCtx == NULL) {
+                    ThrowMsg(XMLError,
+                             "Error: unable to create new XPath context\n");
+                }
+                xpathCtx->node = xmlDocGetRootElement(doc);
+            }
+
+            std::string result;
+            xmlXPathObjectPtr xpathObject;
+            //get requested node's values
+            xpathObject = xmlXPathEvalExpression(BAD_CAST idPath.c_str(), xpathCtx);
+            if (xpathObject == NULL)
+            {
+                ThrowMsg(XMLError, "XPath evaluation failure: " << idPath);
+            }
+            xmlNodeSetPtr nodes = xpathObject->nodesetval;
+            unsigned size = (nodes) ? nodes->nodeNr : 0;
+            LogDebug("Found " << size << " nodes matching xpath");
+            for(unsigned i = 0; i < size; ++i)
+            {
+                LogPedantic("Type: " << nodes->nodeTab[i]->type);
+                if (nodes->nodeTab[i]->type == XML_ATTRIBUTE_NODE) {
+                    xmlNodePtr curNode = nodes->nodeTab[i];
+                    result = getXMLNode(curNode);
+                    LogPedantic("Result: " << result);
+                    normalizeXMLTag(result, testsuite);
+                    casesMap.insert(make_pair(result, false));
+                }
+            }
+            //Cleanup of XPath data
+            xmlXPathFreeObject(xpathObject);
+            xmlXPathFreeContext(xpathCtx);
+            xmlFreeDoc(doc);
+        }
+    }
+    Catch(XMLError)
+    {
+        LogError("Libxml error: " << _rethrown_exception.DumpToString());
+        success = false;
+    }
+    xmlCleanupParser();
+
+    if(!filterByXML(casesMap))
+    {
+        success = false;
+    }
+
+    return success;
+}
+
+bool TestRunner::filterByXML(std::map<std::string, bool> & casesMap)
+{
+    for (auto &group : m_testGroups) {
+        TestCaseStructList newList;
+        for (auto &tc : group.second)
+        {
+            if (casesMap.find(tc.name) != casesMap.end()) {
+                casesMap[tc.name] = true;
+                newList.push_back(tc);
+            }
+        }
+        group.second = newList;
+    }
+    for (auto &cs : casesMap)
+    {
+        if(cs.second == false)
+        {
+            LogError("Cannot find testcase from XML file: " << cs.first);
+            return false;
+        }
+    }
+    return true;
+}
+
+TestRunner::Status TestRunner::RunTestCase(const TestCaseStruct& testCase)
+{
+    setCurrentTestCase(&(const_cast<TestCaseStruct &>(testCase)));
+    try {
+        testCase.proc();
+    } catch (const TestFailed &e) {
+        // Simple test failure
+        CollectResult(testCase.name,
+                      "",
+                      TestResultsCollectorBase::FailStatus::FAILED,
+                      e.GetMessage());
+
+        setCurrentTestCase(NULL);
+        return FAILED;
+    } catch (const Ignored &e) {
+        if (m_runIgnored) {
+            // Simple test have to be implemented
+            CollectResult(testCase.name,
+                          "",
+                          TestResultsCollectorBase::FailStatus::IGNORED,
+                          e.GetMessage());
+        }
+
+        setCurrentTestCase(NULL);
+        return IGNORED;
+    } catch (const DPL::Exception &e) {
+        // DPL exception failure
+        CollectResult(testCase.name,
+                      "",
+                      TestResultsCollectorBase::FailStatus::INTERNAL,
+                      "DPL exception:" + e.GetMessage());
+
+        setCurrentTestCase(NULL);
+        return FAILED;
+    } catch (const std::exception &) {
+        // std exception failure
+        CollectResult(testCase.name,
+                      "",
+                      TestResultsCollectorBase::FailStatus::INTERNAL,
+                      "std exception");
+
+        setCurrentTestCase(NULL);
+        return FAILED;
+    } catch (...) {
+        // Unknown exception failure
+        CollectResult(testCase.name,
+                      "",
+                      TestResultsCollectorBase::FailStatus::INTERNAL,
+                      "unknown exception");
+
+        setCurrentTestCase(NULL);
+        return FAILED;
+    }
+
+    CollectResult(testCase.name,
+                  "",
+                  TestResultsCollectorBase::FailStatus::NONE,
+                  "",
+                  testCase.m_isPerformanceTest,
+                  testCase.m_performanceTestDurationTime,
+                  testCase.m_performanceMaxTime);
+    setCurrentTestCase(NULL);
+
+    // Everything OK
+    return PASS;
+}
+
+void TestRunner::RunTests()
+{
+    using namespace DPL::Colors::Text;
+
+    Banner();
+    for (auto &collector : m_collectors) {
+        collector.second->Start();
+    }
+
+    unsigned count = 0;
+    for (auto &group : m_testGroups) {
+        count += group.second.size();
+    }
+    fprintf(stderr, "%sFound %d testcases...%s\n", GREEN_BEGIN, count, GREEN_END);
+    fprintf(stderr, "%s%s%s\n", GREEN_BEGIN, "Running tests...", GREEN_END);
+    for (auto &group : m_testGroups) {
+        TestCaseStructList list = group.second;
+        if (!list.empty()) {
+            for (auto &collector : m_collectors) {
+                collector.second->CollectCurrentTestGroupName(group.first);
+            }
+            list.sort();
+
+            for (TestCaseStructList::const_iterator iterator = list.begin();
+                 iterator != list.end();
+                 ++iterator)
+            {
+                TestCaseStruct test = *iterator;
+                if (m_startTestId == test.name) {
+                    m_startTestId = "";
+                }
+
+                if (m_startTestId.empty()) {
+                    RunTestCase(test);
+                }
+                if (m_terminate == true) {
+                    // Terminate quietly without any logs
+                    return;
+                }
+            }
+        }
+    }
+
+    std::for_each(m_collectors.begin(),
+                  m_collectors.end(),
+                  [] (const TestResultsCollectors::value_type & collector)
+                  {
+                      collector.second->Finish();
+                  });
+
+    // Finished
+    fprintf(stderr, "%s%s%s\n\n", GREEN_BEGIN, "Finished", GREEN_END);
+}
+
+TestRunner::TestCaseStruct *TestRunner::getCurrentTestCase()
+{
+    return m_currentTestCase;
+}
+
+void TestRunner::setCurrentTestCase(TestCaseStruct* testCase)
+{
+    m_currentTestCase = testCase;
+}
+
+void TestRunner::beginPerformanceTestTime(std::chrono::system_clock::duration maxTimeInMicroseconds)
+{
+    TestCaseStruct* testCase = getCurrentTestCase();
+    if (!testCase)
+        return;
+
+    testCase->m_isPerformanceTest = true;
+    testCase->m_performanceMaxTime = maxTimeInMicroseconds;
+    testCase->m_performanceTestStartTime = std::chrono::system_clock::now();
+
+    // Set result to 0 microseconds. Display 0ms result when end macro is missing.
+    testCase->m_performanceTestDurationTime = std::chrono::microseconds::zero();
+}
+
+void TestRunner::endPerformanceTestTime()
+{
+    TestCaseStruct* testCase = getCurrentTestCase();
+    if (!testCase)
+        return;
+
+    testCase->m_performanceTestDurationTime = std::chrono::system_clock::now() -
+            testCase->m_performanceTestStartTime;
+}
+
+void TestRunner::getCurrentTestCasePerformanceResult(bool& isPerformanceTest,
+                                                     std::chrono::system_clock::duration& result,
+                                                     std::chrono::system_clock::duration& resultMax)
+{
+    TestCaseStruct* testCase = getCurrentTestCase();
+    if (!testCase || !(testCase->m_isPerformanceTest)){
+        isPerformanceTest = false;
+        return;
+    }
+
+    isPerformanceTest = testCase->m_isPerformanceTest;
+    result = testCase->m_performanceTestDurationTime;
+    resultMax = testCase->m_performanceMaxTime;
+}
+
+void TestRunner::setCurrentTestCasePerformanceResult(bool isPerformanceTest,
+                                                     std::chrono::system_clock::duration result,
+                                                     std::chrono::system_clock::duration resultMax)
+{
+    TestCaseStruct* testCase = getCurrentTestCase();
+    if (!testCase)
+        return;
+
+    testCase->m_isPerformanceTest = isPerformanceTest;
+    testCase->m_performanceTestDurationTime = result;
+    testCase->m_performanceMaxTime = resultMax;
+}
+
+
+void TestRunner::CollectResult(
+    const std::string& id,
+    const std::string& description,
+    const TestResultsCollectorBase::FailStatus::Type status,
+    const std::string& reason,
+    const bool& isPerformanceTest,
+    const std::chrono::system_clock::duration& performanceTestDurationTime,
+    const std::chrono::system_clock::duration& performanceMaxTime)
+{
+    std::for_each(m_collectors.begin(),
+                  m_collectors.end(),
+                  [&](const TestResultsCollectors::value_type & collector)
+                  {
+                      collector.second->CollectResult(id,
+                                                      description,
+                                                      status,
+                                                      reason,
+                                                      isPerformanceTest,
+                                                      performanceTestDurationTime,
+                                                      performanceMaxTime);
+                  });
+}
+
+void TestRunner::Banner()
+{
+    using namespace DPL::Colors::Text;
+    fprintf(stderr,
+            "%s%s%s\n",
+            BOLD_GREEN_BEGIN,
+            "DPL tests runner",
+            BOLD_GREEN_END);
+    fprintf(stderr,
+            "%s%s%s%s\n\n",
+            GREEN_BEGIN,
+            "Build: ",
+            __TIMESTAMP__,
+            GREEN_END);
+}
+
+void TestRunner::InvalidArgs(const std::string& message)
+{
+    using namespace DPL::Colors::Text;
+    fprintf(stderr,
+            "%s%s%s\n",
+            BOLD_RED_BEGIN,
+            message.c_str(),
+            BOLD_RED_END);
+}
+
+void TestRunner::Usage()
+{
+    fprintf(stderr, "Usage: runner [options]\n\n");
+    fprintf(stderr, "Output type:\n");
+    fprintf(stderr, "  --output=<output type> --output=<output type> ...\n");
+    fprintf(stderr, "\n  possible output types:\n");
+    for (std::string &type : TestResultsCollectorBase::GetCollectorsNames()) {
+        fprintf(stderr, "    --output=%s\n", type.c_str());
+    }
+    fprintf(stderr, "\n  example:\n");
+    fprintf(stderr,
+            "    test-binary --output=text --output=xml --file=output.xml\n\n");
+    fprintf(stderr, "Other parameters:\n");
+    fprintf(stderr,
+            "  --regexp='regexp'\t Only selected tests"
+            " which names match regexp run\n\n");
+    fprintf(stderr, "  --start=<test id>\tStart from concrete test id");
+    fprintf(stderr, "  --group=<group name>\t Run tests only from one group\n");
+    fprintf(stderr, "  --runignored\t Run also ignored tests\n");
+    fprintf(stderr, "  --list\t Show a list of Test IDs\n");
+    fprintf(stderr, "  --listgroups\t Show a list of Test Group names \n");
+    fprintf(stderr, "  --only-from-xml=<xml file>\t Run only testcases specified in XML file \n"
+                    "       XML name is taken from attribute id=\"part1_part2\" as whole.\n"
+                    "       If part1 is not found (no _) then it is implicitily "
+                           "set according to suite part1 from binary tests\n");
+    fprintf(
+        stderr,
+        "  --listingroup=<group name>\t Show a list of Test IDS in one group\n");
+    fprintf(stderr, "  --allowchildlogs\t Allow to print logs from child process on screen.\n");
+    fprintf(stderr, "       When active child process will be able to print logs on stdout and stderr.\n");
+    fprintf(stderr, "       Both descriptors will be closed after test.\n");
+    fprintf(stderr, "  --help\t This help\n\n");
+    std::for_each(m_collectors.begin(),
+                  m_collectors.end(),
+                  [] (const TestResultsCollectors::value_type & collector)
+                  {
+                      fprintf(stderr,
+                              "Output %s has specific args:\n",
+                              collector.first.c_str());
+                      fprintf(stderr,
+                              "%s\n",
+                              collector.second->
+                                  CollectorSpecificHelp().c_str());
+                  });
+    fprintf(stderr, "For bug reporting, please write to:\n");
+    fprintf(stderr, "<p.dobrowolsk@samsung.com>\n");
+}
+
+int TestRunner::ExecTestRunner(int argc, char *argv[])
+{
+    std::vector<std::string> args;
+    for (int i = 0; i < argc; ++i) {
+        args.push_back(argv[i]);
+    }
+    return ExecTestRunner(args);
+}
+
+void TestRunner::MarkAssertion()
+{
+    ++m_totalAssertions;
+}
+
+int TestRunner::ExecTestRunner(ArgsList args)
+{
+    m_runIgnored = false;
+    // Parse command line
+    if (args.size() == 1) {
+        InvalidArgs();
+        Usage();
+        return -1;
+    }
+
+    args.erase(args.begin());
+
+    bool showHelp = false;
+    bool justList = false;
+    std::vector<std::string> xmlFiles;
+
+    TestResultsCollectorBasePtr currentCollector;
+
+    // Parse each argument
+    for(std::string &arg : args)
+    {
+        const std::string regexp = "--regexp=";
+        const std::string output = "--output=";
+        const std::string groupId = "--group=";
+        const std::string runIgnored = "--runignored";
+        const std::string listCmd = "--list";
+        const std::string startCmd = "--start=";
+        const std::string listGroupsCmd = "--listgroups";
+        const std::string listInGroup = "--listingroup=";
+        const std::string allowChildLogs = "--allowchildlogs";
+        const std::string onlyFromXML = "--only-from-xml=";
+
+        if (currentCollector) {
+            if (currentCollector->ParseCollectorSpecificArg(arg)) {
+                continue;
+            }
+        }
+
+        if (arg.find(startCmd) == 0) {
+            arg.erase(0, startCmd.length());
+            for (auto &group : m_testGroups) {
+                for (auto &tc : group.second) {
+                    if (tc.name == arg) {
+                        m_startTestId = arg;
+                        break;
+                    }
+                }
+                if (!m_startTestId.empty()) {
+                    break;
+                }
+            }
+            if (!m_startTestId.empty()) {
+                continue;
+            }
+            InvalidArgs();
+            fprintf(stderr, "Start test id has not been found\n");
+            Usage();
+            return 0;
+        } else if (arg.find(groupId) == 0) {
+            arg.erase(0, groupId.length());
+            TestCaseGroupMap::iterator found = m_testGroups.find(arg);
+            if (found != m_testGroups.end()) {
+                std::string name = found->first;
+                TestCaseStructList newList = found->second;
+                m_testGroups.clear();
+                m_testGroups[name] = newList;
+            } else {
+                fprintf(stderr, "Group %s not found\n", arg.c_str());
+                InvalidArgs();
+                Usage();
+                return -1;
+            }
+        } else if (arg == runIgnored) {
+            m_runIgnored = true;
+        } else if (arg == listCmd) {
+            justList = true;
+        } else if (arg == listGroupsCmd) {
+            for (auto &group : m_testGroups) {
+                printf("GR:%s\n", group.first.c_str());
+            }
+            return 0;
+        } else if (arg.find(listInGroup) == 0) {
+            arg.erase(0, listInGroup.length());
+            for (auto &test : m_testGroups[arg]) {
+                printf("ID:%s\n", test.name.c_str());
+            }
+            return 0;
+        } else if (arg.find(allowChildLogs) == 0) {
+            arg.erase(0, allowChildLogs.length());
+            m_allowChildLogs = true;
+        } else if (arg == "--help") {
+            showHelp = true;
+        } else if (arg.find(output) == 0) {
+            arg.erase(0, output.length());
+            if (m_collectors.find(arg) != m_collectors.end()) {
+                InvalidArgs(
+                    "Multiple outputs of the same type are not supported!");
+                Usage();
+                return -1;
+            }
+            currentCollector.reset(TestResultsCollectorBase::Create(arg));
+            if (!currentCollector) {
+                InvalidArgs("Unsupported output type!");
+                Usage();
+                return -1;
+            }
+            m_collectors[arg] = currentCollector;
+        } else if (arg.find(regexp) == 0) {
+            arg.erase(0, regexp.length());
+            if (arg.length() == 0) {
+                InvalidArgs();
+                Usage();
+                return -1;
+            }
+
+            if (arg[0] == '\'' && arg[arg.length() - 1] == '\'') {
+                arg.erase(0);
+                arg.erase(arg.length() - 1);
+            }
+
+            if (arg.length() == 0) {
+                InvalidArgs();
+                Usage();
+                return -1;
+            }
+
+            pcrecpp::RE re(arg.c_str());
+            for (auto &group : m_testGroups) {
+                TestCaseStructList newList;
+                for (auto &tc : group.second)
+                {
+                    if (re.PartialMatch(tc.name)) {
+                        newList.push_back(tc);
+                    }
+                }
+                group.second = newList;
+            }
+        } else if(arg.find(onlyFromXML) == 0) {
+            arg.erase(0, onlyFromXML.length());
+            if (arg.length() == 0) {
+                InvalidArgs();
+                Usage();
+                return -1;
+            }
+
+            if (arg[0] == '\'' && arg[arg.length() - 1] == '\'') {
+                arg.erase(0);
+                arg.erase(arg.length() - 1);
+            }
+
+            if (arg.length() == 0) {
+                InvalidArgs();
+                Usage();
+                return -1;
+            }
+
+            xmlFiles.push_back(arg);
+        } else {
+            InvalidArgs();
+            Usage();
+            return -1;
+        }
+    }
+
+    if(!xmlFiles.empty())
+    {
+        if(!filterGroupsByXmls(xmlFiles))
+        {
+            fprintf(stderr, "XML file is not correct\n");
+            return 0;
+        }
+    }
+
+    if(justList)
+    {
+        for (auto &group : m_testGroups) {
+            for (auto &tc : group.second) {
+                printf("ID:%s:%s\n", group.first.c_str(), tc.name.c_str());
+            }
+        }
+        return 0;
+    }
+
+    currentCollector.reset();
+
+    // Show help
+    if (showHelp) {
+        Usage();
+        return 0;
+    }
+
+    if (m_collectors.empty()) {
+        TestResultsCollectorBasePtr collector(
+            TestResultsCollectorBase::Create("text"));
+        m_collectors["text"] = collector;
+    }
+
+    for (auto &collector : m_collectors) {
+        if (!collector.second->Configure()) {
+            fprintf(stderr, "Could not configure selected output");
+            return 0;
+        }
+    }
+
+    // Run tests
+    RunTests();
+
+    return 0;
+}
+
+bool TestRunner::getRunIgnored() const
+{
+    return m_runIgnored;
+}
+
+void TestRunner::Terminate()
+{
+    m_terminate = true;
+}
+
+bool TestRunner::GetAllowChildLogs()
+{
+    return m_allowChildLogs;
+}
+
+}
+} // namespace DPL
diff --git a/tests/framework/src/test_runner_child.cpp b/tests/framework/src/test_runner_child.cpp
new file mode 100644 (file)
index 0000000..19ed08c
--- /dev/null
@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        test_runner_child.cpp
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of test runner
+ */
+#include <stddef.h>
+#include <dpl/test/test_runner.h>
+#include <dpl/test/test_runner_child.h>
+#include <dpl/test/test_results_collector.h>
+#include <dpl/binary_queue.h>
+#include <dpl/exception.h>
+#include <dpl/scoped_free.h>
+#include <dpl/colors.h>
+#include <pcrecpp.h>
+#include <algorithm>
+#include <cstdio>
+#include <memory.h>
+#include <libgen.h>
+#include <cstring>
+#include <cstdlib>
+#include <ctime>
+#include <unistd.h>
+#include <poll.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+
+namespace {
+const int CHILD_TEST_FAIL    = 0;
+const int CHILD_TEST_PASS    = 1;
+const int CHILD_TEST_IGNORED = 2;
+
+const int MSG_TYPE_MESSAGE   = 0; // sizeof(Message) + Message
+const int MSG_TYPE_PERF_TIME = 1; // perfTime + maxTime
+
+int closeOutput() {
+    int devnull;
+    int retcode = -1;
+    if (-1 == (devnull = TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY))))
+        return -1;
+
+    // replace stdout with /dev/null
+    if (-1 == TEMP_FAILURE_RETRY(dup2(devnull, STDOUT_FILENO)))
+        goto end;
+
+    // replace stderr with /dev/null
+    if (-1 == TEMP_FAILURE_RETRY(dup2(devnull, STDERR_FILENO)))
+        goto end;
+
+    retcode = 0;
+
+end:
+    close(devnull);
+    return retcode;
+}
+
+} // namespace anonymous
+
+namespace DPL {
+namespace Test {
+
+PipeWrapper::PipeWrapper()
+{
+    if (-1 == pipe(m_pipefd)) {
+        m_pipefd[0] = PIPE_CLOSED;
+        m_pipefd[1] = PIPE_CLOSED;
+    }
+}
+
+PipeWrapper::~PipeWrapper()
+{
+    closeHelp(0);
+    closeHelp(1);
+}
+
+bool PipeWrapper::isReady()
+{
+    return m_pipefd[0] != PIPE_CLOSED || m_pipefd[1] != PIPE_CLOSED;
+}
+
+void PipeWrapper::setUsage(Usage usage)
+{
+    if (usage == READONLY) {
+        closeHelp(1);
+    }
+    if (usage == WRITEONLY) {
+        closeHelp(0);
+    }
+}
+
+PipeWrapper::Status PipeWrapper::send(int code, std::string &message)
+{
+    if (m_pipefd[1] == PIPE_CLOSED) {
+        return ERROR;
+    }
+
+    std::ostringstream output;
+    output << toBinaryString(code);
+    output << toBinaryString(MSG_TYPE_MESSAGE);
+    output << toBinaryString(static_cast<int>(message.size()));
+    output << message;
+
+    std::string binary = output.str();
+    int size = binary.size();
+
+    if ((writeHelp(&size,
+                   sizeof(int)) == ERROR) ||
+        (writeHelp(binary.c_str(), size) == ERROR))
+    {
+        return ERROR;
+    }
+    return SUCCESS;
+}
+
+PipeWrapper::Status PipeWrapper::sendTime(int code,
+                                          std::chrono::system_clock::duration time,
+                                          std::chrono::system_clock::duration timeMax)
+{
+    if (m_pipefd[1] == PIPE_CLOSED) {
+        return ERROR;
+    }
+
+    std::ostringstream output;
+    output << toBinaryString(code);
+    output << toBinaryString(MSG_TYPE_PERF_TIME);
+    output << toBinaryString(time);
+    output << toBinaryString(timeMax);
+
+    std::string binary = output.str();
+    int size = binary.size();
+
+    if ((writeHelp(&size,
+                   sizeof(int)) == ERROR) ||
+        (writeHelp(binary.c_str(), size) == ERROR))
+    {
+        return ERROR;
+    }
+    return SUCCESS;
+}
+
+PipeWrapper::Status PipeWrapper::receive(int &code,
+                                         int &msgType,
+                                         std::string &data,
+                                         std::chrono::system_clock::duration &time,
+                                         std::chrono::system_clock::duration &timeMax,
+                                         time_t deadline)
+{
+    if (m_pipefd[0] == PIPE_CLOSED) {
+        return ERROR;
+    }
+
+    int size;
+    Status ret;
+
+    if ((ret = readHelp(&size, sizeof(int), deadline)) != SUCCESS) {
+        return ret;
+    }
+
+    std::vector<char> buffer;
+    buffer.resize(size);
+
+    if ((ret = readHelp(&buffer[0], size, deadline)) != SUCCESS) {
+        return ret;
+    }
+
+    try {
+        DPL::BinaryQueue queue;
+        queue.AppendCopy(&buffer[0], size);
+
+        queue.FlattenConsume(&code, sizeof(int));
+        queue.FlattenConsume(&msgType, sizeof(int));
+
+        switch (msgType) {
+        case MSG_TYPE_MESSAGE:
+            queue.FlattenConsume(&size, sizeof(int));
+
+            buffer.resize(size);
+
+            queue.FlattenConsume(&buffer[0], size);
+            data.assign(buffer.begin(), buffer.end());
+            break;
+        case MSG_TYPE_PERF_TIME:
+            queue.FlattenConsume(&time, sizeof(std::chrono::system_clock::duration));
+            queue.FlattenConsume(&timeMax, sizeof(std::chrono::system_clock::duration));
+            break;
+        default:
+            return ERROR;
+        }
+    } catch (DPL::BinaryQueue::Exception::Base &e) {
+        return ERROR;
+    }
+    return SUCCESS;
+}
+
+void PipeWrapper::closeAll()
+{
+    closeHelp(0);
+    closeHelp(1);
+}
+
+std::string PipeWrapper::toBinaryString(int data)
+{
+    char buffer[sizeof(int)];
+    memcpy(buffer, &data, sizeof(int));
+    return std::string(buffer, buffer + sizeof(int));
+}
+
+std::string PipeWrapper::toBinaryString(std::chrono::system_clock::duration data)
+{
+    char buffer[sizeof(std::chrono::system_clock::duration)];
+    memcpy(buffer, &data, sizeof(std::chrono::system_clock::duration));
+    return std::string(buffer, buffer + sizeof(std::chrono::system_clock::duration));
+}
+
+void PipeWrapper::closeHelp(int desc)
+{
+    if (m_pipefd[desc] != PIPE_CLOSED) {
+        TEMP_FAILURE_RETRY(close(m_pipefd[desc]));
+        m_pipefd[desc] = PIPE_CLOSED;
+    }
+}
+
+PipeWrapper::Status PipeWrapper::writeHelp(const void *buffer, int size)
+{
+    int ready = 0;
+    const char *p = static_cast<const char *>(buffer);
+    while (ready != size) {
+        int ret = write(m_pipefd[1], &p[ready], size - ready);
+
+        if (ret == -1 && (errno == EAGAIN || errno == EINTR)) {
+            continue;
+        }
+
+        if (ret == -1) {
+            closeHelp(1);
+            return ERROR;
+        }
+
+        ready += ret;
+    }
+    return SUCCESS;
+}
+
+PipeWrapper::Status PipeWrapper::readHelp(void *buf, int size, time_t deadline)
+{
+    int ready = 0;
+    char *buffer = static_cast<char*>(buf);
+    while (ready != size) {
+        time_t wait = deadline - time(0);
+        wait = wait < 1 ? 1 : wait;
+        pollfd fds = { m_pipefd[0], POLLIN, 0 };
+
+        int pollReturn = poll(&fds, 1, wait * 1000);
+
+        if (pollReturn == 0) {
+            return TIMEOUT; // Timeout
+        }
+
+        if (pollReturn < -1) {
+            return ERROR;
+        }
+
+        int ret = read(m_pipefd[0], &buffer[ready], size - ready);
+
+        if (ret == -1 && (errno == EAGAIN || errno == EINTR)) {
+            continue;
+        }
+
+        if (ret == -1 || ret == 0) {
+            closeHelp(0);
+            return ERROR;
+        }
+
+        ready += ret;
+    }
+    return SUCCESS;
+}
+
+void RunChildProc(TestRunner::TestCase procChild)
+{
+    PipeWrapper pipe;
+    if (!pipe.isReady()) {
+        throw TestRunner::TestFailed("Pipe creation failed");
+    }
+
+    pid_t pid = fork();
+
+    if (pid == -1) {
+        throw TestRunner::TestFailed("Child creation failed");
+    }
+
+    if (pid != 0) {
+        // parent code
+        pipe.setUsage(PipeWrapper::READONLY);
+
+        int code;
+        int msgType;
+        std::chrono::system_clock::duration time_m;
+        std::chrono::system_clock::duration timeMax_m;
+        std::string message;
+
+        int pipeReturn = pipe.receive(code, msgType, message, time_m, timeMax_m, time(0) + 10);
+
+        if (pipeReturn != PipeWrapper::SUCCESS) { // Timeout or reading error
+            pipe.closeAll();
+            kill(pid, SIGKILL);
+        }
+
+        int status;
+        waitpid(pid, &status, 0);
+
+        if (pipeReturn == PipeWrapper::TIMEOUT) {
+            throw TestRunner::TestFailed("Timeout");
+        }
+
+        if (pipeReturn == PipeWrapper::ERROR) {
+            throw TestRunner::TestFailed("Reading pipe error");
+        }
+
+        if (code == CHILD_TEST_PASS && msgType == MSG_TYPE_PERF_TIME) {
+            DPL::Test::TestRunnerSingleton::Instance().setCurrentTestCasePerformanceResult(true,
+                                                                                           time_m,
+                                                                                           timeMax_m);
+        }
+
+        if (code == CHILD_TEST_FAIL) {
+            throw TestRunner::TestFailed(message);
+        } else if (code == CHILD_TEST_IGNORED) {
+            throw TestRunner::Ignored(message);
+        }
+    } else {
+        // child code
+
+        // End Runner after current test
+        TestRunnerSingleton::Instance().Terminate();
+
+        int code = CHILD_TEST_PASS;
+        std::string msg;
+        bool isPerformanceTest;
+        std::chrono::system_clock::duration time_m;
+        std::chrono::system_clock::duration timeMax_m;
+
+        bool allowLogs = TestRunnerSingleton::Instance().GetAllowChildLogs();
+
+        close(STDIN_FILENO);
+        if (!allowLogs) {
+            closeOutput(); // if fails nothing we can do
+        }
+
+        pipe.setUsage(PipeWrapper::WRITEONLY);
+
+        try {
+            procChild();
+        } catch (const DPL::Test::TestRunner::TestFailed &e) {
+            msg = e.GetMessage();
+            code = CHILD_TEST_FAIL;
+        } catch (const DPL::Test::TestRunner::Ignored &e) {
+            msg = e.GetMessage();
+            code = CHILD_TEST_IGNORED;
+        } catch (...) { // catch all exception generated by "user" code
+            msg = "unhandled exeception";
+            code = CHILD_TEST_FAIL;
+        }
+
+        if (allowLogs) {
+            closeOutput();
+        }
+
+        DPL::Test::TestRunnerSingleton::Instance().getCurrentTestCasePerformanceResult(isPerformanceTest,
+                                                                                       time_m,
+                                                                                       timeMax_m);
+
+        if (code == CHILD_TEST_PASS && isPerformanceTest){
+            pipe.sendTime(code,
+                    time_m,
+                    timeMax_m);
+        } else {
+            pipe.send(code, msg);
+        }
+    }
+}
+} // namespace Test
+} // namespace DPL
diff --git a/tests/framework/src/test_runner_multiprocess.cpp b/tests/framework/src/test_runner_multiprocess.cpp
new file mode 100644 (file)
index 0000000..881e1c1
--- /dev/null
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        test_runner_multiprocess.cpp
+ * @author      Marcin Niesluchowski (m.niesluchow@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of multiprocess test runner
+ */
+
+#include <sys/file.h>
+#include <dpl/exception.h>
+#include <dpl/test/test_runner.h>
+#include <dpl/test/test_runner_child.h>
+#include <dpl/test/test_runner_multiprocess.h>
+#include <poll.h>
+#include <limits.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+namespace {
+
+const int MULTI_TEST_ERROR    = -1;
+const int MULTI_TEST_PASS     = 0;
+const int MULTI_TEST_FAILED   = 1;
+const int MULTI_TEST_IGNORED  = 2;
+const int MULTI_TEST_INTERNAL = 3;
+
+}
+
+namespace DPL {
+namespace Test {
+
+SimplePipeWrapper::SimplePipeWrapper()
+: PipeWrapper()
+{
+
+}
+
+SimplePipeWrapper::~SimplePipeWrapper()
+{
+
+}
+
+PipeWrapper::Status SimplePipeWrapper::send(std::string &message)
+{
+    if (m_pipefd[1] == PIPE_CLOSED) {
+           return ERROR;
+    }
+
+    if (message.size() > PIPE_BUF-1) {
+        return ERROR;
+    }
+
+    char buffer[PIPE_BUF] = { 0 };
+
+
+    for(unsigned int i = 0; i < message.size(); ++i) {
+        buffer[i] = message[i];
+    }
+
+    return writeHelp(buffer, PIPE_BUF);
+}
+
+PipeWrapper::Status SimplePipeWrapper::receive(std::string &data, bool &empty, time_t deadline)
+{
+    if (m_pipefd[0] == PIPE_CLOSED) {
+        return ERROR;
+    }
+
+    empty = false;
+
+    data.resize(PIPE_BUF);
+
+    char buffer[PIPE_BUF] = { 0 };
+
+    int ready = 0;
+    while (ready != PIPE_BUF) {
+        time_t wait = deadline - time(0);
+        wait = wait < 1 ? 1 : wait;
+        pollfd fds = { m_pipefd[0], POLLIN, 0 };
+
+        int pollReturn = poll(&fds, 1, wait * 1000);
+
+        if (pollReturn == 0) {
+            return TIMEOUT; // Timeout
+        }
+
+        if (pollReturn < -1) {
+            return ERROR;
+        }
+        int ret = read(m_pipefd[0], &buffer[ready], PIPE_BUF - ready);
+        if (ret == -1 && (errno == EAGAIN || errno == EINTR)) {
+            continue;
+        }
+
+        if (ret == -1) {
+            closeHelp(0);
+            return ERROR;
+        }
+        if (ret == 0) {
+            empty = true;
+            break;
+        }
+
+        ready += ret;
+    }
+
+
+    for(unsigned int i = 0; i < PIPE_BUF; ++i){
+        if(buffer[i] == 0) {
+            data.resize(i);
+            return SUCCESS;
+        }
+        data[i] = buffer[i];
+    }
+
+    return ERROR;
+}
+
+void RunMultiProc(TestRunner::TestCase procMulti)
+{
+    SimplePipeWrapper pipe;
+    int code = MULTI_TEST_PASS;
+    std::string msg = "";
+    int pipeReturn;
+
+    int waitStatus;
+
+    pid_t top_pid = getpid();
+
+    if (!pipe.isReady()) {
+        throw TestRunner::TestFailed("Pipe creation failed");
+    }
+    // pipe
+
+    try {
+        procMulti();
+    } catch (const TestRunner::TestFailed &e) {
+        code = MULTI_TEST_FAILED;
+        msg = e.GetMessage();
+    } catch (const TestRunner::Ignored &e) {
+        code = MULTI_TEST_IGNORED;
+        msg = e.GetMessage();
+    } catch (const DPL::Exception &e) {
+        code = MULTI_TEST_INTERNAL;
+        msg = "DPL exception:" + e.GetMessage();
+    } catch (const std::exception &) {
+        code = MULTI_TEST_INTERNAL;
+        msg = "std exception";
+    } catch (...) {
+        // Unknown exception failure
+        code = MULTI_TEST_INTERNAL;
+        msg = "unknown exception";
+    }
+
+    while (true) {
+        pid_t child_pid = wait(&waitStatus);
+        if (child_pid == -1) {
+            if (errno == ECHILD) {
+                if (top_pid == getpid()) {
+                    std::string recMsg="";
+
+                    pipe.setUsage(PipeWrapper::READONLY);
+
+                    bool empty=false;
+                    while(true) {
+                        pipeReturn = pipe.receive(recMsg, empty, time(0) + 10);
+
+                        if (empty) {
+                            break;
+                        }
+                        if (pipeReturn == PipeWrapper::ERROR) {
+                            pipe.closeAll();
+                            throw TestRunner::TestFailed("Reading pipe error");
+                        } else if (pipeReturn == PipeWrapper::TIMEOUT) {
+                            pipe.closeAll();
+                            throw TestRunner::TestFailed("Timeout error");
+                        }
+                        msg = msg + "\n" + recMsg;
+                    }
+                    pipe.closeAll();
+
+                    switch(code) {
+                    case MULTI_TEST_PASS:
+                        return;
+                    case MULTI_TEST_FAILED:
+                        throw TestRunner::TestFailed(msg);
+                    case MULTI_TEST_IGNORED:
+                        throw TestRunner::Ignored(msg);
+                    case MULTI_TEST_INTERNAL:
+                        throw TestRunner::TestFailed(msg);
+                    default:
+                        throw TestRunner::TestFailed(msg);
+                    }
+                } else {
+                    pipe.setUsage(PipeWrapper::WRITEONLY);
+
+                    pipeReturn = pipe.send(msg);
+
+                    if (pipeReturn == PipeWrapper::ERROR) {
+                        pipe.closeAll();
+                        code = MULTI_TEST_ERROR;
+                    }
+
+                    exit(code);
+                }
+            }
+        } else if (WIFEXITED(waitStatus)) {
+            if ((signed char)WEXITSTATUS(waitStatus) == MULTI_TEST_FAILED) {
+                switch (code) {
+                    case MULTI_TEST_PASS:
+                        code = MULTI_TEST_FAILED;
+                        break;
+                    case MULTI_TEST_FAILED:
+                        break;
+                    case MULTI_TEST_IGNORED:
+                        code = MULTI_TEST_FAILED;
+                        break;
+                    case MULTI_TEST_INTERNAL:
+                        break;
+                    default:
+                        break;
+                    }
+            } else if ((signed char)WEXITSTATUS(waitStatus) == MULTI_TEST_IGNORED) {
+                switch (code) {
+                case MULTI_TEST_PASS:
+                    code = MULTI_TEST_IGNORED;
+                    break;
+                case MULTI_TEST_FAILED:
+                    break;
+                case MULTI_TEST_IGNORED:
+                    break;
+                case MULTI_TEST_INTERNAL:
+                    break;
+                default:
+                    break;
+                }
+            } else if ((signed char)WEXITSTATUS(waitStatus) == MULTI_TEST_INTERNAL) {
+                switch (code) {
+                case MULTI_TEST_PASS:
+                    code = MULTI_TEST_INTERNAL;
+                    break;
+                case MULTI_TEST_FAILED:
+                    code = MULTI_TEST_INTERNAL;
+                    break;
+                case MULTI_TEST_IGNORED:
+                    code = MULTI_TEST_INTERNAL;
+                    break;
+                case MULTI_TEST_INTERNAL:
+                    break;
+                default:
+                    break;
+                }
+            } else  if ((signed char)WEXITSTATUS(waitStatus) != MULTI_TEST_PASS) {
+                code = MULTI_TEST_ERROR;
+                msg = "PROCESS BAD CODE RETURN";
+            }
+        }
+    }
+}
+} // namespace Test
+} // namespace DPL
index 9bd88ba..7a6e956 100644 (file)
@@ -61,7 +61,6 @@ SET(LPC_TARGET_TEST "libprivilege-control-test")
 PKG_CHECK_MODULES(LPC_TARGET_DEP
     libsmack
     libprivilege-control
-    dpl-test-efl
     sqlite3
     libtzplatform-config
     REQUIRED
@@ -99,6 +98,7 @@ ADD_EXECUTABLE(${LPC_TARGET_TEST} ${LPC_TARGET_TEST_SOURCES})
 #linker directories
 TARGET_LINK_LIBRARIES(${LPC_TARGET_TEST}
     ${LPC_TARGET_DEP_LIBRARIES}
+    dpl-test-framework
     tests-common
     -lcrypt
     )
index cf1da99..799d19b 100644 (file)
@@ -23,7 +23,6 @@ SET(TARGET_TEST "libsmack-test")
 #dependencies
 PKG_CHECK_MODULES(TARGET_DEP
     libsmack
-    dpl-test-efl
     REQUIRED
     )
 
@@ -51,6 +50,7 @@ ADD_EXECUTABLE(${TARGET_TEST} ${TARGET_TEST_SOURCES})
 #linker directories
 TARGET_LINK_LIBRARIES(${TARGET_TEST}
     ${TARGET_DEP_LIBRARIES}
+    dpl-test-framework
     tests-common
     )
 
index 066bfcb..ae894b5 100644 (file)
@@ -27,8 +27,7 @@ PKG_CHECK_MODULES(SEC_MGR_TESTS_DEP
     libprivilege-control
     security-manager
     libtzplatform-config
-    sqlite3
-    dpl-test-efl)
+    sqlite3)
 
 
 SET(TARGET_SEC_MGR_TESTS "security-manager-tests")
@@ -53,7 +52,9 @@ ADD_EXECUTABLE(${TARGET_SEC_MGR_TESTS} ${SEC_MGR_SOURCES})
 
 TARGET_LINK_LIBRARIES(${TARGET_SEC_MGR_TESTS}
     ${SEC_MGR_TESTS_DEP_LIBRARIES}
-    tests-common)
+    dpl-test-framework
+    tests-common
+    )
 
 INSTALL(TARGETS ${TARGET_SEC_MGR_TESTS} DESTINATION /usr/bin)
 
index b22e3ca..d0497a9 100644 (file)
@@ -26,7 +26,6 @@ PKG_CHECK_MODULES(SEC_SRV_TESTS_DEP
     libsmack
     libprivilege-control
     security-server
-    dpl-test-efl
     dlog
     dbus-1
     dbus-glib-1
@@ -117,38 +116,54 @@ ADD_EXECUTABLE(${TARGET_SEC_SRV_MEASURER} ${SEC_SRV_MEASURER_SOURCES})
 
 TARGET_LINK_LIBRARIES(${TARGET_SEC_SRV_CLIENT_SMACK_TESTS}
     ${SEC_SRV_TESTS_DEP_LIBRARIES}
-    tests-common)
+    dpl-test-framework
+    tests-common
+    )
 
 TARGET_LINK_LIBRARIES(${TARGET_SEC_SRV_TC_SERVER_TESTS}
     ${TARGET_SEC_SRV_COMMON}
     ${SEC_SRV_TESTS_DEP_LIBRARIES}
-    tests-common)
+    dpl-test-framework
+    tests-common
+    )
 
 TARGET_LINK_LIBRARIES(${TARGET_SEC_SRV_PWD_TESTS}
     ${TARGET_SEC_SRV_COMMON}
     ${SEC_SRV_TESTS_DEP_LIBRARIES}
-    tests-common)
+    dpl-test-framework
+    tests-common
+    )
 
 TARGET_LINK_LIBRARIES(${TARGET_SEC_SRV_PRIVILEGE_TESTS}
     ${SEC_SRV_TESTS_DEP_LIBRARIES}
-    tests-common)
+    dpl-test-framework
+    tests-common
+    )
 
 TARGET_LINK_LIBRARIES(${TARGET_SEC_SRV_STRESS_TESTS}
     ${SEC_SRV_TESTS_DEP_LIBRARIES}
-    tests-common)
+    dpl-test-framework
+    tests-common
+    )
 
 TARGET_LINK_LIBRARIES(${TARGET_SEC_SRV_MT_TESTS}
     ${SEC_SRV_TESTS_DEP_LIBRARIES}
-    tests-common)
+    dpl-test-framework
+    tests-common
+    )
 
 TARGET_LINK_LIBRARIES(${TARGET_SEC_SRV_DBUS_TESTS}
     ${SEC_SRV_TESTS_DEP_LIBRARIES}
-    tests-common)
+    dpl-test-framework
+    tests-common
+    )
 
 TARGET_LINK_LIBRARIES(${TARGET_SEC_SRV_MEASURER}
     ${TARGET_SEC_SRV_COMMON}
     ${SEC_SRV_TESTS_DEP_LIBRARIES}
-    tests-common)
+    dpl-test-framework
+    tests-common
+    )
 
 # Installation
 
index a74625c..db42e3a 100644 (file)
@@ -29,7 +29,6 @@
  */
 
 #include <dpl/log/log.h>
-#include <dpl/serialization.h>
 #include <dpl/singleton.h>
 #include <dpl/singleton_safe_impl.h>
 #include <dpl/test/test_runner.h>