Class: AuditBenchmark

Inherits:
Object
  • Object
show all
Defined in:
lib/audit/lib/benchmark/audit_benchmark.rb

Direct Known Subclasses

YamlBenchmark

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#item_repositoryObject (readonly)

Returns the value of attribute item_repository.



7
8
9
# File 'lib/audit/lib/benchmark/audit_benchmark.rb', line 7

def item_repository
  @item_repository
end

Instance Method Details

#automatic_dependenciesObject



127
128
129
# File 'lib/audit/lib/benchmark/audit_benchmark.rb', line 127

def automatic_dependencies()
  return dependencies() - rules()
end

#dependenciesObject



123
124
125
# File 'lib/audit/lib/benchmark/audit_benchmark.rb', line 123

def dependencies()
  return (rules().map {|x| x.dependencies }.flatten()).uniq
end

#durationObject

def checks()

  checks = []
  not_traversed = @children.dup

  while !not_traversed.empty? do
    item = not_traversed.shift

    if (item.class == Group) then
      item.children.each do |child|
        not_traversed << child unless not_traversed.include? child
      end
    elsif item.class == Check then
      checks << item
      item.dependencies.each do |dep|
        not_traversed << dep unless not_traversed.include? dep
      end
    end
  end

  return checks
end


153
154
155
156
# File 'lib/audit/lib/benchmark/audit_benchmark.rb', line 153

def duration()
  #execution_order().flatten().each().inject(0) {|result, element| result + element.duration}
  execution_order().flatten().inject(0) {|result, element| result + element.duration}
end

#element(name) ⇒ Object



99
100
101
102
103
104
# File 'lib/audit/lib/benchmark/audit_benchmark.rb', line 99

def element(name)
	@elements = {} unless @elements
	@elements[name] = element_impl(name) unless @elements[name]
	
	return @elements[name]
end

#execution_orderObject



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/audit/lib/benchmark/audit_benchmark.rb', line 9

def execution_order()
	# resolve dependencies between checks based on the depends-tag of the checks.
	# In a first pass, all dependencies are discovered iteratively popping checks
	# from a queue of checks with unresolved dependencies, pushing them onto a resolved
	# queue and pushing the check's dependencies onto the unresolved queue if they
	# are not yet in the resolved or unresolved queue. Also, the reversed dependencies
	# (which check is needed by which) are stored for the second pass.
	#
	# In a second pass, starting from checks which do not depend on any other checks,
	# all checks are labelled with the dependency level they're in. Checks without dependencies
	# have dependency level 0, checks which rely on checks from level 0 have level 1,
	# and so on. This is not the optimal solution for the problem ... but I have forgot why,
	# so figure this out yourself.
	#
	# You might wonder why I don't do dependency tracking with the Imports and Exports
	# declarations: If there are two scripts which provide a variable (alternatives),
	# it is very easy to write a mediating script, which chooses one of the provider scripts,
	# and then can be depended on, but it is very hard to do the resolution based on 
	# imports and exports. So imagine this like the linker, which uses library/object
	# names to include dependencies, but still checks that all symbols are resolved
	# correctly (TODO: Add a check that all Imports are satisfied by Exports)
	
	#find all dependencies
	items = @children.dup
	
	unresolved = []
	while not items.empty?
		item = items.shift
		if item.class == Group
			item.children.each do|x| 
				items << x unless items.include? x or unresolved.include? x
			end
		elsif item.class == Check
			unresolved << item
		end
	end

	resolved = []
	dependency_root = []
	reversed_dependencies = {}
	iterations = 0
	
	while !unresolved.empty? and iterations < @item_repository.length
		cur = unresolved.shift
		
		dependency_root.push(cur) if cur.dependencies.empty? and not dependency_root.include? cur
		
		cur.dependencies.each do|dep|
			unresolved.push dep unless unresolved.include? dep or resolved.include? dep
			reversed_dependencies[dep] = [] if reversed_dependencies[dep].nil?
			reversed_dependencies[dep] << cur
		end
	end
	
	untagged = []
	tagged = []
	
	dependency_root.each {|x| untagged.push(x)}
	untagged.push(:NEXT_LEVEL)
	
	level = 0
	while untagged.length > 1
		cur = untagged.shift
		
		if cur == :NEXT_LEVEL then
			level = level + 1
			untagged.push(:NEXT_LEVEL)
			next
		end
		
		tag = tagged.select {|x| x[:check] == cur}
		if tag.empty? then
			tagged << {:level => level, :check => cur}  
		else 
			raise "multiple tags for check #{cur.id} found" if tag.length != 1
			
			tag[0][:level] = level
		end
		
		unless reversed_dependencies[cur].nil? then
			reversed_dependencies[cur].each {|x| untagged.push(x)}
		end
	end
	
	retval = []
	(0 .. level).each {|i| retval.push(tagged.select {|x| x[:level] == i}.map {|x| x[:check]})}
	
	return retval
end

#rulesObject



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/audit/lib/benchmark/audit_benchmark.rb', line 106

def rules()
  untraversed = @children.dup
  rules = []

  while untraversed.length > 0
    item = untraversed.shift

    if item.kind_of? Group then
      untraversed = untraversed + item.children
    elsif item.kind_of? Check then
      rules << item
    end
  end

  return rules.uniq
end

#to_hashObject



158
159
160
161
162
163
164
165
166
# File 'lib/audit/lib/benchmark/audit_benchmark.rb', line 158

def to_hash()
  return {
    :type => :BENCHMARK,
    :id => @id,
    :name => @name,
    :description => @description,
    :children => Lazy.new(Lazy.new(@children, :reject) {|x| !x.in_report?}, :map) {|child| Lazy.new(child, :to_hash)}
  }
end