gs_offloader_unittest.py revision 4211124209fdb4469462b6e1b39433cc52b76d02
1ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette# Copyright 2013 The Chromium OS Authors. All rights reserved. 2ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette# Use of this source code is governed by a BSD-style license that can be 3ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette# found in the LICENSE file. 4ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 5ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnetteimport Queue 6ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnetteimport datetime 7ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnetteimport logging 8ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnetteimport os 9ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnetteimport shutil 102e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnetteimport signal 11ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnetteimport sys 12ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnetteimport tempfile 13ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnetteimport time 14ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnetteimport unittest 15ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 16ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnetteimport mox 17ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 18ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnetteimport common 19ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnetteimport gs_offloader 20ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnetteimport job_directories 21ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 22dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basifrom autotest_lib.client.common_lib import global_config 231b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shifrom autotest_lib.client.common_lib import time_utils 241b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shifrom autotest_lib.client.common_lib import utils 25ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnettefrom autotest_lib.scheduler import email_manager 26ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 2724f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 28ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette# Test value to use for `days_old`, if nothing else is required. 29ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette_TEST_EXPIRATION_AGE = 7 30ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 31ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette# When constructing sample time values for testing expiration, 32ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette# allow this many seconds between the expiration time and the 33ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette# current time. 34ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette_MARGIN_SECS = 10.0 35ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 36ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 37ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnettedef _get_options(argv): 38ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Helper function to exercise command line parsing. 39ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 40ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette @param argv Value of sys.argv to be parsed. 41ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 42ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 43ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette sys.argv = ['bogus.py'] + argv 44ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette return gs_offloader.parse_options() 45ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 46ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 47dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basiclass OffloaderOptionsTests(mox.MoxTestBase): 48ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette """Tests for the `Offloader` constructor. 49ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette 50ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette Tests that offloader instance fields are set as expected 51ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette for given command line options. 52ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette 53ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette """ 54ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette 55ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette _REGULAR_ONLY = set([job_directories.RegularJobDirectory]) 56ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette _SPECIAL_ONLY = set([job_directories.SpecialJobDirectory]) 57ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette _BOTH = _REGULAR_ONLY | _SPECIAL_ONLY 58ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 5924f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 60dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi def setUp(self): 61dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi super(OffloaderOptionsTests, self).setUp() 62dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi self.mox.StubOutWithMock(utils, 'get_offload_gsuri') 63f3e305f2c1342d8dd271256c2594ae54072c514bSimran Basi gs_offloader.GS_OFFLOADING_ENABLED = True 640df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang gs_offloader.GS_OFFLOADER_MULTIPROCESSING = False 65dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi 6624f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 670df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang def _mock_get_offload_func(self, is_moblab, multiprocessing=False): 68dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi """Mock the process of getting the offload_dir function.""" 69dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi if is_moblab: 70dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi expected_gsuri = '%sresults/%s/%s/' % ( 71dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi global_config.global_config.get_config_value( 72dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi 'CROS', 'image_storage_server'), 73dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi 'Fa:ke:ma:c0:12:34', 'rand0m-uu1d') 74dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi else: 75dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi expected_gsuri = utils.DEFAULT_OFFLOAD_GSURI 76dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi utils.get_offload_gsuri().AndReturn(expected_gsuri) 770df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang offload_func = gs_offloader.get_offload_dir_func( 780df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang expected_gsuri, multiprocessing) 79dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi self.mox.StubOutWithMock(gs_offloader, 'get_offload_dir_func') 800df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang gs_offloader.get_offload_dir_func(expected_gsuri, multiprocessing).AndReturn( 81dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi offload_func) 82dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi self.mox.ReplayAll() 83dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi return offload_func 84dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi 8524f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 86ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def test_process_no_options(self): 87ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette """Test default offloader options.""" 88dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi offload_func = self._mock_get_offload_func(False) 89ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette offloader = gs_offloader.Offloader(_get_options([])) 90ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette self.assertEqual(set(offloader._jobdir_classes), 91ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette self._REGULAR_ONLY) 92ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette self.assertEqual(offloader._processes, 1) 93ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette self.assertEqual(offloader._offload_func, 94dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi offload_func) 95ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette self.assertEqual(offloader._age_limit, 0) 96ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 9724f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 98ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def test_process_all_option(self): 99ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette """Test offloader handling for the --all option.""" 100dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi offload_func = self._mock_get_offload_func(False) 101ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette offloader = gs_offloader.Offloader(_get_options(['--all'])) 102ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette self.assertEqual(set(offloader._jobdir_classes), self._BOTH) 103ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette self.assertEqual(offloader._processes, 1) 104ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette self.assertEqual(offloader._offload_func, 105dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi offload_func) 106ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette self.assertEqual(offloader._age_limit, 0) 107ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 10824f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 109ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def test_process_hosts_option(self): 110ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette """Test offloader handling for the --hosts option.""" 111dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi offload_func = self._mock_get_offload_func(False) 112ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette offloader = gs_offloader.Offloader( 113ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette _get_options(['--hosts'])) 114ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette self.assertEqual(set(offloader._jobdir_classes), 115ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette self._SPECIAL_ONLY) 116ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette self.assertEqual(offloader._processes, 1) 117ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette self.assertEqual(offloader._offload_func, 118dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi offload_func) 119ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette self.assertEqual(offloader._age_limit, 0) 120ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 12124f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 122ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def test_parallelism_option(self): 123ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette """Test offloader handling for the --parallelism option.""" 124dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi offload_func = self._mock_get_offload_func(False) 125ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette offloader = gs_offloader.Offloader( 126ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette _get_options(['--parallelism', '2'])) 127ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette self.assertEqual(set(offloader._jobdir_classes), 128ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette self._REGULAR_ONLY) 129ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette self.assertEqual(offloader._processes, 2) 130ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette self.assertEqual(offloader._offload_func, 131dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi offload_func) 132ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette self.assertEqual(offloader._age_limit, 0) 133ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 13424f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 135ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def test_delete_only_option(self): 136ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette """Test offloader handling for the --delete_only option.""" 137ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette offloader = gs_offloader.Offloader( 138ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette _get_options(['--delete_only'])) 139ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette self.assertEqual(set(offloader._jobdir_classes), 140ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette self._REGULAR_ONLY) 141ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette self.assertEqual(offloader._processes, 1) 142ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette self.assertEqual(offloader._offload_func, 143ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette gs_offloader.delete_files) 144ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette self.assertEqual(offloader._age_limit, 0) 145ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 14624f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 147df4751eaab3405bc4f564d033681d093958f0c10Simran Basi def test_days_old_option(self): 148ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette """Test offloader handling for the --days_old option.""" 149dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi offload_func = self._mock_get_offload_func(False) 150ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette offloader = gs_offloader.Offloader( 151ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette _get_options(['--days_old', '7'])) 152ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette self.assertEqual(set(offloader._jobdir_classes), 153ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette self._REGULAR_ONLY) 154ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette self.assertEqual(offloader._processes, 1) 155ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette self.assertEqual(offloader._offload_func, 156dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi offload_func) 157ef4b47dedcb759b46fd1e415172a688f1448df54J. Richard Barnette self.assertEqual(offloader._age_limit, 7) 158ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 15924f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 160dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi def test_moblab_gsuri_generation(self): 161dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi """Test offloader construction for Moblab.""" 162dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi offload_func = self._mock_get_offload_func(True) 163dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi offloader = gs_offloader.Offloader(_get_options([])) 164dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi self.assertEqual(set(offloader._jobdir_classes), 165dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi self._REGULAR_ONLY) 166dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi self.assertEqual(offloader._processes, 1) 167dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi self.assertEqual(offloader._offload_func, 168dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi offload_func) 169dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi self.assertEqual(offloader._age_limit, 0) 170dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi 171ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 172f3e305f2c1342d8dd271256c2594ae54072c514bSimran Basi def test_globalconfig_offloading_flag(self): 173f3e305f2c1342d8dd271256c2594ae54072c514bSimran Basi """Test enabling of --delete_only via global_config.""" 174f3e305f2c1342d8dd271256c2594ae54072c514bSimran Basi gs_offloader.GS_OFFLOADING_ENABLED = False 175f3e305f2c1342d8dd271256c2594ae54072c514bSimran Basi offloader = gs_offloader.Offloader( 176f3e305f2c1342d8dd271256c2594ae54072c514bSimran Basi _get_options([])) 177f3e305f2c1342d8dd271256c2594ae54072c514bSimran Basi self.assertEqual(offloader._offload_func, 178f3e305f2c1342d8dd271256c2594ae54072c514bSimran Basi gs_offloader.delete_files) 179f3e305f2c1342d8dd271256c2594ae54072c514bSimran Basi 1800df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang def test_offloader_multiprocessing_flag_set(self): 1810df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang """Test multiprocessing is set.""" 1820df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang offload_func = self._mock_get_offload_func(True, True) 1830df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang offloader = gs_offloader.Offloader(_get_options(['-m'])) 1840df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang self.assertEqual(offloader._offload_func, 1850df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang offload_func) 1860df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang self.mox.VerifyAll() 1870df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang 1880df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang def test_offloader_multiprocessing_flag_not_set_default_false(self): 1890df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang """Test multiprocessing is set.""" 1900df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang gs_offloader.GS_OFFLOADER_MULTIPROCESSING = False 1910df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang offload_func = self._mock_get_offload_func(True, False) 1920df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang offloader = gs_offloader.Offloader(_get_options([])) 1930df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang self.assertEqual(offloader._offload_func, 1940df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang offload_func) 1950df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang self.mox.VerifyAll() 1960df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang 1970df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang def test_offloader_multiprocessing_flag_not_set_default_true(self): 1980df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang """Test multiprocessing is set.""" 1990df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang gs_offloader.GS_OFFLOADER_MULTIPROCESSING = True 2000df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang offload_func = self._mock_get_offload_func(True, True) 2010df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang offloader = gs_offloader.Offloader(_get_options([])) 2020df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang self.assertEqual(offloader._offload_func, 2030df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang offload_func) 2040df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang self.mox.VerifyAll() 2050df2eb4e1e8638a1a165e8f2dc3b9230f85acf06Michael Tang 206f3e305f2c1342d8dd271256c2594ae54072c514bSimran Basi 207ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnettedef _make_timestamp(age_limit, is_expired): 208ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Create a timestamp for use by `job_directories._is_job_expired()`. 209ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 210ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette The timestamp will meet the syntactic requirements for 211ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette timestamps used as input to `_is_job_expired()`. If 212ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette `is_expired` is true, the timestamp will be older than 213ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette `age_limit` days before the current time; otherwise, the 214ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette date will be younger. 215ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 216ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette @param age_limit The number of days before expiration of the 217ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette target timestamp. 218ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette @param is_expired Whether the timestamp should be expired 219ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette relative to `age_limit`. 220ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 221ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 222ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette seconds = -_MARGIN_SECS 223ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette if is_expired: 224ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette seconds = -seconds 225ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette delta = datetime.timedelta(days=age_limit, seconds=seconds) 226ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette reference_time = datetime.datetime.now() - delta 227dfea368e5c830b1d7950ced5ee7b191e3b141ca3Dan Shi return reference_time.strftime(time_utils.TIME_FMT) 228ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 229ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 230ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnetteclass JobExpirationTests(unittest.TestCase): 231ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Tests to exercise `job_directories._is_job_expired()`.""" 232ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 233ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def test_expired(self): 234ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Test detection of an expired job.""" 235ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette timestamp = _make_timestamp(_TEST_EXPIRATION_AGE, True) 236ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.assertTrue( 237ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette job_directories._is_job_expired( 238ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette _TEST_EXPIRATION_AGE, timestamp)) 239ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 240ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 241ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def test_alive(self): 242ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Test detection of a job that's not expired.""" 243ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette # N.B. This test may fail if its run time exceeds more than 244ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette # about _MARGIN_SECS seconds. 245ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette timestamp = _make_timestamp(_TEST_EXPIRATION_AGE, False) 246ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.assertFalse( 247ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette job_directories._is_job_expired( 248ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette _TEST_EXPIRATION_AGE, timestamp)) 249ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 250ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 251ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnetteclass _MockJobDirectory(job_directories._JobDirectory): 252ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Subclass of `_JobDirectory` used as a helper for tests.""" 253ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 254ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette GLOB_PATTERN = '[0-9]*-*' 255ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 25624f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 257ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def __init__(self, resultsdir): 258ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Create new job in initial state.""" 259ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette super(_MockJobDirectory, self).__init__(resultsdir) 260ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._timestamp = None 2612c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette self.queue_args = [resultsdir, os.path.dirname(resultsdir)] 262ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 26324f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 264ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def get_timestamp_if_finished(self): 265ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette return self._timestamp 266ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 26724f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 268ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def set_finished(self, days_old): 269ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Make this job appear to be finished. 270ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 271ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette After calling this function, calls to `enqueue_offload()` 272ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette will find this job as finished, but not expired and ready 273ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette for offload. Note that when `days_old` is 0, 274ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette `enqueue_offload()` will treat a finished job as eligible 275ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette for offload. 276ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 277ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette @param days_old The value of the `days_old` parameter that 278ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette will be passed to `enqueue_offload()` for 279ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette testing. 280ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 281ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 282ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._timestamp = _make_timestamp(days_old, False) 283ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 28424f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 285ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def set_expired(self, days_old): 286ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Make this job eligible to be offloaded. 287ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 288ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette After calling this function, calls to `offload` will attempt 289ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette to offload this job. 290ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 291ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette @param days_old The value of the `days_old` parameter that 292ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette will be passed to `enqueue_offload()` for 293ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette testing. 294ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 295ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 296ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._timestamp = _make_timestamp(days_old, True) 297ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 29824f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 299ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def set_incomplete(self): 300ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Make this job appear to have failed offload just once.""" 301ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._offload_count += 1 30222dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self._first_offload_start = time.time() 303ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette if not os.path.isdir(self._dirname): 304ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette os.mkdir(self._dirname) 305ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 30624f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 307ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def set_reportable(self): 308ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Make this job be reportable.""" 309ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.set_incomplete() 31022dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self._offload_count += 1 311ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 31224f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 313ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def set_complete(self): 314ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Make this job be completed.""" 315ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._offload_count += 1 316ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette if os.path.isdir(self._dirname): 317ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette os.rmdir(self._dirname) 318ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 319ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 3201e10e92049f4b2724ea43186083e995e418f9802Simran Basi def process_gs_instructions(self): 3211e10e92049f4b2724ea43186083e995e418f9802Simran Basi """Always still offload the job directory.""" 3221e10e92049f4b2724ea43186083e995e418f9802Simran Basi return True 3231e10e92049f4b2724ea43186083e995e418f9802Simran Basi 3241e10e92049f4b2724ea43186083e995e418f9802Simran Basi 3259f4be0d66119211b3ece24bb985f1412d1f61322J. Richard Barnetteclass CommandListTests(unittest.TestCase): 3269f4be0d66119211b3ece24bb985f1412d1f61322J. Richard Barnette """Tests for `get_cmd_list()`.""" 3279f4be0d66119211b3ece24bb985f1412d1f61322J. Richard Barnette 328e93c85778aa8b22aa88482c43092133d59434147MK Ryu def _command_list_assertions(self, job, use_rsync=True, multi=False): 3299f4be0d66119211b3ece24bb985f1412d1f61322J. Richard Barnette """Call `get_cmd_list()` and check the return value. 3309f4be0d66119211b3ece24bb985f1412d1f61322J. Richard Barnette 3319f4be0d66119211b3ece24bb985f1412d1f61322J. Richard Barnette Check the following assertions: 3329f4be0d66119211b3ece24bb985f1412d1f61322J. Richard Barnette * The command name (argv[0]) is 'gsutil'. 333e93c85778aa8b22aa88482c43092133d59434147MK Ryu * '-m' option (argv[1]) is on when the argument, multi, is True. 3349f4be0d66119211b3ece24bb985f1412d1f61322J. Richard Barnette * The arguments contain the 'cp' subcommand. 3359f4be0d66119211b3ece24bb985f1412d1f61322J. Richard Barnette * The next-to-last argument (the source directory) is the 3369f4be0d66119211b3ece24bb985f1412d1f61322J. Richard Barnette job's `queue_args[0]`. 337dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi * The last argument (the destination URL) is the job's 338dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi 'queue_args[1]'. 3399f4be0d66119211b3ece24bb985f1412d1f61322J. Richard Barnette 3409f4be0d66119211b3ece24bb985f1412d1f61322J. Richard Barnette @param job A job with properly calculated arguments to 3419f4be0d66119211b3ece24bb985f1412d1f61322J. Richard Barnette `get_cmd_list()` 342e93c85778aa8b22aa88482c43092133d59434147MK Ryu @param use_rsync True when using 'rsync'. False when using 'cp'. 343e93c85778aa8b22aa88482c43092133d59434147MK Ryu @param multi True when using '-m' option for gsutil. 3449f4be0d66119211b3ece24bb985f1412d1f61322J. Richard Barnette 3459f4be0d66119211b3ece24bb985f1412d1f61322J. Richard Barnette """ 34624f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich test_bucket_uri = 'gs://a-test-bucket' 34724f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 34824f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich gs_offloader.USE_RSYNC_ENABLED = use_rsync 34924f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 35024f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich command = gs_offloader.get_cmd_list( 351e93c85778aa8b22aa88482c43092133d59434147MK Ryu multi, job.queue_args[0], 352e93c85778aa8b22aa88482c43092133d59434147MK Ryu os.path.join(test_bucket_uri, job.queue_args[1])) 35324f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 3549f4be0d66119211b3ece24bb985f1412d1f61322J. Richard Barnette self.assertEqual(command[0], 'gsutil') 355e93c85778aa8b22aa88482c43092133d59434147MK Ryu if multi: 356e93c85778aa8b22aa88482c43092133d59434147MK Ryu self.assertEqual(command[1], '-m') 3579f4be0d66119211b3ece24bb985f1412d1f61322J. Richard Barnette self.assertEqual(command[-2], job.queue_args[0]) 35824f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 35924f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich if use_rsync: 36024f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich self.assertTrue('rsync' in command) 36124f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich self.assertEqual(command[-1], 36224f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich os.path.join(test_bucket_uri, job.queue_args[0])) 36324f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich else: 36424f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich self.assertTrue('cp' in command) 36524f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich self.assertEqual(command[-1], 36624f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich os.path.join(test_bucket_uri, job.queue_args[1])) 36724f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 3689f4be0d66119211b3ece24bb985f1412d1f61322J. Richard Barnette 3699f4be0d66119211b3ece24bb985f1412d1f61322J. Richard Barnette def test_get_cmd_list_regular(self): 3709f4be0d66119211b3ece24bb985f1412d1f61322J. Richard Barnette """Test `get_cmd_list()` as for a regular job.""" 3719f4be0d66119211b3ece24bb985f1412d1f61322J. Richard Barnette job = _MockJobDirectory('118-debug') 3729f4be0d66119211b3ece24bb985f1412d1f61322J. Richard Barnette self._command_list_assertions(job) 3739f4be0d66119211b3ece24bb985f1412d1f61322J. Richard Barnette 37424f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 3759f4be0d66119211b3ece24bb985f1412d1f61322J. Richard Barnette def test_get_cmd_list_special(self): 3769f4be0d66119211b3ece24bb985f1412d1f61322J. Richard Barnette """Test `get_cmd_list()` as for a special job.""" 3779f4be0d66119211b3ece24bb985f1412d1f61322J. Richard Barnette job = _MockJobDirectory('hosts/host1/118-reset') 3789f4be0d66119211b3ece24bb985f1412d1f61322J. Richard Barnette self._command_list_assertions(job) 3799f4be0d66119211b3ece24bb985f1412d1f61322J. Richard Barnette 3809f4be0d66119211b3ece24bb985f1412d1f61322J. Richard Barnette 38124f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich def test_get_cmd_list_regular_no_rsync(self): 38224f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich """Test `get_cmd_list()` as for a regular job.""" 38324f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich job = _MockJobDirectory('118-debug') 38424f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich self._command_list_assertions(job, use_rsync=False) 38524f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 38624f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 38724f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich def test_get_cmd_list_special_no_rsync(self): 38824f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich """Test `get_cmd_list()` as for a special job.""" 38924f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich job = _MockJobDirectory('hosts/host1/118-reset') 39024f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich self._command_list_assertions(job, use_rsync=False) 39124f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 39224f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 393e93c85778aa8b22aa88482c43092133d59434147MK Ryu def test_get_cmd_list_regular_multi(self): 394e93c85778aa8b22aa88482c43092133d59434147MK Ryu """Test `get_cmd_list()` as for a regular job with True multi.""" 395e93c85778aa8b22aa88482c43092133d59434147MK Ryu job = _MockJobDirectory('118-debug') 396e93c85778aa8b22aa88482c43092133d59434147MK Ryu self._command_list_assertions(job, multi=True) 397e93c85778aa8b22aa88482c43092133d59434147MK Ryu 398e93c85778aa8b22aa88482c43092133d59434147MK Ryu 399e93c85778aa8b22aa88482c43092133d59434147MK Ryu def test_get_cmd_list_special_multi(self): 400e93c85778aa8b22aa88482c43092133d59434147MK Ryu """Test `get_cmd_list()` as for a special job with True multi.""" 401e93c85778aa8b22aa88482c43092133d59434147MK Ryu job = _MockJobDirectory('hosts/host1/118-reset') 402e93c85778aa8b22aa88482c43092133d59434147MK Ryu self._command_list_assertions(job, multi=True) 403e93c85778aa8b22aa88482c43092133d59434147MK Ryu 404e93c85778aa8b22aa88482c43092133d59434147MK Ryu 405ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette# Below is partial sample of e-mail notification text. This text is 406ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette# deliberately hard-coded and then parsed to create the test data; 407ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette# the idea is to make sure the actual text format will be reviewed 408ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette# by a human being. 409ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette# 410ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette# first offload count directory 411ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette# --+----1----+---- ----+ ----+----1----+----2----+----3 412ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette_SAMPLE_DIRECTORIES_REPORT = '''\ 413ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette=================== ====== ============================== 414ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette2014-03-14 15:09:26 1 118-fubar 415ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette2014-03-14 15:19:23 2 117-fubar 416ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette2014-03-14 15:29:20 6 116-fubar 417ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette2014-03-14 15:39:17 24 115-fubar 418ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette2014-03-14 15:49:14 120 114-fubar 419ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette2014-03-14 15:59:11 720 113-fubar 420ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette2014-03-14 16:09:08 5040 112-fubar 421ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette2014-03-14 16:19:05 40320 111-fubar 422ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette''' 423ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 424ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 425ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnetteclass EmailTemplateTests(mox.MoxTestBase): 426ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Test the formatting of e-mail notifications.""" 427ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 428ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def setUp(self): 429ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette super(EmailTemplateTests, self).setUp() 430ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.mox.StubOutWithMock(email_manager.manager, 431ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 'send_email') 432ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._joblist = [] 433ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette for line in _SAMPLE_DIRECTORIES_REPORT.split('\n')[1 : -1]: 434ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette date_, time_, count, dir_ = line.split() 435ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette job = _MockJobDirectory(dir_) 436ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette job._offload_count = int(count) 437dfea368e5c830b1d7950ced5ee7b191e3b141ca3Dan Shi timestruct = time.strptime("%s %s" % (date_, time_), 438dfea368e5c830b1d7950ced5ee7b191e3b141ca3Dan Shi gs_offloader.ERROR_EMAIL_TIME_FORMAT) 439ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette job._first_offload_start = time.mktime(timestruct) 440ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette # enter the jobs in reverse order, to make sure we 441ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette # test that the output will be sorted. 442ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._joblist.insert(0, job) 443ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 44424f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 445ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def test_email_template(self): 446ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Trigger an e-mail report and check its contents.""" 447ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette # The last line of the report is a separator that we 448ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette # repeat in the first line of our expected result data. 449ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette # So, we remove that separator from the end of the of 450ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette # the e-mail report message. 451ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette # 452ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette # The last element in the list returned by split('\n') 453ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette # will be an empty string, so to remove the separator, 454ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette # we remove the next-to-last entry in the list. 455ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette report_lines = gs_offloader.ERROR_EMAIL_REPORT_FORMAT.split('\n') 456ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette expected_message = ('\n'.join(report_lines[: -2] + 457ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette report_lines[-1 :]) + 458ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette _SAMPLE_DIRECTORIES_REPORT) 459ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette email_manager.manager.send_email( 460ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette mox.IgnoreArg(), mox.IgnoreArg(), expected_message) 461ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.mox.ReplayAll() 462ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette gs_offloader.report_offload_failures(self._joblist) 463ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 464ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 465686ae8c339d31988e07bde0ab5d7b3731c0570f1Kevin Cheng def test_email_url(self): 466686ae8c339d31988e07bde0ab5d7b3731c0570f1Kevin Cheng """Check that the expected helper url is in the email header.""" 467686ae8c339d31988e07bde0ab5d7b3731c0570f1Kevin Cheng self.assertIn(gs_offloader.ERROR_EMAIL_HELPER_URL, 468686ae8c339d31988e07bde0ab5d7b3731c0570f1Kevin Cheng gs_offloader.ERROR_EMAIL_REPORT_FORMAT) 469686ae8c339d31988e07bde0ab5d7b3731c0570f1Kevin Cheng 470686ae8c339d31988e07bde0ab5d7b3731c0570f1Kevin Cheng 471dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnetteclass _MockJob(object): 472dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette """Class to mock the return value of `AFE.get_jobs()`.""" 473dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette def __init__(self, created): 474dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette self.created_on = created 475dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette 476dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette 477dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnetteclass _MockHostQueueEntry(object): 478dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette """Class to mock the return value of `AFE.get_host_queue_entries()`.""" 479dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette def __init__(self, finished): 480dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette self.finished_on = finished 481dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette 482dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette 483dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnetteclass _MockSpecialTask(object): 484dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette """Class to mock the return value of `AFE.get_special_tasks()`.""" 485dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette def __init__(self, finished): 486dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette self.time_finished = finished 487dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette 488dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette 4892c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnetteclass JobDirectorySubclassTests(mox.MoxTestBase): 4902c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette """Test specific to RegularJobDirectory and SpecialJobDirectory. 4913e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette 4923e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette This provides coverage for the implementation in both 4933e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette RegularJobDirectory and SpecialJobDirectory. 4943e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette 4953e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette """ 4963e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette 4973e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette def setUp(self): 4982c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette super(JobDirectorySubclassTests, self).setUp() 499dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette self.mox.StubOutWithMock(job_directories._AFE, 'get_jobs') 500dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette self.mox.StubOutWithMock(job_directories._AFE, 501dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette 'get_host_queue_entries') 502dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette self.mox.StubOutWithMock(job_directories._AFE, 503dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette 'get_special_tasks') 5043e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette 50524f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 5062c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette def test_regular_job_fields(self): 5072c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette """Test the constructor for `RegularJobDirectory`. 5082c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette 5092c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette Construct a regular job, and assert that the `_dirname` 5102c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette and `_id` attributes are set as expected. 5112c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette 5122c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette """ 5132c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette resultsdir = '118-fubar' 5142c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette job = job_directories.RegularJobDirectory(resultsdir) 5152c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette self.assertEqual(job._dirname, resultsdir) 516cf4d2032ea4bf5af680383f36308d581876bbbb0Dan Shi self.assertEqual(job._id, 118) 5172c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette 51824f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 5192c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette def test_special_job_fields(self): 5202c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette """Test the constructor for `SpecialJobDirectory`. 5212c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette 5222c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette Construct a special job, and assert that the `_dirname` 5232c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette and `_id` attributes are set as expected. 5242c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette 5252c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette """ 5262c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette destdir = 'hosts/host1' 5272c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette resultsdir = destdir + '/118-reset' 5282c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette job = job_directories.SpecialJobDirectory(resultsdir) 5292c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette self.assertEqual(job._dirname, resultsdir) 530cf4d2032ea4bf5af680383f36308d581876bbbb0Dan Shi self.assertEqual(job._id, 118) 5312c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette 53224f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 533dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette def _check_finished_job(self, jobtime, hqetimes, expected): 534dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette """Mock and test behavior of a finished job. 535dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette 536dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette Initialize the mocks for a call to 537dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette `get_timestamp_if_finished()`, then simulate one call. 538dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette Assert that the returned timestamp matches the passed 539dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette in expected value. 540dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette 541dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette @param jobtime Time used to construct a _MockJob object. 542dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette @param hqetimes List of times used to construct 543dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette _MockHostQueueEntry objects. 544dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette @param expected Expected time to be returned by 545dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette get_timestamp_if_finished 546dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette 547dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette """ 548dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette job = job_directories.RegularJobDirectory('118-fubar') 549dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette job_directories._AFE.get_jobs( 550dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette id=job._id, finished=True).AndReturn( 551dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette [_MockJob(jobtime)]) 552dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette job_directories._AFE.get_host_queue_entries( 553dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette finished_on__isnull=False, 554dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette job_id=job._id).AndReturn( 555dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette [_MockHostQueueEntry(t) for t in hqetimes]) 556dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette self.mox.ReplayAll() 557dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette self.assertEqual(expected, job.get_timestamp_if_finished()) 558dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette self.mox.VerifyAll() 559dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette 560dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette 5613e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette def test_finished_regular_job(self): 5623e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette """Test getting the timestamp for a finished regular job. 5633e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette 5643e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette Tests the return value for 5653e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette `RegularJobDirectory.get_timestamp_if_finished()` when 5663e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette the AFE indicates the job is finished. 5673e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette 5683e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette """ 569dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette created_timestamp = _make_timestamp(1, True) 570dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette hqe_timestamp = _make_timestamp(0, True) 571dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette self._check_finished_job(created_timestamp, 572dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette [hqe_timestamp], 573dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette hqe_timestamp) 574fb98e46b33c3f683173b980e027523dfb91f2759Simran Basi 57524f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 576fb98e46b33c3f683173b980e027523dfb91f2759Simran Basi def test_finished_regular_job_multiple_hqes(self): 577fb98e46b33c3f683173b980e027523dfb91f2759Simran Basi """Test getting the timestamp for a regular job with multiple hqes. 578fb98e46b33c3f683173b980e027523dfb91f2759Simran Basi 579fb98e46b33c3f683173b980e027523dfb91f2759Simran Basi Tests the return value for 580fb98e46b33c3f683173b980e027523dfb91f2759Simran Basi `RegularJobDirectory.get_timestamp_if_finished()` when 581fb98e46b33c3f683173b980e027523dfb91f2759Simran Basi the AFE indicates the job is finished and the job has multiple host 582fb98e46b33c3f683173b980e027523dfb91f2759Simran Basi queue entries. 583fb98e46b33c3f683173b980e027523dfb91f2759Simran Basi 584dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette Tests that the returned timestamp is the latest timestamp in 585dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette the list of HQEs, regardless of the returned order. 586dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette 587fb98e46b33c3f683173b980e027523dfb91f2759Simran Basi """ 588fb98e46b33c3f683173b980e027523dfb91f2759Simran Basi created_timestamp = _make_timestamp(2, True) 589fb98e46b33c3f683173b980e027523dfb91f2759Simran Basi older_hqe_timestamp = _make_timestamp(1, True) 590fb98e46b33c3f683173b980e027523dfb91f2759Simran Basi newer_hqe_timestamp = _make_timestamp(0, True) 591dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette hqe_list = [older_hqe_timestamp, 592dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette newer_hqe_timestamp] 593dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette self._check_finished_job(created_timestamp, 594dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette hqe_list, 595dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette newer_hqe_timestamp) 596dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette self.mox.ResetAll() 597dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette hqe_list.reverse() 598dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette self._check_finished_job(created_timestamp, 599dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette hqe_list, 600dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette newer_hqe_timestamp) 601fb98e46b33c3f683173b980e027523dfb91f2759Simran Basi 60224f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 603fb98e46b33c3f683173b980e027523dfb91f2759Simran Basi def test_finished_regular_job_null_finished_times(self): 604fb98e46b33c3f683173b980e027523dfb91f2759Simran Basi """Test getting the timestamp for an aborted regular job. 605fb98e46b33c3f683173b980e027523dfb91f2759Simran Basi 606fb98e46b33c3f683173b980e027523dfb91f2759Simran Basi Tests the return value for 607fb98e46b33c3f683173b980e027523dfb91f2759Simran Basi `RegularJobDirectory.get_timestamp_if_finished()` when 608fb98e46b33c3f683173b980e027523dfb91f2759Simran Basi the AFE indicates the job is finished and the job has aborted host 609fb98e46b33c3f683173b980e027523dfb91f2759Simran Basi queue entries. 610fb98e46b33c3f683173b980e027523dfb91f2759Simran Basi 611fb98e46b33c3f683173b980e027523dfb91f2759Simran Basi """ 612fb98e46b33c3f683173b980e027523dfb91f2759Simran Basi timestamp = _make_timestamp(0, True) 613dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette self._check_finished_job(timestamp, [], timestamp) 6143e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette 61524f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 6163e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette def test_unfinished_regular_job(self): 6173e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette """Test getting the timestamp for an unfinished regular job. 6183e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette 6193e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette Tests the return value for 6203e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette `RegularJobDirectory.get_timestamp_if_finished()` when 6213e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette the AFE indicates the job is not finished. 6223e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette 6233e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette """ 6243e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette job = job_directories.RegularJobDirectory('118-fubar') 625dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette job_directories._AFE.get_jobs( 626dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette id=job._id, finished=True).AndReturn([]) 6273e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette self.mox.ReplayAll() 6283e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette self.assertIsNone(job.get_timestamp_if_finished()) 629dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette self.mox.VerifyAll() 6303e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette 63124f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 6323e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette def test_finished_special_job(self): 6333e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette """Test getting the timestamp for a finished special job. 6343e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette 6353e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette Tests the return value for 6363e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette `SpecialJobDirectory.get_timestamp_if_finished()` when 6373e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette the AFE indicates the job is finished. 6383e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette 6393e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette """ 6402c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette job = job_directories.SpecialJobDirectory( 6412c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette 'hosts/host1/118-reset') 6423e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette timestamp = _make_timestamp(0, True) 643dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette job_directories._AFE.get_special_tasks( 644dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette id=job._id, is_complete=True).AndReturn( 645dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette [_MockSpecialTask(timestamp)]) 6463e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette self.mox.ReplayAll() 6473e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette self.assertEqual(timestamp, 6483e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette job.get_timestamp_if_finished()) 649dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette self.mox.VerifyAll() 6503e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette 65124f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 6523e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette def test_unfinished_special_job(self): 6533e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette """Test getting the timestamp for an unfinished special job. 6543e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette 6553e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette Tests the return value for 6563e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette `SpecialJobDirectory.get_timestamp_if_finished()` when 6573e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette the AFE indicates the job is not finished. 6583e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette 6593e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette """ 6602c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette job = job_directories.SpecialJobDirectory( 6612c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette 'hosts/host1/118-reset') 662dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette job_directories._AFE.get_special_tasks( 663dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette id=job._id, is_complete=True).AndReturn([]) 6643e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette self.mox.ReplayAll() 6653e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette self.assertIsNone(job.get_timestamp_if_finished()) 666dd0227d5503b9c0ea63837eec26f87c4e4958e4aJ. Richard Barnette self.mox.VerifyAll() 6673e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette 6683e3ed6a9627a156a2240d607565e7c6f78151f28J. Richard Barnette 669ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnetteclass _TempResultsDirTestBase(mox.MoxTestBase): 670ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Base class for tests using a temporary results directory.""" 671ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 6720880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette REGULAR_JOBLIST = [ 6730880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette '111-fubar', '112-fubar', '113-fubar', '114-snafu'] 6740880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette HOST_LIST = ['host1', 'host2', 'host3'] 6750880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette SPECIAL_JOBLIST = [ 6760880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette 'hosts/host1/333-reset', 'hosts/host1/334-reset', 6770880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette 'hosts/host2/444-reset', 'hosts/host3/555-reset'] 6780880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette 67924f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 680ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def setUp(self): 681ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette super(_TempResultsDirTestBase, self).setUp() 6820880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette self._resultsroot = tempfile.mkdtemp() 6830880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette self._cwd = os.getcwd() 6840880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette os.chdir(self._resultsroot) 685ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 68624f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 687ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def tearDown(self): 6880880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette os.chdir(self._cwd) 689ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette shutil.rmtree(self._resultsroot) 690ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette super(_TempResultsDirTestBase, self).tearDown() 691ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 69224f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 693ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def make_job(self, jobdir): 694ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Create a job with results in `self._resultsroot`. 695ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 696ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette @param jobdir Name of the subdirectory to be created in 697ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette `self._resultsroot`. 698ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 699ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 7000880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette os.mkdir(jobdir) 7010880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette return _MockJobDirectory(jobdir) 7020880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette 70324f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 7040880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette def make_job_hierarchy(self): 7050880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette """Create a sample hierarchy of job directories. 7060880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette 7070880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette `self.REGULAR_JOBLIST` is a list of directories for regular 7080880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette jobs to be created; `self.SPECIAL_JOBLIST` is a list of 7090880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette directories for special jobs to be created. 7100880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette 7110880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette """ 7120880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette for d in self.REGULAR_JOBLIST: 7130880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette os.mkdir(d) 7140880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette hostsdir = 'hosts' 7150880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette os.mkdir(hostsdir) 7160880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette for host in self.HOST_LIST: 7170880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette os.mkdir(os.path.join(hostsdir, host)) 7180880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette for d in self.SPECIAL_JOBLIST: 7190880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette os.mkdir(d) 720ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 721ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 7222e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnetteclass OffloadDirectoryTests(_TempResultsDirTestBase): 7232e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette """Tests for `offload_dir()`.""" 7242e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette 7252e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette def setUp(self): 7262e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette super(OffloadDirectoryTests, self).setUp() 7272e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette # offload_dir() logs messages; silence them. 7282e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette self._saved_loglevel = logging.getLogger().getEffectiveLevel() 7292e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette logging.getLogger().setLevel(logging.CRITICAL+1) 7302e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette self._job = self.make_job(self.REGULAR_JOBLIST[0]) 7312e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette self.mox.StubOutWithMock(gs_offloader, 'get_cmd_list') 7322e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette self.mox.StubOutWithMock(signal, 'alarm') 7332e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette 73424f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 7352e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette def tearDown(self): 7362e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette logging.getLogger().setLevel(self._saved_loglevel) 7372e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette super(OffloadDirectoryTests, self).tearDown() 7382e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette 7394211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia def _mock_upload_testresult_files(self): 7404211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia self.mox.StubOutWithMock(gs_offloader, 'upload_testresult_files') 7414211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia gs_offloader.upload_testresult_files( 7424211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia mox.IgnoreArg(),mox.IgnoreArg()).AndReturn(None) 74324f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 744dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi def _mock_offload_dir_calls(self, command, queue_args): 7452e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette """Mock out the calls needed by `offload_dir()`. 7462e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette 7472e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette This covers only the calls made when there is no timeout. 7482e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette 7492e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette @param command Command list to be returned by the mocked 7502e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette call to `get_cmd_list()`. 7512e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette 7522e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette """ 7532e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette signal.alarm(gs_offloader.OFFLOAD_TIMEOUT_SECS) 754dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi command.append(queue_args[0]) 7552e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette gs_offloader.get_cmd_list( 756e93c85778aa8b22aa88482c43092133d59434147MK Ryu False, queue_args[0], 757e93c85778aa8b22aa88482c43092133d59434147MK Ryu '%s%s' % (utils.DEFAULT_OFFLOAD_GSURI, 758e93c85778aa8b22aa88482c43092133d59434147MK Ryu queue_args[1])).AndReturn(command) 7594211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia self._mock_upload_testresult_files() 7602e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette signal.alarm(0) 7612e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette signal.alarm(0) 7622e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette 76324f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 7642e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette def _run_offload_dir(self, should_succeed): 7652e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette """Make one call to `offload_dir()`. 7662e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette 7672e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette The caller ensures all mocks are set up already. 7682e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette 7692e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette @param should_succeed True iff the call to `offload_dir()` 7702e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette is expected to succeed and remove the 7712e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette offloaded job directory. 7722e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette 7732e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette """ 7742e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette self.mox.ReplayAll() 775dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi gs_offloader.get_offload_dir_func( 776e93c85778aa8b22aa88482c43092133d59434147MK Ryu utils.DEFAULT_OFFLOAD_GSURI, False)( 777e93c85778aa8b22aa88482c43092133d59434147MK Ryu self._job.queue_args[0], 778e93c85778aa8b22aa88482c43092133d59434147MK Ryu self._job.queue_args[1]) 7792e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette self.mox.VerifyAll() 7802e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette self.assertEqual(not should_succeed, 7812e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette os.path.isdir(self._job.queue_args[0])) 7822e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette 78324f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 7842e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette def test_offload_success(self): 7852e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette """Test that `offload_dir()` can succeed correctly.""" 786dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi self._mock_offload_dir_calls(['test', '-d'], 787dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi self._job.queue_args) 7882e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette self._run_offload_dir(True) 7892e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette 79024f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 7912e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette def test_offload_failure(self): 7922e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette """Test that `offload_dir()` can fail correctly.""" 793dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi self._mock_offload_dir_calls(['test', '!', '-d'], 794dd129979e8227c960f4c7a3d2a1665007f8a424eSimran Basi self._job.queue_args) 7952e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette self._run_offload_dir(False) 7962e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette 79724f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 7982e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette def test_offload_timeout_early(self): 7992e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette """Test that `offload_dir()` times out correctly. 8002e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette 8012e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette This test triggers timeout at the earliest possible moment, 8022e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette at the first call to set the timeout alarm. 8032e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette 8042e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette """ 8054211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia self._mock_upload_testresult_files() 8062e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette signal.alarm(gs_offloader.OFFLOAD_TIMEOUT_SECS).AndRaise( 8072e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette gs_offloader.TimeoutException('fubar')) 8082e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette signal.alarm(0) 8092e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette self._run_offload_dir(False) 8102e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette 81124f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 8122e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette def test_offload_timeout_late(self): 8132e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette """Test that `offload_dir()` times out correctly. 8142e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette 8152e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette This test triggers timeout at the latest possible moment, at 8162e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette the call to clear the timeout alarm. 8172e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette 8182e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette """ 8192e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette signal.alarm(gs_offloader.OFFLOAD_TIMEOUT_SECS) 8202e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette gs_offloader.get_cmd_list( 821e93c85778aa8b22aa88482c43092133d59434147MK Ryu False, mox.IgnoreArg(), mox.IgnoreArg()).AndReturn( 8222e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette ['test', '-d', self._job.queue_args[0]]) 8234211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia self._mock_upload_testresult_files() 8242e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette signal.alarm(0).AndRaise( 8252e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette gs_offloader.TimeoutException('fubar')) 8262e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette signal.alarm(0) 8272e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette self._run_offload_dir(False) 8282e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette 8292e443efce8dc34f6db6ab566a4c8a552fd8fff2dJ. Richard Barnette 830affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi def test_sanitize_dir(self): 831affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi """Test that folder/file name with invalid character can be corrected. 832affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi """ 833affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi results_folder = tempfile.mkdtemp() 834affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi invalid_chars = '_'.join(gs_offloader.INVALID_GS_CHARS) 835affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi invalid_files = [] 836affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi invalid_folder = os.path.join( 837affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi results_folder, 838affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi 'invalid_name_folder_%s' % invalid_chars) 839affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi invalid_files.append(os.path.join( 840affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi invalid_folder, 841affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi 'invalid_name_file_%s' % invalid_chars)) 842affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi for r in gs_offloader.INVALID_GS_CHAR_RANGE: 843affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi for c in range(r[0], r[1]+1): 844affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi # NULL cannot be in file name. 845affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi if c != 0: 846affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi invalid_files.append(os.path.join( 847affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi invalid_folder, 848affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi 'invalid_name_file_%s' % chr(c))) 849affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi good_folder = os.path.join(results_folder, 'valid_name_folder') 850affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi good_file = os.path.join(good_folder, 'valid_name_file') 851affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi for folder in [invalid_folder, good_folder]: 852affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi os.makedirs(folder) 853affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi for f in invalid_files + [good_file]: 854affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi with open(f, 'w'): 855affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi pass 856affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi gs_offloader.sanitize_dir(results_folder) 857affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi for _, dirs, files in os.walk(results_folder): 858affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi for name in dirs + files: 859affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi self.assertEqual(name, gs_offloader.get_sanitized_name(name)) 860affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi for c in name: 861affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi self.assertFalse(c in gs_offloader.INVALID_GS_CHARS) 862affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi for r in gs_offloader.INVALID_GS_CHAR_RANGE: 863affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi self.assertFalse(ord(c) >= r[0] and ord(c) <= r[1]) 864affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi self.assertTrue(os.path.exists(good_file)) 865affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi shutil.rmtree(results_folder) 866affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi 867affb922d30a3f5e528103c0314d5f0586b7a90dcDan Shi 8681b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi def check_limit_file_count(self, is_test_job=True): 8691b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi """Test that folder with too many files can be compressed. 8701b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi 8711b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi @param is_test_job: True to check the method with test job result 8721b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi folder. Set to False for special task folder. 8731b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi """ 8741b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi results_folder = tempfile.mkdtemp() 8751b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi host_folder = os.path.join( 8761b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi results_folder, 8771b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi 'lab1-host1' if is_test_job else 'hosts/lab1-host1/1-repair') 8781b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi debug_folder = os.path.join(host_folder, 'debug') 8791b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi sysinfo_folder = os.path.join(host_folder, 'sysinfo') 8801b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi for folder in [debug_folder, sysinfo_folder]: 8811b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi os.makedirs(folder) 8821b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi for i in range(10): 8831b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi with open(os.path.join(folder, str(i)), 'w') as f: 8841b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi f.write('test') 8851b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi 8861b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi gs_offloader.MAX_FILE_COUNT = 100 8871b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi gs_offloader.limit_file_count( 8881b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi results_folder if is_test_job else host_folder) 8891b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi self.assertTrue(os.path.exists(sysinfo_folder)) 8901b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi 8911b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi gs_offloader.MAX_FILE_COUNT = 10 8921b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi gs_offloader.limit_file_count( 8931b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi results_folder if is_test_job else host_folder) 8941b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi self.assertFalse(os.path.exists(sysinfo_folder)) 8951b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi self.assertTrue(os.path.exists(sysinfo_folder + '.tgz')) 8961b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi self.assertTrue(os.path.exists(debug_folder)) 8971b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi 8981b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi shutil.rmtree(results_folder) 8991b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi 9001b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi 9011b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi def test_limit_file_count(self): 9021b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi """Test that folder with too many files can be compressed. 9031b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi """ 9041b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi self.check_limit_file_count(is_test_job=True) 9051b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi self.check_limit_file_count(is_test_job=False) 9061b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi 9074211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia def test_upload_testresult_files(self): 9084211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia """Test upload_testresult_files""" 9094211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia results_folder = tempfile.mkdtemp() 9104211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia host_folder = os.path.join(results_folder, 'chromeos4-row9-rack11-host22') 9114211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia debug_folder = os.path.join(host_folder, 'debug') 9124211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia sysinfo_folder = os.path.join(host_folder, 'sysinfo') 9134211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia cts_result_folder = os.path.join( 9144211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia host_folder, 'cheets_CTS.android.dpi', 'results', 'cts-results') 9154211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia timestamp_str = '2016.04.28_01.41.44' 9164211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia timestamp_folder = os.path.join(cts_result_folder, timestamp_str) 9174211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia for folder in [debug_folder, sysinfo_folder, cts_result_folder, timestamp_folder]: 9184211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia os.makedirs(folder) 9194211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia zip_file = os.path.join(cts_result_folder, timestamp_str + '.zip') 9204211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia with open(zip_file, 'w') as f: 9214211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia f.write('test') 9224211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia 9234211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia test_result_file = os.path.join(timestamp_folder, 'testResult.xml') 9244211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia with open(test_result_file, 'w') as f: 9254211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia f.write('test') 9264211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia 9274211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia gs_offloader.get_cmd_list( 9284211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia False, mox.IgnoreArg(), mox.IgnoreArg()).AndReturn( 9294211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia ['test', '-d', cts_result_folder]) 9304211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia gs_offloader.get_cmd_list( 9314211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia False, mox.IgnoreArg(), mox.IgnoreArg()).AndReturn( 9324211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia ['test', '-d', cts_result_folder]) 9334211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia 9344211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia self.mox.ReplayAll() 9354211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia gs_offloader.upload_testresult_files(results_folder, False) 9364211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia self.mox.VerifyAll() 9374211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia self.assertTrue(os.path.exists(zip_file)) 9384211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia self.assertFalse(os.path.exists( 9394211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia os.path.join(timestamp_folder,'testResult.xml.gz'))) 9404211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia 9414211124209fdb4469462b6e1b39433cc52b76d02Ningning Xia shutil.rmtree(results_folder) 9421b4c7c396d5043b24d6bf65c069a85371bb00e5cDan Shi 943ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnetteclass JobDirectoryOffloadTests(_TempResultsDirTestBase): 944ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Tests for `_JobDirectory.enqueue_offload()`. 945ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 946ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette When testing with a `days_old` parameter of 0, we use 947ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette `set_finished()` instead of `set_expired()`. This causes the 948ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette job's timestamp to be set in the future. This is done so as 949ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette to test that when `days_old` is 0, the job is always treated 950ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette as eligible for offload, regardless of the timestamp's value. 951ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 952ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette Testing covers the following assertions: 953ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette A. Each time `enqueue_offload()` is called, a message that 954ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette includes the job's directory name will be logged using 955ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette `logging.debug()`, regardless of whether the job was 956ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette enqueued. Nothing else is allowed to be logged. 957ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette B. If the job is not eligible to be offloaded, 95822dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette `get_failure_time()` and `get_failure_count()` are 0. 959ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette C. If the job is not eligible for offload, nothing is 960ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette enqueued in `queue`. 96122dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette D. When the job is offloaded, `get_failure_count()` increments 962ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette each time. 963ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette E. When the job is offloaded, the appropriate parameters are 964ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette enqueued exactly once. 96522dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette F. The first time a job is offloaded, `get_failure_time()` is 966ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette set to the current time. 96722dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette G. `get_failure_time()` only changes the first time that the 968ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette job is offloaded. 969ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 970ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette The test cases below are designed to exercise all of the 971ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette meaningful state transitions at least once. 972ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 973ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 974ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 975ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def setUp(self): 976ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette super(JobDirectoryOffloadTests, self).setUp() 9770880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette self._job = self.make_job(self.REGULAR_JOBLIST[0]) 978ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._queue = Queue.Queue() 979ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 98024f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 981ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def _offload_unexpired_job(self, days_old): 982ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Make calls to `enqueue_offload()` for an unexpired job. 983ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 984ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette This method tests assertions B and C that calling 985ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette `enqueue_offload()` has no effect. 986ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 987ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 98822dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self.assertEqual(self._job.get_failure_count(), 0) 98922dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self.assertEqual(self._job.get_failure_time(), 0) 99022dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self._job.enqueue_offload(self._queue, days_old) 99122dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self._job.enqueue_offload(self._queue, days_old) 992ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.assertTrue(self._queue.empty()) 99322dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self.assertEqual(self._job.get_failure_count(), 0) 99422dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self.assertEqual(self._job.get_failure_time(), 0) 99522dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self.assertFalse(self._job.is_reportable()) 996ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 99724f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 998ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def _offload_expired_once(self, days_old, count): 999ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Make one call to `enqueue_offload()` for an expired job. 1000ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1001ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette This method tests assertions D and E regarding side-effects 1002ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette expected when a job is offloaded. 1003ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1004ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 100522dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self._job.enqueue_offload(self._queue, days_old) 100622dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self.assertEqual(self._job.get_failure_count(), count) 1007ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.assertFalse(self._queue.empty()) 1008ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette v = self._queue.get_nowait() 1009ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.assertTrue(self._queue.empty()) 10102c72dddb1d05ed43b23ebe847601d7f160a9753aJ. Richard Barnette self.assertEqual(v, self._job.queue_args) 1011ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 101224f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 1013ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def _offload_expired_job(self, days_old): 1014ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Make calls to `enqueue_offload()` for a just-expired job. 1015ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1016ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette This method directly tests assertions F and G regarding 101722dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette side-effects on `get_failure_time()`. 1018ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1019ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 1020ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette t0 = time.time() 1021ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._offload_expired_once(days_old, 1) 102222dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self.assertFalse(self._job.is_reportable()) 102322dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette t1 = self._job.get_failure_time() 1024ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.assertLessEqual(t1, time.time()) 1025ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.assertGreaterEqual(t1, t0) 1026ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._offload_expired_once(days_old, 2) 102722dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self.assertTrue(self._job.is_reportable()) 102822dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self.assertEqual(self._job.get_failure_time(), t1) 1029ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._offload_expired_once(days_old, 3) 103022dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self.assertTrue(self._job.is_reportable()) 103122dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self.assertEqual(self._job.get_failure_time(), t1) 1032ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 103324f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 1034ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def test_case_1_no_expiration(self): 1035ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Test a series of `enqueue_offload()` calls with `days_old` of 0. 1036ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1037ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette This tests that offload works as expected if calls are 1038ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette made both before and after the job becomes expired. 1039ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1040ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 1041ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._offload_unexpired_job(0) 1042ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._job.set_finished(0) 1043ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._offload_expired_job(0) 1044ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 104524f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 1046ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def test_case_2_no_expiration(self): 1047ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Test a series of `enqueue_offload()` calls with `days_old` of 0. 1048ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1049ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette This tests that offload works as expected if calls are made 1050ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette only after the job becomes expired. 1051ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1052ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 1053ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._job.set_finished(0) 1054ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._offload_expired_job(0) 1055ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 105624f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 1057ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def test_case_1_with_expiration(self): 1058ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Test a series of `enqueue_offload()` calls with `days_old` non-zero. 1059ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1060ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette This tests that offload works as expected if calls are made 1061ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette before the job finishes, before the job expires, and after 1062ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette the job expires. 1063ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1064ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 1065ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._offload_unexpired_job(_TEST_EXPIRATION_AGE) 1066ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._job.set_finished(_TEST_EXPIRATION_AGE) 1067ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._offload_unexpired_job(_TEST_EXPIRATION_AGE) 1068ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._job.set_expired(_TEST_EXPIRATION_AGE) 1069ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._offload_expired_job(_TEST_EXPIRATION_AGE) 1070ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 107124f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 1072ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def test_case_2_with_expiration(self): 1073ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Test a series of `enqueue_offload()` calls with `days_old` non-zero. 1074ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1075ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette This tests that offload works as expected if calls are made 1076ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette between finishing and expiration, and after the job expires. 1077ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1078ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 1079ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._job.set_finished(_TEST_EXPIRATION_AGE) 1080ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._offload_unexpired_job(_TEST_EXPIRATION_AGE) 1081ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._job.set_expired(_TEST_EXPIRATION_AGE) 1082ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._offload_expired_job(_TEST_EXPIRATION_AGE) 1083ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 108424f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 1085ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def test_case_3_with_expiration(self): 1086ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Test a series of `enqueue_offload()` calls with `days_old` non-zero. 1087ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1088ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette This tests that offload works as expected if calls are made 1089ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette only before finishing and after expiration. 1090ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1091ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 1092ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._offload_unexpired_job(_TEST_EXPIRATION_AGE) 1093ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._job.set_expired(_TEST_EXPIRATION_AGE) 1094ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._offload_expired_job(_TEST_EXPIRATION_AGE) 1095ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 109624f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 1097ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def test_case_4_with_expiration(self): 1098ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Test a series of `enqueue_offload()` calls with `days_old` non-zero. 1099ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1100ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette This tests that offload works as expected if calls are made 1101ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette only after expiration. 1102ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1103ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 1104ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._job.set_expired(_TEST_EXPIRATION_AGE) 1105ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._offload_expired_job(_TEST_EXPIRATION_AGE) 1106ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1107ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1108ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnetteclass GetJobDirectoriesTests(_TempResultsDirTestBase): 1109ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Tests for `_JobDirectory.get_job_directories()`.""" 1110ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1111ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def setUp(self): 1112ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette super(GetJobDirectoriesTests, self).setUp() 11130880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette self.make_job_hierarchy() 11140880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette os.mkdir('not-a-job') 11150880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette open('not-a-dir', 'w').close() 1116ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 111724f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 1118ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def _run_get_directories(self, cls, expected_list): 1119ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Test `get_job_directories()` for the given class. 1120ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1121ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette Calls the method, and asserts that the returned list of 1122ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette directories matches the expected return value. 1123ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1124ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette @param expected_list Expected return value from the call. 1125ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 1126ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette dirlist = cls.get_job_directories() 1127ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.assertEqual(set(dirlist), set(expected_list)) 1128ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 112924f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 1130ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def test_get_regular_jobs(self): 1131ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Test `RegularJobDirectory.get_job_directories()`.""" 1132ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._run_get_directories(job_directories.RegularJobDirectory, 11330880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette self.REGULAR_JOBLIST) 1134ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 113524f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 1136ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def test_get_special_jobs(self): 1137ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Test `SpecialJobDirectory.get_job_directories()`.""" 1138ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._run_get_directories(job_directories.SpecialJobDirectory, 11390880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette self.SPECIAL_JOBLIST) 1140ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1141ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1142ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnetteclass AddJobsTests(_TempResultsDirTestBase): 1143ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Tests for `Offloader._add_new_jobs()`.""" 1144ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 11450880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette MOREJOBS = ['115-fubar', '116-fubar', '117-fubar', '118-snafu'] 1146ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1147ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def setUp(self): 1148ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette super(AddJobsTests, self).setUp() 114922dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self._initial_job_names = ( 115022dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette set(self.REGULAR_JOBLIST) | set(self.SPECIAL_JOBLIST)) 11510880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette self.make_job_hierarchy() 11520880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette self._offloader = gs_offloader.Offloader(_get_options(['-a'])) 115322dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self.mox.StubOutWithMock(logging, 'debug') 1154ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 115524f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 115622dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette def _run_add_new_jobs(self, expected_key_set): 1157ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Basic test assertions for `_add_new_jobs()`. 1158ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1159ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette Asserts the following: 1160ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette * The keys in the offloader's `_open_jobs` dictionary 1161ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette matches the expected set of keys. 1162ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette * For every job in `_open_jobs`, the job has the expected 1163ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette directory name. 1164ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1165ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 116622dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette count = len(expected_key_set) - len(self._offloader._open_jobs) 116722dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette logging.debug(mox.IgnoreArg(), count) 116822dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self.mox.ReplayAll() 116922dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self._offloader._add_new_jobs() 1170ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.assertEqual(expected_key_set, 1171ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette set(self._offloader._open_jobs.keys())) 1172ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette for jobkey, job in self._offloader._open_jobs.items(): 1173ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.assertEqual(jobkey, job._dirname) 117422dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self.mox.VerifyAll() 117522dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self.mox.ResetAll() 1176ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 117724f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 1178ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def test_add_jobs_empty(self): 1179ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Test adding jobs to an empty dictionary. 1180ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1181ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette Calls the offloader's `_add_new_jobs()`, then perform 1182ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette the assertions of `self._check_open_jobs()`. 1183ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1184ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 118522dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self._run_add_new_jobs(self._initial_job_names) 1186ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 118724f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 1188ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def test_add_jobs_non_empty(self): 1189ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Test adding jobs to a non-empty dictionary. 1190ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1191ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette Calls the offloader's `_add_new_jobs()` twice; once from 1192ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette initial conditions, and then again after adding more 1193ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette directories. After the second call, perform the assertions 1194ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette of `self._check_open_jobs()`. Additionally, assert that 1195ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette keys added by the first call still map to their original 1196ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette job object after the second call. 1197ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1198ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 119922dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self._run_add_new_jobs(self._initial_job_names) 1200ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette jobs_copy = self._offloader._open_jobs.copy() 12010880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette for d in self.MOREJOBS: 12020880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette os.mkdir(d) 120322dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self._run_add_new_jobs(self._initial_job_names | 120422dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette set(self.MOREJOBS)) 1205ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette for key in jobs_copy.keys(): 1206ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.assertIs(jobs_copy[key], 1207ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._offloader._open_jobs[key]) 1208ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1209ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1210ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnetteclass JobStateTests(_TempResultsDirTestBase): 1211ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Tests for job state predicates. 1212ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1213ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette This tests for the expected results from the 1214ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette `is_offloaded()` and `is_reportable()` predicate 1215ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette methods. 1216ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1217ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 1218ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1219ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def test_unfinished_job(self): 1220ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Test that an unfinished job reports the correct state. 1221ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1222ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette A job is "unfinished" if it isn't marked complete in the 1223ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette database. A job in this state is neither "complete" nor 1224ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette "reportable". 1225ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1226ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 12270880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette job = self.make_job(self.REGULAR_JOBLIST[0]) 1228ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.assertFalse(job.is_offloaded()) 1229ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.assertFalse(job.is_reportable()) 1230ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 123124f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 1232ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def test_incomplete_job(self): 1233ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Test that an incomplete job reports the correct state. 1234ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1235ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette A job is "incomplete" if exactly one attempt has been made 1236ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette to offload the job, but its results directory still exists. 1237ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette A job in this state is neither "complete" nor "reportable". 1238ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1239ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 12400880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette job = self.make_job(self.REGULAR_JOBLIST[0]) 1241ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette job.set_incomplete() 1242ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.assertFalse(job.is_offloaded()) 1243ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.assertFalse(job.is_reportable()) 1244ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 124524f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 1246ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def test_reportable_job(self): 1247ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Test that a reportable job reports the correct state. 1248ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1249ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette A job is "reportable" if more than one attempt has been made 1250ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette to offload the job, and its results directory still exists. 1251ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette A job in this state is "reportable", but not "complete". 1252ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1253ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 12540880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette job = self.make_job(self.REGULAR_JOBLIST[0]) 1255ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette job.set_reportable() 1256ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.assertFalse(job.is_offloaded()) 1257ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.assertTrue(job.is_reportable()) 1258ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 125924f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 1260ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def test_completed_job(self): 1261ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Test that a completed job reports the correct state. 1262ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1263ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette A job is "completed" if at least one attempt has been made 1264ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette to offload the job, and its results directory still exists. 1265ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette A job in this state is "complete", and not "reportable". 1266ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1267ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 12680880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette job = self.make_job(self.REGULAR_JOBLIST[0]) 1269ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette job.set_complete() 1270ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.assertTrue(job.is_offloaded()) 1271ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.assertFalse(job.is_reportable()) 1272ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1273ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1274ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnetteclass ReportingTests(_TempResultsDirTestBase): 1275ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Tests for `Offloader._update_offload_results()`.""" 1276ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1277ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def setUp(self): 1278ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette super(ReportingTests, self).setUp() 1279ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._offloader = gs_offloader.Offloader(_get_options([])) 1280ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.mox.StubOutWithMock(email_manager.manager, 1281ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 'send_email') 128222dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self.mox.StubOutWithMock(logging, 'debug') 1283ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 128424f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 1285ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def _add_job(self, jobdir): 1286ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Add a job to the dictionary of unfinished jobs.""" 1287ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette j = self.make_job(jobdir) 1288ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._offloader._open_jobs[j._dirname] = j 1289ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette return j 1290ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 129124f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 129222dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette def _expect_log_message(self, new_open_jobs, with_failures): 129322dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette """Mock expected logging calls. 129422dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette 129522dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette `_update_offload_results()` logs one message with the number 129622dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette of jobs removed from the open job set and the number of jobs 129722dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette still remaining. Additionally, if there are reportable 129822dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette jobs, then it logs the number of jobs that haven't yet 129922dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette offloaded. 130022dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette 130122dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette This sets up the logging calls using `new_open_jobs` to 130222dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette figure the job counts. If `with_failures` is true, then 130322dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette the log message is set up assuming that all jobs in 130422dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette `new_open_jobs` have offload failures. 130522dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette 130622dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette @param new_open_jobs New job set for calculating counts 130722dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette in the messages. 130822dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette @param with_failures Whether the log message with a 130922dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette failure count is expected. 131022dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette 131122dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette """ 131222dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette count = len(self._offloader._open_jobs) - len(new_open_jobs) 131322dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette logging.debug(mox.IgnoreArg(), count, len(new_open_jobs)) 131422dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette if with_failures: 131522dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette logging.debug(mox.IgnoreArg(), len(new_open_jobs)) 131622dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette 131724f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 1318ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def _run_update_no_report(self, new_open_jobs): 1319ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Call `_update_offload_results()` expecting no report. 1320ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1321ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette Initial conditions are set up by the caller. This calls 1322ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette `_update_offload_results()` once, and then checks these 1323ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette assertions: 1324ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette * The offloader's `_next_report_time` field is unchanged. 1325ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette * The offloader's new `_open_jobs` field contains only 1326ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette the entries in `new_open_jobs`. 1327ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette * The email_manager's `send_email` stub wasn't called. 1328ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1329ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette @param new_open_jobs A dictionary representing the expected 1330ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette new value of the offloader's 1331ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette `_open_jobs` field. 1332ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 1333ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.mox.ReplayAll() 1334ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette next_report_time = self._offloader._next_report_time 1335ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._offloader._update_offload_results() 1336ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.assertEqual(next_report_time, 1337ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._offloader._next_report_time) 1338ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.assertEqual(self._offloader._open_jobs, new_open_jobs) 1339ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.mox.VerifyAll() 1340ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.mox.ResetAll() 1341ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 134224f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 1343ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def _run_update_with_report(self, new_open_jobs): 1344ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Call `_update_offload_results()` expecting an e-mail report. 1345ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1346ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette Initial conditions are set up by the caller. This calls 1347ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette `_update_offload_results()` once, and then checks these 1348ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette assertions: 1349ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette * The offloader's `_next_report_time` field is updated 1350ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette to an appropriate new time. 1351ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette * The offloader's new `_open_jobs` field contains only 1352ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette the entries in `new_open_jobs`. 1353ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette * The email_manager's `send_email` stub was called. 1354ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1355ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette @param new_open_jobs A dictionary representing the expected 1356ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette new value of the offloader's 1357ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette `_open_jobs` field. 1358ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 135922dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette logging.debug(mox.IgnoreArg()) 1360ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette email_manager.manager.send_email( 1361ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg()) 1362ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.mox.ReplayAll() 1363ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette t0 = time.time() + gs_offloader.REPORT_INTERVAL_SECS 1364ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._offloader._update_offload_results() 1365ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette t1 = time.time() + gs_offloader.REPORT_INTERVAL_SECS 1366ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette next_report_time = self._offloader._next_report_time 1367ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.assertGreaterEqual(next_report_time, t0) 1368ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.assertLessEqual(next_report_time, t1) 1369ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.assertEqual(self._offloader._open_jobs, new_open_jobs) 1370ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.mox.VerifyAll() 1371ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self.mox.ResetAll() 1372ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 137324f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 1374ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def test_no_jobs(self): 1375ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Test `_update_offload_results()` with no open jobs. 1376ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1377ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette Initial conditions are an empty `_open_jobs` list and 1378ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette `_next_report_time` in the past. Expected result is no 1379ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette e-mail report, and an empty `_open_jobs` list. 1380ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1381ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 138222dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self._expect_log_message({}, False) 1383ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._run_update_no_report({}) 1384ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 138524f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 1386ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def test_all_completed(self): 1387ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Test `_update_offload_results()` with only complete jobs. 1388ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1389ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette Initial conditions are an `_open_jobs` list consisting of 1390ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette only completed jobs and `_next_report_time` in the past. 1391ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette Expected result is no e-mail report, and an empty 1392ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette `_open_jobs` list. 1393ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1394ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 13950880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette for d in self.REGULAR_JOBLIST: 1396ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._add_job(d).set_complete() 139722dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self._expect_log_message({}, False) 1398ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._run_update_no_report({}) 1399ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 140024f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 1401ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def test_none_finished(self): 1402ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Test `_update_offload_results()` with only unfinished jobs. 1403ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1404ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette Initial conditions are an `_open_jobs` list consisting of 1405ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette only unfinished jobs and `_next_report_time` in the past. 1406ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette Expected result is no e-mail report, and no change to the 1407ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette `_open_jobs` list. 1408ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1409ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 14100880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette for d in self.REGULAR_JOBLIST: 1411ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._add_job(d) 141222dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette new_jobs = self._offloader._open_jobs.copy() 141322dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self._expect_log_message(new_jobs, False) 141422dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self._run_update_no_report(new_jobs) 1415ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 141624f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 1417ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def test_none_reportable(self): 1418ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Test `_update_offload_results()` with only incomplete jobs. 1419ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1420ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette Initial conditions are an `_open_jobs` list consisting of 1421ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette only incomplete jobs and `_next_report_time` in the past. 1422ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette Expected result is no e-mail report, and no change to the 1423ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette `_open_jobs` list. 1424ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1425ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 14260880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette for d in self.REGULAR_JOBLIST: 1427ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._add_job(d).set_incomplete() 142822dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette new_jobs = self._offloader._open_jobs.copy() 142922dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self._expect_log_message(new_jobs, False) 143022dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self._run_update_no_report(new_jobs) 1431ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 143224f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 1433ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def test_report_not_ready(self): 1434ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Test `_update_offload_results()` e-mail throttling. 1435ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1436ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette Initial conditions are an `_open_jobs` list consisting of 1437ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette only reportable jobs but with `_next_report_time` in 1438ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette the future. Expected result is no e-mail report, and no 1439ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette change to the `_open_jobs` list. 1440ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1441ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 1442ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette # N.B. This test may fail if its run time exceeds more than 1443ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette # about _MARGIN_SECS seconds. 14440880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette for d in self.REGULAR_JOBLIST: 1445ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._add_job(d).set_reportable() 1446ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._offloader._next_report_time += _MARGIN_SECS 144722dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette new_jobs = self._offloader._open_jobs.copy() 144822dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self._expect_log_message(new_jobs, True) 144922dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self._run_update_no_report(new_jobs) 1450ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 145124f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 1452ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette def test_reportable(self): 1453ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """Test `_update_offload_results()` with reportable jobs. 1454ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1455ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette Initial conditions are an `_open_jobs` list consisting of 1456ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette only reportable jobs and with `_next_report_time` in 1457ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette the past. Expected result is an e-mail report, and no 1458ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette change to the `_open_jobs` list. 1459ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1460ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette """ 14610880032b48fbcf11d50f33526f6817a78c2f17bfJ. Richard Barnette for d in self.REGULAR_JOBLIST: 1462ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette self._add_job(d).set_reportable() 146322dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette new_jobs = self._offloader._open_jobs.copy() 146422dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self._expect_log_message(new_jobs, True) 146522dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self._run_update_with_report(new_jobs) 146622dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette 146724f22c2fda0fac684286b168f642c7326a20fac7Jakob Juelich 146822dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette def test_reportable_mixed(self): 146922dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette """Test `_update_offload_results()` with a mixture of jobs. 147022dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette 147122dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette Initial conditions are an `_open_jobs` list consisting of 147222dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette one reportable jobs and the remainder of the jobs 147322dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette incomplete. The value of `_next_report_time` is in the 147422dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette past. Expected result is an e-mail report that includes 147522dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette both the reportable and the incomplete jobs, and no change 147622dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette to the `_open_jobs` list. 147722dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette 147822dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette """ 147922dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self._add_job(self.REGULAR_JOBLIST[0]).set_reportable() 148022dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette for d in self.REGULAR_JOBLIST[1:]: 148122dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self._add_job(d).set_incomplete() 148222dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette new_jobs = self._offloader._open_jobs.copy() 148322dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self._expect_log_message(new_jobs, True) 148422dd7487fba60c457747b478ab0822df3a6e8c64J. Richard Barnette self._run_update_with_report(new_jobs) 1485ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1486ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette 1487ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnetteif __name__ == '__main__': 1488ea785366f46ec4ed7a75d382e152a77aa51069d7J. Richard Barnette unittest.main() 1489