コード例 #1
0
        public void Free_Recording_Must_Use_Best_Fit_Resource()
        {
            // Create recordings
            var plan1 = RecordingDefinition.Create(false, "test", Guid.NewGuid(), null, SourceMock.Source5Group1Pay, TimeBias.AddHours(1), TimeSpan.FromMinutes(100));
            var plan2 = RecordingDefinition.Create(false, "test", Guid.NewGuid(), null, SourceMock.Source4Group1Pay, TimeBias.AddHours(2), TimeSpan.FromMinutes(100));
            var plan3 = RecordingDefinition.Create(false, "test", Guid.NewGuid(), null, SourceMock.Source1Group2Free, TimeBias.AddHours(2).AddMinutes(10), TimeSpan.FromMinutes(100));

            // Attach to the device
            var device = (ResourceMock)PayTVDevice1;
            var prio   = device.AbsolutePriority;

            // Must reset
            try
            {
                // Create component under test but make the device to choose the one with the least priority
                var cut = new RecordingScheduler(StringComparer.InvariantCultureIgnoreCase)
                {
                    device.SetPriority(-100), PayTVDevice2, plan1, plan2, plan3
                };

                // Process
                var schedules = cut.GetSchedules(TimeBias).ToArray();

                // Validate
                Assert.AreEqual(3, schedules.Length, "Schedules");
                Assert.AreSame(device, schedules[2].Resource, "Resource");
            }
            finally
            {
                // Reset
                device.SetPriority(prio);
            }
        }
コード例 #2
0
        public void Recording_Has_Priority_Over_Task()
        {
            // Create the recording
            var plan1 = RecordingDefinition.Create(false, "test", Guid.NewGuid(), null, SourceMock.Source1Group1Free, TimeBias.AddMinutes(15), TimeSpan.FromMinutes(80));
            var plan2 = RecordingDefinition.Create(false, "test", Guid.NewGuid(), null, SourceMock.Source1Group1Free, TimeBias.AddHours(3), TimeSpan.FromMinutes(100));

            // Create the component under test
            var cut = new RecordingScheduler(StringComparer.InvariantCultureIgnoreCase)
            {
                TaskDevice, plan1, plan2
            };

            // Load some
            var schedules = cut.GetSchedules(TimeBias, Task).Take(5).ToArray();

            // Validate
            Assert.AreEqual(5, schedules.Length, "Schedules");
            Assert.AreSame(plan1, schedules[0].Definition, "Definition 1");
            Assert.IsFalse(schedules[0].StartsLate, "Late 1");
            Assert.AreSame(Task, schedules[1].Definition, "Definition 2");
            Assert.IsTrue(schedules[1].StartsLate, "Late 2");
            Assert.AreSame(Task, schedules[2].Definition, "Definition 3");
            Assert.IsFalse(schedules[2].StartsLate, "Late 3");
            Assert.AreEqual(TimeBias.ToLocalTime().Date.AddHours(20).ToUniversalTime(), schedules[2].Time.Start, "Start 3");
            Assert.AreSame(plan2, schedules[3].Definition, "Definition 4");
            Assert.IsFalse(schedules[3].StartsLate, "Late 4");
            Assert.AreSame(Task, schedules[4].Definition, "Definition 5");
            Assert.IsFalse(schedules[4].StartsLate, "Late 5");
            Assert.AreEqual(TimeBias.ToLocalTime().Date.AddDays(1).AddHours(10).ToUniversalTime(), schedules[4].Time.Start, "Start 5");
        }
コード例 #3
0
        public void Will_Choose_Highest_Priority_Source_For_Two_Overlapping_Plan_Items()
        {
            // Create plan
            var group  = Guid.NewGuid();
            var plan1  = RecordingDefinition.Create(false, "test", Guid.NewGuid(), null, SourceMock.Create("s1", group), DateTime.UtcNow.AddHours(1), TimeSpan.FromMinutes(20));
            var times1 = plan1.GetTimes(DateTime.UtcNow).Select(s => s.Planned).Single();
            var plan2  = RecordingDefinition.Create(false, "test", Guid.NewGuid(), null, SourceMock.Create("s1", group), times1.End - TimeSpan.FromMinutes(10), TimeSpan.FromMinutes(20));
            var times2 = plan2.GetTimes(DateTime.UtcNow).Select(s => s.Planned).Single();
            var best   = ResourceMock.Create("r3", SourceMock.Create("s1", group)).SetPriority(6);

            // Create component under test
            var componentUnderTest =
                new RecordingScheduler(StringComparer.InvariantCultureIgnoreCase)
            {
                { ResourceMock.Create("r1", SourceMock.Create("s1", group)).SetPriority(1) },
                { best },
                { ResourceMock.Create("r2", SourceMock.Create("s1", group)).SetPriority(-1) },
                { plan2 },
                { plan1 },
            };

            // Load
            var schedules = componentUnderTest.GetSchedules(DateTime.UtcNow).ToArray();

            // Validate
            Assert.AreEqual(2, schedules.Length, "Schedules");
            Assert.AreSame(best, schedules[0].Resource, "Resource 0");
            Assert.AreSame(best, schedules[1].Resource, "Resource 1");
            Assert.AreSame(plan1, schedules[0].Definition, "Plan 0");
            Assert.AreSame(plan2, schedules[1].Definition, "Plan 1");
            Assert.AreEqual(times1, schedules[0].Time, "Time 0");
            Assert.AreEqual(times2, schedules[1].Time, "Time 1");
            Assert.IsFalse(schedules[0].StartsLate, "Late 0");
            Assert.IsFalse(schedules[1].StartsLate, "Late 1");
        }
コード例 #4
0
        public void Can_Join_Recordings_Even_If_Planning_Creates_Separate_Blocks()
        {
            // Create recordings
            var plan1 = RecordingDefinition.Create(false, "A1", Guid.NewGuid(), null, SourceMock.Source1Group1Free, TimeBias.AddMinutes(60), TimeSpan.FromMinutes(120));
            var plan2 = RecordingDefinition.Create(false, "A2", Guid.NewGuid(), null, SourceMock.Source2Group1Free, TimeBias.AddMinutes(165), TimeSpan.FromMinutes(60));
            var plan3 = RecordingDefinition.Create(false, "B1", Guid.NewGuid(), null, SourceMock.Source1Group2Free, TimeBias.AddMinutes(150), TimeSpan.FromMinutes(120));
            var plan4 = RecordingDefinition.Create(false, "C1", Guid.NewGuid(), null, SourceMock.Source1Group3Free, TimeBias.AddMinutes(120), TimeSpan.FromMinutes(120));

            // Create component under test
            var cut = new RecordingScheduler(StringComparer.InvariantCultureIgnoreCase)
            {
                Device1, Device2, plan1, plan2, plan3, plan4
            };

            // Resolve
            var schedules = cut.GetSchedules(TimeBias).ToArray();

            // Validate
            Assert.AreEqual(4, schedules.Length, "Schedule");

            // Process all
            foreach (var schedule in schedules)
            {
                Assert.AreEqual(ReferenceEquals(schedule.Definition, plan3), schedule.StartsLate, "Late {0}", schedule.Definition.Name);
            }
        }
コード例 #5
0
        public void Restricted_Resource_Can_Not_Serve_Three_Records_At_A_Time()
        {
            // Create recordings
            var plan1 = RecordingDefinition.Create( false, "test", Guid.NewGuid(), null, SourceMock.Source1Group1Free, TimeBias.AddHours( 1 ), TimeSpan.FromMinutes( 90 ) );
            var plan2 = RecordingDefinition.Create( false, "test", Guid.NewGuid(), null, SourceMock.Source2Group1Free, TimeBias.AddHours( 2 ), TimeSpan.FromMinutes( 70 ) );
            var plan3 = RecordingDefinition.Create( false, "test", Guid.NewGuid(), null, SourceMock.Source3Group1Free, TimeBias.AddHours( 2.25 ), TimeSpan.FromMinutes( 90 ) );

            // Load current
            var device = (ResourceMock) FreeTVDevice;
            var limit = device.SourceLimit;
            try
            {
                // Create component under test
                var cut = new RecordingScheduler( StringComparer.InvariantCultureIgnoreCase ) { device.SetSourceLimit( 2 ), plan1, plan2, plan3 };

                // Resolve
                var schedules = cut.GetSchedules( TimeBias ).ToArray();

                // Validate
                Assert.AreEqual( 3, schedules.Length, "Schedules" );
                Assert.IsFalse( schedules[0].StartsLate, "Late 1" );
                Assert.IsFalse( schedules[1].StartsLate, "Late 2" );
                Assert.IsTrue( schedules[2].StartsLate, "Late 3" );
            }
            finally
            {
                // Reset
                device.SetSourceLimit( limit );
            }
        }
コード例 #6
0
        public void A_Recording_May_Be_Discarded_If_Overlapping_Occurs_On_Different_Groups()
        {
            // Create recordings
            var plan1 = RecordingDefinition.Create( false, "test1", Guid.NewGuid(), null, SourceMock.Source1Group1Free, TimeBias.AddHours( 1 ), TimeSpan.FromMinutes( 90 ) );
            var plan2 = RecordingDefinition.Create( false, "test2", Guid.NewGuid(), null, SourceMock.Source1Group2Free, TimeBias.AddHours( 2 ), TimeSpan.FromMinutes( 10 ) );

            // Create component under test
            var cut =
                new RecordingScheduler( StringComparer.InvariantCultureIgnoreCase )
                    {
                        { FreeTVDevice },
                        { plan2 },
                        { plan1 },
                    };

            // Resolve
            var schedules = cut.GetSchedules( TimeBias ).ToArray();

            // Validate
            Assert.AreEqual( 2, schedules.Length, "Schedules" );
            Assert.IsNull( schedules[0].Resource, "Resource 1" );
            Assert.AreSame( FreeTVDevice, schedules[1].Resource, "Resource 2" );
            Assert.AreSame( plan2, schedules[0].Definition, "Plan 1" );
            Assert.AreSame( plan1, schedules[1].Definition, "Plan 2" );
            Assert.IsFalse( schedules[0].StartsLate, "Late 1" );
            Assert.IsFalse( schedules[1].StartsLate, "Late 2" );
        }
コード例 #7
0
        public void Will_Enforce_Start_Order()
        {
            // Create plan
            var source1 = SourceMock.Create("s1");
            var source2 = SourceMock.Create("s2");
            var res1    = ResourceMock.Create("r1", source1, source2).SetPriority(1);
            var res2    = ResourceMock.Create("r2", source1, source2).SetPriority(2);
            var refTime = DateTime.UtcNow.Date.AddDays(10);
            var plan1   = RecordingDefinition.Create(false, "A1", Guid.NewGuid(), null, source1, refTime.AddHours(18), TimeSpan.FromHours(2));
            var plan2   = RecordingDefinition.Create(false, "A2", Guid.NewGuid(), null, source2, refTime.AddHours(19), TimeSpan.FromHours(2));

            // Create component under test
            var componentUnderTest =
                new RecordingScheduler(StringComparer.InvariantCultureIgnoreCase, Properties.Files.EnforceResourceStartOrder)
            {
                { res1 },
                { res2 },
                { plan1 },
                { plan2 },
            };

            // Load
            var schedules = componentUnderTest.GetSchedules(refTime).ToArray();

            // Validate
            Assert.AreEqual(2, schedules.Length, "#schedules");
            Assert.AreSame(plan1, schedules[0].Definition, "plan 1");
            Assert.AreSame(plan2, schedules[1].Definition, "plan 2");
            Assert.AreSame(res1, schedules[0].Resource, "resource 1");
            Assert.AreSame(res2, schedules[1].Resource, "resource 2");
        }
コード例 #8
0
        public void Will_Use_Resource_With_Highest_Priority_When_Explicit_Binding_Is_Used()
        {
            // Create plan
            var source1 = SourceMock.Create("s1");
            var source2 = SourceMock.Create("s2");
            var res1    = ResourceMock.Create("r1", source1, source2).SetPriority(5);
            var res2    = ResourceMock.Create("r2", source1, source2).SetPriority(6);
            var res3    = ResourceMock.Create("r3", source1, source2).SetPriority(0);
            var refTime = DateTime.UtcNow;
            var plan1   = RecordingDefinition.Create(false, "A1", Guid.NewGuid(), new[] { res1 }, source1, refTime.AddMinutes(100), TimeSpan.FromMinutes(20));
            var plan2   = RecordingDefinition.Create(false, "A2", Guid.NewGuid(), new[] { res1 }, source1, refTime.AddMinutes(110), TimeSpan.FromMinutes(20));
            var plan3   = RecordingDefinition.Create(false, "A3", Guid.NewGuid(), null, source2, refTime.AddMinutes(130), TimeSpan.FromMinutes(20));

            // Create component under test
            var componentUnderTest =
                new RecordingScheduler(StringComparer.InvariantCultureIgnoreCase)
            {
                { res1 },
                { res2 },
                { res3 },
                { plan1 },
                { plan2 },
                { plan3 },
            };

            // Load
            var schedules = componentUnderTest.GetSchedules(refTime).ToArray();

            // Validate
            Assert.AreEqual(3, schedules.Length, "#schedule");
            Assert.AreSame(res1, schedules[0].Resource, "resource 0");
            Assert.AreSame(res1, schedules[1].Resource, "resource 1");
            Assert.AreSame(res2, schedules[2].Resource, "resource 2");
        }
コード例 #9
0
        public void Will_Keep_Time_Order_When_Planning()
        {
            // Create recordings
            var plan1 = RecordingDefinition.Create( false, "testA", Guid.NewGuid(), null, SourceMock.Source1Group1Free, TimeBias.AddMinutes( 60 ), TimeSpan.FromMinutes( 60 ) );
            var plan2 = RecordingDefinition.Create( false, "testB", Guid.NewGuid(), null, SourceMock.Source1Group2Free, TimeBias.AddMinutes( 90 ), TimeSpan.FromMinutes( 60 ) );
            var plan3 = RecordingDefinition.Create( false, "testC", Guid.NewGuid(), null, SourceMock.Source2Group1Free, TimeBias.AddMinutes( 100 ), TimeSpan.FromMinutes( 100 ) );

            // Create component under test
            var cut = new RecordingScheduler( StringComparer.InvariantCultureIgnoreCase ) { FreeTVDevice, plan1, plan2, plan3 };

            // Resolve
            var schedules = cut.GetSchedules( TimeBias ).ToArray();

            // Validate
            Assert.AreEqual( 3, schedules.Length, "Schedules" );
            Assert.AreEqual( "testA", schedules[0].Definition.Name, "Name 1" );
            Assert.AreEqual( "testB", schedules[1].Definition.Name, "Name 2" );
            Assert.AreEqual( "testC", schedules[2].Definition.Name, "Name 3" );
            Assert.AreSame( FreeTVDevice, schedules[0].Resource, "Resource 1" );
            Assert.AreSame( FreeTVDevice, schedules[1].Resource, "Resource 2" );
            Assert.AreSame( FreeTVDevice, schedules[2].Resource, "Resource 3" );
            Assert.IsFalse( schedules[0].StartsLate, "Late 1" );
            Assert.IsTrue( schedules[1].StartsLate, "Late 2" );
            Assert.IsTrue( schedules[2].StartsLate, "Late 3" );
        }
コード例 #10
0
        public void A_Repeating_Recording_May_Be_Overlapped_By_A_Single_Recording()
        {
            // Create recordings
            var repeatStart = TimeBias.AddHours( 1 );
            var repeatStartLocal = repeatStart.ToLocalTime();
            var plan1 = RecordingDefinition.Create( false, "test", Guid.NewGuid(), null, SourceMock.Source1Group1Free, repeatStart, TimeSpan.FromMinutes( 90 ), DateTime.MaxValue.Date, repeatStartLocal.DayOfWeek );
            var plan2 = RecordingDefinition.Create( false, "test", Guid.NewGuid(), null, SourceMock.Source1Group2Free, repeatStart.AddDays( 7 ).AddMinutes( -10 ), TimeSpan.FromMinutes( 60 ) );

            // Create component under test
            var cut = new RecordingScheduler( StringComparer.InvariantCultureIgnoreCase ) { FreeTVDevice, plan2, plan1, };

            // Load first repeats
            var schedules = cut.GetSchedules( TimeBias ).Take( 3 ).ToArray();

            // Validate
            Assert.AreEqual( 3, schedules.Length, "Schedules" );
            Assert.AreSame( plan1, schedules[0].Definition, "Plan 1" );
            Assert.AreSame( FreeTVDevice, schedules[0].Resource, "Resource 1" );
            Assert.AreSame( plan2, schedules[1].Definition, "Plan 2" );
            Assert.AreSame( FreeTVDevice, schedules[1].Resource, "Resource 2" );
            Assert.AreEqual( repeatStart.AddDays( 7 ).AddMinutes( -10 ), schedules[1].Time.Start, "Start 2" );
            Assert.AreEqual( TimeSpan.FromMinutes( 60 ), schedules[1].Time.Duration, "Duration 2" );
            Assert.AreSame( plan1, schedules[2].Definition, "Plan 3" );
            Assert.AreSame( FreeTVDevice, schedules[2].Resource, "Resource 3" );
            Assert.IsTrue( schedules[2].StartsLate, "Late" );
            Assert.AreEqual( repeatStart.AddDays( 7 ).AddMinutes( 50 ), schedules[2].Time.Start, "Start 3" );
            Assert.AreEqual( TimeSpan.FromMinutes( 40 ), schedules[2].Time.Duration, "Duration 3" );
        }
コード例 #11
0
        public void Two_Recordings_Of_The_Same_Group_Can_Be_Recorded_Simultanously()
        {
            // Create recordings
            var plan1 = RecordingDefinition.Create( false, "test", Guid.NewGuid(), null, SourceMock.Source1Group1Free, TimeBias.AddHours( 1 ), TimeSpan.FromMinutes( 90 ) );
            var plan2 = RecordingDefinition.Create( false, "test", Guid.NewGuid(), null, SourceMock.Source2Group1Free, TimeBias.AddHours( 2 ), TimeSpan.FromMinutes( 60 ) );

            // Create component under test
            var cut =
                new RecordingScheduler( StringComparer.InvariantCultureIgnoreCase )
                    {
                        { FreeTVDevice },
                        { plan1 },
                        { plan2 },
                    };

            // Resolve
            var schedules = cut.GetSchedules( TimeBias ).ToArray();

            // Validate
            Assert.AreEqual( 2, schedules.Length, "Schedules" );
            Assert.AreSame( FreeTVDevice, schedules[0].Resource, "Resource 1" );
            Assert.AreSame( FreeTVDevice, schedules[1].Resource, "Resource 2" );
            Assert.AreSame( plan1, schedules[0].Definition, "Plan 1" );
            Assert.AreSame( plan2, schedules[1].Definition, "Plan 2" );
            Assert.IsFalse( schedules[0].StartsLate, "Late 1" );
            Assert.IsFalse( schedules[1].StartsLate, "Late 2" );
        }
コード例 #12
0
        public void Decryption_Group_May_Allow_Using_Two_Resources_At_The_Same_Time()
        {
            // Create recordings
            var plan1 = RecordingDefinition.Create(false, "test", Guid.NewGuid(), null, SourceMock.Source1Group1Pay, TimeBias.AddHours(1), TimeSpan.FromMinutes(100));
            var plan2 = RecordingDefinition.Create(false, "test", Guid.NewGuid(), null, SourceMock.Source4Group1Pay, TimeBias.AddHours(2), TimeSpan.FromMinutes(100));

            // Create group
            var group =
                new DecryptionGroup
            {
                ScheduleResources      = new[] { PayTVDevice1, PayTVDevice2 },
                MaximumParallelSources = 2,
            };

            // Create component under test
            var cut = new RecordingScheduler(StringComparer.InvariantCultureIgnoreCase)
            {
                PayTVDevice1, PayTVDevice2, plan1, plan2, group
            };

            // Process
            var schedules = cut.GetSchedules(TimeBias).ToArray();

            // Validate
            Assert.AreEqual(2, schedules.Length, "Schedules");
            Assert.IsFalse(schedules[0].StartsLate, "Late 1");
            Assert.IsFalse(schedules[1].StartsLate, "Late 2");
        }
コード例 #13
0
        public void A_Plan_Can_Have_A_Repeating_Pattern()
        {
            // Create the plan
            var localStart = new DateTime(2011, 9, 8, 21, 35, 0, DateTimeKind.Local);
            var localEnd   = new DateTime(2012, 3, 31, 0, 0, 0, DateTimeKind.Local);
            var gmtStart   = localStart.ToUniversalTime();
            var plan       = RecordingDefinition.Create(false, "test", Guid.NewGuid(), null, SourceMock.Create("s1"), gmtStart, TimeSpan.FromMinutes(10), localEnd.Date, DayOfWeek.Monday, DayOfWeek.Friday, DayOfWeek.Tuesday);

            // Cross check map
            var allowed = new HashSet <DayOfWeek> {
                DayOfWeek.Monday, DayOfWeek.Friday, DayOfWeek.Tuesday
            };

            // Scan all
            foreach (var time in plan.GetTimes(gmtStart.AddYears(-1)).Select(s => s.Planned))
            {
                // Get next good time
                while (!allowed.Contains(localStart.DayOfWeek))
                {
                    localStart = localStart.AddDays(1);
                }

                // Test it
                Assert.AreEqual(localStart, time.LocalStart);
                Assert.AreEqual(TimeSpan.FromMinutes(10), time.Duration);

                // Next day
                localStart = localStart.AddDays(1);
            }

            // Check end
            Assert.AreEqual(localEnd + localStart.TimeOfDay, localStart);
        }
コード例 #14
0
        public void Will_Detect_Recordings_On_Same_Source_As_One()
        {
            // Create recordings
            var plan1 = RecordingDefinition.Create( false, "testA", Guid.NewGuid(), null, SourceMock.Source1Group1Free, TimeBias.AddMinutes( 60 ), TimeSpan.FromMinutes( 90 ) );
            var plan2 = RecordingDefinition.Create( false, "testB", Guid.NewGuid(), null, SourceMock.Source1Group1Free, TimeBias.AddMinutes( 90 ), TimeSpan.FromMinutes( 40 ) );
            var plan3 = RecordingDefinition.Create( false, "testC", Guid.NewGuid(), null, SourceMock.Source2Group1Free, TimeBias.AddMinutes( 100 ), TimeSpan.FromMinutes( 40 ) );

            // Load current
            var device = (ResourceMock) FreeTVDevice;
            var limit = device.SourceLimit;
            try
            {
                // Create component under test
                var cut = new RecordingScheduler( StringComparer.InvariantCultureIgnoreCase ) { device.SetSourceLimit( 2 ), plan1, plan2, plan3 };

                // Resolve
                var schedules = cut.GetSchedules( TimeBias ).ToArray();

                // Validate
                Assert.AreEqual( 3, schedules.Length, "Schedules" );
                Assert.IsFalse( schedules[0].StartsLate, "Late 1" );
                Assert.IsFalse( schedules[1].StartsLate, "Late 2" );
                Assert.IsFalse( schedules[2].StartsLate, "Late 3" );
            }
            finally
            {
                // Reset
                device.SetSourceLimit( limit );
            }
        }
コード例 #15
0
        public void Encrypted_Source_Of_A_Plan_Item_Is_Supported_By_Resource()
        {
            // Create component under test
            var componentUnderTest = new RecordingScheduler(StringComparer.InvariantCultureIgnoreCase);

            // Add
            componentUnderTest.Add(ResourceMock.Create("r1", SourceMock.Create("s1")).SetEncryptionLimit(1));
            componentUnderTest.Add(RecordingDefinition.Create(false, "test", Guid.NewGuid(), null, SourceMock.Create("s1", true), DateTime.UtcNow, TimeSpan.FromMinutes(12)));
        }
コード例 #16
0
        public void Exceptions_Must_Be_Defined_On_A_Full_Date()
        {
            // Create bad exception
            var exception = new PlanException {
                ExceptionDate = DateTime.Now.Date.AddMinutes(12)
            };

            // Create component under test
            var componentUnderTest = new RecordingScheduler(StringComparer.InvariantCultureIgnoreCase);

            // Add
            componentUnderTest.Add(ResourceMock.Create("r1", SourceMock.Create("s1")));
            componentUnderTest.Add(RecordingDefinition.Create(false, "test", Guid.NewGuid(), null, SourceMock.Create("s1"), DateTime.UtcNow, TimeSpan.FromMinutes(12)), exception);
        }
コード例 #17
0
        public void Can_Handle_Very_Long_Recordings_With_Multiple_Devices()
        {
            // All sources
            var sources =
                Enumerable
                .Range(0, 100)
                .Select(i => SourceMock.Create("S" + i.ToString("00")))
                .ToArray();

            // Create environment
            var device1 = ResourceMock.Create("D1", sources);
            var device2 = ResourceMock.Create("D2", sources);
            var device3 = ResourceMock.Create("D3", sources);
            var device4 = ResourceMock.Create("D4", sources);

            // Create the plan
            var allDays = new[] { DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday, DayOfWeek.Saturday, DayOfWeek.Sunday };
            var refTime = new DateTime(2013, 12, 1);
            var plan1   = RecordingDefinition.Create(false, "test1", Guid.NewGuid(), null, sources[0], refTime, TimeSpan.FromHours(23), refTime.AddYears(100), allDays);
            var plan2   = RecordingDefinition.Create(false, "test2", Guid.NewGuid(), null, sources[1], refTime.AddHours(22), TimeSpan.FromHours(4), refTime.AddYears(100), allDays);

            // Create the component under test
            var cut = new RecordingScheduler(StringComparer.InvariantCultureIgnoreCase)
            {
                device1, device2, device3, device4, plan1, plan2
            };

            // Other
            foreach (var plan in
                     Enumerable
                     .Range(2, 10)
                     .Select(i => RecordingDefinition.Create(false, "test" + i.ToString("00"), Guid.NewGuid(), null, sources[i], refTime.AddMinutes(5 * i), TimeSpan.FromMinutes(6), refTime.AddYears(100), allDays)))
            {
                cut.Add(plan);
            }

            // Get the schedule
            var schedules = cut.GetSchedules(refTime.AddHours(-1)).Take(500).ToArray();

            // Validate
            Assert.AreEqual(500, schedules.Length, "#count");
            Assert.IsFalse(schedules.Any(schedule => schedule.StartsLate), "late!");

            // Dump plan
            foreach (var schedule in schedules)
            {
                Console.WriteLine(schedule);
            }
        }
コード例 #18
0
        public void Decrypted_Source_Requires_Decryption_Resource()
        {
            // Create recordings
            var plan1 = RecordingDefinition.Create( false, "test1", Guid.NewGuid(), null, SourceMock.Source1Group1Free, TimeBias.AddHours( 1 ), TimeSpan.FromMinutes( 90 ) );
            var plan2 = RecordingDefinition.Create( false, "test2", Guid.NewGuid(), null, SourceMock.Source1Group1Pay, TimeBias.AddHours( 2 ), TimeSpan.FromMinutes( 90 ) );

            // Create component under test
            var cut = new RecordingScheduler( StringComparer.InvariantCultureIgnoreCase ) { FreeTVDevice, plan1, plan2 };

            // Resolve
            var schedules = cut.GetSchedules( TimeBias ).ToArray();

            // Validate
            Assert.AreEqual( 2, schedules.Length, "Schedule" );
            Assert.IsNull( schedules[0].Resource, "Resource 1" );
            Assert.AreSame( FreeTVDevice, schedules[1].Resource, "Resource 2" );
        }
コード例 #19
0
        public void The_Number_Of_Recordings_Per_Plan_Is_Limited()
        {
            // Create component under test
            var cut = new RecordingScheduler(StringComparer.InvariantCultureIgnoreCase)
            {
                FreeTVDevice
            };

            // Add all plans
            for (int i = 0; i <= RecordingScheduler.MaximumRecordingsInPlan; i++)
            {
                // Create recording
                var plan = RecordingDefinition.Create(false, "test", Guid.NewGuid(), null, SourceMock.Source1Group1Free, TimeBias.AddHours(i), TimeSpan.FromMinutes(90));

                // Add it
                cut.Add(plan);
            }

            // Resolve
            var schedules = cut.GetSchedules(TimeBias).ToArray();

            // Validate
            Assert.AreEqual(RecordingScheduler.MaximumRecordingsInPlan + 1, (uint)schedules.Length, "Schedules");

            // Check all
            for (int i = 0; i < RecordingScheduler.MaximumRecordingsInPlan; i++)
            {
                // Load
                var schedule = schedules[i];

                // Validate
                Assert.AreSame(FreeTVDevice, schedule.Resource, "Resource {0}", i);
                Assert.AreEqual(TimeBias.AddHours(i), schedule.Time.Start, "Start {0}", i);
                Assert.AreEqual(TimeSpan.FromMinutes(90), schedule.Time.Duration, "Duration {0}", i);
                Assert.IsFalse(schedule.StartsLate, "Late {0}", i);
            }

            // Load the last
            var last = schedules[RecordingScheduler.MaximumRecordingsInPlan];

            // Validate - internal planning is not touched
            Assert.AreSame(FreeTVDevice, last.Resource, "Resource");
            Assert.AreEqual(TimeBias.AddHours(RecordingScheduler.MaximumRecordingsInPlan), last.Time.Start, "Start");
            Assert.AreEqual(TimeSpan.FromMinutes(90), last.Time.Duration, "Duration");
            Assert.IsFalse(last.StartsLate, "Late");
        }
コード例 #20
0
        public void There_Can_Be_Only_One_Exception_Per_Date()
        {
            // Create bad exception
            var exception1 = new PlanException {
                ExceptionDate = DateTime.Now.Date
            };
            var exception2 = new PlanException {
                ExceptionDate = exception1.ExceptionDate
            };

            // Create component under test
            var componentUnderTest = new RecordingScheduler(StringComparer.InvariantCultureIgnoreCase);

            // Add
            componentUnderTest.Add(ResourceMock.Create("r1", SourceMock.Create("s1")));
            componentUnderTest.Add(RecordingDefinition.Create(false, "test", Guid.NewGuid(), null, SourceMock.Create("s1"), DateTime.UtcNow, TimeSpan.FromMinutes(12)), exception1, exception2);
        }
コード例 #21
0
        public void Will_Minimize_Sources_Per_Resource()
        {
            // Create plan
            var source1 = SourceMock.Create("s1");
            var source2 = SourceMock.Create("s2");
            var source3 = SourceMock.Create("s3");
            var res1    = ResourceMock.Create("r1", source1, source2, source3).SetPriority(1);
            var res2    = ResourceMock.Create("r2", source1, source2, source3).SetPriority(1);
            var res3    = ResourceMock.Create("r3", source1, source2, source3).SetPriority(0);
            var refTime = DateTime.UtcNow.Date.AddDays(10);
            var plan1   = RecordingDefinition.Create(false, "A1", Guid.NewGuid(), null, source1, refTime.AddHours(19), TimeSpan.FromHours(2));
            var plan2   = RecordingDefinition.Create(false, "A2", Guid.NewGuid(), null, source2, refTime.AddHours(20), TimeSpan.FromHours(3));
            var plan3   = RecordingDefinition.Create(false, "A3", Guid.NewGuid(), null, source3, refTime.AddHours(20), TimeSpan.FromHours(2));
            var plan4   = RecordingDefinition.Create(false, "A4", Guid.NewGuid(), null, source2, refTime.AddHours(22), TimeSpan.FromHours(2));

            // Create component under test
            var componentUnderTest =
                new RecordingScheduler(StringComparer.InvariantCultureIgnoreCase, Properties.Files.MinimizeSourcesPerResource)
            {
                { res1 },
                { res2 },
                { res3 },
                { plan1 },
                { plan2 },
                { plan3 },
                { plan4 },
            };

            // Load
            var schedules = componentUnderTest.GetSchedules(refTime).ToArray();

            // Validate
            Assert.AreEqual(4, schedules.Length, "#schedule");
            var exec1 = schedules.Single(s => s.Definition.UniqueIdentifier == plan1.UniqueIdentifier);
            var exec2 = schedules.Single(s => s.Definition.UniqueIdentifier == plan2.UniqueIdentifier);
            var exec3 = schedules.Single(s => s.Definition.UniqueIdentifier == plan3.UniqueIdentifier);
            var exec4 = schedules.Single(s => s.Definition.UniqueIdentifier == plan4.UniqueIdentifier);

            Assert.AreSame(res1, exec1.Resource, "A1");
            Assert.AreSame(res2, exec2.Resource, "A2");
            Assert.AreSame(res3, exec3.Resource, "A3");
            Assert.AreSame(res2, exec4.Resource, "A4");
        }
コード例 #22
0
        public void WillScheduleSingleRepeatedTask()
        {
            // Create component under test
            using (var cut = ResourceManager.Create(StringComparer.InvariantCultureIgnoreCase))
            {
                // Add a single device
                cut.Add(ResourceMock.Device1);

                // Time to use
                var now = DateTime.UtcNow;

                // Create the recording
                var play1 = RecordingDefinition.Create(this, "test", Guid.NewGuid(), new[] { ResourceMock.Device1 }, SourceMock.Source1Group1Free, now.AddMinutes(10), TimeSpan.FromMinutes(100), new DateTime(2100, 12, 31), DayOfWeek.Monday);

                // Get the schedule
                var scheduler = cut.CreateScheduler();

                // Load recordings
                scheduler.Add(play1);

                // Get all
                var plan = scheduler.GetSchedules(now).Take(100).ToArray();

                // Validate
                Assert.AreEqual(100, plan.Length, "Initial Count");
                Assert.AreEqual(DayOfWeek.Monday, plan[0].Time.LocalStart.DayOfWeek, "Initial Start");
                Assert.IsNull(cut.GetEndOfAllocation(), "Initial Allocation");

                // Mark as started
                Assert.IsTrue(cut.Start(plan[0]), "Start");

                // Get the schedule
                scheduler = cut.CreateScheduler();

                // Load recordings
                scheduler.Add(play1);

                // Test
                Assert.IsFalse(scheduler.GetSchedules(now).Any(), "Ignore Recording");
                Assert.AreEqual(plan[0].Time.End, cut.GetEndOfAllocation(), "End");
            }
        }
コード例 #23
0
        public void Same_Source_Does_Not_Require_Additional_Decyrption_Slot()
        {
            // Create recordings
            var plan1 = RecordingDefinition.Create(false, "test", Guid.NewGuid(), null, SourceMock.Source1Group1Pay, TimeBias.AddHours(1), TimeSpan.FromMinutes(100));
            var plan2 = RecordingDefinition.Create(false, "test", Guid.NewGuid(), null, SourceMock.Source1Group1Pay, TimeBias.AddHours(2), TimeSpan.FromMinutes(100));

            // Create component under test
            var cut = new RecordingScheduler(StringComparer.InvariantCultureIgnoreCase)
            {
                PayTVDevice1, plan1, plan2
            };

            // Process
            var schedules = cut.GetSchedules(TimeBias).ToArray();

            // Validate
            Assert.AreEqual(2, schedules.Length, "Schedules");
            Assert.IsFalse(schedules[0].StartsLate, "Late 1");
            Assert.IsFalse(schedules[1].StartsLate, "Late 2");
        }
コード例 #24
0
        public void WillNotShowCurrentRecordingInPlanIfCut()
        {
            // Create component under test
            using (var cut = ResourceManager.Create(StringComparer.InvariantCultureIgnoreCase))
            {
                // Add a single device
                cut.Add(ResourceMock.Device1);

                // Time to use
                var now = DateTime.UtcNow;

                // Create the recording
                var play1 = RecordingDefinition.Create(this, "test", Guid.NewGuid(), new[] { ResourceMock.Device1 }, SourceMock.Source1Group1Free, now.AddMinutes(10), TimeSpan.FromMinutes(100), new DateTime(2100, 12, 31), DayOfWeek.Monday);

                // Loading helper
                Func <RecordingScheduler, DateTime, IEnumerable <IScheduleInformation> > loader =
                    (s, d) =>
                {
                    // Load recording
                    s.Add(play1);

                    // Report
                    return(s.GetSchedules(d));
                };

                // Find empty list
                var initial = cut.GetSchedules(now, loader).Take(2).ToArray();

                // Start the first one
                Assert.IsTrue(cut.Start(initial[0]));

                // Move it
                Assert.IsTrue(cut.Modify(initial[0].Definition.UniqueIdentifier, initial[0].Time.End.AddMinutes(-20)));

                // Recheck the list
                var follower = cut.GetSchedules(now, loader).First();

                // Make sure that first is skipped
                Assert.AreEqual(initial[1].Time.Start, follower.Time.Start);
            }
        }
コード例 #25
0
        public void An_Unknown_Source_Can_Not_Be_Recorded()
        {
            // Create recordings
            var plan = RecordingDefinition.Create( false, "test", Guid.NewGuid(), null, SourceMock.Create( "unknown" ), TimeBias.AddHours( 1 ), TimeSpan.FromMinutes( 90 ) );

            // Create component under test
            var cut =
                new RecordingScheduler( StringComparer.InvariantCultureIgnoreCase )
                    {
                        { FreeTVDevice },
                        { plan },
                    };

            // Resolve
            var schedules = cut.GetSchedules( TimeBias ).ToArray();

            // Validate
            Assert.AreEqual( 1, schedules.Length, "Schedules" );
            Assert.AreSame( null, schedules[0].Resource, "Resource" );
            Assert.AreSame( plan, schedules[0].Definition, "Plan" );
        }
コード例 #26
0
        public void Will_Skip_Recording_If_Unable_To_Decrypt()
        {
            // Create recordings
            var plan1 = RecordingDefinition.Create(false, "test1", Guid.NewGuid(), null, SourceMock.Source1Group1Pay, TimeBias.AddHours(1), TimeSpan.FromMinutes(100));
            var plan2 = RecordingDefinition.Create(false, "test2", Guid.NewGuid(), null, SourceMock.Source1Group1Free, TimeBias.AddHours(2), TimeSpan.FromMinutes(100));

            // Create component under test
            var cut = new RecordingScheduler(StringComparer.InvariantCultureIgnoreCase)
            {
                FreeTVDevice, plan1, plan2
            };

            // Process
            var schedules = cut.GetSchedules(TimeBias).ToArray();

            // Validate
            Assert.AreEqual(2, schedules.Length, "Schedules");
            Assert.IsNull(schedules[0].Resource, "Resource 1");
            Assert.AreSame(FreeTVDevice, schedules[1].Resource, "Resource 2");
            Assert.IsFalse(schedules[1].StartsLate, "Late 2");
        }
コード例 #27
0
        public void Two_Decrypted_Recordings_On_Same_Group_Require_Two_Decryption_Devices()
        {
            // Create recordings
            var plan1 = RecordingDefinition.Create(false, "test", Guid.NewGuid(), null, SourceMock.Source1Group1Pay, TimeBias.AddHours(1), TimeSpan.FromMinutes(100));
            var plan2 = RecordingDefinition.Create(false, "test", Guid.NewGuid(), null, SourceMock.Source4Group1Pay, TimeBias.AddHours(2), TimeSpan.FromMinutes(10));

            // Create component under test
            var cut = new RecordingScheduler(StringComparer.InvariantCultureIgnoreCase)
            {
                PayTVDevice1, PayTVDevice2, plan1, plan2
            };

            // Process
            var schedules = cut.GetSchedules(TimeBias).ToArray();

            // Validate
            Assert.AreEqual(2, schedules.Length, "Schedules");
            Assert.IsNotNull(schedules[0].Resource, "Resource 1");
            Assert.IsNotNull(schedules[1].Resource, "Resource 2");
            Assert.AreNotSame(schedules[0].Resource, schedules[1].Resource, "Resources");
        }
コード例 #28
0
        public void May_Require_Three_Resources_On_Bad_Mixture_Of_Three_Recordings()
        {
            // Create recordings
            var plan1 = RecordingDefinition.Create(false, "test", Guid.NewGuid(), null, SourceMock.Source1Group1Pay, TimeBias.AddHours(1), TimeSpan.FromMinutes(100));
            var plan2 = RecordingDefinition.Create(false, "test", Guid.NewGuid(), null, SourceMock.Source4Group1Pay, TimeBias.AddHours(2), TimeSpan.FromMinutes(100));
            var plan3 = RecordingDefinition.Create(false, "test", Guid.NewGuid(), null, SourceMock.Source1Group2Free, TimeBias.AddHours(2).AddMinutes(10), TimeSpan.FromMinutes(100));

            // Create component under test
            var cut = new RecordingScheduler(StringComparer.InvariantCultureIgnoreCase)
            {
                FreeTVDevice, PayTVDevice1, PayTVDevice2, plan1, plan2, plan3
            };

            // Process
            var schedules = cut.GetSchedules(TimeBias).ToArray();

            // Validate
            Assert.AreEqual(3, schedules.Length, "Schedules");
            Assert.AreNotSame(FreeTVDevice, schedules[0].Resource, "Resource 1");
            Assert.AreNotSame(FreeTVDevice, schedules[1].Resource, "Resource 2");
            Assert.AreSame(FreeTVDevice, schedules[2].Resource, "Resource 3");
        }
コード例 #29
0
        public void CanAddRecordingOverlappingRunning()
        {
            // Create component under test
            using (var cut = ResourceManager.Create(StringComparer.InvariantCultureIgnoreCase))
            {
                // Add a single device
                cut.Add(ResourceMock.Device1);

                // Time to use
                var now = new DateTime(2013, 12, 3, 17, 0, 0, DateTimeKind.Utc);

                // Start a task
                Assert.IsTrue(cut.Start(ResourceMock.Device1, null, Guid.NewGuid(), "EPG", now, now.AddMinutes(20)), "epg");

                // Create the recording
                var plan1 = RecordingDefinition.Create(false, "testA", Guid.NewGuid(), null, SourceMock.Source1Group1Free, now.AddMinutes(1), TimeSpan.FromMinutes(120));
                var plan2 = RecordingDefinition.Create(false, "testB", Guid.NewGuid(), null, SourceMock.Source1Group2Free, now.AddDays(1).AddHours(1), TimeSpan.FromMinutes(30));
                var plan3 = RecordingDefinition.Create(false, "testC", Guid.NewGuid(), null, SourceMock.Source1Group3Free, now.AddDays(1).AddHours(2), TimeSpan.FromMinutes(30));

                // Loading helper
                Func <RecordingScheduler, DateTime, IEnumerable <IScheduleInformation> > loader =
                    (s, d) =>
                {
                    // Load recording
                    s.Add(plan1);
                    s.Add(plan2);
                    s.Add(plan3);

                    // Report
                    return(s.GetSchedules(d));
                };

                // Find empty list
                var schedules = cut.GetSchedules(now, loader).ToArray();

                // Validate
                Assert.AreEqual(3, schedules.Count(s => s.Resource != null), "#");
            }
        }
コード例 #30
0
        public void Bad_Planning_After_Recording_Start()
        {
            // Create component under test
            using (var rm = ResourceManager.Create(StringComparer.InvariantCultureIgnoreCase))
            {
                var now = DateTime.Now.Date.AddDays(10);

                var source1 = SourceMock.Create("s1");
                var source2 = SourceMock.Create("s2");
                var source3 = SourceMock.Create("s3");

                var dev1 = ResourceMock.Create("dev1", source1, source2, source3);
                var dev2 = ResourceMock.Create("dev2", source1, source2, source3);

                var id1    = Guid.NewGuid();
                var start1 = now.AddHours(11).AddMinutes(40);
                var dur1   = TimeSpan.FromMinutes(15);

                var plan1 = RecordingDefinition.Create(false, "test1", id1, null, source1, start1, dur1);
                var plan2 = RecordingDefinition.Create(false, "test2", Guid.NewGuid(), null, source2, now.AddHours(11).AddMinutes(45), TimeSpan.FromMinutes(15));
                var plan3 = RecordingDefinition.Create(false, "test3", Guid.NewGuid(), null, source3, now.AddHours(11).AddMinutes(50), TimeSpan.FromMinutes(15));

                rm.Add(dev1);
                rm.Add(dev2);

                Assert.IsTrue(rm.Start(dev2, source1, id1, "test1", start1, start1 + dur1));

                var cut = rm.CreateScheduler(false);
                cut.Add(plan1);
                cut.Add(plan2);
                cut.Add(plan3);

                var schedules = cut.GetSchedules(start1.AddMinutes(5).AddTicks(1)).Where(s => s.Definition.UniqueIdentifier != id1).ToArray();

                Assert.AreEqual(2, schedules.Length, "#schedules");
                Assert.AreEqual("test2", schedules[0].Definition.Name, "1");
                Assert.AreEqual("test3", schedules[1].Definition.Name, "2");
            }
        }