Skip to content

Commit 0693939

Browse files
committed
CCBC-1653: fix setting timeout for analytics query
Change-Id: Ida2523df2e27cb37aa601706bf8f7879aa556536 Reviewed-on: https://review.couchbase.org/c/libcouchbase/+/219160 Tested-by: Build Bot <build@couchbase.com> Reviewed-by: Dimitris Christodoulou <dimitris.christodoulou@couchbase.com>
1 parent 6be4bd2 commit 0693939

3 files changed

Lines changed: 102 additions & 3 deletions

File tree

src/analytics/analytics_handle.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,14 +189,14 @@ lcb_ANALYTICS_HANDLE_::lcb_ANALYTICS_HANDLE_(lcb_INSTANCE *obj, void *user_cooki
189189
}
190190
priority_ = cmd->priority();
191191

192+
timeout_ = cmd->timeout_or_default_in_microseconds(LCBT_SETTING(obj, analytics_timeout));
192193
Json::Value &tmoval = json["timeout"];
193194
if (tmoval.isNull()) {
194195
// Set the default timeout as the server-side query timeout if no
195196
// other timeout is used.
196197
char buf[64] = {0};
197-
snprintf(buf, sizeof(buf), "%uus", LCBT_SETTING(obj, analytics_timeout));
198-
tmoval = buf;
199-
timeout_ = LCBT_SETTING(obj, analytics_timeout);
198+
snprintf(buf, sizeof(buf), "%uus", timeout_);
199+
json["timeout"] = buf;
200200
} else if (tmoval.isString()) {
201201
try {
202202
auto tmo_ns = lcb_parse_golang_duration(tmoval.asString());

src/analytics/analytics_handle.hh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,11 @@ struct lcb_ANALYTICS_HANDLE_ : lcb::jsparse::Parser::Actions {
233233
return retries_;
234234
}
235235

236+
lcb_U32 timeout_us() const
237+
{
238+
return timeout_;
239+
}
240+
236241
private:
237242
const lcb_RESPHTTP *http_response_{nullptr};
238243
lcb_HTTP_HANDLE *http_request_{nullptr};

tests/basic/t_analytics.cc

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2+
/*
3+
* Copyright 2015-2024 Couchbase, Inc.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#include "config.h"
19+
#include <cstdint>
20+
#include <gtest/gtest.h>
21+
#include <libcouchbase/couchbase.h>
22+
23+
#include "../iotests/testutil.h"
24+
#include "analytics/analytics_handle.hh"
25+
26+
class AnalyticsQuery : public ::testing::Test
27+
{
28+
};
29+
30+
struct MockInstance {
31+
lcb_INSTANCE *instance{nullptr};
32+
33+
MockInstance()
34+
{
35+
lcb_assert(lcb_create(&instance, nullptr) == LCB_SUCCESS);
36+
}
37+
38+
~MockInstance()
39+
{
40+
lcb_destroy(instance);
41+
}
42+
};
43+
44+
TEST_F(AnalyticsQuery, testSettingTimeout)
45+
{
46+
MockInstance mock;
47+
48+
lcb_CMDANALYTICS *cmd = nullptr;
49+
ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_cmdanalytics_create(&cmd));
50+
51+
std::string statement = "SELECT 42 AS the_answer;";
52+
ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_cmdanalytics_statement(cmd, statement.c_str(), statement.size()));
53+
54+
uint32_t timeout_ms{25000123};
55+
ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_cmdanalytics_timeout(cmd, timeout_ms));
56+
57+
auto *req = new lcb_ANALYTICS_HANDLE_(mock.instance, cmd->cookie(), cmd);
58+
Json::Value json = req->json_const();
59+
json.removeMember("client_context_id");
60+
ASSERT_EQ(R"({"statement":"SELECT 42 AS the_answer;","timeout":"25000123us"})", Json::FastWriter().write(json));
61+
}
62+
63+
TEST_F(AnalyticsQuery, testDefaultTimeout)
64+
{
65+
MockInstance mock;
66+
67+
lcb_CMDANALYTICS *cmd = nullptr;
68+
ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_cmdanalytics_create(&cmd));
69+
70+
std::string statement = "SELECT 42 AS the_answer;";
71+
ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_cmdanalytics_statement(cmd, statement.c_str(), statement.size()));
72+
73+
auto *req = new lcb_ANALYTICS_HANDLE_(mock.instance, cmd->cookie(), cmd);
74+
Json::Value json = req->json_const();
75+
json.removeMember("client_context_id");
76+
ASSERT_EQ(R"({"statement":"SELECT 42 AS the_answer;","timeout":"75000000us"})", Json::FastWriter().write(json));
77+
}
78+
79+
TEST_F(AnalyticsQuery, testTimeoutThroughThePayload)
80+
{
81+
MockInstance mock;
82+
83+
lcb_CMDANALYTICS *cmd = nullptr;
84+
ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_cmdanalytics_create(&cmd));
85+
86+
std::string raw_payload{R"({"statement":"SELECT 42 AS the_answer;","timeout":"23s"})"};
87+
ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_cmdanalytics_payload(cmd, raw_payload.data(), raw_payload.size()));
88+
89+
auto *req = new lcb_ANALYTICS_HANDLE_(mock.instance, cmd->cookie(), cmd);
90+
Json::Value json = req->json_const();
91+
json.removeMember("client_context_id");
92+
ASSERT_EQ(R"({"statement":"SELECT 42 AS the_answer;","timeout":"23s"})", Json::FastWriter().write(json));
93+
ASSERT_EQ(23000000, req->timeout_us());
94+
}

0 commit comments

Comments
 (0)