1#!/usr/bin/env perl
2# tests specific to the proxy request object and meta protocol
3
4use strict;
5use warnings;
6use Test::More;
7use FindBin qw($Bin);
8use lib "$Bin/lib";
9use Carp qw(croak);
10use MemcachedTest;
11use IO::Socket qw(AF_INET SOCK_STREAM);
12use IO::Select;
13
14if (!supports_proxy()) {
15    plan skip_all => 'proxy not enabled';
16    exit 0;
17}
18
19# Set up the listeners _before_ starting the proxy.
20# the fourth listener is only occasionally used.
21my $t = Memcached::ProxyTest->new(servers => [12091]);
22
23my $p_srv = new_memcached('-o proxy_config=./t/proxyrequest.lua -t 1');
24my $ps = $p_srv->sock;
25$ps->autoflush(1);
26
27$t->set_c($ps);
28$t->accept_backends();
29
30subtest 'req:flag_add()' => sub {
31    $t->c_send("mg add1 N50\r\n");
32    $t->be_recv(0, "mg add1 N50 F\r\n", "be received appended request");
33    $t->be_send(0, "HD\r\n");
34    $t->c_recv_be();
35    $t->clear();
36
37    $t->c_send("mg addstr N50\r\n");
38    $t->be_recv(0, "mg addstr N50 F1234\r\n", "be received addstr request");
39    $t->be_send(0, "HD\r\n");
40    $t->c_recv_be();
41    $t->clear();
42
43    $t->c_send("mg addnum N50\r\n");
44    $t->be_recv(0, "mg addnum N50 F5678\r\n", "be received addnum request");
45    $t->be_send(0, "HD\r\n");
46    $t->c_recv_be();
47    $t->clear();
48
49    $t->c_send("mg addexist Oexists\r\n");
50    $t->c_recv("HD\r\n", "client didn't overwrite flag");
51    $t->clear();
52};
53
54subtest 'req:flag_set()' => sub {
55    $t->c_send("mg set1 N50\r\n");
56    $t->be_recv(0, "mg set1 N50 F\r\n", "be received appended request");
57    $t->be_send(0, "HD\r\n");
58    $t->c_recv_be();
59    $t->clear();
60
61    $t->c_send("mg setstr N50\r\n");
62    $t->be_recv(0, "mg setstr N50 F4321\r\n", "be received addstr request");
63    $t->be_send(0, "HD\r\n");
64    $t->c_recv_be();
65    $t->clear();
66
67    $t->c_send("mg setnum N50\r\n");
68    $t->be_recv(0, "mg setnum N50 F8765\r\n", "be received addnum request");
69    $t->be_send(0, "HD\r\n");
70    $t->c_recv_be();
71    $t->clear();
72
73    $t->c_send("mg setexist N50 Oexists\r\n");
74    $t->be_recv(0, "mg setexist N50 Ooverwrite\r\n", "O set at end");
75    $t->be_send(0, "HD\r\n");
76    $t->c_recv_be();
77    $t->clear();
78
79    $t->c_send("mg setexist N50 Oexists T73 c\r\n");
80    $t->be_recv(0, "mg setexist N50 Ooverwrite T73 c\r\n", "O set in middle");
81    $t->be_send(0, "HD\r\n");
82    $t->c_recv_be();
83    $t->clear();
84
85    $t->c_send("mg setflag N50 Oexists T73 c\r\n");
86    $t->be_recv(0, "mg setflag N50 O T73 c\r\n", "O overwritten without token");
87    $t->be_send(0, "HD\r\n");
88    $t->c_recv_be();
89    $t->clear();
90};
91
92subtest 'req:flag_replace()' => sub {
93    $t->c_send("mg repl1 N50 F1234 T73\r\n");
94    $t->be_recv(0, "mg repl1 N50 Ofoo T73\r\n");
95    $t->be_send(0, "HD\r\n");
96    $t->c_recv_be('got repl1 test response');
97    $t->clear();
98
99    $t->c_send("mg repl2 N50 F5678 T73\r\n");
100    $t->be_recv(0, "mg repl2 N50 O T73\r\n");
101    $t->be_send(0, "HD\r\n");
102    $t->c_recv_be('got repl2 test response');
103    $t->clear();
104
105    $t->c_send("mg repl1 F\r\n");
106    $t->be_recv(0, "mg repl1 Ofoo\r\n");
107    $t->be_send(0, "HD\r\n");
108    $t->c_recv_be('got repl1 F response');
109    $t->clear();
110};
111
112subtest 'req:flag_del()' => sub {
113    $t->c_send("mg del1 N50 Oremove T80\r\n");
114    $t->be_recv(0, "mg del1 N50 T80\r\n");
115    $t->be_send(0, "HD\r\n");
116    $t->c_recv_be('got del1 middle removal');
117    $t->clear();
118
119    $t->c_send("mg del1 N51 T81 Oremove\r\n");
120    $t->be_recv(0, "mg del1 N51 T81\r\n");
121    $t->be_send(0, "HD\r\n");
122    $t->c_recv_be('got del1 end removal');
123    $t->clear();
124
125    $t->c_send("mg del1 Oremove N52 T82\r\n");
126    $t->be_recv(0, "mg del1 N52 T82\r\n");
127    $t->be_send(0, "HD\r\n");
128    $t->c_recv_be('got del1 front removal');
129    $t->clear();
130
131    $t->c_send("mg del1 O N52 T82\r\n");
132    $t->be_recv(0, "mg del1 N52 T82\r\n");
133    $t->be_send(0, "HD\r\n");
134    $t->c_recv_be('got del1 tokenless removal');
135    $t->clear();
136};
137
138subtest 'req:flag_token_int()' => sub {
139    $t->c_send("mg fint F59\r\n");
140    $t->be_recv(0, "mg fint F591\r\n");
141    $t->be_send(0, "HD\r\n");
142    $t->c_recv_be("fint converted and adjusted");
143    $t->clear();
144};
145
146subtest 'req:token_int()' => sub {
147    $t->c_send("set setints 8 10 2\r\nhi\r\n");
148    $t->be_recv(0, "set setints 20 10 2\r\n");
149    $t->be_recv(0, "hi\r\n");
150    $t->be_send(0, "STORED\r\n");
151    $t->c_recv_be("setints fetched and modified data");
152    $t->clear();
153};
154
155done_testing();
156