tem_mr_search 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,58 @@
1
+ require 'test/unit'
2
+ require 'tem_mr_search'
3
+
4
+ class MrTestCase < Test::Unit::TestCase
5
+ include Tem::Mr::Search
6
+
7
+ def setup
8
+ super
9
+
10
+ Thread.abort_on_exception = true
11
+
12
+ testdb_path = File.join File.dirname(__FILE__), "..", "testdata",
13
+ "fares.yml"
14
+ @db = Db.new testdb_path
15
+
16
+ @client_query = QueryBuilder.query { |q|
17
+ q.attributes :price => :tem_short, :start => :tem_short,
18
+ :end => :tem_short
19
+ q.id_attribute :flight
20
+
21
+ # Score: 200 + start / 100 - duration - price
22
+ q.map { |s|
23
+ s.ldwc 200
24
+ s.ldw :start
25
+ s.ldbc 100
26
+ s.div
27
+ s.add
28
+ s.ldw :end
29
+ s.ldw :start
30
+ s.sub
31
+ s.sub
32
+ s.ldw :price
33
+ s.sub
34
+ s.stw :score
35
+ }
36
+
37
+ # The greater score wins.
38
+ q.reduce { |s|
39
+ s.ldw :score1
40
+ s.ldw :score2
41
+ s.cmp
42
+ s.stw :comparison
43
+ }
44
+ }
45
+ end
46
+
47
+ def fare_score(fare)
48
+ 200 + fare['start'] / 100 - fare['price'] - (fare['end'] - fare['start'])
49
+ end
50
+
51
+ def fare_id(fare)
52
+ fare['flight']
53
+ end
54
+
55
+ # Ensures that everything has loaded.
56
+ def test_smoke
57
+ end
58
+ end
data/test/test_db.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'test/mr_test_case'
2
+
3
+ class DbTest < MrTestCase
4
+ def test_loading
5
+ assert_equal 4, @db.length, 'Number of items in the database'
6
+ gold_item = {'from' => 'BOS', 'to' => 'NYC', 'price' => 150, 'start' => 900,
7
+ 'end' => 1000, 'flight' => 15 }
8
+ assert_equal gold_item, @db.item(0), 'First database item'
9
+ end
10
+ end
@@ -0,0 +1,37 @@
1
+ require 'test/mr_test_case'
2
+
3
+ class MapReduceExecutorTest < MrTestCase
4
+ MRExecutor = Tem::Mr::Search::MapReduceExecutor
5
+
6
+ def setup
7
+ super
8
+ Tem.auto_conf
9
+ $tem.activate
10
+ $tem.emit
11
+ end
12
+
13
+ def _test_executor(tems, root_tem)
14
+ executor = MRExecutor.new @client_query, @db, tems, root_tem
15
+ packed_output = executor.execute
16
+ result = @client_query.unpack_output packed_output
17
+ assert_equal 18, result[:id], 'Incorrect Map-Reduce result'
18
+ end
19
+
20
+ def test_executor_with_autoconf
21
+ _test_executor [$tem], 0
22
+ end
23
+
24
+ def test_executor_with_cluster
25
+ cluster_config = ['lightbulb2.local', 'darkbulb.local'].map { |host|
26
+ Tem::MultiProxy::Client.query_tems host
27
+ }.flatten
28
+ assert_equal 8, cluster_config.length, 'Incorrect cluster setup'
29
+ tems = cluster_config.map do |config|
30
+ Tem::Session.new Tem::Transport::AutoConfigurator.try_transport(config)
31
+ end
32
+
33
+ tems.each { |tem| tem.activate; tem.emit }
34
+
35
+ _test_executor tems, 0
36
+ end
37
+ end
@@ -0,0 +1,45 @@
1
+ require 'test/mr_test_case'
2
+
3
+ class MapReduceJobTest < MrTestCase
4
+ def setup
5
+ super
6
+
7
+ @obj1 = @db.item 0
8
+ @obj2 = @db.item 1
9
+ @output1 = (1..16).to_a
10
+ @output2 = (17..32).to_a
11
+ end
12
+
13
+ def test_map_for_object
14
+ obj = @obj1.merge 'flight' => 0x12345678
15
+ secpack = @client_query.map_for_object obj
16
+
17
+ assert_equal [0, 0, 0, 0, 0x12, 0x34, 0x56, 0x78],
18
+ secpack.get_bytes(:_id, 8), 'Object ID embedded incorrectly'
19
+ assert_equal @obj1['price'], secpack.get_value(:price, :tem_short),
20
+ 'Price embedded incorrectly'
21
+ assert_equal @obj1['start'], secpack.get_value(:start, :tem_short),
22
+ 'Starting time embedded incorrectly'
23
+ assert_equal @obj1['end'], secpack.get_value(:end, :tem_short),
24
+ 'Ending time embedded incorrectly'
25
+ end
26
+
27
+ def test_reduce_for_outputs
28
+ secpack = @client_query.reduce_for_outputs @output1, @output2
29
+
30
+ assert_equal @output1, secpack.get_bytes(:_output1, 16),
31
+ 'Output1 embedded incorrectly'
32
+ assert_equal @output2, secpack.get_bytes(:_output2, 16),
33
+ 'Output2 embedded incorrectly'
34
+ end
35
+
36
+ def test_unpack_unencrypted_output
37
+ packed_output = [0, 0, 0, 0, 0x12, 0x34, 0x56, 0x78, 0x31, 0x41, 0xCC, 0xCD,
38
+ 0xCE, 0xBE, 0xEF, 0xFE]
39
+ output = @client_query.unpack_decrypted_output packed_output
40
+
41
+ assert_equal 0x12345678, output[:id], 'ID incorrectly unpacked'
42
+ assert_equal 0x3141, output[:score], 'Score incorrectly unpacked'
43
+ assert_equal [0xBE, 0xEF, 0xFE], output[:check], 'Check bytes'
44
+ end
45
+ end
@@ -0,0 +1,55 @@
1
+ require 'test/mr_test_case'
2
+ require 'yaml'
3
+
4
+ class MapReducePlannerTest < Test::Unit::TestCase
5
+ MRPlanner = Tem::Mr::Search::MapReducePlanner
6
+
7
+ def setup
8
+ @testdata_path = File.join(File.dirname(__FILE__), '..', 'testdata')
9
+ end
10
+
11
+ def parallel_planning(planner)
12
+ all_actions = []
13
+ until planner.done?
14
+ actions = planner.next_actions!
15
+ all_actions << actions
16
+ actions.each { |action| planner.action_done action }
17
+ end
18
+ all_actions
19
+ end
20
+
21
+ def serial_planning(planner)
22
+ all_actions = []
23
+ pending_actions = []
24
+ until planner.done?
25
+ actions = planner.next_actions!
26
+ all_actions << actions
27
+ pending_actions += actions
28
+ action = pending_actions.shift
29
+ planner.action_done action if action
30
+ end
31
+ all_actions
32
+ end
33
+
34
+ def _test_planning(method_name, items, tems, root_tem, gold_file)
35
+ planner = MRPlanner.new nil, items, tems, root_tem
36
+ all_actions = self.send method_name, planner
37
+ gold_actions = File.open(File.join(@testdata_path, gold_file), 'r') do |f|
38
+ YAML.load f
39
+ end
40
+ assert_equal gold_actions, all_actions, "Failed #{method_name}: " +
41
+ "#{tems} tems with root #{root_tem}, #{items} items"
42
+ assert_equal items * 2 - 1, planner.output_id, "Wrong final output_id"
43
+ end
44
+
45
+ def test_planning
46
+ [[:parallel_planning, 7, 4, 0, 'parallel_plan_740.yml'],
47
+ [:parallel_planning, 4, 3, 1, 'parallel_plan_431.yml'],
48
+ [:serial_planning, 4, 1, 0, 'serial_plan_410.yml'],
49
+ [:serial_planning, 7, 4, 0, 'serial_plan_740.yml'],
50
+ [:serial_planning, 4, 3, 1, 'serial_plan_431.yml'],
51
+ ].each do |testcase|
52
+ _test_planning *testcase
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,40 @@
1
+ require 'test/mr_test_case'
2
+
3
+ class QueryBuilderTest < MrTestCase
4
+ def setup
5
+ super
6
+ Tem.auto_conf
7
+ $tem.activate
8
+ $tem.emit
9
+ end
10
+
11
+ def _test_map_fare(fare)
12
+ enc_output = @client_query.map_object fare, $tem
13
+ output = @client_query.unpack_output enc_output
14
+ assert_equal fare_id(fare), output[:id], 'Object ID incorrectly encoded'
15
+ assert_equal fare_score(fare), output[:score],
16
+ 'Score incorrectly computed'
17
+ enc_output
18
+ end
19
+
20
+ def test_map_reduce
21
+ fare1 = @db.item 0
22
+ output1 = _test_map_fare fare1
23
+ fare2 = @db.item 1
24
+ output2 = _test_map_fare fare2
25
+
26
+ win_fare = (fare_score(fare1) > fare_score(fare2)) ? fare1 : fare2
27
+ # Try both permutations to ensure all branches of the reduce code work.
28
+ [[output1, output2], [output2, output1]].each do |o1, o2|
29
+ enc_output = @client_query.reduce_outputs o1, o2, $tem
30
+ output = @client_query.unpack_output enc_output
31
+ assert_equal fare_id(win_fare), output[:id], 'The wrong fare won (bad ID)'
32
+ assert_equal fare_score(win_fare), output[:score],
33
+ 'The wrong fare won (bad score)'
34
+ assert_equal [1, 2, 3], output[:check], 'Incorrect check bytes'
35
+
36
+ assert_not_equal enc_output, output1, 'Nonce fail'
37
+ assert_not_equal enc_output, output2, 'Nonce fail'
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,49 @@
1
+ ---
2
+ - from: BOS
3
+ to: NYC
4
+ price: 150
5
+ start: 900
6
+ end: 1000
7
+ flight: 15
8
+ - from: BOS
9
+ to: NYC
10
+ price: 150
11
+ start: 1800
12
+ end: 1900
13
+ flight: 16
14
+ - from: BOS
15
+ to: NYC
16
+ price: 200
17
+ start: 1200
18
+ end: 1245
19
+ flight: 17
20
+ - from: BOS
21
+ to: NYC
22
+ price: 200
23
+ start: 1700
24
+ end: 1745
25
+ flight: 18
26
+ - from: BOS
27
+ to: NYC
28
+ price: 160
29
+ start: 900
30
+ end: 1000
31
+ flight: 21
32
+ - from: BOS
33
+ to: NYC
34
+ price: 160
35
+ start: 1800
36
+ end: 1900
37
+ flight: 22
38
+ - from: BOS
39
+ to: NYC
40
+ price: 210
41
+ start: 1200
42
+ end: 1245
43
+ flight: 23
44
+ - from: BOS
45
+ to: NYC
46
+ price: 210
47
+ start: 1700
48
+ end: 1745
49
+ flight: 24
@@ -0,0 +1,52 @@
1
+ ---
2
+ - - :secpack: :mapper
3
+ :action: :migrate
4
+ :with: 1
5
+ :to: 0
6
+ - - :secpack: :mapper
7
+ :action: :migrate
8
+ :with: 0
9
+ :to: 2
10
+ - :secpack: :reducer
11
+ :action: :migrate
12
+ :with: 1
13
+ :to: 0
14
+ - - :secpack: :reducer
15
+ :action: :migrate
16
+ :with: 0
17
+ :to: 2
18
+ - :output_id: 0
19
+ :action: :map
20
+ :with: 1
21
+ :item: 0
22
+ - :output_id: 1
23
+ :action: :map
24
+ :with: 2
25
+ :item: 1
26
+ - - :output_id: 2
27
+ :action: :map
28
+ :with: 0
29
+ :item: 2
30
+ - :output_id: 3
31
+ :action: :map
32
+ :with: 1
33
+ :item: 3
34
+ - :output1_id: 0
35
+ :output2_id: 1
36
+ :output_id: 4
37
+ :action: :reduce
38
+ :with: 2
39
+ - - :output1_id: 2
40
+ :output2_id: 3
41
+ :output_id: 5
42
+ :action: :reduce
43
+ :with: 0
44
+ - - :output1_id: 4
45
+ :output2_id: 5
46
+ :output_id: 6
47
+ :action: :reduce
48
+ :with: 0
49
+ - - :output_id: 6
50
+ :action: :finalize
51
+ :with: 1
52
+ :final_id: 7
@@ -0,0 +1,87 @@
1
+ ---
2
+ - - :secpack: :mapper
3
+ :action: :migrate
4
+ :with: 0
5
+ :to: 1
6
+ - - :secpack: :mapper
7
+ :action: :migrate
8
+ :with: 0
9
+ :to: 2
10
+ - :secpack: :mapper
11
+ :action: :migrate
12
+ :with: 1
13
+ :to: 3
14
+ - - :secpack: :reducer
15
+ :action: :migrate
16
+ :with: 0
17
+ :to: 1
18
+ - :output_id: 0
19
+ :action: :map
20
+ :with: 1
21
+ :item: 0
22
+ - :output_id: 1
23
+ :action: :map
24
+ :with: 2
25
+ :item: 1
26
+ - :output_id: 2
27
+ :action: :map
28
+ :with: 3
29
+ :item: 2
30
+ - - :secpack: :reducer
31
+ :action: :migrate
32
+ :with: 0
33
+ :to: 2
34
+ - :secpack: :reducer
35
+ :action: :migrate
36
+ :with: 1
37
+ :to: 3
38
+ - :output_id: 3
39
+ :action: :map
40
+ :with: 2
41
+ :item: 3
42
+ - :output_id: 4
43
+ :action: :map
44
+ :with: 3
45
+ :item: 4
46
+ - - :output_id: 5
47
+ :action: :map
48
+ :with: 0
49
+ :item: 5
50
+ - :output_id: 6
51
+ :action: :map
52
+ :with: 1
53
+ :item: 6
54
+ - :output1_id: 0
55
+ :output2_id: 1
56
+ :output_id: 7
57
+ :action: :reduce
58
+ :with: 2
59
+ - :output1_id: 2
60
+ :output2_id: 3
61
+ :output_id: 8
62
+ :action: :reduce
63
+ :with: 3
64
+ - - :output1_id: 4
65
+ :output2_id: 5
66
+ :output_id: 9
67
+ :action: :reduce
68
+ :with: 0
69
+ - :output1_id: 6
70
+ :output2_id: 7
71
+ :output_id: 10
72
+ :action: :reduce
73
+ :with: 1
74
+ - - :output1_id: 8
75
+ :output2_id: 9
76
+ :output_id: 11
77
+ :action: :reduce
78
+ :with: 0
79
+ - - :output1_id: 10
80
+ :output2_id: 11
81
+ :output_id: 12
82
+ :action: :reduce
83
+ :with: 0
84
+ - - :output_id: 12
85
+ :action: :finalize
86
+ :with: 0
87
+ :final_id: 13
@@ -0,0 +1,36 @@
1
+ ---
2
+ - - :output_id: 0
3
+ :action: :map
4
+ :with: 0
5
+ :item: 0
6
+ - - :output_id: 1
7
+ :action: :map
8
+ :with: 0
9
+ :item: 1
10
+ - - :output_id: 2
11
+ :action: :map
12
+ :with: 0
13
+ :item: 2
14
+ - - :output_id: 3
15
+ :action: :map
16
+ :with: 0
17
+ :item: 3
18
+ - - :output1_id: 0
19
+ :output2_id: 1
20
+ :output_id: 4
21
+ :action: :reduce
22
+ :with: 0
23
+ - - :output1_id: 2
24
+ :output2_id: 3
25
+ :output_id: 5
26
+ :action: :reduce
27
+ :with: 0
28
+ - - :output1_id: 4
29
+ :output2_id: 5
30
+ :output_id: 6
31
+ :action: :reduce
32
+ :with: 0
33
+ - - :output_id: 6
34
+ :action: :finalize
35
+ :with: 0
36
+ :final_id: 7
@@ -0,0 +1,56 @@
1
+ ---
2
+ - - :secpack: :mapper
3
+ :action: :migrate
4
+ :with: 1
5
+ :to: 0
6
+ - - :secpack: :mapper
7
+ :action: :migrate
8
+ :with: 0
9
+ :to: 2
10
+ - :secpack: :reducer
11
+ :action: :migrate
12
+ :with: 1
13
+ :to: 0
14
+ - - :output_id: 0
15
+ :action: :map
16
+ :with: 0
17
+ :item: 0
18
+ - :output_id: 1
19
+ :action: :map
20
+ :with: 2
21
+ :item: 1
22
+ - - :secpack: :reducer
23
+ :action: :migrate
24
+ :with: 1
25
+ :to: 2
26
+ - - :output_id: 2
27
+ :action: :map
28
+ :with: 0
29
+ :item: 2
30
+ - - :output_id: 3
31
+ :action: :map
32
+ :with: 2
33
+ :item: 3
34
+ - - :output1_id: 0
35
+ :output2_id: 1
36
+ :output_id: 4
37
+ :action: :reduce
38
+ :with: 1
39
+ - []
40
+
41
+ - - :output1_id: 2
42
+ :output2_id: 3
43
+ :output_id: 5
44
+ :action: :reduce
45
+ :with: 0
46
+ - []
47
+
48
+ - - :output1_id: 4
49
+ :output2_id: 5
50
+ :output_id: 6
51
+ :action: :reduce
52
+ :with: 0
53
+ - - :output_id: 6
54
+ :action: :finalize
55
+ :with: 1
56
+ :final_id: 7
@@ -0,0 +1,93 @@
1
+ ---
2
+ - - :secpack: :mapper
3
+ :action: :migrate
4
+ :with: 0
5
+ :to: 1
6
+ - - :secpack: :mapper
7
+ :action: :migrate
8
+ :with: 0
9
+ :to: 2
10
+ - :secpack: :mapper
11
+ :action: :migrate
12
+ :with: 1
13
+ :to: 3
14
+ - - :secpack: :reducer
15
+ :action: :migrate
16
+ :with: 0
17
+ :to: 1
18
+ - :output_id: 0
19
+ :action: :map
20
+ :with: 2
21
+ :item: 0
22
+ - - :output_id: 1
23
+ :action: :map
24
+ :with: 1
25
+ :item: 1
26
+ - :output_id: 2
27
+ :action: :map
28
+ :with: 3
29
+ :item: 2
30
+ - - :secpack: :reducer
31
+ :action: :migrate
32
+ :with: 0
33
+ :to: 2
34
+ - - :output_id: 3
35
+ :action: :map
36
+ :with: 2
37
+ :item: 3
38
+ - - :secpack: :reducer
39
+ :action: :migrate
40
+ :with: 1
41
+ :to: 3
42
+ - - :output_id: 4
43
+ :action: :map
44
+ :with: 3
45
+ :item: 4
46
+ - - :output_id: 5
47
+ :action: :map
48
+ :with: 0
49
+ :item: 5
50
+ - - :output_id: 6
51
+ :action: :map
52
+ :with: 2
53
+ :item: 6
54
+ - - :output1_id: 0
55
+ :output2_id: 1
56
+ :output_id: 7
57
+ :action: :reduce
58
+ :with: 1
59
+ - - :output1_id: 2
60
+ :output2_id: 3
61
+ :output_id: 8
62
+ :action: :reduce
63
+ :with: 3
64
+ - - :output1_id: 4
65
+ :output2_id: 5
66
+ :output_id: 9
67
+ :action: :reduce
68
+ :with: 0
69
+ - []
70
+
71
+ - - :output1_id: 6
72
+ :output2_id: 7
73
+ :output_id: 10
74
+ :action: :reduce
75
+ :with: 1
76
+ - []
77
+
78
+ - - :output1_id: 8
79
+ :output2_id: 9
80
+ :output_id: 11
81
+ :action: :reduce
82
+ :with: 0
83
+ - []
84
+
85
+ - - :output1_id: 10
86
+ :output2_id: 11
87
+ :output_id: 12
88
+ :action: :reduce
89
+ :with: 0
90
+ - - :output_id: 12
91
+ :action: :finalize
92
+ :with: 0
93
+ :final_id: 13