1fb9a25e7SSteve Yen#!/usr/bin/perl
2fb9a25e7SSteve Yen
3acefad27SSteve Yenmy $test_name     = $ARGV[0] || './t/flags.t';
4acefad27SSteve Yenmy $topology_name = $ARGV[1] || 'simple';
512b1dfdeSSteve Yenmy $protocol_name = $ARGV[2] || 'ascii';
66980f02dSSteve Yenmy $hashlib_name  = $ARGV[3] || 'libvbucket';
76980f02dSSteve Yen
819a4581aSSteve Yenprint "moxi_one.pl: " . $test_name . " " .
919a4581aSSteve Yen                        $topology_name . " " .
1019a4581aSSteve Yen                        $protocol_name . " " .
1119a4581aSSteve Yen                        $hashlib_name . "\n";
12acefad27SSteve Yen
13fb9a25e7SSteve Yenmy $prefix = <<'PREFIX';
14fb9a25e7SSteve Yen
15fb9a25e7SSteve Yenuse strict;
16fb9a25e7SSteve Yenuse FindBin qw($Bin);
17fb9a25e7SSteve Yenuse lib "$Bin/lib";
18fb9a25e7SSteve Yenuse MemcachedTest;
19fb9a25e7SSteve Yen
20fb9a25e7SSteve Yen*new_memcached_orig = *new_memcached;
21fb9a25e7SSteve Yen
22dafbac85SSteve Yenuse IO::Socket::INET;
23dafbac85SSteve Yenuse IO::Socket::UNIX;
24dafbac85SSteve Yenuse Exporter 'import';
25dafbac85SSteve Yenuse Carp qw(croak);
26dafbac85SSteve Yenuse vars qw(@EXPORT);
27dafbac85SSteve Yen
28dafbac85SSteve Yenuse Cwd;
29dafbac85SSteve Yenmy $builddir = getcwd;
30dafbac85SSteve Yen
31fb9a25e7SSteve Yensub new_memcached_proxy {
32dafbac85SSteve Yen    my ($args, $passed_port) = @_;
338c121442SSteve Yen    my $port = $passed_port || free_port();
34dafbac85SSteve Yen
358c121442SSteve Yen    TOPOLOGY
36dafbac85SSteve Yen
370bf946fdSSteve Yen    print("new moxi $args\n");
38dafbac85SSteve Yen
39dafbac85SSteve Yen    my $udpport = free_port("udp");
40dafbac85SSteve Yen    if (supports_udp()) {
41dafbac85SSteve Yen        $args .= " -U $udpport";
42dafbac85SSteve Yen    }
43dafbac85SSteve Yen    if ($< == 0) {
44dafbac85SSteve Yen        $args .= " -u root";
45dafbac85SSteve Yen    }
46dafbac85SSteve Yen    my $childpid = fork();
47dafbac85SSteve Yen
48f8f2c0abSTrond Norbye    my $exe = "$builddir/moxi";
490bf946fdSSteve Yen    croak("moxi binary doesn't exist.  Haven't run 'make' ?\n") unless -e $exe;
500bf946fdSSteve Yen    croak("moxi binary not executable\n") unless -x _;
51dafbac85SSteve Yen
52dafbac85SSteve Yen    unless ($childpid) {
5337064372SAliaksey Kandratsenka        setpgrp();
54dafbac85SSteve Yen        exec "$exe $args";
55dafbac85SSteve Yen        exit; # never gets here.
56dafbac85SSteve Yen    }
5737064372SAliaksey Kandratsenka    setpgrp $childpid, $childpid;
58dafbac85SSteve Yen
59dafbac85SSteve Yen    # unix domain sockets
60dafbac85SSteve Yen    if ($args =~ /-s (\S+)/) {
61dafbac85SSteve Yen        sleep 1;
62dafbac85SSteve Yen	my $filename = $1;
63dafbac85SSteve Yen	my $conn = IO::Socket::UNIX->new(Peer => $filename) ||
64dafbac85SSteve Yen	    croak("Failed to connect to unix domain socket: $! '$filename'");
65dafbac85SSteve Yen
6637064372SAliaksey Kandratsenka	return Memcached::Handle->new(pid  => -$childpid,
67dafbac85SSteve Yen				      conn => $conn,
68dafbac85SSteve Yen				      domainsocket => $filename,
69dafbac85SSteve Yen				      port => $port);
70dafbac85SSteve Yen    }
71dafbac85SSteve Yen
72dafbac85SSteve Yen    # try to connect / find open port, only if we're not using unix domain
73dafbac85SSteve Yen    # sockets
74dafbac85SSteve Yen
75dafbac85SSteve Yen    for (1..20) {
76dafbac85SSteve Yen	my $conn = IO::Socket::INET->new(PeerAddr => "127.0.0.1:$port");
77dafbac85SSteve Yen	if ($conn) {
7837064372SAliaksey Kandratsenka	    return Memcached::Handle->new(pid  => -$childpid,
79dafbac85SSteve Yen					  conn => $conn,
80dafbac85SSteve Yen					  udpport => $udpport,
81dafbac85SSteve Yen					  port => $port);
82dafbac85SSteve Yen	}
83dafbac85SSteve Yen	select undef, undef, undef, 0.10;
84dafbac85SSteve Yen    }
850bf946fdSSteve Yen    croak("Failed to startup/connect to moxi server.");
86dafbac85SSteve Yen}
87dafbac85SSteve Yen
88dafbac85SSteve Yensub supports_udp {
89f8f2c0abSTrond Norbye    my $output = `$builddir/moxi -h`;
90dafbac85SSteve Yen    return 0 if $output =~ /^memcached 1\.1\./;
91dafbac85SSteve Yen    return 1;
92fb9a25e7SSteve Yen}
93fb9a25e7SSteve Yen
94fb9a25e7SSteve Yen*new_memcached = *new_memcached_proxy;
95fb9a25e7SSteve Yen
96fb9a25e7SSteve YenPREFIX
97fb9a25e7SSteve Yen
986980f02dSSteve Yen# ------------------------------------------------------
996980f02dSSteve Yen
1006980f02dSSteve Yenmy $simple_topology_libmemcached = <<'SIMPLE_TOPOLOGY';
1018c121442SSteve Yen    my $portA = free_port();
1028c121442SSteve Yen    my $portC = $portA;
1038c121442SSteve Yen    my $topology =
1049fa958abSSteve Yen      " -z \"".
1058c121442SSteve Yen        "$port=".
1068c121442SSteve Yen          "localhost:$portA\"".
1078c121442SSteve Yen      " -p $portC";
1088c121442SSteve Yen    $args .= $topology;
1098c121442SSteve YenSIMPLE_TOPOLOGY
1108c121442SSteve Yen
1116980f02dSSteve Yenmy $simple_topology_libvbucket = <<'SIMPLE_TOPOLOGY';
1126980f02dSSteve Yen    my $portA = free_port();
1136980f02dSSteve Yen    my $portC = $portA;
1146980f02dSSteve Yen    my $topology =
1156980f02dSSteve Yen      " -z \'".
1166980f02dSSteve Yen       "$port={\"hashAlgorithm\": \"CRC\",\"numReplicas\": 0,".
1176980f02dSSteve Yen              "\"serverList\":[\"127.0.0.1:$portA\"],".
1186980f02dSSteve Yen              "\"vBucketMap\":[[0]]}\"\'".
1196980f02dSSteve Yen      " -p $portC";
1206980f02dSSteve Yen    $args .= $topology;
1216980f02dSSteve YenSIMPLE_TOPOLOGY
1226980f02dSSteve Yen
1236980f02dSSteve Yen# ------------------------------------------------------
1246980f02dSSteve Yen
1256980f02dSSteve Yenmy $chain_topology_libmemcached = <<'CHAIN_TOPOLOGY';
126fabb8d8dSSteve Yen    my $portA0 = free_port();
1277c0742b1SSteve Yen    my $portA1 = free_port();
1287c0742b1SSteve Yen    my $portA2 = free_port();
1297c0742b1SSteve Yen    my $portA3 = free_port();
1307c0742b1SSteve Yen    my $portA4 = free_port();
1317c0742b1SSteve Yen    my $portC = $portA4;
1327c0742b1SSteve Yen    my $topology =
1339fa958abSSteve Yen      " -z \"".
1347c0742b1SSteve Yen        "$port=".
135fabb8d8dSSteve Yen          "localhost:$portA0;".
136fabb8d8dSSteve Yen        "$portA0=".
1377c0742b1SSteve Yen          "localhost:$portA1;".
1387c0742b1SSteve Yen        "$portA1=".
1397c0742b1SSteve Yen          "localhost:$portA2;".
1407c0742b1SSteve Yen        "$portA2=".
1417c0742b1SSteve Yen          "localhost:$portA3;".
1427c0742b1SSteve Yen        "$portA3=".
1437c0742b1SSteve Yen          "localhost:$portA4\"".
1447c0742b1SSteve Yen      " -p $portC";
1457c0742b1SSteve Yen    $args .= $topology;
1467c0742b1SSteve YenCHAIN_TOPOLOGY
1477c0742b1SSteve Yen
1486980f02dSSteve Yenmy $chain_topology_libvbucket = <<'CHAIN_TOPOLOGY';
1496980f02dSSteve Yen    my $portA0 = free_port();
1506980f02dSSteve Yen    my $portA1 = free_port();
1516980f02dSSteve Yen    my $portA2 = free_port();
1526980f02dSSteve Yen    my $portA3 = free_port();
1536980f02dSSteve Yen    my $portA4 = free_port();
1546980f02dSSteve Yen    my $portC = $portA4;
1556980f02dSSteve Yen    my $topology =
1566980f02dSSteve Yen      " -z \'".
1576980f02dSSteve Yen       "$port={\"hashAlgorithm\": \"CRC\",\"numReplicas\": 0,".
1586980f02dSSteve Yen              "\"serverList\":[\"127.0.0.1:$portA0\"],".
1596980f02dSSteve Yen              "\"vBucketMap\":[[0]]};".
1606980f02dSSteve Yen       "$portA0={\"hashAlgorithm\": \"CRC\",\"numReplicas\": 0,".
1616980f02dSSteve Yen              "\"serverList\":[\"127.0.0.1:$portA1\"],".
1626980f02dSSteve Yen              "\"vBucketMap\":[[0]]};".
1636980f02dSSteve Yen       "$portA1={\"hashAlgorithm\": \"CRC\",\"numReplicas\": 0,".
1646980f02dSSteve Yen              "\"serverList\":[\"127.0.0.1:$portA2\"],".
1656980f02dSSteve Yen              "\"vBucketMap\":[[0]]};".
1666980f02dSSteve Yen       "$portA2={\"hashAlgorithm\": \"CRC\",\"numReplicas\": 0,".
1676980f02dSSteve Yen              "\"serverList\":[\"127.0.0.1:$portA3\"],".
1686980f02dSSteve Yen              "\"vBucketMap\":[[0]]};".
1696980f02dSSteve Yen       "$portA3={\"hashAlgorithm\": \"CRC\",\"numReplicas\": 0,".
1706980f02dSSteve Yen              "\"serverList\":[\"127.0.0.1:$portA4\"],".
1716980f02dSSteve Yen              "\"vBucketMap\":[[0]]}\'".
1726980f02dSSteve Yen      " -p $portC";
1736980f02dSSteve Yen    $args .= $topology;
1746980f02dSSteve YenCHAIN_TOPOLOGY
1756980f02dSSteve Yen
1766980f02dSSteve Yen# ------------------------------------------------------
1776980f02dSSteve Yen
1786980f02dSSteve Yenmy $fanout_topology_libmemcached = <<'FANOUT_TOPOLOGY';
1798c121442SSteve Yen    my $portA = free_port();
1808c121442SSteve Yen    my $portC = $portA;
1818c121442SSteve Yen    my $topology =
1829fa958abSSteve Yen      " -z \"".
1838c121442SSteve Yen        "$port=".
1848c121442SSteve Yen          "localhost:$portA,".
1858c121442SSteve Yen          "localhost:$portA,".
1868c121442SSteve Yen          "localhost:$portA,".
1878c121442SSteve Yen          "localhost:$portA\"".
1888c121442SSteve Yen      " -p $portC";
1898c121442SSteve Yen    $args .= $topology;
1908c121442SSteve YenFANOUT_TOPOLOGY
1918c121442SSteve Yen
1926980f02dSSteve Yenmy $fanout_topology_libvbucket = <<'FANOUT_TOPOLOGY';
1936980f02dSSteve Yen    my $portA = free_port();
1946980f02dSSteve Yen    my $portC = $portA;
1956980f02dSSteve Yen    my $topology =
1966980f02dSSteve Yen      " -z \'".
1976980f02dSSteve Yen       "$port={\"hashAlgorithm\": \"CRC\",\"numReplicas\": 0,".
1986980f02dSSteve Yen              "\"serverList\":[\"127.0.0.1:$portA\",\"127.0.0.1:$portA\",\"127.0.0.1:$portA\",\"127.0.0.1:$portA\"],".
1996980f02dSSteve Yen              "\"vBucketMap\":[[0],[1],[2],[3]]}\'".
2006980f02dSSteve Yen      " -p $portC";
2016980f02dSSteve Yen    $args .= $topology;
2026980f02dSSteve YenFANOUT_TOPOLOGY
2036980f02dSSteve Yen
2046980f02dSSteve Yen# ------------------------------------------------------
2056980f02dSSteve Yen
2066980f02dSSteve Yenmy $fanoutin_topology_libmemcached = <<'FANOUTIN_TOPOLOGY';
2078c121442SSteve Yen    my $portA = free_port();
2088c121442SSteve Yen    my $portB = free_port();
2098c121442SSteve Yen    my $portC = $portB;
2108c121442SSteve Yen    my $topology =
2119fa958abSSteve Yen      " -z \"".
2128c121442SSteve Yen        "$port=".
2138c121442SSteve Yen          "localhost:$portA,".
2148c121442SSteve Yen          "localhost:$portA,".
2158c121442SSteve Yen          "localhost:$portA,".
2168c121442SSteve Yen          "localhost:$portA;".
2178c121442SSteve Yen        "$portA=".
2188c121442SSteve Yen          "localhost:$portB\"".
2198c121442SSteve Yen      " -p $portC";
2208c121442SSteve Yen    $args .= $topology;
2218c121442SSteve YenFANOUTIN_TOPOLOGY
2228c121442SSteve Yen
2236980f02dSSteve Yenmy $fanoutin_topology_libvbucket = <<'FANOUTIN_TOPOLOGY';
2246980f02dSSteve Yen    my $portA = free_port();
2256980f02dSSteve Yen    my $portB = free_port();
2266980f02dSSteve Yen    my $portC = $portB;
2276980f02dSSteve Yen    my $topology =
2286980f02dSSteve Yen      " -z \'".
2296980f02dSSteve Yen       "$port={\"hashAlgorithm\": \"CRC\",\"numReplicas\": 0,".
2306980f02dSSteve Yen              "\"serverList\":[\"127.0.0.1:$portA\",\"127.0.0.1:$portA\",\"127.0.0.1:$portA\",\"127.0.0.1:$portA\"],".
2316980f02dSSteve Yen              "\"vBucketMap\":[[0],[1],[2],[3]]};".
2326980f02dSSteve Yen       "$portA={\"hashAlgorithm\": \"CRC\",\"numReplicas\": 0,".
2336980f02dSSteve Yen              "\"serverList\":[\"127.0.0.1:$portB\"],".
2346980f02dSSteve Yen              "\"vBucketMap\":[[0]]}\'".
2356980f02dSSteve Yen      " -p $portC";
2366980f02dSSteve Yen    $args .= $topology;
2376980f02dSSteve YenFANOUTIN_TOPOLOGY
2386980f02dSSteve Yen
2396980f02dSSteve Yen# ------------------------------------------------------
2406980f02dSSteve Yen
2416980f02dSSteve Yenmy %topology_map_libmemcached = (
2426980f02dSSteve Yen    'simple' => $simple_topology_libmemcached,
2436980f02dSSteve Yen    'chain' => $chain_topology_libmemcached,
2446980f02dSSteve Yen    'fanout' => $fanout_topology_libmemcached,
2456980f02dSSteve Yen    'fanoutin' => $fanoutin_topology_libmemcached
2468c121442SSteve Yen);
2478c121442SSteve Yen
2486980f02dSSteve Yenmy %topology_map_libvbucket = (
2496980f02dSSteve Yen    'simple' => $simple_topology_libvbucket,
2506980f02dSSteve Yen    'chain' => $chain_topology_libvbucket,
2516980f02dSSteve Yen    'fanout' => $fanout_topology_libvbucket,
2526980f02dSSteve Yen    'fanoutin' => $fanoutin_topology_libvbucket,
2536980f02dSSteve Yen);
2546980f02dSSteve Yen
2556980f02dSSteve Yen# ------------------------------------------------------
2566980f02dSSteve Yen
2576980f02dSSteve Yenmy $topology = $topology_map_libvbucket{$topology_name};
2586980f02dSSteve Yen
2596980f02dSSteve Yenif ($hashlib_name eq 'libmemcached') {
2606980f02dSSteve Yen    $topology = $topology_map_libmemcached{$topology_name};
2616980f02dSSteve Yen}
2626980f02dSSteve Yen
2636980f02dSSteve Yen# ------------------------------------------------------
264fb9a25e7SSteve Yen
26519a4581aSSteve Yen$topology .= ("\$args .= \" -Z downstream_protocol=$protocol_name," .
26619a4581aSSteve Yen              "downstream_max=1,downstream_conn_max=0\";");
26712b1dfdeSSteve Yen
268fb9a25e7SSteve Yen# Tack on ./t/ directory prefix if needed.
269fb9a25e7SSteve Yenif ($test_name !~ /^\.\/t/) {
270fb9a25e7SSteve Yen  $test_name = "./t/$test_name";
271fb9a25e7SSteve Yen}
272fb9a25e7SSteve Yen
273fb9a25e7SSteve Yen# Tack on .t filename suffix if needed.
274fb9a25e7SSteve Yenif ($test_name !~ /\.t$/) {
275fb9a25e7SSteve Yen  $test_name = "$test_name.t";
276fb9a25e7SSteve Yen}
277fb9a25e7SSteve Yen
27883904f90SSteve Yen$prefix =~ s/TOPOLOGY/{$topology }/g;
27983904f90SSteve Yen
28083904f90SSteve Yeneval($prefix . `cat $test_name`);
28183904f90SSteve Yen
28283904f90SSteve Yenprint($@);
283