示例#1
0
 public void TestInitialize()
 {
     using (MyTrailsContext context = new MyTrailsContext())
     {
         context.ClearDatabase();
         context.SaveChanges();
     }
 }
        public void TestInitialize()
        {
            using (MyTrailsContext context = new MyTrailsContext())
            {
                context.ClearDatabase();
                context.SaveChanges();

                TripType tripType = context.TripTypes.First();
                this._anyTripTypeId = tripType.Id;
                this._anyTripTypeWtaId = tripType.WtaId;
            }

            this._anyTrail = new Trail
            {
                Name = "Any Trail Name",
                WtaId = "any-wta-id",
                Url = new Uri("http://any/trail/uri"),
            };

            this._wtaClientMock = new Mock<IWtaClient>(MockBehavior.Strict);
            this._wtaClientMock
                .Setup(wc => wc.FetchTripReports(It.IsAny<string>()))
                .Returns((string ti) => TaskExt.WrapInTask<IList<WtaTripReport>>(() => new List<WtaTripReport>
                {
                    new WtaTripReport
                    {
                        Title = "Any title",
                        Author = "Any author",
                        Date = DateTime.Now,
                        FullReportUrl = new Uri(new Uri("http://any.base.url"), AnyWtaTripReportId),
                        HikeType = this._anyTripTypeWtaId,
                        Photos = 
                        {
                            new Uri("http://any/domain/photoUrl.jpg"),
                        },
                    }
                }));
            this._wtaClientMock
                .Setup(wc => wc.BuildRetryPolicy(It.IsAny<ILog>()))
                .Returns(new RetryPolicy(new StubErrorDetectionStrategy(), retryCount: 0));

            this._extender = new TripReportExtender
            {
                WtaClient = this._wtaClientMock.Object,
                Logger = new StubLog(),
            };
        }
        /// <summary>
        /// Run the extender for the given trail ID.
        /// </summary>
        /// <param name="trailId">The ID of the trail to run for.</param>
        /// <returns>Task for asynchronous completion.</returns>
        private async Task RunExtender(int trailId)
        {
            using (MyTrailsContext context = new MyTrailsContext())
            {
                Trail trail = context.Trails.Find(trailId);
                await this._extender.Extend(trail, context);

                try
                {
                    context.SaveChanges();
                }
                catch (DbEntityValidationException ex)
                {
                    Assert.Fail("Datastore save failed with validation error: {0}", ex);
                }
            }
        }
        /// <summary>
        /// Add trail data to the datastore and return the trail id.
        /// </summary>
        /// <param name="trail">The trail to add to the datastore.</param>
        /// <returns>The ID of the added trail.</returns>
        private int AddTestData(Trail trail)
        {
            int id;
            using (MyTrailsContext context = new MyTrailsContext())
            {
                context.Trails.Add(trail);
                context.SaveChanges();

                id = trail.Id;
            }

            return id;
        }
示例#5
0
        public void ChecksRecentHeartbeat()
        {
            // Arrange
            using (MyTrailsContext context = new MyTrailsContext())
            {
                context.ImportLog.Add(new ImportLogEntry
                {
                    StartTime = DateTimeOffset.Now - TimeSpan.FromMinutes(1234),
                    LastHeartbeat = DateTimeOffset.Now,
                });

                context.SaveChanges();
            }

            // Act
            try
            {
                this._importer.Run().Wait();
            }
            catch (AggregateException ex)
            {
                // Assert - Expect InvalidOperationException
                ex.Handle(e => e is InvalidOperationException);
            }
        }
示例#6
0
        /// <summary>
        /// Attach heartbeats to the import log entry that the importer is running until cancellation is requested.
        /// </summary>
        /// <param name="entryId">Log entry ID to append heartbeats to.</param>
        /// <param name="token">Cancellation token to stop heartbeats.</param>
        /// <returns>Task for asynchronous runtime.</returns>
        private async Task SendHeartbeats(int entryId, CancellationToken token)
        {
            TimeSpan interval = this.Configuration.HeartbeatInterval;
            this.Logger.DebugFormat("Sending heartbeats at interval: {0}", interval);

            try
            {
                while (!token.IsCancellationRequested)
                {
                    await Task.Delay(interval, token);

                    using (MyTrailsContext context = new MyTrailsContext())
                    {
                        ImportLogEntry logEntry = context.ImportLog.Find(entryId);
                        logEntry.LastHeartbeat = DateTimeOffset.Now;

                        context.SaveChanges();
                    }
                }
            }
            catch (OperationCanceledException)
            {
                // Cancellation requested.
            }

            this.Logger.Debug("Finished heartbeating.");
        }
示例#7
0
        /// <summary>
        /// Import a new <see cref="WtaTrail"/>, or update an existing one.
        /// </summary>
        /// <param name="wtaTrail">The <see cref="WtaTrail"/> to import or update.</param>
        /// <param name="exists">Whether the trail already exists in the database.</param>
        /// <returns>Task for asynchronous completion.</returns>
        private async Task ImportOrUpdateTrail(WtaTrail wtaTrail, bool exists)
        {
            try
            {
                int trailId;
                using (MyTrailsContext trailContext = new MyTrailsContext())
                {
                    Trail trail;
                    if (exists)
                    {
                        trail = trailContext.Trails
                            .Where(t => t.WtaId == wtaTrail.Uid)
                            .First();
                        this.TrailFactory.UpdateTrail(trail, wtaTrail, trailContext);
                    }
                    else
                    {
                        trail = this.TrailFactory.CreateTrail(wtaTrail, trailContext);
                        trailContext.Trails.Add(trail);
                    }

                    trailContext.SaveChanges(this.Logger);
                    trailId = trail.Id;
                }

                IEnumerable<Task> extenderTasks = this.TrailExtenders
                    .Select(te => this.RunExtender(te, trailId));

                await Task.WhenAll(extenderTasks);
            }
            catch (Exception ex)
            {
                Interlocked.Increment(ref this._numImportErrors);
                this.Logger.ErrorFormat("Error importing trail '{0}': {1}", wtaTrail, ex);

                throw;
            }
        }
示例#8
0
        /// <summary>
        /// Execute a trail extender for a new trail.
        /// </summary>
        /// <param name="extender">The extender to run.</param>
        /// <param name="trailId">The trail ID to extend.</param>
        /// <returns>Task for asyncrhonous execution.</returns>
        private async Task RunExtender(ITrailExtender extender, int trailId)
        {
            using (MyTrailsContext trailContext = new MyTrailsContext())
            {
                Trail trail = trailContext.Trails.Find(trailId);
                await extender.Extend(trail, trailContext);

                trailContext.SaveChanges(this.Logger);
            }
        }
示例#9
0
        /// <summary>
        /// Add completion statistics to the import log and save it to the datastore.
        /// </summary>
        /// <param name="logEntryId">The ID log entry to finalize.</param>
        /// <param name="errorString">An error string to associate, or null if no error was found.</param>
        private void FinalizeAndCommitLog(int logEntryId, string errorString)
        {
            using (MyTrailsContext context = new MyTrailsContext())
            {
                ImportLogEntry logEntry = context.ImportLog.Find(logEntryId);

                logEntry.CompletedTrailsCount = context.Trails.Count();
                logEntry.CompletedTripReportsCount = context.TripReports.Count();
                logEntry.CompletedTime = DateTimeOffset.Now;
                logEntry.ErrorString = errorString;
                logEntry.ErrorsCount = this._numImportErrors;

                context.SaveChanges(this.Logger);
            }
        }
示例#10
0
        /// <summary>
        /// Create a new <see cref="ImportLogEntry"/> for the import run.
        /// </summary>
        /// <returns>The ID of the newly created <see cref="ImportLogEntry"/>.</returns>
        private int CreateImportLog()
        {
            int importLogId;
            using (MyTrailsContext context = new MyTrailsContext())
            {
                ImportLogEntry logEntry = new ImportLogEntry
                {
                    StartTime = DateTimeOffset.Now,
                    LastHeartbeat = DateTimeOffset.Now,
                    StartTrailsCount = context.Trails.Count(),
                    StartTripReportsCount = context.TripReports.Count(),
                };

                context.ImportLog.Add(logEntry);
                context.SaveChanges();

                importLogId = logEntry.Id;
            }

            return importLogId;
        }
        /// <summary>
        /// Run <see cref="DrivingDistanceExtender.Extend"/> and save database context changes.
        /// </summary>
        /// <param name="trailId">The ID of the trail to add driving directions for.</param>
        private void RunExtender(int trailId)
        {
            using (MyTrailsContext context = new MyTrailsContext())
            {
                Trail trail = context.Trails.Find(trailId);
                this._extender.Extend(trail, context).Wait();

                context.SaveChanges();
            }
        }
        /// <summary>
        /// Register test data with the datastore context.
        /// </summary>
        /// <param name="trail">Test trail to register.</param>
        /// <param name="addresses">The test addresses to register.</param>
        /// <returns>The ID of the trail in the datastore.</returns>
        private int RegisterTestData(Trail trail, params Address[] addresses)
        {
            int trailId;
            using (MyTrailsContext context = new MyTrailsContext())
            {
                context.Trails.Add(trail);
                foreach (Address address in addresses)
                {
                    context.Addresses.Add(address);
                }

                context.SaveChanges();
                trailId = trail.Id;
            }

            return trailId;
        }
        /// <summary>
        /// Clear test data from the database.
        /// </summary>
        private void ClearDatabase()
        {
            using (MyTrailsContext trailContext = new MyTrailsContext())
            {
                trailContext.ClearDatabase();
                trailContext.Addresses.Truncate();

                trailContext.SaveChanges();
            }
        }