def test_purge(self): """Check we can purge snapshots with a save pattern """ name = PREFIX_TEST_VOLUME + uuid.uuid4().hex # first run the purge without snapshots (should do nothing) resp = self.app.post('/VolumeDriver.Snapshots.Purge', json.dumps({'Name': name, 'Pattern': '2h:2h'})) # create a volume with a file self.create_a_volume_with_a_file(name) def cleanup_snapshots(): btrfs.Subvolume(join(SNAPSHOTS_PATH, PREFIX_TEST_VOLUME) + '*' ).delete(check=False) self.create_20_hourly_snapshots(name) # run the purge with a simple save pattern (2h only once) nb_snaps = len(os.listdir(SNAPSHOTS_PATH)) resp = self.app.post('/VolumeDriver.Snapshots.Purge', json.dumps({'Name': name, 'Pattern': '2h:2h'})) self.assertEqual(jsonloads(resp.body), {'Err': ''}) # check we deleted 17 snapshots self.assertEqual(len(os.listdir(SNAPSHOTS_PATH)), nb_snaps - 17) # run the purge again and check we have one more snapshot deleted, # the oldest at the limit nb_snaps = len(os.listdir(SNAPSHOTS_PATH)) resp = self.app.post('/VolumeDriver.Snapshots.Purge', json.dumps({'Name': name, 'Pattern': '2h:2h'})) self.assertEqual(jsonloads(resp.body), {'Err': ''}) self.assertEqual(len(os.listdir(SNAPSHOTS_PATH)), nb_snaps-1) cleanup_snapshots() self.create_20_hourly_snapshots(name) # run the purge with a more complex save pattern (2h:4h:8h:16h) nb_snaps = len(os.listdir(SNAPSHOTS_PATH)) resp = self.app.post( '/VolumeDriver.Snapshots.Purge', json.dumps({'Name': name, 'Pattern': '2h:4h:8h:16h'})) self.assertEqual(jsonloads(resp.body), {'Err': ''}) # check we deleted 11 snapshots self.assertEqual(len(os.listdir(SNAPSHOTS_PATH)), nb_snaps - 11) cleanup_snapshots() self.create_20_hourly_snapshots(name) # check we have an error with a non numeric pattern resp = self.app.post( '/VolumeDriver.Snapshots.Purge', json.dumps({'Name': name, 'Pattern': '60m:plop:3000m'})) self.assertEqual(jsonloads(resp.body), {'Err': 'Invalid purge pattern'}) # run the purge with a more complex unsorted save pattern nb_snaps = len(os.listdir(SNAPSHOTS_PATH)) resp = self.app.post( '/VolumeDriver.Snapshots.Purge', json.dumps({'Name': name, 'Pattern': '60m:120m:300m:240m:180m'})) self.assertEqual(jsonloads(resp.body), {'Err': ''}) # check we deleted 14 snapshots self.assertEqual(len(os.listdir(SNAPSHOTS_PATH)), nb_snaps - 14) cleanup_snapshots() self.app.post('/VolumeDriver.Remove', json.dumps({'Name': name}))
def get_from(resp, key): """get specified key from plugin response output """ if resp is None: return False try: # bottle content = resp.content except: # TestApp content = resp.body if resp.status_code == 200: error = jsonloads(content)['Err'] if error: log.error(error) return False return jsonloads(content).get(key) else: log.error('%s: %s', resp.status_code, resp.reason) return False
def test(self): """first basic scenario """ # list resp = jsonloads(self.app.post('/VolumeDriver.List', '{}').body) self.assertEqual(resp, {'Volumes': [], 'Err': ''}) # create a volume name = PREFIX_TEST_VOLUME + uuid.uuid4().hex path = join(VOLUMES_PATH, name) resp = jsonloads( self.app.post('/VolumeDriver.Create', json.dumps({'Name': name})).body) self.assertEqual(resp, {'Err': ''}) # get resp = jsonloads( self.app.post('/VolumeDriver.Get', json.dumps({'Name': name})).body) self.assertEqual(resp['Volume']['Name'], name) self.assertEqual(resp['Volume']['Mountpoint'], path) self.assertEqual(resp['Err'], '') # create the same volume resp = jsonloads( self.app.post('/VolumeDriver.Create', json.dumps({'Name': name})).body) self.assertEqual(resp, {'Err': ''}) # list resp = jsonloads(self.app.post('/VolumeDriver.List').body) self.assertEqual(resp['Volumes'], [{u'Name': name}]) # mount resp = jsonloads( self.app.post('/VolumeDriver.Mount', json.dumps({'Name': name})).body) self.assertEqual(resp['Mountpoint'], join(VOLUMES_PATH, name)) resp = jsonloads( self.app.post('/VolumeDriver.Mount', json.dumps({'Name': name})).body) self.assertEqual(resp['Mountpoint'], join(VOLUMES_PATH, name)) # not existing path name2 = PREFIX_TEST_VOLUME + uuid.uuid4().hex resp = jsonloads( self.app.post('/VolumeDriver.Mount', json.dumps({'Name': name2})).body) self.assertTrue(resp['Err'].endswith('no such volume')) # path resp = jsonloads( self.app.post('/VolumeDriver.Path', json.dumps({'Name': name})).body) self.assertEqual(resp['Mountpoint'], join(VOLUMES_PATH, name)) # not existing path resp = jsonloads( self.app.post( '/VolumeDriver.Path', json.dumps({'Name': PREFIX_TEST_VOLUME + uuid.uuid4().hex})).body) self.assertTrue(resp['Err'].endswith('no such volume')) # unmount resp = jsonloads( self.app.post('/VolumeDriver.Unmount', json.dumps({'Name': name})).body) self.assertEqual(resp, {'Err': ''}) resp = jsonloads( self.app.post( '/VolumeDriver.Unmount', json.dumps({'Name': PREFIX_TEST_VOLUME + uuid.uuid4().hex})).body) self.assertEqual(resp, {'Err': ''}) # remove resp = jsonloads( self.app.post('/VolumeDriver.Remove', json.dumps({'Name': name})).body) self.assertEqual(resp, {'Err': ''}) # remove again resp = jsonloads( self.app.post('/VolumeDriver.Remove', json.dumps({'Name': name})).body) self.assertTrue(resp['Err'].endswith("no such volume")) # get resp = jsonloads( self.app.post('/VolumeDriver.Get', json.dumps({'Name': name})).body) self.assertTrue(resp['Err'].endswith("no such volume")) # list resp = jsonloads(self.app.post('/VolumeDriver.List', '{}').body) self.assertEqual(resp['Volumes'], [])