@@ -3,6 +3,7 @@ use std::sync::Arc;
3
3
4
4
use delta_kernel:: Error as KernelError ;
5
5
use delta_kernel:: { DeltaResult , Engine , Snapshot , Version } ;
6
+ use uuid:: Uuid ;
6
7
7
8
use delta_kernel:: arrow:: array:: { ArrayRef , BinaryArray , StructArray } ;
8
9
use delta_kernel:: arrow:: array:: { Int32Array , StringArray , TimestampMicrosecondArray } ;
@@ -35,6 +36,15 @@ use test_utils::{create_table, engine_store_setup, setup_test_tables, test_read}
35
36
mod common;
36
37
use url:: Url ;
37
38
39
+ fn validate_txn_id ( commit_info : & serde_json:: Value ) {
40
+ let txn_id = commit_info[ "txnId" ]
41
+ . as_str ( )
42
+ . expect ( "txnId should be present in commitInfo" ) ;
43
+ Uuid :: parse_str ( txn_id) . expect ( "txnId should be valid UUID format" ) ;
44
+ }
45
+
46
+ const ZERO_UUID : & str = "00000000-0000-0000-0000-000000000000" ;
47
+
38
48
#[ tokio:: test]
39
49
async fn test_commit_info ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
40
50
// setup tracing
@@ -63,11 +73,11 @@ async fn test_commit_info() -> Result<(), Box<dyn std::error::Error>> {
63
73
. await ?;
64
74
65
75
let mut parsed_commit: serde_json:: Value = serde_json:: from_slice ( & commit1. bytes ( ) . await ?) ?;
66
- * parsed_commit
67
- . get_mut ( "commitInfo" )
68
- . unwrap ( )
69
- . get_mut ( " timestamp")
70
- . unwrap ( ) = serde_json :: Value :: Number ( 0 . into ( ) ) ;
76
+
77
+ validate_txn_id ( & parsed_commit [ "commitInfo" ] ) ;
78
+
79
+ set_json_value ( & mut parsed_commit , "commitInfo. timestamp", json ! ( 0 ) ) ? ;
80
+ set_json_value ( & mut parsed_commit , "commitInfo.txnId" , json ! ( ZERO_UUID ) ) ? ;
71
81
72
82
let expected_commit = json ! ( {
73
83
"commitInfo" : {
@@ -76,6 +86,7 @@ async fn test_commit_info() -> Result<(), Box<dyn std::error::Error>> {
76
86
"kernelVersion" : format!( "v{}" , env!( "CARGO_PKG_VERSION" ) ) ,
77
87
"operationParameters" : { } ,
78
88
"engineInfo" : "default engine" ,
89
+ "txnId" : ZERO_UUID ,
79
90
}
80
91
} ) ;
81
92
@@ -217,9 +228,12 @@ async fn test_commit_info_action() -> Result<(), Box<dyn std::error::Error>> {
217
228
. into_iter :: < serde_json:: Value > ( )
218
229
. try_collect ( ) ?;
219
230
220
- // set timestamps to 0 and paths to known string values for comparison
221
- // (otherwise timestamps are non-deterministic and paths are random UUIDs)
231
+ validate_txn_id ( & parsed_commits[ 0 ] [ "commitInfo" ] ) ;
232
+
233
+ // set timestamps to 0, paths and txn_id to known string values for comparison
234
+ // (otherwise timestamps are non-deterministic, paths and txn_id are random UUIDs)
222
235
set_json_value ( & mut parsed_commits[ 0 ] , "commitInfo.timestamp" , json ! ( 0 ) ) ?;
236
+ set_json_value ( & mut parsed_commits[ 0 ] , "commitInfo.txnId" , json ! ( ZERO_UUID ) ) ?;
223
237
224
238
let expected_commit = vec ! [ json!( {
225
239
"commitInfo" : {
@@ -228,6 +242,7 @@ async fn test_commit_info_action() -> Result<(), Box<dyn std::error::Error>> {
228
242
"kernelVersion" : format!( "v{}" , env!( "CARGO_PKG_VERSION" ) ) ,
229
243
"operationParameters" : { } ,
230
244
"engineInfo" : "default engine" ,
245
+ "txnId" : ZERO_UUID
231
246
}
232
247
} ) ] ;
233
248
@@ -270,10 +285,13 @@ async fn test_append() -> Result<(), Box<dyn std::error::Error>> {
270
285
// check that the timestamps in commit_info and add actions are within 10s of SystemTime::now()
271
286
// before we clear them for comparison
272
287
check_action_timestamps ( parsed_commits. iter ( ) ) ?;
288
+ // check that the txn_id is valid before we clear it for comparison
289
+ validate_txn_id ( & parsed_commits[ 0 ] [ "commitInfo" ] ) ;
273
290
274
- // set timestamps to 0 and paths to known string values for comparison
275
- // (otherwise timestamps are non-deterministic and paths are random UUIDs)
291
+ // set timestamps to 0, paths and txn_id to known string values for comparison
292
+ // (otherwise timestamps are non-deterministic, paths and txn_id are random UUIDs)
276
293
set_json_value ( & mut parsed_commits[ 0 ] , "commitInfo.timestamp" , json ! ( 0 ) ) ?;
294
+ set_json_value ( & mut parsed_commits[ 0 ] , "commitInfo.txnId" , json ! ( ZERO_UUID ) ) ?;
277
295
set_json_value ( & mut parsed_commits[ 1 ] , "add.modificationTime" , json ! ( 0 ) ) ?;
278
296
set_json_value ( & mut parsed_commits[ 1 ] , "add.path" , json ! ( "first.parquet" ) ) ?;
279
297
set_json_value ( & mut parsed_commits[ 2 ] , "add.modificationTime" , json ! ( 0 ) ) ?;
@@ -286,6 +304,7 @@ async fn test_append() -> Result<(), Box<dyn std::error::Error>> {
286
304
"operation" : "UNKNOWN" ,
287
305
"kernelVersion" : format!( "v{}" , env!( "CARGO_PKG_VERSION" ) ) ,
288
306
"operationParameters" : { } ,
307
+ "txnId" : ZERO_UUID
289
308
}
290
309
} ) ,
291
310
json!( {
@@ -437,10 +456,13 @@ async fn test_append_partitioned() -> Result<(), Box<dyn std::error::Error>> {
437
456
// check that the timestamps in commit_info and add actions are within 10s of SystemTime::now()
438
457
// before we clear them for comparison
439
458
check_action_timestamps ( parsed_commits. iter ( ) ) ?;
459
+ // check that the txn_id is valid before we clear it for comparison
460
+ validate_txn_id ( & parsed_commits[ 0 ] [ "commitInfo" ] ) ;
440
461
441
- // set timestamps to 0 and paths to known string values for comparison
442
- // (otherwise timestamps are non-deterministic and paths are random UUIDs)
462
+ // set timestamps to 0, paths and txn_id to known string values for comparison
463
+ // (otherwise timestamps are non-deterministic, paths and txn_id are random UUIDs)
443
464
set_json_value ( & mut parsed_commits[ 0 ] , "commitInfo.timestamp" , json ! ( 0 ) ) ?;
465
+ set_json_value ( & mut parsed_commits[ 0 ] , "commitInfo.txnId" , json ! ( ZERO_UUID ) ) ?;
444
466
set_json_value ( & mut parsed_commits[ 1 ] , "add.modificationTime" , json ! ( 0 ) ) ?;
445
467
set_json_value ( & mut parsed_commits[ 1 ] , "add.path" , json ! ( "first.parquet" ) ) ?;
446
468
set_json_value ( & mut parsed_commits[ 2 ] , "add.modificationTime" , json ! ( 0 ) ) ?;
@@ -454,6 +476,7 @@ async fn test_append_partitioned() -> Result<(), Box<dyn std::error::Error>> {
454
476
"kernelVersion" : format!( "v{}" , env!( "CARGO_PKG_VERSION" ) ) ,
455
477
"operationParameters" : { } ,
456
478
"engineInfo" : "default engine" ,
479
+ "txnId" : ZERO_UUID
457
480
}
458
481
} ) ,
459
482
json!( {
@@ -620,11 +643,7 @@ async fn test_write_txn_actions() -> Result<(), Box<dyn std::error::Error>> {
620
643
. into_iter :: < serde_json:: Value > ( )
621
644
. try_collect ( ) ?;
622
645
623
- * parsed_commits[ 0 ]
624
- . get_mut ( "commitInfo" )
625
- . unwrap ( )
626
- . get_mut ( "timestamp" )
627
- . unwrap ( ) = serde_json:: Value :: Number ( 0 . into ( ) ) ;
646
+ set_json_value ( & mut parsed_commits[ 0 ] , "commitInfo.timestamp" , json ! ( 0 ) ) . unwrap ( ) ;
628
647
629
648
let time_ms: i64 = std:: time:: SystemTime :: now ( )
630
649
. duration_since ( std:: time:: UNIX_EPOCH ) ?
@@ -663,6 +682,10 @@ async fn test_write_txn_actions() -> Result<(), Box<dyn std::error::Error>> {
663
682
assert ! ( ( last_updated. as_i64( ) . unwrap( ) - time_ms) . abs( ) < 10_000 ) ;
664
683
* last_updated = serde_json:: Value :: Number ( 2 . into ( ) ) ;
665
684
685
+ validate_txn_id ( & parsed_commits[ 0 ] [ "commitInfo" ] ) ;
686
+
687
+ set_json_value ( & mut parsed_commits[ 0 ] , "commitInfo.txnId" , json ! ( ZERO_UUID ) ) ?;
688
+
666
689
let expected_commit = vec ! [
667
690
json!( {
668
691
"commitInfo" : {
@@ -671,6 +694,7 @@ async fn test_write_txn_actions() -> Result<(), Box<dyn std::error::Error>> {
671
694
"kernelVersion" : format!( "v{}" , env!( "CARGO_PKG_VERSION" ) ) ,
672
695
"operationParameters" : { } ,
673
696
"engineInfo" : "default engine" ,
697
+ "txnId" : ZERO_UUID
674
698
}
675
699
} ) ,
676
700
json!( {
0 commit comments