1//
2// SyslogTest.cpp
3//
4// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
5// and Contributors.
6//
7// SPDX-License-Identifier: BSL-1.0
8//
9
10
11#include "SyslogTest.h"
12#include "Poco/CppUnit/TestCaller.h"
13#include "Poco/CppUnit/TestSuite.h"
14#include "Poco/Net/RemoteSyslogChannel.h"
15#include "Poco/Net/RemoteSyslogListener.h"
16#include "Poco/Net/DNS.h"
17#include "Poco/Thread.h"
18#include "Poco/Message.h"
19#include "Poco/AutoPtr.h"
20#include <list>
21
22
23using namespace Poco::Net;
24
25
26class CachingChannel: public Poco::Channel
27 /// Caches the last n Messages in memory
28{
29public:
30 typedef Poco::AutoPtr<CachingChannel> Ptr;
31 typedef std::list<Poco::Message> Messages;
32
33 CachingChannel(std::size_t n = 100);
34 /// Creates the CachingChannel. Caches n messages in memory
35
36 void log(const Poco::Message& msg);
37 /// Writes the log message to the cache
38
39 void getMessages(std::vector<Poco::Message>& msg, int offset, int numEntries) const;
40 /// Retrieves numEntries Messages starting with position offset. Most recent messages are first.
41
42 std::size_t getMaxSize() const;
43
44 std::size_t getCurrentSize() const;
45
46protected:
47 ~CachingChannel();
48 /// Destroys the CachingChannel.
49
50private:
51 CachingChannel(const CachingChannel&);
52
53 Messages _cache;
54 std::size_t _size;
55 std::size_t _maxSize;
56 mutable Poco::FastMutex _mutex;
57};
58
59
60std::size_t CachingChannel::getMaxSize() const
61{
62 return _maxSize;
63}
64
65
66std::size_t CachingChannel::getCurrentSize() const
67{
68 return _size;
69}
70
71
72CachingChannel::CachingChannel(std::size_t n):
73 _cache(),
74 _size(0),
75 _maxSize(n),
76 _mutex()
77{
78}
79
80
81CachingChannel::~CachingChannel()
82{
83}
84
85
86void CachingChannel::log(const Poco::Message& msg)
87{
88 Poco::FastMutex::ScopedLock lock(_mutex);
89 _cache.push_front(msg);
90 if (_size == _maxSize)
91 {
92 _cache.pop_back();
93 }
94 else
95 ++_size;
96}
97
98
99void CachingChannel::getMessages(std::vector<Poco::Message>& msg, int offset, int numEntries) const
100{
101 msg.clear();
102 Messages::const_iterator it = _cache.begin();
103
104 while (offset > 0 && it != _cache.end())
105 ++it;
106
107 while (numEntries > 0 && it != _cache.end())
108 {
109 msg.push_back(*it);
110 ++it;
111 }
112}
113
114
115SyslogTest::SyslogTest(const std::string& name): CppUnit::TestCase(name)
116{
117}
118
119
120SyslogTest::~SyslogTest()
121{
122}
123
124
125void SyslogTest::testListener()
126{
127 Poco::AutoPtr<RemoteSyslogChannel> channel = new RemoteSyslogChannel();
128 channel->setProperty("loghost", "127.0.0.1:51400");
129 channel->open();
130 Poco::AutoPtr<RemoteSyslogListener> listener = new RemoteSyslogListener(51400);
131 listener->open();
132 CachingChannel::Ptr pCL = new CachingChannel;
133 listener->addChannel(pCL);
134 assertTrue (pCL->getCurrentSize() == 0);
135 Poco::Message msg("asource", "amessage", Poco::Message::PRIO_CRITICAL);
136 channel->log(msg);
137 Poco::Thread::sleep(1000);
138 listener->close();
139 channel->close();
140 assertTrue (pCL->getCurrentSize() == 1);
141 std::vector<Poco::Message> msgs;
142 pCL->getMessages(msgs, 0, 10);
143 assertTrue (msgs.size() == 1);
144 assertTrue (msgs[0].getSource() == "asource");
145 assertTrue (msgs[0].getText() == "amessage");
146 assertTrue (msgs[0].getPriority() == Poco::Message::PRIO_CRITICAL);
147}
148
149
150void SyslogTest::testChannelOpenClose()
151{
152 Poco::AutoPtr<RemoteSyslogChannel> channel = new RemoteSyslogChannel();
153 channel->setProperty("loghost", "127.0.0.1:51400");
154 channel->open();
155 Poco::AutoPtr<RemoteSyslogListener> listener = new RemoteSyslogListener(51400);
156 listener->open();
157 CachingChannel::Ptr pCL = new CachingChannel;
158 listener->addChannel(pCL);
159
160 assertTrue (pCL->getCurrentSize() == 0);
161 Poco::Message msg1("source1", "message1", Poco::Message::PRIO_CRITICAL);
162 channel->log(msg1);
163 Poco::Thread::sleep(1000);
164 assertTrue (pCL->getCurrentSize() == 1);
165
166 channel->close(); // close and re-open channel
167 channel->open();
168
169 Poco::Message msg2("source2", "message2", Poco::Message::PRIO_ERROR);
170 channel->log(msg2);
171 Poco::Thread::sleep(1000);
172 assertTrue (pCL->getCurrentSize() == 2);
173
174 listener->close();
175 std::vector<Poco::Message> msgs;
176 pCL->getMessages(msgs, 0, 10);
177 assertTrue (msgs.size() == 2);
178
179 assertTrue (msgs[1].getSource() == "source1");
180 assertTrue (msgs[1].getText() == "message1");
181 assertTrue (msgs[1].getPriority() == Poco::Message::PRIO_CRITICAL);
182
183 assertTrue (msgs[0].getSource() == "source2");
184 assertTrue (msgs[0].getText() == "message2");
185 assertTrue (msgs[0].getPriority() == Poco::Message::PRIO_ERROR);
186}
187
188
189void SyslogTest::testOldBSD()
190{
191 Poco::AutoPtr<RemoteSyslogChannel> channel = new RemoteSyslogChannel();
192 channel->setProperty("loghost", "127.0.0.1:51400");
193 channel->setProperty("format", "bsd");
194 channel->open();
195 Poco::AutoPtr<RemoteSyslogListener> listener = new RemoteSyslogListener(51400);
196 listener->open();
197 CachingChannel::Ptr pCL = new CachingChannel;
198 listener->addChannel(pCL);
199 assertTrue (pCL->getCurrentSize() == 0);
200 Poco::Message msg("asource", "amessage", Poco::Message::PRIO_CRITICAL);
201 channel->log(msg);
202 Poco::Thread::sleep(1000);
203 listener->close();
204 channel->close();
205 assertTrue (pCL->getCurrentSize() == 1);
206 std::vector<Poco::Message> msgs;
207 pCL->getMessages(msgs, 0, 10);
208 assertTrue (msgs.size() == 1);
209 // the source is lost with old BSD messages: we only send the local host name!
210 assertTrue (msgs[0].getSource() == Poco::Net::DNS::thisHost().name());
211 assertTrue (msgs[0].getText() == "amessage");
212 assertTrue (msgs[0].getPriority() == Poco::Message::PRIO_CRITICAL);
213}
214
215
216void SyslogTest::testStructuredData()
217{
218 Poco::AutoPtr<RemoteSyslogChannel> channel = new RemoteSyslogChannel();
219 channel->setProperty("loghost", "127.0.0.1:51400");
220 channel->open();
221 Poco::AutoPtr<RemoteSyslogListener> listener = new RemoteSyslogListener(51400);
222 listener->open();
223 CachingChannel::Ptr cl = new CachingChannel;
224 listener->addChannel(cl);
225 assertTrue (cl->getCurrentSize() == 0);
226 Poco::Message msg1("asource", "amessage", Poco::Message::PRIO_CRITICAL);
227 msg1.set("structured-data", "[exampleSDID@32473 iut=\"3\" eventSource=\"Application\" eventID=\"1011\"]");
228 channel->log(msg1);
229 Poco::Message msg2("asource", "amessage", Poco::Message::PRIO_CRITICAL);
230 msg2.set("structured-data", "[exampleSDID@32473 iut=\"3\" eventSource=\"Application\" eventID=\"1011\"][examplePriority@32473 class=\"high\"]");
231 channel->log(msg2);
232 Poco::Thread::sleep(1000);
233 listener->close();
234 channel->close();
235 assertTrue (cl->getCurrentSize() == 2);
236 std::vector<Poco::Message> msgs;
237 cl->getMessages(msgs, 0, 10);
238 assertTrue (msgs.size() == 2);
239
240 assertTrue (msgs[0].getSource() == "asource");
241 assertTrue (msgs[0].getText() == "amessage");
242 assertTrue (msgs[0].getPriority() == Poco::Message::PRIO_CRITICAL);
243 assertTrue (msgs[0].get("structured-data") == "[exampleSDID@32473 iut=\"3\" eventSource=\"Application\" eventID=\"1011\"][examplePriority@32473 class=\"high\"]");
244
245 assertTrue (msgs[1].getSource() == "asource");
246 assertTrue (msgs[1].getText() == "amessage");
247 assertTrue (msgs[1].getPriority() == Poco::Message::PRIO_CRITICAL);
248 assertTrue (msgs[1].get("structured-data") == "[exampleSDID@32473 iut=\"3\" eventSource=\"Application\" eventID=\"1011\"]");
249}
250
251
252void SyslogTest::setUp()
253{
254}
255
256
257void SyslogTest::tearDown()
258{
259}
260
261
262CppUnit::Test* SyslogTest::suite()
263{
264 CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("SyslogTest");
265
266 CppUnit_addTest(pSuite, SyslogTest, testListener);
267 CppUnit_addTest(pSuite, SyslogTest, testChannelOpenClose);
268 CppUnit_addTest(pSuite, SyslogTest, testOldBSD);
269 CppUnit_addTest(pSuite, SyslogTest, testStructuredData);
270
271 return pSuite;
272}
273