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.ipc;
019
020import static org.junit.jupiter.api.Assertions.assertEquals;
021import static org.junit.jupiter.api.Assertions.assertTrue;
022
023import java.io.IOException;
024import java.util.ArrayList;
025import java.util.List;
026import org.apache.hadoop.hbase.Cell;
027import org.apache.hadoop.hbase.CellScanner;
028import org.apache.hadoop.hbase.ExtendedCell;
029import org.apache.hadoop.hbase.ExtendedCellScannable;
030import org.apache.hadoop.hbase.ExtendedCellScanner;
031import org.apache.hadoop.hbase.testclassification.ClientTests;
032import org.apache.hadoop.hbase.testclassification.SmallTests;
033import org.apache.hadoop.hbase.util.Bytes;
034import org.junit.jupiter.api.Tag;
035import org.junit.jupiter.api.Test;
036
037@Tag(ClientTests.TAG)
038@Tag(SmallTests.TAG)
039public class TestHBaseRpcControllerImpl {
040
041  @Test
042  public void testListOfCellScannerables() throws IOException {
043    final int count = 10;
044    List<ExtendedCellScannable> cells = new ArrayList<>(count);
045
046    for (int i = 0; i < count; i++) {
047      cells.add(createCell(i));
048    }
049    HBaseRpcController controller = new HBaseRpcControllerImpl(null, cells);
050    CellScanner cellScanner = controller.cellScanner();
051    int index = 0;
052    for (; cellScanner.advance(); index++) {
053      Cell cell = cellScanner.current();
054      byte[] indexBytes = Bytes.toBytes(index);
055      assertTrue(Bytes.equals(indexBytes, 0, indexBytes.length, cell.getValueArray(),
056        cell.getValueOffset(), cell.getValueLength()), "" + index);
057    }
058    assertEquals(count, index);
059  }
060
061  /**
062   * @param index the index of the cell to use as its value
063   * @return A faked out 'Cell' that does nothing but return index as its value
064   */
065  static ExtendedCellScannable createCell(final int index) {
066    return new ExtendedCellScannable() {
067      @Override
068      public ExtendedCellScanner cellScanner() {
069        return new ExtendedCellScanner() {
070          @Override
071          public ExtendedCell current() {
072            // Fake out a Cell. All this Cell has is a value that is an int in size and equal
073            // to the above 'index' param serialized as an int.
074            return new ExtendedCell() {
075              @Override
076              public long heapSize() {
077                return 0;
078              }
079
080              private final int i = index;
081
082              @Override
083              public byte[] getRowArray() {
084                return null;
085              }
086
087              @Override
088              public int getRowOffset() {
089                return 0;
090              }
091
092              @Override
093              public short getRowLength() {
094                return 0;
095              }
096
097              @Override
098              public byte[] getFamilyArray() {
099                return null;
100              }
101
102              @Override
103              public int getFamilyOffset() {
104                return 0;
105              }
106
107              @Override
108              public byte getFamilyLength() {
109                return 0;
110              }
111
112              @Override
113              public byte[] getQualifierArray() {
114                return null;
115              }
116
117              @Override
118              public int getQualifierOffset() {
119                return 0;
120              }
121
122              @Override
123              public int getQualifierLength() {
124                return 0;
125              }
126
127              @Override
128              public long getTimestamp() {
129                return 0;
130              }
131
132              @Override
133              public byte getTypeByte() {
134                return 0;
135              }
136
137              @Override
138              public long getSequenceId() {
139                return 0;
140              }
141
142              @Override
143              public byte[] getValueArray() {
144                return Bytes.toBytes(this.i);
145              }
146
147              @Override
148              public int getValueOffset() {
149                return 0;
150              }
151
152              @Override
153              public int getValueLength() {
154                return Bytes.SIZEOF_INT;
155              }
156
157              @Override
158              public int getSerializedSize() {
159                return 0;
160              }
161
162              @Override
163              public int getTagsOffset() {
164                return 0;
165              }
166
167              @Override
168              public int getTagsLength() {
169                return 0;
170              }
171
172              @Override
173              public byte[] getTagsArray() {
174                return null;
175              }
176
177              @Override
178              public Type getType() {
179                return null;
180              }
181
182              @Override
183              public void setSequenceId(long seqId) throws IOException {
184              }
185
186              @Override
187              public void setTimestamp(long ts) throws IOException {
188              }
189
190              @Override
191              public void setTimestamp(byte[] ts) throws IOException {
192              }
193            };
194          }
195
196          private boolean hasCell = true;
197
198          @Override
199          public boolean advance() {
200            // We have one Cell only so return true first time then false ever after.
201            if (!hasCell) {
202              return hasCell;
203            }
204
205            hasCell = false;
206            return true;
207          }
208        };
209      }
210    };
211  }
212}