using namespace libtest;
+struct socket_st {
+ std::vector<int> fd;
+
+ ~socket_st()
+ {
+ for(std::vector<int>::iterator iter= fd.begin(); iter != fd.end(); iter++)
+ {
+ close(*iter);
+ }
+ }
+};
+
+static socket_st all_socket_fd;
+
static in_port_t global_port= 0;
-static in_port_t global_max_port= 0;
namespace libtest {
in_port_t default_port()
{
- return global_port;
-}
-
-void set_default_port(in_port_t port)
-{
- global_port= port;
-}
-
-in_port_t max_port()
-{
- return global_max_port;
-}
-
-void set_max_port(in_port_t port)
-{
- if (port > global_max_port)
+ if (global_port == 0)
{
- global_max_port= port;
+ global_port= get_free_port();
}
- global_max_port= port;
+ return global_port;
}
in_port_t get_free_port()
{
in_port_t ret_port= in_port_t(0);
- int sd;
- if ((sd= socket(AF_INET, SOCK_STREAM, 0)) != -1)
+
+ int retries= 1024;
+
+ while (retries--)
{
- int optval= 1;
- if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) != -1)
+ int sd;
+ if ((sd= socket(AF_INET, SOCK_STREAM, 0)) != -1)
{
- struct sockaddr_in sin;
- sin.sin_port= 0;
- sin.sin_addr.s_addr= 0;
- sin.sin_addr.s_addr= INADDR_ANY;
- sin.sin_family= AF_INET;
-
- if (bind(sd, (struct sockaddr *)&sin,sizeof(struct sockaddr_in) ) != -1)
+ int optval= 1;
+ if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) != -1)
{
- socklen_t addrlen= sizeof(sin);
+ struct sockaddr_in sin;
+ sin.sin_port= 0;
+ sin.sin_addr.s_addr= 0;
+ sin.sin_addr.s_addr= INADDR_ANY;
+ sin.sin_family= AF_INET;
- if (listen(sd, 100) != -1)
+ if (bind(sd, (struct sockaddr *)&sin,sizeof(struct sockaddr_in) ) != -1)
{
+ socklen_t addrlen= sizeof(sin);
+
if (getsockname(sd, (struct sockaddr *)&sin, &addrlen) != -1)
{
ret_port= sin.sin_port;
+ Error << ret_port;
}
}
}
+
+ all_socket_fd.fd.push_back(sd);
+ }
+
+ if (ret_port > 1024)
+ {
+ break;
}
+ }
- close(sd);
+ // We handle the case where if we max out retries, we still abort.
+ if (ret_port <= 1024)
+ {
+ abort();
}
return ret_port;
LIBTEST_API
in_port_t default_port();
-LIBTEST_API
-void set_default_port(in_port_t port);
-
-LIBTEST_API
-in_port_t max_port();
-
-LIBTEST_API
-void set_max_port(in_port_t port);
-
LIBTEST_API
in_port_t get_free_port();
Outn();
(void)try_port;
- set_max_port(try_port);
-
- // Look to see if we are being provided ports to use
- {
- char variable_buffer[1024];
- snprintf(variable_buffer, sizeof(variable_buffer), "LIBTEST_PORT_%lu", (unsigned long)construct.count());
-
- char *var;
- if ((var= getenv(variable_buffer)))
- {
- in_port_t tmp= in_port_t(atoi(var));
-
- if (tmp > 0)
- try_port= tmp;
- }
- }
-
libtest::Server *server= NULL;
if (0)
{ }
construct.push_server(server);
- if (default_port() == 0)
- {
- assert(server->has_port());
- set_default_port(server->port());
- }
-
Outn();
return true;
{
in_port_t ret_port;
test_true_hint((ret_port= get_free_port()), ret_port);
+ test_true(get_free_port() != default_port());
+ test_true(get_free_port() != get_free_port());
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t default_port_TEST(void *)
+{
+ in_port_t ret_port= default_port();
+ test_compare(ret_port, libtest::default_port());
+ test_compare(ret_port, libtest::default_port());
+
return TEST_SUCCESS;
}
test_st get_free_port_TESTS[] ={
{"get_free_port()", 0, get_free_port_TEST },
+ {"default_port()", 0, default_port_TEST },
{0, 0, 0}
};
while (memcached_server_count(memc) < 2)
{
const char *argv[1]= { "add_shutdown_server" };
- in_port_t port= max_port() +1;
+ in_port_t port= libtest::get_free_port();
test_true(global_framework->servers().start_socket_server("memcached", port, 1, argv));
test_compare(MEMCACHED_SUCCESS, memcached_server_add(memc, "localhost", port));
}
static test_return_t binary_TEST(void *)
{
char buffer[1024];
- snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port()));
+ snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(libtest::default_port()));
const char *args[]= { "--quiet", buffer, " --binary ", 0 };
test_true(exec_cmdline(executable, args));
static test_return_t server_version_TEST(void *)
{
char buffer[1024];
- snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port()));
+ snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(libtest::default_port()));
const char *args[]= { "--quiet", buffer, " --server-version", 0 };
test_true(exec_cmdline(executable, args));
static test_return_t binary_server_version_TEST(void *)
{
char buffer[1024];
- snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port()));
+ snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(libtest::default_port()));
const char *args[]= { "--quiet", buffer, " --binary --server-version", 0 };
test_true(exec_cmdline(executable, args));
}
const char *argv[1]= { "memstat" };
- if (not server_startup(servers, "memcached", libtest::get_free_port(), 1, argv))
+ if (server_startup(servers, "memcached", libtest::default_port(), 1, argv) == false)
{
error= TEST_FAILURE;
}