aboutsummaryrefslogtreecommitdiff
path: root/testing
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2022-04-17 14:15:24 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2022-04-17 14:15:24 +0000
commitf26bb872bf4f043a1b817c808a6947fcb03ecda4 (patch)
tree132ab4d71c41c26fe05e12a57fc9e684ffbd08ec /testing
parent5e7262973c7b0bf753e5e560956c176d9d12424d (diff)
downloadsg3_utils-f26bb872bf4f043a1b817c808a6947fcb03ecda4.tar.gz
sg_lib: add hex2fp(); sg_rtpg: https://github.com/hreinecke/sg3_utils/pull/79 applies; json_builder work
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@944 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'testing')
-rw-r--r--testing/Makefile10
-rw-r--r--testing/sg_mrq_dd.cpp28
-rw-r--r--testing/sg_tst_json_builder.c157
3 files changed, 182 insertions, 13 deletions
diff --git a/testing/Makefile b/testing/Makefile
index 46d00a2e..5d05ad5a 100644
--- a/testing/Makefile
+++ b/testing/Makefile
@@ -7,7 +7,7 @@ MANDIR=$(DESTDIR)/$(PREFIX)/man
EXECS = sg_sense_test sg_queue_tst bsg_queue_tst sg_chk_asc sg_tst_nvme \
sg_tst_ioctl sg_tst_bidi tst_sg_lib sgs_dd sg_tst_excl \
sg_tst_excl2 sg_tst_excl3 sg_tst_context sg_tst_async sgh_dd \
- sg_mrq_dd sg_iovec_tst sg_take_snap
+ sg_mrq_dd sg_iovec_tst sg_take_snap sg_tst_json_builder
EXTRAS =
@@ -49,7 +49,8 @@ LIBFILESOLD = ../lib/sg_lib.o ../lib/sg_lib_data.o ../lib/sg_io_linux.o
LIBFILESNEW = ../lib/sg_pt_linux_nvme.o ../lib/sg_lib.o ../lib/sg_lib_data.o \
../lib/sg_pt_linux.o ../lib/sg_io_linux.o \
../lib/sg_pt_common.o ../lib/sg_cmds_basic.o \
- ../lib/sg_cmds_basic2.o ../lib/sg_lib_names.o
+ ../lib/sg_cmds_basic2.o ../lib/sg_lib_names.o \
+ ../lib/sg_json_builder.o
all: $(EXECS)
@@ -63,7 +64,7 @@ depend dep:
done > .depend
clean:
- /bin/rm -f *.o $(EXECS) $(EXTRAS) $(BSG_EXTRAS) core .depend
+ /bin/rm -f *.o $(EXECS) $(EXTRAS) $(BSG_EXTRAS) json_writer core .depend
sg_sense_test: sg_sense_test.o $(LIBFILESOLD)
$(LD) -o $@ $(LDFLAGS) $^
@@ -120,6 +121,9 @@ sg_iovec_tst: sg_iovec_tst.o sg_scat_gath.o $(LIBFILESNEW)
sg_take_snap: sg_take_snap.o $(LIBFILESNEW)
$(LD) -o $@ $(LDFLAGS) $^
+sg_tst_json_builder: sg_tst_json_builder.o $(LIBFILESNEW)
+ $(LD) -o $@ $(LDFLAGS) $^
+
install: $(EXECS)
install -d $(INSTDIR)
diff --git a/testing/sg_mrq_dd.cpp b/testing/sg_mrq_dd.cpp
index 7b81a63a..9f17146c 100644
--- a/testing/sg_mrq_dd.cpp
+++ b/testing/sg_mrq_dd.cpp
@@ -30,7 +30,7 @@
*
*/
-static const char * version_str = "1.40 20220118";
+static const char * version_str = "1.41 20220413";
#define _XOPEN_SOURCE 600
#ifndef _GNU_SOURCE
@@ -390,6 +390,7 @@ static atomic<int> num_ebusy(0);
static atomic<int> num_start_eagain(0);
static atomic<int> num_fin_eagain(0);
static atomic<int> num_miscompare(0);
+static atomic<int> num_fallthru_sigusr2(0);
static atomic<bool> vb_first_time(true);
static sigset_t signal_set;
@@ -1072,17 +1073,16 @@ siginfo_handler(int sig)
print_stats(" ");
}
-#if 0
+/* Usually this signal (SIGUSR2) will be caught by the timed wait in the
+ * sig_listen_thread thread but some might slip through while the timed
+ * wait is being re-armed or after that thread is finished. This handler
+ * acts as a backstop. */
static void
siginfo2_handler(int sig)
{
if (sig) { ; } /* unused, dummy to suppress warning */
- pr2serr("Progress report, continuing ...\n");
- if (do_time > 0)
- calc_duration_throughput(1);
- print_stats(" ");
+ ++num_fallthru_sigusr2;
}
-#endif
static void
install_handler(int sig_num, void (*sig_handler) (int sig))
@@ -4247,7 +4247,7 @@ main(int argc, char * argv[])
install_handler(SIGQUIT, interrupt_handler);
install_handler(SIGPIPE, interrupt_handler);
install_handler(SIGUSR1, siginfo_handler);
- // install_handler(SIGUSR2, siginfo2_handler);
+ install_handler(SIGUSR2, siginfo2_handler);
num_ifiles = clp->inf_v.size();
num_ofiles = clp->outf_v.size();
@@ -4590,9 +4590,11 @@ jump:
}
std::this_thread::yield(); // not enough it seems
{ /* allow time for SIGUSR2 signal to get through */
- struct timespec tspec = {0, 400000}; /* 400 usecs */
+ struct timespec tspec = {0, 1000000}; /* 1 msec */
+ struct timespec rem;
- nanosleep(&tspec, NULL);
+ while ((nanosleep(&tspec, &rem) < 0) && (EINTR == errno))
+ tspec = rem;
}
}
@@ -4645,5 +4647,11 @@ fini:
if (0 == res)
res = clp->reason_res.load();
sigprocmask(SIG_SETMASK, &orig_signal_set, NULL);
+ if (clp->verbose) {
+ int num_sigusr2 = num_fallthru_sigusr2.load();
+ if (num_sigusr2 > 0)
+ pr2serr("Number of fall-through SIGUSR2 signals caught: %d\n",
+ num_sigusr2);
+ }
return (res >= 0) ? res : SG_LIB_CAT_OTHER;
}
diff --git a/testing/sg_tst_json_builder.c b/testing/sg_tst_json_builder.c
new file mode 100644
index 00000000..f91e600a
--- /dev/null
+++ b/testing/sg_tst_json_builder.c
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
+/*
+ * Simple streaming JSON writer
+ *
+ * This takes care of the annoying bits of JSON syntax like the commas
+ * after elements
+ *
+ * Authors: Stephen Hemminger <stephen@networkplumber.org>
+ *
+ * Borrowed from Linux kernel [5.17.0]: tools/bpf/bpftool/json_writer.[hc]
+ */
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <malloc.h>
+#include <inttypes.h>
+#include <stdint.h>
+
+#include "../lib/sg_json_builder.h"
+
+
+
+static json_serialize_opts out_settings = {
+ json_serialize_mode_multiline,
+ 0,
+ 4
+};
+
+int
+main(int arnum, char * argv[])
+{
+ size_t len;
+ json_value * jv1p;
+ json_value * jv2p;
+ json_value * jv3p = json_object_new(0);
+ json_value * jvp = json_object_new(0);
+ json_value * jv4p;
+ json_value * jv5p;
+ json_value * ja1p = json_array_new(0);
+ json_value * ja2p;
+ json_value * ja3p;
+ json_value * jsp = json_string_new("hello world 1");
+ json_value * js2p = json_string_new("hello world 2");
+ json_value * js3p = json_string_new("hello world 3");
+ json_value * js10 = json_string_new("good-bye world");
+ json_value * js11 = json_string_new("good-bye world 2");
+ json_value * js12 = json_string_new("duplicate name 1");
+ char b[8192];
+
+ jv1p = json_object_push(jvp, "contents", jsp);
+
+ if (jvp == jv1p)
+ printf("jvp == jv1p\n");
+ else
+ printf("jvp != jv1p\n");
+
+#if 1
+ json_array_push(ja1p, js2p);
+ jv2p = json_object_push(jvp, "extra", js3p);
+ if (jv2p)
+ printf("jv2p->type=%d\n", jv2p->type);
+ else
+ printf("jv2p is NULL\n");
+ ja2p = json_array_push(ja1p, json_string_new("hello world 99"));
+ if (ja2p)
+ printf("ja2p->type=%d\n", ja2p->type);
+ else
+ printf("ja2p is NULL\n");
+ // json_object_push(ja2p, "boo", json_string_new("hello world 88"));
+ json_object_push(jvp, "a_array", ja1p);
+ jv4p = json_object_push(jvp, "a_object", jv3p);
+ if (jv4p)
+ printf("jv4p->type=%d\n", jv4p->type);
+ else
+ printf("jv4p is NULL\n");
+ json_object_push(jv4p, "test", js10);
+ json_object_push(jv4p, "test2", js11);
+ json_object_push(jv4p, "test", js12);
+ // ja3p = json_array_push(ja2p, json_string_new("good-bye"));
+ // jv4p = json_object_push(jvp, "a_array", ja2p);
+ // jv5p = json_object_merge(jvp, ja1p);
+#endif
+ jv5p = jvp;
+
+ jv1p = json_string_new("boo");
+
+ len = json_measure_ex(jv5p, out_settings);
+ printf("jvp length: %zu bytes\n", len);
+ if (len < sizeof(b)) {
+ json_serialize_ex(b, jv5p, out_settings);
+ printf("json serialized:\n");
+ printf("%s\n", b);
+ } else
+ printf("since json output length [%zu] > 8192, skip outputting\n",
+ len);
+
+ json_builder_free(jvp);
+ return 0;
+}
+
+
+#if 0
+int main(int argc, char **argv)
+{
+ json_writer_t *wr = jsonw_new(stdout);
+
+ jsonw_start_object(wr);
+ jsonw_pretty(wr, true);
+ jsonw_name(wr, "Vyatta");
+ jsonw_start_object(wr);
+ jsonw_string_field(wr, "url", "http://vyatta.com");
+ jsonw_uint_field(wr, "downloads", 2000000ul);
+ jsonw_float_field(wr, "stock", 8.16);
+
+ jsonw_name(wr, "ARGV");
+ jsonw_start_array(wr);
+ while (--argc)
+ jsonw_string(wr, *++argv);
+ jsonw_end_array(wr);
+
+ jsonw_name(wr, "empty");
+ jsonw_start_array(wr);
+ jsonw_end_array(wr);
+
+ jsonw_name(wr, "NIL");
+ jsonw_start_object(wr);
+ jsonw_end_object(wr);
+
+ jsonw_null_field(wr, "my_null");
+
+ jsonw_name(wr, "special chars");
+ jsonw_start_array(wr);
+ jsonw_string_field(wr, "slash", "/");
+ jsonw_string_field(wr, "newline", "\n");
+ jsonw_string_field(wr, "tab", "\t");
+ jsonw_string_field(wr, "ff", "\f");
+ jsonw_string_field(wr, "quote", "\"");
+ jsonw_string_field(wr, "tick", "\'");
+ jsonw_string_field(wr, "backslash", "\\");
+ jsonw_end_array(wr);
+
+jsonw_name(wr, "ARGV");
+jsonw_start_array(wr);
+jsonw_string(wr, "boo: appended or new entry?");
+jsonw_end_array(wr);
+
+ jsonw_end_object(wr);
+
+ jsonw_end_object(wr);
+ jsonw_destroy(&wr);
+ return 0;
+}
+
+#endif
+