Closed dadz01-betsson closed 8 months ago
Well, the bucket does not exist, nor do you create it. Use the default generated bucket:
_couchbaseContainer.Buckets.Single().Name
Or create one:
var bucketSettings = new BucketSettings();
bucketSettings.Name = TestBucketName;
bucketSettings.FlushEnabled = false;
bucketSettings.ReplicaIndexes = true;
bucketSettings.RamQuotaMB = 100;
bucketSettings.NumReplicas = 0;
await cluster.Buckets.CreateBucketAsync(bucketSettings)
.ConfigureAwait(false);
Well, the bucket does not exist, nor do you create it. Use the default generated bucket:
_couchbaseContainer.Buckets.Single().Name
Or create one:
var bucketSettings = new BucketSettings(); bucketSettings.Name = TestBucketName; bucketSettings.FlushEnabled = false; bucketSettings.ReplicaIndexes = true; bucketSettings.RamQuotaMB = 100; bucketSettings.NumReplicas = 0; await cluster.Buckets.CreateBucketAsync(bucketSettings) .ConfigureAwait(false);
@HofmeisterAn Thanks, however await cluster.BucketAsync(TestBucketName);
Implementation suggest that it will create bucket if it does not exists.
If I create new one as you suggested and want get default collection (to be able to query/add things ) from created bucket with following code:
var bucket = await cluster.BucketAsync(TestBucketName);
var collection = await bucket.DefaultCollectionAsync();
I still getting the same error.
The following lines work fine. You need to wait until the bucket is created. It is not available immediately. I am not a Couchbase expert, but I do not think these issues are related to the module implementation.
await cluster.Buckets.CreateBucketAsync(bucketSettings)
.ConfigureAwait(false);
await Task.Delay(TimeSpan.FromSeconds(5))
.ConfigureAwait(false);
var bucket = await cluster.BucketAsync(bucketName)
.ConfigureAwait(false);
var collection = await bucket.DefaultCollectionAsync()
.ConfigureAwait(false);
The following lines work fine. You need to wait until the bucket is created. It is not available immediately. I am not a Couchbase expert, but I do not think these issues are related to the module implementation.
await cluster.Buckets.CreateBucketAsync(bucketSettings) .ConfigureAwait(false); await Task.Delay(TimeSpan.FromSeconds(5)) .ConfigureAwait(false); var bucket = await cluster.BucketAsync(bucketName) .ConfigureAwait(false); var collection = await bucket.DefaultCollectionAsync() .ConfigureAwait(false);
Is this really working for you ? This sample is giving me still the same error:
using Couchbase;
using Couchbase.Management.Buckets;
using Testcontainers.Couchbase;
string TestBucketName = "Test";
CouchbaseContainer CouchbaseContainer
= new CouchbaseBuilder()
.WithPortBinding(8091, 8091)
.Build();
try
{
await CouchbaseContainer.StartAsync();
var options = new ClusterOptions
{
UserName = CouchbaseBuilder.DefaultUsername,
Password = CouchbaseBuilder.DefaultPassword,
};
var connectionString = CouchbaseContainer.GetConnectionString();
var cluster = await Cluster.ConnectAsync(connectionString, options);
var bucketSettings = new BucketSettings
{
Name = TestBucketName,
FlushEnabled = false,
ReplicaIndexes = true,
RamQuotaMB = 100,
NumReplicas = 0
};
await cluster.Buckets.CreateBucketAsync(bucketSettings)
.ConfigureAwait(false);
await Task.Delay(TimeSpan.FromSeconds(5))
.ConfigureAwait(false);
var bucket = await cluster.BucketAsync(TestBucketName)
.ConfigureAwait(false);
var collection = await bucket.DefaultCollectionAsync()
.ConfigureAwait(false);
}
catch (Exception e)
{
await CouchbaseContainer.DisposeAsync();
Console.WriteLine(e.ToString());
}```
![Error](https://github.com/testcontainers/testcontainers-dotnet/assets/136716460/78218de9-405d-4f39-8092-fe9842595592)
Ah, I see. Remove the .WithPortBinding(8091, 8091)
line for now. It appears that this line is overriding the enabled services (_enabledServices
is empty with your configuration). I can fix it later.
Thank you for suggestion but still I having the same behaviour.
using Couchbase;
using Couchbase.Management.Buckets;
using Testcontainers.Couchbase;
string TestBucketName = "Test";
CouchbaseContainer CouchbaseContainer
= new CouchbaseBuilder()
.Build();
try
{
await CouchbaseContainer.StartAsync();
var options = new ClusterOptions
{
UserName = CouchbaseBuilder.DefaultUsername,
Password = CouchbaseBuilder.DefaultPassword,
};
var connectionString = CouchbaseContainer.GetConnectionString();
var cluster = await Cluster.ConnectAsync(connectionString, options);
var bucketSettings = new BucketSettings
{
Name = TestBucketName,
FlushEnabled = false,
ReplicaIndexes = true,
RamQuotaMB = 100,
NumReplicas = 0
};
await cluster.Buckets.CreateBucketAsync(bucketSettings)
.ConfigureAwait(false);
await Task.Delay(TimeSpan.FromSeconds(5))
.ConfigureAwait(false);
var bucket = await cluster.BucketAsync(TestBucketName)
.ConfigureAwait(false);
var collection = await bucket.DefaultCollectionAsync()
.ConfigureAwait(false);
}
catch (Exception e)
{
await CouchbaseContainer.DisposeAsync();
Console.WriteLine(e.ToString());
}
Can you please share the full stack trace? Without overriding the default configurations, it looks good.
Message:
ChannelConnectionPool
Stacktrace:
at Couchbase.Core.ClusterContext.GetOrCreateBucketLockedAsync(String name) at Program.
$(String[] args) in ~\repos\ConsoleApp4\ConsoleApp4\Program.cs:line 41
After digging a bit I think this is comming from here: https://github.com/couchbase/couchbase-net-client/blob/master/src/Couchbase/Core/IO/Connections/Channels/ChannelConnectionPool.cs#L197
Have you checked the web front-end to see if the bucket exists after some time? It is possible that it is still being created, and it may just require some additional time. Internally, we use the following lines to detect when the default bucket is finally created:
I checked the UI (but this requires to expose port 8091) and its there.
Ive added infinite loop which will check is bucket exists and breaks when its created but result is exactly the same as before:
using Couchbase;
using Couchbase.Management.Buckets;
using Testcontainers.Couchbase;
string TestBucketName = "Test";
CouchbaseContainer CouchbaseContainer
= new CouchbaseBuilder()
// .WithPortBinding(8091, 8091)
.Build();
try
{
await CouchbaseContainer.StartAsync();
var options = new ClusterOptions
{
UserName = CouchbaseBuilder.DefaultUsername,
Password = CouchbaseBuilder.DefaultPassword,
};
var connectionString = CouchbaseContainer.GetConnectionString();
var cluster = await Cluster.ConnectAsync(connectionString, options);
var bucketSettings = new BucketSettings
{
Name = TestBucketName,
FlushEnabled = false,
ReplicaIndexes = true,
RamQuotaMB = 100,
NumReplicas = 0
};
await cluster.Buckets.CreateBucketAsync(bucketSettings)
.ConfigureAwait(false);
while (true)
{
var buckets= await cluster.Buckets.GetAllBucketsAsync();
if (buckets.ContainsKey(TestBucketName))
{
break;
}
await Task.Delay(TimeSpan.FromSeconds(5));
}
var bucket = await cluster.BucketAsync(TestBucketName)
.ConfigureAwait(false);
var collection = await bucket.DefaultCollectionAsync()
.ConfigureAwait(false);
}
catch (Exception e)
{
await CouchbaseContainer.DisposeAsync();
Console.WriteLine(e.ToString());
}
but this requires to expose port 8091
Actually, it does not. You can obtain the randomly assigned host port from the inspect results, and the log messages contain a link to the web front-end as well.
Ive added infinite loop which will check is bucket exists and breaks when its created but result is exactly the same as before:
This confirms my supposition. Just because the bucket exists does not mean it is ready to use. If I create a bucket and immediately check the "/pools/default/buckets/" + bucketName
API, I get a response similar to:
{
"name": "Test",
"nodes": []
}
However, when I wait a couple of seconds, I get:
{
"name": "Test",
"nodes": [
{
"status": "healthy",
"services": [
"fts",
"index",
"kv",
"n1ql"
]
}
]
}
Despite the issue I mentioned regarding overriding the default configuration, I do not see any other issues. I am sorry. I do not know how I can help you further.
Thanks @HofmeisterAn. But even when I run this code on default bucket (which is I assume created already, because there is wait strategy) I am getting same error.
using Couchbase;
using Couchbase.Management.Buckets;
using Testcontainers.Couchbase;
CouchbaseContainer CouchbaseContainer
= new CouchbaseBuilder()
.Build();
try
{
await CouchbaseContainer.StartAsync();
var options = new ClusterOptions
{
UserName = CouchbaseBuilder.DefaultUsername,
Password = CouchbaseBuilder.DefaultPassword,
};
var connectionString = CouchbaseContainer.GetConnectionString();
var cluster = await Cluster.ConnectAsync(connectionString, options);
var defaultBucket = (await cluster.Buckets.GetAllBucketsAsync()).Single();
var bucket = await cluster.BucketAsync(defaultBucket.Key)
.ConfigureAwait(false);
var collection = await bucket.DefaultCollectionAsync()
.ConfigureAwait(false);
}
catch (Exception e)
{
await CouchbaseContainer.DisposeAsync();
Console.WriteLine(e.ToString());
}
As mentioned in SO#77396534, this appears to be a bug in the client. I encountered the same error with the latest client version. Downgrading the client to 3.4.3
resolved the issue. I recommend that you create an upstream issue in the Couchbase .NET client repository and share the test case reproducer leveraging Testcontainers.
I will do that, thanks a lot for your help @HofmeisterAn.
I will close this issue for now. If there is anything to do or to fix on the side of TC for .NET, do not hesitate to reopen the issue again or create a new one. Unfortunately, Couchbase's upstream repository does not allow creating issues. This is the related ticket, I think: NCBC-3545.
Testcontainers version
3.5.0
Using the latest Testcontainers version?
Yes
Host OS
Windows
Host arch
x64
.NET version
6.0.14
Docker version
Docker info
What happened?
I want to create bucket and use couchbase SDK together with Testcontainers. When writing basic code for setting up the container and create bucket I getting not very detailed exception.
Code to repro: Csproj:
Program.cs
Relevant log output
No response
Additional information
I tried to create bucket from the UI and it worked.