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); } }
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"); }
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"); }
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); } }
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 ); } }
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" ); }
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"); }
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"); }
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" ); }
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" ); }
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" ); }
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"); }
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); }
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 ); } }
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))); }
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); }
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); } }
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" ); }
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"); }
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); }
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"); }
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"); } }
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"); }
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); } }
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" ); }
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"); }
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"); }
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"); }
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), "#"); } }
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"); } }