test: one engine pump and one preedit check for the white-box suites
server_test, ibus_test and xim_adapter_test each ran their own copy of the same alt loop that stands in for imthread, and two of them had private checkstr/checkenginepreedit variants. test_util.c now provides Pump (trace, optional hold on a chosen op, stop) in its own proc so a test may block in socket I/O while the engine runs, and test.h declares the engine hooks once; every .c includes dat.h and fn.h itself as the rest of the tree does. server_test's three copies of fixture setup and teardown became serverbegin/serverend.
This commit is contained in:
@@ -4,24 +4,18 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "srv.c"
|
||||
#include "cutest/cutest.h"
|
||||
|
||||
void testengineinit(int);
|
||||
void testenginehandle(Keyreq*);
|
||||
void* testengineowner(void);
|
||||
void testenginepreedit(Str*);
|
||||
#include "test.h"
|
||||
|
||||
#undef recv
|
||||
|
||||
typedef struct Enginegate Enginegate;
|
||||
typedef struct Serverfix Serverfix;
|
||||
typedef struct Testclient Testclient;
|
||||
|
||||
struct Enginegate
|
||||
/* A held pump plus a private client-slot channel of the wanted depth. */
|
||||
struct Serverfix
|
||||
{
|
||||
Channel *seen;
|
||||
Channel *go;
|
||||
Channel *stop;
|
||||
Channel *done;
|
||||
Pump pump;
|
||||
Channel *oldclientc;
|
||||
};
|
||||
|
||||
struct Testclient
|
||||
@@ -34,30 +28,30 @@ struct Testclient
|
||||
};
|
||||
|
||||
static void
|
||||
enginegate(void *arg)
|
||||
serverbegin(Serverfix *f, int nclients)
|
||||
{
|
||||
Enginegate *g;
|
||||
Keyreq req;
|
||||
Drawcmd dc;
|
||||
uchar token;
|
||||
Alt alts[] = {
|
||||
{keyc, &req, CHANRCV, nil},
|
||||
{nil, &token, CHANRCV, nil},
|
||||
{nil, nil, CHANEND, nil},
|
||||
};
|
||||
|
||||
g = arg;
|
||||
alts[1].c = g->stop;
|
||||
for(;;)
|
||||
switch(alt(alts)){
|
||||
case 0:
|
||||
chansend(g->seen, &req);
|
||||
chanrecv(g->go, &token);
|
||||
testenginehandle(&req);
|
||||
break;
|
||||
case 1:
|
||||
chansend(g->done, &token);
|
||||
return;
|
||||
}
|
||||
f->oldclientc = clientc;
|
||||
while(channbrecv(drawc, &dc) > 0)
|
||||
;
|
||||
clientc = chancreate(sizeof token, nclients);
|
||||
testengineinit(LangJP);
|
||||
pumpstart(&f->pump, 0);
|
||||
pumphold(&f->pump, Pumpall);
|
||||
}
|
||||
|
||||
static void
|
||||
serverend(Serverfix *f)
|
||||
{
|
||||
Drawcmd dc;
|
||||
|
||||
pumpstop(&f->pump);
|
||||
chanfree(clientc);
|
||||
clientc = f->oldclientc;
|
||||
while(channbrecv(drawc, &dc) > 0)
|
||||
;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -142,30 +136,30 @@ sendreset(struct ct *t, Testclient *client, int want)
|
||||
}
|
||||
|
||||
static Keyreq
|
||||
nextrequestcap(struct ct *t, Enginegate *g, int op, int cap)
|
||||
nextrequestcap(struct ct *t, Pump *p, int op, int cap)
|
||||
{
|
||||
Keyreq req;
|
||||
|
||||
memset(&req, 0, sizeof req);
|
||||
chanrecv(g->seen, &req);
|
||||
chanrecv(p->trace, &req);
|
||||
CT_EQ_INT(t, op, req.op);
|
||||
CT_EQ_INT(t, cap, req.cap);
|
||||
return req;
|
||||
}
|
||||
|
||||
static Keyreq
|
||||
nextrequest(struct ct *t, Enginegate *g, int op)
|
||||
nextrequest(struct ct *t, Pump *p, int op)
|
||||
{
|
||||
return nextrequestcap(t, g, op, Cclientpreedit);
|
||||
return nextrequestcap(t, p, op, Cclientpreedit);
|
||||
}
|
||||
|
||||
static void
|
||||
allowrequest(Enginegate *g)
|
||||
allowrequest(Pump *p)
|
||||
{
|
||||
uchar token;
|
||||
|
||||
token = 0;
|
||||
chansend(g->go, &token);
|
||||
chansend(p->go, &token);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -222,126 +216,111 @@ waitclient(struct ct *t, Testclient *client)
|
||||
}
|
||||
|
||||
static void
|
||||
disconnectclient(struct ct *t, Enginegate *g, Testclient *client, void *owner)
|
||||
disconnectclient(struct ct *t, Pump *p, Testclient *client, void *owner)
|
||||
{
|
||||
Keyreq req;
|
||||
uchar token;
|
||||
|
||||
close(client->peer);
|
||||
client->peer = -1;
|
||||
req = nextrequest(t, g, Keyrelease);
|
||||
req = nextrequest(t, p, Keyrelease);
|
||||
if(owner != nil)
|
||||
CT_EQ_PTR(t, owner, req.owner);
|
||||
CT_CHECK(t, channbrecv(client->done, &token) <= 0);
|
||||
allowrequest(g);
|
||||
allowrequest(p);
|
||||
waitclient(t, client);
|
||||
}
|
||||
|
||||
void
|
||||
server_connection_ownership(struct ct *t)
|
||||
{
|
||||
Channel *oldclientc;
|
||||
Enginegate gate;
|
||||
Serverfix f;
|
||||
Testclient a, b, c;
|
||||
Keyreq req;
|
||||
Drawcmd dc;
|
||||
Str shown;
|
||||
char preedit[Ipcfieldmax+1];
|
||||
void *aowner, *bowner, *cowner;
|
||||
uchar byte, token;
|
||||
ssize_t n;
|
||||
int gateactive;
|
||||
|
||||
memset(&gate, 0, sizeof gate);
|
||||
memset(&a, 0, sizeof a);
|
||||
memset(&b, 0, sizeof b);
|
||||
memset(&c, 0, sizeof c);
|
||||
a.fd = a.peer = b.fd = b.peer = c.fd = c.peer = -1;
|
||||
aowner = bowner = cowner = nil;
|
||||
oldclientc = clientc;
|
||||
while(channbrecv(drawc, &dc) > 0)
|
||||
;
|
||||
clientc = chancreate(sizeof token, 3);
|
||||
gate.seen = chancreate(sizeof(Keyreq), 0);
|
||||
gate.go = chancreate(sizeof token, 0);
|
||||
gate.stop = chancreate(sizeof token, 0);
|
||||
gate.done = chancreate(sizeof token, 0);
|
||||
testengineinit(LangJP);
|
||||
gateactive = proccreate(enginegate, &gate, 8192) >= 0;
|
||||
if(!CT_CHECK(t, gateactive))
|
||||
goto cleanup;
|
||||
serverbegin(&f, 3);
|
||||
if(!startclient(t, &a) || !startclient(t, &b))
|
||||
goto cleanup;
|
||||
|
||||
if(!sendkey(t, &a, 1, 0, 'k'))
|
||||
goto cleanup;
|
||||
req = nextrequest(t, &gate, Keypress);
|
||||
req = nextrequest(t, &f.pump, Keypress);
|
||||
aowner = req.owner;
|
||||
allowrequest(&gate);
|
||||
allowrequest(&f.pump);
|
||||
CT_CHECK(t, readreply(t, &a, 1, preedit));
|
||||
CT_EQ_STR(t, "k", preedit);
|
||||
if(!sendkey(t, &a, 1, 0, 'a'))
|
||||
goto cleanup;
|
||||
req = nextrequest(t, &gate, Keypress);
|
||||
req = nextrequest(t, &f.pump, Keypress);
|
||||
CT_EQ_PTR(t, aowner, req.owner);
|
||||
allowrequest(&gate);
|
||||
allowrequest(&f.pump);
|
||||
CT_CHECK(t, readreply(t, &a, 1, preedit));
|
||||
CT_EQ_STR(t, "か", preedit);
|
||||
CT_EQ_PTR(t, aowner, testengineowner());
|
||||
|
||||
if(!sendkey(t, &b, 1, 0, 'n'))
|
||||
goto cleanup;
|
||||
req = nextrequest(t, &gate, Keypress);
|
||||
req = nextrequest(t, &f.pump, Keypress);
|
||||
bowner = req.owner;
|
||||
CT_CHECK(t, bowner != aowner);
|
||||
allowrequest(&gate);
|
||||
allowrequest(&f.pump);
|
||||
CT_CHECK(t, readreply(t, &b, 1, preedit));
|
||||
CT_EQ_STR(t, "ん", preedit);
|
||||
CT_EQ_PTR(t, bowner, testengineowner());
|
||||
|
||||
if(!sendreset(t, &a, 1))
|
||||
goto cleanup;
|
||||
req = nextrequest(t, &gate, Keyreset);
|
||||
req = nextrequest(t, &f.pump, Keyreset);
|
||||
CT_EQ_PTR(t, aowner, req.owner);
|
||||
allowrequest(&gate);
|
||||
allowrequest(&f.pump);
|
||||
CT_CHECK(t, readreply(t, &a, 1, preedit));
|
||||
CT_EQ_STR(t, "", preedit);
|
||||
CT_EQ_PTR(t, bowner, testengineowner());
|
||||
if(!sendkey(t, &b, 1, 0, Kmodfirst))
|
||||
goto cleanup;
|
||||
req = nextrequest(t, &gate, Keypress);
|
||||
allowrequest(&gate);
|
||||
req = nextrequest(t, &f.pump, Keypress);
|
||||
allowrequest(&f.pump);
|
||||
CT_CHECK(t, !readreply(t, &b, 1, preedit));
|
||||
CT_EQ_STR(t, "ん", preedit);
|
||||
|
||||
disconnectclient(t, &gate, &a, aowner);
|
||||
disconnectclient(t, &f.pump, &a, aowner);
|
||||
CT_EQ_PTR(t, bowner, testengineowner());
|
||||
if(!sendkey(t, &b, 1, 0, 'y'))
|
||||
goto cleanup;
|
||||
req = nextrequest(t, &gate, Keypress);
|
||||
allowrequest(&gate);
|
||||
req = nextrequest(t, &f.pump, Keypress);
|
||||
allowrequest(&f.pump);
|
||||
CT_CHECK(t, readreply(t, &b, 1, preedit));
|
||||
if(!sendkey(t, &b, 1, 0, 'a'))
|
||||
goto cleanup;
|
||||
req = nextrequest(t, &gate, Keypress);
|
||||
allowrequest(&gate);
|
||||
req = nextrequest(t, &f.pump, Keypress);
|
||||
allowrequest(&f.pump);
|
||||
CT_CHECK(t, readreply(t, &b, 1, preedit));
|
||||
CT_EQ_STR(t, "にゃ", preedit);
|
||||
|
||||
if(!sendreset(t, &b, 1))
|
||||
goto cleanup;
|
||||
req = nextrequest(t, &gate, Keyreset);
|
||||
req = nextrequest(t, &f.pump, Keyreset);
|
||||
CT_EQ_PTR(t, bowner, req.owner);
|
||||
allowrequest(&gate);
|
||||
allowrequest(&f.pump);
|
||||
CT_CHECK(t, readreply(t, &b, 1, preedit));
|
||||
CT_EQ_STR(t, "", preedit);
|
||||
CT_EQ_PTR(t, bowner, testengineowner());
|
||||
|
||||
if(!sendkey(t, &b, 0, 0, 'k'))
|
||||
goto cleanup;
|
||||
req = nextrequestcap(t, &gate, Keypress, 0);
|
||||
req = nextrequestcap(t, &f.pump, Keypress, 0);
|
||||
CT_EQ_PTR(t, bowner, req.owner);
|
||||
allowrequest(&gate);
|
||||
allowrequest(&f.pump);
|
||||
CT_CHECK(t, readreply(t, &b, 0, preedit));
|
||||
errno = 0;
|
||||
n = recv(b.peer, &byte, 1, MSG_PEEK|MSG_DONTWAIT);
|
||||
@@ -350,12 +329,12 @@ server_connection_ownership(struct ct *t)
|
||||
CT_EQ_PTR(t, bowner, testengineowner());
|
||||
if(!sendkey(t, &b, 1, 0, 'a'))
|
||||
goto cleanup;
|
||||
req = nextrequest(t, &gate, Keypress);
|
||||
allowrequest(&gate);
|
||||
req = nextrequest(t, &f.pump, Keypress);
|
||||
allowrequest(&f.pump);
|
||||
CT_CHECK(t, readreply(t, &b, 1, preedit));
|
||||
CT_EQ_STR(t, "か", preedit);
|
||||
|
||||
disconnectclient(t, &gate, &b, bowner);
|
||||
disconnectclient(t, &f.pump, &b, bowner);
|
||||
CT_EQ_PTR(t, nil, testengineowner());
|
||||
testenginepreedit(&shown);
|
||||
CT_EQ_INT(t, 0, shown.n);
|
||||
@@ -364,72 +343,45 @@ server_connection_ownership(struct ct *t)
|
||||
goto cleanup;
|
||||
if(!sendkey(t, &c, 1, 0, 'k'))
|
||||
goto cleanup;
|
||||
req = nextrequest(t, &gate, Keypress);
|
||||
req = nextrequest(t, &f.pump, Keypress);
|
||||
cowner = req.owner;
|
||||
close(c.peer);
|
||||
c.peer = -1;
|
||||
allowrequest(&gate);
|
||||
req = nextrequest(t, &gate, Keyrelease);
|
||||
allowrequest(&f.pump);
|
||||
req = nextrequest(t, &f.pump, Keyrelease);
|
||||
CT_EQ_PTR(t, cowner, req.owner);
|
||||
CT_EQ_PTR(t, cowner, testengineowner());
|
||||
CT_CHECK(t, channbrecv(c.done, &token) <= 0);
|
||||
allowrequest(&gate);
|
||||
allowrequest(&f.pump);
|
||||
waitclient(t, &c);
|
||||
CT_EQ_PTR(t, nil, testengineowner());
|
||||
CT_CHECK(t, channbrecv(clientc, &token) <= 0);
|
||||
|
||||
cleanup:
|
||||
if(a.peer >= 0)
|
||||
disconnectclient(t, &gate, &a, aowner);
|
||||
disconnectclient(t, &f.pump, &a, aowner);
|
||||
if(b.peer >= 0)
|
||||
disconnectclient(t, &gate, &b, bowner);
|
||||
disconnectclient(t, &f.pump, &b, bowner);
|
||||
if(c.peer >= 0)
|
||||
disconnectclient(t, &gate, &c, cowner);
|
||||
if(gateactive){
|
||||
token = 0;
|
||||
chansend(gate.stop, &token);
|
||||
chanrecv(gate.done, &token);
|
||||
}
|
||||
chanfree(gate.seen);
|
||||
chanfree(gate.go);
|
||||
chanfree(gate.stop);
|
||||
chanfree(gate.done);
|
||||
chanfree(clientc);
|
||||
clientc = oldclientc;
|
||||
while(channbrecv(drawc, &dc) > 0)
|
||||
;
|
||||
disconnectclient(t, &f.pump, &c, cowner);
|
||||
serverend(&f);
|
||||
}
|
||||
|
||||
void
|
||||
server_extension_stream(struct ct *t)
|
||||
{
|
||||
Channel *oldclientc;
|
||||
Enginegate gate;
|
||||
Serverfix f;
|
||||
Testclient a, b;
|
||||
Keyreq req;
|
||||
Drawcmd dc;
|
||||
uchar frame[Ipccaretsz], token;
|
||||
uchar frame[Ipccaretsz];
|
||||
char preedit[Ipcfieldmax+1];
|
||||
void *aowner, *bowner;
|
||||
int gateactive;
|
||||
|
||||
memset(&gate, 0, sizeof gate);
|
||||
memset(&a, 0, sizeof a);
|
||||
memset(&b, 0, sizeof b);
|
||||
a.fd = a.peer = b.fd = b.peer = -1;
|
||||
aowner = bowner = nil;
|
||||
oldclientc = clientc;
|
||||
while(channbrecv(drawc, &dc) > 0)
|
||||
;
|
||||
clientc = chancreate(sizeof token, 2);
|
||||
gate.seen = chancreate(sizeof(Keyreq), 0);
|
||||
gate.go = chancreate(sizeof token, 0);
|
||||
gate.stop = chancreate(sizeof token, 0);
|
||||
gate.done = chancreate(sizeof token, 0);
|
||||
testengineinit(LangJP);
|
||||
gateactive = proccreate(enginegate, &gate, 8192) >= 0;
|
||||
if(!CT_CHECK(t, gateactive))
|
||||
goto cleanup;
|
||||
serverbegin(&f, 2);
|
||||
if(!startclient(t, &a))
|
||||
goto cleanup;
|
||||
|
||||
@@ -437,36 +389,36 @@ server_extension_stream(struct ct *t)
|
||||
ipcpackcap(frame, Cclientpreedit);
|
||||
if(!sendframe(t, &a, frame, Ipcreqsz, 1))
|
||||
goto cleanup;
|
||||
req = nextrequest(t, &gate, Keycap);
|
||||
req = nextrequest(t, &f.pump, Keycap);
|
||||
aowner = req.owner;
|
||||
CT_EQ_PTR(t, nil, testengineowner());
|
||||
allowrequest(&gate);
|
||||
allowrequest(&f.pump);
|
||||
CT_EQ_INT(t, 1, readreply(t, &a, 1, preedit));
|
||||
CT_EQ_STR(t, "", preedit);
|
||||
|
||||
ipcpackcaret(frame, 1, -101, -7, 23);
|
||||
if(!sendframe(t, &a, frame, Ipccaretsz, 1))
|
||||
goto cleanup;
|
||||
req = nextrequest(t, &gate, Keycaret);
|
||||
req = nextrequest(t, &f.pump, Keycaret);
|
||||
CT_EQ_PTR(t, aowner, req.owner);
|
||||
CT_EQ_INT(t, 1, req.caret.valid);
|
||||
CT_EQ_INT(t, -101, req.caret.x);
|
||||
CT_EQ_INT(t, -7, req.caret.y);
|
||||
CT_EQ_INT(t, 23, req.caret.h);
|
||||
CT_EQ_PTR(t, nil, testengineowner());
|
||||
allowrequest(&gate);
|
||||
allowrequest(&f.pump);
|
||||
checknoreply(t, &a);
|
||||
|
||||
ipcpackreq(frame, 1, 0, 'k');
|
||||
if(!sendframe(t, &a, frame, Ipcreqsz, 1))
|
||||
goto cleanup;
|
||||
req = nextrequest(t, &gate, Keypress);
|
||||
req = nextrequest(t, &f.pump, Keypress);
|
||||
CT_EQ_PTR(t, aowner, req.owner);
|
||||
CT_EQ_INT(t, 1, req.caret.valid);
|
||||
CT_EQ_INT(t, -101, req.caret.x);
|
||||
CT_EQ_INT(t, -7, req.caret.y);
|
||||
CT_EQ_INT(t, 23, req.caret.h);
|
||||
allowrequest(&gate);
|
||||
allowrequest(&f.pump);
|
||||
CT_EQ_INT(t, 1, readreply(t, &a, 1, preedit));
|
||||
CT_EQ_STR(t, "k", preedit);
|
||||
CT_EQ_PTR(t, aowner, testengineowner());
|
||||
@@ -474,108 +426,81 @@ server_extension_stream(struct ct *t)
|
||||
ipcpackcap(frame, 0);
|
||||
if(!sendframe(t, &a, frame, Ipcreqsz, 0))
|
||||
goto cleanup;
|
||||
req = nextrequestcap(t, &gate, Keycap, 0);
|
||||
req = nextrequestcap(t, &f.pump, Keycap, 0);
|
||||
CT_EQ_PTR(t, aowner, req.owner);
|
||||
CT_EQ_INT(t, 1, req.caret.valid);
|
||||
allowrequest(&gate);
|
||||
allowrequest(&f.pump);
|
||||
CT_EQ_INT(t, 1, readreply(t, &a, 0, preedit));
|
||||
|
||||
/* Reset is still the old six-byte frame and does not discard caret. */
|
||||
ipcpackreset(frame, 0);
|
||||
if(!sendframe(t, &a, frame, Ipcreqsz, 1))
|
||||
goto cleanup;
|
||||
req = nextrequestcap(t, &gate, Keyreset, 0);
|
||||
req = nextrequestcap(t, &f.pump, Keyreset, 0);
|
||||
CT_EQ_PTR(t, aowner, req.owner);
|
||||
CT_EQ_INT(t, 1, req.caret.valid);
|
||||
CT_EQ_INT(t, -101, req.caret.x);
|
||||
CT_EQ_INT(t, -7, req.caret.y);
|
||||
CT_EQ_INT(t, 23, req.caret.h);
|
||||
allowrequest(&gate);
|
||||
allowrequest(&f.pump);
|
||||
CT_EQ_INT(t, 1, readreply(t, &a, 0, preedit));
|
||||
|
||||
ipcpackcap(frame, Cclientpreedit);
|
||||
if(!sendframe(t, &a, frame, Ipcreqsz, 0))
|
||||
goto cleanup;
|
||||
req = nextrequest(t, &gate, Keycap);
|
||||
allowrequest(&gate);
|
||||
req = nextrequest(t, &f.pump, Keycap);
|
||||
allowrequest(&f.pump);
|
||||
CT_EQ_INT(t, 1, readreply(t, &a, 1, preedit));
|
||||
CT_EQ_STR(t, "", preedit);
|
||||
ipcpackreq(frame, 1, 0, 'n');
|
||||
if(!sendframe(t, &a, frame, Ipcreqsz, 0))
|
||||
goto cleanup;
|
||||
req = nextrequest(t, &gate, Keypress);
|
||||
req = nextrequest(t, &f.pump, Keypress);
|
||||
CT_EQ_INT(t, 1, req.caret.valid);
|
||||
CT_EQ_INT(t, -101, req.caret.x);
|
||||
allowrequest(&gate);
|
||||
allowrequest(&f.pump);
|
||||
CT_EQ_INT(t, 1, readreply(t, &a, 1, preedit));
|
||||
CT_EQ_STR(t, "ん", preedit);
|
||||
|
||||
disconnectclient(t, &gate, &a, aowner);
|
||||
disconnectclient(t, &f.pump, &a, aowner);
|
||||
|
||||
/* Disconnect drops state; a legacy client gets the historical defaults. */
|
||||
if(!startclient(t, &b) || !sendkey(t, &b, 1, 0, 'k'))
|
||||
goto cleanup;
|
||||
req = nextrequest(t, &gate, Keypress);
|
||||
req = nextrequest(t, &f.pump, Keypress);
|
||||
bowner = req.owner;
|
||||
CT_EQ_INT(t, 0, req.caret.valid);
|
||||
allowrequest(&gate);
|
||||
allowrequest(&f.pump);
|
||||
CT_EQ_INT(t, 1, readreply(t, &b, 1, preedit));
|
||||
CT_EQ_STR(t, "k", preedit);
|
||||
|
||||
disconnectclient(t, &gate, &b, bowner);
|
||||
disconnectclient(t, &f.pump, &b, bowner);
|
||||
|
||||
cleanup:
|
||||
if(a.peer >= 0)
|
||||
disconnectclient(t, &gate, &a, aowner);
|
||||
disconnectclient(t, &f.pump, &a, aowner);
|
||||
if(b.peer >= 0)
|
||||
disconnectclient(t, &gate, &b, bowner);
|
||||
if(gateactive){
|
||||
token = 0;
|
||||
chansend(gate.stop, &token);
|
||||
chanrecv(gate.done, &token);
|
||||
}
|
||||
chanfree(gate.seen);
|
||||
chanfree(gate.go);
|
||||
chanfree(gate.stop);
|
||||
chanfree(gate.done);
|
||||
chanfree(clientc);
|
||||
clientc = oldclientc;
|
||||
while(channbrecv(drawc, &dc) > 0)
|
||||
;
|
||||
disconnectclient(t, &f.pump, &b, bowner);
|
||||
serverend(&f);
|
||||
}
|
||||
|
||||
void
|
||||
server_rejects_unknown_extension(struct ct *t)
|
||||
{
|
||||
Channel *oldclientc;
|
||||
Enginegate gate;
|
||||
Serverfix f;
|
||||
Testclient badver, badop, good;
|
||||
Keyreq req;
|
||||
Drawcmd dc;
|
||||
uchar frame[Ipccaretsz], token;
|
||||
uchar frame[Ipccaretsz];
|
||||
char preedit[Ipcfieldmax+1];
|
||||
void *owner;
|
||||
int gateactive;
|
||||
|
||||
memset(&gate, 0, sizeof gate);
|
||||
memset(&badver, 0, sizeof badver);
|
||||
memset(&badop, 0, sizeof badop);
|
||||
memset(&good, 0, sizeof good);
|
||||
badver.fd = badver.peer = badop.fd = badop.peer = -1;
|
||||
good.fd = good.peer = -1;
|
||||
owner = nil;
|
||||
oldclientc = clientc;
|
||||
while(channbrecv(drawc, &dc) > 0)
|
||||
;
|
||||
clientc = chancreate(sizeof token, 3);
|
||||
gate.seen = chancreate(sizeof(Keyreq), 0);
|
||||
gate.go = chancreate(sizeof token, 0);
|
||||
gate.stop = chancreate(sizeof token, 0);
|
||||
gate.done = chancreate(sizeof token, 0);
|
||||
testengineinit(LangJP);
|
||||
gateactive = proccreate(enginegate, &gate, 8192) >= 0;
|
||||
if(!CT_CHECK(t, gateactive))
|
||||
goto cleanup;
|
||||
serverbegin(&f, 3);
|
||||
|
||||
if(!startclient(t, &badver))
|
||||
goto cleanup;
|
||||
@@ -583,8 +508,8 @@ server_rejects_unknown_extension(struct ct *t)
|
||||
frame[1]++;
|
||||
if(!sendframe(t, &badver, frame, sizeof frame, 0))
|
||||
goto cleanup;
|
||||
req = nextrequest(t, &gate, Keyrelease);
|
||||
allowrequest(&gate);
|
||||
req = nextrequest(t, &f.pump, Keyrelease);
|
||||
allowrequest(&f.pump);
|
||||
waitclient(t, &badver);
|
||||
close(badver.peer);
|
||||
badver.peer = -1;
|
||||
@@ -595,8 +520,8 @@ server_rejects_unknown_extension(struct ct *t)
|
||||
frame[2]++;
|
||||
if(!sendframe(t, &badop, frame, sizeof frame, 1))
|
||||
goto cleanup;
|
||||
req = nextrequest(t, &gate, Keyrelease);
|
||||
allowrequest(&gate);
|
||||
req = nextrequest(t, &f.pump, Keyrelease);
|
||||
allowrequest(&f.pump);
|
||||
waitclient(t, &badop);
|
||||
close(badop.peer);
|
||||
badop.peer = -1;
|
||||
@@ -604,31 +529,19 @@ server_rejects_unknown_extension(struct ct *t)
|
||||
/* A malformed peer must not disturb another client connection. */
|
||||
if(!startclient(t, &good) || !sendkey(t, &good, 1, 0, 'k'))
|
||||
goto cleanup;
|
||||
req = nextrequest(t, &gate, Keypress);
|
||||
req = nextrequest(t, &f.pump, Keypress);
|
||||
owner = req.owner;
|
||||
allowrequest(&gate);
|
||||
allowrequest(&f.pump);
|
||||
CT_EQ_INT(t, 1, readreply(t, &good, 1, preedit));
|
||||
CT_EQ_STR(t, "k", preedit);
|
||||
disconnectclient(t, &gate, &good, owner);
|
||||
disconnectclient(t, &f.pump, &good, owner);
|
||||
|
||||
cleanup:
|
||||
if(badver.peer >= 0)
|
||||
disconnectclient(t, &gate, &badver, nil);
|
||||
disconnectclient(t, &f.pump, &badver, nil);
|
||||
if(badop.peer >= 0)
|
||||
disconnectclient(t, &gate, &badop, nil);
|
||||
disconnectclient(t, &f.pump, &badop, nil);
|
||||
if(good.peer >= 0)
|
||||
disconnectclient(t, &gate, &good, owner);
|
||||
if(gateactive){
|
||||
token = 0;
|
||||
chansend(gate.stop, &token);
|
||||
chanrecv(gate.done, &token);
|
||||
}
|
||||
chanfree(gate.seen);
|
||||
chanfree(gate.go);
|
||||
chanfree(gate.stop);
|
||||
chanfree(gate.done);
|
||||
chanfree(clientc);
|
||||
clientc = oldclientc;
|
||||
while(channbrecv(drawc, &dc) > 0)
|
||||
;
|
||||
disconnectclient(t, &f.pump, &good, owner);
|
||||
serverend(&f);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user