2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.drools.pooling.state;
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertFalse;
25 import static org.junit.Assert.assertNotNull;
26 import static org.junit.Assert.assertNull;
27 import static org.junit.Assert.assertTrue;
28 import static org.mockito.ArgumentMatchers.any;
29 import static org.mockito.Mockito.mock;
30 import static org.mockito.Mockito.never;
31 import static org.mockito.Mockito.times;
32 import static org.mockito.Mockito.verify;
33 import static org.mockito.Mockito.when;
35 import org.junit.Before;
36 import org.junit.Test;
37 import org.onap.policy.drools.pooling.message.BucketAssignments;
38 import org.onap.policy.drools.pooling.message.Identification;
39 import org.onap.policy.drools.pooling.message.Leader;
40 import org.onap.policy.drools.pooling.message.Message;
41 import org.onap.policy.drools.pooling.message.Offline;
42 import org.onap.policy.drools.utils.Pair;
44 public class QueryStateTest extends BasicStateTester {
46 private QueryState state;
49 public void setUp() throws Exception {
52 state = new QueryState(mgr);
56 public void testGetFilter() {
57 Map<String, Object> filter = state.getFilter();
59 FilterUtilsTest utils = new FilterUtilsTest();
61 utils.checkArray(FilterUtils.CLASS_OR, 2, filter);
62 utils.checkEquals(FilterUtils.MSG_CHANNEL, Message.ADMIN, utils.getItem(filter, 0));
63 utils.checkEquals(FilterUtils.MSG_CHANNEL, MY_HOST, utils.getItem(filter, 1));
67 public void testGoQuery() {
68 assertNull(state.goQuery());
72 public void testStart() {
75 Pair<Long, StateTimerTask> timer = onceTasks.remove();
77 assertEquals(STD_IDENTIFICATION_MS, timer.first().longValue());
78 assertNotNull(timer.second());
82 public void testProcessIdentification_SameSource() {
83 String[] arr = {HOST2, PREV_HOST, MY_HOST};
84 BucketAssignments asgn = new BucketAssignments(arr);
86 assertNull(state.process(new Identification(MY_HOST, asgn)));
88 // info should be unchanged
89 assertEquals(MY_HOST, state.getLeader());
90 verify(mgr, never()).startDistributing(asgn);
94 public void testProcessIdentification_DiffSource() {
95 String[] arr = {HOST2, PREV_HOST, MY_HOST};
96 BucketAssignments asgn = new BucketAssignments(arr);
98 assertNull(state.process(new Identification(HOST2, asgn)));
100 // leader should be unchanged
101 assertEquals(MY_HOST, state.getLeader());
103 // should have picked up the assignments
104 verify(mgr).startDistributing(asgn);
108 public void testProcessLeader_Invalid() {
109 Leader msg = new Leader(PREV_HOST, null);
111 // should stay in the same state, and not start distributing
112 assertNull(state.process(msg));
113 verify(mgr, never()).startDistributing(any());
114 verify(mgr, never()).goActive();
115 verify(mgr, never()).goInactive();
117 // info should be unchanged
118 assertEquals(MY_HOST, state.getLeader());
119 assertEquals(ASGN3, state.getAssignments());
123 public void testProcessLeader_SameLeader() {
124 String[] arr = {HOST2, PREV_HOST, MY_HOST};
125 BucketAssignments asgn = new BucketAssignments(arr);
127 // identify a leader that's better than my host
128 assertEquals(null, state.process(new Identification(PREV_HOST, asgn)));
130 // now send a Leader message for that leader
131 Leader msg = new Leader(PREV_HOST, asgn);
133 State next = mock(State.class);
134 when(mgr.goActive()).thenReturn(next);
136 // should go Active and start distributing
137 assertEquals(next, state.process(msg));
138 verify(mgr, never()).goInactive();
140 // Ident msg + Leader msg = times(2)
141 verify(mgr, times(2)).startDistributing(asgn);
145 public void testProcessLeader_BetterLeaderWithAssignment() {
146 String[] arr = {HOST2, PREV_HOST, MY_HOST};
147 BucketAssignments asgn = new BucketAssignments(arr);
148 Leader msg = new Leader(PREV_HOST, asgn);
150 State next = mock(State.class);
151 when(mgr.goActive()).thenReturn(next);
153 // should go Active and start distributing
154 assertEquals(next, state.process(msg));
155 verify(mgr).startDistributing(asgn);
156 verify(mgr, never()).goInactive();
160 public void testProcessLeader_BetterLeaderWithoutAssignment() {
161 String[] arr = {HOST2, PREV_HOST, HOST1};
162 BucketAssignments asgn = new BucketAssignments(arr);
163 Leader msg = new Leader(PREV_HOST, asgn);
165 State next = mock(State.class);
166 when(mgr.goInactive()).thenReturn(next);
168 // should go Inactive, but start distributing
169 assertEquals(next, state.process(msg));
170 verify(mgr).startDistributing(asgn);
171 verify(mgr, never()).goActive();
175 public void testProcessLeader_NotABetterLeader() {
176 // no assignments yet
177 mgr.startDistributing(null);
178 state = new QueryState(mgr);
180 BucketAssignments asgn = new BucketAssignments(new String[] {HOST1, HOST2});
181 Leader msg = new Leader(HOST1, asgn);
183 State next = mock(State.class);
184 when(mgr.goInactive()).thenReturn(next);
186 // should stay in the same state
187 assertNull(state.process(msg));
188 verify(mgr, never()).goActive();
189 verify(mgr, never()).goInactive();
191 // should have started distributing
192 verify(mgr).startDistributing(asgn);
194 // this host should still be the leader
195 assertEquals(MY_HOST, state.getLeader());
198 assertEquals(asgn, state.getAssignments());
202 public void testProcessOffline_NullHost() {
203 assertNull(state.process(new Offline()));
204 assertEquals(MY_HOST, state.getLeader());
208 public void testProcessOffline_SameHost() {
209 assertNull(state.process(new Offline(MY_HOST)));
210 assertEquals(MY_HOST, state.getLeader());
214 public void testProcessOffline_DiffHost() {
215 BucketAssignments asgn = new BucketAssignments(new String[] {PREV_HOST, HOST1});
216 mgr.startDistributing(asgn);
217 state = new QueryState(mgr);
219 // tell it that the hosts are alive
220 state.process(new Identification(PREV_HOST, asgn));
221 state.process(new Identification(HOST1, asgn));
224 assertNull(state.process(new Offline(HOST1)));
226 // #1 should still be the leader
227 assertEquals(PREV_HOST, state.getLeader());
230 assertNull(state.process(new Offline(PREV_HOST)));
232 // this should still be the leader now
233 assertEquals(MY_HOST, state.getLeader());
237 public void testQueryState() {
239 * Prove the state is attached to the manager by invoking getHost(), which
240 * delegates to the manager.
242 assertEquals(MY_HOST, state.getHost());
246 public void testAwaitIdentification_MissingSelfIdent() {
249 Pair<Long, StateTimerTask> timer = onceTasks.remove();
251 assertEquals(STD_IDENTIFICATION_MS, timer.first().longValue());
252 assertNotNull(timer.second());
254 // should published an Offline message and go inactive
256 State next = mock(State.class);
257 when(mgr.goInactive()).thenReturn(next);
259 assertEquals(next, timer.second().fire());
261 Offline msg = captureAdminMessage(Offline.class);
262 assertEquals(MY_HOST, msg.getSource());
266 public void testAwaitIdentification_Leader() {
268 state.process(new Identification(MY_HOST, null));
270 Pair<Long, StateTimerTask> timer = onceTasks.remove();
272 assertEquals(STD_IDENTIFICATION_MS, timer.first().longValue());
273 assertNotNull(timer.second());
275 State next = mock(State.class);
276 when(mgr.goActive()).thenReturn(next);
278 assertEquals(next, timer.second().fire());
280 // should have published a Leader message
281 Leader msg = captureAdminMessage(Leader.class);
282 assertEquals(MY_HOST, msg.getSource());
283 assertTrue(msg.getAssignments().hasAssignment(MY_HOST));
287 public void testAwaitIdentification_HasAssignment() {
288 // not the leader, but has an assignment
289 BucketAssignments asgn = new BucketAssignments(new String[] {PREV_HOST, MY_HOST, HOST2});
290 mgr.startDistributing(asgn);
291 state = new QueryState(mgr);
294 state.process(new Identification(MY_HOST, null));
296 // tell it the leader is still active
297 state.process(new Identification(PREV_HOST, asgn));
299 Pair<Long, StateTimerTask> timer = onceTasks.remove();
301 assertEquals(STD_IDENTIFICATION_MS, timer.first().longValue());
302 assertNotNull(timer.second());
304 // set up active state, as that's what it should return
305 State next = mock(State.class);
306 when(mgr.goActive()).thenReturn(next);
308 assertEquals(next, timer.second().fire());
310 // should NOT have published a Leader message
311 assertTrue(admin.isEmpty());
313 // should have gone active with the current assignments
314 verify(mgr).goActive();
318 public void testAwaitIdentification_NoAssignment() {
319 // not the leader and no assignment
320 BucketAssignments asgn = new BucketAssignments(new String[] {HOST1, HOST2});
321 mgr.startDistributing(asgn);
322 state = new QueryState(mgr);
325 state.process(new Identification(MY_HOST, null));
327 // tell it the leader is still active
328 state.process(new Identification(PREV_HOST, asgn));
330 Pair<Long, StateTimerTask> timer = onceTasks.remove();
332 assertEquals(STD_IDENTIFICATION_MS, timer.first().longValue());
333 assertNotNull(timer.second());
335 // set up inactive state, as that's what it should return
336 State next = mock(State.class);
337 when(mgr.goInactive()).thenReturn(next);
339 assertEquals(next, timer.second().fire());
341 // should NOT have published a Leader message
342 assertTrue(admin.isEmpty());
346 public void testHasAssignment() {
348 mgr.startDistributing(null);
349 assertFalse(state.hasAssignment());
351 // not in assignments
352 state.setAssignments(new BucketAssignments(new String[] {HOST3}));
353 assertFalse(state.hasAssignment());
355 // it IS in the assignments
356 state.setAssignments(new BucketAssignments(new String[] {MY_HOST}));
357 assertTrue(state.hasAssignment());
361 public void testRecordInfo_NullSource() {
362 state.setAssignments(ASGN3);
363 state.setLeader(MY_HOST);
365 BucketAssignments asgn = new BucketAssignments(new String[] {PREV_HOST, MY_HOST, HOST2});
366 state.process(new Identification(null, asgn));
369 assertEquals(MY_HOST, state.getLeader());
371 // assignments still updated
372 assertEquals(asgn, state.getAssignments());
376 public void testRecordInfo_SourcePreceedsMyHost() {
377 state.setAssignments(ASGN3);
378 state.setLeader(MY_HOST);
380 BucketAssignments asgn = new BucketAssignments(new String[] {PREV_HOST, MY_HOST, HOST2});
381 state.process(new Identification(PREV_HOST, asgn));
384 assertEquals(PREV_HOST, state.getLeader());
386 // assignments still updated
387 assertEquals(asgn, state.getAssignments());
391 public void testRecordInfo_SourceFollowsMyHost() {
392 mgr.startDistributing(null);
393 state.setLeader(MY_HOST);
395 BucketAssignments asgn = new BucketAssignments(new String[] {HOST1, HOST2});
396 state.process(new Identification(HOST1, asgn));
399 assertEquals(MY_HOST, state.getLeader());
401 // assignments still updated
402 assertEquals(asgn, state.getAssignments());
406 public void testRecordInfo_NewIsNull() {
407 state.setAssignments(ASGN3);
408 state.process(new Identification(HOST1, null));
410 assertEquals(ASGN3, state.getAssignments());
414 public void testRecordInfo_NewIsEmpty() {
415 state.setAssignments(ASGN3);
416 state.process(new Identification(PREV_HOST, new BucketAssignments()));
418 assertEquals(ASGN3, state.getAssignments());
422 public void testRecordInfo_OldIsNull() {
423 mgr.startDistributing(null);
425 BucketAssignments asgn = new BucketAssignments(new String[] {HOST1, HOST2});
426 state.process(new Identification(HOST1, asgn));
428 assertEquals(asgn, state.getAssignments());
432 public void testRecordInfo_OldIsEmpty() {
433 state.setAssignments(new BucketAssignments());
435 BucketAssignments asgn = new BucketAssignments(new String[] {HOST1, HOST2});
436 state.process(new Identification(HOST1, asgn));
438 assertEquals(asgn, state.getAssignments());
442 public void testRecordInfo_NewLeaderPreceedsOld() {
443 state.setAssignments(ASGN3);
444 state.setLeader(MY_HOST);
446 BucketAssignments asgn = new BucketAssignments(new String[] {PREV_HOST, MY_HOST, HOST2});
447 state.process(new Identification(HOST3, asgn));
449 assertEquals(asgn, state.getAssignments());
453 public void testRecordInfo_NewLeaderSucceedsOld() {
454 state.setAssignments(ASGN3);
455 state.setLeader(MY_HOST);
457 BucketAssignments asgn = new BucketAssignments(new String[] {HOST2, HOST3});
458 state.process(new Identification(HOST3, asgn));
460 // should be unchanged
461 assertEquals(ASGN3, state.getAssignments());