HBASE-26312 Shell scan fails with timestamp (#3734)
[hbase.git] / dev-support / hbase_nightly_pseudo-distributed-test.sh
blob5241206df11f5419716d77c3543f3385df0f9e5d
1 #!/usr/bin/env bash
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
10 # http://www.apache.org/licenses/LICENSE-2.0
12 # Unless required by applicable law or agreed to in writing,
13 # software distributed under the License is distributed on an
14 # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 # KIND, either express or implied. See the License for the
16 # specific language governing permissions and limitations
17 # under the License.
19 set -e
20 function usage {
21 echo "Usage: ${0} [options] /path/to/component/bin-install /path/to/hadoop/executable /path/to/share/hadoop/yarn/timelineservice /path/to/hadoop/hadoop-yarn-server-tests-tests.jar /path/to/hadoop/hadoop-mapreduce-client-jobclient-tests.jar /path/to/mapred/executable"
22 echo ""
23 echo " --zookeeper-data /path/to/use Where the embedded zookeeper instance should write its data."
24 echo " defaults to 'zk-data' in the working-dir."
25 echo " --working-dir /path/to/use Path for writing configs and logs. must exist."
26 echo " defaults to making a directory via mktemp."
27 echo " --hadoop-client-classpath /path/to/some.jar:/path/to/another.jar classpath for hadoop jars."
28 echo " defaults to 'hadoop classpath'"
29 echo " --hbase-client-install /path/to/unpacked/client/tarball if given we'll look here for hbase client jars instead of the bin-install"
30 echo " --force-data-clean Delete all data in HDFS and ZK prior to starting up hbase"
31 echo " --single-process Run as single process instead of pseudo-distributed"
32 echo ""
33 exit 1
35 # if no args specified, show usage
36 if [ $# -lt 5 ]; then
37 usage
40 # Get arguments
41 declare component_install
42 declare hadoop_exec
43 declare working_dir
44 declare zk_data_dir
45 declare clean
46 declare distributed="true"
47 declare hadoop_jars
48 declare hbase_client
49 while [ $# -gt 0 ]
51 case "$1" in
52 --working-dir) shift; working_dir=$1; shift;;
53 --force-data-clean) shift; clean="true";;
54 --zookeeper-data) shift; zk_data_dir=$1; shift;;
55 --single-process) shift; distributed="false";;
56 --hadoop-client-classpath) shift; hadoop_jars="$1"; shift;;
57 --hbase-client-install) shift; hbase_client="$1"; shift;;
58 --) shift; break;;
59 -*) usage ;;
60 *) break;; # terminate while loop
61 esac
62 done
64 # should still have where component checkout is.
65 if [ $# -lt 5 ]; then
66 usage
68 component_install="$(cd "$(dirname "$1")"; pwd)/$(basename "$1")"
69 hadoop_exec="$(cd "$(dirname "$2")"; pwd)/$(basename "$2")"
70 timeline_service_dir="$(cd "$(dirname "$3")"; pwd)/$(basename "$3")"
71 yarn_server_tests_test_jar="$(cd "$(dirname "$4")"; pwd)/$(basename "$4")"
72 mapred_jobclient_test_jar="$(cd "$(dirname "$5")"; pwd)/$(basename "$5")"
73 mapred_exec="$(cd "$(dirname "$6")"; pwd)/$(basename "$6")"
75 if [ ! -x "${hadoop_exec}" ]; then
76 echo "hadoop cli does not appear to be executable." >&2
77 exit 1
80 if [ ! -x "${mapred_exec}" ]; then
81 echo "mapred cli does not appear to be executable." >&2
82 exit 1
85 if [ ! -d "${component_install}" ]; then
86 echo "Path to HBase binary install should be a directory." >&2
87 exit 1
90 if [ ! -f "${yarn_server_tests_test_jar}" ]; then
91 echo "Specified YARN server tests test jar is not a file." >&2
92 exit 1
95 if [ ! -f "${mapred_jobclient_test_jar}" ]; then
96 echo "Specified MapReduce jobclient test jar is not a file." >&2
97 exit 1
100 if [ -z "${working_dir}" ]; then
101 if ! working_dir="$(mktemp -d -t hbase-pseudo-dist-test)" ; then
102 echo "Failed to create temporary working directory. Please specify via --working-dir" >&2
103 exit 1
105 else
106 # absolutes please
107 working_dir="$(cd "$(dirname "${working_dir}")"; pwd)/$(basename "${working_dir}")"
108 if [ ! -d "${working_dir}" ]; then
109 echo "passed working directory '${working_dir}' must already exist." >&2
110 exit 1
114 if [ -z "${zk_data_dir}" ]; then
115 zk_data_dir="${working_dir}/zk-data"
116 mkdir "${zk_data_dir}"
117 else
118 # absolutes please
119 zk_data_dir="$(cd "$(dirname "${zk_data_dir}")"; pwd)/$(basename "${zk_data_dir}")"
120 if [ ! -d "${zk_data_dir}" ]; then
121 echo "passed directory for unpacking the source tarball '${zk_data_dir}' must already exist."
122 exit 1
126 if [ -z "${hbase_client}" ]; then
127 hbase_client="${component_install}"
128 else
129 echo "Using HBase client-side artifact"
130 # absolutes please
131 hbase_client="$(cd "$(dirname "${hbase_client}")"; pwd)/$(basename "${hbase_client}")"
132 if [ ! -d "${hbase_client}" ]; then
133 echo "If given hbase client install should be a directory with contents of the client tarball." >&2
134 exit 1
138 if [ -n "${hadoop_jars}" ]; then
139 declare -a tmp_jars
140 for entry in $(echo "${hadoop_jars}" | tr ':' '\n'); do
141 tmp_jars=("${tmp_jars[@]}" "$(cd "$(dirname "${entry}")"; pwd)/$(basename "${entry}")")
142 done
143 hadoop_jars="$(IFS=:; echo "${tmp_jars[*]}")"
147 echo "You'll find logs and temp files in ${working_dir}"
149 function redirect_and_run {
150 log_base=$1
151 shift
152 echo "$*" >"${log_base}.err"
153 "$@" >"${log_base}.out" 2>>"${log_base}.err"
156 (cd "${working_dir}"
158 echo "Hadoop version information:"
159 "${hadoop_exec}" version
160 hadoop_version=$("${hadoop_exec}" version | head -n 1)
161 hadoop_version="${hadoop_version#Hadoop }"
162 if [ "${hadoop_version%.*.*}" -gt 2 ]; then
163 "${hadoop_exec}" envvars
164 else
165 echo "JAVA_HOME: ${JAVA_HOME}"
168 # Ensure that if some other Hadoop install happens to be present in the environment we ignore it.
169 HBASE_DISABLE_HADOOP_CLASSPATH_LOOKUP="true"
170 export HBASE_DISABLE_HADOOP_CLASSPATH_LOOKUP
172 if [ -n "${clean}" ]; then
173 echo "Cleaning out ZooKeeper..."
174 rm -rf "${zk_data_dir:?}/*"
177 echo "HBase version information:"
178 "${component_install}/bin/hbase" version 2>/dev/null
179 hbase_version=$("${component_install}/bin/hbase" version 2>&1 | grep ^HBase | head -n 1)
180 hbase_version="${hbase_version#HBase }"
182 if [ ! -s "${hbase_client}/lib/shaded-clients/hbase-shaded-mapreduce-${hbase_version}.jar" ]; then
183 echo "HBase binary install doesn't appear to include a shaded mapreduce artifact." >&2
184 exit 1
187 if [ ! -s "${hbase_client}/lib/shaded-clients/hbase-shaded-client-${hbase_version}.jar" ]; then
188 echo "HBase binary install doesn't appear to include a shaded client artifact." >&2
189 exit 1
192 if [ ! -s "${hbase_client}/lib/shaded-clients/hbase-shaded-client-byo-hadoop-${hbase_version}.jar" ]; then
193 echo "HBase binary install doesn't appear to include a shaded client artifact." >&2
194 exit 1
197 echo "Writing out configuration for HBase."
198 rm -rf "${working_dir}/hbase-conf"
199 mkdir "${working_dir}/hbase-conf"
201 if [ -f "${component_install}/conf/log4j2.xml" ]; then
202 cp "${component_install}/conf/log4j2.xml" "${working_dir}/hbase-conf/log4j2.xml"
203 else
204 cat >"${working_dir}/hbase-conf/log4j2.xml" <<EOF
205 <Configuration>
206 <Appenders>
207 <!-- Console appender -->
208 <Console name="console" target="SYSTEM_ERR">
209 <PatternLayout pattern="%d{ISO8601} %-5p [%t] %c{2}: %.1000m%n" />
210 </Console>
211 </Appenders>
212 <Loggers>
213 <Root level="${sys:hbase.root.logger.level:-info}">
214 <AppenderRef ref="${sys:hbase.root.logger.appender:-console}" />
215 </Root>
216 </Loggers>
217 </Configuration>
221 cat >"${working_dir}/hbase-conf/hbase-site.xml" <<EOF
222 <?xml version="1.0"?>
223 <?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
224 <!--
227 * Licensed to the Apache Software Foundation (ASF) under one
228 * or more contributor license agreements. See the NOTICE file
229 * distributed with this work for additional information
230 * regarding copyright ownership. The ASF licenses this file
231 * to you under the Apache License, Version 2.0 (the
232 * "License"); you may not use this file except in compliance
233 * with the License. You may obtain a copy of the License at
235 * http://www.apache.org/licenses/LICENSE-2.0
237 * Unless required by applicable law or agreed to in writing, software
238 * distributed under the License is distributed on an "AS IS" BASIS,
239 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
240 * See the License for the specific language governing permissions and
241 * limitations under the License.
244 <configuration>
245 <property>
246 <name>hbase.rootdir</name>
247 <!-- We rely on the defaultFS being set in our hadoop confs -->
248 <value>/hbase</value>
249 </property>
250 <property>
251 <name>hbase.zookeeper.property.dataDir</name>
252 <value>${zk_data_dir}</value>
253 </property>
254 <property>
255 <name>hbase.cluster.distributed</name>
256 <value>${distributed}</value>
257 </property>
258 </configuration>
261 if [ "true" = "${distributed}" ]; then
262 cat >"${working_dir}/hbase-conf/regionservers" <<EOF
263 localhost
267 function cleanup {
269 echo "Shutting down HBase"
270 HBASE_CONF_DIR="${working_dir}/hbase-conf/" "${component_install}/bin/stop-hbase.sh"
272 if [ -f "${working_dir}/hadoop.pid" ]; then
273 echo "Shutdown: listing HDFS contents"
274 redirect_and_run "${working_dir}/hadoop_listing_at_end" \
275 "${hadoop_exec}" --config "${working_dir}/hbase-conf/" fs -ls -R /
277 echo "Shutting down Hadoop"
278 kill -6 "$(cat "${working_dir}/hadoop.pid")"
282 trap cleanup EXIT SIGQUIT
284 echo "Starting up Hadoop"
286 if [ "${hadoop_version%.*.*}" -gt 2 ]; then
287 "${mapred_exec}" minicluster -format -writeConfig "${working_dir}/hbase-conf/core-site.xml" -writeDetails "${working_dir}/hadoop_cluster_info.json" >"${working_dir}/hadoop_cluster_command.out" 2>"${working_dir}/hadoop_cluster_command.err" &
288 else
289 HADOOP_CLASSPATH="${timeline_service_dir}/*:${timeline_service_dir}/lib/*:${yarn_server_tests_test_jar}" "${hadoop_exec}" jar "${mapred_jobclient_test_jar}" minicluster -format -writeConfig "${working_dir}/hbase-conf/core-site.xml" -writeDetails "${working_dir}/hadoop_cluster_info.json" >"${working_dir}/hadoop_cluster_command.out" 2>"${working_dir}/hadoop_cluster_command.err" &
292 echo "$!" > "${working_dir}/hadoop.pid"
294 # 2 + 4 + 8 + .. + 256 ~= 8.5 minutes.
295 max_sleep_time=512
296 sleep_time=2
297 until [[ -s "${working_dir}/hbase-conf/core-site.xml" || "${sleep_time}" -ge "${max_sleep_time}" ]]; do
298 printf '\twaiting for Hadoop to finish starting up.\n'
299 sleep "${sleep_time}"
300 sleep_time="$((sleep_time*2))"
301 done
303 if [ "${sleep_time}" -ge "${max_sleep_time}" ] ; then
304 echo "time out waiting for Hadoop to startup" >&2
305 exit 1
308 if [ "${hadoop_version%.*.*}" -gt 2 ]; then
309 echo "Verifying configs"
310 hadoop_conf_files=""
311 for f in "${working_dir}"/hbase-conf/*-site.xml; do
312 hadoop_conf_files="$hadoop_conf_files -conffile $f"
313 done
314 "${hadoop_exec}" --config "${working_dir}/hbase-conf/" conftest $hadoop_conf_files
317 if [ -n "${clean}" ]; then
318 echo "Cleaning out HDFS..."
319 "${hadoop_exec}" --config "${working_dir}/hbase-conf/" fs -rm -r /hbase
320 "${hadoop_exec}" --config "${working_dir}/hbase-conf/" fs -rm -r example/
321 "${hadoop_exec}" --config "${working_dir}/hbase-conf/" fs -rm -r example-region-listing.data
324 echo "Listing HDFS contents"
325 redirect_and_run "${working_dir}/hadoop_cluster_smoke" \
326 "${hadoop_exec}" --config "${working_dir}/hbase-conf/" fs -ls -R /
328 echo "Starting up HBase"
329 HBASE_CONF_DIR="${working_dir}/hbase-conf/" "${component_install}/bin/start-hbase.sh"
331 sleep_time=2
332 until "${component_install}/bin/hbase" --config "${working_dir}/hbase-conf/" shell --noninteractive >"${working_dir}/waiting_hbase_startup.log" 2>&1 <<EOF
333 count 'hbase:meta'
336 printf '\tretry waiting for hbase to come up.\n'
337 sleep "${sleep_time}"
338 sleep_time="$((sleep_time*2))"
339 done
341 echo "Setting up table 'test:example' with 1,000 regions"
342 "${hbase_client}/bin/hbase" --config "${working_dir}/hbase-conf/" shell --noninteractive >"${working_dir}/table_create.log" 2>&1 <<EOF
343 create_namespace 'test'
344 create 'test:example', 'family1', 'family2', {NUMREGIONS => 1000, SPLITALGO => 'UniformSplit'}
347 echo "writing out example TSV to example.tsv"
348 cat >"${working_dir}/example.tsv" <<EOF
349 row1 value8 value8
350 row3 value2
351 row2 value9
352 row10 value1
353 pow1 value8 value8
354 pow3 value2
355 pow2 value9
356 pow10 value1
357 paw1 value8 value8
358 paw3 value2
359 paw2 value9
360 paw10 value1
361 raw1 value8 value8
362 raw3 value2
363 raw2 value9
364 raw10 value1
365 aow1 value8 value8
366 aow3 value2
367 aow2 value9
368 aow10 value1
369 aaw1 value8 value8
370 aaw3 value2
371 aaw2 value9
372 aaw10 value1
373 how1 value8 value8
374 how3 value2
375 how2 value9
376 how10 value1
377 zow1 value8 value8
378 zow3 value2
379 zow2 value9
380 zow10 value1
381 zaw1 value8 value8
382 zaw3 value2
383 zaw2 value9
384 zaw10 value1
385 haw1 value8 value8
386 haw3 value2
387 haw2 value9
388 haw10 value1
389 low1 value8 value8
390 low3 value2
391 low2 value9
392 low10 value1
393 law1 value8 value8
394 law3 value2
395 law2 value9
396 law10 value1
399 echo "uploading example.tsv to HDFS"
400 "${hadoop_exec}" --config "${working_dir}/hbase-conf/" fs -mkdir example
401 "${hadoop_exec}" --config "${working_dir}/hbase-conf/" fs -copyFromLocal "${working_dir}/example.tsv" "example/"
403 echo "Importing TSV via shaded client artifact for HBase - MapReduce integration."
404 # hbase_thirdparty_jars=("${component_install}"/lib/htrace-core4*.jar \
405 # "${component_install}"/lib/slf4j-api-*.jar \
406 # "${component_install}"/lib/commons-logging-*.jar \
407 # "${component_install}"/lib/slf4j-log4j12-*.jar \
408 # "${component_install}"/lib/log4j-1.2.*.jar \
409 # "${working_dir}/hbase-conf/log4j.properties")
410 # hbase_dep_classpath=$(IFS=:; echo "${hbase_thirdparty_jars[*]}")
411 hbase_dep_classpath="$("${hbase_client}/bin/hbase" --config "${working_dir}/hbase-conf/" mapredcp)"
412 HADOOP_CLASSPATH="${hbase_dep_classpath}" redirect_and_run "${working_dir}/mr-importtsv" \
413 "${hadoop_exec}" --config "${working_dir}/hbase-conf/" jar "${hbase_client}/lib/shaded-clients/hbase-shaded-mapreduce-${hbase_version}.jar" importtsv -Dimporttsv.columns=HBASE_ROW_KEY,family1:column1,family1:column4,family1:column3 test:example example/ -libjars "${hbase_dep_classpath}"
414 "${hbase_client}/bin/hbase" --config "${working_dir}/hbase-conf/" shell --noninteractive >"${working_dir}/scan_import.out" 2>"${working_dir}/scan_import.err" <<EOF
415 scan 'test:example'
418 echo "Verifying row count from import."
419 import_rowcount=$(echo 'count "test:example"' | "${hbase_client}/bin/hbase" --config "${working_dir}/hbase-conf/" shell --noninteractive 2>/dev/null | tail -n 1)
420 if [ ! "${import_rowcount}" -eq 48 ]; then
421 echo "ERROR: Instead of finding 48 rows, we found ${import_rowcount}."
422 exit 2
425 if [ -z "${hadoop_jars}" ]; then
426 echo "Hadoop client jars not given; getting them from 'hadoop classpath' for the example."
427 hadoop_jars=$("${hadoop_exec}" --config "${working_dir}/hbase-conf/" classpath)
430 echo "Building shaded client example."
431 cat >"${working_dir}/HBaseClientReadWriteExample.java" <<EOF
432 import org.apache.hadoop.conf.Configuration;
433 import org.apache.hadoop.fs.FileSystem;
434 import org.apache.hadoop.fs.FSDataInputStream;
435 import org.apache.hadoop.fs.FSDataOutputStream;
436 import org.apache.hadoop.fs.Path;
437 import org.apache.hadoop.hbase.Cell;
438 import org.apache.hadoop.hbase.CellBuilder;
439 import org.apache.hadoop.hbase.CellBuilderFactory;
440 import org.apache.hadoop.hbase.CellBuilderType;
441 import org.apache.hadoop.hbase.ClusterMetrics;
442 import org.apache.hadoop.hbase.HBaseConfiguration;
443 import org.apache.hadoop.hbase.RegionMetrics;
444 import org.apache.hadoop.hbase.ServerMetrics;
445 import org.apache.hadoop.hbase.TableName;
446 import org.apache.hadoop.hbase.client.Admin;
447 import org.apache.hadoop.hbase.client.Connection;
448 import org.apache.hadoop.hbase.client.ConnectionFactory;
449 import org.apache.hadoop.hbase.client.Put;
450 import org.apache.hadoop.hbase.client.Table;
451 import org.apache.hadoop.hbase.util.Bytes;
453 import java.util.LinkedList;
454 import java.util.List;
457 public class HBaseClientReadWriteExample {
458 private static final byte[] FAMILY_BYTES = Bytes.toBytes("family2");
460 public static void main(String[] args) throws Exception {
461 Configuration hbase = HBaseConfiguration.create();
462 Configuration hadoop = new Configuration();
463 try (Connection connection = ConnectionFactory.createConnection(hbase)) {
464 System.out.println("Generating list of regions");
465 final List<String> regions = new LinkedList<>();
466 try (Admin admin = connection.getAdmin()) {
467 final ClusterMetrics cluster = admin.getClusterMetrics();
468 System.out.println(String.format("\tCluster reports version %s, ave load %f, region count %d", cluster.getHBaseVersion(), cluster.getAverageLoad(), cluster.getRegionCount()));
469 for (ServerMetrics server : cluster.getLiveServerMetrics().values()) {
470 for (RegionMetrics region : server.getRegionMetrics().values()) {
471 regions.add(region.getNameAsString());
475 final Path listing = new Path("example-region-listing.data");
476 System.out.println("Writing list to HDFS");
477 try (FileSystem fs = FileSystem.newInstance(hadoop)) {
478 final Path path = fs.makeQualified(listing);
479 try (FSDataOutputStream out = fs.create(path)) {
480 out.writeInt(regions.size());
481 for (String region : regions) {
482 out.writeUTF(region);
484 out.hsync();
487 final List<Put> puts = new LinkedList<>();
488 final Put marker = new Put(new byte[] { (byte)0 });
489 System.out.println("Reading list from HDFS");
490 try (FileSystem fs = FileSystem.newInstance(hadoop)) {
491 final Path path = fs.makeQualified(listing);
492 final CellBuilder builder = CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY);
493 try (FSDataInputStream in = fs.open(path)) {
494 final int count = in.readInt();
495 marker.addColumn(FAMILY_BYTES, Bytes.toBytes("count"), Bytes.toBytes(count));
496 for(int i = 0; i < count; i++) {
497 builder.clear();
498 final byte[] row = Bytes.toBytes(in.readUTF());
499 final Put put = new Put(row);
500 builder.setRow(row);
501 builder.setFamily(FAMILY_BYTES);
502 builder.setType(Cell.Type.Put);
503 put.add(builder.build());
504 puts.add(put);
508 System.out.println("Writing list into HBase table");
509 try (Table table = connection.getTable(TableName.valueOf("test:example"))) {
510 table.put(marker);
511 table.put(puts);
517 redirect_and_run "${working_dir}/hbase-shaded-client-compile" \
518 javac -cp "${hbase_client}/lib/shaded-clients/hbase-shaded-client-byo-hadoop-${hbase_version}.jar:${hadoop_jars}" "${working_dir}/HBaseClientReadWriteExample.java"
519 echo "Running shaded client example. It'll fetch the set of regions, round-trip them to a file in HDFS, then write them one-per-row into the test table."
520 # The order of classpath entries here is important. if we're using non-shaded Hadoop 3 / 2.9.0 jars, we have to work around YARN-2190.
521 redirect_and_run "${working_dir}/hbase-shaded-client-example" \
522 java -cp "${working_dir}/hbase-conf/:${hbase_client}/lib/shaded-clients/hbase-shaded-client-byo-hadoop-${hbase_version}.jar:${hbase_dep_classpath}:${working_dir}:${hadoop_jars}" HBaseClientReadWriteExample
524 echo "Checking on results of example program."
525 "${hadoop_exec}" --config "${working_dir}/hbase-conf/" fs -copyToLocal "example-region-listing.data" "${working_dir}/example-region-listing.data"
527 "${hbase_client}/bin/hbase" --config "${working_dir}/hbase-conf/" shell --noninteractive >"${working_dir}/scan_example.out" 2>"${working_dir}/scan_example.err" <<EOF
528 scan 'test:example'
531 echo "Verifying row count from example."
532 example_rowcount=$(echo 'count "test:example"' | "${hbase_client}/bin/hbase" --config "${working_dir}/hbase-conf/" shell --noninteractive 2>/dev/null | tail -n 1)
533 if [ "${example_rowcount}" -gt "1049" ]; then
534 echo "Found ${example_rowcount} rows, which is enough to cover 48 for import, 1000 example's use of user table regions, 1 for example's use of meta region, and 1 for example's count record"
535 else
536 echo "ERROR: Only found ${example_rowcount} rows."