Re: Using Ports Safely in Tests

2021-11-04 Thread Kirk Lund
Dale, Thanks for doing this work and especially for adding these guidelines
to the Wiki!

On Thu, Nov 4, 2021 at 1:08 PM Dale Emery  wrote:

> As of July, 2021, Geode's build system no longer executes test worker
> processes in separate Docker containers.
>
> This increases the risk of port collisions between tests. Each test worker
> JVM and each Java process started by a test executes directly in the
> environment provided by the host machine. If a test is using a port, any
> concurrently running test that tries to bind to the same port number will
> suffer a BindException.
> Safely allocating ports. To reduce this risk, Geode's build system now
> assigns each test worker JVM a distinct range of ports. In CI, which runs
> 24 distributed tests concurrently, each test gets a range of about 400
> ports.
> In JVMs running Geode version 1.14 or later, AvailablePort and
> AvailablePortHelper will choose ports from this assigned range. As a
> result, no two tests will ever receive the same port number from these
> classes, no matter how many are running concurrently.
> When you write a test, keep the following guidelines in mind, to make sure
> your test uses only the ranges of ports that the Geode build system
> assigned to it:
>
>   *   To assign an available port, call AvailablePortHelper or
> AvailablePort. These are the only classes that know about the reduced port
> range for the test.
>   *   Call AvailablePort and AvailablePortHelper only in the current
> version of Geode. Do not call these classes in Child VMs running older
> versions of Geode. Older versions of Geode do not honor the new, reduced
> port ranges.
>   *   Do not launch any service using Geode’s default port for that
> service. Always explicitly assign an available port. The only safe use of
> default ports is in a test to verify that a service uses its default port
> by default. Note that such a test will fail the stress test CI job. To
> exclude such a test from the stress test job, annotate it with
> @Category(IgnoreInRepeatTestTasks.class).
>   *   Do not launch any service using a port number hard-coded into the
> test. Always explicitly assign an available port. There is no safe use of
> any hard-coded port number in tests that can run concurrently.
>   *   Do not attempt to reuse an ephemeral port. Some tests start a member
> on an ephemeral port, stop the member, and attempt to restart it on the
> same port. This is not safe. It was never safe. During the time between
> when the member stops and when it restarts, the port is available for the
> operating system to give to any other process. In CI, it is very, very
> likely that one or more concurrently-running tests (or other processes)
> will request ephemeral ports during the time when your test is not bound to
> it. If one of those processes gets the port your test was using, your test
> will fail.
> This information is available on the Geode wiki:
> https://cwiki.apache.org/confluence/display/GEODE/Using+Ports+Safely+in+Tests
>
> Dale
>
>


Using Ports Safely in Tests

2021-11-04 Thread Dale Emery
As of July, 2021, Geode's build system no longer executes test worker processes 
in separate Docker containers.

This increases the risk of port collisions between tests. Each test worker JVM 
and each Java process started by a test executes directly in the environment 
provided by the host machine. If a test is using a port, any concurrently 
running test that tries to bind to the same port number will suffer a 
BindException.
Safely allocating ports. To reduce this risk, Geode's build system now assigns 
each test worker JVM a distinct range of ports. In CI, which runs 24 
distributed tests concurrently, each test gets a range of about 400 ports.
In JVMs running Geode version 1.14 or later, AvailablePort and 
AvailablePortHelper will choose ports from this assigned range. As a result, no 
two tests will ever receive the same port number from these classes, no matter 
how many are running concurrently.
When you write a test, keep the following guidelines in mind, to make sure your 
test uses only the ranges of ports that the Geode build system assigned to it:

  *   To assign an available port, call AvailablePortHelper or AvailablePort. 
These are the only classes that know about the reduced port range for the test.
  *   Call AvailablePort and AvailablePortHelper only in the current version of 
Geode. Do not call these classes in Child VMs running older versions of Geode. 
Older versions of Geode do not honor the new, reduced port ranges.
  *   Do not launch any service using Geode’s default port for that service. 
Always explicitly assign an available port. The only safe use of default ports 
is in a test to verify that a service uses its default port by default. Note 
that such a test will fail the stress test CI job. To exclude such a test from 
the stress test job, annotate it with @Category(IgnoreInRepeatTestTasks.class).
  *   Do not launch any service using a port number hard-coded into the test. 
Always explicitly assign an available port. There is no safe use of any 
hard-coded port number in tests that can run concurrently.
  *   Do not attempt to reuse an ephemeral port. Some tests start a member on 
an ephemeral port, stop the member, and attempt to restart it on the same port. 
This is not safe. It was never safe. During the time between when the member 
stops and when it restarts, the port is available for the operating system to 
give to any other process. In CI, it is very, very likely that one or more 
concurrently-running tests (or other processes) will request ephemeral ports 
during the time when your test is not bound to it. If one of those processes 
gets the port your test was using, your test will fail.
This information is available on the Geode wiki: 
https://cwiki.apache.org/confluence/display/GEODE/Using+Ports+Safely+in+Tests

Dale