Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testclient #390

Merged
merged 14 commits into from Mar 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/build.yml
Expand Up @@ -40,7 +40,9 @@ jobs:

steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v1
- uses: actions/setup-python@v2
with:
python-version: '3.x'
- uses: seanmiddleditch/gha-setup-vsdevenv@v3
- name: Cache curl
uses: actions/cache@v2
Expand Down
21 changes: 16 additions & 5 deletions cmake/core_tests.cmake
Expand Up @@ -135,13 +135,24 @@ set_tests_properties( shard_ecompile PROPERTIES FIXTURES_REQUIRED shard)
set_tests_properties( shard_ecompile PROPERTIES FIXTURES_SETUP ecompile)

# first test run
add_test(NAME shard_test_1
COMMAND pol
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/coretest
)
find_package(Python3 COMPONENTS Interpreter)
if (${Python3_FOUND})
add_test(NAME shard_test_1
COMMAND ${CMAKE_COMMAND}
-Dpol=$<TARGET_FILE:pol>
-Dtestdir=${CMAKE_CURRENT_SOURCE_DIR}/testsuite
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/core_tests_start.cmake
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/coretest
)
else()
add_test(NAME shard_test_1
COMMAND pol
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/coretest
)
endif()
set_tests_properties( shard_test_1 PROPERTIES FIXTURES_REQUIRED "client;shard;uoconvert;ecompile")
# needed for test_env
set_tests_properties( shard_test_1 PROPERTIES ENVIRONMENT "POLCORE_TEST=1;POLCORE_TEST_RUN=1;POLCORE_TEST_NOACCESS=foo")
set_tests_properties( shard_test_1 PROPERTIES ENVIRONMENT "POLCORE_TEST=1;POLCORE_TEST_RUN=1;POLCORE_TEST_NOACCESS=foo;POLCORE_TESTCLIENT=${Python3_FOUND}")
set_tests_properties(shard_test_1 PROPERTIES FIXTURES_SETUP shard_test)

# second test run
Expand Down
12 changes: 12 additions & 0 deletions cmake/core_tests_start.cmake
@@ -0,0 +1,12 @@
find_package(Python3 COMPONENTS Interpreter REQUIRED QUIET)
execute_process(
COMMAND ${Python3_EXECUTABLE} ${testdir}/testclient/pyuo/testclient.py
COMMAND ${pol}
COMMAND_ECHO STDOUT
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
RESULT_VARIABLE res
TIMEOUT 120
)
if(NOT "${res}" STREQUAL "0")
message(SEND_ERROR "${res}")
endif()
9 changes: 8 additions & 1 deletion docs/docs.polserver.com/pol100/corechanges.xml
Expand Up @@ -2,9 +2,16 @@
<ESCRIPT>
<header>
<topic>Latest Core Changes</topic>
<datemodified>03-14-2021</datemodified>
<datemodified>03-24-2021</datemodified>
</header>
<version name="POL100.1.0">
<entry>
<date>03-24-2021</date>
<author>Turley:</author>
<change type="Added">os:OpenConnection argument keep_connection<br/>
defaults to 0, if set to 1 the connection is kept active on read timeout.<br/>
By default (old behaviour) the connection is closed when for 5 seconds no pkt was received (old behaviour).</change>
</entry>
<entry>
<date>03-14-2021</date>
<author>Kevin:</author>
Expand Down
5 changes: 3 additions & 2 deletions docs/docs.polserver.com/pol100/osem.xml
Expand Up @@ -4,7 +4,7 @@
<ESCRIPT>
<fileheader fname="OS.em">
<filedesc>POL System Environment Functions</filedesc>
<datemodified>12/26/2020</datemodified>
<datemodified>03/23/2021</datemodified>
<constant>// set_script_option constants</constant>
<constant>const SCRIPTOPT_NO_INTERRUPT := 1; // if 1, script runs until it sleeps</constant>
<constant>const SCRIPTOPT_DEBUG := 2; // if 1, prints any debug info included</constant>
Expand Down Expand Up @@ -222,12 +222,13 @@ const SCRIPTOPT_CAN_ACCESS_OFFLINE_MOBILES := 4;</code></explain>
</function>

<function name="OpenConnection">
<prototype>OpenConnection( host, port, scriptdef, params )</prototype>
<prototype>OpenConnection( host, port, scriptdef, params:=0, assume_string:=0, keep_connection:=0 )</prototype>
<parameter name="host" value="Target host"/>
<parameter name="port" value="Target port"/>
<parameter name="scriptdef" value="Name of the script to be started when the connection is established"/>
<parameter name="params" value="A struct of parameters to be sent to the script"/>
<parameter name="assume_string" value="Integer if set to 1 all communication from connection will be sent/received as raw strings."/>
<parameter name="keep_connection" value="Integer if set to 1 the connection will not timeout and will be kept alive until the auxiliary script exists."/>
<explain>Creates an outgoing TCP/IP connection to the host/port, once connection is open the scriptdef is run and</explain>
<explain> any params defined in the struct will be passed to that script. The script type should be in the form of an Auxilry Script.</explain>
<return>1 on success</return>
Expand Down
4 changes: 4 additions & 0 deletions pol-core/doc/core-changes.txt
@@ -1,4 +1,8 @@
-- POL100.1.0 --
03-24-2021 Turley:
Added: os:OpenConnection argument keep_connection
defaults to 0, if set to 1 the connection is kept active on read timeout.
By default (old behaviour) the connection is closed when for 5 seconds no pkt was received (old behaviour).
03-14-2021 Kevin:
Added: Conditional operator: condition ? exprIfTrue : exprIfFalse
This new syntax allows you to efficiently return the result of one of the two expressions, depending on whether the conditon
Expand Down
19 changes: 11 additions & 8 deletions pol-core/pol/module/osmod.cpp
Expand Up @@ -565,8 +565,10 @@ BObjectImp* OSExecutorModule::mf_OpenConnection()
BObjectImp* scriptparam;
unsigned short port;
int assume_string_int;
int keep_connection_int;
if ( getStringParam( 0, host ) && getParam( 1, port ) && getStringParam( 2, scriptname_str ) &&
getParamImp( 3, scriptparam ) && getParam( 4, assume_string_int ) )
getParamImp( 3, scriptparam ) && getParam( 4, assume_string_int ) &&
getParam( 5, keep_connection_int ) )
{
// FIXME needs to inherit available modules?
Core::ScriptDef sd;
Expand All @@ -589,8 +591,10 @@ BObjectImp* OSExecutorModule::mf_OpenConnection()
weak_ptr<Core::UOExecutor> uoexec_w = this_uoexec.weakptr;
std::string hostname( host->value() );
bool assume_string = assume_string_int != 0;
bool keep_connection = keep_connection_int != 0;
BObject paramobj( scriptparam ); // prevent delete
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice find

Core::networkManager.auxthreadpool->push(
[uoexec_w, sd, hostname, port, scriptparam, assume_string]() {
[uoexec_w, sd, hostname, port, paramobj, assume_string, keep_connection]() {
Clib::Socket s;
bool success_open = s.open( hostname.c_str(), port );
{
Expand All @@ -605,15 +609,14 @@ BObjectImp* OSExecutorModule::mf_OpenConnection()
{
uoexec_w.get_weakptr()->ValueStack.back().set(
new BObject( new BError( "Error connecting to client" ) ) );
uoexec_w.get_weakptr()->revive();
return;
}
else
{
uoexec_w.get_weakptr()->ValueStack.back().set( new BObject( new BLong( 1 ) ) );
}
uoexec_w.get_weakptr()->ValueStack.back().set( new BObject( new BLong( 1 ) ) );
uoexec_w.get_weakptr()->revive();
}
std::unique_ptr<Network::AuxClientThread> client( new Network::AuxClientThread(
sd, std::move( s ), scriptparam->copy(), assume_string ) );
sd, std::move( s ), paramobj->copy(), assume_string, keep_connection ) );
client->run();
} );

Expand Down Expand Up @@ -1214,7 +1217,7 @@ BObjectImp* OSExecutorModule::mf_GetEnvironmentVariable()
if ( pos == std::string_view::npos )
continue;
auto key = env.substr( 0, pos );
auto key_lowered = Clib::strlowerASCII( std::string{ key } );
auto key_lowered = Clib::strlowerASCII( std::string{key} );
auto val = env.substr( pos + 1 );

if ( all_allowed || std::find( allowed_vars.begin(), allowed_vars.end(), key_lowered ) !=
Expand Down
12 changes: 7 additions & 5 deletions pol-core/pol/network/auxclient.cpp
Expand Up @@ -102,19 +102,21 @@ AuxClientThread::AuxClientThread( AuxService* auxsvc, Clib::Socket&& sock )
_scriptdef(),
_params( nullptr ),
_assume_string( false ),
_transmit_counter( 0 )
_transmit_counter( 0 ),
_keep_alive( false )
{
}
AuxClientThread::AuxClientThread( Core::ScriptDef scriptdef, Clib::Socket&& sock,
Bscript::BObjectImp* params, bool assume_string )
Bscript::BObjectImp* params, bool assume_string, bool keep_alive )
: SocketClientThread( std::move( sock ) ),
_auxservice( nullptr ),
_auxconnection(),
_uoexec( nullptr ),
_scriptdef( scriptdef ),
_params( params ),
_assume_string( assume_string ),
_transmit_counter( 0 )
_transmit_counter( 0 ),
_keep_alive( keep_alive )
{
}

Expand Down Expand Up @@ -183,11 +185,11 @@ void AuxClientThread::run()

std::string tmp;
bool result, timeout_exit;
Clib::SocketLineReader linereader( _sck, 5 );
Clib::SocketLineReader linereader( _sck, 5, 0, !_keep_alive );
for ( ;; )
{
result = linereader.readline( tmp, &timeout_exit );
if ( !result && !timeout_exit )
if ( !result && !timeout_exit && !_keep_alive )
break;

Core::PolLock lock;
Expand Down
9 changes: 5 additions & 4 deletions pol-core/pol/network/auxclient.h
Expand Up @@ -17,12 +17,12 @@
#include <string>
#include <vector>

#include "../../clib/refptr.h"
#include "../../clib/network/socketsvc.h"
#include "../../clib/refptr.h"
#include "../../clib/weakptr.h"
#include "../polobject.h"
#include "../scrdef.h"
#include "../uoexec.h"
#include "../polobject.h"

namespace Pol
{
Expand Down Expand Up @@ -72,7 +72,7 @@ class AuxConnection final : public Core::PolObjectImp
virtual size_t sizeEstimate() const override;

virtual Bscript::BObjectImp* call_polmethod( const char* methodname,
Core::UOExecutor& ex ) override;
Core::UOExecutor& ex ) override;
virtual Bscript::BObjectRef get_member( const char* membername ) override;

void disconnect();
Expand Down Expand Up @@ -104,7 +104,7 @@ class AuxClientThread final : public Clib::SocketClientThread
public:
AuxClientThread( AuxService* auxsvc, Clib::Socket&& sock );
AuxClientThread( Core::ScriptDef scriptdef, Clib::Socket&& sock, Bscript::BObjectImp* params,
bool assume_string );
bool assume_string, bool keep_alive );
virtual void run() override;
void transmit( const Bscript::BObjectImp* imp );
Bscript::BObjectImp* get_ip();
Expand All @@ -120,6 +120,7 @@ class AuxClientThread final : public Clib::SocketClientThread
Bscript::BObjectImp* _params;
bool _assume_string;
std::atomic<int> _transmit_counter;
bool _keep_alive;
};
} // namespace Network
} // namespace Pol
Expand Down
2 changes: 1 addition & 1 deletion pol-core/support/scripts/os.em
Expand Up @@ -99,7 +99,7 @@ Set_Event_Queue_Size(size);
Is_Critical();

OpenURL( character, url );
OpenConnection( host, port, scriptdef, params := 0, assume_string := 0);
OpenConnection( host, port, scriptdef, params := 0, assume_string := 0, keep_connection := 0);
Debugger(); // put script in debug state

PerformanceMeasure(delta_seconds := 10, max_scripts := 100);
Expand Down
2 changes: 1 addition & 1 deletion testsuite/pol/pol.cfg
Expand Up @@ -508,4 +508,4 @@ MaxObjtype=0xFFFFFFFF
#SelectTimeout=10

# With spaces, to test proper splitting
AllowedEnvironmentVariablesAccess=POLCORE_TEST_RUN ,POLCORE_TEST_FILTER , POLCORE_TEST, POLCORE_TEST_NOTFOUND
AllowedEnvironmentVariablesAccess=POLCORE_TEST_RUN ,POLCORE_TEST_FILTER , POLCORE_TEST, POLCORE_TEST_NOTFOUND, POLCORE_TESTCLIENT
19 changes: 19 additions & 0 deletions testsuite/pol/testpkgs/client/cleanup.src
@@ -0,0 +1,19 @@
use uo;
use os;

var res:=GetGlobalProperty("#clientcon");
if (res)
var clientcon:=GetProcess(res);
clientcon.sendevent(struct{todo:="exit"});
sleep(1);
endif
var a:=FindAccount("testclient0");
if (a)
a.deletecharacter(1);
a.delete();
endif
a:=FindAccount("testclient1");
if (a)
a.deletecharacter(1);
a.delete();
endif
24 changes: 24 additions & 0 deletions testsuite/pol/testpkgs/client/clientconnection.src
@@ -0,0 +1,24 @@
use os;
use uo;

program clientconn(con, test)
SetGlobalProperty("#clientcon", getpid());
while (1)
var ev:=Wait_For_Event(10);
if (!ev)
continue;
endif
if (ev.todo)
var json:=PackJson(ev);
syslog(" to client: "+json,0);
con.transmit(json);
if (ev.todo=="exit")
break;
endif
else
syslog(" from client: "+ev,0);
var e:=UnpackJson(ev.value);
test.sendevent(e);
endif
endwhile
endprogram
36 changes: 36 additions & 0 deletions testsuite/pol/testpkgs/client/communication.inc
@@ -0,0 +1,36 @@
//see pyuo/brain.py method typestr()
const EVT_INIT := "init";
const EVT_HP_CHANGED := "hp_changed";
const EVT_MANA_CHANGED := "mana_changed";
const EVT_STAM_CHANGED := "stam_changed";
const EVT_SPEECH := "speech";
const EVT_NOTORIETY := "notoriety";
const EVT_MOVED := "moved";
const EVT_NEW_MOBILE := "new_mobile";
const EVT_NEW_ITEM := "new_item";

function waitForClient(id, types)
while (1)
var ev:=Wait_For_Event(5);
if (!ev)
return ret_error("no signal received");
endif
if (ev.id != id || !(ev.type in types))
continue;
endif
return ev;
endwhile
endfunction

function waitForClients(types)
while (1)
var ev:=Wait_For_Event(5);
if (!ev)
return ret_error("no signal received");
endif
if (!(ev.type in types))
continue;
endif
return ev;
endwhile
endfunction
2 changes: 2 additions & 0 deletions testsuite/pol/testpkgs/client/pkg.cfg
@@ -0,0 +1,2 @@
name TestClient
enabled 1
15 changes: 15 additions & 0 deletions testsuite/pol/testpkgs/client/setup.src
@@ -0,0 +1,15 @@
use os;
use uo;

var a:=FindAccount("testclient0");
if (!a)
a:=CreateAccount("testclient0","pass",1);
endif
a.addcharacter(0);

var a2:=FindAccount("testclient1");
if (!a2)
a2:=CreateAccount("testclient1","pass",1);
endif
a2.addcharacter(0);
return 1;