//------------------------------------------------------------------------------ void TestDistributed::TestLocalRace() { { const char * target( "../../../../ftmp/Test/Distributed/dist.lib" ); TestHelper( target, 1, false, true ); // allow race } { const char * target( "../../../../ftmp/Test/Distributed/dist.lib" ); TestHelper( target, 4, false, true ); // allow race } #if defined( __WINDOWS__ ) // TODO:MAC TODO:LINUX Fix and enable TestLocalRace+PCH { const char * target( "../../../../ftmp/Test/Distributed/distpch.lib" ); TestHelper( target, 4, false, true ); // allow race } #endif { const char * target( "badcode" ); TestHelper( target, 4, true, true ); // compilation should fail, allow race } }
bool Test() { bool fail = TestHelper(); int r = 0; CBufferedOutStream bout; asIScriptEngine *engine; const char *script; // A type registered with asOBJ_REF must not register destructor bout.buffer = ""; engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = engine->RegisterObjectType("ref", 4, asOBJ_REF); assert( r >= 0 ); r = engine->RegisterObjectBehaviour("ref", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(0), asCALL_GENERIC); if( r != asILLEGAL_BEHAVIOUR_FOR_TYPE ) fail = true; if( bout.buffer != " (0, 0) : Error : The behaviour is not compatible with the type\n" ) { printf(bout.buffer.c_str()); fail = true; } engine->Release(); // A type registered with asOBJ_GC must register all gc behaviours bout.buffer = ""; engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = engine->RegisterObjectType("gc", 4, asOBJ_REF | asOBJ_GC); assert( r >= 0 ); r = engine->ExecuteString(0, ""); if( r >= 0 ) fail = true; if( bout.buffer != " (0, 0) : Error : Type 'gc' is missing behaviours\n" " (0, 0) : Info : A garbage collected type must have the addref, release, and all gc behaviours\n" " (0, 0) : Error : Invalid configuration\n" ) { printf(bout.buffer.c_str()); fail = true; } engine->Release(); // A type registered with asOBJ_VALUE must not register addref, release, and gc behaviours bout.buffer = ""; engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = engine->RegisterObjectType("val", 4, asOBJ_VALUE | asOBJ_APP_PRIMITIVE); assert( r >= 0 ); r = engine->RegisterObjectBehaviour("val", asBEHAVE_ADDREF, "void f()", asFUNCTION(0), asCALL_GENERIC); if( r != asILLEGAL_BEHAVIOUR_FOR_TYPE ) fail = true; r = engine->RegisterObjectBehaviour("val", asBEHAVE_RELEASE, "void f()", asFUNCTION(0), asCALL_GENERIC); if( r != asILLEGAL_BEHAVIOUR_FOR_TYPE ) fail = true; r = engine->RegisterObjectBehaviour("val", asBEHAVE_GETREFCOUNT, "int f()", asFUNCTION(0), asCALL_GENERIC); if( r != asILLEGAL_BEHAVIOUR_FOR_TYPE ) fail = true; if( bout.buffer != " (0, 0) : Error : The behaviour is not compatible with the type\n" " (0, 0) : Error : The behaviour is not compatible with the type\n" " (0, 0) : Error : The behaviour is not compatible with the type\n" ) { printf(bout.buffer.c_str()); fail = true; } engine->Release(); // Object types registered as ref must not be allowed to be // passed by value to registered functions, nor returned by value bout.buffer = ""; engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = engine->RegisterObjectType("ref", 4, asOBJ_REF); assert( r >= 0 ); r = engine->RegisterGlobalFunction("void f(ref)", asFUNCTION(0), asCALL_GENERIC); if( r >= 0 ) fail = true; r = engine->RegisterGlobalFunction("ref f()", asFUNCTION(0), asCALL_GENERIC); if( r >= 0 ) fail = true; if( bout.buffer != "" ) { printf(bout.buffer.c_str()); fail = true; } engine->Release(); // Ref type without registered assignment behaviour won't allow the assignment bout.buffer = ""; engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = engine->RegisterObjectType("ref", 0, asOBJ_REF); assert( r >= 0 ); r = engine->RegisterObjectBehaviour("ref", asBEHAVE_FACTORY, "ref@ f()", asFUNCTION(0), asCALL_GENERIC); assert( r >= 0 ); r = engine->RegisterObjectBehaviour("ref", asBEHAVE_ADDREF, "void f()", asFUNCTION(0), asCALL_GENERIC); assert( r >= 0 ); r = engine->RegisterObjectBehaviour("ref", asBEHAVE_RELEASE, "void f()", asFUNCTION(0), asCALL_GENERIC); assert( r >= 0 ); r = engine->ExecuteString(0, "ref r1, r2; r1 = r2;"); if( r >= 0 ) fail = true; if( bout.buffer != "ExecuteString (1, 18) : Error : There is no copy operator for this type available.\n" "ExecuteString (1, 16) : Error : There is no copy operator for this type available.\n" ) { printf(bout.buffer.c_str()); fail = true; } engine->Release(); // Ref type must register addref and release bout.buffer = ""; engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = engine->RegisterObjectType("ref", 0, asOBJ_REF); assert( r >= 0 ); r = engine->ExecuteString(0, "ref r"); if( r >= 0 ) fail = true; if( bout.buffer != " (0, 0) : Error : Type 'ref' is missing behaviours\n" " (0, 0) : Info : A reference type must have the addref and release behaviours\n" " (0, 0) : Error : Invalid configuration\n" ) { printf(bout.buffer.c_str()); fail = true; } engine->Release(); // Ref type with asOBJ_NOHANDLE must not register addref, release, and factory bout.buffer = ""; engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = engine->RegisterObjectType("ref", 0, asOBJ_REF | asOBJ_NOHANDLE); assert( r >= 0 ); r = engine->RegisterObjectBehaviour("ref", asBEHAVE_ADDREF, "void f()", asFUNCTION(0), asCALL_GENERIC); if( r != asILLEGAL_BEHAVIOUR_FOR_TYPE ) fail = true; r = engine->RegisterObjectBehaviour("ref", asBEHAVE_RELEASE, "void f()", asFUNCTION(0), asCALL_GENERIC); if( r != asILLEGAL_BEHAVIOUR_FOR_TYPE ) fail = true; r = engine->RegisterObjectBehaviour("ref", asBEHAVE_FACTORY, "ref @f()", asFUNCTION(0), asCALL_GENERIC); if( bout.buffer != " (0, 0) : Error : The behaviour is not compatible with the type\n" " (0, 0) : Error : The behaviour is not compatible with the type\n" "System function (1, 5) : Error : Object handle is not supported for this type\n") { printf(bout.buffer.c_str()); fail = true; } engine->Release(); // Value type with asOBJ_POD without registered assignment behaviour should allow bitwise copy bout.buffer = ""; engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = engine->RegisterObjectType("val", 4, asOBJ_VALUE | asOBJ_POD | asOBJ_APP_PRIMITIVE); assert( r >= 0 ); r = engine->ExecuteString(0, "val v1, v2; v1 = v2;"); if( r != asEXECUTION_FINISHED ) fail = true; if( bout.buffer != "" ) { printf(bout.buffer.c_str()); fail = true; } engine->Release(); // Value type without asOBJ_POD and assignment behaviour must not allow bitwise copy bout.buffer = ""; engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = engine->RegisterObjectType("val", 4, asOBJ_VALUE | asOBJ_APP_PRIMITIVE); assert( r >= 0 ); r = engine->RegisterObjectBehaviour("val", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(DummyFunc), asCALL_GENERIC); r = engine->RegisterObjectBehaviour("val", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(DummyFunc), asCALL_GENERIC); r = engine->ExecuteString(0, "val v1, v2; v1 = v2;"); if( r >= 0 ) fail = true; if( bout.buffer != "ExecuteString (1, 18) : Error : There is no copy operator for this type available.\n" "ExecuteString (1, 16) : Error : There is no copy operator for this type available.\n" ) { printf(bout.buffer.c_str()); fail = true; } engine->Release(); // Value types without asOBJ_POD must have constructor and destructor registered bout.buffer = ""; engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = engine->RegisterObjectType("val", 4, asOBJ_VALUE | asOBJ_APP_PRIMITIVE); assert( r >= 0 ); r = engine->RegisterObjectType("val1", 4, asOBJ_VALUE | asOBJ_APP_PRIMITIVE); assert( r >= 0 ); r = engine->RegisterObjectBehaviour("val1", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(DummyFunc), asCALL_GENERIC); r = engine->RegisterObjectType("val2", 4, asOBJ_VALUE | asOBJ_APP_PRIMITIVE); assert( r >= 0 ); r = engine->RegisterObjectBehaviour("val2", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(DummyFunc), asCALL_GENERIC); r = engine->ExecuteString(0, "val v1, v2; v1 = v2;"); if( r >= 0 ) fail = true; if( bout.buffer != " (0, 0) : Error : Type 'val' is missing behaviours\n" " (0, 0) : Info : A non-pod value type must have the constructor and destructor behaviours\n" " (0, 0) : Error : Type 'val1' is missing behaviours\n" " (0, 0) : Info : A non-pod value type must have the constructor and destructor behaviours\n" " (0, 0) : Error : Type 'val2' is missing behaviours\n" " (0, 0) : Info : A non-pod value type must have the constructor and destructor behaviours\n" " (0, 0) : Error : Invalid configuration\n" ) { printf(bout.buffer.c_str()); fail = true; } engine->Release(); // Ref type must register ADDREF and RELEASE bout.buffer = ""; engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = engine->RegisterObjectType("ref", 0, asOBJ_REF); assert( r >= 0 ); r = engine->RegisterObjectType("ref1", 0, asOBJ_REF); assert( r >= 0 ); r = engine->RegisterObjectBehaviour("ref1", asBEHAVE_ADDREF, "void f()", asFUNCTION(DummyFunc), asCALL_GENERIC); r = engine->RegisterObjectType("ref2", 0, asOBJ_REF); assert( r >= 0 ); r = engine->RegisterObjectBehaviour("ref2", asBEHAVE_RELEASE, "void f()", asFUNCTION(DummyFunc), asCALL_GENERIC); r = engine->ExecuteString(0, "ref @r;"); if( r >= 0 ) fail = true; if( bout.buffer != " (0, 0) : Error : Type 'ref' is missing behaviours\n" " (0, 0) : Info : A reference type must have the addref and release behaviours\n" " (0, 0) : Error : Type 'ref1' is missing behaviours\n" " (0, 0) : Info : A reference type must have the addref and release behaviours\n" " (0, 0) : Error : Type 'ref2' is missing behaviours\n" " (0, 0) : Info : A reference type must have the addref and release behaviours\n" " (0, 0) : Error : Invalid configuration\n" ) { printf(bout.buffer.c_str()); fail = true; } engine->Release(); // Ref types without default factory must not be allowed to be initialized, nor must it be allowed to be passed by value in parameters or returned by value bout.buffer = ""; engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = engine->RegisterObjectType("ref", 0, asOBJ_REF); assert( r >= 0 ); r = engine->RegisterObjectBehaviour("ref", asBEHAVE_ADDREF, "void f()", asFUNCTION(DummyFunc), asCALL_GENERIC); r = engine->RegisterObjectBehaviour("ref", asBEHAVE_RELEASE, "void f()", asFUNCTION(DummyFunc), asCALL_GENERIC); script = "ref func(ref r) { ref r2; return ref(); }"; asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection("script", script, strlen(script)); r = mod->Build(); if( r >= 0 ) fail = true; if( bout.buffer != "script (1, 1) : Info : Compiling ref func(ref)\n" "script (1, 1) : Error : Data type can't be 'ref'\n" "script (1, 10) : Error : Parameter type can't be 'ref'\n" "script (1, 23) : Error : Data type can't be 'ref'\n" "script (1, 34) : Error : No matching signatures to 'ref()'\n" "script (1, 34) : Error : Can't implicitly convert from 'const int' to 'ref'.\n" "script (1, 34) : Error : No default constructor for object of type 'ref'.\n" "script (1, 34) : Error : There is no copy operator for this type available.\n" ) { printf(bout.buffer.c_str()); fail = true; } engine->Release(); // Ref types without default constructor must not be allowed to be passed by in/out reference, but must be allowed to be passed by inout reference bout.buffer = ""; engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = engine->RegisterObjectType("ref", 0, asOBJ_REF); assert( r >= 0 ); r = engine->RegisterObjectBehaviour("ref", asBEHAVE_ADDREF, "void f()", asFUNCTION(DummyFunc), asCALL_GENERIC); r = engine->RegisterObjectBehaviour("ref", asBEHAVE_RELEASE, "void f()", asFUNCTION(DummyFunc), asCALL_GENERIC); script = "void func(ref &in r1, ref &out r2, ref &inout r3) { }"; mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection("script", script, strlen(script)); r = mod->Build(); if( r >= 0 ) fail = true; if( bout.buffer != "script (1, 1) : Info : Compiling void func(ref&in, ref&out, ref&inout)\n" "script (1, 11) : Error : Parameter type can't be 'ref&'\n" "script (1, 23) : Error : Parameter type can't be 'ref&'\n" ) { printf(bout.buffer.c_str()); fail = true; } engine->Release(); // It must not be possible to register functions that take handles of types with asOBJ_HANDLE bout.buffer = ""; engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(CBufferedOutStream, Callback), &bout, asCALL_THISCALL); r = engine->RegisterObjectType("ref", 0, asOBJ_REF | asOBJ_NOHANDLE); assert( r >= 0 ); r = engine->ExecuteString(0, "ref @r"); if( r >= 0 ) fail = true; r = engine->RegisterGlobalFunction("ref@ func()", asFUNCTION(0), asCALL_GENERIC); if( r >= 0 ) fail = true; if( bout.buffer != "ExecuteString (1, 5) : Error : Object handle is not supported for this type\n" "ExecuteString (1, 6) : Error : Data type can't be 'ref'\n" "System function (1, 4) : Error : Object handle is not supported for this type\n" ) { printf(bout.buffer.c_str()); fail = true; } // Must be possible to register float types r = engine->RegisterObjectType("real", sizeof(float), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_FLOAT); assert( r >= 0 ); // It should be allowed to register the type without specifying the application type, // if the engine won't use it (i.e. no native functions take or return the type by value) if( !strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") ) { asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(CBufferedOutStream, Callback), &bout, asCALL_THISCALL); bout.buffer = ""; r = engine->RegisterObjectType("test1", 4, asOBJ_VALUE | asOBJ_POD); if( r < 0 ) fail = true; r = engine->RegisterGlobalFunction("test1 f()", asFUNCTION(0), asCALL_CDECL); if( r < 0 ) fail = true; r = engine->RegisterGlobalFunction("void f(test1)", asFUNCTION(0), asCALL_CDECL); if( r < 0 ) fail = true; r = engine->ExecuteString(0, "test1 t"); if( r >= 0 ) fail = true; // TODO: These errors should really be returned immediately when registering the function if( bout.buffer != " (0, 0) : Info : test1 f()\n" " (0, 0) : Error : Can't return type 'test1' by value unless the application type is informed in the registration\n" " (0, 0) : Info : void f(test1)\n" " (0, 0) : Error : Can't pass type 'test1' by value unless the application type is informed in the registration\n" " (0, 0) : Error : Invalid configuration\n" ) { printf(bout.buffer.c_str()); fail = true; } engine->Release(); } // It must not be possible to register a value type without defining the application type r = engine->RegisterObjectType("test2", 4, asOBJ_VALUE | asOBJ_APP_CLASS_CONSTRUCTOR); if( r >= 0 ) fail = true; engine->Release(); // REF+SCOPED if( !fail ) fail = TestRefScoped(); // TODO: // What about asOBJ_NOHANDLE and asEP_ALLOW_UNSAFE_REFERENCES? Should it allow &inout? // TODO: // Validate if the same behaviour is registered twice, e.g. if index // behaviour is registered twice with signature 'int f(int)' and error should be given // Success return fail; }
// TestForceInclude //------------------------------------------------------------------------------ void TestDistributed::TestForceInclude() const { const char * target( "../../../../ftmp/Test/Distributed/ForceInclude/ForceInclude.lib" ); TestHelper( target, 4 ); }
// RegressionTest_RemoteCrashOnErrorFormatting //------------------------------------------------------------------------------ void TestDistributed::RegressionTest_RemoteCrashOnErrorFormatting() { const char * target( "badcode" ); TestHelper( target, 4, true ); // compilation should fail }
// WithPCH //------------------------------------------------------------------------------ void TestDistributed::WithPCH() const { const char * target( "../../../../ftmp/Test/Distributed/distpch.lib" ); TestHelper( target, 4 ); }
// TestWith4RemoteWorkerThreads //------------------------------------------------------------------------------ void TestDistributed::TestWith4RemoteWorkerThreads() const { const char * target( "../../../../ftmp/Test/Distributed/dist.lib" ); TestHelper( target, 4 ); }