1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package org.apache.hc.client5.http.impl.cache;
28
29 import static org.mockito.Mockito.doThrow;
30 import static org.mockito.Mockito.verify;
31 import static org.mockito.Mockito.when;
32
33 import java.util.concurrent.RejectedExecutionException;
34
35 import org.apache.hc.client5.http.schedule.SchedulingStrategy;
36 import org.apache.hc.core5.util.TimeValue;
37 import org.apache.hc.core5.util.Timeout;
38 import org.junit.jupiter.api.Assertions;
39 import org.junit.jupiter.api.BeforeEach;
40 import org.junit.jupiter.api.Test;
41 import org.mockito.ArgumentMatchers;
42 import org.mockito.Mock;
43 import org.mockito.MockitoAnnotations;
44
45 class TestCacheRevalidatorBase {
46
47 @Mock
48 private SchedulingStrategy mockSchedulingStrategy;
49 @Mock
50 private CacheRevalidatorBase.ScheduledExecutor mockScheduledExecutor;
51 @Mock
52 private Runnable mockOperation;
53
54 private CacheRevalidatorBase impl;
55
56
57 @BeforeEach
58 void setUp() {
59 MockitoAnnotations.openMocks(this);
60 impl = new CacheRevalidatorBase(mockScheduledExecutor, mockSchedulingStrategy);
61 }
62
63 @Test
64 void testRevalidateCacheEntrySchedulesExecutionAndPopulatesIdentifier() {
65 when(mockSchedulingStrategy.schedule(ArgumentMatchers.anyInt())).thenReturn(TimeValue.ofSeconds(1));
66
67 final String cacheKey = "blah";
68 impl.scheduleRevalidation(cacheKey, mockOperation);
69
70 verify(mockSchedulingStrategy).schedule(0);
71 verify(mockScheduledExecutor).schedule(ArgumentMatchers.same(mockOperation), ArgumentMatchers.eq(TimeValue.ofSeconds(1)));
72
73 Assertions.assertEquals(1, impl.getScheduledIdentifiers().size());
74 }
75
76 @Test
77 void testMarkCompleteRemovesIdentifier() {
78 when(mockSchedulingStrategy.schedule(ArgumentMatchers.anyInt())).thenReturn(TimeValue.ofSeconds(3));
79
80 final String cacheKey = "blah";
81 impl.scheduleRevalidation(cacheKey, mockOperation);
82
83 verify(mockSchedulingStrategy).schedule(0);
84 verify(mockScheduledExecutor).schedule(ArgumentMatchers.any(), ArgumentMatchers.eq(TimeValue.ofSeconds(3)));
85
86 Assertions.assertEquals(1, impl.getScheduledIdentifiers().size());
87 Assertions.assertTrue(impl.getScheduledIdentifiers().contains(cacheKey));
88
89 impl.jobSuccessful(cacheKey);
90
91 Assertions.assertEquals(0, impl.getScheduledIdentifiers().size());
92 }
93
94 @Test
95 void testRevalidateCacheEntryDoesNotPopulateIdentifierOnRejectedExecutionException() {
96 when(mockSchedulingStrategy.schedule(ArgumentMatchers.anyInt())).thenReturn(TimeValue.ofSeconds(2));
97 doThrow(new RejectedExecutionException()).when(mockScheduledExecutor).schedule(ArgumentMatchers.any(), ArgumentMatchers.any());
98
99 final String cacheKey = "blah";
100 impl.scheduleRevalidation(cacheKey, mockOperation);
101
102 Assertions.assertEquals(0, impl.getScheduledIdentifiers().size());
103 verify(mockScheduledExecutor).schedule(ArgumentMatchers.any(), ArgumentMatchers.eq(TimeValue.ofSeconds(2)));
104 }
105
106 @Test
107 void testRevalidateCacheEntryProperlyCollapsesRequest() {
108 when(mockSchedulingStrategy.schedule(ArgumentMatchers.anyInt())).thenReturn(TimeValue.ofSeconds(2));
109
110 final String cacheKey = "blah";
111 impl.scheduleRevalidation(cacheKey, mockOperation);
112 impl.scheduleRevalidation(cacheKey, mockOperation);
113 impl.scheduleRevalidation(cacheKey, mockOperation);
114
115 verify(mockSchedulingStrategy).schedule(ArgumentMatchers.anyInt());
116 verify(mockScheduledExecutor).schedule(ArgumentMatchers.any(), ArgumentMatchers.eq(TimeValue.ofSeconds(2)));
117
118 Assertions.assertEquals(1, impl.getScheduledIdentifiers().size());
119 }
120
121 @Test
122 void testShutdown() throws Exception {
123 impl.close();
124 impl.awaitTermination(Timeout.ofMinutes(2));
125
126 verify(mockScheduledExecutor).shutdown();
127 verify(mockScheduledExecutor).awaitTermination(Timeout.ofMinutes(2));
128 }
129
130 }