d5a940f73fe6f83347942a5cde5046febf4340bc
[ccsdk/features.git] /
1 /*
2  * ============LICENSE_START=======================================================
3  * ONAP : ccsdk features
4  * ================================================================================
5  * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property.
6  * All rights reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  *
21  */
22 package org.onap.ccsdk.features.sdnr.wt.websocketmanager2.test;
23
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertNotEquals;
26 import java.time.Duration;
27 import java.time.Instant;
28 import java.util.Timer;
29 import java.util.TimerTask;
30 import org.junit.Test;
31 import org.onap.ccsdk.features.sdnr.wt.websocketmanager.utils.RateFilterManager;
32 import org.onap.ccsdk.features.sdnr.wt.websocketmanager.utils.RateFilterManager.RateFilter;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 /**
37  * {@link #RateFilter} Problems of to many notifications during mount of thousand of devices.
38  *
39  * <pre>
40  *  Testcase (e: 17 Event received, rateMaxCount=3)
41  *         1 3                           4  5 6 7 8 9 10 11    14   15        16               17     18
42  *     t            t           t          t              t              t              t         t              t
43  *           eee                           e  e e e e e  e  e e e e    e         e                e      e
44  *    ---//--|--------------|-----//-------|--------------|--------------|--------------|---//----|--------------|
45  *           P1:1           P2:1           P1:2           P2:2           P3:2          P4:2       P1:3
46  * ms  500   1000-1002      2000           3500           4500           5500           6500      7500           8500
47  *Overload              no             no            yes                      yes     no              no
48  * </pre>
49  *
50  */
51 public class RateFilterTest {
52
53     private static final Logger LOG = LoggerFactory.getLogger(RateFilterTest.class.getName());
54
55     private static int INTEGRATIONTIMEMILLIS = 1000;
56     private static long EVENTS_PER_INTERVALL = 4;
57     private static long RATE_PER_MINUTE = EVENTS_PER_INTERVALL * 60;
58     /* Negative event time indicates timer event */
59     private static long[] now = {-500, 1000, 1010, 1020, //P1:1 1-3
60             -1500, -2500, -3500, 3500, 3550, 3560, 3570, 3580, 3590, 3800, //P1:2 3500 4-10
61             -4500, 4510, 4520, 4530, 4540, 4900, //P2:2 4500 11-15
62             -5500, 5700, //P3:2 5500 16
63             -6500, -7500, 7500, 8000};//P1:3 17-18
64     private static boolean[] overload = {false, false, false, false, //P1:1 1-3
65             false, false, false, false, false, false, false, false, false, false, //P1:2 3500 4-10
66             true, true, true, true, true, true, //P2:2 4500 11-15
67             true, true, //P3:2 5500 16
68             false, false, false, false};//P1:3 17-18
69
70     private static int idx;
71     private static long millis;
72
73     @Test
74     public void testStates() {
75         reset();
76         RateFilterManager rateFilterManager =
77                 new RateFilterManager(Duration.ofMillis(INTEGRATIONTIMEMILLIS), false, () -> getNow());
78         RateFilter rateFilter = rateFilterManager.getRateFilter(RATE_PER_MINUTE);
79         LOG.info("Init done");
80         assertEquals("Events per integration period", EVENTS_PER_INTERVALL, rateFilter.getMaxEventsPerIntegration());
81
82         for (int t = 1; t < 30; t++) {
83             boolean expected = tick();
84             if (millis < 0) {
85                 LOG.info("{} - timer {}", t, millis);
86                 rateFilter.timer();
87             } else {
88                 LOG.info("{} - event {}", t, millis);
89                 rateFilter.event();
90             }
91             LOG.info("Overload={} {}", rateFilter.getOverloadStatus(), expected);
92             assertEquals("Filter activity", expected, rateFilter.getOverloadStatus());
93         }
94         rateFilter.close();
95     }
96
97     @Test
98     public void testThread() throws InterruptedException {
99         LOG.info("testThread");
100         reset();
101         RateFilterManager rateFilterManager = new RateFilterManager(Duration.ofMillis(INTEGRATIONTIMEMILLIS));
102         RateFilter rateFilter = rateFilterManager.getRateFilter(RATE_PER_MINUTE);
103
104         tick();
105         Thread.sleep(2000);
106
107         Object objectYouNeedToLockOn = new Object();
108         Timer timer = new Timer();
109         timer.scheduleAtFixedRate(new TimerTask() {
110             long localMillis;
111
112             @Override
113             public void run() {
114                 long xLocalMillis = localMillis += 10;
115                 long xMillis = Math.abs(millis);
116                 if (xLocalMillis >= xMillis) {
117                     LOG.info("aTime:{} Millis:{} Idx={}", xLocalMillis, xMillis, idx);
118                     boolean expected = tick();
119                     if (millis > 0) {
120                         //Skip negatives .. handled by timer
121                         rateFilter.event();
122                         boolean actual = rateFilter.getOverloadStatus();
123                         LOG.info("bTime:{} Millis:{} Idx={} Overload={} Expected={} {}", xLocalMillis, xMillis, idx,
124                                 actual, expected, actual == expected ? "" : "XXXX");
125                         if (idx >= 30) {
126                             LOG.info("Test is ending");
127                             synchronized (objectYouNeedToLockOn) {
128                                 objectYouNeedToLockOn.notify();
129                             }
130                             timer.cancel();
131                         }
132                         assertEquals("Filter activity", expected, rateFilter.getOverloadStatus());
133                     }
134                 }
135             }
136         }, 0, 10);
137         synchronized (objectYouNeedToLockOn) {
138             objectYouNeedToLockOn.wait();
139         }
140         //rateFilter.close();
141         LOG.info("Test end");
142     }
143
144     @Test
145     public void testMultipleClients() {
146         RateFilterManager rateFilterManager = new RateFilterManager(Duration.ofMillis(INTEGRATIONTIMEMILLIS));
147         RateFilter rateFilter1 = rateFilterManager.getRateFilter(RATE_PER_MINUTE);
148         assertEquals("Multiple clients", 1, rateFilter1.getClients());
149         RateFilter rateFilter2 = rateFilterManager.getRateFilter(RATE_PER_MINUTE);
150         assertEquals("Multiple clients", 2, rateFilter1.getClients());
151         RateFilter rateFilter3 = rateFilterManager.getRateFilter(RATE_PER_MINUTE);
152         assertEquals("Multiple clients", 3, rateFilter1.getClients());
153
154         assertEquals("Similar instances", rateFilter1, rateFilter3);
155
156         RateFilter rateFilterOther = rateFilterManager.getRateFilter(2*RATE_PER_MINUTE);
157         assertNotEquals("Different instances", rateFilter1, rateFilterOther);
158         rateFilterOther.close();
159
160         rateFilter3.close();
161         assertEquals("Multiple clients", 2, rateFilter1.getClients());
162         rateFilter2.close();
163         assertEquals("Multiple clients", 1, rateFilter1.getClients());
164         rateFilter1.close();
165         assertEquals("Multiple clients", 0, rateFilter1.getClients());
166
167         rateFilterManager.close();
168     }
169
170     private Instant getNow() {
171         LOG.debug("Now:{}", millis);
172         return Instant.ofEpochMilli(Math.abs(millis));
173     }
174
175     private void reset() {
176         idx = 0;
177     }
178
179     private boolean tick() {
180         if (idx < now.length) {
181             millis = now[idx];
182         } else {
183             int lastIdx = now.length - 1;
184             millis = now[lastIdx] + (idx - lastIdx) * INTEGRATIONTIMEMILLIS;
185         }
186         boolean expected = idx < overload.length ? overload[idx] : false;
187         idx++;
188         return expected;
189     }
190
191 }