def testNormalize(self): """ Tests the normalize() method """ # Empty filter for operator in (pelix.ldapfilter.AND, pelix.ldapfilter.OR, pelix.ldapfilter.NOT): self.assertEqual(pelix.ldapfilter.LDAPFilter(operator).normalize(), None, "Empty filter normalized form must be None") # Standard filter ldap_filter = get_ldap_filter("(|(test=True)(test2=False))") self.assertIs(ldap_filter.normalize(), ldap_filter, "Normalized filter must return itself") criteria = get_ldap_filter("(test=True)") # 'Not' Filter with 1 child ldap_filter = pelix.ldapfilter.LDAPFilter(pelix.ldapfilter.NOT) ldap_filter.append(criteria) self.assertIs(ldap_filter.normalize(), ldap_filter, "'Not' filter with 1 child must return itself") # 'And', 'Or' filter for operator in (pelix.ldapfilter.AND, pelix.ldapfilter.OR): ldap_filter = pelix.ldapfilter.LDAPFilter(operator) ldap_filter.append(criteria) self.assertEqual( ldap_filter.normalize(), criteria, "'And' or 'Or' with 1 child must return the child")
def testEmptyCriteria(self): """ Empty filter test """ self.assertIsNone(get_ldap_filter(None), "None filter must return None") self.assertIsNone(get_ldap_filter(""), "Empty filter must return None") self.assertIsNone(get_ldap_filter(" "), "Trimmed filter must return None")
def testEq(self): """ Tests the LDAPFilter objects equality """ # Some filter str_filter = "(&(test=False)(test2=True))" ldap_filter = get_ldap_filter(str_filter) # Test with other values self.assertNotEqual(ldap_filter, None, "Filter is not equal to None") self.assertEqual(ldap_filter, ldap_filter, "Filter is not self-equal") self.assertNotEqual(pelix.ldapfilter.LDAPFilter(pelix.ldapfilter.NOT), pelix.ldapfilter.LDAPCriteria( 'test', 123, pelix.ldapfilter._comparator_approximate), "Invalid equality (type)") # Tests order must not provide a different filter str_filter_2 = "(&(test2 = True)(test = False))" ldap_filter_2 = get_ldap_filter(str_filter_2) self.assertEqual(ldap_filter, ldap_filter_2, "Filters are not equal") # Inequality check self.assertNotEqual(ldap_filter, get_ldap_filter("(test2=true)"), "Invalid equality (type)") self.assertNotEqual(get_ldap_filter("(test2=true)"), ldap_filter, "Invalid equality (type, reverse)") self.assertNotEqual( ldap_filter, get_ldap_filter("(&(test=False)(test2=True)(test3=1))"), "Invalid equality (size)") self.assertNotEqual( get_ldap_filter("(&(test=False)(test2=True)(test3=1))"), ldap_filter, "Invalid equality (size, reverse)") self.assertNotEqual(ldap_filter, get_ldap_filter("(&(test1=False)(test2=True))"), "Invalid equality (sub-filter)") self.assertNotEqual(get_ldap_filter("(&(test1=False)(test2=True))"), ldap_filter, "Invalid equality (sub-filter, reverse)") self.assertNotEqual(ldap_filter, get_ldap_filter("(|(test=False)(test2=True))"), "Invalid equality (operator)") self.assertNotEqual( get_ldap_filter("(|(test=False)(test2=True))"), ldap_filter, "Invalid equality (operator, reverse)")
def testOr(self): """ Tests the OR operator """ props = {} ldap_filter = get_ldap_filter("(|(test=True)(test2=False))") # Valid ... props["test"] = True props["test2"] = False self.assertTrue(ldap_filter.matches(props), "Filter '{0}' should match {1}" .format(ldap_filter, props)) props["test"] = False props["test2"] = False self.assertTrue(ldap_filter.matches(props), "Filter '{0}' should match {1}" .format(ldap_filter, props)) props["test"] = True props["test2"] = True self.assertTrue(ldap_filter.matches(props), "Filter '{0}' should match {1}" .format(ldap_filter, props)) # Invalid... props["test"] = False props["test2"] = True self.assertFalse(ldap_filter.matches(props), "Filter '{0}' should not match {1}" .format(ldap_filter, props))
def set_filter(self, props_filter): """ Changes the current filter for the given one :param props_filter: The new requirement filter on service properties :raise TypeError: Unknown filter type """ if props_filter is not None and \ not (is_string(props_filter) or isinstance(props_filter, (ldapfilter.LDAPFilter, ldapfilter.LDAPCriteria))): # Unknown type raise TypeError("Invalid filter type {0}" .format(type(props_filter).__name__)) if props_filter is not None: # Filter given, keep its string form self.__original_filter = str(props_filter) else: # No filter self.__original_filter = None # Parse the filter self.filter = ldapfilter.get_ldap_filter(props_filter) # Prepare the full filter spec_filter = "({0}={1})".format(OBJECTCLASS, self.specification) self.__full_filter = ldapfilter.combine_filters( (spec_filter, self.filter))
def find_service_references(self, clazz=None, ldap_filter=None, only_one=False): """ Finds all services references matching the given filter. :param clazz: Class implemented by the service :param ldap_filter: Service filter :param only_one: Return the first matching service reference only :return: A list of found references, or None :raise BundleException: An error occurred looking for service references """ with self.__svc_lock: if clazz is None and ldap_filter is None: # Return a sorted copy of the keys list # Do not return None, as the whole content was required return sorted(self.__svc_registry.keys()) if hasattr(clazz, "__name__"): # Escape the type name clazz = ldapfilter.escape_LDAP(clazz.__name__) elif is_string(clazz): # Escape the class name clazz = ldapfilter.escape_LDAP(clazz) if clazz is None: # Directly use the given filter refs_set = sorted(self.__svc_registry.keys()) else: try: # Only for references with the given specification refs_set = iter(self.__svc_specs[clazz]) except KeyError: # No matching specification return None # Parse the filter try: new_filter = ldapfilter.get_ldap_filter(ldap_filter) except ValueError as ex: raise BundleException(ex) if new_filter is not None: # Prepare a generator, as we might not need a complete # walk-through refs_set = (ref for ref in refs_set if new_filter.matches(ref.get_properties())) if only_one: # Return the first element in the list/generator try: return [next(refs_set)] except StopIteration: # No match return None # Get all the matching references return list(refs_set) or None
def add_service_listener(self, listener, specification=None, ldap_filter=None): """ Registers a service listener :param listener: The service listener :param specification: The specification that must provide the service (optional, None to accept all services) :param ldap_filter: Filter that must match the service properties (optional, None to accept all services) :return: True if the listener has been registered, False if it was already known :raise BundleException: An invalid listener has been given """ if listener is None or not hasattr(listener, 'service_changed'): raise BundleException("Invalid service listener given") with self.__svc_lock: if listener in self.__listeners_data: self._logger.warning("Already known service listener '%s'", listener) return False try: ldap_filter = ldapfilter.get_ldap_filter(ldap_filter) except ValueError as ex: raise BundleException("Invalid service filter: {0}".format(ex)) stored = _Listener(listener, specification, ldap_filter) self.__listeners_data[listener] = stored self.__svc_listeners.setdefault(specification, []).append(stored) return True
def add_service_listener(self, listener, specification=None, ldap_filter=None): """ Registers a service listener :param listener: The service listener :param specification: The specification that must provide the service (optional, None to accept all services) :param ldap_filter: Filter that must match the service properties (optional, None to accept all services) :return: True if the listener has been registered, False if it was already known :raise BundleException: An invalid listener has been given """ if listener is None or not hasattr(listener, 'service_changed'): raise BundleException("Invalid service listener given") with self.__svc_lock: if listener in self.__listeners_data: self._logger.warning( "Already known service listener '%s'", listener) return False try: ldap_filter = ldapfilter.get_ldap_filter(ldap_filter) except ValueError as ex: raise BundleException("Invalid service filter: {0}" .format(ex)) stored = _Listener(listener, specification, ldap_filter) self.__listeners_data[listener] = stored self.__svc_listeners.setdefault(specification, []).append(stored) return True
def applyTest(self, filters, key): """ Applies a list of tests according to the given dictionary Dictionary format: filter -> ([True, results], [False, results]) @param filters: A filters test dictionary @param key: The key to use in the property dictionary """ props = {} for filter_str, tests in filters.items(): ldap_filter = get_ldap_filter(filter_str) self.assertIsNotNone(ldap_filter, "{0} is a valid filter".format(filter_str)) for good in tests[0]: props[key] = good self.assertTrue( ldap_filter.matches(props), "Filter '{0}' should match {1}".format(ldap_filter, props)) for bad in tests[1]: props[key] = bad self.assertFalse( ldap_filter.matches(props), "Filter '{0}' should not match {1}".format(ldap_filter, props))
def testOr(self): """ Tests the OR operator """ props = {} ldap_filter = get_ldap_filter("(|(test=True)(test2=False))") # Valid ... props["test"] = True props["test2"] = False self.assertTrue( ldap_filter.matches(props), "Filter '{0}' should match {1}".format(ldap_filter, props)) props["test"] = False props["test2"] = False self.assertTrue( ldap_filter.matches(props), "Filter '{0}' should match {1}".format(ldap_filter, props)) props["test"] = True props["test2"] = True self.assertTrue( ldap_filter.matches(props), "Filter '{0}' should match {1}".format(ldap_filter, props)) # Invalid... props["test"] = False props["test2"] = True self.assertFalse( ldap_filter.matches(props), "Filter '{0}' should not match {1}".format(ldap_filter, props))
def testSimpleCriteria(self): """ Simple boolean filter test """ props = {} ldap_filter = get_ldap_filter("(valid=True)") self.assertIsNotNone(ldap_filter, "Filter should not be None") # Test with a single property props["valid"] = True self.assertTrue(ldap_filter.matches(props), "Filter '{0}' should match {1}" .format(ldap_filter, props)) props["valid"] = False self.assertFalse(ldap_filter.matches(props), "Filter '{0}' should not match {1}" .format(ldap_filter, props)) # Test the ignorance of other properties props["valid2"] = True self.assertFalse(ldap_filter.matches(props), "Filter '{0}' should not match {1}" .format(ldap_filter, props)) props["valid"] = "True" self.assertTrue(ldap_filter.matches(props), "Filter '{0}' should match {1}" .format(ldap_filter, props))
def testRepr(self): """ Tests repr() -> eval() transformation """ # String filter: no spaces between operators nor operands # => allows direct str() results tests str_criteria = "(test=False)" # Make the filter criteria = get_ldap_filter(str_criteria) assert isinstance(criteria, pelix.ldapfilter.LDAPCriteria) # Assert strings representations are equals self.assertEqual(str_criteria, str(criteria)) # Conversion repr_criteria = repr(criteria) self.assertIn(str_criteria, repr_criteria, "The representation must contain the criteria string") # Evaluation eval_filter = eval(repr_criteria) # Equality based on the string form self.assertEqual(str_criteria, str(eval_filter), "Invalid evaluation")
def testNormalize(self): """ Tests the normalize() method """ criteria = get_ldap_filter("(test=True)") self.assertIs(criteria, criteria.normalize(), "Criteria.normalize() must return itself")
def testSimpleCriteria(self): """ Simple boolean filter test """ props = {} ldap_filter = get_ldap_filter("(valid=True)") self.assertIsNotNone(ldap_filter, "Filter should not be None") # Test with a single property props["valid"] = True self.assertTrue( ldap_filter.matches(props), "Filter '{0}' should match {1}".format(ldap_filter, props)) props["valid"] = False self.assertFalse( ldap_filter.matches(props), "Filter '{0}' should not match {1}".format(ldap_filter, props)) # Test the ignorance of other properties props["valid2"] = True self.assertFalse( ldap_filter.matches(props), "Filter '{0}' should not match {1}".format(ldap_filter, props)) props["valid"] = "True" self.assertTrue( ldap_filter.matches(props), "Filter '{0}' should match {1}".format(ldap_filter, props))
def set_filter(self, props_filter): """ Changes the current filter for the given one :param props_filter: The new requirement filter on service properties :raise TypeError: Unknown filter type """ if props_filter is not None and \ not (is_string(props_filter) or isinstance(props_filter, (ldapfilter.LDAPFilter, ldapfilter.LDAPCriteria))): # Unknown type raise TypeError("Invalid filter type {0}" .format(type(props_filter).__name__)) if props_filter is not None: # Filter given, keep its string form self.__original_filter = str(props_filter) else: # No filter self.__original_filter = None # Parse the filter self.filter = ldapfilter.get_ldap_filter(props_filter) # Prepare the full filter spec_filter = "({0}={1})".format(OBJECTCLASS, self.specification) self.__full_filter = ldapfilter.combine_filters((spec_filter, self.filter))
def applyTest(self, filters, key): """ Applies a list of tests according to the given dictionary Dictionary format: filter -> ([True, results], [False, results]) @param filters: A filters test dictionary @param key: The key to use in the property dictionary """ props = {} for filter_str, tests in filters.items(): ldap_filter = get_ldap_filter(filter_str) self.assertIsNotNone(ldap_filter, "{0} is a valid filter" .format(filter_str)) for good in tests[0]: props[key] = good self.assertTrue(ldap_filter.matches(props), "Filter '{0}' should match {1}" .format(ldap_filter, props)) for bad in tests[1]: props[key] = bad self.assertFalse(ldap_filter.matches(props), "Filter '{0}' should not match {1}" .format(ldap_filter, props))
def find_service_references(self, clazz=None, ldap_filter=None, only_one=False): """ Finds all services references matching the given filter. :param clazz: Class implemented by the service :param ldap_filter: Service filter :param only_one: Return the first matching service reference only :return: A list of found references, or None :raise BundleException: An error occurred looking for service references """ with self.__svc_lock: if clazz is None and ldap_filter is None: # Return a sorted copy of the keys list # Do not return None, as the whole content was required return sorted(self.__svc_registry.keys()) if hasattr(clazz, '__name__'): # Escape the type name clazz = ldapfilter.escape_LDAP(clazz.__name__) elif is_string(clazz): # Escape the class name clazz = ldapfilter.escape_LDAP(clazz) if clazz is None: # Directly use the given filter refs_set = sorted(self.__svc_registry.keys()) else: try: # Only for references with the given specification refs_set = iter(self.__svc_specs[clazz]) except KeyError: # No matching specification return None # Parse the filter try: new_filter = ldapfilter.get_ldap_filter(ldap_filter) except ValueError as ex: raise BundleException(ex) if new_filter is not None: # Prepare a generator, as we might not need a complete # walk-through refs_set = (ref for ref in refs_set if new_filter.matches(ref.get_properties())) if only_one: # Return the first element in the list/generator try: return next(refs_set) except StopIteration: # No match return None # Get all the matching references return list(refs_set) or None
def testCombine(self): """ Tests the combine_filters() method """ # Standard case criterias = [get_ldap_filter("(test=True)"), get_ldap_filter("(test2=False)")] for operator in (pelix.ldapfilter.AND, pelix.ldapfilter.OR): ldap_filter = pelix.ldapfilter.combine_filters(criterias, operator) assert isinstance(ldap_filter, pelix.ldapfilter.LDAPFilter) self.assertEqual(ldap_filter.operator, operator, "Invalid operator") self.assertEqual(len(ldap_filter.subfilters), 2, "Invalid count of sub filters") for criteria in criterias: self.assertIn(criteria, ldap_filter.subfilters, "A criteria is missing in the result") # No filter given for empty in (None, [], tuple(), (None, None, None)): self.assertIsNone(pelix.ldapfilter.combine_filters(empty), "Can't combine an empty list of filters") # Empty sub filters self.assertIsNone(pelix.ldapfilter.combine_filters(empty), "Empty sub filters: return None") # Invalid types for invalid in ("Filters", get_ldap_filter("(!(test=True))")): self.assertRaises(TypeError, pelix.ldapfilter.combine_filters, invalid) ldap_filter_1 = get_ldap_filter("(test=True)") ldap_filter_2 = pelix.ldapfilter.LDAPFilter(pelix.ldapfilter.AND) # Unique filter in result self.assertIs(pelix.ldapfilter.combine_filters((None, ldap_filter_1)), ldap_filter_1, "The result of combine must be minimal") self.assertIs(pelix.ldapfilter.combine_filters((ldap_filter_1, ldap_filter_2)), ldap_filter_1, "The result of combine must be minimal")
def matches(self, ldap_filter): # type: (str) -> bool """ Tests the properties of this EndpointDescription against the given filter :param ldap_filter: A filter :return: True if properties matches the filter """ return get_ldap_filter(ldap_filter).matches(self._properties)
def testCombine(self): """ Tests the combine_filters() method """ # Standard case criterias = [ get_ldap_filter("(test=True)"), get_ldap_filter("(test2=False)") ] for operator in (pelix.ldapfilter.AND, pelix.ldapfilter.OR): ldap_filter = pelix.ldapfilter.combine_filters(criterias, operator) assert isinstance(ldap_filter, pelix.ldapfilter.LDAPFilter) self.assertEqual(ldap_filter.operator, operator, "Invalid operator") self.assertEqual(len(ldap_filter.subfilters), 2, "Invalid count of sub filters") for criteria in criterias: self.assertIn(criteria, ldap_filter.subfilters, "A criteria is missing in the result") # No filter given for empty in (None, [], tuple(), (None, None, None)): self.assertIsNone(pelix.ldapfilter.combine_filters(empty), "Can't combine an empty list of filters") # Invalid types for invalid in ("Filters", get_ldap_filter("(!(test=True))")): self.assertRaises(TypeError, pelix.ldapfilter.combine_filters, invalid) ldap_filter_1 = get_ldap_filter("(test=True)") ldap_filter_2 = pelix.ldapfilter.LDAPFilter(pelix.ldapfilter.AND) # Unique filter in result self.assertIs(pelix.ldapfilter.combine_filters((None, ldap_filter_1)), ldap_filter_1, "The result of combine must be minimal") self.assertIs( pelix.ldapfilter.combine_filters((ldap_filter_1, ldap_filter_2)), ldap_filter_1, "The result of combine must be minimal")
def testGetLdapFilter(self): """ Tests the get_ldap_filter() method """ # Simple parsing / re-parsing test for str_filter, filter_type in \ (("(|(test=True)(test2=False))", pelix.ldapfilter.LDAPFilter), ("(test=True)", pelix.ldapfilter.LDAPCriteria)): ldap_filter = get_ldap_filter(str_filter) assert isinstance(ldap_filter, filter_type) self.assertEqual(str(ldap_filter), str_filter, "Invalid parsing") self.assertIs(get_ldap_filter(ldap_filter), ldap_filter, "get_ldap_filter should return the given object.") # Empty filters for empty in (None, "", " "): self.assertIsNone(get_ldap_filter(empty), "Empty filter should return None") # Invalid types for invalid in (1, [], {}): self.assertRaises(TypeError, get_ldap_filter, invalid)
def list_configurations(self, ldap_filter=None): """ Returns the list of stored configurations :param ldap_filter: Optional LDAP filter :return: The set of matching configurations :raise ValueError: Invalid LDAP filter """ if not ldap_filter: return set(self.__configurations.values()) else: # Using an LDAP filter ldap_filter = ldapfilter.get_ldap_filter(ldap_filter) return set(config for config in self.__configurations.values() if config.matches(ldap_filter))
def testPresenceCriteria(self): """ Test the presence filter """ props = {} ldap_filter = get_ldap_filter("(valid=*)") self.assertIsNotNone(ldap_filter, "Filter should not be None") # Missing value self.assertFalse(ldap_filter.matches(props), "Filter '{0}' should not match {1}" .format(ldap_filter, props)) # Still missing props["valid2"] = True self.assertFalse(ldap_filter.matches(props), "Filter '{0}' should not match {1}" .format(ldap_filter, props)) # Value present props["valid"] = True self.assertTrue(ldap_filter.matches(props), "Filter '{0}' should match {1}" .format(ldap_filter, props)) props["valid"] = False self.assertTrue(ldap_filter.matches(props), "Filter '{0}' should match {1}" .format(ldap_filter, props)) # Some other type props["valid"] = "1234" self.assertTrue(ldap_filter.matches(props), "Filter '{0}' should match {1}" .format(ldap_filter, props)) # Empty values for empty in ('', [], tuple()): props["valid"] = empty self.assertFalse(ldap_filter.matches(props), "Filter '{0}' should not match {1}" .format(ldap_filter, props))
def testPresenceCriteria(self): """ Test the presence filter """ props = {} ldap_filter = get_ldap_filter("(valid=*)") self.assertIsNotNone(ldap_filter, "Filter should not be None") # Missing value self.assertFalse( ldap_filter.matches(props), "Filter '{0}' should not match {1}".format(ldap_filter, props)) # Still missing props["valid2"] = True self.assertFalse( ldap_filter.matches(props), "Filter '{0}' should not match {1}".format(ldap_filter, props)) # Value present props["valid"] = True self.assertTrue( ldap_filter.matches(props), "Filter '{0}' should match {1}".format(ldap_filter, props)) props["valid"] = False self.assertTrue( ldap_filter.matches(props), "Filter '{0}' should match {1}".format(ldap_filter, props)) # Some other type props["valid"] = "1234" self.assertTrue( ldap_filter.matches(props), "Filter '{0}' should match {1}".format(ldap_filter, props)) # Empty values for empty in ('', [], tuple()): props["valid"] = empty self.assertFalse( ldap_filter.matches(props), "Filter '{0}' should not match {1}".format(ldap_filter, props))
def set_channel_filter(self, channel, ldap_filter): """ Sets the LDAP filter for a channel :param channel: Channel to filter :param ldap_filter: Filter on channel data :raise ValueError: Invalid LDAP filter """ # Compute the filter parsed_filter = ldapfilter.get_ldap_filter(ldap_filter) if parsed_filter is None: try: # Remove the filter del self._channels_filters[channel] except KeyError: # No filter to remove pass else: # Store the filter self._channels_filters[channel] = parsed_filter
def testComparator2str(self): """ Tests comparator2str() """ for comparator in ('=', '<', '<=', '>', '>=', '=', '~='): # Parse a criteria with that comparator ldap_filter = get_ldap_filter("(a{0}1)".format(comparator)) # Get the string version of the parsed comparator str_comparator = pelix.ldapfilter.comparator2str( ldap_filter.comparator) self.assertEqual(str_comparator, comparator, "Bad string for comparator '{0}': '{1}'" .format(comparator, str_comparator)) # Invalid comparators for comparator in (None, str, str(), int()): str_comparator = pelix.ldapfilter.comparator2str(comparator) self.assertEqual(str_comparator, "??", "Bad string for comparator '{0}': '{1}'" .format(comparator, str_comparator))
def testRepr(self): """ Test repr() -> eval() transformation """ # String filter: no spaces between operators nor operands # => allows direct str() results tests str_filter = "(&(test=False)(test2=True))" # Make the filter ldap_filter = get_ldap_filter(str_filter) # Assert strings representations are equals self.assertEqual(str_filter, str(ldap_filter)) # Conversion repr_filter = repr(ldap_filter) self.assertIn(str_filter, repr_filter, "The representation must contain the filter string") # Evaluation eval_filter = eval(repr_filter) # Equality based on the string form self.assertEqual(str_filter, str(eval_filter), "Invalid evaluation") # Match test for test_value in (True, False): for test2_value in (True, False): for test3_value in (None, True, False, 42, "string"): properties = { "test": test_value, "test2": test2_value, "test3": test3_value } self.assertEqual( ldap_filter.matches(properties), eval_filter.matches(properties), "Different result found for {0}".format(properties))
def update_filter(self): """ Update the filter according to the new properties :return: True if the filter changed, else False :raise ValueError: The filter is invalid """ # Consider the filter invalid self.valid_filter = False try: # Format the new filter filter_str = self._original_filter.format( **self._component_context.properties ) except KeyError as ex: # An entry is missing: abandon logging.warning("Missing filter value: %s", ex) raise ValueError("Missing filter value") try: # Parse the new LDAP filter new_filter = ldapfilter.get_ldap_filter(filter_str) except (TypeError, ValueError) as ex: logging.warning("Error parsing filter: %s", ex) raise ValueError("Error parsing filter") # The filter is valid self.valid_filter = True # Compare to the "old" one if new_filter != self.requirement.filter: # Replace the requirement filter self.requirement.filter = new_filter return True # Same filter return False
def testAppend(self): """ Tests the filter append() method """ # "And" operator ldap_filter = pelix.ldapfilter.LDAPFilter(pelix.ldapfilter.AND) # Add a "normal" value criteria = get_ldap_filter("(test=True)") ldap_filter.append(criteria) self.assertEqual(len(ldap_filter.subfilters), 1, "Criteria not added") # Add invalid values for invalid_value in (None, "(test=False)", "(|(test=True)(test2=False))"): self.assertRaises(TypeError, ldap_filter.append, invalid_value) # Special case: 'Not' operator ldap_filter = pelix.ldapfilter.LDAPFilter(pelix.ldapfilter.NOT) ldap_filter.append(criteria) # No more value must be accepted self.assertRaises(ValueError, ldap_filter.append, criteria)
def testRepr(self): """ Test repr() -> eval() transformation """ # String filter: no spaces between operators nor operands # => allows direct str() results tests str_filter = "(&(test=False)(test2=True))" # Make the filter ldap_filter = get_ldap_filter(str_filter) # Assert strings representations are equals self.assertEqual(str_filter, str(ldap_filter)) # Conversion repr_filter = repr(ldap_filter) self.assertIn(str_filter, repr_filter, "The representation must contain the filter string") # Evaluation eval_filter = eval(repr_filter) # Equality based on the string form self.assertEqual(str_filter, str(eval_filter), "Invalid evaluation") # Match test for test_value in (True, False): for test2_value in (True, False): for test3_value in (None, True, False, 42, "string"): properties = {"test": test_value, "test2": test2_value, "test3": test3_value} self.assertEqual(ldap_filter.matches(properties), eval_filter.matches(properties), "Different result found for {0}" .format(properties))
def testComparator2str(self): """ Tests comparator2str() """ for comparator in ('=', '<', '<=', '>', '>=', '=', '~='): # Parse a criteria with that comparator ldap_filter = get_ldap_filter("(a{0}1)".format(comparator)) # Get the string version of the parsed comparator str_comparator = pelix.ldapfilter.comparator2str( ldap_filter.comparator) self.assertEqual( str_comparator, comparator, "Bad string for comparator '{0}': '{1}'".format( comparator, str_comparator)) # Invalid comparators for comparator in (None, str, str(), int()): str_comparator = pelix.ldapfilter.comparator2str(comparator) self.assertEqual( str_comparator, "??", "Bad string for comparator '{0}': '{1}'".format( comparator, str_comparator))
def testEq(self): """ Tests the LDAPFilter objects equality """ # Some filter str_filter = "(&(test=False)(test2=True))" ldap_filter = get_ldap_filter(str_filter) # Test with other values self.assertNotEqual(ldap_filter, None, "Filter is not equal to None") self.assertEqual(ldap_filter, ldap_filter, "Filter is not self-equal") self.assertNotEqual( pelix.ldapfilter.LDAPFilter(pelix.ldapfilter.NOT), pelix.ldapfilter.LDAPCriteria( 'test', 123, pelix.ldapfilter._comparator_approximate), "Invalid equality (type)") # Tests order must not provide a different filter str_filter_2 = "(&(test2=True)(test=False))" ldap_filter_2 = get_ldap_filter(str_filter_2) self.assertEqual(ldap_filter, ldap_filter_2, "Filters are not equal") # Inequality check self.assertNotEqual(ldap_filter, get_ldap_filter("(test2=true)"), "Invalid equality (type)") self.assertNotEqual( ldap_filter, get_ldap_filter("(&(test=False)(test2=True)(test3=1))"), "Invalid equality (size)") self.assertNotEqual(ldap_filter, get_ldap_filter("(&(test1=False)(test2=True))"), "Invalid equality (sub-filter)") self.assertNotEqual(ldap_filter, get_ldap_filter("(|(test=False)(test2=True))"), "Invalid equality (operator)")