def test_and(): x = Bits(8, 0b11001100) y = Bits(8, 0b11110000) assert x & y == 0b11000000 assert x & 0b1010 == 0b00001000 assert 0b1010 & x == 0b00001000
def test_index_array(): data = range(2**4) # Indexing into an array x = Bits(4, 3) assert data[x] == 3 # Note, this converts -2 to unsigned, so 14! y = Bits(4, -2) assert data[y] == 14 # Larger bitwidths work as long as the list is big enough a = Bits(8, 4) assert data[a] == 4 # If not, regular indexing error b = Bits(8, 20) with pytest.raises(IndexError): data[b] # Same with negative that become out of range when converted to unsigned c = Bits(8, -1) with pytest.raises(IndexError): data[c]
def test_slice_bounds_checking(): x = Bits(4, 0b1100) with pytest.raises(IndexError): assert x[1:5] == 0b10 with pytest.raises(IndexError): assert x[-1:2] == 0b10 with pytest.raises(IndexError): assert x[2:1] == 0b10 with pytest.raises(IndexError): x[1:5] = 0b10 with pytest.raises(IndexError): x[-1:2] = 0b10 with pytest.raises(IndexError): x[2:1] = 0b10 # FIXED # Bits objects constructed with another Bits object provided as a value # parameter end up having problems when writing to slices. This is # because the mask used when writing to a subslice is often a negative # int in Python, and we don't allow operations on Bits to be performed # with negative values. Current workaround is to force the value param # for the Bits constructor to be an int or a long. #with pytest.raises( AssertionError ): y = Bits(4, Bits(4, 0)) y[1:3] = 1
def test_or(): x = Bits(8, 0b11001100) y = Bits(8, 0b11110000) assert x | y == 0b11111100 assert x | 0b1010 == 0b11001110 assert 0b1010 | x == 0b11001110
def test_return_type(): x = Bits(8, 0b1100) assert isinstance(x.uint(), int) assert isinstance(x.int(), int) assert isinstance(x[1:2], Bits) assert isinstance(x[0:4], Bits) assert isinstance(x[2], Bits)
def test_neg_assign(): x = Bits( 4, -1 ) assert x == 0b1111 assert x.uint() == 0b1111 x = Bits( 4, -2 ) assert x == 0b1110 assert x.uint() == 0b1110
def test_sext(): assert sext( Bits( 4, 2 ), 8 ) == Bits( 8, 0x02 ) assert sext( Bits( 4, 4 ), 8 ) == Bits( 8, 0x04 ) assert sext( Bits( 4, 15 ), 8 ) == Bits( 8, 0xff ) assert sext( Bits( 4, -2 ), 8 ) == Bits( 8, 0xfe ) assert sext( Bits( 4, -4 ), 8 ) == Bits( 8, 0xfc )
def test_return_type(): x = Bits( 8, 0b1100 ) assert isinstance( x.uint(), int ) assert isinstance( x.int(), int ) assert isinstance( x[1:2], Bits ) assert isinstance( x[0:4], Bits ) assert isinstance( x[2], Bits )
def test_zext(): assert zext( Bits( 4, 2 ), 8 ) == Bits( 8, 0x02 ) assert zext( Bits( 4, 4 ), 8 ) == Bits( 8, 0x04 ) assert zext( Bits( 4, 15 ), 8 ) == Bits( 8, 0x0f ) assert zext( Bits( 4, -2 ), 8 ) == Bits( 8, 0x0e ) assert zext( Bits( 4, -4 ), 8 ) == Bits( 8, 0x0c )
def test_invert(): x = Bits(4, 0b0001) assert ~x == 0b1110 x = Bits(4, 0b1001) assert ~x == 0b0110 x = Bits(16, 0b1111000011110000) assert ~x == 0b0000111100001111
def test_set_bit(): x = Bits(4, 0b1100) x[3] = 0 assert x.uint() == 0b0100 x[2] = 1 assert x.uint() == 0b0100 x[1] = 1 assert x.uint() == 0b0110
def test_set_bit(): x = Bits( 4, 0b1100 ) x[3] = 0 assert x.uint() == 0b0100 x[2] = 1 assert x.uint() == 0b0100 x[1] = 1 assert x.uint() == 0b0110
def test_lshift(): x = Bits(8, 0b1100) y = Bits(8, 4) assert x << y == 0b11000000 assert x << 4 == 0b11000000 assert x << 6 == 0b00000000 assert y << x == 0b00000000 assert y << 0 == 0b00000100 assert y << 1 == 0b00001000
def test_gt(): x = Bits( 4, 0b1100 ) y = Bits( 4, 0b0011 ) assert x.uint() > y.uint() assert x.uint() > 2 assert x > y.uint() assert x > 2 assert x > y assert 9 > y
def test_lt(): x = Bits( 4, 0b1100 ) y = Bits( 4, 0b0011 ) assert y.uint() < x.uint() assert y.uint() < 10 assert y < x.uint() assert y < 10 assert y < x assert 1 < y
def test_set_slice(): x = Bits(4, 0b1100) x[:] = 0b0010 assert x.uint() == 0b0010 x[2:4] = 0b11 assert x.uint() == 0b1110 x[0:1] = 0b1 assert x.uint() == 0b1111 x[1:3] = 0b10 assert x.uint() == 0b1101 # check open ended ranges x[1:] = 0b001 assert x.uint() == 0b0011 x[:3] = 0b110 assert x.uint() == 0b0110 with pytest.raises(ValueError): x[1:3] = 0b110 x[:] = 0b1111 assert x.uint() == 0b1111 with pytest.raises(ValueError): x[:] = 0b10000
def test_slice_bits(): data = Bits(8, 0b1101) # Indexing into a bits x = Bits(4, 2) assert data[:] == 0b1101 assert data[x:] == 0b11 assert data[:x] == 0b01 with pytest.raises(IndexError): assert data[x:x] == 0b1
def test_xor(): x = Bits(8, 0b11001100) y = Bits(8, 0b11110000) assert x ^ y == 0b00111100 assert x ^ 0b1010 == 0b11000110 assert 0b1010 ^ x == 0b11000110 a = Bits(1, 1) b = Bits(1, 0) c = Bits(1, 1) assert (a ^ b) ^ c == 0
def test_rshift(): x = Bits(8, 0b11000000) y = Bits(8, 4) assert x >> y == 0b00001100 assert x >> 7 == 0b00000001 assert x >> 8 == 0b00000000 assert x >> 10 == 0b00000000 x = Bits(8, 2) assert y >> x == 0b00000001 assert y >> 0 == 0b00000100 assert y >> 2 == 0b00000001 assert y >> 5 == 0b00000000
def test_sub(): x = Bits(4, 5) y = Bits(4, 4) assert x - y == 1 assert x - Bits(4, 4) == 1 assert x - 4 == 1 y = Bits(4, 5) assert x - y == 0 assert x - 5 == 0 y = Bits(4, 7) assert x - y == 0b1110 assert x - 7 == 0b1110 assert 9 - x == 0b0100
def test_bitstruct_call(): bits_a = Bits(8) bits_b = Bits(8) # Passes. Bits doesn't use metaclasses. assert type(bits_a) == type(bits_b) type_a = MemMsg(16, 32) type_b = MemMsg(16, 32) # Fails. Each call to MemMsg uses metaclassed to build a new class. # Possible fixes: caching? assert type(type_a) == type(type_b)
def test_set_slice(): x = Bits( 4, 0b1100 ) x[:] = 0b0010 assert x.uint() == 0b0010 x[2:4] = 0b11 assert x.uint() == 0b1110 x[0:1] = 0b1 assert x.uint() == 0b1111 x[1:3] = 0b10 assert x.uint() == 0b1101 # check open ended ranges x[1:] = 0b001 assert x.uint() == 0b0011 x[:3] = 0b110 assert x.uint() == 0b0110 with pytest.raises( ValueError ): x[1:3] = 0b110 x[:] = 0b1111 assert x.uint() == 0b1111 with pytest.raises( ValueError ): x[:] = 0b10000
def test_ne(): x = Bits(4, 0b1100) y = Bits(4, 0b0011) # TODO: check width? assert x.uint() != y.uint() assert x != y # added for bug z = Bits(1, 0) assert z.uint() != 1L assert z != 1L assert 5 != x assert z != None assert Bits(4, 0) != None
def test_str(): assert Bits(4, 0x2).__str__() == "2" assert Bits(8, 0x1f).__str__() == "1f" assert Bits(32, 0x0000beef).__str__() == "0000beef" # FIXED # Bits objects constructed with another Bits object provided as a value # parameter end up having problems when printed. This is because the # internal ._uint field is expected to be an int/long, but is instead # a Bits object, which cannot be formatted as expected. Current # workaround is to force the value param for the Bits constructor to be # an int or a long. #with pytest.raises( ValueError ): #with pytest.raises( AssertionError ): # assert Bits( 4, Bits(32,2) ).__str__() == "2" assert Bits(4, Bits(32, 2)).__str__() == "2"
def test_get_bit(): x = Bits(4, 0b1100) assert x[3] == 1 assert x[2] == 1 assert x[1] == 0 assert x[0] == 0
def test_int(): assert Bits(4, 0).int() == 0 assert Bits(4, 2).int() == 2 assert Bits(4, 4).int() == 4 assert Bits(4, 15).int() == -1 assert Bits(4, -1).int() == -1 assert Bits(4, -2).int() == -2 assert Bits(4, -4).int() == -4 assert Bits(4, -8).int() == -8
def test_mult(): x = Bits(8, 0b00000000) y = Bits(8, 0b00000000) assert x * y == 0b0000000000000000 assert x * 0b1000 == 0b0000000000000000 x = Bits(8, 0b11111111) y = Bits(8, 0b11111111) assert x * y == 0b0000000000000001111111000000001 assert x * 0b11111111 == 0b0000000000000001111111000000001 assert 0b11111111 * x == 0b0000000000000001111111000000001 # TODO: Currently fails as the second operand is larger than the Bits # object x. Should update the test when we define the behaviour #assert x * 0b1111111111 == 0b0000000000000001111111000000001 y = Bits(8, 0b10000000) assert x * y == 0b0000000000000000111111110000000
def test_constructor(): assert Bits(4, 2).uint() == 2 assert Bits(4, 4).uint() == 4 assert Bits(4, 15).uint() == 15 assert Bits(4, -2).uint() == 0b1110 assert Bits(4, -4).uint() == 0b1100 assert Bits(4) == Bits(4, 0) assert Bits(4).uint() == 0
def test_reduce_and(): assert reduce_and( Bits(2,0b11) ) == 1 assert reduce_and( Bits(2,0b01) ) == 0 assert reduce_and( Bits(2,0b10) ) == 0 assert reduce_and( Bits(2,0b00) ) == 0 assert reduce_and( Bits(4,0b1111) ) == 1 assert reduce_and( Bits(4,0b1010) ) == 0 assert reduce_and( Bits(4,0b0101) ) == 0 assert reduce_and( Bits(4,0b0000) ) == 0
def test_get_slice(): x = Bits(4, 0b1100) assert x[:] == 0b1100 assert x[2:4] == 0b11 assert x[0:1] == 0b0 assert x[1:3] == 0b10 # check open ended ranges assert x[1:] == 0b110 assert x[:3] == 0b100
def test_uint(): assert Bits(4, 0).uint() == 0 assert Bits(4, 2).uint() == 2 assert Bits(4, 4).uint() == 4 assert Bits(4, 15).uint() == 15 assert Bits(4, -1).uint() == 15 assert Bits(4, -2).uint() == 14 assert Bits(4, -4).uint() == 12
def test_lt(): x = Bits(4, 0b1100) y = Bits(4, 0b0011) assert y.uint() < x.uint() assert y.uint() < 10 assert y < x.uint() assert y < 10 assert y < x assert 1 < y
def test_gt(): x = Bits(4, 0b1100) y = Bits(4, 0b0011) assert x.uint() > y.uint() assert x.uint() > 2 assert x > y.uint() assert x > 2 assert x > y assert 9 > y
def test_index_bits(): data = Bits(8, 0b11001010) # Indexing into a bits x = Bits(4, 3) assert data[x] == 1 # Note, this converts -8 to unsigned, so 8! Out of range! y = Bits(4, -8) with pytest.raises(IndexError): data[y] # Larger bitwidths work as long as the list is big enough a = Bits(8, 4) assert data[a] == 0 # If not, regular indexing error b = Bits(8, 20) with pytest.raises(IndexError): data[b] # Same with negative that become out of range when converted to unsigned c = Bits(8, -1) with pytest.raises(IndexError): data[c]
def test_int_bounds_checking(): Bits(4, 15) with pytest.raises(ValueError): Bits(4, 16) Bits(4, -8) with pytest.raises(ValueError): Bits(4, -9) with pytest.raises(ValueError): Bits(4, -16) Bits(1, 0) Bits(1, 1) with pytest.raises(ValueError): Bits(1, -1) with pytest.raises(ValueError): Bits(1, -2)
def test_neg_assign(): x = Bits(4, -1) assert x == 0b1111 assert x.uint() == 0b1111 x = Bits(4, -2) assert x == 0b1110 assert x.uint() == 0b1110
def test_lte(): x = Bits( 4, 0b1100 ) y = Bits( 4, 0b0011 ) z = Bits( 4, 0b0011 ) assert y.uint() <= x.uint() assert y.uint() <= 10 assert y.uint() <= z.uint() assert y.uint() <= 0b0011 assert y <= x.uint() assert y <= 10 assert y <= z.uint() assert y <= 0b0011 assert y <= x assert y <= z assert z <= x assert z <= z assert 1 <= y assert 3 <= y
def test_gte(): x = Bits( 4, 0b1100 ) y = Bits( 4, 0b0011 ) z = Bits( 4, 0b1100 ) assert x.uint() >= y.uint() assert x.uint() >= 2 assert x.uint() >= z.uint() assert x.uint() >= 0b1100 assert x >= y.uint() assert x >= 2 assert x >= z.uint() assert x >= 0b1100 assert x >= y assert x >= z assert z >= y assert z >= x assert x >= x assert 5 >= y assert 3 <= y
def test_ne(): x = Bits( 4, 0b1100 ) y = Bits( 4, 0b0011 ) # TODO: check width? assert x.uint() != y.uint() assert x != y # added for bug z = Bits( 1, 0 ) assert z.uint() != 1L assert z != 1L assert 5 != x assert z != None assert Bits( 4, 0 ) != None
def test_eq(): x = Bits( 4, 0b1010 ) assert x.uint() == x.uint() # Compare objects by value, not id assert x == x # Check the value assert x.uint() == 0b1010 assert x.uint() == 0xA assert x.uint() == 10 # Checking the equality operator assert x == 0b1010 assert x == 0xA assert x == 10 # Checking comparison with another bit container y = Bits( 4, 0b1010 ) assert x.uint() == y.uint() assert x == y y = Bits( 8 , 0b1010 ) assert x.uint() == y.uint() # TODO: How should equality between Bits objects work? # Just same value or same value and width? #assert x == y # Check the negatives x = Bits( 4, -1 ) assert x.uint() == 0b1111 assert x.uint() == 0xF assert x.uint() == 15 # Checking the equality operator assert x == 0b1111 assert x == 0xF assert x == 15 assert x.uint() == Bits(4, -1).uint() assert x == Bits( 4, -1 ).uint() assert 15 == x assert not x == None assert not Bits( 4, 0 ) == None
def encode(self, msg, path=()): if not path: self.previous_msg = self.current_msg self.current_msg = {} res="" if type(msg)==atlas.ObjectType: if msg.is_map(): #type+len res = res + chr(self.map_enum) + chr(len(msg)) keys = list(msg.keys()) #sorting no effect at all: hashing puts attributes always at same order? #(in these test sets) #keys.sort() same_bits = Bits() res2 = "" for key in keys: current_path = path+(key,) value = getattr(msg,key) if self.type==3: self.current_msg[current_path] = self.stateless_encode(value) #print current_path #1: len(name) + name + value #2: name_id + value #3: repetition elimination + 2 #each value themself add type (+1) if self.type==1: res2 = res2 + self.length_prefix + chr(len(key)) + key + \ self.encode(value,current_path) elif self.type==2: key_id = self.attrib_dict.get(key) if not key_id: key_id = self.attrib_dict[key] = self.latest_enum self.latest_enum = self.latest_enum + 1 res2 = res2 + chr(key_id) + \ self.encode(value,current_path) elif self.type==3: previous_encoded_value = self.previous_msg.get(current_path,"") current_encoded_value = self.current_msg[current_path] same_bits.append(previous_encoded_value == current_encoded_value) if previous_encoded_value != current_encoded_value: if previous_encoded_value: same_bits.append(1) res2 = res2 + self.encode(value,current_path) else: same_bits.append(0) res2 = res2 + self.length_prefix + \ chr(len(key)) + key + \ self.encode(value,current_path) #if self.type==3: # print path,":",same_bits return res + repr(same_bits) + res2 #is_list() #len(type+len) res = res + chr(self.list_enum) + chr(len(msg)) for i in range(len(msg)): res = res + self.encode(msg[i],path+(i,)) return res if type(msg)==IntType: return chr(self.int_enum) + array('l',[msg]).tostring() if type(msg)==FloatType: return chr(self.int_enum) + array('d',[msg]).tostring() if type(msg)==StringType: return chr(self.int_enum) + self.length_prefix + chr(len(msg)) + msg raise TypeError,msg
def test_compare_uint_neg(): x = Bits( 4, 2 ) assert x.uint() != -1 assert x.uint() > -1 assert x.uint() >= -1
def test_compare_int_neg(): x = Bits( 4, -2 ) assert x.int() == -2 assert x.int() < -1 assert x.int() <= -1