From 3152ecaa9baaf0fd399030b71b649d5b0d742988 Mon Sep 17 00:00:00 2001
From: Phenom <retrosharephenom@gmail.com>
Date: Fri, 15 Jul 2016 15:03:41 +0200
Subject: [PATCH] Fix UnitTests and run it in windows too.

---
 RetroShare.pro                                |   2 +
 libretroshare/src/gxs/rsgxsdata.cc            |  20 +--
 libretroshare/src/gxs/rsgxsdata.h             |  22 ++--
 libretroshare/src/retroshare/rsids.h          |   4 +-
 libretroshare/src/serialiser/rsserial.cc      |   2 +-
 libretroshare/src/serialiser/rstlvkeys.cc     | 124 ++++++++++++++++--
 libretroshare/src/serialiser/rstlvkeys.h      |  18 ++-
 tests/librssimulator/librssimulator.pro       |  18 +--
 .../testing/SetServiceTester.cc               |   1 +
 .../gxs/data_service/rsgxsdata_test.cc        | 103 ++++++++-------
 .../gxs/security/gxssecurity_test.cc          |   4 +
 .../serialiser/rsbaseitem_test.cc             |   6 +-
 .../libretroshare/serialiser/rstlvutil.cc     |   1 +
 .../libretroshare/serialiser/support.cc       |  31 ++---
 .../libretroshare/serialiser/support.h        |   8 +-
 .../libretroshare/serialiser/tlvbase_test2.cc |   2 +
 .../libretroshare/serialiser/tlvstack_test.cc |   4 +-
 .../libretroshare/serialiser/tlvtypes_test.cc |   5 +-
 tests/unittests/unittests.pro                 |  41 +++---
 19 files changed, 261 insertions(+), 155 deletions(-)

diff --git a/RetroShare.pro b/RetroShare.pro
index 5b8bf2555..ce5ca7193 100644
--- a/RetroShare.pro
+++ b/RetroShare.pro
@@ -1,6 +1,7 @@
 !include("retroshare.pri"): error("Could not include file retroshare.pri")
 
 TEMPLATE = subdirs
+CONFIG += tests
 
 SUBDIRS += \
         openpgpsdk \
@@ -46,4 +47,5 @@ tests {
     SUBDIRS += unittests
     unittests.file = tests/unittests/unittests.pro
     unittests.depends = libretroshare librssimulator
+    unittests.target = unittests
 }
diff --git a/libretroshare/src/gxs/rsgxsdata.cc b/libretroshare/src/gxs/rsgxsdata.cc
index 4cf7ac1aa..a078f1d6b 100644
--- a/libretroshare/src/gxs/rsgxsdata.cc
+++ b/libretroshare/src/gxs/rsgxsdata.cc
@@ -39,20 +39,20 @@ uint32_t RsGxsGrpMetaData::serial_size(uint32_t api_version)
 
     s += mGroupId.serial_size();
     s += mOrigGrpId.serial_size();
+    s += mParentGrpId.serial_size();
     s += GetTlvStringSize(mGroupName);
-    s += 4;
-    s += 4;
+    s += 4;          // mGroupFlags
+    s += 4;          // mPublishTs
+    s += 4;          // mCircleType
+    s += 4;          // mAuthenFlag
     s += mAuthorId.serial_size();
     s += GetTlvStringSize(mServiceString);
+    s += mCircleId.serial_size();
     s += signSet.TlvSize();
     s += keys.TlvSize();
-    s += 4;                                  // for mCircleType
-    s += mCircleId.serial_size();
-    s += 4;                                  // mAuthenFlag
-    s += mParentGrpId.serial_size();         // mParentGroupId
     
     if(api_version == RS_GXS_GRP_META_DATA_VERSION_ID_0002)
-	    s += 4;                                  // mSignFlag
+        s += 4;      // mSignFlag
     else if(api_version != RS_GXS_GRP_META_DATA_VERSION_ID_0001)
         std::cerr << "(EE) wrong/unknown API version " << api_version << " requested in RsGxsGrpMetaData::serial_size()" << std::endl;
 
@@ -227,8 +227,8 @@ uint32_t RsGxsMsgMetaData::serial_size()
 
     s += signSet.TlvSize();
     s += GetTlvStringSize(mMsgName);
-    s += 4;					// mPublishTS
-    s += 4;					// mMsgFlags
+    s += 4;          // mPublishTS
+    s += 4;          // mMsgFlags
 
     return s;
 }
@@ -311,7 +311,7 @@ bool RsGxsMsgMetaData::deserialise(void *data, uint32_t *size)
 
     ok &= signSet.GetTlv(data, *size, &offset);
     ok &= GetTlvString(data, *size, &offset, 0, mMsgName);
-    uint32_t t;
+    uint32_t t=0;
     ok &= getRawUInt32(data, *size, &offset, &t);
     mPublishTs = t;
     ok &= getRawUInt32(data, *size, &offset, &mMsgFlags);
diff --git a/libretroshare/src/gxs/rsgxsdata.h b/libretroshare/src/gxs/rsgxsdata.h
index 6a9832418..21fbe1445 100644
--- a/libretroshare/src/gxs/rsgxsdata.h
+++ b/libretroshare/src/gxs/rsgxsdata.h
@@ -56,24 +56,22 @@ public:
     void clear();
     void operator =(const RsGroupMetaData& rMeta);
 
+    //Sort data in same order than serialiser and deserializer
     RsGxsGroupId mGroupId;
     RsGxsGroupId mOrigGrpId;
+    RsGxsGroupId mParentGrpId;
     std::string mGroupName;
     uint32_t    mGroupFlags;	// GXS_SERV::FLAG_PRIVACY_RESTRICTED | GXS_SERV::FLAG_PRIVACY_PRIVATE | GXS_SERV::FLAG_PRIVACY_PUBLIC
     uint32_t    mPublishTs;
-    uint32_t    mSignFlags;
+    uint32_t mCircleType;
+    uint32_t mAuthenFlags;
     RsGxsId mAuthorId;
-
+    std::string mServiceString;
     RsGxsCircleId mCircleId;
-    uint32_t mCircleType;
-
-
     RsTlvKeySignatureSet signSet;
     RsTlvSecurityKeySet keys;
 
-    std::string mServiceString;
-    uint32_t mAuthenFlags;
-    RsGxsGroupId mParentGrpId;
+    uint32_t    mSignFlags;
 
     // BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG.
 
@@ -105,18 +103,17 @@ public:
     void clear();
     void operator =(const RsMsgMetaData& rMeta);
 
+    static int refcount;
+
+    //Sort data in same order than serialiser and deserializer
     RsGxsGroupId mGroupId;
     RsGxsMessageId mMsgId;
-    static int refcount;
     RsGxsMessageId mThreadId;
     RsGxsMessageId mParentId;
     RsGxsMessageId mOrigMsgId;
     RsGxsId mAuthorId;
 
     RsTlvKeySignatureSet signSet;
-
-    std::string mServiceString;
-
     std::string mMsgName;
     time_t      mPublishTs;
     uint32_t    mMsgFlags; // Whats this for?
@@ -124,6 +121,7 @@ public:
     // BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG.
     // normally READ / UNREAD flags. LOCAL Data.
 
+    std::string mServiceString;
     uint32_t    mMsgStatus;
     uint32_t    mMsgSize;
     time_t      mChildTs;
diff --git a/libretroshare/src/retroshare/rsids.h b/libretroshare/src/retroshare/rsids.h
index 60b5392c7..db842ab21 100644
--- a/libretroshare/src/retroshare/rsids.h
+++ b/libretroshare/src/retroshare/rsids.h
@@ -162,8 +162,8 @@ template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> t
 	int n=0;
 	if(s.length() != ID_SIZE_IN_BYTES*2)
 	{
-        if(!s.empty())
-            std::cerr << "t_RsGenericIdType<>::t_RsGenericIdType(std::string&): supplied string in constructor has wrong size. Expected ID size=" << ID_SIZE_IN_BYTES << " String=\"" << s << "\"" << std::endl;
+		if(!s.empty())
+			std::cerr << "t_RsGenericIdType<>::t_RsGenericIdType(std::string&): supplied string in constructor has wrong size. Expected ID size=" << ID_SIZE_IN_BYTES*2 << " String=\"" << s << "\" = " << s.length() << std::endl;
 
 		clear();
 		return;
diff --git a/libretroshare/src/serialiser/rsserial.cc b/libretroshare/src/serialiser/rsserial.cc
index 8bb71e635..549bdc42c 100644
--- a/libretroshare/src/serialiser/rsserial.cc
+++ b/libretroshare/src/serialiser/rsserial.cc
@@ -298,7 +298,7 @@ uint32_t    RsSerialiser::size(RsItem *item)
 			{
 
 #ifdef  RSSERIAL_ERROR_DEBUG
-				std::cerr << "RsSerialiser::size() ERROR serialiser missing!";
+				std::cerr << "RsSerialiser::size() ERROR serialiser missing!" << std::endl;
 			
 				std::string out;
 				rs_sprintf(out, "%x", item->PacketId());
diff --git a/libretroshare/src/serialiser/rstlvkeys.cc b/libretroshare/src/serialiser/rstlvkeys.cc
index 5cb06f3ff..538862320 100644
--- a/libretroshare/src/serialiser/rstlvkeys.cc
+++ b/libretroshare/src/serialiser/rstlvkeys.cc
@@ -188,6 +188,76 @@ bool  RsTlvRSAKey::GetTlv(void *data, uint32_t size, uint32_t *offset)
 	return ok && checkKey() ;
 }
 
+/**
+ * @brief RsTlvRSAKey::getKeyTypeTlv: Deserialize data in temp value to get type of key.
+ * @param data: Serialized data
+ * @param size: Size of the data
+ * @param constoffset: Offset where find first data. Not updated by this function.
+ * @return The keyFlag filtered by RSTLV_KEY_TYPE_MASK. 0 if failed
+ */
+uint32_t RsTlvRSAKey::getKeyTypeTlv(void *data, uint32_t size, uint32_t *constoffset) const
+{
+	//Temporay Value. The same name than class to get same code than RsTlvRSAKey::GetTlv
+	uint32_t offValue = *constoffset;
+	uint32_t *offset = &offValue;
+	RsGxsId keyId;		// Mandatory :
+	uint32_t keyFlags;		// Mandatory ;
+	//The Code below have to be same as RsTlvRSAKey::GetTlv excepted last lines until flag is desserialized.
+	//Just comment TlvClear(); and unused values
+
+	if (size < *offset + TLV_HEADER_SIZE)
+		return false;
+
+	uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset])  );
+	uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset])  );
+	uint32_t tlvend = *offset + tlvsize;
+
+	if (size < tlvend)    /* check size */
+	{
+#ifdef TLV_DEBUG
+		std::cerr << "RsTlvSecurityKey::GetTlv() Fail, not enough space";
+		std::cerr << std::endl;
+#endif
+		return false; /* not enough space */
+	}
+
+	if (tlvtype != TLV_TYPE_SECURITY_KEY) /* check type */
+	{
+#ifdef TLV_DEBUG
+		std::cerr << "RsTlvSecurityKey::GetTlv() Fail, wrong type";
+		std::cerr << std::endl;
+#endif
+		return false;
+	}
+
+	bool ok = true;
+
+	/* ready to load */
+	//TlvClear();//RsTlvRSAKey::getKeyTypeTlv
+
+	/* skip the header */
+	(*offset) += TLV_HEADER_SIZE;
+#ifdef KEEP_OLD_SIGNATURE_SERIALISE_FORMAT
+	std::string s ;
+	ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_KEYID, s);
+	keyId = RsGxsId(s) ;
+#else
+	ok &= keyId.deserialise(data, tlvend, *offset) ;
+#endif
+	ok &= getRawUInt32(data, tlvend, offset, &(keyFlags));
+	//Stop here no need more data
+	//RsTlvRSAKey::getKeyTypeTlv specific lines
+	uint32_t ret = keyFlags & RSTLV_KEY_TYPE_MASK;
+	if (!ok)
+	{
+		ret = 0;
+#ifdef TLV_DEBUG
+		std::cerr << "RsTlvRSAKey::getKeyTypeTlv() Failed somewhere ok == false" << std::endl;
+#endif
+	}
+	return ret ;
+}
+
 std::ostream& RsTlvRSAKey::print(std::ostream &out, uint16_t indent) const
 { 
 	printBase(out, "RsTlvSecurityKey", indent);
@@ -220,12 +290,36 @@ std::ostream& RsTlvRSAKey::print(std::ostream &out, uint16_t indent) const
 
 bool RsTlvPrivateRSAKey::checkKey() const
 { 
-    return bool(keyFlags & RSTLV_KEY_TYPE_FULL) && !bool(keyFlags & RSTLV_KEY_TYPE_PUBLIC_ONLY) && GxsSecurity::checkPrivateKey(*this) ;
+	bool keyFlags_TYPE_FULL = (keyFlags & RSTLV_KEY_TYPE_FULL);
+	if (!keyFlags_TYPE_FULL) {std::cout << "RsTlvPrivateRSAKey::checkKey() keyFlags not Type Full " << std::hex << keyFlags << " & " << RSTLV_KEY_TYPE_FULL << std::dec << std::endl;}
+	bool keyFlags_not_PUBLIC_ONLY = !(keyFlags & RSTLV_KEY_TYPE_PUBLIC_ONLY);
+	if (!keyFlags_not_PUBLIC_ONLY) {std::cout << "RsTlvPrivateRSAKey::checkKey() keyFlags is Public Only " << std::hex << keyFlags << " & " << RSTLV_KEY_TYPE_PUBLIC_ONLY << std::dec << std::endl;}
+	bool security_OK = false;
+	if (keyFlags_TYPE_FULL && keyFlags_not_PUBLIC_ONLY)
+	{
+		//Don't trigg error if flags already wrong
+		security_OK = GxsSecurity::checkPrivateKey(*this);
+		if (!security_OK) {std::cout << "RsTlvPublicRSAKey::checkKey() key is not secure."<< std::endl;}
+	}
+
+	return keyFlags_TYPE_FULL && keyFlags_not_PUBLIC_ONLY && security_OK ;
 }
 
 bool RsTlvPublicRSAKey::checkKey() const
-{ 
-    return bool(keyFlags & RSTLV_KEY_TYPE_PUBLIC_ONLY) && !bool(keyFlags & RSTLV_KEY_TYPE_FULL) && GxsSecurity::checkPublicKey(*this) ;
+{
+	bool keyFlags_PUBLIC_ONLY = (keyFlags & RSTLV_KEY_TYPE_PUBLIC_ONLY);
+	if (!keyFlags_PUBLIC_ONLY) {std::cout << "RsTlvPublicRSAKey::checkKey() keyFlags not Public Only " << std::hex << keyFlags << " & " << RSTLV_KEY_TYPE_PUBLIC_ONLY << std::dec << std::endl;}
+	bool keyFlags_not_TYPE_FULL = !(keyFlags & RSTLV_KEY_TYPE_FULL);
+	if (!keyFlags_not_TYPE_FULL) {std::cout << "RsTlvPublicRSAKey::checkKey() keyFlags is Type Full " << std::hex << keyFlags << " & " << RSTLV_KEY_TYPE_FULL << std::dec << std::endl;}
+	bool security_OK = false;
+	if (keyFlags_PUBLIC_ONLY && keyFlags_not_TYPE_FULL)
+	{
+		//Don't trigg error if flags already wrong
+		security_OK = GxsSecurity::checkPublicKey(*this);
+		if (!security_OK) {std::cout << "RsTlvPublicRSAKey::checkKey() key is not secure."<< std::endl;}
+	}
+
+	return keyFlags_PUBLIC_ONLY && keyFlags_not_TYPE_FULL && security_OK ;
 }
 
 /************************************* RsTlvSecurityKeySet ************************************/
@@ -320,21 +414,23 @@ bool  RsTlvSecurityKeySet::GetTlv(void *data, uint32_t size, uint32_t *offset)
 		/* get the next type */
 		uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
 
-                // Security key set can be composed of public or private keys. We sort them into the correct bins after deserialisation
-                
+		// Security key set can be composed of public or private keys. We first ask type to desserialize in good one to not trigg errors.
 		switch(tlvsubtype)
 		{
 		case TLV_TYPE_SECURITY_KEY:
 		{
-			uint32_t offset_save = *offset ;
-
-			RsTlvPublicRSAKey public_key;
-
-			if(public_key.GetTlv(data, tlvend, offset))
-				public_keys[public_key.keyId] = public_key;
-			else
+			RsTlvPublicRSAKey gen_key;
+			uint32_t keyType = gen_key.getKeyTypeTlv(data, tlvend, offset);
+			if(keyType == RSTLV_KEY_TYPE_PUBLIC_ONLY)
+			{
+
+				RsTlvPublicRSAKey public_key;
+
+				if(public_key.GetTlv(data, tlvend, offset))
+					public_keys[public_key.keyId] = public_key;
+			}
+			else if(keyType == RSTLV_KEY_TYPE_FULL)
 			{
-				*offset = offset_save ;
 
 				RsTlvPrivateRSAKey private_key;
 
@@ -342,7 +438,7 @@ bool  RsTlvSecurityKeySet::GetTlv(void *data, uint32_t size, uint32_t *offset)
 					private_keys[private_key.keyId] = private_key;
 			}
 		}
-			break ;
+		break ;
 
 		default:
 			ok &= SkipUnknownTlv(data, tlvend, offset);
diff --git a/libretroshare/src/serialiser/rstlvkeys.h b/libretroshare/src/serialiser/rstlvkeys.h
index 03b41c06d..632a7fb09 100644
--- a/libretroshare/src/serialiser/rstlvkeys.h
+++ b/libretroshare/src/serialiser/rstlvkeys.h
@@ -63,7 +63,9 @@ public:
 
     /* clears KeyData - but doesn't delete - to transfer ownership */
     void ShallowClear(); 
-    
+
+    uint32_t getKeyTypeTlv(void *data, uint32_t size, uint32_t *offset) const;
+
     RsGxsId keyId;		// Mandatory :
     uint32_t keyFlags;		// Mandatory ;
     uint32_t startTS;		// Mandatory : 
@@ -75,17 +77,19 @@ public:
 
 class RsTlvPrivateRSAKey: public RsTlvRSAKey
 {    
-	public:
-		virtual ~RsTlvPrivateRSAKey() {}
+public:
+	RsTlvPrivateRSAKey():RsTlvRSAKey() {}
+	virtual ~RsTlvPrivateRSAKey() {}
 
-        	virtual bool checkKey() const  ;
+	virtual bool checkKey() const  ;
 };
 class RsTlvPublicRSAKey: public RsTlvRSAKey
 {
-	public:
-		virtual ~RsTlvPublicRSAKey() {}
+public:
+	RsTlvPublicRSAKey():RsTlvRSAKey() {}
+	virtual ~RsTlvPublicRSAKey() {}
 
-        	virtual bool checkKey() const  ;
+	virtual bool checkKey() const  ;
 };
 
 class RsTlvSecurityKeySet: public RsTlvItem
diff --git a/tests/librssimulator/librssimulator.pro b/tests/librssimulator/librssimulator.pro
index 34946ac1e..9ef336b57 100644
--- a/tests/librssimulator/librssimulator.pro
+++ b/tests/librssimulator/librssimulator.pro
@@ -1,3 +1,5 @@
+!include("../../retroshare.pri"): error("Could not include file ../../retroshare.pri")
+
 TEMPLATE = lib
 CONFIG += staticlib 
 CONFIG -= qt
@@ -170,19 +172,11 @@ win32 {
 
 	CONFIG += upnp_miniupnpc
 
-	UPNPC_DIR = ../../../miniupnpc-1.3
+	for(lib, LIB_DIR):LIBS += -L"$$lib"
+	for(bin, BIN_DIR):LIBS += -L"$$bin"
 
-	ZLIB_DIR = ../../../zlib-1.2.3
-	SSL_DIR = ../../../openssl-1.0.1c
-	OPENPGPSDK_DIR = ../../openpgpsdk/src
-
-	INCLUDEPATH += . $${SSL_DIR}/include $${UPNPC_DIR} $${ZLIB_DIR} $${OPENPGPSDK_DIR}
-
-	# SQLite include path is required to compile GXS.
-	gxs {
-		SQLITE_DIR = ../../../sqlcipher-2.2.0
-		INCLUDEPATH += $${SQLITE_DIR}
-	}
+	DEPENDPATH += . $$INC_DIR
+	INCLUDEPATH += . $$INC_DIR
 }
 
 ################################# MacOSX ##########################################
diff --git a/tests/librssimulator/testing/SetServiceTester.cc b/tests/librssimulator/testing/SetServiceTester.cc
index ed882be2f..574399a76 100644
--- a/tests/librssimulator/testing/SetServiceTester.cc
+++ b/tests/librssimulator/testing/SetServiceTester.cc
@@ -1,5 +1,6 @@
 
 #include <list>
+#include "time.h"
 #include "retroshare/rsids.h"
 #include "serialiser/rsserial.h"
 
diff --git a/tests/unittests/libretroshare/gxs/data_service/rsgxsdata_test.cc b/tests/unittests/libretroshare/gxs/data_service/rsgxsdata_test.cc
index a6a822ed6..a74dbb280 100644
--- a/tests/unittests/libretroshare/gxs/data_service/rsgxsdata_test.cc
+++ b/tests/unittests/libretroshare/gxs/data_service/rsgxsdata_test.cc
@@ -5,76 +5,85 @@
 #include "libretroshare/gxs/common/data_support.h"
 #include "gxs/rsgxsdata.h"
 
-bool testEqual(const RsGxsGrpMetaData& d1,const RsGxsGrpMetaData& d2)
+#include <sstream>
+
+std::string testEqual(const RsGxsGrpMetaData& d1,const RsGxsGrpMetaData& d2)
 {
-    if(d1.mGroupId      !=  d2.mGroupId       ) return false ;   
-    if(d1.mOrigGrpId    !=  d2.mOrigGrpId     ) return false ;
-    if(d1.mGroupName    !=  d2.mGroupName     ) return false ;
-    if(d1.mGroupFlags   !=  d2.mGroupFlags    ) return false ; 
-    if(d1.mPublishTs    !=  d2.mPublishTs     ) return false ;
-    if(d1.mSignFlags    !=  d2.mSignFlags     ) return false ;
-    if(d1.mAuthorId     !=  d2.mAuthorId      ) return false ;
-    if(d1.mCircleId     !=  d2.mCircleId      ) return false ;
-    if(d1.mCircleType   !=  d2.mCircleType    ) return false ; 
-    if(d1.mServiceString!=  d2.mServiceString ) return false ;    
-    if(d1.mAuthenFlags  !=  d2.mAuthenFlags   ) return false ;  
-    if(d1.mParentGrpId  !=  d2.mParentGrpId   ) return false ;  
-    
-    // if(d1.signSet       !=  d2.signSet        ) return false ;
-    // if(d1.keys          !=  d2.keys           ) return false ;
-    
-    return true ;
+    std::ostringstream out;
+    if(d1.mGroupId      !=  d2.mGroupId       ) { out << "mGroupId"       << ": " << d1.mGroupId.toStdString()       << "!=" << d2.mGroupId.toStdString()       ; return out.str();}
+    if(d1.mOrigGrpId    !=  d2.mOrigGrpId     ) { out << "mOrigGrpId"     << ": " << d1.mOrigGrpId.toStdString()     << "!=" << d2.mOrigGrpId.toStdString()     ; return out.str();}
+    if(d1.mAuthorId     !=  d2.mAuthorId      ) { out << "mAuthorId"      << ": " << d1.mAuthorId.toStdString()      << "!=" << d2.mAuthorId.toStdString()      ; return out.str();}
+    if(d1.mCircleId     !=  d2.mCircleId      ) { out << "mCircleId"      << ": " << d1.mCircleId.toStdString()      << "!=" << d2.mCircleId.toStdString()      ; return out.str();}
+    if(d1.mParentGrpId  !=  d2.mParentGrpId   ) { out << "mParentGrpId"   << ": " << d1.mParentGrpId.toStdString()   << "!=" << d2.mParentGrpId.toStdString()   ; return out.str();}
+    if(d1.mGroupName    !=  d2.mGroupName     ) { out << "mGroupName"     << ": " << d1.mGroupName     << "!=" << d2.mGroupName     ; return out.str();}
+    if(d1.mGroupFlags   !=  d2.mGroupFlags    ) { out << "mGroupFlags"    << ": " << d1.mGroupFlags    << "!=" << d2.mGroupFlags    ; return out.str();}
+    if(d1.mPublishTs    !=  d2.mPublishTs     ) { out << "mPublishTs"     << ": " << d1.mPublishTs     << "!=" << d2.mPublishTs     ; return out.str();}
+    if(d1.mSignFlags    !=  d2.mSignFlags     ) { out << "mSignFlags"     << ": " << d1.mSignFlags     << "!=" << d2.mSignFlags     ; return out.str();}
+    if(d1.mCircleType   !=  d2.mCircleType    ) { out << "mCircleType"    << ": " << d1.mCircleType    << "!=" << d2.mCircleType    ; return out.str();}
+    if(d1.mServiceString!=  d2.mServiceString ) { out << "mServiceString" << ": " << d1.mServiceString << "!=" << d2.mServiceString ; return out.str();}
+    if(d1.mAuthenFlags  !=  d2.mAuthenFlags   ) { out << "mAuthenFlags"   << ": " << d1.mAuthenFlags   << "!=" << d2.mAuthenFlags   ; return out.str();}
+
+    // if(d1.signSet       !=  d2.signSet        ) { out << "signSet"        << ": " << d1.signSet        << "!=" << d2.signSet        ; return out.str();}
+    // if(d1.keys          !=  d2.keys           ) { out << "keys"           << ": " << d1.keys           << "!=" << d2.keys           ; return out.str();}
+
+    return "" ;
 }
-bool testEqual(const RsGxsMsgMetaData& d1,const RsGxsMsgMetaData& d2)
+
+std::string testEqual(const RsGxsMsgMetaData& d1,const RsGxsMsgMetaData& d2)
 {
-    if(d1.mGroupId      !=  d2.mGroupId       ) return false ;   
-    if(d1.mMsgId        !=  d2.mMsgId         ) return false ;
-    if(d1.refcount      !=  d2.refcount       ) return false ;
-    if(d1.mThreadId     !=  d2.mThreadId      ) return false ; 
-    if(d1.mPublishTs    !=  d2.mPublishTs     ) return false ;
-    if(d1.mParentId     !=  d2.mParentId      ) return false ;
-    if(d1.mOrigMsgId    !=  d2.mOrigMsgId     ) return false ;
-    if(d1.mAuthorId     !=  d2.mAuthorId      ) return false ;
-    if(d1.mServiceString!=  d2.mServiceString ) return false ;    
-    if(d1.mMsgName      !=  d2.mMsgName       ) return false ;  
-    if(d1.mPublishTs    !=  d2.mPublishTs     ) return false ;  
-    if(d1.mMsgFlags     !=  d2.mMsgFlags      ) return false ;  
-    
-    // if(d1.signSet       !=  d2.signSet        ) return false ;
-    
-    return true ;
+    std::ostringstream out;
+    if(d1.mGroupId      !=  d2.mGroupId       ) { out << "mGroupId"       << ": " << d1.mGroupId.toStdString()       << " != " << d2.mGroupId.toStdString()       ; return out.str();}
+    if(d1.mOrigMsgId    !=  d2.mOrigMsgId     ) { out << "mOrigMsgId"     << ": " << d1.mOrigMsgId.toStdString()     << " != " << d2.mOrigMsgId.toStdString()     ; return out.str();}
+    if(d1.mAuthorId     !=  d2.mAuthorId      ) { out << "mAuthorId"      << ": " << d1.mAuthorId.toStdString()      << " != " << d2.mAuthorId.toStdString()      ; return out.str();}
+    if(d1.mMsgId        !=  d2.mMsgId         ) { out << "mMsgId"         << ": " << d1.mMsgId.toStdString()         << " != " << d2.mMsgId.toStdString()         ; return out.str();}
+    if(d1.mThreadId     !=  d2.mThreadId      ) { out << "mThreadId"      << ": " << d1.mThreadId.toStdString()      << " != " << d2.mThreadId.toStdString()      ; return out.str();}
+    if(d1.mParentId     !=  d2.mParentId      ) { out << "mParentId"      << ": " << d1.mParentId.toStdString()      << " != " << d2.mParentId.toStdString()      ; return out.str();}
+    if(d1.mPublishTs    !=  d2.mPublishTs     ) { out << "mPublishTs"     << ": " << d1.mPublishTs     << " != " << d2.mPublishTs     ; return out.str();}
+    if(d1.mMsgName      !=  d2.mMsgName       ) { out << "mMsgName"       << ": " << d1.mMsgName       << " != " << d2.mMsgName       ; return out.str();}
+    if(d1.mPublishTs    !=  d2.mPublishTs     ) { out << "mPublishTs"     << ": " << d1.mPublishTs     << " != " << d2.mPublishTs     ; return out.str();}
+    if(d1.mMsgFlags     !=  d2.mMsgFlags      ) { out << "mMsgFlags"      << ": " << d1.mMsgFlags      << " != " << d2.mMsgFlags      ; return out.str();}
+
+    // if(d1.refcount      !=  d2.refcount       ) { out << "refcount"       << ": " << d1.refcount       << " != " << d2.refcount       ; return out.str();} //Is Static
+    // if(d1.signSet       !=  d2.signSet        ) { out << "signSet"        << ": " << d1.signSet        << " != " << d2.signSet        ; return out.str();}
+
+    return "" ;
 }
+
 TEST(libretroshare_gxs, RsGxsData)
 {
 
     RsGxsGrpMetaData grpMeta1, grpMeta2;
-    RsGxsMsgMetaData msgMeta1, msgMeta2;
 
     grpMeta1.clear();
     init_item(&grpMeta1);
 
-    msgMeta1.clear();
-    init_item(&msgMeta1);
-
     uint32_t pktsize = grpMeta1.serial_size(RS_GXS_GRP_META_DATA_CURRENT_API_VERSION);
     char grp_data[pktsize];
 
-    bool ok = true;
-
-    ok &= grpMeta1.serialise(grp_data, pktsize, RS_GXS_GRP_META_DATA_CURRENT_API_VERSION);
+    bool grpSerialise_OK = grpMeta1.serialise(grp_data, pktsize, RS_GXS_GRP_META_DATA_CURRENT_API_VERSION);
+    EXPECT_TRUE(grpSerialise_OK);
     grpMeta2.clear();
-    ok &= grpMeta2.deserialise(grp_data, pktsize);
+    bool grpDeserialise_OK = grpMeta2.deserialise(grp_data, pktsize);
+    EXPECT_TRUE(grpDeserialise_OK);
+
+    EXPECT_EQ(testEqual(grpMeta1, grpMeta2), "");
+
 
-    EXPECT_TRUE(testEqual(grpMeta1 , grpMeta2));
+    RsGxsMsgMetaData msgMeta1, msgMeta2;
+
+    msgMeta1.clear();
+    init_item(&msgMeta1);
 
     pktsize = msgMeta1.serial_size();
     char msg_data[pktsize];
 
-    ok &= msgMeta1.serialise(msg_data, &pktsize);
+    bool msgSerialise_OK = msgMeta1.serialise(msg_data, &pktsize);
+    EXPECT_TRUE(msgSerialise_OK);
     msgMeta2.clear();
-    ok &= msgMeta2.deserialise(msg_data, &pktsize);
+    bool msgDeserialise_OK = msgMeta2.deserialise(msg_data, &pktsize);
+    EXPECT_TRUE(msgDeserialise_OK);
 
-    EXPECT_TRUE(testEqual(msgMeta1 , msgMeta2));
+    EXPECT_EQ(testEqual(msgMeta1, msgMeta2), "");
 }
 
 
diff --git a/tests/unittests/libretroshare/gxs/security/gxssecurity_test.cc b/tests/unittests/libretroshare/gxs/security/gxssecurity_test.cc
index 35a800e38..416979ec0 100644
--- a/tests/unittests/libretroshare/gxs/security/gxssecurity_test.cc
+++ b/tests/unittests/libretroshare/gxs/security/gxssecurity_test.cc
@@ -40,7 +40,11 @@ TEST(libretroshare_gxs, GxsSecurity)
 
 	EXPECT_TRUE(GxsSecurity::generateKeyPair(pub_key,priv_key)) ;
 
+#ifdef WIN32
+	srand(getpid()) ;
+#else
 	srand48(getpid()) ;
+#endif
 
 	EXPECT_TRUE( pub_key.keyId   == priv_key.keyId   );
 	EXPECT_TRUE( pub_key.startTS == priv_key.startTS );
diff --git a/tests/unittests/libretroshare/serialiser/rsbaseitem_test.cc b/tests/unittests/libretroshare/serialiser/rsbaseitem_test.cc
index fc5b1a88e..a3a8d0d01 100644
--- a/tests/unittests/libretroshare/serialiser/rsbaseitem_test.cc
+++ b/tests/unittests/libretroshare/serialiser/rsbaseitem_test.cc
@@ -45,7 +45,7 @@ TEST(libretroshare_serialiser, RsTlvFileItem)
 
 	/* initialise */
 	i1.filesize = 101010;
-	i1.hash = RsFileHash("ABCDEFEGHE");
+	i1.hash = RsFileHash("123456789ABCDEF67890123456789ABCDEF67890");//SHA1_SIZE*2 = 40
 	i1.name = "TestFile.txt";
 	i1.pop  = 12;
 	i1.age  = 456;
@@ -103,7 +103,7 @@ TEST(libretroshare_serialiser, RsTlvFileSet)
 	{
 		RsTlvFileItem fi;
 		fi.filesize = 16 + i * i;
-		fi.hash = RsFileHash("ABCDEF");
+		fi.hash = RsFileHash("123456789ABCDEF67890123456789ABCDEF67890");//SHA1_SIZE*2 = 40
 		std::ostringstream out;
 		out << "File" << i << "_inSet.txt";
 		fi.name = out.str();
@@ -130,7 +130,7 @@ TEST(libretroshare_serialiser, RsTlvFileData)
 
 	/* initialise */
 	d1.file.filesize = 101010;
-	d1.file.hash = RsFileHash("ABCDEFEGHE");
+	d1.file.hash = RsFileHash("123456789ABCDEF67890123456789ABCDEF67890");//SHA1_SIZE*2 = 40
 	d1.file.name = "";
 	d1.file.age = 0;
 	d1.file.pop = 0;
diff --git a/tests/unittests/libretroshare/serialiser/rstlvutil.cc b/tests/unittests/libretroshare/serialiser/rstlvutil.cc
index e7b3b0bc9..6613ed9b3 100644
--- a/tests/unittests/libretroshare/serialiser/rstlvutil.cc
+++ b/tests/unittests/libretroshare/serialiser/rstlvutil.cc
@@ -101,6 +101,7 @@ int test_SerialiseTlvItem(std::ostream &str, RsTlvItem *in, RsTlvItem *out)
 	in->print(str, 0);
 	displayRawPacket(str, serbuffer, serialOffset);
 	out->print(str, 0);
+	str << std::endl;
 	return 1;
 }
 
diff --git a/tests/unittests/libretroshare/serialiser/support.cc b/tests/unittests/libretroshare/serialiser/support.cc
index da20ec41e..2474b77fb 100644
--- a/tests/unittests/libretroshare/serialiser/support.cc
+++ b/tests/unittests/libretroshare/serialiser/support.cc
@@ -27,6 +27,7 @@
 
 #include "support.h"
 #include "serialiser/rstlvbase.h"
+#include "gxs/gxssecurity.h"
 
 void randString(const uint32_t length, std::string& outStr)
 {
@@ -67,12 +68,14 @@ void init_item(RsTlvSecurityKeySet& ks)
 	randString(SHORT_STR, ks.groupId);
 	for(int i=1; i<n; i++)
 	{
-		RsGxsId a_str;
-		a_str = RsGxsId::random();
+		RsGxsId pub_str;
+		RsGxsId pri_str;
+		pub_str = RsGxsId::random();
+		pri_str = RsGxsId::random();
 
-		RsTlvPublicRSAKey& a_key = ks.public_keys[a_str];
-		init_item(a_key);
-		a_key.keyId = a_str;
+		RsTlvPublicRSAKey& pub_key = ks.public_keys[pub_str];
+		RsTlvPrivateRSAKey& pri_key = ks.private_keys[pri_str];
+		GxsSecurity::generateKeyPair(pub_key, pri_key);
 	}
 }
 
@@ -182,24 +185,6 @@ bool operator==(const RsTlvBinaryData& bd1, const RsTlvBinaryData& bd2)
 	return true;
 }
 
-
-void init_item(RsTlvPublicRSAKey& sk)
-{
-	int randnum = rand()%313131;
-
-	sk.endTS = randnum;
-	sk.keyFlags = randnum;
-	sk.startTS = randnum;
-	sk.keyId = RsGxsId::random();
-
-	std::string randomStr;
-	randString(LARGE_STR, randomStr);
-
-	sk.keyData.setBinData(randomStr.c_str(), randomStr.size());
-
-	return;
-}
-
 void init_item(RsTlvKeySignature& ks)
 {
     ks.keyId = RsGxsId::random();
diff --git a/tests/unittests/libretroshare/serialiser/support.h b/tests/unittests/libretroshare/serialiser/support.h
index ea886246a..f681d90ad 100644
--- a/tests/unittests/libretroshare/serialiser/support.h
+++ b/tests/unittests/libretroshare/serialiser/support.h
@@ -58,7 +58,6 @@ void randString(const uint32_t, std::wstring&);
 
 /* for testing compound tlv items */
 
-void init_item(RsTlvPublicRSAKey&);
 void init_item(RsTlvSecurityKeySet&);
 void init_item(RsTlvKeySignature&);
 void init_item(RsTlvKeySignatureSet&);
@@ -112,7 +111,7 @@ template<class T> int test_RsItem()
 	RsSerialType *rsfis = init_item(rsfi) ;
 
 	/* attempt to serialise it before we add it to the serialiser */
-
+	std::cerr << "### These errors are expected." << std::endl;
 	EXPECT_TRUE(0 == srl.size(&rsfi));
 
 	static const uint32_t MAX_BUFSIZE = 22000 ;
@@ -120,6 +119,7 @@ template<class T> int test_RsItem()
 	char *buffer = new char[MAX_BUFSIZE];
 	uint32_t sersize = MAX_BUFSIZE;
 
+	std::cerr << "### These errors are expected." << std::endl;
 	EXPECT_TRUE(false == srl.serialise(&rsfi, (void *) buffer, &sersize));
 
 	/* now add to serialiser */
@@ -133,7 +133,7 @@ template<class T> int test_RsItem()
 	std::cerr << "test_Item() done: " << done << std::endl;
 	std::cerr << "test_Item() sersize: " << sersize << std::endl;
 
-	std::cerr << "test_Item() serialised:" << std::endl;
+	//std::cerr << "test_Item() serialised:" << std::endl;
 	//displayRawPacket(std::cerr, (void *) buffer, sersize);
 
 	EXPECT_TRUE(done == true);
@@ -192,7 +192,7 @@ template<class T> int test_RsItem(uint16_t servtype)
         RsSerialType *rsfis = init_item(rsfi) ; // deleted on destruction of srl
 
         /* attempt to serialise it before we add it to the serialiser */
-
+        std::cerr << "### These errors are expected." << std::endl;
         EXPECT_TRUE(0 == srl.size(&rsfi));
 
         static const uint32_t MAX_BUFSIZE = 22000 ;
diff --git a/tests/unittests/libretroshare/serialiser/tlvbase_test2.cc b/tests/unittests/libretroshare/serialiser/tlvbase_test2.cc
index cfd552858..a1f6d4fee 100644
--- a/tests/unittests/libretroshare/serialiser/tlvbase_test2.cc
+++ b/tests/unittests/libretroshare/serialiser/tlvbase_test2.cc
@@ -81,6 +81,7 @@ int test_OneString(std::string input, uint16_t type)
 	std::cerr << "DeSerialising" << std::endl;
 
 	/* fails if type is wrong! */
+	std::cerr << "### These errors are expected." << std::endl;
 	EXPECT_TRUE(0 == GetTlvString((void*)tlvdata, outOffset, &inOffset, type-1, OutString));
 	EXPECT_TRUE(GetTlvString((void*)tlvdata, outOffset, &inOffset, type, OutString));
 
@@ -141,6 +142,7 @@ int test_IpAddr(struct sockaddr_in *addr, uint16_t type)
 	std::cerr << "DeSerialising" << std::endl;
 
 	/* fails if type is wrong! */
+	std::cerr << "### These errors are expected." << std::endl;
 	EXPECT_TRUE(0 == GetTlvIpAddrPortV4((void*)tlvdata, outOffset, &inOffset, type-1, &outaddr));
 	EXPECT_TRUE(GetTlvIpAddrPortV4((void*)tlvdata, outOffset, &inOffset, type, &outaddr));
 
diff --git a/tests/unittests/libretroshare/serialiser/tlvstack_test.cc b/tests/unittests/libretroshare/serialiser/tlvstack_test.cc
index 0acba2709..d4d46ed0e 100644
--- a/tests/unittests/libretroshare/serialiser/tlvstack_test.cc
+++ b/tests/unittests/libretroshare/serialiser/tlvstack_test.cc
@@ -63,13 +63,13 @@ TEST(libretroshare_serialiser, test_RsTlvStack)
 
         /* initialise */
         fi1->filesize = 101010;
-        fi1->hash = RsFileHash("ABCDEFEGHE");
+        fi1->hash = RsFileHash("123456789ABCDEF67890123456789ABCDEF67890");//SHA1_SIZE*2 = 40
         fi1->name = "TestFile.txt";
         fi1->pop  = 12;
         fi1->age  = 456;
 
         fi2->filesize = 101010;
-        fi2->hash = RsFileHash("ABCDEFEGHE");
+        fi2->hash = RsFileHash("123456789ABCDEF67890123456789ABCDEF67890");//SHA1_SIZE*2 = 40
         fi2->name = "TestFile.txt";
         fi2->pop  = 0;
         fi2->age  = 0;;
diff --git a/tests/unittests/libretroshare/serialiser/tlvtypes_test.cc b/tests/unittests/libretroshare/serialiser/tlvtypes_test.cc
index cc4d93758..c24915e27 100644
--- a/tests/unittests/libretroshare/serialiser/tlvtypes_test.cc
+++ b/tests/unittests/libretroshare/serialiser/tlvtypes_test.cc
@@ -47,7 +47,7 @@ TEST(libretroshare_serialiser, test_RsTlvFileItem)
 
 	/* initialise */
 	i1.filesize = 101010;
-	i1.hash = RsFileHash("ABCDEFEGHE");
+	i1.hash = RsFileHash("123456789ABCDEF67890123456789ABCDEF67890");//SHA1_SIZE*2 = 40
 	i1.name = "TestFile.txt";
 	i1.pop  = 12;
 	i1.age  = 456;
@@ -105,7 +105,7 @@ TEST(libretroshare_serialiser, test_RsTlvFileSet)
 	{
 		RsTlvFileItem fi;
 		fi.filesize = 16 + i * i;
-		fi.hash = RsFileHash("ABCDEF");
+		fi.hash = RsFileHash("123456789ABCDEF67890123456789ABCDEF67890");//SHA1_SIZE*2 = 40
 		std::ostringstream out;
 		out << "File" << i << "_inSet.txt";
 		fi.name = out.str();
@@ -195,6 +195,7 @@ TEST(libretroshare_serialiser, test_RsTlvServiceIdSet)
 		i1.ids.push_back(1 + rand() % 12564);
 	}
 	std::cout << "error here!!!?";
+	std::cout << std::endl;
 	EXPECT_TRUE(test_SerialiseTlvItem(std::cerr, &i1, &i2));
 }
 
diff --git a/tests/unittests/unittests.pro b/tests/unittests/unittests.pro
index 0da23ce37..2409b8845 100644
--- a/tests/unittests/unittests.pro
+++ b/tests/unittests/unittests.pro
@@ -1,3 +1,5 @@
+!include("../../retroshare.pri"): error("Could not include file ../../retroshare.pri")
+
 QT     += network xml script
 CONFIG += bitdht
 
@@ -114,6 +116,9 @@ win32 {
 	QMAKE_CFLAGS += -Wextra
 	QMAKE_CXXFLAGS += -Wextra
 
+	# solve linker warnings because of the order of the libraries
+	QMAKE_LFLAGS += -Wl,--start-group
+
 	# Switch off optimization for release version
 	QMAKE_CXXFLAGS_RELEASE -= -O2
 	QMAKE_CXXFLAGS_RELEASE += -O0
@@ -132,31 +137,35 @@ win32 {
 	PRE_TARGETDEPS *= ../librssimulator/lib/librssimulator.a
 	PRE_TARGETDEPS *= ../../openpgpsdk/src/lib/libops.a
 
+	for(lib, LIB_DIR):LIBS += -L"$$lib"
+	for(bin, BIN_DIR):LIBS += -L"$$bin"
+
 	LIBS += ../../libretroshare/src/lib/libretroshare.a
+	LIBS += ../librssimulator/lib/librssimulator.a
 	LIBS += ../../openpgpsdk/src/lib/libops.a -lbz2
 	LIBS += -L"$$PWD/../../../lib"
 
-	gxs {
-		LIBS += ../../supportlibs/pegmarkdown/lib/libpegmarkdown.a
-		LIBS += -lsqlcipher
-	}
-
 	LIBS += -lssl -lcrypto -lpthread -lminiupnpc -lz
-# added after bitdht
-#	LIBS += -lws2_32
 	LIBS += -luuid -lole32 -liphlpapi -lcrypt32 -lgdi32
-	LIBS += -lole32 -lwinmm
-	RC_FILE = gui/images/retroshare_win.rc
-
-	# export symbols for the plugins
-	LIBS += -Wl,--export-all-symbols,--out-implib,lib/libretroshare-gui.a
-
-	# create lib directory
-	QMAKE_PRE_LINK = $(CHK_DIR_EXISTS) lib $(MKDIR) lib
+	LIBS += -lwinmm
 
 	DEFINES *= WINDOWS_SYS WIN32_LEAN_AND_MEAN _USE_32BIT_TIME_T
 
-	INCLUDEPATH += .
+	# create lib directory
+	message(CHK_DIR_EXISTS=$(CHK_DIR_EXISTS))
+	message(MKDIR=$(MKDIR))
+	QMAKE_PRE_LINK = $(CHK_DIR_EXISTS) lib || $(MKDIR) lib
+
+	DEPENDPATH += . $$INC_DIR
+	INCLUDEPATH += . $$INC_DIR
+
+	greaterThan(QT_MAJOR_VERSION, 4) {
+		# Qt 5
+		RC_INCLUDEPATH += $$_PRO_FILE_PWD_/../../libretroshare/src
+	} else {
+		# Qt 4
+		QMAKE_RC += --include-dir=$$_PRO_FILE_PWD_/../../libretroshare/src
+	}
 }
 
 ##################################### MacOS ######################################