application_insights 0.5.3 → 0.5.4

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.
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