]> granicus.if.org Git - icinga2/blob - test/livestatus.cpp
Make sure the serial number field is always initialized
[icinga2] / test / livestatus.cpp
1 /******************************************************************************
2  * Icinga 2                                                                   *
3  * Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org)    *
4  *                                                                            *
5  * This program is free software; you can redistribute it and/or              *
6  * modify it under the terms of the GNU General Public License                *
7  * as published by the Free Software Foundation; either version 2             *
8  * of the License, or (at your option) any later version.                     *
9  *                                                                            *
10  * This program is distributed in the hope that it will be useful,            *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
13  * GNU General Public License for more details.                               *
14  *                                                                            *
15  * You should have received a copy of the GNU General Public License          *
16  * along with this program; if not, write to the Free Software Foundation     *
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
18  ******************************************************************************/
19
20 #include "livestatus/livestatusquery.hpp"
21 #include "config/configcompiler.hpp"
22 #include "config/configitem.hpp"
23 #include "base/application.hpp"
24 #include "base/stdiostream.hpp"
25 #include "base/json.hpp"
26 #include "base/loader.hpp"
27 #include "cli/daemonutility.hpp"
28 #include <boost/test/unit_test.hpp>
29 #include <fstream>
30
31 using namespace icinga;
32
33 struct GlobalConfigFixture {
34         GlobalConfigFixture()
35             : TestConfig("test-config.conf")
36         {
37                 BOOST_TEST_MESSAGE("setup global config fixture");
38
39                 String cfg_file_path = TestConfig;
40                 String cfg_file_path_tmp = TestConfig + ".tmp";
41
42                 std::ofstream cfgfp;
43                 cfgfp.open(cfg_file_path_tmp.CStr(), std::ofstream::out | std::ofstream::trunc);
44                 cfgfp << std::fixed;
45                 cfgfp << "object CheckCommand \"dummy\" {\n";
46                 cfgfp << "  execute = PluginCheck\n";
47                 cfgfp << "  command = \"/bin/echo\"\n";
48                 cfgfp << "}\n";
49                 cfgfp << "object Host \"test-01\" {\n";
50                 cfgfp << "  address = \"127.0.0.1\"\n";
51                 cfgfp << "  check_command = \"dummy\"\n";
52                 cfgfp << "}\n";
53                 cfgfp << "object Host \"test-02\" {\n";
54                 cfgfp << "  address = \"127.0.0.2\"\n";
55                 cfgfp << "  check_command = \"dummy\"\n";
56                 cfgfp << "}\n";
57                 cfgfp << "apply Service \"livestatus\"{\n";
58                 cfgfp << "  check_command = \"dummy\"\n";
59                 cfgfp << "  notes = \"test livestatus\"\n";
60                 cfgfp << "  assign where match(\"test-*\", host.name)\n";
61                 cfgfp << "}\n";
62
63                 cfgfp.close();
64 #ifdef _WIN32
65                 _unlink(cfg_file_path.CStr());
66 #endif /* _WIN32 */
67
68                 if (rename(cfg_file_path_tmp.CStr(), cfg_file_path.CStr()) < 0) {
69                         BOOST_THROW_EXCEPTION(posix_error()
70                             << boost::errinfo_api_function("rename")
71                             << boost::errinfo_errno(errno)
72                             << boost::errinfo_file_name(cfg_file_path_tmp));
73                 }
74
75                 BOOST_TEST_MESSAGE( "Preparing config objects...");
76
77                 /* start the Icinga application and load the configuration */
78                 Application::DeclareSysconfDir("etc");
79                 Application::DeclareLocalStateDir("var");
80
81                 Loader::LoadExtensionLibrary("icinga");
82                 Loader::LoadExtensionLibrary("methods"); //loaded by ITL
83
84                 std::vector<std::string> configs;
85                 configs.push_back(TestConfig);
86
87                 DaemonUtility::LoadConfigFiles(configs, "icinga2.debug", "icinga2.vars");
88
89                 /* ignore config errors */
90                 WorkQueue upq;
91                 ConfigItem::ActivateItems(upq, false);
92         }
93
94         ~GlobalConfigFixture()
95         {
96                 BOOST_TEST_MESSAGE("cleanup global config fixture");
97
98                 unlink(TestConfig.CStr());
99         }
100
101         String TestConfig;
102 };
103
104 BOOST_GLOBAL_FIXTURE(GlobalConfigFixture);
105
106 struct LocalFixture {
107         LocalFixture() { }
108         ~LocalFixture() { }
109 };
110
111 String LivestatusQueryHelper(const std::vector<String>& lines)
112 {
113         LivestatusQuery::Ptr query = new LivestatusQuery(lines, "");
114
115         std::stringstream stream;
116         StdioStream::Ptr sstream = new StdioStream(&stream, false);
117
118         query->Execute(sstream);
119
120         String output;
121         String result;
122
123         StreamReadContext src;
124         for (;;) {
125                 StreamReadStatus srs = sstream->ReadLine(&result, src);
126
127                 if (srs == StatusEof)
128                         break;
129
130                 if (srs != StatusNewItem)
131                         continue;
132
133                 if (result.GetLength() > 0)
134                         output += result + "\n";
135                 else
136                         break;
137         }
138
139         BOOST_TEST_MESSAGE("Query Result: " + output);
140
141         return output;
142 }
143
144 //____________________________________________________________________________//
145
146 BOOST_FIXTURE_TEST_SUITE(livestatus, LocalFixture)
147
148 BOOST_AUTO_TEST_CASE(hosts)
149 {
150         BOOST_TEST_MESSAGE( "Querying Livestatus...");
151
152         std::vector<String> lines;
153         lines.push_back("GET hosts");
154         lines.push_back("Columns: host_name address check_command");
155         lines.push_back("OutputFormat: json");
156         lines.push_back("\n");
157
158         /* use our query helper */
159         String output = LivestatusQueryHelper(lines);
160
161         Array::Ptr query_result = JsonDecode(output);
162
163         /* the outer elements */
164         BOOST_CHECK(query_result->GetLength() > 1);
165
166         Array::Ptr res1 = query_result->Get(0);
167         Array::Ptr res2 = query_result->Get(1);
168
169         /* results are non-deterministic and not sorted by livestatus */
170         BOOST_CHECK(res1->Contains("test-01") || res2->Contains("test-01"));
171         BOOST_CHECK(res1->Contains("test-02") || res2->Contains("test-02"));
172         BOOST_CHECK(res1->Contains("127.0.0.1") || res2->Contains("127.0.0.1"));
173         BOOST_CHECK(res1->Contains("127.0.0.2") || res2->Contains("127.0.0.2"));
174
175         BOOST_TEST_MESSAGE("Done with testing livestatus hosts...");
176 }
177
178 BOOST_AUTO_TEST_CASE(services)
179 {
180         BOOST_TEST_MESSAGE( "Querying Livestatus...");
181
182         std::vector<String> lines;
183         lines.push_back("GET services");
184         lines.push_back("Columns: host_name service_description check_command notes");
185         lines.push_back("OutputFormat: json");
186         lines.push_back("\n");
187
188         /* use our query helper */
189         String output = LivestatusQueryHelper(lines);
190
191         Array::Ptr query_result = JsonDecode(output);
192
193         /* the outer elements */
194         BOOST_CHECK(query_result->GetLength() > 1);
195
196         Array::Ptr res1 = query_result->Get(0);
197         Array::Ptr res2 = query_result->Get(1);
198
199         /* results are non-deterministic and not sorted by livestatus */
200         BOOST_CHECK(res1->Contains("livestatus") || res2->Contains("livestatus")); //service_description
201         BOOST_CHECK(res1->Contains("test livestatus") || res2->Contains("test livestatus")); //notes
202
203         BOOST_TEST_MESSAGE("Done with testing livestatus services...");
204 }
205 //____________________________________________________________________________//
206
207 BOOST_AUTO_TEST_SUITE_END()