@@ -201,9 +201,13 @@ pub async fn put_and_query_with_beacon(branch_key_id: &str) -> Result<(), crate:
201201 . table_encryption_configs ( HashMap :: from ( [ ( ddb_table_name. to_string ( ) , table_config) ] ) )
202202 . build ( ) ?;
203203
204+ // Generate unique work_id values for this run to avoid collisions with stale items
205+ let work_id1 = uuid:: Uuid :: new_v4 ( ) . to_string ( ) ;
206+ let work_id2 = uuid:: Uuid :: new_v4 ( ) . to_string ( ) ;
207+
204208 // 8. Create item one, specifically with "dessert != fruit", and "fruit in basket".
205209 let item1 = HashMap :: from ( [
206- ( "work_id" . to_string ( ) , AttributeValue :: S ( "1" . to_string ( ) ) ) ,
210+ ( "work_id" . to_string ( ) , AttributeValue :: S ( work_id1 . clone ( ) ) ) ,
207211 (
208212 "inspection_date" . to_string ( ) ,
209213 AttributeValue :: S ( "2023-06-13" . to_string ( ) ) ,
@@ -234,7 +238,7 @@ pub async fn put_and_query_with_beacon(branch_key_id: &str) -> Result<(), crate:
234238
235239 // 9. Create item two, specifically with "dessert == fruit", and "fruit not in basket".
236240 let item2 = HashMap :: from ( [
237- ( "work_id" . to_string ( ) , AttributeValue :: S ( "2" . to_string ( ) ) ) ,
241+ ( "work_id" . to_string ( ) , AttributeValue :: S ( work_id2 . clone ( ) ) ) ,
238242 (
239243 "inspection_date" . to_string ( ) ,
240244 AttributeValue :: S ( "2023-06-13" . to_string ( ) ) ,
@@ -285,43 +289,78 @@ pub async fn put_and_query_with_beacon(branch_key_id: &str) -> Result<(), crate:
285289 . send ( )
286290 . await ?;
287291
292+ // Run all scan tests, then clean up items regardless of success or failure
293+ let result = run_scan_tests ( & ddb, ddb_table_name, & item1, & item2, & work_id1, & work_id2) . await ;
294+
295+ // Clean up: delete both items
296+ let plain_ddb = aws_sdk_dynamodb:: Client :: new ( & sdk_config) ;
297+ let _ = plain_ddb
298+ . delete_item ( )
299+ . table_name ( ddb_table_name)
300+ . key ( "work_id" , AttributeValue :: S ( work_id1) )
301+ . key ( "inspection_date" , AttributeValue :: S ( "2023-06-13" . to_string ( ) ) )
302+ . send ( )
303+ . await ;
304+ let _ = plain_ddb
305+ . delete_item ( )
306+ . table_name ( ddb_table_name)
307+ . key ( "work_id" , AttributeValue :: S ( work_id2) )
308+ . key ( "inspection_date" , AttributeValue :: S ( "2023-06-13" . to_string ( ) ) )
309+ . send ( )
310+ . await ;
311+
312+ result?;
313+ println ! ( "beacon_styles_searchable_encryption successful." ) ;
314+ Ok ( ( ) )
315+ }
316+
317+ async fn run_scan_tests (
318+ ddb : & aws_sdk_dynamodb:: Client ,
319+ ddb_table_name : & str ,
320+ item1 : & HashMap < String , AttributeValue > ,
321+ item2 : & HashMap < String , AttributeValue > ,
322+ work_id1 : & str ,
323+ work_id2 : & str ,
324+ ) -> Result < ( ) , crate :: BoxError > {
325+ // These filters ensure scans only match items created by this test run.
326+ let wid_filter = "work_id IN (:wid1, :wid2)" ;
327+ let wid_values = HashMap :: from ( [
328+ ( ":wid1" . to_string ( ) , AttributeValue :: S ( work_id1. to_string ( ) ) ) ,
329+ ( ":wid2" . to_string ( ) , AttributeValue :: S ( work_id2. to_string ( ) ) ) ,
330+ ] ) ;
331+
288332 // 12. Test the first type of Set operation :
289333 // Select records where the basket attribute holds a particular value
290- let expression_attribute_values = HashMap :: from ( [ (
291- ":value" . to_string ( ) ,
292- AttributeValue :: S ( "banana" . to_string ( ) ) ,
293- ) ] ) ;
334+ let mut expr_vals = wid_values. clone ( ) ;
335+ expr_vals. insert ( ":value" . to_string ( ) , AttributeValue :: S ( "banana" . to_string ( ) ) ) ;
294336
295337 let scan_response = ddb
296338 . scan ( )
297339 . table_name ( ddb_table_name)
298- . filter_expression ( " contains(basket, :value)")
299- . set_expression_attribute_values ( Some ( expression_attribute_values . clone ( ) ) )
340+ . filter_expression ( format ! ( "{wid_filter} AND contains(basket, :value)") )
341+ . set_expression_attribute_values ( Some ( expr_vals ) )
300342 . send ( )
301343 . await ?;
302344
303345 let attribute_values = scan_response. items . unwrap ( ) ;
304346 // Validate only 1 item was returned: item1
305347 assert_eq ! ( attribute_values. len( ) , 1 ) ;
306- let returned_item = & attribute_values[ 0 ] ;
307- // Validate the item has the expected attributes
308- assert_eq ! ( returned_item[ "work_id" ] , item1[ "work_id" ] ) ;
348+ assert_eq ! ( attribute_values[ 0 ] [ "work_id" ] , item1[ "work_id" ] ) ;
309349
310350 // 13. Test the second type of Set operation :
311351 // Select records where the basket attribute holds the fruit attribute
312352 let scan_response = ddb
313353 . scan ( )
314354 . table_name ( ddb_table_name)
315- . filter_expression ( "contains(basket, fruit)" )
355+ . filter_expression ( format ! ( "{wid_filter} AND contains(basket, fruit)" ) )
356+ . set_expression_attribute_values ( Some ( wid_values. clone ( ) ) )
316357 . send ( )
317358 . await ?;
318359
319360 let attribute_values = scan_response. items . unwrap ( ) ;
320361 // Validate only 1 item was returned: item1
321362 assert_eq ! ( attribute_values. len( ) , 1 ) ;
322- let returned_item = & attribute_values[ 0 ] ;
323- // Validate the item has the expected attributes
324- assert_eq ! ( returned_item[ "work_id" ] , item1[ "work_id" ] ) ;
363+ assert_eq ! ( attribute_values[ 0 ] [ "work_id" ] , item1[ "work_id" ] ) ;
325364
326365 // 14. Test the third type of Set operation :
327366 // Select records where the fruit attribute exists in a particular set
@@ -330,80 +369,73 @@ pub async fn put_and_query_with_beacon(branch_key_id: &str) -> Result<(), crate:
330369 "orange" . to_string( ) ,
331370 "grape" . to_string( ) ,
332371 ] ;
333- let expression_attribute_values =
334- HashMap :: from ( [ ( ":value" . to_string ( ) , AttributeValue :: Ss ( basket3) ) ] ) ;
372+ let mut expr_vals = wid_values . clone ( ) ;
373+ expr_vals . insert ( ":value" . to_string ( ) , AttributeValue :: Ss ( basket3) ) ;
335374
336375 let scan_response = ddb
337376 . scan ( )
338377 . table_name ( ddb_table_name)
339- . filter_expression ( " contains(:value, fruit)")
340- . set_expression_attribute_values ( Some ( expression_attribute_values . clone ( ) ) )
378+ . filter_expression ( format ! ( "{wid_filter} AND contains(:value, fruit)") )
379+ . set_expression_attribute_values ( Some ( expr_vals ) )
341380 . send ( )
342381 . await ?;
343382
344383 let attribute_values = scan_response. items . unwrap ( ) ;
345- // Validate only 1 item was returned: item1
384+ // Validate only 1 item was returned: item2
346385 assert_eq ! ( attribute_values. len( ) , 1 ) ;
347- let returned_item = & attribute_values[ 0 ] ;
348- // Validate the item has the expected attributes
349- assert_eq ! ( returned_item[ "work_id" ] , item2[ "work_id" ] ) ;
386+ assert_eq ! ( attribute_values[ 0 ] [ "work_id" ] , item2[ "work_id" ] ) ;
350387
351388 // 15. Test a Shared search. Select records where the dessert attribute matches the fruit attribute
352389 let scan_response = ddb
353390 . scan ( )
354391 . table_name ( ddb_table_name)
355- . filter_expression ( "dessert = fruit" )
392+ . filter_expression ( format ! ( "{wid_filter} AND dessert = fruit" ) )
393+ . set_expression_attribute_values ( Some ( wid_values. clone ( ) ) )
356394 . send ( )
357395 . await ?;
358396
359397 let attribute_values = scan_response. items . unwrap ( ) ;
360- // Validate only 1 item was returned: item1
398+ // Validate only 1 item was returned: item2
361399 assert_eq ! ( attribute_values. len( ) , 1 ) ;
362- let returned_item = & attribute_values[ 0 ] ;
363- // Validate the item has the expected attributes
364- assert_eq ! ( returned_item[ "work_id" ] , item2[ "work_id" ] ) ;
400+ assert_eq ! ( attribute_values[ 0 ] [ "work_id" ] , item2[ "work_id" ] ) ;
365401
366- // 15 . Test the AsSet attribute 'veggies' :
402+ // 16 . Test the AsSet attribute 'veggies' :
367403 // Select records where the veggies attribute holds a particular value
368- let expression_attribute_values =
369- HashMap :: from ( [ ( ":value" . to_string ( ) , AttributeValue :: S ( "peas" . to_string ( ) ) ) ] ) ;
404+ let mut expr_vals = wid_values . clone ( ) ;
405+ expr_vals . insert ( ":value" . to_string ( ) , AttributeValue :: S ( "peas" . to_string ( ) ) ) ;
370406
371407 let scan_response = ddb
372408 . scan ( )
373409 . table_name ( ddb_table_name)
374- . filter_expression ( " contains(veggies, :value)")
375- . set_expression_attribute_values ( Some ( expression_attribute_values . clone ( ) ) )
410+ . filter_expression ( format ! ( "{wid_filter} AND contains(veggies, :value)") )
411+ . set_expression_attribute_values ( Some ( expr_vals ) )
376412 . send ( )
377413 . await ?;
378414
379415 let attribute_values = scan_response. items . unwrap ( ) ;
380- // Validate only 1 item was returned: item1
416+ // Validate only 1 item was returned: item2
381417 assert_eq ! ( attribute_values. len( ) , 1 ) ;
382- let returned_item = & attribute_values[ 0 ] ;
383- // Validate the item has the expected attributes
384- assert_eq ! ( returned_item[ "work_id" ] , item2[ "work_id" ] ) ;
418+ assert_eq ! ( attribute_values[ 0 ] [ "work_id" ] , item2[ "work_id" ] ) ;
385419
386- // 16. Test the compound beacon 'work_unit' :
387- let expression_attribute_values = HashMap :: from ( [ (
420+ // 17. Test the compound beacon 'work_unit' :
421+ let mut expr_vals = wid_values. clone ( ) ;
422+ expr_vals. insert (
388423 ":value" . to_string ( ) ,
389- AttributeValue :: S ( "I-1 .T-small" . to_string ( ) ) ,
390- ) ] ) ;
424+ AttributeValue :: S ( format ! ( "I-{} .T-small" , item1 [ "work_id" ] . as_s ( ) . unwrap ( ) ) ) ,
425+ ) ;
391426
392427 let scan_response = ddb
393428 . scan ( )
394429 . table_name ( ddb_table_name)
395- . filter_expression ( " work_unit = :value")
396- . set_expression_attribute_values ( Some ( expression_attribute_values . clone ( ) ) )
430+ . filter_expression ( format ! ( "{wid_filter} AND work_unit = :value") )
431+ . set_expression_attribute_values ( Some ( expr_vals ) )
397432 . send ( )
398433 . await ?;
399434
400435 let attribute_values = scan_response. items . unwrap ( ) ;
401436 // Validate only 1 item was returned: item1
402437 assert_eq ! ( attribute_values. len( ) , 1 ) ;
403- let returned_item = & attribute_values[ 0 ] ;
404- // Validate the item has the expected attributes
405- assert_eq ! ( returned_item[ "work_id" ] , item1[ "work_id" ] ) ;
438+ assert_eq ! ( attribute_values[ 0 ] [ "work_id" ] , item1[ "work_id" ] ) ;
406439
407- println ! ( "beacon_styles_searchable_encryption successful." ) ;
408440 Ok ( ( ) )
409441}
0 commit comments