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.avro;
19  
20  import static org.junit.Assert.assertEquals;
21  import static org.junit.Assert.assertFalse;
22  import static org.junit.Assert.assertTrue;
23  
24  import java.nio.ByteBuffer;
25  
26  import org.apache.avro.Schema;
27  import org.apache.avro.generic.GenericArray;
28  import org.apache.avro.generic.GenericData;
29  import org.apache.hadoop.hbase.HBaseTestingUtility;
30  import org.apache.hadoop.hbase.MediumTests;
31  import org.apache.hadoop.hbase.avro.generated.AColumn;
32  import org.apache.hadoop.hbase.avro.generated.AColumnValue;
33  import org.apache.hadoop.hbase.avro.generated.AFamilyDescriptor;
34  import org.apache.hadoop.hbase.avro.generated.AGet;
35  import org.apache.hadoop.hbase.avro.generated.APut;
36  import org.apache.hadoop.hbase.avro.generated.ATableDescriptor;
37  import org.apache.hadoop.hbase.util.Bytes;
38  import org.apache.hadoop.hbase.util.Threads;
39  import org.junit.After;
40  import org.junit.AfterClass;
41  import org.junit.Before;
42  import org.junit.BeforeClass;
43  import org.junit.Test;
44  import org.junit.experimental.categories.Category;
45  
46  /**
47   * Unit testing for AvroServer.HBaseImpl, a part of the
48   * org.apache.hadoop.hbase.avro package.
49   */
50  @Category(MediumTests.class)
51  public class TestAvroServer {
52    private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
53  
54    // Static names for tables, columns, rows, and values
55    // TODO(hammer): Better style to define these in test method?
56    private static ByteBuffer tableAname = ByteBuffer.wrap(Bytes.toBytes("tableA"));
57    private static ByteBuffer tableBname = ByteBuffer.wrap(Bytes.toBytes("tableB"));
58    private static ByteBuffer familyAname = ByteBuffer.wrap(Bytes.toBytes("FamilyA"));
59    private static ByteBuffer qualifierAname = ByteBuffer.wrap(Bytes.toBytes("QualifierA"));
60    private static ByteBuffer rowAname = ByteBuffer.wrap(Bytes.toBytes("RowA"));
61    private static ByteBuffer valueA = ByteBuffer.wrap(Bytes.toBytes("ValueA"));
62  
63    /**
64     * @throws java.lang.Exception
65     */
66    @BeforeClass
67    public static void setUpBeforeClass() throws Exception {
68      TEST_UTIL.startMiniCluster();
69    }
70  
71    /**
72     * @throws java.lang.Exception
73     */
74    @AfterClass
75    public static void tearDownAfterClass() throws Exception {
76      TEST_UTIL.shutdownMiniCluster();
77    }
78  
79    /**
80     * @throws java.lang.Exception
81     */
82    @Before
83    public void setUp() throws Exception {
84      // Nothing to do.
85    }
86  
87    /**
88     * @throws java.lang.Exception
89     */
90    @After
91    public void tearDown() throws Exception {
92      // Nothing to do.
93    }
94  
95    /**
96     * Tests for creating, enabling, disabling, modifying, and deleting tables.
97     *
98     * @throws Exception
99     */
100   @Test (timeout=300000)
101   public void testTableAdminAndMetadata() throws Exception {
102     AvroServer.HBaseImpl impl =
103       new AvroServer.HBaseImpl(TEST_UTIL.getConfiguration());
104 
105     assertEquals(impl.listTables().size(), 0);
106 
107     ATableDescriptor tableA = new ATableDescriptor();
108     tableA.name = tableAname;
109     impl.createTable(tableA);
110     assertEquals(impl.listTables().size(), 1);
111     assertTrue(impl.isTableEnabled(tableAname));
112     assertTrue(impl.tableExists(tableAname));
113 
114     ATableDescriptor tableB = new ATableDescriptor();
115     tableB.name = tableBname;
116     impl.createTable(tableB);
117     assertEquals(impl.listTables().size(), 2);
118 
119     impl.disableTable(tableBname);
120     assertFalse(impl.isTableEnabled(tableBname));
121 
122     impl.deleteTable(tableBname);
123     assertEquals(impl.listTables().size(), 1);
124 
125     impl.disableTable(tableAname);
126     assertFalse(impl.isTableEnabled(tableAname));
127 
128     long oldMaxFileSize = impl.describeTable(tableAname).maxFileSize;
129     tableA.maxFileSize = 123456L;
130     impl.modifyTable(tableAname, tableA);
131   
132     // It can take a while for the change to take effect.  Wait here a while.
133     while(impl.describeTable(tableAname).maxFileSize == oldMaxFileSize) {
134       Threads.sleep(100);
135     }
136 
137     assertTrue(impl.describeTable(tableAname).maxFileSize == 123456L);
138     assertEquals(123456L, (long) impl.describeTable(tableAname).maxFileSize);
139 /* DISABLED FOR NOW TILL WE HAVE BETTER DISABLE/ENABLE
140     impl.enableTable(tableAname);
141     assertTrue(impl.isTableEnabled(tableAname));
142     
143     impl.disableTable(tableAname);
144     */
145     impl.deleteTable(tableAname);
146   }
147 
148   /**
149    * Tests for creating, modifying, and deleting column families.
150    *
151    * @throws Exception
152    */
153   @Test
154   public void testFamilyAdminAndMetadata() throws Exception {
155     AvroServer.HBaseImpl impl =
156       new AvroServer.HBaseImpl(TEST_UTIL.getConfiguration());
157 
158     ATableDescriptor tableA = new ATableDescriptor();
159     tableA.name = tableAname;
160     AFamilyDescriptor familyA = new AFamilyDescriptor();
161     familyA.name = familyAname;
162     Schema familyArraySchema = Schema.createArray(AFamilyDescriptor.SCHEMA$);
163     GenericArray<AFamilyDescriptor> families = new GenericData.Array<AFamilyDescriptor>(1, familyArraySchema);
164     families.add(familyA);
165     tableA.families = families;
166     impl.createTable(tableA);
167     assertEquals(impl.describeTable(tableAname).families.size(), 1);
168 
169     impl.disableTable(tableAname);
170     assertFalse(impl.isTableEnabled(tableAname));
171 
172     familyA.maxVersions = 123456;
173     impl.modifyFamily(tableAname, familyAname, familyA);
174     assertEquals((int) impl.describeFamily(tableAname, familyAname).maxVersions, 123456);
175 
176     impl.deleteFamily(tableAname, familyAname);
177     assertEquals(impl.describeTable(tableAname).families.size(), 0);
178 
179     impl.deleteTable(tableAname);
180   }
181 
182   /**
183    * Tests for adding, reading, and deleting data.
184    *
185    * @throws Exception
186    */
187   @Test
188   public void testDML() throws Exception {
189     AvroServer.HBaseImpl impl =
190       new AvroServer.HBaseImpl(TEST_UTIL.getConfiguration());
191 
192     ATableDescriptor tableA = new ATableDescriptor();
193     tableA.name = tableAname;
194     AFamilyDescriptor familyA = new AFamilyDescriptor();
195     familyA.name = familyAname;
196     Schema familyArraySchema = Schema.createArray(AFamilyDescriptor.SCHEMA$);
197     GenericArray<AFamilyDescriptor> families = new GenericData.Array<AFamilyDescriptor>(1, familyArraySchema);
198     families.add(familyA);
199     tableA.families = families;
200     impl.createTable(tableA);
201     assertEquals(impl.describeTable(tableAname).families.size(), 1);
202 
203     AGet getA = new AGet();
204     getA.row = rowAname;
205     Schema columnsSchema = Schema.createArray(AColumn.SCHEMA$);
206     GenericArray<AColumn> columns = new GenericData.Array<AColumn>(1, columnsSchema);
207     AColumn column = new AColumn();
208     column.family = familyAname;
209     column.qualifier = qualifierAname;
210     columns.add(column);
211     getA.columns = columns;
212    
213     assertFalse(impl.exists(tableAname, getA));
214 
215     APut putA = new APut();
216     putA.row = rowAname;
217     Schema columnValuesSchema = Schema.createArray(AColumnValue.SCHEMA$);
218     GenericArray<AColumnValue> columnValues = new GenericData.Array<AColumnValue>(1, columnValuesSchema);
219     AColumnValue acv = new AColumnValue();
220     acv.family = familyAname;
221     acv.qualifier = qualifierAname;
222     acv.value = valueA;
223     columnValues.add(acv);
224     putA.columnValues = columnValues;
225 
226     impl.put(tableAname, putA);
227     assertTrue(impl.exists(tableAname, getA));
228 
229     assertEquals(impl.get(tableAname, getA).entries.size(), 1);
230 
231     impl.disableTable(tableAname);
232     impl.deleteTable(tableAname);
233   }
234 
235   @org.junit.Rule
236   public org.apache.hadoop.hbase.ResourceCheckerJUnitRule cu =
237     new org.apache.hadoop.hbase.ResourceCheckerJUnitRule();
238 }
239