• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"""Tests for apache_error_log_metrics."""
2
3import os
4import re
5import subprocess
6import tempfile
7import unittest
8
9import common
10
11import apache_error_log_metrics
12
13
14SCRIPT_PATH = os.path.abspath(
15    os.path.join(os.path.dirname(__file__),
16                 'apache_error_log_metrics.py'))
17
18
19class ApacheErrorTest(unittest.TestCase):
20    """Unittest for the apache error log regexp."""
21
22    def testNonMatchingLine(self):
23        """Test for log lines which don't match the expected format.."""
24        lines = [
25          '[] [] [] blank components',
26          '[] [:error] [] no "pid" section',
27          '[] [:error] [pid 1234] no timestamp',
28          '[hello world] [:] [pid 1234] no log level',
29          '[hello] [:error] [pid 42]     too far indented.'
30        ]
31        for line in lines:
32          self.assertEqual(
33              None, apache_error_log_metrics.ERROR_LOG_MATCHER.match(line))
34
35    def testMatchingLines(self):
36        """Test for lines that are expected to match the format."""
37        match = apache_error_log_metrics.ERROR_LOG_MATCHER.match(
38            "[foo] [:bar] [pid 123] WARNING")
39        self.assertEqual('bar', match.group('log_level'))
40        self.assertEqual(None, match.group('mod_wsgi'))
41
42        match = apache_error_log_metrics.ERROR_LOG_MATCHER.match(
43            "[foo] [:bar] [pid 123] mod_wsgi (pid=123)")
44        self.assertEqual('bar', match.group('log_level'))
45        self.assertEqual('od_wsgi', match.group('mod_wsgi'))
46
47    def testExampleLog(self):
48        """Try on some example lines from a real apache error log."""
49        with open(os.path.join(os.path.dirname(__file__),
50                               'apache_error_log_example.txt')) as fh:
51          example_log = fh.readlines()
52        matcher_output = [apache_error_log_metrics.ERROR_LOG_MATCHER.match(line)
53                          for line in example_log]
54        matched = filter(bool, matcher_output)
55        self.assertEqual(5, len(matched))
56
57        self.assertEqual('error', matched[0].group('log_level'))
58        self.assertEqual(None, matched[0].group('mod_wsgi'))
59
60        self.assertEqual('warn', matched[1].group('log_level'))
61        self.assertEqual('od_wsgi', matched[1].group('mod_wsgi'))
62
63        self.assertEqual('error', matched[2].group('log_level'))
64        self.assertEqual(None, matched[2].group('mod_wsgi'))
65
66        self.assertEqual('error', matched[3].group('log_level'))
67        self.assertEqual(None, matched[3].group('mod_wsgi'))
68
69        self.assertEqual('error', matched[4].group('log_level'))
70        self.assertEqual(None, matched[4].group('mod_wsgi'))
71
72    def testApacheErrorLogScriptWithNonMatchingLine(self):
73        """Try shelling out the the script with --debug-file.
74
75        Sending it a non-matching line should result in no output from
76        ERROR_LOG_METRIC.
77        """
78        with tempfile.NamedTemporaryFile() as temp_file:
79            p = subprocess.Popen([SCRIPT_PATH,
80                                  '--debug-metrics-file', temp_file.name],
81                                 stdin=subprocess.PIPE, stdout=subprocess.PIPE)
82            p.communicate('an-example-log-line')
83
84            with open(temp_file.name) as fh:
85                contents = fh.read()
86
87            # We have to use re.search here with a word border character ('\b')
88            # because the ERROR_LOG_LINE_METRIC contains ERROR_LOG_METRIC as a
89            # substring.
90            self.assertTrue(re.search(
91                apache_error_log_metrics.ERROR_LOG_LINE_METRIC[1:] + r'\b',
92                contents))
93            self.assertFalse(re.search(
94                apache_error_log_metrics.ERROR_LOG_METRIC[1:] + r'\b',
95                contents))
96
97    def testApachErrorLogScriptWithMatchingLine(self):
98        """Try shelling out the the script with --debug-file.
99
100        Sending it a line which matches the first-line regex should result in
101        output from ERROR_LOG_METRIC.
102        """
103        with tempfile.NamedTemporaryFile() as temp_file:
104            p = subprocess.Popen([SCRIPT_PATH,
105                                  '--debug-metrics-file', temp_file.name],
106                                 stdin=subprocess.PIPE, stdout=subprocess.PIPE)
107            p.communicate('[foo] [:bar] [pid 123] WARNING')
108
109            with open(temp_file.name) as fh:
110                contents = fh.read()
111
112            self.assertTrue(re.search(
113                apache_error_log_metrics.ERROR_LOG_LINE_METRIC[1:] + r'\b',
114                contents))
115            self.assertTrue(re.search(
116                apache_error_log_metrics.ERROR_LOG_METRIC[1:] + r'\b',
117                contents))
118
119
120if __name__ == '__main__':
121    unittest.main()
122