def test_new_object_with_invalid_value(self): with self.assertRaises(ValueError): snapshots.SID('20151219-010324-1234', self.cfg) with self.assertRaises(ValueError): snapshots.SID('20151219-01032', self.cfg) with self.assertRaises(ValueError): snapshots.SID('2015121a-010324-1234', self.cfg)
def test_sort_sids(self): root = snapshots.RootSnapshot(self.cfg) new = snapshots.NewSnapshot(self.cfg) sid1 = snapshots.SID('20151219-010324-123', self.cfg) sid2 = snapshots.SID('20151219-020324-123', self.cfg) sid3 = snapshots.SID('20151219-030324-123', self.cfg) sid4 = snapshots.SID('20151219-040324-123', self.cfg) sids1 = [sid3, sid1, sid4, sid2] sids1.sort() self.assertEqual(sids1, [sid1, sid2, sid3, sid4]) #RootSnapshot 'Now' should always stay on top sids2 = [sid3, sid1, root, sid4, sid2] sids2.sort() self.assertEqual(sids2, [sid1, sid2, sid3, sid4, root]) sids2.sort(reverse=True) self.assertEqual(sids2, [root, sid4, sid3, sid2, sid1]) #new_snapshot should always be the last sids3 = [sid3, sid1, new, sid4, sid2] sids3.sort() self.assertEqual(sids3, [sid1, sid2, sid3, sid4, new]) sids3.sort(reverse=True) self.assertEqual(sids3, [new, sid4, sid3, sid2, sid1])
def test_new_object_with_valid_date(self): sid1 = snapshots.SID('20151219-010324-123', self.cfg) sid2 = snapshots.SID('20151219-010324', self.cfg) sid3 = snapshots.SID(datetime(2015, 12, 19, 1, 3, 24), self.cfg) sid4 = snapshots.SID(date(2015, 12, 19), self.cfg) self.assertEqual(sid1.sid, '20151219-010324-123') self.assertEqual(sid2.sid, '20151219-010324') self.assertRegex(sid3.sid, r'20151219-010324-\d{3}') self.assertRegex(sid4.sid, r'20151219-000000-\d{3}')
def test_equal_sid(self): sid1a = snapshots.SID('20151219-010324-123', self.cfg) sid1b = snapshots.SID('20151219-010324-123', self.cfg) sid2 = snapshots.SID('20151219-020324-123', self.cfg) self.assertIsNot(sid1a, sid1b) self.assertTrue(sid1a == sid1b) self.assertTrue(sid1a == '20151219-010324-123') self.assertTrue(sid1a != sid2) self.assertTrue(sid1a != '20151219-020324-123')
def test_takeSnapshot(self, sleep): now = datetime.today() - timedelta(minutes = 6) sid1 = snapshots.SID(now, self.cfg) self.assertListEqual([True, False], self.sn.takeSnapshot(sid1, now, [(self.include.name, 0),])) self.assertTrue(sid1.exists()) self.assertTrue(sid1.canOpenPath(os.path.join(self.include.name, 'foo', 'bar', 'baz'))) self.assertTrue(sid1.canOpenPath(os.path.join(self.include.name, 'test'))) self.assertTrue(sid1.canOpenPath(os.path.join(self.include.name, 'file with spaces'))) for f in ('config', 'fileinfo.bz2', 'info', 'takesnapshot.log.bz2'): self.assertTrue(os.path.exists(sid1.path(f)), msg = 'file = {}'.format(f)) for f in ('failed', 'save_to_continue'): self.assertFalse(os.path.exists(sid1.path(f)), msg = 'file = {}'.format(f)) # second takeSnapshot which should not create a new snapshot as nothing # has changed now = datetime.today() - timedelta(minutes = 4) sid2 = snapshots.SID(now, self.cfg) self.assertListEqual([False, False], self.sn.takeSnapshot(sid2, now, [(self.include.name, 0),])) self.assertFalse(sid2.exists()) # third takeSnapshot self.remount() with open(os.path.join(self.include.name, 'lalala'), 'wt') as f: f.write('asdf') now = datetime.today() - timedelta(minutes = 2) sid3 = snapshots.SID(now, self.cfg) self.assertListEqual([True, False], self.sn.takeSnapshot(sid3, now, [(self.include.name, 0),])) self.assertTrue(sid3.exists()) self.assertTrue(sid3.canOpenPath(os.path.join(self.include.name, 'lalala'))) inode1 = self.getInode(sid1) inode3 = self.getInode(sid3) self.assertEqual(inode1, inode3) # fourth takeSnapshot with force create new snapshot even if nothing # has changed self.cfg.setTakeSnapshotRegardlessOfChanges(True) now = datetime.today() sid4 = snapshots.SID(now, self.cfg) self.assertListEqual([True, False], self.sn.takeSnapshot(sid4, now, [(self.include.name, 0),])) self.assertTrue(sid4.exists()) self.assertTrue(sid4.canOpenPath(os.path.join(self.include.name, 'foo', 'bar', 'baz'))) self.assertTrue(sid4.canOpenPath(os.path.join(self.include.name, 'test')))
def test_hash(self): sid1a = snapshots.SID('20151219-010324-123', self.cfg) sid1b = snapshots.SID('20151219-010324-123', self.cfg) sid2 = snapshots.SID('20151219-020324-123', self.cfg) self.assertEqual(sid1a.__hash__(), sid1b.__hash__()) self.assertNotEqual(sid1a.__hash__(), sid2.__hash__()) s = set() s.add(sid1a) self.assertEqual(len(s), 1) s.add(sid2) self.assertEqual(len(s), 2) s.add(sid1b) self.assertEqual(len(s), 2)
def test_createLastSnapshotSymlink(self): sid1 = snapshots.SID('20151219-010324-123', self.cfg) sid1.makeDirs() symlink = self.cfg.lastSnapshotSymlink() self.assertNotExists(symlink) self.assertTrue(self.sn.createLastSnapshotSymlink(sid1)) self.assertIsLink(symlink) self.assertEqual(os.path.realpath(symlink), sid1.path()) sid2 = snapshots.SID('20151219-020324-123', self.cfg) sid2.makeDirs() self.assertTrue(self.sn.createLastSnapshotSymlink(sid2)) self.assertIsLink(symlink) self.assertEqual(os.path.realpath(symlink), sid2.path())
def test_canOpenPath(self): sid = snapshots.SID('20151219-010324-123', self.cfg) backupPath = os.path.join(self.snapshotPath, '20151219-010324-123', 'backup') os.makedirs(os.path.join(backupPath, 'foo')) #test existing file and non existing file self.assertTrue(sid.canOpenPath('/foo')) self.assertFalse(sid.canOpenPath('/tmp')) #test valid absolute symlink inside snapshot os.symlink(os.path.join(backupPath, 'foo'), os.path.join(backupPath, 'bar')) self.assertIsLink(backupPath, 'bar') self.assertTrue(sid.canOpenPath('/bar')) #test valid relative symlink inside snapshot os.symlink('./foo', os.path.join(backupPath, 'baz')) self.assertIsLink(backupPath, 'baz') self.assertTrue(sid.canOpenPath('/baz')) #test invalid symlink os.symlink(os.path.join(backupPath, 'asdf'), os.path.join(backupPath, 'qwer')) self.assertIsLink(backupPath, 'qwer') self.assertFalse(sid.canOpenPath('/qwer')) #test valid symlink outside snapshot os.symlink('/tmp', os.path.join(backupPath, 'bla')) self.assertIsLink(backupPath, 'bla') self.assertFalse(sid.canOpenPath('/bla'))
def test_fileInfo(self): sid1 = snapshots.SID('20151219-010324-123', self.cfg) os.makedirs(os.path.join(self.snapshotPath, '20151219-010324-123')) infoFile = os.path.join(self.snapshotPath, '20151219-010324-123', 'fileinfo.bz2') d = snapshots.FileInfoDict() d[b'/tmp'] = (123, b'foo', b'bar') d[b'/tmp/foo'] = (456, b'asdf', b'qwer') sid1.fileInfo = d self.assertIsFile(infoFile) #load fileInfo in a new snapshot sid2 = snapshots.SID('20151219-010324-123', self.cfg) self.assertDictEqual(sid2.fileInfo, d)
def test_takeSnapshot_with_spaces_in_exclude(self): now = datetime.today() sid1 = snapshots.SID(now, self.cfg) exclude = os.path.join(self.include.name, 'test path with spaces') generic.create_test_files(exclude) self.cfg.setExclude([exclude]) self.assertListEqual([True, False], self.sn.takeSnapshot(sid1, now, [ (self.include.name, 0), ])) self.assertTrue(sid1.exists()) self.assertTrue( sid1.canOpenPath( os.path.join(self.include.name, 'foo', 'bar', 'baz'))) self.assertTrue( sid1.canOpenPath(os.path.join(self.include.name, 'test'))) self.assertFalse(sid1.canOpenPath(exclude)) for f in ('config', 'fileinfo.bz2', 'info', 'takesnapshot.log.bz2'): self.assertTrue(os.path.exists(sid1.path(f)), msg='file = {}'.format(f)) for f in ('failed', 'save_to_continue'): self.assertFalse(os.path.exists(sid1.path(f)), msg='file = {}'.format(f))
def _createHeaderItem(self, text, endDate): for item in self.iterHeaderItems(): if item.snapshotID().date == endDate: return False item = HeaderItem(text, snapshots.SID(endDate, self.parent.config)) self.addTopLevelItem(item) return True
def test_takeSnapshot_error_without_continue(self, sleep): os.chmod(os.path.join(self.include.name, 'test'), 0o000) self.cfg.setContinueOnErrors(False) now = datetime.today() sid1 = snapshots.SID(now, self.cfg) self.assertListEqual([False, True], self.sn.takeSnapshot(sid1, now, [(self.include.name, 0),])) self.assertFalse(sid1.exists())
def test_takeSnapshot_fail_create_new_snapshot(self, sleep): with generic.mockPermissions(self.snapshotPath, 0o500): now = datetime.today() sid1 = snapshots.SID(now, self.cfg) self.assertListEqual([False, True], self.sn.takeSnapshot(sid1, now, [ (self.include.name, 0), ]))
def test_info(self): sid1 = snapshots.SID('20151219-010324-123', self.cfg) os.makedirs(os.path.join(self.snapshotPath, '20151219-010324-123')) infoFile = os.path.join(self.snapshotPath, '20151219-010324-123', 'info') i1 = configfile.ConfigFile() i1.setStrValue('foo', 'bar') sid1.info = i1 #test if file exist and has correct content self.assertIsFile(infoFile) with open(infoFile, 'rt') as f: self.assertEqual(f.read(), 'foo=bar\n') #new sid instance and test if correct value is returned sid2 = snapshots.SID('20151219-010324-123', self.cfg) i2 = sid2.info self.assertEqual(i2.strValue('foo', 'default'), 'bar')
def test_takeSnapshot_fail_create_new_snapshot(self, sleep): os.chmod(self.snapshotPath, 0o500) now = datetime.today() sid1 = snapshots.SID(now, self.cfg) self.assertListEqual([False, True], self.sn.takeSnapshot(sid1, now, [(self.include.name, 0),])) # fix permissions because cleanup would fial otherwise os.chmod(self.snapshotPath, 0o700)
def test_setLog_binary(self): sid = snapshots.SID('20151219-010324-123', self.cfg) os.makedirs(os.path.join(self.snapshotPath, '20151219-010324-123')) logFile = os.path.join(self.snapshotPath, '20151219-010324-123', 'takesnapshot.log.bz2') sid.setLog(b'foo bar\nbaz') self.assertIsFile(logFile) self.assertEqual('\n'.join(sid.log()), 'foo bar\nbaz')
def test_name(self): sid = snapshots.SID('20151219-010324-123', self.cfg) os.makedirs(os.path.join(self.snapshotPath, '20151219-010324-123')) self.assertEqual(sid.name, '') sid.name = 'foo' with open(sid.path('name'), 'rt') as f: self.assertEqual(f.read(), 'foo') self.assertEqual(sid.name, 'foo')
def test_exists(self): sid = snapshots.SID('20151219-010324-123', self.cfg) self.assertFalse(sid.exists()) os.makedirs(os.path.join(self.snapshotPath, '20151219-010324-123')) self.assertFalse(sid.exists()) os.makedirs( os.path.join(self.snapshotPath, '20151219-010324-123', 'backup')) self.assertTrue(sid.exists())
def test_fileInfo(self): sid1 = snapshots.SID('20151219-010324-123', self.cfg) os.makedirs(os.path.join(self.snapshotPath, '20151219-010324-123')) infoFile = os.path.join(self.snapshotPath, '20151219-010324-123', 'fileinfo.bz2') d = {} d['/tmp'] = (123, 'foo', 'bar') d['/tmp/foo'] = (456, 'asdf', 'qwer') sid1.fileInfo = d self.assertTrue(os.path.isfile(infoFile)) #load fileInfo in a new snapshot sid2 = snapshots.SID('20151219-010324-123', self.cfg) self.assertDictEqual(sid2.fileInfo, { '/tmp': (123, 'foo', 'bar'), '/tmp/foo': (456, 'asdf', 'qwer') })
def test_log_filter(self): sid = snapshots.SID('20151219-010324-123', self.cfg) os.makedirs(os.path.join(self.snapshotPath, '20151219-010324-123')) logFile = os.path.join(self.snapshotPath, '20151219-010324-123', 'takesnapshot.log.bz2') sid.setLog('foo bar\n[I] 123\n[C] baz\n[E] bla') self.assertIsFile(logFile) self.assertEqual('\n'.join(sid.log(mode=LogFilter.CHANGES)), 'foo bar\n[C] baz')
def test_fileInfoErrorRead(self, mock_logger): sid = snapshots.SID('20151219-010324-123', self.cfg) os.makedirs(os.path.join(self.snapshotPath, '20151219-010324-123')) infoFile = sid.path(sid.FILEINFO) # remove all permissions from file with open(infoFile, 'wt') as f: pass with generic.mockPermissions(infoFile): self.assertEqual(sid.fileInfo, snapshots.FileInfoDict()) self.assertTrue(mock_logger.called)
def test_displayName(self): sid = snapshots.SID('20151219-010324-123', self.cfg) os.makedirs(os.path.join(self.snapshotPath, '20151219-010324-123')) with open(sid.path('name'), 'wt') as f: f.write('foo') self.assertEqual(sid.displayName, '2015-12-19 01:03:24 - foo') with open(sid.path('failed'), 'wt') as f: pass self.assertRegex(sid.displayName, r'2015-12-19 01:03:24 - foo (.+?)')
def test_takeSnapshot_new_exists(self, sleep): new_snapshot = snapshots.NewSnapshot(self.cfg) new_snapshot.makeDirs() with open(new_snapshot.path('leftover'), 'wt') as f: f.write('foo') now = datetime.today() - timedelta(minutes = 6) sid1 = snapshots.SID(now, self.cfg) self.assertListEqual([True, False], self.sn.takeSnapshot(sid1, now, [(self.include.name, 0),])) self.assertTrue(sid1.exists()) self.assertFalse(os.path.exists(sid1.path('leftover')))
def test_makeDirs(self): sid = snapshots.SID('20151219-010324-123', self.cfg) self.assertTrue(sid.makeDirs()) self.assertTrue(os.path.isdir(os.path.join(self.snapshotPath, '20151219-010324-123', 'backup'))) self.assertTrue(sid.makeDirs('foo', 'bar', 'baz')) self.assertTrue(os.path.isdir(os.path.join(self.snapshotPath, '20151219-010324-123', 'backup', 'foo', 'bar', 'baz')))
def test_smartRemove_keep_first_no_errors(self): sid1 = snapshots.SID('20160424-215134-123', self.cfg) sid2 = snapshots.SID('20160422-030324-123', self.cfg) sid2.makeDirs() sid2.failed = True sid3 = snapshots.SID('20160422-020324-123', self.cfg) sid4 = snapshots.SID('20160422-010324-123', self.cfg) sid5 = snapshots.SID('20160421-013218-123', self.cfg) sid6 = snapshots.SID('20160410-134327-123', self.cfg) sids = [sid1, sid2, sid3, sid4, sid5, sid6] # keep the first healty snapshot keep = self.sn.smartRemoveKeepFirst(sids, date(2016, 4, 20), date(2016, 4, 23), keep_healthy = True) self.assertSetEqual(keep, set((sid3,))) # if all snapshots failed, keep the first at all for sid in (sid3, sid4, sid5): sid.makeDirs() sid.failed = True keep = self.sn.smartRemoveKeepFirst(sids, date(2016, 4, 20), date(2016, 4, 23), keep_healthy = True) self.assertSetEqual(keep, set((sid2,)))
def setUp(self): super(SnapshotsWithSidTestCase, self).setUp() self.sid = snapshots.SID('20151219-010324-123', self.cfg) self.sid.makeDirs() self.testDir = 'foo/bar' self.testDirFullPath = self.sid.pathBackup(self.testDir) self.testFile = 'foo/bar/baz' self.testFileFullPath = self.sid.pathBackup(self.testFile) self.sid.makeDirs(self.testDir) with open(self.sid.pathBackup(self.testFile), 'wt') as f: pass
def test_log(self): sid = snapshots.SID('20151219-010324-123', self.cfg) os.makedirs(os.path.join(self.snapshotPath, '20151219-010324-123')) logFile = os.path.join(self.snapshotPath, '20151219-010324-123', 'takesnapshot.log.bz2') #no log available self.assertRegex(sid.log(), r'Failed to get snapshot log from.*') sid.setLog('foo bar\nbaz') self.assertTrue(os.path.isfile(logFile)) self.assertEqual(sid.log(), 'foo bar\nbaz')
def test_fileInfoErrorWrite(self, mock_logger): sid = snapshots.SID('20151219-010324-123', self.cfg) os.makedirs(os.path.join(self.snapshotPath, '20151219-010324-123')) infoFile = sid.path(sid.FILEINFO) # remove all permissions from file with open(infoFile, 'wt') as f: pass with generic.mockPermissions(infoFile): d = snapshots.FileInfoDict() d[b'/tmp'] = (123, b'foo', b'bar') d[b'/tmp/foo'] = (456, b'asdf', b'qwer') sid.fileInfo = d self.assertTrue(mock_logger.called)
def test_fileInfoErrorRead(self, mock_logger): sid = snapshots.SID('20151219-010324-123', self.cfg) os.makedirs(os.path.join(self.snapshotPath, '20151219-010324-123')) infoFile = sid.path(sid.FILEINFO) # remove all permissions from file with open(infoFile, 'wt') as f: pass os.chmod(infoFile, 0o000) self.assertEqual(sid.fileInfo, snapshots.FileInfoDict()) self.assertTrue(mock_logger.called) # make file read/writeable again for deletion os.chmod(infoFile, 0o600)
def test_failed(self): sid = snapshots.SID('20151219-010324-123', self.cfg) snapshotPath = os.path.join(self.snapshotPath, '20151219-010324-123') failedPath = os.path.join(snapshotPath, sid.FAILED) os.makedirs(snapshotPath) self.assertNotExists(failedPath) self.assertFalse(sid.failed) sid.failed = True self.assertExists(failedPath) self.assertTrue(sid.failed) sid.failed = False self.assertNotExists(failedPath) self.assertFalse(sid.failed)