bootm.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Tests for bootm routines
  4. *
  5. * Copyright 2020 Google LLC
  6. */
  7. #include <common.h>
  8. #include <bootm.h>
  9. #include <asm/global_data.h>
  10. #include <test/suites.h>
  11. #include <test/test.h>
  12. #include <test/ut.h>
  13. DECLARE_GLOBAL_DATA_PTR;
  14. #define BOOTM_TEST(_name, _flags) UNIT_TEST(_name, _flags, bootm_test)
  15. enum {
  16. BUF_SIZE = 1024,
  17. };
  18. #define CONSOLE_STR "console=/dev/ttyS0"
  19. /* Test cmdline processing where nothing happens */
  20. static int bootm_test_nop(struct unit_test_state *uts)
  21. {
  22. char buf[BUF_SIZE];
  23. *buf = '\0';
  24. ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, true));
  25. ut_asserteq_str("", buf);
  26. strcpy(buf, "test");
  27. ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, true));
  28. ut_asserteq_str("test", buf);
  29. return 0;
  30. }
  31. BOOTM_TEST(bootm_test_nop, 0);
  32. /* Test cmdline processing when out of space */
  33. static int bootm_test_nospace(struct unit_test_state *uts)
  34. {
  35. char buf[BUF_SIZE];
  36. /* Zero buffer size */
  37. *buf = '\0';
  38. ut_asserteq(-ENOSPC, bootm_process_cmdline(buf, 0, true));
  39. /* Buffer string not terminated */
  40. memset(buf, 'a', BUF_SIZE);
  41. ut_asserteq(-ENOSPC, bootm_process_cmdline(buf, BUF_SIZE, true));
  42. /* Not enough space to copy string */
  43. memset(buf, '\0', BUF_SIZE);
  44. memset(buf, 'a', BUF_SIZE / 2);
  45. ut_asserteq(-ENOSPC, bootm_process_cmdline(buf, BUF_SIZE, true));
  46. /* Just enough space */
  47. memset(buf, '\0', BUF_SIZE);
  48. memset(buf, 'a', BUF_SIZE / 2 - 1);
  49. ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, true));
  50. return 0;
  51. }
  52. BOOTM_TEST(bootm_test_nospace, 0);
  53. /* Test silent processing */
  54. static int bootm_test_silent(struct unit_test_state *uts)
  55. {
  56. char buf[BUF_SIZE];
  57. /* 'silent_linux' not set should do nothing */
  58. env_set("silent_linux", NULL);
  59. strcpy(buf, CONSOLE_STR);
  60. ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SILENT));
  61. ut_asserteq_str(CONSOLE_STR, buf);
  62. ut_assertok(env_set("silent_linux", "no"));
  63. ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SILENT));
  64. ut_asserteq_str(CONSOLE_STR, buf);
  65. ut_assertok(env_set("silent_linux", "yes"));
  66. ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SILENT));
  67. ut_asserteq_str("console=", buf);
  68. /* Empty buffer should still add the string */
  69. *buf = '\0';
  70. ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SILENT));
  71. ut_asserteq_str("console=", buf);
  72. /* Check nothing happens when do_silent is false */
  73. *buf = '\0';
  74. ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, 0));
  75. ut_asserteq_str("", buf);
  76. /* Not enough space */
  77. *buf = '\0';
  78. ut_asserteq(-ENOSPC, bootm_process_cmdline(buf, 8, BOOTM_CL_SILENT));
  79. /* Just enough space */
  80. *buf = '\0';
  81. ut_assertok(bootm_process_cmdline(buf, 9, BOOTM_CL_SILENT));
  82. /* add at end */
  83. strcpy(buf, "something");
  84. ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SILENT));
  85. ut_asserteq_str("something console=", buf);
  86. /* change at start */
  87. strcpy(buf, CONSOLE_STR " something");
  88. ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SILENT));
  89. ut_asserteq_str("console= something", buf);
  90. return 0;
  91. }
  92. BOOTM_TEST(bootm_test_silent, 0);
  93. /* Test substitution processing */
  94. static int bootm_test_subst(struct unit_test_state *uts)
  95. {
  96. char buf[BUF_SIZE];
  97. /* try with an unset variable */
  98. ut_assertok(env_set("var", NULL));
  99. strcpy(buf, "some${var}thing");
  100. ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SUBST));
  101. ut_asserteq_str("something", buf);
  102. /* Replace with shorter string */
  103. ut_assertok(env_set("var", "bb"));
  104. strcpy(buf, "some${var}thing");
  105. ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SUBST));
  106. ut_asserteq_str("somebbthing", buf);
  107. /* Replace with same-length string */
  108. ut_assertok(env_set("var", "abc"));
  109. strcpy(buf, "some${var}thing");
  110. ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SUBST));
  111. ut_asserteq_str("someabcthing", buf);
  112. /* Replace with longer string */
  113. ut_assertok(env_set("var", "abcde"));
  114. strcpy(buf, "some${var}thing");
  115. ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SUBST));
  116. ut_asserteq_str("someabcdething", buf);
  117. /* Check it is case sensitive */
  118. ut_assertok(env_set("VAR", NULL));
  119. strcpy(buf, "some${VAR}thing");
  120. ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SUBST));
  121. ut_asserteq_str("something", buf);
  122. /* Check too long - need 12 bytes for each string */
  123. strcpy(buf, "some${var}thing");
  124. ut_asserteq(-ENOSPC,
  125. bootm_process_cmdline(buf, 12 * 2 - 1, BOOTM_CL_SUBST));
  126. /* Check just enough space */
  127. strcpy(buf, "some${var}thing");
  128. ut_assertok(bootm_process_cmdline(buf, 16 * 2, BOOTM_CL_SUBST));
  129. ut_asserteq_str("someabcdething", buf);
  130. /*
  131. * Check the substition string being too long. This results in a string
  132. * of 12 (13 bytes). We need enough space for that plus the original
  133. * "a${var}c" string of 9 bytes. So 12 + 9 = 21 bytes.
  134. */
  135. ut_assertok(env_set("var", "1234567890"));
  136. strcpy(buf, "a${var}c");
  137. ut_asserteq(-ENOSPC, bootm_process_cmdline(buf, 21, BOOTM_CL_SUBST));
  138. strcpy(buf, "a${var}c");
  139. ut_asserteq(0, bootm_process_cmdline(buf, 22, BOOTM_CL_SUBST));
  140. /* Check multiple substitutions */
  141. ut_assertok(env_set("var", "abc"));
  142. strcpy(buf, "some${var}thing${bvar}else");
  143. ut_asserteq(0, bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SUBST));
  144. ut_asserteq_str("someabcthingelse", buf);
  145. /* Check multiple substitutions */
  146. ut_assertok(env_set("bvar", "123"));
  147. strcpy(buf, "some${var}thing${bvar}else");
  148. ut_asserteq(0, bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SUBST));
  149. ut_asserteq_str("someabcthing123else", buf);
  150. return 0;
  151. }
  152. BOOTM_TEST(bootm_test_subst, 0);
  153. /* Test silent processing in the bootargs variable */
  154. static int bootm_test_silent_var(struct unit_test_state *uts)
  155. {
  156. env_set("bootargs", NULL);
  157. ut_assertok(bootm_process_cmdline_env(BOOTM_CL_SUBST));
  158. ut_assertnull(env_get("bootargs"));
  159. ut_assertok(env_set("bootargs", "some${var}thing"));
  160. ut_assertok(bootm_process_cmdline_env(BOOTM_CL_SUBST));
  161. ut_asserteq_str("something", env_get("bootargs"));
  162. return 0;
  163. }
  164. BOOTM_TEST(bootm_test_silent_var, 0);
  165. /* Test substitution processing in the bootargs variable */
  166. static int bootm_test_subst_var(struct unit_test_state *uts)
  167. {
  168. env_set("bootargs", NULL);
  169. ut_assertok(bootm_process_cmdline_env(BOOTM_CL_SILENT));
  170. ut_asserteq_str("console=", env_get("bootargs"));
  171. ut_assertok(env_set("var", "abc"));
  172. ut_assertok(env_set("bootargs", "some${var}thing"));
  173. ut_assertok(bootm_process_cmdline_env(BOOTM_CL_SILENT));
  174. ut_asserteq_str("some${var}thing console=", env_get("bootargs"));
  175. return 0;
  176. }
  177. BOOTM_TEST(bootm_test_subst_var, 0);
  178. /* Test substitution and silent console processing in the bootargs variable */
  179. static int bootm_test_subst_both(struct unit_test_state *uts)
  180. {
  181. ut_assertok(env_set("silent_linux", "yes"));
  182. env_set("bootargs", NULL);
  183. ut_assertok(bootm_process_cmdline_env(BOOTM_CL_ALL));
  184. ut_asserteq_str("console=", env_get("bootargs"));
  185. ut_assertok(env_set("bootargs", "some${var}thing " CONSOLE_STR));
  186. ut_assertok(env_set("var", "1234567890"));
  187. ut_assertok(bootm_process_cmdline_env(BOOTM_CL_ALL));
  188. ut_asserteq_str("some1234567890thing console=", env_get("bootargs"));
  189. return 0;
  190. }
  191. BOOTM_TEST(bootm_test_subst_both, 0);
  192. int do_ut_bootm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
  193. {
  194. struct unit_test *tests = UNIT_TEST_SUITE_START(bootm_test);
  195. const int n_ents = UNIT_TEST_SUITE_COUNT(bootm_test);
  196. return cmd_ut_category("bootm", "bootm_test_", tests, n_ents,
  197. argc, argv);
  198. }