public void GlobalStrongConsistencyMockTest() { // create a real document service request (with auth token level = god) DocumentServiceRequest entity = DocumentServiceRequest.Create(OperationType.Read, ResourceType.Document, AuthorizationTokenType.SystemAll); // set request charge tracker - this is referenced in store reader (ReadMultipleReplicaAsync) DocumentServiceRequestContext requestContext = new DocumentServiceRequestContext { RequestChargeTracker = new RequestChargeTracker() }; entity.RequestContext = requestContext; // set a dummy resource id on the request. entity.ResourceId = "1-MxAPlgMgA="; // set consistency level on the request to Bounded Staleness entity.Headers[HttpConstants.HttpHeaders.ConsistencyLevel] = ConsistencyLevel.BoundedStaleness.ToString(); // also setup timeout helper, used in store reader entity.RequestContext.TimeoutHelper = new TimeoutHelper(new TimeSpan(2, 2, 2)); // when the store reader throws Invalid Partition exception, the higher layer should // clear this target identity. entity.RequestContext.TargetIdentity = new ServiceIdentity("dummyTargetIdentity1", new Uri("http://dummyTargetIdentity1"), false); entity.RequestContext.ResolvedPartitionKeyRange = new PartitionKeyRange(); AddressInformation[] addressInformation = this.GetMockAddressInformationDuringUpgrade(); Mock <IAddressResolver> mockAddressCache = this.GetMockAddressCache(addressInformation); // validate that the mock works PartitionAddressInformation partitionAddressInformation = mockAddressCache.Object.ResolveAsync(entity, false, new CancellationToken()).Result; IReadOnlyList <AddressInformation> addressInfo = partitionAddressInformation.AllAddresses; Assert.IsTrue(addressInfo[0] == addressInformation[0]); AddressSelector addressSelector = new AddressSelector(mockAddressCache.Object, Protocol.Tcp); Tuple <Uri, AddressCacheToken> primaryAddress = addressSelector.ResolvePrimaryUriAsync(entity, false /*forceAddressRefresh*/).Result; // check if the address return from Address Selector matches the original address info Assert.IsTrue(primaryAddress.Item1.Equals(addressInformation[0].PhysicalUri)); // Quorum Met scenario { // get mock transport client that returns a sequence of responses to simulate upgrade TransportClient mockTransportClient = this.GetMockTransportClientForGlobalStrongReads(addressInformation, ReadQuorumResultKind.QuorumMet); // create a real session container - we don't need session for this test anyway ISessionContainer sessionContainer = new SessionContainer(string.Empty); ConnectionStateListener connectionStateListener = new ConnectionStateListener(null); // create store reader with mock transport client, real address selector (that has mock address cache), and real session container StoreReader storeReader = new StoreReader(mockTransportClient, addressSelector, sessionContainer, connectionStateListener); Mock <IAuthorizationTokenProvider> mockAuthorizationTokenProvider = new Mock <IAuthorizationTokenProvider>(); mockAuthorizationTokenProvider.Setup(provider => provider.AddSystemAuthorizationHeaderAsync( It.IsAny <DocumentServiceRequest>(), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>())) .Returns(Task.FromResult(0)); // setup max replica set size on the config reader ReplicationPolicy replicationPolicy = new ReplicationPolicy { MaxReplicaSetSize = 4 }; Mock <IServiceConfigurationReader> mockServiceConfigReader = new Mock <IServiceConfigurationReader>(); mockServiceConfigReader.SetupGet(x => x.UserReplicationPolicy).Returns(replicationPolicy); QuorumReader reader = new QuorumReader(mockTransportClient, addressSelector, storeReader, mockServiceConfigReader.Object, mockAuthorizationTokenProvider.Object); entity.RequestContext.OriginalRequestConsistencyLevel = Documents.ConsistencyLevel.Strong; entity.RequestContext.ClientRequestStatistics = new ClientSideRequestStatistics(); StoreResponse result = reader.ReadStrongAsync(entity, 2, ReadMode.Strong).Result; Assert.IsTrue(result.LSN == 100); result.TryGetHeaderValue(WFConstants.BackendHeaders.GlobalCommittedLSN, out string globalCommitedLSN); long nGlobalCommitedLSN = long.Parse(globalCommitedLSN, CultureInfo.InvariantCulture); Assert.IsTrue(nGlobalCommitedLSN == 90); } // Quorum Selected scenario { // get mock transport client that returns a sequence of responses to simulate upgrade TransportClient mockTransportClient = this.GetMockTransportClientForGlobalStrongReads(addressInformation, ReadQuorumResultKind.QuorumSelected); // create a real session container - we don't need session for this test anyway ISessionContainer sessionContainer = new SessionContainer(string.Empty); ConnectionStateListener connectionStateListener = new ConnectionStateListener(null); // create store reader with mock transport client, real address selector (that has mock address cache), and real session container StoreReader storeReader = new StoreReader(mockTransportClient, addressSelector, sessionContainer, connectionStateListener); Mock <IAuthorizationTokenProvider> mockAuthorizationTokenProvider = new Mock <IAuthorizationTokenProvider>(); mockAuthorizationTokenProvider.Setup(provider => provider.AddSystemAuthorizationHeaderAsync( It.IsAny <DocumentServiceRequest>(), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>())) .Returns(Task.FromResult(0)); // setup max replica set size on the config reader ReplicationPolicy replicationPolicy = new ReplicationPolicy { MaxReplicaSetSize = 4 }; Mock <IServiceConfigurationReader> mockServiceConfigReader = new Mock <IServiceConfigurationReader>(); mockServiceConfigReader.SetupGet(x => x.UserReplicationPolicy).Returns(replicationPolicy); QuorumReader reader = new QuorumReader(mockTransportClient, addressSelector, storeReader, mockServiceConfigReader.Object, mockAuthorizationTokenProvider.Object); entity.RequestContext.OriginalRequestConsistencyLevel = Documents.ConsistencyLevel.Strong; entity.RequestContext.ClientRequestStatistics = new ClientSideRequestStatistics(); entity.RequestContext.QuorumSelectedLSN = -1; entity.RequestContext.GlobalCommittedSelectedLSN = -1; try { StoreResponse result = reader.ReadStrongAsync(entity, 2, ReadMode.Strong).Result; Assert.IsTrue(false); } catch (AggregateException ex) { if (ex.InnerException is GoneException) { DefaultTrace.TraceInformation("Gone exception expected!"); } } Assert.IsTrue(entity.RequestContext.QuorumSelectedLSN == 100); Assert.IsTrue(entity.RequestContext.GlobalCommittedSelectedLSN == 100); } // Quorum not met scenario { // get mock transport client that returns a sequence of responses to simulate upgrade TransportClient mockTransportClient = this.GetMockTransportClientForGlobalStrongReads(addressInformation, ReadQuorumResultKind.QuorumNotSelected); // create a real session container - we don't need session for this test anyway ISessionContainer sessionContainer = new SessionContainer(string.Empty); ConnectionStateListener connectionStateListener = new ConnectionStateListener(null); // create store reader with mock transport client, real address selector (that has mock address cache), and real session container StoreReader storeReader = new StoreReader(mockTransportClient, addressSelector, sessionContainer, connectionStateListener); Mock <IAuthorizationTokenProvider> mockAuthorizationTokenProvider = new Mock <IAuthorizationTokenProvider>(); mockAuthorizationTokenProvider.Setup(provider => provider.AddSystemAuthorizationHeaderAsync( It.IsAny <DocumentServiceRequest>(), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>())) .Returns(Task.FromResult(0)); // setup max replica set size on the config reader ReplicationPolicy replicationPolicy = new ReplicationPolicy { MaxReplicaSetSize = 4 }; Mock <IServiceConfigurationReader> mockServiceConfigReader = new Mock <IServiceConfigurationReader>(); mockServiceConfigReader.SetupGet(x => x.UserReplicationPolicy).Returns(replicationPolicy); QuorumReader reader = new QuorumReader(mockTransportClient, addressSelector, storeReader, mockServiceConfigReader.Object, mockAuthorizationTokenProvider.Object); entity.RequestContext.PerformLocalRefreshOnGoneException = true; entity.RequestContext.OriginalRequestConsistencyLevel = Documents.ConsistencyLevel.Strong; entity.RequestContext.ClientRequestStatistics = new ClientSideRequestStatistics(); StoreResponse result = reader.ReadStrongAsync(entity, 2, ReadMode.Strong).Result; Assert.IsTrue(result.LSN == 100); result.TryGetHeaderValue(WFConstants.BackendHeaders.GlobalCommittedLSN, out string globalCommitedLSN); long nGlobalCommitedLSN = long.Parse(globalCommitedLSN, CultureInfo.InvariantCulture); Assert.IsTrue(nGlobalCommitedLSN == 90); } }
public void StoreReaderBarrierTest() { // create a real document service request DocumentServiceRequest entity = DocumentServiceRequest.Create(OperationType.Read, ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey); // set request charge tracker - this is referenced in store reader (ReadMultipleReplicaAsync) DocumentServiceRequestContext requestContext = new DocumentServiceRequestContext { ClientRequestStatistics = new ClientSideRequestStatistics(), RequestChargeTracker = new RequestChargeTracker() }; entity.RequestContext = requestContext; // also setup timeout helper, used in store reader entity.RequestContext.TimeoutHelper = new TimeoutHelper(new TimeSpan(2, 2, 2)); // when the store reader throws Invalid Partition exception, the higher layer should // clear this target identity. entity.RequestContext.TargetIdentity = new ServiceIdentity("dummyTargetIdentity1", new Uri("http://dummyTargetIdentity1"), false); entity.RequestContext.ResolvedPartitionKeyRange = new PartitionKeyRange(); AddressInformation[] addressInformation = this.GetMockAddressInformationDuringUpgrade(); Mock <IAddressResolver> mockAddressCache = this.GetMockAddressCache(addressInformation); // validate that the mock works PartitionAddressInformation partitionAddressInformation = mockAddressCache.Object.ResolveAsync(entity, false, new CancellationToken()).Result; IReadOnlyList <AddressInformation> addressInfo = partitionAddressInformation.AllAddresses; Assert.IsTrue(addressInfo[0] == addressInformation[0]); AddressSelector addressSelector = new AddressSelector(mockAddressCache.Object, Protocol.Tcp); Tuple <Uri, AddressCacheToken> primaryAddress = addressSelector.ResolvePrimaryUriAsync(entity, false /*forceAddressRefresh*/).Result; // check if the address return from Address Selector matches the original address info Assert.IsTrue(primaryAddress.Item1.Equals(addressInformation[0].PhysicalUri)); // get mock transport client that returns a sequence of responses to simulate upgrade TransportClient mockTransportClient = this.GetMockTransportClientDuringUpgrade(addressInformation); // get response from mock object StoreResponse response = mockTransportClient.InvokeResourceOperationAsync(new Uri(addressInformation[0].PhysicalUri), entity).Result; // validate that the LSN matches Assert.IsTrue(response.LSN == 50); response.TryGetHeaderValue(WFConstants.BackendHeaders.ActivityId, out string activityId); // validate that the ActivityId Matches Assert.IsTrue(activityId == "ACTIVITYID1_1"); // create a real session container - we don't need session for this test anyway ISessionContainer sessionContainer = new SessionContainer(string.Empty); ConnectionStateListener connectionStateListener = new ConnectionStateListener(null); // create store reader with mock transport client, real address selector (that has mock address cache), and real session container StoreReader storeReader = new StoreReader(mockTransportClient, addressSelector, sessionContainer, connectionStateListener); // reads always go to read quorum (2) replicas int replicaCountToRead = 2; IList <StoreResult> result = storeReader.ReadMultipleReplicaAsync( entity, false /*includePrimary*/, replicaCountToRead, true /*requiresValidLSN*/, false /*useSessionToken*/, ReadMode.Strong).Result; // make sure we got 2 responses from the store reader Assert.IsTrue(result.Count == 2); }
public void GlobalStrongConsistentWriteMockTest() { // create a real document service request (with auth token level = god) DocumentServiceRequest entity = DocumentServiceRequest.Create(OperationType.Create, ResourceType.Document, AuthorizationTokenType.SystemAll); // set request charge tracker - this is referenced in store reader (ReadMultipleReplicaAsync) DocumentServiceRequestContext requestContext = new DocumentServiceRequestContext { RequestChargeTracker = new RequestChargeTracker() }; entity.RequestContext = requestContext; // set a dummy resource id on the request. entity.ResourceId = "1-MxAPlgMgA="; // set consistency level on the request to Bounded Staleness entity.Headers[HttpConstants.HttpHeaders.ConsistencyLevel] = ConsistencyLevel.Strong.ToString(); // also setup timeout helper, used in store reader entity.RequestContext.TimeoutHelper = new TimeoutHelper(new TimeSpan(2, 2, 2)); // when the store reader throws Invalid Partition exception, the higher layer should // clear this target identity. entity.RequestContext.TargetIdentity = new ServiceIdentity("dummyTargetIdentity1", new Uri("http://dummyTargetIdentity1"), false); entity.RequestContext.ResolvedPartitionKeyRange = new PartitionKeyRange(); AddressInformation[] addressInformation = this.GetMockAddressInformationDuringUpgrade(); Mock <IAddressResolver> mockAddressCache = this.GetMockAddressCache(addressInformation); // validate that the mock works PartitionAddressInformation partitionAddressInformation = mockAddressCache.Object.ResolveAsync(entity, false, new CancellationToken()).Result; IReadOnlyList <AddressInformation> addressInfo = partitionAddressInformation.AllAddresses; Assert.IsTrue(addressInfo[0] == addressInformation[0]); AddressSelector addressSelector = new AddressSelector(mockAddressCache.Object, Protocol.Tcp); Tuple <Uri, AddressCacheToken> primaryAddress = addressSelector.ResolvePrimaryUriAsync(entity, false /*forceAddressRefresh*/).Result; // check if the address return from Address Selector matches the original address info Assert.IsTrue(primaryAddress.Item1.Equals(addressInformation[0].PhysicalUri)); // create a real session container - we don't need session for this test anyway ISessionContainer sessionContainer = new SessionContainer(string.Empty); ConnectionStateListener connectionStateListener = new ConnectionStateListener(null); Mock <IServiceConfigurationReader> mockServiceConfigReader = new Mock <IServiceConfigurationReader>(); Mock <IAuthorizationTokenProvider> mockAuthorizationTokenProvider = new Mock <IAuthorizationTokenProvider>(); mockAuthorizationTokenProvider.Setup(provider => provider.AddSystemAuthorizationHeaderAsync( It.IsAny <DocumentServiceRequest>(), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>())) .Returns(Task.FromResult(0)); for (int i = 0; i < addressInformation.Length; i++) { TransportClient mockTransportClient = this.GetMockTransportClientForGlobalStrongWrites(addressInformation, i, false, false, false); StoreReader storeReader = new StoreReader(mockTransportClient, addressSelector, sessionContainer, connectionStateListener); ConsistencyWriter consistencyWriter = new ConsistencyWriter(addressSelector, sessionContainer, mockTransportClient, mockServiceConfigReader.Object, mockAuthorizationTokenProvider.Object, connectionStateListener, false); StoreResponse response = consistencyWriter.WriteAsync(entity, new TimeoutHelper(TimeSpan.FromSeconds(30)), false).Result; Assert.AreEqual(100, response.LSN); //globalCommittedLsn never catches up in this case mockTransportClient = this.GetMockTransportClientForGlobalStrongWrites(addressInformation, i, true, false, false); consistencyWriter = new ConsistencyWriter(addressSelector, sessionContainer, mockTransportClient, mockServiceConfigReader.Object, mockAuthorizationTokenProvider.Object, connectionStateListener, false); try { response = consistencyWriter.WriteAsync(entity, new TimeoutHelper(TimeSpan.FromSeconds(30)), false).Result; Assert.Fail(); } catch (Exception) { } mockTransportClient = this.GetMockTransportClientForGlobalStrongWrites(addressInformation, i, false, true, false); consistencyWriter = new ConsistencyWriter(addressSelector, sessionContainer, mockTransportClient, mockServiceConfigReader.Object, mockAuthorizationTokenProvider.Object, connectionStateListener, false); response = consistencyWriter.WriteAsync(entity, new TimeoutHelper(TimeSpan.FromSeconds(30)), false).Result; Assert.AreEqual(100, response.LSN); mockTransportClient = this.GetMockTransportClientForGlobalStrongWrites(addressInformation, i, false, true, true); consistencyWriter = new ConsistencyWriter(addressSelector, sessionContainer, mockTransportClient, mockServiceConfigReader.Object, mockAuthorizationTokenProvider.Object, connectionStateListener, false); response = consistencyWriter.WriteAsync(entity, new TimeoutHelper(TimeSpan.FromSeconds(30)), false).Result; Assert.AreEqual(100, response.LSN); mockTransportClient = this.GetMockTransportClientForGlobalStrongWrites(addressInformation, i, false, false, true); consistencyWriter = new ConsistencyWriter(addressSelector, sessionContainer, mockTransportClient, mockServiceConfigReader.Object, mockAuthorizationTokenProvider.Object, connectionStateListener, false); response = consistencyWriter.WriteAsync(entity, new TimeoutHelper(TimeSpan.FromSeconds(30)), false).Result; Assert.AreEqual(100, response.LSN); } }
public void MockStoreClientTest() { // create a real document service request (with auth token level = god) DocumentServiceRequest entity = DocumentServiceRequest.Create(OperationType.Read, ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey); // set request charge tracker - this is referenced in store reader (ReadMultipleReplicaAsync) var requestContext = new DocumentServiceRequestContext(); requestContext.RequestChargeTracker = new RequestChargeTracker(); entity.RequestContext = requestContext; // set a dummy resource id on the request. entity.ResourceId = "1-MxAPlgMgA="; // set consistency level on the request to Bounded Staleness entity.Headers[HttpConstants.HttpHeaders.ConsistencyLevel] = ConsistencyLevel.BoundedStaleness.ToString(); // also setup timeout helper, used in store reader entity.RequestContext.TimeoutHelper = new TimeoutHelper(new TimeSpan(2, 2, 2)); // when the store reader throws Invalid Partition exception, the higher layer should // clear this target identity. entity.RequestContext.TargetIdentity = new ServiceIdentity("dummyTargetIdentity1", new Uri("http://dummyTargetIdentity1"), false); entity.RequestContext.ResolvedPartitionKeyRange = new PartitionKeyRange(); AddressInformation[] addressInformation = GetMockAddressInformationDuringUpgrade(); var mockAddressCache = GetMockAddressCache(addressInformation); // validate that the mock works PartitionAddressInformation partitionAddressInformation = mockAddressCache.Object.ResolveAsync(entity, false, new CancellationToken()).Result; var addressInfo = partitionAddressInformation.AllAddresses; Assert.IsTrue(addressInfo[0] == addressInformation[0]); AddressSelector addressSelector = new AddressSelector(mockAddressCache.Object, Protocol.Tcp); var primaryAddress = addressSelector.ResolvePrimaryUriAsync(entity, false /*forceAddressRefresh*/).Result; // check if the address return from Address Selector matches the original address info Assert.IsTrue(primaryAddress.Equals(addressInformation[0].PhysicalUri)); // get mock transport client that returns a sequence of responses to simulate upgrade var mockTransportClient = GetMockTransportClientDuringUpgrade(addressInformation); // get response from mock object var response = mockTransportClient.InvokeResourceOperationAsync(new Uri(addressInformation[0].PhysicalUri), entity).Result; // validate that the LSN matches Assert.IsTrue(response.LSN == 50); string activityId; response.TryGetHeaderValue(WFConstants.BackendHeaders.ActivityId, out activityId); // validate that the ActivityId Matches Assert.IsTrue(activityId == "ACTIVITYID1_1"); // create a real session container - we don't need session for this test anyway ISessionContainer sessionContainer = new SessionContainer(string.Empty); // create store reader with mock transport client, real address selector (that has mock address cache), and real session container StoreReader storeReader = new StoreReader(mockTransportClient, addressSelector, sessionContainer); Mock <IAuthorizationTokenProvider> mockAuthorizationTokenProvider = new Mock <IAuthorizationTokenProvider>(); // setup max replica set size on the config reader ReplicationPolicy replicationPolicy = new ReplicationPolicy(); replicationPolicy.MaxReplicaSetSize = 4; Mock <IServiceConfigurationReader> mockServiceConfigReader = new Mock <IServiceConfigurationReader>(); mockServiceConfigReader.SetupGet(x => x.UserReplicationPolicy).Returns(replicationPolicy); try { StoreClient storeClient = new StoreClient( mockAddressCache.Object, sessionContainer, mockServiceConfigReader.Object, mockAuthorizationTokenProvider.Object, Protocol.Tcp, mockTransportClient); ServerStoreModel storeModel = new ServerStoreModel(storeClient); var result = storeModel.ProcessMessageAsync(entity).Result; // if we have reached this point, there was a successful request. // validate if the target identity has been cleared out. // If the target identity is null and the request still succeeded, it means // that the very first read succeeded without a barrier request. Assert.IsNull(entity.RequestContext.TargetIdentity); Assert.IsNull(entity.RequestContext.ResolvedPartitionKeyRange); } catch (Exception e) { Assert.IsTrue(e.InnerException is ServiceUnavailableException || e.InnerException is ArgumentNullException || e.InnerException is ServiceUnavailableException || e.InnerException is NullReferenceException); } }