You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by bp...@apache.org on 2015/11/24 17:30:34 UTC

celix git commit: CELIX-304: Memory leaks in manifest parser, requirement, capability; out-of-date tests

Repository: celix
Updated Branches:
  refs/heads/develop d61c2076d -> 53c3d9c1a


CELIX-304:  Memory leaks in manifest parser, requirement, capability; out-of-date tests


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

Branch: refs/heads/develop
Commit: 53c3d9c1a1f8234c50c33c713bc80591dfa21920
Parents: d61c207
Author: Bjoern Petri <bp...@apache.org>
Authored: Tue Nov 24 17:28:31 2015 +0100
Committer: Bjoern Petri <bp...@apache.org>
Committed: Tue Nov 24 17:28:31 2015 +0100

----------------------------------------------------------------------
 framework/CMakeLists.txt                        |   8 +-
 .../resources-test/manifest_sections.txt        |  11 +-
 framework/private/src/capability.c              |  25 ++-
 framework/private/src/manifest.c                |  26 ++--
 framework/private/src/manifest_parser.c         |  23 +--
 framework/private/src/requirement.c             |  18 +--
 framework/private/test/capability_test.cpp      |  62 +++++---
 framework/private/test/manifest_parser_test.cpp | 153 +++++++++----------
 framework/private/test/manifest_test.cpp        |  51 +++++--
 framework/private/test/properties_test.cpp      |  18 +++
 framework/private/test/requirement_test.cpp     |  41 ++++-
 framework/private/test/utils_test.cpp           |  25 +++
 12 files changed, 294 insertions(+), 167 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/53c3d9c1/framework/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt
index ff26121..610854e 100644
--- a/framework/CMakeLists.txt
+++ b/framework/CMakeLists.txt
@@ -204,10 +204,10 @@ if (FRAMEWORK)
     
         add_executable(manifest_parser_test 
             private/test/manifest_parser_test.cpp
-            private/mock/attribute_mock.c
             private/mock/manifest_mock.c
             private/mock/version_mock.c
             private/mock/version_range_mock.c
+            private/src/attribute.c
             private/src/capability.c
             private/src/requirement.c
             private/src/utils.c
@@ -379,9 +379,9 @@ if (FRAMEWORK)
         add_test(NAME utils_test COMMAND utils_test)
         add_test(NAME version_range_test COMMAND version_range_test)
         add_test(NAME version_test COMMAND version_test)
-	     add_test(NAME wire_test COMMAND wire_test)
+	    add_test(NAME wire_test COMMAND wire_test)
 	    
-	     SETUP_TARGET_FOR_COVERAGE(attribute_test attribute_test ${CMAKE_BINARY_DIR}/coverage/attribute_test/attribute_test)
+	    SETUP_TARGET_FOR_COVERAGE(attribute_test attribute_test ${CMAKE_BINARY_DIR}/coverage/attribute_test/attribute_test)
         SETUP_TARGET_FOR_COVERAGE(bundle_archive_test bundle_archive_test ${CMAKE_BINARY_DIR}/coverage/bundle_archive_test/bundle_archive_test)
         SETUP_TARGET_FOR_COVERAGE(bundle_cache_test bundle_cache_test ${CMAKE_BINARY_DIR}/coverage/bundle_cache_test/bundle_cache_test)
         SETUP_TARGET_FOR_COVERAGE(bundle_context_test bundle_context_test ${CMAKE_BINARY_DIR}/coverage/bundle_context_test/bundle_context_test)
@@ -405,7 +405,7 @@ if (FRAMEWORK)
         SETUP_TARGET_FOR_COVERAGE(utils_test utils_test ${CMAKE_BINARY_DIR}/coverage/utils_test/utils_test)
         SETUP_TARGET_FOR_COVERAGE(version_range_test version_range_test ${CMAKE_BINARY_DIR}/coverage/version_range_test/version_range_test)
         SETUP_TARGET_FOR_COVERAGE(version_test version_test ${CMAKE_BINARY_DIR}/coverage/version_test/version_test)
-		  SETUP_TARGET_FOR_COVERAGE(wire_test wire_test ${CMAKE_BINARY_DIR}/coverage/wire_test/wire_test)
+		SETUP_TARGET_FOR_COVERAGE(wire_test wire_test ${CMAKE_BINARY_DIR}/coverage/wire_test/wire_test)
 		
 	endif (ENABLE_TESTING AND FRAMEWORK_TESTS)
 endif (FRAMEWORK)

http://git-wip-us.apache.org/repos/asf/celix/blob/53c3d9c1/framework/private/resources-test/manifest_sections.txt
----------------------------------------------------------------------
diff --git a/framework/private/resources-test/manifest_sections.txt b/framework/private/resources-test/manifest_sections.txt
index 2ae2e23..2777e9b 100644
--- a/framework/private/resources-test/manifest_sections.txt
+++ b/framework/private/resources-test/manifest_sections.txt
@@ -4,9 +4,14 @@ library: client
 Import-Service: server
 
 Name: a
-a: 1
+ 
+aa: 1
+ab: 2
 
 Name: b
-b: 1
+ba: 3
+bb: 4
+
+Name: two words
+white space: 5
 
-this_line_is_longer_than_allowed_randomdatafromhereonoutfnkjdsnfaluebfiaubeiufsjdnaiucbeawncuebfihrandomdatafromhereonoutfnkjdsnfaluebfiaubeiufsjdnaiucbeawncuebfihrandomdatafromhereonoutfnkjdsnfaluebfiaubeiufsjdnaiucbeawncuebfihrandomdatafromhereonoutfnkjdsnfaluebfiaubeiufsjdnaiucbeawncuebfihrandomdatafromhereonoutfnkjdsnfaluebfiaubeiufsjdnaiucbeawncuebfihrandomdatafromhereonoutfnkjdsnfaluebfiaubeiufsjdnaiucbeawncuebfihrandomdatafromhereonoutfnkjdsnfaluebfiaubeiufsjdnaiucbeawncuebfihrandomdatafromhereonoutfnkjdsnfaluebfiaubeiufsjdnaiucbeawncuebfihrandomdatafromhereonoutfnkjdsnfaluebfiaubeiufs

http://git-wip-us.apache.org/repos/asf/celix/blob/53c3d9c1/framework/private/src/capability.c
----------------------------------------------------------------------
diff --git a/framework/private/src/capability.c b/framework/private/src/capability.c
index 26511ee..5ca66ea 100644
--- a/framework/private/src/capability.c
+++ b/framework/private/src/capability.c
@@ -38,23 +38,22 @@ celix_status_t capability_create(module_pt module, hash_map_pt directives, hash_
 		(*capability)->module = module;
 		(*capability)->attributes = attributes;
 		(*capability)->directives = directives;
-
 		(*capability)->version = NULL;
-		status = version_createEmptyVersion(&(*capability)->version);
+
+		attribute_pt versionAttribute = NULL;
+		attribute_pt serviceAttribute = (attribute_pt) hashMap_get(attributes, "service");
+		status = attribute_getValue(serviceAttribute, &(*capability)->serviceName);
 		if (status == CELIX_SUCCESS) {
-			attribute_pt versionAttribute = NULL;
-			attribute_pt serviceAttribute = (attribute_pt) hashMap_get(attributes, "service");
-			status = attribute_getValue(serviceAttribute, &(*capability)->serviceName);
-			if (status == CELIX_SUCCESS) {
-				versionAttribute = (attribute_pt) hashMap_get(attributes, "version");
-				if (versionAttribute != NULL) {
-					char *versionStr = NULL;
-					attribute_getValue(versionAttribute, &versionStr);
-					(*capability)->version = NULL;
-					status = version_createVersionFromString(versionStr, &(*capability)->version);
-				}
+			versionAttribute = (attribute_pt) hashMap_get(attributes, "version");
+			if (versionAttribute != NULL) {
+				char *versionStr = NULL;
+				attribute_getValue(versionAttribute, &versionStr);
+				status = version_createVersionFromString(versionStr, &(*capability)->version);
+			} else {
+				status = version_createEmptyVersion(&(*capability)->version);
 			}
 		}
+
 	}
 
 	framework_logIfError(logger, status, NULL, "Failed to create capability");

http://git-wip-us.apache.org/repos/asf/celix/blob/53c3d9c1/framework/private/src/manifest.c
----------------------------------------------------------------------
diff --git a/framework/private/src/manifest.c b/framework/private/src/manifest.c
index c98f39e..f38f60c 100644
--- a/framework/private/src/manifest.c
+++ b/framework/private/src/manifest.c
@@ -64,9 +64,10 @@ celix_status_t manifest_destroy(manifest_pt manifest) {
 }
 
 celix_status_t manifest_createFromFile(char *filename, manifest_pt *manifest) {
-	celix_status_t status = CELIX_SUCCESS;
+	celix_status_t status;
 
 	status = manifest_create(manifest);
+
 	if (status == CELIX_SUCCESS) {
 		manifest_read(*manifest, filename);
 	}
@@ -95,7 +96,6 @@ celix_status_t manifest_read(manifest_pt manifest, char *filename) {
 	FILE *file = fopen ( filename, "r" );
 	if (file != NULL) {
 		char lbuf[512];
-		int len;
 		char name[512];
 		bool skipEmptyLines = true;
 		char lastline[512];
@@ -103,13 +103,14 @@ celix_status_t manifest_read(manifest_pt manifest, char *filename) {
 
 		manifest_readAttributes(manifest, manifest->mainAttributes, file);
 		
-		while (fgets(lbuf, sizeof(lbuf), file) != NULL ) {
+		while (status==CELIX_SUCCESS && fgets(lbuf, sizeof(lbuf), file) != NULL) {
 			properties_pt attributes;
+			int len = strlen(lbuf);
 
-			len = strlen(lbuf);
 			if (lbuf[--len] != '\n') {
+				status = CELIX_FILE_IO_EXCEPTION;
 				framework_logIfError(logger, status, NULL, "Manifest '%s' line too long", filename);
-				return CELIX_FILE_IO_EXCEPTION;
+				return status;
 			}
 			if (len > 0 && lbuf[len - 1] == '\r') {
 				--len;
@@ -128,8 +129,9 @@ celix_status_t manifest_read(manifest_pt manifest, char *filename) {
 					strncpy(name, lbuf+6, len - 6);
 					name[len - 6] = '\0';
 				} else {
-					printf("MANIFEST: Invalid manifest format\n");
-					return CELIX_FILE_IO_EXCEPTION;
+					status = CELIX_FILE_IO_EXCEPTION;
+					framework_logIfError(logger, status, NULL, "Manifest '%s' invalid format", filename);
+					return status;
 				}
 
 				if (fpeek(file) == ' ') {
@@ -200,12 +202,11 @@ celix_status_t manifest_readAttributes(manifest_pt manifest, properties_pt prope
 	char lastLine[512];
 	char lbuf[512];
 
-	int len;
-	while (fgets(lbuf, sizeof(lbuf), file ) != NULL ) {
 
+	while (fgets(lbuf, sizeof(lbuf), file ) != NULL ) {
 		bool lineContinued = false;
-		int i = 0;
-		len = strlen(lbuf);
+		int len = strlen(lbuf);
+
 		if (lbuf[--len] != '\n') {
 			printf("MANIFEST: Line too long\n");
 			return CELIX_FILE_IO_EXCEPTION;
@@ -240,7 +241,8 @@ celix_status_t manifest_readAttributes(manifest_pt manifest, properties_pt prope
 			value[0] = '\0';
 			strcpy(value, buf);
 		} else {
-			while (lbuf[i++] != ':') {
+	        int i = 0;
+			while (lbuf[++i] != ':') {
 				if (i >= len) {
 					printf("MANIFEST: Invalid header\n");
 					return CELIX_FILE_IO_EXCEPTION;

http://git-wip-us.apache.org/repos/asf/celix/blob/53c3d9c1/framework/private/src/manifest_parser.c
----------------------------------------------------------------------
diff --git a/framework/private/src/manifest_parser.c b/framework/private/src/manifest_parser.c
index 9ffd767..1af4665 100644
--- a/framework/private/src/manifest_parser.c
+++ b/framework/private/src/manifest_parser.c
@@ -174,7 +174,6 @@ static linked_list_pt manifestParser_parseStandardHeaderClause(char * clauseStri
     linked_list_pt pieces;
 
     clause = NULL;
-    pieces = NULL;
     pieces = manifestParser_parseDelimitedString(clauseString, ";");
 
     if (linkedList_create(&paths) == CELIX_SUCCESS) {
@@ -182,7 +181,6 @@ static linked_list_pt manifestParser_parseStandardHeaderClause(char * clauseStri
         int pieceIdx;
         hash_map_pt dirsMap = NULL;
         hash_map_pt attrsMap = NULL;
-        char * sepPtr;
         char * sep;
 
         for (pieceIdx = 0; pieceIdx < linkedList_size(pieces); pieceIdx++) {
@@ -193,7 +191,6 @@ static linked_list_pt manifestParser_parseStandardHeaderClause(char * clauseStri
                 linkedList_addElement(paths, strdup(piece));
                 pathCount++;
             }
-            free(piece);
         }
 
         if (pathCount == 0) {
@@ -205,6 +202,7 @@ static linked_list_pt manifestParser_parseStandardHeaderClause(char * clauseStri
 
 
         for (pieceIdx = pathCount; pieceIdx < linkedList_size(pieces); pieceIdx++) {
+            char * sepPtr;
             char * key;
             char * value;
             char * DIRECTIVE_SEP = ":=";
@@ -224,10 +222,12 @@ static linked_list_pt manifestParser_parseStandardHeaderClause(char * clauseStri
             if (value[0] == '"' && value[strlen(value) -1] == '"') {
                 char * oldV = strdup(value);
                 int len = strlen(oldV) - 2;
-                value = (char *) malloc(sizeof(char) * len+1);
+                value = (char *) realloc(value, (sizeof(char) * len+1));
                 value[0] = '\0';
                 value = strncpy(value, oldV+1, strlen(oldV) - 2);
                 value[len] = '\0';
+                //check if correct
+                free(oldV);
             }
 
             if (strcmp(sep, DIRECTIVE_SEP) == 0) {
@@ -251,14 +251,18 @@ static linked_list_pt manifestParser_parseStandardHeaderClause(char * clauseStri
         }
     }
 
+    for(int listIdx = 0; listIdx < linkedList_size(pieces); listIdx++){
+    	void * element = linkedList_get(pieces, listIdx);
+    	free(element);
+    }
+
     linkedList_destroy(pieces);
 
+
 	return clause;
 }
 
 static linked_list_pt manifestParser_parseStandardHeader(char * header) {
-    int i;
-    char *clauseString;
     linked_list_pt clauseStrings = NULL;
     linked_list_pt completeList = NULL;
 
@@ -272,8 +276,9 @@ static linked_list_pt manifestParser_parseStandardHeader(char * header) {
             clauseStrings = manifestParser_parseDelimitedString(hdr, ",");
             free(hdr);
             if (clauseStrings != NULL) {
+                int i;
                 for (i = 0; i < linkedList_size(clauseStrings); i++) {
-                    clauseString = (char *) linkedList_get(clauseStrings, i);
+                    char *clauseString = (char *) linkedList_get(clauseStrings, i);
                     linkedList_addElement(completeList, manifestParser_parseStandardHeaderClause(clauseString));
                     free(clauseString);
                 }
@@ -398,7 +403,7 @@ celix_status_t manifestParser_getBundleVersion(manifest_parser_pt parser, versio
 }
 
 celix_status_t manifestParser_getCapabilities(manifest_parser_pt parser, linked_list_pt *capabilities) {
-	celix_status_t status = CELIX_SUCCESS;
+	celix_status_t status;
 
 	status = linkedList_clone(parser->capabilities, capabilities);
 
@@ -406,7 +411,7 @@ celix_status_t manifestParser_getCapabilities(manifest_parser_pt parser, linked_
 }
 
 celix_status_t manifestParser_getRequirements(manifest_parser_pt parser, linked_list_pt *requirements) {
-	celix_status_t status = CELIX_SUCCESS;
+	celix_status_t status;
 
 	status = linkedList_clone(parser->requirements, requirements);
 

http://git-wip-us.apache.org/repos/asf/celix/blob/53c3d9c1/framework/private/src/requirement.c
----------------------------------------------------------------------
diff --git a/framework/private/src/requirement.c b/framework/private/src/requirement.c
index 7266484..375ede2 100644
--- a/framework/private/src/requirement.c
+++ b/framework/private/src/requirement.c
@@ -42,20 +42,18 @@ celix_status_t requirement_create(hash_map_pt directives, hash_map_pt attributes
 
 		(*requirement)->attributes = attributes;
 		(*requirement)->directives = directives;
+		(*requirement)->versionRange = NULL;
 
 		serviceAttribute = (attribute_pt) hashMap_get(attributes, "service");
 		status = attribute_getValue(serviceAttribute, &(*requirement)->targetName);
 		if (status == CELIX_SUCCESS) {
-			(*requirement)->versionRange = NULL;
-			status = versionRange_createInfiniteVersionRange(&(*requirement)->versionRange);
-			if (status == CELIX_SUCCESS) {
-				versionAttribute = (attribute_pt) hashMap_get(attributes, "version");
-				if (versionAttribute != NULL) {
-					char *versionStr = NULL;
-					attribute_getValue(versionAttribute, &versionStr);
-					(*requirement)->versionRange = NULL;
-					status = versionRange_parse(versionStr, &(*requirement)->versionRange);
-				}
+			versionAttribute = (attribute_pt) hashMap_get(attributes, "version");
+			if (versionAttribute != NULL) {
+				char *versionStr = NULL;
+				attribute_getValue(versionAttribute, &versionStr);
+				status = versionRange_parse(versionStr, &(*requirement)->versionRange);
+			} else {
+				status = versionRange_createInfiniteVersionRange(&(*requirement)->versionRange);
 			}
 		}
 	}

http://git-wip-us.apache.org/repos/asf/celix/blob/53c3d9c1/framework/private/test/capability_test.cpp
----------------------------------------------------------------------
diff --git a/framework/private/test/capability_test.cpp b/framework/private/test/capability_test.cpp
index 4fd8435..b3bd61f 100644
--- a/framework/private/test/capability_test.cpp
+++ b/framework/private/test/capability_test.cpp
@@ -55,48 +55,72 @@ TEST_GROUP(capability) {
 };
 
 TEST(capability, create) {
+	capability_pt capability;
 	module_pt module = (module_pt) 0x10;
-	hash_map_pt directives =  hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-	hash_map_pt attributes = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+	hash_map_pt directives;
+	hash_map_pt attributes;
 
 	attribute_pt serviceAttribute = (attribute_pt) 0x01;
-    hashMap_put(attributes, (void*) "service", serviceAttribute);
     attribute_pt versionAttribute = (attribute_pt) 0x02;
-    hashMap_put(attributes, (void*) "version", versionAttribute);
 
 	version_pt emptyVersion = (version_pt) 0x10;
-
-	mock().expectOneCall("version_createEmptyVersion")
-        .withOutputParameterReturning("version", &emptyVersion, sizeof(emptyVersion))
-        .andReturnValue(CELIX_SUCCESS);
+	version_pt fromstrVersion = (version_pt) 0x11;
 
 	char *value1 = (char *) "target";
+	char *value2 = (char *) "1.0.0";
+
+	//create with empty version
+	directives =  hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+	attributes = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+    hashMap_put(attributes, (void*) "service", serviceAttribute);
+
+
 	mock().expectOneCall("attribute_getValue")
         .withParameter("attribute", serviceAttribute)
         .withOutputParameterReturning("value", &value1, sizeof(value1))
         .andReturnValue(CELIX_SUCCESS);
-
-	char *value2 = (char *) "1.0.0";
-	mock().expectOneCall("attribute_getValue")
-        .withParameter("attribute", versionAttribute)
-        .withOutputParameterReturning("value", &value2, sizeof(value2))
+	mock().expectOneCall("version_createEmptyVersion")
+        .withOutputParameterReturning("version", &emptyVersion, sizeof(emptyVersion))
         .andReturnValue(CELIX_SUCCESS);
 
+	capability = NULL;
+	capability_create(module, directives, attributes, &capability);
+
+	mock().expectOneCall("attribute_destroy")
+			.withParameter("attribute", serviceAttribute);
+	mock().expectOneCall("version_destroy")
+			.withParameter("version", emptyVersion);
+
+	capability_destroy(capability);
+
+	//create with version from version string
+	directives =  hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+	attributes = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+    hashMap_put(attributes, (void*) "service", serviceAttribute);
+    hashMap_put(attributes, (void*) "version", versionAttribute);
+
+	mock().expectOneCall("attribute_getValue")
+			.withParameter("attribute", serviceAttribute)
+        	.withOutputParameterReturning("value", &value1, sizeof(value1))
+        	.andReturnValue(CELIX_SUCCESS);
+	mock().expectOneCall("attribute_getValue")
+    		.withParameter("attribute", versionAttribute)
+    		.withOutputParameterReturning("value", &value2, sizeof(value2))
+    		.andReturnValue(CELIX_SUCCESS);
 	mock().expectOneCall("version_createVersionFromString")
-        .withParameter("versionStr", (char *) "1.0.0")
-        .withOutputParameterReturning("version", &emptyVersion, sizeof(emptyVersion))
-        .andReturnValue(CELIX_SUCCESS);
+			.withParameter("versionStr", (char *) "1.0.0")
+			.withOutputParameterReturning("version", &fromstrVersion, sizeof(fromstrVersion))
+			.andReturnValue(CELIX_SUCCESS);
 
-	capability_pt capability = NULL;
+	capability = NULL;
 	capability_create(module, directives, attributes, &capability);
 
 	mock().expectOneCall("attribute_destroy")
 			.withParameter("attribute", serviceAttribute);
 	mock().expectOneCall("attribute_destroy")
 			.withParameter("attribute", versionAttribute);
-
 	mock().expectOneCall("version_destroy")
-			.withParameter("version", emptyVersion);
+			.withParameter("version", fromstrVersion);
 
 	capability_destroy(capability);
 }

http://git-wip-us.apache.org/repos/asf/celix/blob/53c3d9c1/framework/private/test/manifest_parser_test.cpp
----------------------------------------------------------------------
diff --git a/framework/private/test/manifest_parser_test.cpp b/framework/private/test/manifest_parser_test.cpp
index b395469..598b95a 100644
--- a/framework/private/test/manifest_parser_test.cpp
+++ b/framework/private/test/manifest_parser_test.cpp
@@ -33,6 +33,8 @@
 #include "CppUTestExt/MockSupport.h"
 
 extern "C" {
+#include "capability_private.h"
+#include "requirement_private.h"
 #include "constants.h"
 #include "manifest_parser.h"
 #include "attribute.h"
@@ -67,6 +69,8 @@ TEST_GROUP(manifest_parser) {
 	}
 
 	void teardown() {
+		mock().checkExpectations();
+		mock().clear();
 	}
 };
 
@@ -95,101 +99,55 @@ TEST(manifest_parser, create){
 			.andReturnValue(bundle_name);
 
 	//create capabilities
-	char * export_header = my_strdup("export_service_name;version=\"[4.5,6)\",export_service_name2;version=\"[6.5,4)\"");
+	char * export_header = my_strdup("export_service_name;version=\"4.5.6\",export_service_name2;version=\"6.5.4\"");
 	char * cap_name	= my_strdup("export_service_name");
-	char * cap_name2	= my_strdup("export_service_name2");
-	capability_pt cap = (capability_pt) 0x04;
-	capability_pt cap2 = (capability_pt) 0x05;
-	attribute_pt attribute_cap_name = (attribute_pt) 0x06;
-	attribute_pt attribute_cap_version = (attribute_pt) 0x07;
-	attribute_pt attribute_cap_name2 = (attribute_pt) 0x08;
-	attribute_pt attribute_cap_version2 = (attribute_pt) 0x09;
+	char * cap_name2 = my_strdup("export_service_name2");
+	char * cap_version_str = my_strdup("4.5.6");
+	char * cap_version_str2 = my_strdup("6.5.4");
+	version_pt cap_version = (version_pt) 0x0A;
+	version_pt cap_version2 = (version_pt) 0x0B;
 
 	mock().expectOneCall("manifest_getValue")
 			.withParameter("name", OSGI_FRAMEWORK_EXPORT_LIBRARY)
 			.andReturnValue(export_header);
 
-	//make cap 1
-	mock().expectOneCall("attribute_create")
-			.withParameter("key", service_name_key)
-			.withParameter("value", cap_name)
-			.withOutputParameterReturning("attribute", &attribute_cap_name, sizeof(attribute_cap_name));
-
-	mock().expectOneCall("attribute_create")
-			.withParameter("key", service_version_key)
-			.withParameter("value", "[4.5,6)")
-			.withOutputParameterReturning("attribute", &attribute_cap_version, sizeof(attribute_cap_version));
-
-	mock().expectOneCall("attribute_getKey")
-			.withParameter("attribute", attribute_cap_name)
-			.withOutputParameterReturning("key", &service_name_key, sizeof(service_name_key));
-
-	//make cap2
-	mock().expectOneCall("attribute_create")
-			.withParameter("key", service_name_key)
-			.withParameter("value", cap_name2)
-			.withOutputParameterReturning("attribute", &attribute_cap_name2, sizeof(attribute_cap_name2));
-
-	mock().expectOneCall("attribute_create")
-			.withParameter("key", service_version_key)
-			.withParameter("value", "[6.5,4)")
-			.withOutputParameterReturning("attribute", &attribute_cap_version2, sizeof(attribute_cap_version2));
+	mock().expectOneCall("version_createVersionFromString")
+					.withParameter("versionStr", cap_version_str)
+					.withOutputParameterReturning("version", &cap_version, sizeof(cap_version));
 
-	mock().expectOneCall("attribute_getKey")
-			.withParameter("attribute", attribute_cap_name2)
-			.withOutputParameterReturning("key", &service_name_key, sizeof(service_name_key));
+	mock().expectOneCall("version_createVersionFromString")
+				.withParameter("versionStr", cap_version_str2)
+				.withOutputParameterReturning("version", &cap_version2, sizeof(cap_version2));
 
 	//create requirements
 	char * import_header = my_strdup("import_service_name;version=\"[7.8,9)\",import_service_name2;version=\"[9.8,7)\"");
 	char * req_name	= my_strdup("import_service_name");
 	char * req_name2 = my_strdup("import_service_name2");
-	requirement_pt req = (requirement_pt) 0x0A;
-	requirement_pt req2 = (requirement_pt) 0x0B;
-	attribute_pt attribute_req_name = (attribute_pt) 0x0C;
-	attribute_pt attribute_req_name2 = (attribute_pt) 0x0D;
-	attribute_pt attribute_req_version = (attribute_pt) 0x0E;
-	attribute_pt attribute_req_version2 = (attribute_pt) 0x0F;
+	char * req_version_str = my_strdup("[7.8,9)");
+	char * req_version_str2 = my_strdup("[9.8,7)");
+	version_range_pt req_version_range = (version_range_pt) 0x12;
+	version_range_pt req_version_range2 = (version_range_pt) 0x13;
 
 	mock().expectOneCall("manifest_getValue")
 			.withParameter("name", OSGI_FRAMEWORK_IMPORT_LIBRARY)
 			.andReturnValue(import_header);
 
-	//make req 1
-	mock().expectOneCall("attribute_create")
-			.withParameter("key", service_name_key)
-			.withParameter("value", req_name)
-			.withOutputParameterReturning("attribute", &attribute_req_name, sizeof(attribute_req_name));
-
-	mock().expectOneCall("attribute_create")
-			.withParameter("key", service_version_key)
-			.withParameter("value", "[7.8,9)")
-			.withOutputParameterReturning("attribute", &attribute_req_version, sizeof(attribute_req_version));
-
-	mock().expectOneCall("attribute_getKey")
-			.withParameter("attribute", attribute_req_name)
-			.withOutputParameterReturning("key", &service_name_key, sizeof(service_name_key));
-
-	//make req 2
-	mock().expectOneCall("attribute_create")
-			.withParameter("key", service_name_key)
-			.withParameter("value", req_name2)
-			.withOutputParameterReturning("attribute", &attribute_req_name2, sizeof(attribute_req_name2));
-
-	mock().expectOneCall("attribute_create")
-			.withParameter("key", service_version_key)
-			.withParameter("value", "[9.8,7)")
-			.withOutputParameterReturning("attribute", &attribute_req_version2, sizeof(attribute_req_version2));
+	mock().expectOneCall("versionRange_parse")
+			.withParameter("rangeStr", req_version_str)
+			.withOutputParameterReturning("range", &req_version_range, sizeof(req_version_range));
 
-	mock().expectOneCall("attribute_getKey")
-			.withParameter("attribute", attribute_req_name2)
-			.withOutputParameterReturning("key", &service_name_key, sizeof(service_name_key));
+	mock().expectOneCall("versionRange_parse")
+			.withParameter("rangeStr", req_version_str2)
+			.withOutputParameterReturning("range", &req_version_range2, sizeof(req_version_range2));
 
 
 	//actual call to create
 	manifestParser_create(owner, manifest, &parser);
 
 	//test getters
-	version_pt version_clone = (version_pt) 0x06;
+	capability_pt get_cap;
+	requirement_pt get_req;
+	version_pt version_clone = (version_pt) 0x14;
 	version_pt get_version;
 	linked_list_pt get_caps;
 	linked_list_pt get_reqs;
@@ -206,15 +164,40 @@ TEST(manifest_parser, create){
 
 	status = manifestParser_getCapabilities(parser, &get_caps);
 	LONGS_EQUAL(CELIX_SUCCESS, status);
-	CHECK(linkedList_contains(get_caps, cap));
-	CHECK(linkedList_contains(get_caps, cap2));
 	LONGS_EQUAL(2, linkedList_size(get_caps));
+	//check for both capabilities, in no specific order
+	get_cap = (capability_pt)linkedList_get(get_caps, 0);
+	if (strcmp(get_cap->serviceName, cap_name) == 0){
+		POINTERS_EQUAL(cap_version, get_cap->version);
+		get_cap = (capability_pt)linkedList_get(get_caps, 1);
+		STRCMP_EQUAL(cap_name2, get_cap->serviceName);
+		POINTERS_EQUAL(cap_version2, get_cap->version);
+	} else {
+		STRCMP_EQUAL(cap_name2, get_cap->serviceName);
+		POINTERS_EQUAL(cap_version2, get_cap->version);
+		get_cap = (capability_pt)linkedList_get(get_caps, 1);
+		STRCMP_EQUAL(cap_name, get_cap->serviceName);
+		POINTERS_EQUAL(cap_version, get_cap->serviceName);
+	}
 
 	status = manifestParser_getRequirements(parser, &get_reqs);
 	LONGS_EQUAL(CELIX_SUCCESS, status);
-	CHECK(linkedList_contains(get_reqs, req));
-	CHECK(linkedList_contains(get_reqs, req2));
 	LONGS_EQUAL(2, linkedList_size(get_reqs));
+	//check for both requirements, in no specific order
+	get_req = (requirement_pt)linkedList_get(get_reqs, 0);
+	if (strcmp(get_req->targetName, req_name) == 0){
+		POINTERS_EQUAL(req_version_range, get_req->versionRange);
+		get_req = (requirement_pt)linkedList_get(get_reqs, 1);
+		STRCMP_EQUAL(req_name2, get_req->targetName);
+		POINTERS_EQUAL(req_version_range2, get_req->versionRange);
+	} else {
+		STRCMP_EQUAL(req_name2, get_req->targetName);
+		POINTERS_EQUAL(req_version_range2, get_req->versionRange);
+		get_req = (requirement_pt)linkedList_get(get_reqs, 1);
+		STRCMP_EQUAL(req_name, get_req->targetName);
+		POINTERS_EQUAL(req_version_range, get_req->versionRange);
+	}
+
 
 	status = manifestParser_getSymbolicName(parser, &get_bundle_name);
 	LONGS_EQUAL(CELIX_SUCCESS, status);
@@ -227,6 +210,18 @@ TEST(manifest_parser, create){
 
 	manifestParser_destroy(parser);
 
+	mock().expectOneCall("version_destroy")
+			.withParameter("version", cap_version);
+
+	mock().expectOneCall("version_destroy")
+			.withParameter("version", cap_version2);
+
+	mock().expectOneCall("versionRange_destroy")
+			.withParameter("range", req_version_range);
+
+	mock().expectOneCall("versionRange_destroy")
+				.withParameter("range", req_version_range2);
+
 	capability_destroy((capability_pt) linkedList_get(get_caps, 0));
 	capability_destroy((capability_pt) linkedList_get(get_caps, 1));
 
@@ -234,7 +229,6 @@ TEST(manifest_parser, create){
 	requirement_destroy((requirement_pt) linkedList_get(get_reqs, 1));
 
 	linkedList_destroy(get_caps);
-	linkedList_clear(get_reqs);
 	linkedList_destroy(get_reqs);
 
 	free(service_name_key);
@@ -246,14 +240,15 @@ TEST(manifest_parser, create){
 	free(export_header);
 	free(cap_name);
 	free(cap_name2);
+	free(cap_version_str);
+	free(cap_version_str2);
 
 	free(import_header);
 	free(req_name);
 	free(req_name2);
+	free(req_version_str);
+	free(req_version_str2);
 
 	free(get_bundle_name);
-
-	mock().checkExpectations();
-	mock().clear();
 }
 

http://git-wip-us.apache.org/repos/asf/celix/blob/53c3d9c1/framework/private/test/manifest_test.cpp
----------------------------------------------------------------------
diff --git a/framework/private/test/manifest_test.cpp b/framework/private/test/manifest_test.cpp
index ccd068e..7753c76 100644
--- a/framework/private/test/manifest_test.cpp
+++ b/framework/private/test/manifest_test.cpp
@@ -105,9 +105,10 @@ TEST(manifest, createFromFileWithSections) {
     char manifestFile[] = "resources-test/manifest_sections.txt";
     manifest_pt manifest = NULL;
     //properties_pt properties = properties_create();
-    properties_pt properties = (properties_pt) 0x40;
-    properties_pt properties2 = (properties_pt) 0x41;
-    properties_pt properties3 = (properties_pt) 0x42;
+    properties_pt properties = (properties_pt) 0x01;
+    properties_pt properties2 = (properties_pt) 0x02;
+    properties_pt properties3 = (properties_pt) 0x03;
+    properties_pt properties4 = (properties_pt) 0x04;
     void *ov = (void *) 0x00;
 
     mock()
@@ -137,34 +138,56 @@ TEST(manifest, createFromFileWithSections) {
         .withParameter("key", "Import-Service")
         .withParameter("value", "server")
         .andReturnValue(ov);
+
     mock()
         .expectOneCall("properties_create")
         .andReturnValue(properties2);
     mock()
         .expectOneCall("properties_set")
         .withParameter("properties", properties2)
-        .withParameter("key", "a")
+        .withParameter("key", "aa")
         .withParameter("value", "1")
         .andReturnValue(ov);
     mock()
+        .expectOneCall("properties_set")
+        .withParameter("properties", properties2)
+        .withParameter("key", "ab")
+        .withParameter("value", "2")
+        .andReturnValue(ov);
+
+    mock()
         .expectOneCall("properties_create")
         .andReturnValue(properties3);
     mock()
         .expectOneCall("properties_set")
         .withParameter("properties", properties3)
-        .withParameter("key", "b")
-        .withParameter("value", "1")
+        .withParameter("key", "ba")
+        .withParameter("value", "3")
+        .andReturnValue(ov);
+    mock()
+    	.expectOneCall("properties_set")
+    	.withParameter("properties", properties3)
+    	.withParameter("key", "bb")
+    	.withParameter("value", "4")
+    	.andReturnValue(ov);
+
+    mock()
+        .expectOneCall("properties_create")
+        .andReturnValue(properties4);
+    mock()
+        .expectOneCall("properties_set")
+        .withParameter("properties", properties4)
+        .withParameter("key", "white space")
+        .withParameter("value", "5")
         .andReturnValue(ov);
+
+    manifest_createFromFile(manifestFile, &manifest);
+
     mock()
         .expectOneCall("properties_get")
         .withParameter("properties", properties)
         .withParameter("key", "Bundle-SymbolicName")
         .andReturnValue("bsn");
-    mock()
-        .expectOneCall("properties_destroy")
-        .withParameter("properties", properties);
-
-    manifest_createFromFile(manifestFile, &manifest);
 
     properties_pt main = manifest_getMainAttributes(manifest);
     POINTERS_EQUAL(properties, main);
@@ -174,7 +197,7 @@ TEST(manifest, createFromFileWithSections) {
 
     hash_map_pt map = NULL;
     manifest_getEntries(manifest, &map);
-    LONGS_EQUAL(2, hashMap_size(map));
+    LONGS_EQUAL(3, hashMap_size(map));
 
     properties_pt actual = (properties_pt) hashMap_get(map, (void *) "a");
     POINTERS_EQUAL(properties2, actual);
@@ -182,6 +205,10 @@ TEST(manifest, createFromFileWithSections) {
     actual = (properties_pt) hashMap_get(map, (void *) "b");
     POINTERS_EQUAL(properties3, actual);
 
+    mock()
+    	.expectOneCall("properties_destroy")
+        .withParameter("properties", properties);
+
     manifest_destroy(manifest);
 }
 

http://git-wip-us.apache.org/repos/asf/celix/blob/53c3d9c1/framework/private/test/properties_test.cpp
----------------------------------------------------------------------
diff --git a/framework/private/test/properties_test.cpp b/framework/private/test/properties_test.cpp
index 2be5092..eaed3a3 100644
--- a/framework/private/test/properties_test.cpp
+++ b/framework/private/test/properties_test.cpp
@@ -86,6 +86,24 @@ TEST(properties, store) {
 	properties_destroy(properties);
 }
 
+TEST(properties, copy) {
+	properties_pt copy;
+	char propertiesFile[] = "resources-test/properties.txt";
+	properties = properties_load(propertiesFile);
+	LONGS_EQUAL(3, hashMap_size(properties));
+
+	properties_copy(properties, &copy);
+
+	char keyA[] = "a";
+	char *valueA = properties_get(copy, keyA);
+	STRCMP_EQUAL("b", valueA);
+	char keyB[] = "b";
+	STRCMP_EQUAL("c", properties_get(copy, keyB));
+
+	properties_destroy(properties);
+	properties_destroy(copy);
+}
+
 TEST(properties, getSet) {
 	properties = properties_create();
 	char keyA[] = "x";

http://git-wip-us.apache.org/repos/asf/celix/blob/53c3d9c1/framework/private/test/requirement_test.cpp
----------------------------------------------------------------------
diff --git a/framework/private/test/requirement_test.cpp b/framework/private/test/requirement_test.cpp
index 70114c5..ce25dca 100644
--- a/framework/private/test/requirement_test.cpp
+++ b/framework/private/test/requirement_test.cpp
@@ -56,18 +56,24 @@ TEST_GROUP(requirement) {
 };
 
 TEST(requirement, create) {
-	hash_map_pt directives = hashMap_create(NULL, NULL, NULL, NULL);
-	hash_map_pt attributes = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+	requirement_pt requirement = NULL;
+	hash_map_pt directives;
+	hash_map_pt attributes;
 
 	attribute_pt serviceAttribute = (attribute_pt) 0x01;
-	hashMap_put(attributes, (void*) "service", serviceAttribute);
 	attribute_pt versionAttribute = (attribute_pt) 0x02;
-	hashMap_put(attributes, (void*) "version", versionAttribute);
 
 	version_range_pt infiniteRange = (version_range_pt) 0x10;
 	version_range_pt parsedRange = (version_range_pt) 0x11;
 
 	char *value1 = (char *) "target";
+	char *value2 = (char *) "1.0.0";
+
+	//create with infinite version range
+	directives = hashMap_create(NULL, NULL, NULL, NULL);
+	attributes = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+	hashMap_put(attributes, (void*) "service", serviceAttribute);
+
 	mock().expectOneCall("attribute_getValue")
         .withParameter("attribute", serviceAttribute)
         .withOutputParameterReturning("value", &value1, sizeof(value1))
@@ -75,7 +81,29 @@ TEST(requirement, create) {
 	mock().expectOneCall("versionRange_createInfiniteVersionRange")
 	    .withOutputParameterReturning("range", &infiniteRange, sizeof(infiniteRange))
         .andReturnValue(CELIX_SUCCESS);
-	char *value2 = (char *) "1.0.0";
+
+	requirement_create(directives, attributes, &requirement);
+
+	//clean up
+	mock().expectOneCall("attribute_destroy")
+			.withParameter("attribute", serviceAttribute);
+
+	mock().expectOneCall("versionRange_destroy")
+			.withParameter("range",	infiniteRange);
+
+	requirement_destroy(requirement);
+	requirement = NULL;
+
+	//create with version range
+	directives = hashMap_create(NULL, NULL, NULL, NULL);
+	attributes = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+	hashMap_put(attributes, (void*) "service", serviceAttribute);
+	hashMap_put(attributes, (void*) "version", versionAttribute);
+
+	mock().expectOneCall("attribute_getValue")
+        .withParameter("attribute", serviceAttribute)
+        .withOutputParameterReturning("value", &value1, sizeof(value1))
+        .andReturnValue(CELIX_SUCCESS);
 	mock().expectOneCall("attribute_getValue")
         .withParameter("attribute", versionAttribute)
         .withOutputParameterReturning("value", &value2, sizeof(value2))
@@ -85,9 +113,10 @@ TEST(requirement, create) {
         .withOutputParameterReturning("range", &parsedRange, sizeof(parsedRange))
         .andReturnValue(CELIX_SUCCESS);
 
-	requirement_pt requirement = NULL;
+
 	requirement_create(directives, attributes, &requirement);
 
+	//clean up
 	mock().expectOneCall("attribute_destroy")
 			.withParameter("attribute", versionAttribute);
 

http://git-wip-us.apache.org/repos/asf/celix/blob/53c3d9c1/framework/private/test/utils_test.cpp
----------------------------------------------------------------------
diff --git a/framework/private/test/utils_test.cpp b/framework/private/test/utils_test.cpp
index 27d4a22..fb391f2 100644
--- a/framework/private/test/utils_test.cpp
+++ b/framework/private/test/utils_test.cpp
@@ -272,4 +272,29 @@ TEST(utils, isNumeric) {
 	free(toCheck);
 }
 
+TEST(utils, compareServiceIdsAndRanking){
+	int ret;
+	//service 1 is higher ranked and has a irrelevant ID
+	ret = utils_compareServiceIdsAndRanking(2,2,1,1);
+	LONGS_EQUAL(1, ret);
+
+	//service 1 is equally ranked and has a lower ID
+	ret = utils_compareServiceIdsAndRanking(1,1,2,1);
+	LONGS_EQUAL(1, ret);
+
+	//service 1 is equally ranked and has a higher ID
+	ret = utils_compareServiceIdsAndRanking(2,1,1,1);
+	LONGS_EQUAL(-1, ret);
+
+	//service 1 is lower ranked and has a irrelevant ID
+	ret = utils_compareServiceIdsAndRanking(1,1,2,2);
+	LONGS_EQUAL(-1, ret);
+
+	//service 1 is equal in ID and irrelevantly ranked
+	ret = utils_compareServiceIdsAndRanking(1,1,1,1);
+	LONGS_EQUAL(0, ret);
+
+
+}
+