1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
/*
* Copyright 2022 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
* This source code is licensed under the GNU General Public License version 2
* or later (GPLv2+) WITHOUT ANY WARRANTY.
*/
#include <crm_internal.h>
#include <crm/common/unittest_internal.h>
#include "mock_private.h"
static void
empty_input_string(void **state)
{
pcmk__mock_getenv = true;
// getenv() not called
assert_null(pcmk__env_option(NULL));
assert_null(pcmk__env_option(""));
pcmk__mock_getenv = false;
}
static void
input_too_long_for_both(void **state)
{
/* pcmk__env_option() prepends "PCMK_" before lookup. If the option name is
* too long for the buffer or isn't found in the env, then it prepends "HA_"
* and tries again. A string of length (NAME_MAX - 3) will set us just over
* just over the edge for both tries.
*/
char long_opt[NAME_MAX - 2];
for (int i = 0; i < NAME_MAX - 3; i++) {
long_opt[i] = 'a';
}
long_opt[NAME_MAX - 3] = '\0';
pcmk__mock_getenv = true;
// getenv() not called
assert_null(pcmk__env_option(long_opt));
pcmk__mock_getenv = false;
}
static void
input_too_long_for_pcmk(void **state)
{
/* If an input is too long for "PCMK_<option>", make sure we fall through
* to try "HA_<option>".
*
* pcmk__env_option() prepends "PCMK_" first. A string of length
* (NAME_MAX - 5) will set us just over the edge, still short enough for
* "HA_<option>" to fit.
*/
char long_opt[NAME_MAX - 4];
char buf[NAME_MAX];
for (int i = 0; i < NAME_MAX - 5; i++) {
long_opt[i] = 'a';
}
long_opt[NAME_MAX - 5] = '\0';
pcmk__mock_getenv = true;
/* NULL/non-NULL retval doesn't really matter here; just testing that we
* call getenv() for "HA_" prefix after too long for "PCMK_".
*/
snprintf(buf, NAME_MAX, "HA_%s", long_opt);
expect_string(__wrap_getenv, name, buf);
will_return(__wrap_getenv, "value");
assert_string_equal(pcmk__env_option(long_opt), "value");
pcmk__mock_getenv = false;
}
static void
value_not_found(void **state)
{
// Value not found using PCMK_ or HA_ prefix. Should return NULL.
pcmk__mock_getenv = true;
expect_string(__wrap_getenv, name, "PCMK_env_var");
will_return(__wrap_getenv, NULL);
expect_string(__wrap_getenv, name, "HA_env_var");
will_return(__wrap_getenv, NULL);
assert_null(pcmk__env_option("env_var"));
pcmk__mock_getenv = false;
}
static void
value_found_pcmk(void **state)
{
// Value found using PCMK_. Should return value and skip HA_ lookup.
pcmk__mock_getenv = true;
expect_string(__wrap_getenv, name, "PCMK_env_var");
will_return(__wrap_getenv, "value");
assert_string_equal(pcmk__env_option("env_var"), "value");
pcmk__mock_getenv = false;
}
static void
value_found_ha(void **state)
{
// Value not found using PCMK_. Move on to HA_ lookup, find, and return.
pcmk__mock_getenv = true;
expect_string(__wrap_getenv, name, "PCMK_env_var");
will_return(__wrap_getenv, NULL);
expect_string(__wrap_getenv, name, "HA_env_var");
will_return(__wrap_getenv, "value");
assert_string_equal(pcmk__env_option("env_var"), "value");
pcmk__mock_getenv = false;
}
PCMK__UNIT_TEST(NULL, NULL,
cmocka_unit_test(empty_input_string),
cmocka_unit_test(input_too_long_for_both),
cmocka_unit_test(input_too_long_for_pcmk),
cmocka_unit_test(value_not_found),
cmocka_unit_test(value_found_pcmk),
cmocka_unit_test(value_found_ha))
|