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