@@ -1710,37 +1710,41 @@ describe('Server Access Logs - File Output', async () => {
17101710 objectKey : `${ objectKey } 2` ,
17111711 httpMethod : 'PUT' ,
17121712 } ,
1713+ {
1714+ ...commonProperties ,
1715+ operation : 'REST.POST.MULTI_OBJECT_DELETE' ,
1716+ action : 'DeleteObjects' ,
1717+ httpMethod : 'POST' ,
1718+ objectKey : null ,
1719+ }
1720+ ] ,
1721+ // Objects are deleted concurrently, they might get logged in any order
1722+ // for example errors or non-existent objects might get logged first
1723+ unorderedExpected : [
17131724 {
17141725 ...commonProperties ,
17151726 operation : 'BATCH.DELETE.OBJECT' ,
1716- action : 'DeleteObject ' ,
1727+ action : 'DeleteObjects ' ,
17171728 objectKey,
17181729 httpCode : 204 ,
17191730 httpMethod : 'POST' ,
17201731 } ,
17211732 {
17221733 ...commonProperties ,
17231734 operation : 'BATCH.DELETE.OBJECT' ,
1724- action : 'DeleteObject ' ,
1735+ action : 'DeleteObjects ' ,
17251736 objectKey : `${ objectKey } 2` ,
17261737 httpCode : 204 ,
17271738 httpMethod : 'POST' ,
17281739 } ,
17291740 {
17301741 ...commonProperties ,
17311742 operation : 'BATCH.DELETE.OBJECT' ,
1732- action : 'DeleteObject ' ,
1743+ action : 'DeleteObjects ' ,
17331744 objectKey : `${ objectKey } -non-existent` ,
17341745 httpCode : 204 ,
17351746 httpMethod : 'POST' ,
17361747 } ,
1737- {
1738- ...commonProperties ,
1739- operation : 'REST.POST.MULTI_OBJECT_DELETE' ,
1740- action : 'DeleteObjects' ,
1741- httpMethod : 'POST' ,
1742- objectKey : null ,
1743- }
17441748 ] ,
17451749 } ;
17461750 } ) ( ) ,
@@ -2679,13 +2683,37 @@ describe('Server Access Logs - File Output', async () => {
26792683 for ( const operation of operations ) {
26802684 it ( `should log correct ${ operation . methodName } operation with all required fields` , async ( ) => {
26812685 await operation . method ( ) ;
2682- const logEntries = await waitForLogs ( logFilePath , operation . expected . length ,
2686+ const totalExpected = operation . expected . length + ( operation . unorderedExpected ?. length || 0 ) ;
2687+ const logEntries = await waitForLogs ( logFilePath , totalExpected ,
26832688 TEST_CONFIG . MAX_LOG_WAIT_RETRIES , TEST_CONFIG . LOG_POLL_DELAY_MS ) ;
2684- assert . strictEqual ( logEntries . length , operation . expected . length ,
2685- `Expected ${ operation . expected . length } log entries, got ${ logEntries . length } ` ) ;
2689+ assert . strictEqual ( logEntries . length , totalExpected ,
2690+ `Expected ${ totalExpected } log entries, got ${ logEntries . length } ` ) ;
2691+
2692+ let logIdx = 0 ;
26862693
2694+ // Validate ordered entries
26872695 for ( let i = 0 ; i < operation . expected . length ; i ++ ) {
26882696 validateLogEntry ( logEntries [ i ] , operation . expected [ i ] ) ;
2697+ logIdx ++ ;
2698+ }
2699+
2700+ // Validate unordered entries if present
2701+ if ( operation . unorderedExpected ) {
2702+ const unorderedLogs = logEntries . slice ( logIdx ) ;
2703+ const remaining = [ ...operation . unorderedExpected ] ;
2704+
2705+ for ( const logEntry of unorderedLogs ) {
2706+ const matchIdx = remaining . findIndex ( exp => exp . objectKey === logEntry . objectKey ) ;
2707+
2708+ assert . notStrictEqual ( matchIdx , - 1 ,
2709+ `Unexpected log entry with objectKey: ${ logEntry . objectKey } ` ) ;
2710+
2711+ validateLogEntry ( logEntry , remaining [ matchIdx ] ) ;
2712+ remaining . splice ( matchIdx , 1 ) ;
2713+ }
2714+
2715+ assert . strictEqual ( remaining . length , 0 ,
2716+ `Missing expected entries: ${ JSON . stringify ( remaining ) } ` ) ;
26892717 }
26902718 } ) ;
26912719 }
0 commit comments