public void Watch_ShouldRetryOnTimeoutException() { using (var http = new HttpTest()) { http.SimulateTimeout() .SimulateTimeout() .SimulateTimeout() .RespondWithJson(Fixtures.Watch.DefaultResponse); Etcd.ClientFor(Fixtures.EtcdUrl.ToUri()) .Watch(Fixtures.Watch.Path) .SubscribeFor(1) .Wait(); http.Should() .HaveCalled( Fixtures.EtcdUrl .AppendPathSegment(Constants.Etcd.Path_Keys) .AppendPathSegment(Fixtures.Watch.Path) .SetQueryParam(Constants.Etcd.Parameter_Wait, Constants.Etcd.Parameter_True) ) .WithVerb(HttpMethod.Get) .Times(4); } }
public async Task ShouldCallTheCorrectUrlByAwaitingImmediately() { using (var http = new HttpTest()) { http.RespondWithJson(Fixtures.Cluster.ClusterMemberResponse(new[] {Fixtures.EtcdUrl.ToUri()}, new[] {Fixtures.EtcdUrl.ToUri()})); var leader = await Etcd.ClientFor(Fixtures.EtcdUrl.ToUri()) .Cluster .GetLeader(); http.Should() .HaveCalled( Fixtures.EtcdUrl .AppendPathSegment(Constants.Etcd.Path_Members_Leader) ) .WithVerb(HttpMethod.Get) .Times(1); leader.Should().NotBeNull(); leader.PeerUrls.Should() .NotBeEmpty() .And .ContainSingle(x => Fixtures.EtcdUrl.ToUri().Equals(x)); leader.ClientUrls.Should() .NotBeEmpty() .And .ContainSingle(x => Fixtures.EtcdUrl.ToUri().Equals(x)); } }
public async Task ShouldCallTheCorrectUrlByAwaitingImmediately() { using (var http = new HttpTest()) { http.RespondWith(Fixtures.Statistics.SelfResponse); var response = await Etcd.ClientFor(Fixtures.EtcdUrl.ToUri()) .Statistics .GetServerStatistics(); http.Should() .HaveCalled(Fixtures.EtcdUrl.AppendPathSegment(Constants.Etcd.Path_Stats_Self)) .WithVerb(HttpMethod.Get) .Times(1); response.Should().NotBeNull(); response.Id.Should().NotBeNullOrWhiteSpace(); response.Name.Should().NotBeNullOrWhiteSpace(); response.LeaderInfo.Should().NotBeNull(); response.LeaderInfo.Leader.Should().Be("8a69d5f6b7814500"); response.LeaderInfo.StartTime.Should().HaveValue().And.NotBe(default(DateTime)); response.LeaderInfo.Uptime.Should().NotBeNullOrWhiteSpace(); response.State.Should().Be(StateType.StateFollower); } }
public async Task ShouldCallTheCorrectUrlByAwaitingImmediately() { using (var http = new HttpTest()) { http.RespondWithJson(Fixtures.Cluster.CreateResponse(Fixtures.EtcdUrl.ToUri())); var member = await Etcd.ClientFor(Fixtures.EtcdUrl.ToUri()) .Cluster .CreateMember() .WithPeerUri(Fixtures.EtcdUrl.ToUri()); http.Should() .HaveCalled( Fixtures.EtcdUrl .AppendPathSegment(Constants.Etcd.Path_Members) ) .WithVerb(HttpMethod.Post) .WithContentType(Constants.Http.ContentType_ApplicationJson) .Times(1); member.Should().NotBeNull(); member.PeerUrls.Should() .NotBeEmpty() .And .ContainSingle(x => Fixtures.EtcdUrl.ToUri().Equals(x)); } }
public async Task ExpectedIndex_ShouldCallTheCorrectUrlWithTtlOption() { using (var http = new HttpTest()) { http.RespondWithJson(Fixtures.CompareAndSwap.DefaultResponse) .RespondWithJson(Fixtures.CompareAndSwap.DefaultResponse); var req = Etcd.ClientFor(Fixtures.EtcdUrl.ToUri()) .Atomic.CompareAndSwap(Fixtures.CompareAndSwap.Path) .WithExpectedIndex(Fixtures.CompareAndSwap.ExpectedIndex) .WithNewValue(Fixtures.CompareAndSwap.NewValue) .WithTimeToLive(Fixtures.CompareAndSwap.DefaultTtl); await req; await req.Execute(); http.Should() .HaveCalled( Fixtures.EtcdUrl .AppendPathSegments(Constants.Etcd.Path_Keys, Fixtures.CompareAndSwap.Path) .SetQueryParam(Constants.Etcd.Parameter_PrevIndex, Fixtures.CompareAndSwap.ExpectedIndex) ) .WithVerb(HttpMethod.Put) .WithRequestBody(Fixtures.CompareAndSwap.TtlRequest()) .Times(2); } }
public async Task ShouldCallTheCorrectUrlByAwaitingImmediately() { using (var http = new HttpTest()) { http.RespondWith(Fixtures.Statistics.StoreResponse); var response = await Etcd.ClientFor(Fixtures.EtcdUrl.ToUri()) .Statistics .GetStoreStatistics(); http.Should() .HaveCalled(Fixtures.EtcdUrl.AppendPathSegment(Constants.Etcd.Path_Stats_Store)) .WithVerb(HttpMethod.Get) .Times(1); response.Should().NotBeNull(); response.CreateSuccess.Should().Be(2); response.GetsFail.Should().Be(4); response.GetsSuccess.Should().Be(75); response.SetsFail.Should().Be(2); response.SetsSuccess.Should().Be(4); response.CompareAndDeleteFail.Should().Be(0); response.CompareAndDeleteSuccess.Should().Be(0); response.CompareAndSwapFail.Should().Be(0); response.CompareAndSwapSuccess.Should().Be(0); response.DeleteSuccess.Should().Be(0); response.DeleteFail.Should().Be(0); response.ExpireCount.Should().Be(0); response.Watchers.Should().Be(0); } }
public async Task ShouldCallTheCorrectUrlByAwaitingImmediately() { using (var http = new HttpTest()) { http.RespondWith(Fixtures.Statistics.LeaderResponse); var response = await Etcd.ClientFor(Fixtures.EtcdUrl.ToUri()) .Statistics .GetLeaderStatistics(); http.Should() .HaveCalled(Fixtures.EtcdUrl.AppendPathSegment(Constants.Etcd.Path_Stats_Leader)) .WithVerb(HttpMethod.Get) .Times(1); response.Should().NotBeNull(); response.Leader.Should().NotBeNullOrWhiteSpace(); response.Followers.Should().NotBeNull() .And.HaveCount(2); response.Followers.Keys.OrderBy(x => x).Should() .HaveCount(2) .And.ContainInOrder("6e3bd23ae5f1eae0", "a8266ecf031671f3"); } }
public async Task ShouldCallTheCorrectUrlByAwaitingImmediately() { using (var http = new HttpTest()) { http.RespondWithJson( Fixtures.Cluster.ClusterMembersResponse( Fixtures.Cluster.ClusterMemberResponse(), Fixtures.Cluster.ClusterMemberResponse(), Fixtures.Cluster.ClusterMemberResponse(), Fixtures.Cluster.ClusterMemberResponse(), Fixtures.Cluster.ClusterMemberResponse() )); var members = await Etcd.ClientFor(Fixtures.EtcdUrl.ToUri()) .Cluster .GetMembers(); http.Should() .HaveCalled( Fixtures.EtcdUrl .AppendPathSegment(Constants.Etcd.Path_Members) ) .WithVerb(HttpMethod.Get) .Times(1); members.Should().NotBeNull() .And .HaveCount(5); } }
public async Task Get_ShouldCallTheCorrectUrlByAwaitingImmediately() { using (var http = new HttpTest()) { http.RespondWithJson(Fixtures.Key.DefaultResponse); await Etcd.ClientFor(Fixtures.EtcdUrl.ToUri()) .GetKey(Fixtures.Key.Path); http.Should() .HaveCalled( Fixtures.EtcdUrl .AppendPathSegments(Constants.Etcd.Path_Keys, Fixtures.Key.Path) ) .WithVerb(HttpMethod.Get) .Times(1); } }
public async Task ShouldCallTheCorrectUrlByAwaitingImmediately() { using (var http = new HttpTest()) { http.RespondWithJson( Fixtures.Cluster.ClusterMemberResponse( peerUris : new[] { Fixtures.EtcdUrl.ToUri(), Fixtures.EtcdUrl.ToUri() })); var memberId = StaticRandom.Instance.Next().ToString(); var member = await Etcd.ClientFor(Fixtures.EtcdUrl.ToUri()) .Cluster .UpdateMemberPeerUrls() .WithMemberId(memberId) .WithPeerUri(Fixtures.EtcdUrl.ToUri(), Fixtures.EtcdUrl.ToUri()); http.Should() .HaveCalled( Fixtures.EtcdUrl .AppendPathSegment(Constants.Etcd.Path_Members) .AppendPathSegment(memberId) ) .WithVerb(HttpMethod.Put) .WithContentType(Constants.Http.ContentType_ApplicationJson) .Times(1); member.Should().NotBeNull(); member.PeerUrls .Should() .HaveCount(2) .And .ContainInOrder( Fixtures.EtcdUrl.ToUri(), Fixtures.EtcdUrl.ToUri() ); } }
public async Task ShouldCallTheCorrectUrlByAwaitingImmediately() { using (var http = new HttpTest()) { http.RespondWithJson(Fixtures.Queue.DefaultResponse); await Etcd.ClientFor(Fixtures.EtcdUrl.ToUri()) .Atomic .Enqueue(Fixtures.Queue.Path) .WithValue(Fixtures.Queue.DefaultValue); http.Should() .HaveCalled( Fixtures.EtcdUrl .AppendPathSegments(Constants.Etcd.Path_Keys, Fixtures.Queue.Path) ) .WithVerb(HttpMethod.Post) .WithRequestBody(Fixtures.Queue.DefaultRequest()) .Times(1); } }
public async Task Get_ShouldUseConfiguredValueConverter() { var dto = Fixtures.Dto.SimpleDataContract(); var converter = new XmlValueConverter(); var expected = converter.Write(dto); using (var http = new HttpTest()) { http.RespondWithJson(Fixtures.Key.UpsertResponse(Fixtures.Key.Path, expected)); var client = Etcd.ClientFor(Fixtures.EtcdUrl.ToUri()); client.Configure(x => x.ValueConverter = converter); var response = await client .GetKey(Fixtures.Key.Path); http.Should() .HaveCalled( Fixtures.EtcdUrl .AppendPathSegments(Constants.Etcd.Path_Keys, Fixtures.Key.Path) ) .WithVerb(HttpMethod.Get) .Times(1); response.Should().NotBeNull(); response.Data.Should().NotBeNull(); response.Data.RawValue.Should().NotBeNullOrWhiteSpace(); response.Data.RawValue.Should().Be(expected); SimpleDataContractDto responseDto = null; Action getValue = () => responseDto = response.Data.GetValue<SimpleDataContractDto>(); getValue.ShouldNotThrow(); responseDto.Should().NotBeNull(); responseDto.Id.Should().Be(dto.Id); responseDto.Name.Should().Be(dto.Name); } }
public async Task ShouldCallTheCorrectUrlByAwaitingImmediately() { var expected = true; using (var http = new HttpTest()) { http.RespondWithJson(Fixtures.Cluster.ClusterHealthResponse(expected)); var healthResult = await Etcd.ClientFor(Fixtures.EtcdUrl.ToUri()) .Cluster .GetHealth(); http.Should() .HaveCalled(Fixtures.EtcdUrl.AppendPathSegment(Constants.Etcd.Path_Health)) .WithVerb(HttpMethod.Get) .Times(1); healthResult.Should().NotBeNull(); healthResult.Value.Should() .Be(expected); } }
public async Task Watch_ShouldStopPollingOnA500LevelResponse() { using (var http = new HttpTest()) { http.RespondWith(500, "Some error string") .RespondWithJson(Fixtures.Watch.DefaultResponse) .RespondWithJson(Fixtures.Watch.DefaultResponse); var tcs = new TaskCompletionSource<object>(); var task = tcs.Task; Etcd.ClientFor(Fixtures.EtcdUrl.ToUri()) .Watch(Fixtures.Watch.Path) .Subscribe(tcs.SetResult, x => tcs.SetException(x)); try { await task; } catch { // ignored } http.Should() .HaveCalled( Fixtures.EtcdUrl .AppendPathSegment(Constants.Etcd.Path_Keys) .AppendPathSegment(Fixtures.Watch.Path) .SetQueryParam(Constants.Etcd.Parameter_Wait, Constants.Etcd.Parameter_True) ) .WithVerb(HttpMethod.Get) .Times(1); task.IsCompleted.Should().BeTrue(); task.IsFaulted.Should().BeTrue(); } }
public async Task ShouldCallTheCorrectUrlByAwaitingImmediately() { using (var http = new HttpTest()) { http.RespondWithJson(Fixtures.Cluster.CreateResponse(Fixtures.EtcdUrl.ToUri())); var memberId = StaticRandom.Instance.Next(); await Etcd.ClientFor(Fixtures.EtcdUrl.ToUri()) .Cluster .DeleteMember() .WithMemberId(memberId.ToString()); http.Should() .HaveCalled( Fixtures.EtcdUrl .AppendPathSegment(Constants.Etcd.Path_Members) .AppendPathSegment(memberId.ToString()) ) .WithVerb(HttpMethod.Delete) .Times(1); } }
public async Task ShouldCallTheCorrectUrlWithTtlOptionUsingTimeSpan() { var expectedTtlValue = TimeSpan.FromMinutes(3) + TimeSpan.FromSeconds(16); using (var http = new HttpTest()) { http.RespondWithJson(Fixtures.Queue.DefaultResponse); var result = await Etcd.ClientFor(Fixtures.EtcdUrl.ToUri()) .Atomic .Enqueue(Fixtures.Queue.Path) .WithValue(Fixtures.Queue.DefaultValue) .WithTimeToLive(expectedTtlValue); http.Should() .HaveCalled( Fixtures.EtcdUrl .AppendPathSegments(Constants.Etcd.Path_Keys, Fixtures.Queue.Path) ) .WithVerb(HttpMethod.Post) .WithRequestBody(Fixtures.Key.TtlTimeSpanRequest(Fixtures.Queue.DefaultValue, expectedTtlValue)) .Times(1); } }
public async Task ExpectedValue_ShouldCallTheCorrectUrlByAwaitingImmediately() { using (var http = new HttpTest()) { http.RespondWithJson(Fixtures.CompareAndDelete.DefaultResponse) .RespondWithJson(Fixtures.CompareAndDelete.DefaultResponse); var req = Etcd.ClientFor(Fixtures.EtcdUrl.ToUri()) .Atomic.CompareAndDelete(Fixtures.CompareAndDelete.Path) .WithExpectedValue(Fixtures.CompareAndDelete.ExpectedValue); await req; await req.Execute(); http.Should() .HaveCalled( Fixtures.EtcdUrl .AppendPathSegments(Constants.Etcd.Path_Keys, Fixtures.CompareAndDelete.Path) .SetQueryParam(Constants.Etcd.Parameter_PrevValue, Fixtures.CompareAndDelete.ExpectedValue) ) .WithVerb(HttpMethod.Delete) .Times(2); } }
public void WatchOnce_ShouldOnlyBeNotifiedOnce() { using (var http = new HttpTest()) { http.RespondWithJson(Fixtures.Watch.DefaultResponse) .RespondWithJson(Fixtures.Watch.DefaultResponse); var tcs = new TaskCompletionSource<object>(); Etcd.ClientFor(Fixtures.EtcdUrl.ToUri()) .WatchOnce(Fixtures.Watch.Path) .Subscribe(tcs.SetResult, tcs.SetException); tcs.Task.Wait(); http.Should() .HaveCalled( Fixtures.EtcdUrl .AppendPathSegment(Constants.Etcd.Path_Keys) .AppendPathSegment(Fixtures.Watch.Path) .SetQueryParam(Constants.Etcd.Parameter_Wait, Constants.Etcd.Parameter_True) ) .WithVerb(HttpMethod.Get) .Times(1); http.CallLog.Should() .HaveCount(1); tcs.Task.IsCompleted.Should().BeTrue(); tcs.Task.Result.Should().NotBeNull(); } }
public void WatchOnce_ShouldCallTheCorrectUrlWithRecursiveOption() { using (var http = new HttpTest()) { Etcd.ClientFor(Fixtures.EtcdUrl.ToUri()) .WatchOnce(Fixtures.Watch.Path) .WithRecursive(true) .SubscribeFor(1); http.Should() .HaveCalled( Fixtures.EtcdUrl .AppendPathSegment(Constants.Etcd.Path_Keys) .AppendPathSegment(Fixtures.Watch.Path) .SetQueryParam(Constants.Etcd.Parameter_Wait, Constants.Etcd.Parameter_True) .SetQueryParam(Constants.Etcd.Parameter_Recursive, Constants.Etcd.Parameter_True) ) .WithVerb(HttpMethod.Get) .Times(1); } }
public void WatchOnce_ShouldCallTheCurrectUrlWithModifiedIndexOption() { const int modifiedIndex = 3; using (var http = new HttpTest()) { Etcd.ClientFor(Fixtures.EtcdUrl.ToUri()) .WatchOnce(Fixtures.Watch.Path) .WithModifiedIndex(modifiedIndex) .SubscribeFor(1); http.Should() .HaveCalled( Fixtures.EtcdUrl .AppendPathSegment(Constants.Etcd.Path_Keys) .AppendPathSegment(Fixtures.Watch.Path) .SetQueryParam(Constants.Etcd.Parameter_Wait, Constants.Etcd.Parameter_True) .SetQueryParam(Constants.Etcd.Parameter_WaitIndex, modifiedIndex) ) .WithVerb(HttpMethod.Get) .Times(1); } }
public async Task Get_ShouldCallTheCorrectUrlWithQuorumTrueOption() { using (var http = new HttpTest()) { http.RespondWithJson(Fixtures.Key.DefaultResponse); await Etcd.ClientFor(Fixtures.EtcdUrl.ToUri()) .GetKey(Fixtures.Key.Path) .WithQuorum(); http.Should() .HaveCalled( Fixtures.EtcdUrl .AppendPathSegments(Constants.Etcd.Path_Keys, Fixtures.Key.Path) .SetQueryParam(Constants.Etcd.Parameter_Quorum, Constants.Etcd.Parameter_True) ) .WithVerb(HttpMethod.Get) .Times(1); } }
public async Task Upsert_ShouldHaveTheStringEncodedBodyWhenUsingTheStringValueConverter() { const long dto = 389L; var expected = Convert.ToString(dto); using (var http = new HttpTest()) { http.RespondWithJson(Fixtures.Key.DefaultResponse); var client = Etcd.ClientFor(Fixtures.EtcdUrl.ToUri()); client.Configure(x => x.ValueConverter = Converters.String); await client .UpsertKey(Fixtures.Key.Path) .WithValue(dto); http.Should() .HaveCalled( Fixtures.EtcdUrl .AppendPathSegments(Constants.Etcd.Path_Keys, Fixtures.Key.Path) ) .WithVerb(HttpMethod.Put) .WithRequestBody(Fixtures.Key.DefaultRequest(expected)) .Times(1); } }
public async Task Upsert_ShouldCallTheCorrectUrlWithTtlOption() { using (var http = new HttpTest()) { http.RespondWithJson(Fixtures.Key.DefaultResponse); await Etcd.ClientFor(Fixtures.EtcdUrl.ToUri()) .UpsertKey(Fixtures.Key.Path) .WithValue(Fixtures.Key.DefaultValue) .WithTimeToLive(Fixtures.Key.DefaultTtl); http.Should() .HaveCalled( Fixtures.EtcdUrl .AppendPathSegments(Constants.Etcd.Path_Keys, Fixtures.Key.Path) ) .WithVerb(HttpMethod.Put) .WithRequestBody(Fixtures.Key.TtlRequest()) .Times(1); } }
public async Task Upsert_ShouldUsedPassedValueConverter() { var dto = Fixtures.Dto.SimpleDataContract(); var converter = new XmlValueConverter(); var expected = converter.Write(dto); using (var http = new HttpTest()) { http.RespondWithJson(Fixtures.Key.DefaultResponse); await Etcd.ClientFor(Fixtures.EtcdUrl.ToUri()) .UpsertKey(Fixtures.Key.Path) .WithValue(dto, converter); http.Should() .HaveCalled( Fixtures.EtcdUrl .AppendPathSegments(Constants.Etcd.Path_Keys, Fixtures.Key.Path) ) .WithVerb(HttpMethod.Put) .WithRequestBody(Fixtures.Key.DefaultRequest(expected)) .Times(1); } }
public async Task Upsert_ShouldHaveTheJsonEncodedBodyWhenUsingTheJsonValueConverter() { var dto = Fixtures.Dto.SimpleDataContract(); var expected = JsonConvert.SerializeObject(dto); using (var http = new HttpTest()) { http.RespondWithJson(Fixtures.Key.DefaultResponse); var client = Etcd.ClientFor(Fixtures.EtcdUrl.ToUri()); client.Configure(x => x.ValueConverter = Converters.Json); await client .UpsertKey(Fixtures.Key.Path) .WithValue(dto); http.Should() .HaveCalled( Fixtures.EtcdUrl .AppendPathSegments(Constants.Etcd.Path_Keys, Fixtures.Key.Path) ) .WithVerb(HttpMethod.Put) .WithRequestBody(Fixtures.Key.DefaultRequest(expected)) .Times(1); } }
public void Watch_ShouldStopPollingWhenSubscriptionIsDisposed() { using (var http = new HttpTest()) { http.RespondWithJson(Fixtures.Watch.DefaultResponse) .RespondWithJson(Fixtures.Watch.DefaultResponse) .RespondWithJson(Fixtures.Watch.DefaultResponse) .RespondWithJson(Fixtures.Watch.DefaultResponse) .RespondWithJson(Fixtures.Watch.DefaultResponse); Etcd.ClientFor(Fixtures.EtcdUrl.ToUri()) .Watch(Fixtures.Watch.Path) .SubscribeFor(3) .Wait(); http.Should() .HaveCalled( Fixtures.EtcdUrl .AppendPathSegment(Constants.Etcd.Path_Keys) .AppendPathSegment(Fixtures.Watch.Path) .SetQueryParam(Constants.Etcd.Parameter_Wait, Constants.Etcd.Parameter_True) ) .WithVerb(HttpMethod.Get); http.CallLog.Should() .HaveCount(3); } }