Files
Bubberstation/code/modules/unit_tests/leash.dm
Bloop 3e59765d0f Attempts to fix the leash unit test CI failures (#78157)
## About The Pull Request

Fixes https://github.com/tgstation/tgstation/issues/77704

Fixes https://github.com/Skyrat-SS13/Skyrat-tg/issues/23467
Fixes https://github.com/Skyrat-SS13/Skyrat-tg/issues/23511

What it says on the tin. This has started causing CI failures with the
Tramstation test in almost every single PR downstream and it's gotten to
the point where it's become a major headache.

I don't know why it's happening only only on Tramstation, or why it's
happening at all-- but I will say it instantly began ramping up in
frequency immediately after merging
https://github.com/tgstation/tgstation/pull/75924 , which was the same
PR that was also causing the progressbar harddels previously to crop up
every time @LemonInTheDark .

This attempts to fix it by doing 2 things:

~~1) Make sure the `COMSIG_LEASH_PATH_COMPLETE` always gets sent, which
will prevent needless false 'timeouts' whenever every iteration of the
check_distance() loop returns early. Now it will only timeout when it
actually times out.~~

1) Increases the timeout timer to 80 seconds. Why so long? Well, I've
looked at a number of individual CI failures and it looks like it tries
to complete the path somewhere between 40-75 seconds after the time out
failure. Most of the time it should not take this long though and will
just finish right away as normal.

<details><summary>Timeouts with timestamps shown here so you can see
what I am talking about</summary>


![firefox_mjwj5LCEje](https://github.com/tgstation/tgstation/assets/13398309/376be09f-ab85-4362-a75f-156c76a5c901)


![firefox_St29Dis9Jh](https://github.com/tgstation/tgstation/assets/13398309/f5bfbb5f-fc24-404d-ba41-e84130885500)

</details>

<details><summary>And here</summary>


![firefox_joAs0qA0f6](https://github.com/tgstation/tgstation/assets/13398309/13955036-a120-4ea4-adcb-8c945d0695ab)


![firefox_WABTuH6Z1j](https://github.com/tgstation/tgstation/assets/13398309/222af6fb-8cb1-4ea1-97aa-c5785294da58)

</details>

<details><summary>And here</summary>


![firefox_BaZXVwFzPE](https://github.com/tgstation/tgstation/assets/13398309/c68f0c3a-553b-42ca-aef4-a04628c5abf0)


![firefox_qoMid37BUi](https://github.com/tgstation/tgstation/assets/13398309/8ce48a2d-3b21-4346-aa9f-654e66b2a6b7)

</details>

2) Moves the priority of the test down so it happens later, with the
other long tests. This might even fix the issue on its own--haven't seen
the test take more than 0.1s to complete so far in any of my runs. Maybe
things just needed some more time to load?

So far I've done about 10 test runs and haven't seen a single timeout
with these two changes. I'm fairly confident the issue is fixed but
we'll see.

Test functioning:


![image](https://github.com/tgstation/tgstation/assets/13398309/fd7e9cf4-3573-4971-bbee-2fe45f82dafb)

## Why It's Good For The Game

Stops a PR blocking spurious CI failure.

## Changelog

🆑
fix: leash unit test will time out less often and increases the timer
until it is considered 'timed out', to reduce false CI failures
/🆑
2023-09-06 15:26:50 -07:00

104 lines
3.0 KiB
Plaintext

/datum/unit_test/leash
abstract_type = /datum/unit_test/leash
priority = TEST_LONGER
var/atom/movable/owner
var/atom/movable/pet
var/max_distance = 3
var/forcibly_teleported = FALSE
var/datum/leash_wait/leash_wait
/datum/unit_test/leash/New()
. = ..()
owner = allocate(/obj/item/pen)
pet = allocate(/obj/item/pen)
pet.AddComponent(/datum/component/leash, owner, max_distance)
RegisterSignal(pet, COMSIG_LEASH_FORCE_TELEPORT, PROC_REF(on_leash_force_teleport))
RegisterSignal(pet, COMSIG_LEASH_PATH_STARTED, PROC_REF(on_leash_path_started))
RegisterSignal(pet, COMSIG_LEASH_PATH_COMPLETE, PROC_REF(on_leash_path_complete))
/datum/unit_test/leash/Destroy()
QDEL_NULL(owner)
QDEL_NULL(pet)
return ..()
/datum/unit_test/leash/proc/on_leash_force_teleport()
SIGNAL_HANDLER
forcibly_teleported = TRUE
/datum/unit_test/leash/proc/on_leash_path_complete()
SIGNAL_HANDLER
leash_wait?.completed()
/datum/unit_test/leash/proc/on_leash_path_started()
SIGNAL_HANDLER
leash_wait?.started()
/datum/unit_test/leash/proc/move_away(atom/movable/mover, distance)
RETURN_TYPE(/datum/leash_wait)
leash_wait = new
for (var/_ in 1 to distance)
mover.Move(get_step(mover, EAST))
return leash_wait
/datum/leash_wait
var/completed = FALSE
var/started = FALSE
var/timed_out = FALSE
/datum/leash_wait/New()
addtimer(VARSET_CALLBACK(src, timed_out, TRUE), 80 SECONDS)
/datum/leash_wait/proc/completed()
completed = TRUE
/datum/leash_wait/proc/started()
started = TRUE
/datum/leash_wait/proc/assert_unmoved()
ASSERT(!started, "Leash started to move when it should not have")
/datum/leash_wait/proc/wait()
ASSERT(started, "Leash doesn't plan on moving")
UNTIL(completed || timed_out)
ASSERT(!timed_out, "Waiting for leash movement timed out, it didn't want to move")
/// Validates the leash component will keep its parent within range without teleporting
/// when possible.
/datum/unit_test/leash/no_teleport
/datum/unit_test/leash/no_teleport/Run()
move_away(owner, 1).assert_unmoved()
TEST_ASSERT_EQUAL(get_dist(owner, pet), 1, "Pet should not have moved")
move_away(owner, max_distance).wait() // max_distance + 1 = we move closer, but don't teleport
TEST_ASSERT_EQUAL(get_dist(owner, pet), max_distance, "Pet should have stayed directly outside range of owner")
TEST_ASSERT(!forcibly_teleported, "Pet should not have been forcibly teleported")
/// Validates that the leash component will forcibly teleport when necessary
/datum/unit_test/leash/will_teleport
/datum/unit_test/leash/will_teleport/Run()
leash_wait = new
owner.forceMove(locate(1, 1, 1))
leash_wait.wait()
TEST_ASSERT(forcibly_teleported, "Pet should have been forcibly teleported, since they are too far away with no valid path")
/// Validates that the leashed object cannot move outside of the max distance from owner
/datum/unit_test/leash/limit_range
/datum/unit_test/leash/limit_range/Run()
move_away(pet, max_distance + 1)
TEST_ASSERT_EQUAL(get_dist(owner, pet), max_distance, "Pet should not have moved farther than max_distance")