1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
|
#include <gtest/gtest.h>
#include <libaff4.h>
#include <iostream>
class MemoryDataStoreTest: public ::testing::Test {
protected:
MemoryDataStore store;
virtual void SetUp() {
store.Set(URN("hello"), URN("World"), new XSDString("foo"));
};
};
TEST_F(MemoryDataStoreTest, IncompatibleGet) {
RDFBytes result;
// This should fail since the value is the wrong type.
EXPECT_EQ(INCOMPATIBLE_TYPES,
store.Get(URN("hello"), URN("World"), result));
};
TEST_F(MemoryDataStoreTest, StorageTest) {
XSDString result;
EXPECT_EQ(STATUS_OK,
store.Get(URN("hello"), URN("World"), result));
EXPECT_STREQ(result.SerializeToString().c_str(), "foo");
store.Set(URN("hello"), URN("World"), new XSDString("bar"));
// In the current implementation a second Set() overwrites the previous value.
EXPECT_EQ(STATUS_OK,
store.Get(URN("hello"), URN("World"), result));
EXPECT_STREQ(result.SerializeToString().c_str(), "bar");
};
#if defined(HAVE_LIBYAML_CPP)
TEST_F(MemoryDataStoreTest, YamlSerializationTest) {
MemoryDataStore new_store;
unique_ptr<AFF4Stream> output = StringIO::NewStringIO();
store.DumpToYaml(*output);
output->Seek(0, 0);
// Load the new store with the serialized data. For now YAML support is not
// fully implemented.
EXPECT_EQ(NOT_IMPLEMENTED,
new_store.LoadFromYaml(*output));
}
#endif
TEST_F(MemoryDataStoreTest, TurtleSerializationTest) {
MemoryDataStore new_store;
unique_ptr<AFF4Stream> output = StringIO::NewStringIO();
XSDString result;
store.DumpToTurtle(*output, "");
output->Seek(0, 0);
// Load the new store with the serialized data.
EXPECT_EQ(STATUS_OK,
new_store.LoadFromTurtle(*output));
EXPECT_EQ(STATUS_OK,
store.Get(URN("hello"), URN("World"), result));
EXPECT_STREQ(result.SerializeToString().c_str(), "foo");
}
// Add a method to inspect protected internal state.
class AFF4ObjectCacheMock: public AFF4ObjectCache {
public:
AFF4ObjectCacheMock(size_t size): AFF4ObjectCache(size) {};
vector<string> GetKeys() {
vector<string> result;
for (AFF4ObjectCacheEntry *it=lru_list.next; it!=&lru_list; it=it->next) {
result.push_back(it->key);
};
return result;
};
vector<string> GetInUse() {
vector<string> result;
for(auto it: in_use) {
result.push_back(it.first);
};
return result;
};
};
TEST(AFF4ObjectCacheTest, TestLRU) {
AFF4ObjectCacheMock cache(3);
MemoryDataStore resolver;
URN a = URN::NewURNFromFilename("a");
URN b = URN::NewURNFromFilename("b");
URN c = URN::NewURNFromFilename("c");
URN d = URN::NewURNFromFilename("d");
AFF4Object *obj1 = new AFF4Object(&resolver, a);
AFF4Object *obj2 = new AFF4Object(&resolver, b);
AFF4Object *obj3 = new AFF4Object(&resolver, c);
AFF4Object *obj4 = new AFF4Object(&resolver, d);
cache.Put(obj1);
cache.Put(obj2);
cache.Put(obj3);
{
vector<string> result = cache.GetKeys();
EXPECT_EQ(result[0], c.SerializeToString());
EXPECT_EQ(result[1], b.SerializeToString());
EXPECT_EQ(result[2], a.SerializeToString());
};
// This removes the object from the cache and places it in the in_use
// list.
EXPECT_EQ(cache.Get(a), obj1);
{
vector<string> result = cache.GetKeys();
EXPECT_EQ(result.size(), 2);
EXPECT_EQ(result[0], c.SerializeToString());
EXPECT_EQ(result[1], b.SerializeToString());
vector<string> in_use = cache.GetInUse();
EXPECT_EQ(in_use.size(), 1);
EXPECT_EQ(in_use[0], a.SerializeToString());
// Now we return the object. It should now appear in the lru lists.
cache.Return(obj1);
};
{
vector<string> result = cache.GetKeys();
EXPECT_EQ(result.size(), 3);
EXPECT_EQ(result[0], a.SerializeToString());
EXPECT_EQ(result[1], c.SerializeToString());
EXPECT_EQ(result[2], b.SerializeToString());
vector<string> in_use = cache.GetInUse();
EXPECT_EQ(in_use.size(), 0);
}
// Over flow the cache - this should expire the older object.
cache.Put(obj4);
{
vector<string> result = cache.GetKeys();
EXPECT_EQ(result.size(), 3);
EXPECT_EQ(result[0], d.SerializeToString());
EXPECT_EQ(result[1], a.SerializeToString());
EXPECT_EQ(result[2], c.SerializeToString());
};
// b is now expired so not in cache.
EXPECT_EQ(cache.Get(b), (AFF4Object *)NULL);
// Check that remove works
cache.Remove(obj4);
{
EXPECT_EQ(cache.Get(d), (AFF4Object *)NULL);
vector<string> result = cache.GetKeys();
EXPECT_EQ(result.size(), 2);
}
};
|