public Version18MigrationStepFacts()
        {
            var dbContext = ConnectionUtils.CreateDbContext();

            _database = dbContext.Database;
            _mongoMigrationBagMock = new Mock <IMongoMigrationContext>(MockBehavior.Strict);
        }
Пример #2
0
        // [InlineData("Hangfire-Mongo-Schema-018.zip", true)]
        public void Migrate_Full_Success(string seedFile, bool assertCollectionHasItems)
        {
            var dbContext = ConnectionUtils.CreateDbContext("Hangfire-Mongo-Migration-Tests");

            // ARRANGE
            dbContext.Client.DropDatabase(dbContext.Database.DatabaseNamespace.DatabaseName);
            if (seedFile != null)
            {
                SeedCollectionFromZipArchive(dbContext, Path.Combine("Migration", seedFile));
            }

            var storageOptions = new MongoStorageOptions
            {
                MigrationOptions = new MongoMigrationOptions
                {
                    MigrationStrategy = new MigrateMongoMigrationStrategy(),
                    BackupStrategy    = new NoneMongoBackupStrategy()
                }
            };

            var migrationManager = new MongoMigrationManager(storageOptions, dbContext.Database);

            // ACT
            MongoMigrationManager.MigrateIfNeeded(storageOptions, dbContext.Database);

            // ASSERT
            AssertDataIntegrity(dbContext, assertCollectionHasItems);
        }
Пример #3
0
        public MongoRunFixture()
        {
            var databaseName = "Mongo-Hangfire-CamelCase";
            var context      = ConnectionUtils.CreateDbContext(databaseName);

            DbContext = context;
            // Make sure we start from scratch
            context.Database.Client.DropDatabase(databaseName);

            var storageOptions = new MongoStorageOptions
            {
                MigrationOptions = new MongoMigrationOptions
                {
                    MigrationStrategy = new DropMongoMigrationStrategy(),
                    BackupStrategy    = new NoneMongoBackupStrategy()
                }
            };

            JobStorage.Current = ConnectionUtils.CreateStorage(storageOptions, databaseName);

            var conventionPack = new ConventionPack {
                new CamelCaseElementNameConvention()
            };

            ConventionRegistry.Register("CamelCase", conventionPack, t => true);

            _server = new BackgroundJobServer(new BackgroundJobServerOptions
            {
                SchedulePollingInterval = TimeSpan.FromMilliseconds(100)
            });
        }
Пример #4
0
        private void BackupDatabaseToStream(string databaseName, Stream stream, params string[] allowedEmptyCollections)
        {
            using (var archive = new ZipArchive(stream, ZipArchiveMode.Create, true))
            {
                var context = ConnectionUtils.CreateDbContext(databaseName);
                foreach (var collectionName in context.Database.ListCollections().ToList()
                         .Select(c => c["name"].AsString))
                {
                    var fileName       = $@"{collectionName}.json";
                    var collectionFile = archive.CreateEntry(fileName);

                    var collection = context.Database.GetCollection <BsonDocument>(collectionName);
                    var jsonDocs   = collection.Find(Builders <BsonDocument> .Filter.Empty)
                                     .ToList()
                                     .Select(d => d.ToJson(JsonWriterSettings.Defaults))
                                     .ToList();

                    Assert.True(jsonDocs.Any() || allowedEmptyCollections.Contains(collectionName),
                                $@"Expected collection '{collectionName}' to contain documents");

                    using (var entryStream = collectionFile.Open())
                    {
                        using (var streamWriter = new StreamWriter(entryStream))
                        {
                            streamWriter.Write("[" + string.Join(",", jsonDocs) + "]");
                        }
                    }
                }
            }
        }
Пример #5
0
 private static void UseConnection(Action <HangfireDbContext> action)
 {
     using (var connection = ConnectionUtils.CreateDbContext())
     {
         action(connection);
     }
 }
 private void UseMonitoringApi(Action <HangfireDbContext, MongoMonitoringApi> action)
 {
     using (var database = ConnectionUtils.CreateDbContext())
     {
         var connection = new MongoMonitoringApi(database);
         action(database, connection);
     }
 }
Пример #7
0
        public Version19MigrationStepFacts()
        {
            var dbContext = ConnectionUtils.CreateDbContext();

            _database = dbContext.Database;
            _mongoMigrationBagMock = new Mock <IMongoMigrationContext>(MockBehavior.Strict);
            _random          = new Random();
            _addTypeToSetDto = new AddTypeToSetDto();
        }
Пример #8
0
        public MongoConnectionFacts()
        {
            _jobQueueSemaphoreMock = new Mock <IJobQueueSemaphore>(MockBehavior.Strict);
            var storageOptions = new MongoStorageOptions {
                Factory = { JobQueueSemaphore = _jobQueueSemaphoreMock.Object }
            };

            _dbContext  = ConnectionUtils.CreateDbContext();
            _connection = new MongoConnection(_dbContext, storageOptions);
        }
Пример #9
0
        public MongoJobQueueFacts()
        {
            _jobQueueSemaphoreMock = new Mock <IJobQueueSemaphore>(MockBehavior.Strict);
            var queue    = "default";
            var timedOut = false;

            _jobQueueSemaphoreMock.Setup(s =>
                                         s.WaitAny(DefaultQueues, It.IsAny <CancellationToken>(), It.IsAny <TimeSpan>(), out queue, out timedOut))
            .Returns(true);
            _hangfireDbContext = ConnectionUtils.CreateDbContext();
        }
Пример #10
0
        public void GetVersion_FromDb_Success()
        {
            // ARRANGE
            var db = ConnectionUtils.CreateDbContext();

            // ACT
            var version = MongoVersionHelper.GetVersion(db.Database);

            // ASSERT
            // no exception
        }
        public void GetVersion_FromDb_Success()
        {
            // ARRANGE
            using (var connection = ConnectionUtils.CreateDbContext())
            {
                // ACT
                var version = MongoVersionHelper.GetVersion(connection.Database);
            }

            // ASSERT
            // no exception
        }
Пример #12
0
        public void CamelCaseConvention_HangfireMongoDtos_StillInPascal()
        {
            // ARRANGE
            var mongoStorage = new MongoStorage(
                MongoClientSettings.FromConnectionString(ConnectionUtils.GetConnectionString()),
                ConnectionUtils.GetDatabaseName(), new MongoStorageOptions
            {
                MigrationOptions = new MongoMigrationOptions
                {
                    Strategy       = MongoMigrationStrategy.Drop,
                    BackupStrategy = MongoBackupStrategy.None
                }
            }
                );

            var id        = Guid.NewGuid();
            var dbContext = ConnectionUtils.CreateDbContext();

            JobStorage.Current = mongoStorage;

            bool jobScheduled;

            var conventionPack = new ConventionPack {
                new CamelCaseElementNameConvention()
            };

            ConventionRegistry.Register("CamelCase", conventionPack, t => true);

            // ACT
            using (new BackgroundJobServer(new BackgroundJobServerOptions
            {
                SchedulePollingInterval = TimeSpan.FromMilliseconds(100)
            }))
            {
                BackgroundJob.Enqueue(() => Signal.Set(id));
                jobScheduled = Signal.WaitOne(id, TimeSpan.FromSeconds(1));
            }

            // ASSERT
            var jobGraphCollectionName = dbContext.JobGraph.CollectionNamespace.CollectionName;
            var jobDto = dbContext
                         .Database
                         .GetCollection <BsonDocument>(jobGraphCollectionName)
                         .Find(new BsonDocument("expireAt", new BsonDocument("$exists", true)))
                         .FirstOrDefault();

            Assert.Null(jobDto);
            Assert.True(jobScheduled, "Expected job to be scheduled");
        }
Пример #13
0
        public void Conventions_UsesOwnConventionsForDtoNameSpace_WhenCamelCaseIsRegistered()
        {
            // ARRANGE
            var conventionPack = new ConventionPack {
                new CamelCaseElementNameConvention()
            };

            ConventionRegistry.Register("camelCase", conventionPack, t => true);

            // ACT
            // This line will throw during migration if camelCase is active for the Dto namespace.
            var connection = ConnectionUtils.CreateDbContext();

            // ASSERT
            Assert.NotNull(connection);
        }
        public MongoNotificationObserverErrorFacts()
        {
            _dbContext                = ConnectionUtils.CreateDbContext();
            _jobQueueSemaphoreMock    = new Mock <IJobQueueSemaphore>(MockBehavior.Strict);
            _distributedLockMutexMock = new Mock <IDistributedLockMutex>(MockBehavior.Strict);
            var mongoNotificationObserver = new MongoNotificationObserver(_dbContext, _jobQueueSemaphoreMock.Object,
                                                                          _distributedLockMutexMock.Object);

            _dbContext.Database.DropCollection(_dbContext.Notifications.CollectionNamespace.CollectionName);
            _cts = new CancellationTokenSource();

            Task.Run(async() =>
            {
                await Task.Yield();
                mongoNotificationObserver.Execute(_cts.Token);
            });
            Thread.Sleep(1000);
        }
Пример #15
0
        public void Migrate_MultipleInstances_ThereCanBeOnlyOne()
        {
            var dbContext = ConnectionUtils.CreateDbContext();

            // ARRANGE
            dbContext.Database.DropCollection(dbContext.Schema.CollectionNamespace.CollectionName);
            var storageOptions = new MongoStorageOptions
            {
                MigrationOptions = new MongoMigrationOptions
                {
                    MigrationStrategy = new DropMongoMigrationStrategy(),
                    BackupStrategy    = new NoneMongoBackupStrategy()
                }
            };

            var signal        = new ManualResetEvent(false);
            var signalToStart = new ManualResetEvent(false);
            var taskCount     = 10;
            var tasks         = new Task <bool> [taskCount];
            var count         = 0;

            // ACT
            for (int i = 0; i < taskCount; i++)
            {
                tasks[i] = Task.Factory.StartNew <bool>(() =>
                {
                    count++;
                    if (count == taskCount)
                    {
                        signalToStart.Set();
                    }

                    signal.WaitOne();
                    return(MongoMigrationManager.MigrateIfNeeded(storageOptions, dbContext.Database));
                }, TaskCreationOptions.LongRunning);
            }

            signalToStart.WaitOne();
            signal.Set();
            Task.WaitAll(tasks);

            // ASSERT
            Assert.True(tasks.Select(t => t.Result).Single(b => b));
        }
Пример #16
0
        public void Migrate_DropNoBackup_Success()
        {
            var dbContext = ConnectionUtils.CreateDbContext("Hangfire-Mongo-Migration-Tests");

            // ARRANGE
            dbContext.Client.DropDatabase(dbContext.Database.DatabaseNamespace.DatabaseName);
            SeedCollectionFromZipArchive(dbContext, Path.Combine("Migration", "Hangfire-Mongo-Schema-006.zip"));

            var storageOptions = new MongoStorageOptions
            {
                MigrationOptions = new MongoMigrationOptions
                {
                    MigrationStrategy = new DropMongoMigrationStrategy(),
                    BackupStrategy    = new NoneMongoBackupStrategy()
                }
            };

            // ACT
            MongoMigrationManager.MigrateIfNeeded(storageOptions, dbContext.Database);

            // ASSERT
            AssertDataIntegrity(dbContext, assertCollectionHasItems: false);
        }
Пример #17
0
        //[Fact, Trait("Category", "DataGeneration")]
        public void Clean_Database_Filled()
        {
            var databaseName = "Mongo-Hangfire-Filled";
            var context      = ConnectionUtils.CreateDbContext(databaseName);

            // Make sure we start from scratch
            context.Database.Client.DropDatabase(databaseName);

            var storageOptions = new MongoStorageOptions
            {
                MigrationOptions = new MongoMigrationOptions
                {
                    MigrationStrategy = new DropMongoMigrationStrategy(),
                    BackupStrategy    = new NoneMongoBackupStrategy()
                },
                QueuePollInterval = TimeSpan.FromMilliseconds(500)
            };
            var serverOptions = new BackgroundJobServerOptions
            {
                ShutdownTimeout = TimeSpan.FromSeconds(15)
            };

            JobStorage.Current = ConnectionUtils.CreateStorage(databaseName);

            using (new BackgroundJobServer(serverOptions))
            {
                // Recurring Job
                RecurringJob.AddOrUpdate(() => HangfireTestJobs.ExecuteRecurringJob("Recurring job"), Cron.Minutely);

                // Scheduled job
                BackgroundJob.Schedule(() => HangfireTestJobs.ExecuteScheduledJob("Scheduled job"), TimeSpan.FromSeconds(30));

                // Enqueued job
                BackgroundJob.Enqueue(() => HangfireTestJobs.ExecuteEnqueuedJob("Enqueued job"));

                // Continued job
                var parentId = BackgroundJob.Schedule(() => HangfireTestJobs.ExecuteContinueWithJob("ContinueWith job", false), TimeSpan.FromSeconds(15));
                BackgroundJob.ContinueWith(parentId, () => HangfireTestJobs.ExecuteContinueWithJob("ContinueWith job continued", true));

                // Now the waiting game starts
                HangfireTestJobs.ScheduleEvent.WaitOne();
                BackgroundJob.Schedule(() => HangfireTestJobs.ExecuteScheduledJob("Scheduled job (*)"), TimeSpan.FromMinutes(30));

                HangfireTestJobs.ContinueWithEvent.WaitOne();
                HangfireTestJobs.RecurringEvent.WaitOne();

                HangfireTestJobs.EnqueueEvent.WaitOne();
                BackgroundJob.Enqueue(() => HangfireTestJobs.ExecuteEnqueuedJob("Enqueued job (*)"));
            }


            // Some data are cleaned up when hangfire shuts down.
            // Grab a copy so we can write it back - needed for migration tests.
            var connection = JobStorage.Current.GetConnection();

            connection.AnnounceServer("test-server", new ServerContext
            {
                WorkerCount = serverOptions.WorkerCount,
                Queues      = serverOptions.Queues
            });

            connection.AcquireDistributedLock("test-lock", TimeSpan.FromSeconds(30));

            // Create database snapshot in zip file
            var schemaVersion = (int)MongoMigrationManager.RequiredSchemaVersion;

            using (var stream = new FileStream($@"Hangfire-Mongo-Schema-{schemaVersion:000}.zip", FileMode.Create))
            {
                var allowedEmptyCollections = new List <string>
                {
                    "hangfire.migrationLock"
                };

                if (MongoMigrationManager.RequiredSchemaVersion >= MongoSchema.Version09 &&
                    MongoMigrationManager.RequiredSchemaVersion <= MongoSchema.Version15)
                {
                    // Signal collection work was initiated in schema version 9,
                    // and still not put to use in schema version 15.
                    allowedEmptyCollections.Add($@"{storageOptions.Prefix}.signal");
                }
                BackupDatabaseToStream(databaseName, stream, allowedEmptyCollections.ToArray());
            }
        }
 public MongoConnectionFacts()
 {
     _dbContext  = ConnectionUtils.CreateDbContext();
     _connection = new MongoConnection(_dbContext, new MongoStorageOptions());
 }
 public MongoMonitoringApiFacts()
 {
     _database      = ConnectionUtils.CreateDbContext();
     _monitoringApi = new MongoMonitoringApi(_database);
 }
Пример #20
0
        public ExpirationManagerFacts()
        {
            _dbContext = ConnectionUtils.CreateDbContext();

            _token = new CancellationToken(true);
        }