def test_conjunction_true(self): context = ExecutionContext() aA = jp.PathEqPredicate('a', 'A') bB = jp.PathEqPredicate('b', 'B') conjunction = jc.AND([aA, bB]) expect = jc.CompositePredicateResult( valid=True, pred=conjunction, results=[aA(context, _LETTER_DICT), bB(context, _LETTER_DICT)]) result = conjunction(context, _LETTER_DICT) self.assertTrue(result) self.assertEqual(expect, result)
def test_conjunction_false_aborts_early(self): context = ExecutionContext() aA = jp.PathEqPredicate('a', 'A') b2 = jp.PathEqPredicate('b', 2) bB = jp.PathEqPredicate('b', 'B') conjunction = jc.AND([aA, b2, bB]) expect = jc.CompositePredicateResult( valid=False, pred=conjunction, results=[aA(context, _LETTER_DICT), b2(context, _LETTER_DICT)]) result = conjunction(context, _LETTER_DICT) self.assertFalse(result) self.assertEqual(expect, result)
def test_object_filter_cases(self): context = ExecutionContext() aA = jp.PathPredicate('a', jp.STR_EQ('A')) self._try_map(context, aA, _LETTER_DICT, True) self._try_map(context, aA, _COMPOSITE_DICT, False) self._try_map(context, aA, _NUMBER_DICT, False) self._try_map(context, aA, _MULTI_ARRAY, True) self._try_map(context, aA, [_COMPOSITE_DICT, _COMPOSITE_DICT], False) self._try_map(context, aA, _MIXED_DICT, True) AandB = jp.AND([PathEqPredicate('a', 'A'), PathEqPredicate('b', 'B')]) self._try_map(context, AandB, _LETTER_DICT, True) self._try_map(context, AandB, _COMPOSITE_DICT, False) self._try_map(context, AandB, _NUMBER_DICT, False) self._try_map(context, AandB, _MULTI_ARRAY, True) self._try_map(context, AandB, _MIXED_DICT, False)
def test_condition_else_success(self): aA = jp.PathEqPredicate('a', 'A') bB = jp.PathEqPredicate('b', 'B') cC = jp.PathEqPredicate('c', 'C') aA_and_bB = jc.AND([aA, bB]) ifAthenBelseC = jc.IF(aA, bB, cC) # True if all conditions are true. # True if "if" satisfied and "then" matches. # True if only else condition is true. test_cases = [ _LETTER_DICT, { 'a': 'A', 'b': 'B', 'c': 'X' }, { 'a': 'X', 'b': 'B', 'c': 'C' }, { 'a': 'X', 'b': 'X', 'c': 'C' } ] for i in range(3): test = test_cases[i] tried = [aA(test)] if i < 2: # First two have true IF to just execute THEN tried.append(bB(test)) else: # Remainder have false IF to just execute ELSE tried.append(cC(test)) expect = jc.CompositePredicateResult(valid=True, pred=ifAthenBelseC, results=tried) result = ifAthenBelseC(test) self.assertTrue(result) self.assertEqual(expect, result)
def test_object_observer_map(self): # Test no filter. context = ExecutionContext() observer = jc.ObjectObserver() observation = jc.Observation() expected = jc.Observation() expected.add_object(_NUMBER_DICT) observer.filter_all_objects_to_observation(context, [_NUMBER_DICT], observation) self.assertEqual([_NUMBER_DICT], observation.objects) self.assertEqual(expected, observation) pred_list = [ jp.PathEqPredicate('a', 'A'), jp.PathEqPredicate('b', 'B') ] conjunction = jp.AND(pred_list) observer = jc.ObjectObserver(conjunction) observation = jc.Observation() expected = jc.Observation() expected.add_object(_LETTER_DICT) observer.filter_all_objects_to_observation(context, [_LETTER_DICT], observation) self.assertEqual([_LETTER_DICT], observation.objects) self.assertEqual(expected, observation) observation = jc.Observation() expected = jc.Observation() expected.add_object(_LETTER_DICT) expected.add_object(_LETTER_DICT) observer.filter_all_objects_to_observation( context, [_LETTER_DICT, _NUMBER_DICT, _LETTER_DICT], observation) self.assertEqual([_LETTER_DICT, _LETTER_DICT], observation.objects) observation = jc.Observation() expected = jc.Observation() observer.filter_all_objects_to_observation(context, [_NUMBER_DICT], observation) self.assertEqual([], observation.objects) # Note that filtering doesnt observe errors. self.assertEqual(expected, observation)
def test_path_conjunction(self): context = ExecutionContext() text = 'x=X, a=A, b=B, z=Z' aA = jp.STR_SUBSTR('a=A') bB = jp.STR_SUBSTR('b=B') conjunction = jp.AND([aA, bB]) pred = PathPredicate('value', conjunction) source = {'value': text, 'wrong': 'a=A', 'another': 'b=B'} conjunction_result = conjunction(context, text) builder = PathPredicateResultBuilder(source, pred) builder.add_result_candidate( PathValue('value', text), conjunction_result.clone_with_source(source=source, base_target_path='value', base_value_path='value')) expect = builder.build(True) pred_result = pred(context, source) self.assertEqual(expect, pred_result)
def _add_contract_clauses(self, contract_builder, upsert): '''Add the proper predicates to the contract builder for a given upsert description. ''' host_rules = upsert['hostRules'] # Host rules will be distinct. backend_services = [upsert['defaultService']] for host_rule in host_rules: path_matcher = host_rule['pathMatcher'] backend_services.append(path_matcher['defaultService']) for path_rule in path_matcher['pathRules']: backend_services.append(path_rule['backendService']) health_checks = [service['healthCheck'] for service in backend_services] hc_clause_builder = (contract_builder .new_clause_builder('Health Checks Created', retryable_for_secs=30) .list_resource('httpHealthChecks')) for hc in health_checks: hc_clause_builder.contains_pred_list( [ jp.PathEqPredicate('name', hc['name']), jp.PathEqPredicate('requestPath', hc['requestPath']), jp.PathEqPredicate('port', hc['port']) ] ) bs_clause_builder = (contract_builder. new_clause_builder('Backend Services Created', retryable_for_secs=30). list_resource('backendServices')) for bs in backend_services: bs_clause_builder.contains_pred_list( [ jp.PathEqPredicate('name', bs['name']), jp.PathEqPredicate('portName', 'http'), jp.PathContainsPredicate('healthChecks[0]', self._get_hc_link(bs['healthCheck']['name'])) ] ) url_map_clause_builder = (contract_builder .new_clause_builder('Url Map Created', retryable_for_secs=30) .list_resource('urlMaps')) for hr in host_rules: pred_list = [] pm = hr['pathMatcher'] pred_list.append(jp.AND([ jp.PathEqPredicate('name', self.__lb_name), jp.PathEqPredicate('defaultService', self._get_bs_link(upsert['defaultService']['name'])), jp.PathContainsPredicate( 'pathMatchers/defaultService', self._get_bs_link(pm['defaultService']['name'])), ])) pred_list.append( jp.AND([jp.PathContainsPredicate('hostRules/hosts', host) for host in hr['hostPatterns']]) ) for pr in pm['pathRules']: pred_list.append( jp.PathContainsPredicate( 'pathMatchers/pathRules/service', self._get_bs_link(pr['backendService']['name'])), ) for path in pr['paths']: pred_list.append( jp.PathContainsPredicate('pathMatchers/pathRules/paths', path), ) url_map_clause_builder.contains_pred_list(pred_list) port_string = '443-443' if upsert['certificate'] == '': port_string = '%s-%s' % (upsert['portRange'], upsert['portRange']) (contract_builder.new_clause_builder('Forwarding Rule Created', retryable_for_secs=30) .list_resource('globalForwardingRules') .contains_pred_list( [ jp.PathEqPredicate('name', self.__lb_name), jp.PathEqPredicate('portRange', port_string) ])) proxy_clause_builder = contract_builder.new_clause_builder( 'Target Proxy Created', retryable_for_secs=30) self._add_proxy_clause(upsert['certificate'], proxy_clause_builder)