test_truncate.sh 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. #!/bin/bash
  2. set -eu
  3. export TEST_FILE=$0
  4. trap 'export TEST_LINE=$LINENO' DEBUG
  5. echo "=== Truncate tests ==="
  6. SMALLSIZE=32
  7. MEDIUMSIZE=2048
  8. LARGESIZE=8192
  9. rm -rf blocks
  10. scripts/test.py << TEST
  11. lfs_format(&lfs, &cfg) => 0;
  12. TEST
  13. echo "--- Simple truncate ---"
  14. scripts/test.py << TEST
  15. lfs_mount(&lfs, &cfg) => 0;
  16. lfs_file_open(&lfs, &file, "baldynoop",
  17. LFS_O_WRONLY | LFS_O_CREAT) => 0;
  18. strcpy((char*)buffer, "hair");
  19. lfs_size_t size = strlen((char*)buffer);
  20. for (lfs_off_t j = 0; j < $LARGESIZE; j += size) {
  21. lfs_file_write(&lfs, &file, buffer, size) => size;
  22. }
  23. lfs_file_size(&lfs, &file) => $LARGESIZE;
  24. lfs_file_close(&lfs, &file) => 0;
  25. lfs_unmount(&lfs) => 0;
  26. TEST
  27. scripts/test.py << TEST
  28. lfs_mount(&lfs, &cfg) => 0;
  29. lfs_file_open(&lfs, &file, "baldynoop", LFS_O_RDWR) => 0;
  30. lfs_file_size(&lfs, &file) => $LARGESIZE;
  31. lfs_file_truncate(&lfs, &file, $MEDIUMSIZE) => 0;
  32. lfs_file_size(&lfs, &file) => $MEDIUMSIZE;
  33. lfs_file_close(&lfs, &file) => 0;
  34. lfs_unmount(&lfs) => 0;
  35. TEST
  36. scripts/test.py << TEST
  37. lfs_mount(&lfs, &cfg) => 0;
  38. lfs_file_open(&lfs, &file, "baldynoop", LFS_O_RDONLY) => 0;
  39. lfs_file_size(&lfs, &file) => $MEDIUMSIZE;
  40. lfs_size_t size = strlen("hair");
  41. for (lfs_off_t j = 0; j < $MEDIUMSIZE; j += size) {
  42. lfs_file_read(&lfs, &file, buffer, size) => size;
  43. memcmp(buffer, "hair", size) => 0;
  44. }
  45. lfs_file_read(&lfs, &file, buffer, size) => 0;
  46. lfs_file_close(&lfs, &file) => 0;
  47. lfs_unmount(&lfs) => 0;
  48. TEST
  49. echo "--- Truncate and read ---"
  50. scripts/test.py << TEST
  51. lfs_mount(&lfs, &cfg) => 0;
  52. lfs_file_open(&lfs, &file, "baldyread",
  53. LFS_O_WRONLY | LFS_O_CREAT) => 0;
  54. strcpy((char*)buffer, "hair");
  55. lfs_size_t size = strlen((char*)buffer);
  56. for (lfs_off_t j = 0; j < $LARGESIZE; j += size) {
  57. lfs_file_write(&lfs, &file, buffer, size) => size;
  58. }
  59. lfs_file_size(&lfs, &file) => $LARGESIZE;
  60. lfs_file_close(&lfs, &file) => 0;
  61. lfs_unmount(&lfs) => 0;
  62. TEST
  63. scripts/test.py << TEST
  64. lfs_mount(&lfs, &cfg) => 0;
  65. lfs_file_open(&lfs, &file, "baldyread", LFS_O_RDWR) => 0;
  66. lfs_file_size(&lfs, &file) => $LARGESIZE;
  67. lfs_file_truncate(&lfs, &file, $MEDIUMSIZE) => 0;
  68. lfs_file_size(&lfs, &file) => $MEDIUMSIZE;
  69. lfs_size_t size = strlen("hair");
  70. for (lfs_off_t j = 0; j < $MEDIUMSIZE; j += size) {
  71. lfs_file_read(&lfs, &file, buffer, size) => size;
  72. memcmp(buffer, "hair", size) => 0;
  73. }
  74. lfs_file_read(&lfs, &file, buffer, size) => 0;
  75. lfs_file_close(&lfs, &file) => 0;
  76. lfs_unmount(&lfs) => 0;
  77. TEST
  78. scripts/test.py << TEST
  79. lfs_mount(&lfs, &cfg) => 0;
  80. lfs_file_open(&lfs, &file, "baldyread", LFS_O_RDONLY) => 0;
  81. lfs_file_size(&lfs, &file) => $MEDIUMSIZE;
  82. lfs_size_t size = strlen("hair");
  83. for (lfs_off_t j = 0; j < $MEDIUMSIZE; j += size) {
  84. lfs_file_read(&lfs, &file, buffer, size) => size;
  85. memcmp(buffer, "hair", size) => 0;
  86. }
  87. lfs_file_read(&lfs, &file, buffer, size) => 0;
  88. lfs_file_close(&lfs, &file) => 0;
  89. lfs_unmount(&lfs) => 0;
  90. TEST
  91. echo "--- Write, truncate, and read ---"
  92. scripts/test.py << TEST
  93. lfs_mount(&lfs, &cfg) => 0;
  94. lfs_file_open(&lfs, &file, "sequence",
  95. LFS_O_RDWR | LFS_O_CREAT | LFS_O_TRUNC) => 0;
  96. lfs_size_t size = lfs.cfg->cache_size;
  97. lfs_size_t qsize = size / 4;
  98. uint8_t *wb = buffer;
  99. uint8_t *rb = buffer + size;
  100. for (lfs_off_t j = 0; j < size; ++j) {
  101. wb[j] = j;
  102. }
  103. /* Spread sequence over size */
  104. lfs_file_write(&lfs, &file, wb, size) => size;
  105. lfs_file_size(&lfs, &file) => size;
  106. lfs_file_tell(&lfs, &file) => size;
  107. lfs_file_seek(&lfs, &file, 0, LFS_SEEK_SET) => 0;
  108. lfs_file_tell(&lfs, &file) => 0;
  109. /* Chop off the last quarter */
  110. lfs_size_t trunc = size - qsize;
  111. lfs_file_truncate(&lfs, &file, trunc) => 0;
  112. lfs_file_tell(&lfs, &file) => 0;
  113. lfs_file_size(&lfs, &file) => trunc;
  114. /* Read should produce first 3/4 */
  115. lfs_file_read(&lfs, &file, rb, size) => trunc;
  116. memcmp(rb, wb, trunc) => 0;
  117. /* Move to 1/4 */
  118. lfs_file_size(&lfs, &file) => trunc;
  119. lfs_file_seek(&lfs, &file, qsize, LFS_SEEK_SET) => qsize;
  120. lfs_file_tell(&lfs, &file) => qsize;
  121. /* Chop to 1/2 */
  122. trunc -= qsize;
  123. lfs_file_truncate(&lfs, &file, trunc) => 0;
  124. lfs_file_tell(&lfs, &file) => qsize;
  125. lfs_file_size(&lfs, &file) => trunc;
  126. /* Read should produce second quarter */
  127. lfs_file_read(&lfs, &file, rb, size) => trunc - qsize;
  128. memcmp(rb, wb + qsize, trunc - qsize) => 0;
  129. lfs_file_close(&lfs, &file) => 0;
  130. lfs_unmount(&lfs) => 0;
  131. TEST
  132. echo "--- Truncate and write ---"
  133. scripts/test.py << TEST
  134. lfs_mount(&lfs, &cfg) => 0;
  135. lfs_file_open(&lfs, &file, "baldywrite",
  136. LFS_O_WRONLY | LFS_O_CREAT) => 0;
  137. strcpy((char*)buffer, "hair");
  138. lfs_size_t size = strlen((char*)buffer);
  139. for (lfs_off_t j = 0; j < $LARGESIZE; j += size) {
  140. lfs_file_write(&lfs, &file, buffer, size) => size;
  141. }
  142. lfs_file_size(&lfs, &file) => $LARGESIZE;
  143. lfs_file_close(&lfs, &file) => 0;
  144. lfs_unmount(&lfs) => 0;
  145. TEST
  146. scripts/test.py << TEST
  147. lfs_mount(&lfs, &cfg) => 0;
  148. lfs_file_open(&lfs, &file, "baldywrite", LFS_O_RDWR) => 0;
  149. lfs_file_size(&lfs, &file) => $LARGESIZE;
  150. lfs_file_truncate(&lfs, &file, $MEDIUMSIZE) => 0;
  151. lfs_file_size(&lfs, &file) => $MEDIUMSIZE;
  152. strcpy((char*)buffer, "bald");
  153. lfs_size_t size = strlen((char*)buffer);
  154. for (lfs_off_t j = 0; j < $MEDIUMSIZE; j += size) {
  155. lfs_file_write(&lfs, &file, buffer, size) => size;
  156. }
  157. lfs_file_size(&lfs, &file) => $MEDIUMSIZE;
  158. lfs_file_close(&lfs, &file) => 0;
  159. lfs_unmount(&lfs) => 0;
  160. TEST
  161. scripts/test.py << TEST
  162. lfs_mount(&lfs, &cfg) => 0;
  163. lfs_file_open(&lfs, &file, "baldywrite", LFS_O_RDONLY) => 0;
  164. lfs_file_size(&lfs, &file) => $MEDIUMSIZE;
  165. lfs_size_t size = strlen("bald");
  166. for (lfs_off_t j = 0; j < $MEDIUMSIZE; j += size) {
  167. lfs_file_read(&lfs, &file, buffer, size) => size;
  168. memcmp(buffer, "bald", size) => 0;
  169. }
  170. lfs_file_read(&lfs, &file, buffer, size) => 0;
  171. lfs_file_close(&lfs, &file) => 0;
  172. lfs_unmount(&lfs) => 0;
  173. TEST
  174. # More aggressive general truncation tests
  175. truncate_test() {
  176. STARTSIZES="$1"
  177. STARTSEEKS="$2"
  178. HOTSIZES="$3"
  179. COLDSIZES="$4"
  180. scripts/test.py << TEST
  181. static const lfs_off_t startsizes[] = {$STARTSIZES};
  182. static const lfs_off_t startseeks[] = {$STARTSEEKS};
  183. static const lfs_off_t hotsizes[] = {$HOTSIZES};
  184. lfs_mount(&lfs, &cfg) => 0;
  185. for (unsigned i = 0; i < sizeof(startsizes)/sizeof(startsizes[0]); i++) {
  186. sprintf(path, "hairyhead%d", i);
  187. lfs_file_open(&lfs, &file, path,
  188. LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
  189. strcpy((char*)buffer, "hair");
  190. lfs_size_t size = strlen((char*)buffer);
  191. for (lfs_off_t j = 0; j < startsizes[i]; j += size) {
  192. lfs_file_write(&lfs, &file, buffer, size) => size;
  193. }
  194. lfs_file_size(&lfs, &file) => startsizes[i];
  195. if (startseeks[i] != startsizes[i]) {
  196. lfs_file_seek(&lfs, &file,
  197. startseeks[i], LFS_SEEK_SET) => startseeks[i];
  198. }
  199. lfs_file_truncate(&lfs, &file, hotsizes[i]) => 0;
  200. lfs_file_size(&lfs, &file) => hotsizes[i];
  201. lfs_file_close(&lfs, &file) => 0;
  202. }
  203. lfs_unmount(&lfs) => 0;
  204. TEST
  205. scripts/test.py << TEST
  206. static const lfs_off_t startsizes[] = {$STARTSIZES};
  207. static const lfs_off_t hotsizes[] = {$HOTSIZES};
  208. static const lfs_off_t coldsizes[] = {$COLDSIZES};
  209. lfs_mount(&lfs, &cfg) => 0;
  210. for (unsigned i = 0; i < sizeof(startsizes)/sizeof(startsizes[0]); i++) {
  211. sprintf(path, "hairyhead%d", i);
  212. lfs_file_open(&lfs, &file, path, LFS_O_RDWR) => 0;
  213. lfs_file_size(&lfs, &file) => hotsizes[i];
  214. lfs_size_t size = strlen("hair");
  215. lfs_off_t j = 0;
  216. for (; j < startsizes[i] && j < hotsizes[i]; j += size) {
  217. lfs_file_read(&lfs, &file, buffer, size) => size;
  218. memcmp(buffer, "hair", size) => 0;
  219. }
  220. for (; j < hotsizes[i]; j += size) {
  221. lfs_file_read(&lfs, &file, buffer, size) => size;
  222. memcmp(buffer, "\0\0\0\0", size) => 0;
  223. }
  224. lfs_file_truncate(&lfs, &file, coldsizes[i]) => 0;
  225. lfs_file_size(&lfs, &file) => coldsizes[i];
  226. lfs_file_close(&lfs, &file) => 0;
  227. }
  228. lfs_unmount(&lfs) => 0;
  229. TEST
  230. scripts/test.py << TEST
  231. static const lfs_off_t startsizes[] = {$STARTSIZES};
  232. static const lfs_off_t hotsizes[] = {$HOTSIZES};
  233. static const lfs_off_t coldsizes[] = {$COLDSIZES};
  234. lfs_mount(&lfs, &cfg) => 0;
  235. for (unsigned i = 0; i < sizeof(startsizes)/sizeof(startsizes[0]); i++) {
  236. sprintf(path, "hairyhead%d", i);
  237. lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
  238. lfs_file_size(&lfs, &file) => coldsizes[i];
  239. lfs_size_t size = strlen("hair");
  240. lfs_off_t j = 0;
  241. for (; j < startsizes[i] && j < hotsizes[i] && j < coldsizes[i];
  242. j += size) {
  243. lfs_file_read(&lfs, &file, buffer, size) => size;
  244. memcmp(buffer, "hair", size) => 0;
  245. }
  246. for (; j < coldsizes[i]; j += size) {
  247. lfs_file_read(&lfs, &file, buffer, size) => size;
  248. memcmp(buffer, "\0\0\0\0", size) => 0;
  249. }
  250. lfs_file_close(&lfs, &file) => 0;
  251. }
  252. lfs_unmount(&lfs) => 0;
  253. TEST
  254. }
  255. echo "--- Cold shrinking truncate ---"
  256. truncate_test \
  257. "2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE" \
  258. "2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE" \
  259. "2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE" \
  260. " 0, $SMALLSIZE, $MEDIUMSIZE, $LARGESIZE, 2*$LARGESIZE"
  261. echo "--- Cold expanding truncate ---"
  262. truncate_test \
  263. " 0, $SMALLSIZE, $MEDIUMSIZE, $LARGESIZE, 2*$LARGESIZE" \
  264. " 0, $SMALLSIZE, $MEDIUMSIZE, $LARGESIZE, 2*$LARGESIZE" \
  265. " 0, $SMALLSIZE, $MEDIUMSIZE, $LARGESIZE, 2*$LARGESIZE" \
  266. "2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE"
  267. echo "--- Warm shrinking truncate ---"
  268. truncate_test \
  269. "2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE" \
  270. "2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE" \
  271. " 0, $SMALLSIZE, $MEDIUMSIZE, $LARGESIZE, 2*$LARGESIZE" \
  272. " 0, 0, 0, 0, 0"
  273. echo "--- Warm expanding truncate ---"
  274. truncate_test \
  275. " 0, $SMALLSIZE, $MEDIUMSIZE, $LARGESIZE, 2*$LARGESIZE" \
  276. " 0, $SMALLSIZE, $MEDIUMSIZE, $LARGESIZE, 2*$LARGESIZE" \
  277. "2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE" \
  278. "2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE"
  279. echo "--- Mid-file shrinking truncate ---"
  280. truncate_test \
  281. "2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE" \
  282. " $LARGESIZE, $LARGESIZE, $LARGESIZE, $LARGESIZE, $LARGESIZE" \
  283. " 0, $SMALLSIZE, $MEDIUMSIZE, $LARGESIZE, 2*$LARGESIZE" \
  284. " 0, 0, 0, 0, 0"
  285. echo "--- Mid-file expanding truncate ---"
  286. truncate_test \
  287. " 0, $SMALLSIZE, $MEDIUMSIZE, $LARGESIZE, 2*$LARGESIZE" \
  288. " 0, 0, $SMALLSIZE, $MEDIUMSIZE, $LARGESIZE" \
  289. "2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE" \
  290. "2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE, 2*$LARGESIZE"
  291. scripts/results.py