mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Update core:io tests
- Relax return value requirements on errors. Only the error is checked, as there are multiple conflicting return styles throughout the `os` API. Some return the error along with `0`, `-1`, or another value. This can be smoothed out later. - Test `os2` files now. - No longer test streams after closing; this is considered similar to a use-after-free in `os2`.
This commit is contained in:
@@ -4,6 +4,7 @@ import "core:bytes"
|
|||||||
import "core:io"
|
import "core:io"
|
||||||
import "core:log"
|
import "core:log"
|
||||||
import "core:os"
|
import "core:os"
|
||||||
|
import "core:os/os2"
|
||||||
import "core:strings"
|
import "core:strings"
|
||||||
import "core:testing"
|
import "core:testing"
|
||||||
|
|
||||||
@@ -34,7 +35,7 @@ _test_stream :: proc(
|
|||||||
// Do some basic Seek sanity testing.
|
// Do some basic Seek sanity testing.
|
||||||
if .Seek in mode_set {
|
if .Seek in mode_set {
|
||||||
pos, err := io.seek(stream, 0, io.Seek_From(-1))
|
pos, err := io.seek(stream, 0, io.Seek_From(-1))
|
||||||
testing.expectf(t, pos == 0 && err == .Invalid_Whence,
|
testing.expectf(t, err == .Invalid_Whence,
|
||||||
"Seek(-1) didn't fail with Invalid_Whence: %v, %v", pos, err, loc = loc) or_return
|
"Seek(-1) didn't fail with Invalid_Whence: %v, %v", pos, err, loc = loc) or_return
|
||||||
|
|
||||||
pos, err = io.seek(stream, 0, .Start)
|
pos, err = io.seek(stream, 0, .Start)
|
||||||
@@ -46,11 +47,11 @@ _test_stream :: proc(
|
|||||||
"Seek Current isn't 0 at the start: %v, %v", pos, err, loc = loc) or_return
|
"Seek Current isn't 0 at the start: %v, %v", pos, err, loc = loc) or_return
|
||||||
|
|
||||||
pos, err = io.seek(stream, -1, .Start)
|
pos, err = io.seek(stream, -1, .Start)
|
||||||
testing.expectf(t, pos == 0 && err == .Invalid_Offset,
|
testing.expectf(t, err == .Invalid_Offset,
|
||||||
"Seek Start-1 wasn't Invalid_Offset: %v, %v", pos, err, loc = loc) or_return
|
"Seek Start-1 wasn't Invalid_Offset: %v, %v", pos, err, loc = loc) or_return
|
||||||
|
|
||||||
pos, err = io.seek(stream, -1, .Current)
|
pos, err = io.seek(stream, -1, .Current)
|
||||||
testing.expectf(t, pos == 0 && err == .Invalid_Offset,
|
testing.expectf(t, err == .Invalid_Offset,
|
||||||
"Seek Current-1 wasn't Invalid_Offset: %v, %v", pos, err, loc = loc) or_return
|
"Seek Current-1 wasn't Invalid_Offset: %v, %v", pos, err, loc = loc) or_return
|
||||||
|
|
||||||
pos, err = io.seek(stream, 0, .End)
|
pos, err = io.seek(stream, 0, .End)
|
||||||
@@ -107,7 +108,7 @@ _test_stream :: proc(
|
|||||||
// Test empty streams and EOF.
|
// Test empty streams and EOF.
|
||||||
one_buf: [1]u8
|
one_buf: [1]u8
|
||||||
bytes_read, err := io.read_at(stream, one_buf[:], size)
|
bytes_read, err := io.read_at(stream, one_buf[:], size)
|
||||||
testing.expectf(t, bytes_read == 0 && err == .EOF,
|
testing.expectf(t, err == .EOF,
|
||||||
"Read_At at end of stream failed: %v, %v", bytes_read, err, loc = loc) or_return
|
"Read_At at end of stream failed: %v, %v", bytes_read, err, loc = loc) or_return
|
||||||
|
|
||||||
// Make sure size is still sane.
|
// Make sure size is still sane.
|
||||||
@@ -172,7 +173,7 @@ _test_stream :: proc(
|
|||||||
// Test empty streams and EOF.
|
// Test empty streams and EOF.
|
||||||
one_buf: [1]u8
|
one_buf: [1]u8
|
||||||
bytes_read, err := io.read(stream, one_buf[:])
|
bytes_read, err := io.read(stream, one_buf[:])
|
||||||
testing.expectf(t, bytes_read == 0 && err == .EOF,
|
testing.expectf(t, err == .EOF,
|
||||||
"Read at end of stream failed: %v, %v", bytes_read, err, loc = loc) or_return
|
"Read at end of stream failed: %v, %v", bytes_read, err, loc = loc) or_return
|
||||||
|
|
||||||
if !resets_on_empty && .Size in mode_set {
|
if !resets_on_empty && .Size in mode_set {
|
||||||
@@ -320,49 +321,6 @@ _test_stream :: proc(
|
|||||||
close_err := io.close(stream)
|
close_err := io.close(stream)
|
||||||
testing.expectf(t, close_err == nil, "stream failed to Close: %v", close_err, loc = loc) or_return
|
testing.expectf(t, close_err == nil, "stream failed to Close: %v", close_err, loc = loc) or_return
|
||||||
passed += { .Close }
|
passed += { .Close }
|
||||||
|
|
||||||
// TODO(Feoramund): The OS<->IO interface will need updating for more
|
|
||||||
// specific error messages.
|
|
||||||
//
|
|
||||||
// This test will catch it when they start using them, but so long as
|
|
||||||
// they actually error, it should be okay for now.
|
|
||||||
//
|
|
||||||
// .EOF would be a better message for all of these.
|
|
||||||
|
|
||||||
if .Seek in mode_set {
|
|
||||||
pos, err := io.seek(stream, 0, .Start)
|
|
||||||
|
|
||||||
testing.expectf(t, pos == 0 && err == .Invalid_Offset,
|
|
||||||
"Seek after Close unexpected output: pos<%v>, %v", pos, err, loc = loc) or_return
|
|
||||||
}
|
|
||||||
|
|
||||||
if .Read in mode_set {
|
|
||||||
eof_buf: [1]u8
|
|
||||||
bytes_read, err := io.read(stream, eof_buf[:])
|
|
||||||
testing.expectf(t, bytes_read == 0 && err == .Unknown,
|
|
||||||
"Read after Close unexpected output: bytes_read<%v>, %v", bytes_read, err, loc = loc) or_return
|
|
||||||
}
|
|
||||||
|
|
||||||
if size > 0 && .Read_At in mode_set {
|
|
||||||
eof_buf: [1]u8
|
|
||||||
bytes_read, err := io.read_at(stream, eof_buf[:], 0)
|
|
||||||
testing.expectf(t, bytes_read == 0 && err == .Unknown,
|
|
||||||
"Read_At after Close unexpected output: bytes_read<%v>, %v", bytes_read, err, loc = loc) or_return
|
|
||||||
}
|
|
||||||
|
|
||||||
if .Write in mode_set {
|
|
||||||
eof_buf: [1]u8 = {'Z'}
|
|
||||||
bytes_written, err := io.write(stream, eof_buf[:])
|
|
||||||
testing.expectf(t, bytes_written == 0 && err == .Unknown,
|
|
||||||
"Write after Close unexpected output: bytes_written<%v>, %v", bytes_written, err, loc = loc) or_return
|
|
||||||
}
|
|
||||||
|
|
||||||
if .Write_At in mode_set {
|
|
||||||
eof_buf: [1]u8 = {'Z'}
|
|
||||||
bytes_written, err := io.write_at(stream, eof_buf[:], 0)
|
|
||||||
testing.expectf(t, bytes_written == 0 && err == .Unknown,
|
|
||||||
"Write after Close unexpected output: bytes_written<%v>, %v", bytes_written, err, loc = loc) or_return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if do_destroy && .Destroy in mode_set {
|
if do_destroy && .Destroy in mode_set {
|
||||||
@@ -547,3 +505,41 @@ test_os_file_stream :: proc(t: ^testing.T) {
|
|||||||
|
|
||||||
log.debugf("%#v", results)
|
log.debugf("%#v", results)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test
|
||||||
|
test_os2_file_stream :: proc(t: ^testing.T) {
|
||||||
|
defer if !testing.failed(t) {
|
||||||
|
testing.expect_value(t, os2.remove(TEMPORARY_FILENAME), nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
buf: [32]u8
|
||||||
|
for i in 0..<u8(len(buf)) {
|
||||||
|
buf[i] = 'A' + i
|
||||||
|
}
|
||||||
|
|
||||||
|
TEMPORARY_FILENAME :: "test_core_io_os2_file_stream"
|
||||||
|
|
||||||
|
fd, open_err := os2.open(TEMPORARY_FILENAME, {.Read, .Write, .Create, .Trunc})
|
||||||
|
if !testing.expectf(t, open_err == nil, "error on opening %q: %v", TEMPORARY_FILENAME, open_err) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
stream := os2.to_stream(fd)
|
||||||
|
|
||||||
|
bytes_written, write_err := io.write(stream, buf[:])
|
||||||
|
if !testing.expectf(t, bytes_written == len(buf) && write_err == nil,
|
||||||
|
"failed to Write initial buffer: bytes_written<%v> != len_buf<%v>, %v", bytes_written, len(buf), write_err) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
flush_err := io.flush(stream)
|
||||||
|
if !testing.expectf(t, flush_err == nil,
|
||||||
|
"failed to Flush initial buffer: %v", write_err) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// os2 file stream proc close and destroy are the same.
|
||||||
|
results, _ := _test_stream(t, stream, buf[:], do_destroy = false)
|
||||||
|
|
||||||
|
log.debugf("%#v", results)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user