You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2016/01/25 19:01:37 UTC

[21/51] celix git commit: CELIX-332: add filter tests, fixed small bugs in the source

CELIX-332: add filter tests, fixed small bugs in the source


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/96650491
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/96650491
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/96650491

Branch: refs/heads/feature/CELIX-335_deploy_refactoring
Commit: 9665049158d81a235de995c3d87acc02cb7a17fc
Parents: 099fc6b
Author: Bjoern Petri <bp...@apache.org>
Authored: Mon Jan 11 16:51:06 2016 +0100
Committer: Bjoern Petri <bp...@apache.org>
Committed: Mon Jan 11 16:51:06 2016 +0100

----------------------------------------------------------------------
 framework/private/include/filter_private.h |   1 -
 framework/private/src/filter.c             | 212 ++++++----
 framework/private/test/filter_test.cpp     | 514 ++++++++++++++++++++++--
 3 files changed, 629 insertions(+), 98 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/96650491/framework/private/include/filter_private.h
----------------------------------------------------------------------
diff --git a/framework/private/include/filter_private.h b/framework/private/include/filter_private.h
index 548a6d2..d19de2d 100644
--- a/framework/private/include/filter_private.h
+++ b/framework/private/include/filter_private.h
@@ -49,7 +49,6 @@ typedef enum operand
 struct filter {
 	OPERAND operand;
 	char * attribute;
-	int operands;
 	void * value;
 	char *filterStr;
 };

http://git-wip-us.apache.org/repos/asf/celix/blob/96650491/framework/private/src/filter.c
----------------------------------------------------------------------
diff --git a/framework/private/src/filter.c b/framework/private/src/filter.c
index bf632ff..02ebc83 100644
--- a/framework/private/src/filter.c
+++ b/framework/private/src/filter.c
@@ -31,21 +31,21 @@
 #include "celix_log.h"
 #include "filter_private.h"
 
-void filter_skipWhiteSpace(char * filterString, int * pos);
-filter_pt filter_parseFilter(char * filterString, int * pos);
-filter_pt filter_parseFilterComp(char * filterString, int * pos);
-filter_pt filter_parseAnd(char * filterString, int * pos);
-filter_pt filter_parseOr(char * filterString, int * pos);
-filter_pt filter_parseNot(char * filterString, int * pos);
-filter_pt filter_parseItem(char * filterString, int * pos);
-char * filter_parseAttr(char * filterString, int * pos);
-char * filter_parseValue(char * filterString, int * pos);
-array_list_pt filter_parseSubstring(char * filterString, int * pos);
-
-celix_status_t filter_compare(OPERAND operand, char * string, void * value2, bool *result);
-celix_status_t filter_compareString(OPERAND operand, char * string, void * value2, bool *result);
-
-void filter_skipWhiteSpace(char * filterString, int * pos) {
+static void filter_skipWhiteSpace(char * filterString, int * pos);
+static filter_pt filter_parseFilter(char * filterString, int * pos);
+static filter_pt filter_parseFilterComp(char * filterString, int * pos);
+static filter_pt filter_parseAnd(char * filterString, int * pos);
+static filter_pt filter_parseOr(char * filterString, int * pos);
+static filter_pt filter_parseNot(char * filterString, int * pos);
+static filter_pt filter_parseItem(char * filterString, int * pos);
+static char * filter_parseAttr(char * filterString, int * pos);
+static char * filter_parseValue(char * filterString, int * pos);
+static array_list_pt filter_parseSubstring(char * filterString, int * pos);
+
+static celix_status_t filter_compare(OPERAND operand, char * string, void * value2, bool *result);
+static celix_status_t filter_compareString(OPERAND operand, char * string, void * value2, bool *result);
+
+static void filter_skipWhiteSpace(char * filterString, int * pos) {
 	int length;
 	for (length = strlen(filterString); (*pos < length) && isspace(filterString[*pos]);) {
 		(*pos)++;
@@ -58,38 +58,43 @@ filter_pt filter_create(char * filterString) {
 	filter = filter_parseFilter(filterString, &pos);
 	if (pos != strlen(filterString)) {
 		fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR,  "Error: Extraneous trailing characters.");
+		filter_destroy(filter);
 		return NULL;
 	}
-	filter->filterStr = filterString;
+	if(filter != NULL){
+		filter->filterStr = filterString;
+	}
+
 	return filter;
 }
 
 void filter_destroy(filter_pt filter) {
 	if (filter != NULL) {
-		if (filter->operand == SUBSTRING) {
-			 int size = arrayList_size(filter->value);
-			 for (; size > 0; --size) {
-				 char* operand = (char*) arrayList_remove(filter->value, 0);
-				 free(operand);
-			 }
-			arrayList_clear(filter->value);
-			arrayList_destroy(filter->value);
-			filter->value = NULL;
-		} else if ( (filter->operand == OR) || (filter->operand == AND) ) {
-			int size = arrayList_size(filter->value);
-			unsigned int i = 0;
-			for (i = 0; i < size; i++) {
-				filter_pt f = arrayList_get(filter->value, i);
-				filter_destroy(f);
+		if(filter->value!=NULL){
+			if (filter->operand == SUBSTRING) {
+				int size = arrayList_size(filter->value);
+				for (; size > 0; --size) {
+					char* operand = (char*) arrayList_remove(filter->value, 0);
+					free(operand);
+				}
+				arrayList_destroy(filter->value);
+				filter->value = NULL;
+			} else if ( (filter->operand == OR) || (filter->operand == AND) ) {
+				int size = arrayList_size(filter->value);
+				unsigned int i = 0;
+				for (i = 0; i < size; i++) {
+					filter_pt f = arrayList_get(filter->value, i);
+					filter_destroy(f);
+				}
+				arrayList_destroy(filter->value);
+				filter->value = NULL;
+			} else  if (filter->operand == NOT) {
+				filter_destroy(filter->value);
+				filter->value = NULL;
+			} else {
+				free(filter->value);
+				filter->value = NULL;
 			}
-			arrayList_destroy(filter->value);
-			filter->value = NULL;
-		} else  if (filter->operand == NOT) {
-			filter_destroy(filter->value);
-			filter->value = NULL;
-		} else {
-			free(filter->value);
-			filter->value = NULL;
 		}
 		free(filter->attribute);
 		filter->attribute = NULL;
@@ -98,7 +103,7 @@ void filter_destroy(filter_pt filter) {
 	}
 }
 
-filter_pt filter_parseFilter(char * filterString, int * pos) {
+static filter_pt filter_parseFilter(char * filterString, int * pos) {
 	filter_pt filter;
 	filter_skipWhiteSpace(filterString, pos);
 	if (filterString[*pos] != '(') {
@@ -113,15 +118,25 @@ filter_pt filter_parseFilter(char * filterString, int * pos) {
 
 	if (filterString[*pos] != ')') {
 		fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Error: Missing ')'.");
+		if(filter!=NULL){
+			filter_destroy(filter);
+		}
 		return NULL;
 	}
 	(*pos)++;
 	filter_skipWhiteSpace(filterString, pos);
 
+	if(filter != NULL){
+		if(filter->value == NULL && filter->operand!=PRESENT){
+			filter_destroy(filter);
+			return NULL;
+		}
+	}
+
 	return filter;
 }
 
-filter_pt filter_parseFilterComp(char * filterString, int * pos) {
+static filter_pt filter_parseFilterComp(char * filterString, int * pos) {
 	char c;
 	filter_skipWhiteSpace(filterString, pos);
 
@@ -144,22 +159,39 @@ filter_pt filter_parseFilterComp(char * filterString, int * pos) {
 	return filter_parseItem(filterString, pos);
 }
 
-filter_pt filter_parseAnd(char * filterString, int * pos) {
-	filter_pt filter = (filter_pt) malloc(sizeof(*filter));
+static filter_pt filter_parseAnd(char * filterString, int * pos) {
+
 	array_list_pt operands = NULL;
-	arrayList_create(&operands);
 	filter_skipWhiteSpace(filterString, pos);
+	bool failure = false;
 
 	if (filterString[*pos] != '(') {
 		fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Error: Missing '('.");
 		return NULL;
 	}
 
+	arrayList_create(&operands);
 	while(filterString[*pos] == '(') {
 		filter_pt child = filter_parseFilter(filterString, pos);
+		if(child == NULL){
+			failure = true;
+			break;
+		}
 		arrayList_add(operands, child);
 	}
 
+	if(failure == true){
+		array_list_iterator_pt listIt = arrayListIterator_create(operands);
+		while(arrayListIterator_hasNext(listIt)){
+			filter_pt f = arrayListIterator_next(listIt);
+			filter_destroy(f);
+		}
+		arrayListIterator_destroy(listIt);
+		arrayList_destroy(operands);
+		operands = NULL;
+	}
+
+	filter_pt filter = (filter_pt) malloc(sizeof(*filter));
 	filter->operand = AND;
 	filter->attribute = NULL;
 	filter->value = operands;
@@ -167,22 +199,40 @@ filter_pt filter_parseAnd(char * filterString, int * pos) {
 	return filter;
 }
 
-filter_pt filter_parseOr(char * filterString, int * pos) {
-	filter_pt filter = (filter_pt) malloc(sizeof(*filter));
+static filter_pt filter_parseOr(char * filterString, int * pos) {
+
 	array_list_pt operands = NULL;
-	arrayList_create(&operands);
+
 	filter_skipWhiteSpace(filterString, pos);
+	bool failure = false;
 
 	if (filterString[*pos] != '(') {
 		fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Error: Missing '('.");
 		return NULL;
 	}
 
+	arrayList_create(&operands);
 	while(filterString[*pos] == '(') {
 		filter_pt child = filter_parseFilter(filterString, pos);
+		if(child == NULL){
+			failure = true;
+			break;
+		}
 		arrayList_add(operands, child);
 	}
 
+	if(failure == true){
+		array_list_iterator_pt listIt = arrayListIterator_create(operands);
+		while(arrayListIterator_hasNext(listIt)){
+			filter_pt f = arrayListIterator_next(listIt);
+			filter_destroy(f);
+		}
+		arrayListIterator_destroy(listIt);
+		arrayList_destroy(operands);
+		operands = NULL;
+	}
+
+	filter_pt filter = (filter_pt) malloc(sizeof(*filter));
 	filter->operand = OR;
 	filter->attribute = NULL;
 	filter->value = operands;
@@ -190,9 +240,8 @@ filter_pt filter_parseOr(char * filterString, int * pos) {
 	return filter;
 }
 
-filter_pt filter_parseNot(char * filterString, int * pos) {
+static filter_pt filter_parseNot(char * filterString, int * pos) {
 	filter_pt child = NULL;
-	filter_pt filter = (filter_pt) malloc(sizeof(*filter));
 	filter_skipWhiteSpace(filterString, pos);
 
 	if (filterString[*pos] != '(') {
@@ -202,6 +251,8 @@ filter_pt filter_parseNot(char * filterString, int * pos) {
 
 	child = filter_parseFilter(filterString, pos);
 
+
+	filter_pt filter = (filter_pt) malloc(sizeof(*filter));
 	filter->operand = NOT;
 	filter->attribute = NULL;
 	filter->value = child;
@@ -209,8 +260,12 @@ filter_pt filter_parseNot(char * filterString, int * pos) {
 	return filter;
 }
 
-filter_pt filter_parseItem(char * filterString, int * pos) {
+static filter_pt filter_parseItem(char * filterString, int * pos) {
 	char * attr = filter_parseAttr(filterString, pos);
+	if(attr == NULL){
+		return NULL;
+	}
+
 	filter_skipWhiteSpace(filterString, pos);
 	switch(filterString[*pos]) {
 		case '~': {
@@ -281,17 +336,19 @@ filter_pt filter_parseItem(char * filterString, int * pos) {
 			filter = (filter_pt) malloc(sizeof(*filter));			
 			(*pos)++;
 			subs = filter_parseSubstring(filterString, pos);
-			if (arrayList_size(subs) == 1) {
-				char * string = (char *) arrayList_get(subs, 0);
-				if (string != NULL) {
-					filter->operand = EQUAL;
-					filter->attribute = attr;
-					filter->value = string;
-
-					arrayList_clear(subs);
-					arrayList_destroy(subs);
-
-					return filter;
+			if(subs!=NULL){
+				if (arrayList_size(subs) == 1) {
+					char * string = (char *) arrayList_get(subs, 0);
+					if (string != NULL) {
+						filter->operand = EQUAL;
+						filter->attribute = attr;
+						filter->value = string;
+
+						arrayList_clear(subs);
+						arrayList_destroy(subs);
+
+						return filter;
+					}
 				}
 			}
 			filter->operand = SUBSTRING;
@@ -301,10 +358,11 @@ filter_pt filter_parseItem(char * filterString, int * pos) {
 		}
 	}
 	fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Invalid operator.");
+	free(attr);
 	return NULL;
 }
 
-char * filter_parseAttr(char * filterString, int * pos) {
+static char * filter_parseAttr(char * filterString, int * pos) {
 	char c;
 	int begin = *pos;
 	int end = *pos;
@@ -336,7 +394,7 @@ char * filter_parseAttr(char * filterString, int * pos) {
 	}
 }
 
-char * filter_parseValue(char * filterString, int * pos) {
+static char * filter_parseValue(char * filterString, int * pos) {
 	char *value = calloc(strlen(filterString) + 1, sizeof(*value));
 	int keepRunning = 1;
 
@@ -350,6 +408,12 @@ char * filter_parseValue(char * filterString, int * pos) {
 			}
 			case '(': {
 				fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Invalid value.");
+				free(value);
+				return NULL;
+			}
+			case '\0':{
+				fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Unclosed bracket.");
+				free(value);
 				return NULL;
 			}
 			case '\\': {
@@ -370,16 +434,16 @@ char * filter_parseValue(char * filterString, int * pos) {
 
 	if (strlen(value) == 0) {
 		fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Missing value.");
+		free(value);
 		return NULL;
 	}
 	return value;
 }
 
-array_list_pt filter_parseSubstring(char * filterString, int * pos) {
+static array_list_pt filter_parseSubstring(char * filterString, int * pos) {
 	char *sub = calloc(strlen(filterString) + 1, sizeof(*sub));
 	array_list_pt operands = NULL;
 	int keepRunning = 1;
-	int size;
 
 	arrayList_create(&operands);
 	while (keepRunning) {
@@ -394,9 +458,15 @@ array_list_pt filter_parseSubstring(char * filterString, int * pos) {
 				keepRunning = 0;
 				break;
 			}
+			case '\0':{
+				fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Unclosed bracket.");
+				keepRunning = false;
+				break;
+			}
 			case '(': {
 				fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Invalid value.");
-				return NULL;
+				keepRunning = false;
+				break;
 			}
 			case '*': {
 				if (strlen(sub) > 0) {
@@ -423,10 +493,10 @@ array_list_pt filter_parseSubstring(char * filterString, int * pos) {
 		}
 	}
 	free(sub);
-	size = arrayList_size(operands);
 
-	if (size == 0) {
+	if (arrayList_size(operands) == 0) {
 		fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Missing value.");
+		arrayList_destroy(operands);
 		return NULL;
 	}
 
@@ -493,7 +563,7 @@ celix_status_t filter_match(filter_pt filter, properties_pt properties, bool *re
 	return CELIX_SUCCESS;
 }
 
-celix_status_t filter_compare(OPERAND operand, char * string, void * value2, bool *result) {
+static celix_status_t filter_compare(OPERAND operand, char * string, void * value2, bool *result) {
 	if (string == NULL) {
 		*result = 0;
 		return CELIX_SUCCESS;
@@ -502,7 +572,7 @@ celix_status_t filter_compare(OPERAND operand, char * string, void * value2, boo
 
 }
 
-celix_status_t filter_compareString(OPERAND operand, char * string, void * value2, bool *result) {
+static celix_status_t filter_compareString(OPERAND operand, char * string, void * value2, bool *result) {
 	switch (operand) {
 		case SUBSTRING: {
 			array_list_pt subs = (array_list_pt) value2;
@@ -560,7 +630,7 @@ celix_status_t filter_compareString(OPERAND operand, char * string, void * value
 			*result = true;
 			return CELIX_SUCCESS;
 		}
-		case APPROX:
+		case APPROX: //TODO: Implement strcmp with ignorecase and ignorespaces
 		case EQUAL: {
 			*result = (strcmp(string, (char *) value2) == 0);
 			return CELIX_SUCCESS;

http://git-wip-us.apache.org/repos/asf/celix/blob/96650491/framework/private/test/filter_test.cpp
----------------------------------------------------------------------
diff --git a/framework/private/test/filter_test.cpp b/framework/private/test/filter_test.cpp
index 2ed7485..bf07fc6 100644
--- a/framework/private/test/filter_test.cpp
+++ b/framework/private/test/filter_test.cpp
@@ -25,6 +25,7 @@
  */
 #include <stdlib.h>
 #include <stdio.h>
+#include <string.h>
 
 #include "CppUTest/TestHarness.h"
 #include "CppUTest/TestHarness_c.h"
@@ -35,61 +36,522 @@ extern "C" {
 #include "filter_private.h"
 #include "celix_log.h"
 
-framework_logger_pt logger;
+framework_logger_pt logger = (framework_logger_pt) 0x42;
 }
 
 int main(int argc, char** argv) {
 	return RUN_ALL_TESTS(argc, argv);
 }
 
+static char* my_strdup(const char* s){
+	if(s==NULL){
+		return NULL;
+	}
+
+	size_t len = strlen(s);
+
+	char *d = (char*) calloc (len + 1,sizeof(char));
+
+	if (d == NULL){
+		return NULL;
+	}
+
+	strncpy (d,s,len);
+	return d;
+}
+
+//----------------TESTGROUPS----------------
 TEST_GROUP(filter) {
 	void setup(void) {
-		logger = (framework_logger_pt) malloc(sizeof(*logger));
-		logger->logFunction = frameworkLogger_log;
 	}
 
 	void teardown() {
-		mock().checkExpectations();
 		mock().clear();
-
-		free(logger);
 	}
 };
 
-TEST(filter, create) {
-	char filterStr[] = "(key=value)";
-	filter_pt filter = filter_create(filterStr);
+//----------------FILTER TESTS----------------
+TEST(filter, create_destroy){
+	char * filter_str = my_strdup("(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3=attr3)))");
+	filter_pt get_filter;
+
+	get_filter = filter_create(filter_str);
+	CHECK(get_filter != NULL);
+
+	filter_destroy(get_filter);
+
+	//cleanup
+	free(filter_str);
+
+	mock().checkExpectations();
+}
+
+TEST(filter, create_fail_missing_opening_brackets){
+	char * filter_str;
+	filter_pt get_filter;
+
+	//test missing opening brackets in main filter
+	mock().expectNCalls(2, "framework_log");
+	filter_str = my_strdup("&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3=attr3))");
+	get_filter = filter_create(filter_str);
+	POINTERS_EQUAL(NULL, get_filter);
+	free(filter_str);
+	mock().checkExpectations();
+
+	//test missing opening brackets in AND comparator
+	mock().expectNCalls(3, "framework_log");
+	filter_str = my_strdup("(&test_attr1=attr1|(test_attr2=attr2)(test_attr3=attr3))");
+	get_filter = filter_create(filter_str);
+	POINTERS_EQUAL(NULL, get_filter);
+	free(filter_str);
+	mock().checkExpectations();
+
+	//test missing opening brackets in AND comparator
+	mock().expectNCalls(4, "framework_log");
+	filter_str = my_strdup("(&(test_attr1=attr1)(|test_attr2=attr2(test_attr3=attr3))");
+	get_filter = filter_create(filter_str);
+	POINTERS_EQUAL(NULL, get_filter);
+	free(filter_str);
+	mock().checkExpectations();
+
+	//test missing opening brackets in NOT comparator
+	mock().expectNCalls(4, "framework_log");
+	filter_str = my_strdup("(&(test_attr1=attr1)(!test_attr2=attr2)");
+	get_filter = filter_create(filter_str);
+	POINTERS_EQUAL(NULL, get_filter);
+	free(filter_str);
+	mock().checkExpectations();
+}
+
+TEST(filter, create_fail_missing_closing_brackets){
+	char * filter_str;
+	filter_pt get_filter;
+	//test missing closing brackets in substring
+	mock().expectNCalls(5, "framework_log");
+	filter_str = my_strdup("(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3=attr3");
+	get_filter = filter_create(filter_str);
+	POINTERS_EQUAL(NULL, get_filter);
+	free(filter_str);
+	mock().checkExpectations();
+
+	//test missing closing brackets in value
+	mock().expectNCalls(4, "framework_log");
+	filter_str = my_strdup("(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3>=attr3");
+	get_filter = filter_create(filter_str);
+	POINTERS_EQUAL(NULL, get_filter);
+	free(filter_str);
+	mock().checkExpectations();
+}
+
+TEST(filter, create_fail_invalid_closing_brackets){
+	char * filter_str;
+	filter_pt get_filter;
+	//test missing closing brackets in substring
+	mock().expectNCalls(6, "framework_log");
+	filter_str = my_strdup("(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3=at(tr3)))");
+	get_filter = filter_create(filter_str);
+	POINTERS_EQUAL(NULL, get_filter);
+	free(filter_str);
+	mock().checkExpectations();
+
+	//test missing closing brackets in value
+	mock().expectNCalls(5, "framework_log");
+	filter_str = my_strdup("(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3>=att(r3)))");
+	get_filter = filter_create(filter_str);
+	POINTERS_EQUAL(NULL, get_filter);
+	free(filter_str);
+	mock().checkExpectations();
+}
+
+TEST(filter, create_misc){
+	char * filter_str;
+	filter_pt get_filter;
+	//test trailing chars
+	mock().expectOneCall("framework_log");
+	filter_str = my_strdup("(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3=attr3))) oh no! trailing chars");
+	get_filter = filter_create(filter_str);
+	POINTERS_EQUAL(NULL, get_filter);
+	free(filter_str);
+	mock().checkExpectations();
+
+	//test half APPROX operator (should be "~=", instead is "~")
+	mock().expectNCalls(5, "framework_log");
+	filter_str = my_strdup("(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3~attr3)))");
+	get_filter = filter_create(filter_str);
+	POINTERS_EQUAL(NULL, get_filter);
+	free(filter_str);
+	mock().checkExpectations();
+
+	//test PRESENT operator with trailing chars (should just register as substrings: "*" and "attr3")
+	filter_str = my_strdup("(test_attr3=*attr3)");
+	get_filter = filter_create(filter_str);
+	CHECK(get_filter != NULL);
+	LONGS_EQUAL(SUBSTRING, get_filter->operand)
+	LONGS_EQUAL(2, arrayList_size((array_list_pt) get_filter->value));
+	filter_destroy(get_filter);
+	free(filter_str);
+	mock().checkExpectations();
+
+	//test parsing a attribute of 0 length
+	mock().expectNCalls(3, "framework_log");
+	filter_str = my_strdup("(>=attr3)");
+	get_filter = filter_create(filter_str);
+	POINTERS_EQUAL(NULL, get_filter);
+	free(filter_str);
+	mock().checkExpectations();
+
+	//test parsing a value of 0 length
+	mock().expectOneCall("framework_log");
+	filter_str = my_strdup("(test_attr3>=)");
+	get_filter = filter_create(filter_str);
+	POINTERS_EQUAL(NULL, get_filter);
+	free(filter_str);
+	mock().checkExpectations();
+
+	//test parsing a value with a escaped closing bracket "\)"
+	filter_str = my_strdup("(test_attr3>=strWith\\)inIt)");
+	get_filter = filter_create(filter_str);
+	CHECK(get_filter != NULL);
+	STRCMP_EQUAL("strWith)inIt", (char*)get_filter->value);
+	filter_destroy(get_filter);
+	free(filter_str);
+	mock().checkExpectations();
+
+	//test parsing a substring with a escaped closing bracket "\)"
+	filter_str = my_strdup("(test_attr3=strWith\\)inIt)");
+	get_filter = filter_create(filter_str);
+	CHECK(get_filter != NULL);
+	STRCMP_EQUAL("strWith)inIt", (char*)get_filter->value);
+	filter_destroy(get_filter);
+	free(filter_str);
+	mock().checkExpectations();
+}
+
+TEST(filter, match_comparators){
+	char * filter_str;
+	filter_pt filter;
+	properties_pt props = properties_create();
+	char * key = my_strdup("test_attr1");
+	char * val = my_strdup("attr1");
+	char * key2 = my_strdup("test_attr2");
+	char * val2 = my_strdup("attr2");
+	properties_set(props, key, val);
+	properties_set(props, key2, val2);
 
-	STRCMP_EQUAL(filterStr, filter->filterStr);
+	//test AND
+	filter_str = my_strdup("(&(test_attr1=attr1)(|(test_attr2=attr2)(!(test_attr3=attr3))))");
+	filter = filter_create(filter_str);
+	bool result = false;
+	filter_match(filter, props, &result);
+	CHECK(result);
+
+	//test AND false
+	filter_destroy(filter);
+	free(filter_str);
+	filter_str = my_strdup("(&(test_attr1=attr1)(test_attr1=attr2))");
+	filter = filter_create(filter_str);
+	result = true;
+	filter_match(filter, props, &result);
+	CHECK_FALSE(result);
+
+	//cleanup
+	properties_destroy(props);
+	filter_destroy(filter);
+	free(filter_str);
+	free(key);
+	free(key2);
+	free(val);
+	free(val2);
+
+	mock().checkExpectations();
 }
 
+TEST(filter, match_operators){
+	char * filter_str;
+	filter_pt filter;
+	properties_pt props = properties_create();
+	char * key = my_strdup("test_attr1");
+	char * val = my_strdup("attr1");
+	char * key2 = my_strdup("test_attr2");
+	char * val2 = my_strdup("attr2");
+	properties_set(props, key, val);
+	properties_set(props, key2, val2);
+
+	//test EQUALS
+	filter_str = my_strdup("(test_attr1=attr1)");
+	filter = filter_create(filter_str);
+	bool result = false;
+	filter_match(filter, props, &result);
+	CHECK(result);
+
+	//test EQUALS false
+	filter_destroy(filter);
+	free(filter_str);
+	filter_str = my_strdup("(test_attr1=falseString)");
+	filter = filter_create(filter_str);
+	result = true;
+	filter_match(filter, props, &result);
+	CHECK_FALSE(result);
+
+	//test APPROX TODO: update this test once APPROX is implemented
+	filter_destroy(filter);
+	free(filter_str);
+	filter_str = my_strdup("(test_attr1~=attr1)");
+	filter = filter_create(filter_str);
+	result = false;
+	filter_match(filter, props, &result);
+	CHECK(result);
+
+	//test APROX false TODO: update this test once APPROX is implemented
+	filter_destroy(filter);
+	free(filter_str);
+	filter_str = my_strdup("(test_attr1~=ATTR1)");
+	filter = filter_create(filter_str);
+	result = true;
+	filter_match(filter, props, &result);
+	CHECK_FALSE(result);
+
+	//test PRESENT
+	filter_destroy(filter);
+	free(filter_str);
+	filter_str = my_strdup("(test_attr1=*)");
+	filter = filter_create(filter_str);
+	result = false;
+	filter_match(filter, props, &result);
+	CHECK(result);
+
+	//test PRESENT false
+	filter_destroy(filter);
+	free(filter_str);
+	filter_str = my_strdup("(test_attr3=*)");
+	filter = filter_create(filter_str);
+	result = true;
+	filter_match(filter, props, &result);
+	CHECK_FALSE(result);
+
+	//test LESSEQUAL less
+	filter_destroy(filter);
+	free(filter_str);
+	filter_str = my_strdup("(test_attr1<=attr5)");
+	filter = filter_create(filter_str);
+	result = false;
+	filter_match(filter, props, &result);
+	CHECK(result);
+
+	//test LESSEQUAL equals
+	filter_destroy(filter);
+	free(filter_str);
+	filter_str = my_strdup("(test_attr2<=attr2)");
+	filter = filter_create(filter_str);
+	result = false;
+	filter_match(filter, props, &result);
+	CHECK(result);
+
+	//test LESSEQUAL false
+	filter_destroy(filter);
+	free(filter_str);
+	filter_str = my_strdup("(test_attr2<=attr1)");
+	filter = filter_create(filter_str);
+	result = true;
+	filter_match(filter, props, &result);
+	CHECK_FALSE(result);
+
+	//test GREATEREQUAL greater
+	filter_destroy(filter);
+	free(filter_str);
+	filter_str = my_strdup("(test_attr2>=attr1)");
+	filter = filter_create(filter_str);
+	result = false;
+	filter_match(filter, props, &result);
+	CHECK(result);
+
+	//test GREATEREQUAL equals
+	filter_destroy(filter);
+	free(filter_str);
+	filter_str = my_strdup("(test_attr2>=attr2)");
+	filter = filter_create(filter_str);
+	result = false;
+	filter_match(filter, props, &result);
+	CHECK(result);
+
+	//test GREATEREQUAL false
+	filter_destroy(filter);
+	free(filter_str);
+	filter_str = my_strdup("(test_attr1>=attr5)");
+	filter = filter_create(filter_str);
+	result = true;
+	filter_match(filter, props, &result);
+	CHECK_FALSE(result);
+
+	//test LESS less
+	filter_destroy(filter);
+	free(filter_str);
+	filter_str = my_strdup("(test_attr1<attr5)");
+	filter = filter_create(filter_str);
+	result = false;
+	filter_match(filter, props, &result);
+	CHECK(result);
+
+	//test LESS equals
+	filter_destroy(filter);
+	free(filter_str);
+	filter_str = my_strdup("(test_attr2<attr2)");
+	filter = filter_create(filter_str);
+	result = true;
+	filter_match(filter, props, &result);
+	CHECK_FALSE(result);
+
+	//test LESS false
+	filter_destroy(filter);
+	free(filter_str);
+	filter_str = my_strdup("(test_attr2<attr1)");
+	filter = filter_create(filter_str);
+	result = true;
+	filter_match(filter, props, &result);
+	CHECK_FALSE(result);
 
-TEST(filter, create1) {
-    char filterStr[] = "(key<value)";
-    filter_pt filter = filter_create(filterStr);
+	//test GREATER greater
+	filter_destroy(filter);
+	free(filter_str);
+	filter_str = my_strdup("(test_attr2>attr1)");
+	filter = filter_create(filter_str);
+	result = false;
+	filter_match(filter, props, &result);
+	CHECK(result);
 
-    STRCMP_EQUAL(filterStr, filter->filterStr);
+	//test GREATER equals
+	filter_destroy(filter);
+	free(filter_str);
+	filter_str = my_strdup("(test_attr2>attr2)");
+	filter = filter_create(filter_str);
+	result = true;
+	filter_match(filter, props, &result);
+	CHECK_FALSE(result);
+
+	//test GREATER false
+	filter_destroy(filter);
+	free(filter_str);
+	filter_str = my_strdup("(test_attr1>attr5)");
+	filter = filter_create(filter_str);
+	result = true;
+	filter_match(filter, props, &result);
+	CHECK_FALSE(result);
+
+	//test SUBSTRING equals
+	filter_destroy(filter);
+	free(filter_str);
+	filter_str = my_strdup("(test_attr1=attr*)");
+	filter = filter_create(filter_str);
+	result = true;
+	filter_match(filter, props, &result);
+	CHECK(result);
+
+	//test SUBSTRING false
+	filter_destroy(filter);
+	free(filter_str);
+	filter_str = my_strdup("(test_attr1=attr*charsNotPresent)");
+	filter = filter_create(filter_str);
+	result = true;
+	filter_match(filter, props, &result);
+	CHECK_FALSE(result);
+
+	//cleanup
+	properties_destroy(props);
+	filter_destroy(filter);
+	free(filter_str);
+	free(key);
+	free(key2);
+	free(val);
+	free(val2);
+
+	mock().checkExpectations();
 }
 
-TEST(filter, create2) {
-    char filterStr[] = "(key>value)";
-    filter_pt filter = filter_create(filterStr);
+TEST(filter, match_recursion){
 
-    STRCMP_EQUAL(filterStr, filter->filterStr);
+	char * filter_str = my_strdup("(&(test_attr1=attr1)(|(&(test_attr2=attr2)(!(&(test_attr1=attr1)(test_attr3=attr3))))(test_attr3=attr3)))");
+	filter_pt filter = filter_create(filter_str);
+	properties_pt props = properties_create();
+	char * key = my_strdup("test_attr1");
+	char * val = my_strdup("attr1");
+	char * key2 = my_strdup("test_attr2");
+	char * val2 = my_strdup("attr2");
+	properties_set(props, key, val);
+	properties_set(props, key2, val2);
+
+	bool result = false;
+	filter_match(filter, props, &result);
+	CHECK(result);
+
+	//cleanup
+	properties_destroy(props);
+	filter_destroy(filter);
+	free(filter_str);
+	free(key);
+	free(key2);
+	free(val);
+	free(val2);
+
+	mock().checkExpectations();
 }
 
-TEST(filter, create3) {
-    char filterStr[] = "(key<=value)";
-    filter_pt filter = filter_create(filterStr);
+TEST(filter, match_false){
+	char * filter_str = my_strdup("(&(test_attr1=attr1)(&(test_attr2=attr2)(test_attr3=attr3)))");
+	filter_pt filter = filter_create(filter_str);
+	properties_pt props = properties_create();
+	char * key = my_strdup("test_attr1");
+	char * val = my_strdup("attr1");
+	char * key2 = my_strdup("test_attr2");
+	char * val2 = my_strdup("attr2");
+	properties_set(props, key, val);
+	properties_set(props, key2, val2);
+
+	bool result = true;
+	filter_match(filter, props, &result);
+	CHECK_FALSE(result);
 
-    STRCMP_EQUAL(filterStr, filter->filterStr);
+	//cleanup
+	properties_destroy(props);
+	filter_destroy(filter);
+	free(filter_str);
+	free(key);
+	free(key2);
+	free(val);
+	free(val2);
+
+	mock().checkExpectations();
+}
+
+TEST(filter, match_filter){
+	char * filter_str = my_strdup("(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3=attr3)))");
+	char * compareTo_str = my_strdup("(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3=attr3)))");
+	filter_pt filter = filter_create(filter_str);
+	filter_pt compareTo = filter_create(compareTo_str);
+
+	bool result;
+	filter_match_filter(filter, compareTo, &result);
+
+	//cleanup
+	filter_destroy(filter);
+	filter_destroy(compareTo);
+	free(filter_str);
+	free(compareTo_str);
+
+	mock().checkExpectations();
 }
 
-TEST(filter, create4) {
-    char filterStr[] = "(key>=value)";
-    filter_pt filter = filter_create(filterStr);
+TEST(filter, getString){
+	char * filter_str = my_strdup("(&(test_attr1=attr1)(|(test_attr2=attr2)(test_attr3=attr3)))");
+	filter_pt filter = filter_create(filter_str);
+
+	char * get_str;
+	filter_getString(filter, &get_str);
+
+	//cleanup
+	filter_destroy(filter);
+	free(filter_str);
 
-    STRCMP_EQUAL(filterStr, filter->filterStr);
+	mock().checkExpectations();
 }