| File: | .build-ci/../libnvme/tests/config-api.c |
| Warning: | line 554, column 6 Value of 'errno' was not checked and may be overwritten by function 'fread' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | // SPDX-License-Identifier: LGPL-2.1-or-later | |||
| 2 | /** | |||
| 3 | * This file is part of libnvme. | |||
| 4 | * Copyright (c) 2026 Dell Technologies Inc. or its subsidiaries. | |||
| 5 | * Authors: Martin Belanger <martin.belanger@dell.com> | |||
| 6 | * | |||
| 7 | * Tests for the public connection-config API (<nvme/config.h>). Linked | |||
| 8 | * against the real shared library, so it also proves every symbol is | |||
| 9 | * exported by the version script. | |||
| 10 | */ | |||
| 11 | ||||
| 12 | #include <shared/assert-util.h> | |||
| 13 | #include <errno(*__errno_location ()).h> | |||
| 14 | #include <stdbool.h> | |||
| 15 | #include <stdio.h> | |||
| 16 | #include <stdlib.h> | |||
| 17 | #include <string.h> | |||
| 18 | ||||
| 19 | #include <sys/stat.h> | |||
| 20 | #include <unistd.h> | |||
| 21 | ||||
| 22 | #include <ccan/array_size/array_size.h> | |||
| 23 | ||||
| 24 | #include <shared/string-util.h> | |||
| 25 | ||||
| 26 | #include <nvme/lib.h> | |||
| 27 | #include <nvme/config.h> | |||
| 28 | #include <nvme/fabrics.h> | |||
| 29 | #include <nvme/nvme-types-fabrics.h> | |||
| 30 | #include <nvme/tid.h> | |||
| 31 | ||||
| 32 | static void write_file(const char *dir, const char *name, const char *text) | |||
| 33 | { | |||
| 34 | char path[512]; | |||
| 35 | FILE *fp; | |||
| 36 | ||||
| 37 | snprintf(path, sizeof(path), "%s/%s", dir, name); | |||
| 38 | fp = fopen(path, "w"); | |||
| 39 | shr_assert(fp)((void)((fp) || (shr_assert_fail("../libnvme/tests/config-api.c" , 39, "fp"), 0))); | |||
| 40 | shr_assert(fputs(text, fp) >= 0)((void)((fputs(text, fp) >= 0) || (shr_assert_fail("../libnvme/tests/config-api.c" , 40, "fputs(text, fp) >= 0"), 0))); | |||
| 41 | fclose(fp); | |||
| 42 | } | |||
| 43 | ||||
| 44 | static void rm_file(const char *dir, const char *name) | |||
| 45 | { | |||
| 46 | char path[512]; | |||
| 47 | ||||
| 48 | snprintf(path, sizeof(path), "%s/%s", dir, name); | |||
| 49 | unlink(path); | |||
| 50 | } | |||
| 51 | ||||
| 52 | /* | |||
| 53 | * The shared fixture: a main file with per-type defaults, one DC and one | |||
| 54 | * subsystem, plus a second-persona drop-in. | |||
| 55 | */ | |||
| 56 | static const char main_text[] = | |||
| 57 | "[Discovery Controller Defaults]\n" | |||
| 58 | "ctrl-loss-tmo = 600\n" | |||
| 59 | "keep-alive-tmo = 30\n" | |||
| 60 | "[I/O Controller Defaults]\n" | |||
| 61 | "ctrl-loss-tmo = 600\n" | |||
| 62 | "keep-alive-tmo = 5\n" | |||
| 63 | "[Discovery Controller]\n" | |||
| 64 | "controller = transport=tcp;traddr=10.0.0.5;trsvcid=8009\n" | |||
| 65 | "[Subsystem]\n" | |||
| 66 | "nqn = nqn.2014-08.org.nvmexpress:main-vol\n" | |||
| 67 | "tls = true\n" | |||
| 68 | "data-digest = no\n" | |||
| 69 | "controller = transport=tcp;traddr=10.0.0.9;trsvcid=4420\n"; | |||
| 70 | ||||
| 71 | static const char prod_text[] = | |||
| 72 | "[Host]\n" | |||
| 73 | "hostnqn = nqn.2014-08.org.nvmexpress:prod-host\n" | |||
| 74 | "hostid = 46ba5037-7ce5-41fa-9452-48477bf00080\n" | |||
| 75 | "hostsymname = prod\n" | |||
| 76 | "[Subsystem]\n" | |||
| 77 | "nqn = nqn.2014-08.org.nvmexpress:prod-vol\n" | |||
| 78 | "reconnect-delay =\n" | |||
| 79 | "controller = transport=tcp;traddr=10.0.0.7;trsvcid=4420;ctrl-loss-tmo=1800\n"; | |||
| 80 | ||||
| 81 | struct fixture { | |||
| 82 | char dir[32]; | |||
| 83 | char main_path[288]; | |||
| 84 | char dropin_dir[288]; | |||
| 85 | }; | |||
| 86 | ||||
| 87 | static void fixture_create(struct fixture *fx) | |||
| 88 | { | |||
| 89 | snprintf(fx->dir, sizeof(fx->dir), "/tmp/nvme-config-api-XXXXXX"); | |||
| 90 | shr_assert(mkdtemp(fx->dir))((void)((mkdtemp(fx->dir)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 90, "mkdtemp(fx->dir)"), 0))); | |||
| 91 | snprintf(fx->main_path, sizeof(fx->main_path), "%s/nvme-fabrics.conf", | |||
| 92 | fx->dir); | |||
| 93 | snprintf(fx->dropin_dir, sizeof(fx->dropin_dir), | |||
| 94 | "%s/nvme-fabrics.conf.d", fx->dir); | |||
| 95 | shr_assert(mkdir(fx->dropin_dir, 0755) == 0)((void)((mkdir(fx->dropin_dir, 0755) == 0) || (shr_assert_fail ("../libnvme/tests/config-api.c", 95, "mkdir(fx->dropin_dir, 0755) == 0" ), 0))); | |||
| 96 | write_file(fx->dir, "nvme-fabrics.conf", main_text); | |||
| 97 | write_file(fx->dropin_dir, "10-prod.conf", prod_text); | |||
| 98 | } | |||
| 99 | ||||
| 100 | static void fixture_destroy(struct fixture *fx) | |||
| 101 | { | |||
| 102 | rm_file(fx->dropin_dir, "10-prod.conf"); | |||
| 103 | rmdir(fx->dropin_dir); | |||
| 104 | rm_file(fx->dir, "nvme-fabrics.conf"); | |||
| 105 | rmdir(fx->dir); | |||
| 106 | } | |||
| 107 | ||||
| 108 | struct conn_list { | |||
| 109 | const struct libnvmf_config_conn *conn[8]; | |||
| 110 | size_t n; | |||
| 111 | }; | |||
| 112 | ||||
| 113 | static void collect(const struct libnvmf_config_conn *conn, void *user_data) | |||
| 114 | { | |||
| 115 | struct conn_list *list = user_data; | |||
| 116 | ||||
| 117 | shr_assert(list->n < 8)((void)((list->n < 8) || (shr_assert_fail("../libnvme/tests/config-api.c" , 117, "list->n < 8"), 0))); | |||
| 118 | list->conn[list->n++] = conn; | |||
| 119 | } | |||
| 120 | ||||
| 121 | static bool_Bool test_read(struct libnvme_global_ctx *ctx, const struct fixture *fx) | |||
| 122 | { | |||
| 123 | const struct libnvmf_config_conn *dc, *mv, *pv; | |||
| 124 | struct conn_list list = { 0 }; | |||
| 125 | const struct libnvmf_params *params; | |||
| 126 | struct libnvmf_config *config; | |||
| 127 | bool_Bool pass = true1; | |||
| 128 | ||||
| 129 | printf("test_read:\n"); | |||
| 130 | ||||
| 131 | if (libnvmf_config_read(ctx, fx->main_path, &config)) { | |||
| 132 | printf(" - read failed [FAIL]\n"); | |||
| 133 | return false0; | |||
| 134 | } | |||
| 135 | ||||
| 136 | libnvmf_config_conn_for_each(config, collect, &list); | |||
| 137 | if (list.n != 3) { | |||
| 138 | printf(" - expected 3 connections, got %zu [FAIL]\n", list.n); | |||
| 139 | libnvmf_config_free(config); | |||
| 140 | return false0; | |||
| 141 | } | |||
| 142 | printf(" - 3 connections resolved [PASS]\n"); | |||
| 143 | ||||
| 144 | /* Main file first (DC, then subsystem), then the drop-in. */ | |||
| 145 | dc = list.conn[0]; | |||
| 146 | mv = list.conn[1]; | |||
| 147 | pv = list.conn[2]; | |||
| 148 | ||||
| 149 | if (!libnvmf_config_conn_is_dc(dc) || libnvmf_config_conn_is_dc(mv) || | |||
| 150 | libnvmf_config_conn_is_dc(pv)) { | |||
| 151 | printf(" - connection roles [FAIL]\n"); | |||
| 152 | pass = false0; | |||
| 153 | } else { | |||
| 154 | printf(" - roles: DC + two subsystems [PASS]\n"); | |||
| 155 | } | |||
| 156 | ||||
| 157 | if (strcmp(libnvmf_config_conn_get_transport(dc), "tcp") || | |||
| 158 | strcmp(libnvmf_config_conn_get_traddr(dc), "10.0.0.5") || | |||
| 159 | strcmp(libnvmf_config_conn_get_subsysnqn(dc), | |||
| 160 | NVME_DISC_SUBSYS_NAME"nqn.2014-08.org.nvmexpress.discovery")) { | |||
| 161 | printf(" - DC addressing + well-known NQN [FAIL]\n"); | |||
| 162 | pass = false0; | |||
| 163 | } else { | |||
| 164 | printf(" - DC addressing + well-known NQN [PASS]\n"); | |||
| 165 | } | |||
| 166 | ||||
| 167 | if (strcmp(libnvmf_config_conn_get_subsysnqn(pv), "nqn.2014-08.org.nvmexpress:prod-vol") || | |||
| 168 | strcmp(libnvmf_config_conn_get_hostnqn(pv), "nqn.2014-08.org.nvmexpress:prod-host") || | |||
| 169 | strcmp(libnvmf_config_conn_get_hostid(pv), | |||
| 170 | "46ba5037-7ce5-41fa-9452-48477bf00080")) { | |||
| 171 | printf(" - drop-in persona identity [FAIL]\n"); | |||
| 172 | pass = false0; | |||
| 173 | } else { | |||
| 174 | printf(" - drop-in persona identity raw [PASS]\n"); | |||
| 175 | } | |||
| 176 | ||||
| 177 | if (libnvmf_config_conn_get_hostnqn(mv) || | |||
| 178 | libnvmf_config_conn_get_hostsymname(mv)) { | |||
| 179 | printf(" - main persona left to system default [FAIL]\n"); | |||
| 180 | pass = false0; | |||
| 181 | } else { | |||
| 182 | printf(" - main persona left to system default [PASS]\n"); | |||
| 183 | } | |||
| 184 | ||||
| 185 | if (!libnvmf_config_conn_get_hostsymname(pv) || | |||
| 186 | strcmp(libnvmf_config_conn_get_hostsymname(pv), "prod")) { | |||
| 187 | printf(" - hostsymname [FAIL]\n"); | |||
| 188 | pass = false0; | |||
| 189 | } else { | |||
| 190 | printf(" - hostsymname carried on the drop-in persona [PASS]\n"); | |||
| 191 | } | |||
| 192 | ||||
| 193 | params = libnvmf_config_conn_get_params(mv); | |||
| 194 | if (!params || strcmp(libnvmf_params_get(params, "ctrl-loss-tmo"), "600") || | |||
| 195 | strcmp(libnvmf_params_get(params, "keep-alive-tmo"), "5") || | |||
| 196 | strcmp(libnvmf_params_get(params, "tls"), "true") || | |||
| 197 | libnvmf_params_get(params, "reconnect-delay")) { | |||
| 198 | printf(" - main subsystem cascade [FAIL]\n"); | |||
| 199 | pass = false0; | |||
| 200 | } else { | |||
| 201 | printf(" - main cascade: defaults + section [PASS]\n"); | |||
| 202 | } | |||
| 203 | ||||
| 204 | params = libnvmf_config_conn_get_params(pv); | |||
| 205 | if (!params || | |||
| 206 | strcmp(libnvmf_params_get(params, "ctrl-loss-tmo"), "1800") || | |||
| 207 | strcmp(libnvmf_params_get(params, "keep-alive-tmo"), "5")) { | |||
| 208 | printf(" - per-path override [FAIL]\n"); | |||
| 209 | pass = false0; | |||
| 210 | } else { | |||
| 211 | printf(" - per-path override beats the type default [PASS]\n"); | |||
| 212 | } | |||
| 213 | ||||
| 214 | if (!strstr(libnvmf_config_conn_get_source(dc), "nvme-fabrics.conf")_Generic (0 ? (libnvmf_config_conn_get_source(dc)) : (void *) 1, const void *: (const char *) (strstr (libnvmf_config_conn_get_source (dc), "nvme-fabrics.conf")), default: strstr (libnvmf_config_conn_get_source (dc), "nvme-fabrics.conf")) || | |||
| 215 | !strstr(libnvmf_config_conn_get_source(pv), "10-prod.conf")_Generic (0 ? (libnvmf_config_conn_get_source(pv)) : (void *) 1, const void *: (const char *) (strstr (libnvmf_config_conn_get_source (pv), "10-prod.conf")), default: strstr (libnvmf_config_conn_get_source (pv), "10-prod.conf"))) { | |||
| 216 | printf(" - source provenance [FAIL]\n"); | |||
| 217 | pass = false0; | |||
| 218 | } else { | |||
| 219 | printf(" - source names the originating file [PASS]\n"); | |||
| 220 | } | |||
| 221 | ||||
| 222 | libnvmf_config_free(config); | |||
| 223 | ||||
| 224 | return pass; | |||
| 225 | } | |||
| 226 | ||||
| 227 | static bool_Bool test_resolve_discovered(struct libnvme_global_ctx *ctx, | |||
| 228 | const struct fixture *fx) | |||
| 229 | { | |||
| 230 | const struct libnvmf_params *params; | |||
| 231 | struct conn_list list = { 0 }; | |||
| 232 | struct libnvmf_config *config; | |||
| 233 | bool_Bool pass = true1; | |||
| 234 | ||||
| 235 | printf("test_resolve_discovered:\n"); | |||
| 236 | ||||
| 237 | shr_assert(!libnvmf_config_read(ctx, fx->main_path, &config))((void)((!libnvmf_config_read(ctx, fx->main_path, &config )) || (shr_assert_fail("../libnvme/tests/config-api.c", 237, "!libnvmf_config_read(ctx, fx->main_path, &config)" ), 0))); | |||
| 238 | libnvmf_config_conn_for_each(config, collect, &list); | |||
| 239 | shr_assert(list.n == 3 && libnvmf_config_conn_is_dc(list.conn[0]))((void)((list.n == 3 && libnvmf_config_conn_is_dc(list .conn[0])) || (shr_assert_fail("../libnvme/tests/config-api.c" , 239, "list.n == 3 && libnvmf_config_conn_is_dc(list.conn[0])" ), 0))); | |||
| 240 | ||||
| 241 | /* A DLP IOC discovered via the configured DC: that DC's file scope. */ | |||
| 242 | params = libnvmf_config_resolve_discovered(config, list.conn[0], false0); | |||
| 243 | if (!params || strcmp(libnvmf_params_get(params, "keep-alive-tmo"), "5") || | |||
| 244 | strcmp(libnvmf_params_get(params, "ctrl-loss-tmo"), "600") || | |||
| 245 | libnvmf_params_get(params, "tls")) { | |||
| 246 | printf(" - DLP IOC scope via DC [FAIL]\n"); | |||
| 247 | pass = false0; | |||
| 248 | } else { | |||
| 249 | printf(" - DLP IOC draws the DC's file scope [PASS]\n"); | |||
| 250 | } | |||
| 251 | ||||
| 252 | /* A referral DC discovered via the configured DC. */ | |||
| 253 | params = libnvmf_config_resolve_discovered(config, list.conn[0], true1); | |||
| 254 | if (!params || | |||
| 255 | strcmp(libnvmf_params_get(params, "keep-alive-tmo"), "30")) { | |||
| 256 | printf(" - referral DC scope via DC [FAIL]\n"); | |||
| 257 | pass = false0; | |||
| 258 | } else { | |||
| 259 | printf(" - referral DC draws the DC-defaults scope [PASS]\n"); | |||
| 260 | } | |||
| 261 | ||||
| 262 | /* No configured origin (an mDNS-found DC): the top-level scope. */ | |||
| 263 | params = libnvmf_config_resolve_discovered(config, NULL((void*)0), true1); | |||
| 264 | if (!params || | |||
| 265 | strcmp(libnvmf_params_get(params, "keep-alive-tmo"), "30") || | |||
| 266 | strcmp(libnvmf_params_get(params, "ctrl-loss-tmo"), "600")) { | |||
| 267 | printf(" - top-level scope [FAIL]\n"); | |||
| 268 | pass = false0; | |||
| 269 | } else { | |||
| 270 | printf(" - no origin falls back to the top-level scope [PASS]\n"); | |||
| 271 | } | |||
| 272 | ||||
| 273 | /* An IOC is not a discovery origin. */ | |||
| 274 | if (libnvmf_config_resolve_discovered(config, list.conn[1], false0)) { | |||
| 275 | printf(" - IOC as origin rejected [FAIL]\n"); | |||
| 276 | pass = false0; | |||
| 277 | } else { | |||
| 278 | printf(" - an IOC connection is not a discovery origin [PASS]\n"); | |||
| 279 | } | |||
| 280 | ||||
| 281 | libnvmf_config_free(config); | |||
| 282 | ||||
| 283 | return pass; | |||
| 284 | } | |||
| 285 | ||||
| 286 | /* | |||
| 287 | * Sections that supply the KX-HMAC-CHAP secrets of discovered controllers. | |||
| 288 | * sub1 has no controller= line, sub2 has one. The drop-in is another | |||
| 289 | * persona with its own secret for sub1. | |||
| 290 | */ | |||
| 291 | static const char keys_text[] = | |||
| 292 | "[I/O Controller Defaults]\n" | |||
| 293 | "ctrl-loss-tmo = 600\n" | |||
| 294 | "kxchap-secret = DHHC-1:00:default:\n" | |||
| 295 | "[Discovery Controller]\n" | |||
| 296 | "controller = transport=tcp;traddr=10.0.0.5;trsvcid=8009\n" | |||
| 297 | "[Subsystem]\n" | |||
| 298 | "nqn = nqn.2014-08.org.nvmexpress:sub1\n" | |||
| 299 | "kxchap-secret = DHHC-1:00:sub1-host:\n" | |||
| 300 | "kxchap-ctrl-secret = DHHC-1:00:sub1-ctrl:\n" | |||
| 301 | "[Subsystem]\n" | |||
| 302 | "nqn = nqn.2014-08.org.nvmexpress:sub2\n" | |||
| 303 | "kxchap-ctrl-secret = DHHC-1:00:sub2-ctrl:\n" | |||
| 304 | "controller = transport=tcp;traddr=10.0.0.9;trsvcid=4420\n" | |||
| 305 | "[Subsystem]\n" | |||
| 306 | "nqn = nqn.2014-08.org.nvmexpress:sub3\n" | |||
| 307 | "kxchap-secret =\n" | |||
| 308 | "[Subsystem]\n" | |||
| 309 | "nqn = nqn.2014-08.org.nvmexpress:sub4\n" | |||
| 310 | "tls = true\n" | |||
| 311 | "[Discovery Controller]\n" | |||
| 312 | "nqn = nqn.2014-08.org.nvmexpress:cdc\n" | |||
| 313 | "kxchap-secret = DHHC-1:00:cdc-host:\n" | |||
| 314 | "kxchap-ctrl-secret = DHHC-1:00:cdc-ctrl:\n" | |||
| 315 | "[Discovery Controller]\n" | |||
| 316 | "nqn = " NVME_DISC_SUBSYS_NAME"nqn.2014-08.org.nvmexpress.discovery" "\n" | |||
| 317 | "kxchap-secret = DHHC-1:00:wk-host:\n"; | |||
| 318 | ||||
| 319 | static const char keys_dropin_text[] = | |||
| 320 | "[Host]\n" | |||
| 321 | "hostnqn = nqn.2014-08.org.nvmexpress:other-host\n" | |||
| 322 | "hostid = 2b6f1a0e-4d39-4c5a-9a0e-0b8a3f2c1d00\n" | |||
| 323 | "[Discovery Controller]\n" | |||
| 324 | "controller = transport=tcp;traddr=10.0.0.6;trsvcid=8009\n" | |||
| 325 | "[Subsystem]\n" | |||
| 326 | "nqn = nqn.2014-08.org.nvmexpress:sub1\n" | |||
| 327 | "kxchap-secret = DHHC-1:00:other-host:\n"; | |||
| 328 | ||||
| 329 | /* The parameters of a discovered controller, NULL on error. */ | |||
| 330 | static const struct libnvmf_params *discovered( | |||
| 331 | const struct libnvmf_config *config, const char *hostnqn, | |||
| 332 | bool_Bool is_dc, const char *nqn) | |||
| 333 | { | |||
| 334 | const struct libnvmf_params *params; | |||
| 335 | ||||
| 336 | if (libnvmf_config_get_discovered_params(config, hostnqn, is_dc, nqn, | |||
| 337 | ¶ms)) | |||
| 338 | return NULL((void*)0); | |||
| 339 | ||||
| 340 | return params; | |||
| 341 | } | |||
| 342 | ||||
| 343 | static bool_Bool expect_keys(const char *what, const struct libnvmf_params *params, | |||
| 344 | const char *hostkey, const char *ctrlkey) | |||
| 345 | { | |||
| 346 | const char *h = libnvmf_params_get(params, "kxchap-secret"); | |||
| 347 | const char *c = libnvmf_params_get(params, "kxchap-ctrl-secret"); | |||
| 348 | ||||
| 349 | if (!params || !shr_streq0(h, hostkey) || !shr_streq0(c, ctrlkey)) { | |||
| 350 | printf(" - %s: secret %s, ctrl secret %s [FAIL]\n", | |||
| 351 | what, h ? h : "(unset)", c ? c : "(unset)"); | |||
| 352 | return false0; | |||
| 353 | } | |||
| 354 | printf(" - %s [PASS]\n", what); | |||
| 355 | ||||
| 356 | return true1; | |||
| 357 | } | |||
| 358 | ||||
| 359 | static bool_Bool test_get_discovered_params(struct libnvme_global_ctx *ctx, | |||
| 360 | const struct fixture *fx) | |||
| 361 | { | |||
| 362 | const char *top, *other, *sub1 = "nqn.2014-08.org.nvmexpress:sub1"; | |||
| 363 | const char *cdc = "nqn.2014-08.org.nvmexpress:cdc"; | |||
| 364 | const struct libnvmf_params *params; | |||
| 365 | struct conn_list list = { 0 }; | |||
| 366 | struct libnvmf_config *config; | |||
| 367 | char path[352], dropin_dir[356]; | |||
| 368 | bool_Bool pass = true1; | |||
| 369 | ||||
| 370 | printf("test_get_discovered_params:\n"); | |||
| 371 | ||||
| 372 | write_file(fx->dir, "keys.conf", keys_text); | |||
| 373 | snprintf(path, sizeof(path), "%s/keys.conf", fx->dir); | |||
| 374 | snprintf(dropin_dir, sizeof(dropin_dir), "%s.d", path); | |||
| 375 | shr_assert(mkdir(dropin_dir, 0755) == 0)((void)((mkdir(dropin_dir, 0755) == 0) || (shr_assert_fail("../libnvme/tests/config-api.c" , 375, "mkdir(dropin_dir, 0755) == 0"), 0))); | |||
| 376 | write_file(dropin_dir, "10-other.conf", keys_dropin_text); | |||
| 377 | ||||
| 378 | shr_assert(!libnvmf_config_read(ctx, path, &config))((void)((!libnvmf_config_read(ctx, path, &config)) || (shr_assert_fail ("../libnvme/tests/config-api.c", 378, "!libnvmf_config_read(ctx, path, &config)" ), 0))); | |||
| 379 | libnvmf_config_conn_for_each(config, collect, &list); | |||
| 380 | shr_assert(list.n == 3)((void)((list.n == 3) || (shr_assert_fail("../libnvme/tests/config-api.c" , 380, "list.n == 3"), 0))); | |||
| 381 | shr_assert(libnvmf_config_conn_is_dc(list.conn[0]) &&((void)((libnvmf_config_conn_is_dc(list.conn[0]) && libnvmf_config_conn_is_dc (list.conn[2])) || (shr_assert_fail("../libnvme/tests/config-api.c" , 382, "libnvmf_config_conn_is_dc(list.conn[0]) && libnvmf_config_conn_is_dc(list.conn[2])" ), 0))) | |||
| 382 | libnvmf_config_conn_is_dc(list.conn[2]))((void)((libnvmf_config_conn_is_dc(list.conn[0]) && libnvmf_config_conn_is_dc (list.conn[2])) || (shr_assert_fail("../libnvme/tests/config-api.c" , 382, "libnvmf_config_conn_is_dc(list.conn[0]) && libnvmf_config_conn_is_dc(list.conn[2])" ), 0))); | |||
| 383 | ||||
| 384 | /* The persona of a DC connection, as nvme-discoverd passes it. */ | |||
| 385 | top = libnvmf_config_conn_get_hostnqn(list.conn[0]); | |||
| 386 | other = libnvmf_config_conn_get_hostnqn(list.conn[2]); | |||
| 387 | shr_assert(!top && other)((void)((!top && other) || (shr_assert_fail("../libnvme/tests/config-api.c" , 387, "!top && other"), 0))); | |||
| 388 | ||||
| 389 | params = discovered(config, top, false0, sub1); | |||
| 390 | pass &= expect_keys("a section without controller= matches", params, | |||
| 391 | "DHHC-1:00:sub1-host:", "DHHC-1:00:sub1-ctrl:"); | |||
| 392 | if (!shr_streq0(libnvmf_params_get(params, "ctrl-loss-tmo"), "600")) { | |||
| 393 | printf(" - the file scope defaults are kept [FAIL]\n"); | |||
| 394 | pass = false0; | |||
| 395 | } | |||
| 396 | ||||
| 397 | pass &= expect_keys("a section with controller= matches, scope secret", | |||
| 398 | discovered(config, top, false0, | |||
| 399 | "nqn.2014-08.org.nvmexpress:sub2"), | |||
| 400 | "DHHC-1:00:default:", "DHHC-1:00:sub2-ctrl:"); | |||
| 401 | pass &= expect_keys("a reset secret stays reset", | |||
| 402 | discovered(config, top, false0, | |||
| 403 | "nqn.2014-08.org.nvmexpress:sub3"), | |||
| 404 | "", NULL((void*)0)); | |||
| 405 | pass &= expect_keys("a section without a secret does not match", | |||
| 406 | discovered(config, top, false0, | |||
| 407 | "nqn.2014-08.org.nvmexpress:sub4"), | |||
| 408 | "DHHC-1:00:default:", NULL((void*)0)); | |||
| 409 | pass &= expect_keys("no section: the file scope", | |||
| 410 | discovered(config, top, false0, | |||
| 411 | "nqn.2014-08.org.nvmexpress:unknown"), | |||
| 412 | "DHHC-1:00:default:", NULL((void*)0)); | |||
| 413 | pass &= expect_keys("no NQN: the file scope", | |||
| 414 | discovered(config, top, false0, | |||
| 415 | NULL((void*)0)), | |||
| 416 | "DHHC-1:00:default:", NULL((void*)0)); | |||
| 417 | pass &= expect_keys("a [Subsystem] does not match a DC", | |||
| 418 | discovered(config, top, true1, sub1), | |||
| 419 | NULL((void*)0), NULL((void*)0)); | |||
| 420 | ||||
| 421 | pass &= expect_keys("a DC with a unique NQN", | |||
| 422 | discovered(config, top, true1, cdc), | |||
| 423 | "DHHC-1:00:cdc-host:", "DHHC-1:00:cdc-ctrl:"); | |||
| 424 | pass &= expect_keys("the well-known NQN never matches", | |||
| 425 | discovered(config, top, true1, | |||
| 426 | NVME_DISC_SUBSYS_NAME"nqn.2014-08.org.nvmexpress.discovery"), | |||
| 427 | NULL((void*)0), NULL((void*)0)); | |||
| 428 | ||||
| 429 | pass &= expect_keys("another persona uses the section of its file", | |||
| 430 | discovered(config, other, false0, | |||
| 431 | sub1), | |||
| 432 | "DHHC-1:00:other-host:", NULL((void*)0)); | |||
| 433 | pass &= expect_keys("another persona's section does not match", | |||
| 434 | discovered(config, other, false0, | |||
| 435 | "nqn.2014-08.org.nvmexpress:sub2"), | |||
| 436 | "DHHC-1:00:default:", NULL((void*)0)); | |||
| 437 | ||||
| 438 | if (libnvmf_config_get_discovered_params(config, | |||
| 439 | "nqn.2014-08.org.nvmexpress:no-such-host", false0, | |||
| 440 | sub1, ¶ms) != -ENOENT2) { | |||
| 441 | printf(" - an unknown persona [FAIL]\n"); | |||
| 442 | pass = false0; | |||
| 443 | } else { | |||
| 444 | printf(" - an unknown persona has none [PASS]\n"); | |||
| 445 | } | |||
| 446 | ||||
| 447 | libnvmf_config_free(config); | |||
| 448 | rm_file(dropin_dir, "10-other.conf"); | |||
| 449 | rmdir(dropin_dir); | |||
| 450 | rm_file(fx->dir, "keys.conf"); | |||
| 451 | ||||
| 452 | return pass; | |||
| 453 | } | |||
| 454 | ||||
| 455 | /* Two sections with the same NQN: their secrets are combined. */ | |||
| 456 | static const char dup_text[] = | |||
| 457 | "[Subsystem]\n" | |||
| 458 | "nqn = nqn.2014-08.org.nvmexpress:dup\n" | |||
| 459 | "kxchap-secret = DHHC-1:00:dup-host:\n" | |||
| 460 | "controller = transport=tcp;traddr=10.0.0.9;trsvcid=4420\n" | |||
| 461 | "[Subsystem]\n" | |||
| 462 | "nqn = nqn.2014-08.org.nvmexpress:dup\n" | |||
| 463 | "kxchap-secret = DHHC-1:00:dup-host:\n" | |||
| 464 | "kxchap-ctrl-secret = DHHC-1:00:dup-ctrl:\n" | |||
| 465 | "controller = transport=tcp;traddr=10.0.0.10;trsvcid=4420\n" | |||
| 466 | "[Discovery Controller]\n" | |||
| 467 | "controller = transport=tcp;traddr=10.0.0.5;trsvcid=8009\n" | |||
| 468 | "[Discovery Controller]\n" | |||
| 469 | "controller = transport=tcp;traddr=10.0.0.6;trsvcid=8009\n"; | |||
| 470 | ||||
| 471 | static const char dup_conflict_text[] = | |||
| 472 | "[Subsystem]\n" | |||
| 473 | "nqn = nqn.2014-08.org.nvmexpress:dup\n" | |||
| 474 | "kxchap-secret = DHHC-1:00:dup-host:\n" | |||
| 475 | "[Subsystem]\n" | |||
| 476 | "nqn = nqn.2014-08.org.nvmexpress:dup\n" | |||
| 477 | "kxchap-secret = DHHC-1:00:other:\n"; | |||
| 478 | ||||
| 479 | static bool_Bool test_duplicate_nqn(struct libnvme_global_ctx *ctx, | |||
| 480 | const struct fixture *fx) | |||
| 481 | { | |||
| 482 | struct libnvmf_config *config; | |||
| 483 | char path[352]; | |||
| 484 | bool_Bool pass = true1; | |||
| 485 | ||||
| 486 | printf("test_duplicate_nqn:\n"); | |||
| 487 | ||||
| 488 | snprintf(path, sizeof(path), "%s/dup.conf", fx->dir); | |||
| 489 | ||||
| 490 | write_file(fx->dir, "dup.conf", dup_text); | |||
| 491 | if (libnvmf_config_read(ctx, path, &config)) { | |||
| 492 | printf(" - same NQN, same secrets is accepted [FAIL]\n"); | |||
| 493 | pass = false0; | |||
| 494 | } else { | |||
| 495 | pass &= expect_keys("same NQN, same secrets: combined", | |||
| 496 | discovered(config, NULL((void*)0), | |||
| 497 | false0, "nqn.2014-08.org.nvmexpress:dup"), | |||
| 498 | "DHHC-1:00:dup-host:", "DHHC-1:00:dup-ctrl:"); | |||
| 499 | libnvmf_config_free(config); | |||
| 500 | } | |||
| 501 | ||||
| 502 | write_file(fx->dir, "dup.conf", dup_conflict_text); | |||
| 503 | if (libnvmf_config_read(ctx, path, &config) != -EINVAL22) { | |||
| 504 | printf(" - same NQN, different secrets [FAIL]\n"); | |||
| 505 | pass = false0; | |||
| 506 | } else { | |||
| 507 | printf(" - same NQN, different secrets is rejected [PASS]\n"); | |||
| 508 | } | |||
| 509 | rm_file(fx->dir, "dup.conf"); | |||
| 510 | ||||
| 511 | return pass; | |||
| 512 | } | |||
| 513 | ||||
| 514 | /* Only unidirectional authentication with the well-known discovery NQN */ | |||
| 515 | static const char wk_ctrl_secret_text[] = | |||
| 516 | "[Discovery Controller]\n" | |||
| 517 | "kxchap-secret = DHHC-1:00:wk-host:\n" | |||
| 518 | "kxchap-ctrl-secret = DHHC-1:00:wk-ctrl:\n" | |||
| 519 | "controller = transport=tcp;traddr=10.0.0.5;trsvcid=8009\n" | |||
| 520 | "[Discovery Controller]\n" | |||
| 521 | "nqn = " NVME_DISC_SUBSYS_NAME"nqn.2014-08.org.nvmexpress.discovery" "\n" | |||
| 522 | "kxchap-ctrl-secret = DHHC-1:00:wk-ctrl:\n" | |||
| 523 | "[Discovery Controller]\n" | |||
| 524 | "nqn = " NVME_DISC_SUBSYS_NAME"nqn.2014-08.org.nvmexpress.discovery" "\n" | |||
| 525 | "kxchap-secret = DHHC-1:00:wk-host:\n" | |||
| 526 | "kxchap-ctrl-secret =\n" | |||
| 527 | "[Discovery Controller]\n" | |||
| 528 | "nqn = nqn.2014-08.org.nvmexpress:cdc\n" | |||
| 529 | "kxchap-ctrl-secret = DHHC-1:00:cdc-ctrl:\n"; | |||
| 530 | ||||
| 531 | static bool_Bool test_wellknown_ctrl_secret(struct libnvme_global_ctx *ctx, | |||
| 532 | const struct fixture *fx) | |||
| 533 | { | |||
| 534 | struct libnvmf_config *config = NULL((void*)0); | |||
| 535 | char path[352], log[1024] = ""; | |||
| 536 | unsigned int warnings = 0; | |||
| 537 | const char *p; | |||
| 538 | bool_Bool pass = true1; | |||
| 539 | FILE *fp; | |||
| 540 | int ret; | |||
| 541 | ||||
| 542 | printf("test_wellknown_ctrl_secret:\n"); | |||
| 543 | ||||
| 544 | snprintf(path, sizeof(path), "%s/wk.conf", fx->dir); | |||
| 545 | write_file(fx->dir, "wk.conf", wk_ctrl_secret_text); | |||
| 546 | ||||
| 547 | /* The log goes to the file descriptor, not to the FILE buffer */ | |||
| 548 | fp = tmpfile(); | |||
| 549 | shr_assert(fp)((void)((fp) || (shr_assert_fail("../libnvme/tests/config-api.c" , 549, "fp"), 0))); | |||
| 550 | libnvme_set_logging_file(ctx, fp); | |||
| 551 | ret = libnvmf_config_read(ctx, path, &config); | |||
| 552 | libnvme_set_logging_file(ctx, NULL((void*)0)); | |||
| 553 | rewind(fp); | |||
| ||||
| 554 | log[fread(log, 1, sizeof(log) - 1, fp)] = '\0'; | |||
| ||||
| 555 | fclose(fp); | |||
| 556 | ||||
| 557 | if (ret) { | |||
| 558 | printf(" - well-known DC with a ctrl secret loads [FAIL]\n"); | |||
| 559 | pass = false0; | |||
| 560 | } else { | |||
| 561 | printf(" - well-known DC with a ctrl secret loads [PASS]\n"); | |||
| 562 | } | |||
| 563 | ||||
| 564 | for (p = log; (p = strstr(p, "kxchap-ctrl-secret is not")_Generic (0 ? (p) : (void *) 1, const void *: (const char *) ( strstr (p, "kxchap-ctrl-secret is not")), default: strstr (p, "kxchap-ctrl-secret is not"))); p++) | |||
| 565 | warnings++; | |||
| 566 | if (warnings != 2 || !strstr(log, "line 1:")_Generic (0 ? (log) : (void *) 1, const void *: (const char * ) (strstr (log, "line 1:")), default: strstr (log, "line 1:") ) || | |||
| 567 | !strstr(log, "line 5:")_Generic (0 ? (log) : (void *) 1, const void *: (const char * ) (strstr (log, "line 5:")), default: strstr (log, "line 5:") )) { | |||
| 568 | printf(" - warned for lines 1 and 5 only [FAIL]\n%s", log); | |||
| 569 | pass = false0; | |||
| 570 | } else { | |||
| 571 | printf(" - warned for lines 1 and 5 only [PASS]\n"); | |||
| 572 | } | |||
| 573 | ||||
| 574 | libnvmf_config_free(config); | |||
| 575 | rm_file(fx->dir, "wk.conf"); | |||
| 576 | ||||
| 577 | return pass; | |||
| 578 | } | |||
| 579 | ||||
| 580 | static const char host_only_text[] = | |||
| 581 | "[Host]\n" | |||
| 582 | "hostnqn = nqn.2014-08.org.nvmexpress:solo-host\n" | |||
| 583 | "hostid = 8b6b8b6b-0000-4000-8000-00000000dead\n" | |||
| 584 | "hostsymname = solo\n"; | |||
| 585 | ||||
| 586 | static bool_Bool test_top_level_host(struct libnvme_global_ctx *ctx, | |||
| 587 | const struct fixture *fx) | |||
| 588 | { | |||
| 589 | struct conn_list list = { 0 }; | |||
| 590 | struct libnvmf_config *config; | |||
| 591 | char path[352]; | |||
| 592 | bool_Bool pass = true1; | |||
| 593 | ||||
| 594 | printf("test_top_level_host:\n"); | |||
| 595 | ||||
| 596 | /* | |||
| 597 | * The fixture's main file carries no [Host]; only the drop-in does. | |||
| 598 | * A drop-in's persona belongs to that drop-in's own connections and | |||
| 599 | * must not be reported as the configuration's identity. | |||
| 600 | */ | |||
| 601 | shr_assert(!libnvmf_config_read(ctx, fx->main_path, &config))((void)((!libnvmf_config_read(ctx, fx->main_path, &config )) || (shr_assert_fail("../libnvme/tests/config-api.c", 601, "!libnvmf_config_read(ctx, fx->main_path, &config)" ), 0))); | |||
| 602 | if (libnvmf_config_get_hostnqn(config) || | |||
| 603 | libnvmf_config_get_hostid(config) || | |||
| 604 | libnvmf_config_get_hostsymname(config)) { | |||
| 605 | printf(" - a drop-in persona must not be reported [FAIL]\n"); | |||
| 606 | pass = false0; | |||
| 607 | } else { | |||
| 608 | printf(" - drop-in persona is not the top-level one [PASS]\n"); | |||
| 609 | } | |||
| 610 | libnvmf_config_free(config); | |||
| 611 | ||||
| 612 | /* | |||
| 613 | * A [Host] and nothing else: no connections, but an identity. This is | |||
| 614 | * the host that connects only what it discovers. | |||
| 615 | */ | |||
| 616 | write_file(fx->dir, "host-only.conf", host_only_text); | |||
| 617 | snprintf(path, sizeof(path), "%s/host-only.conf", fx->dir); | |||
| 618 | shr_assert(!libnvmf_config_read(ctx, path, &config))((void)((!libnvmf_config_read(ctx, path, &config)) || (shr_assert_fail ("../libnvme/tests/config-api.c", 618, "!libnvmf_config_read(ctx, path, &config)" ), 0))); | |||
| 619 | ||||
| 620 | libnvmf_config_conn_for_each(config, collect, &list); | |||
| 621 | if (list.n) { | |||
| 622 | printf(" - expected no connections, got %zu [FAIL]\n", list.n); | |||
| 623 | pass = false0; | |||
| 624 | } | |||
| 625 | ||||
| 626 | if (!libnvmf_config_get_hostnqn(config) || | |||
| 627 | strcmp(libnvmf_config_get_hostnqn(config), | |||
| 628 | "nqn.2014-08.org.nvmexpress:solo-host") || | |||
| 629 | !libnvmf_config_get_hostid(config) || | |||
| 630 | strcmp(libnvmf_config_get_hostid(config), | |||
| 631 | "8b6b8b6b-0000-4000-8000-00000000dead") || | |||
| 632 | !libnvmf_config_get_hostsymname(config) || | |||
| 633 | strcmp(libnvmf_config_get_hostsymname(config), "solo")) { | |||
| 634 | printf(" - identity of a connection-less config [FAIL]\n"); | |||
| 635 | pass = false0; | |||
| 636 | } else { | |||
| 637 | printf(" - identity without connections [PASS]\n"); | |||
| 638 | } | |||
| 639 | libnvmf_config_free(config); | |||
| 640 | rm_file(fx->dir, "host-only.conf"); | |||
| 641 | ||||
| 642 | return pass; | |||
| 643 | } | |||
| 644 | ||||
| 645 | static bool_Bool test_persona_validation(struct libnvme_global_ctx *ctx, | |||
| 646 | const struct fixture *fx) | |||
| 647 | { | |||
| 648 | struct libnvmf_config *config; | |||
| 649 | char path[352]; | |||
| 650 | bool_Bool pass = true1; | |||
| 651 | ||||
| 652 | printf("test_persona_validation:\n"); | |||
| 653 | ||||
| 654 | /* A drop-in persona with a hostnqn but no hostid. */ | |||
| 655 | write_file(fx->dropin_dir, "20-no-hostid.conf", | |||
| 656 | "[Host]\n" | |||
| 657 | "hostnqn = nqn.2014-08.org.nvmexpress:no-hostid\n"); | |||
| 658 | if (libnvmf_config_read(ctx, fx->main_path, &config) != -EINVAL22) { | |||
| 659 | printf(" - drop-in hostnqn without hostid [FAIL]\n"); | |||
| 660 | pass = false0; | |||
| 661 | } else { | |||
| 662 | printf(" - drop-in hostnqn without hostid rejected [PASS]\n"); | |||
| 663 | } | |||
| 664 | rm_file(fx->dropin_dir, "20-no-hostid.conf"); | |||
| 665 | ||||
| 666 | /* The same shape on a top-level file's own [Host] section. */ | |||
| 667 | write_file(fx->dir, "top-no-hostid.conf", | |||
| 668 | "[Host]\n" | |||
| 669 | "hostnqn = nqn.2014-08.org.nvmexpress:top-no-hostid\n"); | |||
| 670 | snprintf(path, sizeof(path), "%s/top-no-hostid.conf", fx->dir); | |||
| 671 | if (libnvmf_config_read(ctx, path, &config) != -EINVAL22) { | |||
| 672 | printf(" - top-level hostnqn without hostid [FAIL]\n"); | |||
| 673 | pass = false0; | |||
| 674 | } else { | |||
| 675 | printf(" - top-level hostnqn without hostid rejected [PASS]\n"); | |||
| 676 | } | |||
| 677 | rm_file(fx->dir, "top-no-hostid.conf"); | |||
| 678 | ||||
| 679 | /* A uuid:-form hostnqn is not derived into a hostid either. */ | |||
| 680 | write_file(fx->dropin_dir, "20-uuid-no-hostid.conf", | |||
| 681 | "[Host]\n" | |||
| 682 | "hostnqn = nqn.2014-08.org.nvmexpress:" | |||
| 683 | "uuid:8b6b8b6b-0000-4000-8000-00000000dead\n"); | |||
| 684 | if (libnvmf_config_read(ctx, fx->main_path, &config) != -EINVAL22) { | |||
| 685 | printf(" - uuid: hostnqn without hostid [FAIL]\n"); | |||
| 686 | pass = false0; | |||
| 687 | } else { | |||
| 688 | printf(" - uuid: hostnqn without hostid rejected too [PASS]\n"); | |||
| 689 | } | |||
| 690 | rm_file(fx->dropin_dir, "20-uuid-no-hostid.conf"); | |||
| 691 | ||||
| 692 | /* Regression: hostnqn and hostid together is still unaffected. */ | |||
| 693 | if (libnvmf_config_read(ctx, fx->main_path, &config)) { | |||
| 694 | printf(" - hostnqn+hostid persona still valid [FAIL]\n"); | |||
| 695 | pass = false0; | |||
| 696 | } else { | |||
| 697 | printf(" - hostnqn+hostid persona still valid [PASS]\n"); | |||
| 698 | libnvmf_config_free(config); | |||
| 699 | } | |||
| 700 | ||||
| 701 | return pass; | |||
| 702 | } | |||
| 703 | ||||
| 704 | static bool_Bool test_validate(struct libnvme_global_ctx *ctx, | |||
| 705 | const struct fixture *fx) | |||
| 706 | { | |||
| 707 | struct libnvmf_config *config; | |||
| 708 | char missing[320]; | |||
| 709 | bool_Bool pass = true1; | |||
| 710 | ||||
| 711 | printf("test_validate:\n"); | |||
| 712 | ||||
| 713 | if (libnvmf_config_validate(ctx, fx->main_path)) { | |||
| 714 | printf(" - valid tree [FAIL]\n"); | |||
| 715 | pass = false0; | |||
| 716 | } else { | |||
| 717 | printf(" - valid tree validates clean [PASS]\n"); | |||
| 718 | } | |||
| 719 | ||||
| 720 | /* An absent configuration is a valid (empty) configuration. */ | |||
| 721 | snprintf(missing, sizeof(missing), "%s/no-such.conf", fx->dir); | |||
| 722 | if (libnvmf_config_validate(ctx, missing)) { | |||
| 723 | printf(" - absent config [FAIL]\n"); | |||
| 724 | pass = false0; | |||
| 725 | } else { | |||
| 726 | printf(" - absent config is valid and empty [PASS]\n"); | |||
| 727 | } | |||
| 728 | ||||
| 729 | /* A Tier 1 problem in any file fails the tree as a unit. */ | |||
| 730 | write_file(fx->dropin_dir, "99-bad.conf", "not a key value line\n"); | |||
| 731 | if (libnvmf_config_validate(ctx, fx->main_path) >= 0) { | |||
| 732 | printf(" - Tier 1 error detected [FAIL]\n"); | |||
| 733 | pass = false0; | |||
| 734 | } else { | |||
| 735 | printf(" - Tier 1 error fails the tree as a unit [PASS]\n"); | |||
| 736 | } | |||
| 737 | if (!libnvmf_config_read(ctx, fx->main_path, &config)) { | |||
| 738 | printf(" - read refuses a broken tree [FAIL]\n"); | |||
| 739 | pass = false0; | |||
| 740 | libnvmf_config_free(config); | |||
| 741 | } else { | |||
| 742 | printf(" - read refuses a broken tree [PASS]\n"); | |||
| 743 | } | |||
| 744 | rm_file(fx->dropin_dir, "99-bad.conf"); | |||
| 745 | ||||
| 746 | return pass; | |||
| 747 | } | |||
| 748 | ||||
| 749 | struct arg_list { | |||
| 750 | char args[16][96]; | |||
| 751 | size_t n; | |||
| 752 | }; | |||
| 753 | ||||
| 754 | static void collect_arg(const char *arg, void *user_data) | |||
| 755 | { | |||
| 756 | struct arg_list *list = user_data; | |||
| 757 | ||||
| 758 | shr_assert(list->n < 16)((void)((list->n < 16) || (shr_assert_fail("../libnvme/tests/config-api.c" , 758, "list->n < 16"), 0))); | |||
| 759 | snprintf(list->args[list->n++], sizeof(list->args[0]), "%s", arg); | |||
| 760 | } | |||
| 761 | ||||
| 762 | static bool_Bool args_match(const struct arg_list *list, | |||
| 763 | const char * const *expect, size_t n) | |||
| 764 | { | |||
| 765 | size_t i; | |||
| 766 | ||||
| 767 | if (list->n != n) | |||
| 768 | return false0; | |||
| 769 | for (i = 0; i < n; i++) { | |||
| 770 | if (strcmp(list->args[i], expect[i])) | |||
| 771 | return false0; | |||
| 772 | } | |||
| 773 | ||||
| 774 | return true1; | |||
| 775 | } | |||
| 776 | ||||
| 777 | /* | |||
| 778 | * A connection's addressing is raw strings, not a TID (see config.h) -- an | |||
| 779 | * emitter caller resolves (traddr here is already numeric) and builds the | |||
| 780 | * TID itself, exactly like this. | |||
| 781 | */ | |||
| 782 | static struct libnvmf_tid *build_tid(const struct libnvmf_config_conn *conn) | |||
| 783 | { | |||
| 784 | struct libnvmf_tid *tid; | |||
| 785 | ||||
| 786 | libnvmf_tid_from_fields( | |||
| 787 | libnvmf_config_conn_get_transport(conn), | |||
| 788 | libnvmf_config_conn_get_traddr(conn), | |||
| 789 | libnvmf_config_conn_get_trsvcid(conn), | |||
| 790 | libnvmf_config_conn_get_subsysnqn(conn), | |||
| 791 | libnvmf_config_conn_get_host_traddr(conn), | |||
| 792 | libnvmf_config_conn_get_host_iface(conn), | |||
| 793 | libnvmf_config_conn_get_hostnqn(conn), | |||
| 794 | libnvmf_config_conn_get_hostid(conn), &tid); | |||
| 795 | return tid; | |||
| 796 | } | |||
| 797 | ||||
| 798 | static bool_Bool test_emit(struct libnvme_global_ctx *ctx, const struct fixture *fx) | |||
| 799 | { | |||
| 800 | static const char * const mv_expect[] = { | |||
| 801 | "--transport=tcp", | |||
| 802 | "--traddr=10.0.0.9", | |||
| 803 | "--trsvcid=4420", | |||
| 804 | "--nqn=nqn.2014-08.org.nvmexpress:main-vol", | |||
| 805 | "--ctrl-loss-tmo=600", | |||
| 806 | "--keep-alive-tmo=5", | |||
| 807 | "--tls", | |||
| 808 | }; | |||
| 809 | static const char * const pv_expect[] = { | |||
| 810 | "--transport=tcp", | |||
| 811 | "--traddr=10.0.0.7", | |||
| 812 | "--trsvcid=4420", | |||
| 813 | "--nqn=nqn.2014-08.org.nvmexpress:prod-vol", | |||
| 814 | "--hostnqn=nqn.2014-08.org.nvmexpress:prod-host", | |||
| 815 | "--hostid=46ba5037-7ce5-41fa-9452-48477bf00080", | |||
| 816 | "--ctrl-loss-tmo=1800", | |||
| 817 | "--keep-alive-tmo=5", | |||
| 818 | }; | |||
| 819 | const struct libnvmf_config_conn *mv, *pv; | |||
| 820 | struct conn_list conns = { 0 }; | |||
| 821 | struct arg_list args = { 0 }; | |||
| 822 | struct libnvmf_config *config; | |||
| 823 | struct libnvmf_tid *mv_tid, *pv_tid; | |||
| 824 | bool_Bool pass = true1; | |||
| 825 | ||||
| 826 | printf("test_emit:\n"); | |||
| 827 | ||||
| 828 | shr_assert(!libnvmf_config_read(ctx, fx->main_path, &config))((void)((!libnvmf_config_read(ctx, fx->main_path, &config )) || (shr_assert_fail("../libnvme/tests/config-api.c", 828, "!libnvmf_config_read(ctx, fx->main_path, &config)" ), 0))); | |||
| 829 | libnvmf_config_conn_for_each(config, collect, &conns); | |||
| 830 | shr_assert(conns.n == 3)((void)((conns.n == 3) || (shr_assert_fail("../libnvme/tests/config-api.c" , 830, "conns.n == 3"), 0))); | |||
| 831 | mv = conns.conn[1]; | |||
| 832 | pv = conns.conn[2]; | |||
| 833 | ||||
| 834 | mv_tid = build_tid(mv); | |||
| 835 | pv_tid = build_tid(pv); | |||
| 836 | shr_assert(mv_tid && pv_tid)((void)((mv_tid && pv_tid) || (shr_assert_fail("../libnvme/tests/config-api.c" , 836, "mv_tid && pv_tid"), 0))); | |||
| 837 | ||||
| 838 | /* TID fields in fixed order, then params; true bool = bare flag. */ | |||
| 839 | if (libnvmf_connect_args_emit(mv_tid, | |||
| 840 | libnvmf_config_conn_get_params(mv), | |||
| 841 | collect_arg, &args) || | |||
| 842 | !args_match(&args, mv_expect, ARRAY_SIZE(mv_expect)(sizeof(mv_expect) / sizeof((mv_expect)[0]) + 0))) { | |||
| 843 | printf(" - main subsystem args [FAIL]\n"); | |||
| 844 | pass = false0; | |||
| 845 | } else { | |||
| 846 | printf(" - TID first, params after; bool flags bare [PASS]\n"); | |||
| 847 | } | |||
| 848 | ||||
| 849 | /* Persona identity emitted; per-path override wins; reset skipped. */ | |||
| 850 | memset(&args, 0, sizeof(args)); | |||
| 851 | if (libnvmf_connect_args_emit(pv_tid, | |||
| 852 | libnvmf_config_conn_get_params(pv), | |||
| 853 | collect_arg, &args) || | |||
| 854 | !args_match(&args, pv_expect, ARRAY_SIZE(pv_expect)(sizeof(pv_expect) / sizeof((pv_expect)[0]) + 0))) { | |||
| 855 | printf(" - drop-in subsystem args [FAIL]\n"); | |||
| 856 | pass = false0; | |||
| 857 | } else { | |||
| 858 | printf(" - persona identity kept, reset skipped [PASS]\n"); | |||
| 859 | } | |||
| 860 | ||||
| 861 | /* Each half is optional. */ | |||
| 862 | memset(&args, 0, sizeof(args)); | |||
| 863 | if (libnvmf_connect_args_emit(NULL((void*)0), | |||
| 864 | libnvmf_config_conn_get_params(pv), | |||
| 865 | collect_arg, &args) || | |||
| 866 | !args_match(&args, &pv_expect[6], 2)) { | |||
| 867 | printf(" - params-only emission [FAIL]\n"); | |||
| 868 | pass = false0; | |||
| 869 | } else { | |||
| 870 | printf(" - params-only emission (NULL TID) [PASS]\n"); | |||
| 871 | } | |||
| 872 | ||||
| 873 | memset(&args, 0, sizeof(args)); | |||
| 874 | if (libnvmf_connect_args_emit(mv_tid, NULL((void*)0), collect_arg, &args) || | |||
| 875 | !args_match(&args, mv_expect, 4)) { | |||
| 876 | printf(" - TID-only emission [FAIL]\n"); | |||
| 877 | pass = false0; | |||
| 878 | } else { | |||
| 879 | printf(" - TID-only emission (NULL params) [PASS]\n"); | |||
| 880 | } | |||
| 881 | ||||
| 882 | /* A discovery controller setting is not emitted. */ | |||
| 883 | { | |||
| 884 | struct libnvmf_params *dc = libnvmf_params_new(); | |||
| 885 | ||||
| 886 | memset(&args, 0, sizeof(args)); | |||
| 887 | shr_assert(dc &&((void)((dc && !libnvmf_params_set(dc, "persistent", "force" ) && !libnvmf_params_set(dc, "keep-alive-tmo", "5")) || (shr_assert_fail("../libnvme/tests/config-api.c", 889, "dc && !libnvmf_params_set(dc, \"persistent\", \"force\") && !libnvmf_params_set(dc, \"keep-alive-tmo\", \"5\")" ), 0))) | |||
| 888 | !libnvmf_params_set(dc, "persistent", "force") &&((void)((dc && !libnvmf_params_set(dc, "persistent", "force" ) && !libnvmf_params_set(dc, "keep-alive-tmo", "5")) || (shr_assert_fail("../libnvme/tests/config-api.c", 889, "dc && !libnvmf_params_set(dc, \"persistent\", \"force\") && !libnvmf_params_set(dc, \"keep-alive-tmo\", \"5\")" ), 0))) | |||
| 889 | !libnvmf_params_set(dc, "keep-alive-tmo", "5"))((void)((dc && !libnvmf_params_set(dc, "persistent", "force" ) && !libnvmf_params_set(dc, "keep-alive-tmo", "5")) || (shr_assert_fail("../libnvme/tests/config-api.c", 889, "dc && !libnvmf_params_set(dc, \"persistent\", \"force\") && !libnvmf_params_set(dc, \"keep-alive-tmo\", \"5\")" ), 0))); | |||
| 890 | if (libnvmf_connect_args_emit(NULL((void*)0), dc, collect_arg, &args) || | |||
| 891 | !args_match(&args, &mv_expect[5], 1)) { | |||
| 892 | printf(" - persistent not emitted [FAIL]\n"); | |||
| 893 | pass = false0; | |||
| 894 | } else { | |||
| 895 | printf(" - persistent not emitted [PASS]\n"); | |||
| 896 | } | |||
| 897 | libnvmf_params_free(dc); | |||
| 898 | } | |||
| 899 | ||||
| 900 | if (libnvmf_connect_args_emit(NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)) != -EINVAL22) { | |||
| 901 | printf(" - NULL callback [FAIL]\n"); | |||
| 902 | pass = false0; | |||
| 903 | } else { | |||
| 904 | printf(" - NULL callback rejected [PASS]\n"); | |||
| 905 | } | |||
| 906 | ||||
| 907 | libnvmf_tid_free(mv_tid); | |||
| 908 | libnvmf_tid_free(pv_tid); | |||
| 909 | libnvmf_config_free(config); | |||
| 910 | ||||
| 911 | return pass; | |||
| 912 | } | |||
| 913 | ||||
| 914 | /* Built ad hoc, not from the fixture files, to cover every key class in | |||
| 915 | * one pass: ints, bools, an explicit reset, and the five crypto keys | |||
| 916 | * that share one setter. | |||
| 917 | */ | |||
| 918 | static bool_Bool test_apply_params(struct libnvme_global_ctx *ctx) | |||
| 919 | { | |||
| 920 | struct libnvmf_context *fctx; | |||
| 921 | struct libnvmf_params *params; | |||
| 922 | bool_Bool pass = true1; | |||
| 923 | ||||
| 924 | printf("test_apply_params:\n"); | |||
| 925 | ||||
| 926 | params = libnvmf_params_new(); | |||
| 927 | shr_assert(params)((void)((params) || (shr_assert_fail("../libnvme/tests/config-api.c" , 927, "params"), 0))); | |||
| 928 | /* Hex, matching check_int()'s own base-0 parsing (config-ini.c). */ | |||
| 929 | shr_assert(!libnvmf_params_set(params, "nr-io-queues", "0x10"))((void)((!libnvmf_params_set(params, "nr-io-queues", "0x10")) || (shr_assert_fail("../libnvme/tests/config-api.c", 929, "!libnvmf_params_set(params, \"nr-io-queues\", \"0x10\")" ), 0))); | |||
| 930 | shr_assert(!libnvmf_params_set(params, "keep-alive-tmo", "30"))((void)((!libnvmf_params_set(params, "keep-alive-tmo", "30")) || (shr_assert_fail("../libnvme/tests/config-api.c", 930, "!libnvmf_params_set(params, \"keep-alive-tmo\", \"30\")" ), 0))); | |||
| 931 | shr_assert(!libnvmf_params_set(params, "tls", "true"))((void)((!libnvmf_params_set(params, "tls", "true")) || (shr_assert_fail ("../libnvme/tests/config-api.c", 931, "!libnvmf_params_set(params, \"tls\", \"true\")" ), 0))); | |||
| 932 | shr_assert(!libnvmf_params_set(params, "hdr-digest", "false"))((void)((!libnvmf_params_set(params, "hdr-digest", "false")) || (shr_assert_fail("../libnvme/tests/config-api.c", 932, "!libnvmf_params_set(params, \"hdr-digest\", \"false\")" ), 0))); | |||
| 933 | shr_assert(!libnvmf_params_set(params, "persistent", "force"))((void)((!libnvmf_params_set(params, "persistent", "force")) || (shr_assert_fail("../libnvme/tests/config-api.c", 933, "!libnvmf_params_set(params, \"persistent\", \"force\")" ), 0))); | |||
| 934 | /* Explicit resets: must be skipped, not applied as "0". */ | |||
| 935 | shr_assert(!libnvmf_params_set(params, "tos", ""))((void)((!libnvmf_params_set(params, "tos", "")) || (shr_assert_fail ("../libnvme/tests/config-api.c", 935, "!libnvmf_params_set(params, \"tos\", \"\")" ), 0))); | |||
| 936 | shr_assert(!libnvmf_params_set(params, "ctrl-loss-tmo", ""))((void)((!libnvmf_params_set(params, "ctrl-loss-tmo", "")) || (shr_assert_fail("../libnvme/tests/config-api.c", 936, "!libnvmf_params_set(params, \"ctrl-loss-tmo\", \"\")" ), 0))); | |||
| 937 | /* The five crypto keys: one shared setter, must not clobber. */ | |||
| 938 | shr_assert(!libnvmf_params_set(params, "keyring", "my-keyring"))((void)((!libnvmf_params_set(params, "keyring", "my-keyring") ) || (shr_assert_fail("../libnvme/tests/config-api.c", 938, "!libnvmf_params_set(params, \"keyring\", \"my-keyring\")" ), 0))); | |||
| 939 | shr_assert(!libnvmf_params_set(params, "tls-key", "deadbeef"))((void)((!libnvmf_params_set(params, "tls-key", "deadbeef")) || (shr_assert_fail("../libnvme/tests/config-api.c", 939, "!libnvmf_params_set(params, \"tls-key\", \"deadbeef\")" ), 0))); | |||
| 940 | shr_assert(!libnvmf_params_set(params, "tls-key-identity",((void)((!libnvmf_params_set(params, "tls-key-identity", "NVMe1R02 my-id" )) || (shr_assert_fail("../libnvme/tests/config-api.c", 941, "!libnvmf_params_set(params, \"tls-key-identity\", \"NVMe1R02 my-id\")" ), 0))) | |||
| 941 | "NVMe1R02 my-id"))((void)((!libnvmf_params_set(params, "tls-key-identity", "NVMe1R02 my-id" )) || (shr_assert_fail("../libnvme/tests/config-api.c", 941, "!libnvmf_params_set(params, \"tls-key-identity\", \"NVMe1R02 my-id\")" ), 0))); | |||
| 942 | shr_assert(!libnvmf_params_set(params, "kxchap-secret", "DHHC-1:00:host:"))((void)((!libnvmf_params_set(params, "kxchap-secret", "DHHC-1:00:host:" )) || (shr_assert_fail("../libnvme/tests/config-api.c", 942, "!libnvmf_params_set(params, \"kxchap-secret\", \"DHHC-1:00:host:\")" ), 0))); | |||
| 943 | shr_assert(!libnvmf_params_set(params, "kxchap-ctrl-secret",((void)((!libnvmf_params_set(params, "kxchap-ctrl-secret", "DHHC-1:00:ctrl:" )) || (shr_assert_fail("../libnvme/tests/config-api.c", 944, "!libnvmf_params_set(params, \"kxchap-ctrl-secret\", \"DHHC-1:00:ctrl:\")" ), 0))) | |||
| 944 | "DHHC-1:00:ctrl:"))((void)((!libnvmf_params_set(params, "kxchap-ctrl-secret", "DHHC-1:00:ctrl:" )) || (shr_assert_fail("../libnvme/tests/config-api.c", 944, "!libnvmf_params_set(params, \"kxchap-ctrl-secret\", \"DHHC-1:00:ctrl:\")" ), 0))); | |||
| 945 | ||||
| 946 | shr_assert(!libnvmf_context_create(ctx, NULL, NULL, NULL, NULL, &fctx))((void)((!libnvmf_context_create(ctx, ((void*)0), ((void*)0), ((void*)0), ((void*)0), &fctx)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 946, "!libnvmf_context_create(ctx, NULL, NULL, NULL, NULL, &fctx)" ), 0))); | |||
| 947 | ||||
| 948 | if (libnvmf_context_apply_params(fctx, params)) { | |||
| 949 | printf(" - apply failed [FAIL]\n"); | |||
| 950 | pass = false0; | |||
| 951 | goto out; | |||
| 952 | } | |||
| 953 | ||||
| 954 | if (libnvmf_context_get_nr_io_queues(fctx) != 0x10 || | |||
| 955 | libnvmf_context_get_keep_alive_tmo(fctx) != 30) { | |||
| 956 | printf(" - int fields (hex + decimal) [FAIL]\n"); | |||
| 957 | pass = false0; | |||
| 958 | } else { | |||
| 959 | printf(" - int fields applied (hex + decimal) [PASS]\n"); | |||
| 960 | } | |||
| 961 | ||||
| 962 | { | |||
| 963 | const char *p = libnvmf_context_get_persistent(fctx); | |||
| 964 | ||||
| 965 | if (!libnvmf_context_get_tls(fctx) || | |||
| 966 | libnvmf_context_get_hdr_digest(fctx) || | |||
| 967 | !shr_streq0(p, "force")) { | |||
| 968 | printf(" - bool fields [FAIL]\n"); | |||
| 969 | pass = false0; | |||
| 970 | } else { | |||
| 971 | printf(" - bool fields applied [PASS]\n"); | |||
| 972 | } | |||
| 973 | } | |||
| 974 | ||||
| 975 | /* A fresh context starts at tos=-1, ctrl-loss-tmo=600 (see | |||
| 976 | * libnvmf_default_config()); a reset must leave both untouched, | |||
| 977 | * not overwrite them with 0. | |||
| 978 | */ | |||
| 979 | if (libnvmf_context_get_tos(fctx) != -1 || | |||
| 980 | libnvmf_context_get_ctrl_loss_tmo(fctx) != NVMF_DEF_CTRL_LOSS_TMO600) { | |||
| 981 | printf(" - reset skipped, library default kept [FAIL]\n"); | |||
| 982 | pass = false0; | |||
| 983 | } else { | |||
| 984 | printf(" - reset skipped, library default kept [PASS]\n"); | |||
| 985 | } | |||
| 986 | ||||
| 987 | if (strcmp(libnvmf_context_get_keyring(fctx), "my-keyring") || | |||
| 988 | strcmp(libnvmf_context_get_tls_key(fctx), "deadbeef") || | |||
| 989 | strcmp(libnvmf_context_get_tls_key_identity(fctx), | |||
| 990 | "NVMe1R02 my-id") || | |||
| 991 | strcmp(libnvmf_context_get_hostkey(fctx), "DHHC-1:00:host:") || | |||
| 992 | strcmp(libnvmf_context_get_ctrlkey(fctx), "DHHC-1:00:ctrl:")) { | |||
| 993 | printf(" - crypto fields (shared setter, no clobber) [FAIL]\n"); | |||
| 994 | pass = false0; | |||
| 995 | } else { | |||
| 996 | printf(" - crypto fields (shared setter, no clobber) [PASS]\n"); | |||
| 997 | } | |||
| 998 | ||||
| 999 | out: | |||
| 1000 | if (libnvmf_context_apply_params(NULL((void*)0), params) != -EINVAL22 || | |||
| 1001 | libnvmf_context_apply_params(fctx, NULL((void*)0)) != -EINVAL22) { | |||
| 1002 | printf(" - NULL rejected [FAIL]\n"); | |||
| 1003 | pass = false0; | |||
| 1004 | } else { | |||
| 1005 | printf(" - NULL rejected [PASS]\n"); | |||
| 1006 | } | |||
| 1007 | ||||
| 1008 | libnvmf_context_free(fctx); | |||
| 1009 | libnvmf_params_free(params); | |||
| 1010 | return pass; | |||
| 1011 | } | |||
| 1012 | ||||
| 1013 | static bool_Bool has_arg(const struct arg_list *list, const char *arg) | |||
| 1014 | { | |||
| 1015 | size_t i; | |||
| 1016 | ||||
| 1017 | for (i = 0; i < list->n; i++) { | |||
| 1018 | if (!strcmp(list->args[i], arg)) | |||
| 1019 | return true1; | |||
| 1020 | } | |||
| 1021 | ||||
| 1022 | return false0; | |||
| 1023 | } | |||
| 1024 | ||||
| 1025 | /* | |||
| 1026 | * With tls-key-source other than "inline", tls-key is a name for nvme-keysd. | |||
| 1027 | * Neither connect path may use it as the key. tls-key-source itself is never | |||
| 1028 | * an "nvme connect" option. | |||
| 1029 | */ | |||
| 1030 | static bool_Bool test_tls_key_source(struct libnvme_global_ctx *ctx) | |||
| 1031 | { | |||
| 1032 | struct libnvmf_context *fctx; | |||
| 1033 | struct libnvmf_params *params; | |||
| 1034 | struct arg_list args = { 0 }; | |||
| 1035 | bool_Bool pass = true1; | |||
| 1036 | ||||
| 1037 | printf("test_tls_key_source:\n"); | |||
| 1038 | ||||
| 1039 | params = libnvmf_params_new(); | |||
| 1040 | shr_assert(params)((void)((params) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1040, "params"), 0))); | |||
| 1041 | ||||
| 1042 | shr_assert(!libnvmf_params_set(params, "tls", "true"))((void)((!libnvmf_params_set(params, "tls", "true")) || (shr_assert_fail ("../libnvme/tests/config-api.c", 1042, "!libnvmf_params_set(params, \"tls\", \"true\")" ), 0))); | |||
| 1043 | shr_assert(!libnvmf_params_set(params, "tls-key", "cred_vol1-psk"))((void)((!libnvmf_params_set(params, "tls-key", "cred_vol1-psk" )) || (shr_assert_fail("../libnvme/tests/config-api.c", 1043, "!libnvmf_params_set(params, \"tls-key\", \"cred_vol1-psk\")" ), 0))); | |||
| 1044 | shr_assert(!libnvmf_params_set(params, "tls-key-source",((void)((!libnvmf_params_set(params, "tls-key-source", "systemd-creds" )) || (shr_assert_fail("../libnvme/tests/config-api.c", 1045, "!libnvmf_params_set(params, \"tls-key-source\", \"systemd-creds\")" ), 0))) | |||
| 1045 | "systemd-creds"))((void)((!libnvmf_params_set(params, "tls-key-source", "systemd-creds" )) || (shr_assert_fail("../libnvme/tests/config-api.c", 1045, "!libnvmf_params_set(params, \"tls-key-source\", \"systemd-creds\")" ), 0))); | |||
| 1046 | ||||
| 1047 | shr_assert(!libnvmf_context_create(ctx, NULL, NULL, NULL, NULL, &fctx))((void)((!libnvmf_context_create(ctx, ((void*)0), ((void*)0), ((void*)0), ((void*)0), &fctx)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1047, "!libnvmf_context_create(ctx, NULL, NULL, NULL, NULL, &fctx)" ), 0))); | |||
| 1048 | shr_assert(!libnvmf_context_apply_params(fctx, params))((void)((!libnvmf_context_apply_params(fctx, params)) || (shr_assert_fail ("../libnvme/tests/config-api.c", 1048, "!libnvmf_context_apply_params(fctx, params)" ), 0))); | |||
| 1049 | if (libnvmf_context_get_tls_key(fctx) || | |||
| 1050 | !libnvmf_context_get_tls(fctx)) { | |||
| 1051 | printf(" - systemd-creds: apply drops tls-key [FAIL]\n"); | |||
| 1052 | pass = false0; | |||
| 1053 | } else { | |||
| 1054 | printf(" - systemd-creds: apply drops tls-key [PASS]\n"); | |||
| 1055 | } | |||
| 1056 | libnvmf_context_free(fctx); | |||
| 1057 | ||||
| 1058 | shr_assert(!libnvmf_connect_args_emit(NULL, params, collect_arg,((void)((!libnvmf_connect_args_emit(((void*)0), params, collect_arg , &args)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1059, "!libnvmf_connect_args_emit(NULL, params, collect_arg, &args)" ), 0))) | |||
| 1059 | &args))((void)((!libnvmf_connect_args_emit(((void*)0), params, collect_arg , &args)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1059, "!libnvmf_connect_args_emit(NULL, params, collect_arg, &args)" ), 0))); | |||
| 1060 | if (args.n != 1 || !has_arg(&args, "--tls")) { | |||
| 1061 | printf(" - systemd-creds: emit has --tls only [FAIL]\n"); | |||
| 1062 | pass = false0; | |||
| 1063 | } else { | |||
| 1064 | printf(" - systemd-creds: emit has --tls only [PASS]\n"); | |||
| 1065 | } | |||
| 1066 | ||||
| 1067 | shr_assert(!libnvmf_params_set(params, "tls-key-source", "inline"))((void)((!libnvmf_params_set(params, "tls-key-source", "inline" )) || (shr_assert_fail("../libnvme/tests/config-api.c", 1067, "!libnvmf_params_set(params, \"tls-key-source\", \"inline\")" ), 0))); | |||
| 1068 | ||||
| 1069 | shr_assert(!libnvmf_context_create(ctx, NULL, NULL, NULL, NULL, &fctx))((void)((!libnvmf_context_create(ctx, ((void*)0), ((void*)0), ((void*)0), ((void*)0), &fctx)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1069, "!libnvmf_context_create(ctx, NULL, NULL, NULL, NULL, &fctx)" ), 0))); | |||
| 1070 | shr_assert(!libnvmf_context_apply_params(fctx, params))((void)((!libnvmf_context_apply_params(fctx, params)) || (shr_assert_fail ("../libnvme/tests/config-api.c", 1070, "!libnvmf_context_apply_params(fctx, params)" ), 0))); | |||
| 1071 | if (!shr_streq0(libnvmf_context_get_tls_key(fctx), "cred_vol1-psk")) { | |||
| 1072 | printf(" - inline: apply keeps tls-key [FAIL]\n"); | |||
| 1073 | pass = false0; | |||
| 1074 | } else { | |||
| 1075 | printf(" - inline: apply keeps tls-key [PASS]\n"); | |||
| 1076 | } | |||
| 1077 | libnvmf_context_free(fctx); | |||
| 1078 | ||||
| 1079 | args.n = 0; | |||
| 1080 | shr_assert(!libnvmf_connect_args_emit(NULL, params, collect_arg,((void)((!libnvmf_connect_args_emit(((void*)0), params, collect_arg , &args)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1081, "!libnvmf_connect_args_emit(NULL, params, collect_arg, &args)" ), 0))) | |||
| 1081 | &args))((void)((!libnvmf_connect_args_emit(((void*)0), params, collect_arg , &args)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1081, "!libnvmf_connect_args_emit(NULL, params, collect_arg, &args)" ), 0))); | |||
| 1082 | if (args.n != 2 || !has_arg(&args, "--tls") || | |||
| 1083 | !has_arg(&args, "--tls-key=cred_vol1-psk")) { | |||
| 1084 | printf(" - inline: emit has --tls and --tls-key [FAIL]\n"); | |||
| 1085 | pass = false0; | |||
| 1086 | } else { | |||
| 1087 | printf(" - inline: emit has --tls and --tls-key [PASS]\n"); | |||
| 1088 | } | |||
| 1089 | ||||
| 1090 | libnvmf_params_free(params); | |||
| 1091 | ||||
| 1092 | return pass; | |||
| 1093 | } | |||
| 1094 | ||||
| 1095 | /* | |||
| 1096 | * persistent must distinguish "not configured" (UNSET, the library default | |||
| 1097 | * derived elsewhere, e.g. from the discovery log page) from an explicit | |||
| 1098 | * "no" -- a plain bool cannot represent that third state. | |||
| 1099 | */ | |||
| 1100 | static bool_Bool test_persistent_tristate(struct libnvme_global_ctx *ctx) | |||
| 1101 | { | |||
| 1102 | struct libnvmf_context *fctx; | |||
| 1103 | struct libnvmf_params *params; | |||
| 1104 | bool_Bool pass = true1; | |||
| 1105 | ||||
| 1106 | printf("test_persistent_tristate:\n"); | |||
| 1107 | ||||
| 1108 | shr_assert(!libnvmf_context_create(ctx, NULL, NULL, NULL, NULL, &fctx))((void)((!libnvmf_context_create(ctx, ((void*)0), ((void*)0), ((void*)0), ((void*)0), &fctx)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1108, "!libnvmf_context_create(ctx, NULL, NULL, NULL, NULL, &fctx)" ), 0))); | |||
| 1109 | ||||
| 1110 | if (libnvmf_context_get_persistent(fctx) != NULL((void*)0)) { | |||
| 1111 | printf(" - fresh context defaults to unset [FAIL]\n"); | |||
| 1112 | pass = false0; | |||
| 1113 | } else { | |||
| 1114 | printf(" - fresh context defaults to unset [PASS]\n"); | |||
| 1115 | } | |||
| 1116 | ||||
| 1117 | params = libnvmf_params_new(); | |||
| 1118 | shr_assert(params)((void)((params) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1118, "params"), 0))); | |||
| 1119 | shr_assert(!libnvmf_params_set(params, "persistent", "no"))((void)((!libnvmf_params_set(params, "persistent", "no")) || ( shr_assert_fail("../libnvme/tests/config-api.c", 1119, "!libnvmf_params_set(params, \"persistent\", \"no\")" ), 0))); | |||
| 1120 | shr_assert(!libnvmf_context_apply_params(fctx, params))((void)((!libnvmf_context_apply_params(fctx, params)) || (shr_assert_fail ("../libnvme/tests/config-api.c", 1120, "!libnvmf_context_apply_params(fctx, params)" ), 0))); | |||
| 1121 | ||||
| 1122 | { | |||
| 1123 | const char *p = libnvmf_context_get_persistent(fctx); | |||
| 1124 | ||||
| 1125 | if (!shr_streq0(p, "no")) { | |||
| 1126 | printf(" - explicit \"no\" != unset [FAIL]\n"); | |||
| 1127 | pass = false0; | |||
| 1128 | } else { | |||
| 1129 | printf(" - explicit \"no\" != unset [PASS]\n"); | |||
| 1130 | } | |||
| 1131 | } | |||
| 1132 | ||||
| 1133 | libnvmf_context_free(fctx); | |||
| 1134 | libnvmf_params_free(params); | |||
| 1135 | ||||
| 1136 | return pass; | |||
| 1137 | } | |||
| 1138 | ||||
| 1139 | /* | |||
| 1140 | * The public API leaves hostnqn/hostid resolution to the caller (see | |||
| 1141 | * libnvmf_config_conn_get_hostnqn()'s kdoc) -- this drives that fallback the | |||
| 1142 | * same way a caller (e.g. nvme-cli's build_conn_tid()) does: a connection's | |||
| 1143 | * own value wins, else a caller-supplied default. mv leaves its identity to | |||
| 1144 | * the system default (see test_read()); pv sets its own. Exercises the real | |||
| 1145 | * public-API precedence, not a copy of any one caller's logic. | |||
| 1146 | */ | |||
| 1147 | static bool_Bool test_hostnqn_precedence(struct libnvme_global_ctx *ctx, | |||
| 1148 | const struct fixture *fx) | |||
| 1149 | { | |||
| 1150 | static const char default_hostnqn[] = | |||
| 1151 | "nqn.2014-08.org.nvmexpress:uuid:00000000-0000-0000-0000-000000000000"; | |||
| 1152 | static const char default_hostid[] = | |||
| 1153 | "00000000-0000-0000-0000-000000000000"; | |||
| 1154 | const struct libnvmf_config_conn *mv, *pv; | |||
| 1155 | struct conn_list conns = { 0 }; | |||
| 1156 | struct libnvmf_config *config; | |||
| 1157 | struct libnvmf_tid *mv_tid, *pv_tid; | |||
| 1158 | const char *hostnqn, *hostid; | |||
| 1159 | bool_Bool pass = true1; | |||
| 1160 | ||||
| 1161 | printf("test_hostnqn_precedence:\n"); | |||
| 1162 | ||||
| 1163 | shr_assert(!libnvmf_config_read(ctx, fx->main_path, &config))((void)((!libnvmf_config_read(ctx, fx->main_path, &config )) || (shr_assert_fail("../libnvme/tests/config-api.c", 1163, "!libnvmf_config_read(ctx, fx->main_path, &config)"), 0))); | |||
| 1164 | libnvmf_config_conn_for_each(config, collect, &conns); | |||
| 1165 | shr_assert(conns.n == 3)((void)((conns.n == 3) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1165, "conns.n == 3"), 0))); | |||
| 1166 | mv = conns.conn[1]; | |||
| 1167 | pv = conns.conn[2]; | |||
| 1168 | ||||
| 1169 | hostnqn = libnvmf_config_conn_get_hostnqn(mv); | |||
| 1170 | shr_assert(!hostnqn)((void)((!hostnqn) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1170, "!hostnqn"), 0))); | |||
| 1171 | hostnqn = default_hostnqn; | |||
| 1172 | hostid = libnvmf_config_conn_get_hostid(mv); | |||
| 1173 | shr_assert(!hostid)((void)((!hostid) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1173, "!hostid"), 0))); | |||
| 1174 | hostid = default_hostid; | |||
| 1175 | shr_assert(!libnvmf_tid_from_fields(((void)((!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport (mv), libnvmf_config_conn_get_traddr(mv), libnvmf_config_conn_get_trsvcid (mv), libnvmf_config_conn_get_subsysnqn(mv), libnvmf_config_conn_get_host_traddr (mv), libnvmf_config_conn_get_host_iface(mv), hostnqn, hostid , &mv_tid)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1182, "!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport(mv), libnvmf_config_conn_get_traddr(mv), libnvmf_config_conn_get_trsvcid(mv), libnvmf_config_conn_get_subsysnqn(mv), libnvmf_config_conn_get_host_traddr(mv), libnvmf_config_conn_get_host_iface(mv), hostnqn, hostid, &mv_tid)" ), 0))) | |||
| 1176 | libnvmf_config_conn_get_transport(mv),((void)((!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport (mv), libnvmf_config_conn_get_traddr(mv), libnvmf_config_conn_get_trsvcid (mv), libnvmf_config_conn_get_subsysnqn(mv), libnvmf_config_conn_get_host_traddr (mv), libnvmf_config_conn_get_host_iface(mv), hostnqn, hostid , &mv_tid)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1182, "!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport(mv), libnvmf_config_conn_get_traddr(mv), libnvmf_config_conn_get_trsvcid(mv), libnvmf_config_conn_get_subsysnqn(mv), libnvmf_config_conn_get_host_traddr(mv), libnvmf_config_conn_get_host_iface(mv), hostnqn, hostid, &mv_tid)" ), 0))) | |||
| 1177 | libnvmf_config_conn_get_traddr(mv),((void)((!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport (mv), libnvmf_config_conn_get_traddr(mv), libnvmf_config_conn_get_trsvcid (mv), libnvmf_config_conn_get_subsysnqn(mv), libnvmf_config_conn_get_host_traddr (mv), libnvmf_config_conn_get_host_iface(mv), hostnqn, hostid , &mv_tid)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1182, "!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport(mv), libnvmf_config_conn_get_traddr(mv), libnvmf_config_conn_get_trsvcid(mv), libnvmf_config_conn_get_subsysnqn(mv), libnvmf_config_conn_get_host_traddr(mv), libnvmf_config_conn_get_host_iface(mv), hostnqn, hostid, &mv_tid)" ), 0))) | |||
| 1178 | libnvmf_config_conn_get_trsvcid(mv),((void)((!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport (mv), libnvmf_config_conn_get_traddr(mv), libnvmf_config_conn_get_trsvcid (mv), libnvmf_config_conn_get_subsysnqn(mv), libnvmf_config_conn_get_host_traddr (mv), libnvmf_config_conn_get_host_iface(mv), hostnqn, hostid , &mv_tid)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1182, "!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport(mv), libnvmf_config_conn_get_traddr(mv), libnvmf_config_conn_get_trsvcid(mv), libnvmf_config_conn_get_subsysnqn(mv), libnvmf_config_conn_get_host_traddr(mv), libnvmf_config_conn_get_host_iface(mv), hostnqn, hostid, &mv_tid)" ), 0))) | |||
| 1179 | libnvmf_config_conn_get_subsysnqn(mv),((void)((!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport (mv), libnvmf_config_conn_get_traddr(mv), libnvmf_config_conn_get_trsvcid (mv), libnvmf_config_conn_get_subsysnqn(mv), libnvmf_config_conn_get_host_traddr (mv), libnvmf_config_conn_get_host_iface(mv), hostnqn, hostid , &mv_tid)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1182, "!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport(mv), libnvmf_config_conn_get_traddr(mv), libnvmf_config_conn_get_trsvcid(mv), libnvmf_config_conn_get_subsysnqn(mv), libnvmf_config_conn_get_host_traddr(mv), libnvmf_config_conn_get_host_iface(mv), hostnqn, hostid, &mv_tid)" ), 0))) | |||
| 1180 | libnvmf_config_conn_get_host_traddr(mv),((void)((!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport (mv), libnvmf_config_conn_get_traddr(mv), libnvmf_config_conn_get_trsvcid (mv), libnvmf_config_conn_get_subsysnqn(mv), libnvmf_config_conn_get_host_traddr (mv), libnvmf_config_conn_get_host_iface(mv), hostnqn, hostid , &mv_tid)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1182, "!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport(mv), libnvmf_config_conn_get_traddr(mv), libnvmf_config_conn_get_trsvcid(mv), libnvmf_config_conn_get_subsysnqn(mv), libnvmf_config_conn_get_host_traddr(mv), libnvmf_config_conn_get_host_iface(mv), hostnqn, hostid, &mv_tid)" ), 0))) | |||
| 1181 | libnvmf_config_conn_get_host_iface(mv),((void)((!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport (mv), libnvmf_config_conn_get_traddr(mv), libnvmf_config_conn_get_trsvcid (mv), libnvmf_config_conn_get_subsysnqn(mv), libnvmf_config_conn_get_host_traddr (mv), libnvmf_config_conn_get_host_iface(mv), hostnqn, hostid , &mv_tid)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1182, "!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport(mv), libnvmf_config_conn_get_traddr(mv), libnvmf_config_conn_get_trsvcid(mv), libnvmf_config_conn_get_subsysnqn(mv), libnvmf_config_conn_get_host_traddr(mv), libnvmf_config_conn_get_host_iface(mv), hostnqn, hostid, &mv_tid)" ), 0))) | |||
| 1182 | hostnqn, hostid, &mv_tid))((void)((!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport (mv), libnvmf_config_conn_get_traddr(mv), libnvmf_config_conn_get_trsvcid (mv), libnvmf_config_conn_get_subsysnqn(mv), libnvmf_config_conn_get_host_traddr (mv), libnvmf_config_conn_get_host_iface(mv), hostnqn, hostid , &mv_tid)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1182, "!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport(mv), libnvmf_config_conn_get_traddr(mv), libnvmf_config_conn_get_trsvcid(mv), libnvmf_config_conn_get_subsysnqn(mv), libnvmf_config_conn_get_host_traddr(mv), libnvmf_config_conn_get_host_iface(mv), hostnqn, hostid, &mv_tid)" ), 0))); | |||
| 1183 | ||||
| 1184 | if (strcmp(libnvmf_tid_get_hostnqn(mv_tid), default_hostnqn) || | |||
| 1185 | strcmp(libnvmf_tid_get_hostid(mv_tid), default_hostid)) { | |||
| 1186 | printf(" - unset identity inherits caller default [FAIL]\n"); | |||
| 1187 | pass = false0; | |||
| 1188 | } else { | |||
| 1189 | printf(" - unset identity inherits caller default [PASS]\n"); | |||
| 1190 | } | |||
| 1191 | ||||
| 1192 | hostnqn = libnvmf_config_conn_get_hostnqn(pv); | |||
| 1193 | shr_assert(hostnqn)((void)((hostnqn) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1193, "hostnqn"), 0))); | |||
| 1194 | hostid = libnvmf_config_conn_get_hostid(pv); | |||
| 1195 | shr_assert(hostid)((void)((hostid) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1195, "hostid"), 0))); | |||
| 1196 | shr_assert(!libnvmf_tid_from_fields(((void)((!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport (pv), libnvmf_config_conn_get_traddr(pv), libnvmf_config_conn_get_trsvcid (pv), libnvmf_config_conn_get_subsysnqn(pv), libnvmf_config_conn_get_host_traddr (pv), libnvmf_config_conn_get_host_iface(pv), hostnqn, hostid , &pv_tid)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1203, "!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport(pv), libnvmf_config_conn_get_traddr(pv), libnvmf_config_conn_get_trsvcid(pv), libnvmf_config_conn_get_subsysnqn(pv), libnvmf_config_conn_get_host_traddr(pv), libnvmf_config_conn_get_host_iface(pv), hostnqn, hostid, &pv_tid)" ), 0))) | |||
| 1197 | libnvmf_config_conn_get_transport(pv),((void)((!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport (pv), libnvmf_config_conn_get_traddr(pv), libnvmf_config_conn_get_trsvcid (pv), libnvmf_config_conn_get_subsysnqn(pv), libnvmf_config_conn_get_host_traddr (pv), libnvmf_config_conn_get_host_iface(pv), hostnqn, hostid , &pv_tid)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1203, "!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport(pv), libnvmf_config_conn_get_traddr(pv), libnvmf_config_conn_get_trsvcid(pv), libnvmf_config_conn_get_subsysnqn(pv), libnvmf_config_conn_get_host_traddr(pv), libnvmf_config_conn_get_host_iface(pv), hostnqn, hostid, &pv_tid)" ), 0))) | |||
| 1198 | libnvmf_config_conn_get_traddr(pv),((void)((!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport (pv), libnvmf_config_conn_get_traddr(pv), libnvmf_config_conn_get_trsvcid (pv), libnvmf_config_conn_get_subsysnqn(pv), libnvmf_config_conn_get_host_traddr (pv), libnvmf_config_conn_get_host_iface(pv), hostnqn, hostid , &pv_tid)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1203, "!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport(pv), libnvmf_config_conn_get_traddr(pv), libnvmf_config_conn_get_trsvcid(pv), libnvmf_config_conn_get_subsysnqn(pv), libnvmf_config_conn_get_host_traddr(pv), libnvmf_config_conn_get_host_iface(pv), hostnqn, hostid, &pv_tid)" ), 0))) | |||
| 1199 | libnvmf_config_conn_get_trsvcid(pv),((void)((!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport (pv), libnvmf_config_conn_get_traddr(pv), libnvmf_config_conn_get_trsvcid (pv), libnvmf_config_conn_get_subsysnqn(pv), libnvmf_config_conn_get_host_traddr (pv), libnvmf_config_conn_get_host_iface(pv), hostnqn, hostid , &pv_tid)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1203, "!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport(pv), libnvmf_config_conn_get_traddr(pv), libnvmf_config_conn_get_trsvcid(pv), libnvmf_config_conn_get_subsysnqn(pv), libnvmf_config_conn_get_host_traddr(pv), libnvmf_config_conn_get_host_iface(pv), hostnqn, hostid, &pv_tid)" ), 0))) | |||
| 1200 | libnvmf_config_conn_get_subsysnqn(pv),((void)((!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport (pv), libnvmf_config_conn_get_traddr(pv), libnvmf_config_conn_get_trsvcid (pv), libnvmf_config_conn_get_subsysnqn(pv), libnvmf_config_conn_get_host_traddr (pv), libnvmf_config_conn_get_host_iface(pv), hostnqn, hostid , &pv_tid)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1203, "!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport(pv), libnvmf_config_conn_get_traddr(pv), libnvmf_config_conn_get_trsvcid(pv), libnvmf_config_conn_get_subsysnqn(pv), libnvmf_config_conn_get_host_traddr(pv), libnvmf_config_conn_get_host_iface(pv), hostnqn, hostid, &pv_tid)" ), 0))) | |||
| 1201 | libnvmf_config_conn_get_host_traddr(pv),((void)((!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport (pv), libnvmf_config_conn_get_traddr(pv), libnvmf_config_conn_get_trsvcid (pv), libnvmf_config_conn_get_subsysnqn(pv), libnvmf_config_conn_get_host_traddr (pv), libnvmf_config_conn_get_host_iface(pv), hostnqn, hostid , &pv_tid)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1203, "!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport(pv), libnvmf_config_conn_get_traddr(pv), libnvmf_config_conn_get_trsvcid(pv), libnvmf_config_conn_get_subsysnqn(pv), libnvmf_config_conn_get_host_traddr(pv), libnvmf_config_conn_get_host_iface(pv), hostnqn, hostid, &pv_tid)" ), 0))) | |||
| 1202 | libnvmf_config_conn_get_host_iface(pv),((void)((!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport (pv), libnvmf_config_conn_get_traddr(pv), libnvmf_config_conn_get_trsvcid (pv), libnvmf_config_conn_get_subsysnqn(pv), libnvmf_config_conn_get_host_traddr (pv), libnvmf_config_conn_get_host_iface(pv), hostnqn, hostid , &pv_tid)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1203, "!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport(pv), libnvmf_config_conn_get_traddr(pv), libnvmf_config_conn_get_trsvcid(pv), libnvmf_config_conn_get_subsysnqn(pv), libnvmf_config_conn_get_host_traddr(pv), libnvmf_config_conn_get_host_iface(pv), hostnqn, hostid, &pv_tid)" ), 0))) | |||
| 1203 | hostnqn, hostid, &pv_tid))((void)((!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport (pv), libnvmf_config_conn_get_traddr(pv), libnvmf_config_conn_get_trsvcid (pv), libnvmf_config_conn_get_subsysnqn(pv), libnvmf_config_conn_get_host_traddr (pv), libnvmf_config_conn_get_host_iface(pv), hostnqn, hostid , &pv_tid)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1203, "!libnvmf_tid_from_fields( libnvmf_config_conn_get_transport(pv), libnvmf_config_conn_get_traddr(pv), libnvmf_config_conn_get_trsvcid(pv), libnvmf_config_conn_get_subsysnqn(pv), libnvmf_config_conn_get_host_traddr(pv), libnvmf_config_conn_get_host_iface(pv), hostnqn, hostid, &pv_tid)" ), 0))); | |||
| 1204 | ||||
| 1205 | if (strcmp(libnvmf_tid_get_hostnqn(pv_tid), | |||
| 1206 | "nqn.2014-08.org.nvmexpress:prod-host") || | |||
| 1207 | strcmp(libnvmf_tid_get_hostid(pv_tid), | |||
| 1208 | "46ba5037-7ce5-41fa-9452-48477bf00080")) { | |||
| 1209 | printf(" - own identity overrides caller default [FAIL]\n"); | |||
| 1210 | pass = false0; | |||
| 1211 | } else { | |||
| 1212 | printf(" - own identity overrides caller default [PASS]\n"); | |||
| 1213 | } | |||
| 1214 | ||||
| 1215 | libnvmf_tid_free(mv_tid); | |||
| 1216 | libnvmf_tid_free(pv_tid); | |||
| 1217 | libnvmf_config_free(config); | |||
| 1218 | ||||
| 1219 | return pass; | |||
| 1220 | } | |||
| 1221 | ||||
| 1222 | static bool_Bool test_set_connection_from_tid(struct libnvme_global_ctx *ctx) | |||
| 1223 | { | |||
| 1224 | struct libnvmf_context *fctx; | |||
| 1225 | struct libnvmf_tid *tid; | |||
| 1226 | bool_Bool pass = true1; | |||
| 1227 | ||||
| 1228 | printf("test_set_connection_from_tid:\n"); | |||
| 1229 | ||||
| 1230 | shr_assert(!libnvmf_tid_from_fields("tcp", "10.0.0.9", "4420",((void)((!libnvmf_tid_from_fields("tcp", "10.0.0.9", "4420", "nqn.2014-08.org.nvmexpress:subsys" , "10.0.0.1", "eth0", "nqn.2014-08.org.nvmexpress:host", "2cd2c43b-a90a-45c1-a8cd-86b33ab273b5" , &tid)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1234, "!libnvmf_tid_from_fields(\"tcp\", \"10.0.0.9\", \"4420\", \"nqn.2014-08.org.nvmexpress:subsys\", \"10.0.0.1\", \"eth0\", \"nqn.2014-08.org.nvmexpress:host\", \"2cd2c43b-a90a-45c1-a8cd-86b33ab273b5\", &tid)" ), 0))) | |||
| 1231 | "nqn.2014-08.org.nvmexpress:subsys",((void)((!libnvmf_tid_from_fields("tcp", "10.0.0.9", "4420", "nqn.2014-08.org.nvmexpress:subsys" , "10.0.0.1", "eth0", "nqn.2014-08.org.nvmexpress:host", "2cd2c43b-a90a-45c1-a8cd-86b33ab273b5" , &tid)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1234, "!libnvmf_tid_from_fields(\"tcp\", \"10.0.0.9\", \"4420\", \"nqn.2014-08.org.nvmexpress:subsys\", \"10.0.0.1\", \"eth0\", \"nqn.2014-08.org.nvmexpress:host\", \"2cd2c43b-a90a-45c1-a8cd-86b33ab273b5\", &tid)" ), 0))) | |||
| 1232 | "10.0.0.1", "eth0",((void)((!libnvmf_tid_from_fields("tcp", "10.0.0.9", "4420", "nqn.2014-08.org.nvmexpress:subsys" , "10.0.0.1", "eth0", "nqn.2014-08.org.nvmexpress:host", "2cd2c43b-a90a-45c1-a8cd-86b33ab273b5" , &tid)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1234, "!libnvmf_tid_from_fields(\"tcp\", \"10.0.0.9\", \"4420\", \"nqn.2014-08.org.nvmexpress:subsys\", \"10.0.0.1\", \"eth0\", \"nqn.2014-08.org.nvmexpress:host\", \"2cd2c43b-a90a-45c1-a8cd-86b33ab273b5\", &tid)" ), 0))) | |||
| 1233 | "nqn.2014-08.org.nvmexpress:host",((void)((!libnvmf_tid_from_fields("tcp", "10.0.0.9", "4420", "nqn.2014-08.org.nvmexpress:subsys" , "10.0.0.1", "eth0", "nqn.2014-08.org.nvmexpress:host", "2cd2c43b-a90a-45c1-a8cd-86b33ab273b5" , &tid)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1234, "!libnvmf_tid_from_fields(\"tcp\", \"10.0.0.9\", \"4420\", \"nqn.2014-08.org.nvmexpress:subsys\", \"10.0.0.1\", \"eth0\", \"nqn.2014-08.org.nvmexpress:host\", \"2cd2c43b-a90a-45c1-a8cd-86b33ab273b5\", &tid)" ), 0))) | |||
| 1234 | "2cd2c43b-a90a-45c1-a8cd-86b33ab273b5", &tid))((void)((!libnvmf_tid_from_fields("tcp", "10.0.0.9", "4420", "nqn.2014-08.org.nvmexpress:subsys" , "10.0.0.1", "eth0", "nqn.2014-08.org.nvmexpress:host", "2cd2c43b-a90a-45c1-a8cd-86b33ab273b5" , &tid)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1234, "!libnvmf_tid_from_fields(\"tcp\", \"10.0.0.9\", \"4420\", \"nqn.2014-08.org.nvmexpress:subsys\", \"10.0.0.1\", \"eth0\", \"nqn.2014-08.org.nvmexpress:host\", \"2cd2c43b-a90a-45c1-a8cd-86b33ab273b5\", &tid)" ), 0))); | |||
| 1235 | ||||
| 1236 | shr_assert(!libnvmf_context_create(ctx, NULL, NULL, NULL, NULL, &fctx))((void)((!libnvmf_context_create(ctx, ((void*)0), ((void*)0), ((void*)0), ((void*)0), &fctx)) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1236, "!libnvmf_context_create(ctx, NULL, NULL, NULL, NULL, &fctx)" ), 0))); | |||
| 1237 | ||||
| 1238 | if (libnvmf_context_set_connection_from_tid(fctx, tid)) { | |||
| 1239 | printf(" - set failed [FAIL]\n"); | |||
| 1240 | pass = false0; | |||
| 1241 | goto out; | |||
| 1242 | } | |||
| 1243 | ||||
| 1244 | if (strcmp(libnvmf_context_get_transport(fctx), "tcp") || | |||
| 1245 | strcmp(libnvmf_context_get_traddr(fctx), "10.0.0.9") || | |||
| 1246 | strcmp(libnvmf_context_get_trsvcid(fctx), "4420") || | |||
| 1247 | strcmp(libnvmf_context_get_subsysnqn(fctx), | |||
| 1248 | "nqn.2014-08.org.nvmexpress:subsys") || | |||
| 1249 | strcmp(libnvmf_context_get_host_traddr(fctx), "10.0.0.1") || | |||
| 1250 | strcmp(libnvmf_context_get_host_iface(fctx), "eth0")) { | |||
| 1251 | printf(" - addressing fields [FAIL]\n"); | |||
| 1252 | pass = false0; | |||
| 1253 | } else { | |||
| 1254 | printf(" - addressing fields applied [PASS]\n"); | |||
| 1255 | } | |||
| 1256 | ||||
| 1257 | if (strcmp(libnvmf_context_get_hostnqn(fctx), | |||
| 1258 | "nqn.2014-08.org.nvmexpress:host") || | |||
| 1259 | strcmp(libnvmf_context_get_hostid(fctx), | |||
| 1260 | "2cd2c43b-a90a-45c1-a8cd-86b33ab273b5")) { | |||
| 1261 | printf(" - identity fields [FAIL]\n"); | |||
| 1262 | pass = false0; | |||
| 1263 | } else { | |||
| 1264 | printf(" - identity fields applied [PASS]\n"); | |||
| 1265 | } | |||
| 1266 | ||||
| 1267 | out: | |||
| 1268 | if (libnvmf_context_set_connection_from_tid(NULL((void*)0), tid) != -EINVAL22 || | |||
| 1269 | libnvmf_context_set_connection_from_tid(fctx, NULL((void*)0)) != -EINVAL22) { | |||
| 1270 | printf(" - NULL rejected [FAIL]\n"); | |||
| 1271 | pass = false0; | |||
| 1272 | } else { | |||
| 1273 | printf(" - NULL rejected [PASS]\n"); | |||
| 1274 | } | |||
| 1275 | ||||
| 1276 | libnvmf_context_free(fctx); | |||
| 1277 | libnvmf_tid_free(tid); | |||
| 1278 | ||||
| 1279 | return pass; | |||
| 1280 | } | |||
| 1281 | ||||
| 1282 | static bool_Bool test_edge_cases(struct libnvme_global_ctx *ctx, | |||
| 1283 | const struct fixture *fx) | |||
| 1284 | { | |||
| 1285 | const struct libnvmf_params *params; | |||
| 1286 | struct conn_list list = { 0 }; | |||
| 1287 | struct libnvmf_config *config; | |||
| 1288 | char missing[320]; | |||
| 1289 | bool_Bool pass = true1; | |||
| 1290 | ||||
| 1291 | printf("test_edge_cases:\n"); | |||
| 1292 | ||||
| 1293 | if (!libnvmf_config_read(NULL((void*)0), fx->main_path, &config) || | |||
| 1294 | libnvmf_config_validate(NULL((void*)0), fx->main_path) != -EINVAL22) { | |||
| 1295 | printf(" - NULL ctx [FAIL]\n"); | |||
| 1296 | pass = false0; | |||
| 1297 | } else { | |||
| 1298 | printf(" - NULL ctx rejected [PASS]\n"); | |||
| 1299 | } | |||
| 1300 | ||||
| 1301 | /* Reading an absent configuration yields an empty connection list. */ | |||
| 1302 | snprintf(missing, sizeof(missing), "%s/no-such.conf", fx->dir); | |||
| 1303 | if (libnvmf_config_read(ctx, missing, &config)) { | |||
| 1304 | printf(" - absent config read [FAIL]\n"); | |||
| 1305 | pass = false0; | |||
| 1306 | } else { | |||
| 1307 | libnvmf_config_conn_for_each(config, collect, &list); | |||
| 1308 | if (list.n) { | |||
| 1309 | printf(" - absent config not empty [FAIL]\n"); | |||
| 1310 | pass = false0; | |||
| 1311 | } else { | |||
| 1312 | printf(" - absent config reads as empty [PASS]\n"); | |||
| 1313 | } | |||
| 1314 | } | |||
| 1315 | libnvmf_config_free(config); | |||
| 1316 | ||||
| 1317 | /* Everything is NULL-tolerant on the way out. */ | |||
| 1318 | if (libnvmf_config_conn_is_dc(NULL((void*)0)) || | |||
| 1319 | libnvmf_config_conn_get_transport(NULL((void*)0)) || | |||
| 1320 | libnvmf_config_conn_get_traddr(NULL((void*)0)) || | |||
| 1321 | libnvmf_config_conn_get_trsvcid(NULL((void*)0)) || | |||
| 1322 | libnvmf_config_conn_get_subsysnqn(NULL((void*)0)) || | |||
| 1323 | libnvmf_config_conn_get_host_traddr(NULL((void*)0)) || | |||
| 1324 | libnvmf_config_conn_get_host_iface(NULL((void*)0)) || | |||
| 1325 | libnvmf_config_conn_get_hostnqn(NULL((void*)0)) || | |||
| 1326 | libnvmf_config_conn_get_hostid(NULL((void*)0)) || | |||
| 1327 | libnvmf_config_conn_get_params(NULL((void*)0)) || | |||
| 1328 | libnvmf_config_conn_get_hostsymname(NULL((void*)0)) || | |||
| 1329 | libnvmf_config_conn_get_source(NULL((void*)0)) || | |||
| 1330 | libnvmf_config_resolve_discovered(NULL((void*)0), NULL((void*)0), true1) || | |||
| 1331 | libnvmf_config_get_hostnqn(NULL((void*)0)) || | |||
| 1332 | libnvmf_config_get_hostid(NULL((void*)0)) || | |||
| 1333 | libnvmf_config_get_hostsymname(NULL((void*)0)) || | |||
| 1334 | libnvmf_params_get(NULL((void*)0), "tos")) { | |||
| 1335 | printf(" - NULL tolerance [FAIL]\n"); | |||
| 1336 | pass = false0; | |||
| 1337 | } else { | |||
| 1338 | printf(" - NULL-tolerant getters [PASS]\n"); | |||
| 1339 | } | |||
| 1340 | if (libnvmf_config_get_discovered_params(NULL((void*)0), NULL((void*)0), true1, "nqn", | |||
| 1341 | ¶ms) != -EINVAL22) { | |||
| 1342 | printf(" - discovered params of a NULL config [FAIL]\n"); | |||
| 1343 | pass = false0; | |||
| 1344 | } else { | |||
| 1345 | printf(" - discovered params of a NULL config: -EINVAL [PASS]\n"); | |||
| 1346 | } | |||
| 1347 | libnvmf_config_conn_for_each(NULL((void*)0), collect, NULL((void*)0)); | |||
| 1348 | libnvmf_params_for_each(NULL((void*)0), NULL((void*)0), NULL((void*)0)); | |||
| 1349 | libnvmf_config_free(NULL((void*)0)); | |||
| 1350 | libnvmf_context_set_config(NULL((void*)0), NULL((void*)0), NULL((void*)0)); | |||
| 1351 | printf(" - NULL iteration and free are no-ops [PASS]\n"); | |||
| 1352 | ||||
| 1353 | return pass; | |||
| 1354 | } | |||
| 1355 | ||||
| 1356 | int main(void) | |||
| 1357 | { | |||
| 1358 | struct libnvme_global_ctx *ctx; | |||
| 1359 | struct fixture fx; | |||
| 1360 | bool_Bool pass = true1; | |||
| 1361 | ||||
| 1362 | ctx = libnvme_create_global_ctx(); | |||
| 1363 | shr_assert(ctx)((void)((ctx) || (shr_assert_fail("../libnvme/tests/config-api.c" , 1363, "ctx"), 0))); | |||
| 1364 | fixture_create(&fx); | |||
| 1365 | ||||
| 1366 | pass &= test_read(ctx, &fx); | |||
| 1367 | pass &= test_resolve_discovered(ctx, &fx); | |||
| 1368 | pass &= test_get_discovered_params(ctx, &fx); | |||
| 1369 | pass &= test_duplicate_nqn(ctx, &fx); | |||
| 1370 | pass &= test_wellknown_ctrl_secret(ctx, &fx); | |||
| 1371 | pass &= test_top_level_host(ctx, &fx); | |||
| 1372 | pass &= test_persona_validation(ctx, &fx); | |||
| 1373 | pass &= test_validate(ctx, &fx); | |||
| 1374 | pass &= test_emit(ctx, &fx); | |||
| 1375 | pass &= test_hostnqn_precedence(ctx, &fx); | |||
| 1376 | pass &= test_apply_params(ctx); | |||
| 1377 | pass &= test_persistent_tristate(ctx); | |||
| 1378 | pass &= test_tls_key_source(ctx); | |||
| 1379 | pass &= test_set_connection_from_tid(ctx); | |||
| 1380 | pass &= test_edge_cases(ctx, &fx); | |||
| 1381 | ||||
| 1382 | fixture_destroy(&fx); | |||
| 1383 | libnvme_free_global_ctx(ctx); | |||
| 1384 | ||||
| 1385 | fflush(stdoutstdout); | |||
| 1386 | exit(pass ? EXIT_SUCCESS0 : EXIT_FAILURE1); | |||
| 1387 | } |