1// tstore5.cpp -- Regression test program, storage tests, part 5 2// $Id: tstore5.cpp 1230 2007-03-09 15:58:53Z jcw $ 3// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html 4 5#include "regress.h" 6 7void TestStores5() { 8 B(s40, LoadFrom after commit, 0)W(s40a); 9 { 10 c4_IntProp p1("p1"); 11 12 { 13 // create datafile by streaming out 14 c4_Storage s1; 15 s1.SetStructure("a[p1:I]"); 16 17 c4_View v1 = s1.View("a"); 18 v1.Add(p1[123]); 19 A(p1(v1[0]) == 123); 20 A(v1.GetSize() == 1); 21 22 c4_FileStream fs1(fopen("s40a", "wb"), true); 23 s1.SaveTo(fs1); 24 } 25 { 26 // it should load just fine 27 c4_Storage s2; 28 c4_FileStream fs1(fopen("s40a", "rb"), true); 29 bool ok = s2.LoadFrom(fs1); 30 A(ok); 31 32 c4_View v1 = s2.View("a"); 33 A(p1(v1[0]) == 123); 34 A(v1.GetSize() == 1); 35 } 36 { 37 // open the datafile and commit a change 38 c4_Storage s3("s40a", true); 39 40 c4_View v1 = s3.View("a"); 41 A(p1(v1[0]) == 123); 42 A(v1.GetSize() == 1); 43 p1(v1[0]) = 456; 44 s3.Commit(); 45 A(p1(v1[0]) == 456); 46 A(v1.GetSize() == 1); 47 } 48 { 49 // it should load fine and show the last changes 50 c4_Storage s4; 51 c4_FileStream fs1(fopen("s40a", "rb"), true); 52 bool ok = s4.LoadFrom(fs1); 53 A(ok); 54 55 c4_View v1 = s4.View("a"); 56 A(p1(v1[0]) == 456); 57 A(v1.GetSize() == 1); 58 } 59 { 60 // it should open just fine in the normal way as well 61 c4_Storage s5("s40a", false); 62 c4_View v1 = s5.View("a"); 63 A(p1(v1[0]) == 456); 64 A(v1.GetSize() == 1); 65 } 66 } 67 D(s40a); 68 R(s40a); 69 E; 70 71 // 2002-03-13: failure on Win32, Modify calls base class GetNthMemoCol 72 B(s41, Partial modify blocked, 0)W(s41a); 73 { 74 c4_BytesProp p1("p1"); 75 c4_Storage s1("s41a", true); 76 c4_View v1 = s1.GetAs("a[_B[p1:B]]"); 77 78 // custom viewers did not support partial access in 2.4.3 79 c4_View v2 = v1.Blocked(); 80 s1.Commit(); 81 82 v2.SetSize(1); 83 84 c4_BytesRef m = p1(v2[0]); 85 m.Modify(c4_Bytes("abcdefgh", 8), 0); 86 87 s1.Commit(); 88 89 } 90 D(s41a); 91 R(s41a); 92 E; 93 94 B(s42, Get descriptions, 0) { 95 c4_Storage s1; 96 s1.SetStructure("a[p1:I],b[p2:S]"); 97 98 c4_String x1 = s1.Description(); 99 A(x1 == "a[p1:I],b[p2:S]"); 100 101 c4_String x2 = s1.Description("b"); 102 A(x2 == "p2:S"); 103 104 const char *cp = s1.Description("c"); 105 A(cp == 0); 106 } 107 E; 108 109 // 2002-04-24: VPI subview ints clobbered 110 B(s43, View reuse after sub-byte ints, 0)W(s43a); 111 { 112 c4_IntProp p1("p1"); 113 c4_Storage s1("s43a", true); 114 c4_View v1 = s1.GetAs("a[p1:I]"); 115 116 v1.Add(p1[0]); 117 v1.Add(p1[1]); 118 s1.Commit(); 119 120 v1.SetSize(1); // 1 is an even trickier bug than 0 121 s1.Commit(); 122 123 // adding the following two lines works around the 2.4.4 bug 124 //s1.Rollback(); 125 //v1 = s1.GetAs("a[p1:I]"); 126 127 v1.Add(p1[12345]); 128 s1.Commit(); 129 130 //int n = p1 (v1[1]); 131 A(p1(v1[1]) == 12345); 132 133 } 134 D(s43a); 135 R(s43a); 136 E; 137 138 B(s44, Bad memo free space, 0)W(s44a); 139 { 140 c4_IntProp p1("p1"); 141 c4_BytesProp p2("p2"); 142 c4_Storage s1("s44a", true); 143 c4_View v1 = s1.GetAs("a[p1:I,p2:B]"); 144 145 c4_Bytes data; 146 t4_byte *p = data.SetBuffer(12345); 147 for (int i = 0; i < data.Size(); ++i) 148 p[i] = (t4_byte)i; 149 150 v1.Add(p2[data]); 151 s1.Commit(); 152 153 p1(v1[0]) = 1; 154 s1.Commit(); 155 156 p1(v1[0]) = 0; 157 s1.Commit(); 158 159 c4_Bytes temp = p2(v1[0]); 160 A(temp == data); // this failed in 2.4.5 161 162 } 163 D(s44a); 164 R(s44a); 165 E; 166 167 B(s45, Bad subview memo free space, 0)W(s45a); 168 { 169 c4_IntProp p1("p1"); 170 c4_ViewProp p2("p2"); 171 c4_BytesProp p3("p3"); 172 c4_Storage s1("s45a", true); 173 c4_View v1 = s1.GetAs("a[p1:I,p2[p3:B]]"); 174 175 c4_Bytes data; 176 t4_byte *p = data.SetBuffer(12345); 177 for (int i = 0; i < data.Size(); ++i) 178 p[i] = (t4_byte)i; 179 180 v1.SetSize(1); 181 c4_View v2 = p2(v1[0]); 182 v2.Add(p3[data]); 183 s1.Commit(); 184 185 p1(v1[0]) = 1; 186 s1.Commit(); 187 188 p1(v1[0]) = 0; 189 s1.Commit(); 190 191 c4_View v3 = p2(v1[0]); 192 c4_Bytes temp = p3(v3[0]); 193 A(temp == data); // this failed in 2.4.5 194 195 } 196 D(s45a); 197 R(s45a); 198 E; 199 200 B(s46, LoadFrom after commit, 0)W(s46a); 201 { 202 c4_IntProp p1("p1"); 203 204 { 205 c4_Storage s1("s46a", true); 206 s1.SetStructure("a[p1:I]"); 207 c4_View v1 = s1.View("a"); 208 209 v1.Add(p1[11]); 210 v1.Add(p1[22]); 211 v1.Add(p1[33]); 212 v1.Add(p1[44]); 213 v1.Add(p1[55]); 214 v1.Add(p1[66]); 215 v1.Add(p1[77]); 216 v1.Add(p1[88]); 217 v1.Add(p1[99]); 218 219 s1.Commit(); 220 } 221 { 222 c4_Storage s2("s46a", true); 223 c4_View v2 = s2.View("a"); 224 225 v2.Add(p1[1000]); // force 1->2 byte ints 226 v2.InsertAt(7, c4_Row()); 227 v2.InsertAt(4, c4_Row()); 228 229 //for (int i = 6; i <= 9; ++i) printf("%d\n", (int) p1 (v2[i])); 230 231 A(p1(v2[6]) == 66); 232 A(p1(v2[8]) == 0); 233 A(p1(v2[9]) == 88); 234 A(p1(v2[7]) == 77); // this failed in 2.4.6 235 236 s2.Commit(); 237 } 238 } 239 D(s46a); 240 R(s46a); 241 E; 242 243 // 2004-01-16 bad property type crashes MK 2.4.9.2 and before 244 // this hits an assertion in debug mode, so then it has to be disabled 245 B(s47, Defining bad property type, 0) { 246 c4_IntProp p1("p2"); 247 248 c4_Storage s1; 249#if defined(NDEBUG) 250 c4_View v1 = s1.GetAs("v1[p1:A]"); 251#else 252 // assertions are enabled, turn this into a dummy test instead 253 c4_View v1 = s1.GetAs("v1[p1:I]"); 254#endif 255 v1.Add(p1[123]); 256 257 A(v1.GetSize() == 1); 258 A(p1(v1[0]) == 123); 259 } 260 E; 261 262 // 2004-01-18 file damaging bug, when resizing a comitted subview 263 // to empty, committing, and then resizing back to containing data. 264 // Fortunately this usage pattern never happened in blocked views! 265 B(s48, Resize subview to zero and back, 0)W(s48a); 266 W(s48b); 267 { 268 { 269 c4_Storage s1("s48a", true); 270 c4_View v1 = s1.GetAs("v1[v2[p1:I]]"); 271 v1.SetSize(1); 272 s1.Commit(); 273 } 274 { 275 c4_Storage s1("s48a", true); 276 c4_View v1 = s1.View("v1"); 277 v1.SetSize(0); 278 s1.Commit(); 279 // the problem is that the in-memory copy has forgotten that it 280 // has nothing left on disk, and a comparison is done later on to 281 // avoid saving unmodified data - the bad decision is that data has 282 // not changed, but actually it has and must be reallocated! 283 // (fixes are in c4_FormatV::Insert and c4_FormatV::Remove) 284 v1.SetSize(1); 285 s1.Commit(); 286 // at this point, the 2.4.9.2 file is corrupt! 287 c4_FileStream fs1(fopen("s48b", "wb"), true); 288 s1.SaveTo(fs1); 289 } 290 { 291 // using this damaged datafile will then crash 292 c4_Storage s1("s48a", false); 293 c4_View v1 = s1.View("v1"); 294 v1.SetSize(2); 295 } 296 } 297 D(s48a); 298 D(s48b); 299 R(s48a); 300 R(s48b); 301 E; 302 303 // 2004-01-20 better handling of bad input: ignore repeated props 304 B(s49, Specify conflicting properties, 0)W(s49a); 305 { 306 c4_Storage s1("s49a", true); 307 c4_View v1 = s1.GetAs("v1[p1:I,p1:S]"); 308 c4_View v2 = s1.GetAs("v2[p1:I,P1:S]"); 309 c4_View v3 = s1.GetAs("v3[v3[^]]"); 310 c4_String x1 = s1.Description(); 311 A(x1 == "v1[p1:I],v2[p1:I],v3[v3[^]]"); 312 s1.Commit(); 313 } 314 D(s49a); 315 R(s49a); 316 E; 317 318 B(s50, Free space usage, 0)W(s50a); 319 { 320 t4_i32 c, b; 321 c4_IntProp p1("p1"); 322 323 c4_Storage s1("s50a", true); 324 c4_View v1 = s1.GetAs("a[p1:I]"); 325 326 v1.Add(p1[12345]); 327 328 s1.Commit(); 329 c = s1.FreeSpace(&b); 330 A(c == 0); 331 A(b == 0); 332 333 v1.Add(p1[2345]); 334 335 s1.Commit(); 336 c = s1.FreeSpace(&b); 337 A(c == 1); 338 A(b == 18); 339 s1.Commit(); 340 c = s1.FreeSpace(&b); 341 A(c == 1); 342 A(b == 6); 343 344 v1.Add(p1[345]); 345 346 s1.Commit(); 347 c = s1.FreeSpace(&b); 348 A(c == 2); 349 A(b == 56); 350 s1.Commit(); 351 c = s1.FreeSpace(&b); 352 A(c == 1); 353 A(b == 44); 354 //fprintf(stderr, "c %d b %d\n", c, b); 355 } 356 D(s50a); 357 R(s50a); 358 E; 359} 360