@@ -1223,7 +1223,33 @@ impl Message {
1223
1223
}
1224
1224
}
1225
1225
1226
+ #[ repr( C ) ]
1227
+ #[ derive( Debug , Default , Versionize ) ]
1228
+ struct Message2 {
1229
+ pub len : u32 ,
1230
+ #[ version( end = 4 ) ]
1231
+ pub padding : u32 ,
1232
+ pub value : u32 ,
1233
+ #[ version( start = 2 , default_fn = "default_extra_value" ) ]
1234
+ pub extra_value : u16 ,
1235
+ #[ version( start = 3 , end = 4 , default_fn = "default_status" ) ]
1236
+ pub status : Wrapping < bool > ,
1237
+ pub entries : __IncompleteArrayField < u32 > ,
1238
+ }
1239
+
1240
+ impl Message2 {
1241
+ fn default_extra_value ( _source_version : u16 ) -> u16 {
1242
+ 4
1243
+ }
1244
+
1245
+ fn default_status ( _source_version : u16 ) -> Wrapping < bool > {
1246
+ Wrapping ( false )
1247
+ }
1248
+ }
1249
+
1226
1250
generate_fam_struct_impl ! ( Message , u32 , entries, u32 , len, 100 ) ;
1251
+ // Duplicated structure used but with max_len 1 - for negative testing.
1252
+ generate_fam_struct_impl ! ( Message2 , u32 , entries, u32 , len, 1 ) ;
1227
1253
1228
1254
#[ repr( C ) ]
1229
1255
#[ derive( Default ) ]
@@ -1292,6 +1318,7 @@ impl<T> Versionize for __IncompleteArrayField<T> {
1292
1318
}
1293
1319
1294
1320
type MessageFamStructWrapper = FamStructWrapper < Message > ;
1321
+ type Message2FamStructWrapper = FamStructWrapper < Message2 > ;
1295
1322
1296
1323
#[ test]
1297
1324
fn test_versionize_famstructwrapper ( ) {
@@ -1303,7 +1330,7 @@ fn test_versionize_famstructwrapper() {
1303
1330
. new_version ( )
1304
1331
. set_type_version ( Message :: type_id ( ) , 4 ) ;
1305
1332
1306
- let mut state = MessageFamStructWrapper :: new ( 0 ) ;
1333
+ let mut state = MessageFamStructWrapper :: new ( 0 ) . unwrap ( ) ;
1307
1334
state. as_mut_fam_struct ( ) . padding = 8 ;
1308
1335
state. as_mut_fam_struct ( ) . extra_value = 16 ;
1309
1336
state. as_mut_fam_struct ( ) . status = Wrapping ( true ) ;
@@ -1422,7 +1449,7 @@ pub struct FamStructTest {
1422
1449
1423
1450
impl FamStructTest {
1424
1451
fn default_message ( _target_version : u16 ) -> Vec < MessageFamStructWrapper > {
1425
- let mut f = MessageFamStructWrapper :: new ( 0 ) ;
1452
+ let mut f = MessageFamStructWrapper :: new ( 0 ) . unwrap ( ) ;
1426
1453
f. as_mut_fam_struct ( ) . padding = 1 ;
1427
1454
f. as_mut_fam_struct ( ) . extra_value = 2 ;
1428
1455
@@ -1448,7 +1475,7 @@ impl FamStructTest {
1448
1475
// Fail if semantic deserialization is called for a version >= 2.
1449
1476
assert ! ( target_version < 2 ) ;
1450
1477
1451
- let mut f = MessageFamStructWrapper :: new ( 0 ) ;
1478
+ let mut f = MessageFamStructWrapper :: new ( 0 ) . unwrap ( ) ;
1452
1479
f. as_mut_fam_struct ( ) . padding = 3 ;
1453
1480
f. as_mut_fam_struct ( ) . extra_value = 4 ;
1454
1481
@@ -1472,12 +1499,12 @@ fn test_versionize_struct_with_famstructs() {
1472
1499
1473
1500
let mut snapshot_mem = vec ! [ 0u8 ; 1024 ] ;
1474
1501
1475
- let mut f = MessageFamStructWrapper :: new ( 0 ) ;
1502
+ let mut f = MessageFamStructWrapper :: new ( 0 ) . unwrap ( ) ;
1476
1503
f. as_mut_fam_struct ( ) . padding = 5 ;
1477
1504
f. as_mut_fam_struct ( ) . extra_value = 6 ;
1478
1505
f. push ( 10 ) . unwrap ( ) ;
1479
1506
1480
- let mut f2 = MessageFamStructWrapper :: new ( 0 ) ;
1507
+ let mut f2 = MessageFamStructWrapper :: new ( 0 ) . unwrap ( ) ;
1481
1508
f2. as_mut_fam_struct ( ) . padding = 7 ;
1482
1509
f2. as_mut_fam_struct ( ) . extra_value = 8 ;
1483
1510
f2. push ( 20 ) . unwrap ( ) ;
@@ -1556,12 +1583,30 @@ impl SomeStruct {
1556
1583
// Fail if semantic serialization is called for the latest version.
1557
1584
assert ! ( target_version < 2 ) ;
1558
1585
self . message . as_mut_fam_struct ( ) . padding += 2 ;
1586
+
1559
1587
Ok ( ( ) )
1560
1588
}
1561
1589
}
1562
1590
1563
- // TODO: remove this test once FamStructWrapper `Clone` implementation gets fixed.
1564
- // Tracking issue: https://github.com/rust-vmm/vmm-sys-util/issues/85.
1591
+ #[ derive( Clone , Versionize ) ]
1592
+ pub struct SomeStruct2 {
1593
+ message : Message2FamStructWrapper ,
1594
+ #[ version( start = 2 , ser_fn = "ser_u16" ) ]
1595
+ some_u16 : u16 ,
1596
+ }
1597
+
1598
+ impl SomeStruct2 {
1599
+ fn ser_u16 ( & mut self , target_version : u16 ) -> VersionizeResult < ( ) > {
1600
+ // Fail if semantic serialization is called for the latest version.
1601
+ assert ! ( target_version < 2 ) ;
1602
+ self . message . as_mut_fam_struct ( ) . padding += 2 ;
1603
+
1604
+ Ok ( ( ) )
1605
+ }
1606
+ }
1607
+
1608
+ // `Clone` issue fixed: https://github.com/rust-vmm/vmm-sys-util/issues/85.
1609
+ // We are keeping this as regression test.
1565
1610
#[ test]
1566
1611
fn test_famstructwrapper_clone ( ) {
1567
1612
// Test that having a `FamStructWrapper<T>` in a structure that implements
@@ -1570,7 +1615,7 @@ fn test_famstructwrapper_clone() {
1570
1615
let mut vm = VersionMap :: new ( ) ;
1571
1616
vm. new_version ( ) . set_type_version ( SomeStruct :: type_id ( ) , 2 ) ;
1572
1617
1573
- let mut f = MessageFamStructWrapper :: new ( 0 ) ;
1618
+ let mut f = MessageFamStructWrapper :: new ( 0 ) . unwrap ( ) ;
1574
1619
f. as_mut_fam_struct ( ) . padding = 8 ;
1575
1620
1576
1621
f. push ( 1 ) . unwrap ( ) ;
@@ -1589,6 +1634,12 @@ fn test_famstructwrapper_clone() {
1589
1634
. unwrap ( ) ;
1590
1635
let mut restored_state =
1591
1636
<SomeStruct as Versionize >:: deserialize ( & mut snapshot_mem. as_slice ( ) , & vm, 1 ) . unwrap ( ) ;
1637
+
1638
+ // Negative scenario - FamStruct versionize impl fails due to SizeLimitExceeded.
1639
+ assert ! (
1640
+ <SomeStruct2 as Versionize >:: deserialize( & mut snapshot_mem. as_slice( ) , & vm, 1 ) . is_err( )
1641
+ ) ;
1642
+
1592
1643
let original_values = state. message . as_slice ( ) ;
1593
1644
let restored_values = restored_state. message . as_slice ( ) ;
1594
1645
@@ -1597,20 +1648,23 @@ fn test_famstructwrapper_clone() {
1597
1648
restored_state. message. as_fam_struct_ref( ) . padding
1598
1649
) ;
1599
1650
assert_eq ! ( original_values, restored_values) ;
1600
- // `padding` field will take the default value (0 ), and then it will be incremented with 2
1651
+ // `padding` field will have its value serialized (8 ), and then it will be incremented with 2
1601
1652
// by `ser_u16`.
1602
- assert_eq ! ( 2 , restored_state. message. as_fam_struct_ref( ) . padding) ;
1653
+ assert_eq ! ( 10 , restored_state. message. as_fam_struct_ref( ) . padding) ;
1603
1654
1604
1655
// Serialize as v2.
1605
1656
state
1606
1657
. serialize ( & mut snapshot_mem. as_mut_slice ( ) , & vm, 2 )
1607
1658
. unwrap ( ) ;
1608
1659
restored_state =
1609
1660
<SomeStruct as Versionize >:: deserialize ( & mut snapshot_mem. as_slice ( ) , & vm, 2 ) . unwrap ( ) ;
1610
- assert_ne ! (
1661
+
1662
+ // Padding is correctly preserved and ser_u16 is not called - it would fail due to ser_u16
1663
+ // assert anyways, but we double that check here.
1664
+ assert_eq ! (
1611
1665
state. message. as_fam_struct_ref( ) . padding,
1612
1666
restored_state. message. as_fam_struct_ref( ) . padding
1613
1667
) ;
1614
- // `padding` field will take the default value (0 ). `ser_u16` won't be called at v2.
1615
- assert_eq ! ( 0 , restored_state. message. as_fam_struct_ref( ) . padding) ;
1668
+ // `padding` field will have its value preserved (8 ). `ser_u16` won't be called at v2.
1669
+ assert_eq ! ( 8 , restored_state. message. as_fam_struct_ref( ) . padding) ;
1616
1670
}
0 commit comments