void mediadataclient_object_t::test<13>()
{
    //
    // Test supression of redundant navigates.
    //
    LOG_TEST(13);

    LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_1,"1.0","true"));
    {
        LLPointer<LLObjectMediaNavigateClient> mdc = new LLObjectMediaNavigateClient(NO_PERIOD,NO_PERIOD);
        const char *TEST_URL = "http://foo.example.com";
        const char *TEST_URL_2 = "http://example.com";
        mdc->navigate(o1, 0, TEST_URL);
        mdc->navigate(o1, 1, TEST_URL);
        mdc->navigate(o1, 0, TEST_URL_2);
        mdc->navigate(o1, 1, TEST_URL_2);

        // This should add two requests to the queue, one for face 0 of the object and one for face 1.

        ensure("before pump: 1 is in queue", mdc->isInQueue(o1));

        ::pump_timers();

        ensure("after first pump: 1 is in queue", mdc->isInQueue(o1));

        ::pump_timers();

        ensure("after second pump: 1 is not in queue", !mdc->isInQueue(o1));

        ensure("first post has correct url", (*gPostRecords)[0]["body"][LLMediaEntry::CURRENT_URL_KEY].asString(), std::string(TEST_URL_2));
        ensure("second post has correct url", (*gPostRecords)[1]["body"][LLMediaEntry::CURRENT_URL_KEY].asString(), std::string(TEST_URL_2));

    }
}
void mediadataclient_object_t::test<8>()
{
    // Test queue handling of objects that are marked dead.
    LOG_TEST(8);

    LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_1,"4.0","true"));
    LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_2,"3.0","true"));
    LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_3,"2.0","true"));
    LLMediaDataClientObject::ptr_t o4 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_4,"1.0","true"));
    {
        LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);

        // queue up all 4 objects
        mdc->fetchMedia(o1);
        mdc->fetchMedia(o2);
        mdc->fetchMedia(o3);
        mdc->fetchMedia(o4);

        ensure("is in queue 1", mdc->isInQueue(o1));
        ensure("is in queue 2", mdc->isInQueue(o2));
        ensure("is in queue 3", mdc->isInQueue(o3));
        ensure("is in queue 4", mdc->isInQueue(o4));
        ensure("post records", gPostRecords->size(), 0);

        // and mark the second and fourth ones dead.  Call removeFromQueue when marking dead, since this is what LLVOVolume will do.
        dynamic_cast<LLMediaDataClientObjectTest*>(static_cast<LLMediaDataClientObject*>(o2))->markDead();
        mdc->removeFromQueue(o2);
        dynamic_cast<LLMediaDataClientObjectTest*>(static_cast<LLMediaDataClientObject*>(o4))->markDead();
        mdc->removeFromQueue(o4);

        // The removeFromQueue calls should remove the second and fourth ones
        ensure("is in queue 1", mdc->isInQueue(o1));
        ensure("is not in queue 2", !mdc->isInQueue(o2));
        ensure("is in queue 3", mdc->isInQueue(o3));
        ensure("is not in queue 4", !mdc->isInQueue(o4));
        ensure("post records", gPostRecords->size(), 0);

        ::pump_timers();

        // The first tick should process the first item
        ensure("is not in queue 1", !mdc->isInQueue(o1));
        ensure("is not in queue 2", !mdc->isInQueue(o2));
        ensure("is in queue 3", mdc->isInQueue(o3));
        ensure("is not in queue 4", !mdc->isInQueue(o4));
        ensure("post records", gPostRecords->size(), 1);

        ::pump_timers();

        // The second tick should process the third, emptying the queue
        ensure("is not in queue 3", !mdc->isInQueue(o3));
        ensure("post records", gPostRecords->size(), 2);

        ensure("queue empty", mdc->isEmpty());
    }
    ensure("refcount of o1", o1->getNumRefs(), 1);
    ensure("refcount of o2", o2->getNumRefs(), 1);
    ensure("refcount of o3", o3->getNumRefs(), 1);
    ensure("refcount of o4", o4->getNumRefs(), 1);

}
void mediadataclient_object_t::test<7>()
{
    // Test LLMediaDataClient::isInQueue()
    LOG_TEST(7);

    LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(
        _DATA(VALID_OBJECT_ID_1,"3.0","true"));
    LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(
        _DATA(VALID_OBJECT_ID_2,"1.0","true"));
    int num_refs_start = o1->getNumRefs();
    {
        LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);

        ensure("not in queue yet 1", ! mdc->isInQueue(o1));
        ensure("not in queue yet 2", ! mdc->isInQueue(o2));

        mdc->fetchMedia(o1);

        ensure("is in queue", mdc->isInQueue(o1));
        ensure("is not in queue", ! mdc->isInQueue(o2));

        ::pump_timers();

        ensure("not in queue anymore", ! mdc->isInQueue(o1));
        ensure("still is not in queue", ! mdc->isInQueue(o2));

        ensure("queue empty", mdc->isEmpty());
    }

    // Make sure everyone's destroyed properly
    ensure("REF COUNT", o1->getNumRefs(), num_refs_start);

}
void mediadataclient_object_t::test<12>()
{
    //
    // Test the "not interesting enough" call
    //
    LOG_TEST(12);

    LLMediaDataClientObjectTest *object1 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_1,"1.0","true"));
    LLMediaDataClientObject::ptr_t o1 = object1;
    LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_2,"2.0","true"));
    LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_3,"3.0","true"));
    LLMediaDataClientObject::ptr_t o4 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_4,"4.0","true"));
    {
        LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);

        // queue up all 4 objects.  The first two are "interesting enough".
        // Firing the timer 4 times should therefore leave them.
        // Note that they should be sorted 4,3,2,1
        // Then, we'll make one "interesting enough", fire the timer a few
        // times, and make sure only it gets pulled off the queue
        gMinimumInterestLevel = 2.5;
        mdc->fetchMedia(o1);
        mdc->fetchMedia(o2);
        mdc->fetchMedia(o3);
        mdc->fetchMedia(o4);

        int tick_num = 0;

        // 0
        ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
        ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
        ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
        ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
        ensure(STR(tick_num) + ". post records", gPostRecords->size(), 0);

        ::pump_timers();
        ++tick_num;

        // 1 The first tick should remove object 4
        ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
        ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
        ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
        ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
        ensure(STR(tick_num) + ". post records", gPostRecords->size(), 1);
        ensure(STR(tick_num) + ". post object id", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_4));

        ::pump_timers();
        ++tick_num;

        // 2 The second tick should send object 3
        ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
        ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
        ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
        ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
        ensure(STR(tick_num) + ". post records", gPostRecords->size(), 2);
        ensure(STR(tick_num) + ". post object id", (*gPostRecords)[1]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_3));

        ::pump_timers();
        ++tick_num;

        // 3 The third tick should not pull off anything
        ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
        ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
        ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
        ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
        ensure(STR(tick_num) + ". post records", gPostRecords->size(), 2);

        ::pump_timers();
        ++tick_num;

        // 4 The fourth tick (for good measure) should not pull off anything
        ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
        ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
        ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
        ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
        ensure(STR(tick_num) + ". post records", gPostRecords->size(), 2);

        // Okay, now futz with object 1's interest, such that it is now
        // "interesting enough"
        object1->setMediaInterest((F64)5.0);

        // This should sort so that the queue is now [1 2]
        ::pump_timers();
        ++tick_num;

        // 5 The fifth tick should now identify objects 3 and 4 as no longer
        // needing "updating", and remove them from the queue
        ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1));
        ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
        ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
        ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
        ensure(STR(tick_num) + ". post records", gPostRecords->size(), 3);
        ensure(STR(tick_num) + ". post object id", (*gPostRecords)[2]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_1));

        ::pump_timers();
        ++tick_num;

        // 6 The sixth tick should not pull off anything
        ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1));
        ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
        ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
        ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
        ensure(STR(tick_num) + ". post records", gPostRecords->size(), 3);

        ::pump_timers();
        ++tick_num;

        // Whew....better NOT be empty ... o2 should still be there
        ensure("queue not empty", !mdc->isEmpty());

        // But, we need to clear the queue, or else we won't destroy MDC...
        // this is a strange interplay between the queue timer and the MDC
        mdc->removeFromQueue(o2);
        // tick
        ::pump_timers();
    }
    ensure("refcount of o1", o1->getNumRefs(), 1);
    ensure("refcount of o2", o2->getNumRefs(), 1);
    ensure("refcount of o3", o3->getNumRefs(), 1);
    ensure("refcount of o4", o4->getNumRefs(), 1);
}
void mediadataclient_object_t::test<10>()
{
    //
    // Test using the "round-robin" queue
    //
    LOG_TEST(10);

    LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_1,"1.0","true"));
    LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_2,"2.0","true"));
    LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_3,"3.0","false"));
    LLMediaDataClientObject::ptr_t o4 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_4,"4.0","false"));
    {
        LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);

        // queue up all 4 objects.  The first two should be in the sorted
        // queue [2 1], the second in the round-robin queue.  The queues
        // are serviced interleaved, so we should expect:
        // 2, 3, 1, 4
        mdc->fetchMedia(o1);
        mdc->fetchMedia(o2);
        mdc->fetchMedia(o3);
        mdc->fetchMedia(o4);

        int tick_num = 0;

        // 0
        ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
        ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
        ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
        ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
        ensure(STR(tick_num) + ". post records", gPostRecords->size(), 0);

        ::pump_timers();
        ++tick_num;

        // 1 The first tick should remove object 2
        ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
        ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2));
        ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
        ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
        ensure(STR(tick_num) + ". post records", gPostRecords->size(), 1);
        ensure(STR(tick_num) + ". post object id", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_2));

        ::pump_timers();
        ++tick_num;

        // 2 The second tick should send object 3
        ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
        ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2));
        ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
        ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
        ensure(STR(tick_num) + ". post records", gPostRecords->size(), 2);
        ensure(STR(tick_num) + ". post object id", (*gPostRecords)[1]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_3));

        ::pump_timers();
        ++tick_num;

        // 3 The third tick should remove object 1
        ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1));
        ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2));
        ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
        ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
        ensure(STR(tick_num) + ". post records", gPostRecords->size(), 3);
        ensure(STR(tick_num) + ". post object id", (*gPostRecords)[2]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_1));

        ::pump_timers();
        ++tick_num;

        // 4 The fourth tick should send object 4
        ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1));
        ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2));
        ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
        ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
        ensure(STR(tick_num) + ". post records", gPostRecords->size(), 4);
        ensure(STR(tick_num) + ". post object id", (*gPostRecords)[3]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_4));

        ::pump_timers();
        ++tick_num;

        // 5 The fifth tick should not change the state of anything.
        ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1));
        ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2));
        ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
        ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
        ensure(STR(tick_num) + ". post records", gPostRecords->size(), 4);

        ::pump_timers();

        // Whew....better be empty
        ensure("queue empty", mdc->isEmpty());
    }
    ensure("refcount of o1", o1->getNumRefs(), 1);
    ensure("refcount of o2", o2->getNumRefs(), 1);
    ensure("refcount of o3", o3->getNumRefs(), 1);
    ensure("refcount of o4", o4->getNumRefs(), 1);
}
void mediadataclient_object_t::test<9>()
{
    //
    // Test queue re-ordering
    //
    LOG_TEST(9);

    LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_1,"40.0","true"));
    LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_2,"30.0","true"));
    LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_3,"20.0","true"));
    LLMediaDataClientObjectTest *object4 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_4,"10.0","true"));
    LLMediaDataClientObject::ptr_t o4 = object4;
    {
        LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);

        // queue up all 4 objects.  They should now be in the queue in
        // order 1 through 4, with 4 being at the front of the queue
        mdc->fetchMedia(o1);
        mdc->fetchMedia(o2);
        mdc->fetchMedia(o3);
        mdc->fetchMedia(o4);

        int tick_num = 0;

        ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
        ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
        ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
        ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
        ensure(STR(tick_num) + ". post records", gPostRecords->size(), 0);

        ::pump_timers();
        ++tick_num;

        // The first tick should remove the first one
        ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1));
        ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
        ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
        ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
        ensure(STR(tick_num) + ". post records", gPostRecords->size(), 1);

        // Now, pretend that object 4 moved relative to the avatar such
        // that it is now closest
        object4->setMediaInterest(50.0);

        ::pump_timers();
        ++tick_num;

        // The second tick should still pick off item 2, but then re-sort
        // have picked off object 4
        ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
        ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
        ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
        ensure(STR(tick_num) + ". post records", gPostRecords->size(), 2);

        ::pump_timers();
        ++tick_num;

        // The third tick should pick off object 2
        ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2));
        ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
        ensure(STR(tick_num) + ". post records", gPostRecords->size(), 3);

        // The fourth tick should pick off object 3
        ::pump_timers();
        ++tick_num;

        ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
        ensure(STR(tick_num) + ". post records", gPostRecords->size(), 4);

        ensure("queue empty", mdc->isEmpty());
    }
    ensure("refcount of o1", o1->getNumRefs(), 1);
    ensure("refcount of o2", o2->getNumRefs(), 1);
    ensure("refcount of o3", o3->getNumRefs(), 1);
    ensure("refcount of o4", o4->getNumRefs(), 1);
}