public async override Task<Result> ImportAsync(string fileName, CancellationToken cancellationToken)
        {
            var result = await ReadAsXmlFromDiskAsync<List<ScheduledTaskBackup>>(fileName);

            if (result.HasError)
                return Result.ReportError(result.Message);

            var skippedCount = 0;
            var newSTs = new List<DataModel.ScheduledTask>();

            using (var context = new ZvsContext(EntityContextConnection))
            {
                var existingScheduledTasks = await context.ScheduledTasks
                    .ToListAsync(cancellationToken);

                foreach (var scheduledTaskBackup in result.Data)
                {
                    if (existingScheduledTasks.Any(o => o.Name == scheduledTaskBackup.Name))
                    {
                        skippedCount++;
                        continue;
                    }

                    var cmd =
                        await
                            StoredCmdBackup.RestoreStoredCommandAsync(context, scheduledTaskBackup.StoredCommand,
                                cancellationToken);
                    if (cmd == null) continue;

                    var task = new DataModel.ScheduledTask
                    {
                        Argument = cmd.Argument,
                        Argument2 = cmd.Argument2,
                        CommandId = cmd.CommandId,

                        Name = scheduledTaskBackup.Name,
                        IsEnabled = scheduledTaskBackup.isEnabled,

                        RepeatIntervalInDays = scheduledTaskBackup.RecurDays ?? 0,
                        RepeatIntervalInMonths = scheduledTaskBackup.RecurMonth ?? 0,
                        RepeatIntervalInSeconds = scheduledTaskBackup.RecurSeconds ?? 0,
                        RepeatIntervalInWeeks = scheduledTaskBackup.RecurWeeks ?? 0,
                        SortOrder = scheduledTaskBackup.sortOrder,
                        StartTime = scheduledTaskBackup.startTime ?? DateTime.Now
                    };

                    if (scheduledTaskBackup.Frequency != null)
                        task.TaskType = (ScheduledTaskType)scheduledTaskBackup.Frequency;
                    if (scheduledTaskBackup.DaysOfMonthToActivate != null)
                        task.DaysOfMonthToActivate = (DaysOfMonth)scheduledTaskBackup.DaysOfMonthToActivate;
                    if (scheduledTaskBackup.DaysOfWeekToActivate != null)
                        task.DaysOfWeekToActivate = (DaysOfWeek)scheduledTaskBackup.DaysOfWeekToActivate;

                    
                    newSTs.Add(task);
                }

                context.ScheduledTasks.AddRange(newSTs);

                if (newSTs.Count > 0)
                {
                    var saveResult = await context.TrySaveChangesAsync(cancellationToken);
                    if (saveResult.HasError)
                        return Result.ReportError(saveResult.Message);

                    foreach (var task in newSTs)
                    {
                        task.SetDescription();
                        await task.SetTargetObjectNameAsync(context);
                    }

                    var r = await context.TrySaveChangesAsync(cancellationToken);
                    if (r.HasError)
                        return Result.ReportError(r.Message);
                }

               
            }
            return Result.ReportSuccess(string.Format("Imported {0} scheduled tasks, skipped {1} from {2}", newSTs.Count, skippedCount, Path.GetFileName(fileName)));
        }
        public async Task MultipleAsyncRequestsTest()
        {
            var dbConnection = new StubIEntityContextConnection { NameOrConnectionStringGet = () => "MultipleAsyncRequestsTest" };
            Database.SetInitializer(new CreateFreshDbInitializer());

            var logEntries = new List<LogEntry>();
            var ranstoredCommands = new List<int>();

            //Arrange 
            var log = new StubIFeedback<LogEntry>
            {
                ReportAsyncT0CancellationToken = (e, c) =>
                {
                    Console.WriteLine(e.ToString());
                    logEntries.Add(e);
                    return Task.FromResult(0);
                }
            };

            var commandProcessor = new StubICommandProcessor
            {
                RunCommandAsyncNullableOfInt32StringStringCancellationToken = (commandId, argument, argument2, cancellationToken) =>
                {
                    if (commandId.HasValue) ranstoredCommands.Add(commandId.Value);
                    return Task.FromResult(Result.ReportSuccess());
                }
            };
            var currentTime = new StubITimeProvider { TimeGet = () => DateTime.Parse("5/21/14 15:02:20") };


            var cts = new CancellationTokenSource();
            var taskRunner = new ScheduledTaskRunner(log, commandProcessor, dbConnection, currentTime);

            await taskRunner.StartAsync(cts.Token);

            var command = new Command();
            var commandScheduledTask = new DataModel.ScheduledTask
            {
                IsEnabled = true,
                Name = "New Command added after start",
                Command = command
            };
            using (var context = new ZvsContext(dbConnection))
            {
                context.ScheduledTasks.Add(commandScheduledTask);
                var r2 = await context.TrySaveChangesAsync(cts.Token);
                Assert.IsFalse(r2.HasError, r2.Message);

                commandScheduledTask.StartTime = DateTime.Parse("5/20/14 15:02:20");
                var r = await context.TrySaveChangesAsync(cts.Token);
                Assert.IsFalse(r.HasError, r.Message);

                commandScheduledTask.StartTime = DateTime.Parse("5/20/14 15:02:21");
                var r3 = await context.TrySaveChangesAsync(cts.Token);
                Assert.IsFalse(r3.HasError, r.Message);
            }
            //Act
            await Task.Delay(2000, cts.Token);
            await taskRunner.StopAsync(cts.Token);

            //Assert
            Assert.IsTrue(logEntries.All(o => o.Level == LogEntryLevel.Info), "Expected only info type log entries");
            Assert.IsTrue(ranstoredCommands.Count == 0, "Scheduled task runner did not run the correct amount of commands.");
        }
        public async override Task <Result> ImportAsync(string fileName, CancellationToken cancellationToken)
        {
            var result = await ReadAsXmlFromDiskAsync <List <ScheduledTaskBackup> >(fileName);

            if (result.HasError)
            {
                return(Result.ReportError(result.Message));
            }

            var skippedCount = 0;
            var newSTs       = new List <DataModel.ScheduledTask>();

            using (var context = new ZvsContext(EntityContextConnection))
            {
                var existingScheduledTasks = await context.ScheduledTasks
                                             .ToListAsync(cancellationToken);

                foreach (var scheduledTaskBackup in result.Data)
                {
                    if (existingScheduledTasks.Any(o => o.Name == scheduledTaskBackup.Name))
                    {
                        skippedCount++;
                        continue;
                    }

                    var cmd =
                        await
                        StoredCmdBackup.RestoreStoredCommandAsync(context, scheduledTaskBackup.StoredCommand,
                                                                  cancellationToken);

                    if (cmd == null)
                    {
                        continue;
                    }

                    var task = new DataModel.ScheduledTask
                    {
                        Argument  = cmd.Argument,
                        Argument2 = cmd.Argument2,
                        CommandId = cmd.CommandId,

                        Name      = scheduledTaskBackup.Name,
                        IsEnabled = scheduledTaskBackup.isEnabled,

                        RepeatIntervalInDays    = scheduledTaskBackup.RecurDays ?? 0,
                        RepeatIntervalInMonths  = scheduledTaskBackup.RecurMonth ?? 0,
                        RepeatIntervalInSeconds = scheduledTaskBackup.RecurSeconds ?? 0,
                        RepeatIntervalInWeeks   = scheduledTaskBackup.RecurWeeks ?? 0,
                        SortOrder = scheduledTaskBackup.sortOrder,
                        StartTime = scheduledTaskBackup.startTime ?? DateTime.Now
                    };

                    if (scheduledTaskBackup.Frequency != null)
                    {
                        task.TaskType = (ScheduledTaskType)scheduledTaskBackup.Frequency;
                    }
                    if (scheduledTaskBackup.DaysOfMonthToActivate != null)
                    {
                        task.DaysOfMonthToActivate = (DaysOfMonth)scheduledTaskBackup.DaysOfMonthToActivate;
                    }
                    if (scheduledTaskBackup.DaysOfWeekToActivate != null)
                    {
                        task.DaysOfWeekToActivate = (DaysOfWeek)scheduledTaskBackup.DaysOfWeekToActivate;
                    }


                    newSTs.Add(task);
                }

                context.ScheduledTasks.AddRange(newSTs);

                if (newSTs.Count > 0)
                {
                    var saveResult = await context.TrySaveChangesAsync(cancellationToken);

                    if (saveResult.HasError)
                    {
                        return(Result.ReportError(saveResult.Message));
                    }

                    foreach (var task in newSTs)
                    {
                        task.SetDescription();
                        await task.SetTargetObjectNameAsync(context);
                    }

                    var r = await context.TrySaveChangesAsync(cancellationToken);

                    if (r.HasError)
                    {
                        return(Result.ReportError(r.Message));
                    }
                }
            }
            return(Result.ReportSuccess(
                       $"Imported {newSTs.Count} scheduled tasks, skipped {skippedCount} from {Path.GetFileName(fileName)}"));
        }
        public async Task NewTaskExecutesTest()
        {
            var dbConnection = new UnitTestDbConnection();

            Database.SetInitializer(new CreateFreshDbInitializer());

            var logEntries        = new List <LogEntry>();
            var ranstoredCommands = new List <int>();

            //Arrange
            var log = new StubIFeedback <LogEntry>
            {
                ReportAsyncT0CancellationToken = (e, c) =>
                {
                    Console.WriteLine(e.ToString());
                    logEntries.Add(e);
                    return(Task.FromResult(0));
                }
            };

            var commandProcessor = new StubICommandProcessor
            {
                RunCommandAsyncNullableOfInt32StringStringCancellationToken = (commandId, argument, argument2, cancellationToken) =>
                {
                    if (commandId.HasValue)
                    {
                        ranstoredCommands.Add(commandId.Value);
                    }
                    return(Task.FromResult(Result.ReportSuccess()));
                }
            };
            var currentTime = new StubITimeProvider {
                TimeGet = () => DateTime.Parse("5/21/14 15:02:20")
            };


            var cts        = new CancellationTokenSource();
            var taskRunner = new ScheduledTaskRunner(log, commandProcessor, dbConnection, currentTime);

            var command = new Command();
            var commandScheduledTask = new DataModel.ScheduledTask
            {
                IsEnabled = true,
                Name      = "New Command added after start",
                Command   = command
            };

            using (var context = new ZvsContext(dbConnection))
            {
                context.ScheduledTasks.Add(commandScheduledTask);
                var r2 = await context.TrySaveChangesAsync(cts.Token);

                Assert.IsFalse(r2.HasError, r2.Message);

                await taskRunner.StartAsync(cts.Token);

                await Task.Delay(500, cts.Token);

                //Act
                commandScheduledTask.StartTime = DateTime.Parse("5/20/14 15:02:20");
                var r = await context.TrySaveChangesAsync(cts.Token);

                Assert.IsFalse(r.HasError, r.Message);

                await Task.Delay(1000, cts.Token);

                await taskRunner.StopAsync(cts.Token);
            }

            //Assert
            Assert.IsTrue(logEntries.All(o => o.Level == LogEntryLevel.Info), "Expected only info type log entries");
            Assert.IsTrue(ranstoredCommands.Count == 1, "Scheduled task runner did not run the correct amount of commands.");
        }