Multi-threading in tests, add more tests
This commit is contained in:
@@ -4,6 +4,7 @@ import "base:runtime"
|
|||||||
import "core:fmt"
|
import "core:fmt"
|
||||||
import "core:os"
|
import "core:os"
|
||||||
import "core:path/filepath"
|
import "core:path/filepath"
|
||||||
|
import "core:sort"
|
||||||
import "core:strings"
|
import "core:strings"
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
@@ -98,12 +99,14 @@ list_dir_queue :: proc(
|
|||||||
path := pop(queue)
|
path := pop(queue)
|
||||||
defer delete(path, queue^.allocator)
|
defer delete(path, queue^.allocator)
|
||||||
|
|
||||||
f := os.open(path, {.Read}) or_return
|
entries := os.read_all_directory_by_path(path, allocator) or_return
|
||||||
defer os.close(f)
|
|
||||||
|
|
||||||
entries := os.read_all_directory(f, allocator) or_return
|
|
||||||
defer os.file_info_slice_delete(entries, allocator)
|
defer os.file_info_slice_delete(entries, allocator)
|
||||||
|
|
||||||
|
// Improve determinism, as entries are explicitly returned unsorted by os.read_dir
|
||||||
|
sort.quick_sort_proc(entries, proc(a, b: os.File_Info) -> int {
|
||||||
|
return strings.compare(a.name, b.name)
|
||||||
|
})
|
||||||
|
|
||||||
// Reserve space for new entries, minor waste as directories are also counted.
|
// Reserve space for new entries, minor waste as directories are also counted.
|
||||||
reserve(result, len(result) + len(entries))
|
reserve(result, len(result) + len(entries))
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
mkdir -p build
|
mkdir -p build
|
||||||
|
|
||||||
odin test tests/ -collection:src=src -out:build/tests.bin \
|
odin test tests/ -collection:src=src -out:build/tests.bin \
|
||||||
-define:ODIN_TEST_THREADS=1 \
|
-define:ODIN_TEST_THREADS=0 \
|
||||||
-define:ODIN_TEST_TRACK_MEMORY=false \
|
-define:ODIN_TEST_TRACK_MEMORY=false \
|
||||||
-define:ODIN_TEST_RANDOM_SEED=1 \
|
-define:ODIN_TEST_RANDOM_SEED=1 \
|
||||||
"$@"
|
"$@"
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
package tests
|
|
||||||
|
|
||||||
import "core:os"
|
|
||||||
import "core:testing"
|
|
||||||
|
|
||||||
import "src:file"
|
|
||||||
|
|
||||||
@(test)
|
|
||||||
single_tiny_file :: proc(t: ^testing.T) {
|
|
||||||
// Arrange
|
|
||||||
|
|
||||||
create_file(t, "single_tiny_file", "hello world!")
|
|
||||||
|
|
||||||
// Act
|
|
||||||
|
|
||||||
wd, err := os.get_working_directory(context.allocator)
|
|
||||||
entries, err2 := file.list_dir_recursive_by_path(TEST_DIR, wd)
|
|
||||||
pack(t, 750)
|
|
||||||
delete_path(t, "")
|
|
||||||
read := read(t, "single_tiny_file")
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
|
|
||||||
testing.expect_value(t, read, "hello world!")
|
|
||||||
}
|
|
||||||
+71
-12
@@ -1,23 +1,78 @@
|
|||||||
package tests
|
package tests
|
||||||
|
|
||||||
|
import "core:fmt"
|
||||||
import "core:os"
|
import "core:os"
|
||||||
import "core:testing"
|
import "core:testing"
|
||||||
|
|
||||||
import "src:chunks"
|
import "src:chunks"
|
||||||
import "src:file"
|
import "src:file"
|
||||||
|
|
||||||
TEST_DIR :: "./build/tests"
|
TEST_INPUT_DIR :: "./build/tests/in"
|
||||||
TEST_OUTPUT_DIR :: "./build/out"
|
TEST_OUTPUT_DIR :: "./build/tests/out"
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
|
|
||||||
|
Test_State :: struct {
|
||||||
|
input_dir: string,
|
||||||
|
output_dir: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------
|
||||||
|
|
||||||
|
test_state_init :: proc(
|
||||||
|
t: ^testing.T,
|
||||||
|
allocator := context.allocator,
|
||||||
|
) -> Test_State {
|
||||||
|
ensure_dir(t, TEST_INPUT_DIR)
|
||||||
|
ensure_dir(t, TEST_OUTPUT_DIR)
|
||||||
|
|
||||||
|
temp_input_path, err := os.mkdir_temp(TEST_INPUT_DIR, "", allocator)
|
||||||
|
testing.expect(t, err == nil, os.error_string(err))
|
||||||
|
|
||||||
|
temp_output_path, err2 := os.mkdir_temp(TEST_OUTPUT_DIR, "", allocator)
|
||||||
|
testing.expect(t, err2 == nil, os.error_string(err2))
|
||||||
|
|
||||||
|
return Test_State {
|
||||||
|
input_dir = temp_input_path,
|
||||||
|
output_dir = temp_output_path,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test_state_destroy :: proc(
|
||||||
|
ts: ^Test_State,
|
||||||
|
t: ^testing.T,
|
||||||
|
allocator := context.allocator,
|
||||||
|
) {
|
||||||
|
if os.exists(ts.input_dir) {
|
||||||
|
err := os.remove_all(ts.input_dir)
|
||||||
|
testing.expect(t, err == nil, os.error_string(err))
|
||||||
|
}
|
||||||
|
delete(ts.input_dir, allocator)
|
||||||
|
|
||||||
|
if os.exists(ts.output_dir) {
|
||||||
|
err := os.remove_all(ts.output_dir)
|
||||||
|
testing.expect(t, err == nil, os.error_string(err))
|
||||||
|
}
|
||||||
|
delete(ts.output_dir, allocator)
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------
|
||||||
|
|
||||||
|
ensure_dir :: proc(t: ^testing.T, dir: string) {
|
||||||
|
if !os.exists(dir) {
|
||||||
|
err := os.make_directory_all(dir)
|
||||||
|
testing.expect(t, err == nil, os.error_string(err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
create_file :: proc(
|
create_file :: proc(
|
||||||
|
ts: ^Test_State,
|
||||||
t: ^testing.T,
|
t: ^testing.T,
|
||||||
path: string,
|
path: string,
|
||||||
content: string,
|
content: string,
|
||||||
allocator := context.allocator,
|
allocator := context.allocator,
|
||||||
) {
|
) {
|
||||||
relpath, err := os.join_path({TEST_DIR, path}, allocator)
|
relpath, err := os.join_path({ts.input_dir, path}, allocator)
|
||||||
testing.expect(t, err == nil, os.error_string(err))
|
testing.expect(t, err == nil, os.error_string(err))
|
||||||
defer delete(relpath, allocator)
|
defer delete(relpath, allocator)
|
||||||
|
|
||||||
@@ -36,36 +91,39 @@ create_file :: proc(
|
|||||||
}
|
}
|
||||||
|
|
||||||
delete_path :: proc(
|
delete_path :: proc(
|
||||||
|
ts: ^Test_State,
|
||||||
t: ^testing.T,
|
t: ^testing.T,
|
||||||
path: string,
|
path: string,
|
||||||
allocator := context.allocator,
|
allocator := context.allocator,
|
||||||
) {
|
) {
|
||||||
relpath, err := os.join_path({TEST_DIR, path}, allocator)
|
relpath, err := os.join_path({ts.input_dir, path}, allocator)
|
||||||
defer delete(relpath, allocator)
|
defer delete(relpath, allocator)
|
||||||
testing.expect(t, err == nil, os.error_string(err))
|
testing.expect(t, err == nil, os.error_string(err))
|
||||||
|
|
||||||
|
if os.exists(relpath) {
|
||||||
err2 := os.remove_all(relpath)
|
err2 := os.remove_all(relpath)
|
||||||
testing.expect(t, err2 == nil, os.error_string(err2))
|
testing.expect(t, err2 == nil, os.error_string(err2))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pack :: proc(t: ^testing.T, size: u64) {
|
pack :: proc(ts: ^Test_State, t: ^testing.T, size: u64) {
|
||||||
wd, err := os.get_working_directory(context.allocator)
|
wd, err := os.get_working_directory(context.allocator)
|
||||||
testing.expect(t, err == nil, os.error_string(err))
|
testing.expect(t, err == nil, os.error_string(err))
|
||||||
entries, err2 := file.list_dir_recursive_by_path(TEST_DIR, wd)
|
entries, err2 := file.list_dir_recursive_by_path(ts.input_dir, wd)
|
||||||
testing.expect(t, err2 == nil, file.format_error(err2))
|
testing.expect(t, err2 == nil, file.format_error(err2))
|
||||||
|
|
||||||
w := chunks.writer_init(cast(u64)len(entries))
|
w := chunks.writer_init(cast(u64)len(entries))
|
||||||
defer chunks.writer_destroy(&w)
|
defer chunks.writer_destroy(&w)
|
||||||
|
|
||||||
if os.exists(TEST_OUTPUT_DIR) {
|
if os.exists(ts.output_dir) {
|
||||||
err3 := os.remove_all(TEST_OUTPUT_DIR)
|
err3 := os.remove_all(ts.output_dir)
|
||||||
testing.expect(t, err3 == nil, os.error_string(err3))
|
testing.expect(t, err3 == nil, os.error_string(err3))
|
||||||
}
|
}
|
||||||
|
|
||||||
err4 := os.make_directory_all(TEST_OUTPUT_DIR) // fails if dir exists
|
err4 := os.make_directory_all(ts.output_dir) // fails if dir exists
|
||||||
testing.expect(t, err4 == nil, os.error_string(err4))
|
testing.expect(t, err4 == nil, os.error_string(err4))
|
||||||
|
|
||||||
output_file, err5 := os.open(TEST_OUTPUT_DIR, {.Read})
|
output_file, err5 := os.open(ts.output_dir, {.Read})
|
||||||
testing.expect(t, err5 == nil, os.error_string(err5))
|
testing.expect(t, err5 == nil, os.error_string(err5))
|
||||||
defer os.close(output_file)
|
defer os.close(output_file)
|
||||||
|
|
||||||
@@ -77,15 +135,16 @@ pack :: proc(t: ^testing.T, size: u64) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
read :: proc(
|
read :: proc(
|
||||||
|
ts: ^Test_State,
|
||||||
t: ^testing.T,
|
t: ^testing.T,
|
||||||
path: string,
|
path: string,
|
||||||
allocator := context.allocator,
|
allocator := context.allocator,
|
||||||
) -> string {
|
) -> string {
|
||||||
relpath, err := os.join_path({TEST_DIR, path}, allocator)
|
relpath, err := os.join_path({ts.input_dir, path}, allocator)
|
||||||
testing.expect(t, err == nil, os.error_string(err))
|
testing.expect(t, err == nil, os.error_string(err))
|
||||||
defer delete(relpath, allocator)
|
defer delete(relpath, allocator)
|
||||||
|
|
||||||
file, err2 := os.open(TEST_OUTPUT_DIR)
|
file, err2 := os.open(ts.output_dir)
|
||||||
testing.expect(t, err2 == nil, os.error_string(err2))
|
testing.expect(t, err2 == nil, os.error_string(err2))
|
||||||
defer os.close(file)
|
defer os.close(file)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
package tests
|
||||||
|
|
||||||
|
import "core:testing"
|
||||||
|
|
||||||
|
@(test)
|
||||||
|
single_tiny_file_read_from_chunk :: proc(t: ^testing.T) {
|
||||||
|
// Arrange
|
||||||
|
|
||||||
|
ts := test_state_init(t)
|
||||||
|
defer test_state_destroy(&ts, t)
|
||||||
|
|
||||||
|
delete_path(&ts, t, "")
|
||||||
|
create_file(&ts, t, "single_tiny_file", "hello world!")
|
||||||
|
pack(&ts, t, 750)
|
||||||
|
delete_path(&ts, t, "")
|
||||||
|
|
||||||
|
// Act
|
||||||
|
|
||||||
|
read := read(&ts, t, "single_tiny_file")
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
|
||||||
|
testing.expect_value(t, read, "hello world!")
|
||||||
|
}
|
||||||
|
|
||||||
|
@(test)
|
||||||
|
single_file_single_chunk_read_from_path :: proc(t: ^testing.T) {
|
||||||
|
// Arrange
|
||||||
|
|
||||||
|
ts := test_state_init(t)
|
||||||
|
defer test_state_destroy(&ts, t)
|
||||||
|
|
||||||
|
delete_path(&ts, t, "")
|
||||||
|
create_file(&ts, t, "single_tiny_file", "hello world!")
|
||||||
|
pack(&ts, t, 750)
|
||||||
|
delete_path(&ts, t, "")
|
||||||
|
create_file(&ts, t, "single_tiny_file", "hello world from path!")
|
||||||
|
|
||||||
|
// Act
|
||||||
|
|
||||||
|
read := read(&ts, t, "single_tiny_file")
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
|
||||||
|
testing.expect_value(t, read, "hello world from path!")
|
||||||
|
}
|
||||||
|
|
||||||
|
@(test)
|
||||||
|
multiple_files_single_chunk_read_from_chunk :: proc(t: ^testing.T) {
|
||||||
|
// Arrange
|
||||||
|
|
||||||
|
ts := test_state_init(t)
|
||||||
|
defer test_state_destroy(&ts, t)
|
||||||
|
|
||||||
|
delete_path(&ts, t, "")
|
||||||
|
create_file(&ts, t, "a", "hello a!")
|
||||||
|
create_file(&ts, t, "b", "hello b!")
|
||||||
|
create_file(&ts, t, "c", "hello c!")
|
||||||
|
pack(&ts, t, 1750)
|
||||||
|
delete_path(&ts, t, "")
|
||||||
|
|
||||||
|
// Act
|
||||||
|
|
||||||
|
a := read(&ts, t, "a")
|
||||||
|
b := read(&ts, t, "b")
|
||||||
|
c := read(&ts, t, "c")
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
|
||||||
|
testing.expect_value(t, a, "hello a!")
|
||||||
|
testing.expect_value(t, b, "hello b!")
|
||||||
|
testing.expect_value(t, c, "hello c!")
|
||||||
|
}
|
||||||
|
|
||||||
|
@(test)
|
||||||
|
multiple_files_single_chunk_read_from_path :: proc(t: ^testing.T) {
|
||||||
|
// Arrange
|
||||||
|
|
||||||
|
ts := test_state_init(t)
|
||||||
|
defer test_state_destroy(&ts, t)
|
||||||
|
|
||||||
|
delete_path(&ts, t, "")
|
||||||
|
create_file(&ts, t, "a", "hello a!")
|
||||||
|
create_file(&ts, t, "b", "hello b!")
|
||||||
|
create_file(&ts, t, "c", "hello c!")
|
||||||
|
pack(&ts, t, 1750)
|
||||||
|
delete_path(&ts, t, "")
|
||||||
|
create_file(&ts, t, "a", "hello a from path!")
|
||||||
|
create_file(&ts, t, "b", "hello b from path!")
|
||||||
|
create_file(&ts, t, "c", "hello c from path!")
|
||||||
|
|
||||||
|
// Act
|
||||||
|
|
||||||
|
a := read(&ts, t, "a")
|
||||||
|
b := read(&ts, t, "b")
|
||||||
|
c := read(&ts, t, "c")
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
|
||||||
|
testing.expect_value(t, a, "hello a from path!")
|
||||||
|
testing.expect_value(t, b, "hello b from path!")
|
||||||
|
testing.expect_value(t, c, "hello c from path!")
|
||||||
|
}
|
||||||
|
|
||||||
|
// @(test)
|
||||||
|
// blabla :: proc(t: ^testing.T) {
|
||||||
|
// // Arrange
|
||||||
|
//
|
||||||
|
// // Act
|
||||||
|
//
|
||||||
|
// // Assert
|
||||||
|
// }
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// v multiple files (path and chunk find)
|
||||||
|
// - nested file (path and chunk find)
|
||||||
|
// - not found in path
|
||||||
|
// - not found in path + chunk
|
||||||
Reference in New Issue
Block a user