1818
1919import com .iexec .sms .encryption .EncryptionService ;
2020import lombok .extern .slf4j .Slf4j ;
21- import org .junit .jupiter .api .BeforeEach ;
2221import org .junit .jupiter .api .Test ;
22+ import org .junit .jupiter .api .extension .ExtendWith ;
2323import org .junit .jupiter .api .io .TempDir ;
2424import org .junit .jupiter .params .ParameterizedTest ;
2525import org .junit .jupiter .params .provider .Arguments ;
2626import org .junit .jupiter .params .provider .MethodSource ;
2727import org .mockito .InjectMocks ;
2828import org .mockito .Mock ;
29- import org .mockito .Mockito ;
30- import org .mockito .MockitoAnnotations ;
29+ import org .mockito .junit .jupiter .MockitoExtension ;
3130import org .springframework .http .HttpStatus ;
3231import org .springframework .http .ResponseEntity ;
3332import org .springframework .test .util .ReflectionTestUtils ;
4039import java .util .ArrayList ;
4140import java .util .Collections ;
4241import java .util .List ;
42+ import java .util .concurrent .CountDownLatch ;
4343import java .util .concurrent .TimeUnit ;
4444import java .util .concurrent .locks .ReentrantLock ;
4545import java .util .stream .Stream ;
4646
4747import static org .junit .jupiter .api .Assertions .assertEquals ;
4848import static org .junit .jupiter .api .Assertions .assertThrowsExactly ;
4949import static org .mockito .ArgumentMatchers .any ;
50+ import static org .mockito .Mockito .doReturn ;
5051import static org .mockito .Mockito .when ;
5152
5253@ Slf4j
54+ @ ExtendWith (MockitoExtension .class )
5355class AdminControllerTests {
5456
5557 private static final String STORAGE_PATH = "/storage" ;
@@ -64,51 +66,38 @@ class AdminControllerTests {
6466 @ InjectMocks
6567 private AdminController adminController ;
6668
67- @ BeforeEach
68- void init () {
69- MockitoAnnotations .openMocks (this );
70- }
71-
7269 // region backup
7370 @ Test
7471 void shouldReturnCreatedWhenBackupSuccess () {
75- Mockito . doReturn (true ).when (adminService ).createBackupFile (any (), any ());
72+ doReturn (true ).when (adminService ).createBackupFile (any (), any ());
7673 assertEquals (HttpStatus .CREATED , adminController .createBackup ().getStatusCode ());
7774 }
7875
7976 @ Test
8077 void shouldReturnErrorWhenBackupFail () {
81- Mockito . doReturn (false ).when (adminService ).createBackupFile (any (), any ());
78+ doReturn (false ).when (adminService ).createBackupFile (any (), any ());
8279 assertEquals (HttpStatus .INTERNAL_SERVER_ERROR , adminController .createBackup ().getStatusCode ());
8380 }
8481
8582 @ Test
8683 void shouldReturnTooManyRequestWhenBackupProcessIsAlreadyRunning () throws InterruptedException {
87- AdminController adminControllerWithLongAction = new AdminController (new AdminService (encryptionService , "" , "" , "" , "" ) {
88- @ Override
89- public boolean createBackupFile (String storageLocation , String backupFileName ) {
90- try {
91- log .info ("Long createDatabaseBackupFile action is running ..." );
92- Thread .sleep (2000 );
93- } catch (InterruptedException e ) {
94- Thread .currentThread ().interrupt ();
95- }
96- return true ;
97- }
98- }, "" );
99-
84+ final CountDownLatch done = new CountDownLatch (1 );
85+ final CountDownLatch ready = new CountDownLatch (1 );
86+ final AdminController adminControllerWithLongAction = provideAdminControllerWithDummyService (ready , done );
10087 final List <ResponseEntity <Void >> responses = Collections .synchronizedList (new ArrayList <>(3 ));
10188
10289 Thread firstThread = new Thread (() -> responses .add (adminControllerWithLongAction .createBackup ()));
10390 Thread secondThread = new Thread (() -> responses .add (adminControllerWithLongAction .createBackup ()));
10491
10592 firstThread .start ();
93+ ready .await ();
94+
10695 secondThread .start ();
10796 responses .add (adminControllerWithLongAction .createBackup ());
108-
10997 secondThread .join ();
110- firstThread .join ();
11198
99+ done .countDown ();
100+ firstThread .join ();
112101
113102 long code201 = responses .stream ().filter (element -> element .getStatusCode () == HttpStatus .CREATED ).count ();
114103 long code429 = responses .stream ().filter (element -> element .getStatusCode () == HttpStatus .TOO_MANY_REQUESTS ).count ();
@@ -135,7 +124,6 @@ void testBadRequestOnReplicate(String storageID, String fileName) {
135124
136125 @ Test
137126 void testInternalServerErrorOnReplicate () {
138- when (adminService .copyBackupFile (STORAGE_PATH , FILE_NAME , STORAGE_PATH , FILE_NAME )).thenThrow (RuntimeException .class );
139127 assertEquals (HttpStatus .INTERNAL_SERVER_ERROR , adminController .replicateBackup (STORAGE_PATH , FILE_NAME ).getStatusCode ());
140128 }
141129
@@ -149,38 +137,29 @@ void testInterruptedThreadOnReplicate() throws InterruptedException {
149137 @ Test
150138 void testNotFoundOnReplicate () {
151139 final String storageID = convertToHex (STORAGE_PATH );
152- when (adminService .copyBackupFile (STORAGE_PATH , FILE_NAME , STORAGE_PATH , FILE_NAME )).thenThrow (FileSystemNotFoundException .class );
153140 assertEquals (HttpStatus .NOT_FOUND , adminController .replicateBackup (storageID , FILE_NAME ).getStatusCode ());
154141 }
155142
156143 @ Test
157144 void testTooManyRequestOnReplicate (@ TempDir Path tempDir ) throws InterruptedException {
158- AdminController adminControllerWithLongAction = new AdminController (new AdminService (encryptionService , "" , "" , "" , "" ) {
159- @ Override
160- public boolean copyBackupFile (String backupStoragePath , String backupFileName , String replicateStoragePath , String replicateFileName ) {
161- try {
162- log .info ("Long copyOrReplicateBackupFileFromStorageToStorage action is running ..." );
163- Thread .sleep (2000 );
164- } catch (InterruptedException e ) {
165- Thread .currentThread ().interrupt ();
166- }
167- return true ;
168- }
169- }, "" );
170-
145+ final CountDownLatch done = new CountDownLatch (1 );
146+ final CountDownLatch ready = new CountDownLatch (1 );
147+ final AdminController adminControllerWithLongAction = provideAdminControllerWithDummyService (ready , done );
171148 final List <ResponseEntity <Void >> responses = Collections .synchronizedList (new ArrayList <>(3 ));
172149 final String storageID = convertToHex (tempDir .toString ());
173150
174151 Thread firstThread = new Thread (() -> responses .add (adminControllerWithLongAction .replicateBackup (storageID , FILE_NAME )));
175152 Thread secondThread = new Thread (() -> responses .add (adminControllerWithLongAction .replicateBackup (storageID , FILE_NAME )));
176153
177154 firstThread .start ();
155+ ready .await ();
156+
178157 secondThread .start ();
179158 responses .add (adminControllerWithLongAction .replicateBackup (storageID , FILE_NAME ));
180-
181159 secondThread .join ();
182- firstThread .join ();
183160
161+ done .countDown ();
162+ firstThread .join ();
184163
185164 long code200 = responses .stream ().filter (element -> element .getStatusCode () == HttpStatus .OK ).count ();
186165 long code429 = responses .stream ().filter (element -> element .getStatusCode () == HttpStatus .TOO_MANY_REQUESTS ).count ();
@@ -221,38 +200,29 @@ void testInterruptedThreadOnRestore() throws InterruptedException {
221200 @ Test
222201 void testNotFoundOnRestore () {
223202 final String storageID = convertToHex (STORAGE_PATH );
224- when (adminService .restoreDatabaseFromBackupFile (STORAGE_PATH , FILE_NAME )).thenThrow (FileSystemNotFoundException .class );
225203 assertEquals (HttpStatus .NOT_FOUND , adminController .restoreBackup (storageID , FILE_NAME ).getStatusCode ());
226204 }
227205
228206 @ Test
229207 void testTooManyRequestOnRestore (@ TempDir Path tempDir ) throws InterruptedException {
230- AdminController adminControllerWithLongAction = new AdminController (new AdminService (encryptionService , "" , "" , "" , "" ) {
231- @ Override
232- public boolean restoreDatabaseFromBackupFile (String storageId , String fileName ) {
233- try {
234- log .info ("Long restoreDatabaseFromBackupFile action is running ..." );
235- Thread .sleep (2000 );
236- } catch (InterruptedException e ) {
237- Thread .currentThread ().interrupt ();
238- }
239- return true ;
240- }
241- }, "" );
242-
208+ final CountDownLatch done = new CountDownLatch (1 );
209+ final CountDownLatch ready = new CountDownLatch (1 );
210+ final AdminController adminControllerWithLongAction = provideAdminControllerWithDummyService (ready , done );
243211 final List <ResponseEntity <Void >> responses = Collections .synchronizedList (new ArrayList <>(3 ));
244212 final String storageID = convertToHex (tempDir .toString ());
245213
246214 Thread firstThread = new Thread (() -> responses .add (adminControllerWithLongAction .restoreBackup (storageID , FILE_NAME )));
247215 Thread secondThread = new Thread (() -> responses .add (adminControllerWithLongAction .restoreBackup (storageID , FILE_NAME )));
248216
249217 firstThread .start ();
218+ ready .await ();
219+
250220 secondThread .start ();
251221 responses .add (adminControllerWithLongAction .restoreBackup (storageID , FILE_NAME ));
252-
253222 secondThread .join ();
254- firstThread .join ();
255223
224+ done .countDown ();
225+ firstThread .join ();
256226
257227 long code200 = responses .stream ().filter (element -> element .getStatusCode () == HttpStatus .OK ).count ();
258228 long code429 = responses .stream ().filter (element -> element .getStatusCode () == HttpStatus .TOO_MANY_REQUESTS ).count ();
@@ -316,38 +286,29 @@ void testInterruptedThreadOnDelete() throws InterruptedException {
316286 @ Test
317287 void testNotFoundOnDelete () {
318288 final String storageID = convertToHex (STORAGE_PATH );
319- when (adminService .deleteBackupFileFromStorage (STORAGE_PATH , FILE_NAME )).thenThrow (FileSystemNotFoundException .class );
320289 assertEquals (HttpStatus .NOT_FOUND , adminController .deleteBackup (storageID , FILE_NAME ).getStatusCode ());
321290 }
322291
323292 @ Test
324293 void testTooManyRequestOnDelete (@ TempDir Path tempDir ) throws InterruptedException {
325- AdminController adminControllerWithLongAction = new AdminController (new AdminService (encryptionService , "" , "" , "" , "" ) {
326- @ Override
327- public boolean deleteBackupFileFromStorage (String storageLocation , String backupFileName ) {
328- try {
329- log .info ("Long restoreDatabaseFromBackupFile action is running ..." );
330- Thread .sleep (2000 );
331- } catch (InterruptedException e ) {
332- Thread .currentThread ().interrupt ();
333- }
334- return true ;
335- }
336- }, "" );
337-
294+ final CountDownLatch done = new CountDownLatch (1 );
295+ final CountDownLatch ready = new CountDownLatch (1 );
296+ final AdminController adminControllerWithLongAction = provideAdminControllerWithDummyService (ready , done );
338297 final List <ResponseEntity <Void >> responses = Collections .synchronizedList (new ArrayList <>(3 ));
339298 final String storageID = convertToHex (tempDir .toString ());
340299
341300 Thread firstThread = new Thread (() -> responses .add (adminControllerWithLongAction .deleteBackup (storageID , FILE_NAME )));
342301 Thread secondThread = new Thread (() -> responses .add (adminControllerWithLongAction .deleteBackup (storageID , FILE_NAME )));
343302
344303 firstThread .start ();
304+ ready .await ();
305+
345306 secondThread .start ();
346307 responses .add (adminControllerWithLongAction .deleteBackup (storageID , FILE_NAME ));
347-
348308 secondThread .join ();
349- firstThread .join ();
350309
310+ done .countDown ();
311+ firstThread .join ();
351312
352313 long code200 = responses .stream ().filter (element -> element .getStatusCode () == HttpStatus .OK ).count ();
353314 long code429 = responses .stream ().filter (element -> element .getStatusCode () == HttpStatus .TOO_MANY_REQUESTS ).count ();
@@ -395,33 +356,24 @@ void testInternalServerErrorOnCopy(@TempDir Path tempDir) {
395356
396357 @ Test
397358 void testTooManyRequestOnCopy (@ TempDir Path tempDir ) throws InterruptedException {
398-
399- AdminController adminControllerWithLongAction = new AdminController (new AdminService (encryptionService , "" , "" , "" , "" ) {
400- @ Override
401- public boolean copyBackupFile (String sourceStorageLocation , String sourceBackupFileName , String destinationStorageLocation , String destinationBackupFileName ) {
402- try {
403- log .info ("Long copyOrReplicateBackupFileFromStorageToStorage action is running ..." );
404- Thread .sleep (2000 );
405- } catch (InterruptedException e ) {
406- Thread .currentThread ().interrupt ();
407- }
408- return true ;
409- }
410- }, "" );
411-
359+ final CountDownLatch done = new CountDownLatch (1 );
360+ final CountDownLatch ready = new CountDownLatch (1 );
361+ final AdminController adminControllerWithLongAction = provideAdminControllerWithDummyService (ready , done );
412362 final List <ResponseEntity <Void >> responses = Collections .synchronizedList (new ArrayList <>(3 ));
413363 final String sourceStorageID = convertToHex (tempDir .toString ());
414364
415365 Thread firstThread = new Thread (() -> responses .add (adminControllerWithLongAction .copyBackup (sourceStorageID , sourceStorageID , FILE_NAME , "backup2.sql" )));
416366 Thread secondThread = new Thread (() -> responses .add (adminControllerWithLongAction .copyBackup (sourceStorageID , sourceStorageID , FILE_NAME , "backup2.sql" )));
417367
418368 firstThread .start ();
369+ ready .await ();
370+
419371 secondThread .start ();
420372 responses .add (adminControllerWithLongAction .copyBackup (sourceStorageID , sourceStorageID , FILE_NAME , "backup2.sql" ));
421-
422373 secondThread .join ();
423- firstThread .join ();
424374
375+ done .countDown ();
376+ firstThread .join ();
425377
426378 long code200 = responses .stream ().filter (element -> element .getStatusCode () == HttpStatus .OK ).count ();
427379 long code429 = responses .stream ().filter (element -> element .getStatusCode () == HttpStatus .TOO_MANY_REQUESTS ).count ();
@@ -443,6 +395,41 @@ void testBadRequestOnCopyOnSpecificsCopyControls(String sourceStorageID, String
443395 }
444396 // endregion
445397
398+ private AdminController provideAdminControllerWithDummyService (final CountDownLatch ready , final CountDownLatch done ) {
399+ return new AdminController (new AdminService (encryptionService , "" , "" , "" , "" ) {
400+ private boolean doLongCompute (final String message ) {
401+ try {
402+ log .info (message );
403+ ready .countDown ();
404+ done .await ();
405+ } catch (InterruptedException e ) {
406+ Thread .currentThread ().interrupt ();
407+ }
408+ return true ;
409+ }
410+
411+ @ Override
412+ public boolean createBackupFile (String storageLocation , String backupFileName ) {
413+ return doLongCompute ("Long createBackupFile action is running ..." );
414+ }
415+
416+ @ Override
417+ public boolean restoreDatabaseFromBackupFile (String storageId , String fileName ) {
418+ return doLongCompute ("Long restoreDatabaseFromBackupFile action is running ..." );
419+ }
420+
421+ @ Override
422+ public boolean deleteBackupFileFromStorage (String storageLocation , String backupFileName ) {
423+ return doLongCompute ("Long deleteBackupFileFromStorage action is running ..." );
424+ }
425+
426+ @ Override
427+ public boolean copyBackupFile (String sourceStorageLocation , String sourceBackupFileName , String destinationStorageLocation , String destinationBackupFileName ) {
428+ return doLongCompute ("Long copyBackupFile action is running ..." );
429+ }
430+ }, "" );
431+ }
432+
446433 private static Stream <Arguments > provideBadRequestParameters () {
447434 return Stream .of (
448435 Arguments .of (null , null ),
0 commit comments