2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved.
4 * ================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.pdpx.main.comm;
23 import static org.assertj.core.api.Assertions.assertThatCode;
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertSame;
26 import static org.mockito.ArgumentMatchers.any;
27 import static org.mockito.ArgumentMatchers.anyBoolean;
28 import static org.mockito.ArgumentMatchers.anyLong;
29 import static org.mockito.Mockito.never;
30 import static org.mockito.Mockito.times;
31 import static org.mockito.Mockito.verify;
32 import static org.mockito.Mockito.when;
34 import java.util.Arrays;
35 import java.util.LinkedList;
36 import java.util.Queue;
37 import java.util.concurrent.ScheduledExecutorService;
38 import java.util.concurrent.ScheduledFuture;
39 import java.util.concurrent.TimeUnit;
40 import org.junit.Before;
41 import org.junit.Test;
42 import org.junit.runner.RunWith;
43 import org.mockito.Mock;
44 import org.mockito.junit.MockitoJUnitRunner;
45 import org.onap.policy.common.endpoints.event.comm.TopicSink;
46 import org.onap.policy.common.endpoints.event.comm.client.BidirectionalTopicClient;
47 import org.onap.policy.common.utils.coder.CoderException;
48 import org.onap.policy.models.pdp.concepts.PdpStatus;
49 import org.onap.policy.pdpx.main.XacmlState;
51 @RunWith(MockitoJUnitRunner.class)
52 public class XacmlPdpHearbeatPublisherTest {
54 private static final long INTERVAL1 = 1000L;
55 private static final long INTERVAL2 = 2000L;
56 private static final long INTERVAL_INVALID = 0;
59 private TopicSink sink;
62 private BidirectionalTopicClient checker;
65 private XacmlState state;
68 private ScheduledExecutorService executor;
71 private ScheduledFuture<?> timer1;
74 private ScheduledFuture<?> timer2;
76 private PdpStatus status;
78 private Queue<ScheduledFuture<?>> timers;
80 private XacmlPdpHearbeatPublisher publisher;
84 * Initializes objects, including the publisher.
88 when(sink.getTopic()).thenReturn("my-topic");
89 when(checker.getSink()).thenReturn(sink);
90 when(checker.isReady()).thenReturn(true);
91 when(state.genHeartbeat()).thenReturn(status);
93 status = new PdpStatus();
94 timers = new LinkedList<>(Arrays.asList(timer1, timer2));
96 when(executor.scheduleWithFixedDelay(any(), anyLong(), anyLong(), any())).thenAnswer(args -> timers.remove());
98 publisher = new MyPublisher(checker, 10, state);
102 public void testRun() {
105 verify(state).genHeartbeat();
106 verify(checker).send(any());
110 * Tests the run() method when the probe is disabled.
113 public void testRunNoProbe() throws CoderException {
114 publisher = new MyPublisher(checker, 0, state);
118 verify(checker, never()).isReady();
119 verify(checker, never()).awaitReady(any(), anyLong());
121 verify(state).genHeartbeat();
122 verify(checker).send(any());
126 * Tests the run() method when the topic is not ready, and then becomes ready.
129 public void testRunNotReady() throws CoderException {
131 when(checker.isReady()).thenReturn(false);
132 when(checker.awaitReady(any(), anyLong())).thenReturn(false);
135 verify(state, never()).genHeartbeat();
136 verify(checker, never()).send(any());
138 // isReady is still false, but awaitReady is now true - should generate heartbeat
139 when(checker.awaitReady(any(), anyLong())).thenReturn(true);
142 verify(state).genHeartbeat();
143 verify(checker).send(any());
145 // now isReady is true, too - should not rerun awaitReady
146 when(checker.isReady()).thenReturn(true);
149 verify(state, times(2)).genHeartbeat();
150 verify(checker, times(2)).send(any());
151 verify(checker, times(2)).awaitReady(any(), anyLong());
155 * Tests the run() method when the checker throws an exception.
158 public void testRunCheckerEx() throws CoderException {
159 // force it to call awaitReady
160 when(checker.isReady()).thenReturn(false);
162 when(checker.awaitReady(any(), anyLong()))
163 .thenThrow(new CoderException("expected exception"))
166 // exception thrown - should not generate heartbeat
168 verify(state, never()).genHeartbeat();
169 verify(checker, never()).send(any());
171 // no exception this time - SHOULD generate heartbeat
173 verify(state).genHeartbeat();
174 verify(checker).send(any());
178 public void testTerminate() {
180 publisher.terminate();
182 verify(checker).stopWaiting();
185 // now start it and then try again
187 publisher.terminate();
189 // timer2 should still be in the queue
190 assertSame(timer2, timers.peek());
193 // repeat - nothing more should happen
194 publisher.terminate();
196 // timer2 should still be in the queue
197 assertSame(timer2, timers.peek());
201 public void testRestart() {
202 // not started yet - should only update the interval
203 publisher.restart(INTERVAL1);
205 assertEquals(INTERVAL1, publisher.getIntervalMs());
206 assertSame(timer1, timers.peek());
210 verify(executor).scheduleWithFixedDelay(publisher, 0, INTERVAL1, TimeUnit.MILLISECONDS);
212 // null interval - no changes
213 publisher.restart(null);
214 verify(executor, times(1)).scheduleWithFixedDelay(any(), anyLong(), anyLong(), any());
215 assertSame(timer2, timers.peek());
217 // same interval - no changes
218 publisher.restart(INTERVAL1);
219 verify(executor, times(1)).scheduleWithFixedDelay(any(), anyLong(), anyLong(), any());
220 assertSame(timer2, timers.peek());
222 // invalid interval - no changes
223 publisher.restart(INTERVAL_INVALID);
224 verify(executor, times(1)).scheduleWithFixedDelay(any(), anyLong(), anyLong(), any());
225 assertSame(timer2, timers.peek());
227 // new interval - old timer should be cancelled and new started
228 publisher.restart(INTERVAL2);
229 verify(timer1).cancel(anyBoolean());
230 verify(executor).scheduleWithFixedDelay(publisher, 0, INTERVAL2, TimeUnit.MILLISECONDS);
234 public void testStart() {
237 verify(executor).scheduleWithFixedDelay(publisher, 0, XacmlPdpHearbeatPublisher.DEFAULT_HB_INTERVAL_MS,
238 TimeUnit.MILLISECONDS);
240 // repeat - nothing more should happen
242 verify(executor, times(1)).scheduleWithFixedDelay(any(), anyLong(), anyLong(), any());
243 verify(timer1, never()).cancel(anyBoolean());
247 public void testMakeTimerThread() {
248 // create a plain listener to test the "real" makeTimer() method
249 publisher = new XacmlPdpHearbeatPublisher(checker, 1, state);
251 assertThatCode(() -> {
253 publisher.restart(100L);
254 publisher.terminate();
255 }).doesNotThrowAnyException();
258 private class MyPublisher extends XacmlPdpHearbeatPublisher {
260 public MyPublisher(BidirectionalTopicClient topicChecker, long probeHeartbeatTopicMs, XacmlState state) {
261 super(topicChecker, probeHeartbeatTopicMs, state);
265 protected ScheduledExecutorService makeTimerThread() {