def test_duration(): scheme = S.Scheme("""yamls:// - name: msg fields: - {name: us, type: int64, options.type: duration, options.resolution: us} - {name: fms, type: double, options.type: duration, options.resolution: ms} - {name: second, type: uint32, options.type: duration, options.resolution: second} - {name: day, type: int32, options.type: duration, options.resolution: day} """) dt = datetime.timedelta(days=5, seconds=12345, microseconds=123456) msg = scheme['msg'] m = msg.object(us=dt, fms=dt, second=dt, day=dt) assert m.us.value == int(dt.total_seconds()) * 1000000 + dt.microseconds assert m.fms.value == dt.total_seconds() * 1000 assert m.second.value == int(dt.total_seconds()) assert m.day.value == m.second.value // 86400 u = msg.unpack(memoryview(m.pack())) assert u.as_dict() == m.as_dict() m.us = '123ms' assert m.us == Duration(123000, 'us', int)
def test_string(): s = S.Scheme('''yamls:// - name: sub fields: - {name: s0, type: string} - name: msg fields: - {name: f0, type: string} - {name: f1, type: sub} - {name: f2, type: '*string'} ''') M = s['msg'] m0 = M.object(f0="ыыы", f1={'s0': "nestedtail"}, f2=["a", "b", "c"]) data = m0.pack() assert len(data) == M.size + len( s2b("ыыы\0")) + len(b"nestedtail\0") + 3 * (8 + 2) assert struct.unpack("=QQQ7s11sQQQ2s2s2s", data) == (optr(24, 6 + 1, 1), optr(23, 10 + 1, 1), optr(26, 3, 8), s2b("ыыы\0"), b"nestedtail\0", optr(24, 1 + 1, 1), optr(18, 1 + 1, 1), optr(12, 1 + 1, 1), b'a\0', b'b\0', b'c\0') m1 = M.object().unpack(data) assert m1.f0 == "ыыы" assert m1.f1.s0 == "nestedtail"
def test_decimal128(): scheme = S.Scheme("""yamls:// - name: msg fields: - {name: dec, type: decimal128} - {name: inf, type: decimal128} - {name: ninf, type: decimal128} - {name: nan, type: decimal128} - {name: snan, type: decimal128} """) msg = scheme['msg'] m = msg.object(dec=decimal.Decimal('1234567890.e-5'), inf='Inf', ninf='-Inf', nan='NaN', snan='sNaN') assert m.dec == decimal.Decimal('1234567890.e-5') assert m.inf == decimal.Decimal('Inf') assert m.ninf == decimal.Decimal('-Inf') assert m.nan.is_qnan() assert m.snan.is_snan() data = memoryview(m.pack()) u = msg.unpack(data) assert u.dec == decimal.Decimal('1234567890.e-5') assert u.inf == decimal.Decimal('Inf') assert u.ninf == decimal.Decimal('-Inf') assert u.nan.is_qnan() assert u.snan.is_snan() assert m.SCHEME['dec'].from_string('123.4') == decimal.Decimal('123.4')
def test_import(): SCHEME = '''yamls:// - name: import: - | yamls:// - name: aliases: - {name: license, type: byte64, options.type: string} - | yamls:// - name: sub fields: - {name: s0, type: license} - name: msg fields: - {name: f0, type: license} - {name: fs, type: sub} ''' s = S.Scheme(SCHEME) assert [(f.name, f.type, f.sub_type) for f in s.aliases.values() ] == [("license", F.Bytes, F.Sub.ByteString)] assert [m.name for m in s.messages] == ['sub', 'msg']
def test_enum(): scheme = S.Scheme("""yamls:// - name: msg enums: e8: type: uint8 enum: {A: 1, B: 2, C: 3} e64: type: int64 enum: {A: 10000, B: 20000, C: 30000} fields: - {name: e8, type: e8} - {name: e64, type: e64} """) msg = scheme['msg'] m = msg.object(e8=1, e64='A') assert m.e8.value == 1 assert m.e8 == m.e8.A assert m.e64.value == 10000 assert m.e64 == m.e64.A u = msg.unpack(memoryview(m.pack())) assert u.as_dict() == m.as_dict() assert u.e8.value == 1 assert u.e8 == u.e8.A assert u.e64.value == 10000 assert u.e64 == u.e64.A assert m.SCHEME['e8'].from_string('1') == m.e8.A assert m.SCHEME['e8'].from_string('A') == m.e8.A
def test_list(version): scheme = S.Scheme("""yamls:// - name: sub fields: - {name: f0, type: int8} - name: msg fields: - {name: scalar, type: '*int8', list-options.offset-ptr-type: %(version)s} - {name: msg, type: '*sub', list-options.offset-ptr-type: %(version)s} - {name: fixed, type: 'int8[8]'} """ % {'version': version}) msg = scheme['msg'] m = msg.object(scalar=[1, 2, 3], fixed=[4, 3, 2, 1], msg=[{ 'f0': 10 }, { 'f0': 20 }]) with pytest.raises(TypeError): m.msg.append(None) with pytest.raises(TypeError): m.msg.append(10) with pytest.raises(TypeError): m.fixed.append(None) with pytest.raises(TypeError): m.fixed.append({}) m.msg.append({'f0': 30}) assert m.msg[2].f0 == 30 m.msg = m.msg[:1] m.msg += [{'f0': 20}] assert m.msg[-1].f0 == 20 u = msg.unpack(memoryview(m.pack())) assert m.as_dict() == u.as_dict() c = copy.deepcopy(m) assert c.as_dict() == m.as_dict() c.msg[1].f0 = 100 assert m.msg[1].f0 == 20 u = msg.unpack(memoryview(c.pack())) assert c.as_dict() == u.as_dict() data = m.pack() with pytest.raises(ValueError): msg.unpack(memoryview(data[:-10])) m = msg.object(scalar=[], fixed=[], msg=[]) u = msg.unpack(memoryview(m.pack())) assert m.as_dict() == u.as_dict()
def test_as_dict(): s = S.Scheme(scheme) M = s['sub'].object(s0=10, s1=[1., 2., 3.]) assert M.as_dict() == {'s0': 10, 's1': [1., 2., 3.]} data = M.pack() r = M.SCHEME.reflection(data) assert r.as_dict() == M.as_dict()
def test_list_empty(version): scheme = S.Scheme("""yamls:// - name: msg fields: - {name: list, type: '*int8', list-options.offset-ptr-type: %s} """ % version) msg = scheme['msg'] m = msg.object(list=[]) u = msg.unpack(memoryview(m.pack())) assert m.as_dict() == u.as_dict()
def test_sub_pack(): s = S.Scheme('''yamls:// - name: sub fields: - {name: s0, type: int32} - name: msg fields: - {name: f0, type: sub} - {name: f1, type: 'sub[2]'} - {name: f2, type: '*sub'} - {name: f3, type: '**sub'} ''') M = s['msg'] m0 = M.object(f0={'s0': 10}, f1=[{ 's0': 20 }, { 's0': 30 }], f2=[{ 's0': 40 }, { 's0': 50 }], f3=[[{ 's0': 60 }], [], [{ 's0': 70 }, { 's0': 80 }]]) data = m0.pack() assert len(data) == M.size + 2 * 4 + 3 * 8 + 3 * 4 assert struct.unpack("=ibiiQQiiQQQiii", data) == (10, 2, 20, 30, optr(16, 2, 4), optr(16, 3, 8), 40, 50, optr(24, 1, 4), optr(20, 0, 4), optr(12, 2, 4), 60, 70, 80) m1 = M.object().unpack(data) assert m1.f0.s0 == 10 assert [x.s0 for x in m1.f1] == [20, 30] assert [x.s0 for x in m1.f2] == [40, 50] assert [[x.s0 for x in y] for y in m1.f3] == [[60], [], [70, 80]] r = M.reflection(data) assert r.f0.s0 == m1.f0.s0 assert [x.s0 for x in r.f1] == [20, 30] assert [x.s0 for x in r.f2] == [40, 50] assert [[x.s0 for x in y] for y in r.f3] == [[60], [], [70, 80]]
def test_pack(): s = S.Scheme(scheme) M = s['sub'].object(s0=10, s1=[1., 2., 3.]) data = M.pack() assert len(data) == M.SCHEME.size assert struct.unpack("=ibdddd", data) == (10, 3, 1., 2., 3., 0.) m1 = s['sub'].object().unpack(data) assert m1.s0 == 10 assert m1.s1 == [1., 2., 3.] r = M.SCHEME.reflection(data) assert getattr(r, 'xxx', None) == None assert r.s0 == m1.s0 assert r.s1 == m1.s1
def test_bytes(): scheme = S.Scheme("""yamls:// - name: msg fields: - {name: f0, type: byte1} - {name: f1, type: byte1, options.type: string} - {name: f2, type: byte14, options.type: string} """) msg = scheme['msg'] m = msg.object(f0=b'A', f1='B', f2='CDE') u = msg.unpack(memoryview(m.pack())) assert u.as_dict() == m.as_dict()
def test_pointer_type(): scheme = S.Scheme("""yamls:// - name: msg fields: - {name: default, type: '*int8'} - {name: lshort, type: '*int8', list-options.offset-ptr-type: legacy-short} - {name: llong, type: '*int8', list-options.offset-ptr-type: legacy-long} """) msg = scheme['msg'] assert msg['default'].options == {} assert msg['lshort'].options == {'offset-ptr-type': 'legacy-short'} assert msg['llong'].options == {'offset-ptr-type': 'legacy-long'} s1 = S.Scheme(scheme.dump()) assert [(f.name, f.options) for f in scheme['msg'].values() ] == [(f.name, f.options) for f in s1['msg'].values()] m = msg.object(default=[1, 2, 3], lshort=[10, 11], llong=[100, 101, 102, 103]) data = memoryview(m.pack()) u = msg.unpack(data) assert m.as_dict() == u.as_dict()
def test_field_del(): scheme = S.Scheme("""yamls:// - name: msg fields: - {name: f0, type: int32} """) msg = scheme['msg'] m = msg.object(f0=0xbeef) assert m.as_dict() == {'f0': 0xbeef} del m.f0 assert m.as_dict() == {} u = msg.unpack(memoryview(m.pack())) assert u.as_dict() == {'f0': 0}
def test_bits(): scheme = S.Scheme("""yamls:// - name: msg fields: - {name: i8, type: int8, options.type: bits, bits: [a, b, c]} - {name: u32, type: uint32, options.type: bits, bits: [c, d, e]} """) msg = scheme['msg'] m = msg.object(i8=0, u32=0) m.i8.a = 1 m.i8.b = 0 m.i8.c = 1 m.u32.d = 1 assert m.i8._value == 5 assert m.i8.a == True assert m.i8.b == False assert m.i8.c == True assert m.u32.c == False assert m.u32.d == True assert m.u32.e == False u = msg.unpack(memoryview(m.pack())) assert u.as_dict() == m.as_dict() assert u.i8.a == True assert u.i8.b == False assert u.i8.c == True assert u.u32.c == False assert u.u32.d == True assert u.u32.e == False m.i8 = 0 assert m.i8.a == False assert m.i8.b == False assert m.i8.c == False m.i8 = {'a', 'c'} assert m.i8.a == True assert m.i8.b == False assert m.i8.c == True
def test_union(): scheme = S.Scheme("""yamls:// - name: sub fields: - {name: s0, type: int64} - name: msg fields: - {name: pre, type: uint32} - name: u type: union union: - {name: i8, type: int8} - {name: array, type: 'int8[4]'} - {name: string, type: string} - {name: sub, type: sub} - {name: post, type: uint32} """) msg = scheme['msg'] m = msg.object(pre=0xffffffff, u=('sub', {'s0': 0xbeef}), post=0xffffffff) assert m.u[:1] == ('sub', ) assert m.u[1].as_dict() == {'s0': 0xbeef} assert m.as_dict() == { 'pre': 0xffffffff, 'u': ('sub', { 's0': 0xbeef }), 'post': 0xffffffff } data = memoryview(m.pack()) u = msg.unpack(data) assert u.as_dict() == m.as_dict() m.u = ('i8', 100) assert m.as_dict() == { 'pre': 0xffffffff, 'u': ('i8', 100), 'post': 0xffffffff }
def test_from_string(): s = S.Scheme('''yamls:// - name: msg fields: - {name: int8, type: int8} - {name: int16, type: int16} - {name: int32, type: int32} - {name: int64, type: int64} - {name: double, type: double} - {name: string, type: string} - {name: byte16, type: byte16} - {name: string16, type: byte16, option.type: string} - {name: array, type: 'int8[8]'} - {name: ptr, type: '*int8'} - {name: duration, type: int32, options.type: duration, options.resolution: ns} - {name: ts, type: int32, options.type: time_point, options.resolution: ns} ''') msg = s['msg'] assert msg['int8'].from_string("100") == 100 assert msg['int16'].from_string("0x1234") == 0x1234 assert msg['int32'].from_string("0o777777777") == 0o777777777 assert msg['int64'].from_string("12345678") == 12345678 assert msg['double'].from_string("123.456") == 123.456 assert msg['string'].from_string("string") == "string" assert msg['byte16'].from_string("string") == b"string" assert msg['duration'].from_string("100ns") == Duration(100, 'ns') assert msg['duration'].from_string("10.5us") == Duration(10500, 'ns') assert msg['ts'].from_string("100ns") == TimePoint( 100, 'ns') # FIXME: Change to normal time format? with pytest.raises(OverflowError): msg['int8'].from_string("1000") with pytest.raises(ValueError): msg['int8'].from_string("string") with pytest.raises(TypeError): msg['array'].from_string("[]") with pytest.raises(TypeError): msg['ptr'].from_string("[]")
def test_scalar(t): scheme = S.Scheme("""yamls:// - name: msg fields: - {name: f, type: %s} """ % t) if t[0] == 'u': size = int(t[4:]) imin = 0 imax = 2**size - 1 else: size = int(t[3:]) imin = -1 * 2**(size - 1) imax = 2**(size - 1) - 1 msg = scheme['msg'] m = msg.object() for v in [imin, imax // 2, imax]: m.f = v assert m.f == v u = msg.unpack(memoryview(m.pack())) assert m.as_dict() == u.as_dict() r = msg.reflection(memoryview(m.pack())) assert m.f == r.f assert msg['f'].from_string(str(v)) == v assert msg['f'].from_string(hex(v)) == v with pytest.raises(OverflowError): msg['f'].from_string(str(imax + 1)) with pytest.raises(OverflowError): msg['f'].from_string(str(imin - 1)) with pytest.raises(OverflowError): setattr(m, 'f', imax + 1) with pytest.raises(OverflowError): setattr(m, 'f', imin - 1)
def test_time_point(): scheme = S.Scheme("""yamls:// - name: msg fields: - {name: us, type: int64, options.type: time_point, options.resolution: us} - {name: fms, type: double, options.type: time_point, options.resolution: ms} - {name: second, type: uint32, options.type: time_point, options.resolution: second} - {name: day, type: int32, options.type: time_point, options.resolution: day} """) now = datetime.datetime(2021, 1, 27, 21, 47, 49, 123456) msg = scheme['msg'] m = msg.object(us=now, fms=now, second=now, day=now) assert m.us.value == int(now.timestamp()) * 1000000 + now.microsecond assert m.fms.value == now.timestamp() * 1000 assert m.second.value == int(now.timestamp()) assert m.day.value == m.second.value // 86400 u = msg.unpack(memoryview(m.pack())) assert u.as_dict() == m.as_dict()
def test_fixed(): scheme = S.Scheme("""yamls:// - name: msg fields: - {name: i8, type: int8, options.type: fixed1} - {name: i16, type: int16, options.type: fixed2} - {name: i32, type: int32, options.type: fixed3} - {name: i64, type: int64, options.type: fixed4} - {name: u8, type: uint8, options.type: fixed5} - {name: u16, type: uint16, options.type: fixed6} - {name: u32, type: uint32, options.type: fixed7} """) msg = scheme['msg'] for (i, f) in enumerate(msg.fields): assert f.fixed_precision == i + 1, f"field {f.name}: {f.fixed_precision} != {i + 1}" m = msg.object(i8=-1, i16=2, i32=-3, i64=41.4, u8='0.0007', u16='0.012345', u32='123') assert m.i8 == decimal.Decimal(-1) assert m.i16 == 2 assert m.i32 == decimal.Decimal(-3) assert m.i64 == decimal.Decimal('41.4') assert m.u8 == decimal.Decimal('0.0007') assert m.u16 == decimal.Decimal('0.012345') assert m.u32 == decimal.Decimal('123') data = memoryview(m.pack()) u = msg.unpack(data) assert m.as_dict() == u.as_dict() assert m.SCHEME['i16'].from_string('123.4') == decimal.Decimal('123.4') assert m.SCHEME['u16'].from_string('123.4') == decimal.Decimal('123.4')
def test(): return _test(S.Scheme(scheme))
def test_alias(): return _test_alias(S.Scheme(SCHEME_ALIAS))
def test_alias_copy(): return _test_alias(S.Scheme(SCHEME_ALIAS).copy())
def test_alias_dump(): print(S.Scheme(SCHEME_ALIAS).dump()) return _test_alias(S.Scheme(S.Scheme(SCHEME_ALIAS).dump()))
def test_copy(): return _test(S.Scheme(scheme).copy())
def test_options_dump(): return _test_options(S.Scheme(S.Scheme(scheme).dump()))
def test_dump(): print(S.Scheme(scheme).dump()) return _test(S.Scheme(S.Scheme(scheme).dump()))
def test_options(): return _test_options(S.Scheme(scheme))