1 /**
2 * @file unit-cppapi-config.cc
3 *
4 * @section LICENSE
5 *
6 * The MIT License
7 *
8 * @copyright Copyright (c) 2017-2021 TileDB, Inc.
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 * THE SOFTWARE.
27 *
28 * @section DESCRIPTION
29 *
30 * Util Tests for C++ API.
31 */
32
33 #include <thread>
34
35 #include "catch.hpp"
36 #include "tiledb/sm/c_api/tiledb_serialization.h"
37 #include "tiledb/sm/cpp_api/tiledb"
38
setenv_local(const char * __name,const char * __value)39 int setenv_local(const char* __name, const char* __value) {
40 #ifdef _WIN32
41 return _putenv_s(__name, __value);
42 #else
43 return ::setenv(__name, __value, 1);
44 #endif
45 }
46
47 TEST_CASE("C++ API: Config", "[cppapi][config]") {
48 tiledb::Config config;
49 config["foo"] = "bar";
50 std::string result1 = config["foo"];
51 CHECK(result1 == "bar");
52
__anonf5ec81500102() 53 auto readInvalidKey = [&config]() { std::string result2 = config["bar"]; };
54 REQUIRE_THROWS_AS(readInvalidKey(), tiledb::TileDBError);
55 }
56
57 TEST_CASE("C++ API: Config iterator", "[cppapi][cppapi-config]") {
58 tiledb::Config config;
59 std::vector<std::string> names;
60 for (auto it = config.begin("vfs"), ite = config.end(); it != ite; ++it) {
61 names.push_back(it->first);
62 }
63 // Check number of VFS params in default config object.
64 CHECK(names.size() == 58);
65 }
66
67 TEST_CASE("C++ API: Config Environment Variables", "[cppapi][cppapi-config]") {
68 tiledb::Config config;
__anonf5ec81500202() 69 auto readInvalidKey = [&config]() { std::string result1 = config["foo"]; };
70 REQUIRE_THROWS_AS(readInvalidKey(), tiledb::TileDBError);
71
72 setenv_local("TILEDB_FOO", "bar");
73 std::string result1 = config["foo"];
74 CHECK(result1 == "bar");
75
76 setenv_local("TILEDB_FOO", "bar2");
77 std::string result2 = config["foo"];
78 CHECK(result2 == "bar2");
79
80 config["config.env_var_prefix"] = "TILEDB_TEST_";
__anonf5ec81500302() 81 auto readInvalidKey2 = [&config]() { std::string result2 = config["foo"]; };
82 REQUIRE_THROWS_AS(readInvalidKey2(), tiledb::TileDBError);
83
84 setenv_local("TILEDB_TEST_FOO", "bar3");
85 std::string result3 = config["foo"];
86 CHECK(result3 == "bar3");
87 }
88
89 TEST_CASE(
90 "C++ API: Config Environment Variables Default Override",
91 "[cppapi][cppapi-config]") {
92 tiledb::Config config;
93 const std::string key = "sm.io_concurrency_level";
94
95 unsigned int threads = std::thread::hardware_concurrency();
96 const std::string result1 = config[key];
97 CHECK(result1 == std::to_string(threads));
98
99 const std::string value2 = std::to_string(threads + 1);
100 setenv_local("TILEDB_SM_IO_CONCURRENCY_LEVEL", value2.c_str());
101 const std::string result2 = config[key];
102 CHECK(result2 == value2);
103
104 // Check iterator
105 for (auto& c : config) {
106 if (c.first == key) {
107 CHECK(c.second == value2);
108 }
109 }
110
111 const std::string value3 = std::to_string(threads + 2);
112 config[key] = value3;
113 const std::string result3 = config[key];
114 CHECK(result3 == value3);
115 }
116
117 TEST_CASE("C++ API: Config Equality", "[cppapi][cppapi-config]") {
118 // Check for equality
119 tiledb::Config config1;
120 config1["foo"] = "bar";
121 tiledb::Config config2;
122 config2["foo"] = "bar";
123 bool config_equal = config1 == config2;
124 CHECK(config_equal);
125
126 // Check for inequality
127 config2["foo"] = "bar2";
128 bool config_not_equal = config1 != config2;
129 CHECK(config_not_equal);
130 }
131
132 #ifdef TILEDB_SERIALIZATION
133 TEST_CASE(
134 "C++ API: Config Serialization", "[cppapi][cppapi-config][serialization]") {
135 // this variable is parameterized below, but we initialize
136 // here to avoid warning/error on MSVC
137 // C4701: potentially uninitialized local variable 'format'
138 tiledb_serialization_type_t format = tiledb_serialization_type_t::TILEDB_JSON;
139 SECTION("- json") {
140 format = tiledb_serialization_type_t::TILEDB_JSON;
141 }
142
143 SECTION("- capnp") {
144 format = tiledb_serialization_type_t::TILEDB_CAPNP;
145 }
146 // Check for equality
147 tiledb::Config config1;
148 config1["foo"] = "bar";
149
150 tiledb::Context ctx;
151
152 // Serialize the query (client-side).
153 tiledb_buffer_t* buff1;
154 int32_t rc = tiledb_serialize_config(
155 ctx.ptr().get(), config1.ptr().get(), format, 1, &buff1);
156 CHECK(rc == TILEDB_OK);
157
158 tiledb_config_t* config2_ptr;
159 rc = tiledb_deserialize_config(
160 ctx.ptr().get(), buff1, format, 0, &config2_ptr);
161 CHECK(rc == TILEDB_OK);
162 tiledb::Config config2(&config2_ptr);
163
164 bool config_equal = config1 == config2;
165 CHECK(config_equal);
166
167 // Check for inequality
168 CHECK(config2.get("foo") == std::string("bar"));
169
170 tiledb_buffer_free(&buff1);
171 }
172 #endif // TILEDB_SERIALIZATION
173