Add deserialization IO exception 74/24574/5
authorAleksander Zdyb <a.zdyb@partner.samsung.com>
Thu, 17 Jul 2014 06:55:45 +0000 (08:55 +0200)
committerGerrit Code Review <gerrit@review.vlan103.tizen.org>
Thu, 17 Jul 2014 15:00:54 +0000 (08:00 -0700)
BucketDeserializationException is thrown, when
bucket file stream could not be opened.

Change-Id: I0930793564beb73cfea937d43155e6953d42a6a1

src/common/exceptions/BucketDeserializationException.h [new file with mode: 0644]
src/common/exceptions/DatabaseException.h [new file with mode: 0644]
src/service/storage/StorageDeserializer.cpp
test/storage/serializer/deserialize.cpp

diff --git a/src/common/exceptions/BucketDeserializationException.h b/src/common/exceptions/BucketDeserializationException.h
new file mode 100644 (file)
index 0000000..2a00555
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2014 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        BucketDeserializationException.h
+ * @author      Aleksander Zdyb <a.zdyb@partner.samsung.com>
+ * @version     1.0
+ * @brief       Implementation of BucketDeserializationException
+ */
+#ifndef SRC_COMMON_EXCEPTIONS_BUCKETDESERIALIZATIONEXCEPTION_H_
+#define SRC_COMMON_EXCEPTIONS_BUCKETDESERIALIZATIONEXCEPTION_H_
+
+#include <exceptions/DatabaseException.h>
+#include <types/PolicyBucketId.h>
+
+namespace Cynara {
+
+class BucketDeserializationException : public DatabaseException {
+public:
+    BucketDeserializationException(const PolicyBucketId &bucketId) : m_bucketId(bucketId) {}
+
+    const std::string message(void) const {
+        if (m_message.empty()) {
+            m_message = "Could not deserialize bucket " + m_bucketId;
+        }
+        return m_message;
+    }
+
+    const PolicyBucketId &bucketId(void) const {
+        return m_bucketId;
+    }
+
+private:
+    mutable std::string m_message;
+    PolicyBucketId m_bucketId;
+};
+
+} /* namespace Cynara */
+
+#endif /* SRC_COMMON_EXCEPTIONS_BUCKETDESERIALIZATIONEXCEPTION_H_ */
diff --git a/src/common/exceptions/DatabaseException.h b/src/common/exceptions/DatabaseException.h
new file mode 100644 (file)
index 0000000..b194fd3
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2014 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        DatabaseException.h
+ * @author      Aleksander Zdyb <a.zdyb@partner.samsung.com>
+ * @version     1.0
+ * @brief       Common class for database exceptions
+ */
+#ifndef SRC_COMMON_EXCEPTIONS_DATABASEEXCEPTION_H_
+#define SRC_COMMON_EXCEPTIONS_DATABASEEXCEPTION_H_
+
+#include <exceptions/Exception.h>
+
+namespace Cynara {
+
+class DatabaseException : public Exception {
+
+};
+
+} /* namespace Cynara */
+
+#endif /* SRC_COMMON_EXCEPTIONS_DATABASEEXCEPTION_H_ */
index 5f1b97b..0510670 100644 (file)
  * @brief       Implementation for Cynara::StorageDeserializer
  */
 
-#include <storage/StorageDeserializer.h>
+#include <iostream>
+#include <string>
 
+#include <exceptions/BucketDeserializationException.h>
 #include <exceptions/BucketRecordCorruptedException.h>
 #include <storage/BucketDeserializer.h>
 #include <storage/StorageSerializer.h>
 
-#include <iostream>
-#include <string>
+#include <storage/StorageDeserializer.h>
 
 namespace Cynara {
 
@@ -63,7 +64,7 @@ void StorageDeserializer::loadBuckets(InMemoryStorageBackend::Buckets &buckets)
         if (bucketDeserializer != nullptr) {
             bucket.setPolicyCollection(bucketDeserializer->loadPolicies());
         } else {
-            // TODO: Throw?
+            throw BucketDeserializationException(bucketId);
         }
     }
 }
index bcd5052..1fd6ad3 100644 (file)
  * @brief       Tests for Cynara::StorageDeserializer
  */
 
+#include <istream>
+#include <memory>
+#include <tuple>
 
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
+#include <exceptions/BucketDeserializationException.h>
 #include <types/PolicyBucket.h>
 #include <storage/StorageDeserializer.h>
 
-#include <tuple>
-#include <memory>
-#include <istream>
-
-
 // TODO: Move to .h, because it's used also in bucket_load.cpp
 MATCHER_P(PolicyPtrEq, policy, "") {
     return std::tie(policy->key(), policy->result())
@@ -113,13 +112,16 @@ TEST_F(StorageDeserializerFixture, init_more) {
 TEST_F(StorageDeserializerFixture, init_overwrite) {
     using ::testing::UnorderedElementsAre;
 
-    std::istringstream ss(";0");
+    std::istringstream ss(";0x0");
     StorageDeserializer deserializer(ss, nullStreamOpener);
 
     InMemoryStorageBackend::Buckets buckets;
+    // Default bucket has ALLOW policy as default
     buckets.insert({ "", PolicyBucket("fakeId", PredefinedPolicyType::ALLOW) });
+
     deserializer.initBuckets(buckets);
 
+    // Check, if default bucket has now DENY as default policy, which would be read from stream
     ASSERT_THAT(buckets, UnorderedElementsAre(
         COMPARE_BUCKETS("", PolicyBucket("", PredefinedPolicyType::DENY))
     ));
@@ -146,7 +148,7 @@ TEST_F(StorageDeserializerFixture, load_buckets_plus_policies) {
 
     deserializer.loadBuckets(buckets);
 
-    // Check if our bucket is still there
+    // Check if pre-inserted bucket is still there
     ASSERT_THAT(buckets, UnorderedElementsAre(
         COMPARE_BUCKETS("", PolicyBucket("", PredefinedPolicyType::DENY))
     ));
@@ -179,13 +181,35 @@ TEST_F(StorageDeserializerFixture, load_buckets) {
 
     // Check, if streamOpener was called for each bucket
     EXPECT_CALL(streamOpener, streamForBucketId(""))
-        .WillOnce(Return(nullptr));
+        .WillOnce(Return(emptyBucketStream()));
 
     EXPECT_CALL(streamOpener, streamForBucketId("bucket1"))
-        .WillOnce(Return(nullptr));
+        .WillOnce(Return(emptyBucketStream()));
 
     EXPECT_CALL(streamOpener, streamForBucketId("bucket2"))
-        .WillOnce(Return(nullptr));
+        .WillOnce(Return(emptyBucketStream()));
 
     deserializer.loadBuckets(buckets);
 }
+
+TEST_F(StorageDeserializerFixture, load_buckets_io_error) {
+    using ::testing::_;
+    using ::testing::Return;
+    using ::testing::UnorderedElementsAre;
+
+    // Pre-insert some buckets
+    InMemoryStorageBackend::Buckets buckets;
+    buckets.insert({ "", PolicyBucket("", PredefinedPolicyType::DENY) });
+
+    std::istringstream bucketsStream; // Won't be used; buckets are pre-inserted above
+    FakeStreamForBucketId streamOpener;
+    auto streamOpenerFunc = std::bind(&FakeStreamForBucketId::streamForBucketId, &streamOpener,
+                                      std::placeholders::_1);
+    StorageDeserializer deserializer(bucketsStream, streamOpenerFunc);
+
+    // Check, if streamOpener was called for each bucket
+    EXPECT_CALL(streamOpener, streamForBucketId(""))
+        .WillOnce(Return(nullptr));
+
+    ASSERT_THROW(deserializer.loadBuckets(buckets), BucketDeserializationException);
+}