1   /*
2    * Copyright 2011 The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  package org.apache.hadoop.hbase.coprocessor;
21  
22  import static org.junit.Assert.assertEquals;
23  
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  import org.apache.hadoop.conf.Configuration;
27  import org.apache.hadoop.hbase.HBaseTestingUtility;
28  import org.apache.hadoop.hbase.HConstants;
29  import org.apache.hadoop.hbase.MiniHBaseCluster;
30  import org.apache.hadoop.hbase.client.HTable;
31  import org.apache.hadoop.hbase.client.Put;
32  import org.apache.hadoop.hbase.client.Scan;
33  import org.apache.hadoop.hbase.client.coprocessor.AggregationClient;
34  import org.apache.hadoop.hbase.client.coprocessor.LongColumnInterpreter;
35  import org.apache.hadoop.hbase.filter.Filter;
36  import org.apache.hadoop.hbase.filter.PrefixFilter;
37  import org.apache.hadoop.hbase.util.Bytes;
38  import org.junit.AfterClass;
39  import org.junit.BeforeClass;
40  import org.junit.Test;
41  
42  /**
43   * A test class to cover aggregate functions, that can be implemented using
44   * Coprocessors.
45   */
46  public class TestAggregateProtocol {
47    protected static Log myLog = LogFactory.getLog(TestAggregateProtocol.class);
48  
49    /**
50     * Creating the test infrastructure.
51     */
52    private static final byte[] TEST_TABLE = Bytes.toBytes("TestTable");
53    private static final byte[] TEST_FAMILY = Bytes.toBytes("TestFamily");
54    private static final byte[] TEST_QUALIFIER = Bytes.toBytes("TestQualifier");
55    private static final byte[] TEST_MULTI_CQ = Bytes.toBytes("TestMultiCQ");
56  
57    private static byte[] ROW = Bytes.toBytes("testRow");
58    private static final int ROWSIZE = 20;
59    private static final int rowSeperator1 = 5;
60    private static final int rowSeperator2 = 12;
61    private static byte[][] ROWS = makeN(ROW, ROWSIZE);
62  
63    private static HBaseTestingUtility util = new HBaseTestingUtility();
64    private static MiniHBaseCluster cluster = null;
65    private static Configuration conf = util.getConfiguration();
66  
67    /**
68     * A set up method to start the test cluster. AggregateProtocolImpl is
69     * registered and will be loaded during region startup.
70     * @throws Exception
71     */
72    @BeforeClass
73    public static void setupBeforeClass() throws Exception {
74  
75      conf.set(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY,
76          "org.apache.hadoop.hbase.coprocessor.AggregateImplementation");
77  
78      util.startMiniCluster(2);
79      cluster = util.getMiniHBaseCluster();
80      HTable table = util.createTable(TEST_TABLE, TEST_FAMILY);
81      util.createMultiRegions(util.getConfiguration(), table, TEST_FAMILY,
82          new byte[][] { HConstants.EMPTY_BYTE_ARRAY, ROWS[rowSeperator1],
83              ROWS[rowSeperator2] });
84      /**
85       * The testtable has one CQ which is always populated and one variable CQ
86       * for each row rowkey1: CF:CQ CF:CQ1 rowKey2: CF:CQ CF:CQ2
87       */
88      for (int i = 0; i < ROWSIZE; i++) {
89        Put put = new Put(ROWS[i]);
90        put.setWriteToWAL(false);
91        Long l = new Long(i);
92        put.add(TEST_FAMILY, TEST_QUALIFIER, Bytes.toBytes(l));
93        table.put(put);
94        Put p2 = new Put(ROWS[i]);
95        put.setWriteToWAL(false);
96        p2.add(TEST_FAMILY, Bytes.add(TEST_MULTI_CQ, Bytes.toBytes(l)), Bytes
97            .toBytes(l * 10));
98        table.put(p2);
99      }
100   }
101 
102   /**
103    * Shutting down the cluster
104    * @throws Exception
105    */
106   @AfterClass
107   public static void tearDownAfterClass() throws Exception {
108     util.shutdownMiniCluster();
109   }
110 
111   /**
112    * an infrastructure method to prepare rows for the testtable.
113    * @param base
114    * @param n
115    * @return
116    */
117   private static byte[][] makeN(byte[] base, int n) {
118     byte[][] ret = new byte[n][];
119     for (int i = 0; i < n; i++) {
120       ret[i] = Bytes.add(base, Bytes.toBytes(i));
121     }
122     return ret;
123   }
124 
125   /**
126    * **************************** ROW COUNT Test cases *******************
127    */
128 
129   /**
130    * This will test rowcount with a valid range, i.e., a subset of rows. It will
131    * be the most common use case.
132    * @throws Throwable
133    */
134   @Test
135   public void testRowCountWithValidRange() throws Throwable {
136     AggregationClient aClient = new AggregationClient(conf);
137     Scan scan = new Scan();
138     scan.addColumn(TEST_FAMILY, TEST_QUALIFIER);
139     scan.setStartRow(ROWS[2]);
140     scan.setStopRow(ROWS[14]);
141     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
142     long rowCount = aClient.rowCount(TEST_TABLE, ci, scan);
143     assertEquals(12, rowCount);
144   }
145 
146   /**
147    * This will test the row count on the entire table. Startrow and endrow will
148    * be null.
149    * @throws Throwable
150    */
151   @Test
152   public void testRowCountAllTable() throws Throwable {
153     AggregationClient aClient = new AggregationClient(conf);
154     Scan scan = new Scan();
155     scan.addColumn(TEST_FAMILY, TEST_QUALIFIER);
156     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
157     long rowCount = aClient.rowCount(TEST_TABLE, ci,
158         scan);
159     assertEquals(ROWSIZE, rowCount);
160   }
161 
162   /**
163    * This will test the row count with startrow > endrow. The result should be
164    * -1.
165    * @throws Throwable
166    */
167   @Test
168   public void testRowCountWithInvalidRange1() {
169     AggregationClient aClient = new AggregationClient(conf);
170     Scan scan = new Scan();
171     scan.addColumn(TEST_FAMILY, TEST_QUALIFIER);
172     scan.setStartRow(ROWS[5]);
173     scan.setStopRow(ROWS[2]);
174 
175     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
176     long rowCount = -1;
177     try {
178       rowCount = aClient.rowCount(TEST_TABLE, ci, scan);
179     } catch (Throwable e) {
180       myLog.error("Exception thrown in the invalidRange method"
181           + e.getStackTrace());
182     }
183     assertEquals(-1, rowCount);
184   }
185 
186   /**
187    * This will test the row count with startrow = endrow and they will be
188    * non-null. The result should be 0, as it assumes a non-get query.
189    * @throws Throwable
190    */
191   @Test
192   public void testRowCountWithInvalidRange2() {
193     AggregationClient aClient = new AggregationClient(conf);
194     Scan scan = new Scan();
195     scan.addColumn(TEST_FAMILY, TEST_QUALIFIER);
196     scan.setStartRow(ROWS[5]);
197     scan.setStopRow(ROWS[5]);
198 
199     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
200     long rowCount = -1;
201     try {
202       rowCount = aClient.rowCount(TEST_TABLE, ci, scan);
203     } catch (Throwable e) {
204       rowCount = 0;
205     }
206     assertEquals(0, rowCount);
207   }
208 
209   /**
210    * This should return a 0
211    */
212   @Test
213   public void testRowCountWithNullCF() {
214     AggregationClient aClient = new AggregationClient(conf);
215     Scan scan = new Scan();
216     scan.setStartRow(ROWS[5]);
217     scan.setStopRow(ROWS[15]);
218     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
219     long rowCount = -1;
220     try {
221       rowCount = aClient.rowCount(TEST_TABLE, ci, scan);
222     } catch (Throwable e) {
223        rowCount = 0;
224     }
225     assertEquals(0, rowCount);
226   }
227 
228   @Test
229   public void testRowCountWithNullCQ() throws Throwable {
230     AggregationClient aClient = new AggregationClient(conf);
231     Scan scan = new Scan();
232     scan.addFamily(TEST_FAMILY);
233     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
234     long rowCount = aClient.rowCount(TEST_TABLE, ci,
235         scan);
236     assertEquals(20, rowCount);
237   }
238 
239   @Test
240   public void testRowCountWithPrefixFilter() throws Throwable {
241     AggregationClient aClient = new AggregationClient(conf);
242     Scan scan = new Scan();
243     scan.addColumn(TEST_FAMILY, TEST_QUALIFIER);
244     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
245     Filter f = new PrefixFilter(Bytes.toBytes("foo:bar"));
246     scan.setFilter(f);
247     long rowCount = aClient.rowCount(TEST_TABLE, ci,
248         scan);
249     assertEquals(0, rowCount);
250   }
251 
252   /**
253    * ***************Test cases for Maximum *******************
254    */
255 
256   /**
257    * give max for the entire table.
258    * @throws Throwable
259    */
260   @Test
261   public void testMaxWithValidRange() throws Throwable {
262     AggregationClient aClient = new AggregationClient(conf);
263     Scan scan = new Scan();
264     scan.addColumn(TEST_FAMILY, TEST_QUALIFIER);
265     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
266     long maximum = aClient.max(TEST_TABLE, ci, scan);
267     assertEquals(19, maximum);
268   }
269 
270   /**
271    * @throws Throwable
272    */
273   @Test
274   public void testMaxWithValidRange2() throws Throwable {
275     AggregationClient aClient = new AggregationClient(conf);
276     Scan scan = new Scan();
277     scan.addColumn(TEST_FAMILY, TEST_QUALIFIER);
278     scan.setStartRow(ROWS[5]);
279     scan.setStopRow(ROWS[15]);
280     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
281     long max = aClient.max(TEST_TABLE, ci, scan);
282     assertEquals(14, max);
283   }
284 
285   @Test
286   public void testMaxWithValidRangeWithNoCQ() throws Throwable {
287     AggregationClient aClient = new AggregationClient(conf);
288     Scan scan = new Scan();
289     scan.addFamily(TEST_FAMILY);
290     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
291     long maximum = aClient.max(TEST_TABLE, ci, scan);
292     assertEquals(190, maximum);
293   }
294 
295   @Test
296   public void testMaxWithValidRange2WithNoCQ() throws Throwable {
297     AggregationClient aClient = new AggregationClient(conf);
298     Scan scan = new Scan();
299     scan.addFamily(TEST_FAMILY);
300     scan.setStartRow(ROWS[6]);
301     scan.setStopRow(ROWS[7]);
302     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
303     long max = aClient.max(TEST_TABLE, ci, scan);
304     assertEquals(60, max);
305   }
306 
307   @Test
308   public void testMaxWithValidRangeWithNullCF() {
309     AggregationClient aClient = new AggregationClient(conf);
310     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
311     Scan scan = new Scan();
312     Long max = null;
313     try {
314       max = aClient.max(TEST_TABLE, ci, scan);
315     } catch (Throwable e) {
316       max = null;
317     }
318     assertEquals(null, max);// CP will throw an IOException about the
319     // null column family, and max will be set to 0
320   }
321 
322   @Test
323   public void testMaxWithInvalidRange() {
324     AggregationClient aClient = new AggregationClient(conf);
325     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
326     Scan scan = new Scan();
327     scan.setStartRow(ROWS[4]);
328     scan.setStopRow(ROWS[2]);
329     scan.addColumn(TEST_FAMILY, TEST_QUALIFIER);
330     long max = Long.MIN_VALUE;
331     try {
332       max = aClient.max(TEST_TABLE, ci, scan);
333     } catch (Throwable e) {
334       max = 0;
335     }
336     assertEquals(0, max);// control should go to the catch block
337   }
338 
339   @Test
340   public void testMaxWithInvalidRange2() throws Throwable {
341     long max = Long.MIN_VALUE;
342     Scan scan = new Scan();
343     scan.addColumn(TEST_FAMILY, TEST_QUALIFIER);
344     scan.setStartRow(ROWS[4]);
345     scan.setStopRow(ROWS[4]);
346     try {
347       AggregationClient aClient = new AggregationClient(conf);
348       final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
349       max = aClient.max(TEST_TABLE, ci, scan);
350     } catch (Exception e) {
351       max = 0;
352     }
353     assertEquals(0, max);// control should go to the catch block
354   }
355 
356   @Test
357   public void testMaxWithFilter() throws Throwable {
358     Long max = 0l;
359     AggregationClient aClient = new AggregationClient(conf);
360     Scan scan = new Scan();
361     scan.addColumn(TEST_FAMILY, TEST_QUALIFIER);
362     Filter f = new PrefixFilter(Bytes.toBytes("foo:bar"));
363     scan.setFilter(f);
364     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
365     max = aClient.max(TEST_TABLE, ci, scan);
366     assertEquals(null, max);
367   }
368 
369   /**
370    * **************************Test cases for Minimum ***********************
371    */
372 
373   /**
374    * @throws Throwable
375    */
376   @Test
377   public void testMinWithValidRange() throws Throwable {
378     AggregationClient aClient = new AggregationClient(conf);
379     Scan scan = new Scan();
380     scan.addColumn(TEST_FAMILY, TEST_QUALIFIER);
381     scan.setStartRow(HConstants.EMPTY_START_ROW);
382     scan.setStopRow(HConstants.EMPTY_END_ROW);
383     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
384     Long min = aClient.min(TEST_TABLE, ci,
385         scan);
386     assertEquals(0l, min.longValue());
387   }
388 
389   /**
390    * @throws Throwable
391    */
392   @Test
393   public void testMinWithValidRange2() throws Throwable {
394     AggregationClient aClient = new AggregationClient(conf);
395     Scan scan = new Scan();
396     scan.addColumn(TEST_FAMILY, TEST_QUALIFIER);
397     scan.setStartRow(ROWS[5]);
398     scan.setStopRow(ROWS[15]);
399     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
400     long min = aClient.min(TEST_TABLE, ci, scan);
401     assertEquals(5, min);
402   }
403 
404   @Test
405   public void testMinWithValidRangeWithNoCQ() throws Throwable {
406     AggregationClient aClient = new AggregationClient(conf);
407     Scan scan = new Scan();
408     scan.addFamily(TEST_FAMILY);
409     scan.setStartRow(HConstants.EMPTY_START_ROW);
410     scan.setStopRow(HConstants.EMPTY_END_ROW);
411     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
412     long min = aClient.min(TEST_TABLE, ci,
413         scan);
414     assertEquals(0, min);
415   }
416 
417   @Test
418   public void testMinWithValidRange2WithNoCQ() throws Throwable {
419     AggregationClient aClient = new AggregationClient(conf);
420     Scan scan = new Scan();
421     scan.addFamily(TEST_FAMILY);
422     scan.setStartRow(ROWS[6]);
423     scan.setStopRow(ROWS[7]);
424     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
425     long min = aClient.min(TEST_TABLE, ci, scan);
426     assertEquals(6, min);
427   }
428 
429   @Test
430   public void testMinWithValidRangeWithNullCF() {
431     AggregationClient aClient = new AggregationClient(conf);
432     Scan scan = new Scan();
433     scan.setStartRow(ROWS[5]);
434     scan.setStopRow(ROWS[15]);
435     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
436     Long min = null;
437     try {
438       min = aClient.min(TEST_TABLE, ci, scan);
439     } catch (Throwable e) {
440     }
441     assertEquals(null, min);// CP will throw an IOException about the
442     // null column family, and max will be set to 0
443   }
444 
445   @Test
446   public void testMinWithInvalidRange() {
447     AggregationClient aClient = new AggregationClient(conf);
448     Long min = null;
449     Scan scan = new Scan();
450     scan.addFamily(TEST_FAMILY);
451     scan.setStartRow(ROWS[4]);
452     scan.setStopRow(ROWS[2]);
453     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
454     try {
455       min = aClient.min(TEST_TABLE, ci, scan);
456     } catch (Throwable e) {
457     }
458     assertEquals(null, min);// control should go to the catch block
459   }
460 
461   @Test
462   public void testMinWithInvalidRange2() {
463     AggregationClient aClient = new AggregationClient(conf);
464     Scan scan = new Scan();
465     scan.addFamily(TEST_FAMILY);
466     scan.setStartRow(ROWS[6]);
467     scan.setStopRow(ROWS[6]);
468     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
469     Long min = null;
470     try {
471       min = aClient.min(TEST_TABLE, ci, scan);
472     } catch (Throwable e) {
473     }
474     assertEquals(null, min);// control should go to the catch block
475   }
476 
477   @Test
478   public void testMinWithFilter() throws Throwable {
479     AggregationClient aClient = new AggregationClient(conf);
480     Scan scan = new Scan();
481     scan.addColumn(TEST_FAMILY, TEST_QUALIFIER);
482     Filter f = new PrefixFilter(Bytes.toBytes("foo:bar"));
483     scan.setFilter(f);
484     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
485     Long min = null;
486     min = aClient.min(TEST_TABLE, ci, scan);
487     assertEquals(null, min);
488   }
489 
490   /**
491    * *************** Test cases for Sum *********************
492    */
493   /**
494    * @throws Throwable
495    */
496   @Test
497   public void testSumWithValidRange() throws Throwable {
498     AggregationClient aClient = new AggregationClient(conf);
499     Scan scan = new Scan();
500     scan.addColumn(TEST_FAMILY,TEST_QUALIFIER);
501     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
502     long sum = aClient.sum(TEST_TABLE, ci,
503         scan);
504     assertEquals(190, sum);
505   }
506 
507   /**
508    * @throws Throwable
509    */
510   @Test
511   public void testSumWithValidRange2() throws Throwable {
512     AggregationClient aClient = new AggregationClient(conf);
513     Scan scan = new Scan();
514     scan.addColumn(TEST_FAMILY,TEST_QUALIFIER);
515     scan.setStartRow(ROWS[5]);
516     scan.setStopRow(ROWS[15]);
517     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
518     long sum = aClient.sum(TEST_TABLE, ci, scan);
519     assertEquals(95, sum);
520   }
521 
522   @Test
523   public void testSumWithValidRangeWithNoCQ() throws Throwable {
524     AggregationClient aClient = new AggregationClient(conf);
525     Scan scan = new Scan();
526     scan.addFamily(TEST_FAMILY);
527     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
528     long sum = aClient.sum(TEST_TABLE, ci,
529         scan);
530     assertEquals(190 + 1900, sum);
531   }
532 
533   @Test
534   public void testSumWithValidRange2WithNoCQ() throws Throwable {
535     AggregationClient aClient = new AggregationClient(conf);
536     Scan scan = new Scan();
537     scan.addFamily(TEST_FAMILY);
538     scan.setStartRow(ROWS[6]);
539     scan.setStopRow(ROWS[7]);
540     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
541     long sum = aClient.sum(TEST_TABLE, ci, scan);
542     assertEquals(6 + 60, sum);
543   }
544 
545   @Test
546   public void testSumWithValidRangeWithNullCF() {
547     AggregationClient aClient = new AggregationClient(conf);
548     Scan scan = new Scan();
549     scan.setStartRow(ROWS[6]);
550     scan.setStopRow(ROWS[7]);
551     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
552     Long sum = null;
553     try {
554       sum = aClient.sum(TEST_TABLE, ci, scan);
555     } catch (Throwable e) {
556     }
557     assertEquals(null, sum);// CP will throw an IOException about the
558     // null column family, and max will be set to 0
559   }
560 
561   @Test
562   public void testSumWithInvalidRange() {
563     AggregationClient aClient = new AggregationClient(conf);
564     Scan scan = new Scan();
565     scan.addFamily(TEST_FAMILY);
566     scan.setStartRow(ROWS[6]);
567     scan.setStopRow(ROWS[2]);
568     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
569     Long sum = null;
570     try {
571       sum = aClient.sum(TEST_TABLE, ci, scan);
572     } catch (Throwable e) {
573     }
574     assertEquals(null, sum);// control should go to the catch block
575   }
576 
577   @Test
578   public void testSumWithFilter() throws Throwable {
579     AggregationClient aClient = new AggregationClient(conf);
580     Filter f = new PrefixFilter(Bytes.toBytes("foo:bar"));
581     Scan scan = new Scan();
582     scan.addFamily(TEST_FAMILY);
583     scan.setFilter(f);
584     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
585     Long sum = null;
586     sum = aClient.sum(TEST_TABLE, ci, scan);
587     assertEquals(null, sum);
588   }
589 
590   /**
591    * ****************************** Test Cases for Avg **************
592    */
593   /**
594    * @throws Throwable
595    */
596   @Test
597   public void testAvgWithValidRange() throws Throwable {
598     AggregationClient aClient = new AggregationClient(conf);
599     Scan scan = new Scan();
600     scan.addColumn(TEST_FAMILY,TEST_QUALIFIER);
601     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
602     double avg = aClient.avg(TEST_TABLE, ci,
603         scan);
604     assertEquals(9.5, avg, 0);
605   }
606 
607   /**
608    * @throws Throwable
609    */
610   @Test
611   public void testAvgWithValidRange2() throws Throwable {
612     AggregationClient aClient = new AggregationClient(conf);
613     Scan scan = new Scan();
614     scan.addColumn(TEST_FAMILY,TEST_QUALIFIER);
615     scan.setStartRow(ROWS[5]);
616     scan.setStopRow(ROWS[15]);
617     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
618     double avg = aClient.avg(TEST_TABLE, ci, scan);
619     assertEquals(9.5, avg, 0);
620   }
621 
622   @Test
623   public void testAvgWithValidRangeWithNoCQ() throws Throwable {
624     AggregationClient aClient = new AggregationClient(conf);
625     Scan scan = new Scan();
626     scan.addFamily(TEST_FAMILY);
627     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
628     double avg = aClient.avg(TEST_TABLE, ci,
629         scan);
630     assertEquals(104.5, avg, 0);
631   }
632 
633   @Test
634   public void testAvgWithValidRange2WithNoCQ() throws Throwable {
635     AggregationClient aClient = new AggregationClient(conf);
636     Scan scan = new Scan();
637     scan.addFamily(TEST_FAMILY);
638     scan.setStartRow(ROWS[6]);
639     scan.setStopRow(ROWS[7]);
640     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
641     double avg = aClient.avg(TEST_TABLE, ci, scan);
642     assertEquals(6 + 60, avg, 0);
643   }
644 
645   @Test
646   public void testAvgWithValidRangeWithNullCF() {
647     AggregationClient aClient = new AggregationClient(conf);
648     Scan scan = new Scan();
649     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
650     Double avg = null;
651     try {
652       avg = aClient.avg(TEST_TABLE, ci, scan);
653     } catch (Throwable e) {
654     }
655     assertEquals(null, avg);// CP will throw an IOException about the
656     // null column family, and max will be set to 0
657   }
658 
659   @Test
660   public void testAvgWithInvalidRange() {
661     AggregationClient aClient = new AggregationClient(conf);
662     Scan scan = new Scan();
663     scan.addColumn(TEST_FAMILY,TEST_QUALIFIER);
664     scan.setStartRow(ROWS[5]);
665     scan.setStopRow(ROWS[1]);
666     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
667     Double avg = null;
668     try {
669       avg = aClient.avg(TEST_TABLE, ci, scan);
670     } catch (Throwable e) {
671     }
672     assertEquals(null, avg);// control should go to the catch block
673   }
674 
675   @Test
676   public void testAvgWithFilter() throws Throwable {
677     AggregationClient aClient = new AggregationClient(conf);
678     Scan scan = new Scan();
679     scan.addColumn(TEST_FAMILY,TEST_QUALIFIER);
680     Filter f = new PrefixFilter(Bytes.toBytes("foo:bar"));
681     scan.setFilter(f);
682     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
683     Double avg = null;
684     avg = aClient.avg(TEST_TABLE, ci, scan);
685     assertEquals(Double.NaN, avg, 0);
686   }
687 
688   /**
689    * ****************** Test cases for STD **********************
690    */
691   /**
692    * @throws Throwable
693    */
694   @Test
695   public void testStdWithValidRange() throws Throwable {
696     AggregationClient aClient = new AggregationClient(conf);
697     Scan scan = new Scan();
698     scan.addColumn(TEST_FAMILY,TEST_QUALIFIER);
699     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
700     double std = aClient.std(TEST_TABLE, ci,
701         scan);
702     assertEquals(5.766, std, 0.05d);
703   }
704 
705   /**
706    * @throws Throwable
707    */
708   @Test
709   public void testStdWithValidRange2() throws Throwable {
710     AggregationClient aClient = new AggregationClient(conf);
711     Scan scan = new Scan();
712     scan.addColumn(TEST_FAMILY,TEST_QUALIFIER);
713     scan.setStartRow(ROWS[5]);
714     scan.setStopRow(ROWS[15]);
715     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
716     double std = aClient.std(TEST_TABLE, ci, scan);
717     assertEquals(2.87, std, 0.05d);
718   }
719 
720   @Test
721   public void testStdWithValidRangeWithNoCQ() throws Throwable {
722     AggregationClient aClient = new AggregationClient(conf);
723     Scan scan = new Scan();
724     scan.addFamily(TEST_FAMILY);
725     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
726     double std = aClient.std(TEST_TABLE, ci,
727         scan);
728     assertEquals(63.42, std, 0.05d);
729   }
730 
731   @Test
732   public void testStdWithValidRange2WithNoCQ() throws Throwable {
733     AggregationClient aClient = new AggregationClient(conf);
734     Scan scan = new Scan();
735     scan.addFamily(TEST_FAMILY);
736     scan.setStartRow(ROWS[6]);
737     scan.setStopRow(ROWS[7]);
738     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
739     double std = aClient.std(TEST_TABLE, ci, scan);
740     assertEquals(0, std, 0);
741   }
742 
743   @Test
744   public void testStdWithValidRangeWithNullCF() {
745     AggregationClient aClient = new AggregationClient(conf);
746     Scan scan = new Scan();
747     scan.setStartRow(ROWS[6]);
748     scan.setStopRow(ROWS[17]);
749     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
750     Double std = null;
751     try {
752       std = aClient.std(TEST_TABLE, ci, scan);
753     } catch (Throwable e) {
754     }
755     assertEquals(null, std);// CP will throw an IOException about the
756     // null column family, and max will be set to 0
757   }
758 
759   @Test
760   public void testStdWithInvalidRange() {
761     AggregationClient aClient = new AggregationClient(conf);
762     Scan scan = new Scan();
763     scan.addFamily(TEST_FAMILY);
764     scan.setStartRow(ROWS[6]);
765     scan.setStopRow(ROWS[1]);
766     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
767     Double std = null;
768     try {
769       std = aClient.std(TEST_TABLE, ci, scan);
770     } catch (Throwable e) {
771     }
772     assertEquals(null, std);// control should go to the catch block
773   }
774 
775   @Test
776   public void testStdWithFilter() throws Throwable {
777     AggregationClient aClient = new AggregationClient(conf);
778     Filter f = new PrefixFilter(Bytes.toBytes("foo:bar"));
779     Scan scan = new Scan();
780     scan.addFamily(TEST_FAMILY);
781     scan.setFilter(f);
782     final ColumnInterpreter<Long, Long> ci = new LongColumnInterpreter();
783     Double std = null;
784     std = aClient.std(TEST_TABLE, ci, scan);
785     assertEquals(Double.NaN, std, 0);
786   }
787 }