public void ClientDisconnected_ServerRaisesErrorMessage() { var failedOrigin = IntegrationTestsHelper .GetOriginBuilder() .UseSerializer(IntegrationTestsHelper.GetThrowsSerializationRuleFor <string>()); using (var tcpPair = new TcpConnectionPair <ITestContract, ITestContract, TestContractMock> (failedOrigin, IntegrationTestsHelper.GetProxyBuilder())) { var awaiter = new EventAwaiter <ClientDisconnectEventArgs <ITestContract, TcpChannel> >(); tcpPair.Server.Disconnected += awaiter.EventRaised; //provokes exception at origin-side serialization try { tcpPair.ProxyContract.Ask("some string"); } catch (RemoteSerializationException) {} var receivedArgs = awaiter.WaitOneOrDefault(500); //Client disconnected event is expected Assert.IsNotNull(receivedArgs); Assert.IsNotNull(receivedArgs.ErrorMessageOrNull); Assert.AreEqual(ErrorType.SerializationError, receivedArgs.ErrorMessageOrNull.ErrorType); } }
public async Task TestInitializeAsync() { if (this.ClassData.monitoredCollectionInfo == null) { try { if (this.ClassData.monitoredCollectionInfo == null) { this.ClassData.leaseCollectionInfoTemplate = await TestClassInitializeAsync(this, $"data_{this.GetType().Name}"); } } catch (Exception ex) { Debug.Write(ex); throw; } } this.LeaseCollectionInfo = new DocumentCollectionInfo(this.ClassData.leaseCollectionInfoTemplate); this.LeaseCollectionInfo.CollectionName = $"leases_{this.GetType().Name}_{Guid.NewGuid().ToString()}"; var leaseCollection = new DocumentCollection { Id = this.LeaseCollectionInfo.CollectionName }; using (var client = new DocumentClient(this.LeaseCollectionInfo.Uri, this.LeaseCollectionInfo.MasterKey, this.LeaseCollectionInfo.ConnectionPolicy)) { await IntegrationTestsHelper.CreateDocumentCollectionAsync(client, this.LeaseCollectionInfo.DatabaseName, leaseCollection, leaseOfferThroughput); } }
public async Task InitializeAsync() { try { await this.CreateMonitoredCollectionAsync($"data_{this.GetType().Name}"); } catch (Exception ex) { Debug.WriteLine(ex); throw; } this.LeaseCollectionInfo.CollectionName = $"leases_{this.GetType().Name}_{Guid.NewGuid().ToString()}"; var leaseCollection = new DocumentCollection { Id = this.LeaseCollectionInfo.CollectionName, }; if (this.IsPartitionedLeaseCollection) { leaseCollection.PartitionKey = new PartitionKeyDefinition { Paths = { "/id" } }; } using (var client = new DocumentClient(this.LeaseCollectionInfo.Uri, this.LeaseCollectionInfo.MasterKey, this.LeaseCollectionInfo.ConnectionPolicy)) { await IntegrationTestsHelper.CreateDocumentCollectionAsync(client, this.LeaseCollectionInfo.DatabaseName, leaseCollection, leaseOfferThroughput); } }
public void HundredOf2mbPacket_transmitsViaTcp_oneByOne() { var origin = TntBuilder .UseContract <ISingleMessageContract <Company>, SingleMessageContract <Company> >() .SetMaxAnsDelay(5 * 60 * 1000); var proxy = TntBuilder .UseContract <ISingleMessageContract <Company> >() .SetMaxAnsDelay(5 * 60 * 1000); using (var tcpPair = new TcpConnectionPair <ISingleMessageContract <Company>, ISingleMessageContract <Company>, SingleMessageContract <Company> >(origin, proxy)) { var receivedList = new List <Company>(200); tcpPair.OriginContract.SayCalled += (Sender, received) => receivedList.Add(received); var company = IntegrationTestsHelper.CreateCompany(2000); int sendCount = 100; for (int i = 0; i < sendCount; i++) { tcpPair.ProxyConnection.Contract.Ask(company); } Assert.AreEqual(sendCount, receivedList.Count); foreach (var received in receivedList) { received.AssertIsSameTo(company); } } }
public async Task CountDocumentsInCollection_TwoHosts() { await this.InitializeDocumentsAsync(); int partitionKeyRangeCount = await IntegrationTestsHelper.GetPartitionCount(this.MonitoredCollectionInfo); Assert.True(partitionKeyRangeCount > 1, "Prerequisite failed: expected monitored collection with at least 2 partitions."); int processedCount = 0; var allDocsProcessed = new ManualResetEvent(false); var observerFactory = new TestObserverFactory( (ChangeFeedObserverContext context, IReadOnlyList <Document> docs) => { int newCount = Interlocked.Add(ref processedCount, docs.Count); if (newCount == documentCount) { allDocsProcessed.Set(); } return(Task.CompletedTask); }); var host1 = new ChangeFeedEventHost( Guid.NewGuid().ToString(), this.MonitoredCollectionInfo, this.LeaseCollectionInfo, new ChangeFeedOptions { StartFromBeginning = true }, new ChangeFeedHostOptions { MaxPartitionCount = partitionKeyRangeCount / 2 }); await host1.RegisterObserverFactoryAsync(observerFactory); var host2 = new ChangeFeedEventHost( Guid.NewGuid().ToString(), this.MonitoredCollectionInfo, this.LeaseCollectionInfo, new ChangeFeedOptions { StartFromBeginning = true }, new ChangeFeedHostOptions { MaxPartitionCount = partitionKeyRangeCount - partitionKeyRangeCount / 2 }); await host2.RegisterObserverFactoryAsync(observerFactory); allDocsProcessed.WaitOne(changeWaitTimeout + changeWaitTimeout); try { Assert.True(documentCount == processedCount, $"Wrong processedCount {documentCount} {processedCount}"); } finally { await host1.UnregisterObserversAsync(); await host2.UnregisterObserversAsync(); } }
private async Task <DiffData> CallSetData(string url, string data) { var requestBody = IntegrationTestsHelper.BuildSetDataRequest(data); var response = await _client.PostAsync(url, requestBody); return(JsonConvert.DeserializeObject <DiffData>(await response.Content.ReadAsStringAsync())); }
private async Task <ErrorResponse> EndToEndTestWithError(string id, string leftData, string rightData) { await SetupData(id, leftData, rightData); var diffResponse = await _client.GetAsync(IntegrationTestsHelper.GetDiffUrl(id)); return(JsonConvert.DeserializeObject <ErrorResponse>(await diffResponse.Content.ReadAsStringAsync())); }
public void DeserializationThrowsRule_throws() { //Just check the Moq generator behaves as expected var rule = IntegrationTestsHelper.GetThrowsDeserializationRuleFor <string>(); var deserializer = rule.GetDeserializer(typeof(string), DeserializerFactory.CreateDefault()); Assert.Throws <Exception>(() => deserializer.Deserialize(new MemoryStream(), 0)); }
protected override async Task FinishTestClassInitializeAsync() { using (var client = new DocumentClient(this.ClassData.monitoredCollectionInfo.Uri, this.ClassData.monitoredCollectionInfo.MasterKey, this.ClassData.monitoredCollectionInfo.ConnectionPolicy)) { var collectionUri = UriFactory.CreateDocumentCollectionUri(this.ClassData.monitoredCollectionInfo.DatabaseName, this.ClassData.monitoredCollectionInfo.CollectionName); await IntegrationTestsHelper.CreateDocumentsAsync(client, collectionUri, documentCount); } }
private async Task InitializeDocumentsAsync() { using (var client = new DocumentClient(this.MonitoredCollectionInfo.Uri, this.MonitoredCollectionInfo.MasterKey, this.MonitoredCollectionInfo.ConnectionPolicy)) { var collectionUri = UriFactory.CreateDocumentCollectionUri(this.MonitoredCollectionInfo.DatabaseName, this.MonitoredCollectionInfo.CollectionName); await IntegrationTestsHelper.CreateDocumentsAsync(client, collectionUri, documentCount); } }
public async Task WhenLeasesHaveContinuationTokenNullReturn0() { // Cleanup the test collection to avoid other tests' documents causing issues with StartFromBeginning await this.ResetTestCollection(); int documentCount = 1; int partitionCount = await IntegrationTestsHelper.GetPartitionCount(this.ClassData.monitoredCollectionInfo); int openedCount = 0, processedCount = 0; var allObserversStarted = new ManualResetEvent(false); var allDocsProcessed = new ManualResetEvent(false); var observerFactory = new TestObserverFactory( context => { int newCount = Interlocked.Increment(ref openedCount); if (newCount == partitionCount) { allObserversStarted.Set(); } return(Task.CompletedTask); }, null, (ChangeFeedObserverContext context, IReadOnlyList <Document> docs) => { int newCount = Interlocked.Add(ref processedCount, docs.Count); if (newCount == documentCount) { allDocsProcessed.Set(); } return(Task.CompletedTask); }); var hostName = Guid.NewGuid().ToString(); // We create a host to initialize the leases with ContinuationToken null var host = new ChangeFeedEventHost( hostName, this.ClassData.monitoredCollectionInfo, this.LeaseCollectionInfo, new ChangeFeedOptions { StartFromBeginning = false }, new ChangeFeedHostOptions()); // Initialize leases await host.RegisterObserverFactoryAsync(observerFactory); // Stop host, this leaves the leases with ContinuationToken null state await host.UnregisterObserversAsync(); // Since the leases have ContinuationToken null state, the estimator will use StartFromBeginning and pick-up the changes that happened from the start long estimation = await host.GetEstimatedRemainingWork(); Assert.Equal(0, estimation); }
public void WordFilesRepository_Should_Store_Image_As_Answer() { var wordDocRepo = new WordFilesRepository(); var rootPath = IntegrationTestsHelper.GetFullResourcePath("integration-test-question-image.docx"); var doc = wordDocRepo.GetDocument(rootPath); doc.Tables.Should().HaveCount(1); }
private async Task SetupData(string id, string leftData, string rightData) { var leftResponse = await CallSetData(IntegrationTestsHelper.GetSetLeftUrl(id), leftData); var rightResponse = await CallSetData(IntegrationTestsHelper.GetSetRightUrl(id), rightData); Assert.Equal(leftData, leftResponse.Data); Assert.Equal(id, leftResponse.RequestId); Assert.Equal(rightData, rightResponse.Data); Assert.Equal(id, rightResponse.RequestId); }
private static void SerializeAndDeserializeProtobuffMessage(int companySize) { var company = IntegrationTestsHelper.CreateCompany(companySize); using (var stream = new MemoryStream()) { var serializer = new TNT.Presentation.Serializers.ProtoSerializer <Company>(); serializer.SerializeT(company, stream); stream.Position = 0; var deserializer = new TNT.Presentation.Deserializers.ProtoDeserializer <Company>(); var deserialized = deserializer.DeserializeT(stream, (int)stream.Length); company.AssertIsSameTo(deserialized); } }
public void WordFilesRepository_Should_Extract_Question_Table_From_Docx() { var wordDocRepo = new WordFilesRepository(); var rootPath = IntegrationTestsHelper.GetFullResourcePath("integration-test-question-table.docx"); var doc = wordDocRepo.GetDocument(rootPath); doc.Should().NotBeNull(); doc.Tables.Should().HaveCount(1); doc.Tables[0].Question.Should().Be("Test question"); doc.Tables[0].Answers[0].Should().Be("Test answer 1"); doc.Tables[0].Answers[1].Should().Be("Test answer 2"); doc.Tables[0].Answers[2].Should().Be("Test answer 3"); }
public void HundredOf2mbPacket_transmitsViaTcp_concurent() { var origin = TntBuilder .UseContract <ISingleMessageContract <Company>, SingleMessageContract <Company> >() .SetMaxAnsDelay(5 * 60 * 1000); var proxy = TntBuilder .UseContract <ISingleMessageContract <Company> >() .SetMaxAnsDelay(5 * 60 * 1000); using (var tcpPair = new TcpConnectionPair <ISingleMessageContract <Company>, ISingleMessageContract <Company>, SingleMessageContract <Company> >(origin, proxy)) { var receivedList = new List <Company>(200); tcpPair.OriginContract.SayCalled += (Sender, received) => receivedList.Add(received); tcpPair.ClientChannel.OnDisconnect += (s, err) => { Console.WriteLine("asdasd"); }; var company = IntegrationTestsHelper.CreateCompany(2000); int sendCount = 100; List <Task> sendTasks = new List <Task>(sendCount); for (int i = 0; i < sendCount; i++) { sendTasks.Add(new Task(() => tcpPair.ProxyConnection.Contract.Ask(company))); } foreach (Task task in sendTasks) { task.Start(); } if (!Task.WaitAll(sendTasks.ToArray(), 5 * 60 * 1000)) { Assert.Fail("Test timeout "); } Assert.AreEqual(sendCount, receivedList.Count); foreach (var received in receivedList) { received.AssertIsSameTo(company); } } }
public void LocalOriginSerializationFails_throws() { var originContractBuilder = IntegrationTestsHelper.GetOriginBuilder() .UseSerializer(IntegrationTestsHelper.GetThrowsSerializationRuleFor <string>()); using (var tcpPair = new TcpConnectionPair <ITestContract, ITestContract, TestContractMock> (originContractBuilder, IntegrationTestsHelper.GetProxyBuilder())) { //local origin serializer fails Assert.Multiple(() => { Assert.Throws <LocalSerializationException>(() => tcpPair.OriginContract.OnSayS("testString")); tcpPair.AssertPairIsDisconnected(); }); } }
private static void CheckProtobuffEchoTransaction(int itemsSize) { using (var tcpPair = new TcpConnectionPair <ISingleMessageContract <Company>, ISingleMessageContract <Company>, SingleMessageContract <Company> >()) { EventAwaiter <Company> callAwaiter = new EventAwaiter <Company>(); tcpPair.OriginContract.SayCalled += callAwaiter.EventRaised; var company = IntegrationTestsHelper.CreateCompany(itemsSize); tcpPair.ProxyConnection.Contract.Ask(company); var received = callAwaiter.WaitOneOrDefault(5000); Assert.IsNotNull(received); received.AssertIsSameTo(company); } }
public void LocalProxyDeserializationFails_throws() { var proxyContractBuilder = IntegrationTestsHelper .GetProxyBuilder() .UseDeserializer(IntegrationTestsHelper.GetThrowsDeserializationRuleFor <string>()); using (var tcpPair = new TcpConnectionPair <ITestContract, ITestContract, TestContractMock> (IntegrationTestsHelper.GetOriginBuilder(), proxyContractBuilder)) { //proxy contract uses failed string deserializer, when it accepts answer Assert.Multiple(() => { Assert.Throws <LocalSerializationException>(() => tcpPair.ProxyContract.Ask("testString")); tcpPair.AssertPairIsDisconnected(); }); } }
public async Task CountDocumentsInCollection_NormalCase() { await this.InitializeDocumentsAsync(); int partitionKeyRangeCount = await IntegrationTestsHelper.GetPartitionCount(this.MonitoredCollectionInfo); int openedCount = 0, closedCount = 0, processedCount = 0; var allDocsProcessed = new ManualResetEvent(false); var observerFactory = new TestObserverFactory( context => { Interlocked.Increment(ref openedCount); return(Task.CompletedTask); }, (context, reason) => { Interlocked.Increment(ref closedCount); return(Task.CompletedTask); }, (ChangeFeedObserverContext context, IReadOnlyList <Document> docs) => { int newCount = Interlocked.Add(ref processedCount, docs.Count); if (newCount == documentCount) { allDocsProcessed.Set(); } return(Task.CompletedTask); }); var host = new ChangeFeedEventHost( Guid.NewGuid().ToString(), this.MonitoredCollectionInfo, this.LeaseCollectionInfo, new ChangeFeedOptions { StartFromBeginning = true }, new ChangeFeedHostOptions()); await host.RegisterObserverFactoryAsync(observerFactory); allDocsProcessed.WaitOne(changeWaitTimeout + changeWaitTimeout); try { Assert.True(partitionKeyRangeCount == openedCount, "Wrong openedCount"); Assert.True(documentCount == processedCount, $"Wrong processedCount {documentCount} {processedCount}"); } finally { await host.UnregisterObserversAsync(); } Assert.True(partitionKeyRangeCount == closedCount, "Wrong closedCount"); }
public void WordFilesRepository_Should_Extract_Cheatsheet_Table_From_Docx() { var wordDocRepo = new WordFilesRepository(); var rootPath = IntegrationTestsHelper.GetFullResourcePath("integration-test-cheatsheet-table.docx"); var doc = wordDocRepo.GetDocument(rootPath); doc.Should().NotBeNull(); doc.Tables.Should().HaveCount(3); doc.Tables[0].Question.Should().Be(@"Test question 1/3"); doc.Tables[0].Answer.Should().Be(@"cmd answer –demo1"); doc.Tables[1].Question.Should().Be(@"Test question 2/3"); doc.Tables[1].Answer.Should().Be(@"cmd answer –demo2"); doc.Tables[2].Question.Should().Be(@"Test question 3/3"); doc.Tables[2].Answer.Should().Be(@"cmd answer –demo3"); }
public void RemoteOriginSeserializationFails_throws() { var proxyContractBuilder = IntegrationTestsHelper .GetProxyBuilder() .UseSerializer(IntegrationTestsHelper.GetThrowsSerializationRuleFor <string>()); using (var tcpPair = new TcpConnectionPair <ITestContract, ITestContract, TestContractMock> (IntegrationTestsHelper.GetOriginBuilder(), proxyContractBuilder)) { //proxy contract uses failed string serializer, when it returns answer Assert.Multiple(() => { Assert.Throws <RemoteSerializationException>(() => tcpPair.OriginContract.OnAskS("testString")); tcpPair.AssertPairIsDisconnected(); }); } }
private static async Task <DocumentCollectionInfo> TestClassInitializeAsync(IntegrationTest test, string monitoredCollectionName) { Debug.Assert(test != null); Debug.Assert(monitoredCollectionName != null); DocumentCollectionInfo leaseCollectionInfo; IntegrationTestsHelper.GetConfigurationSettings( out test.ClassData.monitoredCollectionInfo, out leaseCollectionInfo, out monitoredOfferThroughput, out leaseOfferThroughput); test.ClassData.monitoredCollectionInfo.CollectionName = monitoredCollectionName; var monitoredCollection = new DocumentCollection { Id = test.ClassData.monitoredCollectionInfo.CollectionName, }; if (test.ClassData.isPartitionedCollection) { monitoredCollection.PartitionKey = new PartitionKeyDefinition { Paths = new Collection <string> { "/id" } }; } else { if (monitoredOfferThroughput > 10000) { monitoredOfferThroughput = 10000; } } using (var client = new DocumentClient(test.ClassData.monitoredCollectionInfo.Uri, test.ClassData.monitoredCollectionInfo.MasterKey, test.ClassData.monitoredCollectionInfo.ConnectionPolicy)) { await IntegrationTestsHelper.CreateDocumentCollectionAsync(client, test.ClassData.monitoredCollectionInfo.DatabaseName, monitoredCollection, monitoredOfferThroughput); } test.FinishTestClassInitializeAsync().Wait(); return(leaseCollectionInfo); }
private async Task CreateMonitoredCollectionAsync(string monitoredCollectionName) { Debug.Assert(monitoredCollectionName != null); IntegrationTestsHelper.GetConfigurationSettings( out DocumentCollectionInfo baseMonitoredCollectionInfo, out DocumentCollectionInfo baseLeaseCollectionInfo, out monitoredOfferThroughput, out leaseOfferThroughput); this.MonitoredCollectionInfo = baseMonitoredCollectionInfo; this.LeaseCollectionInfo = baseLeaseCollectionInfo; this.MonitoredCollectionInfo.CollectionName = monitoredCollectionName; var monitoredCollection = new DocumentCollection { Id = this.MonitoredCollectionInfo.CollectionName, }; if (this.IsPartitionedMonitoredCollection) { monitoredCollection.PartitionKey = new PartitionKeyDefinition { Paths = { "/id" } }; } else { if (monitoredOfferThroughput > 10000) { monitoredOfferThroughput = 10000; } } using (var client = new DocumentClient(this.MonitoredCollectionInfo.Uri, this.MonitoredCollectionInfo.MasterKey, this.MonitoredCollectionInfo.ConnectionPolicy)) { await IntegrationTestsHelper.CreateDocumentCollectionAsync(client, this.MonitoredCollectionInfo.DatabaseName, monitoredCollection, monitoredOfferThroughput); } }
public void RunMockup() { var gmThread = CreateGmThread(); var csThread = IntegrationTestsHelper.CreateCsThread(); csThread.Start(); gmThread.Start(); Thread.Sleep(3000); //time for connecting gm with cs var agents = IntegrationTestsHelper.CreateAgents(agentsInTeam); foreach (var agent in agents) { var agentThread = new Thread(RunAgent); agentThread.IsBackground = true; //background threads for termination at test exit agentThread.Start(agent); } gmThread.Join(); Environment.Exit(Environment.ExitCode); //second nail for preventing thread garbage }
public async Task StopAtFullSpeed() { int partitionKeyRangeCount = await IntegrationTestsHelper.GetPartitionCount(this.MonitoredCollectionInfo); int openedCount = 0, closedCount = 0, processedCount = 0; var quarterDocsProcessed = new ManualResetEvent(false); var observerFactory = new TestObserverFactory( context => { Interlocked.Increment(ref openedCount); return(Task.CompletedTask); }, (context, reason) => { Interlocked.Increment(ref closedCount); return(Task.CompletedTask); }, (ChangeFeedObserverContext context, IReadOnlyList <Document> docs) => { int newCount = Interlocked.Add(ref processedCount, docs.Count); if (newCount >= documentCount / 4) { quarterDocsProcessed.Set(); } return(Task.CompletedTask); }); var host = new ChangeFeedEventHost( Guid.NewGuid().ToString(), this.MonitoredCollectionInfo, this.LeaseCollectionInfo, new ChangeFeedOptions { StartFromBeginning = true, MaxItemCount = 2 }, new ChangeFeedHostOptions()); await host.RegisterObserverFactoryAsync(observerFactory); quarterDocsProcessed.WaitOne(changeWaitTimeout + changeWaitTimeout); await host.UnregisterObserversAsync(); Assert.True(partitionKeyRangeCount == openedCount, "Wrong closedCount"); Assert.True(partitionKeyRangeCount == closedCount, "Wrong closedCount"); }
public async Task CountPendingDocuments() { int documentCount = 1; int partitionCount = await IntegrationTestsHelper.GetPartitionCount(this.MonitoredCollectionInfo); int openedCount = 0, processedCount = 0; var allObserversStarted = new ManualResetEvent(false); var allDocsProcessed = new ManualResetEvent(false); var observerFactory = new TestObserverFactory( context => { int newCount = Interlocked.Increment(ref openedCount); if (newCount == partitionCount) { allObserversStarted.Set(); } return(Task.CompletedTask); }, null, (ChangeFeedObserverContext context, IReadOnlyList <Document> docs) => { int newCount = Interlocked.Add(ref processedCount, docs.Count); if (newCount == documentCount) { allDocsProcessed.Set(); } return(Task.CompletedTask); }); var hostName = Guid.NewGuid().ToString(); var host = new ChangeFeedEventHost( hostName, this.MonitoredCollectionInfo, this.LeaseCollectionInfo, new ChangeFeedOptions { StartFromBeginning = false }, new ChangeFeedHostOptions()); // Initialize leases await host.RegisterObserverFactoryAsync(observerFactory); // Verify that 0 is returned on empty collection long estimation = await host.GetEstimatedRemainingWork(); Assert.Equal(0, estimation); using (var client = new DocumentClient(this.MonitoredCollectionInfo.Uri, this.MonitoredCollectionInfo.MasterKey, this.MonitoredCollectionInfo.ConnectionPolicy)) { await IntegrationTestsHelper.CreateDocumentsAsync( client, UriFactory.CreateDocumentCollectionUri(this.MonitoredCollectionInfo.DatabaseName, this.MonitoredCollectionInfo.CollectionName), 1); var isStartOk = allObserversStarted.WaitOne(IntegrationTest.changeWaitTimeout + IntegrationTest.changeWaitTimeout); Assert.True(isStartOk, "Timed out waiting for observer to start"); allDocsProcessed.WaitOne(IntegrationTest.changeWaitTimeout); // Halt the processor temporarily await host.UnregisterObserversAsync(); estimation = await host.GetEstimatedRemainingWork(); Assert.Equal(0, estimation); await IntegrationTestsHelper.CreateDocumentsAsync( client, UriFactory.CreateDocumentCollectionUri(this.MonitoredCollectionInfo.DatabaseName, this.MonitoredCollectionInfo.CollectionName), 1); estimation = await host.GetEstimatedRemainingWork(); Assert.Equal(1, estimation); await IntegrationTestsHelper.CreateDocumentsAsync( client, UriFactory.CreateDocumentCollectionUri(this.MonitoredCollectionInfo.DatabaseName, this.MonitoredCollectionInfo.CollectionName), 10); estimation = await host.GetEstimatedRemainingWork(); Assert.Equal(11, estimation); // Create a new host to process pending changes var newHost = new ChangeFeedEventHost( hostName, this.MonitoredCollectionInfo, this.LeaseCollectionInfo, new ChangeFeedOptions { StartFromBeginning = false }, new ChangeFeedHostOptions()); openedCount = 0; processedCount = 0; allObserversStarted.Reset(); allDocsProcessed.Reset(); await newHost.RegisterObserverFactoryAsync(observerFactory); isStartOk = allObserversStarted.WaitOne(IntegrationTest.changeWaitTimeout + IntegrationTest.changeWaitTimeout); Assert.True(isStartOk, "Timed out waiting for observer to start"); allDocsProcessed.WaitOne(IntegrationTest.changeWaitTimeout); try { estimation = await newHost.GetEstimatedRemainingWork(); Assert.Equal(0, estimation); } finally { await newHost.UnregisterObserversAsync(); } } }
public async Task Schema_OnV2MigrationMaintainLeaseToken() { const int batchSize = 10; int partitionCount = await IntegrationTestsHelper.GetPartitionCount(this.MonitoredCollectionInfo); int openedCount = 0; ManualResetEvent allObserversStarted = new ManualResetEvent(false); List <int> expectedIds = Enumerable.Range(0, batchSize * 2).ToList(); ManualResetEvent firstSetOfResultsProcessed = new ManualResetEvent(false); ManualResetEvent secondSetOfResultsProcessed = new ManualResetEvent(false); List <int> receivedIds = new List <int>(); TestObserverFactory observerFactory = new TestObserverFactory( context => { int newCount = Interlocked.Increment(ref openedCount); if (newCount == partitionCount) { allObserversStarted.Set(); } return(Task.CompletedTask); }, (FeedProcessing.IChangeFeedObserverContext context, IReadOnlyList <Document> docs) => { foreach (Document doc in docs) { receivedIds.Add(int.Parse(doc.Id)); } if (receivedIds.Count == batchSize) { firstSetOfResultsProcessed.Set(); } if (receivedIds.Count == batchSize * 2) { secondSetOfResultsProcessed.Set(); } return(Task.CompletedTask); }); IChangeFeedProcessor changeFeedProcessorBuilder = await new ChangeFeedProcessorBuilder() .WithObserverFactory(observerFactory) .WithHostName("smoke_test") .WithFeedCollection(this.MonitoredCollectionInfo) .WithLeaseCollection(this.LeaseCollectionInfo) .BuildAsync(); await changeFeedProcessorBuilder.StartAsync(); await this.WaitUntilLeaseStoreIsInitializedAsync(new CancellationTokenSource(5000).Token); // Inserting some documents using (DocumentClient client = new DocumentClient(this.MonitoredCollectionInfo.Uri, this.MonitoredCollectionInfo.MasterKey, this.MonitoredCollectionInfo.ConnectionPolicy)) { Uri collectionUri = UriFactory.CreateDocumentCollectionUri(this.MonitoredCollectionInfo.DatabaseName, this.MonitoredCollectionInfo.CollectionName); foreach (int id in expectedIds.Take(10)) { await client.CreateDocumentAsync(collectionUri, new { id = id.ToString() }); } } Assert.True(firstSetOfResultsProcessed.WaitOne(IntegrationTest.changeWaitTimeout), "Timed out waiting for first set of items to be received."); await changeFeedProcessorBuilder.StopAsync(); // At this point we have leases for V2, so we will simulate V3 by manually adding LeaseToken and removing PartitionId using (DocumentClient client = new DocumentClient(this.LeaseCollectionInfo.Uri, this.LeaseCollectionInfo.MasterKey, this.LeaseCollectionInfo.ConnectionPolicy)) { Uri collectionUri = UriFactory.CreateDocumentCollectionUri(this.LeaseCollectionInfo.DatabaseName, this.LeaseCollectionInfo.CollectionName); IDocumentQuery <JObject> query = client.CreateDocumentQuery <JObject>(collectionUri, "SELECT * FROM c").AsDocumentQuery(); while (query.HasMoreResults) { foreach (JObject lease in await query.ExecuteNextAsync()) { string leaseId = lease.Value <string>("id"); if (leaseId.Contains(".info")) { // These are the store initialization marks continue; } // create the LeaseToken property lease.Add("LeaseToken", lease.Value <string>("PartitionId")); lease.Remove("PartitionId"); await client.UpsertDocumentAsync(collectionUri, lease); } } } // Now all leases are V3 leases, start another processor that should migrate to V2 schema and maintain LeaseToken for compatibility openedCount = 0; allObserversStarted.Reset(); changeFeedProcessorBuilder = await new ChangeFeedProcessorBuilder() .WithObserverFactory(observerFactory) .WithHostName("smoke_test") .WithFeedCollection(this.MonitoredCollectionInfo) .WithLeaseCollection(this.LeaseCollectionInfo) .BuildAsync(); await changeFeedProcessorBuilder.StartAsync(); Assert.True(allObserversStarted.WaitOne(IntegrationTest.changeWaitTimeout + IntegrationTest.changeWaitTimeout), "Timed out waiting for observres to start"); // Create the rest of the documents using (DocumentClient client = new DocumentClient(this.MonitoredCollectionInfo.Uri, this.MonitoredCollectionInfo.MasterKey, this.MonitoredCollectionInfo.ConnectionPolicy)) { Uri collectionUri = UriFactory.CreateDocumentCollectionUri(this.MonitoredCollectionInfo.DatabaseName, this.MonitoredCollectionInfo.CollectionName); foreach (int id in expectedIds.TakeLast(10)) { await client.CreateDocumentAsync(collectionUri, new { id = id.ToString() }); } } Assert.True(secondSetOfResultsProcessed.WaitOne(IntegrationTest.changeWaitTimeout), "Timed out waiting for second set of items to be received."); await changeFeedProcessorBuilder.StopAsync(); // Verify we processed all items (including when using the V3 leases) Assert.True(!expectedIds.Except(receivedIds).Any() && expectedIds.Count == expectedIds.Count); // Verify the after-migration leases have both PartitionId and LeaseToken with the same value using (DocumentClient client = new DocumentClient(this.LeaseCollectionInfo.Uri, this.LeaseCollectionInfo.MasterKey, this.LeaseCollectionInfo.ConnectionPolicy)) { Uri collectionUri = UriFactory.CreateDocumentCollectionUri(this.LeaseCollectionInfo.DatabaseName, this.LeaseCollectionInfo.CollectionName); IDocumentQuery <JObject> query = client.CreateDocumentQuery <JObject>(collectionUri, "SELECT * FROM c").AsDocumentQuery(); while (query.HasMoreResults) { foreach (JObject lease in await query.ExecuteNextAsync()) { string leaseId = lease.Value <string>("id"); if (leaseId.Contains(".info")) { // These are the store initialization marks continue; } Assert.NotNull(lease.Value <string>("PartitionId")); Assert.Null(lease.Value <string>("LeaseToken")); } } } }
public async Task TestStartTime() { var collectionUri = UriFactory.CreateDocumentCollectionUri(this.MonitoredCollectionInfo.DatabaseName, this.MonitoredCollectionInfo.CollectionName); using (var client = new DocumentClient(this.MonitoredCollectionInfo.Uri, this.MonitoredCollectionInfo.MasterKey, this.MonitoredCollectionInfo.ConnectionPolicy)) { await client.CreateDocumentAsync(collectionUri, JsonConvert.DeserializeObject("{\"id\": \"doc1\"}")); // In worst case (long transaction, heavy load, the atomicity of StartTime is 5 sec). // For this case (different transactions) it's OK to wait timestamp precision time. await Task.Delay(TimeSpan.FromSeconds(1)); DateTime timeInBeweeen = DateTime.Now; await Task.Delay(TimeSpan.FromSeconds(1)); await client.CreateDocumentAsync(collectionUri, JsonConvert.DeserializeObject("{\"id\": \"doc2\"}")); int partitionCount = await IntegrationTestsHelper.GetPartitionCount(this.MonitoredCollectionInfo); var allDocsProcessed = new ManualResetEvent(false); var processedDocs = new List <Document>(); var observerFactory = new TestObserverFactory( null, null, (context, docs) => { processedDocs.AddRange(docs); foreach (var doc in docs) { if (doc.Id == "doc2") { allDocsProcessed.Set(); } } return(Task.CompletedTask); }); var host = new ChangeFeedEventHost( Guid.NewGuid().ToString(), this.MonitoredCollectionInfo, this.LeaseCollectionInfo, new ChangeFeedOptions { StartTime = timeInBeweeen }, new ChangeFeedHostOptions()); await host.RegisterObserverFactoryAsync(observerFactory); var isStartOk = allDocsProcessed.WaitOne(IntegrationTest.changeWaitTimeout + IntegrationTest.changeWaitTimeout); try { Assert.True(isStartOk, "Timed out waiting for docs to process"); Assert.True(1 == processedDocs.Count, "Wrong processed count"); Assert.True("doc2" == processedDocs[0].Id, "Wrong doc.id"); } finally { await host.UnregisterObserversAsync(); } } }
public async Task CountAddedDocuments() { int partitionCount = await IntegrationTestsHelper.GetPartitionCount(this.MonitoredCollectionInfo); int openedCount = 0, processedCount = 0; var allObserversStarted = new ManualResetEvent(false); var allDocsProcessed = new ManualResetEvent(false); var observerFactory = new TestObserverFactory( context => { int newCount = Interlocked.Increment(ref openedCount); if (newCount == partitionCount) { allObserversStarted.Set(); } return(Task.CompletedTask); }, null, (ChangeFeedObserverContext context, IReadOnlyList <Document> docs) => { int newCount = Interlocked.Add(ref processedCount, docs.Count); if (newCount == documentCount) { allDocsProcessed.Set(); } return(Task.CompletedTask); }); var host = new ChangeFeedEventHost( Guid.NewGuid().ToString(), this.MonitoredCollectionInfo, this.LeaseCollectionInfo, new ChangeFeedOptions { StartFromBeginning = false }, new ChangeFeedHostOptions()); await host.RegisterObserverFactoryAsync(observerFactory); var isStartOk = allObserversStarted.WaitOne(IntegrationTest.changeWaitTimeout + IntegrationTest.changeWaitTimeout); Assert.True(isStartOk, "Timed out waiting for observres to start"); using (var client = new DocumentClient(this.MonitoredCollectionInfo.Uri, this.MonitoredCollectionInfo.MasterKey, this.MonitoredCollectionInfo.ConnectionPolicy)) { await IntegrationTestsHelper.CreateDocumentsAsync( client, UriFactory.CreateDocumentCollectionUri(this.MonitoredCollectionInfo.DatabaseName, this.MonitoredCollectionInfo.CollectionName), documentCount); } allDocsProcessed.WaitOne(IntegrationTest.changeWaitTimeout); try { Assert.True(documentCount == processedCount, "Wrong processedCount"); } finally { await host.UnregisterObserversAsync(); } }