Allow lab status to block based on a build regex.

Previously, the lab status could contain a string to block testing
based on the board.  With this change, the status can block any
build that matches a regex in the status.  This allows closing the
lab to either a build or a milestone.  It also allows closing the
lab for other more specific conditions, for anyone desperate enough
to want to.

BUG=chromium:220934
TEST=unit tests

Change-Id: I8a44f5e9be504415a7c5bd73c714c778bf684d2c
Reviewed-on: https://chromium-review.googlesource.com/179544
Tested-by: Richard Barnette <jrbarnette@chromium.org>
Reviewed-by: Alex Miller <milleral@chromium.org>
Commit-Queue: Richard Barnette <jrbarnette@chromium.org>
diff --git a/server/lab_status_unittest.py b/server/lab_status_unittest.py
index fad4285..1299a66 100644
--- a/server/lab_status_unittest.py
+++ b/server/lab_status_unittest.py
@@ -13,6 +13,8 @@
 from autotest_lib.client.common_lib import global_config
 from autotest_lib.server import site_utils
 
+_DEADBUILD = 'deadboard-release/R33-4966.0.0'
+_LIVEBUILD = 'liveboard-release/R32-4920.14.0'
 
 _OPEN_STATUS_VALUES = [
     '''
@@ -44,6 +46,16 @@
       "general_state": "open"
     }
     ''',
+
+    '''
+    {
+      "username": "fizzbin@google.com",
+      "date": "2013-11-16 00:25:23.511208",
+      "message": "Lab is up despite R33-4966.0.0",
+      "can_commit_freely": true,
+      "general_state": "open"
+    }
+    ''',
 ]
 
 _CLOSED_STATUS_VALUES = [
@@ -61,19 +73,19 @@
     {
       "username": "fizzbin@google.com",
       "date": "2013-11-16 00:25:23.511208",
-      "message": "Lab is down even for [deadboard]",
+      "message": "Lab is down even for [liveboard-release/R32-4920.14.0]",
       "can_commit_freely": false,
       "general_state": "closed"
     }
     ''',
 ]
 
-_DEADBOARD_STATUS_VALUES = [
+_DEADBUILD_STATUS_VALUES = [
     '''
     {
       "username": "fizzbin@google.com",
       "date": "2013-11-16 00:25:23.511208",
-      "message": "Lab is up except for [deadboard]",
+      "message": "Lab is up except for [deadboard-]",
       "can_commit_freely": false,
       "general_state": "open"
     }
@@ -83,7 +95,7 @@
     {
       "username": "fizzbin@google.com",
       "date": "2013-11-16 00:25:23.511208",
-      "message": "liveboard is good, but [deadboard] is bad",
+      "message": "Lab is up except for [R33-]",
       "can_commit_freely": false,
       "general_state": "open"
     }
@@ -93,7 +105,7 @@
     {
       "username": "fizzbin@google.com",
       "date": "2013-11-16 00:25:23.511208",
-      "message": "Lab is up [deadboard otherboard]",
+      "message": "Lab is up except for [deadboard-.*/R33-]",
       "can_commit_freely": false,
       "general_state": "open"
     }
@@ -103,7 +115,7 @@
     {
       "username": "fizzbin@google.com",
       "date": "2013-11-16 00:25:23.511208",
-      "message": "Lab is up [otherboard deadboard]",
+      "message": "Lab is up except for [ deadboard-]",
       "can_commit_freely": false,
       "general_state": "open"
     }
@@ -113,7 +125,47 @@
     {
       "username": "fizzbin@google.com",
       "date": "2013-11-16 00:25:23.511208",
-      "message": "Lab is up [first deadboard last]",
+      "message": "Lab is up except for [deadboard- ]",
+      "can_commit_freely": false,
+      "general_state": "open"
+    }
+    ''',
+
+    '''
+    {
+      "username": "fizzbin@google.com",
+      "date": "2013-11-16 00:25:23.511208",
+      "message": "Lab is up [first R33- last]",
+      "can_commit_freely": false,
+      "general_state": "open"
+    }
+    ''',
+
+    '''
+    {
+      "username": "fizzbin@google.com",
+      "date": "2013-11-16 00:25:23.511208",
+      "message": "liveboard is good, but [deadboard-] is bad",
+      "can_commit_freely": false,
+      "general_state": "open"
+    }
+    ''',
+
+    '''
+    {
+      "username": "fizzbin@google.com",
+      "date": "2013-11-16 00:25:23.511208",
+      "message": "Lab is up [deadboard- otherboard-]",
+      "can_commit_freely": false,
+      "general_state": "open"
+    }
+    ''',
+
+    '''
+    {
+      "username": "fizzbin@google.com",
+      "date": "2013-11-16 00:25:23.511208",
+      "message": "Lab is up [otherboard- deadboard-]",
       "can_commit_freely": false,
       "general_state": "open"
     }
@@ -249,10 +301,10 @@
      1. Lab is up.  All calls to _decode_lab_status() will
         succeed without raising an exception.
      2. Lab is down.  All calls to _decode_lab_status() will
-        fail with LabIsDownException.
-     3. Board disabled.  Calls to _decode_lab_status() will
-        succeed, except that board 'deadboard' will raise
-        BoardIsDisabledException.
+        fail with TestLabException.
+     3. Build disabled.  Calls to _decode_lab_status() will
+        succeed, except that board `_DEADBUILD` will raise
+        TestLabException.
 
     """
 
@@ -265,42 +317,37 @@
         @param lab_status JSON value describing lab status.
 
         """
-        site_utils._decode_lab_status(lab_status, None)
-        site_utils._decode_lab_status(lab_status, 'liveboard')
-        site_utils._decode_lab_status(lab_status, 'deadboard')
+        site_utils._decode_lab_status(lab_status, _LIVEBUILD)
+        site_utils._decode_lab_status(lab_status, _DEADBUILD)
 
 
     def _assert_lab_closed(self, lab_status):
         """Test that closed status values are handled properly.
 
-        Test that _decode_lab_status() raises LabIsDownException
+        Test that _decode_lab_status() raises TestLabException
         when the lab status is down.
 
         @param lab_status JSON value describing lab status.
 
         """
-        with self.assertRaises(site_utils.LabIsDownException):
-            site_utils._decode_lab_status(lab_status, None)
-        with self.assertRaises(site_utils.LabIsDownException):
-            site_utils._decode_lab_status(lab_status, 'liveboard')
-        with self.assertRaises(site_utils.LabIsDownException):
-            site_utils._decode_lab_status(lab_status, 'deadboard')
+        with self.assertRaises(site_utils.TestLabException):
+            site_utils._decode_lab_status(lab_status, _LIVEBUILD)
+        with self.assertRaises(site_utils.TestLabException):
+            site_utils._decode_lab_status(lab_status, _DEADBUILD)
 
 
-    def _assert_lab_deadboard(self, lab_status):
-        """Test that disabled boards are handled properly.
+    def _assert_lab_deadbuild(self, lab_status):
+        """Test that disabled builds are handled properly.
 
-        Test that _decode_lab_status() raises
-        BoardIsDisabledException for board 'deadboard' and
-        succeeds otherwise.
+        Test that _decode_lab_status() raises TestLabException
+        for build `_DEADBUILD` and succeeds otherwise.
 
         @param lab_status JSON value describing lab status.
 
         """
-        site_utils._decode_lab_status(lab_status, None)
-        site_utils._decode_lab_status(lab_status, 'liveboard')
-        with self.assertRaises(site_utils.BoardIsDisabledException):
-            site_utils._decode_lab_status(lab_status, 'deadboard')
+        site_utils._decode_lab_status(lab_status, _LIVEBUILD)
+        with self.assertRaises(site_utils.TestLabException):
+            site_utils._decode_lab_status(lab_status, _DEADBUILD)
 
 
     def _assert_lab_status(self, test_values, checker):
@@ -333,10 +380,10 @@
                                 self._assert_lab_closed)
 
 
-    def test_dead_board(self):
-        """Test that disabled boards are handled correctly."""
-        self._assert_lab_status(_DEADBOARD_STATUS_VALUES,
-                                self._assert_lab_deadboard)
+    def test_dead_build(self):
+        """Test that disabled builds are handled correctly."""
+        self._assert_lab_status(_DEADBUILD_STATUS_VALUES,
+                                self._assert_lab_deadbuild)
 
 
 class CheckStatusTest(mox.MoxTestBase):
@@ -389,100 +436,51 @@
         site_utils._get_lab_status(_FAKE_URL).AndReturn(json_value)
 
 
-    def _try_check_no_board(self):
-        """Test calling check_lab_status() with no board."""
+    def _try_check_status(self, build):
+        """Test calling check_lab_status() with `build`."""
         try:
             self.mox.ReplayAll()
-            site_utils.check_lab_status()
+            site_utils.check_lab_status(build)
         finally:
             self.mox.VerifyAll()
 
 
-    def _try_check_dead_board(self):
-        """Test calling check_lab_status() with 'deadboard'."""
-        try:
-            self.mox.ReplayAll()
-            site_utils.check_lab_status('deadboard')
-        finally:
-            self.mox.VerifyAll()
-
-
-    def _try_check_live_board(self):
-        """Test calling check_lab_status() with 'liveboard'."""
-        try:
-            self.mox.ReplayAll()
-            site_utils.check_lab_status('liveboard')
-        finally:
-            self.mox.VerifyAll()
-
-
-    def test_non_cautotest_no_board(self):
-        """Test a call with no board when the host isn't cautotest."""
+    def test_non_cautotest(self):
+        """Test a call with a build when the host isn't cautotest."""
         self._setup_not_cautotest()
-        self._try_check_no_board()
+        self._try_check_status(_LIVEBUILD)
 
 
-    def test_non_cautotest_with_board(self):
-        """Test a call with a board when the host isn't cautotest."""
-        self._setup_not_cautotest()
-        self._try_check_live_board()
-
-
-    def test_no_status_no_board(self):
-        """Test without a board when `_get_lab_status()` returns `None`."""
+    def test_no_lab_status(self):
+        """Test with a build when `_get_lab_status()` returns `None`."""
         self._setup_no_status()
-        self._try_check_no_board()
+        self._try_check_status(_LIVEBUILD)
 
 
-    def test_no_lab_status_with_board(self):
-        """Test with a board when `_get_lab_status()` returns `None`."""
-        self._setup_no_status()
-        self._try_check_live_board()
-
-
-    def test_lab_up_no_board(self):
-        """Test lab open with no board specified."""
+    def test_lab_up_live_build(self):
+        """Test lab open with a build specified."""
         self._setup_lab_status(_OPEN_STATUS_VALUES[0])
-        self._try_check_no_board()
+        self._try_check_status(_LIVEBUILD)
 
 
-    def test_lab_up_live_board(self):
-        """Test lab open with a board specified."""
-        self._setup_lab_status(_OPEN_STATUS_VALUES[0])
-        self._try_check_live_board()
-
-
-    def test_lab_down_no_board(self):
-        """Test lab closed with no board specified."""
+    def test_lab_down_live_build(self):
+        """Test lab closed with a build specified."""
         self._setup_lab_status(_CLOSED_STATUS_VALUES[0])
-        with self.assertRaises(site_utils.LabIsDownException):
-            self._try_check_no_board()
+        with self.assertRaises(site_utils.TestLabException):
+            self._try_check_status(_LIVEBUILD)
 
 
-    def test_lab_down_live_board(self):
-        """Test lab closed with a board specified."""
-        self._setup_lab_status(_CLOSED_STATUS_VALUES[0])
-        with self.assertRaises(site_utils.LabIsDownException):
-            self._try_check_live_board()
+    def test_build_disabled_live_build(self):
+        """Test build disabled with a live build specified."""
+        self._setup_lab_status(_DEADBUILD_STATUS_VALUES[0])
+        self._try_check_status(_LIVEBUILD)
 
 
-    def test_board_disabled_no_board(self):
-        """Test board disabled with no board specified."""
-        self._setup_lab_status(_DEADBOARD_STATUS_VALUES[0])
-        self._try_check_no_board()
-
-
-    def test_board_disabled_live_board(self):
-        """Test board disabled with a live board specified."""
-        self._setup_lab_status(_DEADBOARD_STATUS_VALUES[0])
-        self._try_check_live_board()
-
-
-    def test_board_disabled_dead_board(self):
-        """Test board disabled with the disabled board specified."""
-        self._setup_lab_status(_DEADBOARD_STATUS_VALUES[0])
-        with self.assertRaises(site_utils.BoardIsDisabledException):
-            self._try_check_dead_board()
+    def test_build_disabled_dead_build(self):
+        """Test build disabled with the disabled build specified."""
+        self._setup_lab_status(_DEADBUILD_STATUS_VALUES[0])
+        with self.assertRaises(site_utils.TestLabException):
+            self._try_check_status(_DEADBUILD)
 
 
 if __name__ == '__main__':
diff --git a/server/site_utils.py b/server/site_utils.py
index daa0a6b..d27aff3 100644
--- a/server/site_utils.py
+++ b/server/site_utils.py
@@ -25,13 +25,8 @@
 LAB_GOOD_STATES = ('open', 'throttled')
 
 
-class LabIsDownException(Exception):
-    """Raised when the Lab is Down"""
-    pass
-
-
-class BoardIsDisabledException(Exception):
-    """Raised when a certain board is disabled in the Lab"""
+class TestLabException(Exception):
+    """Exception raised when the Test Lab blocks a test or suite."""
     pass
 
 
@@ -178,50 +173,48 @@
     return None
 
 
-def _decode_lab_status(lab_status, board):
+def _decode_lab_status(lab_status, build):
     """Decode lab status, and report exceptions as needed.
 
-    Takes a deserialized JSON object from the lab status page, and
-    interprets it to determine the actual lab status.  Raises
+    Take a deserialized JSON object from the lab status page, and
+    interpret it to determine the actual lab status.  Raise
     exceptions as required to report when the lab is down.
 
-    @param board: board name that we want to check the status of.
+    @param build: build name that we want to check the status of.
 
-    @raises LabIsDownException if the lab is not up.
-    @raises BoardIsDisabledException if the desired board is currently
-                                           disabled.
+    @raises TestLabException Raised if a request to test for the given
+                             status and build should be blocked.
     """
     # First check if the lab is up.
     if not lab_status['general_state'] in LAB_GOOD_STATES:
-        raise LabIsDownException('Chromium OS Lab is currently not up: '
-                                 '%s.' % lab_status['message'])
+        raise TestLabException('Chromium OS Test Lab is closed: '
+                               '%s.' % lab_status['message'])
 
-    # Check if the board we wish to use is disabled.
+    # Check if the build we wish to use is disabled.
     # Lab messages should be in the format of:
-    # Lab is 'status' [boards not to be ran] (comment). Example:
-    # Lab is Open [stumpy, kiev, x86-alex] (power_resume rtc causing duts to go
-    # down)
-    boards_are_disabled = re.search('\[(.*)\]', lab_status['message'])
-    if board and boards_are_disabled:
-        if board in boards_are_disabled.group(1):
-            raise BoardIsDisabledException('Chromium OS Lab is '
-                    'currently not allowing suites to be scheduled on board '
-                    '%s: %s' % (board, lab_status['message']))
+    #    Lab is 'status' [regex ...] (comment)
+    # If the build name matches any regex, it will be blocked.
+    build_exceptions = re.search('\[(.*)\]', lab_status['message'])
+    if not build_exceptions:
+        return
+    for build_pattern in build_exceptions.group(1).split():
+        if re.search(build_pattern, build):
+            raise TestLabException('Chromium OS Test Lab is closed: '
+                                   '%s matches %s.' % (
+                                           build, build_pattern))
     return
 
 
-def check_lab_status(board=None):
-    """Check if the lab status allows us to schedule suites.
+def check_lab_status(build):
+    """Check if the lab status allows us to schedule for a build.
 
-    Also checks if the lab is disabled for that particular board, and if so
-    will raise an error to prevent new suites from being scheduled for that
-    board.
+    Checks if the lab is down, or if testing for the requested build
+    should be blocked.
 
-    @param board: board name that we want to check the status of.
+    @param build: Name of the build to be scheduled for testing.
 
-    @raises LabIsDownException if the lab is not up.
-    @raises BoardIsDisabledException if the desired board is currently
-                                           disabled.
+    @raises TestLabException Raised if a request to test for the given
+                             status and build should be blocked.
 
     """
     # Ensure we are trying to schedule on the actual lab.
@@ -238,4 +231,4 @@
         # We go ahead and say the lab is open if we can't get the status.
         logging.warn('Could not get a status from %s', status_url)
         return
-    _decode_lab_status(json_status, board)
+    _decode_lab_status(json_status, build)
diff --git a/site_utils/run_suite.py b/site_utils/run_suite.py
index 689b45d..6d2a67a 100755
--- a/site_utils/run_suite.py
+++ b/site_utils/run_suite.py
@@ -597,8 +597,8 @@
 
     try:
         if not options.bypass_labstatus:
-            utils.check_lab_status(options.board)
-    except (utils.LabIsDownException, utils.BoardIsDisabledException) as e:
+            utils.check_lab_status(options.build)
+    except utils.TestLabException as e:
         logging.warning('Error Message: %s', e)
         return RETURN_CODES.WARNING
 
diff --git a/site_utils/suite_scheduler/deduping_scheduler.py b/site_utils/suite_scheduler/deduping_scheduler.py
index c27faaf..1edafd4 100644
--- a/site_utils/suite_scheduler/deduping_scheduler.py
+++ b/site_utils/suite_scheduler/deduping_scheduler.py
@@ -49,8 +49,8 @@
     def _ShouldScheduleSuite(self, suite, board, build):
         """Return True if |suite| has not yet been run for |build| on |board|.
 
-        True if |suite| has not been run for |build| on |board|.
-        False if it has been.
+        True if |suite| has not been run for |build| on |board|, and
+        the lab is open for this particular request.  False otherwise.
 
         @param suite: the name of the suite to run, e.g. 'bvt'
         @param board: the board to run the suite on, e.g. x86-alex
@@ -60,6 +60,12 @@
         @raise DedupException if the AFE raises while searching for jobs.
         """
         try:
+            site_utils.check_lab_status(build)
+        except site_utils.TestLabException as ex:
+            logging.debug('Skipping suite %s, board %s, build %s:  %s',
+                          suite, board, build, str(ex))
+            return False
+        try:
             return not self._afe.get_jobs(name__startswith=build,
                                           name__endswith='control.'+suite)
         except Exception as e:
diff --git a/site_utils/suite_scheduler/deduping_scheduler_unittest.py b/site_utils/suite_scheduler/deduping_scheduler_unittest.py
index a92e3ee..9002547 100644
--- a/site_utils/suite_scheduler/deduping_scheduler_unittest.py
+++ b/site_utils/suite_scheduler/deduping_scheduler_unittest.py
@@ -42,10 +42,30 @@
         super(DedupingSchedulerTest, self).setUp()
         self.afe = self.mox.CreateMock(frontend.AFE)
         self.scheduler = deduping_scheduler.DedupingScheduler(afe=self.afe)
+        self.mox.StubOutWithMock(site_utils, 'check_lab_status')
+
+
+    def _SetupLabStatus(self, build, message=None):
+        """Set up to mock one call to `site_utils.check_lab_status()`.
+
+        @param build    The build to expect to be passed to
+                        `check_lab_status()`.
+        @param message  `None` if the mocked call should return that
+                        the lab status is up.  Otherwise, a string for
+                        the exception message.
+
+        """
+        if message is None:
+            site_utils.check_lab_status(build)
+        else:
+            site_utils.check_lab_status(build).AndRaise(
+                site_utils.TestLabException(message))
 
 
     def testScheduleSuite(self):
         """Test a successful de-dup and suite schedule."""
+        # Lab is UP!
+        self._SetupLabStatus(self._BUILD)
         # A similar suite has not already been scheduled.
         self.afe.get_jobs(name__startswith=self._BUILD,
                           name__endswith='control.'+self._SUITE).AndReturn([])
@@ -72,6 +92,8 @@
 
     def testShouldNotScheduleSuite(self):
         """Test a successful de-dup and avoiding scheduling the suite."""
+        # Lab is UP!
+        self._SetupLabStatus(self._BUILD)
         # A similar suite has already been scheduled.
         self.afe.get_jobs(
             name__startswith=self._BUILD,
@@ -86,6 +108,20 @@
                                                       self._TIMEOUT))
 
 
+    def testShouldNotScheduleSuiteLabClosed(self):
+        """Test that we don't schedule when the lab is closed."""
+        # Lab is down.  :-(
+        self._SetupLabStatus(self._BUILD, 'Lab closed due to sheep.')
+        self.mox.ReplayAll()
+        self.assertFalse(self.scheduler.ScheduleSuite(self._SUITE,
+                                                      self._BOARD,
+                                                      self._BUILD,
+                                                      self._POOL,
+                                                      None,
+                                                      self._PRIORITY,
+                                                      self._TIMEOUT))
+
+
     def testForceScheduleSuite(self):
         """Test a successful de-dup, but force scheduling the suite."""
         # Expect an attempt to schedule; allow it to succeed.
@@ -112,6 +148,8 @@
 
     def testShouldScheduleSuiteExplodes(self):
         """Test a failure to de-dup."""
+        # Lab is UP!
+        self._SetupLabStatus(self._BUILD)
         # Barf while checking for similar suites.
         self.afe.get_jobs(
             name__startswith=self._BUILD,
@@ -130,6 +168,8 @@
 
     def testScheduleFail(self):
         """Test a successful de-dup and failure to schedule the suite."""
+        # Lab is UP!
+        self._SetupLabStatus(self._BUILD)
         # A similar suite has not already been scheduled.
         self.afe.get_jobs(name__startswith=self._BUILD,
                           name__endswith='control.'+self._SUITE).AndReturn([])
@@ -158,6 +198,8 @@
 
     def testScheduleExplodes(self):
         """Test a successful de-dup and barf while scheduling the suite."""
+        # Lab is UP!
+        self._SetupLabStatus(self._BUILD)
         # A similar suite has not already been scheduled.
         self.afe.get_jobs(name__startswith=self._BUILD,
                           name__endswith='control.'+self._SUITE).AndReturn([])
@@ -191,6 +233,8 @@
         self.mox.StubOutWithMock(reporting.Reporter, '_check_tracker')
         self.mox.StubOutWithMock(site_utils, 'get_sheriffs')
         self.scheduler._file_bug = True
+        # Lab is UP!
+        self._SetupLabStatus(self._BUILD)
         # A similar suite has not already been scheduled.
         self.afe.get_jobs(name__startswith=self._BUILD,
                           name__endswith='control.'+self._SUITE).AndReturn([])
diff --git a/site_utils/suite_scheduler/driver.py b/site_utils/suite_scheduler/driver.py
index cda71f5..b43b196 100644
--- a/site_utils/suite_scheduler/driver.py
+++ b/site_utils/suite_scheduler/driver.py
@@ -132,13 +132,6 @@
         logging.info('Boards currently in the lab: %r', boards)
         for e in self._events.itervalues():
             if e.ShouldHandle():
-                try:
-                    utils.check_lab_status()
-                except utils.LabIsDownException as ex:
-                    logging.debug('Skipping event %s, because lab is down '
-                                  'with message: %s', e.keyword, ex.message)
-                    continue
-
                 logging.info('Handling %s event', e.keyword)
                 for board in boards:
                     branch_builds = e.GetBranchBuildsForBoard(board)
diff --git a/site_utils/suite_scheduler/driver_unittest.py b/site_utils/suite_scheduler/driver_unittest.py
index f949ceb..c754d1c 100644
--- a/site_utils/suite_scheduler/driver_unittest.py
+++ b/site_utils/suite_scheduler/driver_unittest.py
@@ -15,7 +15,6 @@
 
 import common
 from autotest_lib.server import frontend
-from autotest_lib.server import utils
 from constants import Labels
 
 
@@ -56,7 +55,6 @@
         self.mox.StubOutWithMock(timed_event.Nightly, 'CreateFromConfig')
         self.mox.StubOutWithMock(timed_event.Weekly, 'CreateFromConfig')
         self.mox.StubOutWithMock(build_event.NewBuild, 'CreateFromConfig')
-        self.mox.StubOutWithMock(utils, 'check_lab_status')
         timed_event.Nightly.CreateFromConfig(
             mox.IgnoreArg(), self.mv).AndReturn(mock_nightly)
         timed_event.Weekly.CreateFromConfig(
@@ -88,19 +86,6 @@
         self.afe.get_labels(name__startswith=prefix).AndReturn(mocks)
 
 
-    def _ExpectLabStatusQuery(self, lab_up=True, message='No message.'):
-        """Expect one call to utils.check_lab_status
-        @param lab_up: True if lab shoule be up. False if lab should be down.
-                       Default: True.
-        @param message: String message with which lab should be down, if down.
-        """
-        if lab_up:
-            utils.check_lab_status()
-        else:
-            utils.check_lab_status().AndRaise(
-                utils.LabIsDownException(message))
-
-
     def _ExpectHandle(self, event, group):
         """Make event report that it's handle-able, and expect it to be handle.
 
@@ -176,7 +161,6 @@
         events = self._ExpectSetup()
         self._ExpectEnumeration()
         for event in events:
-            self._ExpectLabStatusQuery()
             self._ExpectHandle(event, 'events')
         self.mox.ReplayAll()
 
@@ -190,7 +174,6 @@
         self._ExpectEnumeration()
         for event in events:
             if event.keyword == timed_event.Nightly.KEYWORD:
-                self._ExpectLabStatusQuery()
                 self._ExpectHandle(event, 'events')
             else:
                 event.ShouldHandle().InAnyOrder('events').AndReturn(False)
@@ -200,19 +183,6 @@
         self.driver.HandleEventsOnce(self.mv)
 
 
-    def testClosedLab(self):
-        """Test that events do not get handled if the lab is closed."""
-        events = self._ExpectSetup()
-        self._ExpectEnumeration()
-        for event in events:
-            self._ExpectLabStatusQuery(False, 'Lab closed due to sheep.')
-            self._ExpectNoHandle(event, 'events')
-        self.mox.ReplayAll()
-
-        self.driver.SetUpEventsAndTasks(self.config, self.mv)
-        self.driver.HandleEventsOnce(self.mv)
-
-
     def testForceOnceForBuild(self):
         """Test that one event being forced is handled correctly."""
         events = self._ExpectSetup()