Class: Reflection

Inherits:
Object
  • Object
show all
Defined in:
lib/Reflection.rb

Direct Known Subclasses

Control

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(execution, number, aggregator) ⇒ Reflection

Create a Reflection.

Parameters:

  • execution (Execution)

    The Execution that created this Reflection.

  • number (Integer)

    Multiple Reflections can be created per Execution.

  • aggregator (Aggregator)

    The aggregated RuleSet for this class/method.



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
# File 'lib/Reflection.rb', line 36

def initialize(execution, number, aggregator)

  @execution = execution
  @unique_id = execution.unique_id + number
  @number = number

  # Dependency.
  @aggregator = aggregator

  # Caller.
  @klass = execution.klass
  @method = execution.method

  # Metadata.
  @inputs = nil
  @output = nil

  # Clone the execution's calling object.
  # TODO: Abstract away into Clone class.
  @clone = execution.caller_object.clone

  # Result.
  @status = :pass
  @time = Time.now.to_i
  @message = nil

end

Instance Attribute Details

#statusObject (readonly)

Returns the value of attribute status.



27
28
29
# File 'lib/Reflection.rb', line 27

def status
  @status
end

Instance Method Details

#randomize(args, input_rule_sets) ⇒ Dynamic

Create random values for each argument from control reflections.

Parameters:

  • args (Dynamic)

    The arguments to create random values for.

  • input_rule_sets (Array)

    Aggregated rule sets for each argument.

Returns:

  • (Dynamic)

    Random arguments.



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/Reflection.rb', line 133

def randomize(args, input_rule_sets)

  random_args = []

  args.each_with_index do |arg, arg_num|

    rule_type = Aggregator.value_to_rule_type(arg)
    agg_rule = input_rule_sets[arg_num].rules[rule_type]

    random_args << agg_rule.random()

  end

  return random_args

end

#reflect(*args) ⇒ Object

Reflect on a method.

Creates a shadow execution.

Parameters:

  • *args (Dynamic)

    The method’s arguments.



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
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
# File 'lib/Reflection.rb', line 70

def reflect(*args)

  # Get aggregated rule sets.
  input_rule_sets = @aggregator.get_input_rule_sets(@klass, @method)
  output_rule_set = @aggregator.get_output_rule_set(@klass, @method)

  # When arguments exist.
  unless args.size == 0

    # Create random arguments from aggregated rule sets.
    unless input_rule_sets.nil?

      # Base random arguments on the types of the current arguments.
      if Aggregator.testable?(args, input_rule_sets)

        args = randomize(args, input_rule_sets)

      # TODO: Fallback to argument types from aggregated control rule sets
      # when arg types not testable or reflect_amount above 3.
      else
        @status = :fail
      end

    end

    # Create metadata for each argument.
    # TODO: Create metadata for other inputs such as properties on the instance.
    @inputs = MetaBuilder.create_many(args)

  end

  # Action method with new/old arguments.
  begin

    # Run reflection.
    output = @clone.send(@method, *args)
    @output = MetaBuilder.create(output)

    # Validate output against aggregated control rule sets.
    unless output_rule_set.nil?
      unless @aggregator.test_output(output, output_rule_set)
        @status = :fail
      end
    end

  # When a system error occurs.
  rescue StandardError => message

    @status = :fail
    @message = message

  end

end

#serializeHash

Get the results of the reflection.

Returns:

  • (Hash)

    Reflection metadata.



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/Reflection.rb', line 155

def serialize()

  # The ID of the first execution in the ShadowStack.
  base_id = nil
  unless @execution.base == nil
    base_id = @execution.base.unique_id
  end

  # Build reflection.
  reflection = {
    :base_id => base_id,
    :exe_id => @execution.unique_id,
    :ref_id => @unique_id,
    :ref_num => @number,
    :time => @time,
    :class => @klass,
    :method => @method,
    :status => @status,
    :message => @message,
    :inputs => nil,
    :output => nil,
  }

  unless @inputs.nil?
    reflection[:inputs] = []
    @inputs.each do |meta|
      reflection[:inputs] << meta.serialize()
    end
  end

  unless @output.nil?
    reflection[:output] = @output.serialize()
  end

  return reflection

end