command_ut.c 6.33 KB
Newer Older
1 2 3
/*
 * Copyright (c) 2012, The Chromium Authors
 *
4
 * SPDX-License-Identifier:	GPL-2.0+
5 6 7 8 9
 */

#define DEBUG

#include <common.h>
10 11 12
#ifdef CONFIG_SANDBOX
#include <os.h>
#endif
13 14 15 16 17 18 19 20

static const char test_cmd[] = "setenv list 1\n setenv list ${list}2; "
		"setenv list ${list}3\0"
		"setenv list ${list}4";

static int do_ut_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	printf("%s: Testing commands\n", __func__);
21
	run_command("env default -f -a", 0);
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

	/* run a single command */
	run_command("setenv single 1", 0);
	assert(!strcmp("1", getenv("single")));

	/* make sure that compound statements work */
#ifdef CONFIG_SYS_HUSH_PARSER
	run_command("if test -n ${single} ; then setenv check 1; fi", 0);
	assert(!strcmp("1", getenv("check")));
	run_command("setenv check", 0);
#endif

	/* commands separated by ; */
	run_command_list("setenv list 1; setenv list ${list}1", -1, 0);
	assert(!strcmp("11", getenv("list")));

	/* commands separated by \n */
	run_command_list("setenv list 1\n setenv list ${list}1", -1, 0);
	assert(!strcmp("11", getenv("list")));

	/* command followed by \n and nothing else */
	run_command_list("setenv list 1${list}\n", -1, 0);
	assert(!strcmp("111", getenv("list")));

	/* three commands in a row */
	run_command_list("setenv list 1\n setenv list ${list}2; "
		"setenv list ${list}3", -1, 0);
	assert(!strcmp("123", getenv("list")));

	/* a command string with \0 in it. Stuff after \0 should be ignored */
	run_command("setenv list", 0);
	run_command_list(test_cmd, sizeof(test_cmd), 0);
	assert(!strcmp("123", getenv("list")));

	/*
	 * a command list where we limit execution to only the first command
	 * using the length parameter.
	 */
	run_command_list("setenv list 1\n setenv list ${list}2; "
		"setenv list ${list}3", strlen("setenv list 1"), 0);
	assert(!strcmp("1", getenv("list")));

64 65 66 67 68
	assert(run_command("false", 0) == 1);
	assert(run_command("echo", 0) == 0);
	assert(run_command_list("false", -1, 0) == 1);
	assert(run_command_list("echo", -1, 0) == 0);

69 70 71 72 73 74 75
	run_command("setenv foo 'setenv monty 1; setenv python 2'", 0);
	run_command("run foo", 0);
	assert(getenv("monty") != NULL);
	assert(!strcmp("1", getenv("monty")));
	assert(getenv("python") != NULL);
	assert(!strcmp("2", getenv("python")));

76
#ifdef CONFIG_SYS_HUSH_PARSER
77 78 79 80 81 82 83
	run_command("setenv foo 'setenv black 1\nsetenv adder 2'", 0);
	run_command("run foo", 0);
	assert(getenv("black") != NULL);
	assert(!strcmp("1", getenv("black")));
	assert(getenv("adder") != NULL);
	assert(!strcmp("2", getenv("adder")));

84 85 86 87 88 89
	/* Test the 'test' command */

#define HUSH_TEST(name, expr, expected_result) \
	run_command("if test " expr " ; then " \
			"setenv " #name "_" #expected_result " y; else " \
			"setenv " #name "_" #expected_result " n; fi", 0); \
90 91
	assert(!strcmp(#expected_result, getenv(#name "_" #expected_result))); \
	setenv(#name "_" #expected_result, NULL);
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 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162

	/* Basic operators */
	HUSH_TEST(streq, "aaa = aaa", y);
	HUSH_TEST(streq, "aaa = bbb", n);

	HUSH_TEST(strneq, "aaa != bbb", y);
	HUSH_TEST(strneq, "aaa != aaa", n);

	HUSH_TEST(strlt, "aaa < bbb", y);
	HUSH_TEST(strlt, "bbb < aaa", n);

	HUSH_TEST(strgt, "bbb > aaa", y);
	HUSH_TEST(strgt, "aaa > bbb", n);

	HUSH_TEST(eq, "123 -eq 123", y);
	HUSH_TEST(eq, "123 -eq 456", n);

	HUSH_TEST(ne, "123 -ne 456", y);
	HUSH_TEST(ne, "123 -ne 123", n);

	HUSH_TEST(lt, "123 -lt 456", y);
	HUSH_TEST(lt_eq, "123 -lt 123", n);
	HUSH_TEST(lt, "456 -lt 123", n);

	HUSH_TEST(le, "123 -le 456", y);
	HUSH_TEST(le_eq, "123 -le 123", y);
	HUSH_TEST(le, "456 -le 123", n);

	HUSH_TEST(gt, "456 -gt 123", y);
	HUSH_TEST(gt_eq, "123 -gt 123", n);
	HUSH_TEST(gt, "123 -gt 456", n);

	HUSH_TEST(ge, "456 -ge 123", y);
	HUSH_TEST(ge_eq, "123 -ge 123", y);
	HUSH_TEST(ge, "123 -ge 456", n);

	HUSH_TEST(z, "-z \"\"", y);
	HUSH_TEST(z, "-z \"aaa\"", n);

	HUSH_TEST(n, "-n \"aaa\"", y);
	HUSH_TEST(n, "-n \"\"", n);

	/* Inversion of simple tests */
	HUSH_TEST(streq_inv, "! aaa = aaa", n);
	HUSH_TEST(streq_inv, "! aaa = bbb", y);

	HUSH_TEST(streq_inv_inv, "! ! aaa = aaa", y);
	HUSH_TEST(streq_inv_inv, "! ! aaa = bbb", n);

	/* Binary operators */
	HUSH_TEST(or_0_0, "aaa != aaa -o bbb != bbb", n);
	HUSH_TEST(or_0_1, "aaa != aaa -o bbb = bbb", y);
	HUSH_TEST(or_1_0, "aaa = aaa -o bbb != bbb", y);
	HUSH_TEST(or_1_1, "aaa = aaa -o bbb = bbb", y);

	HUSH_TEST(and_0_0, "aaa != aaa -a bbb != bbb", n);
	HUSH_TEST(and_0_1, "aaa != aaa -a bbb = bbb", n);
	HUSH_TEST(and_1_0, "aaa = aaa -a bbb != bbb", n);
	HUSH_TEST(and_1_1, "aaa = aaa -a bbb = bbb", y);

	/* Inversion within binary operators */
	HUSH_TEST(or_0_0_inv, "! aaa != aaa -o ! bbb != bbb", y);
	HUSH_TEST(or_0_1_inv, "! aaa != aaa -o ! bbb = bbb", y);
	HUSH_TEST(or_1_0_inv, "! aaa = aaa -o ! bbb != bbb", y);
	HUSH_TEST(or_1_1_inv, "! aaa = aaa -o ! bbb = bbb", n);

	HUSH_TEST(or_0_0_inv_inv, "! ! aaa != aaa -o ! ! bbb != bbb", n);
	HUSH_TEST(or_0_1_inv_inv, "! ! aaa != aaa -o ! ! bbb = bbb", y);
	HUSH_TEST(or_1_0_inv_inv, "! ! aaa = aaa -o ! ! bbb != bbb", y);
	HUSH_TEST(or_1_1_inv_inv, "! ! aaa = aaa -o ! ! bbb = bbb", y);

163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
	setenv("ut_var_nonexistent", NULL);
	setenv("ut_var_exists", "1");
	HUSH_TEST(z_varexp_quoted, "-z \"$ut_var_nonexistent\"", y);
	HUSH_TEST(z_varexp_quoted, "-z \"$ut_var_exists\"", n);
	setenv("ut_var_exists", NULL);

	run_command("setenv ut_var_space \" \"", 0);
	assert(!strcmp(getenv("ut_var_space"), " "));
	run_command("setenv ut_var_test $ut_var_space", 0);
	assert(!getenv("ut_var_test"));
	run_command("setenv ut_var_test \"$ut_var_space\"", 0);
	assert(!strcmp(getenv("ut_var_test"), " "));
	run_command("setenv ut_var_test \" 1${ut_var_space}${ut_var_space} 2 \"", 0);
	assert(!strcmp(getenv("ut_var_test"), " 1   2 "));
	setenv("ut_var_space", NULL);
	setenv("ut_var_test", NULL);

180
#ifdef CONFIG_SANDBOX
181
	/* File existence */
182 183 184
	HUSH_TEST(e, "-e hostfs - creating_this_file_breaks_uboot_unit_test", n);
	run_command("sb save hostfs - creating_this_file_breaks_uboot_unit_test 0 1", 0);
	HUSH_TEST(e, "-e hostfs - creating_this_file_breaks_uboot_unit_test", y);
185 186
	/* Perhaps this could be replaced by an "rm" shell command one day */
	assert(!os_unlink("creating_this_file_breaks_uboot_unit_test"));
187
	HUSH_TEST(e, "-e hostfs - creating_this_file_breaks_uboot_unit_test", n);
188 189 190
#endif
#endif

191 192 193
	assert(run_command("", 0) == 0);
	assert(run_command(" ", 0) == 0);

194 195 196 197 198 199 200 201 202
	printf("%s: Everything went swimmingly\n", __func__);
	return 0;
}

U_BOOT_CMD(
	ut_cmd,	5,	1,	do_ut_cmd,
	"Very basic test of command parsers",
	""
);