[Release] wrt-commons_0.2.101 submit/sdk/20130306.102906
authorJihoon Chung <jihoon.chung@samsung.com>
Wed, 6 Mar 2013 10:28:47 +0000 (19:28 +0900)
committerJihoon Chung <jihoon.chung@samsung.com>
Wed, 6 Mar 2013 10:28:47 +0000 (19:28 +0900)
Change-Id: I725f2d24dfbb7771d3398c7b907d7c97d48ea2d8

33 files changed:
debian/changelog
examples/fake_rpc/fake_rpc.cpp
modules/core/config.cmake
modules/core/include/dpl/static_block.h [new file with mode: 0644]
modules/db/src/naive_synchronization_object.cpp
modules/localization/src/LanguageTagsProvider.cpp
modules/test/src/test_results_collector.cpp
modules/utils/src/file_utils.cpp
modules/utils/src/wrt_global_settings.cpp
modules/widget_dao/dao/config_parser_data.cpp
modules/widget_dao/dao/widget_dao.cpp
modules/widget_dao/dao/widget_dao_read_only.cpp
modules/widget_dao/include/dpl/wrt-dao-ro/common_dao_types.h
modules/widget_dao/include/dpl/wrt-dao-ro/config_parser_data.h
modules/widget_dao/include/dpl/wrt-dao-ro/widget_dao_read_only.h
modules/widget_dao/orm/wrt_db
packaging/wrt-commons.spec
tests/CMakeLists.txt
tests/core/CMakeLists.txt
tests/core/test_fast_delegate.cpp
tests/core/test_serialization.cpp
tests/core/test_static_block.cpp [new file with mode: 0644]
tests/dao/TestCases_PluginDAO.cpp
tests/db/test_orm.cpp
tests/event/test_controller.cpp
tests/files_localization/CMakeLists.txt
tests/files_localization/files/CMakeLists.txt
tests/files_localization/test_localization.cpp
tests/files_localization/test_suite01.cpp
tests/files_localization/wrt_db_localization_prepare.sh [new file with mode: 0644]
tests/unused/test_shm.cpp
tests/unused/test_sql_connection.cpp
tests/utils/wrt_utility.cpp

index bd79ca4df8d48b8cbffebbd3a7f1f0b2bf20db3d..d3991a0588dfb53b14a92d402f9f3fb972a2b3a9 100644 (file)
@@ -1,3 +1,17 @@
+wrt-commons (0.2.101) unstable; urgency=low
+
+  * CSP report only support
+
+ -- Jihoon Chung <jihoon.chung@samsung.com>  Wed, 06 Mar 2013 19:22:11 +0900
+
+wrt-commons (0.2.100) unstable; urgency=low
+
+  * Prepare database for additional appservice parameter
+  * Enable DPL::Localization tests
+  * Fix warnings shown by cppcheck for wrt-commons
+
+ -- leerang <leerang.song@samsung.com>  Thu, 28 Feb 2013 12:53:01 +0900
+
 wrt-commons (0.2.99) unstable; urgency=low
 
   * Unused fields in WidgetRegisterInfo
index 3396a59d74b18666d17738e66d2ccbe2270e2f2b..82a244327a7305b2c7b5e1464d692ad6fee9c0ee 100644 (file)
@@ -102,6 +102,14 @@ private:
     }
 
 public:
+    MyThread() :
+        m_rpcUnixClient(NULL),
+        m_rpcFakeClient(NULL),
+        m_connections(0),
+        m_sentData(0),
+        m_receivedData(0)
+    {}
+
     virtual ~MyThread()
     {
         // Always quit thread
index 147f15568ac7c3f16980aec4a602fb204cc41faa..b681dd59a4d0b595e2a7b5aa74a27666ee843016 100644 (file)
@@ -123,6 +123,7 @@ SET(DPL_CORE_HEADERS
     ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/singleton.h
     ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/singleton_impl.h
     ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/singleton_safe_impl.h
+    ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/static_block.h
     ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/string.h
     ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/sstream.h
     ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/task.h
diff --git a/modules/core/include/dpl/static_block.h b/modules/core/include/dpl/static_block.h
new file mode 100644 (file)
index 0000000..62fae46
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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        static_block.h
+ * @author      Iwanek Tomasz (t.iwanek@samsung.com)
+ * @version     1.0
+ */
+#ifndef STATIC_BLOCK_H
+#define STATIC_BLOCK_H
+
+#include <dpl/preprocessor.h>
+
+//NOTE: order of static initialization of blocks is not specified
+
+// to be used only outside class of function scopes
+#define STATIC_BLOCK_IMPL( UNIQUE )                                                                 \
+    static void DPL_MACRO_CONCAT( _staticBlock , UNIQUE() );                                        \
+    static int DPL_MACRO_CONCAT( _staticBlockInitAssurence , UNIQUE ) = []() -> int                 \
+    {                                                                                               \
+        (void) DPL_MACRO_CONCAT( _staticBlockInitAssurence , UNIQUE );                              \
+        DPL_MACRO_CONCAT( _staticBlock ,  UNIQUE() );                                               \
+        return 0;                                                                                   \
+    }();                                                                                            \
+    void DPL_MACRO_CONCAT( _staticBlock , UNIQUE() )                                                \
+
+#define STATIC_BLOCK                                                                                \
+    STATIC_BLOCK_IMPL( __COUNTER__ )                                                               \
+
+//for class implementation
+#define STATIC_BLOCK_CLASS( classname, methodname ) STATIC_BLOCK { classname::methodname(); }
+
+#endif // STATIC_BLOCK_H
index 0fbc386f2a479ef7727d266304b534a94675dfe6..1ac71ca4b864432c857e9d73347d1b58b71b3818 100644 (file)
 #include <dpl/db/naive_synchronization_object.h>
 #include <dpl/thread.h>
 
+namespace {
+    unsigned int seed = time(NULL);
+}
+
 namespace DPL {
 namespace DB {
 void NaiveSynchronizationObject::Synchronize()
 {
     // Sleep for about 10ms - 30ms
-    Thread::MiliSleep(10 + rand() % 20);
+    Thread::MiliSleep(10 + rand_r(&seed) % 20);
 }
 
 void NaiveSynchronizationObject::NotifyAll()
index fcf2077bb88e95bec17e2c65485dfac2199e1f62..0d97e163a2d855604de34f64f2a01f9d2aad143f 100644 (file)
@@ -139,12 +139,12 @@ void LanguageTagsProvider::createTagsFromLocales(const char* language)
     DPL::String langdescr =
         LocaleToBCP47LanguageTag(DPL::FromUTF8String(language));
 
-    size_t position;
     if (langdescr.empty()) {
         LogError("Empty language description while correct value needed");
     } else {
         /* Language tags list should not be cleared before this place to
          * avoid losing current data when new data are invalid */
+        size_t position;
         while (true) {
             LogDebug("Processing language description: " << langdescr);
             m_languageTagsList.push_back(langdescr);
index 482b13229b6cc9cdebee78433277f4bc59afab2d..025dd8413dacec7a4cf7f251e653a93fb96ef020 100644 (file)
@@ -48,7 +48,7 @@ const char *DEFAULT_XML_FILE_NAME = "results.xml";
 bool ParseCollectorFileArg(const std::string &arg, std::string &filename)
 {
     const std::string argname = "--file=";
-    if (0 == arg.find(argname)) {
+    if (arg.find(argname) == 0 ) {
         filename = arg.substr(argname.size());
         return true;
     }
index 25100694374d7fb3fa3a2f14c673ce4345403d12..c6e77e2bf3e18da1eec13f0c7555420a2efaa44c 100644 (file)
@@ -89,28 +89,32 @@ int RmDir(const char* path)
         return -1;
     }
 
-    struct dirent* entry = NULL;
-    do {
+    int return_code;
+    struct dirent entry = NULL;
+    struct dirent* entry_result;
+
+    for (return_code = readdir_r(dir, &entry, &entry_result) != 0;
+            entry_result != NULL && return_code != 0;
+            return_code = readdir_r(dir, &entry, &entry_result))
+    {
         errno = 0;
-        if (NULL != (entry = ::readdir(dir))) {
-            if (!::strncmp(entry->d_name, ".", 1) ||
-                !::strncmp(entry->d_name, "..", 2))
-            {
-                continue;
-            }
-            std::string fullPath = WrtDB::PathBuilder(path)
-                    .Append(entry->d_name)
-                    .GetFullPath();
-            if (RmNode(fullPath.c_str()) != 0) {
-                int error = errno;
-                TEMP_FAILURE_RETRY(::closedir(dir));
-                errno = error;
-                return -1;
-            }
+        if (!::strncmp(entry.d_name, ".", 1) ||
+            !::strncmp(entry.d_name, "..", 2))
+        {
+            continue;
         }
-    } while (NULL != entry);
+        std::string fullPath = WrtDB::PathBuilder(path)
+                .Append(entry.d_name)
+                .GetFullPath();
+        if (RmNode(fullPath.c_str()) != 0) {
+            int error = errno;
+            TEMP_FAILURE_RETRY(::closedir(dir));
+            errno = error;
+            return -1;
+        }
+    }
 
-    int error = errno;
+    int error = (!errno) ? errno : return_code;
     if (TEMP_FAILURE_RETRY(::closedir(dir)) != 0) {
         return -1;
     }
index adaac78a971e2195319c886aeccfd39544e9910a..4f005c5026a53d07b848fd89c8f891bdb565985d 100644 (file)
@@ -91,9 +91,9 @@ bool initializeGlobalSettings()
     // ignore environment variables if this flag is not set
 #ifdef GLOBAL_SETTINGS_CONTROL
     char * envStr = getenv(WRT_TEST_MODE);
-    int testMode = 0;
     if (NULL != envStr) {
         std::string env = envStr;
+        int testMode = 0;
         if ("1" == env) {
             testMode = ALL_TEST;
         } else {
index eccbe40389a75f7ae368e476603b0147fabad51b..cc5253a385ec25bcbcb82dc6d9e742e117c4d64f 100644 (file)
@@ -451,7 +451,8 @@ bool ConfigParserData::ServiceInfo::operator== (const ServiceInfo& info) const
     return m_src == info.m_src &&
            m_operation == info.m_operation &&
            m_scheme == info.m_scheme &&
-           m_mime == info.m_mime;
+           m_mime == info.m_mime &&
+           m_disposition == info.m_disposition;
 }
 
 bool ConfigParserData::ServiceInfo::operator!= (const ServiceInfo& info) const
@@ -459,7 +460,8 @@ bool ConfigParserData::ServiceInfo::operator!= (const ServiceInfo& info) const
     return m_src != info.m_src &&
            m_operation != info.m_operation &&
            m_scheme != info.m_scheme &&
-           m_mime != info.m_mime;
+           m_mime != info.m_mime &&
+           m_disposition != info.m_disposition;
 }
 
 bool ConfigParserData::LiveboxInfo::operator==(const LiveboxInfo& other) const
index 65ea027ca67206e99e4ea5899ca4e0ed2e31f6ae..a58c4786bdd0056b60b6422feff426ee3aa15385 100644 (file)
 #include <orm_generator_wrt.h>
 #include <dpl/wrt-dao-ro/WrtDatabase.h>
 
+namespace {
+    unsigned int seed = time(NULL);
+}
+
 namespace WrtDB {
 //TODO in current solution in each getter there exists a check
 //"IsWidgetInstalled". Maybe it should be verified, if it could be done
@@ -244,10 +248,9 @@ DbWidgetHandle WidgetDAO::registerWidget(
     //make it more precise due to very fast tests
     struct timeval tv;
     gettimeofday(&tv, NULL);
-    srand(time(NULL) + tv.tv_usec);
     DbWidgetHandle widgetHandle;
     do {
-        widgetHandle = rand();
+        widgetHandle = rand_r(&seed);
     } while (isWidgetInstalled(widgetHandle));
 
     registerWidget(*pWidgetRegisterInfo.configInfo.tizenAppId,
@@ -391,6 +394,7 @@ DbWidgetHandle WidgetDAO::registerWidgetInfo(
     row.Set_author_email(widgetConfigurationInfo.authorEmail);
     row.Set_author_href(widgetConfigurationInfo.authorHref);
     row.Set_csp_policy(widgetConfigurationInfo.cspPolicy);
+    row.Set_csp_policy_report_only(widgetConfigurationInfo.cspPolicyReportOnly);
     row.Set_base_folder(DPL::FromUTF8String(regInfo.baseFolder));
     row.Set_webkit_plugins_required(widgetConfigurationInfo.flashNeeded);
     row.Set_recognized(wacSecurity.isRecognized());
@@ -706,6 +710,7 @@ void WidgetDAO::registerAppService(DbWidgetHandle widgetHandle,
         row.Set_operation(ASIt->m_operation);
         row.Set_scheme(ASIt->m_scheme);
         row.Set_mime(ASIt->m_mime);
+        row.Set_disposition(static_cast<int>(ASIt->m_disposition));
 
         DO_INSERT(row, ApplicationServiceInfo)
     }
index f8fdf0bc0e5fa8ae473ae202842d55ccff5bf034..b52a2b003d3b17e1c663df5feb6628a60762afe8 100644 (file)
 #include <orm_generator_wrt.h>
 #include <LanguageTagsProvider.h>
 
+namespace {
+    unsigned int seed = time(NULL);
+}
+
 namespace WrtDB {
 //TODO in current solution in each getter there exists a check
 //"IsWidgetInstalled". Maybe it should be verified, if it could be done
@@ -691,6 +695,12 @@ DPL::OptionalString WidgetDAOReadOnly::getCspPolicy() const
     return row.Get_csp_policy();
 }
 
+DPL::OptionalString WidgetDAOReadOnly::getCspPolicyReportOnly() const
+{
+    WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle);
+    return row.Get_csp_policy_report_only();
+}
+
 bool WidgetDAOReadOnly::getWebkitPluginsRequired() const
 {
     WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle);
@@ -1125,6 +1135,7 @@ void WidgetDAOReadOnly::getAppServiceList(
             ret.operation = it->Get_operation();
             ret.scheme = it->Get_scheme();
             ret.mime = it->Get_mime();
+            ret.disposition = static_cast<WidgetApplicationService::Disposition>(it->Get_disposition());
             outAppServiceList.push_back(ret);
         }
 
@@ -1185,7 +1196,7 @@ TizenPkgId WidgetDAOReadOnly::generatePkgId()
     pkgId.resize(MAX_TIZENID_LENGTH);
     do {
         for (int i = 0; i < MAX_TIZENID_LENGTH; ++i) {
-            pkgId[i] = allowed[rand() % allowed.length()];
+            pkgId[i] = allowed[rand_r(&seed) % allowed.length()];
         }
     } while (isWidgetInstalled(pkgId));
     return pkgId;
index ff30556b90fbc33ab13dd250466ca3a2a8506326..234ef6e0f51d9958d49c995bb03160b3beb14413 100644 (file)
@@ -378,18 +378,24 @@ typedef std::list<WidgetSetting> WidgetSettings;
  */
 struct WidgetApplicationService
 {
-  public:
+    enum class Disposition {
+        WINDOW = 0,
+        INLINE
+    };
+
     DPL::String src;       /* start uri */
     DPL::String operation; /* service name */
     DPL::String scheme;    /* scheme type*/
     DPL::String mime;      /* mime type */
+    Disposition disposition;
 
     bool operator== (const WidgetApplicationService& other) const
     {
         return src == other.src &&
                operation == other.operation &&
                scheme == other.scheme &&
-               mime == other.mime;
+               mime == other.mime &&
+               disposition == other.disposition;
     }
 };
 
index f56be5509774b6ac365a2181d38558f6cd513eb5..ee09d08485464e6b6471636254a1cc58f8b90152 100644 (file)
@@ -181,20 +181,27 @@ class ConfigParserData
      */
     struct ServiceInfo
     {
+        enum class Disposition {
+            WINDOW = 0,
+            INLINE
+        };
         ServiceInfo(
             const DPL::String& src,
             const DPL::String& operation,
             const DPL::String& scheme,
-            const DPL::String& mime) :
+            const DPL::String& mime,
+            const Disposition dispos) :
             m_src(src),
             m_operation(operation),
             m_scheme(scheme),
-            m_mime(mime)
+            m_mime(mime),
+            m_disposition(dispos)
         {}
         DPL::String m_src;
         DPL::String m_operation;
         DPL::String m_scheme;
         DPL::String m_mime;
+        Disposition m_disposition;
 
         bool operator==(const ServiceInfo&) const;
         bool operator!=(const ServiceInfo&) const;
@@ -305,6 +312,7 @@ class ConfigParserData
 
     //csp polic for widget
     DPL::OptionalString cspPolicy;
+    DPL::OptionalString cspPolicyReportOnly;
 
     //Application service model list
     ServiceInfoList appServiceList; //It will be removed.
index c2b1de279241f6cebd8916cfc9b7439164108756..95f036509981d0caf0fb48284539ea4059005eca 100644 (file)
@@ -349,7 +349,7 @@ class WidgetDAOReadOnly
      * @exception WRT_CONF_ERR_EMDB_NO_RECORD - Can not find matching records in
      * DB table.
      */
-    DPL::String getPath() const;
+    virtual DPL::String getPath() const;
 
     DPL::String getFullPath() const;
 
@@ -503,6 +503,13 @@ class WidgetDAOReadOnly
      */
     DPL::OptionalString getCspPolicy() const;
 
+    /**
+     * This method is used as a getter for report only csp policy of widget.
+     * It may be provided in configuration file.
+     * @return global csp report only policy for widget
+     */
+    DPL::OptionalString getCspPolicyReportOnly() const;
+
     /**
      * This method returns list filed with Common Name entries from certificate.
      *
index 9a41d5bc1cfddaadb26ea901220fb90745e45565..4f5f1363d9f78db941ca4bd9e95149666d838273 100755 (executable)
@@ -32,6 +32,7 @@ CREATE_TABLE(WidgetInfo)
     COLUMN(webkit_plugins_required, TINYINT,       DEFAULT 0)
     COLUMN(security_domain,         INT,           DEFAULT 0)
     COLUMN(csp_policy,              TEXT,          DEFAULT '')
+    COLUMN(csp_policy_report_only,  TEXT,          DEFAULT '')
     COLUMN(recognized,              INT,           DEFAULT 0)
     COLUMN(wac_signed,              INT,           DEFAULT 0)
     COLUMN(distributor_signed,      INT,           DEFAULT 0)
@@ -313,20 +314,21 @@ CREATE_TABLE(CRLResponseStorage)
 CREATE_TABLE_END()
 
 CREATE_TABLE(SettingsList)
-    COLUMN_NOT_NULL(appId,         INT,)
-    COLUMN_NOT_NULL(settingName,               TEXT,   )
-    COLUMN_NOT_NULL(settingValue,        TEXT,   )
+    COLUMN_NOT_NULL(appId,          INT,)
+    COLUMN_NOT_NULL(settingName,    TEXT,)
+    COLUMN_NOT_NULL(settingValue,   TEXT,)
     TABLE_CONSTRAINTS(
         FOREIGN KEY (appId) REFERENCES WidgetInfo (app_id) ON DELETE CASCADE
     )
 CREATE_TABLE_END()
 
 CREATE_TABLE(ApplicationServiceInfo)
-    COLUMN_NOT_NULL(app_id,    INT,)
-    COLUMN_NOT_NULL(src,       TEXT,)
-    COLUMN_NOT_NULL(operation, TEXT,)
-    COLUMN_NOT_NULL(scheme,    TEXT,)
-    COLUMN_NOT_NULL(mime,      TEXT,)
+    COLUMN_NOT_NULL(app_id,         INT,)
+    COLUMN_NOT_NULL(src,            TEXT,)
+    COLUMN_NOT_NULL(operation,      TEXT,)
+    COLUMN_NOT_NULL(scheme,         TEXT,)
+    COLUMN_NOT_NULL(mime,           TEXT,)
+    COLUMN_NOT_NULL(disposition,    TINYINT, DEFAULT 0)
 
     TABLE_CONSTRAINTS(
         PRIMARY KEY(app_id, operation, scheme, mime)
index 412ea1ef6af0d8da77c73a26f70f68b63318365e..448f84a5fe19355fb959cd75b019b2292e41d287 100644 (file)
@@ -1,7 +1,7 @@
-#git:framework/web/wrt-commons wrt-commons 0.2.99
+#git:framework/web/wrt-commons wrt-commons 0.2.101
 Name:       wrt-commons
 Summary:    Wrt common library
-Version:    0.2.99
+Version:    0.2.101
 Release:    1
 Group:      Development/Libraries
 License:    Apache License, Version 2.0
@@ -141,8 +141,10 @@ echo "[WRT] wrt-commons postinst done ..."
 %if %{with_tests}
     %attr(755,root,root) %{_bindir}/wrt-commons-tests-*
     %attr(755,root,root) %{_bindir}/wrt_dao_tests_prepare_db.sh
+    %attr(755,root,root) %{_bindir}/wrt_db_localization_prepare.sh
     %{_datadir}/dbus-1/services/org.tizen.DBusTestService.service
     /opt/share/wrt/wrt-commons/tests/*
+    /opt/share/widget/tests/localization/*
 %endif
 
 %files devel
index 8ebf885ea381991a5ef5d911095f622338d694aa..d3a9edf12a9e3f0aafb0f8cc6a8f89d9488de8ac 100644 (file)
@@ -16,10 +16,10 @@ ADD_SUBDIRECTORY(dao)
 ADD_SUBDIRECTORY(db)
 ADD_SUBDIRECTORY(dbus)
 ADD_SUBDIRECTORY(event)
-#ADD_SUBDIRECTORY(files_localization) TODO localization mockups need to be fixed
+ADD_SUBDIRECTORY(files_localization)
 ADD_SUBDIRECTORY(localizationTagsProvider)
 ADD_SUBDIRECTORY(utils)
 ADD_SUBDIRECTORY(test)
 
 # Rollback CXX flags
-#SET(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS_BACKUP})
\ No newline at end of file
+#SET(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS_BACKUP})
index 9e7ffa4da555114d839063c73514a2c24546566b..73e7ec53b185f496dd5e43878cf30eefefda735b 100644 (file)
@@ -45,6 +45,7 @@ SET(DPL_TESTS_CORE_SOURCES
     ${TESTS_DIR}/core/test_scoped_ptr.cpp
     ${TESTS_DIR}/core/test_semaphore.cpp
     ${TESTS_DIR}/core/test_shared_ptr.cpp
+    ${TESTS_DIR}/core/test_static_block.cpp
     ${TESTS_DIR}/core/test_string.cpp
     ${TESTS_DIR}/core/test_thread.cpp
     ${TESTS_DIR}/core/test_type_list.cpp
index dc9b34aaab23f44deee1b92f061198e781714699..c773c4edd343d314c493ce3be047fb95bf818869 100644 (file)
@@ -96,6 +96,10 @@ class COtherClass
     double rubbish; // to ensure this class has non-zero size.
 
   public:
+    COtherClass() :
+        rubbish(0)
+    {}
+
     virtual ~COtherClass()
     {}
 
@@ -106,6 +110,13 @@ class COtherClass
 
 class VeryBigClass
 {
+  public:
+    VeryBigClass() {
+        memset(letsMakeThingsComplicated, 0,
+                400 * sizeof(letsMakeThingsComplicated[0]));
+    }
+
+  private:
     int letsMakeThingsComplicated[400];
 };
 
index 202589b3b35ba78360c6985a71cf004e1111471d..7bbf8def49bd13811eae995a6ea9ad594bdb859e 100644 (file)
@@ -70,7 +70,8 @@ class TestClass : public DPL::ISerializable
         c.push_back(str2);
         c.push_back(str1 + str2);
     }
-    TestClass(DPL::IStream& stream)
+    TestClass(DPL::IStream& stream) :
+        a(0)    //TODO: consider the need (g.rynkowski)
     {
         DPL::Deserialization::Deserialize(stream, a);
         DPL::Deserialization::Deserialize(stream, b);
diff --git a/tests/core/test_static_block.cpp b/tests/core/test_static_block.cpp
new file mode 100644 (file)
index 0000000..0fc686e
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * 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_static_block.cpp
+ * @author     Tomasz Iwanek (t.iwanek@samsung.com)
+ * @version    0.1
+ * @brief
+ */
+
+#include <dpl/test/test_runner.h>
+#include <dpl/static_block.h>
+
+RUNNER_TEST_GROUP_INIT(DPL)
+
+namespace {
+bool ok_namespace = false;
+bool ok_class = false;
+
+STATIC_BLOCK
+{
+    ok_namespace = true;
+}
+
+struct A
+{
+    static void init()
+    {
+        ok_class = true;
+    }
+};
+STATIC_BLOCK_CLASS( A, init );
+}
+
+/*
+Name: StaticBlockInitCheck
+Description: checks if static blocks were run
+Expected: variables should be set
+*/
+RUNNER_TEST(StaticBlockInitCheck)
+{
+    RUNNER_ASSERT(ok_namespace);
+    RUNNER_ASSERT(ok_class);
+}
index 6c73a7bf2c54380713f59d1af1866b20fc21c886..5254a2b9bdc6d086ce0793a3a0d753a3489867cb 100644 (file)
@@ -140,8 +140,8 @@ RUNNER_TEST(plugin_dao_test_register_library_dependencies)
         PluginHandle depHandles[] = { 117, 119 };
 
         PluginHandleSetPtr dependencies(new PluginHandleSet);
+        dependencies->insert(depHandles[0]);
         dependencies->insert(depHandles[1]);
-        dependencies->insert(depHandles[2]);
 
         PluginDAO::registerPluginLibrariesDependencies(handle, dependencies);
 
@@ -153,9 +153,9 @@ RUNNER_TEST(plugin_dao_test_register_library_dependencies)
             retDependencies->size() == sizeof(depHandles) /
             sizeof(depHandles[0]));
         RUNNER_ASSERT(
-            retDependencies->find(depHandles[1]) != retDependencies->end());
+            retDependencies->find(depHandles[0]) != retDependencies->end());
         RUNNER_ASSERT(
-            retDependencies->find(depHandles[2]) != retDependencies->end());
+            retDependencies->find(depHandles[1]) != retDependencies->end());
     }
 }
 
index 500f43d8f272f499edf6d2d55ff3adc9a865fa58..c7c9ea9f7c0fdc8b0332c6f1134833b1714d4bd0 100644 (file)
@@ -589,7 +589,7 @@ RUNNER_TEST(ORM_Delete)
     // properly
     for (std::list<TestTableDelete::Row>::iterator i = originalList.begin();
          i != originalList.end();
-         i++)
+         ++i)
     {
         TestTableDelete::Insert insert(interface.get());
         insert.Values(*i);
@@ -1095,14 +1095,14 @@ RUNNER_TEST(ORM_SelectOrderByMultipleColumns)
                               DPL::FromASCIIString(
                                   "test 6"), "Wrong row 1 order");
             RUNNER_ASSERT_MSG(iter->Get_TestID() == 10, "Wrong row 1 order");
-            iter++;
+            ++iter;
         }
         { //2 row
             RUNNER_ASSERT_MSG(*iter->Get_TestText33() ==
                               DPL::FromASCIIString(
                                   "test 5"), "Wrong row 2 order");
             RUNNER_ASSERT_MSG(iter->Get_TestID() == 7, "Wrong row 2 order");
-            iter++;
+            ++iter;
         }
         { //3 row
             RUNNER_ASSERT_MSG(iter->Get_Value3() == 111, "Wrong row 3 order");
@@ -1110,7 +1110,7 @@ RUNNER_TEST(ORM_SelectOrderByMultipleColumns)
                               DPL::FromASCIIString(
                                   "test 2"), "Wrong row 3 order");
             RUNNER_ASSERT_MSG(iter->Get_TestID() == 2, "Wrong row 3 order");
-            iter++;
+            ++iter;
         }
         { //4 row
             RUNNER_ASSERT_MSG(iter->Get_Value3() == 111, "Wrong row 4 order");
@@ -1118,7 +1118,7 @@ RUNNER_TEST(ORM_SelectOrderByMultipleColumns)
                               DPL::FromASCIIString(
                                   "test 1"), "Wrong row 4 order");
             RUNNER_ASSERT_MSG(iter->Get_TestID() == 1, "Wrong row 4 order");
-            iter++;
+            ++iter;
         }
         { //5 row
             RUNNER_ASSERT_MSG(iter->Get_Value3() == 222, "Wrong row 5 order");
@@ -1126,7 +1126,7 @@ RUNNER_TEST(ORM_SelectOrderByMultipleColumns)
                               DPL::FromASCIIString(
                                   "test 4"), "Wrong row 5 order");
             RUNNER_ASSERT_MSG(iter->Get_TestID() == 6, "Wrong row 5 order");
-            iter++;
+            ++iter;
         }
         { //6 row
             RUNNER_ASSERT_MSG(iter->Get_Value3() == 222, "Wrong row 6 order");
@@ -1134,7 +1134,7 @@ RUNNER_TEST(ORM_SelectOrderByMultipleColumns)
                               DPL::FromASCIIString(
                                   "test 3"), "Wrong row 6 order");
             RUNNER_ASSERT_MSG(iter->Get_TestID() == 3, "Wrong row 6 order");
-            iter++;
+            ++iter;
         }
     }
 }
index 8f0a630b445d230e10695278416543b5a6429232..53087200a45325dbafeecab87c4462618f26d670 100644 (file)
 
 RUNNER_TEST_GROUP_INIT(DPL)
 
+namespace {
+    unsigned int seed = time(NULL);
+}
+
 class IntController :
     public DPL::Event::Controller<DPL::TypeListDecl<int>::Type>
 {
@@ -375,7 +379,7 @@ class TestController :
                 return;
             }
             ++testContextPtr->g_SentCounter;
-            int id = rand() % static_cast<int>(testContextPtr->controllers.size());
+            int id = rand_r(&seed) % static_cast<int>(testContextPtr->controllers.size());
             testContextPtr->controllers.at(id)->DPL::Event::
                 ControllerEventHandler<RandomEvent>::PostEvent(RandomEvent());
         }
index 37d79c196ef19a773db202e14db534c9575f0965..3fdd256f801cec4fd810a482f4aa6abb6b044cab 100644 (file)
 SET(TARGET_LOC "wrt-commons-tests-loc")
 
 SET(LOC_TESTS_SOURCES
-    ${TESTS_DIR}/files_localization/test_localization.cpp
-    ${TESTS_DIR}/files_localization/test_suite01.cpp
-    #${DPL_TESTS_DIR}/localization/mockup_src/widget_dao.cpp
-    #${PROJECT_SOURCE_DIR}/modules/localization/src/localization_utils.cpp
-    #${PROJECT_SOURCE_DIR}/modules/localization/src/w3c_file_localization.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/test_localization.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/test_suite01.cpp
 )
 
-#WRT_INCLUDE_DIRECTORIES(
-    #${SYS_EFL_INCLUDE_DIRS}
-    #${DPL_TEST_INCLUDE_DIR}
-    #${DPL_TESTS_DIR}/localization/mockup_include
-    #${PROJECT_SOURCE_DIR}/modules/localization/include
-#)
-
-#LINK_DIRECTORIES(${SYS_EFL_LIBRARY_DIRS})
-
+WRT_TEST_ADD_INTERNAL_DEPENDENCIES(${TARGET_LOC} ${TARGET_WRT_DAO_RW_LIB} ${TARGET_CUSTOM_HANDLER_DAO_RW_LIB})
 WRT_TEST_BUILD(${TARGET_LOC} ${LOC_TESTS_SOURCES})
 WRT_TEST_INSTALL(${TARGET_LOC})
 
 ADD_SUBDIRECTORY(files)
+
+INSTALL(PROGRAMS "${CMAKE_CURRENT_SOURCE_DIR}/wrt_db_localization_prepare.sh"
+        DESTINATION bin)
index 17c7fda888b15dcce6359d248bbc2e12571c376c..65034d36332dbaaddc374eafb2d27cfb0b6bb62f 100644 (file)
@@ -1,19 +1,19 @@
 INSTALL(FILES
-    ${DPL_TESTS_DIR}/localization/files/one
+    ${CMAKE_CURRENT_SOURCE_DIR}/one
     DESTINATION
-    /opt/share/widget/tests/localization/widget1/locales/pl-en
+    /opt/share/widget/tests/localization/widget1/res/wgt/locales/pl-en
   )
 
 INSTALL(FILES
-    ${DPL_TESTS_DIR}/localization/files/one
-    ${DPL_TESTS_DIR}/localization/files/two
+    ${CMAKE_CURRENT_SOURCE_DIR}/one
+    ${CMAKE_CURRENT_SOURCE_DIR}/two
     DESTINATION
-    /opt/share/widget/tests/localization/widget2/locales/pl-en
+    /opt/share/widget/tests/localization/widget2/res/wgt/locales/pl-en
   )
 
 INSTALL(FILES
-    ${DPL_TESTS_DIR}/localization/files/two
+    ${CMAKE_CURRENT_SOURCE_DIR}/two
     DESTINATION
-    /opt/share/widget/tests/localization/widget2/locales/en-en
+    /opt/share/widget/tests/localization/widget2/res/wgt/locales/en-en
   )
 
index 42ffe3a8469778f35a76dcc71df6e7a51238ae4d..ae4925a7d786bdcfb4743d10d38a0293ce8002e7 100644 (file)
  * @brief       This file is the implementation file of main
  */
 #include <dpl/test/test_runner.h>
+#include <dpl/log/log.h>
+#include <dpl/wrt-dao-ro/WrtDatabase.h>
 
 int main(int argc, char *argv[])
 {
-    return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);
+
+    int ret = system("/usr/bin/wrt_db_localization_prepare.sh start");
+    if (ret != 0) {
+        LogError("Preparation script has return error: " << ret
+                                                         << ". Quitting");
+        return -1;
+    }
+
+    WrtDB::WrtDatabase::attachToThreadRW();
+    int status = DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);
+    WrtDB::WrtDatabase::detachFromThread();
+
+    ret = system("/usr/bin/wrt_db_localization_prepare.sh stop");
+    if (ret != 0) {
+        LogError("Preparation script has return error: " << ret
+                                                         << ". Quitting");
+        return -1;
+    }
+    return status;
 }
 
index d3cb17434e1b1d7237db916aaabe4cddcdb24ba0..d2d28ed1f7a15841fb608b7565ea68a299e3f699 100644 (file)
 
 #include <dpl/log/log.h>
 #include <dpl/test/test_runner.h>
-
-//#include "mockup_include/dpl/wrt-dao-rw/widget_dao.h"
-#include <dpl/wrt-dao-rw/widget_dao.h>
+#include <dpl/static_block.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
 #include <dpl/localization/w3c_file_localization.h>
+#include <LanguageTagsProvider.h>
 
 namespace {
-WrtDB::LanguageTagList generateLanguageTags()
+
+STATIC_BLOCK
 {
     WrtDB::LanguageTagList tags;
     tags.push_back(L"pl-pl");
     tags.push_back(L"en-en");
     tags.push_back(L"pl-en");
-    return tags;
+    LanguageTagsProviderSingleton::Instance().setLanguageTags(tags);
 }
 
-static const WrtDB::LanguageTagList languageTags = generateLanguageTags();
 static const DPL::String widget1Path =
     L"/opt/share/widget/tests/localization/widget1/";
 static const DPL::String widget2Path =
@@ -47,73 +47,68 @@ static const DPL::String widget2Path =
 } // anonymous namespace
 
 RUNNER_TEST(test01_getFilePathInWidgetPackageFromUrl){
-    const int widgetHandle = 1;
-    WrtDB::WidgetDAO dao(widgetHandle);
-    //dao.setPath(widget1Path);
+    WrtDB::WidgetPkgName name = L"tizenid201";
+    WrtDB::WidgetDAOReadOnly dao(name);
 
-    auto result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl(
-            widgetHandle,
-            languageTags,
-            L"widget://one");
+    DPL::Optional<DPL::String> result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl(
+            name,
+            DPL::String(L"widget://one"));
 
+    RUNNER_ASSERT_MSG(!!result, "No result");
     RUNNER_ASSERT(
         *result ==
-        L"/opt/share/widget/tests/localization/widget1/locales/pl-en/one");
+        L"/opt/share/widget/tests/localization/widget1/res/wgt/locales/pl-en/one");
 }
 
 RUNNER_TEST(test02_getFilePathInWidgetPackageFromUrl){
-    const int widgetHandle = 2;
-    WrtDB::WidgetDAO dao(widgetHandle);
-    //dao.setPath(widget2Path);
+    WrtDB::WidgetPkgName name = L"tizenid202";
+    WrtDB::WidgetDAOReadOnly dao(name);
 
-    auto result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl(
-            widgetHandle,
-            languageTags,
-            L"widget://one");
+    DPL::Optional<DPL::String> result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl(
+            name,
+            DPL::String(L"widget://one"));
 
+    RUNNER_ASSERT_MSG(!!result, "No result");
     RUNNER_ASSERT(
         *result ==
-        L"/opt/share/widget/tests/localization/widget2/locales/pl-en/one");
+        L"/opt/share/widget/tests/localization/widget2/res/wgt/locales/pl-en/one");
 }
 
 RUNNER_TEST(test03_getFilePathInWidgetPackageFromUrl){
-    const int widgetHandle = 2;
-    WrtDB::WidgetDAO dao(widgetHandle);
-    //dao.setPath(widget2Path);
+    WrtDB::WidgetPkgName name = L"tizenid202";
+    WrtDB::WidgetDAOReadOnly dao(name);
 
-    auto result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl(
-            widgetHandle,
-            languageTags,
-            L"widget://two");
+    DPL::Optional<DPL::String> result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl(
+            name,
+            DPL::String(L"widget://two"));
 
+    RUNNER_ASSERT_MSG(!!result, "No result");
     RUNNER_ASSERT(
         *result ==
-        L"/opt/share/widget/tests/localization/widget2/locales/en-en/two");
+        L"/opt/share/widget/tests/localization/widget2/res/wgt/locales/en-en/two");
 }
 
 RUNNER_TEST(test04_getFilePathInWidgetPackage){
-    const int widgetHandle = 1;
-    WrtDB::WidgetDAO dao(widgetHandle);
-    //dao.setPath(widget1Path);
+    WrtDB::WidgetPkgName name = L"tizenid201";
+    WrtDB::WidgetDAOReadOnly dao(name);
 
-    auto result = W3CFileLocalization::getFilePathInWidgetPackage(
-            widgetHandle,
-            languageTags,
-            L"one");
+    DPL::Optional<DPL::String> result = W3CFileLocalization::getFilePathInWidgetPackage(
+            name,
+            DPL::String(L"one"));
 
+    RUNNER_ASSERT_MSG(!!result, "No result");
     RUNNER_ASSERT(*result == L"locales/pl-en/one");
 }
 
 RUNNER_TEST(test05_getFilePathInWidgetPackage){
-    const int widgetHandle = 2;
-    WrtDB::WidgetDAO dao(widgetHandle);
-    //dao.setPath(widget2Path);
+    WrtDB::WidgetPkgName name = L"tizenid202";
+    WrtDB::WidgetDAOReadOnly dao(name);
 
-    auto result = W3CFileLocalization::getFilePathInWidgetPackage(
-            widgetHandle,
-            languageTags,
-            L"two");
+    DPL::Optional<DPL::String> result = W3CFileLocalization::getFilePathInWidgetPackage(
+            name,
+            DPL::String(L"two"));
 
+    RUNNER_ASSERT_MSG(!!result, "No result");
     RUNNER_ASSERT(*result == L"locales/en-en/two");
 }
 
diff --git a/tests/files_localization/wrt_db_localization_prepare.sh b/tests/files_localization/wrt_db_localization_prepare.sh
new file mode 100644 (file)
index 0000000..67bed04
--- /dev/null
@@ -0,0 +1,51 @@
+#!/bin/bash
+
+# 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.
+#
+
+set -e
+
+trap 'echo "Script failed"; exit 1' ERR
+
+WRT_DB=/opt/dbspace/.wrt.db
+WRT_DB_BCK=/tmp/wrt.db_backup
+WIDGET_INSTALL_PATH=/opt/usr/apps
+
+case $1 in
+    start)
+        echo "start"
+        cp $WRT_DB $WRT_DB_BCK
+        wrt_commons_create_clean_db.sh
+
+        #Widgets
+        INS_ALL_WIDGETEXT="insert into WidgetExtendedInfo(app_id, installed_path)"
+        INS_ALL_WIDGET="insert into WidgetInfo(app_id, tizen_appid)"
+
+        sqlite3 $WRT_DB "${INS_ALL_WIDGET} VALUES(1, 'tizenid201')";
+        sqlite3 $WRT_DB "${INS_ALL_WIDGET} VALUES(2, 'tizenid202')";
+        sqlite3 $WRT_DB "${INS_ALL_WIDGETEXT} VALUES(1, '/opt/share/widget/tests/localization/widget1')";
+        sqlite3 $WRT_DB "${INS_ALL_WIDGETEXT} VALUES(2, '/opt/share/widget/tests/localization/widget2')";
+        exit 0
+        ;;
+    stop)
+        echo "stop";
+        cp $WRT_DB_BCK $WRT_DB
+        exit 0
+        ;;
+    *)
+        echo "nothing to do"
+        exit 1
+        ;;
+esac
index 4f2d93a4a903637e9b091468f82983e0e1d71c43..a5c6046395f062e096837437211f6f6eac86c9cd 100644 (file)
@@ -558,7 +558,10 @@ class EnumTestSO1 : public TestSharedObject
 
   protected:
     explicit EnumTestSO1(const std::string& semaphore) :
-        TestSharedObject(semaphore) {}
+        TestSharedObject(semaphore),
+        m_waitable(NULL)
+    {}
+
 
     virtual void PropertyChanged(size_t propertyEnum);
 
@@ -1065,7 +1068,7 @@ RUNNER_TEST(SharedMemory_070_SharedObjectListeners)
     RUNNER_ASSERT(g_values[2] == 3);
 
     int array[64];
-    memset(array, 64 * sizeof(array[0]), 0);
+    memset(array, 0, 64 * sizeof(array[0]));
     array[5] = 5;
     sho->SetProperty<3, int[64]>(array);
     Wait(waitable);
@@ -1172,6 +1175,11 @@ RUNNER_TEST(SharedMemory_090_SetPropertyDelegate)
  */
 class LazySharedObject : public SharedObject<TestTypeList>
 {
+  private:
+    LazySharedObject() :
+        m_read(false)
+    {}
+
   public:
     explicit LazySharedObject(const std::string& semaphore) :
         SharedObject<TestTypeList>(semaphore)
@@ -1391,7 +1399,8 @@ class ShmController4 : public ListeningController<MTSharedObject>,
     };
 
     explicit ShmController4(DPL::WaitableEvent* event) :
-        ListeningController<MTSharedObject>(event)
+        ListeningController<MTSharedObject>(event),
+        m_counter(0)
     {}
 
     virtual void OnEventReceived(const int& event);
@@ -1412,6 +1421,7 @@ class ShmController4 : public ListeningController<MTSharedObject>,
     void Sleep();
 
     size_t m_counter;
+    static unsigned int seed = time(NULL);
 };
 
 void ShmController4::ValueChanged(size_t propertyEnum,
@@ -1449,7 +1459,7 @@ void ShmController4::ValueChanged(size_t propertyEnum,
 void ShmController4::Sleep()
 {
     DPL::Thread::GetCurrentThread()->MiliSleep(
-        rand() % MAX_SINGLETON_LISTENER_DELAY);
+        rand_r(&seed) % MAX_SINGLETON_LISTENER_DELAY);
 }
 
 void ShmController4::OnEventReceived(const int& event)
@@ -1531,8 +1541,6 @@ RUNNER_TEST(SharedMemory_130_SharedObjectSingleton)
 {
     RemoveIpcs();   // we need non existing shm
 
-    srand(time(NULL));
-
     // writer shared object
     TestSharedObjectPtr sho = SharedObjectFactory<TestSharedObject>::Create(
             SHM_KEY, SEM_NAME);
index 4525c981ee103ea80f1cd2dca6eee79f5d7ca1ad..bc2b7e0f5364b4315a3e28316f7835c4c7952d38 100644 (file)
 
 RUNNER_TEST(SqlConnection_MassiveReadWrite_SemaphoreSynchronization)
 {
-    srand(time(NULL));
-
     std::ostringstream dbSemaporeFileNameStream;
+    unsigned int seed = time(NULL);
+
     dbSemaporeFileNameStream << "dpl_tests_dbso_sem_";
-    dbSemaporeFileNameStream << rand() << ".sem";
+    dbSemaporeFileNameStream << rand_r(&seed) << ".sem";
 
     std::string dbSemaphoreFileName = dbSemaporeFileNameStream.str();
 
index eb78ed6a7edcc640a5caa7931800b774afd6a52e..710b5785c37758ca09004ad98230c4593d5c0c08 100644 (file)
@@ -89,16 +89,26 @@ RUNNER_TEST(wrt_utility_WrtUtilMakeDir)
 RUNNER_TEST(wrt_utility_WrtUtilMakeDir_PermissionError)
 {
     if (0 == getuid()) {
+        int bufsize;
+        if ((bufsize = sysconf(_SC_GETPW_R_SIZE_MAX)) == -1)
+            RUNNER_ASSERT_MSG(false,
+                    "Getting an initial value suggested for the size of buffer failed.");
+
         //Change UID to execute the test correctly
         errno = 0;
-        struct passwd *p = getpwnam("app");
-        if (p == NULL) {
+        char *buffer = new char[bufsize];
+        struct passwd p;
+        struct passwd *result = NULL;
+        int return_value = getpwnam_r("app", &p, buffer, bufsize, &result);
+        delete[] buffer;
+
+        if (return_value != 0 || !result) {
             int error = errno;
             RUNNER_ASSERT_MSG(false, "Getting app user UID failed: "
                               << (error ==
                                   0 ? "No error detected" : strerror(error)));
         }
-        if (setuid(p->pw_uid) != 0) {
+        if (setuid(p.pw_uid) != 0) {
             int error = errno;
             RUNNER_ASSERT_MSG(false, "Changing to app user's UID failed: "
                               << (error ==