/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.hadoop.hbase; import static org.junit.Assert.*; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.NoSuchElementException; import java.util.Queue; import java.util.LinkedList; import org.apache.hadoop.fs.FSDataInputStream; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.hbase.PerformanceEvaluation.RandomReadTest; import org.apache.hadoop.hbase.PerformanceEvaluation.TestOptions; import org.apache.hadoop.hbase.testclassification.MiscTests; import org.apache.hadoop.hbase.testclassification.SmallTests; import org.codehaus.jackson.JsonGenerationException; import org.codehaus.jackson.map.JsonMappingException; import org.codehaus.jackson.map.ObjectMapper; import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import com.codahale.metrics.Histogram; import com.codahale.metrics.Snapshot; import com.codahale.metrics.UniformReservoir; @Category({MiscTests.class, SmallTests.class}) public class TestPerformanceEvaluation { private static final HBaseTestingUtility HTU = new HBaseTestingUtility(); @Test public void testSerialization() throws JsonGenerationException, JsonMappingException, IOException { PerformanceEvaluation.TestOptions options = new PerformanceEvaluation.TestOptions(); assertTrue(!options.isAutoFlush()); options.setAutoFlush(true); ObjectMapper mapper = new ObjectMapper(); String optionsString = mapper.writeValueAsString(options); PerformanceEvaluation.TestOptions optionsDeserialized = mapper.readValue(optionsString, PerformanceEvaluation.TestOptions.class); assertTrue(optionsDeserialized.isAutoFlush()); } /** * Exercise the mr spec writing. Simple assertions to make sure it is basically working. * @throws IOException */ @Ignore @Test public void testWriteInputFile() throws IOException { TestOptions opts = new PerformanceEvaluation.TestOptions(); final int clients = 10; opts.setNumClientThreads(clients); opts.setPerClientRunRows(10); Path dir = PerformanceEvaluation.writeInputFile(HTU.getConfiguration(), opts, HTU.getDataTestDir()); FileSystem fs = FileSystem.get(HTU.getConfiguration()); Path p = new Path(dir, PerformanceEvaluation.JOB_INPUT_FILENAME); long len = fs.getFileStatus(p).getLen(); assertTrue(len > 0); byte [] content = new byte[(int)len]; FSDataInputStream dis = fs.open(p); try { dis.readFully(content); BufferedReader br = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(content))); int count = 0; while (br.readLine() != null) { count++; } assertEquals(clients, count); } finally { dis.close(); } } @Test public void testSizeCalculation() { TestOptions opts = new PerformanceEvaluation.TestOptions(); opts = PerformanceEvaluation.calculateRowsAndSize(opts); int rows = opts.getPerClientRunRows(); // Default row count final int defaultPerClientRunRows = 1024 * 1024; assertEquals(defaultPerClientRunRows, rows); // If size is 2G, then twice the row count. opts.setSize(2.0f); opts = PerformanceEvaluation.calculateRowsAndSize(opts); assertEquals(defaultPerClientRunRows * 2, opts.getPerClientRunRows()); // If two clients, then they get half the rows each. opts.setNumClientThreads(2); opts = PerformanceEvaluation.calculateRowsAndSize(opts); assertEquals(defaultPerClientRunRows, opts.getPerClientRunRows()); // What if valueSize is 'random'? Then half of the valueSize so twice the rows. opts.valueRandom = true; opts = PerformanceEvaluation.calculateRowsAndSize(opts); assertEquals(defaultPerClientRunRows * 2, opts.getPerClientRunRows()); } @Test public void testZipfian() throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { TestOptions opts = new PerformanceEvaluation.TestOptions(); opts.setValueZipf(true); final int valueSize = 1024; opts.setValueSize(valueSize); RandomReadTest rrt = new RandomReadTest(null, opts, null); Constructor<?> ctor = Histogram.class.getDeclaredConstructor(com.codahale.metrics.Reservoir.class); ctor.setAccessible(true); Histogram histogram = (Histogram)ctor.newInstance(new UniformReservoir(1024 * 500)); for (int i = 0; i < 100; i++) { histogram.update(rrt.getValueLength(null)); } Snapshot snapshot = histogram.getSnapshot(); double stddev = snapshot.getStdDev(); assertTrue(stddev != 0 && stddev != 1.0); assertTrue(snapshot.getStdDev() != 0); double median = snapshot.getMedian(); assertTrue(median != 0 && median != 1 && median != valueSize); } @Test public void testParseOptsWithThreads() { Queue<String> opts = new LinkedList<>(); String cmdName = "sequentialWrite"; int threads = 1; opts.offer(cmdName); opts.offer(String.valueOf(threads)); PerformanceEvaluation.TestOptions options = PerformanceEvaluation.parseOpts(opts); assertNotNull(options); assertNotNull(options.getCmdName()); assertEquals(cmdName, options.getCmdName()); assertEquals(threads, options.getNumClientThreads()); } @Test public void testParseOptsWrongThreads() { Queue<String> opts = new LinkedList<>(); String cmdName = "sequentialWrite"; opts.offer(cmdName); opts.offer("qq"); try { PerformanceEvaluation.parseOpts(opts); } catch (IllegalArgumentException e) { System.out.println(e.getMessage()); assertEquals("Command " + cmdName + " does not have threads number", e.getMessage()); assertTrue(e.getCause() instanceof NumberFormatException); } } @Test public void testParseOptsNoThreads() { Queue<String> opts = new LinkedList<>(); String cmdName = "sequentialWrite"; try { PerformanceEvaluation.parseOpts(opts); } catch (IllegalArgumentException e) { System.out.println(e.getMessage()); assertEquals("Command " + cmdName + " does not have threads number", e.getMessage()); assertTrue(e.getCause() instanceof NoSuchElementException); } } }