mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2024-12-29 10:26:36 +01:00
changes to support automated testing of background messages sends: new
param gives name of Unix domain socket to be used to accept connection that passes in messages from relay and receives messages to be sent back. Works once but needs debugging....
This commit is contained in:
parent
c952ebd8e6
commit
c992c65015
4 changed files with 239 additions and 47 deletions
|
@ -1,6 +1,6 @@
|
|||
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; compile-command: "make MEMDEBUG=TRUE"; -*- */
|
||||
/* -*- compile-command: "make MEMDEBUG=TRUE -j3"; -*- */
|
||||
/*
|
||||
* Copyright 2000-2009 by Eric House (xwords@eehouse.org). All rights
|
||||
* Copyright 2000-2011 by Eric House (xwords@eehouse.org). All rights
|
||||
* reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -52,6 +52,7 @@
|
|||
#include "xwproto.h"
|
||||
#include "xwstream.h"
|
||||
#include "xwstate.h"
|
||||
#include "strutils.h"
|
||||
#include "server.h"
|
||||
#include "memstream.h"
|
||||
#include "util.h"
|
||||
|
@ -1575,6 +1576,53 @@ positionSizeStuff( CursesAppGlobals* globals, int width, int height )
|
|||
board_invalAll( board );
|
||||
} /* positionSizeStuff */
|
||||
|
||||
static XP_Bool
|
||||
relay_sendNoConn_curses( const XP_U8* msg, XP_U16 len,
|
||||
const XP_UCHAR* relayID, void* closure )
|
||||
{
|
||||
LOG_FUNC();
|
||||
CursesAppGlobals* globals = (CursesAppGlobals*)closure;
|
||||
CommonGlobals* cGlobals = &globals->cGlobals;
|
||||
int fd = cGlobals->nbsFD;
|
||||
XP_Bool success = 0 <= fd;
|
||||
if ( success ) {
|
||||
XP_LOGF( "%s: given %d bytes for %s", __func__, len, relayID );
|
||||
|
||||
// format: total msg lenth: 2
|
||||
// number-of-relayIDs: 2
|
||||
// for-each-relayid: relayid + '\n': varies
|
||||
// message count: 1
|
||||
// for-each-message: length: 2
|
||||
// message: varies
|
||||
|
||||
XWStreamCtxt* stream =
|
||||
mem_stream_make( MPPARM(globals->cGlobals.params->util->mpool)
|
||||
globals->cGlobals.params->vtMgr,
|
||||
globals, CHANNEL_NONE, NULL );
|
||||
stream_putU16( stream, 1 ); /* number of relayIDs */
|
||||
stream_catString( stream, relayID );
|
||||
stream_putU8( stream, '\n' );
|
||||
stream_putU16( stream, 1 ); /* message count */
|
||||
stream_putU16( stream, len );
|
||||
stream_putBytes( stream, msg, len );
|
||||
|
||||
XP_U16 siz = stream_getSize( stream );
|
||||
XP_U8 buf[siz];
|
||||
stream_getBytes( stream, buf, siz );
|
||||
XP_U16 tmp = XP_HTONS( siz );
|
||||
ssize_t nwritten = write( fd, &tmp, sizeof(tmp) );
|
||||
XP_ASSERT( nwritten == sizeof(tmp) );
|
||||
nwritten = write( fd, buf/*stream_getPtr( stream )*/, siz );
|
||||
log_hex( buf/*stream_getPtr( stream )*/, siz, __func__ );
|
||||
XP_ASSERT( nwritten == siz );
|
||||
stream_destroy( stream );
|
||||
} else {
|
||||
XP_LOGF( "%s: nbsFD=%d", __func__, fd );
|
||||
}
|
||||
LOG_RETURNF( "%d", success );
|
||||
return success;
|
||||
} /* relay_sendNoConn_curses */
|
||||
|
||||
static void
|
||||
relay_status_curses( void* XP_UNUSED(closure),
|
||||
CommsRelayState XP_UNUSED_DBG(state) )
|
||||
|
@ -1654,6 +1702,7 @@ cursesmain( XP_Bool isServer, LaunchParams* params )
|
|||
g_globals.cGlobals.cp.robotThinkMin = params->robotThinkMin;
|
||||
g_globals.cGlobals.cp.robotThinkMax = params->robotThinkMax;
|
||||
#endif
|
||||
g_globals.cGlobals.nbsFD = -1;
|
||||
|
||||
setupCursesUtilCallbacks( &g_globals, params->util );
|
||||
|
||||
|
@ -1681,8 +1730,26 @@ cursesmain( XP_Bool isServer, LaunchParams* params )
|
|||
struct sigaction act2 = { .sa_handler = SIGWINCH_handler };
|
||||
sigaction( SIGWINCH, &act2, NULL );
|
||||
|
||||
TransportProcs procs = {
|
||||
.closure = &g_globals,
|
||||
.send = LINUX_SEND,
|
||||
#ifdef COMMS_HEARTBEAT
|
||||
.reset = linux_reset,
|
||||
#endif
|
||||
#ifdef XWFEATURE_RELAY
|
||||
.rstatus = relay_status_curses,
|
||||
.rconnd = relay_connd_curses,
|
||||
.rerror = relay_error_curses,
|
||||
.sendNoConn = relay_sendNoConn_curses,
|
||||
.flags = COMMS_XPORT_FLAGS_HASNOCONN,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
if ( !!params->pipe && !!params->fileName ) {
|
||||
read_pipe_then_close( &g_globals.cGlobals );
|
||||
read_pipe_then_close( &g_globals.cGlobals, &procs );
|
||||
} else if ( !!params->nbs && !!params->fileName ) {
|
||||
do_nbs_then_close( &g_globals.cGlobals, &procs );
|
||||
} else {
|
||||
|
||||
initCurses( &g_globals );
|
||||
|
@ -1691,19 +1758,6 @@ cursesmain( XP_Bool isServer, LaunchParams* params )
|
|||
g_globals.draw = (struct CursesDrawCtx*)
|
||||
cursesDrawCtxtMake( g_globals.boardWin );
|
||||
|
||||
TransportProcs procs = {
|
||||
.closure = &g_globals,
|
||||
.send = LINUX_SEND,
|
||||
#ifdef COMMS_HEARTBEAT
|
||||
.reset = linux_reset,
|
||||
#endif
|
||||
#ifdef XWFEATURE_RELAY
|
||||
.rstatus = relay_status_curses,
|
||||
.rconnd = relay_connd_curses,
|
||||
.rerror = relay_error_curses,
|
||||
#endif
|
||||
};
|
||||
|
||||
if ( !!params->fileName && file_exists( params->fileName ) ) {
|
||||
XWStreamCtxt* stream;
|
||||
stream = streamFromFile( &g_globals.cGlobals, params->fileName,
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <time.h>
|
||||
#include <syslog.h>
|
||||
#include <stdarg.h>
|
||||
#include <linux/un.h>
|
||||
|
||||
#ifdef XWFEATURE_BLUETOOTH
|
||||
# include <bluetooth/bluetooth.h>
|
||||
|
@ -189,9 +190,11 @@ strFromStream( XWStreamCtxt* stream )
|
|||
return buf;
|
||||
} /* strFromStream */
|
||||
|
||||
void
|
||||
read_pipe_then_close( CommonGlobals* cGlobals )
|
||||
static void
|
||||
handle_messages_from( CommonGlobals* cGlobals, const TransportProcs* procs,
|
||||
int fdin )
|
||||
{
|
||||
LOG_FUNC();
|
||||
LaunchParams* params = cGlobals->params;
|
||||
XWStreamCtxt* stream =
|
||||
streamFromFile( cGlobals, params->fileName, cGlobals );
|
||||
|
@ -204,45 +207,167 @@ read_pipe_then_close( CommonGlobals* cGlobals )
|
|||
¶ms->gi, params->dict,
|
||||
¶ms->dicts, params->util,
|
||||
NULL /*draw*/,
|
||||
&cGlobals->cp, NULL );
|
||||
&cGlobals->cp, procs );
|
||||
XP_ASSERT( opened );
|
||||
stream_destroy( stream );
|
||||
|
||||
XP_Bool handled = XP_FALSE;
|
||||
int fd = open( params->pipe, O_RDONLY );
|
||||
while ( fd >= 0 ) {
|
||||
unsigned short len;
|
||||
ssize_t nRead = blocking_read( fd, (unsigned char*)&len, sizeof(len) );
|
||||
if ( nRead != 2 ) {
|
||||
unsigned short len;
|
||||
for ( ; ; ) {
|
||||
ssize_t nRead = blocking_read( fdin, (unsigned char*)&len,
|
||||
sizeof(len) );
|
||||
if ( nRead != sizeof(len) ) {
|
||||
XP_LOGF( "%s: 1: unexpected nRead: %d", __func__, nRead );
|
||||
break;
|
||||
}
|
||||
len = ntohs( len );
|
||||
if ( 0 == len ) {
|
||||
break;
|
||||
}
|
||||
unsigned char buf[len];
|
||||
nRead = blocking_read( fd, buf, len );
|
||||
nRead = blocking_read( fdin, buf, len );
|
||||
if ( nRead != len ) {
|
||||
XP_LOGF( "%s: 2: unexpected nRead: %d", __func__, nRead );
|
||||
break;
|
||||
}
|
||||
stream = mem_stream_make( MPPARM(cGlobals->params->util->mpool)
|
||||
params->vtMgr, cGlobals, CHANNEL_NONE, NULL );
|
||||
params->vtMgr, cGlobals, CHANNEL_NONE,
|
||||
NULL );
|
||||
stream_putBytes( stream, buf, len );
|
||||
|
||||
if ( comms_checkIncomingStream( cGlobals->game.comms,
|
||||
stream, NULL ) ) {
|
||||
handled = server_receiveMessage( cGlobals->game.server,
|
||||
stream ) || handled;
|
||||
ServerCtxt* server = cGlobals->game.server;
|
||||
(void)server_do( server, NULL );
|
||||
handled = server_receiveMessage( server, stream ) || handled;
|
||||
|
||||
XP_Bool notDone;
|
||||
XP_U16 ii;
|
||||
for ( ii = 0, notDone = XP_TRUE; notDone && ii < 5; ++ii ) {
|
||||
(void)server_do( server, ¬Done );
|
||||
}
|
||||
}
|
||||
stream_destroy( stream );
|
||||
}
|
||||
LOG_RETURNF( "%d", handled );
|
||||
|
||||
/* Write it out */
|
||||
/* stream = mem_stream_make( MEMPOOLCG(cGlobals) params->vtMgr, */
|
||||
/* cGlobals, 0, writeToFile ); */
|
||||
/* stream_open( stream ); */
|
||||
/* game_saveToStream( &cGlobals->game, ¶ms->gi, stream ); */
|
||||
/* stream_destroy( stream ); */
|
||||
LOG_RETURN_VOID();
|
||||
} /* handle_messages_from */
|
||||
|
||||
void
|
||||
read_pipe_then_close( CommonGlobals* cGlobals, const TransportProcs* procs )
|
||||
{
|
||||
LOG_FUNC();
|
||||
LaunchParams* params = cGlobals->params;
|
||||
XWStreamCtxt* stream =
|
||||
streamFromFile( cGlobals, params->fileName, cGlobals );
|
||||
|
||||
#ifdef DEBUG
|
||||
XP_Bool opened =
|
||||
#endif
|
||||
game_makeFromStream( MPPARM(cGlobals->params->util->mpool)
|
||||
stream, &cGlobals->game,
|
||||
¶ms->gi, params->dict,
|
||||
¶ms->dicts, params->util,
|
||||
NULL /*draw*/,
|
||||
&cGlobals->cp, procs );
|
||||
XP_ASSERT( opened );
|
||||
stream_destroy( stream );
|
||||
|
||||
XP_Bool handled = XP_FALSE;
|
||||
int fd = open( params->pipe, O_RDWR );
|
||||
XP_ASSERT( fd >= 0 );
|
||||
if ( fd >= 0 ) {
|
||||
unsigned short len;
|
||||
for ( ; ; ) {
|
||||
ssize_t nRead = blocking_read( fd, (unsigned char*)&len,
|
||||
sizeof(len) );
|
||||
if ( nRead != sizeof(len) ) {
|
||||
XP_LOGF( "%s: 1: unexpected nRead: %d", __func__, nRead );
|
||||
break;
|
||||
}
|
||||
len = ntohs( len );
|
||||
if ( 0 == len ) {
|
||||
break;
|
||||
}
|
||||
unsigned char buf[len];
|
||||
nRead = blocking_read( fd, buf, len );
|
||||
if ( nRead != len ) {
|
||||
XP_LOGF( "%s: 2: unexpected nRead: %d", __func__, nRead );
|
||||
break;
|
||||
}
|
||||
stream = mem_stream_make( MPPARM(cGlobals->params->util->mpool)
|
||||
params->vtMgr, cGlobals, CHANNEL_NONE,
|
||||
NULL );
|
||||
stream_putBytes( stream, buf, len );
|
||||
|
||||
if ( comms_checkIncomingStream( cGlobals->game.comms,
|
||||
stream, NULL ) ) {
|
||||
ServerCtxt* server = cGlobals->game.server;
|
||||
(void)server_do( server, NULL );
|
||||
handled = server_receiveMessage( server, stream ) || handled;
|
||||
|
||||
XP_Bool notDone;
|
||||
XP_U16 ii;
|
||||
for ( ii = 0, notDone = XP_TRUE; notDone && ii < 5; ++ii ) {
|
||||
(void)server_do( server, ¬Done );
|
||||
}
|
||||
}
|
||||
stream_destroy( stream );
|
||||
}
|
||||
|
||||
/* 0-length packet closes it off */
|
||||
XP_LOGF( "%s: writing 0-length packet", __func__ );
|
||||
len = 0;
|
||||
ssize_t nwritten = write( fd, &len, sizeof(len) );
|
||||
XP_ASSERT( nwritten == sizeof(len) );
|
||||
|
||||
close( fd );
|
||||
}
|
||||
|
||||
LOG_RETURN_VOID();
|
||||
} /* read_pipe_then_close */
|
||||
|
||||
void
|
||||
do_nbs_then_close( CommonGlobals* cGlobals, const TransportProcs* procs )
|
||||
{
|
||||
LOG_FUNC();
|
||||
int sockfd = socket( AF_UNIX, SOCK_STREAM, 0 );
|
||||
|
||||
struct sockaddr_un addr;
|
||||
addr.sun_family = AF_UNIX;
|
||||
strcpy( addr.sun_path, cGlobals->params->nbs );
|
||||
|
||||
int err = bind( sockfd, (struct sockaddr*)&addr, sizeof(addr) );
|
||||
if ( 0 != err ) {
|
||||
XP_LOGF( "%s: bind=>%s", __func__, strerror( errno ) );
|
||||
XP_ASSERT( 0 );
|
||||
}
|
||||
XP_LOGF( "calling listen" );
|
||||
err = listen( sockfd, 1 );
|
||||
assert( 0 == err );
|
||||
|
||||
struct sockaddr remote;
|
||||
socklen_t addrlen = sizeof(remote);
|
||||
XP_LOGF( "calling accept" );
|
||||
int fd = accept( sockfd, &remote, &addrlen );
|
||||
XP_LOGF( "%s: accept=>%d", __func__, fd );
|
||||
assert( 0 <= fd );
|
||||
|
||||
/* do stuff here */
|
||||
cGlobals->nbsFD = fd;
|
||||
handle_messages_from( cGlobals, procs, fd );
|
||||
cGlobals->nbsFD = -1;
|
||||
|
||||
/* Do I need this? Will reader get err if I close? */
|
||||
unsigned short len = 0;
|
||||
ssize_t nwritten = write( fd, &len, sizeof(len) );
|
||||
XP_ASSERT( nwritten == sizeof(len) );
|
||||
|
||||
close( fd );
|
||||
close( sockfd );
|
||||
LOG_RETURN_VOID();
|
||||
} /* do_nbs_then_close */
|
||||
|
||||
typedef enum {
|
||||
CMD_SKIP_GAMEOVER
|
||||
,CMD_SHOW_OTHERSCORES
|
||||
|
@ -280,6 +405,7 @@ typedef enum {
|
|||
,CMD_VERTICALSCORE
|
||||
,CMD_NOPEEK
|
||||
,CMD_ADDPIPE
|
||||
,CMD_ADDNBS
|
||||
#ifdef XWFEATURE_SEARCHLIMIT
|
||||
,CMD_HINTRECT
|
||||
#endif
|
||||
|
@ -354,6 +480,8 @@ static CmdInfoRec CmdInfoRecs[] = {
|
|||
,{ CMD_VERTICALSCORE, false, "vertical", "scoreboard is vertical" }
|
||||
,{ CMD_NOPEEK, false, "no-peek", "disallow scoreboard tap changing player" }
|
||||
,{ CMD_ADDPIPE, true, "with-pipe", "named pipe to listen on for relay msgs" }
|
||||
,{ CMD_ADDNBS, true, "with-nbs",
|
||||
"nbs socket to listen/reply on for relay msgs" }
|
||||
#ifdef XWFEATURE_SEARCHLIMIT
|
||||
,{ CMD_HINTRECT, false, "hintrect", "enable draggable hint-limits rect" }
|
||||
#endif
|
||||
|
@ -659,14 +787,15 @@ blocking_read( int fd, unsigned char* buf, int len )
|
|||
{
|
||||
int nRead = 0;
|
||||
while ( nRead < len ) {
|
||||
ssize_t siz = read( fd, buf + nRead, len - nRead );
|
||||
if ( siz <= 0 ) {
|
||||
XP_LOGF( "read => %d, errno=%d (\"%s\")", nRead,
|
||||
errno, strerror(errno) );
|
||||
nRead = -1;
|
||||
break;
|
||||
}
|
||||
nRead += siz;
|
||||
XP_LOGF( "%s: blocking for %d bytes", __func__, len );
|
||||
ssize_t siz = read( fd, buf + nRead, len - nRead );
|
||||
if ( siz <= 0 ) {
|
||||
XP_LOGF( "read => %d, errno=%d (\"%s\")", nRead,
|
||||
errno, strerror(errno) );
|
||||
nRead = -1;
|
||||
break;
|
||||
}
|
||||
nRead += siz;
|
||||
}
|
||||
return nRead;
|
||||
}
|
||||
|
@ -1186,6 +1315,9 @@ main( int argc, char** argv )
|
|||
case CMD_ADDPIPE:
|
||||
mainParams.pipe = optarg;
|
||||
break;
|
||||
case CMD_ADDNBS:
|
||||
mainParams.nbs = optarg;
|
||||
break;
|
||||
#ifdef XWFEATURE_SLOW_ROBOT
|
||||
case CMD_SLOWROBOT:
|
||||
if ( !parsePair( optarg, &mainParams.robotThinkMin,
|
||||
|
@ -1397,7 +1529,7 @@ main( int argc, char** argv )
|
|||
|
||||
free( mainParams.util );
|
||||
|
||||
XP_LOGF( "exiting main" );
|
||||
XP_LOGF( "%s exiting main", argv[0] );
|
||||
return 0;
|
||||
} /* main */
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; compile-command: "make -k";-*- */
|
||||
/* -*- compile-command: "make MEMDEBUG=TRUE -j3"; -*- */
|
||||
/*
|
||||
* Copyright 1997-2008 by Eric House (xwords@eehouse.org). All rights reserved.
|
||||
* Copyright 1997-2011 by Eric House (xwords@eehouse.org). All rights
|
||||
* reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -74,6 +75,9 @@ XP_Bool linShiftFocus( CommonGlobals* cGlobals, XP_Key key,
|
|||
BoardObjectType* nxtP );
|
||||
#endif
|
||||
|
||||
void read_pipe_then_close( CommonGlobals* cGlobals );
|
||||
void read_pipe_then_close( CommonGlobals* cGlobals,
|
||||
const TransportProcs* procs );
|
||||
void do_nbs_then_close( CommonGlobals* cGlobals,
|
||||
const TransportProcs* procs );
|
||||
|
||||
#endif
|
||||
|
|
|
@ -50,6 +50,7 @@ typedef struct LaunchParams {
|
|||
PlayerDicts dicts;
|
||||
char* fileName;
|
||||
char* pipe;
|
||||
char* nbs;
|
||||
char* bonusFile;
|
||||
VTableMgr* vtMgr;
|
||||
XP_U16 nLocalPlayers;
|
||||
|
@ -161,6 +162,7 @@ struct CommonGlobals {
|
|||
* polling mechanism.*/
|
||||
AddAcceptorFunc addAcceptor;
|
||||
Acceptor acceptor;
|
||||
int nbsFD;
|
||||
|
||||
#ifdef XWFEATURE_RELAY
|
||||
int socket; /* relay */
|
||||
|
|
Loading…
Reference in a new issue