public async Task TestHandlingOfConnectionErrors() { using var kernel = new FakeItEasyMockingKernel(); kernel.Rebind <ILogger>().ToConstant(Log.Logger); kernel.Rebind <Configuration>().ToConstant(config); kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope(); var conFac = kernel.Get <ImapConnectionFactory>(); // note: for docker-imap-devel the connection limit per IP is 10, for Google it is 15 according to their documentation var connectionCount = 30; var tasks = new List <Task>(); var counter = 0; var rand = new Random(); for (var i = 0; i < connectionCount; i++) { var task = Task.Run(async() => { await Task.Delay(rand.Next(500)); var imapClient = await conFac.GetImapConnectionAsync(); var folder = await imapClient.GetFolderAsync(imapClient.PersonalNamespaces[0].Path); await Task.Delay(rand.Next(1000, 3000)); await imapClient.DisconnectAsync(true); lock (tasks) { counter++; } }); tasks.Add(task); } await Task.WhenAll(tasks); Assert.AreEqual(connectionCount, counter); }
public static void RemoveFolder(string folderName, Configuration config) { using var kernel = new FakeItEasyMockingKernel(); kernel.Rebind <ILogger>().ToConstant(Log.Logger); kernel.Rebind <Configuration>().ToConstant(config); kernel.Rebind <ImapStore>().ToSelf().InSingletonScope(); kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope(); var imapFac = kernel.Get <ImapConnectionFactory>(); using var connection = imapFac.GetImapConnectionAsync().Result; var parentFolder = connection.GetFolder(connection.PersonalNamespaces[0].Path); IMailFolder mailFolder; try { mailFolder = parentFolder.GetSubfolder(folderName); } catch { // most likely folder not found return; } RemoveFolder(mailFolder, config); connection.Disconnect(true); }
public static void RemoveFolder(IMailFolder folder, Configuration config) { using var kernel = new FakeItEasyMockingKernel(); kernel.Rebind <ILogger>().ToConstant(Log.Logger); kernel.Rebind <Configuration>().ToConstant(config); kernel.Rebind <ImapStore>().ToSelf().InSingletonScope(); kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope(); var imapFac = kernel.Get <ImapConnectionFactory>(); using var connection = imapFac.GetImapConnectionAsync().Result; var subFolders = folder.GetSubfolders(); foreach (var subFolder in subFolders) { RemoveFolder(subFolder, config); } folder.Open(FolderAccess.ReadWrite); var allMessages = folder.Search(SearchQuery.All); folder.SetFlags(allMessages, MessageFlags.Deleted, true); folder.Expunge(); folder.Close(); try { folder.Delete(); } catch (Exception e) { Debug.WriteLine("Exception while deleting folder: " + e.ToString()); } connection.Disconnect(true); }
public async Task TestUpdateLock() { using var kernel = new FakeItEasyMockingKernel(); kernel.Rebind <ILogger>().ToConstant(Log.Logger); kernel.Rebind <Configuration>().ToConstant(config); kernel.Rebind <ImapStore>().ToSelf().InSingletonScope(); kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope(); var imapFac = kernel.Get <ImapConnectionFactory>(); var remoteLock = kernel.Get <ImapBackedRemoteLock>(); remoteLock.LockTimeOut = TimeSpan.FromSeconds(5); using var connection = await imapFac.GetImapConnectionAsync(); var parentFolder = await connection.GetFolderAsync(connection.PersonalNamespaces[0].Path); await remoteLock.ReleaseLock(parentFolder, "resourcelock", -1); var lockResult = await remoteLock.AcquireLock(parentFolder, "resourcelock"); Assert.IsTrue(lockResult.IsSuccess); Assert.IsNotNull(lockResult.ResultingLockCookie); var lockResult2 = await remoteLock.AcquireLock(parentFolder, "resourcelock", lockResult.ResultingLockCookie); Assert.IsTrue(lockResult2.IsSuccess); Assert.IsNotNull(lockResult2.ResultingLockCookie); Assert.AreEqual(lockResult.ResultingLockCookie, lockResult2.ResultingLockCookie); var unlockResult = await remoteLock.ReleaseLock(parentFolder, "resourcelock", lockResult.ResultingLockCookie.Value); Assert.IsTrue(unlockResult); }
public async Task TestConnectionCachingForStoreUserOperation() { using var kernel = new FakeItEasyMockingKernel(); kernel.Rebind <ILogger>().ToConstant(Log.Logger); kernel.Rebind <Configuration>().ToConstant(config); kernel.Rebind <ITeamsUserStore>().To <ImapStore>().InSingletonScope(); kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope(); var factory = kernel.Get <ImapConnectionFactory>(); var factoryWrap = A.Fake <ImapConnectionFactory>(a => a.Wrapping(factory)); kernel.Rebind <ImapConnectionFactory>().ToConstant(factoryWrap); var imapStore = kernel.Get <ITeamsUserStore>(); var user = new ProcessedTeamsUser(fakeContext, (TeamsParticipant)"test.fakeuserid"); user.RegisterAlternateDisplayName("Heinrich Ulbricht", DateTime.UtcNow); user.RegisterAlternateEmailAddress("heinrich.ulbricht@localhost", DateTime.UtcNow); var user2 = new ProcessedTeamsUser(fakeContext, (TeamsParticipant)"test.fakeuserid"); user2.RegisterAlternateDisplayName("Heinrich Ulbricht", DateTime.UtcNow); user2.RegisterAlternateEmailAddress("heinrich.ulbricht@localhost", DateTime.UtcNow); await Task.Run(() => { imapStore.PersistUserAsync(fakeContext, user).Wait(); imapStore.PersistUserAsync(fakeContext, user2).Wait(); }); A.CallTo(() => factoryWrap.GetImapConnectionAsync()).MustHaveHappenedOnceExactly(); }
public async Task TestConcurrentLockAcquisition() { using var kernel = new FakeItEasyMockingKernel(); kernel.Rebind <ILogger>().ToConstant(Log.Logger); kernel.Rebind <Configuration>().ToConstant(config); kernel.Rebind <ImapStore>().ToSelf().InSingletonScope(); kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope(); var imapFac = kernel.Get <ImapConnectionFactory>(); var remoteLock = kernel.Get <ImapBackedRemoteLock>(); remoteLock.LockTimeOut = TimeSpan.FromSeconds(5); using var connection = await imapFac.GetImapConnectionAsync(); var parentFolder = await connection.GetFolderAsync(connection.PersonalNamespaces[0].Path); await remoteLock.ReleaseLock(parentFolder, "resourcelock", -1); connection.Disconnect(true); var tasks = new List <Task>(); for (var i = 0; i < 10; i++) { tasks.Add(Task.Run(async() => { using var connection = await imapFac.GetImapConnectionAsync(); var parentFolder = await connection.GetFolderAsync(connection.PersonalNamespaces[0].Path); var lockResult = await remoteLock.AcquireLock(parentFolder, "resourcelock"); connection.Disconnect(true); while (!lockResult.IsSuccess) { await Task.Delay(lockResult.TryAgainIn); using var connection2 = await imapFac.GetImapConnectionAsync(); var parentFolder2 = await connection2.GetFolderAsync(connection2.PersonalNamespaces[0].Path); lockResult = await remoteLock.AcquireLock(parentFolder2, "resourcelock"); connection2.Disconnect(true); } await Task.Delay(100); using var connection3 = await imapFac.GetImapConnectionAsync(); var parentFolder3 = await connection3.GetFolderAsync(connection3.PersonalNamespaces[0].Path); var unlockResult = await remoteLock.ReleaseLock(parentFolder3, "resourcelock", lockResult.ResultingLockCookie.Value); connection3.Disconnect(true); Assert.IsTrue(unlockResult); })); } await Task.WhenAll(tasks); using var connection2 = await imapFac.GetImapConnectionAsync(); var parentFolder2 = await connection2.GetFolderAsync(connection2.PersonalNamespaces[0].Path); var hasLock = await remoteLock.HasLockAsync(parentFolder2, "resourcelock"); connection2.Disconnect(true); Assert.IsFalse(hasLock); Assert.AreEqual(0, remoteLock.TimeoutCount, "Unexpected number of timeouts"); }
public async Task TestVisitMessages() { using var kernel = new FakeItEasyMockingKernel(); kernel.Rebind <ILogger>().ToConstant(Log.Logger); kernel.Rebind <Configuration>().ToConstant(config); kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope(); kernel.Rebind <ITeamsChatStore>().To <ImapStore>().InSingletonScope(); var conFac = kernel.Get <ImapConnectionFactory>(); var logger = kernel.Get <ILogger>(); var imapStore = kernel.Get <ITeamsChatStore>(); var imapClient = await conFac.GetImapConnectionAsync(); var rootFolder = await imapClient.GetFolderAsync(imapClient.PersonalNamespaces[0].Path); var mainUserFolder = await rootFolder.CreateAsync(fakeContext.MainUserId.Id.MakeSafeFolderName(rootFolder.DirectorySeparator), false); var tenantFolder = await mainUserFolder.CreateAsync("Fake Tenant", false); var chatsFolder = await tenantFolder.CreateAsync(Constants.TenantChatsFolderName, false); var chatFolder = await chatsFolder.CreateAsync("chat title or someting", false); await chatFolder.OpenAsync(MailKit.FolderAccess.ReadWrite); var message = new MimeMessage(); message.From.Add(new MailboxAddress(Constants.AppName, Constants.AppFakeEmail)); message.To.Add(new MailboxAddress(Constants.AppName, Constants.AppFakeEmail)); message.Subject = "Delete me User {{00000000-0000-beef-0000-000000000000}}"; var kvStore = new EmailBackedKeyValueStore(logger, message); kvStore.Set("originalMessage", new Message() { version = "123", content = "message content" }); var id = await chatFolder.AppendAsync(message); await imapStore.VisitMissingUserDisplayNames(fakeContext, async message => { message.MessageSubject = "Delete me - Changed subject"; message.TextContent = "new text content"; message.HtmlContent = "new html content"; return(await Task.FromResult((true, new List <string>()))); }); var newId = (await chatFolder.SearchAsync(SearchQuery.All)).First(); var changedMessage = await chatFolder.GetMessageAsync(newId); Assert.AreEqual("Delete me - Changed subject", changedMessage.Subject); await chatFolder.SetFlagsAsync(newId, MailKit.MessageFlags.Deleted, true); await chatFolder.ExpungeAsync(); }
public async Task TestImapServerFolderDuplicateBehavior() { using var kernel = new FakeItEasyMockingKernel(); kernel.Rebind <ILogger>().ToConstant(Log.Logger); kernel.Rebind <Configuration>().ToConstant(config); kernel.Rebind <ImapStore>().ToSelf().InSingletonScope(); kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope(); var imapFac = kernel.Get <ImapConnectionFactory>(); var failures = 0; var otherFailures = 0; var tasks = new List <Task>(); var taskCount = 9; for (var i = 0; i < taskCount; i++) { tasks.Add(Task.Run(async() => { using var connection = await imapFac.GetImapConnectionAsync(); var parentFolder = await connection.GetFolderAsync(connection.PersonalNamespaces[0].Path); try { var mailFolder = parentFolder.Create(testFolderName, true); var id = mailFolder.UidNext; } catch (Exception e) { if (e.Message.Contains("mailbox already exists", StringComparison.OrdinalIgnoreCase)) { lock (this) { failures++; } } else { otherFailures++; } } connection.Disconnect(true); })); } await Task.WhenAll(tasks); Assert.AreEqual(0, otherFailures, "Unexpected number of OTHER failures"); // Greenmail fails for duplicates, Dovecot succeeds Assert.IsTrue(taskCount == failures || failures == 0, "Unexpected number of failures"); }
public async Task TestWriteAndReadUser() { using var kernel = new FakeItEasyMockingKernel(); kernel.Rebind <ILogger>().ToConstant(Log.Logger); kernel.Rebind <Configuration>().ToConstant(config); kernel.Rebind <ITeamsUserStore>().To <ImapStore>().InSingletonScope(); var imapStore = kernel.Get <ITeamsUserStore>(); var userName = new Random().Next().ToString(); var user = new ProcessedTeamsUser(fakeContext, (TeamsParticipant)"test.fakeuserid"); user.RegisterAlternateDisplayName(userName, DateTime.UtcNow); user.RegisterAlternateEmailAddress("heinrich.ulbricht@localhost", DateTime.UtcNow); await imapStore.PersistUserAsync(fakeContext, user); var users = await imapStore.RetrieveUsersAsync(fakeContext); Assert.AreEqual(1, users.Where(u => u.DisplayName == userName).Count(), "Cannot find previously saved user"); }
public async Task TestStoreAndRetrieveChat() { using var kernel = new FakeItEasyMockingKernel(); kernel.Rebind <ILogger>().ToConstant(Log.Logger); kernel.Rebind <Configuration>().ToConstant(config); kernel.Rebind <ITeamsChatStore>().To <ImapStore>().InSingletonScope(); var chatStore = kernel.Get <ITeamsChatStore>(); var chatId = $"chatId-{rand.Next()}"; var chat1 = new ProcessedChat(new TeamsInternal.TeamsInternalApi.api.csa.api.v1.teams.users.Chat() { id = chatId, version = 10, threadVersion = 1000 }); await chatStore.StoreMailThreadAndUpdateMetadataAsync(fakeContext, "TestGetAllChatMetadata_1", chat1, null); var metadata = await chatStore.GetChatMetadataAsync(fakeContext, false, chatId); Assert.IsNotNull(metadata); }
public static void CreateFolder(string testFolderName, Configuration config) { using var kernel = new FakeItEasyMockingKernel(); kernel.Rebind <ILogger>().ToConstant(Log.Logger); kernel.Rebind <Configuration>().ToConstant(config); kernel.Rebind <ImapStore>().ToSelf().InSingletonScope(); kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope(); var imapFac = kernel.Get <ImapConnectionFactory>(); using var connection = imapFac.GetImapConnectionAsync().Result; var parentFolder = connection.GetFolder(connection.PersonalNamespaces[0].Path); var mailFolder = parentFolder.Create(testFolderName, true); mailFolder.Open(FolderAccess.ReadWrite); if (!mailFolder.PermanentFlags.HasFlag(MessageFlags.UserDefined)) { //throw new TeasmCompanionException("Folder does not support user defined flags"); } connection.Disconnect(true); }
public async Task TestMimeMessageGenerationForMessageThatOnceFailed() { var fakeUserRegistry = A.Fake <ITeamsUserRegistry>(); using var kernel = new FakeItEasyMockingKernel(); kernel.Rebind <ILogger>().ToConstant(Log.Logger); kernel.Rebind <Configuration>().ToConstant(config); kernel.Rebind <ImapStore>().ToSelf().InSingletonScope(); kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope(); kernel.Rebind <ITeamsUserRegistry>().ToConstant(fakeUserRegistry); var imapStore = kernel.Get <ImapStore>(); var json = "{\"id\":\"1111111111111\",\"sequenceId\":1111,\"clientmessageid\":\"1111111111111111111\",\"version\":\"1111111111111\",\"conversationid\":\"19:meeting_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@thread.v2\",\"conversationLink\":\"https://emea.ng.msg.teams.microsoft.com/v1/users/ME/conversations/19:meeting_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@thread.v2\",\"type\":\"Message\",\"messagetype\":\"Text\",\"contenttype\":\"text\",\"content\":\"aaa, aaaaaaaaaa aaaaaaaaaaa! \",\"amsreferences\":[],\"from\":\"https://emea.ng.msg.teams.microsoft.com/v1/users/ME/contacts/8:teamsvisitor:a111a1a111aa111a1aa1aa1a11aaaaa1\",\"imdisplayname\":\"aaa aaaaaaa (aaaa)\",\"composetime\":\"2000-01-01T01:01:01.111Z\",\"originalarrivaltime\":\"2000-01-01T01:01:01.111Z\",\"properties\":{}}"; var message = JsonConvert.DeserializeObject <Message>(json); var processedMessage = kernel.Get <ProcessedMessage>(); await processedMessage.InitFromMessageAsync(fakeContext, message.conversationid, message); // about "PrivateObject" see here: https://github.com/Microsoft/testfx/issues/366#issuecomment-580147403 var imapStorePrivate = new PrivateObject(imapStore); var result = (Task <MimeMessage>)imapStorePrivate.Invoke("CreateMimeMessageFromChatMessageAsync", processedMessage, null); var realResult = result.Result; }
public async Task TestModifyingExistingMessage() { using var kernel = new FakeItEasyMockingKernel(); kernel.Rebind <ILogger>().ToConstant(Log.Logger); kernel.Rebind <Configuration>().ToConstant(config); kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope(); var conFac = kernel.Get <ImapConnectionFactory>(); var logger = kernel.Get <ILogger>(); var imapClient = await conFac.GetImapConnectionAsync(); var folder = imapClient.Inbox; await folder.OpenAsync(MailKit.FolderAccess.ReadWrite); var message = new MimeMessage(); message.From.Add(new MailboxAddress(Constants.AppName, Constants.AppFakeEmail)); message.To.Add(new MailboxAddress(Constants.AppName, Constants.AppFakeEmail)); message.Subject = "Delete me"; var id = await folder.AppendAsync(message); var readMessage = await folder.GetMessageAsync(id.Value); var kvStore = new EmailBackedKeyValueStore(logger, readMessage); kvStore.SetTextContent("test text"); kvStore.SetHtmlContent("<div>test html</div>"); kvStore.SetJson("jsonValue", "{}"); kvStore.Set("object", new { Data = "test data" }); var newId = await folder.ReplaceAsync(id.Value, readMessage); Assert.IsTrue(newId.HasValue); await folder.SetFlagsAsync(newId.Value, MailKit.MessageFlags.Deleted, true); await folder.ExpungeAsync(); }
public async Task TestResolveParticipantPlaceholders() { using var kernel = new FakeItEasyMockingKernel(); kernel.Rebind <ILogger>().ToConstant(Log.Logger); kernel.Rebind <ITeamsUserStore>().ToConstant(A.Fake <ITeamsUserStore>()).InSingletonScope(); kernel.Rebind <ITeamsUserRegistry>().To <TeamsUserRegistry>().InSingletonScope(); var userRegistry = kernel.Get <ITeamsUserRegistry>(); var logger = kernel.Get <ILogger>(); var fakeContext = new TeamsDataContext((TeamsParticipant)"8:orgid:00000000-0000-beef-0000-000000000000", new ProcessedTenant(new Tenant() { tenantId = "Tenant ID", userId = "8:orgid:00000000-0000-beef-0000-000000000000", tenantName = "Fake User" }, DateTime.UtcNow)); await userRegistry.RegisterDisplayNameForUserIdAsync(fakeContext, (TeamsParticipant)"12300000-0000-beef-0000-000000000000", "Test Name", DateTime.UtcNow); var message = A.Fake <IMutableChatMessage>(); message.MessageSubject = "User {{12300000-0000-beef-0000-000000000000}} added: User {{12300000-0000-beef-0000-000000000000}}, Heinrich Ulbricht"; await TeamsChatRetriever.ResolveParticipantPlaceholders(logger, userRegistry, fakeContext, message); Assert.AreEqual("Test Name added: Test Name, Heinrich Ulbricht", message.MessageSubject); }
public async Task TestModifyingExistingMessage2() { using var kernel = new FakeItEasyMockingKernel(); kernel.Rebind <ILogger>().ToConstant(Log.Logger); kernel.Rebind <Configuration>().ToConstant(config); kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope(); var conFac = kernel.Get <ImapConnectionFactory>(); var logger = kernel.Get <ILogger>(); var imapClient = await conFac.GetImapConnectionAsync(); var folder = imapClient.Inbox; await folder.OpenAsync(MailKit.FolderAccess.ReadWrite); var message = new MimeMessage(); message.From.Add(new MailboxAddress(Constants.AppName, Constants.AppFakeEmail)); message.To.Add(new MailboxAddress(Constants.AppName, Constants.AppFakeEmail)); message.Subject = "Delete me"; var id = await folder.AppendAsync(message); var readMessage = await folder.GetMessageAsync(id.Value); var wrap = new MimeMessageWrapper(logger, readMessage); wrap.TextContent = "test text"; wrap.HtmlContent = "HTML content"; wrap.MessageSubject = "Delete me - changed subject"; var newId = await folder.ReplaceAsync(id.Value, readMessage); Assert.IsTrue(newId.HasValue); await folder.SetFlagsAsync(newId.Value, MailKit.MessageFlags.Deleted, true); await folder.ExpungeAsync(); }
public async Task TestWriteAccess() { using var kernel = new FakeItEasyMockingKernel(); kernel.Rebind <ILogger>().ToConstant(Log.Logger); kernel.Rebind <Configuration>().ToConstant(config); kernel.Rebind <ImapBackedDatabase>().ToSelf().InSingletonScope(); var logger = kernel.Get <ILogger>(); var fac = kernel.Get <ImapConnectionFactory>(); var remoteLock = kernel.Get <ImapBackedRemoteLock>(); var db = new ImapBackedDatabase(logger, fac, remoteLock); var folderName = "TestEmailBackedDatabase_TestWriteAccess"; ImapTestUtils.RemoveFolder(folderName, config); ImapTestUtils.CreateFolder(folderName, config); var imapClient = await fac.GetImapConnectionAsync(); try { int dbValue = rand.Next(); var(kvStore, lockResult) = await db.LockStoreForWriting(folderName, "Fictional Store"); kvStore.Set("dbkey", dbValue); var uid = await db.WriteAndUnlockStore(folderName, kvStore, lockResult); Assert.IsTrue(uid.HasValue && uid.Value.IsValid); var readOnlyStore = await db.GetStoreForReading(folderName, "Fictional Store"); var prevValue = readOnlyStore.GetOrCreateEmpty <int>("dbkey"); Assert.AreEqual(dbValue, prevValue.AsObject); } finally { await imapClient.DisconnectAsync(true); } }
public async Task TestWaitForLockTimeout() { using var kernel = new FakeItEasyMockingKernel(); kernel.Rebind <ILogger>().ToConstant(Log.Logger); kernel.Rebind <Configuration>().ToConstant(config); kernel.Rebind <ImapStore>().ToSelf().InSingletonScope(); kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope(); var imapFac = kernel.Get <ImapConnectionFactory>(); var remoteLock = kernel.Get <ImapBackedRemoteLock>(); remoteLock.LockTimeOut = TimeSpan.FromSeconds(3); using var connection = await imapFac.GetImapConnectionAsync(); var parentFolder = await connection.GetFolderAsync(connection.PersonalNamespaces[0].Path); await remoteLock.ReleaseLock(parentFolder, "resourcelock", -1); var successfulLock = await remoteLock.AcquireLock(parentFolder, "resourcelock"); var unsuccessfulLock = await remoteLock.AcquireLock(parentFolder, "resourcelock"); Assert.IsFalse(unsuccessfulLock.IsSuccess); Assert.IsTrue(unsuccessfulLock.TryAgainIn.TotalSeconds >= 1 && unsuccessfulLock.TryAgainIn.TotalSeconds < 3); await Task.Delay(unsuccessfulLock.TryAgainIn); var secondSuccessfulLock = await remoteLock.AcquireLock(parentFolder, "resourcelock"); Assert.IsTrue(secondSuccessfulLock.IsSuccess); // got new cookie? Assert.AreNotEqual(successfulLock.ResultingLockCookie, secondSuccessfulLock.ResultingLockCookie); var unlockResult = await remoteLock.ReleaseLock(parentFolder, "resourcelock", secondSuccessfulLock.ResultingLockCookie.Value); Assert.IsTrue(unlockResult); }
public async Task TestBotAndChatReplacement() { using var kernel = new FakeItEasyMockingKernel(); kernel.Rebind <ILogger>().ToConstant(Log.Logger); kernel.Rebind <ITeamsUserStore>().ToConstant(A.Fake <ITeamsUserStore>()).InSingletonScope(); kernel.Rebind <ITeamsUserRegistry>().To <TeamsUserRegistry>().InSingletonScope(); var userRegistry = kernel.Get <ITeamsUserRegistry>(); var fakeContext = new TeamsDataContext((TeamsParticipant)"8:orgid:00000000-0000-beef-0000-000000000000", new ProcessedTenant(new Tenant() { tenantId = "Tenant ID", userId = "8:orgid:00000000-0000-beef-0000-000000000000", tenantName = "Fake User" }, DateTime.UtcNow)); await userRegistry.RecognizeUserIdAsync(fakeContext, (TeamsParticipant)"817c2506-de4a-4795-971e-371ea75a03ed"); // polly await userRegistry.RecognizeUserIdAsync(fakeContext, (TeamsParticipant)"19:00000000-0000-beef-0000-000000000000_00000000-0000-beef-0000-000000000000@unq.gbl.spaces"); // a chat string s; s = await userRegistry.ReplaceUserIdsWithDisplayNamesAsync(fakeContext, "817c2506-de4a-4795-971e-371ea75a03ed, 19:00000000-0000-beef-0000-000000000000_00000000-0000-beef-0000-000000000000@unq.gbl.spaces"); Assert.AreEqual("Polly, Microsoft Teams Chat", s); }
public async Task TestReleaseWithoutAcquisition() { using var kernel = new FakeItEasyMockingKernel(); kernel.Rebind <ILogger>().ToConstant(Log.Logger); kernel.Rebind <Configuration>().ToConstant(config); kernel.Rebind <ImapStore>().ToSelf().InSingletonScope(); kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope(); var imapFac = kernel.Get <ImapConnectionFactory>(); var remoteLock = kernel.Get <ImapBackedRemoteLock>(); remoteLock.LockTimeOut = TimeSpan.FromSeconds(5); using var connection = await imapFac.GetImapConnectionAsync(); var parentFolder = await connection.GetFolderAsync(connection.PersonalNamespaces[0].Path); await remoteLock.ReleaseLock(parentFolder, "resourcelock", -1); var result = await remoteLock.ReleaseLock(parentFolder, "resourcelock", 1234); Assert.IsTrue(result); }
public async Task TestWriteAndReadManyUsers() { using var kernel = new FakeItEasyMockingKernel(); kernel.Rebind <ILogger>().ToConstant(Log.Logger); kernel.Rebind <Configuration>().ToConstant(config); kernel.Rebind <ITeamsUserStore>().To <ImapStore>().InSingletonScope(); var imapStore = kernel.Get <ITeamsUserStore>(); var sw = new Stopwatch(); sw.Start(); for (var i = 0; i < 10; i++) { var user = new ProcessedTeamsUser(fakeContext, (TeamsParticipant)i.ToString()); user.RegisterAlternateDisplayName("Massentest", DateTime.UtcNow); user.RegisterAlternateEmailAddress("heinrich.ulbricht@localhost", DateTime.UtcNow); await imapStore.PersistUserAsync(fakeContext, user); } var users = await imapStore.RetrieveUsersAsync(fakeContext); sw.Stop(); Assert.IsTrue(sw.ElapsedMilliseconds < 10000, "Needing quite a lot of time to store users"); }
public async Task TestMriReplacement() { using var kernel = new FakeItEasyMockingKernel(); kernel.Rebind <ILogger>().ToConstant(Log.Logger); kernel.Rebind <ITeamsUserStore>().ToConstant(A.Fake <ITeamsUserStore>()).InSingletonScope(); kernel.Rebind <ITeamsUserRegistry>().To <TeamsUserRegistry>().InSingletonScope(); var userRegistry = kernel.Get <ITeamsUserRegistry>(); var fakeContext = new TeamsDataContext((TeamsParticipant)"8:orgid:00000000-0000-beef-0000-000000000000", new ProcessedTenant(new Tenant() { tenantId = "Tenant ID", userId = "8:orgid:00000000-0000-beef-0000-000000000000", tenantName = "Fake User" }, DateTime.UtcNow)); var userId = (TeamsParticipant)"8:orgid:00000000-0000-beef-0000-000000000000"; await userRegistry.RecognizeUserIdAsync(fakeContext, userId); await userRegistry.RegisterDisplayNameForUserIdAsync(fakeContext, userId, "User Name", DateTime.UtcNow); var user = await userRegistry.GetUserByIdAsync(fakeContext, userId, false); Assert.AreEqual("User Name", user.DisplayName); string s; s = await userRegistry.ReplaceUserIdsWithDisplayNamesAsync(fakeContext, "8:orgid:00000000-0000-beef-0000-000000000000"); Assert.AreEqual("User Name", s); s = await userRegistry.ReplaceUserIdsWithDisplayNamesAsync(fakeContext, "00000000-0000-beef-0000-000000000000"); Assert.AreEqual("User Name", s); s = await userRegistry.ReplaceUserIdsWithDisplayNamesAsync(fakeContext, "00000000-0000-beef-0000-000000000000, 00000000-0000-beef-0000-000000000000"); Assert.AreEqual("User Name, User Name", s); s = await userRegistry.ReplaceUserIdsWithDisplayNamesAsync(fakeContext, "8:00000000-0000-beef-0000-000000000000"); Assert.AreEqual("User Name", s); }
public async Task TestReadOnlyAccess() { using var kernel = new FakeItEasyMockingKernel(); kernel.Rebind <ILogger>().ToConstant(Log.Logger); kernel.Rebind <Configuration>().ToConstant(config); kernel.Rebind <ImapBackedDatabase>().ToSelf().InSingletonScope(); var logger = kernel.Get <ILogger>(); var fac = kernel.Get <ImapConnectionFactory>(); var remoteLock = kernel.Get <ImapBackedRemoteLock>(); var db = new ImapBackedDatabase(logger, fac, remoteLock); var folderName = "TestEmailBackedDatabase_TestReadOnlyAccess"; ImapTestUtils.RemoveFolder(folderName, config); ImapTestUtils.CreateFolder(folderName, config); var imapClient = await fac.GetImapConnectionAsync(); try { var testheadervalue = rand.Next().ToString(); var store = await db.GetStoreForReading(folderName, "Fictional Store", message => { message.Subject = "[META] Fictional Store"; message.Headers.Add("testheaderkey", testheadervalue); }); var folder = await imapClient.GetFolderAsync(folderName); folder.Open(FolderAccess.ReadOnly); var metaMessage = await folder.GetMessageAsync(store.MessageAndId.UniqueId); Assert.IsTrue(metaMessage.Headers.Contains("testheaderkey")); Assert.AreEqual(testheadervalue, metaMessage.Headers["testheaderkey"]); } finally { await imapClient.DisconnectAsync(true); } }
public async Task TestStoreAndGetAllChatMetadata() { using var kernel = new FakeItEasyMockingKernel(); kernel.Rebind <ILogger>().ToConstant(Log.Logger); kernel.Rebind <Configuration>().ToConstant(config); kernel.Rebind <ITeamsChatStore>().To <ImapStore>().InSingletonScope(); var chatStore = kernel.Get <ITeamsChatStore>(); var chat1 = new ProcessedChat(new TeamsInternal.TeamsInternalApi.api.csa.api.v1.teams.users.Chat() { id = "chat1", version = 10, threadVersion = 1000 }); await chatStore.StoreMailThreadAndUpdateMetadataAsync(fakeContext, "TestGetAllChatMetadata_1", chat1, null); var chat2 = new ProcessedChat(new TeamsInternal.TeamsInternalApi.api.csa.api.v1.teams.users.Chat() { id = "chat2", version = 20, threadVersion = 2000 }); await chatStore.StoreMailThreadAndUpdateMetadataAsync(fakeContext, "TestGetAllChatMetadata_2", chat2, null); //await chatStore.GetAllChatMetadataRecursivelyAsync(fakeContext); //Assert.IsTrue(sw.ElapsedMilliseconds < 10000, "Needing quite a lot of time to store users"); }
public async Task TestModSeqBasedLockingInGeneral() { using var kernel = new FakeItEasyMockingKernel(); kernel.Rebind <ILogger>().ToConstant(Log.Logger); kernel.Rebind <Configuration>().ToConstant(config); kernel.Rebind <ImapStore>().ToSelf().InSingletonScope(); kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope(); var imapFac = kernel.Get <ImapConnectionFactory>(); var logger = kernel.Get <ILogger>(); logger.Debug("=====> START"); using var con1 = await imapFac.GetImapConnectionAsync(); var parentFolder = await con1.GetFolderAsync(con1.PersonalNamespaces[0].Path); var mailFolder = parentFolder.GetSubfolder(testFolderName); mailFolder.Open(FolderAccess.ReadWrite); var id = mailFolder.Append(GetMessage("Lock", "0")); mailFolder.Fetch(new List <UniqueId>() { id.Value }, MessageSummaryItems.ModSeq); mailFolder.Append(GetMessage("Counter inside", "0")); con1.Disconnect(true); var taskCount = 9; var loopCount = 20; for (var loop = 0; loop < loopCount; loop++) { var tasks = new List <Task>(); for (var i = 0; i < taskCount; i++) { CreateTask createTask = (int index) => Task.Run(() => { var taskIndex = index; logger.Debug("{0:00} Starting task", taskIndex); int cookie; lock (rand) { cookie = rand.Next(); } #pragma warning disable CS0618 // Type or member is obsolete var cookiestring = $"{taskIndex}-{AppDomain.GetCurrentThreadId()}-{cookie}"; #pragma warning restore CS0618 // Type or member is obsolete logger.Debug("{0:00} Cookiestring: {1}", taskIndex, cookiestring); using var con2 = imapFac.GetImapConnectionAsync().Result; var parentFolder = con2.GetFolder(con2.PersonalNamespaces[0].Path); var mailFolder = parentFolder.GetSubfolder(testFolderName); mailFolder.UidValidityChanged += (a, b) => { logger.Warning("0:00 UI VALIDITY changed!", taskIndex); }; mailFolder.Open(FolderAccess.ReadWrite); var idOfLockEmail = mailFolder.Search(SearchQuery.SubjectContains("Lock")).Single(); logger.Debug("{0:00} Lock email ID: {1}", taskIndex, idOfLockEmail); try { IMessageSummary summary; IList <UniqueId> failList; var keywords = new HashSet <string>() { cookiestring, DateTime.UtcNow.ToFileTimeUtc().ToString() }; ulong modSeqMax; do { // might return multiple unrelated summaries... var summaries = mailFolder.Fetch(new List <UniqueId>() { idOfLockEmail }, MessageSummaryItems.Flags | MessageSummaryItems.UniqueId | MessageSummaryItems.ModSeq); if (summaries.Where(s => s.UniqueId == idOfLockEmail && s.Keywords?.Count > 0).Any()) { logger.Debug("{0:00} Got summary with keywords, need to wait", taskIndex); Task.Delay(rand.Next(100, 2000)).Wait(); continue; } logger.Debug("{0:00} Got summary without keywords - trying to set them", taskIndex); summary = summaries.Where(s => s.UniqueId == idOfLockEmail).Single(); modSeqMax = summary.ModSeq.Value; //summary = mailFolder.Fetch(indizes, MessageSummaryItems.ModSeq | MessageSummaryItems.UniqueId); failList = mailFolder.SetFlags(new List <UniqueId>() { idOfLockEmail }, modSeqMax, MessageFlags.UserDefined, keywords, false); if (failList.Count > 0) { logger.Debug("{0:00} Could not set keywords with modSeq {1}, starting over", taskIndex, modSeqMax); Task.Delay(rand.Next(100, 2000)).Wait(); continue; } else { logger.Debug("{0:00} Successfully set keywords, modSeq was {1}", taskIndex, modSeqMax); // really?? check this... var lockMessageSummary = mailFolder .Fetch(new List <UniqueId>() { idOfLockEmail }, MessageSummaryItems.Flags | MessageSummaryItems.UniqueId | MessageSummaryItems.ModSeq) .Where(s => s.UniqueId == idOfLockEmail) .SingleOrDefault(); if (lockMessageSummary == null) { logger.Error("{0:00} Could not fetch lock message summary!", taskIndex); } logger.Debug("{0:00} Got lock messgage keywords: {1}", taskIndex, lockMessageSummary.Keywords); if (lockMessageSummary.Keywords.Count > 2) { cookie = rand.Next(); #pragma warning disable CS0618 // Type or member is obsolete cookiestring = $"{taskIndex}-{AppDomain.GetCurrentThreadId()}-{cookie}"; #pragma warning restore CS0618 // Type or member is obsolete keywords = new HashSet <string>() { cookiestring, DateTime.UtcNow.ToFileTimeUtc().ToString() }; // with Dovecot it sometimes happened that two threads succeed in setting their keywords although only one should succeed (as both use the same modSeq number) logger.Warning("{0:00} Got wrong number of keywords, starting over with new keywords for thread: {1}", taskIndex, keywords); mailFolder.RemoveFlags(new List <UniqueId>() { idOfLockEmail }, MessageFlags.UserDefined, lockMessageSummary.Keywords, true); continue; } if (!lockMessageSummary.Keywords.Contains(cookiestring)) { // with Dovecot it sometimes happened that sometimes the keywords cannot be set but failList nevertheless is empty logger.Warning("{0:00} Control keyword f-up: {1} (expected cookiestring {2}); starting over", lockMessageSummary.Keywords, cookiestring); continue; } Assert.AreEqual(2, lockMessageSummary.Keywords.Count); break; } } while (true); logger.Debug("{0:00} Increasing count section", taskIndex); summary = mailFolder .Fetch(new List <UniqueId>() { idOfLockEmail }, MessageSummaryItems.ModSeq) .Where(s => s.UniqueId == idOfLockEmail) .Single(); var idOfCounterEmail = mailFolder.Search(SearchQuery.SubjectContains("Counter inside")).Single(); // increase count var loadedMessage = mailFolder.GetMessage(idOfCounterEmail); var count = int.Parse(loadedMessage.TextBody); logger.Debug("{0:00} Got old count: {1}", taskIndex, count); var newBody = $"{count + 1}"; // note: the UniqueId does change logger.Debug("{0:00} Updating count mail", taskIndex); idOfCounterEmail = mailFolder.Replace(idOfCounterEmail, GetMessage("Counter inside", newBody), MessageFlags.None).Value; Assert.IsNotNull(idOfCounterEmail); Assert.IsTrue(idOfCounterEmail.IsValid); //Assert.AreEqual(modSeqMax + 4, mailFolder.HighestModSeq); logger.Debug("{0:00} Removing keywords", taskIndex); mailFolder.RemoveFlags(new List <UniqueId>() { idOfLockEmail }, MessageFlags.UserDefined, keywords, true); //Assert.AreEqual(0, failList.Count, "Somebody removed keywords in parallel which must not happen"); logger.Debug("{0:00} DONE", taskIndex); } catch { Debugger.Break(); } finally { con2.Disconnect(true); } logger.Debug("Exiting task {0}", taskIndex); }); tasks.Add(createTask(i)); } await Task.WhenAll(tasks); } using var con3 = await imapFac.GetImapConnectionAsync(); var parentFolder2 = await con3.GetFolderAsync(con3.PersonalNamespaces[0].Path); var mailFolder2 = parentFolder2.GetSubfolder(testFolderName); mailFolder2.Open(FolderAccess.ReadWrite); var idOfCounterEmail = mailFolder2.Search(SearchQuery.SubjectContains("Counter inside")).Single(); var msg = mailFolder2.GetMessage(idOfCounterEmail); con3.Disconnect(true); Assert.AreEqual(taskCount * loopCount, int.Parse(msg.TextBody)); }
public async Task TestLockingWithEmailBackedRemoteLockImplementation() { using var kernel = new FakeItEasyMockingKernel(); kernel.Rebind <ILogger>().ToConstant(Log.Logger); kernel.Rebind <Configuration>().ToConstant(config); kernel.Rebind <ImapStore>().ToSelf().InSingletonScope(); kernel.Rebind <ImapConnectionFactory>().ToSelf().InSingletonScope(); var remoteLock = kernel.Get <ImapBackedRemoteLock>(); var imapFac = kernel.Get <ImapConnectionFactory>(); var logger = kernel.Get <ILogger>(); logger.Debug("=====> START"); using var con1 = await imapFac.GetImapConnectionAsync(); var parentFolder = await con1.GetFolderAsync(con1.PersonalNamespaces[0].Path); var lockFolder = parentFolder.GetSubfolder(testFolderName); lockFolder.Open(FolderAccess.ReadWrite); lockFolder.Append(GetMessage("Counter inside", "0")); var lockFolderName = "locktest"; // release any old lock await remoteLock.ReleaseLock(lockFolder, lockFolderName, -1); con1.Disconnect(true); var taskCount = 2; var loopCount = 20; for (var loop = 0; loop < loopCount; loop++) { var tasks = new List <Task>(); for (var i = 0; i < taskCount; i++) { CreateTask createTask = (int index) => Task.Run(async() => { var taskIndex = index; logger.Debug("{0:00} Starting task", taskIndex); using var con2 = imapFac.GetImapConnectionAsync().Result; var parentFolder = con2.GetFolder(con2.PersonalNamespaces[0].Path); var lockFolder = parentFolder.GetSubfolder(testFolderName); var lockResult = await remoteLock.AcquireLockRetry(lockFolder, lockFolderName, agressiveMode: true); Assert.IsTrue(lockResult.IsSuccess); Assert.IsNotNull(lockResult.ResultingLockCookie); logger.Debug("{0:00} Increasing count section", taskIndex); lockFolder.Open(FolderAccess.ReadWrite); var idOfCounterEmail = lockFolder.Search(SearchQuery.SubjectContains("Counter inside")).Single(); // increase count var loadedMessage = lockFolder.GetMessage(idOfCounterEmail); var count = int.Parse(loadedMessage.TextBody); logger.Debug("{0:00} Got old count: {1}", taskIndex, count); var newBody = $"{count + 1}"; // note: the UniqueId does change logger.Debug("{0:00} Updating count mail", taskIndex); idOfCounterEmail = lockFolder.Replace(idOfCounterEmail, GetMessage("Counter inside", newBody), MessageFlags.None).Value; Assert.IsNotNull(idOfCounterEmail); Assert.IsTrue(idOfCounterEmail.IsValid); await remoteLock.ReleaseLock(lockFolder, lockFolderName, lockResult.ResultingLockCookie.Value); con2.Disconnect(true); }); tasks.Add(createTask(i)); } await Task.WhenAll(tasks); } using var con3 = await imapFac.GetImapConnectionAsync(); var parentFolder2 = await con3.GetFolderAsync(con3.PersonalNamespaces[0].Path); var mailFolder2 = parentFolder2.GetSubfolder(testFolderName); mailFolder2.Open(FolderAccess.ReadWrite); var idOfCounterEmail = mailFolder2.Search(SearchQuery.SubjectContains("Counter inside")).Single(); var msg = mailFolder2.GetMessage(idOfCounterEmail); con3.Disconnect(true); Assert.AreEqual(taskCount * loopCount, int.Parse(msg.TextBody)); }