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.codec; 019 020import static org.junit.jupiter.api.Assertions.assertEquals; 021import static org.junit.jupiter.api.Assertions.assertFalse; 022import static org.junit.jupiter.api.Assertions.assertTrue; 023 024import java.io.ByteArrayInputStream; 025import java.io.ByteArrayOutputStream; 026import java.io.DataInputStream; 027import java.io.DataOutputStream; 028import java.io.IOException; 029import org.apache.hadoop.hbase.KeyValue; 030import org.apache.hadoop.hbase.testclassification.MiscTests; 031import org.apache.hadoop.hbase.testclassification.SmallTests; 032import org.apache.hadoop.hbase.util.Bytes; 033import org.junit.jupiter.api.Tag; 034import org.junit.jupiter.api.Test; 035 036import org.apache.hbase.thirdparty.com.google.common.io.CountingInputStream; 037import org.apache.hbase.thirdparty.com.google.common.io.CountingOutputStream; 038 039@Tag(MiscTests.TAG) 040@Tag(SmallTests.TAG) 041public class TestKeyValueCodec { 042 043 @Test 044 public void testEmptyWorks() throws IOException { 045 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 046 CountingOutputStream cos = new CountingOutputStream(baos); 047 DataOutputStream dos = new DataOutputStream(cos); 048 KeyValueCodec kvc = new KeyValueCodec(); 049 Codec.Encoder encoder = kvc.getEncoder(dos); 050 encoder.flush(); 051 dos.close(); 052 long offset = cos.getCount(); 053 assertEquals(0, offset); 054 CountingInputStream cis = new CountingInputStream(new ByteArrayInputStream(baos.toByteArray())); 055 DataInputStream dis = new DataInputStream(cis); 056 Codec.Decoder decoder = kvc.getDecoder(dis); 057 assertFalse(decoder.advance()); 058 dis.close(); 059 assertEquals(0, cis.getCount()); 060 } 061 062 @Test 063 public void testOne() throws IOException { 064 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 065 CountingOutputStream cos = new CountingOutputStream(baos); 066 DataOutputStream dos = new DataOutputStream(cos); 067 KeyValueCodec kvc = new KeyValueCodec(); 068 Codec.Encoder encoder = kvc.getEncoder(dos); 069 final KeyValue kv = 070 new KeyValue(Bytes.toBytes("r"), Bytes.toBytes("f"), Bytes.toBytes("q"), Bytes.toBytes("v")); 071 final int length = kv.getLength() + Bytes.SIZEOF_INT; 072 encoder.write(kv); 073 encoder.flush(); 074 dos.close(); 075 long offset = cos.getCount(); 076 assertEquals(length, offset); 077 CountingInputStream cis = new CountingInputStream(new ByteArrayInputStream(baos.toByteArray())); 078 DataInputStream dis = new DataInputStream(cis); 079 Codec.Decoder decoder = kvc.getDecoder(dis); 080 assertTrue(decoder.advance()); // First read should pull in the KV 081 // Second read should trip over the end-of-stream marker and return false 082 assertFalse(decoder.advance()); 083 dis.close(); 084 assertEquals(length, cis.getCount()); 085 } 086 087 @Test 088 public void testThree() throws IOException { 089 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 090 CountingOutputStream cos = new CountingOutputStream(baos); 091 DataOutputStream dos = new DataOutputStream(cos); 092 KeyValueCodec kvc = new KeyValueCodec(); 093 Codec.Encoder encoder = kvc.getEncoder(dos); 094 final KeyValue kv1 = 095 new KeyValue(Bytes.toBytes("r"), Bytes.toBytes("f"), Bytes.toBytes("1"), Bytes.toBytes("1")); 096 final KeyValue kv2 = 097 new KeyValue(Bytes.toBytes("r"), Bytes.toBytes("f"), Bytes.toBytes("2"), Bytes.toBytes("2")); 098 final KeyValue kv3 = 099 new KeyValue(Bytes.toBytes("r"), Bytes.toBytes("f"), Bytes.toBytes("3"), Bytes.toBytes("3")); 100 final int length = kv1.getLength() + Bytes.SIZEOF_INT; 101 encoder.write(kv1); 102 encoder.write(kv2); 103 encoder.write(kv3); 104 encoder.flush(); 105 dos.close(); 106 long offset = cos.getCount(); 107 assertEquals(length * 3, offset); 108 CountingInputStream cis = new CountingInputStream(new ByteArrayInputStream(baos.toByteArray())); 109 DataInputStream dis = new DataInputStream(cis); 110 Codec.Decoder decoder = kvc.getDecoder(dis); 111 assertTrue(decoder.advance()); 112 KeyValue kv = (KeyValue) decoder.current(); 113 assertTrue(kv1.equals(kv)); 114 assertTrue(decoder.advance()); 115 kv = (KeyValue) decoder.current(); 116 assertTrue(kv2.equals(kv)); 117 assertTrue(decoder.advance()); 118 kv = (KeyValue) decoder.current(); 119 assertTrue(kv3.equals(kv)); 120 assertFalse(decoder.advance()); 121 dis.close(); 122 assertEquals((length * 3), cis.getCount()); 123 } 124}