PageRenderTime 54ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/hbase-shell/src/test/ruby/hbase/table_test.rb

http://github.com/apache/hbase
Ruby | 869 lines | 702 code | 115 blank | 52 comment | 12 complexity | 7cd4fcf50354fa7f45daa351f8f8026d MD5 | raw file
Possible License(s): Apache-2.0, MIT
  1. #
  2. #
  3. # Licensed to the Apache Software Foundation (ASF) under one
  4. # or more contributor license agreements. See the NOTICE file
  5. # distributed with this work for additional information
  6. # regarding copyright ownership. The ASF licenses this file
  7. # to you under the Apache License, Version 2.0 (the
  8. # "License"); you may not use this file except in compliance
  9. # with the License. You may obtain a copy of the License at
  10. #
  11. # http://www.apache.org/licenses/LICENSE-2.0
  12. #
  13. # Unless required by applicable law or agreed to in writing, software
  14. # distributed under the License is distributed on an "AS IS" BASIS,
  15. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. # See the License for the specific language governing permissions and
  17. # limitations under the License.
  18. #
  19. require 'hbase_constants'
  20. module Hbase
  21. # Constructor tests
  22. class TableConstructorTest < Test::Unit::TestCase
  23. include TestHelpers
  24. include HBaseConstants
  25. def setup
  26. setup_hbase
  27. end
  28. def teardown
  29. shutdown
  30. end
  31. define_test "Hbase::Table constructor should not fail for existent tables" do
  32. assert_nothing_raised do
  33. table('hbase:meta').close()
  34. end
  35. end
  36. end
  37. # Helper methods tests
  38. class TableHelpersTest < Test::Unit::TestCase
  39. include TestHelpers
  40. def setup
  41. setup_hbase
  42. # Create test table if it does not exist
  43. @test_name = "hbase_shell_tests_table"
  44. create_test_table(@test_name)
  45. @test_table = table(@test_name)
  46. end
  47. def tearDown
  48. @test_table.close()
  49. shutdown
  50. end
  51. define_test "is_meta_table? method should return true for the meta table" do
  52. assert(table('hbase:meta').is_meta_table?)
  53. end
  54. define_test "is_meta_table? method should return false for a normal table" do
  55. assert(!@test_table.is_meta_table?)
  56. end
  57. #-------------------------------------------------------------------------------
  58. define_test "get_all_columns should return columns list" do
  59. cols = table('hbase:meta').get_all_columns
  60. assert_kind_of(Array, cols)
  61. assert(cols.length > 0)
  62. end
  63. #-------------------------------------------------------------------------------
  64. define_test "parse_column_name should not return a qualifier for name-only column specifiers" do
  65. col, qual = table('hbase:meta').parse_column_name('foo')
  66. assert_not_nil(col)
  67. assert_nil(qual)
  68. end
  69. define_test "parse_column_name should support and empty column qualifier" do
  70. col, qual = table('hbase:meta').parse_column_name('foo:')
  71. assert_not_nil(col)
  72. assert_not_nil(qual)
  73. end
  74. define_test "parse_column_name should return a qualifier for family:qualifier column specifiers" do
  75. col, qual = table('hbase:meta').parse_column_name('foo:bar')
  76. assert_not_nil(col)
  77. assert_not_nil(qual)
  78. end
  79. end
  80. # Simple data management methods tests
  81. class TableSimpleMethodsTest < Test::Unit::TestCase
  82. include TestHelpers
  83. include HBaseConstants
  84. def setup
  85. setup_hbase
  86. # Create test table if it does not exist
  87. @test_name = "hbase_shell_tests_table"
  88. create_test_table(@test_name)
  89. @test_table = table(@test_name)
  90. # Insert data to perform delete operations
  91. @test_table.put("102", "x:a", "2", 1212)
  92. @test_table.put(103, "x:a", "3", 1214)
  93. @test_table.put("104", "x:a", 5)
  94. @test_table.put("104", "x:b", 6)
  95. @test_table.put(105, "x:a", "3")
  96. @test_table.put(105, "x:a", "4")
  97. @test_table.put(106, "x:a", "3", 1588765900000)
  98. @test_table.put(106, "x:b", "4", 1588765900010)
  99. @test_table.put("111", "x:a", "5")
  100. @test_table.put("111", "x:b", "6")
  101. @test_table.put("112", "x:a", "5")
  102. end
  103. def teardown
  104. @test_table.close
  105. shutdown
  106. end
  107. define_test "put should work without timestamp" do
  108. @test_table.put("123", "x:a", "1")
  109. end
  110. define_test "put should work with timestamp" do
  111. @test_table.put("123", "x:a", "2", Time.now.to_i)
  112. end
  113. define_test "put should work with integer keys" do
  114. @test_table.put(123, "x:a", "3")
  115. end
  116. define_test "put should work with integer values" do
  117. @test_table.put("123", "x:a", 4)
  118. end
  119. define_test "put should work with attributes" do
  120. @test_table.put("123", "x:a", 4, {ATTRIBUTES=>{'mykey'=>'myvalue'}})
  121. end
  122. #-------------------------------------------------------------------------------
  123. define_test "delete should work with string keys" do
  124. @test_table.delete('102', 'x:a', 1212)
  125. res = @test_table._get_internal('102', 'x:a')
  126. assert_nil(res)
  127. end
  128. define_test "delete should work with integer keys" do
  129. res = @test_table._get_internal('103', 'x:a')
  130. assert_not_nil(res)
  131. @test_table.delete(103, 'x:a', 1214)
  132. res = @test_table._get_internal('103', 'x:a')
  133. assert_nil(res)
  134. end
  135. #-------------------------------------------------------------------------------
  136. define_test "deleteall should work w/o columns and timestamps" do
  137. @test_table.deleteall("104")
  138. res = @test_table._get_internal('104', 'x:a', 'x:b')
  139. assert_nil(res)
  140. end
  141. define_test "deleteall should work with timestamps but w/o columns" do
  142. @test_table.deleteall("106", "", 1588765900005)
  143. res = @test_table._get_internal('106', 'x:a')
  144. assert_nil(res)
  145. res = @test_table._get_internal('106', 'x:b')
  146. assert_not_nil(res)
  147. end
  148. define_test "deleteall should work with integer keys" do
  149. @test_table.deleteall(105)
  150. res = @test_table._get_internal('105', 'x:a')
  151. assert_nil(res)
  152. end
  153. define_test "deletall should work with row prefix" do
  154. @test_table.deleteall({ROWPREFIXFILTER => '11'})
  155. res1 = @test_table._get_internal('111')
  156. assert_nil(res1)
  157. res2 = @test_table._get_internal('112')
  158. assert_nil(res2)
  159. end
  160. define_test "append should work with value" do
  161. @test_table.append("123", 'x:cnt2', '123')
  162. assert_equal("123123", @test_table._append_internal("123", 'x:cnt2', '123'))
  163. end
  164. define_test 'append should work without qualifier' do
  165. @test_table.append('1001', 'x', '123')
  166. assert_equal('123321', @test_table._append_internal('1001', 'x', '321'))
  167. end
  168. #-------------------------------------------------------------------------------
  169. define_test 'incr should work without qualifier' do
  170. @test_table.incr('1010', 'x', 123)
  171. assert_equal(123, @test_table._get_counter_internal('1010', 'x'))
  172. @test_table.incr('1010', 'x', 123)
  173. assert_equal(246, @test_table._get_counter_internal('1010', 'x'))
  174. end
  175. define_test "get_counter should work with integer keys" do
  176. @test_table.incr(12345, 'x:cnt')
  177. assert_kind_of(Fixnum, @test_table._get_counter_internal(12345, 'x:cnt'))
  178. end
  179. define_test "get_counter should return nil for non-existent counters" do
  180. assert_nil(@test_table._get_counter_internal(12345, 'x:qqqq'))
  181. end
  182. end
  183. # Complex data management methods tests
  184. # rubocop:disable Metrics/ClassLength
  185. class TableComplexMethodsTest < Test::Unit::TestCase
  186. include TestHelpers
  187. include HBaseConstants
  188. def setup
  189. setup_hbase
  190. # Create test table if it does not exist
  191. @test_name = "hbase_shell_tests_table"
  192. create_test_table(@test_name)
  193. @test_table = table(@test_name)
  194. # Instert test data
  195. @test_ts = 12345678
  196. @test_table.put(1, "x:a", 1)
  197. @test_table.put(1, "x:b", 2, @test_ts)
  198. @test_table.put(1, "x:\x11", [921].pack("N"))
  199. @test_table.put(2, "x:a", 11)
  200. @test_table.put(2, "x:b", 12, @test_ts)
  201. @test_table.put(3, "x:a", 21, {ATTRIBUTES=>{'mykey'=>'myvalue'}})
  202. @test_table.put(3, "x:b", 22, @test_ts, {ATTRIBUTES=>{'mykey'=>'myvalue'}})
  203. end
  204. def teardown
  205. @test_table.close
  206. shutdown
  207. end
  208. define_test "count should work w/o a block passed" do
  209. assert(@test_table._count_internal > 0)
  210. end
  211. define_test "count should work with a block passed (and yield)" do
  212. rows = []
  213. cnt = @test_table._count_internal(1) do |cnt, row|
  214. rows << row
  215. end
  216. assert(cnt > 0)
  217. assert(!rows.empty?)
  218. end
  219. define_test "count should support STARTROW parameter" do
  220. count = @test_table.count STARTROW => '4'
  221. assert(count == 0)
  222. end
  223. define_test "count should support STOPROW parameter" do
  224. count = @test_table.count STOPROW => '0'
  225. assert(count == 0)
  226. end
  227. define_test "count should support COLUMNS parameter" do
  228. @test_table.put(4, "x:c", "31")
  229. begin
  230. count = @test_table.count COLUMNS => [ 'x:c']
  231. assert(count == 1)
  232. ensure
  233. @test_table.deleteall(4, 'x:c')
  234. end
  235. end
  236. define_test "count should support FILTER parameter" do
  237. count = @test_table.count FILTER => "ValueFilter(=, 'binary:11')"
  238. assert(count == 1)
  239. end
  240. #-------------------------------------------------------------------------------
  241. define_test "get should work w/o columns specification" do
  242. res = @test_table._get_internal('1')
  243. assert_not_nil(res)
  244. assert_kind_of(Hash, res)
  245. assert_not_nil(res['x:a'])
  246. assert_not_nil(res['x:b'])
  247. end
  248. define_test "get should work for data written with Attributes" do
  249. res = @test_table._get_internal('3')
  250. assert_not_nil(res)
  251. assert_kind_of(Hash, res)
  252. assert_not_nil(res['x:a'])
  253. assert_not_nil(res['x:b'])
  254. end
  255. define_test "get should work with integer keys" do
  256. res = @test_table._get_internal(1)
  257. assert_not_nil(res)
  258. assert_kind_of(Hash, res)
  259. assert_not_nil(res['x:a'])
  260. assert_not_nil(res['x:b'])
  261. end
  262. define_test "get should work with hash columns spec and a single string COLUMN parameter" do
  263. res = @test_table._get_internal('1', COLUMN => 'x:a')
  264. assert_not_nil(res)
  265. assert_kind_of(Hash, res)
  266. assert_not_nil(res['x:a'])
  267. assert_nil(res['x:b'])
  268. end
  269. define_test "get should work with hash columns spec and a single string COLUMNS parameter" do
  270. res = @test_table._get_internal('1', COLUMNS => 'x:a')
  271. assert_not_nil(res)
  272. assert_kind_of(Hash, res)
  273. assert_not_nil(res['x:a'])
  274. assert_nil(res['x:b'])
  275. end
  276. define_test "get should work with hash columns spec and an array of strings COLUMN parameter" do
  277. res = @test_table._get_internal('1', COLUMN => [ "x:\x11", 'x:a', 'x:b' ])
  278. assert_not_nil(res)
  279. assert_kind_of(Hash, res)
  280. assert_not_nil(res['x:\x11'])
  281. assert_not_nil(res['x:a'])
  282. assert_not_nil(res['x:b'])
  283. end
  284. define_test "get should work with hash columns spec and an array of strings COLUMNS parameter" do
  285. res = @test_table._get_internal('1', COLUMNS => [ 'x:a', 'x:b' ])
  286. assert_not_nil(res)
  287. assert_kind_of(Hash, res)
  288. assert_not_nil(res['x:a'])
  289. assert_not_nil(res['x:b'])
  290. end
  291. define_test "get should work with hash columns spec and an array of strings COLUMNS parameter with AUTHORIZATIONS" do
  292. res = @test_table._get_internal('1', COLUMNS => [ 'x:a', 'x:b' ], AUTHORIZATIONS=>['PRIVATE'])
  293. assert_not_nil(res)
  294. assert_kind_of(Hash, res)
  295. assert_not_nil(res['x:a'])
  296. assert_not_nil(res['x:b'])
  297. end
  298. define_test "get should work with non-printable columns and values" do
  299. res = @test_table._get_internal('1', COLUMNS => [ "x:\x11" ])
  300. assert_not_nil(res)
  301. assert_kind_of(Hash, res)
  302. assert_match(/value=\\x00\\x00\\x03\\x99/, res[ 'x:\x11' ])
  303. res = @test_table._get_internal('1', COLUMNS => [ "x:\x11:toInt" ])
  304. assert_not_nil(res)
  305. assert_kind_of(Hash, res)
  306. assert_match(/value=921/, res[ 'x:\x11' ])
  307. end
  308. define_test "get should work with hash columns spec and TIMESTAMP only" do
  309. res = @test_table._get_internal('1', TIMESTAMP => @test_ts)
  310. assert_not_nil(res)
  311. assert_kind_of(Hash, res)
  312. assert_nil(res['x:a'])
  313. assert_not_nil(res['x:b'])
  314. end
  315. define_test 'get should work with hash columns spec and TIMESTAMP and' \
  316. ' AUTHORIZATIONS' do
  317. res = @test_table._get_internal('1', TIMESTAMP => 1234, AUTHORIZATIONS=>['PRIVATE'])
  318. assert_nil(res)
  319. end
  320. define_test "get should fail with hash columns spec and strange COLUMN value" do
  321. assert_raise(ArgumentError) do
  322. @test_table._get_internal('1', COLUMN => {})
  323. end
  324. end
  325. define_test "get should fail with hash columns spec and strange COLUMNS value" do
  326. assert_raise(ArgumentError) do
  327. @test_table._get_internal('1', COLUMN => {})
  328. end
  329. end
  330. define_test "get should fail with hash columns spec and no TIMESTAMP or COLUMN[S]" do
  331. assert_raise(ArgumentError) do
  332. @test_table._get_internal('1', { :foo => :bar })
  333. end
  334. end
  335. define_test "get should work with a string column spec" do
  336. res = @test_table._get_internal('1', 'x:b')
  337. assert_not_nil(res)
  338. assert_kind_of(Hash, res)
  339. assert_nil(res['x:a'])
  340. assert_not_nil(res['x:b'])
  341. end
  342. define_test "get should work with an array columns spec" do
  343. res = @test_table._get_internal('1', 'x:a', 'x:b')
  344. assert_not_nil(res)
  345. assert_kind_of(Hash, res)
  346. assert_not_nil(res['x:a'])
  347. assert_not_nil(res['x:b'])
  348. end
  349. define_test "get should work with an array or arrays columns spec (yeah, crazy)" do
  350. res = @test_table._get_internal('1', ['x:a'], ['x:b'])
  351. assert_not_nil(res)
  352. assert_kind_of(Hash, res)
  353. assert_not_nil(res['x:a'])
  354. assert_not_nil(res['x:b'])
  355. end
  356. define_test "get with a block should yield (formatted column, value) pairs" do
  357. res = {}
  358. @test_table._get_internal('1') { |col, val| res[col] = val }
  359. assert_equal([ 'x:\x11', 'x:a', 'x:b' ], res.keys.sort)
  360. end
  361. define_test "get should support COLUMNS with value CONVERTER information" do
  362. @test_table.put(1, "x:c", [1024].pack('N'))
  363. @test_table.put(1, "x:d", [98].pack('N'))
  364. begin
  365. res = @test_table._get_internal('1', ['x:c:toInt'], ['x:d:c(org.apache.hadoop.hbase.util.Bytes).toInt'])
  366. assert_not_nil(res)
  367. assert_kind_of(Hash, res)
  368. assert_not_nil(/value=1024/.match(res['x:c']))
  369. assert_not_nil(/value=98/.match(res['x:d']))
  370. ensure
  371. # clean up newly added columns for this test only.
  372. @test_table.deleteall(1, 'x:c')
  373. @test_table.deleteall(1, 'x:d')
  374. end
  375. end
  376. define_test "get should support FILTER" do
  377. @test_table.put(1, "x:v", "thisvalue")
  378. begin
  379. res = @test_table._get_internal('1', FILTER => "ValueFilter(=, 'binary:thisvalue')")
  380. assert_not_nil(res)
  381. assert_kind_of(Hash, res)
  382. assert_not_nil(res['x:v'])
  383. assert_nil(res['x:a'])
  384. res = @test_table._get_internal('1', FILTER => "ValueFilter(=, 'binary:thatvalue')")
  385. assert_nil(res)
  386. ensure
  387. # clean up newly added columns for this test only.
  388. @test_table.deleteall(1, 'x:v')
  389. end
  390. end
  391. define_test 'get should work with a custom converter class' do
  392. @test_table.put(1, 'x:v', 1234)
  393. begin
  394. res = @test_table._get_internal('1', 'COLUMNS' =>
  395. ['x:v:c(org.apache.hadoop.hbase.util.Bytes).len'])
  396. assert_not_nil(res)
  397. assert_kind_of(Hash, res)
  398. assert_not_nil(res['x:v'])
  399. assert_not_nil(/value=4/.match(res['x:v']))
  400. ensure
  401. # clean up newly added columns for this test only.
  402. @test_table.deleteall(1, 'x:v')
  403. end
  404. end
  405. #-------------------------------------------------------------------------------
  406. define_test "scan should work w/o any params" do
  407. res = @test_table._scan_internal
  408. assert_not_nil(res)
  409. assert_kind_of(Hash, res)
  410. assert_not_nil(res['1'])
  411. assert_not_nil(res['1']['x:a'])
  412. assert_not_nil(res['1']['x:b'])
  413. assert_not_nil(res['2'])
  414. assert_not_nil(res['2']['x:a'])
  415. assert_not_nil(res['2']['x:b'])
  416. end
  417. define_test "scan should support STARTROW parameter" do
  418. res = @test_table._scan_internal STARTROW => '2'
  419. assert_not_nil(res)
  420. assert_kind_of(Hash, res)
  421. assert_nil(res['1'])
  422. assert_not_nil(res['2'])
  423. assert_not_nil(res['2']['x:a'])
  424. assert_not_nil(res['2']['x:b'])
  425. end
  426. define_test "scan should support STARTKEY parameter" do
  427. res = @test_table._scan_internal STARTKEY => '2'
  428. assert_not_nil(res)
  429. assert_kind_of(Hash, res)
  430. assert_nil(res['1'])
  431. assert_not_nil(res['2'])
  432. assert_not_nil(res['2']['x:a'])
  433. assert_not_nil(res['2']['x:b'])
  434. end
  435. define_test "scan should support STOPROW parameter" do
  436. res = @test_table._scan_internal STOPROW => '2'
  437. assert_not_nil(res)
  438. assert_kind_of(Hash, res)
  439. assert_not_nil(res['1'])
  440. assert_not_nil(res['1']['x:a'])
  441. assert_not_nil(res['1']['x:b'])
  442. assert_nil(res['2'])
  443. end
  444. define_test "scan should support ENDROW parameter" do
  445. res = @test_table._scan_internal ENDROW => '2'
  446. assert_not_nil(res)
  447. assert_kind_of(Hash, res)
  448. assert_not_nil(res['1'])
  449. assert_not_nil(res['1']['x:a'])
  450. assert_not_nil(res['1']['x:b'])
  451. assert_nil(res['2'])
  452. end
  453. define_test "scan should support ENDKEY parameter" do
  454. res = @test_table._scan_internal ENDKEY => '2'
  455. assert_not_nil(res)
  456. assert_kind_of(Hash, res)
  457. assert_not_nil(res['1'])
  458. assert_not_nil(res['1']['x:a'])
  459. assert_not_nil(res['1']['x:b'])
  460. assert_nil(res['2'])
  461. end
  462. define_test 'scan should support ROWPREFIXFILTER parameter (test 1)' do
  463. res = @test_table._scan_internal ROWPREFIXFILTER => '1'
  464. assert_not_nil(res)
  465. assert_kind_of(Hash, res)
  466. assert_not_nil(res['1'])
  467. assert_not_nil(res['1']['x:a'])
  468. assert_not_nil(res['1']['x:b'])
  469. assert_nil(res['2'])
  470. end
  471. define_test 'scan should support ROWPREFIXFILTER parameter (test 2)' do
  472. res = @test_table._scan_internal ROWPREFIXFILTER => '2'
  473. assert_not_nil(res)
  474. assert_kind_of(Hash, res)
  475. assert_nil(res['1'])
  476. assert_not_nil(res['2'])
  477. assert_not_nil(res['2']['x:a'])
  478. assert_not_nil(res['2']['x:b'])
  479. end
  480. define_test 'scan should support LIMIT parameter' do
  481. res = @test_table._scan_internal LIMIT => 1
  482. assert_not_nil(res)
  483. assert_kind_of(Hash, res)
  484. assert_not_nil(res['1'])
  485. assert_not_nil(res['1']['x:a'])
  486. assert_not_nil(res['1']['x:b'])
  487. assert_nil(res['2'])
  488. end
  489. define_test "scan should support REVERSED parameter" do
  490. res = @test_table._scan_internal REVERSED => true
  491. assert_not_nil(res)
  492. assert_kind_of(Hash, res)
  493. assert_not_nil(res['1'])
  494. assert_not_nil(res['1']['x:a'])
  495. assert_not_nil(res['1']['x:b'])
  496. assert_not_nil(res['2'])
  497. assert_not_nil(res['2']['x:a'])
  498. assert_not_nil(res['2']['x:b'])
  499. end
  500. define_test "scan should support TIMESTAMP parameter" do
  501. res = @test_table._scan_internal TIMESTAMP => @test_ts
  502. assert_not_nil(res)
  503. assert_kind_of(Hash, res)
  504. assert_not_nil(res['1'])
  505. assert_nil(res['1']['x:a'])
  506. assert_not_nil(res['1']['x:b'])
  507. assert_not_nil(res['2'])
  508. assert_nil(res['2']['x:a'])
  509. assert_not_nil(res['2']['x:b'])
  510. end
  511. define_test "scan should support TIMERANGE parameter" do
  512. res = @test_table._scan_internal TIMERANGE => [0, 1]
  513. assert_not_nil(res)
  514. assert_kind_of(Hash, res)
  515. assert_nil(res['1'])
  516. assert_nil(res['2'])
  517. end
  518. define_test "scan should support COLUMNS parameter with an array of columns" do
  519. res = @test_table._scan_internal COLUMNS => [ 'x:a', 'x:b' ]
  520. assert_not_nil(res)
  521. assert_kind_of(Hash, res)
  522. assert_not_nil(res['1'])
  523. assert_not_nil(res['1']['x:a'])
  524. assert_not_nil(res['1']['x:b'])
  525. assert_not_nil(res['2'])
  526. assert_not_nil(res['2']['x:a'])
  527. assert_not_nil(res['2']['x:b'])
  528. end
  529. define_test "scan should support COLUMNS parameter with a single column name" do
  530. res = @test_table._scan_internal COLUMNS => 'x:a'
  531. assert_not_nil(res)
  532. assert_kind_of(Hash, res)
  533. assert_not_nil(res['1'])
  534. assert_not_nil(res['1']['x:a'])
  535. assert_nil(res['1']['x:b'])
  536. assert_not_nil(res['2'])
  537. assert_not_nil(res['2']['x:a'])
  538. assert_nil(res['2']['x:b'])
  539. end
  540. define_test 'scan should support REGION_REPLICA_ID' do
  541. res = @test_table._scan_internal REGION_REPLICA_ID => 0
  542. assert_not_nil(res)
  543. end
  544. define_test 'scan should support ISOLATION_LEVEL' do
  545. res = @test_table._scan_internal ISOLATION_LEVEL => 'READ_COMMITTED'
  546. assert_not_nil(res)
  547. end
  548. define_test 'scan should support READ_TYPE parameter' do
  549. res = @test_table._scan_internal READ_TYPE => 'PREAD'
  550. assert_not_nil(res)
  551. res = @test_table._scan_internal READ_TYPE => 'STREAM'
  552. assert_not_nil(res)
  553. res = @test_table._scan_internal READ_TYPE => 'DEFAULT'
  554. assert_not_nil(res)
  555. end
  556. define_test 'scan should support ALLOW_PARTIAL_RESULTS' do
  557. res = @test_table._scan_internal ALLOW_PARTIAL_RESULTS => true
  558. assert_not_nil(res)
  559. end
  560. define_test "scan should work with raw and version parameter" do
  561. # Create test table if it does not exist
  562. @test_name_raw = "hbase_shell_tests_raw_scan"
  563. create_test_table(@test_name_raw)
  564. @test_table = table(@test_name_raw)
  565. # Instert test data
  566. @test_table.put(1, "x:a", 1)
  567. @test_table.put(2, "x:raw1", 11)
  568. @test_table.put(2, "x:raw1", 11)
  569. @test_table.put(2, "x:raw1", 11)
  570. @test_table.put(2, "x:raw1", 11)
  571. args = {}
  572. num_rows = 0
  573. @test_table._scan_internal(args) do # Normal Scan
  574. num_rows += 1
  575. end
  576. assert_equal(num_rows, 2,
  577. 'Num rows scanned without RAW/VERSIONS are not 2')
  578. args = { VERSIONS => 10, RAW => true } # Since 4 versions of row with rowkey 2 is been added, we can use any number >= 4 for VERSIONS to scan all 4 versions.
  579. num_rows = 0
  580. @test_table._scan_internal(args) do # Raw Scan
  581. num_rows += 1
  582. end
  583. # 5 since , 1 from row key '1' and other 4 from row key '4'
  584. assert_equal(num_rows, 5,
  585. 'Num rows scanned without RAW/VERSIONS are not 5')
  586. @test_table.delete(1, 'x:a')
  587. args = {}
  588. num_rows = 0
  589. @test_table._scan_internal(args) do # Normal Scan
  590. num_rows += 1
  591. end
  592. assert_equal(num_rows, 1,
  593. 'Num rows scanned without RAW/VERSIONS are not 1')
  594. args = { VERSIONS => 10, RAW => true }
  595. num_rows = 0
  596. @test_table._scan_internal(args) do # Raw Scan
  597. num_rows += 1
  598. end
  599. # 6 since , 2 from row key '1' and other 4 from row key '4'
  600. assert_equal(num_rows, 6,
  601. 'Num rows scanned without RAW/VERSIONS are not 5')
  602. end
  603. define_test "scan should fail on invalid COLUMNS parameter types" do
  604. assert_raise(ArgumentError) do
  605. @test_table._scan_internal COLUMNS => {}
  606. end
  607. end
  608. define_test "scan should fail on non-hash params" do
  609. assert_raise(ArgumentError) do
  610. @test_table._scan_internal 123
  611. end
  612. end
  613. define_test "scan with a block should yield rows and return rows counter" do
  614. rows = {}
  615. res = @test_table._scan_internal { |row, cells| rows[row] = cells }
  616. assert_equal([rows.keys.size,false], res)
  617. end
  618. define_test "scan should support COLUMNS with value CONVERTER information" do
  619. @test_table.put(1, "x:c", [1024].pack('N'))
  620. @test_table.put(1, "x:d", [98].pack('N'))
  621. @test_table.put(1, "x:\x11", [712].pack('N'))
  622. begin
  623. res = @test_table._scan_internal COLUMNS => ['x:c:toInt', 'x:d:c(org.apache.hadoop.hbase.util.Bytes).toInt', "x:\x11:toInt"]
  624. assert_not_nil(res)
  625. assert_kind_of(Hash, res)
  626. assert_match(/value=1024/, res['1']['x:c'])
  627. assert_match(/value=98/, res['1']['x:d'])
  628. assert_match(/value=712/, res['1']['x:\x11'])
  629. ensure
  630. # clean up newly added columns for this test only.
  631. @test_table.deleteall(1, 'x:c')
  632. @test_table.deleteall(1, 'x:d')
  633. end
  634. end
  635. define_test "scan should support FILTER" do
  636. @test_table.put(1, "x:v", "thisvalue")
  637. begin
  638. res = @test_table._scan_internal FILTER => "ValueFilter(=, 'binary:thisvalue')"
  639. assert_not_equal(res, {}, "Result is empty")
  640. assert_kind_of(Hash, res)
  641. assert_not_nil(res['1'])
  642. assert_not_nil(res['1']['x:v'])
  643. assert_nil(res['1']['x:a'])
  644. assert_nil(res['2'])
  645. res = @test_table._scan_internal FILTER => "ValueFilter(=, 'binary:thatvalue')"
  646. assert_equal(res, {}, "Result is not empty")
  647. ensure
  648. # clean up newly added columns for this test only.
  649. @test_table.deleteall(1, 'x:v')
  650. end
  651. end
  652. define_test "scan should support FILTER with non-ASCII bytes" do
  653. @test_table.put(4, "x:a", "\x82")
  654. begin
  655. res = @test_table._scan_internal FILTER => "SingleColumnValueFilter('x', 'a', >=, 'binary:\x82', true, true)"
  656. assert_not_equal(res, {}, "Result is empty")
  657. assert_kind_of(Hash, res)
  658. assert_not_nil(res['4'])
  659. assert_not_nil(res['4']['x:a'])
  660. assert_nil(res['1'])
  661. assert_nil(res['2'])
  662. ensure
  663. # clean up newly added columns for this test only.
  664. @test_table.deleteall(4, 'x:a')
  665. end
  666. end
  667. define_test "scan hbase meta table" do
  668. res = table("hbase:meta")._scan_internal
  669. assert_not_nil(res)
  670. end
  671. define_test 'scan should work with a custom converter class' do
  672. @test_table.put(1, 'x:v', 1234)
  673. begin
  674. res = @test_table._scan_internal 'COLUMNS' =>
  675. ['x:v:c(org.apache.hadoop.hbase.util.Bytes).len']
  676. assert_not_nil(res)
  677. assert_kind_of(Hash, res)
  678. assert_not_nil(res['1']['x:v'])
  679. assert_not_nil(/value=4/.match(res['1']['x:v']))
  680. ensure
  681. # clean up newly added columns for this test only.
  682. @test_table.deleteall(1, 'x:v')
  683. end
  684. end
  685. define_test "mutation with TTL should expire" do
  686. @test_table.put('ttlTest', 'x:a', 'foo', { TTL => 1000 } )
  687. begin
  688. res = @test_table._get_internal('ttlTest', 'x:a')
  689. assert_not_nil(res)
  690. sleep 2
  691. res = @test_table._get_internal('ttlTest', 'x:a')
  692. assert_nil(res)
  693. ensure
  694. @test_table.deleteall('ttlTest', 'x:a')
  695. end
  696. end
  697. define_test 'Split count for a table' do
  698. @test_table_name = 'table_with_splits'
  699. create_test_table_with_splits(@test_table_name, SPLITS => %w[10 20 30 40])
  700. @table = table(@test_table_name)
  701. splits = @table._get_splits_internal
  702. # Total splits is 5 but here count is 4 as we ignore implicit empty split.
  703. assert_equal(4, splits.size)
  704. assert_equal(%w[10 20 30 40], splits)
  705. drop_test_table(@test_table_name)
  706. end
  707. define_test 'Split count for a table by file' do
  708. @test_table_name = 'table_with_splits_file'
  709. @splits_file = 'target/generated-test-sources/splits.txt'
  710. File.exist?(@splits_file) && File.delete(@splits_file)
  711. file = File.new(@splits_file, 'w')
  712. %w[10 20 30 40].each { |item| file.puts item }
  713. file.close
  714. create_test_table_with_splits_file(@test_table_name,
  715. SPLITS_FILE => @splits_file)
  716. @table = table(@test_table_name)
  717. splits = @table._get_splits_internal
  718. # Total splits is 5 but here count is 4 as we ignore implicit empty split.
  719. assert_equal(4, splits.size)
  720. assert_equal(%w[10 20 30 40], splits)
  721. drop_test_table(@test_table_name)
  722. File.delete(@splits_file)
  723. end
  724. define_test 'Split count for a empty table' do
  725. splits = @test_table._get_splits_internal
  726. # Empty split should not be part of this array.
  727. assert_equal(0, splits.size)
  728. assert_equal([], splits)
  729. end
  730. define_test 'Split count for a table with region replicas' do
  731. @test_table_name = 'tableWithRegionReplicas'
  732. create_test_table_with_region_replicas(@test_table_name, 3,
  733. SPLITS => ['10'])
  734. @table = table(@test_table_name)
  735. splits = @table._get_splits_internal
  736. # In this case, total splits should be 1 even if the number of region
  737. # replicas is 3.
  738. assert_equal(1, splits.size)
  739. assert_equal(['10'], splits)
  740. drop_test_table(@test_table_name)
  741. end
  742. define_test "scan should throw an exception on a disabled table" do
  743. @test_table.disable
  744. begin
  745. assert_raise(RuntimeError) do
  746. @test_table.scan
  747. end
  748. ensure
  749. @test_table.enable
  750. end
  751. end
  752. end
  753. # rubocop:enable Metrics/ClassLength
  754. end