Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Communicating between processes in test suite run

2 views
Skip to first unread message

Cosimo Streppone

unread,
Apr 23, 2015, 12:15:06 PM4/23/15
to per...@perl.org
Hi,

trying to pick your brains here.
I hope to be able to explain decently what I'm trying to achieve.

This is about the test suite of Net::Statsd::Server, a perl port
of the javascript statsd daemon, and in particular the
t/integration-tests/*.t cases.

Integration here means that the *.t files, through a
Test::Statsd class, bring up a Net::Statsd::Server server
on a fixed port, f.ex. 40001.

This "bringing up" happens by fork and exec of a given binary
(bin/statsd in the same dist). I chose this path because I can
run my unmodified test suite against the javascript statsd
and test that the js and perl versions behave exactly the same.

Now, problem.

I'd like to use port 0 to bring up the daemon, so that the test suite
can be run in parallel without port clashes. With port == 0 the TCP/UDP
bind will happen on a random free port.

When the fork + exec'd daemon chooses a random port, I need to be able
to know which port it has bound itself to, and here lies the problem.

How would you communicate this information back to the parent process
that spawns the daemon binary?

The solution I found so far works but it's totally unsatisfactory to me.

Basically I set an ENV variable such as $ENV{STATSD_PORT_FILE} with a
temporary random file name.

In the daemon startup code, if $ENV{HARNESS_ACTIVE} and
$ENV{STATSD_PORT_FILE} are both there (since the daemon is spawned by
the *.t script), then the port number is saved into the file name
indicated by $ENV{STATSD_PORT_FILE}.

I don't like this mess.

--
Cosimo

Tim Bunce

unread,
Apr 23, 2015, 1:15:02 PM4/23/15
to Cosimo Streppone, per...@perl.org
On Thu, Apr 23, 2015 at 05:59:34PM +0200, Cosimo Streppone wrote:
>
> Now, problem.
>
> I'd like to use port 0 to bring up the daemon, so that the test suite
> can be run in parallel without port clashes. With port == 0 the TCP/UDP
> bind will happen on a random free port.
>
> When the fork + exec'd daemon chooses a random port, I need to be able
> to know which port it has bound itself to, and here lies the problem.
>
> How would you communicate this information back to the parent process
> that spawns the daemon binary?

Perhaps dodge the problem by not picking a random port. Have the parent
process look for free ports itself in some obscure part of the range.
Then pass that port number to the daemon. There's a very small race
hazard here but that seems quite acceptable under the circumstances.
Especially as you'll know you've hit it because the statsd daemon will die.

> The solution I found so far works but it's totally unsatisfactory to me.
>
> Basically I set an ENV variable such as $ENV{STATSD_PORT_FILE} with a
> temporary random file name.
>
> In the daemon startup code, if $ENV{HARNESS_ACTIVE} and
> $ENV{STATSD_PORT_FILE} are both there (since the daemon is spawned by
> the *.t script), then the port number is saved into the file name
> indicated by $ENV{STATSD_PORT_FILE}.
>
> I don't like this mess.

How is "the port number is saved into the file" when you don't know
which port it has bound itself to?

Tim.

Cosimo Streppone

unread,
Apr 23, 2015, 2:30:03 PM4/23/15
to per...@perl.org, Tim Bunce
On 23. april 2015 19:02, Tim Bunce wrote:

> On Thu, Apr 23, 2015 at 05:59:34PM +0200, Cosimo Streppone wrote:
>>
>> When the fork + exec'd daemon chooses a random port, I need to be able
>> to know which port it has bound itself to, and here lies the problem.
>
> Perhaps dodge the problem by not picking a random port. Have the parent
> process look for free ports itself in some obscure part of the range.
> Then pass that port number to the daemon. There's a very small race
> hazard here but that seems quite acceptable under the circumstances.
> Especially as you'll know you've hit it because the statsd daemon will die.

Thanks Tim, I can certainly experiment with this idea.
My hunch is that port clashes will still happen, but that
needs to be verified.

>> Basically I set an ENV variable such as $ENV{STATSD_PORT_FILE} with a
>> temporary random file name.
>>
>> In the daemon startup code, if $ENV{HARNESS_ACTIVE} and
>> $ENV{STATSD_PORT_FILE} are both there (since the daemon is spawned by
>> the *.t script), then the port number is saved into the file name
>> indicated by $ENV{STATSD_PORT_FILE}.
>
> How is "the port number is saved into the file" when you don't know
> which port it has bound itself to?

The daemon starts and binds using port 0. Still within the daemon code,
I can then query for the used port, through regular socket calls.
After that, I check for HARNESS_ACTIVE and STATSD_PORT_FILE
and I write the port to the file indicated by STATSD_PORT_FILE.

Of course I don't like that the statsd daemon code needs to know about
this at all.

Thanks,

--
Cosimo

Chad Granum

unread,
Apr 23, 2015, 2:30:03 PM4/23/15
to Cosimo Streppone, Perl QA, Tim Bunce
Can you start the server and get the port in the parent process, then fork and run the tests from the child?

Chad Granum

unread,
Apr 23, 2015, 2:30:03 PM4/23/15
to Cosimo Streppone, Perl QA, Tim Bunce
oops ignore my last message, obviously forking the server is a dumb idea.

Cosimo Streppone

unread,
Apr 23, 2015, 2:45:01 PM4/23/15
to Perl QA, Chad Granum
On 23. april 2015 20:23, Chad Granum wrote:

> Can you start the server and get the port in the parent process, then
> fork and run the tests from the child?

Unfortunately that is not possible, as client and server code
are completely separated, and I'd like to run
the test suite against the javascript statsd daemon
(think another black box binary I have no control over).

--
Cosimo


Tim Bunce

unread,
Apr 23, 2015, 4:00:02 PM4/23/15
to Cosimo Streppone, per...@perl.org, Tim Bunce
That approach only applies to your perl statsd, right? For the nodejs
or C statsd's you don't have an easy[*] a way to find the port.

Tim.

[*] Ignoring options like parsing log output of running lsof.

Cosimo Streppone

unread,
Apr 23, 2015, 5:45:02 PM4/23/15
to Tim Bunce, per...@perl.org
Il 23/04/2015 21:53, Tim Bunce ha scritto:

>>> How is "the port number is saved into the file" when you don't know
>>> which port it has bound itself to?
>>
>> The daemon starts and binds using port 0. Still within the daemon code,
>> I can then query for the used port, through regular socket calls.
>> After that, I check for HARNESS_ACTIVE and STATSD_PORT_FILE
>> and I write the port to the file indicated by STATSD_PORT_FILE.
>>
>> Of course I don't like that the statsd daemon code needs to know about
>> this at all.
>
> That approach only applies to your perl statsd, right? For the nodejs
> or C statsd's you don't have an easy[*] a way to find the port.

Correct. That would be an argument in favour of avoiding port zero,
and providing the daemon binary with a dynamic configuration,
so the port is chosen before-hand by the test "client".

--
Cosimo

Michael Kiwala

unread,
Apr 24, 2015, 12:30:02 PM4/24/15
to Tim Bunce, Cosimo Streppone, Perl QA
I was about to suggest running `lsof -i -sTCP:LISTEN -p $PID_OF_STATSD` in the parent after the server has been spawned, when I noticed that Tim already mentioned the lsof option in his footnote.

Why not use lsof to query the port that was assigned?

Michael

 

Cosimo Streppone

unread,
Apr 25, 2015, 3:30:02 PM4/25/15
to Michael Kiwala, Perl QA
Il 24/04/2015 18:12, Michael Kiwala ha scritto:
> On Thu, Apr 23, 2015 at 2:53 PM, Tim Bunce <Tim....@pobox.com
> <mailto:Tim....@pobox.com>> wrote:
>
> That approach only applies to your perl statsd, right? For the nodejs
> or C statsd's you don't have an easy[*] a way to find the port.
>
> I was about to suggest running `lsof -i -sTCP:LISTEN -p $PID_OF_STATSD`
> in the parent after the server has been spawned, when I noticed that Tim
> already mentioned the lsof option in his footnote.
>
> Why not use lsof to query the port that was assigned?

I'm often a bit reluctant to use system commands as that
makes the whole process more OS dependent.

Even considering Win32 out of the picture, is lsof working
in the same way for every OS where perl is running?

I guess that is my only argument against it, but thanks for
suggesting it, it's certainly a valid strategy.

--
Cosimo

David Cantrell

unread,
Apr 27, 2015, 9:30:01 AM4/27/15
to per...@perl.org
On Sat, Apr 25, 2015 at 09:19:00PM +0200, Cosimo Streppone wrote:
> Il 24/04/2015 18:12, Michael Kiwala ha scritto:
> >Why not use lsof to query the port that was assigned?
> I'm often a bit reluctant to use system commands as that
> makes the whole process more OS dependent.
> Even considering Win32 out of the picture, is lsof working
> in the same way for every OS where perl is running?

Never mind working - is it even installed?

--
David Cantrell | Official London Perl Mongers Bad Influence

You are so cynical. And by "cynical", of course, I mean "correct".
-- Kurt Starsinic

Lars Dɪᴇᴄᴋᴏᴡ 迪拉斯

unread,
May 27, 2015, 4:45:01 AM5/27/15
to per...@perl.org
> avoiding port zero,
> and providing the daemon binary with a dynamic configuration,
> so the port is chosen before-hand by the test "client".

http://p3rl.org/Net::EmptyPort does that.
0 new messages