PageRenderTime 164ms CodeModel.GetById 60ms app.highlight 61ms RepoModel.GetById 40ms app.codeStats 0ms

/mordor/tests/config.cpp

http://github.com/mozy/mordor
C++ | 272 lines | 236 code | 28 blank | 8 comment | 12 complexity | 026500cf3eee1fb69f527b123913b802 MD5 | raw file
  1// Copyright (c) 2011 - Mozy, Inc.
  2
  3#include "mordor/config.h"
  4#include "mordor/test/test.h"
  5
  6#ifdef HAVE_CONFIG_H
  7#include "autoconfig.h"
  8#endif
  9
 10#ifdef HAVE_LIBYAML
 11#include "mordor/yaml.h"
 12#endif
 13
 14using namespace Mordor;
 15using namespace Mordor::Test;
 16
 17static ConfigVar<int>::ptr g_testVar1 = Config::lookup(
 18    "config.test", 0, "Config var used by unit test");
 19
 20MORDOR_UNITTEST(Config, loadFromCommandLineNull)
 21{
 22    int argc = 0;
 23    char **argv = NULL;
 24    Config::loadFromCommandLine(argc, argv);
 25    MORDOR_TEST_ASSERT_EQUAL(argc, 0);
 26    MORDOR_TEST_ASSERT(argv == NULL);
 27}
 28
 29MORDOR_UNITTEST(Config, loadFromCommandLineEmpty)
 30{
 31    int argc = 1;
 32    std::string args[] = { "--config.test=1" };
 33    char *argv[1];
 34    for (int i = 0; i < argc; ++i)
 35        argv[i] = const_cast<char *>(args[i].c_str());
 36    g_testVar1->val(0);
 37    Config::loadFromCommandLine(argc, argv);
 38    // Didn't do anything, even though it looks like a config argument
 39    MORDOR_TEST_ASSERT_EQUAL(argc, 1);
 40    MORDOR_TEST_ASSERT_EQUAL((const char *)argv[0], "--config.test=1");
 41    MORDOR_TEST_ASSERT_EQUAL(g_testVar1->val(), 0);
 42}
 43
 44MORDOR_UNITTEST(Config, loadFromCommandLineSimpleEquals)
 45{
 46    int argc = 2;
 47    std::string args[] = { "program",
 48                           "--config.test=1" };
 49    char *argv[2];
 50    for (int i = 0; i < argc; ++i)
 51        argv[i] = const_cast<char *>(args[i].c_str());
 52    g_testVar1->val(0);
 53    Config::loadFromCommandLine(argc, argv);
 54    MORDOR_TEST_ASSERT_EQUAL(argc, 1);
 55    MORDOR_TEST_ASSERT_EQUAL((const char *)argv[0], "program");
 56    MORDOR_TEST_ASSERT_EQUAL(g_testVar1->val(), 1);
 57}
 58
 59MORDOR_UNITTEST(Config, loadFromCommandLineSimple)
 60{
 61    int argc = 3;
 62    std::string args[] = { "program",
 63                           "--config.test",
 64                           "1" };
 65    char *argv[3];
 66    for (int i = 0; i < argc; ++i)
 67        argv[i] = const_cast<char *>(args[i].c_str());
 68    g_testVar1->val(0);
 69    Config::loadFromCommandLine(argc, argv);
 70    MORDOR_TEST_ASSERT_EQUAL(argc, 1);
 71    MORDOR_TEST_ASSERT_EQUAL((const char *)argv[0], "program");
 72    MORDOR_TEST_ASSERT_EQUAL(g_testVar1->val(), 1);
 73}
 74
 75MORDOR_UNITTEST(Config, loadFromCommandLineNoConfigVars)
 76{
 77    int argc = 3;
 78    std::string args[] = { "program",
 79                           "--notaconfigvar",
 80                           "norami" };
 81    char *argv[3];
 82    for (int i = 0; i < argc; ++i)
 83        argv[i] = const_cast<char *>(args[i].c_str());
 84    Config::loadFromCommandLine(argc, argv);
 85    MORDOR_TEST_ASSERT_EQUAL(argc, 3);
 86    MORDOR_TEST_ASSERT_EQUAL((const char *)argv[0], "program");
 87    MORDOR_TEST_ASSERT_EQUAL((const char *)argv[1], "--notaconfigvar");
 88    MORDOR_TEST_ASSERT_EQUAL((const char *)argv[2], "norami");
 89}
 90
 91MORDOR_UNITTEST(Config, loadFromCommandLineStripConfigVars)
 92{
 93    int argc = 4;
 94    std::string args[] = { "program",
 95                           "--notaconfigvar",
 96                           "--config.test=1",
 97                           "norami" };
 98    char *argv[4];
 99    for (int i = 0; i < argc; ++i)
100        argv[i] = const_cast<char *>(args[i].c_str());
101    g_testVar1->val(0);
102    Config::loadFromCommandLine(argc, argv);
103    MORDOR_TEST_ASSERT_EQUAL(argc, 3);
104    MORDOR_TEST_ASSERT_EQUAL((const char *)argv[0], "program");
105    MORDOR_TEST_ASSERT_EQUAL((const char *)argv[1], "--notaconfigvar");
106    MORDOR_TEST_ASSERT_EQUAL((const char *)argv[2], "norami");
107    MORDOR_TEST_ASSERT_EQUAL(g_testVar1->val(), 1);
108}
109
110MORDOR_UNITTEST(Config, loadFromCommandLineStripConfigVars2)
111{
112    int argc = 5;
113    std::string args[] = { "program",
114                           "--notaconfigvar",
115                           "--config.test",
116                           "1",
117                           "norami" };
118    char *argv[5];
119    for (int i = 0; i < argc; ++i)
120        argv[i] = const_cast<char *>(args[i].c_str());
121    g_testVar1->val(0);
122    Config::loadFromCommandLine(argc, argv);
123    MORDOR_TEST_ASSERT_EQUAL(argc, 3);
124    MORDOR_TEST_ASSERT_EQUAL((const char *)argv[0], "program");
125    MORDOR_TEST_ASSERT_EQUAL((const char *)argv[1], "--notaconfigvar");
126    MORDOR_TEST_ASSERT_EQUAL((const char *)argv[2], "norami");
127    MORDOR_TEST_ASSERT_EQUAL(g_testVar1->val(), 1);
128}
129
130MORDOR_UNITTEST(Config, loadFromCommandLineMissingArg)
131{
132    int argc = 2;
133    std::string args[] = { "program",
134                           "--config.test" };
135    char *argv[2];
136    for (int i = 0; i < argc; ++i)
137        argv[i] = const_cast<char *>(args[i].c_str());
138    MORDOR_TEST_ASSERT_EXCEPTION(Config::loadFromCommandLine(argc, argv),
139        std::invalid_argument);
140}
141
142MORDOR_UNITTEST(Config, loadFromCommandLineBadArg)
143{
144    int argc = 2;
145    std::string args[] = { "program",
146                           "--config.test=bad" };
147    char *argv[2];
148    for (int i = 0; i < argc; ++i)
149        argv[i] = const_cast<char *>(args[i].c_str());
150    MORDOR_TEST_ASSERT_EXCEPTION(Config::loadFromCommandLine(argc, argv),
151        std::invalid_argument);
152}
153
154MORDOR_UNITTEST(Config, loadFromCommandLineDuplicates)
155{
156    int argc = 4;
157    std::string args[] = { "program",
158                           "--config.test=1",
159                           "--config.test=2",
160                           "--config.test=3" };
161    char *argv[4];
162    for (int i = 0; i < argc; ++i)
163        argv[i] = const_cast<char *>(args[i].c_str());
164    g_testVar1->val(0);
165    Config::loadFromCommandLine(argc, argv);
166    MORDOR_TEST_ASSERT_EQUAL(argc, 1);
167    MORDOR_TEST_ASSERT_EQUAL((const char *)argv[0], "program");
168    MORDOR_TEST_ASSERT_EQUAL(g_testVar1->val(), 3);
169}
170
171MORDOR_UNITTEST(Config, loadFromCommandLineNoConfigVarsAfterDashDash)
172{
173    int argc = 4;
174    std::string args[] = { "program",
175                           "--config.test=1",
176                           "--",
177                           "--config.test=2" };
178    char *argv[4];
179    for (int i = 0; i < argc; ++i)
180        argv[i] = const_cast<char *>(args[i].c_str());
181    g_testVar1->val(0);
182    Config::loadFromCommandLine(argc, argv);
183    MORDOR_TEST_ASSERT_EQUAL(argc, 3);
184    MORDOR_TEST_ASSERT_EQUAL((const char *)argv[0], "program");
185    MORDOR_TEST_ASSERT_EQUAL((const char *)argv[1], "--");
186    MORDOR_TEST_ASSERT_EQUAL((const char *)argv[2], "--config.test=2");
187    MORDOR_TEST_ASSERT_EQUAL(g_testVar1->val(), 1);
188}
189
190MORDOR_UNITTEST(Config, configVarNameRules)
191{
192    // valid name
193    MORDOR_TEST_ASSERT(Config::lookup("validname1.test", 0));
194    MORDOR_TEST_ASSERT(Config::lookup("a1.2x", 0));
195    // This is a little corner case that still valid
196    // Currently I don't think we are trying to use this specific case,
197    // but it could be still useful, for example, some env var can be
198    // named as A_2.
199    MORDOR_TEST_ASSERT(Config::lookup("a.2", 0));
200
201    MORDOR_TEST_ASSERT_EXCEPTION(Config::lookup("1a", 0), std::invalid_argument);
202    MORDOR_TEST_ASSERT_EXCEPTION(Config::lookup("Aa", 0), std::invalid_argument);
203    MORDOR_TEST_ASSERT_EXCEPTION(Config::lookup("a_", 0), std::invalid_argument);
204    MORDOR_TEST_ASSERT_EXCEPTION(Config::lookup("a.", 0), std::invalid_argument);
205    MORDOR_TEST_ASSERT_EXCEPTION(Config::lookup("a_b", 0), std::invalid_argument);
206}
207
208#ifdef HAVE_LIBYAML
209MORDOR_UNITTEST(Config, loadFromJSON)
210{
211    ConfigVar<int>::ptr port = Config::lookup("http.port", 8080, "");
212    ConfigVar<int>::ptr quantity = Config::lookup("quantity", 123456, "");
213
214    std::ostringstream ss;
215    ss << "http:\n"
216       << "    host: 192.168.0.1\n"
217       << "    port: 80\n"
218       << "quantity: 654321\n"
219       << "price: 800.34";
220
221    Config::loadFromJSON(YAML::parse(ss.str()));
222
223    MORDOR_TEST_ASSERT_EQUAL(port->val(), 80);
224    MORDOR_TEST_ASSERT_EQUAL(quantity->val(), 654321);
225
226    MORDOR_TEST_ASSERT_EQUAL(Config::lookup("http.host")->toString(), "192.168.0.1");
227    MORDOR_TEST_ASSERT_EQUAL(Config::lookup("price")->toString(), "800.34");
228}
229
230MORDOR_UNITTEST(Config, configVarNameFromJSONValid)
231{
232    std::ostringstream ss;
233    ss << "s3:\n"
234       << "    host: 192.168.1.1\n";
235    JSON::Value json = YAML::parse(ss.str());
236    MORDOR_TEST_ASSERT(!json["s3"]["host"].isBlank());
237    Config::loadFromJSON(json);
238    MORDOR_TEST_ASSERT(Config::lookup("s3.host"));
239    MORDOR_TEST_ASSERT_EQUAL(Config::lookup("s3.host")->toString(), "192.168.1.1");
240}
241
242MORDOR_UNITTEST(Config, configVarNameFromJSONInvalid)
243{
244    // dot (.) can't be used as ConfigVar name in loadFromJSON case
245    std::ostringstream ss("s3.host: 192.168.1.1\n");
246    JSON::Value json = YAML::parse(ss.str());
247    MORDOR_TEST_ASSERT(json.find("s3.host") != json.end());
248    Config::loadFromJSON(json);
249    MORDOR_TEST_ASSERT(!Config::lookup("s3.host"));
250}
251#endif
252
253MORDOR_UNITTEST(Config, lockConfigVar)
254{
255    ConfigVar<int>::ptr var1 = Config::lookup(
256            "test.lockable", 100, "configvar can be locked", true);
257    ConfigVar<int>::ptr var2 = Config::lookup(
258            "test.unlockable", 200, "configvar can't be locked", false);
259
260    MORDOR_TEST_ASSERT_EQUAL(Config::isLocked(), false);
261    MORDOR_TEST_ASSERT_EQUAL(var1->val(101), true);
262    MORDOR_TEST_ASSERT_EQUAL(var2->val(202), true);
263    MORDOR_TEST_ASSERT_EQUAL(var1->val(), 101);
264    MORDOR_TEST_ASSERT_EQUAL(var2->val(), 202);
265
266    Config::lock(true);
267    MORDOR_TEST_ASSERT_EQUAL(Config::isLocked(), true);
268    MORDOR_TEST_ASSERT_EQUAL(var1->val(111), false);
269    MORDOR_TEST_ASSERT_EQUAL(var2->val(222), true);
270    MORDOR_TEST_ASSERT_EQUAL(var1->val(), 101);
271    MORDOR_TEST_ASSERT_EQUAL(var2->val(), 222);
272}