8
8
9
9
package org .opensearch .remotestore ;
10
10
11
+ import org .opensearch .action .LatchedActionListener ;
11
12
import org .opensearch .common .collect .Tuple ;
12
13
import org .opensearch .common .settings .Settings ;
13
14
import org .opensearch .common .unit .TimeValue ;
17
18
import org .opensearch .test .OpenSearchIntegTestCase ;
18
19
19
20
import java .util .Set ;
21
+ import java .util .concurrent .CountDownLatch ;
20
22
21
23
@ OpenSearchIntegTestCase .ClusterScope (scope = OpenSearchIntegTestCase .Scope .TEST , numDataNodes = 0 )
22
24
public class RemoteStorePinnedTimestampsIT extends RemoteStoreBaseIntegTestCase {
@@ -75,10 +77,25 @@ public void testTimestampPinUnpin() throws Exception {
75
77
76
78
remoteStorePinnedTimestampService .rescheduleAsyncUpdatePinnedTimestampTask (TimeValue .timeValueMinutes (3 ));
77
79
78
- // This should be a no-op as pinning entity is different
79
- remoteStorePinnedTimestampService .unpinTimestamp (timestamp1 , "no-snapshot" , noOpActionListener );
80
80
// Unpinning already pinned entity
81
81
remoteStorePinnedTimestampService .unpinTimestamp (timestamp2 , "ss3" , noOpActionListener );
82
+
83
+ // This should fail as timestamp is not pinned by pinning entity
84
+ CountDownLatch latch = new CountDownLatch (1 );
85
+ remoteStorePinnedTimestampService .unpinTimestamp (timestamp1 , "no-snapshot" , new LatchedActionListener <>(new ActionListener <Void >() {
86
+ @ Override
87
+ public void onResponse (Void unused ) {
88
+ // onResponse should not get called.
89
+ fail ();
90
+ }
91
+
92
+ @ Override
93
+ public void onFailure (Exception e ) {
94
+ assertTrue (e instanceof IllegalArgumentException );
95
+ }
96
+ }, latch ));
97
+ latch .await ();
98
+
82
99
// Adding different entity to already pinned timestamp
83
100
remoteStorePinnedTimestampService .pinTimestamp (timestamp3 , "ss5" , noOpActionListener );
84
101
@@ -93,4 +110,74 @@ public void testTimestampPinUnpin() throws Exception {
93
110
94
111
remoteStorePinnedTimestampService .rescheduleAsyncUpdatePinnedTimestampTask (TimeValue .timeValueMinutes (3 ));
95
112
}
113
+
114
+ public void testPinnedTimestampClone () throws Exception {
115
+ prepareCluster (1 , 1 , INDEX_NAME , 0 , 2 );
116
+ ensureGreen (INDEX_NAME );
117
+
118
+ RemoteStorePinnedTimestampService remoteStorePinnedTimestampService = internalCluster ().getInstance (
119
+ RemoteStorePinnedTimestampService .class ,
120
+ primaryNodeName (INDEX_NAME )
121
+ );
122
+
123
+ long timestamp1 = System .currentTimeMillis () + 30000L ;
124
+ long timestamp2 = System .currentTimeMillis () + 60000L ;
125
+ long timestamp3 = System .currentTimeMillis () + 900000L ;
126
+ remoteStorePinnedTimestampService .pinTimestamp (timestamp1 , "ss2" , noOpActionListener );
127
+ remoteStorePinnedTimestampService .pinTimestamp (timestamp2 , "ss3" , noOpActionListener );
128
+ remoteStorePinnedTimestampService .pinTimestamp (timestamp3 , "ss4" , noOpActionListener );
129
+
130
+ // Clone timestamp1
131
+ remoteStorePinnedTimestampService .cloneTimestamp (timestamp1 , "ss2" , "ss2-2" , noOpActionListener );
132
+
133
+ // With clone, set of pinned timestamp will not change
134
+ remoteStorePinnedTimestampService .rescheduleAsyncUpdatePinnedTimestampTask (TimeValue .timeValueSeconds (1 ));
135
+ assertBusy (
136
+ () -> assertEquals (Set .of (timestamp1 , timestamp2 , timestamp3 ), RemoteStorePinnedTimestampService .getPinnedTimestamps ().v2 ())
137
+ );
138
+ remoteStorePinnedTimestampService .rescheduleAsyncUpdatePinnedTimestampTask (TimeValue .timeValueMinutes (3 ));
139
+
140
+ // Clone timestamp1 but provide invalid existing entity
141
+ CountDownLatch latch = new CountDownLatch (1 );
142
+ remoteStorePinnedTimestampService .cloneTimestamp (
143
+ timestamp1 ,
144
+ "ss3" ,
145
+ "ss2-3" ,
146
+ new LatchedActionListener <>(new ActionListener <Void >() {
147
+ @ Override
148
+ public void onResponse (Void unused ) {
149
+ // onResponse should not get called.
150
+ fail ();
151
+ }
152
+
153
+ @ Override
154
+ public void onFailure (Exception e ) {
155
+ assertTrue (e instanceof IllegalArgumentException );
156
+ }
157
+ }, latch )
158
+ );
159
+ latch .await ();
160
+
161
+ remoteStorePinnedTimestampService .rescheduleAsyncUpdatePinnedTimestampTask (TimeValue .timeValueSeconds (1 ));
162
+ assertBusy (
163
+ () -> assertEquals (Set .of (timestamp1 , timestamp2 , timestamp3 ), RemoteStorePinnedTimestampService .getPinnedTimestamps ().v2 ())
164
+ );
165
+ remoteStorePinnedTimestampService .rescheduleAsyncUpdatePinnedTimestampTask (TimeValue .timeValueMinutes (3 ));
166
+
167
+ // Now we have timestamp1 pinned by 2 entities, unpin 1, this should not change set of pinned timestamps
168
+ remoteStorePinnedTimestampService .unpinTimestamp (timestamp1 , "ss2" , noOpActionListener );
169
+
170
+ remoteStorePinnedTimestampService .rescheduleAsyncUpdatePinnedTimestampTask (TimeValue .timeValueSeconds (1 ));
171
+ assertBusy (
172
+ () -> assertEquals (Set .of (timestamp1 , timestamp2 , timestamp3 ), RemoteStorePinnedTimestampService .getPinnedTimestamps ().v2 ())
173
+ );
174
+ remoteStorePinnedTimestampService .rescheduleAsyncUpdatePinnedTimestampTask (TimeValue .timeValueMinutes (3 ));
175
+
176
+ // Now unpin second entity as well, set of pinned timestamp should be reduced by 1
177
+ remoteStorePinnedTimestampService .unpinTimestamp (timestamp1 , "ss2-2" , noOpActionListener );
178
+
179
+ remoteStorePinnedTimestampService .rescheduleAsyncUpdatePinnedTimestampTask (TimeValue .timeValueSeconds (1 ));
180
+ assertBusy (() -> assertEquals (Set .of (timestamp2 , timestamp3 ), RemoteStorePinnedTimestampService .getPinnedTimestamps ().v2 ()));
181
+ remoteStorePinnedTimestampService .rescheduleAsyncUpdatePinnedTimestampTask (TimeValue .timeValueMinutes (3 ));
182
+ }
96
183
}
0 commit comments