spooled.rs 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. #![deny(rust_2018_idioms)]
  2. use std::io::{Read, Seek, SeekFrom, Write};
  3. use tempfile::{spooled_tempfile, SpooledTempFile};
  4. #[test]
  5. fn test_automatic_rollover() {
  6. let mut t = spooled_tempfile(10);
  7. let mut buf = Vec::new();
  8. assert!(!t.is_rolled());
  9. assert_eq!(t.seek(SeekFrom::Current(0)).unwrap(), 0);
  10. assert_eq!(t.read_to_end(&mut buf).unwrap(), 0);
  11. assert_eq!(buf.as_slice(), b"");
  12. buf.clear();
  13. assert_eq!(t.write(b"abcde").unwrap(), 5);
  14. assert!(!t.is_rolled());
  15. assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0);
  16. assert_eq!(t.read_to_end(&mut buf).unwrap(), 5);
  17. assert_eq!(buf.as_slice(), b"abcde");
  18. assert_eq!(t.write(b"fghijklmno").unwrap(), 10);
  19. assert_eq!(t.seek(SeekFrom::Current(0)).unwrap(), 15);
  20. assert!(t.is_rolled());
  21. }
  22. #[test]
  23. fn test_explicit_rollover() {
  24. let mut t = SpooledTempFile::new(100);
  25. assert_eq!(t.write(b"abcdefghijklmnopqrstuvwxyz").unwrap(), 26);
  26. assert_eq!(t.seek(SeekFrom::Current(0)).unwrap(), 26);
  27. assert!(!t.is_rolled());
  28. // roll over explicitly
  29. assert!(t.roll().is_ok());
  30. assert!(t.is_rolled());
  31. assert_eq!(t.seek(SeekFrom::Current(0)).unwrap(), 26);
  32. let mut buf = Vec::new();
  33. assert_eq!(t.read_to_end(&mut buf).unwrap(), 0);
  34. assert_eq!(buf.as_slice(), b"");
  35. buf.clear();
  36. assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0);
  37. assert_eq!(t.read_to_end(&mut buf).unwrap(), 26);
  38. assert_eq!(buf.as_slice(), b"abcdefghijklmnopqrstuvwxyz");
  39. assert_eq!(t.seek(SeekFrom::Current(0)).unwrap(), 26);
  40. }
  41. // called by test_seek_{buffer, file}
  42. // assumes t is empty and offset is 0 to start
  43. fn test_seek(t: &mut SpooledTempFile) {
  44. assert_eq!(t.write(b"abcdefghijklmnopqrstuvwxyz").unwrap(), 26);
  45. assert_eq!(t.seek(SeekFrom::Current(0)).unwrap(), 26); // tell()
  46. assert_eq!(t.seek(SeekFrom::Current(-1)).unwrap(), 25);
  47. assert_eq!(t.seek(SeekFrom::Current(1)).unwrap(), 26);
  48. assert_eq!(t.seek(SeekFrom::Current(1)).unwrap(), 27);
  49. assert_eq!(t.seek(SeekFrom::Current(-27)).unwrap(), 0);
  50. assert!(t.seek(SeekFrom::Current(-1)).is_err());
  51. assert!(t.seek(SeekFrom::Current(-1245)).is_err());
  52. assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0);
  53. assert_eq!(t.seek(SeekFrom::Start(1)).unwrap(), 1);
  54. assert_eq!(t.seek(SeekFrom::Start(26)).unwrap(), 26);
  55. assert_eq!(t.seek(SeekFrom::Start(27)).unwrap(), 27);
  56. // // these are build errors
  57. // assert!(t.seek(SeekFrom::Start(-1)).is_err());
  58. // assert!(t.seek(SeekFrom::Start(-1000)).is_err());
  59. assert_eq!(t.seek(SeekFrom::End(0)).unwrap(), 26);
  60. assert_eq!(t.seek(SeekFrom::End(-1)).unwrap(), 25);
  61. assert_eq!(t.seek(SeekFrom::End(-26)).unwrap(), 0);
  62. assert!(t.seek(SeekFrom::End(-27)).is_err());
  63. assert!(t.seek(SeekFrom::End(-99)).is_err());
  64. assert_eq!(t.seek(SeekFrom::End(1)).unwrap(), 27);
  65. assert_eq!(t.seek(SeekFrom::End(1)).unwrap(), 27);
  66. }
  67. #[test]
  68. fn test_seek_buffer() {
  69. let mut t = spooled_tempfile(100);
  70. test_seek(&mut t);
  71. }
  72. #[test]
  73. fn test_seek_file() {
  74. let mut t = SpooledTempFile::new(10);
  75. test_seek(&mut t);
  76. }
  77. fn test_seek_read(t: &mut SpooledTempFile) {
  78. assert_eq!(t.write(b"abcdefghijklmnopqrstuvwxyz").unwrap(), 26);
  79. let mut buf = Vec::new();
  80. // we're at the end
  81. assert_eq!(t.read_to_end(&mut buf).unwrap(), 0);
  82. assert_eq!(buf.as_slice(), b"");
  83. buf.clear();
  84. // seek to start, read whole thing
  85. assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0);
  86. assert_eq!(t.read_to_end(&mut buf).unwrap(), 26);
  87. assert_eq!(buf.as_slice(), b"abcdefghijklmnopqrstuvwxyz");
  88. buf.clear();
  89. // now we're at the end again
  90. assert_eq!(t.seek(SeekFrom::Current(0)).unwrap(), 26); // tell()
  91. assert_eq!(t.read_to_end(&mut buf).unwrap(), 0);
  92. assert_eq!(buf.as_slice(), b"");
  93. buf.clear();
  94. // seek to somewhere in the middle, read a bit
  95. assert_eq!(t.seek(SeekFrom::Start(5)).unwrap(), 5);
  96. let mut buf = [0; 5];
  97. assert!(t.read_exact(&mut buf).is_ok());
  98. assert_eq!(buf, *b"fghij");
  99. // read again from current spot
  100. assert_eq!(t.seek(SeekFrom::Current(0)).unwrap(), 10); // tell()
  101. assert!(t.read_exact(&mut buf).is_ok());
  102. assert_eq!(buf, *b"klmno");
  103. let mut buf = [0; 15];
  104. // partial read
  105. assert_eq!(t.read(&mut buf).unwrap(), 11);
  106. assert_eq!(buf[0..11], *b"pqrstuvwxyz");
  107. // try to read off the end: UnexpectedEof
  108. assert!(t.read_exact(&mut buf).is_err());
  109. }
  110. #[test]
  111. fn test_seek_read_buffer() {
  112. let mut t = spooled_tempfile(100);
  113. test_seek_read(&mut t);
  114. }
  115. #[test]
  116. fn test_seek_read_file() {
  117. let mut t = SpooledTempFile::new(10);
  118. test_seek_read(&mut t);
  119. }
  120. fn test_overwrite_middle(t: &mut SpooledTempFile) {
  121. assert_eq!(t.write(b"abcdefghijklmnopqrstuvwxyz").unwrap(), 26);
  122. assert_eq!(t.seek(SeekFrom::Start(10)).unwrap(), 10);
  123. assert_eq!(t.write(b"0123456789").unwrap(), 10);
  124. assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0);
  125. let mut buf = Vec::new();
  126. assert_eq!(t.read_to_end(&mut buf).unwrap(), 26);
  127. assert_eq!(buf.as_slice(), b"abcdefghij0123456789uvwxyz");
  128. }
  129. #[test]
  130. fn test_overwrite_middle_of_buffer() {
  131. let mut t = spooled_tempfile(100);
  132. test_overwrite_middle(&mut t);
  133. }
  134. #[test]
  135. fn test_overwrite_middle_of_file() {
  136. let mut t = SpooledTempFile::new(10);
  137. test_overwrite_middle(&mut t);
  138. }
  139. #[test]
  140. fn test_overwrite_and_extend_buffer() {
  141. let mut t = spooled_tempfile(100);
  142. assert_eq!(t.write(b"abcdefghijklmnopqrstuvwxyz").unwrap(), 26);
  143. assert_eq!(t.seek(SeekFrom::End(-5)).unwrap(), 21);
  144. assert_eq!(t.write(b"0123456789").unwrap(), 10);
  145. assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0);
  146. let mut buf = Vec::new();
  147. assert_eq!(t.read_to_end(&mut buf).unwrap(), 31);
  148. assert_eq!(buf.as_slice(), b"abcdefghijklmnopqrstu0123456789");
  149. assert!(!t.is_rolled());
  150. }
  151. #[test]
  152. fn test_overwrite_and_extend_rollover() {
  153. let mut t = SpooledTempFile::new(20);
  154. assert_eq!(t.write(b"abcdefghijklmno").unwrap(), 15);
  155. assert!(!t.is_rolled());
  156. assert_eq!(t.seek(SeekFrom::End(-5)).unwrap(), 10);
  157. assert_eq!(t.seek(SeekFrom::Current(0)).unwrap(), 10); // tell()
  158. assert!(!t.is_rolled());
  159. assert_eq!(t.write(b"0123456789)!@#$%^&*(").unwrap(), 20);
  160. assert!(t.is_rolled());
  161. assert_eq!(t.seek(SeekFrom::Current(0)).unwrap(), 30); // tell()
  162. let mut buf = Vec::new();
  163. assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0);
  164. assert_eq!(t.read_to_end(&mut buf).unwrap(), 30);
  165. assert_eq!(buf.as_slice(), b"abcdefghij0123456789)!@#$%^&*(");
  166. }
  167. fn test_sparse(t: &mut SpooledTempFile) {
  168. assert_eq!(t.write(b"abcde").unwrap(), 5);
  169. assert_eq!(t.seek(SeekFrom::Current(5)).unwrap(), 10);
  170. assert_eq!(t.write(b"klmno").unwrap(), 5);
  171. assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0);
  172. let mut buf = Vec::new();
  173. assert_eq!(t.read_to_end(&mut buf).unwrap(), 15);
  174. assert_eq!(buf.as_slice(), b"abcde\0\0\0\0\0klmno");
  175. }
  176. #[test]
  177. fn test_sparse_buffer() {
  178. let mut t = spooled_tempfile(100);
  179. test_sparse(&mut t);
  180. }
  181. #[test]
  182. fn test_sparse_file() {
  183. let mut t = SpooledTempFile::new(1);
  184. test_sparse(&mut t);
  185. }
  186. #[test]
  187. fn test_sparse_write_rollover() {
  188. let mut t = spooled_tempfile(10);
  189. assert_eq!(t.write(b"abcde").unwrap(), 5);
  190. assert!(!t.is_rolled());
  191. assert_eq!(t.seek(SeekFrom::Current(5)).unwrap(), 10);
  192. assert!(!t.is_rolled());
  193. assert_eq!(t.write(b"klmno").unwrap(), 5);
  194. assert!(t.is_rolled());
  195. assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0);
  196. let mut buf = Vec::new();
  197. assert_eq!(t.read_to_end(&mut buf).unwrap(), 15);
  198. assert_eq!(buf.as_slice(), b"abcde\0\0\0\0\0klmno");
  199. }
  200. fn test_set_len(t: &mut SpooledTempFile) {
  201. let mut buf: Vec<u8> = Vec::new();
  202. assert_eq!(t.write(b"abcdefghijklmnopqrstuvwxyz").unwrap(), 26);
  203. // truncate to 10 bytes
  204. assert!(t.set_len(10).is_ok());
  205. // position should not have moved
  206. assert_eq!(t.seek(SeekFrom::Current(0)).unwrap(), 26); // tell()
  207. assert_eq!(t.read_to_end(&mut buf).unwrap(), 0);
  208. assert_eq!(buf.as_slice(), b"");
  209. assert_eq!(t.seek(SeekFrom::Current(0)).unwrap(), 26); // tell()
  210. buf.clear();
  211. // read whole thing
  212. assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0);
  213. assert_eq!(t.read_to_end(&mut buf).unwrap(), 10);
  214. assert_eq!(buf.as_slice(), b"abcdefghij");
  215. buf.clear();
  216. // set_len to expand beyond the end
  217. assert!(t.set_len(40).is_ok());
  218. assert_eq!(t.seek(SeekFrom::Current(0)).unwrap(), 10); // tell()
  219. assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0);
  220. assert_eq!(t.read_to_end(&mut buf).unwrap(), 40);
  221. assert_eq!(
  222. buf.as_slice(),
  223. &b"abcdefghij\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"[..]
  224. );
  225. }
  226. #[test]
  227. fn test_set_len_buffer() {
  228. let mut t = spooled_tempfile(100);
  229. test_set_len(&mut t);
  230. }
  231. #[test]
  232. fn test_set_len_file() {
  233. let mut t = spooled_tempfile(100);
  234. test_set_len(&mut t);
  235. }
  236. #[test]
  237. fn test_set_len_rollover() {
  238. let mut buf: Vec<u8> = Vec::new();
  239. let mut t = spooled_tempfile(10);
  240. assert_eq!(t.write(b"abcde").unwrap(), 5);
  241. assert!(!t.is_rolled());
  242. assert_eq!(t.seek(SeekFrom::Current(0)).unwrap(), 5); // tell()
  243. assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0);
  244. assert_eq!(t.read_to_end(&mut buf).unwrap(), 5);
  245. assert_eq!(buf.as_slice(), b"abcde");
  246. assert_eq!(t.seek(SeekFrom::Current(0)).unwrap(), 5); // tell()
  247. buf.clear();
  248. assert!(t.set_len(20).is_ok());
  249. assert!(t.is_rolled());
  250. assert_eq!(t.seek(SeekFrom::Current(0)).unwrap(), 5); // tell()
  251. assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0);
  252. assert_eq!(t.read_to_end(&mut buf).unwrap(), 20);
  253. assert_eq!(buf.as_slice(), b"abcde\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
  254. }