new world
[rubydium.git] / baby / testing.rb
blob67f824def5c4a8564aeb4cabebc64ef4d1359216
1 require "test/unit"
2 require "src/dispatcher.rb"
3 $enable_cache = false
4 require "tempfile"
6 module TestMod
8    def do_blah src, expected, expected_counts = nil
9       if expected.nil?
10          tempfile = Tempfile.new "rblex_test"
11          tempfile.write <<EOF
12 class Object
13    def alloc_self
14       @data = []
15    end
16    def set a, b
17       @data[a] = b
18    end
19    def dset a, b
20       @data[a] = b
21    end
22    def dget a
23       @data[a]
24    end
25    def get a
26       @data[a]
27    end
28    def set_self string
29       @data = [string.length]
30       string.each_byte { |b| @data << b }
31    end
32 end
33 module Kernel
34    def pi integer
35       puts integer.to_s
36    end
37    def putch byte
38       Kernel.print byte.chr
39    end
40 end
41 EOF
42          tempfile.write src
43          tempfile.close
44             expected = `bash -c "ruby #{tempfile.path} 2>&1"`
45       end
46       $str_buffer = ""
47       t = Context.new
48       machine = EvalMachine.new t, src
49       machine.execute
50       if $debug
51          puts "OUTPUT:"
52          puts $str_buffer
53       end
54       $boo.each {
55          |meth|
56          method(meth).call(machine)
57       }
58       if !$debug
59          if expected.is_a? Regexp
60             assert_equal [expected, !(expected =~ $str_buffer).nil?], [expected, true]
61          else 
62             assert_equal expected, $str_buffer
63          end
64       end
65       actual = "actual: [#{machine.number_of_instructions_executed}, #{machine.number_of_generated_instructions}]"
66       fail "no expected counts given!, #{actual}" \
67          if expected_counts.nil?
68       diff = (machine.number_of_instructions_executed-expected_counts[0]).abs
69       error_ratio = diff.to_f / machine.number_of_instructions_executed.to_f
70       if error_ratio > 0.03
71          fail "error perc.: #{(error_ratio * 100).to_i}%, #{actual} vs expected #{expected_counts.inspect}"
72       end
73       fail "number_of_generated_instructions did not match! #{actual}" \
74          if expected_counts[1] != machine.number_of_generated_instructions
75    end
77    def do_test ctx, string, should_be
78       execute_string ctx, string
79       assert_equal should_be, $str_buffer
80   end
82    def fmt machine, tuple, func
83       return "initial" if tuple.nil?
84       node = machine.crawler.find_path machine.crawler.id2path(tuple[1])
85       desc = node.inspect
86       pp func
87       exit
88       "#{tuple[0]} - #{tuple[1]} [#{desc[0..20]}]"
89    end
91    # TODO items - word ( => ) wrap the hashes / which will eventualy be structs, so, figure out word wrapping for those too
93    def dump_null machine
94    end
95    
96    def dump_summary machine
97       if $debug
98          puts "Total number of instructions in all functions: #{machine.number_of_generated_instructions}"
99          puts "Total number of instructions executed: #{machine.number_of_instructions_executed}"
100       end
101    end
103     def self.metadata_dump machine
104       puts "Reporting on in cached function metadata"
105       machine.func_cache.each_pair {
106          |id, atom|
107          next unless id.is_a? Integer
108          print "IS : #{machine.crawler.paths2orderdesc atom.func.metadata[:path_range].map { |id| machine.crawler.id2path id }}"
109          print "JUMPS TO : #{machine.crawler.paths2orderdesc atom.func.metadata[:statically_dispatches_to].map { |(id, pos)| machine.crawler.id2path id }}" if atom.func.metadata[:statically_dispatches_to]
110          puts "=> ("
111          pp machine.metadata_inspect(atom.func.metadata)
112          puts ")"
113       }
114    end
116    def self.dump_max_point machine
117       self.metadata_dump machine
118       last = 0
119       shifted_log = machine.time_vs_instructions_log.slice(1..-1)
120       diffs = []
121       machine.time_vs_instructions_log.zip(shifted_log) { |arr| a,b = *arr; diffs << (b[1]-a[1]).abs unless b.nil? }
122       max_point = diffs.max
123       puts "non unique max point! o_O" if diffs.index(max_point) != diffs.rindex(max_point)
124       idx = diffs.index max_point 
125       puts "LOG"
126       p machine.time_vs_instructions_log
127       puts "POINT OF MAX"
128       p idx
129       puts "COUNT DIFFS"
130       p diffs
131       puts "MAX INFO"
132       p machine.time_vs_instructions_log[idx]
133       exit if $debug
134    end
136    def dump_asm machine
137       machine.old_functions.each {
138          |func|
139          dump_instructions func
140       }
141    end
143    def dump_profile machine
144       line2count = Hash.new { 0 }
145       machine.old_functions.each {
146          |func|
147          next if func.profile_hash.nil?
148          func.profile_hash.each_pair {
149             |key,val|
150             line = func.metadata[:caller_map][key]
151             line2count[line] += val
152          }
153       }
154       require 'pp'
155       line2count.inject([]) { |a,(k,d)| a << [k, d] }
156       pp line2count.sort_by { |(a,b)| b }
157       dump_summary machine
158    end
160    def dump_graph machine
161       nodes = ""
162       machine.func_cache.each_pair {
163          |id, atom|
164          next unless id.is_a? Integer
165          atom.func.metadata[:path_range].each {
166             |sid|
167             curr = [atom.func.object_id, sid]
168             nodes << "\"#{fmt machine, curr, atom.func}\" [color=green];"
169          }
170       }
171       machine.import_from_trace_stack
172       first_iteration = true
173       execution_log = []
174       boo = proc {
175          |func|
176          execution_log << func
177       }
178       machine.trace_stack_history.each {
179          |trace_stack|
180          machine.trace_stack_iterator(trace_stack.dat) {
181             |old_func, new_func|
182             boo.call old_func if first_iteration
183             boo.call new_func
184             first_iteration = false
185          }
186       }
187       prev = nil
188       idx = 0
189       execution_log.each {
190          |t|
191          curr = [t.object_id, machine.md_get_id(t)]
192          nodes << "\"#{fmt machine, prev, t}\" -> \"#{fmt machine, curr, t}\" [color=green label=\"#{idx}\"];"
193          prev = curr
194          idx += 1
195       }
196       tf = File.open "/tmp/blah.dot", "w"
197       desc = "\"#{machine.crawler.paths2orderdesc(machine.ast_order).gsub(/\n\s*#/m,"#").gsub("\n","\\n")}\" [color=blue shape=plaintext];"
198       tf.write <<EOF
199 digraph Viewfile {
200 node [ style = filled ];
201 #{nodes}
202 #{desc}
203 \"#{machine.source.gsub("\n","\\n")} [shape=plaintext]\"
206       tf.close
207       `open /tmp/blah.dot`
208       exit
209    end