Line data Source code
1 : /*
2 : * Copyright (c) 2006-2019 Made to Order Software Corp. All Rights Reserved
3 : *
4 : * https://snapwebsites.org/project/snaplogger
5 : * contact@m2osw.com
6 : *
7 : * This program is free software; you can redistribute it and/or modify
8 : * it under the terms of the GNU General Public License as published by
9 : * the Free Software Foundation; either version 2 of the License, or
10 : * (at your option) any later version.
11 : *
12 : * This program is distributed in the hope that it will be useful,
13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : * GNU General Public License for more details.
16 : *
17 : * You should have received a copy of the GNU General Public License along
18 : * with this program; if not, write to the Free Software Foundation, Inc.,
19 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 : */
21 :
22 : // self
23 : //
24 : #include "main.h"
25 :
26 :
27 : // snaplogger lib
28 : //
29 : #include <snaplogger/buffer_appender.h>
30 : #include <snaplogger/exception.h>
31 : #include <snaplogger/format.h>
32 : #include <snaplogger/logger.h>
33 : #include <snaplogger/map_diagnostic.h>
34 : #include <snaplogger/message.h>
35 : #include <snaplogger/severity.h>
36 : #include <snaplogger/version.h>
37 :
38 :
39 : // C lib
40 : //
41 : #include <unistd.h>
42 : #include <netdb.h>
43 : #include <sys/param.h>
44 :
45 :
46 :
47 :
48 :
49 3 : CATCH_TEST_CASE("variable_param", "[variable][param]")
50 : {
51 2 : CATCH_START_SECTION("Param Name is Mandatory")
52 : {
53 1 : CATCH_REQUIRE_THROWS_MATCHES(
54 : new snaplogger::param(std::string())
55 : , snaplogger::invalid_parameter
56 : , Catch::Matchers::ExceptionMessage(
57 : "a parameter must have a non-empty name."));
58 : }
59 : CATCH_END_SECTION()
60 1 : }
61 :
62 :
63 :
64 4 : CATCH_TEST_CASE("system_variable", "[variable][param]")
65 : {
66 4 : CATCH_START_SECTION("get_type() to use padding as integer or string (hostname)")
67 : {
68 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "message-logging");
69 :
70 2 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
71 2 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
72 :
73 1 : advgetopt::options_environment opt_env;
74 1 : opt_env.f_project_name = "test-logger";
75 2 : advgetopt::getopt opts(opt_env);
76 1 : buffer->set_config(opts);
77 :
78 2 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${hostname:padding=3:align=right:min_width=30} ${message}"));
79 1 : buffer->set_format(f);
80 :
81 1 : l->add_appender(buffer);
82 :
83 : char host[HOST_NAME_MAX + 2 + 30];
84 1 : CATCH_REQUIRE(gethostname(host, HOST_NAME_MAX + 1) == 0);
85 1 : host[HOST_NAME_MAX + 1] = '\0';
86 2 : std::string aligned(host);
87 53 : while(aligned.length() < 30)
88 : {
89 26 : aligned = "3" + aligned;
90 : }
91 :
92 1 : SNAP_LOG_ERROR << "Check the param::get_type()" << SNAP_LOG_SEND;
93 1 : CATCH_REQUIRE(buffer->str() == aligned + " Check the param::get_type()\n");
94 :
95 1 : buffer->clear();
96 :
97 1 : f = std::make_shared<snaplogger::format>("${hostname:padding=\"t\":align=right:min_width=30} ${message}");
98 1 : buffer->set_format(f);
99 :
100 1 : aligned = host;
101 53 : while(aligned.length() < 30)
102 : {
103 26 : aligned = "t" + aligned;
104 : }
105 :
106 1 : SNAP_LOG_ERROR << "Try again with a string" << SNAP_LOG_SEND;
107 1 : CATCH_REQUIRE(buffer->str() == aligned + " Try again with a string\n");
108 :
109 1 : buffer->clear();
110 :
111 1 : f = std::make_shared<snaplogger::format>("${hostname:padding=\"q\":align=101:min_width=30} ${message}");
112 1 : buffer->set_format(f);
113 :
114 : snaplogger::message::pointer_t msg(std::make_shared<snaplogger::message>
115 2 : (::snaplogger::severity_t::SEVERITY_ERROR, __FILE__, __func__, __LINE__));
116 1 : *msg << "The align=101 parameter is the wrong type";
117 1 : CATCH_REQUIRE_THROWS_MATCHES(
118 : l->log_message(*msg)
119 : , snaplogger::invalid_parameter
120 : , Catch::Matchers::ExceptionMessage(
121 : "the ${...:align=<value>} parameter must be a valid string (not an integer)."));
122 :
123 : // this is important here because we want to make sure that the
124 : // `message` destructor works as expected (i.e. it does not call
125 : // std::terminate() because of the throw as the align=101 is
126 : // invalid)
127 : //
128 1 : msg.reset();
129 :
130 1 : buffer->clear();
131 :
132 1 : f = std::make_shared<snaplogger::format>("${hostname:padding=\"q\":align=left:min_width=wide} ${message}");
133 1 : buffer->set_format(f);
134 :
135 : msg = std::make_shared<snaplogger::message>
136 1 : (::snaplogger::severity_t::SEVERITY_ERROR, __FILE__, __func__, __LINE__);
137 1 : *msg << "The min_width=wide parameter is the wrong type";
138 1 : CATCH_REQUIRE_THROWS_MATCHES(
139 : l->log_message(*msg)
140 : , snaplogger::invalid_parameter
141 : , Catch::Matchers::ExceptionMessage(
142 : "the ${...:min_width=<value>} parameter must be a valid integer."));
143 :
144 : // this is important here because we want to make sure that the
145 : // `message` destructor works as expected (i.e. it does not call
146 : // std::terminate() because of the throw as the align=101 is
147 : // invalid)
148 : //
149 1 : msg.reset();
150 :
151 1 : l->reset();
152 : }
153 : CATCH_END_SECTION()
154 :
155 4 : CATCH_START_SECTION("default align value")
156 : {
157 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "message-variable-default-param");
158 :
159 2 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
160 2 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
161 :
162 1 : advgetopt::options_environment opt_env;
163 1 : opt_env.f_project_name = "test-logger";
164 2 : advgetopt::getopt opts(opt_env);
165 1 : buffer->set_config(opts);
166 :
167 2 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${hostname:max_width=3} ${message}"));
168 1 : buffer->set_format(f);
169 :
170 1 : l->add_appender(buffer);
171 :
172 : char host[HOST_NAME_MAX + 2 + 30];
173 1 : CATCH_REQUIRE(gethostname(host, HOST_NAME_MAX + 1) == 0);
174 1 : host[HOST_NAME_MAX + 1] = '\0';
175 2 : std::string aligned(host);
176 1 : aligned = aligned.substr(0, 3);
177 1 : while(aligned.length() < 3)
178 : {
179 0 : aligned = " " + aligned;
180 : }
181 :
182 1 : SNAP_LOG_ERROR << "<- first three letters of hostname" << SNAP_LOG_SEND;
183 1 : CATCH_REQUIRE(buffer->str() == aligned + " <- first three letters of hostname\n");
184 : }
185 : CATCH_END_SECTION()
186 2 : }
187 :
188 :
189 :
190 5 : CATCH_TEST_CASE("duplicate_factory", "[variable][factory]")
191 : {
192 6 : CATCH_START_SECTION("attempt dynamically creating a factory which already exists")
193 : {
194 1 : class fake_variable_factory final
195 : : public snaplogger::variable_factory
196 : {
197 : public:
198 1 : fake_variable_factory()
199 1 : : variable_factory("version")
200 : {
201 1 : }
202 :
203 0 : virtual snaplogger::variable::pointer_t create_variable() override final
204 : {
205 : // we can't even register this one so returning an empty
206 : // pointer is perfectly safe here
207 : //
208 0 : return snaplogger::variable::pointer_t();
209 : }
210 : };
211 :
212 1 : CATCH_REQUIRE_THROWS_MATCHES(
213 : snaplogger::register_variable_factory(std::make_shared<fake_variable_factory>())
214 : , snaplogger::duplicate_error
215 : , Catch::Matchers::ExceptionMessage("trying to add two variable factories of type \"version\"."));
216 : }
217 : CATCH_END_SECTION()
218 :
219 6 : CATCH_START_SECTION("attempt creating a variable with a non-existant type")
220 : {
221 1 : CATCH_REQUIRE_THROWS_MATCHES(
222 : snaplogger::get_variable("fake")
223 : , snaplogger::invalid_variable
224 : , Catch::Matchers::ExceptionMessage("You can't create variable with type \"fake\", no such variable type was registered."));
225 : }
226 : CATCH_END_SECTION()
227 :
228 6 : CATCH_START_SECTION("attempt creating a function factory with an existing name")
229 : {
230 1 : class fake_function final
231 : : public snaplogger::function
232 : {
233 : public:
234 1 : fake_function()
235 1 : : function("padding")
236 : {
237 1 : }
238 :
239 0 : virtual void apply(
240 : ::snaplogger::message const & msg
241 : , ::snaplogger::function_data & d
242 : , ::snaplogger::param::pointer_t const & p) override
243 : {
244 0 : snap::NOTUSED(msg);
245 0 : snap::NOTUSED(d);
246 0 : snap::NOTUSED(p);
247 0 : }
248 : };
249 :
250 1 : CATCH_REQUIRE_THROWS_MATCHES(
251 : snaplogger::register_function(std::make_shared<fake_function>())
252 : , snaplogger::duplicate_error
253 : , Catch::Matchers::ExceptionMessage("trying to add two functions named \"padding\"."));
254 : }
255 : CATCH_END_SECTION()
256 9 : }
257 :
258 :
259 : // vim: ts=4 sw=4 et
|