2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
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
9 package org.opendaylight.controller.cluster.datastore;
11 import static org.junit.Assert.fail;
12 import static org.mockito.Matchers.anyDouble;
13 import static org.mockito.Mockito.doReturn;
14 import static org.mockito.Mockito.never;
15 import static org.mockito.Mockito.verify;
16 import com.codahale.metrics.Snapshot;
17 import com.codahale.metrics.Timer;
18 import java.util.concurrent.TimeUnit;
19 import org.hamcrest.BaseMatcher;
20 import org.hamcrest.Description;
21 import org.hamcrest.Matcher;
22 import org.junit.Before;
23 import org.junit.Test;
24 import org.mockito.Matchers;
25 import org.mockito.Mock;
26 import org.mockito.MockitoAnnotations;
27 import org.opendaylight.controller.cluster.datastore.utils.ActorContext;
29 public class TransactionRateLimitingCommitCallbackTest {
32 public ActorContext actorContext;
35 public DatastoreContext datastoreContext;
38 public Timer commitTimer;
41 private Timer.Context commitTimerContext;
44 private Snapshot commitSnapshot;
48 MockitoAnnotations.initMocks(this);
49 doReturn(datastoreContext).when(actorContext).getDatastoreContext();
50 doReturn(30).when(datastoreContext).getShardTransactionCommitTimeoutInSeconds();
51 doReturn(commitTimer).when(actorContext).getOperationTimer("commit");
52 doReturn(commitTimerContext).when(commitTimer).time();
53 doReturn(commitSnapshot).when(commitTimer).getSnapshot();
57 public void testSuccess(){
59 for(int i=1;i<11;i++){
60 // Keep on increasing the amount of time it takes to complete transaction for each tenth of a
61 // percentile. Essentially this would be 1ms for the 10th percentile, 2ms for 20th percentile and so on.
62 doReturn(TimeUnit.MILLISECONDS.toNanos(i) * 1D).when(commitSnapshot).getValue(i * 0.1);
66 TransactionRateLimitingCallback commitCallback = new TransactionRateLimitingCallback(actorContext);
68 commitCallback.success();
70 verify(actorContext).setTxCreationLimit(Matchers.doubleThat(approximately(292)));
74 public void testSuccessPercentileValueZero(){
76 for(int i=1;i<11;i++){
77 // Keep on increasing the amount of time it takes to complete transaction for each tenth of a
78 // percentile. Essentially this would be 1ms for the 10th percentile, 2ms for 20th percentile and so on.
79 doReturn(TimeUnit.MILLISECONDS.toNanos(i) * 1D).when(commitSnapshot).getValue(i * 0.1);
82 doReturn(TimeUnit.MILLISECONDS.toNanos(0) * 1D).when(commitSnapshot).getValue(0.1);
84 TransactionRateLimitingCallback commitCallback = new TransactionRateLimitingCallback(actorContext);
86 commitCallback.success();
88 verify(actorContext).setTxCreationLimit(Matchers.doubleThat(approximately(192)));
92 public void testSuccessOnePercentileValueVeryHigh(){
94 for(int i=1;i<11;i++){
95 // Keep on increasing the amount of time it takes to complete transaction for each tenth of a
96 // percentile. Essentially this would be 1ms for the 10th percentile, 2ms for 20th percentile and so on.
97 doReturn(TimeUnit.MILLISECONDS.toNanos(i) * 1D).when(commitSnapshot).getValue(i * 0.1);
101 doReturn(TimeUnit.MILLISECONDS.toNanos(10000) * 1D).when(commitSnapshot).getValue(1.0);
103 TransactionRateLimitingCallback commitCallback = new TransactionRateLimitingCallback(actorContext);
104 commitCallback.run();
105 commitCallback.success();
107 verify(actorContext).setTxCreationLimit(Matchers.doubleThat(approximately(282)));
111 public void testSuccessWithAllPercentileValueVeryHigh(){
113 for(int i=1;i<11;i++){
114 // Keep on increasing the amount of time it takes to complete transaction for each tenth of a
115 // percentile. Essentially this would be 1ms for the 10th percentile, 2ms for 20th percentile and so on.
116 doReturn(TimeUnit.MILLISECONDS.toNanos(10000) * 1D).when(commitSnapshot).getValue(i * 0.1);
119 TransactionRateLimitingCallback commitCallback = new TransactionRateLimitingCallback(actorContext);
120 commitCallback.run();
121 commitCallback.success();
123 verify(actorContext).setTxCreationLimit(Matchers.doubleThat(approximately(0)));
127 public void testSuccessWithRealPercentileValues(){
129 for(int i=1;i<11;i++){
130 // Keep on increasing the amount of time it takes to complete transaction for each tenth of a
131 // percentile. Essentially this would be 1ms for the 10th percentile, 2ms for 20th percentile and so on.
132 doReturn(TimeUnit.MILLISECONDS.toNanos(8) * 1D).when(commitSnapshot).getValue(i * 0.1);
135 doReturn(TimeUnit.MILLISECONDS.toNanos(20) * 1D).when(commitSnapshot).getValue( 0.7);
136 doReturn(TimeUnit.MILLISECONDS.toNanos(100) * 1D).when(commitSnapshot).getValue( 0.9);
137 doReturn(TimeUnit.MILLISECONDS.toNanos(200) * 1D).when(commitSnapshot).getValue( 1.0);
139 TransactionRateLimitingCallback commitCallback = new TransactionRateLimitingCallback(actorContext);
140 commitCallback.run();
141 commitCallback.success();
143 verify(actorContext).setTxCreationLimit(Matchers.doubleThat(approximately(101)));
148 public void testSuccessWithoutRun(){
149 TransactionRateLimitingCallback commitCallback = new TransactionRateLimitingCallback(actorContext);
152 commitCallback.success();
153 fail("Expected IllegalStateException");
154 } catch(IllegalStateException e){
158 verify(actorContext, never()).setTxCreationLimit(anyDouble());
164 public void testFailure(){
165 TransactionRateLimitingCallback commitCallback = new TransactionRateLimitingCallback(actorContext);
166 commitCallback.run();
167 commitCallback.failure();
169 verify(actorContext, never()).setTxCreationLimit(anyDouble());
173 public Matcher<Double> approximately(final double val){
174 return new BaseMatcher<Double>() {
176 public boolean matches(Object o) {
177 Double aDouble = (Double) o;
178 return aDouble > val && aDouble < val+1;
182 public void describeTo(Description description) {
183 description.appendText("> " + val +" < " + (val+1));