Add basic testing code.
authorlinus <linus@nordu.net>
Wed, 19 Jan 2011 15:47:37 +0000 (16:47 +0100)
committerlinus <linus@nordu.net>
Wed, 19 Jan 2011 15:47:37 +0000 (16:47 +0100)
lib/tests/Makefile.am [new file with mode: 0644]
lib/tests/test-udp.c [new file with mode: 0644]
lib/tests/test.conf [new file with mode: 0644]
lib/tests/udp-server.c [new file with mode: 0644]
lib/tests/udp.c [new file with mode: 0644]
lib/tests/udp.h [new file with mode: 0644]

diff --git a/lib/tests/Makefile.am b/lib/tests/Makefile.am
new file mode 100644 (file)
index 0000000..243719f
--- /dev/null
@@ -0,0 +1,10 @@
+AUTOMAKE_OPTIONS = foreign
+INCLUDES = -I$(top_srcdir)/include
+AM_CFLAGS = -Wall -g
+
+bin_PROGRAMS = test-udp udp-server
+
+test_udp_SOURCES = test-udp.c
+test_udp_LDADD = ../libradsec.la -lcgreen -lm
+
+udp_server_SOURCES = udp-server.c udp.c
diff --git a/lib/tests/test-udp.c b/lib/tests/test-udp.c
new file mode 100644 (file)
index 0000000..3ebbc96
--- /dev/null
@@ -0,0 +1,84 @@
+#include <stdlib.h>
+#include <cgreen/cgreen.h>
+#include <freeradius/libradius.h>
+#include "radsec/radsec.h"
+#include "radsec/request.h"
+
+#define true 1                 /* FIXME: Bug report cgreen.  */
+#define false 0
+
+#define FREERADIUS_DICT "/usr/share/freeradius/dictionary"
+
+void
+authenticate (struct rs_connection *conn, const char *user, const char *pw)
+{
+  struct rs_request *req;
+  struct rs_packet *msg, *resp;
+
+  assert_true (rs_request_create (conn, &req) == 0);
+  assert_true (rs_packet_create_auth_request (conn, &msg, user, pw) == 0);
+  assert_true (rs_request_send (req, msg, &resp) == 0);
+  assert_true (rs_packet_frpkt (resp)->code == PW_AUTHENTICATION_ACK);
+
+  rs_request_destroy(req);
+}
+
+#if 0
+int
+send_more_than_one_msg_in_one_packet (const char *server)
+{
+  struct rs_request *req;
+  struct rs_packet *msg, *resp;
+
+
+
+}
+#endif
+
+/* ************************************************************ */
+static struct setup {
+  char *config_file;
+  char *config_name;
+  char *username;
+  char *pw;
+} setup;
+
+void
+test_auth ()
+{
+  struct rs_context *ctx;
+  struct rs_connection *conn;
+
+  assert_true (rs_context_create (&ctx, FREERADIUS_DICT) == 0);
+  assert_true (rs_context_read_config (ctx, setup.config_file) == 0);
+  assert_true (rs_conn_create (ctx, &conn, setup.config_name) == 0);
+
+  authenticate (conn, setup.username, setup.pw);
+
+  rs_conn_destroy (conn);
+  rs_context_destroy (ctx);
+}
+
+int
+test_udp (int argc, char *argv[], TestSuite *ts)
+{
+  add_test (ts, test_auth);
+
+  if (argc > 1)
+    return run_single_test (ts, argv[1], create_text_reporter ());
+
+  return run_test_suite (ts, create_text_reporter ());
+}
+
+int
+main (int argc, char *argv[])
+{
+  TestSuite *ts = create_test_suite ();
+
+  setup.config_file = "test.conf";
+  setup.config_name = "test-udp";
+  setup.username = "molgan";
+  setup.pw = "password";
+
+  return test_udp (argc, argv, ts);
+}
diff --git a/lib/tests/test.conf b/lib/tests/test.conf
new file mode 100644 (file)
index 0000000..2f65a80
--- /dev/null
@@ -0,0 +1,8 @@
+config test-udp {
+    type = "UDP"
+    server {
+        hostname = "localhost"
+       service = "1820"
+       secret = "sikrit"
+    }
+}
diff --git a/lib/tests/udp-server.c b/lib/tests/udp-server.c
new file mode 100644 (file)
index 0000000..9275e10
--- /dev/null
@@ -0,0 +1,47 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include "udp.h"
+
+ssize_t
+handle_data (const uint8_t *buf, ssize_t len)
+{
+  int i;
+
+  printf ("# len: %ld\n", len);
+  for (i = 0; i < len; i++)
+    {
+      printf ("%02x%s", buf[i], (i+1) % 8 ? " " : "   ");
+      if ((i + 1) % 16 == 0)
+       printf ("\n");
+    }
+  printf ("\n");
+  return len;
+}
+
+int
+main (int argc, char *argv[])
+{
+  int n, i;
+  struct timeval tv;
+  struct polldata *data;
+
+#define TIMEOUT 1              /* Seconds.  */
+
+  tv.tv_sec = TIMEOUT;
+  tv.tv_usec = 0;
+  data = server (argv[1], &tv, handle_data);
+
+  for (i = 0, n = poll (data); n == 0 && i < 3; n = poll (data), i++)
+    {
+      fprintf (stderr, "waiting another %ld second%s\n",
+              tv.tv_sec, tv.tv_sec > 1 ? "s" : "");
+    }
+
+  if (data)
+    {
+      if (data->timeout)
+       free (data->timeout);
+      free (data);
+    }
+  return (n <= 0);
+}
diff --git a/lib/tests/udp.c b/lib/tests/udp.c
new file mode 100644 (file)
index 0000000..6c43a2f
--- /dev/null
@@ -0,0 +1,108 @@
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+#include <stdio.h>
+#include <event2/event.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/types.h>
+#include <netdb.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include "udp.h"
+
+static struct addrinfo *
+_resolve (const char *str)
+{
+  static int first = 1;
+  static struct addrinfo hints, *result = NULL;
+  struct addrinfo *rp = NULL;
+  int r;
+
+  if (first)
+    {
+      first = 0;
+      memset (&hints, 0, sizeof (hints));
+      hints.ai_family = AF_INET; /* AF_UNSPEC */
+      hints.ai_socktype = SOCK_DGRAM;
+      r = getaddrinfo (NULL, str, &hints, &result);
+      if (r)
+       fprintf (stderr, "getaddrinfo: %s\n", gai_strerror (r));
+    }
+
+  if (result)
+    {
+      rp = result;
+      result = result->ai_next;
+    }
+
+  return rp;
+}
+
+ssize_t
+poll (struct polldata *data)
+{
+  int r;
+  long timeout;
+  fd_set rfds;
+  ssize_t len;
+  uint8_t buf[4096];
+
+  FD_ZERO (&rfds);
+  FD_SET (data->s, &rfds);
+  if (data->timeout)
+    timeout = data->timeout->tv_sec; /* Save from destruction (Linux).  */
+  //fprintf (stderr, "calling select with timeout %ld\n", timeout);
+  r = select (data->s + 1, &rfds, NULL, NULL, data->timeout);
+  if (data->timeout)
+    data->timeout->tv_sec = timeout; /* Restore.  */
+  //fprintf (stderr, "select returning %d\n", r);
+  if (r > 0)
+    {
+      len = recv (data->s, buf, sizeof (buf), 0);
+      if (len > 0)
+       return data->cb (buf, len);
+    }
+  return r;
+}
+
+struct polldata *
+server (const char *bindto, struct timeval *timeout, data_cb cb)
+{
+  struct addrinfo *res;
+  int s = -1;
+
+  for (res = _resolve (bindto); res; res = _resolve (bindto))
+    {
+      s = socket (res->ai_family, res->ai_socktype, res->ai_protocol);
+      if (s >= 0)
+       {
+         if (bind (s, res->ai_addr, res->ai_addrlen) == 0)
+           break;              /* Done.  */
+         else
+           {
+             close (s);
+             s = -1;
+           }
+       }
+    }
+
+  if (s >= 0)
+    {
+      struct polldata *data = malloc (sizeof (struct polldata));
+      assert (data);
+      memset (data, 0, sizeof (struct polldata));
+      data->s = s;
+      data->cb = cb;
+      if (timeout)
+       {
+         data->timeout = malloc (sizeof (struct timeval));
+         assert (data->timeout);
+         memcpy (data->timeout, timeout, sizeof (struct timeval));
+       }
+      return data;
+    }
+
+  return NULL;
+}
diff --git a/lib/tests/udp.h b/lib/tests/udp.h
new file mode 100644 (file)
index 0000000..402295f
--- /dev/null
@@ -0,0 +1,14 @@
+#include <stdint.h>
+#include <unistd.h>
+#include <sys/time.h>
+//#include <sys/types.h>
+
+typedef ssize_t (*data_cb) (const uint8_t *buf, ssize_t len);
+struct polldata {
+  int s;
+  data_cb cb;
+  struct timeval *timeout;
+};
+
+struct polldata *server (const char *bindto, struct timeval *timeout, data_cb cb);
+ssize_t poll (struct polldata *data);