blob: d935cd8ea90b23f37eec8141bf41aeb65253a811 [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Thomas Vachuskaecb63c52015-02-19 10:03:48 -080016package org.onlab.util;
tom931af4e2014-09-13 12:00:57 -070017
Jonathan Hartecaa8a82015-02-04 09:44:08 -080018import org.junit.Test;
19
20import java.util.List;
Thomas Vachuskaa82341c2015-08-25 17:36:59 -070021import java.util.stream.IntStream;
Jonathan Hartecaa8a82015-02-04 09:44:08 -080022
Brian O'Connorc590ebb2016-12-08 18:16:41 -080023import static org.junit.Assert.*;
Thomas Vachuskaa82341c2015-08-25 17:36:59 -070024import static org.onlab.junit.TestTools.assertAfter;
tom931af4e2014-09-13 12:00:57 -070025
tom931af4e2014-09-13 12:00:57 -070026/**
27 * Tests the operation of the accumulator.
28 */
Thomas Vachuskaecb63c52015-02-19 10:03:48 -080029public class AbstractAccumulatorTest {
tom931af4e2014-09-13 12:00:57 -070030
Aaron Kruglikov4ce0b042015-10-07 14:04:17 -070031
Aaron Kruglikovf27dba62015-10-27 15:06:29 -070032 private final ManuallyAdvancingTimer timer = new ManuallyAdvancingTimer(true);
Aaron Kruglikov4ce0b042015-10-07 14:04:17 -070033
Aaron Kruglikovb0ca8cf2015-10-27 10:33:41 -070034 private static final int LONG_REAL_TIME_DELAY = 30;
35 private static final int SHORT_REAL_TIME_DELAY = 5;
36
tom931af4e2014-09-13 12:00:57 -070037
38 @Test
39 public void basics() throws Exception {
40 TestAccumulator accumulator = new TestAccumulator();
41 assertEquals("incorrect timer", timer, accumulator.timer());
Thomas Vachuskaecb63c52015-02-19 10:03:48 -080042 assertEquals("incorrect max events", 5, accumulator.maxItems());
tom931af4e2014-09-13 12:00:57 -070043 assertEquals("incorrect max ms", 100, accumulator.maxBatchMillis());
Thomas Vachuska75af68a2015-02-22 12:13:52 -080044 assertEquals("incorrect idle ms", 70, accumulator.maxIdleMillis());
tom931af4e2014-09-13 12:00:57 -070045 }
46
47 @Test
48 public void eventTrigger() {
49 TestAccumulator accumulator = new TestAccumulator();
Thomas Vachuskaecb63c52015-02-19 10:03:48 -080050 accumulator.add(new TestItem("a"));
51 accumulator.add(new TestItem("b"));
52 accumulator.add(new TestItem("c"));
53 accumulator.add(new TestItem("d"));
tom931af4e2014-09-13 12:00:57 -070054 assertTrue("should not have fired yet", accumulator.batch.isEmpty());
Thomas Vachuskaecb63c52015-02-19 10:03:48 -080055 accumulator.add(new TestItem("e"));
Aaron Kruglikovb0ca8cf2015-10-27 10:33:41 -070056 timer.advanceTimeMillis(20, LONG_REAL_TIME_DELAY);
tom931af4e2014-09-13 12:00:57 -070057 assertFalse("should have fired", accumulator.batch.isEmpty());
58 assertEquals("incorrect batch", "abcde", accumulator.batch);
59 }
60
61 @Test
62 public void timeTrigger() {
63 TestAccumulator accumulator = new TestAccumulator();
Thomas Vachuskaecb63c52015-02-19 10:03:48 -080064 accumulator.add(new TestItem("a"));
Aaron Kruglikovb0ca8cf2015-10-27 10:33:41 -070065 timer.advanceTimeMillis(30, SHORT_REAL_TIME_DELAY);
tom931af4e2014-09-13 12:00:57 -070066 assertTrue("should not have fired yet", accumulator.batch.isEmpty());
Thomas Vachuskaecb63c52015-02-19 10:03:48 -080067 accumulator.add(new TestItem("b"));
Aaron Kruglikovb0ca8cf2015-10-27 10:33:41 -070068 timer.advanceTimeMillis(30, SHORT_REAL_TIME_DELAY);
tom931af4e2014-09-13 12:00:57 -070069 assertTrue("should not have fired yet", accumulator.batch.isEmpty());
Thomas Vachuskaecb63c52015-02-19 10:03:48 -080070 accumulator.add(new TestItem("c"));
Aaron Kruglikovb0ca8cf2015-10-27 10:33:41 -070071 timer.advanceTimeMillis(30, SHORT_REAL_TIME_DELAY);
tom093340b2014-10-10 00:15:36 -070072 assertTrue("should not have fired yet", accumulator.batch.isEmpty());
Thomas Vachuskaecb63c52015-02-19 10:03:48 -080073 accumulator.add(new TestItem("d"));
Aaron Kruglikovb0ca8cf2015-10-27 10:33:41 -070074 timer.advanceTimeMillis(10, LONG_REAL_TIME_DELAY);
tom931af4e2014-09-13 12:00:57 -070075 assertFalse("should have fired", accumulator.batch.isEmpty());
tom093340b2014-10-10 00:15:36 -070076 assertEquals("incorrect batch", "abcd", accumulator.batch);
tom931af4e2014-09-13 12:00:57 -070077 }
78
79 @Test
80 public void idleTrigger() {
81 TestAccumulator accumulator = new TestAccumulator();
Thomas Vachuskaecb63c52015-02-19 10:03:48 -080082 accumulator.add(new TestItem("a"));
tom931af4e2014-09-13 12:00:57 -070083 assertTrue("should not have fired yet", accumulator.batch.isEmpty());
Thomas Vachuskaecb63c52015-02-19 10:03:48 -080084 accumulator.add(new TestItem("b"));
Aaron Kruglikovb0ca8cf2015-10-27 10:33:41 -070085 timer.advanceTimeMillis(70, LONG_REAL_TIME_DELAY);
tom931af4e2014-09-13 12:00:57 -070086 assertFalse("should have fired", accumulator.batch.isEmpty());
87 assertEquals("incorrect batch", "ab", accumulator.batch);
88 }
89
Thomas Vachuska75af68a2015-02-22 12:13:52 -080090 @Test
91 public void readyIdleTrigger() {
92 TestAccumulator accumulator = new TestAccumulator();
93 accumulator.ready = false;
94 accumulator.add(new TestItem("a"));
95 assertTrue("should not have fired yet", accumulator.batch.isEmpty());
96 accumulator.add(new TestItem("b"));
Aaron Kruglikovb0ca8cf2015-10-27 10:33:41 -070097 timer.advanceTimeMillis(80, SHORT_REAL_TIME_DELAY);
Thomas Vachuska75af68a2015-02-22 12:13:52 -080098 assertTrue("should not have fired yet", accumulator.batch.isEmpty());
99 accumulator.ready = true;
Aaron Kruglikovb0ca8cf2015-10-27 10:33:41 -0700100 timer.advanceTimeMillis(80, LONG_REAL_TIME_DELAY);
Thomas Vachuska75af68a2015-02-22 12:13:52 -0800101 assertFalse("should have fired", accumulator.batch.isEmpty());
102 assertEquals("incorrect batch", "ab", accumulator.batch);
103 }
104
105 @Test
106 public void readyLongTrigger() {
107 TestAccumulator accumulator = new TestAccumulator();
108 accumulator.ready = false;
Aaron Kruglikovb0ca8cf2015-10-27 10:33:41 -0700109 timer.advanceTimeMillis(120, SHORT_REAL_TIME_DELAY);
Thomas Vachuska75af68a2015-02-22 12:13:52 -0800110 assertTrue("should not have fired yet", accumulator.batch.isEmpty());
111 accumulator.add(new TestItem("a"));
112 assertTrue("should not have fired yet", accumulator.batch.isEmpty());
113 accumulator.ready = true;
Aaron Kruglikovb0ca8cf2015-10-27 10:33:41 -0700114 timer.advanceTimeMillis(120, LONG_REAL_TIME_DELAY);
Thomas Vachuska75af68a2015-02-22 12:13:52 -0800115 assertFalse("should have fired", accumulator.batch.isEmpty());
116 assertEquals("incorrect batch", "a", accumulator.batch);
117 }
118
119 @Test
120 public void readyMaxTrigger() {
121 TestAccumulator accumulator = new TestAccumulator();
122 accumulator.ready = false;
123 accumulator.add(new TestItem("a"));
124 accumulator.add(new TestItem("b"));
125 accumulator.add(new TestItem("c"));
126 accumulator.add(new TestItem("d"));
127 accumulator.add(new TestItem("e"));
128 accumulator.add(new TestItem("f"));
129 assertTrue("should not have fired yet", accumulator.batch.isEmpty());
130 accumulator.ready = true;
131 accumulator.add(new TestItem("g"));
Aaron Kruglikovb0ca8cf2015-10-27 10:33:41 -0700132 timer.advanceTimeMillis(10, LONG_REAL_TIME_DELAY);
Thomas Vachuska75af68a2015-02-22 12:13:52 -0800133 assertFalse("should have fired", accumulator.batch.isEmpty());
134 assertEquals("incorrect batch", "abcdefg", accumulator.batch);
135 }
136
Thomas Vachuskaa82341c2015-08-25 17:36:59 -0700137 @Test
138 public void stormTest() {
139 TestAccumulator accumulator = new TestAccumulator();
140 IntStream.range(0, 1000).forEach(i -> accumulator.add(new TestItem("#" + i)));
Aaron Kruglikov4ce0b042015-10-07 14:04:17 -0700141 timer.advanceTimeMillis(1);
Thomas Vachuskaa82341c2015-08-25 17:36:59 -0700142 assertAfter(100, () -> assertEquals("wrong item count", 1000, accumulator.itemCount));
Brian O'Connorc590ebb2016-12-08 18:16:41 -0800143 //TODO this assertion could fail under heavy load
144 assertTrue("batch count not near 200", Math.abs(200 - accumulator.batchCount) < 10);
Thomas Vachuskaa82341c2015-08-25 17:36:59 -0700145 }
Thomas Vachuska75af68a2015-02-22 12:13:52 -0800146
Thomas Vachuskaecb63c52015-02-19 10:03:48 -0800147 private class TestItem {
148 private final String s;
149
150 public TestItem(String s) {
151 this.s = s;
152 }
153 }
154
155 private class TestAccumulator extends AbstractAccumulator<TestItem> {
tom931af4e2014-09-13 12:00:57 -0700156
157 String batch = "";
Thomas Vachuska75af68a2015-02-22 12:13:52 -0800158 boolean ready = true;
Thomas Vachuskaa82341c2015-08-25 17:36:59 -0700159 int batchCount = 0;
160 int itemCount = 0;
tom931af4e2014-09-13 12:00:57 -0700161
162 protected TestAccumulator() {
Thomas Vachuska75af68a2015-02-22 12:13:52 -0800163 super(timer, 5, 100, 70);
tom931af4e2014-09-13 12:00:57 -0700164 }
165
166 @Override
Thomas Vachuskaecb63c52015-02-19 10:03:48 -0800167 public void processItems(List<TestItem> items) {
Thomas Vachuskaa82341c2015-08-25 17:36:59 -0700168 batchCount++;
169 itemCount += items.size();
Thomas Vachuskaecb63c52015-02-19 10:03:48 -0800170 for (TestItem item : items) {
171 batch += item.s;
tom931af4e2014-09-13 12:00:57 -0700172 }
173 }
Thomas Vachuska75af68a2015-02-22 12:13:52 -0800174
175 @Override
176 public boolean isReady() {
177 return ready;
178 }
tom931af4e2014-09-13 12:00:57 -0700179 }
tom931af4e2014-09-13 12:00:57 -0700180}