@@ -18,7 +18,7 @@ fn test_generate_versionstamp() {
1818
1919#[ test]
2020fn test_substitute_versionstamp_success ( ) {
21- let incomplete = Versionstamp :: from ( [ 0xff ; 12 ] ) ;
21+ let incomplete = Versionstamp :: incomplete ( 100 ) ;
2222 let tuple = vec ! [
2323 Element :: String ( "mykey" . into( ) ) ,
2424 Element :: Versionstamp ( incomplete) ,
@@ -99,9 +99,83 @@ fn test_substitute_versionstamp_already_complete() {
9999 assert ! ( result. is_ok( ) ) ;
100100}
101101
102+ #[ test]
103+ fn test_substitute_raw_versionstamp_trims_explicit_operand_offset ( ) {
104+ let versionstamp = generate_versionstamp ( 100 ) ;
105+ let mut param = b"prefix" . to_vec ( ) ;
106+ let offset = param. len ( ) as u32 ;
107+ param. extend_from_slice ( & [ 0xff ; 10 ] ) ;
108+ param. extend_from_slice ( b"suffix" ) ;
109+ param. extend_from_slice ( & offset. to_le_bytes ( ) ) ;
110+
111+ let substituted = substitute_raw_versionstamp ( param. clone ( ) , & versionstamp) . unwrap ( ) ;
112+
113+ assert_eq ! ( substituted. len( ) , param. len( ) - 4 ) ;
114+ assert_eq ! ( & substituted[ ..offset as usize ] , b"prefix" ) ;
115+ assert_eq ! (
116+ & substituted[ offset as usize ..offset as usize + 10 ] ,
117+ & versionstamp. as_bytes( ) [ ..10 ]
118+ ) ;
119+ assert_eq ! ( & substituted[ offset as usize + 10 ..] , b"suffix" ) ;
120+ }
121+
122+ #[ test]
123+ fn test_substitute_raw_versionstamp_matches_fdb_metadata_value_operand ( ) {
124+ let versionstamp = generate_versionstamp ( 100 ) ;
125+ let mut param = vec ! [ 0 ; 14 ] ;
126+ param[ 10 ..] . copy_from_slice ( & 0u32 . to_le_bytes ( ) ) ;
127+
128+ let substituted = substitute_raw_versionstamp ( param, & versionstamp) . unwrap ( ) ;
129+
130+ assert_eq ! ( substituted, versionstamp. as_bytes( ) [ ..10 ] ) ;
131+ }
132+
133+ #[ test]
134+ fn test_substitute_raw_versionstamp_preserves_depot_suffix_bytes ( ) {
135+ let versionstamp = generate_versionstamp ( 100 ) ;
136+ let mut param = vec ! [ 0xff ; 10 ] ;
137+ param. extend_from_slice ( & [ 0 ; 6 ] ) ;
138+ param. extend_from_slice ( & 0u32 . to_le_bytes ( ) ) ;
139+
140+ let substituted = substitute_raw_versionstamp ( param, & versionstamp) . unwrap ( ) ;
141+
142+ assert_eq ! ( substituted. len( ) , 16 ) ;
143+ assert_eq ! ( & substituted[ ..10 ] , & versionstamp. as_bytes( ) [ ..10 ] ) ;
144+ assert_eq ! ( & substituted[ 10 ..] , & [ 0 ; 6 ] ) ;
145+ }
146+
147+ #[ test]
148+ fn test_substitute_versionstamp_matches_official_tuple_operand_layout ( ) {
149+ let tuple = (
150+ "prefix" ,
151+ Versionstamp :: incomplete ( 12345 ) ,
152+ "suffix" ,
153+ ) ;
154+ let mut ours = pack_with_versionstamp ( & tuple) ;
155+ let official = ours. clone ( ) ;
156+ let versionstamp = generate_versionstamp ( 54321 ) ;
157+
158+ substitute_versionstamp ( & mut ours, versionstamp. clone ( ) ) . unwrap ( ) ;
159+
160+ let offset_start = official. len ( ) - 4 ;
161+ let offset = u32:: from_le_bytes (
162+ official[ offset_start..]
163+ . try_into ( )
164+ . expect ( "official tuple offset should be four bytes" ) ,
165+ ) as usize ;
166+ let mut expected = official[ ..offset_start] . to_vec ( ) ;
167+ expected[ offset..offset + 10 ] . copy_from_slice ( & versionstamp. as_bytes ( ) [ ..10 ] ) ;
168+
169+ assert_eq ! ( ours, expected) ;
170+
171+ let unpacked: ( String , Versionstamp , String ) = unpack ( & ours) . unwrap ( ) ;
172+ assert ! ( unpacked. 1 . is_complete( ) ) ;
173+ assert_eq ! ( unpacked. 1 . user_version( ) , 12345 ) ;
174+ }
175+
102176#[ test]
103177fn test_pack_and_substitute_versionstamp ( ) {
104- let incomplete = Versionstamp :: from ( [ 0xff ; 12 ] ) ;
178+ let incomplete = Versionstamp :: incomplete ( 100 ) ;
105179 let tuple = vec ! [
106180 Element :: String ( "mykey" . into( ) ) ,
107181 Element :: Versionstamp ( incomplete) ,
@@ -155,8 +229,6 @@ fn test_versionstamp_incomplete_preserves_user_version() {
155229 "User version bytes should match"
156230 ) ;
157231
158- // Test with substitute_versionstamp - the user version from the incomplete versionstamp
159- // should be ignored and replaced with the one from the generated versionstamp
160232 let tuple = vec ! [
161233 Element :: String ( "test" . into( ) ) ,
162234 Element :: Versionstamp ( incomplete) ,
@@ -172,11 +244,10 @@ fn test_versionstamp_incomplete_preserves_user_version() {
172244 match & unpacked[ 1 ] {
173245 Element :: Versionstamp ( v) => {
174246 assert ! ( v. is_complete( ) ) ;
175- // The user version should be from the generated versionstamp, not the original incomplete one
176247 assert_eq ! (
177248 v. user_version( ) ,
178- new_user_version ,
179- "Substituted versionstamp should have the new user version"
249+ user_version ,
250+ "Substituted versionstamp should preserve the tuple user version"
180251 ) ;
181252 }
182253 _ => panic ! ( "Expected versionstamp" ) ,
0 commit comments