Skip to content

Commit a8eaeea

Browse files
committed
UT[mqba]
Signed-off-by: Evgeny Malygin <emalygin@bloomberg.net>
1 parent 34817b2 commit a8eaeea

1 file changed

Lines changed: 88 additions & 3 deletions

File tree

src/groups/mqb/mqba/mqba_clientsession.t.cpp

Lines changed: 88 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -553,9 +553,13 @@ class MyMockDomain : public mqbmock::Domain {
553553
mqbmock::Dispatcher* d_mockDispatcher;
554554
bmqp_ctrlmsg::RoutingConfiguration d_routingConfiguration;
555555
bsl::shared_ptr<MyMockQueueHandle> d_queueHandle;
556-
MyQueueEngine d_mockQueueEngine;
557-
const bool d_atMostOnce;
558-
bslma::Allocator* d_allocator_p;
556+
// Previously created handles, kept alive so that their addresses remain
557+
// distinct across successive `openQueue` calls (tests relying on handle
558+
// pointer identity, e.g. duplicate-queueId, depend on this).
559+
bsl::vector<bsl::shared_ptr<MyMockQueueHandle> > d_retiredHandles;
560+
MyQueueEngine d_mockQueueEngine;
561+
const bool d_atMostOnce;
562+
bslma::Allocator* d_allocator_p;
559563

560564
// CREATORS
561565

@@ -567,6 +571,7 @@ class MyMockDomain : public mqbmock::Domain {
567571
: mqbmock::Domain(cluster, allocator)
568572
, d_mockDispatcher(dispatcher)
569573
, d_queueHandle()
574+
, d_retiredHandles(allocator)
570575
, d_mockQueueEngine(allocator)
571576
, d_atMostOnce(atMostOnce)
572577
, d_allocator_p(allocator)
@@ -595,6 +600,12 @@ class MyMockDomain : public mqbmock::Domain {
595600
queue->_setAtMostOnce(d_atMostOnce);
596601
queue->_setDispatcher(d_mockDispatcher);
597602

603+
// Retain the previously created handle so its address is not reused by
604+
// the handle created below.
605+
if (d_queueHandle) {
606+
d_retiredHandles.push_back(d_queueHandle);
607+
}
608+
598609
d_queueHandle.createInplace(d_allocator_p,
599610
queue,
600611
clientContext,
@@ -2262,6 +2273,79 @@ static void test11_initiateShutdown()
22622273
}
22632274
}
22642275

2276+
static void test12_openQueueDuplicateQueueId()
2277+
// ------------------------------------------------------------------------
2278+
// TESTS OPEN QUEUE WITH A DUPLICATE QUEUE ID
2279+
//
2280+
// Concerns:
2281+
// - A misbehaving client may send a second openQueue request reusing a
2282+
// queueId that is already associated with a different queue. The
2283+
// broker must reject that request gracefully (returning an error to
2284+
// the client).
2285+
//
2286+
// Plan:
2287+
// Instantiate a testbench, open a first queue with a given queueId, then
2288+
// send a second openQueue for a *different* URI reusing the same
2289+
// queueId. Verify the first response is a successful OpenQueueResponse
2290+
// and the second is an E_INVALID_ARGUMENT Status.
2291+
//
2292+
// Testing:
2293+
// That reusing a queueId for a different queue is rejected.
2294+
// ------------------------------------------------------------------------
2295+
{
2296+
bmqtst::TestHelper::printTestName(
2297+
"TESTS OPEN QUEUE WITH A DUPLICATE QUEUE ID");
2298+
2299+
const bsl::string uri1("bmq://my.domain/queue-first",
2300+
bmqtst::TestHelperUtil::allocator());
2301+
const bsl::string uri2("bmq://my.domain/queue-second",
2302+
bmqtst::TestHelperUtil::allocator());
2303+
const int queueId = 1;
2304+
2305+
TestBench tb(client(e_FirstHop),
2306+
false, // atMostOnce
2307+
bmqtst::TestHelperUtil::allocator());
2308+
2309+
// Open the first queue: expect a successful OpenQueueResponse.
2310+
tb.openQueue(uri1, queueId);
2311+
tb.d_cs.flush();
2312+
2313+
{
2314+
bmqio::TestChannel::WriteCall writeCall;
2315+
BMQTST_ASSERT(tb.d_channel->getWriteCall(&writeCall, 0));
2316+
2317+
bmqp::Event event(&writeCall.d_blob,
2318+
bmqtst::TestHelperUtil::allocator());
2319+
BMQTST_ASSERT(event.isControlEvent());
2320+
2321+
bmqp_ctrlmsg::ControlMessage response(
2322+
bmqtst::TestHelperUtil::allocator());
2323+
BMQTST_ASSERT_EQ(0, event.loadControlEvent(&response));
2324+
BMQTST_ASSERT(response.choice().isOpenQueueResponseValue());
2325+
}
2326+
2327+
// Open a *different* queue reusing the same queueId: expect a failure
2328+
// Status rather than a crash or a silent overwrite.
2329+
tb.openQueue(uri2, queueId);
2330+
tb.d_cs.flush();
2331+
2332+
{
2333+
bmqio::TestChannel::WriteCall writeCall;
2334+
BMQTST_ASSERT(tb.d_channel->getWriteCall(&writeCall, 1));
2335+
2336+
bmqp::Event event(&writeCall.d_blob,
2337+
bmqtst::TestHelperUtil::allocator());
2338+
BMQTST_ASSERT(event.isControlEvent());
2339+
2340+
bmqp_ctrlmsg::ControlMessage response(
2341+
bmqtst::TestHelperUtil::allocator());
2342+
BMQTST_ASSERT_EQ(0, event.loadControlEvent(&response));
2343+
BMQTST_ASSERT(response.choice().isStatusValue());
2344+
BMQTST_ASSERT_EQ(response.choice().status().category(),
2345+
bmqp_ctrlmsg::StatusCategory::E_INVALID_ARGUMENT);
2346+
}
2347+
}
2348+
22652349
static void testN1_ackConfiguration()
22662350
// ------------------------------------------------------------------------
22672351
// TESTS ACK CONFIGURATION FOR CLIENT SESSION
@@ -2512,6 +2596,7 @@ int main(int argc, char* argv[])
25122596

25132597
switch (_testCase) {
25142598
case 0:
2599+
case 12: test12_openQueueDuplicateQueueId(); break;
25152600
case 11: test11_initiateShutdown(); break;
25162601
case 10: test10_newStyleCompressedPush(); break;
25172602
case 9: test9_newStylePush(); break;

0 commit comments

Comments
 (0)