@@ -81,6 +81,10 @@ final class FileOperationsTest: XCTestCase {
8181 _ = try fd. duplicate ( as: FileDescriptor ( rawValue: 42 ) ,
8282 retryOnInterrupt: retryOnInterrupt)
8383 } ,
84+
85+ MockTestCase ( name: " ftruncate " , . interruptable, rawFD, 42 ) { retryOnInterrupt in
86+ _ = try fd. resize ( to: 42 , retryOnInterrupt: retryOnInterrupt)
87+ } ,
8488 ]
8589
8690 for test in syscallTestCases { test. runAllTests ( ) }
@@ -160,5 +164,49 @@ final class FileOperationsTest: XCTestCase {
160164 issue26. runAllTests ( )
161165
162166 }
167+
168+ #if !os(Windows)
169+ func testResizeFile( ) throws {
170+ let fd = try FileDescriptor . open ( " /tmp/ \( UUID ( ) . uuidString) .txt " , . readWrite, options: [ . create, . truncate] , permissions: . ownerReadWrite)
171+ try fd. closeAfter {
172+ // File should be empty initially.
173+ XCTAssertEqual ( try fd. fileSize ( ) , 0 )
174+ // Write 3 bytes.
175+ try fd. writeAll ( " abc " . utf8)
176+ // File should now be 3 bytes.
177+ XCTAssertEqual ( try fd. fileSize ( ) , 3 )
178+ // Resize to 6 bytes.
179+ try fd. resize ( to: 6 )
180+ // File should now be 6 bytes.
181+ XCTAssertEqual ( try fd. fileSize ( ) , 6 )
182+ // Read in the 6 bytes.
183+ let readBytes = try Array < UInt8 > ( unsafeUninitializedCapacity: 6 ) { ( buf, count) in
184+ try fd. seek ( offset: 0 , from: . start)
185+ // Should have read all 6 bytes.
186+ count = try fd. read ( into: UnsafeMutableRawBufferPointer ( buf) )
187+ XCTAssertEqual ( count, 6 )
188+ }
189+ // First 3 bytes should be unaffected by resize.
190+ XCTAssertEqual ( Array ( readBytes [ ..< 3 ] ) , Array ( " abc " . utf8) )
191+ // Extension should be padded with zeros.
192+ XCTAssertEqual ( Array ( readBytes [ 3 ... ] ) , Array ( repeating: 0 , count: 3 ) )
193+ // File should still be 6 bytes.
194+ XCTAssertEqual ( try fd. fileSize ( ) , 6 )
195+ // Resize to 2 bytes.
196+ try fd. resize ( to: 2 )
197+ // File should now be 2 bytes.
198+ XCTAssertEqual ( try fd. fileSize ( ) , 2 )
199+ // Read in file with a buffer big enough for 6 bytes.
200+ let readBytesAfterTruncation = try Array < UInt8 > ( unsafeUninitializedCapacity: 6 ) { ( buf, count) in
201+ try fd. seek ( offset: 0 , from: . start)
202+ count = try fd. read ( into: UnsafeMutableRawBufferPointer ( buf) )
203+ // Should only have read 2 bytes.
204+ XCTAssertEqual ( count, 2 )
205+ }
206+ // Written content was trunctated.
207+ XCTAssertEqual ( readBytesAfterTruncation, Array ( " ab " . utf8) )
208+ }
209+ }
210+ #endif
163211}
164212
0 commit comments