Sementara adopsi Apache HBase untuk membangun aplikasi pengguna akhir telah meroket, banyak dari aplikasi tersebut (dan banyak aplikasi pada umumnya) belum teruji dengan baik. Dalam postingan ini, Anda akan mempelajari beberapa cara agar pengujian ini dapat dilakukan dengan mudah.
Kami akan mulai dengan pengujian unit melalui JUnit, kemudian beralih menggunakan Mockito dan Apache MRUnit, dan kemudian menggunakan kluster mini HBase untuk pengujian integrasi. (Basis kode HBase sendiri diuji melalui mini-cluster, jadi mengapa tidak memanfaatkannya untuk aplikasi upstream juga?)
Sebagai dasar untuk diskusi, mari kita asumsikan Anda memiliki objek akses data HBase (DAO) yang melakukan penyisipan berikut ke dalam HBase. Logikanya bisa lebih rumit tentu saja, tetapi demi contoh, ini berhasil.
public class MyHBaseDAO { public static void insertRecord(tabel HTableInterface, HBaseTestObj obj) throws Exception { Put put =createPut(obj); tabel.put(menempatkan); } private static Put createPut(HBaseTestObj obj) { Put put =new Put(Bytes.toBytes(obj.getRowKey())); put.add(Bytes.toBytes("CF"), Bytes.toBytes("CQ-1"), Bytes.toBytes(obj.getData1())); put.add(Bytes.toBytes("CF"), Bytes.toBytes("CQ-2"), Bytes.toBytes(obj.getData2())); kembali menempatkan; }}
HBaseTestObj adalah objek data dasar dengan getter dan setter untuk rowkey, data1, dan data2.
insertRecord melakukan penyisipan ke tabel HBase terhadap keluarga kolom CF, dengan CQ-1 dan CQ-2 sebagai kualifikasi. Metode createPut cukup mengisi sebuah Put dan mengembalikannya ke metode pemanggilan.
Menggunakan JUnit
JUnit, yang saat ini dikenal oleh sebagian besar pengembang Java, mudah diterapkan ke banyak aplikasi HBase. Pertama, tambahkan ketergantungan ke pom Anda:
junit junit 4.11 test
Sekarang, di dalam kelas tes:
kelas publik TestMyHbaseDAOData { @Test public void testCreatePut() melempar Pengecualian { HBaseTestObj obj =new HBaseTestObj(); obj.setRowKey("ROWKEY-1"); obj.setData1("DATA-1"); obj.setData2("DATA-2"); Masukan put =MyHBaseDAO.createPut(obj); assertEquals(obj.getRowKey(), Bytes.toString(put.getRow())); assertEquals(obj.getData1(), Bytes.toString(put.get(Bytes.toBytes("CF"), Bytes.toBytes("CQ-1")).get(0).getValue())); assertEquals(obj.getData2(), Bytes.toString(put.get(Bytes.toBytes("CF"), Bytes.toBytes("CQ-2")).get(0).getValue())); } }
Apa yang Anda lakukan di sini adalah untuk memastikan bahwa metode createPut Anda membuat, mengisi, dan mengembalikan objek Put dengan nilai yang diharapkan.
Menggunakan Mockito
Jadi bagaimana Anda melakukan pengujian unit metode insertRecord di atas? Salah satu pendekatan yang sangat efektif adalah melakukannya dengan Mockito.
Pertama, tambahkan Mockito sebagai ketergantungan pada pom Anda:
org.mockito mockito-all 1.9.5 test
Kemudian, di kelas tes:
@RunWith(MockitoJUnitRunner.class)kelas publik TestMyHBaseDAO{ @Mock tabel HTableInterface pribadi; @Mock pribadi HTablePool hTablePool; @Captor private ArgumentCaptor putCaptor; @Test public void testInsertRecord() melempar Pengecualian { //mengembalikan tabel tiruan saat getTable dipanggil when(hTablePool.getTable("tablename")).thenReturn(table); //membuat objek uji dan melakukan panggilan ke DAO yang memerlukan pengujian HBaseTestObj obj =new HBaseTestObj(); obj.setRowKey("ROWKEY-1"); obj.setData1("DATA-1"); obj.setData2("DATA-2"); MyHBaseDAO.insertRecord(tabel, obj); verifikasi(tabel).put(putCaptor.capture()); Masukan put =putCaptor.getValue(); assertEquals(Bytes.toString(put.getRow()), obj.getRowKey()); menegaskan(put.has(Bytes.toBytes("CF"), Bytes.toBytes("CQ-1"))); menegaskan(put.has(Bytes.toBytes("CF"), Bytes.toBytes("CQ-2"))); assertEquals(Bytes.toString(put.get(Bytes.toBytes("CF"),Bytes.toBytes("CQ-1")).get(0).getValue()), "DATA-1"); assertEquals(Bytes.toString(put.get(Bytes.toBytes("CF"),Bytes.toBytes("CQ-2")).get(0).getValue()), "DATA-2"); }}
Di sini Anda telah mengisi HBaseTestObj dengan "ROWKEY-1", "DATA-1", "DATA-2" sebagai nilai. Anda kemudian menggunakan tabel tiruan dan DAO untuk memasukkan catatan. Anda menangkap Put yang akan dimasukkan DAO dan memverifikasi bahwa rowkey, data1, dan data2 adalah seperti yang Anda harapkan.
Kuncinya di sini adalah mengelola kumpulan htable dan pembuatan instance htable di luar DAO. Ini memungkinkan Anda untuk mengejeknya dengan bersih dan menguji Put seperti yang ditunjukkan di atas. Demikian pula, Anda sekarang dapat memperluas ke semua operasi lain seperti Dapatkan, Pindai, Hapus, dan seterusnya.
Menggunakan MRUnit
Dengan tercakupnya pengujian unit akses data reguler, mari beralih ke tugas MapReduce yang bertentangan dengan tabel HBase.
Menguji pekerjaan MR yang bertentangan dengan HBase semudah menguji pekerjaan MapReduce biasa. MRUnit membuatnya sangat mudah untuk menguji pekerjaan MapReduce termasuk yang HBase.
Bayangkan Anda memiliki pekerjaan MR yang menulis ke tabel HBase, "MyTest", yang memiliki satu keluarga kolom, "CF". Peredam pekerjaan seperti itu bisa terlihat seperti:
public class MyReducer memperluas TableReducer{ public static final byte[] CF ="CF".getBytes(); byte akhir public static[] QUALIFIER ="CQ-1".getBytes(); public void reduce(Text key, Iterable values, Context context) throws IOException, InterruptedException { //sekelompok pemrosesan untuk mengekstrak data yang akan dimasukkan, dalam kasus kami, katakanlah kami hanya //menambahkan semua catatan yang kami terima dari mapper untuk //key ini dan masukkan satu record ke HBase StringBuffer data =new StringBuffer(); Put put =new Put(Bytes.toBytes(key.toString())); for (Teks val :nilai) { data =data.append(val); } put.add(CF, QUALIFIER, Bytes.toBytes(data.toString())); //menulis ke HBase context.write(new ImmutableBytesWritable(Bytes.toBytes(key.toString())), put); } }
Sekarang bagaimana Anda melakukan pengujian unit peredam di atas di MRUnit? Pertama, tambahkan MRUnit sebagai dependensi ke pom Anda.
org.apache.mrunit mrunit 1.0.0 test
Kemudian, di dalam kelas pengujian, gunakan ReduceDriver yang disediakan MRUnit seperti di bawah ini:
public class MyReducerTest { ReduceDriverreduceDriver; byte[] CF ="CF".getBytes(); byte[] KUALIFIKASI ="CQ-1".getBytes(); @Before public void setUp() { MyReducer reducer =new MyReducer(); reduceDriver =ReduceDriver.newReduceDriver(peredam); } @Test public void testHBaseInsert() throws IOException { String strKey ="RowKey-1", strValue ="DATA", strValue1 ="DATA1", strValue2 ="DATA2"; Daftar daftar =new ArrayList (); list.add(Teks baru(strValue)); list.add(Teks baru(strValue1)); list.add(Teks baru(strValue2)); //karena dalam kasus kita semua yang dilakukan peredam adalah menambahkan catatan yang mapper //mengirimnya, kita harus mendapatkan yang berikut ini kembali String ekspektasiOutput =strValue + strValue1 + strValue2; //Setup Input, meniru apa yang mapper akan lulus //ke peredam dan menjalankan tes reduceDriver.withInput(new Text(strKey), list); //jalankan peredam dan dapatkan outputnya List > result =reduceDriver.run(); //ekstrak kunci dari hasil dan verifikasi assertEquals(Bytes.toString(result.get(0).getFirst().get()), strKey); //ekstrak nilai untuk CF/QUALIFIER dan verifikasi Masukan a =(Put)result.get(0).getSecond(); String c =Bytes.toString(a.get(CF, QUALIFIER).get(0).getValue()); assertEquals(expectedOutput,c ); }}
Pada dasarnya, setelah banyak pemrosesan di MyReducer, Anda memverifikasi bahwa:
- Hasilnya sesuai dengan yang Anda harapkan.
- Put yang disisipkan di HBase memiliki “RowKey-1” sebagai kunci baris.
- “DATADATA1DATA2” adalah nilai untuk kelompok kolom CF dan kualifikasi kolom CQ.
Anda juga dapat menguji Pemeta yang mendapatkan data dari HBase dengan cara yang sama menggunakan MapperDriver, atau menguji tugas MR yang membaca dari HBase, memproses data, dan menulis ke HDFS.
Menggunakan HBase Mini-cluster
Sekarang kita akan melihat bagaimana melakukan pengujian integrasi. HBase dikirimkan dengan HBaseTestingUtility, yang membuat pengujian integrasi penulisan dengan kluster mini HBase menjadi mudah. Untuk menarik pustaka yang benar, dependensi berikut diperlukan di pom Anda:
org.apache.hadoop hadoop-common 2.0.0-cdh4.2.0 test-jar test org.apache.hbase hbase 0.94.2-cdh4.2.0 test-jar test org.apache.hadoop hadoop-hdfs 2.0.0-cdh4.2.0 test-jar test org.apache.hadoop hadoop-hdfs 2.0.0-cdh4.2.0 test
Sekarang, mari kita lihat cara menjalankan pengujian integrasi untuk sisipan MyDAO yang dijelaskan dalam pendahuluan:
public class MyHBaseIntegrationTest {utilitas HBaseTestingUtility statis pribadi;byte[] CF ="CF".getBytes();byte[] QUALIFIER ="CQ-1".getBytes();@Beforepublic void setup() melempar Exception { utilitas =baru HBaseTestingUtility(); utility.startMiniCluster();}@Test public void testInsert() throws Exception { HTableInterface table =utility.createTable(Bytes.toBytes("MyTest"), Bytes.toBytes("CF")); HBaseTestObj obj =HBaseTestObj baru(); obj.setRowKey("ROWKEY-1"); obj.setData1("DATA-1"); obj.setData2("DATA-2"); MyHBaseDAO.insertRecord(tabel, obj); Dapatkan get1 =Get baru(Bytes.toBytes(obj.getRowKey())); get1.addColumn(CF, CQ1); Hasil result1 =table.get(get1); assertEquals(Bytes.toString(result1.getRow()), obj.getRowKey()); assertEquals(Bytes.toString(result1.value()), obj.getData1()); Dapatkan get2 =Get baru(Bytes.toBytes(obj.getRowKey())); get2.addColumn(CF, CQ2); Hasil result2 =table.get(get2); assertEquals(Bytes.toString(result2.getRow()), obj.getRowKey()); assertEquals(Bytes.toString(result2.value()), obj.getData2()); }}
Di sini Anda membuat mini-cluster HBase dan memulainya. Anda kemudian membuat tabel yang disebut "MyTest" dengan satu keluarga kolom, "CF". Anda memasukkan catatan menggunakan DAO yang perlu Anda uji, melakukan Dapatkan dari tabel yang sama, dan memverifikasi bahwa DAO memasukkan catatan dengan benar.
Hal yang sama dapat dilakukan untuk kasus penggunaan yang jauh lebih rumit bersama dengan pekerjaan MR seperti yang ditunjukkan di atas. Anda juga dapat mengakses mini-cluster HDFS dan ZooKeeper yang dibuat saat membuat HBase, menjalankan tugas MR, mengeluarkannya ke HBase, dan memverifikasi catatan yang dimasukkan.
Hanya peringatan singkat:memulai mini-cluster membutuhkan waktu 20 hingga 30 detik dan tidak dapat dilakukan di Windows tanpa Cygwin. Namun, karena hanya dijalankan secara berkala, waktu pengoperasian yang lebih lama dapat diterima.
Anda dapat menemukan kode contoh untuk contoh di atas di https://github.com/sitaula/HBaseTest. Selamat menguji!