mirror of https://github.com/dapr/dotnet-sdk.git
313 lines
13 KiB
C#
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; }
|
|
}
|
|
}
|
|
}
|