def __init__(self, project=PROJECT): """ Initialize the configuration """ THIS_DIR = os.path.dirname(os.path.abspath(__file__)) oscrc = os.path.join(THIS_DIR, 'test.oscrc') self.apiurl = APIURL logging.basicConfig() # clear cache from other tests - otherwise the VCR is replayed depending # on test order, which can be harmful memoize_session_reset() osc.core.conf.get_config(override_conffile=oscrc, override_no_keyring=True, override_no_gnome_keyring=True) if os.environ.get('OSC_DEBUG'): osc.core.conf.config['debug'] = 1 self.project = project self.projects = {} self.requests = [] self.groups = [] self.users = [] CacheManager.test = True # disable caching, the TTLs break any reproduciblity Cache.CACHE_DIR = None Cache.PATTERNS = {} Cache.init() self.setup_remote_config() self.load_config() self.api = StagingAPI(APIURL, project)
def test_get_memoize_reset(self): """Ensure memoize_session_reset() properly forces re-fetch of config.""" self.assertEqual('remote-indeed', Config.get(obs.APIURL, obs.PROJECT)['remote-only']) attribute_value_save(obs.APIURL, obs.PROJECT, 'Config', 'remote-only = new value\n') memoize_session_reset() self.assertEqual('new value', Config.get(obs.APIURL, obs.PROJECT)['remote-only'])
def test_get_memoize_reset(self): """Ensure memoize_session_reset() properly forces re-fetch of config.""" wf = self.setup_vcr() self.assertEqual('remote-indeed', Config.get(wf.apiurl, wf.project)['remote-only']) attribute_value_save(wf.apiurl, wf.project, 'Config', 'remote-only = new value\n') memoize_session_reset() self.assertEqual('new value', Config.get(wf.apiurl, wf.project)['remote-only'])
def __enter__(self): if devel_project_simulate.lock: raise devel_project_simulate_exception( 'Devel project simulation lock already aquired for {}:{}/{}'. format(self.apiurl, self.target_project, self.target_package)) devel_project_simulate.lock = self # Ensure devel lookups are forgotten. memoize_session_reset()
def test_get_memoize_reset(self): """Ensure memoize_session_reset() properly forces re-fetch of config.""" self.assertEqual('remote-indeed', Config.get(APIURL, PROJECT)['remote-only']) attribute_value_save(APIURL, PROJECT, 'Config', 'remote-only = new value\n') memoize_session_reset() self.assertEqual('new value', Config.get(APIURL, PROJECT)['remote-only'])
def test_config(self): attribute_value_save(self.wf.apiurl, self.target_project, 'OriginConfig', 'origins: []') config = config_load(self.wf.apiurl, self.wf.project) self.assertEqual(config['unknown_origin_wait'], False) self.assertEqual(config['review-user'], NAME) memoize_session_reset() self.origin_config_write([{'fakeProject': {}}, {'*~': {}}]) config = config_load(self.wf.apiurl, self.wf.project) self.assertEqual(config_origin_list(config), ['fakeProject', 'fakeProject~']) for _, values in config_origin_generator(config['origins']): self.assertEqual(values['automatic_updates'], True)
def _assertUpdate(self, package, desired): memoize_session_reset() self.osc_user(self.bot_user) request_future = origin_update(self.wf.apiurl, self.wf.project, package) if desired: self.assertNotEqual(request_future, False) request_id = request_future.print_and_create() else: self.assertEqual(request_future, False) request_id = None self.osc_user_pop() return request_id
def runner(self, workfunc, interval): """ runs the specified callback every <interval> minutes or once if interval is None or 0 """ class ExTimeout(Exception): """raised on timeout""" if interval: def alarm_called(nr, frame): raise ExTimeout() signal.signal(signal.SIGALRM, alarm_called) while True: try: workfunc() except Exception as e: self.logger.exception(e) if interval: if os.isatty(0): self.logger.info( "sleeping %d minutes. Press enter to check now ..." % interval) signal.alarm(interval * 60) try: raw_input() except ExTimeout: pass signal.alarm(0) self.logger.info("recheck at %s" % datetime.datetime.now().isoformat()) else: self.logger.info("sleeping %d minutes." % interval) time.sleep(interval * 60) # Reset all memoize session caches which are designed for single # tool run and not extended usage. memoize_session_reset() # Reload checker to flush instance variables and thus any config # or caches they may contain. self.postoptparse() continue break
def __init__(self, project=PROJECT): """Initializes the configuration Note this constructor calls :func:`create_target`, which implies several projects and users are created right away. :param project: default target project :type project: str """ THIS_DIR = os.path.dirname(os.path.abspath(__file__)) oscrc = os.path.join(THIS_DIR, 'test.oscrc') # set to None so we return the destructor early in case of exceptions self.api = None self.apiurl = APIURL self.project = project self.projects = {} self.requests = [] self.groups = [] self.users = [] self.attr_types = {} logging.basicConfig() # clear cache from other tests - otherwise the VCR is replayed depending # on test order, which can be harmful memoize_session_reset() osc.core.conf.get_config(override_conffile=oscrc, override_no_keyring=True, override_no_gnome_keyring=True) os.environ['OSC_CONFIG'] = oscrc if os.environ.get('OSC_DEBUG'): osc.core.conf.config['debug'] = 1 CacheManager.test = True # disable caching, the TTLs break any reproduciblity Cache.CACHE_DIR = None Cache.PATTERNS = {} Cache.init() # Note this implicitly calls create_target() self.setup_remote_config() self.load_config() self.api = StagingAPI(APIURL, project)
def runner(self, workfunc, interval): """ runs the specified callback every <interval> minutes or once if interval is None or 0 """ class ExTimeout(Exception): """raised on timeout""" if interval: def alarm_called(nr, frame): raise ExTimeout() signal.signal(signal.SIGALRM, alarm_called) while True: try: workfunc() except Exception as e: self.logger.exception(e) if interval: if os.isatty(0): self.logger.info("sleeping %d minutes. Press enter to check now ..."%interval) signal.alarm(interval*60) try: input() except ExTimeout: pass signal.alarm(0) self.logger.info("recheck at %s"%datetime.datetime.now().isoformat()) else: self.logger.info("sleeping %d minutes." % interval) time.sleep(interval * 60) # Reset all memoize session caches which are designed for single # tool run and not extended usage. memoize_session_reset() # Reload checker to flush instance variables and thus any config # or caches they may contain. self.postoptparse() continue break
def test_new_package_submission(self): self.remote_config_set_age_minimum() upstream1_project = self.randomString('upstream1') upstream2_project = self.randomString('upstream2') upstream3_project = self.randomString('upstream3') package1 = self.randomString('package1') package2 = self.randomString('package2') package3 = self.randomString('package3') target_package1 = self.wf.create_package(self.target_project, package1) upstream1_package1 = self.wf.create_package(upstream1_project, package1) upstream2_package1 = self.wf.create_package(upstream2_project, package1) upstream1_package1.create_commit() copy_package(self.wf.apiurl, upstream1_project, package1, self.wf.apiurl, upstream2_project, package1) upstream3_package2 = self.wf.create_package(upstream3_project, package2) upstream3_package2.create_commit() upstream1_package3 = self.wf.create_package(upstream1_project, package3) upstream1_package3.create_commit() attribute_value_save(self.wf.apiurl, upstream1_project, 'ApprovedRequestSource', '', 'OBS') attribute_value_save(self.wf.apiurl, upstream2_project, 'ApprovedRequestSource', '', 'OBS') attribute_value_save(self.wf.apiurl, upstream3_project, 'ApprovedRequestSource', '', 'OBS') self.origin_config_write([ {upstream1_project: { 'automatic_updates_initial': True }}, {upstream2_project: { 'automatic_updates_initial': True }}, {upstream3_project: {}}, ]) self.osc_user(self.bot_user) memoize_session_reset() request_future = origin_update(self.wf.apiurl, self.wf.project, package1) self.assertNotEqual(request_future, False) if request_future: request_id_package1 = request_future.print_and_create() # Ensure a second request is not triggered. memoize_session_reset() request_future = origin_update(self.wf.apiurl, self.wf.project, package1) self.assertEqual(request_future, False) # No new package submission from upstream3 since not automatic_updates_initial. memoize_session_reset() request_future = origin_update(self.wf.apiurl, self.wf.project, package2) self.assertEqual(request_future, False) self.osc_user_pop() upstream2_package2 = self.wf.create_package(upstream2_project, package2) upstream2_package2.create_commit() self.osc_user(self.bot_user) memoize_session_reset() request_future = origin_update(self.wf.apiurl, self.wf.project, package2) self.assertNotEqual(request_future, False) if request_future: request_id_package2 = request_future.print_and_create() self.osc_user_pop() request_state_change(self.wf.apiurl, request_id_package2, 'declined') upstream2_package2.create_commit() self.osc_user(self.bot_user) # No new package submission from upstream2 for new revision since # declined initial package submission. memoize_session_reset() request_future = origin_update(self.wf.apiurl, self.wf.project, package2) self.assertEqual(request_future, False) self.osc_user_pop() # Ensure blacklist prevents initial package submission. self.wf.create_attribute_type('OSRT', 'OriginUpdateInitialBlacklist', 1) attribute_value_save(self.wf.apiurl, self.target_project, 'OriginUpdateInitialBlacklist', package3) self.assertNoUpdate(package3) attribute_value_delete(self.wf.apiurl, self.target_project, 'OriginUpdateInitialBlacklist') self.assertUpdate(package3)
def test_split_product(self): self.remote_config_set_age_minimum() upstream1_project = self.randomString('upstream1') upstream2_project = self.randomString('upstream2') devel_project = self.randomString('devel') package = self.randomString('package') target_package = self.wf.create_package(self.target_project, package) upstream1_package = self.wf.create_package(upstream1_project, package) upstream2_package = self.wf.create_package(upstream2_project, package) devel_package = self.wf.create_package(devel_project, package) upstream1_package.create_commit() upstream2_package.create_commit() devel_package.create_commit() attribute_value_save(self.wf.apiurl, upstream1_project, 'ApprovedRequestSource', '', 'OBS') attribute_value_save(self.wf.apiurl, upstream2_project, 'ApprovedRequestSource', '', 'OBS') attribute_value_save(self.wf.apiurl, devel_project, 'ApprovedRequestSource', '', 'OBS') self.origin_config_write([ {'<devel>': {}}, {upstream1_project: {}}, {upstream2_project: { 'pending_submission_consider': True }}, {'*~': {}}, ], {'unknown_origin_wait': True}) # Simulate branch project from upstream1. copy_package(self.wf.apiurl, upstream1_project, package, self.wf.apiurl, self.target_project, package) memoize_session_reset() origin_info = origin_find(self.wf.apiurl, self.target_project, package) self.assertEqual(str(origin_info), upstream1_project) # Create request against upstream2 which considers pending submissions. request_upstream2 = self.wf.submit_package(devel_package, upstream2_project) request_target = self.wf.submit_package(devel_package, self.target_project) self.assertReviewBot(request_target.reqid, self.bot_user, 'new', 'new') comment = [ '<!-- OriginManager state=seen result=None -->', f'Waiting on acceptance of request#{request_upstream2.reqid}.', ] self.assertComment(request_target.reqid, comment) request_upstream2.change_state('accepted') self.assertReviewBot(request_target.reqid, self.bot_user, 'new', 'accepted') self.assertAnnotation(request_target.reqid, { 'origin': upstream2_project, 'origin_old': upstream1_project, }) # Accept fallback review for changing to lower priority origin. self.accept_fallback_review(request_target.reqid) request_target.change_state('accepted') memoize_session_reset() origin_info = origin_find(self.wf.apiurl, self.target_project, package) self.assertEqual(str(origin_info), upstream2_project) # Simulate upstream1 incorporating upstream2 version of package. copy_package(self.wf.apiurl, upstream2_project, package, self.wf.apiurl, upstream1_project, package) memoize_session_reset() origin_info = origin_find(self.wf.apiurl, self.target_project, package) self.assertEqual(str(origin_info), upstream1_project)
def devel_workflow(self, only_devel): self.remote_config_set_age_minimum() devel_project = self.randomString('devel') package = self.randomString('package') request = self.wf.create_submit_request(devel_project, package) attribute_value_save(self.wf.apiurl, devel_project, 'ApprovedRequestSource', '', 'OBS') if not only_devel: self.assertReviewBot(request.reqid, self.bot_user, 'new', 'new') comment = [ '<!-- OriginManager state=seen result=None -->', 'Source not found in allowed origins:', f'- {self.product_project}', f'Decision may be overridden via `@{self.bot_user} override`.', ] self.assertComment(request.reqid, comment) CommentAPI(self.wf.api.apiurl).add_comment( request_id=request.reqid, comment=f'@{self.bot_user} change_devel') comment = 'change_devel command by {}'.format('Admin') else: comment = 'only devel origin allowed' self.assertReviewBot(request.reqid, self.bot_user, 'new', 'accepted') self.assertAnnotation(request.reqid, { 'comment': comment, 'origin': devel_project, }) request.change_state('accepted') memoize_session_reset() self.osc_user(self.bot_user) request_future = origin_update(self.wf.apiurl, self.wf.project, package) self.assertNotEqual(request_future, False) if request_future: request_id_change_devel = request_future.print_and_create() # Ensure a second request is not triggered. request_future = origin_update(self.wf.apiurl, self.wf.project, package) self.assertEqual(request_future, False) self.osc_user_pop() memoize_session_reset() origin_info = origin_find(self.wf.apiurl, self.wf.project, package) self.assertEqual(origin_info, None) self.assertReviewBot(request_id_change_devel, self.bot_user, 'new', 'accepted') self.assertAnnotation(request_id_change_devel, { 'origin': devel_project, }) # Origin should change before request is accepted since it is properly # annotated and without fallback review. memoize_session_reset() origin_info = origin_find(self.wf.apiurl, self.wf.project, package) self.assertEqual(str(origin_info), devel_project) self.wf.projects[devel_project].packages[0].create_commit() self.osc_user(self.bot_user) request_future = origin_update(self.wf.apiurl, self.wf.project, package) self.assertNotEqual(request_future, False) if request_future: request_id_update = request_future.print_and_create() request_future = origin_update(self.wf.apiurl, self.wf.project, package) self.assertEqual(request_future, False) self.osc_user_pop() self.assertReviewBot(request_id_update, self.bot_user, 'new', 'accepted') self.assertAnnotation(request_id_update, { 'origin': devel_project, }) memoize_session_reset() devel_project_actual, _ = devel_project_get(self.wf.apiurl, self.wf.project, package) self.assertEqual(devel_project_actual, None) request = get_request(self.wf.apiurl, request_id_change_devel) request_state_change(self.wf.apiurl, request_id_change_devel, 'accepted') memoize_session_reset() devel_project_actual, devel_package_actual = devel_project_get( self.wf.apiurl, self.wf.project, package) self.assertEqual(devel_project_actual, devel_project) self.assertEqual(devel_package_actual, package) request = get_request(self.wf.apiurl, request_id_update) request_state_change(self.wf.apiurl, request_id_update, 'accepted') devel_project_new = self.randomString('develnew') self.wf.create_package(devel_project_new, package) attribute_value_save(self.wf.apiurl, devel_project_new, 'ApprovedRequestSource', '', 'OBS') copy_package(self.wf.apiurl, devel_project, package, self.wf.apiurl, devel_project_new, package) request_future = request_create_change_devel( self.wf.apiurl, devel_project_new, package, self.wf.project) self.assertNotEqual(request_future, False) if request_future: request_id_change_devel_new = request_future.print_and_create() self.assertReviewBot(request_id_change_devel_new, self.bot_user, 'new', 'accepted') self.assertAnnotation(request_id_change_devel_new, { 'origin': devel_project_new, 'origin_old': devel_project, }) self.accept_fallback_review(request_id_change_devel_new) request_state_change(self.wf.apiurl, request_id_change_devel_new, 'accepted') memoize_session_reset() origin_info = origin_find(self.wf.apiurl, self.wf.project, package) self.assertEqual(str(origin_info), devel_project_new)
def __exit__(self, exc_type, exc_val, exc_tb): devel_project_simulate.lock = None # Ensure devel lookups are forgotten. memoize_session_reset()