From 542efe69ec50cee9a47b9cdf2d49cb1f3b10090f Mon Sep 17 00:00:00 2001 From: Dennis Oberst Date: Mon, 7 Jul 2025 18:32:31 +0200 Subject: [PATCH] QtGrpcClientUnaryCallTest: improve test logic for metadata() Extend the testcase to cover both, initial and trailing metadata. This also shows the current problems with having a QHash metadata and also the missing separation between initial and trailing metadata. Pick-to: 6.10 6.9 6.8 Change-Id: I880846ae06e8db338cdb3629dafdff430cab3edb Reviewed-by: Alexey Edelev --- .../shared/test_server/testserverrunner.cpp | 51 ++++++++++++++----- .../unarycall/tst_grpc_client_unarycall.cpp | 50 +++++++++--------- 2 files changed, 62 insertions(+), 39 deletions(-) diff --git a/tests/auto/grpc/client/shared/test_server/testserverrunner.cpp b/tests/auto/grpc/client/shared/test_server/testserverrunner.cpp index 37735179..8157e7e6 100644 --- a/tests/auto/grpc/client/shared/test_server/testserverrunner.cpp +++ b/tests/auto/grpc/client/shared/test_server/testserverrunner.cpp @@ -13,6 +13,7 @@ #include #include +#include namespace { @@ -226,21 +227,45 @@ Status TestServiceServiceImpl::testMethodNonCompatibleArgRet(grpc::ServerContext Status TestServiceServiceImpl::testMetadata(grpc::ServerContext *ctx, const Empty *, qtgrpc::tests::Empty *) { - std::string client_return_header; - for (const auto &header : ctx->client_metadata()) { - if (header.first == "client_header") { - ctx->AddTrailingMetadata("server_header", - std::string(header.second.data(), header.second.size())); - } else if (header.first == "client_return_header") { - if (client_return_header.empty()) - client_return_header = std::string(header.second.data(), header.second.size()); - else - client_return_header = "invalid_value"; - } + const auto &md = ctx->client_metadata(); + auto initial = md.find("request_initial"); + uint initialCount = 0; + if (initial != md.end()) { + std::string v (initial->second.begin(), initial->second.end()); + auto result = std::from_chars(v.data(), v.data() + v.size(), initialCount); + if (result.ec != std::errc()) + return { grpc::StatusCode::ABORTED, "conversion failed initial" }; } - ctx->AddTrailingMetadata("client_return_header", client_return_header); - return Status(); + auto trailing = md.find("request_trailing"); + uint trailingCount = 0; + if (trailing != md.end()) { + std::string v (trailing->second.begin(), trailing->second.end()); + auto result = std::from_chars(v.data(), v.data() + v.size(), trailingCount); + if (result.ec != std::errc()) + return { grpc::StatusCode::ABORTED, "conversion failed trailing" }; + } + + auto sum = md.equal_range("request_sum"); + uint sumCount = 0; + while (sum.first != sum.second) { + uint temp = 0; + std::string v (sum.first->second.begin(), sum.first->second.end()); + auto result = std::from_chars(v.data(), v.data() + v.size(), temp); + if (result.ec != std::errc()) + return { grpc::StatusCode::ABORTED, "conversion failed sum" }; + sumCount += temp; + ++sum.first; + } + + for (auto i = 0u; i < initialCount; ++i) + ctx->AddInitialMetadata("response_initial", std::to_string(i)); + for (auto i = 0u; i < trailingCount; ++i) + ctx->AddTrailingMetadata("response_trailing", std::to_string(i)); + if (sumCount > 0) + ctx->AddTrailingMetadata("response_sum", std::to_string(sumCount)); + + return Status::OK; } grpc::Status TestServiceServiceImpl::testMethodClientStream( diff --git a/tests/auto/grpc/client/unarycall/tst_grpc_client_unarycall.cpp b/tests/auto/grpc/client/unarycall/tst_grpc_client_unarycall.cpp index b4ce7a79..9cbe869b 100644 --- a/tests/auto/grpc/client/unarycall/tst_grpc_client_unarycall.cpp +++ b/tests/auto/grpc/client/unarycall/tst_grpc_client_unarycall.cpp @@ -142,37 +142,35 @@ void QtGrpcClientUnaryCallTest::asyncStatusMessage() void QtGrpcClientUnaryCallTest::metadata() { QGrpcCallOptions opt; - opt.setMetadata({ - { "client_header", "1" }, - { "client_return_header", "valid_value" } - }); + QHash clientMd{ + { "request_initial", "3" }, + { "request_trailing", "2" }, + { "request_sum", "20" }, + { "request_sum", "10" } + }; + QT_IGNORE_DEPRECATIONS(opt.setMetadata(clientMd);) auto reply = client()->testMetadata({}, opt); + QSignalSpy replyFinishedSpy(reply.get(), &QGrpcCallReply::finished); + QVERIFY(replyFinishedSpy.isValid()); - QHash metadata; - QEventLoop waiter; + QTRY_COMPARE_EQ_WITH_TIMEOUT(replyFinishedSpy.count(), 1, FailTimeout); + const auto &args = replyFinishedSpy.first(); + QCOMPARE_EQ(args.count(), 1); + QVERIFY(args.first().value().isOk()); - connect( - reply.get(), &QGrpcOperation::finished, this, - [&reply, &metadata, &waiter](const QGrpcStatus &) { - metadata = reply->metadata(); - waiter.quit(); - }, - Qt::SingleShotConnection); + const auto &md = reply->metadata(); + auto initialIt = md.equal_range("response_initial"); + QCOMPARE_EQ(std::distance(initialIt.first, initialIt.second), 1); + QCOMPARE_EQ(initialIt.first.value(), "2"); - waiter.exec(); + auto trailingIt = md.equal_range("response_trailing"); + QCOMPARE_EQ(std::distance(trailingIt.first, trailingIt.second), 1); + QCOMPARE_EQ(trailingIt.first.value(), "1"); - int serverHeaderCount = 0; - QByteArray clientReturnHeader; - for (const auto &[key, value] : reply->metadata().asKeyValueRange()) { - if (key == "server_header") { - QCOMPARE_EQ(QString::fromLatin1(value), QString::number(++serverHeaderCount)); - } else if (key == "client_return_header") { - clientReturnHeader = value; - } - } - - QCOMPARE_EQ(serverHeaderCount, 1); - QCOMPARE_EQ(clientReturnHeader, "valid_value"_ba); + auto sumIt = md.equal_range("response_sum"); + QCOMPARE_EQ(std::distance(sumIt.first, sumIt.second), 1); + auto sum = sumIt.first.value(); + QVERIFY(sum == "20"_ba || sum == "10"_ba); } QTEST_MAIN(QtGrpcClientUnaryCallTest)