def test_schedule_purge(self): # create a volume with a file name = PREFIX_TEST_VOLUME + uuid.uuid4().hex self.create_a_volume_with_a_file(name) self.create_20_hourly_snapshots(name) # schedule a purge of the volumes self.app.post( '/VolumeDriver.Schedule', json.dumps({ 'Name': name, 'Action': 'purge:2h:2h', 'Timer': 60 })) SCHEDULE_LOG.setdefault('purge:2h:2h', {}) SCHEDULE_LOG['purge:2h:2h'][name] = datetime.now() - timedelta( minutes=90) nb_snaps = len(os.listdir(SNAPSHOTS_PATH)) scheduler(SCHEDULE, test=True) self.assertEqual(len(os.listdir(SNAPSHOTS_PATH)), nb_snaps - 18) # unschedule self.app.post( '/VolumeDriver.Schedule', json.dumps({ 'Name': name, 'Action': 'purge:2h:2h', 'Timer': 0 }))
def test_schedule_replicate(self): # create a volume with a file name = PREFIX_TEST_VOLUME + uuid.uuid4().hex self.create_a_volume_with_a_file(name) # check we have no schedule resp = self.app.get('/VolumeDriver.Schedule.List') schedule = json.loads(resp.body.decode())['Schedule'] self.assertEqual(len(schedule), 0) # check we have no snapshots resp = self.app.post('/VolumeDriver.Snapshot.List', json.dumps({})) snapshots = json.loads(resp.body.decode())['Snapshots'] self.assertEqual(len(snapshots), 0) # replicate the volume every 120 minutes self.app.post('/VolumeDriver.Schedule', json.dumps( {'Name': name, 'Action': 'replicate:localhost', 'Timer': 120})) # also replicate a non existing volume self.app.post('/VolumeDriver.Schedule', json.dumps( {'Name': 'boo', 'Action': 'replicate:localhost', 'Timer': 120})) # simulate we spent more time SCHEDULE_LOG.setdefault('replicate:localhost', {}) SCHEDULE_LOG['replicate:localhost' ][name] = datetime.now() - timedelta(1) # run the scheduler and check we only have two more snapshots scheduler(SCHEDULE, test=True) self.assertEqual( 2, len({s for s in os.listdir(SNAPSHOTS_PATH) if s.startswith(name) or s.startswith(name)})) self.assertEqual( 1, len({s for s in os.listdir(TEST_REMOTE_PATH) if s.startswith(name) or s.startswith(name)})) # unschedule the last job self.app.post('/VolumeDriver.Schedule', json.dumps( {'Name': 'boo', 'Action': 'replicate:localhost', 'Timer': 0})) self.app.post('/VolumeDriver.Schedule', json.dumps( {'Name': name, 'Action': 'replicate:localhost', 'Timer': 0}))
def test_schedule_snapshot(self): """check we can schedule actions such as snapshots """ # create two volumes with a file name = PREFIX_TEST_VOLUME + uuid.uuid4().hex self.create_a_volume_with_a_file(name) name2 = PREFIX_TEST_VOLUME + uuid.uuid4().hex self.create_a_volume_with_a_file(name2) # check we have no schedule resp = self.app.get('/VolumeDriver.Schedule.List') schedule = json.loads(resp.body.decode())['Schedule'] self.assertEqual(len(schedule), 0) # schedule a snapshot of the two volumes every 60 minutes self.app.post('/VolumeDriver.Schedule', json.dumps( {'Name': name, 'Action': 'snapshot', 'Timer': 60})) self.app.post('/VolumeDriver.Schedule', json.dumps( {'Name': name2, 'Action': 'snapshot', 'Timer': 60})) # check we have 2 scheduled jobs resp = self.app.get('/VolumeDriver.Schedule.List') schedule = json.loads(resp.body.decode())['Schedule'] self.assertEqual(len(schedule), 2) self.assertEqual(schedule[0]['Action'], 'snapshot') self.assertEqual(schedule[1]['Timer'], '60') # check that the schedule is stored with open(SCHEDULE) as f: lines = f.readlines() self.assertEqual(lines[1], '{},snapshot,60\n'.format(name)) # run the scheduler scheduler(SCHEDULE, test=True) # check we have two snapshots self.assertEqual( 2, len({s for s in os.listdir(SNAPSHOTS_PATH) if s.startswith(name) or s.startswith(name2)})) # unschedule self.app.post('/VolumeDriver.Schedule', json.dumps( {'Name': name, 'Action': 'snapshot', 'Timer': 0})) with open(SCHEDULE) as f: lines = f.readlines() self.assertEqual(len(lines), 1) # check we have 1 scheduled job resp = self.app.get('/VolumeDriver.Schedule.List') schedule = json.loads(resp.body.decode())['Schedule'] self.assertEqual(len(schedule), 1) # simulate we spent more time SCHEDULE_LOG['snapshot'][name2] = datetime.now() - timedelta(1) # run the scheduler and check we only have one more snapshot scheduler(SCHEDULE, test=True) self.assertEqual( 3, len({s for s in os.listdir(SNAPSHOTS_PATH) if s.startswith(name) or s.startswith(name2)})) # unschedule the last job self.app.post('/VolumeDriver.Schedule', json.dumps( {'Name': name2, 'Action': 'snapshot', 'Timer': 0})) resp = self.app.get('/VolumeDriver.Schedule.List') schedule = json.loads(resp.body.decode())['Schedule'] self.assertEqual(len(schedule), 0) # unschedule self.app.post('/VolumeDriver.Schedule', json.dumps( {'Name': name, 'Action': 'snapshot', 'Timer': 0}))
def test_schedule_synchronization(self): # create a volume with a file name = PREFIX_TEST_VOLUME + uuid.uuid4().hex path = join(VOLUMES_PATH, name) remote_path = join(TEST_REMOTE_PATH, name) self.create_a_volume_with_a_file(name) # check we have no schedule resp = self.app.get('/VolumeDriver.Schedule.List') schedule = json.loads(resp.body.decode())['Schedule'] self.assertEqual(len(schedule), 0) # check we have no snapshots resp = self.app.post('/VolumeDriver.Snapshot.List', json.dumps({})) snapshots = json.loads(resp.body.decode())['Snapshots'] self.assertEqual(len(snapshots), 0) # synchronize the volume every 120 minutes, even some host are not # responding we should synchronise other hosts self.app.post('/VolumeDriver.Schedule', json.dumps( { 'Name': name, 'Action': 'synchronize:localhost,wronghost.mlf', 'Timer': 120 })) # also replicate a non existing volume self.app.post('/VolumeDriver.Schedule', json.dumps( {'Name': 'boo', 'Action': 'synchronize:localhost', 'Timer': 120})) # simulate we spent more time SCHEDULE_LOG.setdefault( 'synchronize:localhost,wronghost.mlf', {} ) SCHEDULE_LOG['synchronize:localhost,wronghost.mlf'][name] = \ datetime.now() - timedelta(1) with TemporaryDirectory(path=remote_path) as remote_path: with open(join(remote_path, 'foobar'), 'w') as f: f.write('test sync') # run the scheduler and check we only have two more snapshots scheduler(SCHEDULE, test=True) # make sure a snapshot has occure before rsync snapshots = [s for s in os.listdir(SNAPSHOTS_PATH) if s.startswith(name)] self.assertEqual( 1, len(snapshots)) with open(join(SNAPSHOTS_PATH, snapshots[0], 'foobar')) as x: self.assertEqual(x.read(), "foobar") with open(join(path, 'foobar')) as x: self.assertEqual(x.read(), "test sync") # unschedule the last job self.app.post('/VolumeDriver.Schedule', json.dumps( {'Name': 'boo', 'Action': 'synchronize:localhost', 'Timer': 0})) self.app.post('/VolumeDriver.Schedule', json.dumps( { 'Name': name, 'Action': 'synchronize:localhost,wronghost.mlf', 'Timer': 0, } ))