oklahoma_mixer 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,161 @@
1
+ require "test_helper"
2
+
3
+ class TestKeyRange < Test::Unit::TestCase
4
+ def teardown
5
+ remove_db_files
6
+ end
7
+
8
+ def test_b_tree_supports_non_range_key_requests
9
+ abc_db do |db|
10
+ assert_equal(%w[a b], db.keys(:limit => 2))
11
+ end
12
+ end
13
+
14
+ def test_keys_can_return_a_range_of_keys_for_a_b_tree_database
15
+ abc_db do |db|
16
+ assert_equal(%w[b c], db.keys(:range => "b".."c"))
17
+ end
18
+ end
19
+
20
+ def test_range_overrides_prefix_and_triggers_a_warning
21
+ abc_db do |db|
22
+ warning = capture_stderr do
23
+ # returns range
24
+ assert_equal(%w[b c], db.keys(:range => "b".."c", :prefix => "ignored"))
25
+ end
26
+ assert(!warning.empty?, "A warning was not issued for a range and prefix")
27
+ end
28
+
29
+ num_db do |db|
30
+ warning = capture_stderr do
31
+ # returns range
32
+ assert_equal([2, 3], db.keys(:range => 2..3, :prefix => "ignored"))
33
+ end
34
+ assert(!warning.empty?, "A warning was not issued for a range and prefix")
35
+ end
36
+ end
37
+
38
+ def test_b_tree_key_ranges_must_be_passed_a_range_object
39
+ abc_db do |db|
40
+ assert_nothing_raised(ArgumentError) do
41
+ db.keys(:range => "b".."c")
42
+ end
43
+ assert_raise(ArgumentError) do
44
+ db.keys(:range => "not a Range")
45
+ end
46
+ end
47
+ end
48
+
49
+ def test_boundaries_are_converted_to_strings_for_a_b_tree_database
50
+ abc_db do |db|
51
+ assert_equal(%w[b c], db.keys(:range => %w[b]..%w[c]))
52
+ end
53
+ end
54
+
55
+ def test_key_ranges_can_exclude_the_last_member_in_a_b_tree_database
56
+ abc_db do |db|
57
+ assert_equal(%w[b], db.keys(:range => "b"..."c"))
58
+ end
59
+ end
60
+
61
+ def test_key_ranges_can_exclude_the_first_member_in_a_b_tree_database
62
+ abc_db do |db|
63
+ assert_equal(%w[c], db.keys(:range => "b".."c", :exclude_start => true))
64
+ end
65
+ end
66
+
67
+ def test_key_ranges_can_use_values_between_keys_in_a_b_tree_database
68
+ abc_db do |db|
69
+ assert_equal(%w[b c], db.keys(:range => "ab".."f"))
70
+ end
71
+ end
72
+
73
+ def test_a_limit_can_be_set_for_key_ranges_in_a_b_tree_database
74
+ abc_db do |db|
75
+ assert_equal(%w[b], db.keys(:range => "b".."c", :limit => 1))
76
+ end
77
+ end
78
+
79
+ def test_range_queries_work_with_custom_ordering
80
+ bdb(:cmpfunc => lambda { |a, b| a.to_i <=> b.to_i }) do |db|
81
+ db.update(1 => :a, 11 => :b, 2 => :c)
82
+ assert_equal(%w[2 11], db.keys(:range => 2..100))
83
+ end
84
+ end
85
+
86
+ def test_fixed_length_supports_non_range_key_requests
87
+ num_db do |db|
88
+ assert_equal([1, 2], db.keys(:limit => 2))
89
+ end
90
+ end
91
+
92
+ def test_keys_can_return_a_range_of_keys_for_a_fixed_length_database
93
+ num_db do |db|
94
+ assert_equal([2, 3], db.keys(:range => 2..3))
95
+ end
96
+ end
97
+
98
+ def test_fixed_length_key_ranges_must_be_passed_a_range_or_array
99
+ num_db do |db|
100
+ assert_nothing_raised(ArgumentError) do
101
+ db.keys(:range => "min".."max")
102
+ end
103
+ assert_nothing_raised(ArgumentError) do
104
+ db.keys(:range => [:min, 100])
105
+ end
106
+ assert_raise(ArgumentError) do
107
+ db.keys(:range => "not a Range")
108
+ end
109
+ end
110
+ end
111
+
112
+ def test_boundaries_are_converted_to_integers_for_a_fixed_length_database
113
+ num_db do |db|
114
+ assert_equal([2, 3], db.keys(:range => "2".."3"))
115
+ end
116
+ end
117
+
118
+ def test_key_ranges_can_exclude_the_last_member_in_a_fixed_length_database
119
+ num_db do |db|
120
+ assert_equal([2], db.keys(:range => 2...3))
121
+ assert_equal([2], db.keys(:range => [2, 3], :exclude_end => true))
122
+ end
123
+ end
124
+
125
+ def test_key_ranges_can_exclude_the_first_member_in_a_fixed_length_database
126
+ num_db do |db|
127
+ assert_equal([3], db.keys(:range => 2..3, :exclude_start => true))
128
+ end
129
+ end
130
+
131
+ def test_key_ranges_can_use_values_between_keys_in_a_fixed_length_database
132
+ num_db do |db|
133
+ db.update(5 => 500, 6 => 600)
134
+ assert_equal([5, 6], db.keys(:range => 4..7))
135
+ end
136
+ end
137
+
138
+ def test_a_limit_can_be_set_for_key_ranges_in_a_fixed_length_database
139
+ num_db do |db|
140
+ assert_equal([2], db.keys(:range => 2..3, :limit => 1))
141
+ end
142
+ end
143
+
144
+ #######
145
+ private
146
+ #######
147
+
148
+ def abc_db
149
+ bdb do |db|
150
+ db.update(:a => 1, :b => 2, :c => 3)
151
+ yield db
152
+ end
153
+ end
154
+
155
+ def num_db
156
+ fdb do |db|
157
+ db.update(1 => 100, 2 => 200, 3 => 300)
158
+ yield db
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,122 @@
1
+ require "test_helper"
2
+
3
+ class TestOrder < Test::Unit::TestCase
4
+ REVERSE_ORDER_CMPFUNC = lambda { |a, b| a == "" ? a <=> b : b <=> a }
5
+
6
+ def teardown
7
+ remove_db_files
8
+ end
9
+
10
+ def test_b_tree_databases_default_to_lexical_ordering
11
+ bdb do |db|
12
+ db.update(:c => 3, :a => 1, :b => 2)
13
+ assert_equal(%w[a b c], db.keys)
14
+ assert_equal([%w[a 1], %w[b 2], %w[c 3]], db.to_a)
15
+ end
16
+
17
+ remove_db_files
18
+ bdb do |db|
19
+ db.update(1 => :a, 11 => :b, 2 => :c)
20
+ assert_equal(%w[1 11 2], db.keys)
21
+ assert_equal([%w[1 a], %w[11 b], %w[2 c]], db.to_a)
22
+ end
23
+ end
24
+
25
+ def test_b_tree_database_ordering_can_be_changed_with_a_comparison_function
26
+ bdb(:cmpfunc => REVERSE_ORDER_CMPFUNC) do |db|
27
+ db.update(:c => 3, :a => 1, :b => 2)
28
+ assert_equal(%w[c b a], db.keys)
29
+ assert_equal([%w[c 3], %w[b 2], %w[a 1]], db.to_a)
30
+ end
31
+
32
+ remove_db_files
33
+ cmpfunc = lambda { |a, b| a.to_i <=> b.to_i } # numerical order
34
+ bdb(:cmpfunc => cmpfunc) do |db|
35
+ db.update(1 => :a, 11 => :b, 2 => :c)
36
+ assert_equal(%w[1 2 11], db.keys)
37
+ assert_equal([%w[1 a], %w[2 c], %w[11 b]], db.to_a)
38
+ end
39
+ end
40
+
41
+ def test_each_key_iterates_through_keys_in_order_for_b_trees
42
+ assert_forward_iteration(%w[a b c], :each_key)
43
+ assert_reverse_iteration(%w[c b a], :each_key)
44
+ end
45
+
46
+ def test_each_iterates_through_key_value_pairs_in_order_for_b_trees
47
+ assert_forward_iteration([%w[a 1], %w[b 2], %w[c 3]], :each)
48
+ assert_reverse_iteration([%w[c 3], %w[b 2], %w[a 1]], :each)
49
+ end
50
+
51
+ def test_reverse_each_iterates_through_key_value_pairs_in_revserse_order
52
+ assert_forward_iteration([%w[c 3], %w[b 2], %w[a 1]], :reverse_each)
53
+ assert_reverse_iteration([%w[a 1], %w[b 2], %w[c 3]], :reverse_each)
54
+ end
55
+
56
+ def test_each_value_iterates_through_values_in_order_for_b_trees
57
+ assert_forward_iteration(%w[1 2 3], :each_value)
58
+ assert_reverse_iteration(%w[3 2 1], :each_value)
59
+ end
60
+
61
+ def test_delete_if_iterates_through_key_value_pairs_in_order_for_b_trees
62
+ assert_forward_iteration([%w[a 1], %w[b 2], %w[c 3]], :delete_if)
63
+ assert_reverse_iteration([%w[c 3], %w[b 2], %w[a 1]], :delete_if)
64
+ end
65
+
66
+ def test_fixed_length_databases_have_numerical_ordering_by_keys
67
+ fdb do |db|
68
+ db.update(3 => 300, 1 => 100, 2 => 200)
69
+ assert_equal([1, 2, 3], db.keys)
70
+ assert_equal([[1, "100"], [2, "200"], [3, "300"]], db.to_a)
71
+ end
72
+ end
73
+
74
+ def test_each_key_iterates_through_keys_in_order_for_fixed_lengths
75
+ assert_forward_iteration([1, 2, 3], :each_key, :fdb)
76
+ end
77
+
78
+ def test_each_iterates_through_key_value_pairs_in_order_for_fixed_lengths
79
+ assert_forward_iteration([[1, "100"], [2, "200"], [3, "300"]], :each, :fdb)
80
+ end
81
+
82
+ def test_each_value_iterates_through_values_in_order_for_fixed_lengths
83
+ assert_forward_iteration(%w[100 200 300], :each_value, :fdb)
84
+ end
85
+
86
+ def test_delete_if_iterates_through_key_value_pairs_in_order_for_fixed_lengths
87
+ assert_forward_iteration( [[1, "100"], [2, "200"], [3, "300"]],
88
+ :delete_if,
89
+ :fdb )
90
+ end
91
+
92
+ #######
93
+ private
94
+ #######
95
+
96
+ def assert_forward_iteration(expected_order, iterator, option = nil)
97
+ remove_db_files
98
+ if option == :fdb
99
+ fdb do |db|
100
+ db.update(3 => 300, 1 => 100, 2 => 200)
101
+ actual_order = [ ]
102
+ db.send(iterator) do |*args|
103
+ actual_order << (args.size == 1 ? args.first : args)
104
+ end
105
+ assert_equal(expected_order, actual_order)
106
+ end
107
+ else
108
+ bdb(:cmpfunc => option) do |db|
109
+ db.update(:c => 3, :a => 1, :b => 2)
110
+ actual_order = [ ]
111
+ db.send(iterator) do |*args|
112
+ actual_order << (args.size == 1 ? args.first : args)
113
+ end
114
+ assert_equal(expected_order, actual_order)
115
+ end
116
+ end
117
+ end
118
+
119
+ def assert_reverse_iteration(expected_order, iterator)
120
+ assert_forward_iteration(expected_order, iterator, REVERSE_ORDER_CMPFUNC)
121
+ end
122
+ end
@@ -0,0 +1,14 @@
1
+ module SharedBinaryData
2
+ def test_null_bytes_are_preserved_during_key_iteration
3
+ @db.each_key do |key|
4
+ assert_equal(@key, key)
5
+ end
6
+ end
7
+
8
+ def test_null_bytes_are_preserved_during_iteration
9
+ @db.each do |key, value|
10
+ assert_equal(@key, key)
11
+ assert_equal(@value, value)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,99 @@
1
+ module SharedIteration
2
+ def test_each_key_iterates_over_all_keys_in_the_database
3
+ @db.each_key do |key|
4
+ @keys.delete(key)
5
+ end
6
+ assert(@keys.empty?, "All keys were not iterated over")
7
+ end
8
+
9
+ def test_each_iterates_over_all_key_value_pairs_in_arrays
10
+ @db.each do |key_value_array|
11
+ assert_instance_of(Array, key_value_array)
12
+ assert_equal(2, key_value_array.size)
13
+ key, value = key_value_array
14
+ assert_equal(key * 2, value)
15
+ @keys.delete(key)
16
+ @values.delete(value)
17
+ end
18
+ assert( @keys.empty? && @values.empty?,
19
+ "All key/value pairs were not iterated over" )
20
+ end
21
+
22
+ def test_the_arrays_passed_to_each_can_be_split
23
+ @db.each do |key, value|
24
+ @keys.delete(key)
25
+ @values.delete(value)
26
+ end
27
+ assert( @keys.empty? && @values.empty?,
28
+ "All key/value pairs were not iterated over" )
29
+ end
30
+
31
+ def test_each_pair_is_an_alias_for_each
32
+ each_arrays = [ ]
33
+ @db.each do |array|
34
+ each_arrays << array
35
+ end
36
+ @db.each_pair do |array|
37
+ each_arrays.delete(array)
38
+ end
39
+ each_keys_and_values = [ ]
40
+ @db.each do |key, value|
41
+ each_keys_and_values << [key, value]
42
+ end
43
+ @db.each_pair do |key, value|
44
+ each_keys_and_values.delete([key, value])
45
+ end
46
+ assert( each_arrays.empty? && each_keys_and_values.empty?,
47
+ "The iterations did not match" )
48
+ end
49
+
50
+ def test_each_value_iterates_over_all_values_in_the_database
51
+ @db.each_value do |value|
52
+ @values.delete(value)
53
+ end
54
+ assert(@values.empty?, "All values were not iterated over")
55
+ end
56
+
57
+ def test_the_standard_iterators_are_supported
58
+ assert_kind_of(Enumerable, @db)
59
+
60
+ # examples
61
+ assert_equal(%w[b bb], @db.find { |_, value| value == "bb" })
62
+ assert_nil(@db.find { |_, value| value == "dd" })
63
+ assert_equal(%w[aaa bbb ccc], @db.map { |key, value| key + value }.sort)
64
+ assert( @db.any? { |_, value| value.include? "c" },
65
+ "A value was not found during iteration" )
66
+ end
67
+
68
+ def test_delete_if_removes_all_keys_for_which_the_block_returns_true
69
+ @db.delete_if { |key, _| key != "a" }
70
+ assert_equal([%w[a aa]], @db.to_a)
71
+ end
72
+
73
+ def test_iterators_return_self_to_match_hash_interface
74
+ %w[each_key each each_pair each_value delete_if].each do |iterator|
75
+ assert_equal(@db, @db.send(iterator) { })
76
+ end
77
+ end
78
+
79
+ def test_to_hash_converts_the_database_to_a_hash
80
+ assert_equal(Hash[*@keys.zip(@values).flatten], @db.to_hash)
81
+ end
82
+
83
+ def test_to_hash_keeps_a_default_object_by_default
84
+ @db.default = 0
85
+ assert_equal(0, @db.to_hash[:missing])
86
+ end
87
+
88
+ def test_to_hash_keeps_a_default_proc_by_default
89
+ @db.default = lambda { |key| "is #{key}" }
90
+ assert_equal("is missing", @db.to_hash[:missing])
91
+ end
92
+
93
+ def test_to_hash_can_be_told_to_ignore_a_default
94
+ @db.default = 0
95
+ assert_nil(@db.to_hash(false)[:missing])
96
+ @db.default = lambda { |key| "is #{key}" }
97
+ assert_nil(@db.to_hash(false)[:missing])
98
+ end
99
+ end
@@ -0,0 +1,91 @@
1
+ module SharedTuning
2
+ def test_a_mutex_can_be_activated_as_the_database_is_created
3
+ assert_option_calls([:setmutex], :mutex => true)
4
+ end
5
+
6
+ def test_a_size_can_be_set_for_extra_mapped_memory
7
+ size = rand(1_000) + 1
8
+ assert_option_calls([:setxmsiz, size], :xmsiz => size)
9
+ end
10
+
11
+ def test_extra_mapped_memory_size_is_converted_to_an_int
12
+ assert_option_calls([:setxmsiz, 42], :xmsiz => "42")
13
+ end
14
+
15
+ def test_a_step_unit_can_be_set_for_auto_defragmentation
16
+ unit = rand(1_000) + 1
17
+ assert_option_calls([:setdfunit, unit], :dfunit => unit)
18
+ end
19
+
20
+ def test_auto_defragmentation_step_unit_is_converted_to_an_int
21
+ assert_option_calls([:setdfunit, 42], :dfunit => "42")
22
+ end
23
+
24
+ def test_nested_transactions_can_be_ignored
25
+ db(:nested_transactions => :ignore) do |db|
26
+ result = db.transaction {
27
+ db.transaction { # ignored
28
+ 41
29
+ } + 1 # ignored
30
+ }
31
+ assert_equal(42, result)
32
+ end
33
+ end
34
+
35
+ def test_nested_transactions_can_be_set_to_fail_with_an_error
36
+ [:fail, :raise].each do |setting|
37
+ db(:nested_transactions => setting) do |db|
38
+ db.transaction do
39
+ assert_raise(OKMixer::Error::TransactionError) do
40
+ db.transaction { } # nested fails with error
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ def test_a_mode_string_can_be_passed
48
+ assert_raise(OKMixer::Error::CabinetError) do # file not found
49
+ db("r")
50
+ end
51
+ end
52
+
53
+ def test_the_mode_can_be_passed_as_as_option
54
+ assert_raise(OKMixer::Error::CabinetError) do # file not found
55
+ db(:mode => "r")
56
+ end
57
+ end
58
+
59
+ def test_an_option_mode_overrides_the_mode_argument_and_triggers_a_warning
60
+ warning = capture_stderr do
61
+ db("r", :mode => "wc") do
62
+ # just open and close
63
+ end
64
+ end
65
+ assert( !warning.empty?,
66
+ "A warning was not issued for an option mode with a mode argument" )
67
+ end
68
+
69
+ def test_an_unknown_mode_triggers_a_warning
70
+ warning = capture_stderr do
71
+ db("wcu") do
72
+ # just open and close
73
+ end
74
+ end
75
+ assert(!warning.empty?, "A warning was not issued for an unknown mode")
76
+ end
77
+
78
+ #######
79
+ private
80
+ #######
81
+
82
+ def assert_option_calls(c_call, options)
83
+ args = capture_args(lib, c_call[0]) do
84
+ db(options) do
85
+ # just open and close
86
+ end
87
+ end
88
+ assert_instance_of(FFI::Pointer, args[0])
89
+ assert_equal(c_call[1..-1], args[1..-1])
90
+ end
91
+ end