1488570ebSJim Harris /* SPDX-License-Identifier: BSD-3-Clause 2a6dbe372Spaul luse * Copyright (C) 2016 Intel Corporation. 3af935f76SBen Walker * All rights reserved. 497385af1SAlexey Marchuk * Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 5af935f76SBen Walker */ 6af935f76SBen Walker 7af935f76SBen Walker #include "spdk/stdinc.h" 8af935f76SBen Walker 9ae431e31SKonrad Sztyber #include "spdk_internal/cunit.h" 10af935f76SBen Walker 11af935f76SBen Walker #include "unit/lib/json_mock.c" 12af935f76SBen Walker #include "init/subsystem.c" 13af935f76SBen Walker #include "common/lib/test_env.c" 14af935f76SBen Walker 15af935f76SBen Walker static struct spdk_subsystem g_ut_subsystems[8]; 16af935f76SBen Walker static struct spdk_subsystem_depend g_ut_subsystem_deps[8]; 17af935f76SBen Walker static int global_rc; 18af935f76SBen Walker 19af935f76SBen Walker static void 20af935f76SBen Walker ut_event_fn(int rc, void *arg1) 21af935f76SBen Walker { 22af935f76SBen Walker global_rc = rc; 23af935f76SBen Walker } 24af935f76SBen Walker 25af935f76SBen Walker static void 26af935f76SBen Walker set_up_subsystem(struct spdk_subsystem *subsystem, const char *name) 27af935f76SBen Walker { 28af935f76SBen Walker subsystem->init = NULL; 29af935f76SBen Walker subsystem->fini = NULL; 30af935f76SBen Walker subsystem->name = name; 31af935f76SBen Walker } 32af935f76SBen Walker 33af935f76SBen Walker static void 34af935f76SBen Walker set_up_depends(struct spdk_subsystem_depend *depend, const char *subsystem_name, 35c9c7c281SJosh Soref const char *depends_on_name) 36af935f76SBen Walker { 37af935f76SBen Walker depend->name = subsystem_name; 38c9c7c281SJosh Soref depend->depends_on = depends_on_name; 39af935f76SBen Walker } 40af935f76SBen Walker 41af935f76SBen Walker static void 42af935f76SBen Walker subsystem_clear(void) 43af935f76SBen Walker { 44af935f76SBen Walker struct spdk_subsystem *subsystem, *subsystem_tmp; 45af935f76SBen Walker struct spdk_subsystem_depend *subsystem_dep, *subsystem_dep_tmp; 46af935f76SBen Walker 47af935f76SBen Walker TAILQ_FOREACH_SAFE(subsystem, &g_subsystems, tailq, subsystem_tmp) { 48af935f76SBen Walker TAILQ_REMOVE(&g_subsystems, subsystem, tailq); 49af935f76SBen Walker } 50af935f76SBen Walker 51af935f76SBen Walker TAILQ_FOREACH_SAFE(subsystem_dep, &g_subsystems_deps, tailq, subsystem_dep_tmp) { 52af935f76SBen Walker TAILQ_REMOVE(&g_subsystems_deps, subsystem_dep, tailq); 53af935f76SBen Walker } 54af935f76SBen Walker } 55af935f76SBen Walker 56af935f76SBen Walker static void 57af935f76SBen Walker subsystem_sort_test_depends_on_single(void) 58af935f76SBen Walker { 59af935f76SBen Walker struct spdk_subsystem *subsystem; 60*d8f52da1SMichal Berger short int i; 61af935f76SBen Walker char subsystem_name[16]; 62af935f76SBen Walker 63af935f76SBen Walker global_rc = -1; 64af935f76SBen Walker spdk_subsystem_init(ut_event_fn, NULL); 65af935f76SBen Walker CU_ASSERT(global_rc == 0); 66af935f76SBen Walker 67af935f76SBen Walker i = 4; 68af935f76SBen Walker TAILQ_FOREACH(subsystem, &g_subsystems, tailq) { 69af935f76SBen Walker snprintf(subsystem_name, sizeof(subsystem_name), "subsystem%d", i); 70af935f76SBen Walker SPDK_CU_ASSERT_FATAL(i > 0); 71af935f76SBen Walker i--; 72af935f76SBen Walker CU_ASSERT(strcmp(subsystem_name, subsystem->name) == 0); 73af935f76SBen Walker } 74af935f76SBen Walker } 75af935f76SBen Walker 76af935f76SBen Walker static void 77af935f76SBen Walker subsystem_sort_test_depends_on_multiple(void) 78af935f76SBen Walker { 79af935f76SBen Walker int i; 80af935f76SBen Walker struct spdk_subsystem *subsystem; 81af935f76SBen Walker 82af935f76SBen Walker subsystem_clear(); 83af935f76SBen Walker set_up_subsystem(&g_ut_subsystems[0], "iscsi"); 84af935f76SBen Walker set_up_subsystem(&g_ut_subsystems[1], "nvmf"); 85af935f76SBen Walker set_up_subsystem(&g_ut_subsystems[2], "sock"); 86af935f76SBen Walker set_up_subsystem(&g_ut_subsystems[3], "bdev"); 87af935f76SBen Walker set_up_subsystem(&g_ut_subsystems[4], "rpc"); 88af935f76SBen Walker set_up_subsystem(&g_ut_subsystems[5], "scsi"); 89af935f76SBen Walker set_up_subsystem(&g_ut_subsystems[6], "interface"); 90af935f76SBen Walker set_up_subsystem(&g_ut_subsystems[7], "accel"); 91af935f76SBen Walker 92af935f76SBen Walker for (i = 0; i < 8; i++) { 93af935f76SBen Walker spdk_add_subsystem(&g_ut_subsystems[i]); 94af935f76SBen Walker } 95af935f76SBen Walker 96af935f76SBen Walker set_up_depends(&g_ut_subsystem_deps[0], "bdev", "accel"); 97af935f76SBen Walker set_up_depends(&g_ut_subsystem_deps[1], "scsi", "bdev"); 98af935f76SBen Walker set_up_depends(&g_ut_subsystem_deps[2], "rpc", "interface"); 99af935f76SBen Walker set_up_depends(&g_ut_subsystem_deps[3], "sock", "interface"); 100af935f76SBen Walker set_up_depends(&g_ut_subsystem_deps[4], "nvmf", "interface"); 101af935f76SBen Walker set_up_depends(&g_ut_subsystem_deps[5], "iscsi", "scsi"); 102af935f76SBen Walker set_up_depends(&g_ut_subsystem_deps[6], "iscsi", "sock"); 103af935f76SBen Walker set_up_depends(&g_ut_subsystem_deps[7], "iscsi", "rpc"); 104af935f76SBen Walker 105af935f76SBen Walker for (i = 0; i < 8; i++) { 106af935f76SBen Walker spdk_add_subsystem_depend(&g_ut_subsystem_deps[i]); 107af935f76SBen Walker } 108af935f76SBen Walker 109af935f76SBen Walker global_rc = -1; 110af935f76SBen Walker spdk_subsystem_init(ut_event_fn, NULL); 111af935f76SBen Walker CU_ASSERT(global_rc == 0); 112af935f76SBen Walker 113af935f76SBen Walker subsystem = TAILQ_FIRST(&g_subsystems); 114af935f76SBen Walker CU_ASSERT(strcmp(subsystem->name, "interface") == 0); 115af935f76SBen Walker TAILQ_REMOVE(&g_subsystems, subsystem, tailq); 116af935f76SBen Walker 117af935f76SBen Walker subsystem = TAILQ_FIRST(&g_subsystems); 118af935f76SBen Walker CU_ASSERT(strcmp(subsystem->name, "accel") == 0); 119af935f76SBen Walker TAILQ_REMOVE(&g_subsystems, subsystem, tailq); 120af935f76SBen Walker 121af935f76SBen Walker subsystem = TAILQ_FIRST(&g_subsystems); 122af935f76SBen Walker CU_ASSERT(strcmp(subsystem->name, "nvmf") == 0); 123af935f76SBen Walker TAILQ_REMOVE(&g_subsystems, subsystem, tailq); 124af935f76SBen Walker 125af935f76SBen Walker subsystem = TAILQ_FIRST(&g_subsystems); 126af935f76SBen Walker CU_ASSERT(strcmp(subsystem->name, "sock") == 0); 127af935f76SBen Walker TAILQ_REMOVE(&g_subsystems, subsystem, tailq); 128af935f76SBen Walker 129af935f76SBen Walker subsystem = TAILQ_FIRST(&g_subsystems); 130af935f76SBen Walker CU_ASSERT(strcmp(subsystem->name, "bdev") == 0); 131af935f76SBen Walker TAILQ_REMOVE(&g_subsystems, subsystem, tailq); 132af935f76SBen Walker 133af935f76SBen Walker subsystem = TAILQ_FIRST(&g_subsystems); 134af935f76SBen Walker CU_ASSERT(strcmp(subsystem->name, "rpc") == 0); 135af935f76SBen Walker TAILQ_REMOVE(&g_subsystems, subsystem, tailq); 136af935f76SBen Walker 137af935f76SBen Walker subsystem = TAILQ_FIRST(&g_subsystems); 138af935f76SBen Walker CU_ASSERT(strcmp(subsystem->name, "scsi") == 0); 139af935f76SBen Walker TAILQ_REMOVE(&g_subsystems, subsystem, tailq); 140af935f76SBen Walker 141af935f76SBen Walker subsystem = TAILQ_FIRST(&g_subsystems); 142af935f76SBen Walker CU_ASSERT(strcmp(subsystem->name, "iscsi") == 0); 143af935f76SBen Walker TAILQ_REMOVE(&g_subsystems, subsystem, tailq); 144af935f76SBen Walker } 145af935f76SBen Walker 146af935f76SBen Walker struct spdk_subsystem subsystem1 = { 147af935f76SBen Walker .name = "subsystem1", 148af935f76SBen Walker }; 149af935f76SBen Walker 150af935f76SBen Walker struct spdk_subsystem subsystem2 = { 151af935f76SBen Walker .name = "subsystem2", 152af935f76SBen Walker }; 153af935f76SBen Walker struct spdk_subsystem subsystem3 = { 154af935f76SBen Walker .name = "subsystem3", 155af935f76SBen Walker }; 156af935f76SBen Walker 157af935f76SBen Walker struct spdk_subsystem subsystem4 = { 158af935f76SBen Walker .name = "subsystem4", 159af935f76SBen Walker }; 160af935f76SBen Walker 161af935f76SBen Walker SPDK_SUBSYSTEM_REGISTER(subsystem1); 162af935f76SBen Walker SPDK_SUBSYSTEM_REGISTER(subsystem2); 163af935f76SBen Walker SPDK_SUBSYSTEM_REGISTER(subsystem3); 164af935f76SBen Walker SPDK_SUBSYSTEM_REGISTER(subsystem4); 165af935f76SBen Walker 166af935f76SBen Walker SPDK_SUBSYSTEM_DEPEND(subsystem1, subsystem2) 167af935f76SBen Walker SPDK_SUBSYSTEM_DEPEND(subsystem2, subsystem3) 168af935f76SBen Walker SPDK_SUBSYSTEM_DEPEND(subsystem3, subsystem4) 169af935f76SBen Walker 170af935f76SBen Walker 171af935f76SBen Walker static void 172af935f76SBen Walker subsystem_sort_test_missing_dependency(void) 173af935f76SBen Walker { 174af935f76SBen Walker /* 175af935f76SBen Walker * A depends on B, but B is missing 176af935f76SBen Walker */ 177af935f76SBen Walker 178af935f76SBen Walker subsystem_clear(); 179af935f76SBen Walker set_up_subsystem(&g_ut_subsystems[0], "A"); 180af935f76SBen Walker spdk_add_subsystem(&g_ut_subsystems[0]); 181af935f76SBen Walker 182af935f76SBen Walker set_up_depends(&g_ut_subsystem_deps[0], "A", "B"); 183af935f76SBen Walker spdk_add_subsystem_depend(&g_ut_subsystem_deps[0]); 184af935f76SBen Walker 185af935f76SBen Walker global_rc = -1; 186af935f76SBen Walker spdk_subsystem_init(ut_event_fn, NULL); 187af935f76SBen Walker CU_ASSERT(global_rc != 0); 188af935f76SBen Walker 189af935f76SBen Walker /* 190af935f76SBen Walker * Dependency from C to A is defined, but C is missing 191af935f76SBen Walker */ 192af935f76SBen Walker 193af935f76SBen Walker subsystem_clear(); 194af935f76SBen Walker set_up_subsystem(&g_ut_subsystems[0], "A"); 195af935f76SBen Walker spdk_add_subsystem(&g_ut_subsystems[0]); 196af935f76SBen Walker 197af935f76SBen Walker set_up_depends(&g_ut_subsystem_deps[0], "C", "A"); 198af935f76SBen Walker spdk_add_subsystem_depend(&g_ut_subsystem_deps[0]); 199af935f76SBen Walker 200af935f76SBen Walker global_rc = -1; 201af935f76SBen Walker spdk_subsystem_init(ut_event_fn, NULL); 202af935f76SBen Walker CU_ASSERT(global_rc != 0); 203af935f76SBen Walker 204af935f76SBen Walker } 205af935f76SBen Walker 206af935f76SBen Walker int 207af935f76SBen Walker main(int argc, char **argv) 208af935f76SBen Walker { 209af935f76SBen Walker CU_pSuite suite = NULL; 210af935f76SBen Walker unsigned int num_failures; 2110d3b5482SJim Harris struct spdk_thread *thread; 212af935f76SBen Walker 213af935f76SBen Walker CU_initialize_registry(); 214af935f76SBen Walker 215af935f76SBen Walker suite = CU_add_suite("subsystem_suite", NULL, NULL); 216af935f76SBen Walker 2170d3b5482SJim Harris spdk_thread_lib_init(NULL, 0); 2180d3b5482SJim Harris thread = spdk_thread_create(NULL, NULL); 2190d3b5482SJim Harris spdk_set_thread(thread); 2200d3b5482SJim Harris 221af935f76SBen Walker CU_ADD_TEST(suite, subsystem_sort_test_depends_on_single); 222af935f76SBen Walker CU_ADD_TEST(suite, subsystem_sort_test_depends_on_multiple); 223af935f76SBen Walker CU_ADD_TEST(suite, subsystem_sort_test_missing_dependency); 224af935f76SBen Walker 225ea941caeSKonrad Sztyber num_failures = spdk_ut_run_tests(argc, argv, NULL); 226af935f76SBen Walker CU_cleanup_registry(); 227af935f76SBen Walker 228af935f76SBen Walker return num_failures; 229af935f76SBen Walker } 230