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)));
72 doReturn(TimeUnit.MILLISECONDS.toNanos(0) * 1D).when(commitSnapshot).getValue(0.1);
74 commitCallback = new TransactionRateLimitingCallback(actorContext);
76 commitCallback.success();
78 verify(actorContext).setTxCreationLimit(Matchers.doubleThat(approximately(292)));
82 public void testSuccessPercentileValueZero(){
84 for(int i=1;i<11;i++){
85 // Keep on increasing the amount of time it takes to complete transaction for each tenth of a
86 // percentile. Essentially this would be 1ms for the 10th percentile, 2ms for 20th percentile and so on.
87 doReturn(TimeUnit.MILLISECONDS.toNanos(i) * 1D).when(commitSnapshot).getValue(i * 0.1);
90 doReturn(TimeUnit.MILLISECONDS.toNanos(0) * 1D).when(commitSnapshot).getValue(0.1);
92 TransactionRateLimitingCallback commitCallback = new TransactionRateLimitingCallback(actorContext);
94 commitCallback.success();
96 verify(actorContext).setTxCreationLimit(Matchers.doubleThat(approximately(192)));
100 public void testSuccessOnePercentileValueVeryHigh(){
102 for(int i=1;i<11;i++){
103 // Keep on increasing the amount of time it takes to complete transaction for each tenth of a
104 // percentile. Essentially this would be 1ms for the 10th percentile, 2ms for 20th percentile and so on.
105 doReturn(TimeUnit.MILLISECONDS.toNanos(i) * 1D).when(commitSnapshot).getValue(i * 0.1);
109 doReturn(TimeUnit.MILLISECONDS.toNanos(10000) * 1D).when(commitSnapshot).getValue(1.0);
111 TransactionRateLimitingCallback commitCallback = new TransactionRateLimitingCallback(actorContext);
112 commitCallback.run();
113 commitCallback.success();
115 verify(actorContext).setTxCreationLimit(Matchers.doubleThat(approximately(282)));
119 public void testSuccessWithAllPercentileValueVeryHigh(){
121 for(int i=1;i<11;i++){
122 // Keep on increasing the amount of time it takes to complete transaction for each tenth of a
123 // percentile. Essentially this would be 1ms for the 10th percentile, 2ms for 20th percentile and so on.
124 doReturn(TimeUnit.MILLISECONDS.toNanos(10000) * 1D).when(commitSnapshot).getValue(i * 0.1);
127 TransactionRateLimitingCallback commitCallback = new TransactionRateLimitingCallback(actorContext);
128 commitCallback.run();
129 commitCallback.success();
131 verify(actorContext).setTxCreationLimit(Matchers.doubleThat(approximately(0)));
135 public void testSuccessWithRealPercentileValues(){
137 for(int i=1;i<11;i++){
138 // Keep on increasing the amount of time it takes to complete transaction for each tenth of a
139 // percentile. Essentially this would be 1ms for the 10th percentile, 2ms for 20th percentile and so on.
140 doReturn(TimeUnit.MILLISECONDS.toNanos(8) * 1D).when(commitSnapshot).getValue(i * 0.1);
143 doReturn(TimeUnit.MILLISECONDS.toNanos(20) * 1D).when(commitSnapshot).getValue( 0.7);
144 doReturn(TimeUnit.MILLISECONDS.toNanos(100) * 1D).when(commitSnapshot).getValue( 0.9);
145 doReturn(TimeUnit.MILLISECONDS.toNanos(200) * 1D).when(commitSnapshot).getValue( 1.0);
147 TransactionRateLimitingCallback commitCallback = new TransactionRateLimitingCallback(actorContext);
148 commitCallback.run();
149 commitCallback.success();
151 verify(actorContext).setTxCreationLimit(Matchers.doubleThat(approximately(101)));
156 public void testSuccessWithoutRun(){
157 TransactionRateLimitingCallback commitCallback = new TransactionRateLimitingCallback(actorContext);
160 commitCallback.success();
161 fail("Expected IllegalStateException");
162 } catch(IllegalStateException e){
166 verify(actorContext, never()).setTxCreationLimit(anyDouble());
172 public void testFailure(){
173 TransactionRateLimitingCallback commitCallback = new TransactionRateLimitingCallback(actorContext);
174 commitCallback.run();
175 commitCallback.failure();
177 verify(actorContext, never()).setTxCreationLimit(anyDouble());
181 public Matcher<Double> approximately(final double val){
182 return new BaseMatcher<Double>() {
184 public boolean matches(Object o) {
185 Double aDouble = (Double) o;
186 return aDouble > val && aDouble < val+1;
190 public void describeTo(Description description) {