host.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  2. /*
  3. * Copyright 2022 Google LLC
  4. * Written by Simon Glass <sjg@chromium.org>
  5. */
  6. #include <common.h>
  7. #include <blk.h>
  8. #include <dm.h>
  9. #include <fs.h>
  10. #include <sandbox_host.h>
  11. #include <asm/test.h>
  12. #include <dm/device-internal.h>
  13. #include <dm/test.h>
  14. #include <test/test.h>
  15. #include <test/ut.h>
  16. static const char filename[] = "2MB.ext2.img";
  17. static const char filename2[] = "1MB.fat32.img";
  18. /* Basic test of host interface */
  19. static int dm_test_host(struct unit_test_state *uts)
  20. {
  21. static char label[] = "test";
  22. struct udevice *dev, *part, *chk, *blk;
  23. struct host_sb_plat *plat;
  24. struct blk_desc *desc;
  25. ulong mem_start;
  26. loff_t actwrite;
  27. ut_asserteq(-ENODEV, uclass_first_device_err(UCLASS_HOST, &dev));
  28. ut_asserteq(-ENODEV, uclass_first_device_err(UCLASS_PARTITION, &part));
  29. mem_start = ut_check_delta(0);
  30. ut_assertok(host_create_device(label, true, &dev));
  31. /* Check that the plat data has been allocated */
  32. plat = dev_get_plat(dev);
  33. ut_asserteq_str("test", plat->label);
  34. ut_assert(label != plat->label);
  35. ut_asserteq(0, plat->fd);
  36. /* Attach a file created in test_host.py */
  37. ut_assertok(host_attach_file(dev, filename));
  38. ut_assertok(uclass_first_device_err(UCLASS_HOST, &chk));
  39. ut_asserteq_ptr(chk, dev);
  40. ut_asserteq_str(filename, plat->filename);
  41. ut_assert(filename != plat->filename);
  42. ut_assert(plat->fd != 0);
  43. /* Get the block device */
  44. ut_assertok(blk_get_from_parent(dev, &blk));
  45. ut_assertok(device_probe(blk));
  46. /* There should be no partition table in this device */
  47. ut_asserteq(-ENODEV, uclass_first_device_err(UCLASS_PARTITION, &part));
  48. /* Write to a file on the ext4 filesystem */
  49. desc = dev_get_uclass_plat(blk);
  50. ut_asserteq(true, desc->removable);
  51. ut_assertok(fs_set_blk_dev_with_part(desc, 0));
  52. ut_assertok(fs_write("/testing", 0, 0, 0x1000, &actwrite));
  53. ut_assertok(host_detach_file(dev));
  54. ut_asserteq(0, plat->fd);
  55. ut_asserteq(-ENODEV, blk_get_from_parent(dev, &blk));
  56. ut_assertok(device_unbind(dev));
  57. /* check there were no memory leaks */
  58. ut_asserteq(0, ut_check_delta(mem_start));
  59. return 0;
  60. }
  61. DM_TEST(dm_test_host, UT_TESTF_SCAN_FDT);
  62. /* reusing the same label should work */
  63. static int dm_test_host_dup(struct unit_test_state *uts)
  64. {
  65. static char label[] = "test";
  66. struct udevice *dev, *chk;
  67. ut_asserteq(0, uclass_id_count(UCLASS_HOST));
  68. ut_assertok(host_create_device(label, true, &dev));
  69. /* Attach a file created in test_host.py */
  70. ut_assertok(host_attach_file(dev, filename));
  71. ut_assertok(uclass_first_device_err(UCLASS_HOST, &chk));
  72. ut_asserteq_ptr(chk, dev);
  73. ut_asserteq(1, uclass_id_count(UCLASS_HOST));
  74. /* Create another device with the same label (should remove old one) */
  75. ut_assertok(host_create_device(label, true, &dev));
  76. /* Attach a different file created in test_host.py */
  77. ut_assertok(host_attach_file(dev, filename2));
  78. ut_assertok(uclass_first_device_err(UCLASS_HOST, &chk));
  79. ut_asserteq_ptr(chk, dev);
  80. /* Make sure there is still only one device */
  81. ut_asserteq(1, uclass_id_count(UCLASS_HOST));
  82. return 0;
  83. }
  84. DM_TEST(dm_test_host_dup, UT_TESTF_SCAN_FDT);
  85. /* Basic test of 'host' command */
  86. static int dm_test_cmd_host(struct unit_test_state *uts)
  87. {
  88. struct udevice *dev, *blk;
  89. struct blk_desc *desc;
  90. console_record_reset();
  91. /* first check 'host info' with binding */
  92. ut_assertok(run_command("host info", 0));
  93. ut_assert_nextline("dev blocks label path");
  94. ut_assert_console_end();
  95. ut_assertok(run_commandf("host bind -r test2 %s", filename));
  96. /* Check the -r flag worked */
  97. ut_assertok(uclass_first_device_err(UCLASS_HOST, &dev));
  98. ut_assertok(blk_get_from_parent(dev, &blk));
  99. desc = dev_get_uclass_plat(blk);
  100. ut_asserteq(true, desc->removable);
  101. ut_assertok(run_command("host info", 0));
  102. ut_assert_nextline("dev blocks label path");
  103. ut_assert_nextline(" 0 4096 test2 2MB.ext2.img");
  104. ut_assert_console_end();
  105. ut_assertok(run_commandf("host bind fat %s", filename2));
  106. /* Check it is not removable (no '-r') */
  107. ut_assertok(uclass_next_device_err(&dev));
  108. ut_assertok(blk_get_from_parent(dev, &blk));
  109. desc = dev_get_uclass_plat(blk);
  110. ut_asserteq(false, desc->removable);
  111. ut_assertok(run_command("host info", 0));
  112. ut_assert_nextline("dev blocks label path");
  113. ut_assert_nextline(" 0 4096 test2 2MB.ext2.img");
  114. ut_assert_nextline(" 1 2048 fat 1MB.fat32.img");
  115. ut_assert_console_end();
  116. ut_asserteq(1, run_command("host info test", 0));
  117. ut_assert_nextline("No such device 'test'");
  118. ut_assert_console_end();
  119. ut_assertok(run_command("host info fat", 0));
  120. ut_assert_nextline("dev blocks label path");
  121. ut_assert_nextline(" 1 2048 fat 1MB.fat32.img");
  122. ut_assert_console_end();
  123. /* check 'host dev' */
  124. ut_asserteq(1, run_command("host dev", 0));
  125. ut_assert_nextline("No current host device");
  126. ut_assert_console_end();
  127. ut_asserteq(1, run_command("host dev missing", 0));
  128. ut_assert_nextline("No such device 'missing'");
  129. ut_assert_console_end();
  130. ut_assertok(run_command("host dev fat", 0));
  131. ut_assert_console_end();
  132. ut_assertok(run_command("host dev", 0));
  133. ut_assert_nextline("Current host device: 1: fat");
  134. ut_assert_console_end();
  135. /* Try a numerical label */
  136. ut_assertok(run_command("host dev 0", 0));
  137. ut_assert_console_end();
  138. ut_assertok(run_command("host dev", 0));
  139. ut_assert_nextline("Current host device: 0: test2");
  140. ut_assert_console_end();
  141. /* Remove one of the bindings */
  142. ut_assertok(run_commandf("host unbind test2"));
  143. /* There should now be no current device */
  144. ut_asserteq(1, run_command("host dev", 0));
  145. ut_assert_nextline("No current host device");
  146. ut_assert_console_end();
  147. ut_assertok(run_command("host info", 0));
  148. ut_assert_nextline("dev blocks label path");
  149. ut_assert_nextline(" 1 2048 fat 1MB.fat32.img");
  150. ut_assert_console_end();
  151. return 0;
  152. }
  153. DM_TEST(dm_test_cmd_host, UT_TESTF_SCAN_FDT);