[git] GPGME - branch, aheinecke/json-test, created. gpgme-1.12.0-54-g0c31837

by Andre Heinecke cvs at cvs.gnupg.org
Wed Nov 14 11:51:38 CET 2018


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GnuPG Made Easy".

The branch, aheinecke/json-test has been created
        at  0c31837766e016227b3c8dfd44c476949cd4741e (commit)

- Log -----------------------------------------------------------------
commit 0c31837766e016227b3c8dfd44c476949cd4741e
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Wed Nov 14 11:47:59 2018 +0100

    tests: Add json testrunner
    
    * configure.ac: Configure makefile.
    * tests/Makefile.am: Run json tests if gpg tests are run.
    * tests/json/t-json.c: New testrunner for json tests.
    * tests/json/t-config.in, tests/json/t-config.out: First test.
    --
    The idea of this test runner is that it only looks for parts
    in the output. This should allow it to write robust tests
    that check for the basics in the output but don't fail when
    the output is extended or slightly changed.

diff --git a/configure.ac b/configure.ac
index b733a9c..4976b5b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -853,6 +853,7 @@ AC_CONFIG_FILES(Makefile src/Makefile
                 tests/gpg/Makefile
                 tests/gpgsm/Makefile
                 tests/opassuan/Makefile
+                tests/json/Makefile
 		doc/Makefile
                 src/versioninfo.rc
                 src/gpgme.pc
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b5825d2..29e0c42 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -38,7 +38,7 @@ noinst_PROGRAMS = $(TESTS) run-keylist run-export run-import run-sign \
 
 
 if RUN_GPG_TESTS
-gpgtests = gpg
+gpgtests = gpg json
 else
 gpgtests =
 endif
diff --git a/tests/json/t-config.in b/tests/json/t-config.in
new file mode 100644
index 0000000..22b37ee
--- /dev/null
+++ b/tests/json/t-config.in
@@ -0,0 +1,4 @@
+{
+    "op": "config",
+    "component": "gpg"
+}
diff --git a/tests/json/t-config.out b/tests/json/t-config.out
new file mode 100644
index 0000000..fce36a0
--- /dev/null
+++ b/tests/json/t-config.out
@@ -0,0 +1,19 @@
+{
+    "components":   [{
+        "name": "gpg",
+            "description":  "OpenPGP",
+            "options":      [{
+                "name": "Monitor",
+                "flags":        1,
+                "level":        0,
+                "type": 0,
+                "alt_type":     0
+            }, {
+                "name": "verbose",
+                "description":  "verbose",
+                "level":        0,
+                "type": 0,
+                "alt_type":     0
+            }]
+    }]
+}
diff --git a/tests/json/t-json.c b/tests/json/t-json.c
new file mode 100644
index 0000000..ec294f7
--- /dev/null
+++ b/tests/json/t-json.c
@@ -0,0 +1,344 @@
+/* t-json.c - Regression test.
+   Copyright (C) 2018 Bundesamt für Sicherheit in der Informationstechnik
+                      Software engineering by Intevation GmbH
+
+   This file is part of GPGME.
+
+   GPGME is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of
+   the License, or (at your option) any later version.
+
+   GPGME is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+#include <gpgme.h>
+#include <gpg-error.h>
+
+#include "../gpg/t-support.h"
+#include "../../src/cJSON.h"
+
+/* Register tests here */
+static const char*tests[] = { "t-config", NULL };
+
+static int verbose = 0;
+
+static char *
+get_file (const char *fname)
+{
+  gpg_error_t err;
+  gpgrt_stream_t fp;
+  struct stat st;
+  char *buf;
+  size_t buflen;
+
+  fp = gpgrt_fopen (fname, "r");
+  if (!fp)
+    {
+      err = gpg_error_from_syserror ();
+      fprintf (stderr, "Error: can't open '%s': %s\n", fname,
+               gpg_strerror (err));
+      return NULL;
+    }
+
+  if (fstat (gpgrt_fileno(fp), &st))
+    {
+      err = gpg_error_from_syserror ();
+      fprintf (stderr, "Error: can't stat '%s': %s\n", fname,
+               gpg_strerror (err));
+      gpgrt_fclose (fp);
+      return NULL;
+    }
+
+  buflen = st.st_size;
+  buf = malloc (buflen+1);
+  if (!buf)
+    {
+      fprintf (stderr, "Error: no mem\n");
+      gpgrt_fclose (fp);
+      return NULL;
+    }
+
+  if (gpgrt_fread (buf, buflen, 1, fp) != 1)
+    {
+      err = gpg_error_from_syserror ();
+      fprintf (stderr, "error reading '%s': %s\n", fname, gpg_strerror (err));
+      gpgrt_fclose (fp);
+      free (buf);
+      return NULL;
+    }
+  buf[buflen] = 0;
+  gpgrt_fclose (fp);
+
+  return buf;
+}
+
+/* Check that the element needle exists in hay. Returns 0 if
+   the needle was found. */
+int
+test_contains (cjson_t needle, cjson_t hay)
+{
+  /*fprintf (stderr, "checking \n%s\n -------against-------- \n%s\n",
+           cJSON_Print (needle), cJSON_Print (hay)); */
+
+  /* Type check. This automatically checks bool vals and NULL */
+  if (needle->type != hay->type)
+    {
+      if (verbose)
+        fprintf (stderr, "type mismatch expected %i got %i\n", needle->type,
+                 hay->type);
+      return 1;
+    }
+
+  /* First the simple types */
+  if (cjson_is_number (needle))
+    {
+      if (needle->valueint != hay->valueint)
+        {
+          if (verbose)
+            fprintf (stderr, "Value mismatch. Expected %i got %i\n",
+                     needle->valueint, hay->valueint);
+          return 1;
+        }
+    }
+  if (cjson_is_string (needle))
+    {
+      if (strcmp (needle->valuestring, hay->valuestring))
+        {
+          if (verbose)
+            fprintf (stderr, "String mismatch Expected '%s' got '%s'\n",
+                     needle->valuestring, hay->valuestring);
+          return 1;
+        }
+    }
+
+  /* Now the complex types */
+  if (needle->child)
+    {
+      if (!hay->child)
+        {
+          fprintf (stderr, "Depth mismatch. Expected child for %s\n",
+                   nonnull (needle->string));
+        }
+      if (test_contains (needle->child, hay->child))
+        {
+          return 1;
+        }
+    }
+
+  if (needle->prev)
+    {
+      return 0;
+    }
+
+  /* Walk elements of an array */
+  for (cjson_t it = needle->next; it; it = it->next)
+    {
+      int found = 0;
+      if (!it->string && it->child)
+        {
+          /* Try out all other anonymous children on the same level */
+          cjson_t hit = hay;
+          /* Return to the beginning */
+          while (hit->prev)
+            {
+              hit = hit->prev;
+            }
+          for (; hit && hit->child; hit = hit->next)
+            {
+              found |= !test_contains (it->child, hit->child);
+              if (found)
+                {
+                  break;
+                }
+            }
+          if (!found)
+            {
+              return 1;
+            }
+          continue;
+        }
+
+      /* Try the children in the haystack */
+      for (cjson_t hit = hay; hit; hit = hit->next)
+        {
+          if (hit->string && it->string &&
+              !strcmp (hit->string, it->string))
+            {
+              found = 1;
+              if (test_contains (it, hit))
+                {
+                  return 1;
+                }
+            }
+        }
+      if (!found)
+        {
+          if (verbose)
+            fprintf (stderr, "Failed to find '%s' in list\n",
+                     nonnull (it->string));
+          return 1;
+        }
+    }
+  return 0;
+}
+
+
+int
+check_response (const char *response, const char *expected)
+{
+  cjson_t hay;
+  cjson_t needle;
+  int rc;
+  size_t erroff;
+
+  hay = cJSON_Parse (response, &erroff);
+
+  if (!hay)
+    {
+      fprintf (stderr, "Failed to parse json at %i:\n%s\n", (int) erroff,
+               response);
+      return 1;
+    }
+  needle = cJSON_Parse (expected, &erroff);
+  if (!needle)
+    {
+      fprintf (stderr, "Failed to parse json at %i:\n%s\n", (int) erroff,
+               expected);
+      cJSON_Delete (hay);
+      return 1;
+    }
+
+  rc = test_contains (needle, hay);
+
+  cJSON_Delete (needle);
+  cJSON_Delete (hay);
+  return rc;
+}
+
+
+int
+run_test (const char *test, const char *gpgme_json)
+{
+  gpgme_ctx_t ctx;
+  gpgme_data_t json_stdin = NULL;
+  gpgme_data_t json_stdout = NULL;
+  gpgme_data_t json_stderr = NULL;
+  char *test_in;
+  char *test_out;
+  const char *argv[2];
+  char *response;
+  char *expected;
+  size_t response_size;
+  int rc = 0;
+  const char *top_srcdir = getenv ("top_srcdir");
+
+  if (!top_srcdir)
+    {
+      fprintf (stderr, "Error top_srcdir environment variable not set\n");
+      exit(1);
+    }
+
+  gpgrt_asprintf (&test_in, "%s//tests//json//%s.in",
+                  top_srcdir, test);
+  gpgrt_asprintf (&test_out, "%s//tests//json//%s.out",
+                  top_srcdir, test);
+
+  printf ("Running %s...\n", test);
+
+  fail_if_err (gpgme_new (&ctx));
+
+  gpgme_set_protocol (ctx, GPGME_PROTOCOL_SPAWN);
+
+  fail_if_err (gpgme_data_new_from_file (&json_stdin, test_in, 1));
+  fail_if_err (gpgme_data_new (&json_stdout));
+  fail_if_err (gpgme_data_new (&json_stderr));
+
+  argv[0] = gpgme_json;
+  argv[1] = "-s";
+
+  fail_if_err (gpgme_op_spawn (ctx, gpgme_json, argv,
+                               json_stdin,
+                               json_stdout,
+                               json_stderr,
+                               0));
+  response = gpgme_data_release_and_get_mem (json_stdout,
+                                             &response_size);
+  test (response_size);
+
+  expected = get_file (test_out);
+
+  test (expected);
+
+  rc = check_response (response, expected);
+
+  if (!rc)
+    {
+      printf (" success\n");
+      gpgme_data_release (json_stderr);
+    }
+  else
+    {
+      char *buf;
+      size_t size;
+
+      buf = gpgme_data_release_and_get_mem (json_stderr, &size);
+      printf (" failed\n");
+      if (size)
+        {
+          printf ("gpgme-json stderr:\n%.*s\n", (int)size, buf);
+        }
+      free (buf);
+    }
+
+  free (test_out);
+  free (test_in);
+  free (response);
+  free (expected);
+  gpgme_data_release (json_stdin);
+  gpgme_release (ctx);
+
+  return rc;
+}
+
+int
+main (int argc, char *argv[])
+{
+  const char *gpgme_json = getenv ("gpgme_json");
+
+  if (argc == 2 && !strcmp (argv[1], "--verbose"))
+    {
+      /* Note that verbose will print out lots of mismatchs
+         because we have to try trough anonymous objects */
+      verbose = 1;
+    }
+
+
+  init_gpgme (GPGME_PROTOCOL_SPAWN);
+
+  for (const char **test = tests; *test; test++)
+    {
+      if (run_test (*test, gpgme_json))
+        {
+          exit(1);
+        }
+    }
+  return 0;
+}

-----------------------------------------------------------------------


hooks/post-receive
-- 
GnuPG Made Easy
http://git.gnupg.org




More information about the Gnupg-commits mailing list