def testGetWindowTimes(self): # test wa = WindowAlerts.WindowAlerts() now = datetime(2009, 1, 1) times = wa.getWindowTimes(now) # expected result sch = [(datetime(2009, 4, 6), self.window.end_datetime()) ] bss = [(datetime(2009, 4, 6), datetime(2009, 4, 7, 13, 0))] schHrs = TimeAgent.timedelta2minutes(sch[0][1] - sch[0][0])/60.0 bssHrs = TimeAgent.timedelta2minutes(bss[0][1] - bss[0][0])/60.0 exp = [(self.window , (schHrs , bssHrs , sch , [bss]))] self.assertEquals(exp[0][0], times[0][0]) self.assertEquals(exp[0][1], times[0][1]) # add some blacked out time - 3 days bsStart = datetime(2009, 4, 8) bsEnd = datetime(2009, 4, 11) blackout = create_blackout(project = self.project, start = bsStart, end = bsEnd, repeat = 'Once') bss.insert(0, (bsStart, bsEnd)) bssHrs += 3*24 times = wa.getWindowTimes(now) exp = [(self.window , (schHrs , bssHrs , sch , [bss]))] self.assertEquals(exp[0][0], times[0][0]) self.assertEquals(exp[0][1], times[0][1]) # move the current time forward now = datetime(2009, 4, 9, 12, 15, 0) times = wa.getWindowTimes(now) sch = [(now, self.window.end_datetime()) ] bss = [(now, bsEnd)] schHrs = TimeAgent.timedelta2minutes(sch[0][1] - sch[0][0])/60.0 bssHrs = TimeAgent.timedelta2minutes(bss[0][1] - bss[0][0])/60.0 exp = [(self.window , (schHrs , bssHrs , sch , [bss]))] self.assertEquals(exp[0][0], times[0][0]) self.assertEquals(exp[0][1], times[0][1])
def getWindowTimeBlackedOut(self): "How many hours in this window have been blacked out?" bs = [] for wr in self.ranges(): bstart = wr.start_datetime() bend = wr.end_datetime() bs.extend(self.session.project.get_blackout_times(bstart, bend)) return sum([TimeAgent.timedelta2minutes(b[1] - b[0])/60.0 \ for b in bs])
def getWindowTimeNotSchedulable(self, blackouts = True): "How many hours in this window are not schedulable?" ns = [] for wr in self.ranges(): ns.extend(self.session.get_time_not_schedulable( \ wr.start_datetime() , wr.end_datetime() , blackouts = blackouts)) return sum([TimeAgent.timedelta2minutes(n[1] - n[0])/60.0 \ for n in ns])
def test_get_time_not_schedulable(self): "Test a number of overlapping bad things" # First bad thing: a receiver schedule that leaves out our rx # Schedule = 4/01/2009: 450, 600, 800 # 4/06/2009: 600, 800, 1070 # 4/11/2009: 800, 1070, 1_2 # 4/16/2009: 1070, 1_2, 2_3 # 4/21/2009: 1_2, 2_3, 4_6 # 4/26/2009: 2_3, 4_6, 8_10 # 5/01/2009: 4_6, 8_10, 12_18 # 5/06/2009: 8_10, 12_18, 18_26 # 5/11/2009: 12_18, 18_26, 26_40 start = datetime(2009, 4, 1, 0) # April 1 end = datetime(2009, 6, 1, 0) # June 1 rcvr_id = 3 for i in range(9): start_date = start + timedelta(5*i) for j in range(1, 4): rcvr_id = rcvr_id + 1 rs = Receiver_Schedule() rs.start_date = start_date rs.receiver = Receiver.objects.get(id = rcvr_id) rs.save() rcvr_id = rcvr_id - 2 # Now add some receivers to this session SessionHttpAdapter(self.sesshun).save_receivers('L | (X & S)') blackouts = self.sesshun.get_time_not_schedulable(start, end) # No available receivers at these times: exp = [(datetime(2009, 4, 1), datetime(2009, 4, 11)) , (datetime(2009, 5, 1), end) ] expected = set(exp) self.assertEquals(exp, blackouts) # Now add a project w/ prescheduled times. otherproject = Project() pdata = {"semester" : "09A" , "type" : "science" , "total_time" : "10.0" , "PSC_time" : "10.0" , "sem_time" : "10.0" , "grade" : "4.0" , "notes" : "notes" , "schd_notes" : "scheduler's notes" } adapter = ProjectHttpAdapter(otherproject) adapter.update_from_post(pdata) othersesshun = create_sesshun() othersesshun.project = otherproject othersesshun.save() fdata = {'session' : othersesshun.id , 'date' : '2009-04-20' , 'time' : '13:00' , 'duration' : 1.0 , 'backup' : False} otherperiod = Period() adapter = PeriodHttpAdapter(otherperiod) adapter.init_from_post(fdata, 'UTC') otherperiod.state = Period_State.objects.filter(abbreviation = 'S')[0] otherperiod.save() #exp.append((datetime(2009, 4, 20, 13, 0), datetime(2009, 4, 20, 14, 0))) exp = [(datetime(2009, 4, 1), datetime(2009, 4, 11)) , (datetime(2009, 4, 20, 13), datetime(2009, 4, 20, 14)) , (datetime(2009, 5, 1), end) ] blackouts = self.sesshun.get_time_not_schedulable(start, end) self.assertEquals(exp, blackouts) # how much time is that? hrsNotSchedulable = sum([TimeAgent.timedelta2minutes(b[1] - b[0])/60.0\ for b in blackouts]) self.assertEquals(985.0, hrsNotSchedulable) # how does this work when limiting the range? newEnd = datetime(2009, 4, 3) blackouts = self.sesshun.get_time_not_schedulable(start, newEnd) self.assertEquals([(start, newEnd)], blackouts) # extend this with a Project Blackout blackout = create_blackout(project = self.sesshun.project, start = datetime(2009, 4, 18, 12), end = datetime(2009, 4, 23, 12), repeat = 'Once') exp = [(datetime(2009, 4, 1), datetime(2009, 4, 11)) , (datetime(2009, 4, 18, 12), datetime(2009, 4, 23, 12)) , (datetime(2009, 5, 1), end) ] blackouts = self.sesshun.get_time_not_schedulable(start, end) self.assertEquals(exp, blackouts) # test the time available blacked out calculations # Calculate the expected result: # it turns out that the project blackout overlaps with all # schedulable time, except for one hour on 4/20 hrsBlackedOut = (TimeAgent.timedelta2minutes(blackout.getEndDate() - blackout.getStartDate()) / 60.0) - 1.0 totalTime = TimeAgent.timedelta2minutes(end - start) / 60.0 hrsSchedulable = totalTime - hrsNotSchedulable s, b, ss, bb = self.sesshun.getBlackedOutSchedulableTime(start, end) self.assertEquals(hrsSchedulable, s) self.assertEquals(hrsBlackedOut, b) # test it some more, but in different ranges start = datetime(2009, 5, 1) s, b, ss, bb = self.sesshun.getBlackedOutSchedulableTime(start, end) self.assertEquals(0.0, b) start = datetime(2009, 4, 22) end = datetime(2009, 4, 26) totalTime = TimeAgent.timedelta2minutes(end - start) / 60.0 s, b, ss, bb = self.sesshun.getBlackedOutSchedulableTime(start, end) self.assertEquals(totalTime, s) self.assertEquals(36.0, b) # cleanup self.sesshun.receiver_group_set.all().delete()
def testGetWindowTimesNonContigious(self): # test now = datetime(2009, 1, 1) wa = WindowAlerts.WindowAlerts() times = wa.getWindowTimes(now) # expected result sch = [(datetime(2009, 4, 6), self.window.end_datetime()) ] bss = [(datetime(2009, 4, 6), datetime(2009, 4, 7, 13, 0))] schHrs = TimeAgent.timedelta2minutes(sch[0][1] - sch[0][0])/60.0 bssHrs = TimeAgent.timedelta2minutes(bss[0][1] - bss[0][0])/60.0 exp = [(self.window , (schHrs , bssHrs , sch , [bss]))] self.assertEquals(exp[0][0], times[0][0]) self.assertEquals(exp[0][1], times[0][1]) # now split up this window into two ranges w/ out changing result # 4/5 -> 4/12 changes to 4/2 - 4/4 and 4/6 - 4/12 wr1 = self.window.windowrange_set.all()[0] wr1.start_date = datetime(2009, 4, 6) wr1.duration = 6 # days wr1.save() wr2 = WindowRange(window = self.window , start_date = datetime(2009, 4, 2) , duration = 2) wr2.save() wa = WindowAlerts.WindowAlerts() times = wa.getWindowTimes(now) # expected result sch = [(datetime(2009, 4, 6), self.window.end_datetime()) ] bss = [(datetime(2009, 4, 6), datetime(2009, 4, 7, 13, 0))] schHrs = TimeAgent.timedelta2minutes(sch[0][1] - sch[0][0])/60.0 bssHrs = TimeAgent.timedelta2minutes(bss[0][1] - bss[0][0])/60.0 exp = [(self.window , (schHrs , bssHrs , sch , [bss]))] self.assertEquals(exp[0][0], times[0][0]) self.assertEquals(exp[0][1], times[0][1]) # now change the window ranges to affect the result - change the # second range so that there is less scheduable time wr1.start_date = datetime(2009, 4, 7) wr1.duration = 5 wr1.save() wa = WindowAlerts.WindowAlerts() times = wa.getWindowTimes(now) # expected result sch = [(datetime(2009, 4, 7), self.window.end_datetime()) ] bss = [(datetime(2009, 4, 7), datetime(2009, 4, 7, 13, 0))] schHrs = TimeAgent.timedelta2minutes(sch[0][1] - sch[0][0])/60.0 bssHrs = TimeAgent.timedelta2minutes(bss[0][1] - bss[0][0])/60.0 exp = [(self.window , (schHrs , bssHrs , sch , [bss]))]