Beispiel #1
0
int
MyApplication::run(int argc, char* argv[])
{
    cout << "testing single instance... " << flush;
    {
        NPtr n = new N;
        test(getNum() == 1);
    }
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing single instance cycle... " << flush;
    {
        NPtr n = new N;
        n->left = n;
        test(getNum() == 1);
        n->ice_collectable(true);
        TestHaveCycles().visit(n.get());
    }
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing single instance cycle with double pointers... " << flush;
    {
        NPtr n = new N;
        n->left = n;
        n->right = n;
        n->ice_collectable(true);
        TestHaveCycles().visit(n.get());
        test(getNum() == 1);
    }
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing double instance cycle... " << flush;
    {
        NPtr n1 = new N;
        NPtr n2 = new N;
        n1->left = n2;
        n2->left = n1;
        n1->ice_collectable(true);
        TestHaveCycles().visit(n1.get());
        n1 = 0;
        test(n2->left->left == n2);
        test(getNum() == 2);
    }
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing double instance cycle with double pointers... " << flush;
    {
        NPtr n1 = new N;
        NPtr n2 = new N;
        n1->left = n2;
        n2->left = n1;
        n1->right = n2;
        n2->right = n1;
        n1->ice_collectable(true);
        TestHaveCycles().visit(n1.get());
        n1 = 0;
        test(n2->left->left == n2);
        test(getNum() == 2);
    }
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing double instance cycle with looped pointers... " << flush;
    {
        NPtr n1 = new N;
        NPtr n2 = new N;
        n1->left = n2;
        n2->left = n1;
        n1->right = n1;
        n2->right = n2;
        n1->ice_collectable(true);
        TestHaveCycles().visit(n1.get());
        test(getNum() == 2);
        n1 = 0;
        test(n2->left->left == n2);
    }
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing triple instance cycle... " << flush;
    {
        NPtr n1 = new N;
        NPtr n2 = new N;
        NPtr n3 = new N;
        n1->left = n2;
        n2->left = n3;
        n3->left = n1;
        n1->ice_collectable(true);
        TestHaveCycles().visit(n1.get());
        n1 = 0;
        test(n2->left->left->left == n2);
        test(getNum() == 3);
    }
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing triple instance cycle with double pointers... " << flush;
    {
        NPtr n1 = new N;
        NPtr n2 = new N;
        NPtr n3 = new N;
        n1->left = n2;
        n2->left = n3;
        n3->left = n1;
        n1->right = n2;
        n2->right = n3;
        n3->right = n1;
        test(getNum() == 3);
        n1->ice_collectable(true);
        TestHaveCycles().visit(n1.get());
    }
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing triple instance cycle with opposing pointers... " << flush;
    {
        NPtr n1 = new N;
        NPtr n2 = new N;
        NPtr n3 = new N;
        n1->left = n2;
        n2->left = n3;
        n3->left = n1;
        n1->right = n3;
        n2->right = n1;
        n3->right = n2;
        n1->ice_collectable(true);
        TestHaveCycles().visit(n1.get());
        test(getNum() == 3);
    }
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing cycle with trailing instances... " << flush;
    NPtr n;
    {
        NPtr n1 = new N;
        NPtr n2 = new N;
        NPtr n3 = new N;
        NPtr n4 = new N;
        n1->left = n2;
        n2->left = n1;
        n2->right = n3;
        n3->left = n4;
        n = n3;
        n1->ice_collectable(true);
        TestHaveCycles().visit(n1.get());
        test(getNum() == 4);
    }
    test(getNum() == 2);
    n = 0;
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing cycle with trailing instances and trailing cycle... " << flush;
    {
        NPtr n1 = new N;
        NPtr n2 = new N;
        NPtr n3 = new N;
        NPtr n4 = new N;
        NPtr n5 = new N;
        NPtr n6 = new N;
        n1->left = n2;
        n2->left = n1;
        n2->right = n3;
        n3->left = n4;
        n4->right = n5;
        n5->right = n6;
        n6->right = n5;
        n1->ice_collectable(true);
        TestHaveCycles().visit(n1.get());
        n = n4;
        test(getNum() == 6);
    }
    test(getNum() == 3);
    n = 0;
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing complex cycles... " << flush;
    {
        NPtr n1 = new N;
        NPtr n2 = new N;
        NPtr n3 = new N;
        NPtr n4 = new N;
        NPtr n5 = new N;
        NPtr n6 = new N;
        NPtr n7 = new N;
        NPtr n8 = new N;
        
        n1->left = n2;
        n2->left = n3;
        n2->right = n4;
        n3->left = n8;
        n3->right = n5;
        n4->left = n5;
        n5->left = n6;
        n6->left = n5;
        n6->right = n7;
        n7->left = n3;
        n8->left = n1;
        n1->ice_collectable(true);
        TestHaveCycles().visit(n1.get());

        n4->ice_collectable(false);

        n4->ice_collectable(true);
        TestHaveCycles().visit(n4.get());

        n = n4;
        test(getNum() == 8);
    }
    test(getNum() == 8);
    n = 0;
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing random graphs... " << flush;
    {
        for(int i = 10; i <= 150; i += 10) // random graphs with 10 to 150 nodes
        {
            {
                vector<NPtr> nodes;
                for(int j = 0; j < i; ++j)
                {
                    nodes.push_back(new N());
                }
                for(int j = 0; j < i; ++j)
                {
                    nodes[j]->left = nodes[IceUtilInternal::random(i)];
                    nodes[j]->right = nodes[IceUtilInternal::random(i)];
                }
                for(int j = 0; j < i; ++j)
                {
                    nodes[j]->ice_collectable(true);
                }
                test(getNum() == i);
            }
            test(getNum() == 0);
        }
    }
    cout << "ok" << endl;

    cout << "testing sequence element cycle... " << flush;
    {
        CSeq cs;
        cs.push_back(new N);
        cs.push_back(new N);
        cs[0]->left = cs[1];
        cs[1]->left = cs[0];
        cs[0]->ice_collectable(true);
        cs[1]->ice_collectable(true);
        test(getNum() == 2);
    }
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing dictionary element cycle... " << flush;
    {
        CDict cd;
        NPtr n1 = new N;
        NPtr n2 = new N;
        n1->left = n2;
        n2->left = n1;
        cd[0] = n1;
        cd[1] = n2;
        cd[0]->ice_collectable(true);
        cd[1]->ice_collectable(true);
        test(getNum() == 2);
    }
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing sequence of struct cycle... " << flush;
    {
        SSeq ss;
        S s;

        ss.push_back(s);
        ss.push_back(s);
        ss[0].theC = new N;
        ss[1].theC = new N;
        ss[0].theC->left = ss[1].theC;
        ss[1].theC->left = ss[0].theC;
        ss[0].theC->ice_collectable(true);
        ss[1].theC->ice_collectable(true);
        test(getNum() == 2);
    }
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing sequence of struct of dictionary cycle... " << flush;
    {
        N2Ptr n2 = new N2;
        S2 s2;
        n2->theS2Seq.push_back(s2);
        n2->theS2Seq.push_back(s2);
        n2->theS2Seq[0].theC2Dict[0] = n2;
        n2->theS2Seq[0].theC2Dict[1] = n2;
        n2->theS2Seq[1].theC2Dict[0] = n2;
        n2->theS2Seq[1].theC2Dict[1] = n2;
        n2->ice_collectable(true);
        test(getNum() == 1);
    }
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing leaf nodes... " << flush;

    {
        NNPtr nn = new NN;
        nn->l = new NL;
        test(getNum() == 2);
    }
    test(getNum() == 0);

    {
        NLPtr p;
        {
            NNPtr nn = new NN;
            p = new NL;
            nn->l = p;
            test(getNum() == 2);
        }
        test(getNum() == 1);
    }
    test(getNum() == 0);

    {
        NNPtr nn = new NN;
        NLPtr nl = new NL;
        nn->l = nl;
        nn->n = nn;
        nn->ice_collectable(true);
        TestHaveCycles().visit(nn.get());
        test(getNum() == 2);
    }
    test(getNum() == 0);

    {
        NNPtr nn1 = new NN;
        NNPtr nn2 = new NN;
        NLPtr nl = new NL;
        nn1->l = nl;
        nn1->n = nn2;
        nn2->l = nl;
        nn2->n = nn1;
        nn1->ice_collectable(true);
        TestHaveCycles().visit(nn1.get());
        test(getNum() == 3);
    }
    test(getNum() == 0);

    {
        NLPtr nl = new NL;
        test(getNum() == 1);
    }
    test(getNum() == 0);

    {
        NNPtr nn1 = new NN;
        nn1->n = new NN;
        test(getNum() == 2);
    }
    test(getNum() == 0);

    cout << "ok" << endl;
    return 0;
}
Beispiel #2
0
int
MyApplication::run(int argc, char* argv[])
{
    if(argc < 2 || argc > 3)
    {
        cerr << "usage: " << argv[0] << " [testoptions] seedfile [seed]" << endl;
        return EXIT_FAILURE;
    }

    cout << "testing single instance... " << flush;
    {
        NPtr n = new N;
        test(getNum() == 1);
        Ice::collectGarbage();
        test(getNum() == 1);
    }
    test(getNum() == 0);
    Ice::collectGarbage();
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing single instance cycle... " << flush;
    {
        NPtr n = new N;
        n->left = n;
        test(getNum() == 1);
        Ice::collectGarbage();
        test(getNum() == 1);
    }
    test(getNum() == 1);
    Ice::collectGarbage();
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing single instance cycle with double pointers... " << flush;
    {
        NPtr n = new N;
        n->left = n;
        n->right = n;
        test(getNum() == 1);
        Ice::collectGarbage();
        test(getNum() == 1);
    }
    test(getNum() == 1);
    Ice::collectGarbage();
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing double instance cycle... " << flush;
    {
        NPtr n1 = new N;
        NPtr n2 = new N;
        n1->left = n2;
        n2->left = n1;
        test(getNum() == 2);
        Ice::collectGarbage();
        test(getNum() == 2);
    }
    test(getNum() == 2);
    Ice::collectGarbage();
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing double instance cycle with double pointers... " << flush;
    {
        NPtr n1 = new N;
        NPtr n2 = new N;
        n1->left = n2;
        n2->left = n1;
        n1->right = n2;
        n2->right = n1;
        test(getNum() == 2);
        Ice::collectGarbage();
        test(getNum() == 2);
    }
    test(getNum() == 2);
    Ice::collectGarbage();
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing double instance cycle with looped pointers... " << flush;
    {
        NPtr n1 = new N;
        NPtr n2 = new N;
        n1->left = n2;
        n2->left = n1;
        n1->right = n1;
        n2->right = n2;
        test(getNum() == 2);
        Ice::collectGarbage();
        test(getNum() == 2);
    }
    test(getNum() == 2);
    Ice::collectGarbage();
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing triple instance cycle... " << flush;
    {
        NPtr n1 = new N;
        NPtr n2 = new N;
        NPtr n3 = new N;
        n1->left = n2;
        n2->left = n3;
        n3->left = n1;
        test(getNum() == 3);
        Ice::collectGarbage();
        test(getNum() == 3);
    }
    test(getNum() == 3);
    Ice::collectGarbage();
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing triple instance cycle with double pointers... " << flush;
    {
        NPtr n1 = new N;
        NPtr n2 = new N;
        NPtr n3 = new N;
        n1->left = n2;
        n2->left = n3;
        n3->left = n1;
        n1->right = n2;
        n2->right = n3;
        n3->right = n1;
        test(getNum() == 3);
        Ice::collectGarbage();
        test(getNum() == 3);
    }
    test(getNum() == 3);
    Ice::collectGarbage();
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing triple instance cycle with opposing pointers... " << flush;
    {
        NPtr n1 = new N;
        NPtr n2 = new N;
        NPtr n3 = new N;
        n1->left = n2;
        n2->left = n3;
        n3->left = n1;
        n1->right = n3;
        n2->right = n1;
        n3->right = n2;
        test(getNum() == 3);
        Ice::collectGarbage();
        test(getNum() == 3);
    }
    test(getNum() == 3);
    Ice::collectGarbage();
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing cycle with trailing instances... " << flush;
    NPtr n;
    {
        NPtr n1 = new N;
        NPtr n2 = new N;
        NPtr n3 = new N;
        NPtr n4 = new N;
        n1->left = n2;
        n2->left = n1;
        n2->right = n3;
        n3->left = n4;
        n = n3;
        test(getNum() == 4);
        Ice::collectGarbage();
        test(getNum() == 4);
    }
    test(getNum() == 4);
    Ice::collectGarbage();
    test(getNum() == 2);
    n = 0;
    test(getNum() == 0);
    Ice::collectGarbage();
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing cycle with trailing instances and trailing cycle... " << flush;
    {
        NPtr n1 = new N;
        NPtr n2 = new N;
        NPtr n3 = new N;
        NPtr n4 = new N;
        NPtr n5 = new N;
        NPtr n6 = new N;
        n1->left = n2;
        n2->left = n1;
        n2->right = n3;
        n3->left = n4;
        n4->right = n5;
        n5->right = n6;
        n6->right = n5;
        n = n4;
        test(getNum() == 6);
        Ice::collectGarbage();
        test(getNum() == 6);
    }
    test(getNum() == 6);
    Ice::collectGarbage();
    test(getNum() == 3);
    n = 0;
    test(getNum() == 2);
    Ice::collectGarbage();
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing sequence element cycle... " << flush;
    {
        CSeq cs;
        cs.push_back(new N);
        cs.push_back(new N);
        cs[0]->left = cs[1];
        cs[1]->left = cs[0];
        test(getNum() == 2);
        Ice::collectGarbage();
        test(getNum() == 2);
    }
    Ice::collectGarbage();
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing dictionary element cycle... " << flush;
    {
        CDict cd;
        NPtr n1 = new N;
        NPtr n2 = new N;
        n1->left = n2;
        n2->left = n1;
        cd[0] = n1;
        cd[1] = n2;
        test(getNum() == 2);
        Ice::collectGarbage();
        test(getNum() == 2);
    }
    Ice::collectGarbage();
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing sequence of struct cycle... " << flush;
    {
        SSeq ss;
        S s;

        ss.push_back(s);
        ss.push_back(s);
        ss[0].theC = new N;
        ss[1].theC = new N;
        ss[0].theC->left = ss[1].theC;
        ss[1].theC->left = ss[0].theC;
        test(getNum() == 2);
        Ice::collectGarbage();
        test(getNum() == 2);
    }
    Ice::collectGarbage();
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing sequence of struct of dictionary cycle... " << flush;
    {
        N2Ptr n2 = new N2;
        S2 s2;

        n2->theS2Seq.push_back(s2);
        n2->theS2Seq.push_back(s2);
        n2->theS2Seq[0].theC2Dict[0] = n2;
        n2->theS2Seq[0].theC2Dict[1] = n2;
        n2->theS2Seq[1].theC2Dict[0] = n2;
        n2->theS2Seq[1].theC2Dict[1] = n2;
        test(getNum() == 1);
        Ice::collectGarbage();
        test(getNum() == 1);
    }
    Ice::collectGarbage();
    test(getNum() == 0);
    cout << "ok" << endl;

    cout << "testing leaf nodes... " << flush;

    {
        NNPtr nn = new NN;
        nn->l = new NL;
        test(getNum() == 2);
        Ice::collectGarbage();
        test(getNum() == 2);
    }
    Ice::collectGarbage();
    test(getNum() == 0);

    {
        NLPtr p;
        {
            NNPtr nn = new NN;
            p = new NL;
            nn->l = p;
            test(getNum() == 2);
            Ice::collectGarbage();
            test(getNum() == 2);
        }
        Ice::collectGarbage();
        test(getNum() == 1);
    }
    test(getNum() == 0);

    {
        NNPtr nn = new NN;
        NLPtr nl = new NL;
        nn->l = nl;
        nn->n = nn;
        test(getNum() == 2);
        Ice::collectGarbage();
        test(getNum() == 2);
    }
    test(getNum() == 2);
    Ice::collectGarbage();
    test(getNum() == 0);

    {
        NNPtr nn1 = new NN;
        NNPtr nn2 = new NN;
        NLPtr nl = new NL;
        nn1->l = nl;
        nn1->n = nn2;
        nn2->l = nl;
        nn2->n = nn1;
        test(getNum() == 3);
        Ice::collectGarbage();
        test(getNum() == 3);
    }
    test(getNum() == 3);
    Ice::collectGarbage();
    test(getNum() == 0);

    {
        NLPtr nl = new NL;
        test(getNum() == 1);
    }
    test(getNum() == 0);
    Ice::collectGarbage();
    test(getNum() == 0);

    {
        NNPtr nn1 = new NN;
        nn1->n = new NN;
        test(getNum() == 2);
        Ice::collectGarbage();
        test(getNum() == 2);
    }
    test(getNum() == 0);
    Ice::collectGarbage();
    test(getNum() == 0);

    cout << "ok" << endl;
    
    cout << "testing for race conditions... " << flush;
    string seedfile = argv[1];
    ofstream file(seedfile.c_str());
    if(!file)
    {
        cerr << argv[0] << ": cannot open `" << seedfile << "' for writing" << endl;
        return EXIT_FAILURE;
    }
    ::IceUtil::Time t = ::IceUtil::Time::now();
    int seed = argc > 2 ? atoi(argv[2]) : static_cast<int>(t.toMilliSeconds());
    file << seed << "\n";
    file.close();
    srand(seed);

    typedef ::IceUtil::Handle<GarbageProducer> GarbageThreadPtr;
    GarbageThreadPtr garbageThread = new GarbageProducer();
    garbageThread->start();

    for(int i = 0; i < 50; ++i)
    {
        if(interrupted())
        {
            break;
        }
        garbageThread->randomWait();
        Ice::collectGarbage();
    }

    garbageThread->stop();
    IceUtil::ThreadControl::sleep(IceUtil::Time::seconds(1));
    Ice::collectGarbage();
    if(!interrupted())
    {
        test(getNum() == 0);
        cout << "ok" << endl;
        return EXIT_SUCCESS;
    }
    else
    {
        return 130; // SIGINT + 128
    }
}