jbm: it compiles... but bombs in unit tests
2 * VersionDictionary_test.cpp
5 * Created by Jens Alfke on 9/2/09.
6 * Copyright 2009 Jens Alfke. All rights reserved.
7 * BSD-Licensed: See the file "LICENSE.txt" for details.
11 #define VERSIONDICTIONARY_TESTING 1
13 #include <gtest/gtest.h>
14 #include "TestUtils.h"
17 #include "VersionDictionary.h"
22 using namespace Mooseyard;
25 class OverlayVersionDictionary :public OverlayDictionary {
27 OverlayVersionDictionary (File *file)
28 :OverlayDictionary(new VersionDictionary(file))
31 int generation() const {return ((VersionDictionary*)base())->generation();}
32 time_t timestamp() const {return ((VersionDictionary*)base())->timestamp();}
35 saveAs(((VersionDictionary*)base())->file());
38 void saveAs (File *dstFile) {
39 VersionDictionary* oldBase = (VersionDictionary*) base();
40 revertTo( ((VersionDictionary*)base())->_appendAndOpen(overlay(), dstFile, baseReplaced()) );
49 File f("/tmp/jubba", O_RDWR | O_CREAT | O_TRUNC, true);
53 File f("/tmp/jubba", O_RDWR, true);
54 EXPECT_TRUE(f.hasPath("/tmp/jubba"));
55 File::unlink("/tmp/jubba");
56 EXPECT_FALSE(f.hasPath("/tmp/jubba"));
58 File f2("/tmp/jubba", O_RDWR | O_CREAT | O_TRUNC, true);
62 EXPECT_FALSE(f.hasPath("/tmp/jubba"));
63 EXPECT_TRUE(f2.hasPath("/tmp/jubba"));
65 File::unlink("/tmp/jubba");
69 static int TestIterate (File *file) {
70 printf("Iterating the chunks...\n");
74 ChunkIterator it(file, 4);
76 uint16_t type = it.chunk()->type();
77 if (type != lastType) {
79 printf("%6d\n", count);
80 printf("type %u ... ", type);
86 if (type != 0) // don't count padding chunks
90 printf("%6d\n", count);
91 EXPECT_TRUE(it.atEOF());
96 static void TestWithWords (const int nWords) {
97 ASSERT_EQ(8, sizeof(Chunk));
98 ASSERT_EQ(8, sizeof(KeyValueChunk));
100 printf("Building dictionary of %i words...\n", nWords);
103 for( int i=0; i<nWords; i++) {
105 dict.put(Key(kv),kv);
108 time_t startTime = ::time(NULL);
111 File file("/tmp/hashfiletest", O_RDWR | O_CREAT | O_TRUNC, true);
112 VersionDictionary *hf;
114 Timer t("Creating & writing VersionDictionary", nWords);
115 file.write("Ha5h", 4); // VersionDictionary won't write to an empty file
116 hf = VersionDictionary::create(&file, &dict);
118 printf("File size: %llu bytes\n", file.length());
119 ASSERT_TRUE(hf!=NULL);
120 ASSERT_EQ(0, hf->generation());
121 createTime = hf->timestamp();
122 ASSERT_GE(createTime, startTime);
123 ASSERT_LE(createTime, ::time(NULL));
127 File file("/tmp/hashfiletest");
128 VersionDictionary hf(&file);
129 ASSERT_EQ(0, hf.generation());
130 ASSERT_EQ(createTime, hf.timestamp());
132 Timer t("Reading from VersionDictionary", nWords);
133 EXPECT_EQ( nWords , hf.count() );
134 for( int i=0; i<nWords; i++) {
136 Blob value = hf.get(key);
138 ASSERT_TRUE( value.equals(key) ) << "expected '" << key << "', got '" << value << "' (i=" << i <<")";
142 printf("Iterating through the VersionDictionary...\n");
143 Timer t("Iterating VersionDictionary", nWords);
145 for( VersionDictionary::Iterator it(&hf); it; ++it) {
147 ASSERT_TRUE(it.key().length > 0 && it.key().length < 50);
148 ASSERT_TRUE(it.key().equals(it.value()));
149 ASSERT_EQ( 0, ((size_t)it.value().bytes & 0x3) ); // 4-byte aligned
151 ASSERT_EQ(nWords, n);
154 printf("Opening OverlayVersionDictionary...\n");
155 File file("/tmp/hashfiletest", O_RDWR, true);
156 OverlayVersionDictionary hf(&file);
157 EXPECT_EQ( nWords , hf.count() );
158 EXPECT_TRUE(hf.get("abatement").equals("abatement"));
160 hf.put("abaser", "DEBASER");
161 hf.put("growf", "growf");
162 EXPECT_TRUE(hf.remove("abatement"));
164 EXPECT_EQ( nWords, hf.count() );
165 EXPECT_TRUE(hf.get("abaser").equals("DEBASER"));
166 EXPECT_TRUE(hf.get("growf").equals("growf"));
167 EXPECT_EQ( NULL, hf.get("abatement").bytes );
168 EXPECT_TRUE(!hf.contains("abatement"));
171 for( OverlayVersionDictionary::Iterator it(hf); it; ++it) {
173 ASSERT_TRUE(!it.key().equals("abatement"));
175 ASSERT_EQ(nWords, n);
177 printf("Saving OverlayVersionDictionary...\n");
179 Timer t("Saving OverlayVersionDictionary");
182 printf("File size: %llu bytes\n", file.length());
184 EXPECT_EQ( nWords, hf.count() );
185 EXPECT_TRUE(hf.get("abaser").equals("DEBASER"));
186 EXPECT_TRUE(hf.get("growf").equals("growf"));
187 EXPECT_EQ( NULL, hf.get("abatement").bytes );
188 EXPECT_TRUE(!hf.contains("abatement"));
191 for( OverlayVersionDictionary::Iterator it(hf); it; ++it) {
193 ASSERT_TRUE(!it.key().equals("abatement"));
195 ASSERT_EQ(nWords, n);
198 printf("Re-opening OverlayVersionDictionary...\n");
199 File file("/tmp/hashfiletest");
200 OverlayVersionDictionary hf(&file);
202 ASSERT_EQ(1, hf.generation());
203 ASSERT_GE(hf.timestamp(), createTime);
204 ASSERT_LE(hf.timestamp(), ::time(NULL));
205 EXPECT_EQ( nWords , hf.count() );
206 EXPECT_TRUE(hf.get("abaser").equals("DEBASER"));
207 EXPECT_TRUE(hf.get("growf").equals("growf"));
208 EXPECT_EQ( NULL, hf.get("abatement").bytes );
209 EXPECT_TRUE(!hf.contains("abatement"));
212 for( OverlayVersionDictionary::Iterator it(hf); it; ++it) {
214 ASSERT_TRUE(!it.key().equals("abatement"));
216 ASSERT_EQ(nWords, n);
218 n = TestIterate(&file);
219 EXPECT_GE(n, nWords+1+4);
221 EXPECT_GE(n, nWords+256+4);
224 printf("Writing VersionDictionary to a new file...\n");
225 File oldFile("/tmp/hashfiletest");
226 OverlayVersionDictionary oldhf(&oldFile);
228 File newFile("/tmp/hashfiletest2", O_RDWR | O_CREAT | O_TRUNC, true);
229 newFile.write("Ha5h", 4); // VersionDictionary won't write to an empty file
230 oldhf.saveAs(&newFile);
231 printf("File size: %llu bytes\n", newFile.length());
234 printf("Opening new file...\n");
235 File file("/tmp/hashfiletest2");
236 OverlayVersionDictionary hf(&file);
238 EXPECT_EQ( nWords , hf.count() );
239 EXPECT_TRUE(hf.get("abaser").equals("DEBASER"));
240 EXPECT_TRUE(hf.get("growf").equals("growf"));
241 EXPECT_EQ( NULL, hf.get("abatement").bytes );
242 EXPECT_TRUE(!hf.contains("abatement"));
245 for( OverlayVersionDictionary::Iterator it(hf); it; ++it) {
247 ASSERT_TRUE(!it.key().equals("abatement"));
249 ASSERT_EQ(nWords, n);
251 n = TestIterate(&file);
252 EXPECT_GE(n, nWords+1+1);
254 EXPECT_EQ(nWords+256+1, n);
259 TEST(VersionDictionary,BuildSmall) {
263 TEST(VersionDictionary,BuildLarge) {
264 TestWithWords(sNWords);