hbase-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nkey...@apache.org
Subject svn commit: r1525642 [4/4] - in /hbase/branches/0.96: ./ bin/ hbase-assembly/src/main/assembly/ hbase-it/ hbase-server/ hbase-server/src/main/ruby/ hbase-server/src/main/ruby/hbase/ hbase-server/src/main/ruby/irb/ hbase-server/src/main/ruby/shell/ hbas...
Date Mon, 23 Sep 2013 16:45:46 GMT
Added: hbase/branches/0.96/hbase-shell/src/main/ruby/shell/commands/truncate_preserve.rb
URL: http://svn.apache.org/viewvc/hbase/branches/0.96/hbase-shell/src/main/ruby/shell/commands/truncate_preserve.rb?rev=1525642&view=auto
==============================================================================
--- hbase/branches/0.96/hbase-shell/src/main/ruby/shell/commands/truncate_preserve.rb (added)
+++ hbase/branches/0.96/hbase-shell/src/main/ruby/shell/commands/truncate_preserve.rb Mon Sep 23 16:45:42 2013
@@ -0,0 +1,38 @@
+#
+#
+# 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.
+#
+
+module Shell
+  module Commands
+    class TruncatePreserve < Command
+      def help
+        return <<-EOF
+  Disables, drops and recreates the specified table while still maintaing the previous region boundaries.
+EOF
+      end
+
+      def command(table)
+        format_simple_command do
+          puts "Truncating '#{table}' table (it may take a while):"
+          admin.truncate_preserve(table) { |log| puts " - #{log}" }
+        end
+      end
+
+    end
+  end
+end

Added: hbase/branches/0.96/hbase-shell/src/main/ruby/shell/commands/unassign.rb
URL: http://svn.apache.org/viewvc/hbase/branches/0.96/hbase-shell/src/main/ruby/shell/commands/unassign.rb?rev=1525642&view=auto
==============================================================================
--- hbase/branches/0.96/hbase-shell/src/main/ruby/shell/commands/unassign.rb (added)
+++ hbase/branches/0.96/hbase-shell/src/main/ruby/shell/commands/unassign.rb Mon Sep 23 16:45:42 2013
@@ -0,0 +1,45 @@
+#
+#
+# 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.
+#
+
+module Shell
+  module Commands
+    class Unassign < Command
+      def help
+        return <<-EOF
+Unassign a region. Unassign will close region in current location and then
+reopen it again.  Pass 'true' to force the unassignment ('force' will clear
+all in-memory state in master before the reassign. If results in
+double assignment use hbck -fix to resolve. To be used by experts).
+Use with caution.  For expert use only.  Examples:
+
+  hbase> unassign 'REGIONNAME'
+  hbase> unassign 'REGIONNAME', true
+  hbase> unassign 'ENCODED_REGIONNAME'
+  hbase> unassign 'ENCODED_REGIONNAME', true
+EOF
+      end
+
+      def command(region_name, force = 'false')
+        format_simple_command do
+          admin.unassign(region_name, force)
+        end
+      end
+    end
+  end
+end

Added: hbase/branches/0.96/hbase-shell/src/main/ruby/shell/commands/user_permission.rb
URL: http://svn.apache.org/viewvc/hbase/branches/0.96/hbase-shell/src/main/ruby/shell/commands/user_permission.rb?rev=1525642&view=auto
==============================================================================
--- hbase/branches/0.96/hbase-shell/src/main/ruby/shell/commands/user_permission.rb (added)
+++ hbase/branches/0.96/hbase-shell/src/main/ruby/shell/commands/user_permission.rb Mon Sep 23 16:45:42 2013
@@ -0,0 +1,47 @@
+#
+# 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.
+#
+
+module Shell
+  module Commands
+    class UserPermission < Command
+      def help
+        return <<-EOF
+Show all permissions for the particular user.
+Syntax : user_permission <table>
+For example:
+
+    hbase> user_permission
+    hbase> user_permission 'table1'
+EOF
+      end
+
+      def command(table=nil)
+        #format_simple_command do
+        #admin.user_permission(table)
+        now = Time.now
+        formatter.header(["User", "Table,Family,Qualifier:Permission"])
+
+        count = security_admin.user_permission(table) do |user, permission|
+          formatter.row([ user, permission])
+        end
+
+        formatter.footer(now, count)
+      end
+    end
+  end
+end

Added: hbase/branches/0.96/hbase-shell/src/main/ruby/shell/commands/version.rb
URL: http://svn.apache.org/viewvc/hbase/branches/0.96/hbase-shell/src/main/ruby/shell/commands/version.rb?rev=1525642&view=auto
==============================================================================
--- hbase/branches/0.96/hbase-shell/src/main/ruby/shell/commands/version.rb (added)
+++ hbase/branches/0.96/hbase-shell/src/main/ruby/shell/commands/version.rb Mon Sep 23 16:45:42 2013
@@ -0,0 +1,37 @@
+#
+#
+# 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.
+#
+
+module Shell
+  module Commands
+    class Version < Command
+      def help
+        return <<-EOF
+Output this HBase version
+EOF
+      end
+
+      def command
+        # Output version.
+        puts "#{org.apache.hadoop.hbase.util.VersionInfo.getVersion()}, " +
+             "r#{org.apache.hadoop.hbase.util.VersionInfo.getRevision()}, " +
+             "#{org.apache.hadoop.hbase.util.VersionInfo.getDate()}"
+      end
+    end
+  end
+end

Added: hbase/branches/0.96/hbase-shell/src/main/ruby/shell/commands/whoami.rb
URL: http://svn.apache.org/viewvc/hbase/branches/0.96/hbase-shell/src/main/ruby/shell/commands/whoami.rb?rev=1525642&view=auto
==============================================================================
--- hbase/branches/0.96/hbase-shell/src/main/ruby/shell/commands/whoami.rb (added)
+++ hbase/branches/0.96/hbase-shell/src/main/ruby/shell/commands/whoami.rb Mon Sep 23 16:45:42 2013
@@ -0,0 +1,37 @@
+#
+# 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.
+#
+
+module Shell
+  module Commands
+    class Whoami < Command
+      def help
+        return <<-EOF
+Show the current hbase user.
+Syntax : whoami
+For example:
+
+    hbase> whoami
+EOF
+      end
+
+      def command()
+        puts "#{org.apache.hadoop.hbase.security.User.getCurrent().toString()}"
+      end
+    end
+  end
+end

Added: hbase/branches/0.96/hbase-shell/src/main/ruby/shell/commands/zk_dump.rb
URL: http://svn.apache.org/viewvc/hbase/branches/0.96/hbase-shell/src/main/ruby/shell/commands/zk_dump.rb?rev=1525642&view=auto
==============================================================================
--- hbase/branches/0.96/hbase-shell/src/main/ruby/shell/commands/zk_dump.rb (added)
+++ hbase/branches/0.96/hbase-shell/src/main/ruby/shell/commands/zk_dump.rb Mon Sep 23 16:45:42 2013
@@ -0,0 +1,34 @@
+#
+#
+# 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.
+#
+
+module Shell
+  module Commands
+    class ZkDump < Command
+      def help
+        return <<-EOF
+Dump status of HBase cluster as seen by ZooKeeper.
+EOF
+      end
+
+      def command
+        puts admin.zk_dump
+      end
+    end
+  end
+end

Added: hbase/branches/0.96/hbase-shell/src/main/ruby/shell/formatter.rb
URL: http://svn.apache.org/viewvc/hbase/branches/0.96/hbase-shell/src/main/ruby/shell/formatter.rb?rev=1525642&view=auto
==============================================================================
--- hbase/branches/0.96/hbase-shell/src/main/ruby/shell/formatter.rb (added)
+++ hbase/branches/0.96/hbase-shell/src/main/ruby/shell/formatter.rb Mon Sep 23 16:45:42 2013
@@ -0,0 +1,170 @@
+#
+#
+# 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.
+#
+
+# Results formatter
+module Shell
+  module Formatter
+    # Base abstract class for results formatting.
+    class Base
+      attr_reader :row_count
+
+      def is_valid_io?(obj)
+        obj.instance_of?(IO) || obj == Kernel
+      end
+
+      def refresh_width()
+        if $stdout.tty?
+          @max_width = Java::jline.Terminal.getTerminal().getTerminalWidth()
+        else
+          @max_width = 0
+        end
+      end
+
+      # Takes an output stream and a print width.
+      def initialize(opts = {})
+        options = {
+          :output_stream => Kernel,
+        }.merge(opts)
+
+        @out = options[:output_stream]
+        refresh_width
+        @row_count = 0
+
+        # raise an error if the stream is not valid
+        raise(TypeError, "Type #{@out.class} of parameter #{@out} is not IO") unless is_valid_io?(@out)
+      end
+
+      def header(args = [], widths = [])
+        refresh_width
+        row(args, false, widths) if args.length > 0
+        @row_count = 0
+      end
+
+      # Output a row.
+      # Inset is whether or not to offset row by a space.
+      def row(args = [], inset = true, widths = [])
+        # Print out nothing
+        return if !args || args.empty?
+
+        # Print a string
+        if args.is_a?(String)
+          output(args)
+          @out.puts
+          return
+        end
+
+        # TODO: Look at the type.  Is it RowResult?
+        if args.length == 1
+          splits = split(@max_width, dump(args[0]))
+          for l in splits
+            output(@max_width, l)
+            @out.puts
+          end
+        elsif args.length == 2
+          if @max_width == 0
+            col1width = col2width = 0
+          else
+            col1width = (not widths or widths.length == 0) ? @max_width / 4 : @max_width * widths[0] / 100
+            col2width = (not widths or widths.length < 2) ? @max_width - col1width - 2 : @max_width * widths[1] / 100 - 2
+          end
+          splits1 = split(col1width, dump(args[0]))
+          splits2 = split(col2width, dump(args[1]))
+          biggest = (splits2.length > splits1.length)? splits2.length: splits1.length
+          index = 0
+          while index < biggest
+            # Inset by one space if inset is set.
+            @out.print(" ") if inset
+            output(col1width, splits1[index])
+            # Add extra space so second column lines up w/ second column output
+            @out.print(" ") unless inset
+            @out.print(" ")
+            output(col2width, splits2[index])
+            index += 1
+            @out.puts
+          end
+        else
+          # Print a space to set off multi-column rows
+          print ' '
+          first = true
+          for e in args
+            @out.print " " unless first
+            first = false
+            @out.print e
+          end
+          puts
+        end
+        @row_count += 1
+      end
+
+      def split(width, str)
+        if width == 0
+          return [str]
+        end
+        result = []
+        index = 0
+        while index < str.length do
+          result << str.slice(index, width)
+          index += width
+        end
+        result
+      end
+
+      def dump(str)
+        return if str.instance_of?(Fixnum)
+        # Remove double-quotes added by 'dump'.
+        return str
+      end
+
+      def output(str)
+        output(@max_width, str)
+      end
+
+      def output(width, str)
+        if str == nil
+          str = ''
+        end
+        if not width or width == str.length
+          @out.print(str)
+        else
+          @out.printf('%-*s', width, str)
+        end
+      end
+
+      def footer(start_time = nil, row_count = nil)
+        return unless start_time
+        row_count ||= @row_count
+        # Only output elapsed time and row count if startTime passed
+        @out.puts("%d row(s) in %.4f seconds" % [row_count, Time.now - start_time])
+      end
+    end
+
+
+    class Console < Base
+    end
+
+    class XHTMLFormatter < Base
+      # http://www.germane-software.com/software/rexml/doc/classes/REXML/Document.html
+      # http://www.crummy.com/writing/RubyCookbook/test_results/75942.html
+    end
+
+    class JSON < Base
+    end
+  end
+end
+

Added: hbase/branches/0.96/hbase-shell/src/test/java/org/apache/hadoop/hbase/client/TestShell.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.96/hbase-shell/src/test/java/org/apache/hadoop/hbase/client/TestShell.java?rev=1525642&view=auto
==============================================================================
--- hbase/branches/0.96/hbase-shell/src/test/java/org/apache/hadoop/hbase/client/TestShell.java (added)
+++ hbase/branches/0.96/hbase-shell/src/test/java/org/apache/hadoop/hbase/client/TestShell.java Mon Sep 23 16:45:42 2013
@@ -0,0 +1,74 @@
+/**
+ *
+ * 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.client;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.HBaseTestingUtility;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.LargeTests;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import org.jruby.embed.ScriptingContainer;
+import org.jruby.embed.PathType;
+import org.junit.experimental.categories.Category;
+
+@Category(LargeTests.class)
+public class TestShell {
+  final Log LOG = LogFactory.getLog(getClass());
+  private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
+  private final static ScriptingContainer jruby = new ScriptingContainer();
+
+  @BeforeClass
+  public static void setUpBeforeClass() throws Exception {
+    // Start mini cluster
+    TEST_UTIL.getConfiguration().setBoolean("hbase.online.schema.update.enable", true);
+    TEST_UTIL.getConfiguration().setInt("hbase.regionserver.msginterval", 100);
+    TEST_UTIL.getConfiguration().setInt("hbase.client.pause", 250);
+    TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 6);
+    TEST_UTIL.startMiniCluster();
+
+    // Configure jruby runtime
+    List<String> loadPaths = new ArrayList();
+    loadPaths.add("src/main/ruby");
+    loadPaths.add("src/test/ruby");
+    jruby.getProvider().setLoadPaths(loadPaths);
+    jruby.put("$TEST_CLUSTER", TEST_UTIL);
+  }
+
+  @AfterClass
+  public static void tearDownAfterClass() throws Exception {
+    TEST_UTIL.shutdownMiniCluster();
+  }
+
+  @Test
+  public void testRunShellTests() throws IOException {
+    // Start all ruby tests
+    jruby.runScriptlet(PathType.ABSOLUTE, "src/test/ruby/tests_runner.rb");
+  }
+
+}
+

Added: hbase/branches/0.96/hbase-shell/src/test/ruby/hbase/admin_test.rb
URL: http://svn.apache.org/viewvc/hbase/branches/0.96/hbase-shell/src/test/ruby/hbase/admin_test.rb?rev=1525642&view=auto
==============================================================================
--- hbase/branches/0.96/hbase-shell/src/test/ruby/hbase/admin_test.rb (added)
+++ hbase/branches/0.96/hbase-shell/src/test/ruby/hbase/admin_test.rb Mon Sep 23 16:45:42 2013
@@ -0,0 +1,355 @@
+#
+#
+# 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.
+#
+
+require 'shell'
+require 'shell/formatter'
+require 'hbase'
+require 'hbase/hbase'
+require 'hbase/table'
+
+include HBaseConstants
+
+module Hbase
+  class AdminHelpersTest < Test::Unit::TestCase
+    include TestHelpers
+
+    def setup
+      setup_hbase
+      # Create test table if it does not exist
+      @test_name = "hbase_shell_tests_table"
+      create_test_table(@test_name)
+    end
+
+    define_test "exists? should return true when a table exists" do
+      assert(admin.exists?('hbase:meta'))
+    end
+
+    define_test "exists? should return false when a table exists" do
+      assert(!admin.exists?('NOT.EXISTS'))
+    end
+
+    define_test "enabled? should return true for enabled tables" do
+      admin.enable(@test_name)
+      assert(admin.enabled?(@test_name))
+    end
+
+    define_test "enabled? should return false for disabled tables" do
+      admin.disable(@test_name)
+      assert(!admin.enabled?(@test_name))
+    end
+  end
+
+    # Simple administration methods tests
+  class AdminMethodsTest < Test::Unit::TestCase
+    include TestHelpers
+
+    def setup
+      setup_hbase
+      # Create test table if it does not exist
+      @test_name = "hbase_shell_tests_table"
+      create_test_table(@test_name)
+
+      # Create table test table name
+      @create_test_name = 'hbase_create_table_test_table'
+    end
+
+    define_test "list should return a list of tables" do
+      assert(admin.list.member?(@test_name))
+    end
+
+    define_test "list should not return meta tables" do
+      assert(!admin.list.member?('hbase:meta'))
+    end
+
+    define_test "list_namespace_tables for the system namespace should return a list of tables" do
+      assert(admin.list_namespace_tables('hbase').count > 0)
+    end
+
+    define_test "list_namespace_tables for the default namespace should return a list of tables" do
+      assert(admin.list_namespace_tables('default').count > 0)
+    end
+
+    #-------------------------------------------------------------------------------
+
+    define_test "flush should work" do
+      admin.flush('hbase:meta')
+    end
+
+    #-------------------------------------------------------------------------------
+
+    define_test "compact should work" do
+      admin.compact('hbase:meta')
+    end
+
+    #-------------------------------------------------------------------------------
+
+    define_test "major_compact should work" do
+      admin.major_compact('hbase:meta')
+    end
+
+    #-------------------------------------------------------------------------------
+
+    define_test "split should work" do
+      admin.split('hbase:meta', nil)
+    end
+
+    #-------------------------------------------------------------------------------
+
+    define_test "drop should fail on non-existent tables" do
+      assert_raise(ArgumentError) do
+        admin.drop('NOT.EXISTS')
+      end
+    end
+
+    define_test "drop should fail on enabled tables" do
+      assert_raise(ArgumentError) do
+        admin.drop(@test_name)
+      end
+    end
+
+    define_test "drop should drop tables" do
+      admin.disable(@test_name)
+      admin.drop(@test_name)
+      assert(!admin.exists?(@test_name))
+    end
+
+    #-------------------------------------------------------------------------------
+
+    define_test "zk_dump should work" do
+      assert_not_nil(admin.zk_dump)
+    end
+
+    #-------------------------------------------------------------------------------
+
+    define_test "create should fail with non-string table names" do
+      assert_raise(ArgumentError) do
+        admin.create(123, 'xxx')
+      end
+    end
+
+    define_test "create should fail with non-string/non-hash column args" do
+      assert_raise(ArgumentError) do
+        admin.create(@create_test_name, 123)
+      end
+    end
+
+    define_test "create should fail without columns" do
+      drop_test_table(@create_test_name)
+      assert_raise(ArgumentError) do
+        admin.create(@create_test_name)
+      end
+    end
+    
+    define_test "create should fail without columns when called with options" do
+      drop_test_table(@create_test_name)
+      assert_raise(ArgumentError) do
+        admin.create(@create_test_name, { OWNER => 'a' })
+      end
+    end
+
+    define_test "create should work with string column args" do
+      drop_test_table(@create_test_name)
+      admin.create(@create_test_name, 'a', 'b')
+      assert_equal(['a:', 'b:'], table(@create_test_name).get_all_columns.sort)
+     end
+
+    define_test "create should work with hash column args" do
+      drop_test_table(@create_test_name)
+      admin.create(@create_test_name, { NAME => 'a'}, { NAME => 'b'})
+      assert_equal(['a:', 'b:'], table(@create_test_name).get_all_columns.sort)
+    end
+    
+    define_test "create should be able to set table options" do
+      drop_test_table(@create_test_name)
+      admin.create(@create_test_name, 'a', 'b', 'MAX_FILESIZE' => 12345678, OWNER => '987654321')
+      assert_equal(['a:', 'b:'], table(@create_test_name).get_all_columns.sort)
+      assert_match(/12345678/, admin.describe(@create_test_name))
+      assert_match(/987654321/, admin.describe(@create_test_name))
+    end
+        
+    define_test "create should ignore table_att" do
+      drop_test_table(@create_test_name)
+      admin.create(@create_test_name, 'a', 'b', METHOD => 'table_att', OWNER => '987654321')
+      assert_equal(['a:', 'b:'], table(@create_test_name).get_all_columns.sort)
+      assert_match(/987654321/, admin.describe(@create_test_name))
+    end
+    
+    define_test "create should work with SPLITALGO" do
+      drop_test_table(@create_test_name)
+      admin.create(@create_test_name, 'a', 'b', {NUMREGIONS => 10, SPLITALGO => 'HexStringSplit'})
+      assert_equal(['a:', 'b:'], table(@create_test_name).get_all_columns.sort)
+    end
+
+    #-------------------------------------------------------------------------------
+
+    define_test "describe should fail for non-existent tables" do
+      assert_raise(NativeException) do
+        admin.describe('.NOT.EXISTS.')
+      end
+    end
+
+    define_test "describe should return a description" do
+      assert_not_nil admin.describe(@test_name)
+    end
+
+    #-------------------------------------------------------------------------------
+
+    define_test "truncate should empty a table" do
+      table(@test_name).put(1, "x:a", 1)
+      table(@test_name).put(2, "x:a", 2)
+      assert_equal(2, table(@test_name)._count_internal)
+      # This is hacky.  Need to get the configuration into admin instance
+      admin.truncate(@test_name, $TEST_CLUSTER.getConfiguration)
+      assert_equal(0, table(@test_name)._count_internal)
+    end
+
+    define_test "truncate should yield log records" do
+      logs = []
+      admin.truncate(@test_name, $TEST_CLUSTER.getConfiguration) do |log|
+        assert_kind_of(String, log)
+        logs << log
+      end
+      assert(!logs.empty?)
+    end
+  end
+
+ # Simple administration methods tests
+  class AdminAlterTableTest < Test::Unit::TestCase
+    include TestHelpers
+
+    def setup
+      setup_hbase
+      # Create test table if it does not exist
+      @test_name = "hbase_shell_tests_table"
+      drop_test_table(@test_name)
+      create_test_table(@test_name)
+    end
+
+    #-------------------------------------------------------------------------------
+
+    define_test "alter should fail with non-string table names" do
+      assert_raise(ArgumentError) do
+        admin.alter(123, true, METHOD => 'delete', NAME => 'y')
+      end
+    end
+
+    define_test "alter should fail with non-existing tables" do
+      assert_raise(ArgumentError) do
+        admin.alter('NOT.EXISTS', true, METHOD => 'delete', NAME => 'y')
+      end
+    end
+
+    define_test "alter should not fail with enabled tables" do
+      admin.enable(@test_name)
+      admin.alter(@test_name, true, METHOD => 'delete', NAME => 'y')
+    end
+
+    define_test "alter should be able to delete column families" do
+      assert_equal(['x:', 'y:'], table(@test_name).get_all_columns.sort)
+      admin.alter(@test_name, true, METHOD => 'delete', NAME => 'y')
+      admin.enable(@test_name)
+      assert_equal(['x:'], table(@test_name).get_all_columns.sort)
+    end
+
+    define_test "alter should be able to add column families" do
+      assert_equal(['x:', 'y:'], table(@test_name).get_all_columns.sort)
+      admin.alter(@test_name, true, NAME => 'z')
+      admin.enable(@test_name)
+      assert_equal(['x:', 'y:', 'z:'], table(@test_name).get_all_columns.sort)
+    end
+
+    define_test "alter should be able to add column families (name-only alter spec)" do
+      assert_equal(['x:', 'y:'], table(@test_name).get_all_columns.sort)
+      admin.alter(@test_name, true, 'z')
+      admin.enable(@test_name)
+      assert_equal(['x:', 'y:', 'z:'], table(@test_name).get_all_columns.sort)
+    end
+
+    define_test "alter should support more than one alteration in one call" do
+      assert_equal(['x:', 'y:'], table(@test_name).get_all_columns.sort)
+      admin.alter(@test_name, true, { NAME => 'z' }, { METHOD => 'delete', NAME => 'y' }, 'MAX_FILESIZE' => 12345678)
+      admin.enable(@test_name)
+      assert_equal(['x:', 'z:'], table(@test_name).get_all_columns.sort)
+      assert_match(/12345678/, admin.describe(@test_name))
+    end
+
+    define_test 'alter should support shortcut DELETE alter specs' do
+      assert_equal(['x:', 'y:'], table(@test_name).get_all_columns.sort)
+      admin.alter(@test_name, true, 'delete' => 'y')
+      assert_equal(['x:'], table(@test_name).get_all_columns.sort)
+    end
+
+    define_test "alter should be able to change table options" do
+      admin.alter(@test_name, true, METHOD => 'table_att', 'MAX_FILESIZE' => 12345678)
+      assert_match(/12345678/, admin.describe(@test_name))
+    end
+
+    define_test "alter should be able to change table options w/o table_att" do
+      admin.alter(@test_name, true, 'MAX_FILESIZE' => 12345678)
+      assert_match(/12345678/, admin.describe(@test_name))
+    end
+    
+    define_test "alter should be able to change coprocessor attributes" do
+      drop_test_table(@test_name)
+      create_test_table(@test_name)
+
+      cp_key = "coprocessor"
+      class_name = "SimpleRegionObserver"
+
+      cp_value = "hdfs:///foo.jar|" + class_name + "|12|arg1=1,arg2=2"
+
+      # eval() is used to convert a string to regex
+      assert_no_match(eval("/" + class_name + "/"), admin.describe(@test_name))
+      assert_no_match(eval("/" + cp_key + "/"), admin.describe(@test_name))
+      admin.alter(@test_name, true, 'METHOD' => 'table_att', cp_key => cp_value)
+      assert_match(eval("/" + class_name + "/"), admin.describe(@test_name))
+      assert_match(eval("/" + cp_key + "\\$(\\d+)/"), admin.describe(@test_name))
+    end
+
+    define_test "alter should be able to remove a table attribute" do
+      drop_test_table(@test_name)
+      create_test_table(@test_name)
+
+      key1 = "coprocessor"
+      key2 = "MAX_FILESIZE"
+      admin.alter(@test_name, true, 'METHOD' => 'table_att', key1 => "|TestCP||")
+      admin.alter(@test_name, true, 'METHOD' => 'table_att', key2 => 12345678)
+
+      # eval() is used to convert a string to regex
+      assert_match(eval("/" + key1 + "\\$(\\d+)/"), admin.describe(@test_name))
+      assert_match(eval("/" + key2 + "/"), admin.describe(@test_name))
+
+      # get the cp key
+      cp_keys = admin.describe(@test_name).scan(/(coprocessor\$\d+)/i)
+
+      admin.alter(@test_name, true, 'METHOD' => 'table_att_unset', 'NAME' => cp_keys[0][0])
+      admin.alter(@test_name, true, 'METHOD' => 'table_att_unset', 'NAME' => key2)
+      assert_no_match(eval("/" + key1 + "\\$(\\d+)/"), admin.describe(@test_name))
+      assert_no_match(eval("/" + key2 + "/"), admin.describe(@test_name))
+    end
+
+    define_test "get_table should get a real table" do
+      drop_test_table(@test_name)
+      create_test_table(@test_name)
+
+      table = table(@test_name)
+      assert_not_equal(nil, table)
+    end
+  end
+end

Added: hbase/branches/0.96/hbase-shell/src/test/ruby/hbase/hbase_test.rb
URL: http://svn.apache.org/viewvc/hbase/branches/0.96/hbase-shell/src/test/ruby/hbase/hbase_test.rb?rev=1525642&view=auto
==============================================================================
--- hbase/branches/0.96/hbase-shell/src/test/ruby/hbase/hbase_test.rb (added)
+++ hbase/branches/0.96/hbase-shell/src/test/ruby/hbase/hbase_test.rb Mon Sep 23 16:45:42 2013
@@ -0,0 +1,49 @@
+#
+#
+# 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.
+#
+
+require 'hbase'
+
+module Hbase
+  class HbaseTest < Test::Unit::TestCase
+    def setup
+      @formatter = Shell::Formatter::Console.new()
+      @hbase = ::Hbase::Hbase.new($TEST_CLUSTER.getConfiguration)
+    end
+
+    define_test "Hbase::Hbase constructor should initialize hbase configuration object" do
+      assert_kind_of(org.apache.hadoop.conf.Configuration, @hbase.configuration)
+    end
+
+    define_test "Hbase::Hbase#admin should create a new admin object when called the first time" do
+      assert_kind_of(::Hbase::Admin, @hbase.admin(@formatter))
+    end
+
+    define_test "Hbase::Hbase#admin should create a new admin object every call" do
+      assert_not_same(@hbase.admin(@formatter), @hbase.admin(@formatter))
+    end
+
+    define_test "Hbase::Hbase#table should create a new table object when called the first time" do
+      assert_kind_of(::Hbase::Table, @hbase.table('hbase:meta', @formatter))
+    end
+
+    define_test "Hbase::Hbase#table should create a new table object every call" do
+      assert_not_same(@hbase.table('hbase:meta', @formatter), @hbase.table('hbase:meta', @formatter))
+    end
+  end
+end

Added: hbase/branches/0.96/hbase-shell/src/test/ruby/hbase/table_test.rb
URL: http://svn.apache.org/viewvc/hbase/branches/0.96/hbase-shell/src/test/ruby/hbase/table_test.rb?rev=1525642&view=auto
==============================================================================
--- hbase/branches/0.96/hbase-shell/src/test/ruby/hbase/table_test.rb (added)
+++ hbase/branches/0.96/hbase-shell/src/test/ruby/hbase/table_test.rb Mon Sep 23 16:45:42 2013
@@ -0,0 +1,510 @@
+#
+#
+# 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.
+#
+
+require 'hbase'
+
+include HBaseConstants
+
+module Hbase
+  # Constructor tests
+  class TableConstructorTest < Test::Unit::TestCase
+    include TestHelpers
+    def setup
+      setup_hbase
+    end
+
+    define_test "Hbase::Table constructor should fail for non-existent tables" do
+      assert_raise(NativeException) do
+        table('non-existent-table-name')
+      end
+    end
+
+    define_test "Hbase::Table constructor should not fail for existent tables" do
+      assert_nothing_raised do
+        table('hbase:meta')
+      end
+    end
+  end
+
+  # Helper methods tests
+  class TableHelpersTest < Test::Unit::TestCase
+    include TestHelpers
+
+    def setup
+      setup_hbase
+      # Create test table if it does not exist
+      @test_name = "hbase_shell_tests_table"
+      create_test_table(@test_name)
+      @test_table = table(@test_name)
+    end
+
+    define_test "is_meta_table? method should return true for the meta table" do
+      assert(table('hbase:meta').is_meta_table?)
+    end
+
+    define_test "is_meta_table? method should return false for a normal table" do
+      assert(!@test_table.is_meta_table?)
+    end
+
+    #-------------------------------------------------------------------------------
+
+    define_test "get_all_columns should return columns list" do
+      cols = table('hbase:meta').get_all_columns
+      assert_kind_of(Array, cols)
+      assert(cols.length > 0)
+    end
+
+    #-------------------------------------------------------------------------------
+
+    define_test "parse_column_name should not return a qualifier for name-only column specifiers" do
+      col, qual = table('hbase:meta').parse_column_name('foo')
+      assert_not_nil(col)
+      assert_nil(qual)
+    end
+
+    define_test "parse_column_name should support and empty column qualifier" do
+      col, qual = table('hbase:meta').parse_column_name('foo:')
+      assert_not_nil(col)
+      assert_not_nil(qual)
+    end
+
+    define_test "parse_column_name should return a qualifier for family:qualifier column specifiers" do
+      col, qual = table('hbase:meta').parse_column_name('foo:bar')
+      assert_not_nil(col)
+      assert_not_nil(qual)
+    end
+  end
+
+  # Simple data management methods tests
+  class TableSimpleMethodsTest < Test::Unit::TestCase
+    include TestHelpers
+
+    def setup
+      setup_hbase
+      # Create test table if it does not exist
+      @test_name = "hbase_shell_tests_table"
+      create_test_table(@test_name)
+      @test_table = table(@test_name)
+      
+      # Insert data to perform delete operations
+      @test_table.put("101", "x:a", "1")
+      @test_table.put("101", "x:a", "2", Time.now.to_i)
+      
+      @test_table.put("102", "x:a", "1",1212)
+      @test_table.put("102", "x:a", "2", 1213)
+      
+      @test_table.put(103, "x:a", "3")
+      @test_table.put(103, "x:a", "4")
+      
+      @test_table.put("104", "x:a", 5)
+      @test_table.put("104", "x:b", 6)
+      
+      @test_table.put(105, "x:a", "3")
+      @test_table.put(105, "x:a", "4")
+    end
+
+    define_test "put should work without timestamp" do
+      @test_table.put("123", "x:a", "1")
+    end
+
+    define_test "put should work with timestamp" do
+      @test_table.put("123", "x:a", "2", Time.now.to_i)
+    end
+
+    define_test "put should work with integer keys" do
+      @test_table.put(123, "x:a", "3")
+    end
+
+    define_test "put should work with integer values" do
+      @test_table.put("123", "x:a", 4)
+    end
+
+    #-------------------------------------------------------------------------------
+
+    define_test "delete should work without timestamp" do
+      @test_table.delete("101", "x:a")
+      res = @test_table._get_internal('101', 'x:a')
+      assert_nil(res)
+    end
+
+    define_test "delete should work with timestamp" do
+      @test_table.delete("102", "x:a", 1214)
+      res = @test_table._get_internal('102', 'x:a')
+      assert_nil(res)
+    end
+
+    define_test "delete should work with integer keys" do
+      @test_table.delete(103, "x:a")
+      res = @test_table._get_internal('103', 'x:a')
+      assert_nil(res)
+    end
+
+    #-------------------------------------------------------------------------------
+
+    define_test "deleteall should work w/o columns and timestamps" do
+      @test_table.deleteall("104")
+      res = @test_table._get_internal('104', 'x:a', 'x:b')
+      assert_nil(res)
+    end
+
+    define_test "deleteall should work with integer keys" do
+      @test_table.deleteall(105)
+      res = @test_table._get_internal('105', 'x:a')
+      assert_nil(res)
+    end
+
+    #-------------------------------------------------------------------------------
+
+    define_test "incr should work w/o value" do
+      @test_table.incr("123", 'x:cnt1')
+    end
+
+    define_test "incr should work with value" do
+      @test_table.incr("123", 'x:cnt2', 10)
+    end
+
+    define_test "incr should work with integer keys" do
+      @test_table.incr(123, 'x:cnt3')
+    end
+
+    #-------------------------------------------------------------------------------
+
+    define_test "get_counter should work with integer keys" do
+      @test_table.incr(12345, 'x:cnt')
+      assert_kind_of(Fixnum, @test_table._get_counter_internal(12345, 'x:cnt'))
+    end
+
+    define_test "get_counter should return nil for non-existent counters" do
+      assert_nil(@test_table._get_counter_internal(12345, 'x:qqqq'))
+    end
+  end
+
+  # Complex data management methods tests
+  class TableComplexMethodsTest < Test::Unit::TestCase
+    include TestHelpers
+
+    def setup
+      setup_hbase
+      # Create test table if it does not exist
+      @test_name = "hbase_shell_tests_table"
+      create_test_table(@test_name)
+      @test_table = table(@test_name)
+
+      # Instert test data
+      @test_ts = 12345678
+      @test_table.put(1, "x:a", 1)
+      @test_table.put(1, "x:b", 2, @test_ts)
+
+      @test_table.put(2, "x:a", 11)
+      @test_table.put(2, "x:b", 12, @test_ts)
+    end
+
+    define_test "count should work w/o a block passed" do
+      assert(@test_table._count_internal > 0)
+    end
+
+    define_test "count should work with a block passed (and yield)" do
+      rows = []
+      cnt = @test_table._count_internal(1) do |cnt, row|
+        rows << row
+      end
+      assert(cnt > 0)
+      assert(!rows.empty?)
+    end
+
+    #-------------------------------------------------------------------------------
+
+    define_test "get should work w/o columns specification" do
+      res = @test_table._get_internal('1')
+      assert_not_nil(res)
+      assert_kind_of(Hash, res)
+      assert_not_nil(res['x:a'])
+      assert_not_nil(res['x:b'])
+    end
+
+    define_test "get should work with integer keys" do
+      res = @test_table._get_internal(1)
+      assert_not_nil(res)
+      assert_kind_of(Hash, res)
+      assert_not_nil(res['x:a'])
+      assert_not_nil(res['x:b'])
+    end
+
+    define_test "get should work with hash columns spec and a single string COLUMN parameter" do
+      res = @test_table._get_internal('1', COLUMN => 'x:a')
+      assert_not_nil(res)
+      assert_kind_of(Hash, res)
+      assert_not_nil(res['x:a'])
+      assert_nil(res['x:b'])
+    end
+
+    define_test "get should work with hash columns spec and a single string COLUMNS parameter" do
+      res = @test_table._get_internal('1', COLUMNS => 'x:a')
+      assert_not_nil(res)
+      assert_kind_of(Hash, res)
+      assert_not_nil(res['x:a'])
+      assert_nil(res['x:b'])
+    end
+
+    define_test "get should work with hash columns spec and an array of strings COLUMN parameter" do
+      res = @test_table._get_internal('1', COLUMN => [ 'x:a', 'x:b' ])
+      assert_not_nil(res)
+      assert_kind_of(Hash, res)
+      assert_not_nil(res['x:a'])
+      assert_not_nil(res['x:b'])
+    end
+
+    define_test "get should work with hash columns spec and an array of strings COLUMNS parameter" do
+      res = @test_table._get_internal('1', COLUMNS => [ 'x:a', 'x:b' ])
+      assert_not_nil(res)
+      assert_kind_of(Hash, res)
+      assert_not_nil(res['x:a'])
+      assert_not_nil(res['x:b'])
+    end
+
+    define_test "get should work with hash columns spec and TIMESTAMP only" do
+      res = @test_table._get_internal('1', TIMESTAMP => @test_ts)
+      assert_not_nil(res)
+      assert_kind_of(Hash, res)
+      assert_nil(res['x:a'])
+      assert_not_nil(res['x:b'])
+    end
+
+    define_test "get should fail with hash columns spec and strange COLUMN value" do
+      assert_raise(ArgumentError) do
+        @test_table._get_internal('1', COLUMN => {})
+      end
+    end
+
+    define_test "get should fail with hash columns spec and strange COLUMNS value" do
+      assert_raise(ArgumentError) do
+        @test_table._get_internal('1', COLUMN => {})
+      end
+    end
+
+    define_test "get should fail with hash columns spec and no TIMESTAMP or COLUMN[S]" do
+      assert_raise(ArgumentError) do
+        @test_table._get_internal('1', { :foo => :bar })
+      end
+    end
+
+    define_test "get should work with a string column spec" do
+      res = @test_table._get_internal('1', 'x:b')
+      assert_not_nil(res)
+      assert_kind_of(Hash, res)
+      assert_nil(res['x:a'])
+      assert_not_nil(res['x:b'])
+    end
+
+    define_test "get should work with an array columns spec" do
+      res = @test_table._get_internal('1', 'x:a', 'x:b')
+      assert_not_nil(res)
+      assert_kind_of(Hash, res)
+      assert_not_nil(res['x:a'])
+      assert_not_nil(res['x:b'])
+    end
+
+    define_test "get should work with an array or arrays columns spec (yeah, crazy)" do
+      res = @test_table._get_internal('1', ['x:a'], ['x:b'])
+      assert_not_nil(res)
+      assert_kind_of(Hash, res)
+      assert_not_nil(res['x:a'])
+      assert_not_nil(res['x:b'])
+    end
+
+    define_test "get with a block should yield (column, value) pairs" do
+      res = {}
+      @test_table._get_internal('1') { |col, val| res[col] = val }
+      assert_equal(res.keys.sort, [ 'x:a', 'x:b' ])
+    end
+    
+    define_test "get should support COLUMNS with value CONVERTER information" do
+        @test_table.put(1, "x:c", [1024].pack('N'))
+        @test_table.put(1, "x:d", [98].pack('N'))
+        begin
+          res = @test_table._get_internal('1', ['x:c:toInt'], ['x:d:c(org.apache.hadoop.hbase.util.Bytes).toInt'])
+          assert_not_nil(res)
+          assert_kind_of(Hash, res)
+          assert_not_nil(/value=1024/.match(res['x:c']))
+          assert_not_nil(/value=98/.match(res['x:d']))
+        ensure
+          # clean up newly added columns for this test only.
+          @test_table.delete(1, "x:c")
+          @test_table.delete(1, "x:d")
+        end
+    end
+
+    define_test "get should support FILTER" do
+      @test_table.put(1, "x:v", "thisvalue")
+      begin
+        res = @test_table._get_internal('1', FILTER => "ValueFilter(=, 'binary:thisvalue')")
+        assert_not_nil(res)
+        assert_kind_of(Hash, res)
+        assert_not_nil(res['x:v'])
+        assert_nil(res['x:a'])
+        res = @test_table._get_internal('1', FILTER => "ValueFilter(=, 'binary:thatvalue')")
+        assert_nil(res)
+      ensure
+        # clean up newly added columns for this test only.
+        @test_table.delete(1, "x:v")
+      end
+    end
+
+    #-------------------------------------------------------------------------------
+
+    define_test "scan should work w/o any params" do
+      res = @test_table._scan_internal
+      assert_not_nil(res)
+      assert_kind_of(Hash, res)
+      assert_not_nil(res['1'])
+      assert_not_nil(res['1']['x:a'])
+      assert_not_nil(res['1']['x:b'])
+      assert_not_nil(res['2'])
+      assert_not_nil(res['2']['x:a'])
+      assert_not_nil(res['2']['x:b'])
+    end
+
+    define_test "scan should support STARTROW parameter" do
+      res = @test_table._scan_internal STARTROW => '2'
+      assert_not_nil(res)
+      assert_kind_of(Hash, res)
+      assert_nil(res['1'])
+      assert_not_nil(res['2'])
+      assert_not_nil(res['2']['x:a'])
+      assert_not_nil(res['2']['x:b'])
+    end
+
+    define_test "scan should support STOPROW parameter" do
+      res = @test_table._scan_internal STOPROW => '2'
+      assert_not_nil(res)
+      assert_kind_of(Hash, res)
+      assert_not_nil(res['1'])
+      assert_not_nil(res['1']['x:a'])
+      assert_not_nil(res['1']['x:b'])
+      assert_nil(res['2'])
+    end
+
+    define_test "scan should support LIMIT parameter" do
+      res = @test_table._scan_internal LIMIT => 1
+      assert_not_nil(res)
+      assert_kind_of(Hash, res)
+      assert_not_nil(res['1'])
+      assert_not_nil(res['1']['x:a'])
+      assert_not_nil(res['1']['x:b'])
+      assert_nil(res['2'])
+    end
+
+    define_test "scan should support TIMESTAMP parameter" do
+      res = @test_table._scan_internal TIMESTAMP => @test_ts
+      assert_not_nil(res)
+      assert_kind_of(Hash, res)
+      assert_not_nil(res['1'])
+      assert_nil(res['1']['x:a'])
+      assert_not_nil(res['1']['x:b'])
+      assert_not_nil(res['2'])
+      assert_nil(res['2']['x:a'])
+      assert_not_nil(res['2']['x:b'])
+    end
+
+    define_test "scan should support TIMERANGE parameter" do
+      res = @test_table._scan_internal TIMERANGE => [0, 1]
+      assert_not_nil(res)
+      assert_kind_of(Hash, res)
+      assert_nil(res['1'])
+      assert_nil(res['2'])
+    end
+
+    define_test "scan should support COLUMNS parameter with an array of columns" do
+      res = @test_table._scan_internal COLUMNS => [ 'x:a', 'x:b' ]
+      assert_not_nil(res)
+      assert_kind_of(Hash, res)
+      assert_not_nil(res['1'])
+      assert_not_nil(res['1']['x:a'])
+      assert_not_nil(res['1']['x:b'])
+      assert_not_nil(res['2'])
+      assert_not_nil(res['2']['x:a'])
+      assert_not_nil(res['2']['x:b'])
+    end
+
+    define_test "scan should support COLUMNS parameter with a single column name" do
+      res = @test_table._scan_internal COLUMNS => 'x:a'
+      assert_not_nil(res)
+      assert_kind_of(Hash, res)
+      assert_not_nil(res['1'])
+      assert_not_nil(res['1']['x:a'])
+      assert_nil(res['1']['x:b'])
+      assert_not_nil(res['2'])
+      assert_not_nil(res['2']['x:a'])
+      assert_nil(res['2']['x:b'])
+    end
+
+    define_test "scan should fail on invalid COLUMNS parameter types" do
+      assert_raise(ArgumentError) do
+        @test_table._scan_internal COLUMNS => {}
+      end
+    end
+
+    define_test "scan should fail on non-hash params" do
+      assert_raise(ArgumentError) do
+        @test_table._scan_internal 123
+      end
+    end
+
+    define_test "scan with a block should yield rows and return rows counter" do
+      rows = {}
+      res = @test_table._scan_internal { |row, cells| rows[row] = cells }
+      assert_equal(rows.keys.size, res)
+    end
+    
+    define_test "scan should support COLUMNS with value CONVERTER information" do
+      @test_table.put(1, "x:c", [1024].pack('N'))
+      @test_table.put(1, "x:d", [98].pack('N'))
+      begin
+        res = @test_table._scan_internal COLUMNS => ['x:c:toInt', 'x:d:c(org.apache.hadoop.hbase.util.Bytes).toInt']
+        assert_not_nil(res)
+        assert_kind_of(Hash, res)
+        assert_not_nil(/value=1024/.match(res['1']['x:c']))
+        assert_not_nil(/value=98/.match(res['1']['x:d']))
+      ensure
+        # clean up newly added columns for this test only.
+        @test_table.delete(1, "x:c")
+        @test_table.delete(1, "x:d")
+      end
+    end
+
+    define_test "scan should support FILTER" do
+      @test_table.put(1, "x:v", "thisvalue")
+      begin
+        res = @test_table._scan_internal FILTER => "ValueFilter(=, 'binary:thisvalue')"
+        assert_not_equal(res, {}, "Result is empty")
+        assert_kind_of(Hash, res)
+        assert_not_nil(res['1'])
+        assert_not_nil(res['1']['x:v'])
+        assert_nil(res['1']['x:a'])
+        assert_nil(res['2'])
+        res = @test_table._scan_internal FILTER => "ValueFilter(=, 'binary:thatvalue')"
+        assert_equal(res, {}, "Result is not empty")
+      ensure
+        # clean up newly added columns for this test only.
+        @test_table.delete(1, "x:v")
+      end
+    end
+
+  end
+end

Added: hbase/branches/0.96/hbase-shell/src/test/ruby/shell/commands_test.rb
URL: http://svn.apache.org/viewvc/hbase/branches/0.96/hbase-shell/src/test/ruby/shell/commands_test.rb?rev=1525642&view=auto
==============================================================================
--- hbase/branches/0.96/hbase-shell/src/test/ruby/shell/commands_test.rb (added)
+++ hbase/branches/0.96/hbase-shell/src/test/ruby/shell/commands_test.rb Mon Sep 23 16:45:42 2013
@@ -0,0 +1,34 @@
+#
+#
+# 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.
+#
+
+require 'hbase'
+require 'hbase/table'
+require 'shell'
+
+class ShellCommandsTest < Test::Unit::TestCase
+  Shell.commands.each do |name, klass|
+    define_test "#{name} command class #{klass} should respond to help" do
+      assert_respond_to(klass.new(nil), :help)
+    end
+
+    define_test "#{name} command class #{klass} should respond to :command" do
+      assert_respond_to(klass.new(nil), :command)
+    end
+  end
+end

Added: hbase/branches/0.96/hbase-shell/src/test/ruby/shell/formatter_test.rb
URL: http://svn.apache.org/viewvc/hbase/branches/0.96/hbase-shell/src/test/ruby/shell/formatter_test.rb?rev=1525642&view=auto
==============================================================================
--- hbase/branches/0.96/hbase-shell/src/test/ruby/shell/formatter_test.rb (added)
+++ hbase/branches/0.96/hbase-shell/src/test/ruby/shell/formatter_test.rb Mon Sep 23 16:45:42 2013
@@ -0,0 +1,68 @@
+#
+#
+# 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.
+#
+
+require 'shell/formatter'
+
+class ShellFormatterTest < Test::Unit::TestCase
+  # Helper method to construct a null formatter
+  def formatter
+    Shell::Formatter::Base.new(:output_stream => STDOUT)
+  end
+
+  #
+  # Constructor tests
+  #
+  define_test "Formatter constructor should not raise error valid IO streams" do
+    assert_nothing_raised do
+      Shell::Formatter::Base.new(:output_stream => STDOUT)
+    end
+  end
+
+  define_test "Formatter constructor should not raise error when no IO stream passed" do
+    assert_nothing_raised do
+      Shell::Formatter::Base.new()
+    end
+  end
+
+  define_test "Formatter constructor should raise error on non-IO streams" do
+    assert_raise TypeError do
+      Shell::Formatter::Base.new(:output_stream => 'foostring')
+    end
+  end
+
+  #-------------------------------------------------------------------------------------------------------
+  # Printing methods tests
+  # FIXME: The tests are just checking that the code has no typos, try to figure out a better way to test
+  #
+  define_test "Formatter#header should work" do
+    formatter.header(['a', 'b'])
+    formatter.header(['a', 'b'], [10, 20])
+  end
+
+  define_test "Formatter#row should work" do
+    formatter.row(['a', 'b'])
+    formatter.row(['xxxxxxxxx xxxxxxxxxxx xxxxxxxxxxx xxxxxxxxxxxx xxxxxxxxx xxxxxxxxxxxx xxxxxxxxxxxxxxx xxxxxxxxx xxxxxxxxxxxxxx'])
+    formatter.row(['yyyyyy yyyyyy yyyyy yyy', 'xxxxxxxxx xxxxxxxxxxx xxxxxxxxxxx xxxxxxxxxxxx xxxxxxxxx xxxxxxxxxxxx xxxxxxxxxxxxxxx xxxxxxxxx xxxxxxxxxxxxxx  xxx xx x xx xxx xx xx xx x xx x x xxx x x xxx x x xx x x x x x x xx '])
+    formatter.row(["NAME => 'table1', FAMILIES => [{NAME => 'fam2', VERSIONS => 3, COMPRESSION => 'NONE', IN_MEMORY => false, BLOCKCACHE => false, LENGTH => 2147483647, TTL => FOREVER, BLOOMFILTER => NONE}, {NAME => 'fam1', VERSIONS => 3, COMPRESSION => 'NONE', IN_MEMORY => false, BLOCKCACHE => false, LENGTH => 2147483647, TTL => FOREVER, BLOOMFILTER => NONE}]"])
+  end
+
+  define_test "Froematter#footer should work" do
+    formatter.footer(Time.now - 5)
+  end
+end

Added: hbase/branches/0.96/hbase-shell/src/test/ruby/shell/shell_test.rb
URL: http://svn.apache.org/viewvc/hbase/branches/0.96/hbase-shell/src/test/ruby/shell/shell_test.rb?rev=1525642&view=auto
==============================================================================
--- hbase/branches/0.96/hbase-shell/src/test/ruby/shell/shell_test.rb (added)
+++ hbase/branches/0.96/hbase-shell/src/test/ruby/shell/shell_test.rb Mon Sep 23 16:45:42 2013
@@ -0,0 +1,69 @@
+#
+#
+# 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.
+#
+
+require 'hbase'
+require 'shell'
+require 'shell/formatter'
+
+class ShellTest < Test::Unit::TestCase
+  def setup
+    @formatter = ::Shell::Formatter::Console.new()
+    @hbase = ::Hbase::Hbase.new($TEST_CLUSTER.getConfiguration)
+    @shell = Shell::Shell.new(@hbase, @formatter)
+  end
+
+  define_test "Shell::Shell#hbase_admin should return an admin instance" do
+    assert_kind_of(Hbase::Admin, @shell.hbase_admin)
+  end
+
+  define_test "Shell::Shell#hbase_admin should cache admin instances" do
+    assert_same(@shell.hbase_admin, @shell.hbase_admin)
+  end
+
+  #-------------------------------------------------------------------------------
+
+  define_test "Shell::Shell#hbase_table should return a table instance" do
+    assert_kind_of(Hbase::Table, @shell.hbase_table('hbase:meta'))
+  end
+
+  define_test "Shell::Shell#hbase_table should not cache table instances" do
+    assert_not_same(@shell.hbase_table('hbase:meta'), @shell.hbase_table('hbase:meta'))
+  end
+
+  #-------------------------------------------------------------------------------
+
+  define_test "Shell::Shell#export_commands should export command methods to specified object" do
+    module Foo; end
+    assert(!Foo.respond_to?(:version))
+    @shell.export_commands(Foo)
+    assert(Foo.respond_to?(:version))
+  end
+
+  #-------------------------------------------------------------------------------
+
+  define_test "Shell::Shell#command_instance should return a command class" do
+    assert_kind_of(Shell::Commands::Command, @shell.command_instance('version'))
+  end
+
+  #-------------------------------------------------------------------------------
+
+  define_test "Shell::Shell#command should execute a command" do
+    @shell.command('version')
+  end
+end

Added: hbase/branches/0.96/hbase-shell/src/test/ruby/test_helper.rb
URL: http://svn.apache.org/viewvc/hbase/branches/0.96/hbase-shell/src/test/ruby/test_helper.rb?rev=1525642&view=auto
==============================================================================
--- hbase/branches/0.96/hbase-shell/src/test/ruby/test_helper.rb (added)
+++ hbase/branches/0.96/hbase-shell/src/test/ruby/test_helper.rb Mon Sep 23 16:45:42 2013
@@ -0,0 +1,93 @@
+# 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.
+require 'test/unit'
+
+module Testing
+  module Declarative
+    # define_test "should do something" do
+    #   ...
+    # end
+    def define_test(name, &block)
+      test_name = "test_#{name.gsub(/\s+/,'_')}".to_sym
+      defined = instance_method(test_name) rescue false
+      raise "#{test_name} is already defined in #{self}" if defined
+      if block_given?
+        define_method(test_name, &block)
+      else
+        define_method(test_name) do
+          flunk "No implementation provided for #{name}"
+        end
+      end
+    end
+  end
+end
+
+module Hbase
+  module TestHelpers
+    require 'hbase'
+    require 'hbase/hbase'
+    require 'shell'
+    require 'shell/formatter'
+
+    def setup_hbase
+      formatter = ::Shell::Formatter::Console.new
+      hbase = ::Hbase::Hbase.new($TEST_CLUSTER.getConfiguration)
+      @shell = ::Shell::Shell.new(hbase, formatter)
+    end
+
+    def table(table)
+      @shell.hbase_table(table)
+    end
+
+    def admin
+      @shell.hbase_admin
+    end
+
+    def create_test_table(name)
+      # Create the table if needed
+      unless admin.exists?(name)
+        admin.create name, [{'NAME' => 'x', 'VERSIONS' => 5}, 'y']
+        return
+      end
+
+      # Enable the table if needed
+      unless admin.enabled?(name)
+        admin.enable(name)
+      end
+    end
+
+    def drop_test_table(name)
+      return unless admin.exists?(name)
+      begin
+        admin.disable(name) if admin.enabled?(name)
+      rescue => e
+        puts "IGNORING DISABLE TABLE ERROR: #{e}"
+      end
+      begin
+        admin.drop(name)
+      rescue => e
+        puts "IGNORING DROP TABLE ERROR: #{e}"
+      end
+    end
+  end
+end
+
+# Extend standard unit tests with our helpers
+Test::Unit::TestCase.extend(Testing::Declarative)
+
+# Add the $HBASE_HOME/lib/ruby directory to the ruby
+# load path so I can load up my HBase ruby modules
+$LOAD_PATH.unshift File.join(File.dirname(__FILE__), "..", "..", "main", "ruby")

Added: hbase/branches/0.96/hbase-shell/src/test/ruby/tests_runner.rb
URL: http://svn.apache.org/viewvc/hbase/branches/0.96/hbase-shell/src/test/ruby/tests_runner.rb?rev=1525642&view=auto
==============================================================================
--- hbase/branches/0.96/hbase-shell/src/test/ruby/tests_runner.rb (added)
+++ hbase/branches/0.96/hbase-shell/src/test/ruby/tests_runner.rb Mon Sep 23 16:45:42 2013
@@ -0,0 +1,65 @@
+#
+#
+# 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.
+#
+
+require 'rubygems'
+require 'rake'
+
+unless defined?($TEST_CLUSTER)
+  include Java
+
+  # Set logging level to avoid verboseness
+  org.apache.log4j.Logger.getRootLogger.setLevel(org.apache.log4j.Level::OFF)
+  org.apache.log4j.Logger.getLogger("org.apache.zookeeper").setLevel(org.apache.log4j.Level::OFF)
+  org.apache.log4j.Logger.getLogger("org.apache.hadoop.hdfs").setLevel(org.apache.log4j.Level::OFF)
+  org.apache.log4j.Logger.getLogger("org.apache.hadoop.hbase").setLevel(org.apache.log4j.Level::OFF)
+  org.apache.log4j.Logger.getLogger("org.apache.hadoop.ipc.HBaseServer").setLevel(org.apache.log4j.Level::OFF)
+
+  java_import org.apache.hadoop.hbase.HBaseTestingUtility
+
+  $TEST_CLUSTER = HBaseTestingUtility.new
+  $TEST_CLUSTER.configuration.setInt("hbase.regionserver.msginterval", 100)
+  $TEST_CLUSTER.configuration.setInt("hbase.client.pause", 250)
+  $TEST_CLUSTER.configuration.setInt(org.apache.hadoop.hbase.HConstants::HBASE_CLIENT_RETRIES_NUMBER, 6)
+  $TEST_CLUSTER.startMiniCluster
+  @own_cluster = true
+end
+
+require 'test_helper'
+
+puts "Running tests..."
+
+files = Dir[ File.dirname(__FILE__) + "/**/*_test.rb" ]
+files.each do |file|
+  begin
+    load(file)
+  rescue => e
+    puts "ERROR: #{e}"
+    raise
+  end
+end
+
+if !Test::Unit::AutoRunner.run
+  raise "Shell unit tests failed. Check output file for details."
+end
+
+puts "Done with tests! Shutting down the cluster..."
+if @own_cluster
+  $TEST_CLUSTER.shutdownMiniCluster
+  java.lang.System.exit(0)
+end

Modified: hbase/branches/0.96/pom.xml
URL: http://svn.apache.org/viewvc/hbase/branches/0.96/pom.xml?rev=1525642&r1=1525641&r2=1525642&view=diff
==============================================================================
--- hbase/branches/0.96/pom.xml (original)
+++ hbase/branches/0.96/pom.xml Mon Sep 23 16:45:42 2013
@@ -51,6 +51,7 @@
   <modules>
     <module>hbase-server</module>
     <module>hbase-thrift</module>
+    <module>hbase-shell</module>
     <module>hbase-protocol</module>
     <module>hbase-client</module>
     <module>hbase-hadoop-compat</module>
@@ -980,6 +981,18 @@
         <scope>test</scope>
       </dependency>
       <dependency>
+        <artifactId>hbase-shell</artifactId>
+        <groupId>org.apache.hbase</groupId>
+        <version>${project.version}</version>
+      </dependency>
+      <dependency>
+        <artifactId>hbase-shell</artifactId>
+        <groupId>org.apache.hbase</groupId>
+        <version>${project.version}</version>
+        <type>test-jar</type>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
         <artifactId>hbase-thrift</artifactId>
         <groupId>org.apache.hbase</groupId>
         <version>${project.version}</version>



Mime
View raw message