Class: Toaster::TestGenerator

Inherits:
Object
  • Object
show all
Defined in:
lib/toaster/test/test_generator.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(test_suite, state_graph = nil) ⇒ TestGenerator

Returns a new instance of TestGenerator.



18
19
20
21
22
23
24
25
26
# File 'lib/toaster/test/test_generator.rb', line 18

def initialize(test_suite, state_graph = nil)
  @state_graph = state_graph
  @test_suite = test_suite
  @automation = test_suite.automation
  if !state_graph
    @state_graph = StateTransitionGraph.build_graph_for_test_suite(@test_suite)
  end
  @coverage = TestCoverage.new(@test_suite, @state_graph)
end

Instance Attribute Details

#state_graphObject

Returns the value of attribute state_graph.



16
17
18
# File 'lib/toaster/test/test_generator.rb', line 16

def state_graph
  @state_graph
end

#test_suiteObject

Returns the value of attribute test_suite.



16
17
18
# File 'lib/toaster/test/test_generator.rb', line 16

def test_suite
  @test_suite
end

Instance Method Details

#default_test_caseObject



28
29
30
31
# File 'lib/toaster/test/test_generator.rb', line 28

def default_test_case()
  c = TestCase.new(:test_suite => @test_suite)
  return c
end

#gen_all_testsObject



84
85
86
87
88
89
90
91
92
93
# File 'lib/toaster/test/test_generator.rb', line 84

def gen_all_tests()
  cvg_goal = @test_suite.coverage_goal
  if cvg_goal.graph == StateGraphCoverage::STATES
    return gen_test_each_state()
  elsif cvg_goal.graph == StateGraphCoverage::TRANSITIONS
    return gen_test_each_transition()
  end
  puts "WARN: Coverage goal should be either STATES or TRANSITIONS."
  return []
end

#gen_param_combinations(all_params, current = {}, result = Set.new) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/toaster/test/test_generator.rb', line 61

def gen_param_combinations(all_params, current={}, result=Set.new)
  if all_params.empty?
    result << current
    return result
  end
  all_params_new = all_params.dup
  this_param = all_params_new[0]
  all_params_new.delete(this_param)
  key = this_param.key

  @test_suite.parameter_test_values[key].each do |val|
    new_cur = current.clone()
    new_cur[key] = val
    gen_param_combinations(all_params_new, new_cur, result)
  end
  
  return result
end

#gen_test_each_state(max_node_occurrences = 2) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/toaster/test/test_generator.rb', line 95

def gen_test_each_state(max_node_occurrences=2)
  result = []
  all_states = state_graph.nodes
  covered_states = Set.new
  covered_states << @state_graph.start_node
  problem_states = []
  while covered_states.size + problem_states.size < all_states.size
    state_to_cover = (all_states - problem_states - covered_states).to_a[0]
    path = do_create_path([state_to_cover], max_node_occurrences)
    if !path
      puts "INFO: problem state detected: #{state_to_cover}"
      state_to_cover.outgoing.each do |e|
        #puts "#{state_to_cover} --> #{e.node_to}"
        e.node_to.outgoing.each do |e1|
          #puts "#{e.node_to} ==> #{e1.node_to}"
        end
      end
      state_to_cover.incoming.each do |e|
        #puts "#{e.node_from} ~~> #{state_to_cover}"
      end
      problem_states << state_to_cover
    else
      covered_states.merge(path.collect { |e| e.node_to } )
      tasks = get_task_sequence(path)
      c = TestCase.new(:test_suite => @test_suite)
      #puts "DEBUG: sequence of tasks for test case: #{tasks.collect {|t| t.uuid}}"
      c.repeat_task_uuids = gen_repeat_config(tasks)
      #puts "DEBUG: repeat tasks: #{c.repeat_task_uuids}"
      params = {}
      path.each do |edge|
        # TODO! add parameters!
        #params.merge!(edge.transition.parameters)
      end
      c.test_attributes.concat(RunAttribute.from_hash(params))
      if !result.include?(c) && !test_executed?(c)
        result << c
      end
    end
    #puts "--> #{covered_states.size} of #{all_states.size} states covered by #{result.size} test cases"
  end
  return result
end

#gen_test_each_task(exclude_self = false) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/toaster/test/test_generator.rb', line 33

def gen_test_each_task(exclude_self=false)
  result = []

  tasks = @automation.tasks
  # remove tasks that are related to the Chef instrumentation 
  # performed by the Testing framework
  tasks = tasks.select{ |t| !t.toaster_testing_task? }

  tasks.each do |t|

    parameter_combinations = gen_param_combinations(t.parameters)
    puts "INFO: generated #{parameter_combinations.size} parameter combinations: #{parameter_combinations.inspect}"

    parameter_combinations.each do |params|
      c = TestCase.new(:test_suite => @test_suite)
      skip_tasks = tasks.select{ |t1| exclude_self ? t1.uuid == t.uuid : t1.uuid != t.uuid }
      skip_task_uuids = skip_tasks.collect{ |t1| t1.uuid }
      c.skip_task_uuids.concat(skip_task_uuids)
      c.test_attributes.merge(params)
      if !result.include?(c) && !test_executed?(c)
        result << c
      end
    end
  end

  return result
end

#gen_test_each_transitionObject



138
139
140
141
# File 'lib/toaster/test/test_generator.rb', line 138

def gen_test_each_transition()
  # TODO
  raise "not implemented"
end

#gen_test_exclude_each_taskObject



80
81
82
# File 'lib/toaster/test/test_generator.rb', line 80

def gen_test_exclude_each_task()
  gen_test_each_task(true)
end