dotnet-sdk/test/Dapr.Client.Test/InvokeBindingApiTest.cs

313 lines
13 KiB
C#

// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
namespace Dapr.Client.Test
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Dapr.Client.Autogen.Grpc.v1;
using Shouldly;
using Google.Protobuf;
using Grpc.Core;
using Moq;
using Xunit;
public class InvokeBindingApiTest
{
[Fact]
public async Task InvokeBindingAsync_ValidateRequest()
{
await using var client = TestClient.CreateForDaprClient();
var invokeRequest = new InvokeRequest() { RequestParameter = "Hello " };
var request = await client.CaptureGrpcRequestAsync(async daprClient =>
{
await daprClient.InvokeBindingAsync<InvokeRequest>("test", "create", invokeRequest);
});
request.Dismiss();
// Get Request and validate
var envelope = await request.GetRequestEnvelopeAsync<InvokeBindingRequest>();
envelope.Name.ShouldBe("test");
envelope.Metadata.Count.ShouldBe(0);
var json = envelope.Data.ToStringUtf8();
var typeFromRequest = JsonSerializer.Deserialize<InvokeRequest>(json, client.InnerClient.JsonSerializerOptions);
typeFromRequest.RequestParameter.ShouldBe("Hello ");
}
[Fact]
public async Task InvokeBindingAsync_ValidateRequest_WithMetadata()
{
await using var client = TestClient.CreateForDaprClient();
var metadata = new Dictionary<string, string>
{
{ "key1", "value1" },
{ "key2", "value2" }
};
var invokeRequest = new InvokeRequest() { RequestParameter = "Hello " };
var request = await client.CaptureGrpcRequestAsync(async daprClient =>
{
await daprClient.InvokeBindingAsync<InvokeRequest>("test", "create", invokeRequest, metadata);
});
request.Dismiss();
// Get Request and validate
var envelope = await request.GetRequestEnvelopeAsync<InvokeBindingRequest>();
envelope.Name.ShouldBe("test");
envelope.Metadata.Count.ShouldBe(2);
envelope.Metadata.Keys.Contains("key1").ShouldBeTrue();
envelope.Metadata.Keys.Contains("key2").ShouldBeTrue();
envelope.Metadata["key1"].ShouldBe("value1");
envelope.Metadata["key2"].ShouldBe("value2");
var json = envelope.Data.ToStringUtf8();
var typeFromRequest = JsonSerializer.Deserialize<InvokeRequest>(json, client.InnerClient.JsonSerializerOptions);
typeFromRequest.RequestParameter.ShouldBe("Hello ");
}
[Fact]
public async Task InvokeBindingAsync_WithNullPayload_ValidateRequest()
{
await using var client = TestClient.CreateForDaprClient();
var request = await client.CaptureGrpcRequestAsync(async daprClient =>
{
await daprClient.InvokeBindingAsync<InvokeRequest>("test", "create", null);
});
request.Dismiss();
// Get Request and validate
var envelope = await request.GetRequestEnvelopeAsync<InvokeBindingRequest>();
envelope.Name.ShouldBe("test");
envelope.Metadata.Count.ShouldBe(0);
var json = envelope.Data.ToStringUtf8();
Assert.Equal("null", json);
}
[Fact]
public async Task InvokeBindingAsync_WithRequest_ValidateRequest()
{
await using var client = TestClient.CreateForDaprClient();
var payload = new InvokeRequest() { RequestParameter = "Hello " };
var bindingRequest = new BindingRequest("test", "create")
{
Data = JsonSerializer.SerializeToUtf8Bytes(payload, client.InnerClient.JsonSerializerOptions),
Metadata =
{
{ "key1", "value1" },
{ "key2", "value2" }
}
};
var request = await client.CaptureGrpcRequestAsync(async daprClient =>
{
return await daprClient.InvokeBindingAsync(bindingRequest);
});
var gRpcResponse = new Autogen.Grpc.v1.InvokeBindingResponse()
{
Data = ByteString.CopyFrom(JsonSerializer.SerializeToUtf8Bytes(new Widget() { Color = "red", }, client.InnerClient.JsonSerializerOptions)),
Metadata =
{
{ "anotherkey", "anothervalue" },
}
};
var response = await request.CompleteWithMessageAsync(gRpcResponse);
var envelope = await request.GetRequestEnvelopeAsync<InvokeBindingRequest>();
envelope.Name.ShouldBe("test");
envelope.Metadata.Count.ShouldBe(2);
envelope.Metadata.Keys.Contains("key1").ShouldBeTrue();
envelope.Metadata.Keys.Contains("key2").ShouldBeTrue();
envelope.Metadata["key1"].ShouldBe("value1");
envelope.Metadata["key2"].ShouldBe("value2");
var json = envelope.Data.ToStringUtf8();
var typeFromRequest = JsonSerializer.Deserialize<InvokeRequest>(json, client.InnerClient.JsonSerializerOptions);
typeFromRequest.RequestParameter.ShouldBe("Hello ");
Assert.Same(bindingRequest, response.Request);
Assert.Equal("red", JsonSerializer.Deserialize<Widget>(response.Data.Span, client.InnerClient.JsonSerializerOptions).Color);
Assert.Collection(
response.Metadata,
kvp =>
{
Assert.Equal("anotherkey", kvp.Key);
Assert.Equal("anothervalue", kvp.Value);
});
}
[Fact]
public async Task InvokeBindingAsync_WithCancelledToken()
{
await using var client = TestClient.CreateForDaprClient();
var cts = new CancellationTokenSource();
cts.Cancel();
var metadata = new Dictionary<string, string>
{
{ "key1", "value1" },
{ "key2", "value2" }
};
var invokeRequest = new InvokeRequest() { RequestParameter = "Hello " };
await Assert.ThrowsAsync<OperationCanceledException>(async () =>
{
await client.InnerClient.InvokeBindingAsync<InvokeRequest>("test", "create", invokeRequest, metadata, cts.Token);
});
}
[Fact]
public async Task InvokeBindingAsync_WrapsRpcException()
{
var client = new MockClient();
var rpcStatus = new Status(StatusCode.Internal, "not gonna work");
var rpcException = new RpcException(rpcStatus, new Metadata(), "not gonna work");
client.Mock
.Setup(m => m.InvokeBindingAsync(It.IsAny<Autogen.Grpc.v1.InvokeBindingRequest>(), It.IsAny<CallOptions>()))
.Throws(rpcException);
var ex = await Assert.ThrowsAsync<DaprException>(async () =>
{
await client.DaprClient.InvokeBindingAsync("test", "test", new InvokeRequest() { RequestParameter = "Hello " });
});
Assert.Same(rpcException, ex.InnerException);
}
[Fact]
public async Task InvokeBindingAsync_WrapsJsonException()
{
await using var client = TestClient.CreateForDaprClient();
var response = new Autogen.Grpc.v1.InvokeBindingResponse();
var bytes = JsonSerializer.SerializeToUtf8Bytes<Widget>(new Widget(){ Color = "red", }, client.InnerClient.JsonSerializerOptions);
response.Data = ByteString.CopyFrom(bytes.Take(10).ToArray()); // trim it to make invalid JSON blob
var request = await client.CaptureGrpcRequestAsync(async daprClient =>
{
return await daprClient.InvokeBindingAsync<InvokeRequest, Widget>("test", "test", new InvokeRequest() { RequestParameter = "Hello " });
});
await request.GetRequestEnvelopeAsync<InvokeBindingRequest>();
var ex = await Assert.ThrowsAsync<DaprException>(async () =>
{
await request.CompleteWithMessageAsync(response);
});
Assert.IsType<JsonException>(ex.InnerException);
}
[Fact]
public async Task InvokeBindingRequest_WithCustomRequest_ValidateRequest()
{
await using var client = TestClient.CreateForDaprClient();
var data = new InvokeRequest { RequestParameter = "Test" };
var metadata = new Dictionary<string, string>
{
{ "key1", "value1" }
};
var req = await client.CaptureGrpcRequestAsync(async daprClient =>
{
return await daprClient.InvokeBindingAsync<InvokeRequest, Widget>("binding", "operation", data, metadata);
});
var resp = new InvokeBindingResponse
{
Data = ByteString.CopyFrom(JsonSerializer.SerializeToUtf8Bytes(new Widget() { Color = "red", }, client.InnerClient.JsonSerializerOptions))
};
var response = await req.CompleteWithMessageAsync(resp);
var envelope = await req.GetRequestEnvelopeAsync<InvokeBindingRequest>();
envelope.Name.ShouldBe("binding");
envelope.Operation.ShouldBe("operation");
envelope.Metadata.Count.ShouldBe(1);
envelope.Metadata.Keys.Contains("key1").ShouldBeTrue();
envelope.Metadata["key1"].ShouldBe("value1");
var json = envelope.Data.ToStringUtf8();
var typeFromRequest = JsonSerializer.Deserialize<InvokeRequest>(json, client.InnerClient.JsonSerializerOptions);
typeFromRequest.RequestParameter.ShouldBe("Test");
Assert.Equal("red", response.Color);
}
[Fact]
public async Task InvokeBindingRequest_WithNullData_ValidateRequest()
{
await using var client = TestClient.CreateForDaprClient();
var req = await client.CaptureGrpcRequestAsync(async daprClient =>
{
return await daprClient.InvokeBindingAsync<InvokeRequest, Widget>("binding", "operation", null);
});
var resp = new InvokeBindingResponse
{
Data = ByteString.CopyFrom(JsonSerializer.SerializeToUtf8Bytes(new Widget() { Color = "red", }, client.InnerClient.JsonSerializerOptions))
};
var response = await req.CompleteWithMessageAsync(resp);
var envelope = await req.GetRequestEnvelopeAsync<InvokeBindingRequest>();
envelope.Name.ShouldBe("binding");
envelope.Operation.ShouldBe("operation");
Assert.Equal("red", response.Color);
}
[Fact]
public async Task InvokeBindingRequest_WithBindingNull_CheckException()
{
await using var client = TestClient.CreateForDaprClient();
var ex = await Assert.ThrowsAsync<ArgumentNullException>(async () =>
{
await client.InnerClient.InvokeBindingAsync<InvokeRequest, Widget>(null, "operation", null);
});
Assert.IsType<ArgumentNullException>(ex);
}
[Fact]
public async Task InvokeBindingRequest_WithOperationNull_CheckException()
{
await using var client = TestClient.CreateForDaprClient();
var ex = await Assert.ThrowsAsync<ArgumentNullException>(async () =>
{
await client.InnerClient.InvokeBindingAsync<InvokeRequest, Widget>("binding", null, null);
});
Assert.IsType<ArgumentNullException>(ex);
}
private class InvokeRequest
{
public string RequestParameter { get; set; }
}
private class Widget
{
public string Color { get; set; }
}
}
}