OPNFLWPLUG-1032: Neon-MRI: Bump odlparent, yangtools, mdsal
[openflowplugin.git] / openflowplugin-impl / src / test / java / org / opendaylight / openflowplugin / impl / device / PacketInRateLimiterTest.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.openflowplugin.impl.device;
10
11 import static org.mockito.ArgumentMatchers.anyBoolean;
12
13 import org.junit.Assert;
14 import org.junit.Before;
15 import org.junit.Test;
16 import org.junit.runner.RunWith;
17 import org.mockito.InOrder;
18 import org.mockito.Mock;
19 import org.mockito.Mockito;
20 import org.mockito.runners.MockitoJUnitRunner;
21 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter;
22 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
23 import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
24
25 /**
26  * Test for {@link PacketInRateLimiter}.
27  */
28 @RunWith(MockitoJUnitRunner.class)
29 public class PacketInRateLimiterTest {
30
31     private PacketInRateLimiter rateLimiter;
32     @Mock
33     private ConnectionAdapter connectionAdapter;
34     @Mock
35     private MessageSpy messageSpy;
36     private InOrder caOrdered;
37
38     @Before
39     public void setUp() throws Exception {
40         caOrdered = Mockito.inOrder(connectionAdapter);
41         rateLimiter = new PacketInRateLimiter(connectionAdapter, 4, 10, messageSpy, 0.5f);
42     }
43
44     @Test
45     public void testDisableFlow() throws Exception {
46         rateLimiter.disableFlow();
47
48         Mockito.verify(messageSpy).spyMessage(DeviceContext.class, MessageSpy.StatisticsGroup.OFJ_BACKPRESSURE_ON);
49         Mockito.verify(connectionAdapter).setPacketInFiltering(true);
50     }
51
52     @Test
53     public void testEnableFlow() throws Exception {
54         rateLimiter.enableFlow();
55
56         Mockito.verify(messageSpy).spyMessage(DeviceContext.class, MessageSpy.StatisticsGroup.OFJ_BACKPRESSURE_OFF);
57         Mockito.verify(connectionAdapter).setPacketInFiltering(false);
58     }
59
60     @Test
61     public void testDrainLowWaterMark() throws Exception {
62         // scenario:
63         // occupy 4 permits
64         // drain low water mark = lwm temporarily set to 50% (= 2) and get limited
65         // need to free 2 permits to escape the limit and reset lwm
66         // now free to get more than 2 permits
67
68         Assert.assertEquals(0, rateLimiter.getOccupiedPermits());
69         Assert.assertFalse(rateLimiter.isLimited());
70         acquirePermits(4);
71         Assert.assertEquals(4, rateLimiter.getOccupiedPermits());
72
73         // drain current
74         rateLimiter.drainLowWaterMark();
75         Assert.assertEquals(4, rateLimiter.getOccupiedPermits());
76         Assert.assertTrue(rateLimiter.isLimited());
77         caOrdered.verify(connectionAdapter).setPacketInFiltering(true);
78
79         // release 1 permit ->  3 occupied but threshold = 2 -> stay limited
80         rateLimiter.releasePermit();
81         Assert.assertEquals(3, rateLimiter.getOccupiedPermits());
82         Assert.assertTrue(rateLimiter.isLimited());
83
84         // release 1 permit ->  2 occupied but threshold = 2 -> escape limit
85         rateLimiter.releasePermit();
86         Assert.assertEquals(2, rateLimiter.getOccupiedPermits());
87         Assert.assertFalse(rateLimiter.isLimited());
88         caOrdered.verify(connectionAdapter).setPacketInFiltering(false);
89
90         // lwm is reset
91         acquirePermits(4);
92         Assert.assertEquals(6, rateLimiter.getOccupiedPermits());
93         Assert.assertFalse(rateLimiter.isLimited());
94
95         Mockito.verify(connectionAdapter, Mockito.times(2)).setPacketInFiltering(anyBoolean());
96     }
97
98     private void acquirePermits(int permits) {
99         for (int i = 0; i < permits; i++) {
100             final boolean gainedPermit = rateLimiter.acquirePermit();
101             if (!gainedPermit) {
102                 throw new IllegalStateException("not enough permits");
103             }
104         }
105     }
106
107     private void releasePermits(int permits) {
108         for (int i = 0; i < permits; i++) {
109             rateLimiter.releasePermit();
110         }
111     }
112
113     @Test
114     public void testAcquirePermit() throws Exception {
115         Assert.assertEquals(0, rateLimiter.getOccupiedPermits());
116         Assert.assertFalse(rateLimiter.isLimited());
117
118         // approach hwm
119         acquirePermits(10);
120         Assert.assertEquals(10, rateLimiter.getOccupiedPermits());
121         Assert.assertFalse(rateLimiter.isLimited());
122
123         // hit hwm
124         Assert.assertFalse(rateLimiter.acquirePermit());
125         Assert.assertEquals(10, rateLimiter.getOccupiedPermits());
126         Assert.assertTrue(rateLimiter.isLimited());
127         caOrdered.verify(connectionAdapter).setPacketInFiltering(true);
128
129         // approach lwm
130         releasePermits(5);
131         Assert.assertEquals(5, rateLimiter.getOccupiedPermits());
132         Assert.assertTrue(rateLimiter.isLimited());
133
134         // cross lwm
135         rateLimiter.releasePermit();
136         Assert.assertEquals(4, rateLimiter.getOccupiedPermits());
137         Assert.assertFalse(rateLimiter.isLimited());
138         caOrdered.verify(connectionAdapter).setPacketInFiltering(false);
139
140         Mockito.verify(connectionAdapter, Mockito.times(2)).setPacketInFiltering(anyBoolean());
141     }
142
143     @Test
144     public void testChangeWaterMarks1() throws Exception {
145         rateLimiter.changeWaterMarks(2, 4);
146         acquirePermits(4);
147         Assert.assertEquals(4, rateLimiter.getOccupiedPermits());
148         Assert.assertFalse(rateLimiter.isLimited());
149
150         // hit hwm
151         Assert.assertFalse(rateLimiter.acquirePermit());
152         Assert.assertEquals(4, rateLimiter.getOccupiedPermits());
153         Assert.assertTrue(rateLimiter.isLimited());
154         caOrdered.verify(connectionAdapter).setPacketInFiltering(true);
155
156         // approach lwm
157         rateLimiter.releasePermit();
158         Assert.assertEquals(3, rateLimiter.getOccupiedPermits());
159         Assert.assertTrue(rateLimiter.isLimited());
160
161         // cross lwm, escape limit
162         rateLimiter.releasePermit();
163         Assert.assertEquals(2, rateLimiter.getOccupiedPermits());
164         Assert.assertFalse(rateLimiter.isLimited());
165         caOrdered.verify(connectionAdapter).setPacketInFiltering(false);
166
167         Mockito.verify(connectionAdapter, Mockito.times(2)).setPacketInFiltering(anyBoolean());
168     }
169
170     @Test
171     public void testChangeWaterMarks2() throws Exception {
172         // draining to lwm/occupied = 3/6
173         acquirePermits(6);
174         rateLimiter.drainLowWaterMark();
175         Assert.assertEquals(6, rateLimiter.getOccupiedPermits());
176         Assert.assertTrue(rateLimiter.isLimited());
177         caOrdered.verify(connectionAdapter).setPacketInFiltering(true);
178
179         rateLimiter.changeWaterMarks(7, 12);
180         Assert.assertEquals(6, rateLimiter.getOccupiedPermits());
181         Assert.assertTrue(rateLimiter.isLimited());
182
183         // new lwm is equal to current occupied permits - we can acquire more but flow is still limited
184         acquirePermits(1);
185         Assert.assertTrue(rateLimiter.isLimited());
186         Assert.assertEquals(7, rateLimiter.getOccupiedPermits());
187
188         // cross lwm, escape old lwm limit, reset lwm
189         rateLimiter.releasePermit();
190         Assert.assertEquals(6, rateLimiter.getOccupiedPermits());
191         Assert.assertFalse(rateLimiter.isLimited());
192         caOrdered.verify(connectionAdapter).setPacketInFiltering(false);
193
194         // free to reach hwm of 12
195         acquirePermits(6);
196         Assert.assertEquals(12, rateLimiter.getOccupiedPermits());
197         Assert.assertFalse(rateLimiter.isLimited());
198
199         Mockito.verify(connectionAdapter, Mockito.times(2)).setPacketInFiltering(anyBoolean());
200     }
201 }