PageRenderTime 50ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/test/test-access-log-parser.rb

https://github.com/ranguba/racknga
Ruby | 303 lines | 233 code | 52 blank | 18 comment | 0 complexity | 17dfb771914406f42e1952fa5b1307ab MD5 | raw file
  1. # -*- coding: utf-8 -*-
  2. #
  3. # Copyright (C) 2011 Ryo Onodera <onodera@clear-code.com>
  4. # Copyright (C) 2011 Kouhei Sutou <kou@clear-code.com>
  5. #
  6. # This library is free software; you can redistribute it and/or
  7. # modify it under the terms of the GNU Lesser General Public
  8. # License as published by the Free Software Foundation; either
  9. # version 2.1 of the License, or (at your option) any later version.
  10. #
  11. # This library is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. # Lesser General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU Lesser General Public
  17. # License along with this library; if not, write to the Free Software
  18. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. require 'stringio'
  20. module AccessLogParserTests
  21. module Data
  22. private
  23. def time_local
  24. "03/Aug/2011:16:58:01 +0900"
  25. end
  26. def log_line(content)
  27. content
  28. end
  29. def usual_log_line
  30. log_line("127.0.0.1 - - #{time_log_component} " +
  31. "\"GET / HTTP/1.1\" 200 613 \"-\" \"Ruby\"")
  32. end
  33. def usual_log_entry_options
  34. {
  35. :remote_address => "127.0.0.1",
  36. :remote_user => nil,
  37. :time_local => Time.local(2011, 8, 3, 16, 58, 1),
  38. :runtime => runtime,
  39. :request_time => request_time,
  40. :request => "GET / HTTP/1.1",
  41. :status => 200,
  42. :body_bytes_sent => 613,
  43. :http_referer => nil,
  44. :http_user_agent => "Ruby",
  45. }
  46. end
  47. def usual_log_entry
  48. create_log_entry(usual_log_entry_options)
  49. end
  50. def not_found_log_line
  51. log_line("127.0.0.1 - - #{time_log_component} " +
  52. "\"GET /the-truth.html HTTP/1.1\" 404 613 \"-\" \"Ruby\"")
  53. end
  54. def not_found_log_entry
  55. options = {
  56. :status => 404,
  57. :request => "GET /the-truth.html HTTP/1.1",
  58. }
  59. create_log_entry(usual_log_entry_options.merge(options))
  60. end
  61. def utf8_path
  62. "/トップページ.html"
  63. end
  64. def valid_utf8_log_line
  65. path = utf8_path
  66. log_line("127.0.0.1 - - #{time_log_component} " +
  67. "\"GET #{path} HTTP/1.1\" 200 613 \"-\" \"Ruby\"")
  68. end
  69. def valid_utf8_log_entry
  70. options = {
  71. :request => "GET #{utf8_path} HTTP/1.1",
  72. }
  73. create_log_entry(usual_log_entry_options.merge(options))
  74. end
  75. def garbled_path
  76. "/#{Random.new.bytes(10)}".force_encoding(Encoding::UTF_8)
  77. end
  78. def invalid_utf8_log_line
  79. path = garbled_path
  80. log_line("127.0.0.1 - - #{time_log_component} " +
  81. "\"GET #{path} HTTP/1.1\" 200 613 \"-\" \"Ruby\"")
  82. end
  83. def ipv6_log_line
  84. log_line("::1 - - #{time_log_component} " +
  85. "\"GET / HTTP/1.1\" 200 613 \"-\" \"Ruby\"")
  86. end
  87. def ipv6_log_entry
  88. options = {
  89. :remote_address => "::1",
  90. }
  91. create_log_entry(usual_log_entry_options.merge(options))
  92. end
  93. def apache_combined_log_line
  94. log_line("127.0.0.1 - - #{time_log_component} " +
  95. "\"GET / HTTP/1.1\" 200 613 \"-\" \"Ruby\"")
  96. end
  97. def apache_combined_log_entry
  98. usual_log_entry
  99. end
  100. def no_body_bytes_sent_log_line
  101. log_line("127.0.0.1 - - #{time_log_component} " +
  102. "\"GET / HTTP/1.1\" 200 - \"-\" \"Ruby\"")
  103. end
  104. def no_body_bytes_sent_log_entry
  105. options = {
  106. :body_bytes_sent => nil,
  107. }
  108. create_log_entry(usual_log_entry_options.merge(options))
  109. end
  110. def bad_log_line
  111. "bad"
  112. end
  113. end
  114. module Environment
  115. private
  116. def create_log_entry(options)
  117. Racknga::LogEntry.new(options)
  118. end
  119. def create_log_file(string)
  120. StringIO.new(string)
  121. end
  122. def create_log_parser(file)
  123. Racknga::AccessLogParser.new(file)
  124. end
  125. def create_reversed_log_parser(file)
  126. Racknga::ReversedAccessLogParser.new(file)
  127. end
  128. def join_lines(*lines)
  129. lines.collect do |line|
  130. line + "\n"
  131. end.join
  132. end
  133. def parse(string)
  134. file = create_log_file(string)
  135. parser = create_log_parser(file)
  136. parser.collect.to_a
  137. end
  138. def reversed_parse(string)
  139. file = create_log_file(string)
  140. parser = create_reversed_log_parser(file)
  141. parser.collect.to_a
  142. end
  143. end
  144. module Tests
  145. def test_usual_log
  146. accesses = parse(join_lines(usual_log_line))
  147. assert_equal([usual_log_entry],
  148. accesses)
  149. end
  150. def test_ipv6_log
  151. accesses = parse(join_lines(ipv6_log_line))
  152. assert_equal([ipv6_log_entry],
  153. accesses)
  154. end
  155. def test_apache_combined_log
  156. accesses = parse(join_lines(apache_combined_log_line))
  157. assert_equal([apache_combined_log_entry],
  158. accesses)
  159. end
  160. def test_no_body_bytes_sent_log
  161. accesses = parse(join_lines(no_body_bytes_sent_log_line))
  162. assert_equal([no_body_bytes_sent_log_entry],
  163. accesses)
  164. end
  165. def test_no_log
  166. accesses = parse(join_lines())
  167. assert_equal([], accesses)
  168. end
  169. def test_multiple_logs
  170. accesses = parse(join_lines(usual_log_line,
  171. usual_log_line,
  172. not_found_log_line))
  173. assert_equal([usual_log_entry,
  174. usual_log_entry,
  175. not_found_log_entry],
  176. accesses)
  177. end
  178. def test_reversed_parse
  179. accesses = reversed_parse(join_lines(usual_log_line,
  180. usual_log_line,
  181. not_found_log_line))
  182. assert_equal([usual_log_entry,
  183. usual_log_entry,
  184. not_found_log_entry].reverse,
  185. accesses)
  186. end
  187. def test_bad_log
  188. assert_raise(Racknga::AccessLogParser::FormatError) do
  189. parse(join_lines(bad_log_line))
  190. end
  191. end
  192. def test_invalid_utf8_log_line_ignored
  193. accesses = parse(join_lines(valid_utf8_log_line,
  194. invalid_utf8_log_line,
  195. valid_utf8_log_line))
  196. assert_equal([valid_utf8_log_entry,
  197. valid_utf8_log_entry],
  198. accesses)
  199. end
  200. end
  201. class CombinedLogTest < Test::Unit::TestCase
  202. include Environment
  203. include Data
  204. include Tests
  205. private
  206. def time_log_component
  207. times = [time_local, runtime, request_time].compact
  208. "[#{times.join(', ')}]"
  209. end
  210. def runtime
  211. nil
  212. end
  213. def request_time
  214. nil
  215. end
  216. end
  217. class CombinedWithTimeNginxLogTest < Test::Unit::TestCase
  218. include Environment
  219. include Data
  220. include Tests
  221. private
  222. def time_log_component
  223. times = [time_local, runtime, request_time].compact
  224. "[#{times.join(', ')}]"
  225. end
  226. def runtime
  227. 0.000573
  228. end
  229. def request_time
  230. 0.001
  231. end
  232. end
  233. class CombinedWithTimeApacheLogTest < Test::Unit::TestCase
  234. include Environment
  235. include Data
  236. include Tests
  237. private
  238. def time_log_component
  239. "[#{time_local}]"
  240. end
  241. def log_line(content)
  242. "#{content} #{runtime} #{(request_time * 1_000_000).to_i}"
  243. end
  244. def runtime
  245. 0.000573
  246. end
  247. def request_time
  248. 0.001
  249. end
  250. end
  251. end