View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.hbtop.screen.top;
19  
20  import static org.apache.hadoop.hbase.hbtop.Record.entry;
21  import static org.mockito.Mockito.any;
22  import static org.mockito.Mockito.argThat;
23  import static org.mockito.Mockito.inOrder;
24  import static org.mockito.Mockito.verify;
25  import static org.mockito.Mockito.when;
26  
27  import java.util.ArrayList;
28  import java.util.Arrays;
29  import java.util.List;
30  import org.apache.hadoop.hbase.hbtop.Record;
31  import org.apache.hadoop.hbase.hbtop.field.Field;
32  import org.apache.hadoop.hbase.hbtop.field.FieldInfo;
33  import org.apache.hadoop.hbase.hbtop.terminal.TerminalSize;
34  import org.apache.hadoop.hbase.testclassification.SmallTests;
35  import org.junit.Before;
36  import org.junit.Test;
37  import org.junit.experimental.categories.Category;
38  import org.junit.runner.RunWith;
39  import org.mockito.ArgumentMatcher;
40  import org.mockito.InOrder;
41  import org.mockito.Mock;
42  import org.mockito.runners.MockitoJUnitRunner;
43  
44  @Category(SmallTests.class)
45  @RunWith(MockitoJUnitRunner.class)
46  public class TestTopScreenPresenter {
47  
48    private static final List<FieldInfo> TEST_FIELD_INFOS = Arrays.asList(
49      new FieldInfo(Field.REGION, 10, true),
50      new FieldInfo(Field.REQUEST_COUNT_PER_SECOND, 10, true),
51      new FieldInfo(Field.LOCALITY, 10, true)
52    );
53  
54    private static final List<Record> TEST_RECORDS = Arrays.asList(
55      Record.ofEntries(
56        entry(Field.REGION, "region1"),
57        entry(Field.REQUEST_COUNT_PER_SECOND, 1L),
58        entry(Field.LOCALITY, 0.3f)),
59      Record.ofEntries(
60        entry(Field.REGION, "region2"),
61        entry(Field.REQUEST_COUNT_PER_SECOND, 2L),
62        entry(Field.LOCALITY, 0.2f)),
63      Record.ofEntries(
64        entry(Field.REGION, "region3"),
65        entry(Field.REQUEST_COUNT_PER_SECOND, 3L),
66        entry(Field.LOCALITY, 0.1f))
67    );
68  
69    private static final Summary TEST_SUMMARY = new Summary(
70      "00:00:01", "3.0.0-SNAPSHOT", "01234567-89ab-cdef-0123-456789abcdef",
71      3, 2, 1, 6, 1, 3.0, 300);
72  
73    @Mock
74    private TopScreenView topScreenView;
75  
76    @Mock
77    private TopScreenModel topScreenModel;
78  
79    private TopScreenPresenter topScreenPresenter;
80  
81    @Before
82    public void setup() {
83      when(topScreenView.getTerminalSize()).thenReturn(new TerminalSize(100, 100));
84      when(topScreenView.getPageSize()).thenReturn(100);
85  
86      when(topScreenModel.getFieldInfos()).thenReturn(TEST_FIELD_INFOS);
87  
88      List<Field> fields = new ArrayList<>();
89      for (FieldInfo fieldInfo : TEST_FIELD_INFOS) {
90        fields.add(fieldInfo.getField());
91      }
92      when(topScreenModel.getFields()).thenReturn(fields);
93  
94      when(topScreenModel.getRecords()).thenReturn(TEST_RECORDS);
95      when(topScreenModel.getSummary()).thenReturn(TEST_SUMMARY);
96  
97      topScreenPresenter = new TopScreenPresenter(topScreenView, 3000, topScreenModel,
98        null, Long.MAX_VALUE);
99    }
100 
101   @Test
102   public void testRefresh() {
103     topScreenPresenter.init();
104     topScreenPresenter.refresh(true);
105 
106     verify(topScreenView).showTopScreen(
107       argThat(new ArgumentMatcher<Summary>() {
108         @Override
109         public boolean matches(Object argument) {
110           return assertSummary((Summary) argument);
111         }
112       }), argThat(new ArgumentMatcher<List<Header>>() {
113         @Override
114         @SuppressWarnings("unchecked")
115         public boolean matches(Object argument) {
116           return assertHeaders((List<Header>) argument);
117         }
118       }), argThat(new ArgumentMatcher<List<Record>>() {
119         @Override
120         @SuppressWarnings("unchecked")
121         public boolean matches(Object argument) {
122           return assertRecords((List<Record>) argument);
123         }
124       }), argThat(new ArgumentMatcher<Record>() {
125         @Override
126         public boolean matches(Object argument) {
127           return assertSelectedRecord((Record) argument, 0);
128         }
129       }));
130   }
131 
132   @Test
133   public void testVerticalScrolling() {
134     topScreenPresenter.init();
135     topScreenPresenter.refresh(true);
136 
137     topScreenPresenter.arrowDown();
138     topScreenPresenter.arrowDown();
139     topScreenPresenter.arrowDown();
140 
141     topScreenPresenter.arrowDown();
142     topScreenPresenter.arrowDown();
143     topScreenPresenter.arrowDown();
144 
145     topScreenPresenter.arrowUp();
146     topScreenPresenter.arrowUp();
147     topScreenPresenter.arrowUp();
148 
149     topScreenPresenter.pageDown();
150     topScreenPresenter.pageDown();
151 
152     topScreenPresenter.pageUp();
153     topScreenPresenter.pageUp();
154 
155     InOrder inOrder = inOrder(topScreenView);
156     verifyVerticalScrolling(inOrder, 0);
157 
158     verifyVerticalScrolling(inOrder, 1);
159     verifyVerticalScrolling(inOrder, 2);
160     verifyVerticalScrolling(inOrder, 2);
161 
162     verifyVerticalScrolling(inOrder, 1);
163     verifyVerticalScrolling(inOrder, 0);
164     verifyVerticalScrolling(inOrder, 0);
165 
166     verifyVerticalScrolling(inOrder, 2);
167     verifyVerticalScrolling(inOrder, 2);
168 
169     verifyVerticalScrolling(inOrder, 0);
170     verifyVerticalScrolling(inOrder, 0);
171   }
172 
173   @SuppressWarnings("unchecked")
174   private void verifyVerticalScrolling(InOrder inOrder, final int expectedSelectedRecodeIndex) {
175     inOrder.verify(topScreenView).showTopScreen(any(Summary.class), any(List.class),
176       any(List.class), argThat(new ArgumentMatcher<Record>() {
177         @Override
178         public boolean matches(Object argument) {
179           return assertSelectedRecord((Record) argument, expectedSelectedRecodeIndex);
180         }
181       })
182     );
183   }
184 
185   @Test
186   public void testHorizontalScrolling() {
187     topScreenPresenter.init();
188     topScreenPresenter.refresh(true);
189 
190     topScreenPresenter.arrowRight();
191     topScreenPresenter.arrowRight();
192     topScreenPresenter.arrowRight();
193 
194     topScreenPresenter.arrowLeft();
195     topScreenPresenter.arrowLeft();
196     topScreenPresenter.arrowLeft();
197 
198     topScreenPresenter.end();
199     topScreenPresenter.end();
200 
201     topScreenPresenter.home();
202     topScreenPresenter.home();
203 
204     InOrder inOrder = inOrder(topScreenView);
205     verifyHorizontalScrolling(inOrder, 3);
206 
207     verifyHorizontalScrolling(inOrder, 2);
208     verifyHorizontalScrolling(inOrder, 1);
209     verifyHorizontalScrolling(inOrder, 1);
210 
211     verifyHorizontalScrolling(inOrder, 2);
212     verifyHorizontalScrolling(inOrder, 3);
213     verifyHorizontalScrolling(inOrder, 3);
214 
215     verifyHorizontalScrolling(inOrder, 1);
216     verifyHorizontalScrolling(inOrder, 1);
217 
218     verifyHorizontalScrolling(inOrder, 3);
219     verifyHorizontalScrolling(inOrder, 3);
220   }
221 
222   @SuppressWarnings("unchecked")
223   private void verifyHorizontalScrolling(InOrder inOrder, final int expectedHeaderCount) {
224     inOrder.verify(topScreenView).showTopScreen(any(Summary.class),
225       argThat(new ArgumentMatcher<List<Header>>() {
226         @Override
227         public boolean matches(Object argument) {
228           List<Header> headers = (List<Header>) argument;
229           return headers.size() == expectedHeaderCount;
230         }
231       }), any(List.class), any(Record.class));
232   }
233 
234   private boolean assertSummary(Summary actual) {
235     return actual.getCurrentTime().equals(TEST_SUMMARY.getCurrentTime())
236       && actual.getVersion().equals(TEST_SUMMARY.getVersion())
237       && actual.getClusterId().equals(TEST_SUMMARY.getClusterId())
238       && actual.getServers() == TEST_SUMMARY.getServers()
239       && actual.getLiveServers() == TEST_SUMMARY.getLiveServers()
240       && actual.getDeadServers() == TEST_SUMMARY.getDeadServers()
241       && actual.getRegionCount() == TEST_SUMMARY.getRegionCount()
242       && actual.getRitCount() == TEST_SUMMARY.getRitCount()
243       && actual.getAverageLoad() == TEST_SUMMARY.getAverageLoad()
244       && actual.getAggregateRequestPerSecond() == TEST_SUMMARY.getAggregateRequestPerSecond();
245   }
246 
247   private boolean assertHeaders(List<Header> actual) {
248     List<Header> expected = new ArrayList<>();
249     for (FieldInfo fieldInfo : TEST_FIELD_INFOS) {
250       expected.add(new Header(fieldInfo.getField(), fieldInfo.getDefaultLength()));
251     }
252 
253     if (actual.size() != expected.size()) {
254       return false;
255     }
256 
257     for (int i = 0; i < actual.size(); i++) {
258       if (actual.get(i).getField() != expected.get(i).getField()) {
259         return false;
260       }
261       if (actual.get(i).getLength() != expected.get(i).getLength()) {
262         return false;
263       }
264     }
265 
266     return true;
267   }
268 
269   private boolean assertRecords(List<Record> actual) {
270     if (actual.size() != TEST_RECORDS.size()) {
271       return false;
272     }
273 
274     for (int i = 0; i < actual.size(); i++) {
275       if (!assertRecord(actual.get(i), TEST_RECORDS.get(i))) {
276         return false;
277       }
278     }
279 
280     return true;
281   }
282 
283   private boolean assertSelectedRecord(Record actual, int expectedSelectedRecodeIndex) {
284     return assertRecord(actual, TEST_RECORDS.get(expectedSelectedRecodeIndex));
285   }
286 
287   private boolean assertRecord(Record actual, Record expected) {
288     return actual.get(Field.REGION).equals(expected.get(Field.REGION)) && actual
289       .get(Field.REQUEST_COUNT_PER_SECOND).equals(expected.get(Field.REQUEST_COUNT_PER_SECOND))
290       && actual.get(Field.LOCALITY).equals(expected.get(Field.LOCALITY));
291   }
292 }