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

Await in Pre-Run Hook Script #670

Open
LowFire opened this issue Nov 27, 2024 · 3 comments
Open

Await in Pre-Run Hook Script #670

LowFire opened this issue Nov 27, 2024 · 3 comments

Comments

@LowFire
Copy link
Contributor

LowFire commented Nov 27, 2024

Versions

What versions of Godot do you want to use this feature in?
4.x

The Feature

I would like the ability to await in the pre-run hook script, meaning, you can halt the execution of the tests until something happens. I don't know if this is already possible or not, but from what I could tell, it doesn't seem like you can do this. Correct me if i'm wrong.

So here's a use case example of why I think this could be useful, and it applies to the game project I'm currently working on. My game is multiplayer, so some of my tests require a multiplayer connection. I've created a test server that responds to requests from a test client. The client runs the tests. It sends requests to the server. The server receives the requests and does stuff that's related to the test that the client is currently running. Server sends results back to the client. Client runs asserts on the results. That's the short of what i'm doing.

I try to spin up my test server in the pre-run hook script, but here's the problem. I don't want to run my tests until a connection has been established with the test server. This is to prevent the possibility that a test is ran that requires a multiplayer connection before a connection has even been established. For that reason, I want to be able to pause before the tests are ran so that there is time for a connection to be made. Additionally, if for whatever reason, connection to the test server has failed, I want to be able to abort the tests using abort()

@LowFire
Copy link
Contributor Author

LowFire commented Nov 27, 2024

I dug into GUT's source code and hacked it in. Here's what I did.

In gut.gd:

Added an awaiter property in gut.
gut1

Add the awatier as a child of gut in the ready function.
gut3PNG

Then I added the await keyword before _run_hook_script on the pre-run script. I also added await right before the run() method is called on the pre-run script.
gut2

And this is what my pre-run hook script looks like:
gut4

So basically, I await a signal for a certain amount of time until either a connection is made to the server, or the awaiter times out. If connection has been made, then great, we continue with the tests. If not, then we abort the tests.

Seems to work fine. I'll stick with this for the time being unless there's a better solution.

@bitwes
Copy link
Owner

bitwes commented Nov 27, 2024

I think this is a good addition. This should probably also be done for the post-run script. And maybe should_skip_script per the idea I have below.

Great use of the Awaiter. Always happy to see some internal piece of GUT get reused. You could move the Awaiter creation into your hook script so you don't have to edit GUT when a new version comes out.

func run():
    var awaiter = GutUtils.Awaiter.new()
    gut.add_child(awaiter)
    ...
    awaiter.queue_free()    

If it becomes annoying to wait for the server when you don't need it, you could move your server check logic into the should_skip_script. Skipping a script will not run any tests in the script and mark it as risky in the output.

This would require adding an await into GUT when it calls should_skip_script for it to work.

You could implement should_skip_script in a MultiplayerTest class that you inherit from instead of GutTest. In this case, you can use wait_for_signal instead of making an Awaiter.

extends GutTest
class_name MultiplayerTest

func should_skip_script():
    ...
    await wait_for_signal(multiplayer_tester.connected, 10)
    return not multiplayer_tester.is_connected_to_server()

@LowFire
Copy link
Contributor Author

LowFire commented Nov 27, 2024

I think this is a good addition. This should probably also be done for the post-run script. And maybe should_skip_script per the idea I have below.

Great use of the Awaiter. Always happy to see some internal piece of GUT get reused. You could move the Awaiter creation into your hook script so you don't have to edit GUT when a new version comes out.

func run():
    var awaiter = GutUtils.Awaiter.new()
    gut.add_child(awaiter)
    ...
    awaiter.queue_free()    

If it becomes annoying to wait for the server when you don't need it, you could move your server check logic into the should_skip_script. Skipping a script will not run any tests in the script and mark it as risky in the output.

This would require adding an await into GUT when it calls should_skip_script for it to work.

You could implement should_skip_script in a MultiplayerTest class that you inherit from instead of GutTest. In this case, you can use wait_for_signal instead of making an Awaiter.

extends GutTest
class_name MultiplayerTest

func should_skip_script():
    ...
    await wait_for_signal(multiplayer_tester.connected, 10)
    return not multiplayer_tester.is_connected_to_server()

These are great ideas. I'll do this instead. Thank you for suggest this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants