bootm.c 7.3 KB

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