Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Functions | Variables
TestXPC.cpp File Reference
#include <stdio.h>
#include "nsIXPConnect.h"
#include "nsIScriptError.h"
#include "nsIServiceManager.h"
#include "nsIComponentManager.h"
#include "nsIComponentRegistrar.h"
#include "nsIJSContextStack.h"
#include "nsIJSRuntimeService.h"
#include "nsMemory.h"
#include "nsIXPCSecurityManager.h"
#include "nsICategoryManager.h"
#include "nsString.h"
#include "nsIVariant.h"
#include "jsapi.h"
#include "xpctest.h"

Go to the source code of this file.

Classes

class  nsTestXPCFoo
class  MySecMan

Defines

#define DIE(_msg)

Functions

 Print (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 Load (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 my_ErrorReporter (JSContext *cx, const char *message, JSErrorReport *report)
static void TestSecurityManager (JSContext *jscontext, JSObject *glob, nsIXPConnect *xpc)
static void TestArgFormatter (JSContext *jscontext, JSObject *glob, nsIXPConnect *xpc)
static void TestThreadJSContextStack (JSContext *jscontext)
static void ShowXPCException ()
static void TestCategoryManmager ()
int main ()

Variables

FILEgOutFile = NULL
FILEgErrFile = NULL
static JSFunctionSpec glob_functions []
static JSClass global_class

Define Documentation

#define DIE (   _msg)
Value:
PR_BEGIN_MACRO  \
        printf(_msg); \
        printf("\n"); \
        return 1; \
    PR_END_MACRO

Definition at line 692 of file TestXPC.cpp.


Function Documentation

Load ( JSContext cx,
JSObject obj,
uintN  argc,
jsval argv,
jsval rval 
)

Definition at line 87 of file TestXPC.cpp.

{
    uintN i;
    JSString *str;
    const char *filename;
    JSScript *script;
    JSBool ok;
    jsval result;

    for (i = 0; i < argc; i++) {
        str = JS_ValueToString(cx, argv[i]);
        if (!str)
            return JS_FALSE;
        argv[i] = STRING_TO_JSVAL(str);
        filename = JS_GetStringBytes(str);
        script = JS_CompileFile(cx, obj, filename);
        if (!script)
            ok = JS_FALSE;
        else {
            ok = JS_ExecuteScript(cx, obj, script, &result);
            JS_DestroyScript(cx, script);
        }
        if (!ok)
            return JS_FALSE;
    }
    return JS_TRUE;
}

Here is the call graph for this function:

int main ( void  )

Definition at line 699 of file TestXPC.cpp.

{
    JSRuntime *rt;
    JSContext *jscontext;
    JSObject *glob;
    nsresult rv;

    gErrFile = stderr;
    gOutFile = stdout;
    {
        nsCOMPtr<nsIServiceManager> servMan;
        NS_InitXPCOM2(getter_AddRefs(servMan), nsnull, nsnull);
        nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan);
        NS_ASSERTION(registrar, "Null nsIComponentRegistrar");
        if(registrar)
            registrar->AutoRegister(nsnull);
    
        // get the JSRuntime from the runtime svc, if possible
        nsCOMPtr<nsIJSRuntimeService> rtsvc =
                 do_GetService("@mozilla.org/js/xpc/RuntimeService;1", &rv);
        if(NS_FAILED(rv) || NS_FAILED(rtsvc->GetRuntime(&rt)) || !rt)
            DIE("FAILED to get a JSRuntime");

        jscontext = JS_NewContext(rt, 8192);
        if(!jscontext)
            DIE("FAILED to create a JSContext");

        JS_SetErrorReporter(jscontext, my_ErrorReporter);

        nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv));
        if(!xpc)
            DIE("FAILED to get xpconnect service\n");

        nsCOMPtr<nsIJSContextStack> cxstack =
                 do_GetService("@mozilla.org/js/xpc/ContextStack;1", &rv);
        if(NS_FAILED(rv))
            DIE("FAILED to get the nsThreadJSContextStack service!\n");

        if(NS_FAILED(cxstack->Push(jscontext)))
            DIE("FAILED to push the current jscontext on the nsThreadJSContextStack service!\n");

        // XXX I'd like to replace this with code that uses a wrapped xpcom object
        // as the global object. The old TextXPC did this. The support for this
        // is not working now in the new xpconnect code.

        glob = JS_NewObject(jscontext, &global_class, NULL, NULL);
        if (!glob)
            DIE("FAILED to create global object");
        if (!JS_InitStandardClasses(jscontext, glob))
            DIE("FAILED to init standard classes");
        if (!JS_DefineFunctions(jscontext, glob, glob_functions))
            DIE("FAILED to define global functions");
        if (NS_FAILED(xpc->InitClasses(jscontext, glob)))
            DIE("FAILED to init xpconnect classes");

        /**********************************************/
        // run the tests...

        TestCategoryManmager();
        TestSecurityManager(jscontext, glob, xpc);
        TestArgFormatter(jscontext, glob, xpc);
        TestThreadJSContextStack(jscontext);

        /**********************************************/

        if(NS_FAILED(cxstack->Pop(nsnull)))
            DIE("FAILED to pop the current jscontext from the nsThreadJSContextStack service!\n");

        JS_ClearScope(jscontext, glob);
        JS_GC(jscontext);
        JS_GC(jscontext);
        JS_DestroyContext(jscontext);
        xpc->SyncJSContexts();
        xpc->DebugDump(4);

        cxstack = nsnull;   // release service held by nsCOMPtr
        xpc     = nsnull;   // release service held by nsCOMPtr
        rtsvc   = nsnull;   // release service held by nsCOMPtr
    }
    rv = NS_ShutdownXPCOM( NULL );
    NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM FAILED");

    return 0;
}

Here is the call graph for this function:

my_ErrorReporter ( JSContext cx,
const char *  message,
JSErrorReport report 
)

Definition at line 128 of file TestXPC.cpp.

Print ( JSContext cx,
JSObject obj,
uintN  argc,
jsval argv,
jsval rval 
)

Definition at line 69 of file TestXPC.cpp.

{
    uintN i, n;
    JSString *str;

    for (i = n = 0; i < argc; i++) {
        str = JS_ValueToString(cx, argv[i]);
        if (!str)
            return JS_FALSE;
        fprintf(gOutFile, "%s%s", i ? " " : "", JS_GetStringBytes(str));
    }
    n++;
    if (n)
        fputc('\n', gOutFile);
    return JS_TRUE;
}

Here is the call graph for this function:

static void ShowXPCException ( ) [static]

Definition at line 596 of file TestXPC.cpp.

{
    nsresult rv;
    nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv));
    if(NS_SUCCEEDED(rv) && xpc)
    {
        nsCOMPtr<nsIException> e;
        xpc->GetPendingException(getter_AddRefs(e));
        if(e)
        {
            char* str;
            rv = e->ToString(&str);
            if(NS_SUCCEEDED(rv) && str)
            {
                printf(str);
                printf("\n");
                nsMemory::Free(str);

                nsresult res;
                e->GetResult(&res);
                if(res == NS_ERROR_XPC_JAVASCRIPT_ERROR_WITH_DETAILS)
                {
                    nsCOMPtr<nsISupports> data;
                    e->GetData(getter_AddRefs(data));
                    if(data)
                    {
                        nsCOMPtr<nsIScriptError> report = do_QueryInterface(data);
                        if(report)
                        {
                            nsCAutoString str2;
                            rv = report->ToString(str2);
                            if(NS_SUCCEEDED(rv))
                            {
                                printf("%s\n", str2.get());
                            }                            
                        }                            
                    }                            
                    else        
                        printf("can't get data for pending XPC exception\n");    
                }
            }
            else        
                printf("can't get string for pending XPC exception\n");    
        }
        else        
            printf("no pending XPC exception\n");    
    }
    else
        printf("can't get xpconnect\n");    
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void TestArgFormatter ( JSContext jscontext,
JSObject glob,
nsIXPConnect xpc 
) [static]

Definition at line 434 of file TestXPC.cpp.

{
    jsval* argv;
    void* mark;

    const char*                  a_in = "some string";
    nsCOMPtr<nsITestXPCFoo>      b_in = new nsTestXPCFoo();
    nsCOMPtr<nsIWritableVariant> c_in = do_CreateInstance("@mozilla.org/variant;1"); 
    static NS_NAMED_LITERAL_STRING(d_in, "foo bar");
    const char*                  e_in = "another meaningless chunck of text";
    

    char*                   a_out;
    nsCOMPtr<nsISupports>   b_out;
    nsCOMPtr<nsIVariant>    c_out;
    nsAutoString            d_out;
    char*                   e_out;

    nsCOMPtr<nsITestXPCFoo> specified;
    PRInt32                 val;

    printf("ArgumentFormatter test: ");

    if(!b_in || !c_in || NS_FAILED(c_in->SetAsInt32(5)))
    {
        printf(" failed to construct test objects -- FAILED!\n");
        return;
    }

    argv = JS_PushArguments(jscontext, &mark, "s %ip %iv %is s",
                            a_in, 
                            &NS_GET_IID(nsITestXPCFoo2), b_in.get(), 
                            c_in.get(),
                            NS_STATIC_CAST(const nsAString*, &d_in), 
                            e_in);

    if(!argv)
    {
        printf(" could not convert from native to JS -- FAILED!\n");
        return;
    }

    if(!JS_ConvertArguments(jscontext, 5, argv, "s %ip %iv %is s",
                            &a_out, 
                            NS_STATIC_CAST(nsISupports**, getter_AddRefs(b_out)), 
                            NS_STATIC_CAST(nsIVariant**, getter_AddRefs(c_out)),
                            NS_STATIC_CAST(nsAString*, &d_out), 
                            &e_out))
    {
        printf(" could not convert from JS to native -- FAILED!\n");
        goto out;
    }

    if(!b_out)
    {
        printf(" JS to native for %%ip returned NULL -- FAILED!\n");
        goto out;
    }

    specified = do_QueryInterface(b_out);
    if(!specified)
    {
        printf(" could not QI value JS to native returned -- FAILED!\n");
        goto out;
    }

    if(specified.get() != b_in.get())
    {
        printf(" JS to native returned wrong value -- FAILED!\n");
        goto out;
    }

    if(!c_out)
    {
        printf(" JS to native for %%iv returned NULL -- FAILED!\n");
        goto out;
    }

    if(NS_FAILED(c_out->GetAsInt32(&val)) || val != 5)
    {
        printf(" JS to native for %%iv holds wrong value -- FAILED!\n");
        goto out;
    }

    if(d_in != d_out)
    {
        printf(" JS to native for %%is returned the wrong value -- FAILED!\n");
        goto out;
    }

    if(!strcmp(a_in, a_out) && !strcmp(e_in, e_out))
        printf("passed\n");
    else
        printf(" conversion OK, but surrounding was mangled -- FAILED!\n");

out:
    JS_PopArguments(jscontext, mark);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void TestCategoryManmager ( ) [static]

Definition at line 647 of file TestXPC.cpp.

{
    printf("\n");    

    nsresult rv;
    nsCOMPtr<nsICategoryManager> catman = 
             do_GetService("@mozilla.org/categorymanager;1", &rv);
    if(NS_SUCCEEDED(rv) && catman)
    {
        printf("got category manager\n");    
 
        nsCOMPtr<nsISimpleEnumerator> e;
        rv = catman->EnumerateCategory("foo", getter_AddRefs(e));
        if(NS_SUCCEEDED(rv) && e)
        {
            printf("got enumerator\n");

            nsCOMPtr<nsISupports> el;
            rv = e->GetNext(getter_AddRefs(el));
            if(NS_SUCCEEDED(rv) && el)
            {
                printf("e.GetNext() succeeded\n");
            }
            else
            {
                printf("e.GetNext() FAILED with result %0x\n", (int)rv);        
                ShowXPCException();
            }
                        
        }
        else
            printf("get of enumerator FAILED with result %0x\n", (int)rv);        
    }
    else
        printf("!!! can't get category manager\n");    


    printf("\n");    
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void TestSecurityManager ( JSContext jscontext,
JSObject glob,
nsIXPConnect xpc 
) [static]

Definition at line 302 of file TestXPC.cpp.

{
    const char* t;
    jsval rval;
    JSBool success = JS_TRUE;
    MySecMan* sm = new MySecMan();
    nsTestXPCFoo* foo = new nsTestXPCFoo();

    if(!sm || ! foo)
    {
        success = JS_FALSE;
        printf("FAILED to create object!\n");
        goto sm_test_done;
    }

    rval = JSVAL_FALSE;
    JS_SetProperty(jscontext, glob, "failed", &rval);
    printf("Individual SecurityManager tests...\n");
    if(NS_FAILED(xpc->SetSecurityManagerForJSContext(jscontext, sm,
                                        nsIXPCSecurityManager::HOOK_ALL)))
    {
        success = JS_FALSE;
        printf("SetSecurityManagerForJSContext FAILED!\n");
        goto sm_test_done;
    }

    printf("  build wrapper with veto: TEST NOT RUN\n");
/*
    // This test is broken because xpconnect now detects that this is a
    // call from native code and lets it succeed without calling the security manager

    sm->SetMode(MySecMan::VETO_ALL);
    printf("  build wrapper with veto: ");
    if(NS_SUCCEEDED(xpc->WrapNative(jscontext, glob, foo, NS_GET_IID(nsITestXPCFoo2), &wrapper)))
    {
        success = JS_FALSE;
        printf("FAILED\n");
        NS_RELEASE(wrapper);
    }
    else
    {
        printf("passed\n");
    }
*/
    sm->SetMode(MySecMan::OK_ALL);
    printf("  build wrapper no veto: ");
    nsIXPConnectJSObjectHolder* holder;
    if(NS_SUCCEEDED(xpc->WrapNative(jscontext, glob, foo, 
                    NS_GET_IID(nsITestXPCFoo2), &holder)))
    {
        printf("passed\n");
        JSObject* obj;
        if(NS_SUCCEEDED(holder->GetJSObject(&obj)))
        {
            rval = OBJECT_TO_JSVAL(obj);
            JS_SetProperty(jscontext, glob, "foo", &rval);
        }
            
        NS_RELEASE(holder);
    }
    else
    {
        success = JS_FALSE;
        printf("FAILED\n");
    }

    sm->SetMode(MySecMan::OK_ALL);
    printf("  getService no veto: ");
    t = "try{Components.classes['@mozilla.org/js/xpc/XPConnect;1'].getService(); print('passed');}catch(e){failed = true; print('FAILED');}";
    JS_EvaluateScript(jscontext, glob, t, strlen(t), "builtin", 1, &rval);

    sm->SetMode(MySecMan::VETO_ALL);
    printf("  getService with veto: ");
    t = "try{Components.classes['@mozilla.org/js/xpc/XPConnect;1'].getService(); failed = true; print('FAILED');}catch(e){print('passed');}";
    JS_EvaluateScript(jscontext, glob, t, strlen(t), "builtin", 1, &rval);


    sm->SetMode(MySecMan::OK_ALL);
    printf("  createInstance no veto: ");
    t = "try{Components.classes['@mozilla.org/js/xpc/ID;1'].createInstance(Components.interfaces.nsIJSID); print('passed');}catch(e){failed = true; print('FAILED');}";
    JS_EvaluateScript(jscontext, glob, t, strlen(t), "builtin", 1, &rval);

    sm->SetMode(MySecMan::VETO_ALL);
    printf("  getService with veto: ");
    t = "try{Components.classes['@mozilla.org/js/xpc/ID;1'].createInstance(Components.interfaces.nsIJSID); failed = true; print('FAILED');}catch(e){print('passed');}";
    JS_EvaluateScript(jscontext, glob, t, strlen(t), "builtin", 1, &rval);


    sm->SetMode(MySecMan::OK_ALL);
    printf("  call method no veto: ");
    t = "try{foo.Test2(); print(' : passed');}catch(e){failed = true; print(' : FAILED');}";
    JS_EvaluateScript(jscontext, glob, t, strlen(t), "builtin", 1, &rval);

    sm->SetMode(MySecMan::VETO_ALL);
    printf("  call method with veto: ");
    t = "try{foo.Test2(); failed = true; print(' : FAILED');}catch(e){print(' : passed');}";
    JS_EvaluateScript(jscontext, glob, t, strlen(t), "builtin", 1, &rval);


    sm->SetMode(MySecMan::OK_ALL);
    printf("  get attribute no veto: ");
    t = "try{foo.Foo; print(' : passed');}catch(e){failed = true; print(' : FAILED');}";
    JS_EvaluateScript(jscontext, glob, t, strlen(t), "builtin", 1, &rval);

    sm->SetMode(MySecMan::VETO_ALL);
    printf("  get attribute with veto: ");
    t = "try{foo.Foo; failed = true; print(' : FAILED');}catch(e){print(' : passed');}";
    JS_EvaluateScript(jscontext, glob, t, strlen(t), "builtin", 1, &rval);


    sm->SetMode(MySecMan::OK_ALL);
    printf("  set attribute no veto: ");
    t = "try{foo.Foo = 0; print(' : passed');}catch(e){failed = true; print(' : FAILED');}";
    JS_EvaluateScript(jscontext, glob, t, strlen(t), "builtin", 1, &rval);

    sm->SetMode(MySecMan::VETO_ALL);
    printf("  set attribute with veto: ");
    t = "try{foo.Foo = 0; failed = true; print(' : FAILED');}catch(e){print(' : passed');}";
    JS_EvaluateScript(jscontext, glob, t, strlen(t), "builtin", 1, &rval);

sm_test_done:
    success = success && JS_GetProperty(jscontext, glob, "failed", &rval) && JSVAL_TRUE != rval;
    printf("SecurityManager tests : %s\n", success ? "passed" : "FAILED");
    NS_IF_RELEASE(foo);
    xpc->SetSecurityManagerForJSContext(jscontext, nsnull, 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void TestThreadJSContextStack ( JSContext jscontext) [static]

Definition at line 537 of file TestXPC.cpp.

{

    printf("ThreadJSContextStack tests...\n");

    nsresult rv;
    nsCOMPtr<nsIJSContextStack> stack = 
             do_GetService("@mozilla.org/js/xpc/ContextStack;1", &rv);

    if(NS_SUCCEEDED(rv))
    {
        PRInt32 count;
        PRInt32 base_count;

        if(NS_SUCCEEDED(stack->GetCount(&base_count)))
            printf("\tstack->GetCount() : passed\n");
        else
            printf("\tstack->GetCount() FAILED!\n");

        if(NS_FAILED(stack->Push(jscontext)))
            printf("\tstack->Push() FAILED!\n");
        else
            printf("\tstack->Push() passed\n");

        if(NS_SUCCEEDED(stack->GetCount(&count)))
            printf("\tstack->GetCount() : %s\n",
                    count == base_count+1 ? "passed" : "FAILED!");
        else
            printf("\tstack->GetCount() FAILED!\n");

        JSContext* testCX;
        if(NS_FAILED(stack->Peek(&testCX)))
            printf("\tstack->Peek() FAILED!\n");

        if(jscontext == testCX)
            printf("\tstack->Push/Peek : passed\n");
        else
            printf("\tstack->Push/Peek : FAILED\n");

        if(NS_FAILED(stack->Pop(&testCX)))
            printf("\tstack->Pop() FAILED!\n");

        if(jscontext == testCX)
            printf("\tstack->Push/Pop : passed\n");
        else
            printf("\tstack->Push/Pop : FAILED\n");

        if(NS_SUCCEEDED(stack->GetCount(&count)))
            printf("\tstack->GetCount() : %s\n",
                    count == base_count ? "passed" : "FAILED!");
        else
            printf("\tstack->GetCount() FAILED!\n");
    }
    else
        printf("\tFAILED to get nsThreadJSContextStack service!\n");
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 66 of file TestXPC.cpp.

Initial value:
 {
    {"print",           Print,          0},
    {"load",            Load,           1},
    {0}
}

Definition at line 115 of file TestXPC.cpp.

Definition at line 65 of file TestXPC.cpp.