---
name: "Test::TCP"
section: "3pm"
platform: "linux"
package: "libtest-tcp-perl"
version: "2.22-2"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/Test::TCP"
---

# Test::TCP(3pm)

testing TCP program

## NAME

Test::TCP - testing TCP program

## SYNOPSIS

```
    use Test::TCP;
    my $server = Test::TCP->new(
        listen => 1,
        code => sub {
            my $socket = shift;
            ...
        },
    );
    my $client = MyClient->new(host => '127.0.0.1', port => $server->port);
    undef $server; # kill child process on DESTROY
```

If using a server that can only accept a port number, e.g. memcached:

```
    use Test::TCP;
    my $memcached = Test::TCP->new(
        code => sub {
            my $port = shift;
            exec $bin, '-p' => $port;
            die "cannot execute $bin: $!";
        },
    );
    my $memd = Cache::Memcached->new({servers => ['127.0.0.1:' . $memcached->port]});
    ...
```

**N.B.**: This is vulnerable to race conditions, if another process binds to the same port after Net::EmptyPort found it available.

And functional interface is available:

```
    use Test::TCP;
    test_tcp(
        listen => 1,
        client => sub {
            my ($port, $server_pid) = @_;
            # send request to the server
        },
        server => sub {
            my $socket = shift;
            # run server, calling $socket->accept
        },
    );
    test_tcp(
        client => sub {
            my ($port, $server_pid) = @_;
            # send request to the server
        },
        server => sub {
            my $port = shift;
            # run server, binding to $port
        },
    );
```

## DESCRIPTION

Test::TCP is a test utility to test TCP/IP-based server programs.

## METHODS

- test\_tcp

  Functional interface.

  ```
      test_tcp(
          listen => 1,
          client => sub {
              my $port = shift;
              # send request to the server
          },
          server => sub {
              my $socket = shift;
              # run server
          },
          # optional
          host => '127.0.0.1', # specify '::1' to test using IPv6
          port => 8080,
          max_wait => 3, # seconds
      );
  ```

  If `"listen"` is false, `"server"` is instead passed a port number that was free before it was called.

- wait\_port

  ```
      wait_port(8080);
  ```

  Waits for a particular port is available for connect.

## Object Oriented interface

- my $server = Test::TCP-\>new(%args);

  Create new instance of Test::TCP.

  Arguments are following:

  - $args{auto\_start}: Boolean

    Call `"$server->start()"` after create instance.

    Default: true

  - $args{code}: CodeRef

    The callback function. Argument for callback function is: `"$code->($socket)"` or `"$code->($port)"`, depending on the value of `"listen"`.

    This parameter is required.

  - $args{max\_wait} : Number

    Will wait for at most `$max_wait` seconds before checking port.

    See also Net::EmptyPort.

    *Default: 10*

  - $args{listen} : Boolean

    If true, open a listening socket and pass this to the callback. Otherwise find a free port and pass the number of it to the callback.

- $server-\>**start()**

  Start the server process. Normally, you don't need to call this method.

- $server-\>**stop()**

  Stop the server process.

- my $pid = $server-\>**pid()**;

  Get the pid of child process.

- my $port = $server-\>**port()**;

  Get the port number of child process.

## FAQ

- How to invoke two servers?

  You can call **test\_tcp()** twice!

  ```
      test_tcp(
          client => sub {
              my $port1 = shift;
              test_tcp(
                  client => sub {
                      my $port2 = shift;
                      # some client code here
                  },
                  server => sub {
                      my $port2 = shift;
                      # some server2 code here
                  },
              );
          },
          server => sub {
              my $port1 = shift;
              # some server1 code here
          },
      );
  ```

  Or use the OO interface instead.

  ```
      my $server1 = Test::TCP->new(code => sub {
          my $port1 = shift;
          ...
      });
      my $server2 = Test::TCP->new(code => sub {
          my $port2 = shift;
          ...
      });
      # your client code here.
      ...
  ```

- How do you test server program written in other languages like memcached?

  You can use `"exec()"` in child process.

  ```
      use strict;
      use warnings;
      use utf8;
      use Test::More;
      use Test::TCP 1.08;
      use File::Which;
      my $bin = scalar which 'memcached';
      plan skip_all => 'memcached binary is not found' unless defined $bin;
      my $memcached = Test::TCP->new(
          code => sub {
              my $port = shift;
              exec $bin, '-p' => $port;
              die "cannot execute $bin: $!";
          },
      );
      use Cache::Memcached;
      my $memd = Cache::Memcached->new({servers => ['127.0.0.1:' . $memcached->port]});
      $memd->set(foo => 'bar');
      is $memd->get('foo'), 'bar';
      done_testing;
  ```

- How do I use address other than "127.0.0.1" for testing?

  You can use the `"host"` parameter to specify the bind address.

  ```
      # let the server bind to "0.0.0.0" for testing
      test_tcp(
          client => sub {
              ...
          },
          server => sub {
              ...
          },
          host => '0.0.0.0',
      );
  ```

- How should I write IPv6 tests?

  You should use the "can\_bind" in Net::EmptyPort function to check if the program can bind to the loopback address of IPv6, as well as the `"host"` parameter of the "test\_tcp" function to specify the same address as the bind address.

  ```
      use Net::EmptyPort qw(can_bind);
      plan skip_all => "IPv6 not available"
          unless can_bind('::1');
      test_tcp(
          client => sub {
              ...
          },
          server => sub {
              ...
          },
          host => '::1',
      );
  ```

## AUTHOR

Tokuhiro Matsuno \<tokuhirom@gmail.com\>

## THANKS TO

kazuhooku

dragon3

charsbar

Tatsuhiko Miyagawa

lestrrat

## SEE ALSO

## LICENSE

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
