Skip to content

Commit 35c3060

Browse files
Add predicate dequeue animation regression
1 parent 1b6d28a commit 35c3060

1 file changed

Lines changed: 108 additions & 18 deletions

File tree

tests/unit/Ieee80211AddbaTransaction_1.test

Lines changed: 108 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,18 @@ class TestSignalListener : public cListener
412412
virtual void receiveSignal(cComponent *, simsignal_t, cObject *, cObject *) override { numSignals++; }
413413
};
414414

415+
class TestPacketArrivalListener : public cListener
416+
{
417+
public:
418+
int numSignals = 0;
419+
cGate *lastArrivalGate = nullptr;
420+
421+
virtual void receiveSignal(cComponent *, simsignal_t, cObject *value, cObject *) override {
422+
numSignals++;
423+
lastArrivalGate = check_and_cast<Packet *>(value)->getArrivalGate();
424+
}
425+
};
426+
415427
class TestOrderedSignalListener : public cListener
416428
{
417429
public:
@@ -3311,46 +3323,124 @@ auto deferredFrames = deferredInProgressFrames.releaseFrames();
33113323
ASSERT(deferredFrames.size() == 1);
33123324
delete deferredFrames.at(0);
33133325

3314-
// A simulation-registered real queue records selected-dequeue residence and
3315-
// emits its semantic pull exactly once.
3316-
Packet *compoundPacket = nullptr;
3326+
// A real queue with a downstream collector predicate-dequeues a non-front
3327+
// packet, records its residence and semantic pull once, and animates it to the
3328+
// collector while retaining the front packet.
33173329
{
33183330
TestPacketPulledListener pullListener;
3319-
auto leafQueue = createPacketQueue("selectedDequeueQueue");
3331+
TestPacketDropCallback removalCallback;
3332+
auto leafQueueModule = cModuleType::get("inet.queueing.queue.PacketQueue")->create("selectedDequeueQueue", this);
3333+
auto sinkModule = cModuleType::get("inet.queueing.sink.FullPacketSink")->create("selectedDequeueSink", this);
3334+
leafQueueModule->gate("out")->connectTo(sinkModule->gate("in"));
3335+
leafQueueModule->callInitialize();
3336+
sinkModule->callInitialize();
3337+
auto leafQueue = check_and_cast<queueing::PacketQueue *>(leafQueueModule);
33203338
pullListener.leaf = leafQueue;
33213339
leafQueue->subscribe(packetPulledSignal, &pullListener);
3322-
compoundPacket = new Packet("compoundPacket", makeQosHeader(peer1, 1, SequenceNumberCyclic(1)));
3323-
auto queueingTimeTag = compoundPacket->addRegionTag<QueueingTimeTag>();
3340+
leafQueue->addPacketCallback(&removalCallback);
3341+
auto frontPacket = new Packet("selectedDequeueFront", makeShared<ByteCountChunk>(B(1)));
3342+
auto selectedPacket = new Packet("selectedDequeueMatch", makeQosHeader(peer1, 1, SequenceNumberCyclic(1)));
3343+
auto queueingTimeTag = selectedPacket->addRegionTag<QueueingTimeTag>();
33243344
queueingTimeTag->setBitTotalTimesArraySize(1);
33253345
queueingTimeTag->setBitTotalTimes(0, 0);
33263346
queueingTimeTag->setPacketTotalTimesArraySize(1);
33273347
queueingTimeTag->setPacketTotalTimes(0, 0);
3328-
compoundPacket->addRegionTag<PacketEventTag>();
3329-
compoundPacket->setArrivalTime(simTime() - 1);
3330-
leafQueue->pushPacket(compoundPacket, nullptr);
3331-
auto dequeuedPacket = leafQueue->dequeuePacket([compoundPacket](const Packet *packet) { return packet == compoundPacket; });
3332-
ASSERT(dequeuedPacket == compoundPacket);
3348+
selectedPacket->addRegionTag<PacketEventTag>();
3349+
selectedPacket->setArrivalTime(simTime() - 1);
3350+
leafQueue->pushPacket(frontPacket, nullptr);
3351+
leafQueue->pushPacket(selectedPacket, nullptr);
3352+
auto dequeuedPacket = leafQueue->dequeuePacket([selectedPacket](const Packet *packet) { return packet == selectedPacket; });
3353+
ASSERT(dequeuedPacket == selectedPacket);
33333354
int numQueuedEvents = 0;
3334-
compoundPacket->mapAllRegionTags<PacketEventTag>(b(0), compoundPacket->getTotalLength(), [&](b, b, const Ptr<const PacketEventTag>& tag) {
3355+
selectedPacket->mapAllRegionTags<PacketEventTag>(b(0), selectedPacket->getTotalLength(), [&](b, b, const Ptr<const PacketEventTag>& tag) {
33353356
for (size_t i = 0; i < tag->getPacketEventsArraySize(); i++)
33363357
if (tag->getPacketEvents(i)->getKind() == PEK_QUEUED)
33373358
numQueuedEvents++;
33383359
});
33393360
simtime_t totalQueueingTime = -1;
3340-
compoundPacket->mapAllRegionTags<QueueingTimeTag>(b(0), compoundPacket->getTotalLength(), [&](b, b, const Ptr<const QueueingTimeTag>& tag) {
3361+
selectedPacket->mapAllRegionTags<QueueingTimeTag>(b(0), selectedPacket->getTotalLength(), [&](b, b, const Ptr<const QueueingTimeTag>& tag) {
33413362
ASSERT(tag->getPacketTotalTimesArraySize() == 1);
33423363
totalQueueingTime = tag->getPacketTotalTimes(0);
33433364
});
33443365
ASSERT(numQueuedEvents == 1);
33453366
ASSERT(totalQueueingTime == 1);
3346-
ASSERT(leafQueue->getNumPackets() == 0);
3367+
ASSERT(leafQueue->getNumPackets() == 1);
3368+
ASSERT(leafQueue->getPacket(0) == frontPacket);
33473369
ASSERT(pullListener.numLeafPulls == 1);
3370+
ASSERT(removalCallback.numDequeuedPackets == 1);
3371+
ASSERT(selectedPacket->getArrivalGate() == sinkModule->gate("in"));
33483372
leafQueue->unsubscribe(packetPulledSignal, &pullListener);
3349-
leafQueue->callFinish();
3350-
leafQueue->deleteModule();
3351-
compoundPacket = nullptr;
3373+
leafQueue->removePacketCallback(&removalCallback);
3374+
leafQueue->removePacket(frontPacket);
3375+
take(frontPacket);
3376+
take(selectedPacket);
3377+
delete frontPacket;
3378+
delete selectedPacket;
3379+
sinkModule->callFinish();
3380+
leafQueueModule->callFinish();
3381+
sinkModule->deleteModule();
3382+
leafQueueModule->deleteModule();
3383+
}
3384+
3385+
// Predicate extraction through a concrete PacketFlowBase module processes a
3386+
// non-front packet once. The queue animates it to the flow input before the
3387+
// flow signals, and the flow then animates it to the final collector.
3388+
{
3389+
TestPacketPulledListener pullListener;
3390+
TestPacketDropCallback removalCallback;
3391+
TestPacketArrivalListener flowInputListener;
3392+
TestPacketArrivalListener flowOutputListener;
3393+
auto leafQueueModule = cModuleType::get("inet.queueing.queue.PacketQueue")->create("selectedFlowLeaf", this);
3394+
auto gateModule = cModuleType::get("inet.queueing.gate.PacketGate")->create("selectedFlowGate", this);
3395+
auto sinkModule = cModuleType::get("inet.queueing.sink.FullPacketSink")->create("selectedFlowSink", this);
3396+
gateModule->par("initiallyOpen").setBoolValue(true);
3397+
gateModule->par("openTime").setDoubleValue(10);
3398+
gateModule->par("closeTime").setDoubleValue(20);
3399+
leafQueueModule->gate("out")->connectTo(gateModule->gate("in"));
3400+
gateModule->gate("out")->connectTo(sinkModule->gate("in"));
3401+
leafQueueModule->callInitialize();
3402+
gateModule->callInitialize();
3403+
sinkModule->callInitialize();
3404+
auto leafQueue = check_and_cast<queueing::PacketQueue *>(leafQueueModule);
3405+
auto packetGate = check_and_cast<queueing::PacketGate *>(gateModule);
3406+
auto packetExtractor = check_and_cast<queueing::IPacketExtractor *>(gateModule);
3407+
pullListener.leaf = leafQueue;
3408+
leafQueue->subscribe(packetPulledSignal, &pullListener);
3409+
leafQueue->addPacketCallback(&removalCallback);
3410+
gateModule->subscribe(packetPulledInSignal, &flowInputListener);
3411+
gateModule->subscribe(packetPulledOutSignal, &flowOutputListener);
3412+
auto frontPacket = new Packet("selectedFlowFront", makeShared<ByteCountChunk>(B(1)));
3413+
auto selectedPacket = new Packet("selectedFlowMatch", makeShared<ByteCountChunk>(B(1)));
3414+
leafQueue->pushPacket(frontPacket, nullptr);
3415+
leafQueue->pushPacket(selectedPacket, nullptr);
3416+
auto dequeuedPacket = packetExtractor->dequeuePacket([selectedPacket](const Packet *packet) { return packet == selectedPacket; });
3417+
ASSERT(dequeuedPacket == selectedPacket);
3418+
ASSERT(leafQueue->getNumPackets() == 1);
3419+
ASSERT(leafQueue->getPacket(0) == frontPacket);
3420+
ASSERT(pullListener.numLeafPulls == 1);
3421+
ASSERT(removalCallback.numDequeuedPackets == 1);
3422+
ASSERT(flowInputListener.numSignals == 1);
3423+
ASSERT(flowInputListener.lastArrivalGate == gateModule->gate("in"));
3424+
ASSERT(flowOutputListener.numSignals == 1);
3425+
ASSERT(flowOutputListener.lastArrivalGate == gateModule->gate("in"));
3426+
ASSERT(packetGate->resolveDirective('p') == "1");
3427+
ASSERT(selectedPacket->getArrivalGate() == sinkModule->gate("in"));
3428+
leafQueue->unsubscribe(packetPulledSignal, &pullListener);
3429+
leafQueue->removePacketCallback(&removalCallback);
3430+
gateModule->unsubscribe(packetPulledInSignal, &flowInputListener);
3431+
gateModule->unsubscribe(packetPulledOutSignal, &flowOutputListener);
3432+
leafQueue->removePacket(frontPacket);
3433+
take(frontPacket);
3434+
take(selectedPacket);
3435+
delete frontPacket;
3436+
delete selectedPacket;
3437+
sinkModule->callFinish();
3438+
gateModule->callFinish();
3439+
leafQueueModule->callFinish();
3440+
sinkModule->deleteModule();
3441+
gateModule->deleteModule();
3442+
leafQueueModule->deleteModule();
33523443
}
3353-
delete compoundPacket;
33543444

33553445
// Ordinary queue overflow must not trigger channel-access re-evaluation, while
33563446
// cancelling a dropped setup transaction must immediately release held traffic.

0 commit comments

Comments
 (0)