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

Add a FreePort extension #141

Open
krzyk opened this issue Aug 14, 2019 · 12 comments
Open

Add a FreePort extension #141

krzyk opened this issue Aug 14, 2019 · 12 comments

Comments

@krzyk
Copy link

krzyk commented Aug 14, 2019

This is quite similar to TempDirectory.

There are frequently tests that depend on network layer that need to use a port that is not already used by any other service (either to start a server on it, or to test a failure scenario where there is no service at given port).

Proposed usage:

@Test
@ExtendWith(FreePort.class)
void test(@FreePrt int port) {
    // do something with the `port`
}
@marcphilipp
Copy link
Member

How do you guarantee the port stays free between the time you've checked it and the test actually using it? Usually you can pass 0 to servers to assign a randomly allocated port and then query the port that's been allocated after they're started. This approach doesn't have the race condition problem. Do you have use cases where this approach wouldn't work?

@krzyk
Copy link
Author

krzyk commented Aug 16, 2019

Yes, race condition is problematic, but in some cases it can't be avoided, and the proposition is still better than hardcoding port number.

  1. I have a test that needs to have nothing listening at the port (to test the application behavior for invalid host+port).
  2. Some Java libraries allow passing a 0 as a port, but don't have a way to retrieve the assigned port back, so I need to pass a known free port there (yes, with possibility that it will be taken).

As for 2, I don't recall the names, because I had those problems some time ago, but as for 1, I needed to create such extension to be able to test failure conditions. So maybe someone else would find it useful also.

@sbrannen
Copy link

How do you guarantee the port stays free between the time you've checked it and the test actually using it?

You of course cannot guarantee that the port remains free, but there are use cases for it.

For example, Spring has SocketUtils exactly for such use cases.

@nipafx nipafx added 🏗️ type: enhancement 🚦 status: in discussion ⚙️ component: Jupiter Issues coming from (internal/official) Jupiter features etc. labels Nov 1, 2019
@nipafx
Copy link
Member

nipafx commented Nov 1, 2019

I think this is an interesting idea, but I don't have enough experience with testing port-reliant code to add anything to the discussion except a few (possibly naive) ideas. Here's one:

Would it make sense to design the extension so that the strategy to find a free port can be plugged in? That way, a Spring app (to use a random example) can use Spring's facilities to discover free ports and other apps use other mechanism. Or users could ask for random port scan or for a linear port scan in a certain range, ...

What do you think, @krzyk?

@Bukama
Copy link
Member

Bukama commented Mar 17, 2020

I would guess that for such things testcontainers are the right thing to use as they handle the port things out of the box?

@krzyk
Copy link
Author

krzyk commented Mar 18, 2020

@Bukama Running docker just for a single test (or even for the whole suit) is a overkill in majority of projects.

@nipafx
Copy link
Member

nipafx commented Mar 29, 2020

I think this idea is sound enough to give it a go. One more idea, maybe don't pas the port as an int, but as an instance of a class (Free)Port. This removes the need for a @FreePort annotation on the argument and allows for a richer API if it's ever needed, e.g. checking whether a specific port is free at the moment.

@nipafx
Copy link
Member

nipafx commented Mar 29, 2020

If anybody wants to work on this, let me know and I will mark it as in progress.

@Bukama Bukama added 📖 theme: extensions 🏗️ type: new feature and removed ⚙️ component: Jupiter Issues coming from (internal/official) Jupiter features etc. 🏗️ type: enhancement labels May 9, 2020
@nipafx
Copy link
Member

nipafx commented Apr 13, 2021

As a first iteration, please pass an instance of the to-be-created class Port.

@Bukama
Copy link
Member

Bukama commented Dec 4, 2021

PR opend by @p1729

@nipafx
Copy link
Member

nipafx commented Dec 9, 2021

Blocked until #348/#491 is resolved as ports may turn out to be good resources.

nipafx pushed a commit that referenced this issue Nov 14, 2022
Introduces a general mechanism to inject resources into tests. These
resources are either newly created for each test or shared across
several tests - depending on which annotation was used.

This change also introduces a specific resource that uses this
mechanism, namely the temporary directory extension.

Closes: #348
Relates to: #141
PR: #491
@nipafx
Copy link
Member

nipafx commented Dec 15, 2022

I'm gonna remove this from the the 2.0 milestone, so we can progress on that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Up for grabs...
Ready to get started
Development

Successfully merging a pull request may close this issue.

5 participants