Skip to content

Commit 27818de

Browse files
committed
NCBC-4207: Speed up Stellar unit tests with fast-fail timeouts
Motivation ========== Couchbase.UnitTests wall-clock had grown to ~98s, dominated by Stellar tests that point at an unreachable host ("couchbase2://xxx") and rely on default per-service timeouts to fail. A single QueryAsync test alone took 75s (default QueryTimeout), and the Test_Schema theory took 6-12s per case waiting on DNS SRV resolution during classic bootstrap. Modification ============ - Added FastFailClusterOptions.WithFastFailTimeouts(FastFailServices), a fluent extension on ClusterOptions that applies a short KvConnectTimeout plus only the per-service timeouts the caller exercises, with an optional DisableDnsSrv flag. - Wired it into ClusterTests (Query|Analytics for CreateCluster; DisableDnsSrv for Test_Schema_Delivers_The_Correct_ICluster_Impl) and CollectionTests (Kv for CreateCollection). Result ====== Unit test wall-clock drops from ~98s to ~9s on net8.0. Tests still exercise the same failure paths. Change-Id: I2a934064338348c59c684b3a2a8756c74fbabbde Reviewed-on: https://review.couchbase.org/c/couchbase-net-client/+/245844 Tested-by: Build Bot <build@couchbase.com> Reviewed-by: Jeffry Morris <jeffrymorris@gmail.com>
1 parent f5104af commit 27818de

3 files changed

Lines changed: 51 additions & 3 deletions

File tree

tests/Couchbase.UnitTests/Stellar/ClusterTests.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
using Couchbase.Stellar.Core;
1818
using Couchbase.Stellar.Search;
1919
using Couchbase.Stellar.Util;
20+
using Couchbase.UnitTests.Utils;
2021
using Grpc.Core;
2122
using Grpc.Net.Client;
2223
using Moq;
@@ -109,7 +110,9 @@ public async Task Test_Schema_Delivers_The_Correct_ICluster_Impl(string connecti
109110
#pragma warning disable CS0618 // Type or member is obsolete
110111
var options = new ClusterOptions().WithCredentials("Administrator", "password");
111112
#pragma warning restore CS0618 // Type or member is obsolete
112-
options.KvConnectTimeout = TimeSpan.FromMilliseconds(1);
113+
// Classic schemes do DNS SRV lookup during bootstrap which adds several seconds
114+
// before bootstrap gives up against the unreachable "xxx" host.
115+
options.WithFastFailTimeouts(FastFailServices.DisableDnsSrv);
113116
var cluster = await Cluster.ConnectAsync(connectionString,options);
114117

115118
Assert.IsType(type, cluster);
@@ -121,7 +124,9 @@ public async Task<ICluster> CreateCluster()
121124

122125
#pragma warning disable CS0618 // Type or member is obsolete
123126
var options = new ClusterOptions().WithCredentials("Administrator", "password");
124-
options.KvConnectTimeout = TimeSpan.FromMilliseconds(1);
127+
// Tests using this helper exercise Query/Analytics; shorten those so the failing op
128+
// surfaces a CouchbaseException quickly instead of waiting the default 75s.
129+
options.WithFastFailTimeouts(FastFailServices.Query | FastFailServices.Analytics);
125130
options.HttpIgnoreRemoteCertificateMismatch = true;
126131
options.KvIgnoreRemoteCertificateNameMismatch = true;
127132
#pragma warning restore CS0618 // Type or member is obsolete

tests/Couchbase.UnitTests/Stellar/KeyValue/CollectionTests.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using Couchbase.KeyValue.RangeScan;
99
using Couchbase.Stellar;
1010
using Couchbase.Stellar.Util;
11+
using Couchbase.UnitTests.Utils;
1112
using Xunit;
1213

1314
namespace Couchbase.UnitTests.Stellar.KeyValue;
@@ -154,7 +155,9 @@ private async Task<ICouchbaseCollection> CreateCollection()
154155
#pragma warning disable CS0618 // Type or member is obsolete
155156
var options = new ClusterOptions().WithCredentials("Administrator", "password");
156157
#pragma warning restore CS0618 // Type or member is obsolete
157-
options.KvConnectTimeout = TimeSpan.FromMilliseconds(1);
158+
// All tests using this helper drive KV ops against an unreachable host; without a short
159+
// KvTimeout each failing op would block on the default 2.5s.
160+
options.WithFastFailTimeouts(FastFailServices.Kv);
158161

159162
var cluster = await Cluster.ConnectAsync(connectionString, options);
160163
var bucket = await cluster.BucketAsync("default");
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using System;
2+
3+
namespace Couchbase.UnitTests.Utils;
4+
5+
[Flags]
6+
internal enum FastFailServices
7+
{
8+
None = 0,
9+
Kv = 1 << 0,
10+
Query = 1 << 1,
11+
Analytics = 1 << 2,
12+
Search = 1 << 3,
13+
View = 1 << 4,
14+
Management = 1 << 5,
15+
DisableDnsSrv = 1 << 6,
16+
}
17+
18+
internal static class FastFailClusterOptions
19+
{
20+
private static readonly TimeSpan FastFail = TimeSpan.FromMilliseconds(100);
21+
22+
// Unit tests that deliberately point at an unreachable host need short timeouts so the
23+
// failing op surfaces a CouchbaseException quickly instead of waiting the default
24+
// per-service timeout (75s for Query/Analytics/Search/View/Management, 2.5s for KV).
25+
// Classic-scheme bootstrap additionally does DNS SRV resolution that adds several
26+
// seconds. This extension applies only the knobs the caller actually exercises so each
27+
// test surface is explicit.
28+
public static ClusterOptions WithFastFailTimeouts(this ClusterOptions options, FastFailServices services)
29+
{
30+
options.KvConnectTimeout = TimeSpan.FromMilliseconds(1);
31+
if ((services & FastFailServices.DisableDnsSrv) != 0) options.EnableDnsSrvResolution = false;
32+
if ((services & FastFailServices.Kv) != 0) options.KvTimeout = FastFail;
33+
if ((services & FastFailServices.Query) != 0) options.QueryTimeout = FastFail;
34+
if ((services & FastFailServices.Analytics) != 0) options.AnalyticsTimeout = FastFail;
35+
if ((services & FastFailServices.Search) != 0) options.SearchTimeout = FastFail;
36+
if ((services & FastFailServices.View) != 0) options.ViewTimeout = FastFail;
37+
if ((services & FastFailServices.Management) != 0) options.ManagementTimeout = FastFail;
38+
return options;
39+
}
40+
}

0 commit comments

Comments
 (0)