Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate station/unit tests and disable lavaland procgen and ruin spawning in tests (for now). #28106

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 33 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,20 +99,42 @@ jobs:
tools/ci/generate_maplist.sh
DreamMaker -DMULTIINSTANCE -DCIMAP paradise.dme

station_mapload_tests:
name: Station Tests
runs-on: ubuntu-22.04
strategy:
fail-fast: false # Let all map tests run to completion
matrix:
station:
['boxstation', 'deltastation', 'metastation', 'cerestation', 'emeraldstation']
byondtype: ['STABLE', 'BETA']
steps:
- uses: actions/checkout@v4
- name: Setup Cache
uses: actions/cache@v4
with:
path: $HOME/BYOND
key: ${{ runner.os }}-byond
- name: Install RUST_G Deps
run: |
sudo dpkg --add-architecture i386
sudo apt update || true
sudo apt install zlib1g-dev:i386
tools/ci/install_rustg.sh
- name: Compile & Run Unit Tests
run: |
tools/ci/install_byond.sh '${{ matrix.byondtype }}'
source $HOME/BYOND/byond/bin/byondsetup
DreamMaker -DMAP_TESTS -DTEST_CONFIG_OVERRIDE=\"unit_tests\" -DMULTIINSTANCE -DCIBUILDING paradise.dme
echo '/datum/map/${{ matrix.station }}' > data/next_map.txt
tools/ci/run_server.sh

unit_tests_and_sql:
name: Unit Tests + SQL Validation
runs-on: ubuntu-22.04
strategy:
fail-fast: false # Let all map tests run to completion
fail-fast: false
matrix:
maptype:
[
'/datum/map/boxstation',
'/datum/map/deltastation',
'/datum/map/metastation',
'/datum/map/cerestation',
'/datum/map/emeraldstation',
]
byondtype: ['STABLE', 'BETA']
services:
mariadb:
Expand Down Expand Up @@ -144,8 +166,8 @@ jobs:
run: |
tools/ci/install_byond.sh '${{ matrix.byondtype }}'
source $HOME/BYOND/byond/bin/byondsetup
DreamMaker -DMULTIINSTANCE -DCIBUILDING paradise.dme
echo '${{ matrix.maptype }}' > data/next_map.txt
DreamMaker -DGAME_TESTS -DTEST_CONFIG_OVERRIDE=\"unit_tests\" -DMULTIINSTANCE -DCIBUILDING paradise.dme
echo '/datum/map/test_tiny' > data/next_map.txt
tools/ci/run_server.sh

windows_dll_tests:
Expand Down
9 changes: 5 additions & 4 deletions code/_compile_options.dm
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,17 @@

#ifdef LOCAL_GAME_TESTS
#define GAME_TESTS
#endif

#ifdef CIBUILDING
#define GAME_TESTS
#define MAP_TESTS
#endif

#if defined(CIBUILDING) && defined(LOCAL_GAME_TESTS)
#error CIBUILDING and LOCAL_GAME_TESTS should not be enabled at the same time!
#endif

#if defined(GAME_TESTS) || defined(MAP_TESTS)
#define TEST_RUNNER
#endif
warriorstar-orion marked this conversation as resolved.
Show resolved Hide resolved

/***** All toggles for the GC ref finder *****/

// #define REFERENCE_TRACKING // Uncomment to enable ref finding
Expand Down
7 changes: 3 additions & 4 deletions code/controllers/configuration/configuration_core.dm
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,12 @@ GLOBAL_DATUM_INIT(configuration, /datum/server_configuration, new())
safe_load(asset_cache, "asset_cache_configuration")

// Proc to load up instance-specific overrides
/datum/server_configuration/proc/load_overrides()
var/override_file = "config/overrides_[world.port].toml"
/datum/server_configuration/proc/load_overrides(override_file)
if(!fexists(override_file))
DIRECT_OUTPUT(world.log, "Overrides not found for this instance.")
DIRECT_OUTPUT(world.log, "Override file [override_file] not found for this instance.")
return

DIRECT_OUTPUT(world.log, "Overrides found for this instance. Loading them.")
DIRECT_OUTPUT(world.log, "Override file [override_file] found. Loading.")
var/start = start_watch() // Time tracking

raw_data = rustg_read_toml_file(override_file)
Expand Down
11 changes: 0 additions & 11 deletions code/controllers/configuration/sections/database_configuration.dm
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,6 @@
var/async_thread_limit = 50

/datum/configuration_section/database_configuration/load_data(list/data)
// UNIT TESTS ARE DEFINED - USE CUSTOM CI VALUES
#ifdef GAME_TESTS

enabled = TRUE
// This needs to happen in the CI environment to ensure the example SQL version gets updated.
CONFIG_LOAD_NUM(version, data["sql_version"])

#else
// Load the normal config. Were not in CI mode
// Use the load wrappers here. That way the default isnt made 'null' if you comment out the config line
CONFIG_LOAD_BOOL(enabled, data["sql_enabled"])
CONFIG_LOAD_NUM(version, data["sql_version"])
CONFIG_LOAD_STR(address, data["sql_address"])
Expand All @@ -40,4 +30,3 @@
CONFIG_LOAD_STR(db, data["sql_database"])
CONFIG_LOAD_NUM(async_query_timeout, data["async_query_timeout"])
CONFIG_LOAD_NUM(async_thread_limit, data["async_thread_limit"])
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,5 @@
var/connstring = "redis://127.0.0.1/"

/datum/configuration_section/redis_configuration/load_data(list/data)
// UNIT TESTS ARE DEFINED - USE CUSTOM CI VALUES
#ifdef GAME_TESTS

// enabled = TRUE

#else
// Load the normal config. Were not in CI mode
// Use the load wrappers here. That way the default isnt made 'null' if you comment out the config line
CONFIG_LOAD_BOOL(enabled, data["redis_enabled"])
CONFIG_LOAD_STR(connstring, data["redis_connstring"])
#endif
2 changes: 1 addition & 1 deletion code/controllers/master.dm
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new

/datum/controller/master/New()
if(!random_seed)
#ifdef GAME_TESTS
#ifdef TEST_RUNNER
random_seed = 29051994
#else
random_seed = rand(1, 1e9)
Expand Down
6 changes: 2 additions & 4 deletions code/controllers/subsystem/SSticker.dm
Original file line number Diff line number Diff line change
Expand Up @@ -363,10 +363,8 @@ SUBSYSTEM_DEF(ticker)
if(GLOB.configuration.general.enable_night_shifts)
SSnightshift.check_nightshift(TRUE)

#ifdef GAME_TESTS
// Run map tests first in case unit tests futz with map state
GLOB.test_runner.RunMap()
GLOB.test_runner.Run()
#ifdef TEST_RUNNER
GLOB.test_runner.RunAll()
#endif

// Do this 10 second after roundstart because of roundstart lag, and make it more visible
Expand Down
16 changes: 10 additions & 6 deletions code/game/world.dm
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
GLOBAL_LIST_INIT(map_transition_config, list(CC_TRANSITION_CONFIG))

#ifdef GAME_TESTS
#ifdef TEST_RUNNER
GLOBAL_DATUM(test_runner, /datum/test_runner)
#endif

Expand All @@ -26,7 +26,11 @@ GLOBAL_DATUM(test_runner, /datum/test_runner)
GLOB.configuration.load_configuration() // Load up the base config.toml
// Load up overrides for this specific instance, based on port
// If this instance is listening on port 6666, the server will look for config/overrides_6666.toml
GLOB.configuration.load_overrides()
GLOB.configuration.load_overrides("config/overrides_[world.port].toml")

#ifdef TEST_CONFIG_OVERRIDE
GLOB.configuration.load_overrides("config/tests/config_[TEST_CONFIG_OVERRIDE].toml")
#endif

// Right off the bat, load up the DB
SSdbcore.CheckSchemaVersion() // This doesnt just check the schema version, it also connects to the db! This needs to happen super early! I cannot stress this enough!
Expand All @@ -51,8 +55,8 @@ GLOBAL_DATUM(test_runner, /datum/test_runner)
if(TgsAvailable())
world.log = file("[GLOB.log_directory]/dd.log") //not all runtimes trigger world/Error, so this is the only way to ensure we can see all of them.

#ifdef GAME_TESTS
log_world("Unit Tests Are Enabled!")
#ifdef TEST_RUNNER
log_world("Test runner enabled.")
#endif

if(byond_version < MIN_COMPILER_VERSION || byond_build < MIN_COMPILER_BUILD)
Expand All @@ -69,7 +73,7 @@ GLOBAL_DATUM(test_runner, /datum/test_runner)
Master.Initialize(10, FALSE, TRUE)


#ifdef GAME_TESTS
#ifdef TEST_RUNNER
GLOB.test_runner = new
GLOB.test_runner.Start()
#endif
Expand Down Expand Up @@ -144,7 +148,7 @@ GLOBAL_LIST_EMPTY(world_topic_handlers)
Master.Shutdown() // Shutdown subsystems

// If we were running unit tests, finish that run
#ifdef GAME_TESTS
#ifdef TEST_RUNNER
GLOB.test_runner.Finalize()
return
#endif
Expand Down
20 changes: 20 additions & 0 deletions code/tests/_map_per_tile_test.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* Map per-tile test.
*
* Per-tile map tests iterate over each tile of a map to perform a check, and
* fails the test if a tile does not pass the check. A new test can be
* written by extending /datum/map_per_tile_test, and implementing the check
* in CheckTile.
*/
/datum/map_per_tile_test
var/succeeded = TRUE
var/list/fail_reasons
var/failure_count = 0

/datum/map_per_tile_test/proc/CheckTile(turf/T)
Fail("CheckTile() called parent or not implemented")

/datum/map_per_tile_test/proc/Fail(turf/T, reason)
succeeded = FALSE
LAZYADD(fail_reasons, "[T.x],[T.y],[T.z]: [reason]")
failure_count++
15 changes: 11 additions & 4 deletions code/tests/game_tests.dm
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
//include game test files in this module in this ifdef
//Keep this sorted alphabetically

#ifdef GAME_TESTS
#ifdef TEST_RUNNER
#include "_game_test_puppeteer.dm"
#include "_game_test.dm"
#include "_map_per_tile_test.dm"
#include "test_runner.dm"
#endif

#ifdef GAME_TESTS
#include "atmos\test_ventcrawl.dm"
#include "attack_chain\test_attack_chain_cult_dagger.dm"
#include "attack_chain\test_attack_chain_machinery.dm"
Expand All @@ -13,7 +18,6 @@
#include "jobs\test_job_globals.dm"
#include "test_aicard_icons.dm"
#include "test_announcements.dm"
#include "test_areas_apcs.dm"
#include "test_components.dm"
#include "test_config_sanity.dm"
#include "test_crafting_lists.dm"
Expand All @@ -22,12 +26,10 @@
#include "test_init_sanity.dm"
#include "test_log_format.dm"
#include "test_map_templates.dm"
#include "test_map_tests.dm"
#include "test_missing_icons.dm"
#include "test_origin_tech.dm"
#include "test_purchase_reference_test.dm"
#include "test_reagent_id_typos.dm"
#include "test_runner.dm"
#include "test_rustg_version.dm"
#include "test_spawn_humans.dm"
#include "test_spell_targeting_test.dm"
Expand All @@ -37,3 +39,8 @@
#include "test_subsystem_metric_sanity.dm"
#include "test_timer_sanity.dm"
#endif

#ifdef MAP_TESTS
#include "test_areas_apcs.dm"
#include "test_map_tests.dm"
#endif
21 changes: 0 additions & 21 deletions code/tests/test_map_tests.dm
Original file line number Diff line number Diff line change
@@ -1,24 +1,3 @@
/**
* Map per-tile test.
*
* Per-tile map tests iterate over each tile of a map to perform a check, and
* fails the test if a tile does not pass the check. A new test can be
* written by extending /datum/map_per_tile_test, and implementing the check
* in CheckTile.
*/
/datum/map_per_tile_test
var/succeeded = TRUE
var/list/fail_reasons
var/failure_count = 0

/datum/map_per_tile_test/proc/CheckTile(turf/T)
Fail("CheckTile() called parent or not implemented")

/datum/map_per_tile_test/proc/Fail(turf/T, reason)
succeeded = FALSE
LAZYADD(fail_reasons, "[T.x],[T.y],[T.z]: [reason]")
failure_count++

/**
* Check to ensure that APCs have a cable node on their tile.
*/
Expand Down
70 changes: 39 additions & 31 deletions code/tests/test_runner.dm
Original file line number Diff line number Diff line change
Expand Up @@ -22,38 +22,18 @@
// 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


/datum/test_runner/proc/RunMap(z_level = 2)
CHECK_TICK

var/list/tests = list()

for(var/I in subtypesof(/datum/map_per_tile_test))
tests += new I
test_logs[I] = list()
durations[I] = 0

for(var/turf/T in block(1, 1, z_level, world.maxx, world.maxy, z_level))
for(var/datum/map_per_tile_test/test in tests)
if(test.failure_count < MAX_MAP_TEST_FAILURE_COUNT)
var/duration = REALTIMEOFDAY
test.CheckTile(T)
durations[test.type] += REALTIMEOFDAY - duration

if(test.failure_count >= MAX_MAP_TEST_FAILURE_COUNT)
test.Fail(T, "failure threshold reached at this tile")

CHECK_TICK

for(var/datum/map_per_tile_test/test in tests)
if(!test.succeeded)
failed_any_test = TRUE
test_logs[test.type] += test.fail_reasons

QDEL_LIST_CONTENTS(tests)

/datum/test_runner/proc/RunAll()
#ifdef MAP_TESTS
// Run map tests first in case unit tests futz with map state
RunMap()
#endif
#ifdef GAME_TESTS
Run()
#endif
SSticker.reboot_helper("Unit Test Reboot", "tests ended", 0)

/datum/test_runner/proc/Run()
log_world("Test runner: game tests.")
CHECK_TICK

for(var/I in subtypesof(/datum/game_test))
Expand Down Expand Up @@ -84,10 +64,38 @@

CHECK_TICK

SSticker.reboot_helper("Unit Test Reboot", "tests ended", 0)
/datum/test_runner/proc/RunMap(z_level = 2)
log_world("Test runner: map tests.")
CHECK_TICK

var/list/tests = list()

for(var/I in subtypesof(/datum/map_per_tile_test))
tests += new I
test_logs[I] = list()
durations[I] = 0

for(var/turf/T in block(1, 1, z_level, world.maxx, world.maxy, z_level))
for(var/datum/map_per_tile_test/test in tests)
if(test.failure_count < MAX_MAP_TEST_FAILURE_COUNT)
var/duration = REALTIMEOFDAY
test.CheckTile(T)
durations[test.type] += REALTIMEOFDAY - duration

if(test.failure_count >= MAX_MAP_TEST_FAILURE_COUNT)
test.Fail(T, "failure threshold reached at this tile")

CHECK_TICK

for(var/datum/map_per_tile_test/test in tests)
if(!test.succeeded)
failed_any_test = TRUE
test_logs[test.type] += test.fail_reasons

QDEL_LIST_CONTENTS(tests)

/datum/test_runner/proc/Finalize(emit_failures = FALSE)
log_world("Test runner: finalizing.")
var/time = world.timeofday
set waitfor = FALSE

Expand Down
Loading