261 lines
6.7 KiB
GLSL
Executable File
261 lines
6.7 KiB
GLSL
Executable File
#!/usr/bin/env -S v -n -w -gc none -no-retry-compilation -cc tcc -d use_openssl -enable-globals run
|
|
|
|
import os
|
|
import flag
|
|
import net
|
|
import time
|
|
|
|
|
|
// Check if Redis is available
|
|
fn check_redis() bool {
|
|
mut redis_available := false
|
|
mut sock := net.dial_tcp('127.0.0.1:6379') or { return false }
|
|
sock.close() or {}
|
|
return true
|
|
}
|
|
|
|
const redis_key_prefix = 'vtests'
|
|
|
|
// Set Redis key with expiration
|
|
fn redis_set(key string) ! {
|
|
mut sock := net.dial_tcp('127.0.0.1:6379')!
|
|
defer { sock.close() or {} }
|
|
|
|
// SET key value EX seconds
|
|
cmd := 'SET ${redis_key_prefix}.${key} 1 EX 3600\r\n'
|
|
sock.write_string(cmd)!
|
|
}
|
|
|
|
// Check if key exists in Redis
|
|
fn redis_exists(key string) bool {
|
|
mut sock := net.dial_tcp('127.0.0.1:6379') or { return false }
|
|
defer { sock.close() or {} }
|
|
|
|
// EXISTS key
|
|
cmd := 'EXISTS ${redis_key_prefix}.${key}\r\n'
|
|
sock.write_string(cmd) or { return false }
|
|
|
|
response := sock.read_line()
|
|
return response.trim_space() == ':1'
|
|
}
|
|
|
|
// Delete Redis key
|
|
// fn redis_del(key string) ! {
|
|
// mut sock := net.dial_tcp('127.0.0.1:6379')!
|
|
// defer { sock.close() or {} }
|
|
|
|
// // DEL key
|
|
// cmd := 'DEL ${redis_key_prefix}.${key}\r\n'
|
|
// sock.write_string(cmd)!
|
|
// }
|
|
|
|
// Normalize a path for consistent handling
|
|
fn normalize_path(path string) string {
|
|
mut norm_path := os.abs_path(path)
|
|
norm_path = norm_path.replace('//', '/') // Remove any double slashes
|
|
return norm_path
|
|
}
|
|
|
|
// Get normalized and relative path
|
|
fn get_normalized_paths(path string, base_dir_norm string) (string, string) {
|
|
// base_dir_norm is already normalized
|
|
norm_path := normalize_path(path)
|
|
rel_path := norm_path.replace(base_dir_norm + '/', '')
|
|
return norm_path, rel_path
|
|
}
|
|
|
|
// Generate a Redis key from a path
|
|
fn get_redis_key(path string, base_dir string) string {
|
|
_, rel_path := get_normalized_paths(path, base_dir)
|
|
// Create consistent key format
|
|
return rel_path.replace('/', '_').trim('_').to_lower()
|
|
}
|
|
|
|
// Check if a file should be ignored or marked as error based on its path
|
|
fn process_test_file(path string, base_dir string, test_files_ignore []string, test_files_error []string, redis_available bool, mut tests_in_error []string)! {
|
|
// Get normalized paths
|
|
norm_path, rel_path := get_normalized_paths(path, base_dir)
|
|
|
|
mut should_ignore := false
|
|
mut is_error := false
|
|
|
|
if ! path.to_lower().contains("_test.v"){
|
|
return
|
|
}
|
|
|
|
// Check if any ignore pattern matches the path
|
|
for pattern in test_files_ignore {
|
|
if pattern.trim_space() != '' && rel_path.contains(pattern) {
|
|
should_ignore = true
|
|
break
|
|
}
|
|
}
|
|
|
|
// Check if any error pattern matches the path
|
|
for pattern in test_files_error {
|
|
if pattern.trim_space() != '' && rel_path.contains(pattern) {
|
|
is_error = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !should_ignore && !is_error {
|
|
dotest(norm_path, base_dir, redis_available)!
|
|
} else {
|
|
println('Ignoring test: ${rel_path}')
|
|
if !should_ignore {
|
|
tests_in_error << rel_path
|
|
}
|
|
}
|
|
}
|
|
|
|
fn dotest(path string, base_dir string, use_redis bool)! {
|
|
norm_path, _ := get_normalized_paths(path, base_dir)
|
|
|
|
if use_redis {
|
|
redis_key := get_redis_key(norm_path, base_dir)
|
|
|
|
// Check if test result is cached
|
|
if redis_exists(redis_key) {
|
|
println('Test cached (passed): ${path}')
|
|
return
|
|
}
|
|
}
|
|
|
|
cmd := 'v -stats -enable-globals -n -w -gc none -no-retry-compilation -cc tcc test ${norm_path}'
|
|
println(cmd)
|
|
result := os.execute(cmd)
|
|
eprintln(result)
|
|
if result.exit_code != 0 {
|
|
eprintln('Test failed: ${path}')
|
|
eprintln(result.output)
|
|
exit(1)
|
|
}
|
|
|
|
if use_redis {
|
|
redis_key := get_redis_key(norm_path, base_dir)
|
|
redis_set(redis_key) or {
|
|
eprintln('Failed to cache test result: ${err}')
|
|
}
|
|
}
|
|
|
|
println('Test passed: ${path}')
|
|
}
|
|
|
|
|
|
/////////////////////////
|
|
/////////////////////////
|
|
|
|
|
|
abs_dir_of_script := dir(@FILE)
|
|
norm_dir_of_script := normalize_path(abs_dir_of_script)
|
|
os.chdir(abs_dir_of_script) or { panic(err) }
|
|
|
|
|
|
|
|
// can use // inside this list as well to ignore temporary certain dirs, useful for testing
|
|
tests := "
|
|
lib/data
|
|
lib/osal
|
|
lib/lang
|
|
lib/code
|
|
lib/clients
|
|
// lib/crypt
|
|
lib/core
|
|
lib/develop
|
|
"
|
|
|
|
tests_ignore := "
|
|
|
|
"
|
|
|
|
tests_error := "
|
|
net_test.v
|
|
osal/package_test.v
|
|
systemd_process_test.v
|
|
rpc_test.v
|
|
screen_test.v
|
|
tmux_session_test.v
|
|
tmux_window_test.v
|
|
tmux_test.v
|
|
startupmanager_test.v
|
|
python_test.v
|
|
flist_test.v
|
|
mnemonic_test.v
|
|
decode_test.v
|
|
codegen_test.v
|
|
generate_test.v
|
|
dbfs_test.v
|
|
namedb_test.v
|
|
timetools_test.v
|
|
markdownparser/link_test.v
|
|
markdownparser/link_def_test.v
|
|
markdownparser/char_parser_test.v
|
|
markdownparser/action_test.v
|
|
markdownparser/elements/char_parser_test.v
|
|
markdownparser/markdown_test.v
|
|
markdownparser/list_test.v
|
|
markdownparser/table_test.v
|
|
ourdb/lookup_test.v
|
|
ourdb/lookup_id_test.v
|
|
ourdb/db_test.v
|
|
ourdb/lookup_location_test.v
|
|
encoderhero/encoder_test.v
|
|
encoderhero/decoder_test.v
|
|
code/codeparser
|
|
clients/meilisearch
|
|
clients/zdb
|
|
"
|
|
|
|
|
|
// Split tests into array and remove empty lines
|
|
test_files := tests.split('\n').filter(it.trim_space() != '')
|
|
test_files_ignore := tests_ignore.split('\n').filter(it.trim_space() != '')
|
|
test_files_error := tests_error.split('\n').filter(it.trim_space() != '')
|
|
|
|
mut tests_in_error := []string{}
|
|
|
|
|
|
// Check if Redis is available
|
|
redis_available := check_redis()
|
|
if redis_available {
|
|
println('Redis cache enabled')
|
|
} else {
|
|
println('Redis not available, running without cache')
|
|
}
|
|
|
|
// Run each test with proper v command flags
|
|
for test in test_files {
|
|
if test.trim_space() == '' || test.trim_space().starts_with("//") || test.trim_space().starts_with("#") {
|
|
continue
|
|
}
|
|
|
|
full_path := os.join_path(abs_dir_of_script, test)
|
|
|
|
if !os.exists(full_path) {
|
|
eprintln('Path does not exist: ${full_path}')
|
|
exit(1)
|
|
}
|
|
|
|
if os.is_dir(full_path) {
|
|
// If directory, run tests for each .v file in it recursively
|
|
files := os.walk_ext(full_path, '.v')
|
|
for file in files {
|
|
process_test_file(file, norm_dir_of_script, test_files_ignore, test_files_error, redis_available, mut tests_in_error)!
|
|
|
|
}
|
|
} else if os.is_file(full_path) {
|
|
process_test_file(full_path, norm_dir_of_script, test_files_ignore, test_files_error, redis_available, mut tests_in_error)!
|
|
}
|
|
}
|
|
|
|
println('All (non skipped) tests ok')
|
|
|
|
if tests_in_error.len > 0 {
|
|
println('\n\033[31mTests that need to be fixed (not executed):')
|
|
for test in tests_in_error {
|
|
println(' ${test}')
|
|
}
|
|
println('\033[0m')
|
|
}
|