|
24 | 24 | import java.io.File; |
25 | 25 | import java.io.IOException; |
26 | 26 | import java.nio.file.Files; |
| 27 | +import java.util.Arrays; |
27 | 28 | import java.util.HashSet; |
| 29 | +import java.util.List; |
28 | 30 | import java.util.Map; |
29 | 31 | import java.util.Set; |
30 | 32 | import org.apache.commons.io.FileUtils; |
|
48 | 50 | import org.apache.zeppelin.user.AuthenticationInfo; |
49 | 51 | import org.apache.zeppelin.user.Credentials; |
50 | 52 | import org.junit.jupiter.api.AfterEach; |
| 53 | +import org.junit.jupiter.api.Assertions; |
51 | 54 | import org.junit.jupiter.api.BeforeEach; |
52 | 55 | import org.junit.jupiter.api.Test; |
| 56 | +import org.mockito.Mockito; |
53 | 57 | import org.quartz.SchedulerException; |
54 | 58 | import org.slf4j.Logger; |
55 | 59 | import org.slf4j.LoggerFactory; |
@@ -434,4 +438,42 @@ void testSyncWithAcl() throws IOException { |
434 | 438 | assertEquals(0, authorizationService.getRunners(noteId).size()); |
435 | 439 | assertEquals(0, authorizationService.getWriters(noteId).size()); |
436 | 440 | } |
| 441 | + |
| 442 | + @Test |
| 443 | + void testSyncOnDeleteWithPartialFailure() throws Exception { |
| 444 | + |
| 445 | + assertTrue(notebookRepoSync.getRepoCount() > 1); |
| 446 | + String noteId = notebook.createNote("test_partial_failure", "", anonymous); |
| 447 | + String notePath = notebookRepoSync.list(0, anonymous).get(0).getPath(); |
| 448 | + |
| 449 | + assertEquals(1, notebookRepoSync.list(0, anonymous).size()); |
| 450 | + assertEquals(1, notebookRepoSync.list(1, anonymous).size()); |
| 451 | + |
| 452 | + // given (setup) |
| 453 | + NotebookRepo mockPrimaryRepo = Mockito.mock(NotebookRepo.class); |
| 454 | + NotebookRepo mockSecondaryRepo = Mockito.mock(NotebookRepo.class); |
| 455 | + List<NotebookRepo> mockRepos = Arrays.asList(mockPrimaryRepo, mockSecondaryRepo); |
| 456 | + |
| 457 | + java.lang.reflect.Field reposField = notebookRepoSync.getClass().getDeclaredField("repos"); |
| 458 | + reposField.setAccessible(true); |
| 459 | + |
| 460 | + reposField.set(notebookRepoSync, mockRepos); |
| 461 | + |
| 462 | + // define Mock behavior |
| 463 | + Mockito.doNothing().when(mockPrimaryRepo).remove(Mockito.any(), Mockito.any(), Mockito.any()); |
| 464 | + Mockito.doThrow(IOException.class) |
| 465 | + .when(mockSecondaryRepo).remove(Mockito.any(), Mockito.any(), Mockito.any()); |
| 466 | + |
| 467 | + // when & then |
| 468 | + IOException thrownException = Assertions.assertThrows(IOException.class, () -> { |
| 469 | + notebookRepoSync.remove(noteId, notePath, anonymous); |
| 470 | + }); |
| 471 | + |
| 472 | + Mockito.verify(mockPrimaryRepo, Mockito.times(1)).remove(noteId, notePath, anonymous); |
| 473 | + Mockito.verify(mockSecondaryRepo, Mockito.times(1)).remove(noteId, notePath, anonymous); |
| 474 | + Assertions.assertTrue( |
| 475 | + thrownException.getMessage().contains("Failed to remove note from one or more repositories")); |
| 476 | + |
| 477 | + notebook.close(); |
| 478 | + } |
437 | 479 | } |
0 commit comments