bugfix: Clean stale data on blob creation
It is possible that previous actions has stored stale data that are
valid protobufs, with different parameters. Detect stale data and
overwrite them.
Signed-off-by: Kun Yi <kunyi731@gmail.com>
Change-Id: I25b54885cdab928d1ad0b740d1c9b96335d2c60e
diff --git a/binarystore.cpp b/binarystore.cpp
index 29e6b9f..a18a980 100644
--- a/binarystore.cpp
+++ b/binarystore.cpp
@@ -42,6 +42,11 @@
auto store =
std::make_unique<BinaryStore>(baseBlobId, std::move(file), maxSize);
+ if (!store->loadSerializedData())
+ {
+ return nullptr;
+ }
+
return std::move(store);
}
@@ -79,6 +84,19 @@
return false;
}
+ if (blob_.blob_base_id() != baseBlobId_)
+ {
+ /* Uh oh, stale data loaded. Clean it and commit. */
+ // TODO: it might be safer to add an option in config to error out
+ // instead of to overwrite.
+ log<level::ERR>("Stale blob data, resetting internals...",
+ entry("LOADED=%s", blob_.blob_base_id().c_str()),
+ entry("EXPECTED=%s", baseBlobId_.c_str()));
+ blob_.Clear();
+ blob_.set_blob_base_id(baseBlobId_);
+ return this->commit();
+ }
+
return true;
}
diff --git a/test/fake_sys_file.hpp b/test/fake_sys_file.hpp
index 1c6a45d..eb8d024 100644
--- a/test/fake_sys_file.hpp
+++ b/test/fake_sys_file.hpp
@@ -23,6 +23,13 @@
class FakeSysFile : public SysFile
{
public:
+ FakeSysFile()
+ {
+ }
+ FakeSysFile(const std::string& s) : data_(s)
+ {
+ }
+
size_t readToBuf(size_t pos, size_t count, char* buf) const override
{
auto result = readAsStr(pos, count);
diff --git a/test/handler_unittest.cpp b/test/handler_unittest.cpp
index ef42ea6..31ccdc6 100644
--- a/test/handler_unittest.cpp
+++ b/test/handler_unittest.cpp
@@ -1,10 +1,18 @@
#include "handler_unittest.hpp"
+#include "fake_sys_file.hpp"
+
+#include <google/protobuf/message_lite.h>
+#include <google/protobuf/text_format.h>
+
#include <algorithm>
+#include <boost/endian/arithmetic.hpp>
#include <memory>
#include <string>
#include <vector>
+#include "binaryblob.pb.h"
+
using ::testing::_;
using ::testing::AtLeast;
using ::testing::ElementsAreArray;
@@ -140,4 +148,34 @@
EXPECT_TRUE(handler.deleteBlob(basicTestBlobId));
}
+TEST_F(BinaryStoreBlobHandlerBasicTest, StaleDataIsClearedDuringCreation)
+{
+ using namespace google::protobuf;
+
+ auto basicTestStaleBlobStr =
+ R"(blob_base_id: "/stale/"
+ blobs {
+ blob_id: "/stale/blob"
+ })";
+
+ // Create sysfile containing a valid but stale blob
+ const std::string staleBaseId = "/stale/"s;
+ const std::string staleBlobId = "/stale/blob"s;
+ binaryblobproto::BinaryBlobBase staleBlob;
+ EXPECT_TRUE(TextFormat::ParseFromString(basicTestStaleBlobStr, &staleBlob));
+
+ // Serialize to string stored in the fakeSysFile
+ auto staleBlobData = staleBlob.SerializeAsString();
+ boost::endian::little_uint64_t sizeLE = staleBlobData.size();
+ std::string commitData(sizeLE.data(), sizeof(sizeLE));
+ commitData += staleBlobData;
+
+ std::vector<std::string> expectedIdList = {basicTestBaseId};
+
+ handler.addNewBinaryStore(BinaryStore::createFromConfig(
+ basicTestBaseId, std::make_unique<FakeSysFile>(commitData), 0));
+ EXPECT_FALSE(handler.canHandleBlob(staleBlobId));
+ EXPECT_EQ(handler.getBlobIds(), expectedIdList);
+}
+
} // namespace blobs