sonar

Scan files at memory bandwidth speed.
Log | Files | Refs

volume_other_test.odin (3227B)


      1 #+build !windows
      2 package ntfs
      3 
      4 import "core:fmt"
      5 import "core:os"
      6 import "core:slice"
      7 import "core:testing"
      8 
      9 // A volume is a block device or a file holding an image of one, and both open the
     10 // same way, so a file standing in for an image exercises every path here without a
     11 // device to read or the rights to read it.
     12 @(private = "file")
     13 image :: proc(t: ^testing.T, size: int) -> (path: string, content: []byte) {
     14 	content = make([]byte, size, context.temp_allocator)
     15 	for i in 0 ..< size {
     16 		content[i] = byte(i * 7 + 1)
     17 	}
     18 	dir, dir_err := os.temp_directory(context.temp_allocator)
     19 	testing.expect(t, dir_err == nil, "no temp directory")
     20 	path = fmt.tprintf("%s/sonar_volume_%d.img", dir, size)
     21 	testing.expect(t, os.write_entire_file(path, content) == nil, "could not write the image")
     22 	return
     23 }
     24 
     25 @(private = "file")
     26 discard :: proc(path: string) {
     27 	_ = os.remove(path)
     28 }
     29 
     30 @(test)
     31 test_volume_read_at_offsets :: proc(t: ^testing.T) {
     32 	path, content := image(t, 8192)
     33 	defer discard(path)
     34 
     35 	v, err := volume_open(path)
     36 	testing.expect_value(t, err, Error.None)
     37 	defer volume_close(&v)
     38 
     39 	// A whole read, a tail read, an aligned middle and a single byte: the reader
     40 	// works in whole clusters, so every offset it asks for is one of these shapes.
     41 	spans := [][2]int{{0, 8192}, {4096, 4096}, {512, 1024}, {8191, 1}}
     42 	for span in spans {
     43 		off, size := span[0], span[1]
     44 		buf := make([]byte, size, context.temp_allocator)
     45 		testing.expect_value(t, volume_read_at(&v, buf, u64(off)), Error.None)
     46 		testing.expectf(
     47 			t,
     48 			slice.equal(buf, content[off:off + size]),
     49 			"wrong bytes at %d for %d",
     50 			off,
     51 			size,
     52 		)
     53 	}
     54 }
     55 
     56 @(test)
     57 test_volume_read_past_the_end_is_short :: proc(t: ^testing.T) {
     58 	path, _ := image(t, 1024)
     59 	defer discard(path)
     60 
     61 	v, err := volume_open(path)
     62 	testing.expect_value(t, err, Error.None)
     63 	defer volume_close(&v)
     64 
     65 	// Asking for more than is there has to say so, or the tail of the buffer would
     66 	// parse as records that were never read.
     67 	buf := make([]byte, 4096, context.temp_allocator)
     68 	testing.expect_value(t, volume_read_at(&v, buf, 0), Error.Short_Read)
     69 	testing.expect_value(t, volume_read_at(&v, buf[:1], 1024), Error.Short_Read)
     70 }
     71 
     72 @(test)
     73 test_volume_clone_reads_independently :: proc(t: ^testing.T) {
     74 	path, content := image(t, 2048)
     75 	defer discard(path)
     76 
     77 	v, err := volume_open(path)
     78 	testing.expect_value(t, err, Error.None)
     79 	defer volume_close(&v)
     80 
     81 	c, clone_err := volume_clone(&v)
     82 	testing.expect_value(t, clone_err, Error.None)
     83 
     84 	buf := make([]byte, 16, context.temp_allocator)
     85 	testing.expect_value(t, volume_read_at(&c, buf, 100), Error.None)
     86 	testing.expect_value(t, buf[0], content[100])
     87 
     88 	// Closing a clone must leave the handle it was made from readable, or the first
     89 	// worker to finish would take the rest of them with it.
     90 	volume_close(&c)
     91 	testing.expect(t, c.file == nil, "a closed volume still holds a handle")
     92 	testing.expect_value(t, volume_read_at(&v, buf, 100), Error.None)
     93 	testing.expect_value(t, buf[0], content[100])
     94 }
     95 
     96 @(test)
     97 test_volume_open_missing_path :: proc(t: ^testing.T) {
     98 	v, err := volume_open("/nonexistent/sonar/volume.img")
     99 	testing.expect_value(t, err, Error.Open_Failed)
    100 	testing.expect(t, v.file == nil, "a failed open returned a handle")
    101 }