mirror of
https://github.com/kevingruesser/bootstrap-vz.git
synced 2025-08-24 15:36:27 +00:00
Add new Sectors unit, enhance Bytes unit, add unit tests for both
This commit is contained in:
parent
456a68ea25
commit
9a6975ce7d
5 changed files with 436 additions and 23 deletions
|
@ -1,3 +1,14 @@
|
||||||
|
from exceptions import UnitError
|
||||||
|
|
||||||
|
|
||||||
|
def onlybytes(msg):
|
||||||
|
def decorator(func):
|
||||||
|
def check_other(self, other):
|
||||||
|
if not isinstance(other, Bytes):
|
||||||
|
raise UnitError(msg)
|
||||||
|
return func(self, other)
|
||||||
|
return check_other
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
class Bytes(object):
|
class Bytes(object):
|
||||||
|
@ -61,25 +72,48 @@ class Bytes(object):
|
||||||
def __long__(self):
|
def __long__(self):
|
||||||
return self.qty
|
return self.qty
|
||||||
|
|
||||||
|
def __abs__(self):
|
||||||
|
return self.qty
|
||||||
|
|
||||||
|
@onlybytes('Can only compare Bytes to Bytes')
|
||||||
|
def __lt__(self, other):
|
||||||
|
return self.qty < other.qty
|
||||||
|
|
||||||
|
@onlybytes('Can only compare Bytes to Bytes')
|
||||||
|
def __le__(self, other):
|
||||||
|
return self.qty <= other.qty
|
||||||
|
|
||||||
|
@onlybytes('Can only compare Bytes to Bytes')
|
||||||
|
def __eq__(self, other):
|
||||||
|
return self.qty == other.qty
|
||||||
|
|
||||||
|
@onlybytes('Can only compare Bytes to Bytes')
|
||||||
|
def __ne__(self, other):
|
||||||
|
return self.qty != other.qty
|
||||||
|
|
||||||
|
@onlybytes('Can only compare Bytes to Bytes')
|
||||||
|
def __ge__(self, other):
|
||||||
|
return self.qty >= other.qty
|
||||||
|
|
||||||
|
@onlybytes('Can only compare Bytes to Bytes')
|
||||||
|
def __gt__(self, other):
|
||||||
|
return self.qty > other.qty
|
||||||
|
|
||||||
|
@onlybytes('Can only add Bytes to Bytes')
|
||||||
def __add__(self, other):
|
def __add__(self, other):
|
||||||
if not isinstance(other, Bytes):
|
|
||||||
raise UnitError('Can only add Bytes to Bytes')
|
|
||||||
return Bytes(self.qty + other.qty)
|
return Bytes(self.qty + other.qty)
|
||||||
|
|
||||||
|
@onlybytes('Can only add Bytes to Bytes')
|
||||||
def __iadd__(self, other):
|
def __iadd__(self, other):
|
||||||
if not isinstance(other, Bytes):
|
|
||||||
raise UnitError('Can only add Bytes to Bytes')
|
|
||||||
self.qty += other.qty
|
self.qty += other.qty
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
@onlybytes('Can only subtract Bytes from Bytes')
|
||||||
def __sub__(self, other):
|
def __sub__(self, other):
|
||||||
if not isinstance(other, Bytes):
|
|
||||||
raise UnitError('Can only subtract Bytes from Bytes')
|
|
||||||
return Bytes(self.qty - other.qty)
|
return Bytes(self.qty - other.qty)
|
||||||
|
|
||||||
|
@onlybytes('Can only subtract Bytes from Bytes')
|
||||||
def __isub__(self, other):
|
def __isub__(self, other):
|
||||||
if not isinstance(other, Bytes):
|
|
||||||
raise UnitError('Can only subtract Bytes from Bytes')
|
|
||||||
self.qty -= other.qty
|
self.qty -= other.qty
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
@ -110,20 +144,13 @@ class Bytes(object):
|
||||||
self.qty /= other
|
self.qty /= other
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
@onlybytes('Can only take modulus of Bytes with Bytes')
|
||||||
def __mod__(self, other):
|
def __mod__(self, other):
|
||||||
if isinstance(other, Bytes):
|
return Bytes(self.qty % other.qty)
|
||||||
return self.qty % other.qty
|
|
||||||
if not isinstance(other, (int, long)):
|
|
||||||
raise UnitError('Can only take modulus of Bytes with integers or Bytes')
|
|
||||||
return Bytes(self.qty % other)
|
|
||||||
|
|
||||||
|
@onlybytes('Can only take modulus of Bytes with Bytes')
|
||||||
def __imod__(self, other):
|
def __imod__(self, other):
|
||||||
if isinstance(other, Bytes):
|
|
||||||
self.qty %= other.qty
|
self.qty %= other.qty
|
||||||
else:
|
|
||||||
if not isinstance(other, (int, long)):
|
|
||||||
raise UnitError('Can only divide Bytes with integers or Bytes')
|
|
||||||
self.qty %= other
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def __getstate__(self):
|
def __getstate__(self):
|
||||||
|
@ -133,7 +160,3 @@ class Bytes(object):
|
||||||
|
|
||||||
def __setstate__(self, state):
|
def __setstate__(self, state):
|
||||||
self.qty = state['qty']
|
self.qty = state['qty']
|
||||||
|
|
||||||
|
|
||||||
class UnitError(Exception):
|
|
||||||
pass
|
|
||||||
|
|
154
bootstrapvz/common/sectors.py
Normal file
154
bootstrapvz/common/sectors.py
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
from exceptions import UnitError
|
||||||
|
from bytes import Bytes
|
||||||
|
|
||||||
|
|
||||||
|
def onlysectors(msg):
|
||||||
|
def decorator(func):
|
||||||
|
def check_other(self, other):
|
||||||
|
if not isinstance(other, Sectors):
|
||||||
|
raise UnitError(msg)
|
||||||
|
return func(self, other)
|
||||||
|
return check_other
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
class Sectors(object):
|
||||||
|
|
||||||
|
def __init__(self, quantity, sector_size):
|
||||||
|
if isinstance(sector_size, Bytes):
|
||||||
|
self.sector_size = sector_size
|
||||||
|
else:
|
||||||
|
self.sector_size = Bytes(sector_size)
|
||||||
|
|
||||||
|
if isinstance(quantity, Bytes):
|
||||||
|
self.bytes = quantity
|
||||||
|
else:
|
||||||
|
if isinstance(quantity, (int, long)):
|
||||||
|
self.bytes = self.sector_size * quantity
|
||||||
|
else:
|
||||||
|
self.bytes = Bytes(quantity)
|
||||||
|
|
||||||
|
def get_sectors(self):
|
||||||
|
return self.bytes / self.sector_size
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return str(self.get_sectors()) + 's'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.__repr__()
|
||||||
|
|
||||||
|
def __int__(self):
|
||||||
|
return self.get_sectors()
|
||||||
|
|
||||||
|
def __long__(self):
|
||||||
|
return self.get_sectors()
|
||||||
|
|
||||||
|
def __abs__(self):
|
||||||
|
return self.get_sectors()
|
||||||
|
|
||||||
|
@onlysectors('Can only compare sectors with sectors')
|
||||||
|
def __lt__(self, other):
|
||||||
|
return self.bytes < other.bytes
|
||||||
|
|
||||||
|
@onlysectors('Can only compare sectors with sectors')
|
||||||
|
def __le__(self, other):
|
||||||
|
return self.bytes <= other.bytes
|
||||||
|
|
||||||
|
@onlysectors('Can only compare sectors with sectors')
|
||||||
|
def __eq__(self, other):
|
||||||
|
return self.bytes == other.bytes
|
||||||
|
|
||||||
|
@onlysectors('Can only compare sectors with sectors')
|
||||||
|
def __ne__(self, other):
|
||||||
|
return self.bytes != other.bytes
|
||||||
|
|
||||||
|
@onlysectors('Can only compare sectors with sectors')
|
||||||
|
def __ge__(self, other):
|
||||||
|
return self.bytes >= other.bytes
|
||||||
|
|
||||||
|
@onlysectors('Can only compare sectors with sectors')
|
||||||
|
def __gt__(self, other):
|
||||||
|
return self.bytes > other.bytes
|
||||||
|
|
||||||
|
def __add__(self, other):
|
||||||
|
if not isinstance(other, Sectors):
|
||||||
|
raise UnitError('Can only add sectors to sectors')
|
||||||
|
if self.sector_size != other.sector_size:
|
||||||
|
raise UnitError('Cannot sum sectors with different sector sizes')
|
||||||
|
return Sectors(self.bytes + other.bytes, self.sector_size)
|
||||||
|
|
||||||
|
def __iadd__(self, other):
|
||||||
|
if not isinstance(other, (Bytes, Sectors)):
|
||||||
|
raise UnitError('Can only add Bytes or sectors to sectors')
|
||||||
|
if isinstance(other, Bytes):
|
||||||
|
self.bytes += other
|
||||||
|
if isinstance(other, Sectors):
|
||||||
|
if self.sector_size != other.sector_size:
|
||||||
|
raise UnitError('Cannot sum sectors with different sector sizes')
|
||||||
|
self.bytes += other.bytes
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __sub__(self, other):
|
||||||
|
if not isinstance(other, (Sectors, int, long)):
|
||||||
|
raise UnitError('Can only subtract sectors or integers from sectors')
|
||||||
|
if isinstance(other, int):
|
||||||
|
return Sectors(self.bytes - self.sector_size * other, self.sector_size)
|
||||||
|
else:
|
||||||
|
if self.sector_size != other.sector_size:
|
||||||
|
raise UnitError('Cannot subtract sectors with different sector sizes')
|
||||||
|
return Sectors(self.bytes - other.bytes, self.sector_size)
|
||||||
|
|
||||||
|
def __isub__(self, other):
|
||||||
|
if not isinstance(other, (Sectors, int, long)):
|
||||||
|
raise UnitError('Can only subtract sectors or integers from sectors')
|
||||||
|
if isinstance(other, int):
|
||||||
|
self.bytes -= self.sector_size * other
|
||||||
|
else:
|
||||||
|
if self.sector_size != other.sector_size:
|
||||||
|
raise UnitError('Cannot subtract sectors with different sector sizes')
|
||||||
|
self.bytes -= other.bytes
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __mul__(self, other):
|
||||||
|
if not isinstance(other, (int, long)):
|
||||||
|
raise UnitError('Can only multiply sectors with integers')
|
||||||
|
return Sectors(self.bytes * other, self.sector_size)
|
||||||
|
|
||||||
|
def __imul__(self, other):
|
||||||
|
if not isinstance(other, (int, long)):
|
||||||
|
raise UnitError('Can only multiply sectors with integers')
|
||||||
|
self.bytes *= other
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __div__(self, other):
|
||||||
|
if isinstance(other, Sectors):
|
||||||
|
if self.sector_size != other.sector_size:
|
||||||
|
raise UnitError('Cannot divide sectors with different sector sizes')
|
||||||
|
return self.bytes / other.bytes
|
||||||
|
if not isinstance(other, (int, long)):
|
||||||
|
raise UnitError('Can only divide sectors with integers or sectors')
|
||||||
|
return Sectors(self.bytes / other, self.sector_size)
|
||||||
|
|
||||||
|
def __idiv__(self, other):
|
||||||
|
if isinstance(other, Sectors):
|
||||||
|
if self.sector_size != other.sector_size:
|
||||||
|
raise UnitError('Cannot divide sectors with different sector sizes')
|
||||||
|
self.bytes /= other.bytes
|
||||||
|
else:
|
||||||
|
if not isinstance(other, (int, long)):
|
||||||
|
raise UnitError('Can only divide sectors with integers or sectors')
|
||||||
|
self.bytes /= other
|
||||||
|
return self
|
||||||
|
|
||||||
|
@onlysectors('Can only take modulus of sectors with sectors')
|
||||||
|
def __mod__(self, other):
|
||||||
|
if self.sector_size != other.sector_size:
|
||||||
|
raise UnitError('Cannot take modulus of sectors with different sector sizes')
|
||||||
|
return Sectors(self.bytes % other.bytes, self.sector_size)
|
||||||
|
|
||||||
|
@onlysectors('Can only take modulus of sectors with sectors')
|
||||||
|
def __imod__(self, other):
|
||||||
|
if self.sector_size != other.sector_size:
|
||||||
|
raise UnitError('Cannot take modulus of sectors with different sector sizes')
|
||||||
|
self.bytes %= other.bytes
|
||||||
|
return self
|
0
tests/unit/__init__.py
Normal file
0
tests/unit/__init__.py
Normal file
108
tests/unit/bytes.py
Normal file
108
tests/unit/bytes.py
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
from nose.tools import eq_
|
||||||
|
from nose.tools import raises
|
||||||
|
from bootstrapvz.common.bytes import Bytes
|
||||||
|
from bootstrapvz.common.exceptions import UnitError
|
||||||
|
|
||||||
|
|
||||||
|
def test_lt():
|
||||||
|
assert Bytes('1MiB') < Bytes('2MiB')
|
||||||
|
|
||||||
|
|
||||||
|
def test_le():
|
||||||
|
assert Bytes('1MiB') <= Bytes('2MiB')
|
||||||
|
assert Bytes('1MiB') <= Bytes('1MiB')
|
||||||
|
|
||||||
|
|
||||||
|
def test_eq():
|
||||||
|
eq_(Bytes('1MiB'), Bytes('1MiB'))
|
||||||
|
|
||||||
|
|
||||||
|
def test_neq():
|
||||||
|
assert Bytes('15MiB') != Bytes('1MiB')
|
||||||
|
|
||||||
|
|
||||||
|
def test_gt():
|
||||||
|
assert Bytes('2MiB') > Bytes('1MiB')
|
||||||
|
|
||||||
|
|
||||||
|
def test_ge():
|
||||||
|
assert Bytes('2MiB') >= Bytes('1MiB')
|
||||||
|
assert Bytes('2MiB') >= Bytes('2MiB')
|
||||||
|
|
||||||
|
|
||||||
|
def test_eq_unit():
|
||||||
|
eq_(Bytes('1024MiB'), Bytes('1GiB'))
|
||||||
|
|
||||||
|
|
||||||
|
def test_add():
|
||||||
|
eq_(Bytes('2GiB'), Bytes('1GiB') + Bytes('1GiB'))
|
||||||
|
|
||||||
|
|
||||||
|
def test_iadd():
|
||||||
|
b = Bytes('1GiB')
|
||||||
|
b += Bytes('1GiB')
|
||||||
|
eq_(Bytes('2GiB'), b)
|
||||||
|
|
||||||
|
|
||||||
|
def test_sub():
|
||||||
|
eq_(Bytes('1GiB'), Bytes('2GiB') - Bytes('1GiB'))
|
||||||
|
|
||||||
|
|
||||||
|
def test_isub():
|
||||||
|
b = Bytes('2GiB')
|
||||||
|
b -= Bytes('1GiB')
|
||||||
|
eq_(Bytes('1GiB'), b)
|
||||||
|
|
||||||
|
|
||||||
|
def test_mul():
|
||||||
|
eq_(Bytes('2GiB'), Bytes('1GiB') * 2)
|
||||||
|
|
||||||
|
|
||||||
|
@raises(UnitError)
|
||||||
|
def test_mul_bytes():
|
||||||
|
Bytes('1GiB') * Bytes('1GiB')
|
||||||
|
|
||||||
|
|
||||||
|
def test_imul():
|
||||||
|
b = Bytes('1GiB')
|
||||||
|
b *= 2
|
||||||
|
eq_(Bytes('2GiB'), b)
|
||||||
|
|
||||||
|
|
||||||
|
def test_div():
|
||||||
|
eq_(Bytes('1GiB'), Bytes('2GiB') / 2)
|
||||||
|
|
||||||
|
|
||||||
|
def test_div_bytes():
|
||||||
|
eq_(2, Bytes('2GiB') / Bytes('1GiB'))
|
||||||
|
|
||||||
|
|
||||||
|
def test_idiv():
|
||||||
|
b = Bytes('2GiB')
|
||||||
|
b /= 2
|
||||||
|
eq_(Bytes('1GiB'), b)
|
||||||
|
|
||||||
|
|
||||||
|
def test_mod():
|
||||||
|
eq_(Bytes('256MiB'), Bytes('1GiB') % Bytes('768MiB'))
|
||||||
|
|
||||||
|
|
||||||
|
@raises(UnitError)
|
||||||
|
def test_mod_int():
|
||||||
|
Bytes('1GiB') % 768
|
||||||
|
|
||||||
|
|
||||||
|
def test_imod():
|
||||||
|
b = Bytes('1GiB')
|
||||||
|
b %= Bytes('768MiB')
|
||||||
|
eq_(Bytes('256MiB'), b)
|
||||||
|
|
||||||
|
|
||||||
|
@raises(UnitError)
|
||||||
|
def test_imod_int():
|
||||||
|
b = Bytes('1GiB')
|
||||||
|
b %= 5
|
||||||
|
|
||||||
|
|
||||||
|
def test_abs():
|
||||||
|
eq_(pow(1024, 3), abs(Bytes('1GiB')))
|
128
tests/unit/sectors.py
Normal file
128
tests/unit/sectors.py
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
from nose.tools import eq_
|
||||||
|
from nose.tools import raises
|
||||||
|
from bootstrapvz.common.sectors import Sectors
|
||||||
|
from bootstrapvz.common.bytes import Bytes
|
||||||
|
from bootstrapvz.common.exceptions import UnitError
|
||||||
|
|
||||||
|
std_secsz = Bytes(512)
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_with_int():
|
||||||
|
eq_(4, abs(Sectors(4, std_secsz)))
|
||||||
|
secsize = 4096
|
||||||
|
eq_(Sectors('1MiB', secsize), Sectors(256, secsize))
|
||||||
|
|
||||||
|
|
||||||
|
def test_lt():
|
||||||
|
assert Sectors('1MiB', std_secsz) < Sectors('2MiB', std_secsz)
|
||||||
|
|
||||||
|
|
||||||
|
def test_le():
|
||||||
|
assert Sectors('1MiB', std_secsz) <= Sectors('2MiB', std_secsz)
|
||||||
|
assert Sectors('1MiB', std_secsz) <= Sectors('1MiB', std_secsz)
|
||||||
|
|
||||||
|
|
||||||
|
def test_eq():
|
||||||
|
eq_(Sectors('1MiB', std_secsz), Sectors('1MiB', std_secsz))
|
||||||
|
|
||||||
|
|
||||||
|
def test_neq():
|
||||||
|
assert Sectors('15MiB', std_secsz) != Sectors('1MiB', std_secsz)
|
||||||
|
|
||||||
|
|
||||||
|
def test_gt():
|
||||||
|
assert Sectors('2MiB', std_secsz) > Sectors('1MiB', std_secsz)
|
||||||
|
|
||||||
|
|
||||||
|
def test_ge():
|
||||||
|
assert Sectors('2MiB', std_secsz) >= Sectors('1MiB', std_secsz)
|
||||||
|
assert Sectors('2MiB', std_secsz) >= Sectors('2MiB', std_secsz)
|
||||||
|
|
||||||
|
|
||||||
|
def test_eq_unit():
|
||||||
|
eq_(Sectors('1024MiB', std_secsz), Sectors('1GiB', std_secsz))
|
||||||
|
|
||||||
|
|
||||||
|
def test_add():
|
||||||
|
eq_(Sectors('2GiB', std_secsz), Sectors('1GiB', std_secsz) + Sectors('1GiB', std_secsz))
|
||||||
|
|
||||||
|
|
||||||
|
@raises(UnitError)
|
||||||
|
def test_add_with_diff_secsize():
|
||||||
|
Sectors('1GiB', Bytes(512)) + Sectors('1GiB', Bytes(4096))
|
||||||
|
|
||||||
|
|
||||||
|
def test_iadd():
|
||||||
|
s = Sectors('1GiB', std_secsz)
|
||||||
|
s += Sectors('1GiB', std_secsz)
|
||||||
|
eq_(Sectors('2GiB', std_secsz), s)
|
||||||
|
|
||||||
|
|
||||||
|
def test_sub():
|
||||||
|
eq_(Sectors('1GiB', std_secsz), Sectors('2GiB', std_secsz) - Sectors('1GiB', std_secsz))
|
||||||
|
|
||||||
|
|
||||||
|
def test_sub_int():
|
||||||
|
secsize = Bytes('4KiB')
|
||||||
|
eq_(Sectors('1MiB', secsize), Sectors('1028KiB', secsize) - 1)
|
||||||
|
|
||||||
|
|
||||||
|
def test_isub():
|
||||||
|
s = Sectors('2GiB', std_secsz)
|
||||||
|
s -= Sectors('1GiB', std_secsz)
|
||||||
|
eq_(Sectors('1GiB', std_secsz), s)
|
||||||
|
|
||||||
|
|
||||||
|
def test_mul():
|
||||||
|
eq_(Sectors('2GiB', std_secsz), Sectors('1GiB', std_secsz) * 2)
|
||||||
|
|
||||||
|
|
||||||
|
@raises(UnitError)
|
||||||
|
def test_mul_bytes():
|
||||||
|
Sectors('1GiB', std_secsz) * Sectors('1GiB', std_secsz)
|
||||||
|
|
||||||
|
|
||||||
|
def test_imul():
|
||||||
|
s = Sectors('1GiB', std_secsz)
|
||||||
|
s *= 2
|
||||||
|
eq_(Sectors('2GiB', std_secsz), s)
|
||||||
|
|
||||||
|
|
||||||
|
def test_div():
|
||||||
|
eq_(Sectors('1GiB', std_secsz), Sectors('2GiB', std_secsz) / 2)
|
||||||
|
|
||||||
|
|
||||||
|
def test_div_bytes():
|
||||||
|
eq_(2, Sectors('2GiB', std_secsz) / Sectors('1GiB', std_secsz))
|
||||||
|
|
||||||
|
|
||||||
|
def test_idiv():
|
||||||
|
s = Sectors('2GiB', std_secsz)
|
||||||
|
s /= 2
|
||||||
|
eq_(Sectors('1GiB', std_secsz), s)
|
||||||
|
|
||||||
|
|
||||||
|
def test_mod():
|
||||||
|
eq_(Sectors('256MiB', std_secsz), Sectors('1GiB', std_secsz) % Sectors('768MiB', std_secsz))
|
||||||
|
|
||||||
|
|
||||||
|
@raises(UnitError)
|
||||||
|
def test_mod_int():
|
||||||
|
Sectors('1GiB', std_secsz) % 768
|
||||||
|
|
||||||
|
|
||||||
|
def test_imod():
|
||||||
|
s = Sectors('1GiB', std_secsz)
|
||||||
|
s %= Sectors('768MiB', std_secsz)
|
||||||
|
eq_(Sectors('256MiB', std_secsz), s)
|
||||||
|
|
||||||
|
|
||||||
|
@raises(UnitError)
|
||||||
|
def test_imod_int():
|
||||||
|
s = Sectors('1GiB', std_secsz)
|
||||||
|
s %= 5
|
||||||
|
|
||||||
|
|
||||||
|
def test_abs():
|
||||||
|
secsize = 512
|
||||||
|
eq_(pow(1024, 3) / secsize, abs(Sectors('1GiB', secsize)))
|
Loading…
Add table
Reference in a new issue