001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.hbtop.screen.top; 019 020import static org.apache.hadoop.hbase.hbtop.Record.entry; 021import static org.mockito.ArgumentMatchers.any; 022import static org.mockito.ArgumentMatchers.argThat; 023import static org.mockito.Mockito.inOrder; 024import static org.mockito.Mockito.verify; 025import static org.mockito.Mockito.when; 026 027import java.util.Arrays; 028import java.util.List; 029import java.util.stream.Collectors; 030import org.apache.hadoop.hbase.HBaseClassTestRule; 031import org.apache.hadoop.hbase.hbtop.Record; 032import org.apache.hadoop.hbase.hbtop.field.Field; 033import org.apache.hadoop.hbase.hbtop.field.FieldInfo; 034import org.apache.hadoop.hbase.hbtop.terminal.TerminalSize; 035import org.apache.hadoop.hbase.testclassification.SmallTests; 036import org.junit.Before; 037import org.junit.ClassRule; 038import org.junit.Test; 039import org.junit.experimental.categories.Category; 040import org.junit.runner.RunWith; 041import org.mockito.InOrder; 042import org.mockito.Mock; 043import org.mockito.runners.MockitoJUnitRunner; 044 045@Category(SmallTests.class) 046@RunWith(MockitoJUnitRunner.class) 047public class TestTopScreenPresenter { 048 049 @ClassRule 050 public static final HBaseClassTestRule CLASS_RULE = 051 HBaseClassTestRule.forClass(TestTopScreenPresenter.class); 052 053 private static final List<FieldInfo> TEST_FIELD_INFOS = Arrays.asList( 054 new FieldInfo(Field.REGION, 10, true), new FieldInfo(Field.REQUEST_COUNT_PER_SECOND, 10, true), 055 new FieldInfo(Field.LOCALITY, 10, true)); 056 057 private static final List<Record> TEST_RECORDS = Arrays.asList( 058 Record.ofEntries(entry(Field.REGION, "region1"), entry(Field.REQUEST_COUNT_PER_SECOND, 1L), 059 entry(Field.LOCALITY, 0.3f)), 060 Record.ofEntries(entry(Field.REGION, "region2"), entry(Field.REQUEST_COUNT_PER_SECOND, 2L), 061 entry(Field.LOCALITY, 0.2f)), 062 Record.ofEntries(entry(Field.REGION, "region3"), entry(Field.REQUEST_COUNT_PER_SECOND, 3L), 063 entry(Field.LOCALITY, 0.1f))); 064 065 private static final Summary TEST_SUMMARY = new Summary("00:00:01", "3.0.0-SNAPSHOT", 066 "01234567-89ab-cdef-0123-456789abcdef", 3, 2, 1, 6, 1, 3.0, 300); 067 068 @Mock 069 private TopScreenView topScreenView; 070 071 @Mock 072 private TopScreenModel topScreenModel; 073 074 private TopScreenPresenter topScreenPresenter; 075 076 @Before 077 public void setup() { 078 when(topScreenView.getTerminalSize()).thenReturn(new TerminalSize(100, 100)); 079 when(topScreenView.getPageSize()).thenReturn(100); 080 081 when(topScreenModel.getFieldInfos()).thenReturn(TEST_FIELD_INFOS); 082 when(topScreenModel.getFields()) 083 .thenReturn(TEST_FIELD_INFOS.stream().map(FieldInfo::getField).collect(Collectors.toList())); 084 when(topScreenModel.getRecords()).thenReturn(TEST_RECORDS); 085 when(topScreenModel.getSummary()).thenReturn(TEST_SUMMARY); 086 087 topScreenPresenter = 088 new TopScreenPresenter(topScreenView, 3000, topScreenModel, null, Long.MAX_VALUE); 089 } 090 091 @Test 092 public void testRefresh() { 093 topScreenPresenter.init(); 094 topScreenPresenter.refresh(true); 095 096 verify(topScreenView).showTopScreen(argThat(this::assertSummary), argThat(this::assertHeaders), 097 argThat(this::assertRecords), 098 argThat(selectedRecord -> assertSelectedRecord(selectedRecord, 0))); 099 } 100 101 @Test 102 public void testVerticalScrolling() { 103 topScreenPresenter.init(); 104 topScreenPresenter.refresh(true); 105 106 topScreenPresenter.arrowDown(); 107 topScreenPresenter.arrowDown(); 108 topScreenPresenter.arrowDown(); 109 110 topScreenPresenter.arrowDown(); 111 topScreenPresenter.arrowDown(); 112 topScreenPresenter.arrowDown(); 113 114 topScreenPresenter.arrowUp(); 115 topScreenPresenter.arrowUp(); 116 topScreenPresenter.arrowUp(); 117 118 topScreenPresenter.pageDown(); 119 topScreenPresenter.pageDown(); 120 121 topScreenPresenter.pageUp(); 122 topScreenPresenter.pageUp(); 123 124 InOrder inOrder = inOrder(topScreenView); 125 verifyVerticalScrolling(inOrder, 0); 126 127 verifyVerticalScrolling(inOrder, 1); 128 verifyVerticalScrolling(inOrder, 2); 129 verifyVerticalScrolling(inOrder, 2); 130 131 verifyVerticalScrolling(inOrder, 1); 132 verifyVerticalScrolling(inOrder, 0); 133 verifyVerticalScrolling(inOrder, 0); 134 135 verifyVerticalScrolling(inOrder, 2); 136 verifyVerticalScrolling(inOrder, 2); 137 138 verifyVerticalScrolling(inOrder, 0); 139 verifyVerticalScrolling(inOrder, 0); 140 } 141 142 private void verifyVerticalScrolling(InOrder inOrder, int expectedSelectedRecodeIndex) { 143 inOrder.verify(topScreenView).showTopScreen(any(), any(), any(), 144 argThat(selectedRecord -> assertSelectedRecord(selectedRecord, expectedSelectedRecodeIndex))); 145 } 146 147 @Test 148 public void testHorizontalScrolling() { 149 topScreenPresenter.init(); 150 topScreenPresenter.refresh(true); 151 152 topScreenPresenter.arrowRight(); 153 topScreenPresenter.arrowRight(); 154 topScreenPresenter.arrowRight(); 155 156 topScreenPresenter.arrowLeft(); 157 topScreenPresenter.arrowLeft(); 158 topScreenPresenter.arrowLeft(); 159 160 topScreenPresenter.end(); 161 topScreenPresenter.end(); 162 163 topScreenPresenter.home(); 164 topScreenPresenter.home(); 165 166 InOrder inOrder = inOrder(topScreenView); 167 verifyHorizontalScrolling(inOrder, 3); 168 169 verifyHorizontalScrolling(inOrder, 2); 170 verifyHorizontalScrolling(inOrder, 1); 171 verifyHorizontalScrolling(inOrder, 1); 172 173 verifyHorizontalScrolling(inOrder, 2); 174 verifyHorizontalScrolling(inOrder, 3); 175 verifyHorizontalScrolling(inOrder, 3); 176 177 verifyHorizontalScrolling(inOrder, 1); 178 verifyHorizontalScrolling(inOrder, 1); 179 180 verifyHorizontalScrolling(inOrder, 3); 181 verifyHorizontalScrolling(inOrder, 3); 182 } 183 184 private void verifyHorizontalScrolling(InOrder inOrder, int expectedHeaderCount) { 185 inOrder.verify(topScreenView).showTopScreen(any(), 186 argThat(headers -> headers.size() == expectedHeaderCount), any(), any()); 187 } 188 189 private boolean assertSummary(Summary actual) { 190 return actual.getCurrentTime().equals(TEST_SUMMARY.getCurrentTime()) 191 && actual.getVersion().equals(TEST_SUMMARY.getVersion()) 192 && actual.getClusterId().equals(TEST_SUMMARY.getClusterId()) 193 && actual.getServers() == TEST_SUMMARY.getServers() 194 && actual.getLiveServers() == TEST_SUMMARY.getLiveServers() 195 && actual.getDeadServers() == TEST_SUMMARY.getDeadServers() 196 && actual.getRegionCount() == TEST_SUMMARY.getRegionCount() 197 && actual.getRitCount() == TEST_SUMMARY.getRitCount() 198 && actual.getAverageLoad() == TEST_SUMMARY.getAverageLoad() 199 && actual.getAggregateRequestPerSecond() == TEST_SUMMARY.getAggregateRequestPerSecond(); 200 } 201 202 private boolean assertHeaders(List<Header> actual) { 203 List<Header> expected = TEST_FIELD_INFOS.stream() 204 .map(fi -> new Header(fi.getField(), fi.getDefaultLength())).collect(Collectors.toList()); 205 206 if (actual.size() != expected.size()) { 207 return false; 208 } 209 210 for (int i = 0; i < actual.size(); i++) { 211 if (actual.get(i).getField() != expected.get(i).getField()) { 212 return false; 213 } 214 if (actual.get(i).getLength() != expected.get(i).getLength()) { 215 return false; 216 } 217 } 218 219 return true; 220 } 221 222 private boolean assertRecords(List<Record> actual) { 223 if (actual.size() != TEST_RECORDS.size()) { 224 return false; 225 } 226 227 for (int i = 0; i < actual.size(); i++) { 228 if (!assertRecord(actual.get(i), TEST_RECORDS.get(i))) { 229 return false; 230 } 231 } 232 233 return true; 234 } 235 236 private boolean assertSelectedRecord(Record actual, int expectedSelectedRecodeIndex) { 237 return assertRecord(actual, TEST_RECORDS.get(expectedSelectedRecodeIndex)); 238 } 239 240 private boolean assertRecord(Record actual, Record expected) { 241 return actual.get(Field.REGION).equals(expected.get(Field.REGION)) 242 && actual.get(Field.REQUEST_COUNT_PER_SECOND) 243 .equals(expected.get(Field.REQUEST_COUNT_PER_SECOND)) 244 && actual.get(Field.LOCALITY).equals(expected.get(Field.LOCALITY)); 245 } 246}