bond-spy 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.yardopts +1 -0
- data/Gemfile +4 -0
- data/LICENSE +27 -0
- data/README.rst +65 -0
- data/Rakefile +6 -0
- data/bin/bond_reconcile.py +385 -0
- data/bin/setup +5 -0
- data/bond.gemspec +36 -0
- data/lib/bond.rb +469 -0
- data/lib/bond/spec_helper.rb +32 -0
- data/lib/bond/targetable.rb +210 -0
- data/lib/bond/version.rb +3 -0
- data/spec/bond_spec.rb +158 -0
- data/spec/bond_targetable_spec.rb +202 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/test_observations/.gitignore +2 -0
- data/spec/test_observations/bond_spec/Bond_with_agents_should_call_doers_before_returning_result.json +14 -0
- data/spec/test_observations/bond_spec/Bond_with_agents_should_call_the_function_passed_as_result_if_it_is_callable.json +23 -0
- data/spec/test_observations/bond_spec/Bond_with_agents_should_correctly_call_a_single_doer_if_filter_criteria_are_met.json +10 -0
- data/spec/test_observations/bond_spec/Bond_with_agents_should_correctly_call_multiple_doers.json +13 -0
- data/spec/test_observations/bond_spec/Bond_with_agents_should_not_call_doers_of_overriden_agents.json +8 -0
- data/spec/test_observations/bond_spec/Bond_with_agents_should_override_old_agents_with_newer_agents.json +0 -0
- data/spec/test_observations/bond_spec/Bond_with_agents_should_throw_an_exception_if_specified_by_agent.json +9 -0
- data/spec/test_observations/bond_spec/Bond_with_agents_should_throw_the_result_of_the_value_passed_to_exception_if_callable.json +10 -0
- data/spec/test_observations/bond_spec/Bond_with_agents_should_work_with_multiple_agents_for_different_spy_points.json +23 -0
- data/spec/test_observations/bond_spec/Bond_with_agents_with_filters_should_override_old_agents_with_newer_agents_unless_theott8glo1xn.json +22 -0
- data/spec/test_observations/bond_spec/Bond_with_agents_with_filters_should_respect_combinations_of_filters.json +37 -0
- data/spec/test_observations/bond_spec/Bond_with_agents_with_filters_should_respect_function_filters.json +16 -0
- data/spec/test_observations/bond_spec/Bond_with_agents_with_filters_should_respect_single_key_value_filters_of_all_types.json +121 -0
- data/spec/test_observations/bond_spec/Bond_without_any_agents_should_correctly_log_nested_hashes_and_arrays_with_hash_sorting.json +31 -0
- data/spec/test_observations/bond_spec/Bond_without_any_agents_should_correctly_log_some_normal_arguments_with_a_spy_point_name.json +12 -0
- data/spec/test_observations/bond_spec/Bond_without_any_agents_should_correctly_log_some_normal_arguments_without_a_spy_point_name.json +10 -0
- data/spec/test_observations/bond_targetable_spec/BondTargetable_correctly_continues_to_the_method_when_agent_result_continue_is_returned.json +10 -0
- data/spec/test_observations/bond_targetable_spec/BondTargetable_correctly_continues_to_the_method_when_agent_result_none_is_returned.json +14 -0
- data/spec/test_observations/bond_targetable_spec/BondTargetable_correctly_passes_through_blocks.json +10 -0
- data/spec/test_observations/bond_targetable_spec/BondTargetable_correctly_returns_nil__and_mocks__when_an_agent_returns_nil.json +11 -0
- data/spec/test_observations/bond_targetable_spec/BondTargetable_correctly_spies_private_methods.json +6 -0
- data/spec/test_observations/bond_targetable_spec/BondTargetable_correctly_spies_protected_methods.json +6 -0
- data/spec/test_observations/bond_targetable_spec/BondTargetable_with_different_argument_types_correctly_spies_on_a_class_method.json +7 -0
- data/spec/test_observations/bond_targetable_spec/BondTargetable_with_different_argument_types_correctly_spies_on_a_method_with_variabl19nhijeqoo.json +13 -0
- data/spec/test_observations/bond_targetable_spec/BondTargetable_with_different_argument_types_correctly_spies_on_a_mix_of_positional_a6qc3d4el92.json +33 -0
- data/spec/test_observations/bond_targetable_spec/BondTargetable_with_different_argument_types_correctly_spies_on_a_mix_of_positional_aott8glo1xn.json +20 -0
- data/spec/test_observations/bond_targetable_spec/BondTargetable_with_different_argument_types_correctly_spies_on_a_mix_of_required_andbcgjq06had.json +17 -0
- data/spec/test_observations/bond_targetable_spec/BondTargetable_with_different_argument_types_correctly_spies_on_a_normal_method.json +7 -0
- data/spec/test_observations/bond_targetable_spec/BondTargetable_with_different_argument_types_correctly_spies_on_all_optional_keyword_arguments.json +10 -0
- data/spec/test_observations/bond_targetable_spec/BondTargetable_with_different_argument_types_correctly_spies_on_variable_keyword_arguments.json +22 -0
- data/spec/test_observations/bond_targetable_spec/BondTargetable_with_different_spy_point_parameters_correctly_changes_the_spy_point_naj4gnwvcu8n.json +5 -0
- data/spec/test_observations/bond_targetable_spec/BondTargetable_with_different_spy_point_parameters_correctly_errors_when_mocking_is_r9j7wklng0z.json +6 -0
- data/spec/test_observations/bond_targetable_spec/BondTargetable_with_different_spy_point_parameters_correctly_ignores_excluded_keys.json +10 -0
- data/spec/test_observations/bond_targetable_spec/BondTargetable_with_different_spy_point_parameters_correctly_mocks_when_one_is_specified.json +10 -0
- data/spec/test_observations/bond_targetable_spec/BondTargetable_with_different_spy_point_parameters_correctly_spies_the_return_value_w19nhijeqoo.json +10 -0
- data/spec/test_observations/bond_targetable_spec/BondTargetable_with_different_spy_point_parameters_correctly_spies_the_return_value_ww8esw1qdxc.json +10 -0
- data/spec/test_observations/bond_targetable_spec/BondTargetable_with_modules_correctly_spies_on_included_module_methods.json +6 -0
- data/spec/test_observations/bond_targetable_spec/BondTargetable_with_modules_correctly_spies_on_module_methods.json +7 -0
- data/tutorials/binary_search_tree/bst.rb +120 -0
- data/tutorials/binary_search_tree/bst_spec.rb +82 -0
- data/tutorials/binary_search_tree/run_tests.sh +4 -0
- data/tutorials/binary_search_tree/test_observations/.gitignore +2 -0
- data/tutorials/binary_search_tree/test_observations/bst_spec/Node_should_add_nodes_to_the_BST_correctly__testing_with_Bond.json +20 -0
- data/tutorials/binary_search_tree/test_observations/bst_spec/Node_should_add_nodes_to_the_BST_correctly__testing_without_Bond.json +3 -0
- data/tutorials/binary_search_tree/test_observations/bst_spec/Node_should_correctly_delete_nodes_from_the_BST.json +29 -0
- data/tutorials/heat_watcher/heat_watcher.rb +107 -0
- data/tutorials/heat_watcher/heat_watcher_spec.rb +116 -0
- data/tutorials/heat_watcher/run_tests.sh +4 -0
- data/tutorials/heat_watcher/test_observations/.gitignore +2 -0
- data/tutorials/heat_watcher/test_observations/heat_watcher_spec/HeatWatcher_should_properly_report_critical_errors.json +142 -0
- data/tutorials/heat_watcher/test_observations/heat_watcher_spec/HeatWatcher_should_properly_report_warnings_and_switch_back_to_OK_status.json +132 -0
- metadata +211 -0
@@ -0,0 +1,29 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"__spy_point__": "test_delete_1",
|
4
|
+
"tree": {
|
5
|
+
"data": 8,
|
6
|
+
"left": {
|
7
|
+
"data": 3,
|
8
|
+
"right": {
|
9
|
+
"data": 6
|
10
|
+
}
|
11
|
+
},
|
12
|
+
"right": {
|
13
|
+
"data": 12
|
14
|
+
}
|
15
|
+
}
|
16
|
+
},
|
17
|
+
{
|
18
|
+
"__spy_point__": "test_delete_2",
|
19
|
+
"tree": {
|
20
|
+
"data": 12,
|
21
|
+
"left": {
|
22
|
+
"data": 3,
|
23
|
+
"right": {
|
24
|
+
"data": 6
|
25
|
+
}
|
26
|
+
}
|
27
|
+
}
|
28
|
+
}
|
29
|
+
]
|
@@ -0,0 +1,107 @@
|
|
1
|
+
#
|
2
|
+
# A simple demonstration of using Bond for spying and mocking
|
3
|
+
# an application for monitoring temperature and sending alerts
|
4
|
+
#
|
5
|
+
# See a full explanation of this example at
|
6
|
+
# http://necula01.github.io/bond/example_heat.html
|
7
|
+
#
|
8
|
+
# rst_Start
|
9
|
+
|
10
|
+
require 'bond'
|
11
|
+
|
12
|
+
# Monitor temperature rise over time.
|
13
|
+
# See description in the Bond documentation.
|
14
|
+
class HeatWatcher
|
15
|
+
# Marks this class as being able to be spied on. Exports `bond` method
|
16
|
+
# to use as e.g. bond.spy and bond.spy_point.
|
17
|
+
extend BondTargetable
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
@last_temp = nil # The last temp measurement
|
21
|
+
@last_time = nil # The time when we took the last measurement
|
22
|
+
@last_alert_state = 'Ok' # Ok, Warning, Critical
|
23
|
+
@last_alert_time = -Float::INFINITY # The time when we sent the last alert
|
24
|
+
end
|
25
|
+
|
26
|
+
# Monitor the temperature and send alerts
|
27
|
+
# @param exit_time the time when to exit the monitor loop.
|
28
|
+
def monitor_loop(exit_time = nil)
|
29
|
+
loop do
|
30
|
+
temp = get_temperature
|
31
|
+
now = get_current_time
|
32
|
+
return if !exit_time.nil? && now >= exit_time
|
33
|
+
|
34
|
+
if @last_temp.nil?
|
35
|
+
# First reading
|
36
|
+
@last_temp = temp
|
37
|
+
@last_time = now
|
38
|
+
interval = 60
|
39
|
+
else
|
40
|
+
change_rate = (temp - @last_temp) / (now - @last_time) * 60
|
41
|
+
if change_rate < 1
|
42
|
+
interval = 60
|
43
|
+
alert_state = 'Ok'
|
44
|
+
elsif change_rate < 2
|
45
|
+
interval = 10
|
46
|
+
alert_state = 'Warning'
|
47
|
+
else
|
48
|
+
interval = 10
|
49
|
+
alert_state = 'Critical'
|
50
|
+
end
|
51
|
+
|
52
|
+
@last_temp = temp
|
53
|
+
@last_time = now
|
54
|
+
|
55
|
+
if alert_state != @last_alert_state ||
|
56
|
+
(alert_state != 'Ok' && now >= 600 + @last_alert_time)
|
57
|
+
# Send an alert
|
58
|
+
send_alert("#{alert_state}: Temperature is rising at #{change_rate.round(1)} deg/min")
|
59
|
+
@last_alert_time = now
|
60
|
+
end
|
61
|
+
|
62
|
+
@last_alert_state = alert_state
|
63
|
+
end
|
64
|
+
|
65
|
+
sleep(interval)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Spy this function, want to spy the result
|
70
|
+
bond.spy_point(spy_result: true)
|
71
|
+
# Read the temperature from a sensor
|
72
|
+
def get_temperature
|
73
|
+
resp_code, temp_data =
|
74
|
+
make_request('http://system.server.com/temperature')
|
75
|
+
raise 'Error while retrieving temperature!' unless resp_code == 200
|
76
|
+
match = /<temperature>([0-9.]+)<\/temperature>/.match(temp_data)
|
77
|
+
raise "Error while parsing temperature from: #{temp_data}" if match.nil?
|
78
|
+
match[1].to_f
|
79
|
+
end
|
80
|
+
|
81
|
+
bond.spy_point
|
82
|
+
# Read the current time
|
83
|
+
def get_current_time
|
84
|
+
Time.now.to_i
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
bond.spy_point
|
89
|
+
# Sleep a few seconds
|
90
|
+
def sleep(seconds)
|
91
|
+
sleep(seconds)
|
92
|
+
end
|
93
|
+
|
94
|
+
bond.spy_point
|
95
|
+
# Send an alert
|
96
|
+
def send_alert(message)
|
97
|
+
make_request('http://backend.server.com/messages', {message: message})
|
98
|
+
end
|
99
|
+
|
100
|
+
bond.spy_point(require_agent_result: true)
|
101
|
+
# HTTP request (GET, or POST if the data is provided)
|
102
|
+
def make_request(url, data = nil)
|
103
|
+
full_url = "#{url}?#{URI.encode_www_form(data)}"
|
104
|
+
resp = Net::HTTP.get_response(URI(full_url))
|
105
|
+
[resp.code.to_i, resp.body]
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
#
|
2
|
+
# Tests using Bond for the heat_watcher.py app
|
3
|
+
#
|
4
|
+
# See a full explanation of this example at
|
5
|
+
# http://necula01.github.io/bond/example_heat.html
|
6
|
+
#
|
7
|
+
|
8
|
+
require 'bond/spec_helper'
|
9
|
+
require_relative 'heat_watcher'
|
10
|
+
|
11
|
+
describe HeatWatcher do
|
12
|
+
# Sets up the testing environment to use Bond. Exports bond as a variable
|
13
|
+
# to use as e.g. bond.deploy_agent.
|
14
|
+
include_context :bond
|
15
|
+
|
16
|
+
# Helper function to setup the time mocks and agents
|
17
|
+
def deploy_time_mock
|
18
|
+
@time_mocker = TimeMocker.new
|
19
|
+
|
20
|
+
bond.deploy_agent('HeatWatcher#get_current_time',
|
21
|
+
result: lambda { |_| @time_mocker.time })
|
22
|
+
bond.deploy_agent('HeatWatcher#sleep',
|
23
|
+
result: lambda { |obs| @time_mocker.sleep(obs[:seconds]) })
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should properly report warnings and switch back to OK status' do
|
27
|
+
# A test where the higher-level functions get_temperature and send_alert
|
28
|
+
# are mocked out to return specified temperatures and do nothing, respectively.
|
29
|
+
deploy_time_mock
|
30
|
+
@temp_mocker = TemperatureMocker.new(time_mocker: @time_mocker,
|
31
|
+
temp_start: 70,
|
32
|
+
temp_rates: [[0, 0.5], [60, 1.3], [110, 0.1]])
|
33
|
+
|
34
|
+
bond.deploy_agent('HeatWatcher#get_temperature',
|
35
|
+
result: lambda { |_| @temp_mocker.temperature })
|
36
|
+
bond.deploy_agent('HeatWatcher#send_alert',
|
37
|
+
result: nil)
|
38
|
+
|
39
|
+
HeatWatcher.new.monitor_loop(@time_mocker.time + 400)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should properly report critical errors' do
|
43
|
+
# A test where make_request is mocked out, and returns different responses
|
44
|
+
# depending on the URL that is passed in. This can allow you to test that the
|
45
|
+
# parsing logic in get_temperature is working correctly.
|
46
|
+
deploy_time_mock
|
47
|
+
@temp_mocker = TemperatureMocker.new(time_mocker: @time_mocker,
|
48
|
+
temp_start: 70,
|
49
|
+
temp_rates: [[0, 0.5], [60, 2.5], [120, 3], [140, 0.5]])
|
50
|
+
|
51
|
+
bond.deploy_agent('HeatWatcher#make_request',
|
52
|
+
url__contains: 'messages',
|
53
|
+
result: nil)
|
54
|
+
bond.deploy_agent('HeatWatcher#make_request',
|
55
|
+
url__contains: 'temperature',
|
56
|
+
result: lambda do |_|
|
57
|
+
[200, "<temperature>#{@temp_mocker.temperature}</temperature>"]
|
58
|
+
end)
|
59
|
+
|
60
|
+
HeatWatcher.new.monitor_loop(@time_mocker.time + 210)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# rst_TimeMocker
|
65
|
+
# A class to mock time
|
66
|
+
class TimeMocker
|
67
|
+
def initialize(current_time = 1445567700)
|
68
|
+
# Default 10/23/2015 @ 2:35am (UTC)
|
69
|
+
@current_time = current_time
|
70
|
+
end
|
71
|
+
|
72
|
+
def time
|
73
|
+
@current_time
|
74
|
+
end
|
75
|
+
|
76
|
+
def sleep(seconds)
|
77
|
+
@current_time += seconds
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# rst_TemperatureMocker
|
82
|
+
# A class to mock temperature
|
83
|
+
class TemperatureMocker
|
84
|
+
|
85
|
+
# @param time_mocker a reference to the current time mocker
|
86
|
+
# @param temp_start the starting temperature
|
87
|
+
# @param temp_rates a list of pairs (time_since_start,
|
88
|
+
# temperature_increase_rate_per_min) ordered by time_since_start
|
89
|
+
def initialize(time_mocker:, temp_start:, temp_rates: [])
|
90
|
+
@time_mocker = time_mocker
|
91
|
+
@start_time = time_mocker.time
|
92
|
+
@last_temp = temp_start # last temp read
|
93
|
+
@last_temp_time = @start_time # last temp read time
|
94
|
+
@temp_rates = temp_rates
|
95
|
+
end
|
96
|
+
|
97
|
+
def temperature
|
98
|
+
now = @time_mocker.time
|
99
|
+
time_since_start = now - @start_time
|
100
|
+
# See if we need to advance to the next temperature rate
|
101
|
+
if @temp_rates.length > 1 && time_since_start >= @temp_rates[1][0]
|
102
|
+
|
103
|
+
old_rate = @temp_rates.shift[1]
|
104
|
+
|
105
|
+
old_rate_time = @temp_rates[0][0]
|
106
|
+
@last_temp += (old_rate_time + @start_time - @last_temp_time) / 60.0 * old_rate
|
107
|
+
@last_temp_time = old_rate_time + @start_time
|
108
|
+
end
|
109
|
+
|
110
|
+
# The first pair is the one we use to get the rate
|
111
|
+
rate = @temp_rates.length > 0 ? @temp_rates[0][1] : 0
|
112
|
+
@last_temp += (now - @last_temp_time) / 60.0 * rate
|
113
|
+
@last_temp_time = now
|
114
|
+
@last_temp
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"__spy_point__": "HeatWatcher#get_temperature"
|
4
|
+
},
|
5
|
+
{
|
6
|
+
"__spy_point__": "HeatWatcher#make_request",
|
7
|
+
"url": "http://system.server.com/temperature"
|
8
|
+
},
|
9
|
+
{
|
10
|
+
"__spy_point__": "HeatWatcher#get_temperature.result",
|
11
|
+
"result": 70.0
|
12
|
+
},
|
13
|
+
{
|
14
|
+
"__spy_point__": "HeatWatcher#get_current_time"
|
15
|
+
},
|
16
|
+
{
|
17
|
+
"__spy_point__": "HeatWatcher#sleep",
|
18
|
+
"seconds": 60
|
19
|
+
},
|
20
|
+
{
|
21
|
+
"__spy_point__": "HeatWatcher#get_temperature"
|
22
|
+
},
|
23
|
+
{
|
24
|
+
"__spy_point__": "HeatWatcher#make_request",
|
25
|
+
"url": "http://system.server.com/temperature"
|
26
|
+
},
|
27
|
+
{
|
28
|
+
"__spy_point__": "HeatWatcher#get_temperature.result",
|
29
|
+
"result": 70.5
|
30
|
+
},
|
31
|
+
{
|
32
|
+
"__spy_point__": "HeatWatcher#get_current_time"
|
33
|
+
},
|
34
|
+
{
|
35
|
+
"__spy_point__": "HeatWatcher#sleep",
|
36
|
+
"seconds": 60
|
37
|
+
},
|
38
|
+
{
|
39
|
+
"__spy_point__": "HeatWatcher#get_temperature"
|
40
|
+
},
|
41
|
+
{
|
42
|
+
"__spy_point__": "HeatWatcher#make_request",
|
43
|
+
"url": "http://system.server.com/temperature"
|
44
|
+
},
|
45
|
+
{
|
46
|
+
"__spy_point__": "HeatWatcher#get_temperature.result",
|
47
|
+
"result": 73.0
|
48
|
+
},
|
49
|
+
{
|
50
|
+
"__spy_point__": "HeatWatcher#get_current_time"
|
51
|
+
},
|
52
|
+
{
|
53
|
+
"__spy_point__": "HeatWatcher#send_alert",
|
54
|
+
"message": "Critical: Temperature is rising at 2.5 deg/min"
|
55
|
+
},
|
56
|
+
{
|
57
|
+
"__spy_point__": "HeatWatcher#make_request",
|
58
|
+
"message": "Critical: Temperature is rising at 2.5 deg/min",
|
59
|
+
"url": "http://backend.server.com/messages"
|
60
|
+
},
|
61
|
+
{
|
62
|
+
"__spy_point__": "HeatWatcher#sleep",
|
63
|
+
"seconds": 10
|
64
|
+
},
|
65
|
+
{
|
66
|
+
"__spy_point__": "HeatWatcher#get_temperature"
|
67
|
+
},
|
68
|
+
{
|
69
|
+
"__spy_point__": "HeatWatcher#make_request",
|
70
|
+
"url": "http://system.server.com/temperature"
|
71
|
+
},
|
72
|
+
{
|
73
|
+
"__spy_point__": "HeatWatcher#get_temperature.result",
|
74
|
+
"result": 73.5
|
75
|
+
},
|
76
|
+
{
|
77
|
+
"__spy_point__": "HeatWatcher#get_current_time"
|
78
|
+
},
|
79
|
+
{
|
80
|
+
"__spy_point__": "HeatWatcher#sleep",
|
81
|
+
"seconds": 10
|
82
|
+
},
|
83
|
+
{
|
84
|
+
"__spy_point__": "HeatWatcher#get_temperature"
|
85
|
+
},
|
86
|
+
{
|
87
|
+
"__spy_point__": "HeatWatcher#make_request",
|
88
|
+
"url": "http://system.server.com/temperature"
|
89
|
+
},
|
90
|
+
{
|
91
|
+
"__spy_point__": "HeatWatcher#get_temperature.result",
|
92
|
+
"result": 74.0
|
93
|
+
},
|
94
|
+
{
|
95
|
+
"__spy_point__": "HeatWatcher#get_current_time"
|
96
|
+
},
|
97
|
+
{
|
98
|
+
"__spy_point__": "HeatWatcher#sleep",
|
99
|
+
"seconds": 10
|
100
|
+
},
|
101
|
+
{
|
102
|
+
"__spy_point__": "HeatWatcher#get_temperature"
|
103
|
+
},
|
104
|
+
{
|
105
|
+
"__spy_point__": "HeatWatcher#make_request",
|
106
|
+
"url": "http://system.server.com/temperature"
|
107
|
+
},
|
108
|
+
{
|
109
|
+
"__spy_point__": "HeatWatcher#get_temperature.result",
|
110
|
+
"result": 74.08333333333333
|
111
|
+
},
|
112
|
+
{
|
113
|
+
"__spy_point__": "HeatWatcher#get_current_time"
|
114
|
+
},
|
115
|
+
{
|
116
|
+
"__spy_point__": "HeatWatcher#send_alert",
|
117
|
+
"message": "Ok: Temperature is rising at 0.5 deg/min"
|
118
|
+
},
|
119
|
+
{
|
120
|
+
"__spy_point__": "HeatWatcher#make_request",
|
121
|
+
"message": "Ok: Temperature is rising at 0.5 deg/min",
|
122
|
+
"url": "http://backend.server.com/messages"
|
123
|
+
},
|
124
|
+
{
|
125
|
+
"__spy_point__": "HeatWatcher#sleep",
|
126
|
+
"seconds": 60
|
127
|
+
},
|
128
|
+
{
|
129
|
+
"__spy_point__": "HeatWatcher#get_temperature"
|
130
|
+
},
|
131
|
+
{
|
132
|
+
"__spy_point__": "HeatWatcher#make_request",
|
133
|
+
"url": "http://system.server.com/temperature"
|
134
|
+
},
|
135
|
+
{
|
136
|
+
"__spy_point__": "HeatWatcher#get_temperature.result",
|
137
|
+
"result": 74.58333333333333
|
138
|
+
},
|
139
|
+
{
|
140
|
+
"__spy_point__": "HeatWatcher#get_current_time"
|
141
|
+
}
|
142
|
+
]
|
@@ -0,0 +1,132 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"__spy_point__": "HeatWatcher#get_temperature"
|
4
|
+
},
|
5
|
+
{
|
6
|
+
"__spy_point__": "HeatWatcher#get_temperature.result",
|
7
|
+
"result": 70.0
|
8
|
+
},
|
9
|
+
{
|
10
|
+
"__spy_point__": "HeatWatcher#get_current_time"
|
11
|
+
},
|
12
|
+
{
|
13
|
+
"__spy_point__": "HeatWatcher#sleep",
|
14
|
+
"seconds": 60
|
15
|
+
},
|
16
|
+
{
|
17
|
+
"__spy_point__": "HeatWatcher#get_temperature"
|
18
|
+
},
|
19
|
+
{
|
20
|
+
"__spy_point__": "HeatWatcher#get_temperature.result",
|
21
|
+
"result": 70.5
|
22
|
+
},
|
23
|
+
{
|
24
|
+
"__spy_point__": "HeatWatcher#get_current_time"
|
25
|
+
},
|
26
|
+
{
|
27
|
+
"__spy_point__": "HeatWatcher#sleep",
|
28
|
+
"seconds": 60
|
29
|
+
},
|
30
|
+
{
|
31
|
+
"__spy_point__": "HeatWatcher#get_temperature"
|
32
|
+
},
|
33
|
+
{
|
34
|
+
"__spy_point__": "HeatWatcher#get_temperature.result",
|
35
|
+
"result": 71.6
|
36
|
+
},
|
37
|
+
{
|
38
|
+
"__spy_point__": "HeatWatcher#get_current_time"
|
39
|
+
},
|
40
|
+
{
|
41
|
+
"__spy_point__": "HeatWatcher#send_alert",
|
42
|
+
"message": "Warning: Temperature is rising at 1.1 deg/min"
|
43
|
+
},
|
44
|
+
{
|
45
|
+
"__spy_point__": "HeatWatcher#sleep",
|
46
|
+
"seconds": 10
|
47
|
+
},
|
48
|
+
{
|
49
|
+
"__spy_point__": "HeatWatcher#get_temperature"
|
50
|
+
},
|
51
|
+
{
|
52
|
+
"__spy_point__": "HeatWatcher#get_temperature.result",
|
53
|
+
"result": 71.61666666666666
|
54
|
+
},
|
55
|
+
{
|
56
|
+
"__spy_point__": "HeatWatcher#get_current_time"
|
57
|
+
},
|
58
|
+
{
|
59
|
+
"__spy_point__": "HeatWatcher#send_alert",
|
60
|
+
"message": "Ok: Temperature is rising at 0.1 deg/min"
|
61
|
+
},
|
62
|
+
{
|
63
|
+
"__spy_point__": "HeatWatcher#sleep",
|
64
|
+
"seconds": 60
|
65
|
+
},
|
66
|
+
{
|
67
|
+
"__spy_point__": "HeatWatcher#get_temperature"
|
68
|
+
},
|
69
|
+
{
|
70
|
+
"__spy_point__": "HeatWatcher#get_temperature.result",
|
71
|
+
"result": 71.71666666666665
|
72
|
+
},
|
73
|
+
{
|
74
|
+
"__spy_point__": "HeatWatcher#get_current_time"
|
75
|
+
},
|
76
|
+
{
|
77
|
+
"__spy_point__": "HeatWatcher#sleep",
|
78
|
+
"seconds": 60
|
79
|
+
},
|
80
|
+
{
|
81
|
+
"__spy_point__": "HeatWatcher#get_temperature"
|
82
|
+
},
|
83
|
+
{
|
84
|
+
"__spy_point__": "HeatWatcher#get_temperature.result",
|
85
|
+
"result": 71.81666666666665
|
86
|
+
},
|
87
|
+
{
|
88
|
+
"__spy_point__": "HeatWatcher#get_current_time"
|
89
|
+
},
|
90
|
+
{
|
91
|
+
"__spy_point__": "HeatWatcher#sleep",
|
92
|
+
"seconds": 60
|
93
|
+
},
|
94
|
+
{
|
95
|
+
"__spy_point__": "HeatWatcher#get_temperature"
|
96
|
+
},
|
97
|
+
{
|
98
|
+
"__spy_point__": "HeatWatcher#get_temperature.result",
|
99
|
+
"result": 71.91666666666664
|
100
|
+
},
|
101
|
+
{
|
102
|
+
"__spy_point__": "HeatWatcher#get_current_time"
|
103
|
+
},
|
104
|
+
{
|
105
|
+
"__spy_point__": "HeatWatcher#sleep",
|
106
|
+
"seconds": 60
|
107
|
+
},
|
108
|
+
{
|
109
|
+
"__spy_point__": "HeatWatcher#get_temperature"
|
110
|
+
},
|
111
|
+
{
|
112
|
+
"__spy_point__": "HeatWatcher#get_temperature.result",
|
113
|
+
"result": 72.01666666666664
|
114
|
+
},
|
115
|
+
{
|
116
|
+
"__spy_point__": "HeatWatcher#get_current_time"
|
117
|
+
},
|
118
|
+
{
|
119
|
+
"__spy_point__": "HeatWatcher#sleep",
|
120
|
+
"seconds": 60
|
121
|
+
},
|
122
|
+
{
|
123
|
+
"__spy_point__": "HeatWatcher#get_temperature"
|
124
|
+
},
|
125
|
+
{
|
126
|
+
"__spy_point__": "HeatWatcher#get_temperature.result",
|
127
|
+
"result": 72.11666666666663
|
128
|
+
},
|
129
|
+
{
|
130
|
+
"__spy_point__": "HeatWatcher#get_current_time"
|
131
|
+
}
|
132
|
+
]
|