Fixes to drone_manager behavior. Fixed bug where a drone that a user is not allowed to access may get a job scheduled on it anyways if all drones are over capacity.
Modified capacity computation to handle drones with the same ratio of running-to-max processes, but different total max processes. Signed-off-by: James Ren <[email protected]> --- autotest/scheduler/drone_manager.py 2010-03-24 11:14:47.000000000 -0700 +++ autotest/scheduler/drone_manager.py 2010-03-24 11:14:47.000000000 -0700 @@ -423,8 +423,10 @@ if not usable_drone_wrappers: # all drones disabled or inaccessible return 0 - return max(wrapper.drone.max_processes - wrapper.drone.active_processes - for wrapper in usable_drone_wrappers) + runnable_processes = [ + wrapper.drone.max_processes - wrapper.drone.active_processes + for wrapper in usable_drone_wrappers] + return max([0] + runnable_processes) def _least_loaded_drone(self, drones): @@ -439,12 +441,14 @@ # cycle through drones is order of increasing used capacity until # we find one that can handle these processes checked_drones = [] + usable_drones = [] drone_to_use = None while self._drone_queue: drone = heapq.heappop(self._drone_queue).drone checked_drones.append(drone) if not drone.usable_by(username): continue + usable_drones.append(drone) if drone.active_processes + num_processes <= drone.max_processes: drone_to_use = drone break @@ -453,10 +457,10 @@ drone_summary = ','.join('%s %s/%s' % (drone.hostname, drone.active_processes, drone.max_processes) - for drone in checked_drones) - logging.error('No drone has capacity to handle %d processes (%s)', - num_processes, drone_summary) - drone_to_use = self._least_loaded_drone(checked_drones) + for drone in usable_drones) + logging.error('No drone has capacity to handle %d processes (%s) ' + 'for user %s', num_processes, drone_summary, username) + drone_to_use = self._least_loaded_drone(usable_drones) # refill _drone_queue for drone in checked_drones: --- autotest/scheduler/drone_manager_unittest.py 2010-03-24 11:14:47.000000000 -0700 +++ autotest/scheduler/drone_manager_unittest.py 2010-03-24 11:14:47.000000000 -0700 @@ -121,6 +121,12 @@ self.assertEquals(drone.name, 1) + def test_choose_drone_for_execution_all_full_same_percentage_capacity(self): + drone = self._test_choose_drone_for_execution_helper([(5, 3), (10, 6)], + 1) + self.assertEquals(drone.name, 1) + + def test_user_restrictions(self): # this drone is restricted to a different user self.manager._enqueue_drone(MockDrone(1, max_processes=10, @@ -136,6 +142,22 @@ self.assertEquals(drone.name, 2) + def test_user_restrictions_with_full_drone(self): + # this drone is restricted to a different user + self.manager._enqueue_drone(MockDrone(1, max_processes=10, + allowed_users=['fakeuser'])) + # this drone is allowed but is full + self.manager._enqueue_drone(MockDrone(2, active_processes=3, + max_processes=2, + allowed_users=[self._USERNAME])) + + self.assertEquals(0, + self.manager.max_runnable_processes(self._USERNAME)) + drone = self.manager._choose_drone_for_execution( + 1, username=self._USERNAME) + self.assertEquals(drone.name, 2) + + def test_initialize(self): results_hostname = 'results_repo' results_install_dir = '/results/install' --- autotest/scheduler/drones.py 2010-03-24 11:14:47.000000000 -0700 +++ autotest/scheduler/drones.py 2010-03-24 11:14:47.000000000 -0700 @@ -27,9 +27,20 @@ def used_capacity(self): + """Gets the capacity used by this drone + + Returns a tuple of (percentage_full, -max_capacity). This is to aid + direct comparisons, so that a 0/10 drone is considered less heavily + loaded than a 0/2 drone. + + This value should never be used directly. It should only be used in + direct comparisons using the basic comparison operators, or using the + cmp() function. + """ if self.max_processes == 0: - return 1.0 - return float(self.active_processes) / self.max_processes + return (1.0, 0) + return (float(self.active_processes) / self.max_processes, + -self.max_processes) def usable_by(self, user): _______________________________________________ Autotest mailing list [email protected] http://test.kernel.org/cgi-bin/mailman/listinfo/autotest
