23
23
import static io .grpc .rls .CachingRlsLbClient .RLS_DATA_KEY ;
24
24
import static org .junit .Assert .assertNotNull ;
25
25
import static org .junit .Assert .assertSame ;
26
+ import static org .mockito .AdditionalAnswers .delegatesTo ;
26
27
import static org .mockito .ArgumentMatchers .any ;
28
+ import static org .mockito .ArgumentMatchers .argThat ;
27
29
import static org .mockito .ArgumentMatchers .eq ;
28
30
import static org .mockito .Mockito .inOrder ;
29
31
import static org .mockito .Mockito .mock ;
30
32
import static org .mockito .Mockito .times ;
31
33
import static org .mockito .Mockito .verify ;
34
+ import static org .mockito .Mockito .when ;
32
35
33
36
import com .google .common .base .Converter ;
34
37
import com .google .common .collect .ImmutableList ;
47
50
import io .grpc .LoadBalancer .PickResult ;
48
51
import io .grpc .LoadBalancer .SubchannelPicker ;
49
52
import io .grpc .LoadBalancerProvider ;
53
+ import io .grpc .LongGaugeMetricInstrument ;
50
54
import io .grpc .ManagedChannel ;
51
55
import io .grpc .ManagedChannelBuilder ;
52
56
import io .grpc .Metadata ;
53
57
import io .grpc .MetricRecorder ;
58
+ import io .grpc .MetricRecorder .BatchCallback ;
59
+ import io .grpc .MetricRecorder .BatchRecorder ;
60
+ import io .grpc .MetricRecorder .Registration ;
54
61
import io .grpc .NameResolver .ConfigOrError ;
55
62
import io .grpc .Status ;
56
63
import io .grpc .Status .Code ;
95
102
import java .util .concurrent .TimeoutException ;
96
103
import javax .annotation .Nonnull ;
97
104
import org .junit .After ;
105
+ import org .junit .Before ;
98
106
import org .junit .Rule ;
99
107
import org .junit .Test ;
100
108
import org .junit .runner .RunWith ;
101
109
import org .junit .runners .JUnit4 ;
102
- import org .mockito .AdditionalAnswers ;
103
110
import org .mockito .ArgumentCaptor ;
111
+ import org .mockito .ArgumentMatcher ;
112
+ import org .mockito .Captor ;
104
113
import org .mockito .InOrder ;
105
114
import org .mockito .Mock ;
106
115
import org .mockito .junit .MockitoJUnit ;
@@ -124,6 +133,13 @@ public class CachingRlsLbClientTest {
124
133
private SocketAddress socketAddress ;
125
134
@ Mock
126
135
private MetricRecorder mockMetricRecorder ;
136
+ @ Mock
137
+ private BatchRecorder mockBatchRecorder ;
138
+ @ Mock
139
+ private Registration mockGaugeRegistration ;
140
+ @ Captor
141
+ private ArgumentCaptor <BatchCallback > gaugeBatchCallbackCaptor ;
142
+
127
143
128
144
private final SynchronizationContext syncContext =
129
145
new SynchronizationContext (new UncaughtExceptionHandler () {
@@ -145,7 +161,7 @@ public void uncaughtException(Thread t, Throwable e) {
145
161
private final ChildLoadBalancingPolicy childLbPolicy =
146
162
new ChildLoadBalancingPolicy ("target" , Collections .<String , Object >emptyMap (), lbProvider );
147
163
private final Helper helper =
148
- mock (Helper .class , AdditionalAnswers . delegatesTo (new FakeHelper ()));
164
+ mock (Helper .class , delegatesTo (new FakeHelper ()));
149
165
private final FakeThrottler fakeThrottler = new FakeThrottler ();
150
166
private final LbPolicyConfiguration lbPolicyConfiguration =
151
167
new LbPolicyConfiguration (ROUTE_LOOKUP_CONFIG , null , childLbPolicy );
@@ -168,6 +184,11 @@ private void setUpRlsLbClient() {
168
184
.build ();
169
185
}
170
186
187
+ @ Before
188
+ public void setUpMockMetricRecorder () {
189
+ when (mockMetricRecorder .registerBatchCallback (any (), any ())).thenReturn (mockGaugeRegistration );
190
+ }
191
+
171
192
@ After
172
193
public void tearDown () throws Exception {
173
194
rlsLbClient .close ();
@@ -636,6 +657,51 @@ private void setState(ChildPolicyWrapper policyWrapper, ConnectivityState newSta
636
657
policyWrapper .getHelper ().updateBalancingState (newState , policyWrapper .getPicker ());
637
658
}
638
659
660
+ @ Test
661
+ public void metricGauges () throws ExecutionException , InterruptedException , TimeoutException {
662
+ setUpRlsLbClient ();
663
+
664
+ verify (mockMetricRecorder ).registerBatchCallback (gaugeBatchCallbackCaptor .capture (),
665
+ any ());
666
+
667
+ BatchCallback gaugeBatchCallback = gaugeBatchCallbackCaptor .getValue ();
668
+
669
+ // Verify the correct cache gauge values when requested at this point.
670
+ InOrder inOrder = inOrder (mockBatchRecorder );
671
+ gaugeBatchCallback .accept (mockBatchRecorder );
672
+ inOrder .verify (mockBatchRecorder ).recordLongGauge (
673
+ argThat (new LongGaugeInstrumentArgumentMatcher ("grpc.lb.rls.cache_entries" )), eq (0L ),
674
+ any (), any ());
675
+ inOrder .verify (mockBatchRecorder )
676
+ .recordLongGauge (argThat (new LongGaugeInstrumentArgumentMatcher ("grpc.lb.rls.cache_size" )),
677
+ eq (0L ), any (), any ());
678
+
679
+ RouteLookupRequest routeLookupRequest = RouteLookupRequest .create (
680
+ ImmutableMap .of ("server" , "bigtable.googleapis.com" , "service-key" , "foo" , "method-key" ,
681
+ "bar" ));
682
+ rlsServerImpl .setLookupTable (ImmutableMap .of (routeLookupRequest ,
683
+ RouteLookupResponse .create (ImmutableList .of ("target" ), "header" )));
684
+
685
+ // Make a request that will populate the cache with an entry
686
+ getInSyncContext (routeLookupRequest );
687
+ fakeClock .forwardTime (SERVER_LATENCY_MILLIS , TimeUnit .MILLISECONDS );
688
+
689
+ // Gauge values should reflect the new cache entry.
690
+ gaugeBatchCallback .accept (mockBatchRecorder );
691
+ inOrder .verify (mockBatchRecorder ).recordLongGauge (
692
+ argThat (new LongGaugeInstrumentArgumentMatcher ("grpc.lb.rls.cache_entries" )), eq (1L ),
693
+ any (), any ());
694
+ inOrder .verify (mockBatchRecorder )
695
+ .recordLongGauge (argThat (new LongGaugeInstrumentArgumentMatcher ("grpc.lb.rls.cache_size" )),
696
+ eq (260L ), any (), any ());
697
+
698
+ inOrder .verifyNoMoreInteractions ();
699
+
700
+ // Shutdown
701
+ rlsLbClient .close ();
702
+ verify (mockGaugeRegistration ).close ();
703
+ }
704
+
639
705
private static RouteLookupConfig getRouteLookupConfig () {
640
706
return RouteLookupConfig .builder ()
641
707
.grpcKeybuilders (ImmutableList .of (
@@ -667,6 +733,21 @@ public long nextBackoffNanos() {
667
733
};
668
734
}
669
735
736
+ private static class LongGaugeInstrumentArgumentMatcher implements
737
+ ArgumentMatcher <LongGaugeMetricInstrument > {
738
+
739
+ private final String instrumentName ;
740
+
741
+ public LongGaugeInstrumentArgumentMatcher (String instrumentName ) {
742
+ this .instrumentName = instrumentName ;
743
+ }
744
+
745
+ @ Override
746
+ public boolean matches (LongGaugeMetricInstrument instrument ) {
747
+ return instrument .getName ().equals (instrumentName );
748
+ }
749
+ }
750
+
670
751
private static final class FakeBackoffProvider implements BackoffPolicy .Provider {
671
752
672
753
private BackoffPolicy nextPolicy = createBackoffPolicy (100 , TimeUnit .MILLISECONDS );
0 commit comments