v4-0007-Adding-frontend-tests-for-json-parser.patch
application/octet-stream
Filename: v4-0007-Adding-frontend-tests-for-json-parser.patch
Type: application/octet-stream
Part: 1
Patch
Format: format-patch
Series: patch v4-0007
Subject: Adding frontend tests for json parser.
| File | + | − |
|---|---|---|
| src/Makefile | 3 | 1 |
| src/test/bin/.gitignore | 1 | 0 |
| src/test/bin/Makefile | 41 | 0 |
| src/test/bin/README | 15 | 0 |
| src/test/bin/t/001_test_json.pl | 47 | 0 |
| src/test/bin/test_json.c | 67 | 0 |
| src/test/Makefile | 4 | 3 |
From f2f2792ec244a59a3773ad654d1478a1d48ac81c Mon Sep 17 00:00:00 2001
From: Mark Dilger <mark.dilger@enterprisedb.com>
Date: Sun, 26 Jan 2020 10:41:37 -0800
Subject: [PATCH 2/2] Adding frontend tests for json parser.
Creating tests in new directory src/test/bin for testing
that the json parser can be included and used from within
a frontend standalone binary.
---
src/Makefile | 4 +-
src/test/Makefile | 7 ++--
src/test/bin/.gitignore | 1 +
src/test/bin/Makefile | 41 ++++++++++++++++++++
src/test/bin/README | 15 ++++++++
src/test/bin/t/001_test_json.pl | 48 +++++++++++++++++++++++
src/test/bin/test_json.c | 67 +++++++++++++++++++++++++++++++++
7 files changed, 179 insertions(+), 4 deletions(-)
create mode 100644 src/test/bin/.gitignore
create mode 100644 src/test/bin/Makefile
create mode 100644 src/test/bin/README
create mode 100644 src/test/bin/t/001_test_json.pl
create mode 100644 src/test/bin/test_json.c
diff --git a/src/Makefile b/src/Makefile
index bcdbd9588a..ccd4bab0de 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -2,7 +2,8 @@
#
# Makefile for src
#
-# Copyright (c) 1994, Regents of the University of California
+# Portions Copyright (c) 1994, Regents of the University of California
+# Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
#
# src/Makefile
#
@@ -27,6 +28,7 @@ SUBDIRS = \
bin \
pl \
makefiles \
+ test/bin \
test/regress \
test/isolation \
test/perl
diff --git a/src/test/Makefile b/src/test/Makefile
index efb206aa75..e24732f190 100644
--- a/src/test/Makefile
+++ b/src/test/Makefile
@@ -12,7 +12,7 @@ subdir = src/test
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
-SUBDIRS = perl regress isolation modules authentication recovery subscription
+SUBDIRS = bin perl regress isolation modules authentication recovery subscription
# Test suites that are not safe by default but can be run if selected
# by the user via the whitespace-separated list in variable
@@ -40,10 +40,11 @@ endif
ALWAYS_SUBDIRS = $(filter-out $(SUBDIRS),examples kerberos ldap locale thread ssl)
# We want to recurse to all subdirs for all standard targets, except that
-# installcheck and install should not recurse into the subdirectory "modules".
+# installcheck and install should not recurse into the subdirectory "modules"
+# nor "bin".
recurse_alldirs_targets := $(filter-out installcheck install, $(standard_targets))
-installable_dirs := $(filter-out modules, $(SUBDIRS))
+installable_dirs := $(filter-out modules bin, $(SUBDIRS))
$(call recurse,$(recurse_alldirs_targets))
$(call recurse,installcheck, $(installable_dirs))
diff --git a/src/test/bin/.gitignore b/src/test/bin/.gitignore
new file mode 100644
index 0000000000..6709c749d8
--- /dev/null
+++ b/src/test/bin/.gitignore
@@ -0,0 +1 @@
+test_json
diff --git a/src/test/bin/Makefile b/src/test/bin/Makefile
new file mode 100644
index 0000000000..3eee9091bc
--- /dev/null
+++ b/src/test/bin/Makefile
@@ -0,0 +1,41 @@
+#-------------------------------------------------------------------------
+#
+# Makefile for src/test/bin
+#
+# Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
+# Portions Copyright (c) 1994, Regents of the University of California
+#
+# src/bin/bin/Makefile
+#
+#-------------------------------------------------------------------------
+
+PGFILEDESC = "bin - the PostgreSQL standalone code binaries for testing"
+PGAPPICON=win32
+
+subdir = src/test/bin
+top_builddir = ../../..
+include $(top_builddir)/src/Makefile.global
+
+# make this available to TAP test scripts
+export with_readline
+
+REFDOCDIR= $(top_srcdir)/doc/src/sgml/ref
+
+override CPPFLAGS := -I. -I$(srcdir) -I$(libpq_srcdir) $(CPPFLAGS)
+LDFLAGS_INTERNAL += -L$(top_builddir)/src/fe_utils -lpgfeutils $(libpq_pgport)
+
+OBJS = \
+ $(WIN32RES) \
+ test_json.o
+
+all: test_json
+
+test_json: $(OBJS) | submake-libpq submake-libpgport submake-libpgfeutils
+ $(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)
+
+check:
+ PATH="$(abs_top_builddir)/src/test/bin:$$PATH" $(prove_check)
+
+clean distclean maintainer-clean:
+ rm -f test_json$(X) $(OBJS)
+ rm -rf tmp_check
diff --git a/src/test/bin/README b/src/test/bin/README
new file mode 100644
index 0000000000..214671af88
--- /dev/null
+++ b/src/test/bin/README
@@ -0,0 +1,15 @@
+src/test/bin/README
+
+Binary executable tests
+=======================
+
+This directory contains a set of programs that exercise functionality declared
+in src/include/common and defined in src/common. The purpose of these programs
+is to verify that code intended to work both from frontend and backend code do
+indeed work when compiled and used in frontend code. The structure of this
+directory makes no attempt to test that such code works in the backend, as the
+backend has its own tests already, and presumably those tests sufficiently
+exercide the code as used by it.
+
+These test programs are part of the tap-test suite. Configure with tap tests
+enabled or these tests will be skipped.
diff --git a/src/test/bin/t/001_test_json.pl b/src/test/bin/t/001_test_json.pl
new file mode 100644
index 0000000000..08e15c956d
--- /dev/null
+++ b/src/test/bin/t/001_test_json.pl
@@ -0,0 +1,48 @@
+# Basic logical replication test
+use strict;
+use warnings;
+use TestLib ();
+use Cwd;
+
+use Test::More tests => 83;
+
+# There doesn't seem to be any easy way to get TestLib to use the binaries from
+# our directory, so we hack up a path to our binary and run that directly. This
+# seems brittle enough that some other solution should be found, if possible.
+
+my $test_json = join('/', $ENV{TESTDIR}, 'test_json');
+
+ok(-f $test_json, "test_json file exists");
+ok(-x $test_json, "test_json file is executable");
+
+# Verify some valid JSON is accepted by our parser
+TestLib::command_like( [$test_json, q/null/ ], qr{\bVALID\b}, "null");
+TestLib::command_like( [$test_json, q/{}/ ], qr{\bVALID\b}, "empty object");
+TestLib::command_like( [$test_json, q/[]/ ], qr{\bVALID\b}, "empty array");
+TestLib::command_like( [$test_json, q/-12345/ ], qr{\bVALID\b}, "negative integer");
+TestLib::command_like( [$test_json, q/-1/ ], qr{\bVALID\b}, "negative integer");
+TestLib::command_like( [$test_json, q/0/ ], qr{\bVALID\b}, "zero");
+TestLib::command_like( [$test_json, q/1/ ], qr{\bVALID\b}, "positive integer");
+TestLib::command_like( [$test_json, q/12345/ ], qr{\bVALID\b}, "positive integer");
+TestLib::command_like( [$test_json, q/-1.23456789/], qr{\bVALID\b}, "negative float");
+TestLib::command_like( [$test_json, q/1.23456789/ ], qr{\bVALID\b}, "positive float");
+TestLib::command_like( [$test_json, q/{"a": "b"}/ ], qr{\bVALID\b}, "object");
+TestLib::command_like( [$test_json, q/["a", "b"]/ ], qr{\bVALID\b}, "array");
+TestLib::command_like( [$test_json, q/"pigs feet"/], qr{\bVALID\b}, 'text string');
+
+# Verify some invalid JSON is rejected by our parser
+TestLib::command_like( [$test_json, q/{/ ], qr{\bINVALID\b}, 'unclosed object');
+TestLib::command_like( [$test_json, q/[/ ], qr{\bINVALID\b}, 'unclosed array');
+TestLib::command_like( [$test_json, q/(/ ], qr{\bINVALID\b}, 'unclosed parenthesis');
+TestLib::command_like( [$test_json, q/}/ ], qr{\bINVALID\b}, 'unopened object');
+TestLib::command_like( [$test_json, q/]/ ], qr{\bINVALID\b}, 'unopened array');
+TestLib::command_like( [$test_json, q/)/ ], qr{\bINVALID\b}, 'unopened parenthesis');
+TestLib::command_like( [$test_json, q/{{{}}/ ], qr{\bINVALID\b}, 'unbalanced object curlies');
+TestLib::command_like( [$test_json, q/{{}}}/ ], qr{\bINVALID\b}, 'unbalanced object curlies');
+TestLib::command_like( [$test_json, q/[[[]]/ ], qr{\bINVALID\b}, 'unbalanced array braces');
+TestLib::command_like( [$test_json, q/[[]]]/ ], qr{\bINVALID\b}, 'unbalanced array braces');
+TestLib::command_like( [$test_json, q/((())/ ], qr{\bINVALID\b}, 'unbalanced array braces');
+TestLib::command_like( [$test_json, q/(()))/ ], qr{\bINVALID\b}, 'unbalanced array braces');
+TestLib::command_like( [$test_json, q/1 7 13/ ], qr{\bINVALID\b}, 'integer sequence');
+TestLib::command_like( [$test_json, q/{"a", "b"}/ ], qr{\bINVALID\b}, 'mixed object and array syntax');
diff --git a/src/test/bin/test_json.c b/src/test/bin/test_json.c
new file mode 100644
index 0000000000..567a35f3b0
--- /dev/null
+++ b/src/test/bin/test_json.c
@@ -0,0 +1,67 @@
+/*
+ * pg_test_json.c
+ * tests validity of json strings against parser implementation.
+ */
+
+#include "postgres_fe.h"
+
+#include "common/jsonapi.h"
+#include "libpq-fe.h"
+
+static const char *progname;
+
+static void parse_json(const char *str);
+
+int
+main(int argc, char *argv[])
+{
+ int argidx;
+
+ set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_test_json"));
+ progname = get_progname(argv[0]);
+
+ /*
+ * Make stdout unbuffered to match stderr; and ensure stderr is unbuffered
+ * too, which it should already be everywhere except sometimes in Windows.
+ */
+ setbuf(stdout, NULL);
+ setbuf(stderr, NULL);
+
+ if (argc > 1)
+ {
+ if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
+ {
+ printf(_("Usage: %s jsonstr [, ...]\n"), progname);
+ exit(0);
+ }
+ if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
+ {
+ puts("pg_test_json (PostgreSQL) " PG_VERSION);
+ exit(0);
+ }
+ }
+
+ for (argidx = 1; argidx < argc; argidx++)
+ parse_json(argv[argidx]);
+
+ return 0;
+}
+
+static void
+parse_json(const char *str)
+{
+ char *json;
+ unsigned int json_len;
+ JsonLexContext *lex;
+ int client_encoding;
+ JsonParseErrorType parse_result;
+
+ json_len = (unsigned int) strlen(str);
+ client_encoding = PQenv2encoding();
+
+ json = strdup(str);
+ lex = makeJsonLexContextCstringLen(json, strlen(json), client_encoding, true /* need_escapes */);
+ parse_result = pg_parse_json(lex, &nullSemAction);
+ fprintf(stdout, _("%s\n"), (JSON_SUCCESS == parse_result ? "VALID" : "INVALID"));
+ return;
+}
--
2.21.1 (Apple Git-122.3)