Implement more unit tests

refs #7805
This commit is contained in:
Gunnar Beutner 2014-11-23 12:35:13 +01:00
parent e302158631
commit 8d0ddb7c8c
7 changed files with 215 additions and 8 deletions

View File

@ -24,6 +24,7 @@ set(cli_SOURCES
objectlistcommand.cpp objectlistcommand.cpp
pkinewcacommand.cpp pkinewcertcommand.cpp pkisigncsrcommand.cpp pkirequestcommand.cpp pkisavecertcommand.cpp pkiticketcommand.cpp pkinewcacommand.cpp pkinewcertcommand.cpp pkisigncsrcommand.cpp pkirequestcommand.cpp pkisavecertcommand.cpp pkiticketcommand.cpp
pkiutility.cpp pkiutility.cpp
replcommand.cpp
repositoryclearchangescommand.cpp repositorycommitcommand.cpp repositoryobjectcommand.cpp repositoryutility.cpp repositoryclearchangescommand.cpp repositorycommitcommand.cpp repositoryobjectcommand.cpp repositoryutility.cpp
variablegetcommand.cpp variablelistcommand.cpp variableutility.cpp variablegetcommand.cpp variablelistcommand.cpp variableutility.cpp
) )

View File

@ -106,12 +106,14 @@ static bool LoadConfigFiles(const boost::program_options::variables_map& vm, con
if (vm.count("config") > 0) { if (vm.count("config") > 0) {
BOOST_FOREACH(const String& configPath, vm["config"].as<std::vector<std::string> >()) { BOOST_FOREACH(const String& configPath, vm["config"].as<std::vector<std::string> >()) {
Expression *expression = ConfigCompiler::CompileFile(configPath); Expression *expression = ConfigCompiler::CompileFile(configPath);
ExecuteExpression(expression); if (expression)
ExecuteExpression(expression);
delete expression; delete expression;
} }
} else if (!vm.count("no-config")) { } else if (!vm.count("no-config")) {
Expression *expression = ConfigCompiler::CompileFile(Application::GetSysconfDir() + "/icinga2/icinga2.conf"); Expression *expression = ConfigCompiler::CompileFile(Application::GetSysconfDir() + "/icinga2/icinga2.conf");
ExecuteExpression(expression); if (expression)
ExecuteExpression(expression);
delete expression; delete expression;
} }
@ -128,7 +130,8 @@ static bool LoadConfigFiles(const boost::program_options::variables_map& vm, con
String name, fragment; String name, fragment;
BOOST_FOREACH(boost::tie(name, fragment), ConfigFragmentRegistry::GetInstance()->GetItems()) { BOOST_FOREACH(boost::tie(name, fragment), ConfigFragmentRegistry::GetInstance()->GetItems()) {
Expression *expression = ConfigCompiler::CompileText(name, fragment); Expression *expression = ConfigCompiler::CompileText(name, fragment);
ExecuteExpression(expression); if (expression)
ExecuteExpression(expression);
delete expression; delete expression;
} }

92
lib/cli/replcommand.cpp Normal file
View File

@ -0,0 +1,92 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#include "cli/replcommand.hpp"
#include "config/configcompiler.hpp"
#include "config/configcompilercontext.hpp"
#include "base/json.hpp"
#include <iostream>
using namespace icinga;
namespace po = boost::program_options;
REGISTER_CLICOMMAND("repl", ReplCommand);
String ReplCommand::GetDescription(void) const
{
return "Interprets Icinga script expressions.";
}
String ReplCommand::GetShortDescription(void) const
{
return "Icinga REPL console";
}
bool ReplCommand::IsHidden(void) const
{
return true;
}
void ReplCommand::InitParameters(boost::program_options::options_description& visibleDesc,
boost::program_options::options_description& hiddenDesc) const
{
}
/**
* The entry point for the "repl" CLI command.
*
* @returns An exit status.
*/
int ReplCommand::Run(const po::variables_map& vm, const std::vector<std::string>& ap) const
{
VMFrame frame;
while (std::cin.good()) {
std::cout << "=> ";
std::string line;
std::getline(std::cin, line);
Expression *expr;
try {
ConfigCompilerContext::GetInstance()->Reset();
expr = ConfigCompiler::CompileText("<console>", line);
BOOST_FOREACH(const ConfigCompilerMessage& message, ConfigCompilerContext::GetInstance()->GetMessages()) {
std::cout << (message.Error ? "Error" : "Warning") << ": " << message.Text << "\n";
}
if (expr) {
Value result = expr->Evaluate(frame);
if (!result.IsObject() || result.IsObjectType<Array>() || result.IsObjectType<Dictionary>())
std::cout << JsonEncode(result) << "\n";
else
std::cout << result << "\n";
}
} catch (const ConfigError& ex) {
std::cout << ex.what() << "\n";
} catch (const std::exception& ex) {
std::cout << "Error: " << DiagnosticInformation(ex) << "\n";
}
delete expr;
}
}

48
lib/cli/replcommand.hpp Normal file
View File

@ -0,0 +1,48 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#ifndef REPLCOMMAND_H
#define REPLCOMMAND_H
#include "cli/clicommand.hpp"
namespace icinga
{
/**
* The "repl" CLI command.
*
* @ingroup cli
*/
class ReplCommand : public CLICommand
{
public:
DECLARE_PTR_TYPEDEFS(ReplCommand);
virtual String GetDescription(void) const;
virtual String GetShortDescription(void) const;
virtual bool IsHidden(void) const;
virtual void InitParameters(boost::program_options::options_description& visibleDesc,
boost::program_options::options_description& hiddenDesc) const;
virtual int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const;
};
}
#endif /* REPLCOMMAND_H */

View File

@ -255,8 +255,10 @@ Expression *ConfigCompiler::Compile(void)
m_Expressions.push(std::vector<Expression *>()); m_Expressions.push(std::vector<Expression *>());
try { try {
if (yyparse(this) != 0) if (yyparse(this) != 0) {
BOOST_THROW_EXCEPTION(ConfigError("Syntax error")); m_Expressions.pop();
return NULL;
}
DictExpression *expr = new DictExpression(m_Expressions.top()); DictExpression *expr = new DictExpression(m_Expressions.top());
m_Expressions.pop(); m_Expressions.pop();
@ -279,7 +281,8 @@ Expression *ConfigCompiler::Compile(void)
%} %}
%% %%
statements: statement sep statements: newlines
| statement sep
| statements statement sep | statements statement sep
; ;

View File

@ -85,6 +85,7 @@ add_boost_test(base
base_value/convert base_value/convert
base_value/format base_value/format
config_ops/simple config_ops/simple
config_ops/advanced
icinga_perfdata/simple icinga_perfdata/simple
icinga_perfdata/multiple icinga_perfdata/multiple
icinga_perfdata/uom icinga_perfdata/uom

View File

@ -30,6 +30,18 @@ BOOST_AUTO_TEST_CASE(simple)
Expression *expr; Expression *expr;
Dictionary::Ptr dict; Dictionary::Ptr dict;
expr = ConfigCompiler::CompileText("<test>", "");
BOOST_CHECK(expr->Evaluate(frame) == Empty);
delete expr;
expr = ConfigCompiler::CompileText("<test>", "\n3");
BOOST_CHECK(expr->Evaluate(frame) == 3);
delete expr;
expr = ConfigCompiler::CompileText("<test>", "{ 3\n\n5 }");
BOOST_CHECK(expr->Evaluate(frame) != Empty);
delete expr;
expr = ConfigCompiler::CompileText("<test>", "1 + 3"); expr = ConfigCompiler::CompileText("<test>", "1 + 3");
BOOST_CHECK(expr->Evaluate(frame) == 4); BOOST_CHECK(expr->Evaluate(frame) == 4);
delete expr; delete expr;
@ -90,8 +102,8 @@ BOOST_AUTO_TEST_CASE(simple)
BOOST_CHECK(expr->Evaluate(frame)); BOOST_CHECK(expr->Evaluate(frame));
delete expr; delete expr;
expr = ConfigCompiler::CompileText("<test>", "!0 == true"); expr = ConfigCompiler::CompileText("<test>", "~0");
BOOST_CHECK(expr->Evaluate(frame)); BOOST_CHECK(expr->Evaluate(frame) == (double)~(long)0);
delete expr; delete expr;
expr = ConfigCompiler::CompileText("<test>", "4 << 8"); expr = ConfigCompiler::CompileText("<test>", "4 << 8");
@ -156,6 +168,53 @@ BOOST_AUTO_TEST_CASE(simple)
BOOST_CHECK(dict->GetLength() == 1); BOOST_CHECK(dict->GetLength() == 1);
BOOST_CHECK(dict->Get("a") == 3); BOOST_CHECK(dict->Get("a") == 3);
expr = ConfigCompiler::CompileText("<test>", "test");
BOOST_CHECK_THROW(expr->Evaluate(frame), ConfigError);
delete expr;
}
BOOST_AUTO_TEST_CASE(advanced)
{
VMFrame frame;
Expression *expr;
expr = ConfigCompiler::CompileText("<test>", "regex(\"^Hello\", \"Hello World\")");
BOOST_CHECK(expr->Evaluate(frame));
delete expr;
expr = ConfigCompiler::CompileText("<test>", "\"regex\"(\"^Hello\", \"Hello World\")");
BOOST_CHECK(expr->Evaluate(frame));
delete expr;
expr = ConfigCompiler::CompileText("<test>", "__boost_test()");
BOOST_CHECK_THROW(expr->Evaluate(frame), ConfigError);
delete expr;
Object::Ptr self = new Object();
VMFrame frame2(self);
expr = ConfigCompiler::CompileText("<test>", "this");
BOOST_CHECK(expr->Evaluate(frame2) == Value(self));
delete expr;
expr = ConfigCompiler::CompileText("<test>", "local v = 7; v");
BOOST_CHECK(expr->Evaluate(frame));
delete expr;
expr = ConfigCompiler::CompileText("<test>", "{ a = 3 }.a");
BOOST_CHECK(expr->Evaluate(frame) == 3);
delete expr;
expr = ConfigCompiler::CompileText("<test>", "[ 2, 3 ][1]");
BOOST_CHECK(expr->Evaluate(frame) == 3);
delete expr;
/* Uncomment this once #7800 is fixed
expr = ConfigCompiler::CompileText("<test>", "local v = { a = 3}; v.a");
BOOST_CHECK(expr->Evaluate(frame) == 3);
delete expr;*/
expr = ConfigCompiler::CompileText("<test>", "a = 3 b = 3");
BOOST_CHECK(expr == NULL);
} }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()