application_insights 0.5.3 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +6 -14
  2. data/.travis.yml +21 -9
  3. data/CONTRIBUTING.md +30 -0
  4. data/Gemfile +4 -4
  5. data/LICENSE.txt +11 -11
  6. data/README.md +13 -14
  7. data/Rakefile +14 -14
  8. data/application_insights.gemspec +28 -29
  9. data/lib/application_insights.rb +9 -9
  10. data/lib/application_insights/channel/asynchronous_queue.rb +58 -51
  11. data/lib/application_insights/channel/asynchronous_sender.rb +132 -123
  12. data/lib/application_insights/channel/contracts/application.rb +14 -53
  13. data/lib/application_insights/channel/contracts/cloud.rb +14 -0
  14. data/lib/application_insights/channel/contracts/data.rb +14 -48
  15. data/lib/application_insights/channel/contracts/data_point.rb +24 -130
  16. data/lib/application_insights/channel/contracts/data_point_type.rb +7 -16
  17. data/lib/application_insights/channel/contracts/dependency_kind.rb +9 -19
  18. data/lib/application_insights/channel/contracts/dependency_source_type.rb +9 -19
  19. data/lib/application_insights/channel/contracts/device.rb +28 -257
  20. data/lib/application_insights/channel/contracts/envelope.rb +40 -266
  21. data/lib/application_insights/channel/contracts/event_data.rb +28 -77
  22. data/lib/application_insights/channel/contracts/exception_data.rb +37 -140
  23. data/lib/application_insights/channel/contracts/exception_details.rb +28 -129
  24. data/lib/application_insights/channel/contracts/internal.rb +14 -53
  25. data/lib/application_insights/channel/contracts/json_serializable.rb +59 -59
  26. data/lib/application_insights/channel/contracts/location.rb +16 -36
  27. data/lib/application_insights/channel/contracts/message_data.rb +24 -77
  28. data/lib/application_insights/channel/contracts/metric_data.rb +27 -60
  29. data/lib/application_insights/channel/contracts/operation.rb +19 -121
  30. data/lib/application_insights/channel/contracts/page_view_data.rb +30 -111
  31. data/lib/application_insights/channel/contracts/remote_dependency_data.rb +56 -260
  32. data/lib/application_insights/channel/contracts/request_data.rb +36 -176
  33. data/lib/application_insights/channel/contracts/session.rb +15 -70
  34. data/lib/application_insights/channel/contracts/severity_level.rb +13 -25
  35. data/lib/application_insights/channel/contracts/stack_frame.rb +17 -94
  36. data/lib/application_insights/channel/contracts/user.rb +19 -104
  37. data/lib/application_insights/channel/event.rb +68 -64
  38. data/lib/application_insights/channel/queue_base.rb +65 -62
  39. data/lib/application_insights/channel/sender_base.rb +79 -72
  40. data/lib/application_insights/channel/synchronous_queue.rb +45 -39
  41. data/lib/application_insights/channel/synchronous_sender.rb +17 -15
  42. data/lib/application_insights/channel/telemetry_channel.rb +120 -102
  43. data/lib/application_insights/channel/telemetry_context.rb +85 -68
  44. data/lib/application_insights/rack/track_request.rb +87 -84
  45. data/lib/application_insights/telemetry_client.rb +229 -217
  46. data/lib/application_insights/unhandled_exception.rb +49 -47
  47. data/lib/application_insights/version.rb +3 -3
  48. data/test/application_insights.rb +8 -9
  49. data/test/application_insights/channel/contracts/test_application.rb +44 -44
  50. data/test/application_insights/channel/contracts/test_cloud.rb +44 -0
  51. data/test/application_insights/channel/contracts/test_data.rb +44 -44
  52. data/test/application_insights/channel/contracts/test_data_point.rb +109 -109
  53. data/test/application_insights/channel/contracts/test_device.rb +200 -200
  54. data/test/application_insights/channel/contracts/test_envelope.rb +209 -209
  55. data/test/application_insights/channel/contracts/test_event_data.rb +62 -62
  56. data/test/application_insights/channel/contracts/test_exception_data.rb +111 -111
  57. data/test/application_insights/channel/contracts/test_exception_details.rb +106 -106
  58. data/test/application_insights/channel/contracts/test_internal.rb +44 -44
  59. data/test/application_insights/channel/contracts/test_location.rb +70 -31
  60. data/test/application_insights/channel/contracts/test_message_data.rb +66 -66
  61. data/test/application_insights/channel/contracts/test_metric_data.rb +50 -50
  62. data/test/application_insights/channel/contracts/test_operation.rb +109 -96
  63. data/test/application_insights/channel/contracts/test_page_view_data.rb +88 -88
  64. data/test/application_insights/channel/contracts/test_remote_dependency_data.rb +209 -209
  65. data/test/application_insights/channel/contracts/test_request_data.rb +153 -153
  66. data/test/application_insights/channel/contracts/test_session.rb +57 -57
  67. data/test/application_insights/channel/contracts/test_stack_frame.rb +83 -83
  68. data/test/application_insights/channel/contracts/test_user.rb +96 -83
  69. data/test/application_insights/channel/test_asynchronous_queue.rb +47 -47
  70. data/test/application_insights/channel/test_asynchronous_sender.rb +80 -80
  71. data/test/application_insights/channel/test_event.rb +52 -52
  72. data/test/application_insights/channel/test_queue_base.rb +88 -88
  73. data/test/application_insights/channel/test_sender_base.rb +87 -87
  74. data/test/application_insights/channel/test_synchronous_queue.rb +27 -27
  75. data/test/application_insights/channel/test_synchronous_sender.rb +10 -10
  76. data/test/application_insights/channel/test_telemetry_channel.rb +126 -102
  77. data/test/application_insights/channel/test_telemetry_context.rb +82 -74
  78. data/test/application_insights/mock_sender.rb +37 -37
  79. data/test/application_insights/rack/test_track_request.rb +142 -139
  80. data/test/application_insights/test_telemetry_client.rb +133 -123
  81. data/test/application_insights/test_unhandled_exception.rb +23 -24
  82. metadata +23 -33
@@ -1,75 +1,83 @@
1
- require_relative '../../../lib/application_insights/channel/telemetry_context'
2
- require 'test/unit'
3
-
4
- include ApplicationInsights::Channel
5
-
6
- class TestTelemetryContext < Test::Unit::TestCase
7
- def test_initialize
8
- context = TelemetryContext.new
9
- assert_nil context.instrumentation_key
10
- assert_not_nil context.application
11
- assert_not_nil context.device
12
- assert_not_nil context.user
13
- assert_not_nil context.session
14
- assert_not_nil context.operation
15
- assert_not_nil context.location
16
- assert_not_nil context.properties
17
- end
18
-
19
- def test_application_works_as_expected
20
- context = TelemetryContext.new
21
- assert_not_nil context.application
22
- expected = Contracts::Application.new
23
- context.application = expected
24
- assert_same expected, context.application
25
- end
26
-
27
- def test_device_works_as_expected
28
- context = TelemetryContext.new
29
- assert_not_nil context.device
30
- expected = Contracts::Device.new
31
- context.device = expected
32
- assert_same expected, context.device
33
- end
34
-
35
- def test_user_works_as_expected
36
- context = TelemetryContext.new
37
- assert_not_nil context.user
38
- expected = Contracts::User.new
39
- context.user = expected
40
- assert_same expected, context.user
41
- end
42
-
43
- def test_session_works_as_expected
44
- context = TelemetryContext.new
45
- assert_not_nil context.session
46
- expected = Contracts::Session.new
47
- context.session = expected
48
- assert_same expected, context.session
49
- end
50
-
51
- def test_operation_works_as_expected
52
- context = TelemetryContext.new
53
- assert_not_nil context.operation
54
- expected = Contracts::Operation.new
55
- context.operation = expected
56
- assert_same expected, context.operation
57
- end
58
-
59
- def test_location_works_as_expected
60
- context = TelemetryContext.new
61
- assert_not_nil context.location
62
- expected = Contracts::Location.new
63
- context.location = expected
64
- assert_same expected, context.location
65
- end
66
-
67
- def test_properties_works_as_expected
68
- context = TelemetryContext.new
69
- assert_not_nil context.properties
70
- assert_equal 0, context.properties.count
71
- expected = {:a => 'a', :b => 'b'}
72
- context.properties = expected
73
- assert_same expected, context.properties
74
- end
1
+ require_relative '../../../lib/application_insights/channel/telemetry_context'
2
+ require 'test/unit'
3
+
4
+ include ApplicationInsights::Channel
5
+
6
+ class TestTelemetryContext < Test::Unit::TestCase
7
+ def test_initialize
8
+ context = TelemetryContext.new
9
+ assert_nil context.instrumentation_key
10
+ assert_not_nil context.application
11
+ assert_not_nil context.device
12
+ assert_not_nil context.user
13
+ assert_not_nil context.session
14
+ assert_not_nil context.operation
15
+ assert_not_nil context.location
16
+ assert_not_nil context.properties
17
+ end
18
+
19
+ def test_application_works_as_expected
20
+ context = TelemetryContext.new
21
+ assert_not_nil context.application
22
+ expected = Contracts::Application.new
23
+ context.application = expected
24
+ assert_same expected, context.application
25
+ end
26
+
27
+ def test_cloud_works_as_expected
28
+ context = TelemetryContext.new
29
+ assert_not_nil context.cloud
30
+ expected = Contracts::Cloud.new
31
+ context.cloud = expected
32
+ assert_same expected, context.cloud
33
+ end
34
+
35
+ def test_device_works_as_expected
36
+ context = TelemetryContext.new
37
+ assert_not_nil context.device
38
+ expected = Contracts::Device.new
39
+ context.device = expected
40
+ assert_same expected, context.device
41
+ end
42
+
43
+ def test_user_works_as_expected
44
+ context = TelemetryContext.new
45
+ assert_not_nil context.user
46
+ expected = Contracts::User.new
47
+ context.user = expected
48
+ assert_same expected, context.user
49
+ end
50
+
51
+ def test_session_works_as_expected
52
+ context = TelemetryContext.new
53
+ assert_not_nil context.session
54
+ expected = Contracts::Session.new
55
+ context.session = expected
56
+ assert_same expected, context.session
57
+ end
58
+
59
+ def test_operation_works_as_expected
60
+ context = TelemetryContext.new
61
+ assert_not_nil context.operation
62
+ expected = Contracts::Operation.new
63
+ context.operation = expected
64
+ assert_same expected, context.operation
65
+ end
66
+
67
+ def test_location_works_as_expected
68
+ context = TelemetryContext.new
69
+ assert_not_nil context.location
70
+ expected = Contracts::Location.new
71
+ context.location = expected
72
+ assert_same expected, context.location
73
+ end
74
+
75
+ def test_properties_works_as_expected
76
+ context = TelemetryContext.new
77
+ assert_not_nil context.properties
78
+ assert_equal 0, context.properties.count
79
+ expected = {:a => 'a', :b => 'b'}
80
+ context.properties = expected
81
+ assert_same expected, context.properties
82
+ end
75
83
  end
@@ -1,37 +1,37 @@
1
- require_relative '../../lib/application_insights/channel/synchronous_sender'
2
- require_relative '../../lib/application_insights/channel/asynchronous_sender'
3
-
4
- include ApplicationInsights::Channel
5
-
6
- class MockSynchronousSender < SynchronousSender
7
- def initialize
8
- @buffer = []
9
- super
10
- end
11
-
12
- attr_accessor :buffer
13
-
14
- def send(data)
15
- @buffer << data
16
- end
17
- end
18
-
19
- class MockAsynchronousSender < AsynchronousSender
20
- def initialize
21
- @buffer = []
22
- @start_call_count = 0
23
- super
24
- end
25
-
26
- attr_accessor :start_call_count
27
- attr_accessor :buffer
28
-
29
- def start
30
- @start_call_count += 1
31
- super
32
- end
33
-
34
- def send(data)
35
- @buffer << data
36
- end
37
- end
1
+ require_relative '../../lib/application_insights/channel/synchronous_sender'
2
+ require_relative '../../lib/application_insights/channel/asynchronous_sender'
3
+
4
+ include ApplicationInsights::Channel
5
+
6
+ class MockSynchronousSender < SynchronousSender
7
+ def initialize
8
+ @buffer = []
9
+ super
10
+ end
11
+
12
+ attr_accessor :buffer
13
+
14
+ def send(data)
15
+ @buffer << data
16
+ end
17
+ end
18
+
19
+ class MockAsynchronousSender < AsynchronousSender
20
+ def initialize
21
+ @buffer = []
22
+ @start_call_count = 0
23
+ super
24
+ end
25
+
26
+ attr_accessor :start_call_count
27
+ attr_accessor :buffer
28
+
29
+ def start
30
+ @start_call_count += 1
31
+ super
32
+ end
33
+
34
+ def send(data)
35
+ @buffer << data
36
+ end
37
+ end
@@ -1,139 +1,142 @@
1
- require 'test/unit'
2
- require 'rack/mock'
3
- require_relative '../mock_sender'
4
- require_relative '../../../lib/application_insights/rack/track_request'
5
-
6
- include ApplicationInsights::Rack
7
-
8
- class TestTrackRequest < Test::Unit::TestCase
9
- def test_call_works_as_expected
10
- response_code = rand(200..204)
11
- app = Proc.new {|env| sleep(2); [response_code, {"Content-Type" => "text/html"}, ["Hello Rack!"]]}
12
- url = "http://localhost:8080/foo?a=b"
13
- http_method = 'PUT'
14
- env = Rack::MockRequest.env_for(url, :method => http_method)
15
- instrumentation_key = 'key'
16
- sender = MockAsynchronousSender.new
17
- track_request = TrackRequest.new app, instrumentation_key, 500, 1
18
- track_request.send(:sender=, sender)
19
- start_time = Time.now
20
- result = track_request.call(env)
21
- assert_equal app.call(env), result
22
- sleep(sender.send_interval)
23
-
24
- assert_equal 1, sender.buffer.count
25
- payload = sender.buffer[0]
26
- assert_equal instrumentation_key, payload[0].i_key
27
-
28
- request_data = payload[0].data.base_data
29
- assert_equal "#{http_method} /foo", request_data.name
30
- assert_equal response_code, request_data.response_code
31
- assert_equal true, request_data.success
32
- assert_equal http_method, request_data.http_method
33
- assert_equal url, request_data.url
34
- assert_equal true, request_data.duration.start_with?("0:00:00:02")
35
- assert Time.parse(request_data.start_time) - start_time < 0.01
36
- end
37
-
38
- def test_call_with_failed_request
39
- response_code = rand(400..600)
40
- app = Proc.new {|env| [response_code, {"Content-Type" => "text/html"}, ["Hello Rack!"]]}
41
- url = "http://localhost:8080/foo"
42
- http_method = 'PUT'
43
- env = Rack::MockRequest.env_for(url, :method => http_method)
44
- instrumentation_key = 'key'
45
- sender = MockAsynchronousSender.new
46
- track_request = TrackRequest.new app, instrumentation_key, 500, 1
47
- track_request.send(:sender=, sender)
48
- track_request.call(env)
49
- sleep(sender.send_interval)
50
-
51
- payload = sender.buffer[0]
52
- request_data = payload[0].data.base_data
53
- assert_equal false, request_data.success
54
- end
55
-
56
- def test_call_with_unhandled_exception
57
- app = Proc.new {|env| raise StandardError, 'Boom!'}
58
- env = Rack::MockRequest.env_for( "http://localhost:8080/foo", :method => "GET")
59
- instrumentation_key = 'key'
60
- sender = MockAsynchronousSender.new
61
- track_request = TrackRequest.new app, instrumentation_key, 500, 1
62
- track_request.send(:sender=, sender)
63
-
64
- begin
65
- track_request.call(env)
66
- rescue => ex
67
- assert_equal 'Boom!', ex.message
68
- end
69
-
70
- sleep(sender.send_interval)
71
- payload = sender.buffer[0]
72
- assert_equal 2, payload.count
73
- request_data = payload[0].data.base_data
74
- assert_equal false, request_data.success
75
- assert_equal 500, request_data.response_code
76
-
77
- exception_data = payload[1].data.base_data
78
- assert_equal instrumentation_key, payload[1].i_key
79
- assert_equal 'Unhandled', exception_data.handled_at
80
- end
81
-
82
- def test_internal_client
83
- app = Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["Hello Rack!"]]}
84
- env = Rack::MockRequest.env_for('http://localhost:8080/foo', :method => "GET")
85
- buffer_size = 30
86
- send_interval = 5
87
- track_request = TrackRequest.new app, 'key', buffer_size, send_interval
88
- client = track_request.send(:client)
89
- # test lazy initialization
90
- assert_nil client
91
-
92
- track_request.call(env)
93
- client = track_request.send(:client)
94
- channel = client.channel
95
- assert_equal buffer_size, channel.queue.max_queue_length
96
- assert_equal send_interval, channel.sender.send_interval
97
-
98
- track_request.call(env)
99
- client2 = track_request.send(:client)
100
- channel2 = client2.channel
101
- assert_same client, client2
102
- assert_same channel, channel2
103
- end
104
-
105
- def test_format_request_duration_less_than_a_day
106
- app = Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["Hello Rack!"]]}
107
- track_request = TrackRequest.new app, 'one'
108
- duration_seconds = rand(86400) + rand
109
- time_span = track_request.send(:format_request_duration, duration_seconds)
110
- time_span_format = /^(?<day>\d{1}):(?<hour>\d{2}):(?<minute>\d{2}):(?<second>\d{2}).(?<fraction>\d{7})$/
111
- match = time_span_format.match time_span
112
- assert_not_nil match
113
- days = duration_seconds.to_i/86400
114
- assert_equal days, match['day'].to_i
115
- hours = (duration_seconds - days * 86400).to_i/3600
116
- assert_equal hours, match['hour'].to_i
117
- minutes = (duration_seconds - days * 86400 - hours * 3600).to_i/60
118
- assert_equal minutes, match['minute'].to_i
119
- seconds = (duration_seconds - days * 86400 - hours * 3600 - minutes * 60).to_i
120
- assert_equal seconds, match['second'].to_i
121
- fraction = ((duration_seconds - duration_seconds.to_i) * 10 ** 7).to_i
122
- assert_equal fraction, match['fraction'].to_i
123
- end
124
-
125
- def test_format_request_duration_more_than_a_day
126
- app = Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["Hello Rack!"]]}
127
- track_request = TrackRequest.new app, 'one'
128
- duration_seconds = rand(86400..240000) + rand
129
- time_span = track_request.send(:format_request_duration, duration_seconds)
130
- time_span_format = /^(?<day>\d{1}):(?<hour>\d{2}):(?<minute>\d{2}):(?<second>\d{2}).(?<fraction>\d{7})$/
131
- match = time_span_format.match time_span
132
- assert_not_nil match
133
- assert_equal 1, match['day'].to_i
134
- assert_equal 0, match['hour'].to_i
135
- assert_equal 0, match['minute'].to_i
136
- assert_equal 0, match['second'].to_i
137
- assert_equal 0, match['fraction'].to_i
138
- end
139
- end
1
+ require 'test/unit'
2
+ require 'rack/mock'
3
+ require_relative '../mock_sender'
4
+ require_relative '../../../lib/application_insights/rack/track_request'
5
+
6
+ include ApplicationInsights::Rack
7
+
8
+ class TestTrackRequest < Test::Unit::TestCase
9
+
10
+ TIME_SPAN_FORMAT = /^(?<day>\d{2})\.(?<hour>\d{2}):(?<minute>\d{2}):(?<second>\d{2}).(?<fraction>\d{7})$/
11
+
12
+ def test_call_works_as_expected
13
+ response_code = rand(200..204)
14
+ app = Proc.new {|env| sleep(2.5); [response_code, {"Content-Type" => "text/html"}, ["Hello Rack!"]]}
15
+ url = "http://localhost:8080/foo?a=b"
16
+ http_method = 'PUT'
17
+ env = Rack::MockRequest.env_for(url, :method => http_method)
18
+ instrumentation_key = 'key'
19
+ sender = MockAsynchronousSender.new
20
+ track_request = TrackRequest.new app, instrumentation_key, 500, 1
21
+ track_request.send(:sender=, sender)
22
+ start_time = Time.now
23
+ result = track_request.call(env)
24
+ assert_equal app.call(env), result
25
+ sleep(sender.send_interval)
26
+
27
+ assert_equal 1, sender.buffer.count
28
+ payload = sender.buffer[0]
29
+ assert_equal instrumentation_key, payload[0].i_key
30
+
31
+ request_data = payload[0].data.base_data
32
+ assert_equal "#{http_method} /foo", request_data.name
33
+ assert_equal response_code, request_data.response_code
34
+ assert_equal true, request_data.success
35
+ assert_equal http_method, request_data.http_method
36
+ assert_equal url, request_data.url
37
+ assert_equal true, request_data.duration.start_with?("00.00:00:02")
38
+ assert Time.parse(request_data.start_time) - start_time < 0.01
39
+ end
40
+
41
+ def test_call_with_failed_request
42
+ response_code = rand(400..600)
43
+ app = Proc.new {|env| [response_code, {"Content-Type" => "text/html"}, ["Hello Rack!"]]}
44
+ url = "http://localhost:8080/foo"
45
+ http_method = 'PUT'
46
+ env = Rack::MockRequest.env_for(url, :method => http_method)
47
+ instrumentation_key = 'key'
48
+ sender = MockAsynchronousSender.new
49
+ track_request = TrackRequest.new app, instrumentation_key, 500, 1
50
+ track_request.send(:sender=, sender)
51
+ track_request.call(env)
52
+ sleep(sender.send_interval)
53
+
54
+ payload = sender.buffer[0]
55
+ request_data = payload[0].data.base_data
56
+ assert_equal false, request_data.success
57
+ end
58
+
59
+ def test_call_with_unhandled_exception
60
+ app = Proc.new {|env| raise StandardError, 'Boom!'}
61
+ env = Rack::MockRequest.env_for( "http://localhost:8080/foo", :method => "GET")
62
+ instrumentation_key = 'key'
63
+ sender = MockAsynchronousSender.new
64
+ track_request = TrackRequest.new app, instrumentation_key, 500, 1
65
+ track_request.send(:sender=, sender)
66
+
67
+ begin
68
+ track_request.call(env)
69
+ rescue => ex
70
+ assert_equal 'Boom!', ex.message
71
+ end
72
+
73
+ sleep(sender.send_interval)
74
+ payload = sender.buffer[0]
75
+ assert_equal 2, payload.count
76
+ request_data = payload[0].data.base_data
77
+ assert_equal false, request_data.success
78
+ assert_equal 500, request_data.response_code
79
+
80
+ exception_data = payload[1].data.base_data
81
+ assert_equal instrumentation_key, payload[1].i_key
82
+ assert_equal 'Unhandled', exception_data.handled_at
83
+ end
84
+
85
+ def test_internal_client
86
+ app = Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["Hello Rack!"]]}
87
+ env = Rack::MockRequest.env_for('http://localhost:8080/foo', :method => "GET")
88
+ buffer_size = 30
89
+ send_interval = 5
90
+ track_request = TrackRequest.new app, 'key', buffer_size, send_interval
91
+ client = track_request.send(:client)
92
+ # test lazy initialization
93
+ assert_nil client
94
+
95
+ track_request.call(env)
96
+ client = track_request.send(:client)
97
+ channel = client.channel
98
+ assert_equal buffer_size, channel.queue.max_queue_length
99
+ assert_equal send_interval, channel.sender.send_interval
100
+
101
+ track_request.call(env)
102
+ client2 = track_request.send(:client)
103
+ channel2 = client2.channel
104
+ assert_same client, client2
105
+ assert_same channel, channel2
106
+ end
107
+
108
+ def test_format_request_duration_less_than_a_day
109
+ app = Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["Hello Rack!"]]}
110
+ track_request = TrackRequest.new app, 'one'
111
+ duration_seconds = rand(86400) + rand
112
+ time_span = track_request.send(:format_request_duration, duration_seconds)
113
+
114
+ match = TIME_SPAN_FORMAT.match time_span
115
+ assert_not_nil match
116
+ days = duration_seconds.to_i/86400
117
+ assert_equal days, match['day'].to_i
118
+ hours = (duration_seconds - days * 86400).to_i/3600
119
+ assert_equal hours, match['hour'].to_i
120
+ minutes = (duration_seconds - days * 86400 - hours * 3600).to_i/60
121
+ assert_equal minutes, match['minute'].to_i
122
+ seconds = (duration_seconds - days * 86400 - hours * 3600 - minutes * 60).to_i
123
+ assert_equal seconds, match['second'].to_i
124
+ fraction = ((duration_seconds - duration_seconds.to_i) * 10 ** 7).to_i
125
+ assert_equal fraction, match['fraction'].to_i
126
+ end
127
+
128
+ def test_format_request_duration_more_than_a_day
129
+ app = Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["Hello Rack!"]]}
130
+ track_request = TrackRequest.new app, 'one'
131
+ duration_seconds = rand(86400..240000) + rand
132
+ time_span = track_request.send(:format_request_duration, duration_seconds)
133
+
134
+ match = TIME_SPAN_FORMAT.match time_span
135
+ assert_not_nil match
136
+ assert_equal 1, match['day'].to_i
137
+ assert_equal 0, match['hour'].to_i
138
+ assert_equal 0, match['minute'].to_i
139
+ assert_equal 0, match['second'].to_i
140
+ assert_equal 0, match['fraction'].to_i
141
+ end
142
+ end