mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-18 10:33:30 +01:00
Travis Update Finale: Unit Tests + SQL Validation (#13331)
* SQL Validation, the first of many * Initial test of the world loading * This was prefixed when it shouldnt have been :v * This also isnt a valid table * Escape time * Chmod * This **should** work * Oops * RUST gone bust * Please work * Why did I do this twice * I think I got it * Fixes AFK SS * AAAAAAAAAAAAAAAAAAAAAA * Fixes AI cam runtime * Cleanup * *screams* * Fare fixes * Removes un-needed stuff * I hope this works * chmoooood * SQL Version Unit Test * Failure test * Kinda ironic how I forgot this * Task failed successfully * Moves a global var around * Bump SQL version in travis * New test: SQL example DBconfig update * Lets test an invalid version * TASK FAILED SUCCESSFULLY * Programmatic maplist generation * Removes a duplicate check * Lets try this * What about this * hnnng * Lets just update BYOND
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
//include unit test files in this module in this ifdef
|
||||
//Keep this sorted alphabetically
|
||||
|
||||
#ifdef UNIT_TESTS
|
||||
#include "component_tests.dm"
|
||||
#include "reagent_id_typos.dm"
|
||||
#include "spawn_humans.dm"
|
||||
#include "sql.dm"
|
||||
#include "subsystem_init.dm"
|
||||
#include "timer_sanity.dm"
|
||||
#include "unit_test.dm"
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
/datum/unit_test/component_duping/Run()
|
||||
var/list/bad_dms = list()
|
||||
var/list/bad_dts = list()
|
||||
for(var/t in typesof(/datum/component))
|
||||
var/datum/component/comp = t
|
||||
if(!isnum(initial(comp.dupe_mode)))
|
||||
bad_dms += t
|
||||
var/dupe_type = initial(comp.dupe_type)
|
||||
if(dupe_type && !ispath(dupe_type))
|
||||
bad_dts += t
|
||||
if(length(bad_dms) || length(bad_dts))
|
||||
Fail("Components with invalid dupe modes: ([bad_dms.Join(",")]) ||| Components with invalid dupe types: ([bad_dts.Join(",")])")
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
|
||||
/datum/unit_test/reagent_id_typos
|
||||
|
||||
/datum/unit_test/reagent_id_typos/Run()
|
||||
for(var/I in GLOB.chemical_reactions_list)
|
||||
for(var/V in GLOB.chemical_reactions_list[I])
|
||||
var/datum/chemical_reaction/R = V
|
||||
for(var/id in (R.required_reagents + R.required_catalysts))
|
||||
if(!GLOB.chemical_reagents_list[id])
|
||||
Fail("Unknown chemical id \"[id]\" in recipe [R.type]")
|
||||
@@ -0,0 +1,8 @@
|
||||
/datum/unit_test/spawn_humans/Run()
|
||||
var/locs = block(run_loc_bottom_left, run_loc_top_right)
|
||||
|
||||
for(var/I in 1 to 5)
|
||||
new /mob/living/carbon/human(pick(locs))
|
||||
|
||||
// There is a 5 second delay here so that all the items on the humans have time to initialize and spawn
|
||||
sleep(50)
|
||||
@@ -0,0 +1,42 @@
|
||||
// Unit test to check SQL version has been updated properly.,
|
||||
/datum/unit_test/sql_version/Run()
|
||||
// Check if the SQL version set in the code is equal to the travis DB config
|
||||
if(config.sql_enabled && sql_version != SQL_VERSION)
|
||||
Fail("SQL version error: Game is running V[SQL_VERSION] but config is V[sql_version]. You may need to update tools/travis/dbconfig.txt")
|
||||
// Check if the travis DB config is up to date with the example dbconfig
|
||||
// This proc is a little unclean but it works
|
||||
var/example_db_version
|
||||
var/list/Lines = file2list("config/example/dbconfig.txt")
|
||||
for(var/t in Lines)
|
||||
if(!t) continue
|
||||
|
||||
t = trim(t)
|
||||
if(length(t) == 0)
|
||||
continue
|
||||
else if(copytext(t, 1, 2) == "#")
|
||||
continue
|
||||
|
||||
var/pos = findtext(t, " ")
|
||||
var/name = null
|
||||
var/value = null
|
||||
|
||||
if(pos)
|
||||
name = lowertext(copytext(t, 1, pos))
|
||||
value = copytext(t, pos + 1)
|
||||
else
|
||||
name = lowertext(t)
|
||||
|
||||
if(!name)
|
||||
continue
|
||||
|
||||
switch(name)
|
||||
if("db_version")
|
||||
example_db_version = text2num(value)
|
||||
|
||||
if(!example_db_version)
|
||||
Fail("SQL version error: File config/example/dbconfig.txt does not have a valid SQL version set!")
|
||||
|
||||
if(example_db_version != SQL_VERSION)
|
||||
Fail("SQL version error: Game is running V[SQL_VERSION] but config/example/dbconfig.txt is V[example_db_version].")
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
/datum/unit_test/subsystem_init/Run()
|
||||
for(var/i in Master.subsystems)
|
||||
var/datum/controller/subsystem/ss = i
|
||||
if(ss.flags & SS_NO_INIT)
|
||||
continue
|
||||
if(!ss.initialized)
|
||||
Fail("[ss]([ss.type]) is a subsystem meant to initialize but doesn't get set as initialized.")
|
||||
@@ -0,0 +1,3 @@
|
||||
/datum/unit_test/timer_sanity/Run()
|
||||
if(SStimer.bucket_count < 0)
|
||||
Fail("SStimer is going into negative bucket count from something")
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
Usage:
|
||||
Override /Run() to run your test code
|
||||
Call Fail() to fail the test (You should specify a reason)
|
||||
You may use /New() and /Destroy() for setup/teardown respectively
|
||||
You can use the run_loc_bottom_left and run_loc_top_right to get turfs for testing
|
||||
*/
|
||||
|
||||
/// VARS FOR UNIT TESTS
|
||||
GLOBAL_DATUM(current_test, /datum/unit_test)
|
||||
GLOBAL_VAR_INIT(failed_any_test, FALSE)
|
||||
GLOBAL_VAR(test_log)
|
||||
|
||||
/datum/unit_test
|
||||
//Bit of metadata for the future maybe
|
||||
var/list/procs_tested
|
||||
|
||||
//usable vars
|
||||
var/turf/run_loc_bottom_left
|
||||
var/turf/run_loc_top_right
|
||||
|
||||
//internal shit
|
||||
var/succeeded = TRUE
|
||||
var/list/fail_reasons
|
||||
|
||||
/datum/unit_test/New()
|
||||
run_loc_bottom_left = locate(1, 1, 1)
|
||||
run_loc_top_right = locate(5, 5, 1)
|
||||
|
||||
/datum/unit_test/Destroy()
|
||||
//clear the test area
|
||||
for(var/atom/movable/AM in block(run_loc_bottom_left, run_loc_top_right))
|
||||
qdel(AM)
|
||||
return ..()
|
||||
|
||||
/datum/unit_test/proc/Run()
|
||||
Fail("Run() called parent or not implemented")
|
||||
|
||||
/datum/unit_test/proc/Fail(reason = "No reason")
|
||||
succeeded = FALSE
|
||||
|
||||
if(!istext(reason))
|
||||
reason = "FORMATTED: [reason != null ? reason : "NULL"]"
|
||||
|
||||
LAZYADD(fail_reasons, reason)
|
||||
|
||||
/proc/RunUnitTests()
|
||||
CHECK_TICK
|
||||
|
||||
for(var/I in subtypesof(/datum/unit_test))
|
||||
var/datum/unit_test/test = new I
|
||||
|
||||
GLOB.current_test = test
|
||||
var/duration = REALTIMEOFDAY
|
||||
|
||||
test.Run()
|
||||
|
||||
duration = REALTIMEOFDAY - duration
|
||||
GLOB.current_test = null
|
||||
GLOB.failed_any_test |= !test.succeeded
|
||||
|
||||
var/list/log_entry = list("[test.succeeded ? "PASS" : "FAIL"]: [I] [duration / 10]s")
|
||||
var/list/fail_reasons = test.fail_reasons
|
||||
|
||||
qdel(test)
|
||||
|
||||
for(var/J in 1 to LAZYLEN(fail_reasons))
|
||||
log_entry += "\tREASON #[J]: [fail_reasons[J]]"
|
||||
log_world(log_entry.Join("\n"))
|
||||
|
||||
CHECK_TICK
|
||||
|
||||
world.Reboot("Unit Test Reboot", "end_test", "tests ended", 0)
|
||||
|
||||
|
||||
// OTHER MISC PROCS RELATED TO UNIT TESTS //
|
||||
|
||||
/world/proc/HandleTestRun()
|
||||
//trigger things to run the whole process
|
||||
Master.sleep_offline_after_initializations = FALSE
|
||||
// This will have the ticker set the game up
|
||||
// Running the tests is part of the ticker's start function, because I cant think of any better place to put it
|
||||
SSticker.force_start = TRUE
|
||||
|
||||
/world/proc/FinishTestRun()
|
||||
set waitfor = FALSE
|
||||
var/list/fail_reasons
|
||||
if(GLOB)
|
||||
if(GLOB.total_runtimes != 0)
|
||||
fail_reasons = list("Total runtimes: [GLOB.total_runtimes]")
|
||||
if(!GLOB.log_directory)
|
||||
LAZYADD(fail_reasons, "Missing GLOB.log_directory!")
|
||||
if(GLOB.failed_any_test)
|
||||
LAZYADD(fail_reasons, "Unit Tests failed!")
|
||||
else
|
||||
fail_reasons = list("Missing GLOB!")
|
||||
if(!fail_reasons)
|
||||
text2file("Success!", "data/clean_run.lk")
|
||||
else
|
||||
log_world("Test run failed!\n[fail_reasons.Join("\n")]")
|
||||
sleep(0) //yes, 0, this'll let Reboot finish and prevent byond memes
|
||||
del(src) //shut it down
|
||||
Reference in New Issue
Block a user