Implement map tests for catching common errors. (#19204)

* Implement map tests for catching common errors.

- Adds test runner:
	- to make it easier to track things across test types
	- for example to ensure a fully specified log can be emitted

- Adds map tile test type:
	- when writing a test, coders implement CheckTile, which is
	  handed a single turf
	- when the test runner runs these tests, it iterates over
	  all turfs in the specified z-level, and runs each test's
	  CheckTile on each turf in turn.

- Adds two sample map tile tests:
	- check to see if a pipe exists on the same tile as a scrubber
	  or vent
	- check to see if a tile contains two cables, each with a center
	  node

* Review #1:

- Replace nested loops over map tiles with `block`
- Remove check for valid turf in individual tests, I think it's safe to
  assume `block` will always return legit turfs
- Added proper duration tracking for old tests
- Gave log file an appropriate extension
- Actually use `Fail` for tests

* whoops

* add more tests suggested by @Vi3trice

* Add some more tests courtesy @Bm0n and @Vi3trice

* windows are okay in space as long as it's nearspace

* Add failure threshold to prevent excessive logging.

Once this threshold is reached, a test will stop being processed for
every tile.

Note that this applies to `log_world` and `text2file` equally when
logging large amounts of failures.

* Document each test.

* Remove unnecessary reboot

* Let all map tests run to completion in CI matrix.

* I know what alphabetical means
This commit is contained in:
warriorstar-orion
2022-11-05 11:32:17 -04:00
committed by GitHub
parent 091d5afbd9
commit 4ace2d6c2b
7 changed files with 239 additions and 66 deletions
-62
View File
@@ -6,11 +6,6 @@ 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
@@ -43,60 +38,3 @@ GLOBAL_VAR(test_log)
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
SSticker.reboot_helper("Unit Test Reboot", "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