test_build_system.sh 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #!/bin/bash
  2. #
  3. # Test the build system for basic consistency
  4. #
  5. # Just a bash script that tests some likely make failure scenarios in a row
  6. # Creates its own test build directory under TMP and cleans it up when done.
  7. #
  8. # Environment variables:
  9. # IDF_PATH - must be set
  10. # TMP - can override /tmp location for build directory
  11. # ESP_IDF_TEMPLATE_GIT - Can override git clone source for template app. Otherwise github.
  12. # NOCLEANUP - Set to '1' if you want the script to leave its temporary directory when done, for post-mortem.
  13. #
  14. # Set up some variables
  15. #
  16. [ -z ${TMP} ] && TMP="/tmp"
  17. # override ESP_IDF_TEMPLATE_GIT to point to a local dir if you're testing and want fast iterations
  18. [ -z ${ESP_IDF_TEMPLATE_GIT} ] && ESP_IDF_TEMPLATE_GIT=https://github.com/espressif/esp-idf-template.git
  19. export V=1
  20. function run_tests()
  21. {
  22. FAILURES=
  23. STATUS="Starting"
  24. print_status "Checking prerequisites"
  25. [ -z ${IDF_PATH} ] && echo "IDF_PATH is not set. Need path to esp-idf installation." && exit 2
  26. print_status "Cloning template from ${ESP_IDF_TEMPLATE_GIT}..."
  27. git clone ${ESP_IDF_TEMPLATE_GIT} template
  28. cd template
  29. git checkout ${CI_BUILD_REF_NAME} || echo "Using esp-idf-template default branch..."
  30. print_status "Updating template config..."
  31. make defconfig || exit $?
  32. BOOTLOADER_BINS="bootloader/bootloader.elf bootloader/bootloader.bin"
  33. APP_BINS="app-template.elf app-template.bin"
  34. print_status "Initial clean build"
  35. # if make fails here, everything fails
  36. make || exit $?
  37. # check all the expected build artifacts from the clean build
  38. assert_built ${APP_BINS} ${BOOTLOADER_BINS} partitions_singleapp.bin
  39. [ -f ${BUILD}/partition*.bin ] || failure "A partition table should have been built"
  40. print_status "Updating component source file rebuilds component"
  41. # touch a file & do a build
  42. take_build_snapshot
  43. touch ${IDF_PATH}/components/esp32/syscalls.c
  44. make || failure "Failed to partial build"
  45. assert_rebuilt ${APP_BINS} esp32/libesp32.a esp32/syscalls.o
  46. assert_not_rebuilt lwip/liblwip.a freertos/libfreertos.a ${BOOTLOADER_BINS} partitions_singleapp.bin
  47. print_status "Bootloader source file rebuilds bootloader"
  48. take_build_snapshot
  49. touch ${IDF_PATH}/components/bootloader/src/main/bootloader_start.c
  50. make bootloader || failure "Failed to partial build bootloader"
  51. assert_rebuilt ${BOOTLOADER_BINS} bootloader/main/bootloader_start.o
  52. assert_not_rebuilt ${APP_BINS} partitions_singleapp.bin
  53. print_status "Partition CSV file rebuilds partitions"
  54. take_build_snapshot
  55. touch ${IDF_PATH}/components/partition_table/partitions_singleapp.csv
  56. make partition_table
  57. assert_rebuilt partitions_singleapp.bin
  58. assert_not_rebuilt app-template.bin app-template.elf ${BOOTLOADER_BINS}
  59. print_status "Partial build doesn't compile anything by default"
  60. take_build_snapshot
  61. # verify no build files are refreshed by a partial make
  62. ALL_BUILD_FILES=$(find ${BUILD} -type f | sed "s@${BUILD}/@@")
  63. make
  64. assert_not_rebuilt ${ALL_BUILD_FILES}
  65. print_status "Cleaning should remove all files from build"
  66. make clean
  67. ALL_BUILD_FILES=$(find ${BUILD} -type f)
  68. if [ -n "${ALL_BUILD_FILES}" ]; then
  69. failure "Files weren't cleaned: ${ALL_BUILD_FILES}"
  70. fi
  71. print_status "All tests completed"
  72. if [ -n "${FAILURES}" ]; then
  73. echo "Some failures were detected:"
  74. echo -e "${FAILURES}"
  75. exit 1
  76. else
  77. echo "Build tests passed."
  78. fi
  79. }
  80. function print_status()
  81. {
  82. echo "******** $1"
  83. STATUS="$1"
  84. }
  85. function failure()
  86. {
  87. echo "!!!!!!!!!!!!!!!!!!!"
  88. echo "FAILURE: $1"
  89. echo "!!!!!!!!!!!!!!!!!!!"
  90. FAILURES="${FAILURES}${STATUS} :: $1\n"
  91. }
  92. TESTDIR=${TMP}/build_system_tests_$$
  93. mkdir -p ${TESTDIR}
  94. # set NOCLEANUP=1 if you want to keep the test directory around
  95. # for post-mortem debugging
  96. [ -z ${NOCLEANUP} ] && trap "rm -rf ${TESTDIR}" EXIT KILL
  97. SNAPSHOT=${TESTDIR}/snapshot
  98. BUILD=${TESTDIR}/template/build
  99. # copy all the build output to a snapshot directory
  100. function take_build_snapshot()
  101. {
  102. rm -rf ${SNAPSHOT}
  103. cp -ap ${TESTDIR}/template/build ${SNAPSHOT}
  104. }
  105. # verify that all the arguments are present in the build output directory
  106. function assert_built()
  107. {
  108. until [ -z "$1" ]; do
  109. if [ ! -f "${BUILD}/$1" ]; then
  110. failure "File $1 should be in the build output directory"
  111. fi
  112. shift
  113. done
  114. }
  115. # Test if a file has been rebuilt.
  116. function file_was_rebuilt()
  117. {
  118. # can't use [ a -ot b ] here as -ot only gives second resolution
  119. # but stat -c %y seems to be microsecond at least for tmpfs, ext4..
  120. if [ "$(stat -c %y ${SNAPSHOT}/$1)" != "$(stat -c %y ${BUILD}/$1)" ]; then
  121. return 0
  122. else
  123. return 1
  124. fi
  125. }
  126. # verify all the arguments passed in were rebuilt relative to the snapshot
  127. function assert_rebuilt()
  128. {
  129. until [ -z "$1" ]; do
  130. assert_built "$1"
  131. if [ ! -f "${SNAPSHOT}/$1" ]; then
  132. failure "File $1 should have been original build snapshot"
  133. fi
  134. if ! file_was_rebuilt "$1"; then
  135. failure "File $1 should have been rebuilt"
  136. fi
  137. shift
  138. done
  139. }
  140. # verify all the arguments are in the build directory & snapshot,
  141. # but were not rebuilt
  142. function assert_not_rebuilt()
  143. {
  144. until [ -z "$1" ]; do
  145. assert_built "$1"
  146. if [ ! -f "${SNAPSHOT}/$1" ]; then
  147. failure "File $1 should be in snapshot build directory"
  148. fi
  149. if file_was_rebuilt "$1"; then
  150. failure "File $1 should not have been rebuilt"
  151. fi
  152. shift
  153. done
  154. }
  155. cd ${TESTDIR}
  156. run_tests