From 63d7e433f104dd13d015df3a048697fad6d43a55 Mon Sep 17 00:00:00 2001
From: deva <deva>
Date: Thu, 15 May 2008 14:19:02 +0000
Subject: Added a lot of testcode... and fixed a lot of minor error (-Wall
 -Werror)

---
 server/src/Makefile.am       |  24 ++++++
 server/src/luaquerymapper.cc |  33 ++++----
 server/src/queryhandler.cc   | 196 ++++++++++++++++++++++++++++++++++++++++++-
 server/src/queryhandler.h    |  31 +++++--
 server/src/queryparser.cc    |  33 ++++----
 server/src/saxparser.cc      |   7 +-
 server/src/saxparser.h       |   1 +
 server/src/tostring.cc       |   4 +-
 server/src/uid.cc            |   2 +-
 9 files changed, 290 insertions(+), 41 deletions(-)

diff --git a/server/src/Makefile.am b/server/src/Makefile.am
index 251560b..7b66663 100644
--- a/server/src/Makefile.am
+++ b/server/src/Makefile.am
@@ -47,3 +47,27 @@ EXTRA_DIST = \
 	tcpsocket.h \
 	tostring.h \
 	uid.h
+
+TESTFILES = \
+	test_queryhandler \
+	test_queryparser \
+	test_luaquerymapper
+
+TESTLOGS = `for F in ${TESTFILES}; do echo $$F.log; done`
+
+test: $(TESTFILES)
+	@echo "All tests done."
+
+test_clean:
+	rm -f $(TESTFILES)
+
+test_queryhandler: queryhandler.cc
+	@../../tools/test queryhandler.cc tcpsocket.cc exception.cc tostring.cc uid.cc log.cc
+
+test_queryparser: queryparser.cc
+	@../../tools/test queryparser.cc queryhandler.cc tcpsocket.cc exception.cc tostring.cc uid.cc log.cc saxparser.cc -lexpat
+
+test_luaquerymapper: luaquerymapper.cc
+	@../../tools/test luaquerymapper.cc queryparser.cc queryhandler.cc tcpsocket.cc exception.cc tostring.cc uid.cc log.cc saxparser.cc -lexpat $(LUA_LIBS)
+
+CLEANFILES = $(TESTFILES) $(TESTLOGS)
diff --git a/server/src/luaquerymapper.cc b/server/src/luaquerymapper.cc
index f4f6f20..be18742 100644
--- a/server/src/luaquerymapper.cc
+++ b/server/src/luaquerymapper.cc
@@ -105,28 +105,33 @@ std::string LUAQueryMapper::map(const std::string &mapper)
 
 #ifdef TEST_LUAQUERYMAPPER
 
+#include "queryhandler.h"
+#include "queryparser.h"
+
 int main()
 {
-  QueryResult res;
+  TCPSocket s;
+  s.connect("localhost", 11108);
+
+  QueryHandler qh(&s, "2003791613");
 
-  QueryResult group1;
-  group1.values["dims"] = "42";
+  Query q1("lensmeter", "lensmeter");
+  qh.addQuery(q1);
 
-  QueryResult group2;
-  group2.values["foo"] = "bar";
-  group2.values["bar"] = "foo";
-  group2.groups["fnuller"] = group1;
+  std::string res = qh.exec();
+  
+  printf("%s\n", res.c_str());
 
-  res.values["dims"] = "42";
-  res.groups["dimmer"] = group2;
+  QueryParser e(res);
+  e.parse();
 
-  LUAQueryMapper mapper(res);
+  LUAQueryMapper mapper(e.result);
 
-  std::string luamap = "return dimmer.fnuller.dims * 2 + dims";
-  printf("%s\n", mapper.map(luamap).c_str());
+  std::string luamap = "return right.sphere";
+  printf("%s : %s\n", luamap.c_str(), mapper.map(luamap).c_str());
 
-  luamap = "return math.sin(dimmer.fnuller.dims * 2 + dims)";
-  printf("%s\n", mapper.map(luamap).c_str());
+  luamap = "return math.sin(right.cyl) * 2";
+  printf("%s : %s\n", luamap.c_str(), mapper.map(luamap).c_str());
 
   return 0;
 }
diff --git a/server/src/queryhandler.cc b/server/src/queryhandler.cc
index 16db038..e21d820 100644
--- a/server/src/queryhandler.cc
+++ b/server/src/queryhandler.cc
@@ -26,6 +26,200 @@
  */
 #include "queryhandler.h"
 
-QueryHandler::QueryHandler()
+// For time
+#include <time.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+// For getpid
+#include <unistd.h>
+#include <sys/types.h>
+
+// For time
+#include <time.h>
+
+// For strerror and errno
+#include <errno.h>
+
+// For socket and friends
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <netinet/in.h>
+
+// For ioctl
+#include <sys/ioctl.h>
+
+typedef struct {
+  in_addr_t ip;
+  time_t time;
+  pid_t pid;
+  unsigned short int count;
+} UID;
+
+
+#define SIOCGIFCONF 0x8912 // get iface list
+
+static in_addr_t getIP(char *interface)
 {
+  in_addr_t ret = 0;
+  int numreqs = 30, sd, n;
+  struct ifconf ifc;
+  struct ifreq *ifr;
+  struct in_addr *ia;
+
+  sd = socket(AF_INET, SOCK_STREAM, 0);
+  if(sd == -1) {
+    //    throw Pentominos::UIDCouldNotConnectException(strerror(errno));
+  }
+
+  ifc.ifc_buf = NULL;
+  ifc.ifc_len = sizeof(struct ifreq) * numreqs;
+
+  ifc.ifc_buf = (char*)malloc(ifc.ifc_len);
+  if(ifc.ifc_buf == NULL) {
+    //    throw Pentominos::UIDOutOfMemoryException();
+  }
+
+  if (ioctl(sd, SIOCGIFCONF, &ifc) < 0) {
+    //    throw Pentominos::UIDInterfaceListException(strerror(errno));
+  } 
+
+  ifr = ifc.ifc_req; 
+  for (n = 0; n < ifc.ifc_len; n += sizeof(struct ifreq)) {
+    ia = (struct in_addr *)((ifr->ifr_ifru.ifru_addr.sa_data)+2);
+    if(!strcmp(ifr->ifr_ifrn.ifrn_name, interface)) {
+      ret = *(in_addr_t*)ia;
+    }
+    ifr++; 
+  }
+
+  if(!ret) { // Still no interface... We're fucked!
+    //    throw Pentominos::UIDInterfaceException(interface);
+  }
+
+  free(ifc.ifc_buf);
+  return ret;
+}
+
+
+static unsigned short counter = 0;
+static unsigned short getCounter()
+{
+  return counter++;
+}
+
+static UID uid = {0,0,0,0};
+static std::string getUID(char *interface)
+{
+  if(!uid.ip) uid.ip = getIP(interface);
+
+  time_t t = time(NULL);
+  if(uid.time != t) counter = 0; // If time differes, reset the counter
+  uid.time = t; // We need this value every time.
+
+  if(!uid.pid) uid.pid = getpid();
+
+  uid.count = getCounter();
+
+  char buf[32];
+  sprintf(buf, "%08x%08x%04x%04x", uid.ip, (unsigned int)uid.time, uid.pid, uid.count);
+  return std::string(buf);
 }
+
+
+QueryHandler::QueryHandler(TCPSocket *socket, std::string cpr)
+{
+  this->cpr = cpr;
+  this->socket = socket;
+}
+
+void QueryHandler::addQuery(Query &query)
+{
+  queries.push_back(query);
+}
+
+std::string QueryHandler::exec()
+{
+  time_t timestamp = time(NULL);
+  std::string uid = getUID("eth0");
+
+  char buf[512];
+  char header[] =
+    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+    "<artefact xmlns=\"http://www.aasimon.org/pentominos\"\n"
+    "          xmlns:pentominos=\"http://www.aasimon.org/pentominos\"\n"
+    "          xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
+    "          xsi:schemaLocation=\"http://www.aasimon.org/pentominos schema.xsd\">\n";
+  socket->write(header, strlen(header));
+
+  sprintf(buf, "  <pentominos:entry cpr=\"%s\"\n"
+          "                    src_addr=\"%s\"\n"
+          "                    dst_addr=\"%s\"\n"
+          "                    timestamp=\"%d\"\n"
+          "                    uid=\"%s\"/>\n",
+          cpr.c_str(),
+          socket->srcaddr().c_str(),
+          socket->dstaddr().c_str(),
+          (unsigned int)timestamp,
+          uid.c_str());
+  socket->write(buf, strlen(buf));
+
+  std::vector< Query >::iterator j = queries.begin();
+  while(j != queries.end()) {
+    Query query = *j;
+
+    sprintf(buf, "  <pentominos:query format=\"pracroxml\"\n"
+            "                    device_id=\"%s\"\n"
+            "                    device_type=\"%s\"\n"
+            "                    filter=\"latest\"\n"
+            "                    location=\"all\"/>\n",
+            query.device_id.c_str(),
+            query.device_type.c_str());
+
+    socket->write(buf, strlen(buf));
+
+    j++;
+  }
+
+  sprintf(buf, "</artefact>\n");
+  socket->write(buf, strlen(buf));
+
+  // Terminate
+  socket->write("\0", 1);
+
+  // Wait for answer
+  char abuf[64];
+  int res;
+  std::string answer;
+  do {
+    memset(abuf, 0, sizeof(abuf));
+    res = socket->read(abuf, sizeof(abuf) - 1);
+    answer += abuf;
+  } while(res);
+
+  return answer;
+}
+
+#ifdef TEST_QUERYHANDLER
+
+int main()
+{
+  TCPSocket s;
+  s.connect("localhost", 11108);
+
+  QueryHandler qh(&s, "2003791613");
+
+  Query q1("lensmeter", "lensmeter");
+  qh.addQuery(q1);
+
+  std::string res = qh.exec();
+  
+  printf("%s\n", res.c_str());
+
+  return 0;
+}
+
+#endif/*TEST_QUERYHANDLER*/
diff --git a/server/src/queryhandler.h b/server/src/queryhandler.h
index 2de62ae..14e97c2 100644
--- a/server/src/queryhandler.h
+++ b/server/src/queryhandler.h
@@ -27,20 +27,41 @@
 #ifndef __PRACRO_QUERYHANDLER_H__
 #define __PRACRO_QUERYHANDLER_H__
 
-class Query {};
+#include "tcpsocket.h"
+
+#include <vector>
+#include <string>
+
+/**
+ * Query specific values. This is the in-memory representation of a query transaction.
+ */
+class Query {
+public:
+  Query(std::string id, std::string type) :
+    device_id(id), device_type(type) {}
+  std::string device_id;
+  std::string device_type;
+};
+
 
 /**
  * This class handles the query of external data.
  */
 class QueryHandler {
 public:
-  QueryHandler();
+  QueryHandler(TCPSocket *socket, std::string cpr);
 
   // Add a query to the query queue
-  void addQuery(Query &query) {}
+  void addQuery(Query &query);
+
+  // Execute all queries.
+  std::string exec();
+
+private:
+  TCPSocket *socket;
+  std::string cpr;
 
-  // Execute all queries in parallel, for speed improv.
-  void exec() {}
+  std::vector< Query > queries;
 };
 
 #endif/*__PRACRO_QUERYHANDLER_H__*/
diff --git a/server/src/queryparser.cc b/server/src/queryparser.cc
index 38e3037..34c7aa3 100644
--- a/server/src/queryparser.cc
+++ b/server/src/queryparser.cc
@@ -62,7 +62,9 @@ int QueryParser::readData(char *data, size_t size)
   return len;
 }
 
-#ifdef TEST_EXTERNALDATAQUERYPARSER
+#ifdef TEST_QUERYPARSER
+
+#include "queryhandler.h"
 
 static std::string loadresultstring(QueryResult &res, std::string group = "")
 {
@@ -84,24 +86,21 @@ static std::string loadresultstring(QueryResult &res, std::string group = "")
   return s;
 }
 
-char xml[] =
-  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
-  "<group name=\"dims\">\n"
-  "  <value name=\"fisk\" value=\"42\"/>"
-  "  <value name=\"futte\" value=\"bamse\"/>"
-  "  <group name=\"dims2\">\n"
-  "    <value name=\"fisk2\" value=\"42\"/>"
-  "    <value name=\"futte2\" value=\"bamse\"/>"
-  "  </group>\n"
-  "  <group name=\"dims3\">\n"
-  "    <value name=\"fisk3\" value=\"42\"/>"
-  "    <value name=\"futte3\" value=\"bamse\"/>"
-  "  </group>\n"
-  "</group>\n";
-
 int main()
 {
-  QueryParser e(xml);
+  TCPSocket s;
+  s.connect("localhost", 11108);
+
+  QueryHandler qh(&s, "2003791613");
+
+  Query q1("lensmeter", "lensmeter");
+  qh.addQuery(q1);
+
+  std::string res = qh.exec();
+  
+  printf("%s\n", res.c_str());
+
+  QueryParser e(res);
   e.parse();
 
   printf("%s\n", loadresultstring(e.result).c_str());
diff --git a/server/src/saxparser.cc b/server/src/saxparser.cc
index e0d849a..2eabf38 100644
--- a/server/src/saxparser.cc
+++ b/server/src/saxparser.cc
@@ -68,6 +68,11 @@ SAXParser::SAXParser()
   XML_SetElementHandler(p, start_hndl, end_hndl);
 }
 
+SAXParser::~SAXParser()
+{
+  XML_ParserFree(p);
+}
+
 int SAXParser::parse()
 {
   char buf[32];
@@ -77,7 +82,7 @@ int SAXParser::parse()
     len = readData(buf, sizeof(buf) - 1);
     if (! XML_Parse(p, buf, len, len == 0)) {
       fprintf(stderr, "Parse error at line %d:\n%s\n",
-              XML_GetCurrentLineNumber(p),
+              (int)XML_GetCurrentLineNumber(p),
               XML_ErrorString(XML_GetErrorCode(p)));
       return -1;
     }
diff --git a/server/src/saxparser.h b/server/src/saxparser.h
index c03b281..e15b38c 100644
--- a/server/src/saxparser.h
+++ b/server/src/saxparser.h
@@ -34,6 +34,7 @@
 class SAXParser {
 public:
   SAXParser();
+  virtual ~SAXParser();
 
   int parse();
 
diff --git a/server/src/tostring.cc b/server/src/tostring.cc
index bde5498..3179e00 100644
--- a/server/src/tostring.cc
+++ b/server/src/tostring.cc
@@ -70,7 +70,7 @@ std::string toString(short unsigned int su)
 std::string toString(int li)
 {
   char buf[32];
-  sprintf(buf, "%ld", li);
+  sprintf(buf, "%ld", (long int)li);
   std::string out = buf;
   return buf;
 }
@@ -78,7 +78,7 @@ std::string toString(int li)
 std::string toString(unsigned int lu)
 {
   char buf[32];
-  sprintf(buf, "%lu", lu);
+  sprintf(buf, "%lu", (long unsigned int)lu);
   std::string out = buf;
   return buf;
 }
diff --git a/server/src/uid.cc b/server/src/uid.cc
index f9f98ae..7cf3bb8 100644
--- a/server/src/uid.cc
+++ b/server/src/uid.cc
@@ -58,6 +58,6 @@ std::string UID::toString()
 {
   //  std::string uid;
   char buf[256];
-  sprintf(buf, "%08x%04x%02x", time, pid, cnt);
+  sprintf(buf, "%08x%04x%02x", (unsigned int)time, pid, cnt);
   return buf;
 }
-- 
cgit v1.2.3