1import py
2import sys
3
4from py._log.log import default_keywordmapper
5
6callcapture = py.io.StdCapture.call
7
8def setup_module(mod):
9    mod._oldstate = default_keywordmapper.getstate()
10
11def teardown_module(mod):
12    default_keywordmapper.setstate(mod._oldstate)
13
14class TestLogProducer:
15    def setup_method(self, meth):
16        default_keywordmapper.setstate(_oldstate)
17
18    def test_getstate_setstate(self):
19        state = py.log._getstate()
20        py.log.setconsumer("hello", [].append)
21        state2 = py.log._getstate()
22        assert state2 != state
23        py.log._setstate(state)
24        state3 = py.log._getstate()
25        assert state3 == state
26
27    def test_producer_repr(self):
28        d = py.log.Producer("default")
29        assert repr(d).find('default') != -1
30
31    def test_produce_one_keyword(self):
32        l = []
33        py.log.setconsumer('s1', l.append)
34        py.log.Producer('s1')("hello world")
35        assert len(l) == 1
36        msg = l[0]
37        assert msg.content().startswith('hello world')
38        assert msg.prefix() == '[s1] '
39        assert str(msg) == "[s1] hello world"
40
41    def test_producer_class(self):
42        p = py.log.Producer('x1')
43        l = []
44        py.log.setconsumer(p._keywords, l.append)
45        p("hello")
46        assert len(l) == 1
47        assert len(l[0].keywords) == 1
48        assert 'x1' == l[0].keywords[0]
49
50    def test_producer_caching(self):
51        p = py.log.Producer('x1')
52        x2 = p.x2
53        assert x2 is p.x2
54
55class TestLogConsumer:
56    def setup_method(self, meth):
57        default_keywordmapper.setstate(_oldstate)
58    def test_log_none(self):
59        log = py.log.Producer("XXX")
60        l = []
61        py.log.setconsumer('XXX', l.append)
62        log("1")
63        assert l
64        l[:] = []
65        py.log.setconsumer('XXX', None)
66        log("2")
67        assert not l
68
69    def test_log_default_stderr(self):
70        res, out, err = callcapture(py.log.Producer("default"), "hello")
71        assert err.strip() == "[default] hello"
72
73    def test_simple_consumer_match(self):
74        l = []
75        py.log.setconsumer("x1", l.append)
76        p = py.log.Producer("x1 x2")
77        p("hello")
78        assert l
79        assert l[0].content() == "hello"
80
81    def test_simple_consumer_match_2(self):
82        l = []
83        p = py.log.Producer("x1 x2")
84        py.log.setconsumer(p._keywords, l.append)
85        p("42")
86        assert l
87        assert l[0].content() == "42"
88
89    def test_no_auto_producer(self):
90        p = py.log.Producer('x')
91        py.test.raises(AttributeError, "p._x")
92        py.test.raises(AttributeError, "p.x_y")
93
94    def test_setconsumer_with_producer(self):
95        l = []
96        p = py.log.Producer("hello")
97        py.log.setconsumer(p, l.append)
98        p("world")
99        assert str(l[0]) == "[hello] world"
100
101    def test_multi_consumer(self):
102        l = []
103        py.log.setconsumer("x1", l.append)
104        py.log.setconsumer("x1 x2", None)
105        p = py.log.Producer("x1 x2")
106        p("hello")
107        assert not l
108        py.log.Producer("x1")("hello")
109        assert l
110        assert l[0].content() == "hello"
111
112    def test_log_stderr(self):
113        py.log.setconsumer("xyz", py.log.STDOUT)
114        res, out, err = callcapture(py.log.Producer("xyz"), "hello")
115        assert not err
116        assert out.strip() == '[xyz] hello'
117
118    def test_log_file(self, tmpdir):
119        customlog = tmpdir.join('log.out')
120        py.log.setconsumer("default", open(str(customlog), 'w', 1))
121        py.log.Producer("default")("hello world #1")
122        assert customlog.readlines() == ['[default] hello world #1\n']
123
124        py.log.setconsumer("default", py.log.Path(customlog, buffering=False))
125        py.log.Producer("default")("hello world #2")
126        res = customlog.readlines()
127        assert res == ['[default] hello world #2\n'] # no append by default!
128
129    def test_log_file_append_mode(self, tmpdir):
130        logfilefn = tmpdir.join('log_append.out')
131
132        # The append mode is on by default, so we don't need to specify it for File
133        py.log.setconsumer("default", py.log.Path(logfilefn, append=True,
134                                                    buffering=0))
135        assert logfilefn.check()
136        py.log.Producer("default")("hello world #1")
137        lines = logfilefn.readlines()
138        assert lines == ['[default] hello world #1\n']
139        py.log.setconsumer("default", py.log.Path(logfilefn, append=True,
140                                                    buffering=0))
141        py.log.Producer("default")("hello world #1")
142        lines = logfilefn.readlines()
143        assert lines == ['[default] hello world #1\n',
144                         '[default] hello world #1\n']
145
146    def test_log_file_delayed_create(self, tmpdir):
147        logfilefn = tmpdir.join('log_create.out')
148
149        py.log.setconsumer("default", py.log.Path(logfilefn,
150                                        delayed_create=True, buffering=0))
151        assert not logfilefn.check()
152        py.log.Producer("default")("hello world #1")
153        lines = logfilefn.readlines()
154        assert lines == ['[default] hello world #1\n']
155
156    def test_keyword_based_log_files(self, tmpdir):
157        logfiles = []
158        keywords = 'k1 k2 k3'.split()
159        for key in keywords:
160            path = tmpdir.join(key)
161            py.log.setconsumer(key, py.log.Path(path, buffering=0))
162
163        py.log.Producer('k1')('1')
164        py.log.Producer('k2')('2')
165        py.log.Producer('k3')('3')
166
167        for key in keywords:
168            path = tmpdir.join(key)
169            assert path.read().strip() == '[%s] %s' % (key, key[-1])
170
171    # disabled for now; the syslog log file can usually be read only by root
172    # I manually inspected /var/log/messages and the entries were there
173    def no_test_log_syslog(self):
174        py.log.setconsumer("default", py.log.Syslog())
175        py.log.default("hello world #1")
176
177    # disabled for now until I figure out how to read entries in the
178    # Event Logs on Windows
179    # I manually inspected the Application Log and the entries were there
180    def no_test_log_winevent(self):
181        py.log.setconsumer("default", py.log.WinEvent())
182        py.log.default("hello world #1")
183
184    # disabled for now until I figure out how to properly pass the parameters
185    def no_test_log_email(self):
186        py.log.setconsumer("default", py.log.Email(mailhost="gheorghiu.net",
187                                                   fromaddr="grig",
188                                                   toaddrs="grig",
189                                                   subject = "py.log email"))
190        py.log.default("hello world #1")
191