source: box/trunk/test/backupstorefix/testbackupstorefix.cpp @ 3040

Revision 3040, 19.5 KB checked in by chris, 7 months ago (diff)

Test that invalid directory entries (pointers to nonexistent objects) are removed properly.

  • Property svn:eol-style set to native
Line 
1// --------------------------------------------------------------------------
2//
3// File
4//              Name:    testbackupstorefix.cpp
5//              Purpose: Test BackupStoreCheck functionality
6//              Created: 23/4/04
7//
8// --------------------------------------------------------------------------
9
10
11#include "Box.h"
12
13#include <stdlib.h>
14#include <string.h>
15#include <stdio.h>
16#include <string>
17#include <map>
18
19#include "Test.h"
20#include "BackupStoreCheck.h"
21#include "BackupStoreConstants.h"
22#include "BackupStoreDirectory.h"
23#include "BackupStoreFile.h"
24#include "FileStream.h"
25#include "RaidFileController.h"
26#include "RaidFileWrite.h"
27#include "RaidFileRead.h"
28#include "BackupStoreInfo.h"
29#include "BackupStoreException.h"
30#include "RaidFileException.h"
31#include "StoreStructure.h"
32#include "BackupStoreFileWire.h"
33#include "ServerControl.h"
34
35#include "MemLeakFindOn.h"
36
37/*
38
39Errors checked:
40
41make some BackupDirectoryStore objects, CheckAndFix(), then verify
42        - multiple objects with same ID
43        - wrong order of old flags
44        - all old flags
45
46delete store info
47add spurious file
48delete directory (should appear again)
49change container ID of directory
50delete a file
51double reference to a file inside a single dir
52modify the object ID of a directory
53delete directory, which has no members (will be removed)
54extra reference to a file in another dir (higher ID to allow consistency -- use something in subti)
55delete dir + dir2 in dir/dir2/file where nothing in dir2 except file, file should end up in lost+found
56similarly with a dir, but that should get a dirxxx name
57corrupt dir
58corrupt file
59delete root, copy a file to it instead (equivalent to deleting it too)
60
61*/
62
63std::string storeRoot("backup/01234567/");
64int discSetNum = 0;
65
66std::map<std::string, int32_t> nameToID;
67std::map<int32_t, bool> objectIsDir;
68
69#define RUN_CHECK       \
70        ::system(BBSTOREACCOUNTS " -c testfiles/bbstored.conf check 01234567"); \
71        ::system(BBSTOREACCOUNTS " -c testfiles/bbstored.conf check 01234567 fix");
72
73// Get ID of an object given a filename
74int32_t getID(const char *name)
75{
76        std::map<std::string, int32_t>::iterator i(nameToID.find(std::string(name)));
77        TEST_THAT(i != nameToID.end());
78        if(i == nameToID.end()) return -1;
79       
80        return i->second;
81}
82
83// Get the RAID filename of an object
84std::string getObjectName(int32_t id)
85{
86        std::string fn;
87        StoreStructure::MakeObjectFilename(id, storeRoot, discSetNum, fn, false);
88        return fn;
89}
90
91// Delete an object
92void DeleteObject(const char *name)
93{
94        RaidFileWrite del(discSetNum, getObjectName(getID(name)));
95        del.Delete();
96}
97
98// Load a directory
99void LoadDirectory(const char *name, BackupStoreDirectory &rDir)
100{
101        std::auto_ptr<RaidFileRead> file(RaidFileRead::Open(discSetNum, getObjectName(getID(name))));
102        rDir.ReadFromStream(*file, IOStream::TimeOutInfinite);
103}
104// Save a directory back again
105void SaveDirectory(const char *name, const BackupStoreDirectory &rDir)
106{
107        RaidFileWrite d(discSetNum, getObjectName(getID(name)));
108        d.Open(true /* allow overwrite */);
109        rDir.WriteToStream(d);
110        d.Commit(true /* write now! */);
111}
112
113void CorruptObject(const char *name, int start, const char *rubbish)
114{
115        int rubbish_len = ::strlen(rubbish);
116        std::string fn(getObjectName(getID(name)));
117        std::auto_ptr<RaidFileRead> r(RaidFileRead::Open(discSetNum, fn));
118        RaidFileWrite w(discSetNum, fn);
119        w.Open(true /* allow overwrite */);
120        // Copy beginning
121        char buf[2048];
122        r->Read(buf, start, IOStream::TimeOutInfinite);
123        w.Write(buf, start);
124        // Write rubbish
125        r->Seek(rubbish_len, IOStream::SeekType_Relative);
126        w.Write(rubbish, rubbish_len);
127        // Copy rest of file
128        r->CopyStreamTo(w);
129        r->Close();
130        // Commit
131        w.Commit(true /* convert now */);
132}
133
134BackupStoreFilename fnames[3];
135
136typedef struct
137{
138        int name;
139        int64_t id;
140        int flags;
141} dir_en_check;
142
143void check_dir(BackupStoreDirectory &dir, dir_en_check *ck)
144{
145        BackupStoreDirectory::Iterator i(dir);
146        BackupStoreDirectory::Entry *en;
147       
148        while((en = i.Next()) != 0)
149        {
150                TEST_THAT(ck->name != -1);
151                if(ck->name == -1)
152                {
153                        break;
154                }
155                TEST_THAT(en->GetName() == fnames[ck->name]);
156                TEST_THAT(en->GetObjectID() == ck->id);
157                TEST_THAT(en->GetFlags() == ck->flags);
158                ++ck;
159        }
160       
161        TEST_THAT(en == 0);
162        TEST_THAT(ck->name == -1);
163}
164
165typedef struct
166{
167        int64_t id, depNewer, depOlder;
168} checkdepinfoen;
169
170void check_dir_dep(BackupStoreDirectory &dir, checkdepinfoen *ck)
171{
172        BackupStoreDirectory::Iterator i(dir);
173        BackupStoreDirectory::Entry *en;
174       
175        while((en = i.Next()) != 0)
176        {
177                TEST_THAT(ck->id != -1);
178                if(ck->id == -1)
179                {
180                        break;
181                }
182                TEST_THAT(en->GetObjectID() == ck->id);
183                TEST_THAT(en->GetDependsNewer() == ck->depNewer);
184                TEST_THAT(en->GetDependsOlder() == ck->depOlder);
185                ++ck;
186        }
187       
188        TEST_THAT(en == 0);
189        TEST_THAT(ck->id == -1);
190}
191
192void test_dir_fixing()
193{
194        {
195                MEMLEAKFINDER_NO_LEAKS;
196                fnames[0].SetAsClearFilename("x1");
197                fnames[1].SetAsClearFilename("x2");
198                fnames[2].SetAsClearFilename("x3");
199        }
200
201        {
202                BackupStoreDirectory dir;
203                dir.AddEntry(fnames[0], 12, 2 /* id */, 1, BackupStoreDirectory::Entry::Flags_File, 2);
204                dir.AddEntry(fnames[1], 12, 2 /* id */, 1, BackupStoreDirectory::Entry::Flags_File, 2);
205                dir.AddEntry(fnames[0], 12, 3 /* id */, 1, BackupStoreDirectory::Entry::Flags_File, 2);
206                dir.AddEntry(fnames[0], 12, 5 /* id */, 1, BackupStoreDirectory::Entry::Flags_File | BackupStoreDirectory::Entry::Flags_OldVersion, 2);
207               
208                dir_en_check ck[] = {
209                        {1, 2, BackupStoreDirectory::Entry::Flags_File},
210                        {0, 3, BackupStoreDirectory::Entry::Flags_File | BackupStoreDirectory::Entry::Flags_OldVersion},
211                        {0, 5, BackupStoreDirectory::Entry::Flags_File},
212                        {-1, 0, 0}
213                };
214               
215                TEST_THAT(dir.CheckAndFix() == true);
216                TEST_THAT(dir.CheckAndFix() == false);
217                check_dir(dir, ck);
218        }
219
220        {
221                BackupStoreDirectory dir;
222                dir.AddEntry(fnames[0], 12, 2 /* id */, 1, BackupStoreDirectory::Entry::Flags_File, 2);
223                dir.AddEntry(fnames[1], 12, 10 /* id */, 1, BackupStoreDirectory::Entry::Flags_File | BackupStoreDirectory::Entry::Flags_Dir | BackupStoreDirectory::Entry::Flags_OldVersion, 2);
224                dir.AddEntry(fnames[0], 12, 3 /* id */, 1, BackupStoreDirectory::Entry::Flags_File | BackupStoreDirectory::Entry::Flags_OldVersion, 2);
225                dir.AddEntry(fnames[0], 12, 5 /* id */, 1, BackupStoreDirectory::Entry::Flags_File | BackupStoreDirectory::Entry::Flags_OldVersion, 2);
226               
227                dir_en_check ck[] = {
228                        {0, 2, BackupStoreDirectory::Entry::Flags_File | BackupStoreDirectory::Entry::Flags_OldVersion},
229                        {1, 10, BackupStoreDirectory::Entry::Flags_Dir},
230                        {0, 3, BackupStoreDirectory::Entry::Flags_File | BackupStoreDirectory::Entry::Flags_OldVersion},
231                        {0, 5, BackupStoreDirectory::Entry::Flags_File},
232                        {-1, 0, 0}
233                };
234               
235                TEST_THAT(dir.CheckAndFix() == true);
236                TEST_THAT(dir.CheckAndFix() == false);
237                check_dir(dir, ck);
238        }
239
240        // Test dependency fixing
241        {
242                BackupStoreDirectory dir;
243                BackupStoreDirectory::Entry *e2
244                  = dir.AddEntry(fnames[0], 12, 2 /* id */, 1, BackupStoreDirectory::Entry::Flags_File | BackupStoreDirectory::Entry::Flags_OldVersion, 2);
245                TEST_THAT(e2 != 0);
246                e2->SetDependsNewer(3);
247                BackupStoreDirectory::Entry *e3
248                  = dir.AddEntry(fnames[0], 12, 3 /* id */, 1, BackupStoreDirectory::Entry::Flags_File | BackupStoreDirectory::Entry::Flags_OldVersion, 2);
249                TEST_THAT(e3 != 0);
250                e3->SetDependsNewer(4); e3->SetDependsOlder(2);
251                BackupStoreDirectory::Entry *e4
252                  = dir.AddEntry(fnames[0], 12, 4 /* id */, 1, BackupStoreDirectory::Entry::Flags_File | BackupStoreDirectory::Entry::Flags_OldVersion, 2);
253                TEST_THAT(e4 != 0);
254                e4->SetDependsNewer(5); e4->SetDependsOlder(3);
255                BackupStoreDirectory::Entry *e5
256                  = dir.AddEntry(fnames[0], 12, 5 /* id */, 1, BackupStoreDirectory::Entry::Flags_File, 2);
257                TEST_THAT(e5 != 0);
258                e5->SetDependsOlder(4);
259               
260                // This should all be nice and valid
261                TEST_THAT(dir.CheckAndFix() == false);
262                static checkdepinfoen c1[] = {{2, 3, 0}, {3, 4, 2}, {4, 5, 3}, {5, 0, 4}, {-1, 0, 0}};
263                check_dir_dep(dir, c1);
264
265                // Check that dependency forwards are restored
266                e4->SetDependsOlder(34343);
267                TEST_THAT(dir.CheckAndFix() == true);
268                TEST_THAT(dir.CheckAndFix() == false);
269                check_dir_dep(dir, c1);
270
271                // Check that a spurious depends older ref is undone
272                e2->SetDependsOlder(1);
273                TEST_THAT(dir.CheckAndFix() == true);
274                TEST_THAT(dir.CheckAndFix() == false);
275                check_dir_dep(dir, c1);
276
277                // Now delete an entry, and check it's cleaned up nicely
278                dir.DeleteEntry(3);
279                TEST_THAT(dir.CheckAndFix() == true);
280                TEST_THAT(dir.CheckAndFix() == false);
281                static checkdepinfoen c2[] = {{4, 5, 0}, {5, 0, 4}, {-1, 0, 0}};
282                check_dir_dep(dir, c2);
283        }
284}
285
286int test(int argc, const char *argv[])
287{
288        // Test the backupstore directory fixing
289        test_dir_fixing();
290
291        // Initialise the raidfile controller
292        RaidFileController &rcontroller = RaidFileController::GetController();
293        rcontroller.Initialise("testfiles/raidfile.conf");
294
295        // Create an account
296        TEST_THAT_ABORTONFAIL(::system(BBSTOREACCOUNTS
297                " -c testfiles/bbstored.conf "
298                "create 01234567 0 10000B 20000B") == 0);
299        TestRemoteProcessMemLeaks("bbstoreaccounts.memleaks");
300
301        // Start the bbstored server
302        int bbstored_pid = LaunchServer(BBSTORED " testfiles/bbstored.conf", 
303                "testfiles/bbstored.pid");
304        TEST_THAT(bbstored_pid > 0);
305        if (bbstored_pid <= 0) return 1;
306       
307        ::sleep(1);
308        TEST_THAT(ServerIsAlive(bbstored_pid));
309
310        // Run the perl script to create the initial directories
311        TEST_THAT_ABORTONFAIL(::system(PERL_EXECUTABLE
312                " testfiles/testbackupstorefix.pl init") == 0);
313
314        std::string cmd = BBACKUPD " " + bbackupd_args +
315                " testfiles/bbackupd.conf";
316        int bbackupd_pid = LaunchServer(cmd, "testfiles/bbackupd.pid");
317        TEST_THAT(bbackupd_pid > 0);
318        if (bbackupd_pid <= 0) return 1;
319
320        ::safe_sleep(1);
321        TEST_THAT(ServerIsAlive(bbackupd_pid));
322
323        // Wait 4 more seconds for the files to be old enough
324        // to upload
325        ::safe_sleep(4);
326
327        // Upload files to create a nice store directory
328        ::sync_and_wait();
329
330        // Stop bbackupd
331        #ifdef WIN32
332                terminate_bbackupd(bbackupd_pid);
333                // implicit check for memory leaks
334        #else
335                TEST_THAT(KillServer(bbackupd_pid));
336                TestRemoteProcessMemLeaks("bbackupd.memleaks");
337        #endif
338
339        // Add a reference to a file that doesn't exist, check that it's removed
340        {
341                std::string fn;
342                StoreStructure::MakeObjectFilename(1 /* root */, storeRoot,
343                        discSetNum, fn, true /* EnsureDirectoryExists */);
344
345                std::auto_ptr<RaidFileRead> file(RaidFileRead::Open(discSetNum,
346                        fn));
347                BackupStoreDirectory dir;
348                dir.ReadFromStream(*file, IOStream::TimeOutInfinite);
349               
350                dir.AddEntry(fnames[0], 12, 0x1234567890123456LL /* id */, 1,
351                        BackupStoreDirectory::Entry::Flags_File, 2);
352               
353                RaidFileWrite d(discSetNum, fn);
354                d.Open(true /* allow overwrite */);
355                dir.WriteToStream(d);
356                d.Commit(true /* write now! */);
357
358                file = RaidFileRead::Open(discSetNum, fn);
359                dir.ReadFromStream(*file, IOStream::TimeOutInfinite);
360                TEST_THAT(dir.FindEntryByID(0x1234567890123456LL) != 0);
361
362                // Check it
363                BackupStoreCheck checker(storeRoot, discSetNum,
364                        0x01234567, true /* FixErrors */, false /* Quiet */);
365                checker.Check();
366                TEST_EQUAL(1, checker.GetNumErrorsFound());
367
368                file = RaidFileRead::Open(discSetNum, fn);
369                dir.ReadFromStream(*file, IOStream::TimeOutInfinite);
370                TEST_THAT(dir.FindEntryByID(0x1234567890123456LL) == 0);
371        }
372
373        if (failures > 0) return 1;
374       
375        // Generate a list of all the object IDs
376        TEST_THAT_ABORTONFAIL(::system(BBACKUPQUERY " -Wwarning "
377                "-c testfiles/bbackupd.conf \"list -r\" quit "
378                "> testfiles/initial-listing.txt") == 0);
379
380        // And load it in
381        {
382                FILE *f = ::fopen("testfiles/initial-listing.txt", "r");
383                TEST_THAT_ABORTONFAIL(f != 0);
384                char line[512];
385                int32_t id;
386                char flags[32];
387                char name[256];
388                while(::fgets(line, sizeof(line), f) != 0)
389                {
390                        TEST_THAT(::sscanf(line, "%x %s %s", &id, 
391                                flags, name) == 3);
392                        bool isDir = (::strcmp(flags, "-d---") == 0);
393                        //TRACE3("%x,%d,%s\n", id, isDir, name);
394                        MEMLEAKFINDER_NO_LEAKS;
395                        nameToID[std::string(name)] = id;
396                        objectIsDir[id] = isDir;
397                }
398                ::fclose(f);
399        }
400
401        // ------------------------------------------------------------------------------------------------             
402        ::printf("  === Delete store info, add random file\n");
403        {
404                // Delete store info
405                RaidFileWrite del(discSetNum, storeRoot + "info");
406                del.Delete();
407        }
408        {
409                // Add a spurious file
410                RaidFileWrite random(discSetNum, 
411                        storeRoot + "randomfile");
412                random.Open();
413                random.Write("test", 4);
414                random.Commit(true);
415        }
416
417        // Fix it
418        RUN_CHECK
419
420        // Check everything is as it was
421        TEST_THAT(::system(PERL_EXECUTABLE
422                " testfiles/testbackupstorefix.pl check 0") == 0);
423        // Check the random file doesn't exist
424        {
425                TEST_THAT(!RaidFileRead::FileExists(discSetNum, 
426                        storeRoot + "01/randomfile"));
427        }
428
429        // ------------------------------------------------------------------------------------------------             
430        ::printf("  === Delete an entry for an object from dir, change that object to be a patch, check it's deleted\n");
431        {
432                // Open dir and find entry
433                int64_t delID = getID("Test1/cannes/ict/metegoguered/oats");
434                {
435                        BackupStoreDirectory dir;
436                        LoadDirectory("Test1/cannes/ict/metegoguered", dir);
437                        TEST_THAT(dir.FindEntryByID(delID) != 0);
438                        dir.DeleteEntry(delID);
439                        SaveDirectory("Test1/cannes/ict/metegoguered", dir);
440                }
441               
442                // Adjust that entry
443                //
444                // IMPORTANT NOTE: There's a special hack in testbackupstorefix.pl to make sure that
445                // the file we're modifiying has at least two blocks so we can modify it and produce a valid file
446                // which will pass the verify checks.
447                //
448                std::string fn(getObjectName(delID));
449                {
450                        std::auto_ptr<RaidFileRead> file(RaidFileRead::Open(discSetNum, fn));
451                        RaidFileWrite f(discSetNum, fn);
452                        f.Open(true /* allow overwrite */);
453                        // Make a copy of the original
454                        file->CopyStreamTo(f);
455                        // Move to header in both
456                        file->Seek(0, IOStream::SeekType_Absolute);
457                        BackupStoreFile::MoveStreamPositionToBlockIndex(*file);
458                        f.Seek(file->GetPosition(), IOStream::SeekType_Absolute);
459                        // Read header
460                        struct
461                        {
462                                file_BlockIndexHeader hdr;
463                                file_BlockIndexEntry e[2];
464                        } h;
465                        TEST_THAT(file->Read(&h, sizeof(h)) == sizeof(h));
466                        file->Close();
467
468                        // Modify
469                        TEST_THAT(box_ntoh64(h.hdr.mOtherFileID) == 0);
470                        TEST_THAT(box_ntoh64(h.hdr.mNumBlocks) >= 2);
471                        h.hdr.mOtherFileID = box_hton64(2345); // don't worry about endianness
472                        h.e[0].mEncodedSize = box_hton64((box_ntoh64(h.e[0].mEncodedSize)) + (box_ntoh64(h.e[1].mEncodedSize)));
473                        h.e[1].mOtherBlockIndex = box_hton64(static_cast<uint64_t>(-2));
474                        // Write to modified file
475                        f.Write(&h, sizeof(h));
476                        // Commit new version
477                        f.Commit(true /* write now! */);
478                }
479
480                // Fix it
481                RUN_CHECK
482                // Check
483                TEST_THAT(::system(PERL_EXECUTABLE
484                        " testfiles/testbackupstorefix.pl check 1") 
485                        == 0);
486
487                // Check the modified file doesn't exist
488                TEST_THAT(!RaidFileRead::FileExists(discSetNum, fn));
489        }
490       
491        // ------------------------------------------------------------------------------------------------             
492        ::printf("  === Delete directory, change container ID of another, duplicate entry in dir, spurious file size, delete file\n");
493        {
494                BackupStoreDirectory dir;
495                LoadDirectory("Test1/foreomizes/stemptinevidate/ict", dir);
496                dir.SetContainerID(73773);
497                SaveDirectory("Test1/foreomizes/stemptinevidate/ict", dir);
498        }
499        int64_t duplicatedID = 0;
500        int64_t notSpuriousFileSize = 0;
501        {
502                BackupStoreDirectory dir;
503                LoadDirectory("Test1/cannes/ict/peep", dir);
504                // Duplicate the second entry
505                {
506                        BackupStoreDirectory::Iterator i(dir);
507                        i.Next();
508                        BackupStoreDirectory::Entry *en = i.Next();
509                        TEST_THAT(en != 0);
510                        duplicatedID = en->GetObjectID();
511                        dir.AddEntry(*en);
512                }
513                // Adjust file size of first file
514                {
515                        BackupStoreDirectory::Iterator i(dir);
516                        BackupStoreDirectory::Entry *en = i.Next(BackupStoreDirectory::Entry::Flags_File);
517                        TEST_THAT(en != 0);
518                        notSpuriousFileSize = en->GetSizeInBlocks();
519                        en->SetSizeInBlocks(3473874);
520                        TEST_THAT(en->GetSizeInBlocks() == 3473874);
521                }
522                SaveDirectory("Test1/cannes/ict/peep", dir);
523        }
524        // Delete a directory
525        DeleteObject("Test1/pass/cacted/ming");
526        // Delete a file
527        DeleteObject("Test1/cannes/ict/scely");
528        // Fix it
529        RUN_CHECK
530        // Check everything is as it should be
531        TEST_THAT(::system(PERL_EXECUTABLE
532                " testfiles/testbackupstorefix.pl check 2") == 0);
533        {
534                BackupStoreDirectory dir;
535                LoadDirectory("Test1/foreomizes/stemptinevidate/ict", dir);
536                TEST_THAT(dir.GetContainerID() == getID("Test1/foreomizes/stemptinevidate"));
537        }
538        {
539                BackupStoreDirectory dir;
540                LoadDirectory("Test1/cannes/ict/peep", dir);
541                BackupStoreDirectory::Iterator i(dir);
542                // Count the number of entries with the ID which was duplicated
543                int count = 0;
544                BackupStoreDirectory::Entry *en = 0;
545                while((en = i.Next()) != 0)
546                {
547                        if(en->GetObjectID() == duplicatedID)
548                        {
549                                ++count;
550                        }
551                }
552                TEST_THAT(count == 1);
553                // Check file size has changed
554                {
555                        BackupStoreDirectory::Iterator i(dir);
556                        BackupStoreDirectory::Entry *en = i.Next(BackupStoreDirectory::Entry::Flags_File);
557                        TEST_THAT(en != 0);
558                        TEST_THAT(en->GetSizeInBlocks() == notSpuriousFileSize);
559                }
560        }
561
562        // ------------------------------------------------------------------------------------------------             
563        ::printf("  === Modify the obj ID of dir, delete dir with no members, add extra reference to a file\n");
564        // Set bad object ID
565        {
566                BackupStoreDirectory dir;
567                LoadDirectory("Test1/foreomizes/stemptinevidate/ict", dir);
568                dir.TESTONLY_SetObjectID(73773);
569                SaveDirectory("Test1/foreomizes/stemptinevidate/ict", dir);
570        }
571        // Delete dir with no members
572        DeleteObject("Test1/dir-no-members");
573        // Add extra reference
574        {
575                BackupStoreDirectory dir;
576                LoadDirectory("Test1/divel", dir);
577                BackupStoreDirectory::Iterator i(dir);
578                BackupStoreDirectory::Entry *en = i.Next(BackupStoreDirectory::Entry::Flags_File);
579                TEST_THAT(en != 0);
580                BackupStoreDirectory dir2;
581                LoadDirectory("Test1/divel/torsines/cruishery", dir2);
582                dir2.AddEntry(*en);
583                SaveDirectory("Test1/divel/torsines/cruishery", dir2);
584        }
585        // Fix it
586        RUN_CHECK
587        // Check everything is as it should be
588        TEST_THAT(::system(PERL_EXECUTABLE
589                " testfiles/testbackupstorefix.pl check 3") == 0);
590        {
591                BackupStoreDirectory dir;
592                LoadDirectory("Test1/foreomizes/stemptinevidate/ict", dir);
593                TEST_THAT(dir.GetObjectID() == getID("Test1/foreomizes/stemptinevidate/ict"));
594        }
595       
596        // ------------------------------------------------------------------------------------------------             
597        ::printf("  === Orphan files and dirs without being recoverable\n");
598        DeleteObject("Test1/dir1");             
599        DeleteObject("Test1/dir1/dir2");               
600        // Fix it
601        RUN_CHECK
602        // Check everything is where it is predicted to be
603        TEST_THAT(::system(PERL_EXECUTABLE
604                " testfiles/testbackupstorefix.pl check 4") == 0);
605
606        // ------------------------------------------------------------------------------------------------             
607        ::printf("  === Corrupt file and dir\n");
608        // File
609        CorruptObject("Test1/foreomizes/stemptinevidate/algoughtnerge",
610                33, "34i729834298349283479233472983sdfhasgs");
611        // Dir
612        CorruptObject("Test1/cannes/imulatrougge/foreomizes",23, 
613                "dsf32489sdnadf897fd2hjkesdfmnbsdfcsfoisufio2iofe2hdfkjhsf");
614        // Fix it
615        RUN_CHECK
616        // Check everything is where it should be
617        TEST_THAT(::system(PERL_EXECUTABLE
618                " testfiles/testbackupstorefix.pl check 5") == 0);
619
620        // ------------------------------------------------------------------------------------------------             
621        ::printf("  === Overwrite root with a file\n");
622        {
623                std::auto_ptr<RaidFileRead> r(RaidFileRead::Open(discSetNum, getObjectName(getID("Test1/pass/shuted/brightinats/milamptimaskates"))));
624                RaidFileWrite w(discSetNum, getObjectName(1 /* root */));
625                w.Open(true /* allow overwrite */);
626                r->CopyStreamTo(w);
627                w.Commit(true /* convert now */);
628        }
629        // Fix it
630        RUN_CHECK
631        // Check everything is where it should be
632        TEST_THAT(::system(PERL_EXECUTABLE
633                " testfiles/testbackupstorefix.pl reroot 6") == 0);
634
635
636        // ---------------------------------------------------------
637        // Stop server
638        TEST_THAT(KillServer(bbstored_pid));
639
640        #ifdef WIN32
641                TEST_THAT(unlink("testfiles/bbstored.pid") == 0);
642        #else
643                TestRemoteProcessMemLeaks("bbstored.memleaks");
644        #endif
645
646        return 0;
647}
648
Note: See TracBrowser for help on using the repository browser.