def fill_up_share(pname, sname, chunk=(1024 * 1024 * 2)): so = Share.objects.get(name=sname) rusage, eusage = share_usage(so.pool, so.qgroup) print('Writing to Share(%s) until quota is exceeded.' % sname) print('Share(%s) Size: %d Usage: %d' % (sname, so.size, rusage)) spath = '/mnt2/%s/%s' % (pname, sname) file_indices = sorted([int(f.split('-')[1]) for f in os.listdir(spath)], reverse=True) counter = 0 if (len(file_indices) > 0): counter = file_indices[0] + 1 quota_exceeded = False while (not quota_exceeded): fname = '%s/file-%d' % (spath, counter) one_mb = 's' * chunk try: with open(fname, 'w') as ofo: for i in range(100): ofo.write(one_mb) except IOError, e: if (re.search('Disk quota exceeded', e.__str__()) is not None): print(e.__str__()) quota_exceeded = True else: raise e run_command(['/usr/bin/sync']) rusage, eusage = share_usage(so.pool, so.qgroup) print('Share(%s) Size: %d Usage: %d' % (sname, so.size, rusage)) counter += 1
def fill_up_share(pname, sname, chunk=(1024 * 1024 * 2)): so = Share.objects.get(name=sname) rusage, eusage = share_usage(so.pool, so.qgroup) print('Writing to Share(%s) until quota is exceeded.' % sname) print('Share(%s) Size: %d Usage: %d' % (sname, so.size, rusage)) spath = '/mnt2/%s/%s' % (pname, sname) file_indices = sorted([int(f.split('-')[1]) for f in os.listdir(spath)], reverse=True) counter = 0 if (len(file_indices) > 0): counter = file_indices[0] + 1 quota_exceeded = False while (not quota_exceeded): fname = '%s/file-%d' % (spath, counter) one_mb = 's' * chunk try: with open(fname, 'w') as ofo: for i in range(100): ofo.write(one_mb) except IOError as e: if (re.search('Disk quota exceeded', e.__str__()) is not None): print(e.__str__()) quota_exceeded = True else: raise e run_command(['/usr/bin/sync']) rusage, eusage = share_usage(so.pool, so.qgroup) print('Share(%s) Size: %d Usage: %d' % (sname, so.size, rusage)) counter += 1
def fill_up_share(pname, sname, chunk=(1024 * 1024 * 2)): so = Share.objects.get(name=sname) rusage, eusage = share_usage(so.pool, so.qgroup) print("Writing to Share(%s) until quota is exceeded." % sname) print("Share(%s) Size: %d Usage: %d" % (sname, so.size, rusage)) spath = "/mnt2/%s/%s" % (pname, sname) file_indices = sorted([int(f.split("-")[1]) for f in os.listdir(spath)], reverse=True) counter = 0 if len(file_indices) > 0: counter = file_indices[0] + 1 quota_exceeded = False while not quota_exceeded: fname = "%s/file-%d" % (spath, counter) one_mb = "s" * chunk try: with open(fname, "w") as ofo: for i in range(100): ofo.write(one_mb) except IOError as e: if re.search("Disk quota exceeded", e.__str__()) is not None: print(e.__str__()) quota_exceeded = True else: raise e run_command(["/usr/bin/sync"]) rusage, eusage = share_usage(so.pool, so.qgroup) print("Share(%s) Size: %d Usage: %d" % (sname, so.size, rusage)) counter += 1
def import_shares(pool, request): disk = Disk.objects.filter(pool=pool)[0].name shares = [s.name for s in Share.objects.filter(pool=pool)] shares_d = shares_info('%s%s' % (settings.MNT_PT, pool.name)) for s in shares: if (s not in shares_d): Share.objects.get(pool=pool, name=s).delete() for s in shares_d: if (s in shares): share = Share.objects.get(name=s) share.qgroup = shares_d[s] rusage, eusage = share_usage(pool, share.qgroup) ts = datetime.utcnow().replace(tzinfo=utc) if (rusage != share.rusage or eusage != share.eusage): share.rusage = rusage share.eusage = eusage su = ShareUsage(name=s, r_usage=rusage, e_usage=eusage, ts=ts) su.save() else: try: su = ShareUsage.objects.filter(name=s).latest('id') su.ts = ts su.count += 1 except ShareUsage.DoesNotExist: su = ShareUsage(name=s, r_usage=rusage, e_usage=eusage, ts=ts) finally: su.save() share.save() continue try: cshare = Share.objects.get(name=s) cshares_d = shares_info('%s%s' % (settings.MNT_PT, cshare.pool.name)) if (s in cshares_d): e_msg = ('Another pool(%s) has a Share with this same ' 'name(%s) as this pool(%s). This configuration is not supported.' ' You can delete one of them manually with this command: ' 'btrfs subvol delete %s[pool name]/%s' % (cshare.pool.name, s, pool.name, settings.MNT_PT, s)) handle_exception(Exception(e_msg), request) else: cshare.pool = pool cshare.qgroup = shares_d[s] cshare.size = pool.size cshare.subvol_name = s cshare.rusage, cshare.eusage = share_usage(pool, cshare.qgroup) cshare.save() except Share.DoesNotExist: pqid = qgroup_create(pool) update_quota(pool, pqid, pool.size * 1024) nso = Share(pool=pool, qgroup=shares_d[s], pqgroup=pqid, name=s, size=pool.size, subvol_name=s) nso.save() mount_share(nso, '%s%s' % (settings.MNT_PT, s))
def import_shares(pool, request): disk = Disk.objects.filter(pool=pool)[0].name shares = [s.name for s in Share.objects.filter(pool=pool)] shares_d = shares_info(pool) for s in shares: if (s not in shares_d): Share.objects.get(pool=pool, name=s).delete() for s in shares_d: if (s in shares): share = Share.objects.get(name=s) share.qgroup = shares_d[s] rusage, eusage = share_usage(pool, share.qgroup) ts = datetime.utcnow().replace(tzinfo=utc) if (rusage != share.rusage or eusage != share.eusage): share.rusage = rusage share.eusage = eusage su = ShareUsage(name=s, r_usage=rusage, e_usage=eusage, ts=ts) su.save() else: try: su = ShareUsage.objects.filter(name=s).latest('id') su.ts = ts su.count += 1 except ShareUsage.DoesNotExist: su = ShareUsage(name=s, r_usage=rusage, e_usage=eusage, ts=ts) finally: su.save() share.save() continue try: cshare = Share.objects.get(name=s) cshares_d = shares_info('%s%s' % (settings.MNT_PT, cshare.pool.name)) if (s in cshares_d): e_msg = ('Another pool(%s) has a Share with this same ' 'name(%s) as this pool(%s). This configuration is not supported.' ' You can delete one of them manually with this command: ' 'btrfs subvol delete %s[pool name]/%s' % (cshare.pool.name, s, pool.name, settings.MNT_PT, s)) handle_exception(Exception(e_msg), request) else: cshare.pool = pool cshare.qgroup = shares_d[s] cshare.size = pool.size cshare.subvol_name = s cshare.rusage, cshare.eusage = share_usage(pool, cshare.qgroup) cshare.save() except Share.DoesNotExist: pqid = qgroup_create(pool) update_quota(pool, pqid, pool.size * 1024) nso = Share(pool=pool, qgroup=shares_d[s], pqgroup=pqid, name=s, size=pool.size, subvol_name=s) nso.save() mount_share(nso, '%s%s' % (settings.MNT_PT, s))
def remove_random_files(pname, sname): so = Share.objects.get(name=sname) rusage, eusage = share_usage(so.pool, so.qgroup) print ('Share(%s) usage before file removal: %d' % (sname, rusage)) spath = ('/mnt2/%s/%s' % (pname, sname)) flist = os.listdir(spath) random.shuffle(flist) rnum = random.randint(0, len(flist)) for i in range(rnum): os.remove('%s/%s' % (spath, flist[i])) run_command(['/usr/bin/sync']) rusage, eusage = share_usage(so.pool, so.qgroup) print ('Share(%s) usage after removing %d files: %d' % (sname, rnum, rusage))
def remove_random_files(pname, sname): so = Share.objects.get(name=sname) rusage, eusage = share_usage(so.pool, so.qgroup) print('Share(%s) usage before file removal: %d' % (sname, rusage)) spath = ('/mnt2/%s/%s' % (pname, sname)) flist = os.listdir(spath) random.shuffle(flist) rnum = random.randint(0, len(flist)) for i in range(rnum): os.remove('%s/%s' % (spath, flist[i])) run_command(['/usr/bin/sync']) rusage, eusage = share_usage(so.pool, so.qgroup) print('Share(%s) usage after removing %d files: %d' % (sname, rnum, rusage))
def post(self, request, sname): try: if (Share.objects.filter(name=sname).exists()): e_msg = ('Share with name: %s already exists.' % sname) handle_exception(Exception(e_msg), request) pool_name = request.DATA['pool'] size = int(request.DATA['size']) pool = None try: pool = Pool.objects.get(name=pool_name) except: e_msg = ('Pool with name: %s does not exist.' % pool_name) handle_exception(Exception(e_msg), request) disk = None try: disk = Disk.objects.filter(pool=pool)[0] except: e_msg = ('Pool with name: %s does not have any disks in it.' % pool_name) handle_exception(Exception(e_msg), request) add_share(pool_name, disk.name, sname) qgroup_id = self._update_quota(pool_name, disk.name, sname, size) cur_usage = int(share_usage(pool_name, disk.name, qgroup_id)) s = Share(pool=pool, qgroup=qgroup_id, name=sname, size=size, free=(size - cur_usage)) s.save() return Response(ShareSerializer(s).data) except RockStorAPIException: raise except Exception, e: handle_exception(e, request)
def put(self, request, sname): try: if (not Share.objects.filter(name=sname).exists()): e_msg = ('Share with name: %s does not exist' % sname) handle_exception(Exception(e_msg), request) share = Share.objects.get(name=sname) new_size = int(request.DATA['size']) self._validate_share_size(request, new_size) disk = Disk.objects.filter(pool=share.pool)[0] qgroup_id = self._update_quota(share.pool.name, disk.name, sname, new_size) cur_usage = share_usage(share.pool.name, disk.name, qgroup_id) if (new_size < cur_usage): e_msg = ('Unable to resize because requested new size(%dKB) ' 'is less than current usage(%dKB) of the share.' % (new_size, cur_usage)) handle_exception(Exception(e_msg), request) share.size = new_size share.save() return Response(ShareSerializer(share).data) except RockStorAPIException: raise except Exception, e: handle_exception(e, request)
def _create(self, share, snap_name, pool_device, request, uvisible, snap_type, writable): if (Snapshot.objects.filter(share=share, name=snap_name).exists()): e_msg = ('Snapshot with name: %s already exists for the ' 'share: %s' % (snap_name, share.name)) handle_exception(Exception(e_msg), request) try: real_name = ('%s_%s' % (share.name, snap_name)) snap_size = 0 qgroup_id = '0/na' if (snap_type != 'receiver'): add_snap(share.pool.name, pool_device, share.subvol_name, real_name, share_prepend=False, readonly=not writable) snap_id = share_id(share.pool.name, pool_device, real_name) qgroup_id = ('0/%s' % snap_id) snap_size = share_usage(share.pool.name, pool_device, qgroup_id) s = Snapshot(share=share, name=snap_name, real_name=real_name, size=snap_size, qgroup=qgroup_id, uvisible=uvisible, snap_type=snap_type, writable=writable) s.save() return Response(SnapshotSerializer(s).data) except Exception, e: e_msg = ('Failed to create snapshot due to a system error.') logger.error(e_msg) logger.exception(e) handle_exception(Exception(e_msg), request)
def _create(self, share, snap_name, pool_device, request, uvisible, snap_type): if (Snapshot.objects.filter(share=share, name=snap_name).exists()): e_msg = ('Snapshot with name: %s already exists for the ' 'share: %s' % (snap_name, share.name)) handle_exception(Exception(e_msg), request) try: real_name = ('%s_%s' % (share.name, snap_name)) snap_size = 0 qgroup_id = '0/na' if (snap_type != 'receiver'): add_snap(share.pool.name, pool_device, share.subvol_name, real_name, share_prepend=False) snap_id = share_id(share.pool.name, pool_device, real_name) qgroup_id = ('0/%s' % snap_id) snap_size = share_usage(share.pool.name, pool_device, qgroup_id) s = Snapshot(share=share, name=snap_name, real_name=real_name, size=snap_size, qgroup=qgroup_id, uvisible=uvisible, snap_type=snap_type) s.save() return Response(SnapshotSerializer(s).data) except Exception, e: e_msg = ('Failed to create snapshot due to a system error.') logger.error(e_msg) logger.exception(e) handle_exception(Exception(e_msg), request)
def import_snapshots(share): snaps_d = snaps_info('%s%s' % (settings.MNT_PT, share.pool.name), share.name) disk = Disk.objects.filter(pool=share.pool)[0].name snaps = [s.name for s in Snapshot.objects.filter(share=share)] for s in snaps: if (s not in snaps_d): Snapshot.objects.get(share=share,name=s).delete() for s in snaps_d: if (s in snaps): so = Snapshot.objects.get(share=share, name=s) else: so = Snapshot(share=share, name=s, real_name=s, writable=snaps_d[s][1], qgroup=snaps_d[s][0]) rusage, eusage = share_usage(share.pool, snaps_d[s][0]) ts = datetime.utcnow().replace(tzinfo=utc) if (rusage != so.rusage or eusage != so.eusage): so.rusage = rusage so.eusage = eusage su = ShareUsage(name=s, r_usage=rusage, e_usage=eusage, ts=ts) su.save() else: try: su = ShareUsage.objects.filter(name=s).latest('id') su.ts = ts su.count += 1 except ShareUsage.DoesNotExist: su = ShareUsage(name=s, r_usage=rusage, e_usage=eusage, ts=ts) finally: su.save() so.save()
def _refresh_snapshots_state(self, share): snaps_d = snaps_info('%s%s' % (settings.MNT_PT, share.pool.name), share.name) disk = Disk.objects.filter(pool=share.pool)[0].name snaps = [s.name for s in Snapshot.objects.filter(share=share)] for s in snaps: if (s not in snaps_d): Snapshot.objects.get(share=share,name=s).delete() for s in snaps_d: if (s in snaps): so = Snapshot.objects.get(share=share, name=s) else: so = Snapshot(share=share, name=s, real_name=s, writable=snaps_d[s][1], qgroup=snaps_d[s][0]) rusage, eusage = share_usage(share.pool, disk, snaps_d[s][0]) ts = datetime.utcnow().replace(tzinfo=utc) if (rusage != so.rusage or eusage != so.eusage): so.rusage = rusage so.eusage = eusage su = ShareUsage(name=s, r_usage=rusage, e_usage=eusage, ts=ts) su.save() else: try: su = ShareUsage.objects.filter(name=s).latest('id') su.ts = ts su.count += 1 except ShareUsage.DoesNotExist: su = ShareUsage(name=s, r_usage=rusage, e_usage=eusage, ts=ts) finally: su.save() so.save()
def _create(self, share, snap_name, request, uvisible, snap_type, writable): if (Snapshot.objects.filter(share=share, name=snap_name).exists()): e_msg = ('Snapshot(%s) already exists for the Share(%s).' % (snap_name, share.name)) handle_exception(Exception(e_msg), request) snap_size = 0 qgroup_id = '0/na' if (snap_type == 'replication'): writable = False add_snap(share.pool, share.subvol_name, snap_name, writable) snap_id = share_id(share.pool, snap_name) qgroup_id = ('0/%s' % snap_id) qgroup_assign(qgroup_id, share.pqgroup, ('%s/%s' % (settings.MNT_PT, share.pool.name))) snap_size, eusage = share_usage(share.pool, qgroup_id) s = Snapshot(share=share, name=snap_name, real_name=snap_name, size=snap_size, qgroup=qgroup_id, uvisible=uvisible, snap_type=snap_type, writable=writable) s.save() return Response(SnapshotSerializer(s).data)
def put(self, request, sname): with self._handle_exception(request): share = self._validate_share(request, sname) if ('size' in request.data): new_size = self._validate_share_size(request, share.pool) disk = Disk.objects.filter(pool=share.pool)[0] qid = qgroup_id(share.pool, share.subvol_name) cur_rusage, cur_eusage = share_usage(share.pool, qid) if (new_size < cur_rusage): e_msg = ('Unable to resize because requested new size(%dKB) ' 'is less than current usage(%dKB) of the share.' % (new_size, cur_rusage)) handle_exception(Exception(e_msg), request) update_quota(share.pool, share.pqgroup, new_size * 1024) share.size = new_size if ('compression' in request.data): new_compression = self._validate_compression(request) if (share.compression_algo != new_compression): share.compression_algo = new_compression mnt_pt = '%s%s' % (settings.MNT_PT, sname) if (new_compression == 'no'): new_compression = '' set_property(mnt_pt, 'compression', new_compression) share.save() return Response(ShareSerializer(share).data)
def _create(self, share, snap_name, pool_device, request, uvisible, snap_type, writable): if (Snapshot.objects.filter(share=share, name=snap_name).exists()): e_msg = ('Snapshot(%s) already exists for the Share(%s).' % (snap_name, share.name)) handle_exception(Exception(e_msg), request) real_name = snap_name snap_size = 0 qgroup_id = '0/na' if (snap_type != 'receiver'): if (snap_type == 'replication'): writable = False add_snap(share.pool, pool_device, share.subvol_name, real_name, readonly=not writable) snap_id = share_id(share.pool, pool_device, real_name) qgroup_id = ('0/%s' % snap_id) snap_size = share_usage(share.pool, pool_device, qgroup_id) s = Snapshot(share=share, name=snap_name, real_name=real_name, size=snap_size, qgroup=qgroup_id, uvisible=uvisible, snap_type=snap_type, writable=writable) s.save() return Response(SnapshotSerializer(s).data)
def put(self, request, sname): with self._handle_exception(request): share = self._validate_share(request, sname) if ('size' in request.data): new_size = self._validate_share_size(request, share.pool) disk = Disk.objects.filter(pool=share.pool)[0] qid = qgroup_id(share.pool, share.subvol_name) cur_rusage, cur_eusage = share_usage(share.pool, qid) if (new_size < cur_rusage): e_msg = ( 'Unable to resize because requested new size(%dKB) ' 'is less than current usage(%dKB) of the share.' % (new_size, cur_rusage)) handle_exception(Exception(e_msg), request) update_quota(share.pool, share.pqgroup, new_size * 1024) share.size = new_size if ('compression' in request.data): new_compression = self._validate_compression(request) if (share.compression_algo != new_compression): share.compression_algo = new_compression mnt_pt = '%s%s' % (settings.MNT_PT, sname) if (new_compression == 'no'): new_compression = '' set_property(mnt_pt, 'compression', new_compression) share.save() return Response(ShareSerializer(share).data)
def btrfs_share_scan(): pools = btrfs_pool_scan() shares = [] for pool in pools: info = shares_info(pool) for i in range(len(info.keys())): share = {} share["name"] = info.keys()[i] share["subvol_name"] = info.keys()[i] share["group"] = info[info.keys()[i]] share["pool"] = pool qid = qgroup_id(pool, share["subvol_name"]) cur_rusage, cur_eusage = share_usage(pool, qid) share["rusage"] = cur_rusage share["eusage"] = cur_eusage share["pqgroup"] = "xxx" # print qgroup_info(pool) shares.append(share) return shares
def main(): if (len(sys.argv) == 1): sys.exit('Usage: %s <pool name>' % sys.argv[0]) pname = sys.argv[1] sname = 'qgroup-test-share1' size = 1024 * 1024 #1 GiB aw = APIWrapper() res = create_share(aw, sname, pname, size) print('Share(%s) created. Size: %d' % (sname, size)) fill_up_share(pname, sname) #expand Share and fillup. repeat 3 times for i in range(3): size += (1024 * 512) resize_share(aw, sname, size) fill_up_share(pname, sname) #remove random files and fillup. repeat 3 times. for i in range(3): #expand a bit so we can actually remove some files. size += (1024 * 128) resize_share(aw, sname, size) remove_random_files(pname, sname) fill_up_share(pname, sname) #remove random files, shrink the pool by half of free'd capacity, fill up. repeat 3 times for i in range(3): #expand a bit so we can actually remove files. size += (1024 * 128) resize_share(aw, sname, size) remove_random_files(pname, sname) so = Share.objects.get(name=sname) rusage, eusage = share_usage(so.pool, so.qgroup) free_space = so.size - rusage print('Free space on Share(%s): %d' % (sname, free_space)) size -= int(free_space / 2) resize_share(aw, sname, size) fill_up_share(pname, sname) res2 = aw.api_call('shares/%s' % sname, calltype='delete', save_error=False) print('Share(%s) deleted.' % sname)
def main(): if (len(sys.argv) == 1): sys.exit('Usage: %s <pool name>' % sys.argv[0]) pname = sys.argv[1] sname = 'qgroup-test-share1' size = 1024 * 1024 #1 GiB aw = APIWrapper() res = create_share(aw, sname, pname, size) print('Share(%s) created. Size: %d' % (sname, size)) fill_up_share(pname, sname) #expand Share and fillup. repeat 3 times for i in range(3): size += (1024 * 512) resize_share(aw, sname, size) fill_up_share(pname, sname) #remove random files and fillup. repeat 3 times. for i in range(3): #expand a bit so we can actually remove some files. size += (1024 * 128) resize_share(aw, sname, size) remove_random_files(pname, sname) fill_up_share(pname, sname) #remove random files, shrink the pool by half of free'd capacity, fill up. repeat 3 times for i in range(3): #expand a bit so we can actually remove files. size += (1024 * 128) resize_share(aw, sname, size) remove_random_files(pname, sname) so = Share.objects.get(name=sname) rusage, eusage = share_usage(so.pool, so.qgroup) free_space = so.size - rusage print('Free space on Share(%s): %d' % (sname, free_space)) size -= int(free_space/2) resize_share(aw, sname, size) fill_up_share(pname, sname) res2 = aw.api_call('shares/%s' % sname, calltype='delete', save_error=False) print('Share(%s) deleted.' % sname)
def put(self, request, sname): with self._handle_exception(request): if (not Share.objects.filter(name=sname).exists()): e_msg = ('Share(%s) does not exist.' % sname) handle_exception(Exception(e_msg), request) share = Share.objects.get(name=sname) new_size = self._validate_share_size(request, share.pool) disk = Disk.objects.filter(pool=share.pool)[0] qgroup_id = self._update_quota(share.pool, disk.name, share.subvol_name, new_size) cur_usage = share_usage(share.pool, disk.name, qgroup_id) if (new_size < cur_usage): e_msg = ('Unable to resize because requested new size(%dKB) ' 'is less than current usage(%dKB) of the share.' % (new_size, cur_usage)) handle_exception(Exception(e_msg), request) share.size = new_size share.save() return Response(ShareSerializer(share).data)
def put(self, request, sname): try: if (not Share.objects.filter(name=sname).exists()): e_msg = ('Share with name: %s does not exist' % sname) handle_exception(Exception(e_msg), request) share = Share.objects.get(name=sname) new_size = int(request.DATA['size']) #if new_size < cur_usage, throw exception disk = Disk.objects.filter(pool=share.pool)[0] qgroup_id = self._update_quota(share.pool.name, disk.name, sname, new_size) cur_usage = share_usage(share.pool.name, disk.name, qgroup_id) share.size = new_size share.free = new_size - cur_usage share.save() return Response(ShareSerializer(share).data) except RockStorAPIException: raise except Exception, e: handle_exception(e, request)
def post(self, request): try: pool_name = request.DATA['pool'] share_name = request.DATA['name'] size = int(request.DATA['size']) pool = None for p in Pool.objects.all(): if (p.name == pool_name): pool = p break disk = Disk.objects.filter(pool=p)[0] add_share(pool_name, disk.name, share_name) sid = share_id(pool_name, disk.name, share_name) qgroup_id = '0/' + sid update_quota(pool_name, disk.name, qgroup_id, str(size)) cur_usage = int(share_usage(pool_name, disk.name, qgroup_id)) qgroup = Qgroup(uuid=qgroup_id) qgroup.save() s = Share(pool=pool, qgroup=qgroup, name=share_name, size=size, free=(size - cur_usage)) s.save() return Response(ShareSerializer(s).data) except Exception, e: handle_exception(e, request)
def test_share_usage(self): """ Moc the return value of "btrfs qgroup show pool_mount_point" to assess test_share's parsing capabilities to extract rfer and excl subvol usage information. :return: """ # share_usage() CALLED WITH pool name of=test-pool and share_id=0/285 # mount_root(Pool object) returned /mnt2/test-pool # share_usage cmd=['/sbin/btrfs', 'qgroup', 'show', u'/mnt2/test-pool'] # share_usage returning rusage=461404 and eusage=3512 # # Setup our calling variables and mock the root pool as mounted. root_mount_point = '/mnt2/test-pool' o = [ 'qgroupid rfer excl ', '-------- ---- ---- ', '0/5 16.00KiB 16.00KiB ', '0/259 2.04MiB 2.04MiB ', '0/260 7.37GiB 7.37GiB ', '0/261 63.65MiB 63.65MiB ', '0/263 195.32MiB 496.00KiB ', '0/264 195.34MiB 112.00KiB ', '0/265 195.34MiB 80.00KiB ', '0/266 195.34MiB 80.00KiB ', '0/267 195.34MiB 80.00KiB ', '0/268 195.38MiB 152.00KiB ', '0/269 229.06MiB 80.00KiB ', '0/270 229.06MiB 80.00KiB ', '0/271 229.06MiB 80.00KiB ', '0/272 229.06MiB 96.00KiB ', '0/273 229.06MiB 128.00KiB ', '0/274 236.90MiB 80.00KiB ', '0/275 236.90MiB 80.00KiB ', '0/276 236.90MiB 80.00KiB ', '0/277 450.54MiB 128.00KiB ', '0/278 450.54MiB 112.00KiB ', '0/279 450.54MiB 128.00KiB ', '0/280 450.54MiB 80.00KiB ', '0/281 450.54MiB 80.00KiB ', '0/282 450.54MiB 80.00KiB ', '0/283 450.54MiB 80.00KiB ', '0/284 450.54MiB 176.00KiB ', '0/285 450.59MiB 3.43MiB ', '2015/1 0.00B 0.00B ', '2015/2 2.04MiB 2.04MiB ', '2015/3 7.37GiB 7.37GiB ', '2015/4 63.65MiB 63.65MiB ', '' ] e = [''] rc = 0 # is_mounted returning True avoids mount command calls in mount_root() mount_point = '/mnt2/test-mount' self.mock_mount_root.return_value = mount_point # setup the return values from our run_command wrapper # examples of output from /mnt2/test-pool from a real system install self.mock_run_command.return_value = (o, e, rc) # create a fake pool object pool = Pool(raid='raid0', name='test-pool') # and fake share_id / qgroupid share_id = '0/285' # As share_usage uses convert_to_kib() everything is converted to KiB # here we convert 450.59MiB and 3.43MiB to their KiB equivalent (x1024) expected_results = (461404, 3512) self.assertEqual(share_usage(pool, share_id), expected_results, msg='Failed to retrieve expected rfer and excl usage')
def test_share_usage(self): """ Moc the return value of "btrfs qgroup show pool_mount_point" to assess test_share's parsing capabilities to extract rfer and excl subvol usage information. :return: """ # share_usage() CALLED WITH pool name of=test-pool and share_id=0/285 # mount_root(Pool object) returned /mnt2/test-pool # share_usage cmd=['/sbin/btrfs', 'qgroup', 'show', u'/mnt2/test-pool'] # share_usage returning rusage=461404 and eusage=3512 # # Setup our calling variables and mock the root pool as mounted. root_mount_point = '/mnt2/test-pool' o = ['qgroupid rfer excl ', '-------- ---- ---- ', '0/5 16.00KiB 16.00KiB ', '0/259 2.04MiB 2.04MiB ', '0/260 7.37GiB 7.37GiB ', '0/261 63.65MiB 63.65MiB ', '0/263 195.32MiB 496.00KiB ', '0/264 195.34MiB 112.00KiB ', '0/265 195.34MiB 80.00KiB ', '0/266 195.34MiB 80.00KiB ', '0/267 195.34MiB 80.00KiB ', '0/268 195.38MiB 152.00KiB ', '0/269 229.06MiB 80.00KiB ', '0/270 229.06MiB 80.00KiB ', '0/271 229.06MiB 80.00KiB ', '0/272 229.06MiB 96.00KiB ', '0/273 229.06MiB 128.00KiB ', '0/274 236.90MiB 80.00KiB ', '0/275 236.90MiB 80.00KiB ', '0/276 236.90MiB 80.00KiB ', '0/277 450.54MiB 128.00KiB ', '0/278 450.54MiB 112.00KiB ', '0/279 450.54MiB 128.00KiB ', '0/280 450.54MiB 80.00KiB ', '0/281 450.54MiB 80.00KiB ', '0/282 450.54MiB 80.00KiB ', '0/283 450.54MiB 80.00KiB ', '0/284 450.54MiB 176.00KiB ', '0/285 450.59MiB 3.43MiB ', '2015/1 0.00B 0.00B ', '2015/2 2.04MiB 2.04MiB ', '2015/3 7.37GiB 7.37GiB ', '2015/4 63.65MiB 63.65MiB ', ''] e = [''] rc = 0 # is_mounted returning True avoids mount command calls in mount_root() mount_point = '/mnt2/test-mount' self.mock_mount_root.return_value = mount_point # setup the return values from our run_command wrapper # examples of output from /mnt2/test-pool from a real system install self.mock_run_command.return_value = (o, e, rc) # create a fake pool object pool = Pool(raid='raid0', name='test-pool') # and fake share_id / qgroupid share_id = '0/285' # As share_usage uses convert_to_kib() everything is converted to KiB # here we convert 450.59MiB and 3.43MiB to their KiB equivalent (x1024) expected_results = (461404, 3512) self.assertEqual(share_usage(pool, share_id), expected_results, msg='Failed to retrieve expected rfer and excl usage')