aboutsummaryrefslogtreecommitdiffstats
path: root/config/src/tests/functiontest
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
committerJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
commit72231250ed81e10d66bfe70701e64fa5fe50f712 (patch)
tree2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /config/src/tests/functiontest
Publish
Diffstat (limited to 'config/src/tests/functiontest')
-rw-r--r--config/src/tests/functiontest/.gitignore6
-rw-r--r--config/src/tests/functiontest/CMakeLists.txt9
-rw-r--r--config/src/tests/functiontest/defaultvalues.xml62
-rw-r--r--config/src/tests/functiontest/defaultvalues/function-test.cfg46
-rw-r--r--config/src/tests/functiontest/errorval_double/function-test.cfg67
-rw-r--r--config/src/tests/functiontest/errorval_int/function-test.cfg67
-rw-r--r--config/src/tests/functiontest/errorval_long/function-test.cfg67
-rw-r--r--config/src/tests/functiontest/functiontest.cpp304
-rw-r--r--config/src/tests/functiontest/missingvalue/function-test.cfg39
-rw-r--r--config/src/tests/functiontest/randomorder/function-test.cfg55
-rw-r--r--config/src/tests/functiontest/slime-payload.json103
-rw-r--r--config/src/tests/functiontest/variableaccess/function-test.cfg67
12 files changed, 892 insertions, 0 deletions
diff --git a/config/src/tests/functiontest/.gitignore b/config/src/tests/functiontest/.gitignore
new file mode 100644
index 00000000000..44d74bb5ec7
--- /dev/null
+++ b/config/src/tests/functiontest/.gitignore
@@ -0,0 +1,6 @@
+.depend
+Makefile
+functiontesttest_test
+/config-function-test.cpp
+/config-function-test.h
+config_functiontest_test_app
diff --git a/config/src/tests/functiontest/CMakeLists.txt b/config/src/tests/functiontest/CMakeLists.txt
new file mode 100644
index 00000000000..d798ad53de4
--- /dev/null
+++ b/config/src/tests/functiontest/CMakeLists.txt
@@ -0,0 +1,9 @@
+# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+vespa_add_executable(config_functiontest_test_app
+ SOURCES
+ functiontest.cpp
+ DEPENDS
+ config_cloudconfig
+)
+vespa_add_test(NAME config_functiontest_test_app COMMAND config_functiontest_test_app)
+vespa_generate_config(config_functiontest_test_app ../../test/resources/configdefinitions/function-test.def)
diff --git a/config/src/tests/functiontest/defaultvalues.xml b/config/src/tests/functiontest/defaultvalues.xml
new file mode 100644
index 00000000000..80644c2fdb1
--- /dev/null
+++ b/config/src/tests/functiontest/defaultvalues.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<config name="function-test">
+ <bool_val>false</bool_val>
+ <int_val>5</int_val>
+ <long_val>1234567890123</long_val>
+ <double_val>41.23</double_val>
+ <string_val>foo</string_val>
+ <enum_val>FOOBAR</enum_val>
+ <refval>:parent:</refval>
+ <fileVal>vespa.log</fileVal>
+
+ <boolarr index="0">false</boolarr>
+ <doublearr index="0">2344</doublearr>
+ <doublearr index="1">123</doublearr>
+ <stringarr index="0">bar</stringarr>
+ <enumarr index="0">VALUES</enumarr>
+
+ <basicStruct>
+ <bar>3</bar>
+ <intArr index="0">10</intArr>
+ </basicStruct>
+
+ <rootStruct>
+ <inner0>
+ <index>11</index>
+ </inner0>
+ <inner1>
+ <index>12</index>
+ </inner1>
+ <innerArr index="0">
+ <stringVal>deep</stringVal>
+ </innerArr>
+ </rootStruct>
+
+ <myarray index="0">
+ <stringval index="0">baah</stringval>
+ <stringval index="1">yikes</stringval>
+ <refval>:parent:</refval>
+ <fileVal>command.com</fileVal>
+ <anotherarray index="0">
+ <foo>7</foo>
+ </anotherarray>
+ <myStruct>
+ <a>1</a>
+ </myStruct>
+ </myarray>
+ <myarray index="1">
+ <refval>:parent:</refval>
+ <fileVal>display.sys</fileVal>
+ <anotherarray index="0">
+ <foo>1</foo>
+ </anotherarray>
+ <anotherarray index="1">
+ <foo>2</foo>
+ </anotherarray>
+ <myStruct>
+ <a>-1</a>
+ </myStruct>
+ </myarray>
+
+</config>
diff --git a/config/src/tests/functiontest/defaultvalues/function-test.cfg b/config/src/tests/functiontest/defaultvalues/function-test.cfg
new file mode 100644
index 00000000000..854d2a5a1cb
--- /dev/null
+++ b/config/src/tests/functiontest/defaultvalues/function-test.cfg
@@ -0,0 +1,46 @@
+bool_val false
+int_val 5
+long_val 1234567890123
+double_val 41.23
+string_val "foo"
+enum_val FOOBAR
+refval :parent:
+fileVal "vespa.log"
+boolarr[1]
+boolarr[0] false
+intarr[0]
+longarr[0]
+doublearr[2]
+doublearr[0] 2344
+doublearr[1] 123
+stringarr[1]
+stringarr[0] "bar"
+enumarr[1]
+enumarr[0] VALUES
+refarr[0]
+fileArr[0]
+
+basicStruct.bar 3
+basicStruct.intArr[1]
+basicStruct.intArr[0] 10
+rootStruct.inner0.index 11
+rootStruct.inner1.index 12
+rootStruct.innerArr[1]
+rootStruct.innerArr[0].stringVal "deep"
+
+myarray[2]
+myarray[0].stringval[2]
+myarray[0].stringval[0] "baah"
+myarray[0].stringval[1] "yikes"
+myarray[0].refval ":parent:"
+myarray[0].fileVal "command.com"
+myarray[0].anotherarray[1]
+myarray[0].anotherarray[0].foo 7
+myarray[0].myStruct.a 1
+myarray[1].stringval[0]
+myarray[1].refval ":parent:"
+myarray[1].fileVal "display.sys"
+myarray[1].anotherarray[2]
+myarray[1].anotherarray[0].foo 1
+myarray[1].anotherarray[1].foo 2
+myarray[1].myStruct.a -1
diff --git a/config/src/tests/functiontest/errorval_double/function-test.cfg b/config/src/tests/functiontest/errorval_double/function-test.cfg
new file mode 100644
index 00000000000..d6fff604406
--- /dev/null
+++ b/config/src/tests/functiontest/errorval_double/function-test.cfg
@@ -0,0 +1,67 @@
+bool_val false
+bool_with_def true
+int_val 5
+int_with_def -14
+long_val 12345678901
+long_with_def -9876543210
+double_val 41.23jf
+double_with_def -12
+string_val "foo"
+stringwithdef "bar"
+enum_val FOOBAR
+enumwithdef BAR2
+refval :parent:
+refwithdef ":parent:"
+fileVal "etc"
+boolarr[1]
+boolarr[0] false
+intarr[0]
+longarr[2]
+longarr[0] 9223372036854775807
+longarr[1] -9223372036854775808
+doublearr[2]
+doublearr[0] 2344
+doublearr[1] 123
+stringarr[1]
+stringarr[0] "bar"
+enumarr[1]
+enumarr[0] VALUES
+refarr[3]
+refarr[0] ":parent:"
+refarr[1] ":parent"
+refarr[2] "parent:"
+fileArr[1]
+fileArr[0] "bin"
+
+basicStruct.foo "basicFoo"
+basicStruct.bar 3
+basicStruct.intArr[1]
+basicStruct.intArr[0] 310
+rootStruct.inner0.index 11
+rootStruct.inner1.index 12
+rootStruct.innerArr[1]
+rootStruct.innerArr[0].boolVal true
+rootStruct.innerArr[0].stringVal "deep"
+
+myarray[2]
+myarray[0].intval -5
+myarray[0].stringval[2]
+myarray[0].stringval[0] "baah"
+myarray[0].stringval[1] "yikes"
+myarray[0].enumval INNER
+myarray[0].refval :parent:
+myarray[0].fileVal "file0"
+myarray[0].anotherarray[1]
+myarray[0].anotherarray[0].foo 7
+myarray[0].myStruct.a 1
+myarray[0].myStruct.b 2
+myarray[1].intval 5
+myarray[1].stringval[0]
+myarray[1].enumval INNER
+myarray[1].refval ":parent:"
+myarray[1].fileVal "file1"
+myarray[1].anotherarray[2]
+myarray[1].anotherarray[0].foo 1
+myarray[1].anotherarray[1].foo 2
+myarray[1].myStruct.a -1
+myarray[1].myStruct.b -2
diff --git a/config/src/tests/functiontest/errorval_int/function-test.cfg b/config/src/tests/functiontest/errorval_int/function-test.cfg
new file mode 100644
index 00000000000..7f3eba1ba55
--- /dev/null
+++ b/config/src/tests/functiontest/errorval_int/function-test.cfg
@@ -0,0 +1,67 @@
+bool_val false
+bool_with_def true
+int_val 5foo
+int_with_def -14
+long_val 12345678901
+long_with_def -9876543210
+double_val 41.23
+double_with_def -12
+string_val "foo"
+stringwithdef "bar"
+enum_val FOOBAR
+enumwithdef BAR2
+refval :parent:
+refwithdef ":parent:"
+fileVal "etc"
+boolarr[1]
+boolarr[0] false
+intarr[0]
+longarr[2]
+longarr[0] 9223372036854775807
+longarr[1] -9223372036854775808
+doublearr[2]
+doublearr[0] 2344
+doublearr[1] 123
+stringarr[1]
+stringarr[0] "bar"
+enumarr[1]
+enumarr[0] VALUES
+refarr[3]
+refarr[0] ":parent:"
+refarr[1] ":parent"
+refarr[2] "parent:"
+fileArr[1]
+fileArr[0] "bin"
+
+basicStruct.foo "basicFoo"
+basicStruct.bar 3
+basicStruct.intArr[1]
+basicStruct.intArr[0] 310
+rootStruct.inner0.index 11
+rootStruct.inner1.index 12
+rootStruct.innerArr[1]
+rootStruct.innerArr[0].boolVal true
+rootStruct.innerArr[0].stringVal "deep"
+
+myarray[2]
+myarray[0].intval -5
+myarray[0].stringval[2]
+myarray[0].stringval[0] "baah"
+myarray[0].stringval[1] "yikes"
+myarray[0].enumval INNER
+myarray[0].refval :parent:
+myarray[0].fileVal "file0"
+myarray[0].anotherarray[1]
+myarray[0].anotherarray[0].foo 7
+myarray[0].myStruct.a 1
+myarray[0].myStruct.b 2
+myarray[1].intval 5
+myarray[1].stringval[0]
+myarray[1].enumval INNER
+myarray[1].refval ":parent:"
+myarray[1].fileVal "file1"
+myarray[1].anotherarray[2]
+myarray[1].anotherarray[0].foo 1
+myarray[1].anotherarray[1].foo 2
+myarray[1].myStruct.a -1
+myarray[1].myStruct.b -2
diff --git a/config/src/tests/functiontest/errorval_long/function-test.cfg b/config/src/tests/functiontest/errorval_long/function-test.cfg
new file mode 100644
index 00000000000..ab14a1a9e5a
--- /dev/null
+++ b/config/src/tests/functiontest/errorval_long/function-test.cfg
@@ -0,0 +1,67 @@
+bool_val false
+bool_with_def true
+int_val 5
+int_with_def -14
+long_val 12345678901foo
+long_with_def -9876543210
+double_val 41.23
+double_with_def -12
+string_val "foo"
+stringwithdef "bar"
+enum_val FOOBAR
+enumwithdef BAR2
+refval :parent:
+refwithdef ":parent:"
+fileVal "etc"
+boolarr[1]
+boolarr[0] false
+intarr[0]
+longarr[2]
+longarr[0] 9223372036854775807
+longarr[1] -9223372036854775808
+doublearr[2]
+doublearr[0] 2344
+doublearr[1] 123
+stringarr[1]
+stringarr[0] "bar"
+enumarr[1]
+enumarr[0] VALUES
+refarr[3]
+refarr[0] ":parent:"
+refarr[1] ":parent"
+refarr[2] "parent:"
+fileArr[1]
+fileArr[0] "bin"
+
+basicStruct.foo "basicFoo"
+basicStruct.bar 3
+basicStruct.intArr[1]
+basicStruct.intArr[0] 310
+rootStruct.inner0.index 11
+rootStruct.inner1.index 12
+rootStruct.innerArr[1]
+rootStruct.innerArr[0].boolVal true
+rootStruct.innerArr[0].stringVal "deep"
+
+myarray[2]
+myarray[0].intval -5
+myarray[0].stringval[2]
+myarray[0].stringval[0] "baah"
+myarray[0].stringval[1] "yikes"
+myarray[0].enumval INNER
+myarray[0].refval :parent:
+myarray[0].fileVal "file0"
+myarray[0].anotherarray[1]
+myarray[0].anotherarray[0].foo 7
+myarray[0].myStruct.a 1
+myarray[0].myStruct.b 2
+myarray[1].intval 5
+myarray[1].stringval[0]
+myarray[1].enumval INNER
+myarray[1].refval ":parent:"
+myarray[1].fileVal "file1"
+myarray[1].anotherarray[2]
+myarray[1].anotherarray[0].foo 1
+myarray[1].anotherarray[1].foo 2
+myarray[1].myStruct.a -1
+myarray[1].myStruct.b -2
diff --git a/config/src/tests/functiontest/functiontest.cpp b/config/src/tests/functiontest/functiontest.cpp
new file mode 100644
index 00000000000..6541e76e06a
--- /dev/null
+++ b/config/src/tests/functiontest/functiontest.cpp
@@ -0,0 +1,304 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include <vespa/fastos/fastos.h>
+#include <vespa/config/config.h>
+#include "config-function-test.h"
+
+#include <fstream>
+#include <vespa/log/log.h>
+#include <vespa/vespalib/testkit/testapp.h>
+#include <vespa/vespalib/data/slime/slime.h>
+
+LOG_SETUP("functiontest_test");
+
+using namespace config;
+
+namespace {
+
+void
+checkVariableAccess(const FunctionTestConfig & config)
+{
+ EXPECT_EQUAL(false, config.boolVal);
+ EXPECT_EQUAL(true, config.boolWithDef);
+ EXPECT_EQUAL(5, config.intVal);
+ EXPECT_EQUAL(-14, config.intWithDef);
+ EXPECT_EQUAL(12345678901LL, config.longVal);
+ EXPECT_EQUAL(-9876543210LL, config.longWithDef);
+ EXPECT_APPROX(41.23, config.doubleVal, 0.000001);
+ EXPECT_APPROX(-12, config.doubleWithDef, 0.000001);
+ EXPECT_EQUAL("foo", config.stringVal);
+ EXPECT_EQUAL("bar", config.stringwithdef);
+ EXPECT_EQUAL("FOOBAR", FunctionTestConfig::getEnumValName(config.enumVal));
+ EXPECT_EQUAL("BAR2",
+ FunctionTestConfig::getEnumwithdefName(config.enumwithdef));
+ EXPECT_EQUAL(":parent:", config.refval);
+ EXPECT_EQUAL(":parent:", config.refwithdef);
+ EXPECT_EQUAL("etc", config.fileVal);
+ EXPECT_EQUAL(1u, config.boolarr.size());
+ EXPECT_EQUAL(0u, config.intarr.size());
+ EXPECT_EQUAL(2u, config.longarr.size());
+ LOG(error, "0: %" PRId64, config.longarr[0]);
+ LOG(error, "1: %" PRId64, config.longarr[1]);
+ EXPECT_EQUAL(std::numeric_limits<int64_t>::max(), config.longarr[0]);
+ EXPECT_EQUAL(std::numeric_limits<int64_t>::min(), config.longarr[1]);
+ EXPECT_EQUAL(2u, config.doublearr.size());
+ EXPECT_EQUAL(1u, config.stringarr.size());
+ EXPECT_EQUAL(1u, config.enumarr.size());
+ EXPECT_EQUAL(3u, config.refarr.size());
+ EXPECT_EQUAL(1u, config.fileArr.size());
+ EXPECT_EQUAL("bin", config.fileArr[0]);
+
+ EXPECT_EQUAL("basicFoo", config.basicStruct.foo);
+ EXPECT_EQUAL(3, config.basicStruct.bar);
+ EXPECT_EQUAL(1u, config.basicStruct.intArr.size());
+ EXPECT_EQUAL(310, config.basicStruct.intArr[0]);
+ EXPECT_EQUAL("inner0", config.rootStruct.inner0.name);
+ EXPECT_EQUAL(11, config.rootStruct.inner0.index);
+ EXPECT_EQUAL("inner1", config.rootStruct.inner1.name);
+ EXPECT_EQUAL(12, config.rootStruct.inner1.index);
+ EXPECT_EQUAL(1u, config.rootStruct.innerArr.size());
+ EXPECT_EQUAL(true, config.rootStruct.innerArr[0].boolVal);
+ EXPECT_EQUAL("deep", config.rootStruct.innerArr[0].stringVal);
+
+ // TODO: replace ':parent:' with 'configId' when references are handled properly also in C++.
+ EXPECT_EQUAL(2u, config.myarray.size());
+ EXPECT_EQUAL(":parent:", config.myarray[0].refval);
+ EXPECT_EQUAL("file0", config.myarray[0].fileVal);
+ EXPECT_EQUAL(1, config.myarray[0].myStruct.a);
+ EXPECT_EQUAL(2, config.myarray[0].myStruct.b);
+ EXPECT_EQUAL(":parent:", config.myarray[1].refval);
+ EXPECT_EQUAL("file1", config.myarray[1].fileVal);
+ EXPECT_EQUAL(-1, config.myarray[1].myStruct.a);
+ EXPECT_EQUAL(-2, config.myarray[1].myStruct.b);
+}
+
+std::string
+readFile(const std::string & fileName)
+{
+ std::ifstream f(fileName.c_str());
+ ASSERT_FALSE(f.fail());
+ std::string content;
+ std::string line;
+ while (getline(f, line)) {
+ content += line;
+ }
+ return content;
+}
+
+}
+
+struct LazyTestFixture
+{
+ const DirSpec _spec;
+ ConfigSubscriber _subscriber;
+ ConfigHandle<FunctionTestConfig>::UP _handle;
+ std::unique_ptr<FunctionTestConfig> _config;
+
+ LazyTestFixture(const std::string & dirName)
+ : _spec(dirName),
+ _subscriber(_spec),
+ _handle(_subscriber.subscribe<FunctionTestConfig>(""))
+ {
+ }
+};
+
+struct TestFixture : public LazyTestFixture
+{
+ TestFixture(const std::string & dirName)
+ : LazyTestFixture(dirName)
+ {
+ ASSERT_TRUE(_subscriber.nextConfig(0));
+ _config = _handle->getConfig();
+ }
+};
+
+struct ErrorFixture
+{
+ LazyTestFixture & f;
+ ErrorFixture(LazyTestFixture & f1) : f(f1) { }
+ void run() {
+ f._subscriber.nextConfig(0);
+ bool thrown = false;
+ try {
+ f._handle->getConfig();
+ } catch (const InvalidConfigException & e) {
+ thrown = true;
+ LOG(info, "Error: %s", e.getMessage().c_str());
+ }
+ ASSERT_TRUE(thrown);
+ }
+};
+
+void attemptLacking(const std::string& param, bool isArray) {
+ std::ifstream in("defaultvalues/function-test.cfg", std::ios_base::in);
+ std::ostringstream config;
+ std::string s;
+ while (std::getline(in, s)) {
+ if (s.size() > param.size() &&
+ s.substr(0, param.size()) == param &&
+ (s[param.size()] == ' ' || s[param.size()] == '['))
+ {
+ // Ignore values matched
+ } else {
+ config << s << "\n";
+
+ }
+ }
+ //std::cerr << "Config lacking " << param << "\n"
+ // << config.str() << "\n";
+ try{
+ RawSpec spec(config.str());
+ ConfigSubscriber subscriber(spec);
+ ConfigHandle<FunctionTestConfig>::UP handle = subscriber.subscribe<FunctionTestConfig>("foo");
+ ASSERT_TRUE(subscriber.nextConfig(0));
+ std::unique_ptr<FunctionTestConfig> cfg = handle->getConfig();
+ if (isArray) {
+ // Arrays are empty by default
+ return;
+ }
+ TEST_FATAL(("Expected to fail when not specifying value " + param
+ + " without default").c_str());
+ } catch (InvalidConfigException& e) {
+ if (isArray) {
+ TEST_FATAL("Arrays should be empty by default.");
+ }
+ }
+}
+
+TEST_F("testVariableAccess", TestFixture("variableaccess")) {
+ checkVariableAccess(*f._config);
+}
+
+
+TEST("test variable access from slime") {
+ vespalib::Slime slime;
+ std::string json(readFile("slime-payload.json"));
+ vespalib::slime::JsonFormat::decode(json, slime);
+ FunctionTestConfig config(config::ConfigPayload(slime.get()));
+ checkVariableAccess(config);
+}
+
+TEST_F("testDefaultValues", TestFixture("defaultvalues")) {
+ EXPECT_EQUAL(false, f._config->boolVal);
+ EXPECT_EQUAL(false, f._config->boolWithDef);
+ EXPECT_EQUAL(5, f._config->intVal);
+ EXPECT_EQUAL(-545, f._config->intWithDef);
+ EXPECT_EQUAL(1234567890123LL, f._config->longVal);
+ EXPECT_EQUAL(-50000000000LL, f._config->longWithDef);
+ EXPECT_APPROX(41.23, f._config->doubleVal, 0.000001);
+ EXPECT_APPROX(-6.43, f._config->doubleWithDef, 0.000001);
+ EXPECT_EQUAL("foo", f._config->stringVal);
+ EXPECT_EQUAL("foobar", f._config->stringwithdef);
+ EXPECT_EQUAL("FOOBAR", FunctionTestConfig::getEnumValName(f._config->enumVal));
+ EXPECT_EQUAL("BAR2",
+ FunctionTestConfig::getEnumwithdefName(f._config->enumwithdef));
+ EXPECT_EQUAL(":parent:", f._config->refval);
+ EXPECT_EQUAL(":parent:", f._config->refwithdef);
+ EXPECT_EQUAL("vespa.log", f._config->fileVal);
+ EXPECT_EQUAL(1u, f._config->boolarr.size());
+ EXPECT_EQUAL(0u, f._config->intarr.size());
+ EXPECT_EQUAL(0u, f._config->longarr.size());
+ EXPECT_EQUAL(2u, f._config->doublearr.size());
+ EXPECT_EQUAL(1u, f._config->stringarr.size());
+ EXPECT_EQUAL(1u, f._config->enumarr.size());
+ EXPECT_EQUAL(0u, f._config->refarr.size());
+ EXPECT_EQUAL(0u, f._config->fileArr.size());
+
+ EXPECT_EQUAL(3, f._config->basicStruct.bar);
+ EXPECT_EQUAL(1u, f._config->basicStruct.intArr.size());
+ EXPECT_EQUAL(10, f._config->basicStruct.intArr[0]);
+ EXPECT_EQUAL(11, f._config->rootStruct.inner0.index);
+ EXPECT_EQUAL(12, f._config->rootStruct.inner1.index);
+ EXPECT_EQUAL(1u, f._config->rootStruct.innerArr.size());
+ EXPECT_EQUAL("deep", f._config->rootStruct.innerArr[0].stringVal);
+
+ EXPECT_EQUAL(2u, f._config->myarray.size());
+ EXPECT_EQUAL(1, f._config->myarray[0].myStruct.a);
+ EXPECT_EQUAL(-1, f._config->myarray[1].myStruct.a);
+ EXPECT_EQUAL("command.com", f._config->myarray[0].fileVal);
+ EXPECT_EQUAL("display.sys", f._config->myarray[1].fileVal);
+}
+
+TEST("testLackingDefaults") {
+ attemptLacking("bool_val", false);
+ attemptLacking("int_val", false);
+ attemptLacking("long_val", false);
+ attemptLacking("double_val", false);
+ attemptLacking("string_val", false);
+ attemptLacking("enum_val", false);
+ attemptLacking("refval", false);
+ attemptLacking("fileVal", false);
+
+ attemptLacking("boolarr", true);
+ attemptLacking("intarr", true);
+ attemptLacking("longarr", true);
+ attemptLacking("doublearr", true);
+ attemptLacking("enumarr", true);
+ attemptLacking("stringarr", true);
+ attemptLacking("refarr", true);
+ attemptLacking("fileArr", true);
+ attemptLacking("myarray", true);
+
+ attemptLacking("basicStruct.bar", false);
+ attemptLacking("rootStruct.inner0.index", false);
+ attemptLacking("rootStruct.inner1.index", false);
+
+ // NOTE: When this line is lacking in C++, the array will be empty, and no exception is thrown. In Java, the array
+ // is initialized to length 1 (by the preceeding line 'rootStruct.innerArr[1]'), and an exception is thrown
+ // when the value is lacking.
+ attemptLacking("rootStruct.innerArr[0].stringVal", true);
+
+ attemptLacking("myarray[0].stringval", true);
+ attemptLacking("myarray[0].refval", false);
+ attemptLacking("myarray[0].anotherarray", true);
+ attemptLacking("myarray[0].anotherarray", true);
+ attemptLacking("myarray[0].myStruct.a", false);
+}
+
+TEST_F("testRandomOrder", TestFixture("randomorder")) {
+ EXPECT_EQUAL(false, f._config->boolVal);
+ EXPECT_EQUAL(true, f._config->boolWithDef);
+ EXPECT_EQUAL(5, f._config->intVal);
+ EXPECT_EQUAL(-14, f._config->intWithDef);
+ EXPECT_EQUAL(666000666000LL, f._config->longVal);
+ EXPECT_EQUAL(-333000333000LL, f._config->longWithDef);
+ EXPECT_APPROX(41.23, f._config->doubleVal, 0.000001);
+ EXPECT_APPROX(-12, f._config->doubleWithDef, 0.000001);
+ EXPECT_EQUAL("foo", f._config->stringVal);
+ EXPECT_EQUAL("bar", f._config->stringwithdef);
+ EXPECT_EQUAL("FOOBAR", FunctionTestConfig::getEnumValName(f._config->enumVal));
+ EXPECT_EQUAL("BAR2",
+ FunctionTestConfig::getEnumwithdefName(f._config->enumwithdef));
+ EXPECT_EQUAL(":parent:", f._config->refval);
+ EXPECT_EQUAL(":parent:", f._config->refwithdef);
+ EXPECT_EQUAL("autoexec.bat", f._config->fileVal);
+ EXPECT_EQUAL(1u, f._config->boolarr.size());
+ EXPECT_EQUAL(0u, f._config->intarr.size());
+ EXPECT_EQUAL(0u, f._config->longarr.size());
+ EXPECT_EQUAL(2u, f._config->doublearr.size());
+ EXPECT_EQUAL(1u, f._config->stringarr.size());
+ EXPECT_EQUAL(1u, f._config->enumarr.size());
+ EXPECT_EQUAL(0u, f._config->refarr.size());
+ EXPECT_EQUAL(0u, f._config->fileArr.size());
+ EXPECT_EQUAL(2u, f._config->myarray.size());
+}
+
+TEST_FF("testErrorRangeInt32", LazyTestFixture("errorval_int"), ErrorFixture(f1)) { f2.run(); }
+TEST_FF("testErrorRangeInt64", LazyTestFixture("errorval_long"), ErrorFixture(f1)) { f2.run(); }
+TEST_FF("testErrorRangeDouble", LazyTestFixture("errorval_double"), ErrorFixture(f1)) { f2.run(); }
+
+#if 0
+TEST_F("testEquality", TestFixture("variableaccess")) {
+ FunctionTestConfig myconfig(*f._config);
+ EXPECT_EQUAL(_config, myconfig);
+ myconfig.intVal = 2;
+ EXPECT_TRUE(_config != myconfig);
+ EXPECT_TRUE(_config.myarray == myconfig.myarray);
+ myconfig.myarray[1].anotherarray[1].foo = 5;
+ EXPECT_TRUE(_config.myarray != myconfig.myarray);
+ EXPECT_EQUAL(_config.myarray[0], myconfig.myarray[0]);
+ EXPECT_EQUAL(_config.myarray[1].refval, myconfig.myarray[1].refval);
+}
+#endif
+
+TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/config/src/tests/functiontest/missingvalue/function-test.cfg b/config/src/tests/functiontest/missingvalue/function-test.cfg
new file mode 100644
index 00000000000..9616ac3d27b
--- /dev/null
+++ b/config/src/tests/functiontest/missingvalue/function-test.cfg
@@ -0,0 +1,39 @@
+bool_val false
+long_val 123
+double_val 41.23
+string_val "foo"
+enum_val FOOBAR
+refval ":parent:"
+fileVal "msdos.sys"
+boolarr[1]
+boolarr[0] false
+intarr[0]
+longarr[0]
+doublearr[2]
+doublearr[0] 2344
+doublearr[1] 123
+stringarr[1]
+stringarr[0] "bar"
+enumarr[1]
+enumarr[0] VALUES
+refarr[0]
+basicStruct.bar 3
+rootStruct.inner0.index 11
+rootStruct.inner1.index 12
+rootStruct.innerArr[0]
+myarray[2]
+myarray[0].stringval[2]
+myarray[0].stringval[0] "baah"
+myarray[0].stringval[1] "yikes"
+myarray[0].refval ":parent:"
+myarray[0].fileVal "command.com"
+myarray[0].anotherarray[1]
+myarray[0].anotherarray[0].foo 7
+myarray[0].myStruct.a 1
+myarray[1].stringval[0]
+myarray[1].refval ":parent:"
+myarray[1].fileVal "display.sys"
+myarray[1].anotherarray[2]
+myarray[1].anotherarray[0].foo 1
+myarray[1].anotherarray[1].foo 2
+myarray[1].myStruct.a 1
diff --git a/config/src/tests/functiontest/randomorder/function-test.cfg b/config/src/tests/functiontest/randomorder/function-test.cfg
new file mode 100644
index 00000000000..d3ec59491d2
--- /dev/null
+++ b/config/src/tests/functiontest/randomorder/function-test.cfg
@@ -0,0 +1,55 @@
+boolarr[1]
+boolarr[0] false
+int_with_def -14
+double_val 41.23
+double_with_def -12
+enumwithdef BAR2
+refval ":parent:"
+refwithdef ":parent:"
+intarr[0]
+basicStruct.intArr[1]
+basicStruct.intArr[0] 10
+doublearr[2]
+doublearr[0] 2344
+doublearr[1] 123
+string_val "foo"
+stringwithdef "bar"
+enum_val FOOBAR
+stringarr[1]
+stringarr[0] "bar"
+basicStruct.bar 3
+long_with_def -333000333000
+enumarr[1]
+enumarr[0] VALUES
+refarr[0]
+rootStruct.innerArr[1]
+rootStruct.innerArr[0].stringVal "deep"
+fileVal "autoexec.bat"
+myarray[2]
+myarray[0].intval -5
+myarray[0].myStruct.a 1
+myarray[0].enumval INNER
+myarray[0].refval ":parent:"
+myarray[0].anotherarray[1]
+myarray[0].anotherarray[0].foo 7
+myarray[0].stringval[2]
+myarray[0].stringval[0] "baah"
+myarray[0].stringval[1] "yikes"
+myarray[0].fileVal "file0"
+myarray[1].stringval[0]
+myarray[1].enumval INNER
+myarray[1].anotherarray[2]
+myarray[1].anotherarray[0].foo 1
+myarray[1].anotherarray[1].foo 2
+myarray[1].myStruct.a -1
+myarray[1].refval ":parent:"
+myarray[1].intval 5
+myarray[1].fileVal "file1"
+bool_val false
+bool_with_def true
+longarr[0]
+rootStruct.inner1.index 12
+int_val 5
+rootStruct.inner0.index 11
+long_val 666000666000
+fileArr[0]
diff --git a/config/src/tests/functiontest/slime-payload.json b/config/src/tests/functiontest/slime-payload.json
new file mode 100644
index 00000000000..7e3a16e69eb
--- /dev/null
+++ b/config/src/tests/functiontest/slime-payload.json
@@ -0,0 +1,103 @@
+{
+ "bool_val": false,
+ "bool_with_def": true,
+ "int_val": 5,
+ "int_with_def": -14,
+ "long_val": 12345678901,
+ "long_with_def": -9876543210,
+ "double_val": 41.23,
+ "double_with_def": -12,
+ "string_val": "foo",
+ "stringwithdef": "bar",
+ "enum_val": "FOOBAR",
+ "enumwithdef": "BAR2",
+ "refval": ":parent:",
+ "refwithdef": ":parent:",
+ "fileVal": "etc",
+ "boolarr": [
+ false
+ ],
+ "intarr": [],
+ "longarr": [
+ 9223372036854775807,
+ -9223372036854775808
+ ],
+ "doublearr": [
+ 2344,
+ 123
+ ],
+ "stringarr": [
+ "bar"
+ ],
+ "enumarr": [
+ "VALUES"
+ ],
+ "refarr": [
+ ":parent:",
+ ":parent:",
+ ":parent:"
+ ],
+ "fileArr": [
+ "bin"
+ ],
+ "basicStruct": {
+ "foo": "basicFoo",
+ "bar": 3,
+ "intArr": [
+ 310
+ ]
+ },
+ "rootStruct": {
+ "inner0": {
+ "index": 11
+ },
+ "inner1": {
+ "index": 12
+ },
+ "innerArr": [
+ {
+ "boolVal": true,
+ "stringVal": "deep"
+ }
+ ]
+ },
+ "myarray": [
+ {
+ "intval": -5,
+ "stringval": [
+ "baah",
+ "yikes"
+ ],
+ "enumval": "INNER",
+ "refval": ":parent:",
+ "fileVal": "file0",
+ "anotherarray": [
+ {
+ "foo": 7
+ }
+ ],
+ "myStruct": {
+ "a": 1,
+ "b": 2
+ }
+ },
+ {
+ "intval": 5,
+ "enumval": "INNER",
+ "refval": ":parent:",
+ "fileVal": "file1",
+ "anotherarray": [
+ {
+ "foo": 1
+ },
+ {
+ "foo": 2
+ }
+ ],
+ "myStruct": {
+ "a": -1,
+ "b": -2
+ }
+ }
+ ]
+}
diff --git a/config/src/tests/functiontest/variableaccess/function-test.cfg b/config/src/tests/functiontest/variableaccess/function-test.cfg
new file mode 100644
index 00000000000..d15bae0b764
--- /dev/null
+++ b/config/src/tests/functiontest/variableaccess/function-test.cfg
@@ -0,0 +1,67 @@
+bool_val false
+bool_with_def true
+int_val 5
+int_with_def -14
+long_val 12345678901
+long_with_def -9876543210
+double_val 41.23
+double_with_def -12
+string_val "foo"
+stringwithdef "bar"
+enum_val FOOBAR
+enumwithdef BAR2
+refval :parent:
+refwithdef ":parent:"
+fileVal "etc"
+boolarr[1]
+boolarr[0] false
+intarr[0]
+longarr[2]
+longarr[0] 9223372036854775807
+longarr[1] -9223372036854775808
+doublearr[2]
+doublearr[0] 2344
+doublearr[1] 123
+stringarr[1]
+stringarr[0] "bar"
+enumarr[1]
+enumarr[0] VALUES
+refarr[3]
+refarr[0] ":parent:"
+refarr[1] ":parent"
+refarr[2] "parent:"
+fileArr[1]
+fileArr[0] "bin"
+
+basicStruct.foo "basicFoo"
+basicStruct.bar 3
+basicStruct.intArr[1]
+basicStruct.intArr[0] 310
+rootStruct.inner0.index 11
+rootStruct.inner1.index 12
+rootStruct.innerArr[1]
+rootStruct.innerArr[0].boolVal true
+rootStruct.innerArr[0].stringVal "deep"
+
+myarray[2]
+myarray[0].intval -5
+myarray[0].stringval[2]
+myarray[0].stringval[0] "baah"
+myarray[0].stringval[1] "yikes"
+myarray[0].enumval INNER
+myarray[0].refval :parent:
+myarray[0].fileVal "file0"
+myarray[0].anotherarray[1]
+myarray[0].anotherarray[0].foo 7
+myarray[0].myStruct.a 1
+myarray[0].myStruct.b 2
+myarray[1].intval 5
+myarray[1].stringval[0]
+myarray[1].enumval INNER
+myarray[1].refval ":parent:"
+myarray[1].fileVal "file1"
+myarray[1].anotherarray[2]
+myarray[1].anotherarray[0].foo 1
+myarray[1].anotherarray[1].foo 2
+myarray[1].myStruct.a -1
+myarray[1].myStruct.b -2