From: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
To: igt-dev@lists.freedesktop.org
Cc: Petri Latvala <petri.latvala@intel.com>
Subject: [igt-dev] [PATCH i-g-t 1/5] lib/igt_core: Add support for subtest descriptions
Date: Mon, 17 Jun 2019 13:54:39 +0300 [thread overview]
Message-ID: <20190617105443.8264-1-arkadiusz.hiler@intel.com> (raw)
This patch adds igt_description() which attaches a description to the
following igt_subtest or igt_subtest_group block.
Descriptions are accessible via './test --describe[=pattern]'
Subtest description is its own igt_describe as well as igt_describes
of all the parenting igt_subtest_groups, starting from the outermost
scope.
Examples of code and produced outputs are included in
lib/test/igt_describe.c and as a documentation comment on igt_describe()
macro.
Cc: Petri Latvala <petri.latvala@intel.com>
Signed-off-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
---
lib/igt_core.c | 179 ++++++++++++++++++++++++--
lib/igt_core.h | 137 ++++++++++++++++++--
lib/tests/igt_describe.c | 266 +++++++++++++++++++++++++++++++++++++++
lib/tests/meson.build | 1 +
4 files changed, 562 insertions(+), 21 deletions(-)
create mode 100644 lib/tests/igt_describe.c
diff --git a/lib/igt_core.c b/lib/igt_core.c
index 6b9f0425..8b1c7b2f 100644
--- a/lib/igt_core.c
+++ b/lib/igt_core.c
@@ -70,6 +70,7 @@
#include "igt_sysfs.h"
#include "igt_sysrq.h"
#include "igt_rc.h"
+#include "igt_list.h"
#define UNW_LOCAL_ONLY
#include <libunwind.h>
@@ -259,6 +260,7 @@ const char *igt_interactive_debug;
/* subtests helpers */
static bool list_subtests = false;
+static bool describe_subtests = false;
static char *run_single_subtest = NULL;
static bool run_single_subtest_found = false;
static const char *in_subtest = NULL;
@@ -271,6 +273,16 @@ static enum {
CONT = 0, SKIP, FAIL
} skip_subtests_henceforth = CONT;
+static char __current_description[4096];
+
+struct description_node {
+ char desc[sizeof(__current_description)];
+ struct igt_list link;
+};
+
+static struct igt_list subgroup_descriptions;
+
+
bool __igt_plain_output = false;
/* fork support state */
@@ -285,6 +297,7 @@ enum {
* conflict with core ones
*/
OPT_LIST_SUBTESTS = 500,
+ OPT_DESCRIBE_SUBTESTS,
OPT_RUN_SUBTEST,
OPT_DESCRIPTION,
OPT_DEBUG,
@@ -528,10 +541,59 @@ static void common_exit_handler(int sig)
assert(sig != 0 || igt_exit_called);
}
+static void print_line_wrapping(const char *indent, const char *text)
+{
+ char *copy, *curr, *next_space;
+ int current_line_length = 0;
+ bool done = false;
+
+ const int total_line_length = 80;
+ const int line_length = total_line_length - strlen(indent);
+
+ copy = malloc(strlen(text) + 1);
+ memcpy(copy, text, strlen(text) + 1);
+
+ curr = copy;
+
+ printf("%s", indent);
+
+ while (!done) {
+ next_space = strchr(curr, ' ');
+
+ if (!next_space) { /* no more spaces, print everything that is left */
+ done = true;
+ next_space = strchr(curr, '\0');
+ }
+
+ *next_space = '\0';
+
+ if ((next_space - curr) + current_line_length > line_length && curr != copy) {
+ printf("\n%s", indent);
+ current_line_length = 0;
+ }
+
+ if (current_line_length == 0)
+ printf("%s", curr); /* first word in a line, don't space out */
+ else
+ printf(" %s", curr);
+
+ current_line_length += next_space - curr;
+ curr = next_space + 1;
+ }
+
+ printf("\n");
+
+ free(copy);
+}
+
+
static void print_test_description(void)
{
- if (&__igt_test_description)
- printf("%s\n", __igt_test_description);
+ if (&__igt_test_description) {
+ print_line_wrapping("", __igt_test_description);
+ if (describe_subtests)
+ printf("\n");
+ }
}
static void print_version(void)
@@ -558,6 +620,7 @@ static void print_usage(const char *help_str, bool output_on_stderr)
" --debug[=log-domain]\n"
" --interactive-debug[=domain]\n"
" --help-description\n"
+ " --describe\n"
" --help|-h\n");
if (help_str)
fprintf(f, "%s\n", help_str);
@@ -671,6 +734,7 @@ static int common_init(int *argc, char **argv,
int c, option_index = 0, i, x;
static struct option long_options[] = {
{"list-subtests", no_argument, NULL, OPT_LIST_SUBTESTS},
+ {"describe", optional_argument, NULL, OPT_DESCRIBE_SUBTESTS},
{"run-subtest", required_argument, NULL, OPT_RUN_SUBTEST},
{"help-description", no_argument, NULL, OPT_DESCRIPTION},
{"debug", optional_argument, NULL, OPT_DEBUG},
@@ -687,6 +751,7 @@ static int common_init(int *argc, char **argv,
int ret = 0;
common_init_env();
+ igt_list_init(&subgroup_descriptions);
command_str = argv[0];
if (strrchr(command_str, '/'))
@@ -777,6 +842,13 @@ static int common_init(int *argc, char **argv,
if (!run_single_subtest)
list_subtests = true;
break;
+ case OPT_DESCRIBE_SUBTESTS:
+ if (optarg)
+ run_single_subtest = strdup(optarg);
+ list_subtests = true;
+ describe_subtests = true;
+ print_test_description();
+ break;
case OPT_RUN_SUBTEST:
assert(optarg);
if (!list_subtests)
@@ -934,12 +1006,41 @@ void igt_simple_init_parse_opts(int *argc, char **argv,
extra_opt_handler, handler_data);
}
+static void _clear_current_description(void) {
+ __current_description[0] = '\0';
+}
+
+#define __INDENT " "
+static void __igt_print_description(const char *subtest_name, const char *file, const int line)
+{
+ struct description_node *desc;
+ bool has_doc = false;
+
+ printf("SUB %s %s:%d:\n", subtest_name, file, line);
+
+ igt_list_for_each(desc, &subgroup_descriptions, link) {
+ print_line_wrapping(__INDENT, desc->desc);
+ printf("\n");
+ has_doc = true;
+ }
+
+ if (__current_description[0] != '\0') {
+ print_line_wrapping(__INDENT, __current_description);
+ printf("\n");
+ has_doc = true;
+ }
+
+ if (!has_doc)
+ printf("%sNO DOCUMENTATION!\n\n", __INDENT);
+}
+#undef __INDENT
+
/*
* Note: Testcases which use these helpers MUST NOT output anything to stdout
* outside of places protected by igt_run_subtest checks - the piglit
* runner adds every line to the subtest list.
*/
-bool __igt_run_subtest(const char *subtest_name)
+bool __igt_run_subtest(const char *subtest_name, const char *file, const int line)
{
int i;
@@ -954,18 +1055,25 @@ bool __igt_run_subtest(const char *subtest_name)
igt_exit();
}
- if (list_subtests) {
- printf("%s\n", subtest_name);
- return false;
- }
-
if (run_single_subtest) {
- if (uwildmat(subtest_name, run_single_subtest) == 0)
+ if (uwildmat(subtest_name, run_single_subtest) == 0) {
+ _clear_current_description();
return false;
- else
+ } else {
run_single_subtest_found = true;
+ }
}
+ if (describe_subtests) {
+ __igt_print_description(subtest_name, file, line);
+ _clear_current_description();
+ return false;
+ } else if (list_subtests) {
+ printf("%s\n", subtest_name);
+ return false;
+ }
+
+
if (skip_subtests_henceforth) {
printf("%sSubtest %s: %s%s\n",
(!__igt_plain_output) ? "\x1b[1m" : "", subtest_name,
@@ -1014,15 +1122,32 @@ bool igt_only_list_subtests(void)
return list_subtests;
}
-void __igt_subtest_group_save(int *save)
+
+
+void __igt_subtest_group_save(int *save, int *desc)
{
assert(test_with_subtests);
+ if (__current_description[0] != '\0') {
+ struct description_node *new = calloc(1, sizeof(*new));
+ memcpy(new->desc, __current_description, sizeof(__current_description));
+ igt_list_add_tail(&new->link, &subgroup_descriptions);
+ _clear_current_description();
+ *desc = true;
+ }
+
*save = skip_subtests_henceforth;
}
-void __igt_subtest_group_restore(int save)
+void __igt_subtest_group_restore(int save, int desc)
{
+ if (desc) {
+ struct description_node *last =
+ igt_list_last_entry(&subgroup_descriptions, last, link);
+ igt_list_del(&last->link);
+ free(last);
+ }
+
skip_subtests_henceforth = save;
}
@@ -1229,6 +1354,34 @@ bool igt_can_fail(void)
return !test_with_subtests || in_fixture || in_subtest;
}
+/**
+ * igt_describe_f:
+ * @fmt: format string containing description
+ * @...: argument used by the format string
+ *
+ * Attach a description to the following #igt_subtest or #igt_subtest_group
+ * block.
+ *
+ * Check #igt_describe for more details.
+ *
+ */
+void igt_describe_f(const char *fmt, ...)
+{
+ int ret;
+ va_list args;
+
+ if (!describe_subtests)
+ return;
+
+ va_start(args, fmt);
+
+ ret = vsnprintf(__current_description, sizeof(__current_description), fmt, args);
+
+ va_end(args);
+
+ assert(ret < sizeof(__current_description));
+}
+
static bool running_under_gdb(void)
{
char pathname[30], buf[1024];
@@ -1540,7 +1693,7 @@ void igt_exit(void)
g_key_file_free(igt_key_file);
if (run_single_subtest && !run_single_subtest_found) {
- igt_warn("Unknown subtest: %s\n", run_single_subtest);
+ igt_critical("Unknown subtest: %s\n", run_single_subtest);
exit(IGT_EXIT_INVALID);
}
diff --git a/lib/igt_core.h b/lib/igt_core.h
index 88a95ec2..1b37f142 100644
--- a/lib/igt_core.h
+++ b/lib/igt_core.h
@@ -174,7 +174,7 @@ int igt_subtest_init_parse_opts(int *argc, char **argv,
#define igt_subtest_init(argc, argv) \
igt_subtest_init_parse_opts(&argc, argv, NULL, NULL, NULL, NULL, NULL);
-bool __igt_run_subtest(const char *subtest_name);
+bool __igt_run_subtest(const char *subtest_name, const char *file, const int line);
#define __igt_tokencat2(x, y) x ## y
/**
@@ -198,14 +198,14 @@ bool __igt_run_subtest(const char *subtest_name);
*
* This is a simpler version of igt_subtest_f()
*/
-#define igt_subtest(name) for (; __igt_run_subtest((name)) && \
+#define igt_subtest(name) for (; __igt_run_subtest((name), __FILE__, __LINE__) && \
(sigsetjmp(igt_subtest_jmpbuf, 1) == 0); \
igt_success())
#define __igt_subtest_f(tmp, format...) \
for (char tmp [256]; \
snprintf( tmp , sizeof( tmp ), \
format), \
- __igt_run_subtest( tmp ) && \
+ __igt_run_subtest(tmp, __FILE__, __LINE__) && \
(sigsetjmp(igt_subtest_jmpbuf, 1) == 0); \
igt_success())
@@ -227,8 +227,8 @@ bool __igt_run_subtest(const char *subtest_name);
const char *igt_subtest_name(void);
bool igt_only_list_subtests(void);
-void __igt_subtest_group_save(int *);
-void __igt_subtest_group_restore(int);
+void __igt_subtest_group_save(int *, int *);
+void __igt_subtest_group_restore(int, int);
/**
* igt_subtest_group:
*
@@ -245,11 +245,14 @@ void __igt_subtest_group_restore(int);
* group will fail or skip. Subtest groups can be arbitrarily nested.
*/
#define igt_subtest_group for (int igt_tokencat(__tmpint,__LINE__) = 0, \
- igt_tokencat(__save,__LINE__) = 0; \
+ igt_tokencat(__save,__LINE__) = 0, \
+ igt_tokencat(__desc,__LINE__) = 0; \
igt_tokencat(__tmpint,__LINE__) < 1 && \
- (__igt_subtest_group_save(& igt_tokencat(__save,__LINE__) ), true); \
+ (__igt_subtest_group_save(& igt_tokencat(__save,__LINE__), \
+ & igt_tokencat(__desc,__LINE__) ), true); \
igt_tokencat(__tmpint,__LINE__) ++, \
- __igt_subtest_group_restore(igt_tokencat(__save,__LINE__) ))
+ __igt_subtest_group_restore(igt_tokencat(__save,__LINE__), \
+ igt_tokencat(__desc,__LINE__)))
/**
* igt_main_args:
@@ -385,6 +388,124 @@ static inline void igt_ignore_warn(bool value)
{
}
+__attribute__((format(printf, 1, 2)))
+void igt_describe_f(const char *fmt, ...);
+
+/**
+ * igt_describe:
+ * @dsc: string containing description
+ *
+ * Attach a description to the following #igt_subtest or #igt_subtest_group
+ * block.
+ *
+ * The description should complement the test/subtest name and provide more
+ * context on what is being tested. It should explain the idea of the test and
+ * do not mention implementation details, so that it never goes out of date.
+ *
+ * DO:
+ * * focus on the userspace's perspective
+ * * try to capture the reason for the test's existence
+ * * be brief
+ *
+ * DON'T:
+ * * try to translate the code into English
+ * * explain all the checks the test does
+ * * delve on the implementation
+ *
+ * Good examples:
+ * * "make sure that legacy cursor updates do not stall atomic commits"
+ * * "check that atomic updates of many planes are indeed atomic and take
+ * effect immediately after the commit"
+ * * "make sure that the meta-data exposed by the kernel to the userspace
+ * is correct and matches the used EDID"
+ *
+ * Bad examples:
+ * * "spawn 10 threads, each pinning cpu core with a busy loop..."
+ * * "randomly generate holes in a primary plane then try to cover each hole
+ * with a plane and make sure that CRC matches, do 25 gazillion rounds of
+ * that..."
+ *
+ *
+ * Resulting #igt_subtest documentation is a concatenation of its own
+ * description and all the parenting #igt_subtest_group descriptions, starting
+ * from the outermost one. Example:
+ *
+ * |[<!-- language="C" -->
+ * #include "igt.h"
+ *
+ * IGT_TEST_DESCRIPTION("Global description of the whole binary");
+ * igt_main
+ * {
+ * igt_describe("Desc of the subgroup with A and B");
+ * igt_subtest_group {
+ * igt_describe("Desc of the subtest A");
+ * igt_subtest("subtest-a") {
+ * ...
+ * }
+ *
+ * igt_describe("Desc of the subtest B");
+ * igt_subtest("subtest-b") {
+ * ...
+ * }
+ * }
+ *
+ * igt_describe("Desc of the subtest C");
+ * igt_subtest("subtest-c") {
+ * ...
+ * }
+ * }
+ * ]|
+ *
+ * It's will accessible via --describe command line switch:
+ *
+ * |[
+ * $ test --describe
+ * Global description of the whole binary
+ *
+ * SUB subtest-a test.c:5:
+ * Desc of the subgroup with A and B
+ *
+ * Desc of the subtest A
+ *
+ * SUB subtest-b test.c:10:
+ * Desc of the subgroup with A and B
+ *
+ * Desc of the subtest B
+ *
+ * SUB subtest-c test.c:15:
+ * Desc of the subtest C
+ * ]|
+ *
+ * Every single #igt_subtest does not have to be preceded with a #igt_describe
+ * as long as it has good-enough explanation provided on the #igt_subtest_group
+ * level.
+ *
+ * Example:
+ *
+ * |[<!-- language="C" -->
+ * #include "igt.h"
+ *
+ * igt_main
+ * {
+ * igt_describe("check xyz with different tilings");
+ * igt_subtest_group {
+ * // no need for extra description, group is enough and tiling is
+ * // obvious from the test name
+ * igt_subtest("foo-tiling-x") {
+ * ...
+ * }
+ *
+ * igt_subtest("foo-tiling-y") {
+ * ...
+ * }
+ * }
+ * }
+ * ]|
+ *
+ */
+#define igt_describe(dsc) \
+ igt_describe_f("%s", dsc)
+
/**
* igt_assert:
* @expr: condition to test
diff --git a/lib/tests/igt_describe.c b/lib/tests/igt_describe.c
new file mode 100644
index 00000000..a9f857bb
--- /dev/null
+++ b/lib/tests/igt_describe.c
@@ -0,0 +1,266 @@
+/*
+ * Copyright © 2019 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <sys/wait.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "drmtest.h"
+#include "igt_tests_common.h"
+
+IGT_TEST_DESCRIPTION("the top level description");
+static void fake_main(int argc, char **argv) {
+ igt_subtest_init(argc, argv);
+
+ igt_describe("Basic A");
+ igt_subtest("A")
+ ;
+
+ igt_fixture
+ printf("should not be executed!\n");
+
+ igt_describe("Group with B, C & D");
+ igt_subtest_group {
+ igt_describe("Basic B");
+ igt_subtest("B")
+ ;
+
+ if (!igt_only_list_subtests())
+ printf("should not be executed!\n");
+
+ igt_describe("Group with C & D");
+ igt_subtest_group {
+ igt_describe("Basic C");
+ igt_subtest("C")
+ printf("should not be executed!\n");
+
+ // NO DOC
+ igt_subtest("D")
+ ;
+ }
+ }
+
+ // NO DOC
+ igt_subtest_group {
+ // NO DOC
+ igt_subtest("E")
+ ;
+ }
+
+ // NO DOC
+ igt_subtest("F")
+ ;
+
+ igt_describe("this description should be so long that it wraps itself nicely in the terminal "
+ "this description should be so long that it wraps itself nicely in the terminal "
+ "this description should be so long that it wraps itself nicely in the terminal "
+ "this description should be so long that it wraps itself nicely in the terminal "
+ "this description should be so long that it wraps itself nicely in the terminal "
+ "this description should be so long that it wraps itself nicely in the terminal");
+ igt_subtest("G")
+ ;
+
+ igt_describe("verylongwordthatshoudlbeprintedeventhoughitspastthewrppinglimit"
+ "verylongwordthatshoudlbeprintedeventhoughitspastthewrappinglimit "
+ "verylongwordthatshoudlbeprintedeventhoughitspastthewrappinglimit"
+ "verylongwordthatshoudlbeprintedeventhoughitspastthewrappinglimit");
+ igt_subtest("F")
+ ;
+
+ igt_exit();
+}
+
+static const char DESCRIBE_ALL_OUTPUT[] = \
+ "the top level description\n"
+ "\n"
+ "SUB A ../lib/tests/igt_describe.c:36:\n"
+ " Basic A\n"
+ "\n"
+ "SUB B ../lib/tests/igt_describe.c:45:\n"
+ " Group with B, C & D\n"
+ "\n"
+ " Basic B\n"
+ "\n"
+ "SUB C ../lib/tests/igt_describe.c:54:\n"
+ " Group with B, C & D\n"
+ "\n"
+ " Group with C & D\n"
+ "\n"
+ " Basic C\n"
+ "\n"
+ "SUB D ../lib/tests/igt_describe.c:58:\n"
+ " Group with B, C & D\n"
+ "\n"
+ " Group with C & D\n"
+ "\n"
+ "SUB E ../lib/tests/igt_describe.c:66:\n"
+ " NO DOCUMENTATION!\n"
+ "\n"
+ "SUB F ../lib/tests/igt_describe.c:71:\n"
+ " NO DOCUMENTATION!\n"
+ "\n"
+ "SUB G ../lib/tests/igt_describe.c:80:\n"
+ " this description should be so long that it wraps itself nicely in the terminal this\n"
+ " description should be so long that it wraps itself nicely in the terminal this description\n"
+ " should be so long that it wraps itself nicely in the terminal this description should be so\n"
+ " long that it wraps itself nicely in the terminal this description should be so long that it\n"
+ " wraps itself nicely in the terminal this description should be so long that it wraps itself\n"
+ " nicely in the terminal\n"
+ "\n"
+ "SUB F ../lib/tests/igt_describe.c:87:\n"
+ " verylongwordthatshoudlbeprintedeventhoughitspastthewrppinglimitverylongwordthatshoudlbeprintedeventhoughitspastthewrappinglimit\n"
+ " verylongwordthatshoudlbeprintedeventhoughitspastthewrappinglimitverylongwordthatshoudlbeprintedeventhoughitspastthewrappinglimit\n\n";
+
+static const char JUST_C_OUTPUT[] = \
+ "the top level description\n"
+ "\n"
+ "SUB C ../lib/tests/igt_describe.c:54:\n"
+ " Group with B, C & D\n"
+ "\n"
+ " Group with C & D\n"
+ "\n"
+ " Basic C\n"
+ "\n";
+
+static void assert_pipe_empty(int fd)
+{
+ char buf[5];
+ internal_assert(0 == read(fd, buf, sizeof(buf)));
+}
+
+static void read_whole_pipe(int fd, char *buf, size_t buflen)
+{
+ ssize_t readlen;
+ off_t offset;
+
+ offset = 0;
+ while ((readlen = read(fd, buf+offset, buflen-offset))) {
+ internal_assert(readlen != -1);
+ offset += readlen;
+ }
+}
+
+static pid_t do_fork(int argc, char **argv, int *out, int *err)
+{
+ int outfd[2], errfd[2];
+ pid_t pid;
+
+ internal_assert(pipe(outfd) != -1);
+ internal_assert(pipe(errfd) != -1);
+
+ pid = fork();
+ internal_assert(pid != -1);
+
+ if (pid == 0) {
+ while ((dup2(outfd[1], STDOUT_FILENO) == -1) && (errno == EINTR)) {}
+ while ((dup2(errfd[1], STDERR_FILENO) == -1) && (errno == EINTR)) {}
+
+ fake_main(argc, argv);
+
+ exit(-1);
+ } else {
+ /* close the writing ends */
+ close(outfd[1]);
+ close(errfd[1]);
+
+ *out = outfd[0];
+ *err = errfd[0];
+
+ return pid;
+ }
+}
+
+static int _wait(pid_t pid, int *status) {
+ int ret;
+
+ do {
+ ret = waitpid(pid, status, 0);
+ } while (ret == -1 && errno == EINTR);
+
+ return ret;
+}
+
+int main(int argc, char **argv)
+{
+ char prog[] = "igt_describe";
+ int status;
+ int outfd, errfd;
+
+ /* describe all subtest */ {
+ static char out[4096];
+ char arg[] = "--describe";
+ char *fake_argv[] = {prog, arg};
+ int fake_argc = ARRAY_SIZE(fake_argv);
+
+ pid_t pid = do_fork(fake_argc, fake_argv, &outfd, &errfd);
+
+ read_whole_pipe(outfd, out, sizeof(out));
+ assert_pipe_empty(errfd);
+
+ internal_assert(_wait(pid, &status) != -1);
+ internal_assert(WEXITSTATUS(status) == IGT_EXIT_SUCCESS);
+ internal_assert(0 == strcmp(DESCRIBE_ALL_OUTPUT, out));
+
+ close(outfd);
+ close(errfd);
+ }
+
+ /* describe C using a pattern */ {
+ static char out[4096];
+ char arg[] = "--describe=C";
+ char *fake_argv[] = {prog, arg};
+ int fake_argc = ARRAY_SIZE(fake_argv);
+
+ pid_t pid = do_fork(fake_argc, fake_argv, &outfd, &errfd);
+
+ read_whole_pipe(outfd, out, sizeof(out));
+ assert_pipe_empty(errfd);
+
+ internal_assert(_wait(pid, &status) != -1);
+ internal_assert(WEXITSTATUS(status) == IGT_EXIT_SUCCESS);
+ internal_assert(0 == strcmp(JUST_C_OUTPUT, out));
+
+ close(outfd);
+ close(errfd);
+ }
+
+ /* fail describing with a bad pattern */ {
+ static char err[4096];
+ char arg[] = "--describe=Z";
+ char *fake_argv[] = {prog, arg};
+ int fake_argc = ARRAY_SIZE(fake_argv);
+
+ pid_t pid = do_fork(fake_argc, fake_argv, &outfd, &errfd);
+
+ read_whole_pipe(errfd, err, sizeof(err));
+
+ internal_assert(_wait(pid, &status) != -1);
+ internal_assert(WEXITSTATUS(status) == IGT_EXIT_INVALID);
+ internal_assert(strstr(err, "Unknown subtest: Z"));
+
+ close(outfd);
+ close(errfd);
+ }
+
+ return 0;
+}
diff --git a/lib/tests/meson.build b/lib/tests/meson.build
index b930ee6e..4d907e34 100644
--- a/lib/tests/meson.build
+++ b/lib/tests/meson.build
@@ -3,6 +3,7 @@ lib_tests = [
'igt_can_fail',
'igt_can_fail_simple',
'igt_conflicting_args',
+ 'igt_describe',
'igt_edid',
'igt_exit_handler',
'igt_fork',
--
2.21.0
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
next reply other threads:[~2019-06-17 10:54 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-06-17 10:54 Arkadiusz Hiler [this message]
2019-06-17 10:54 ` [igt-dev] [PATCH i-g-t 2/5] tests/kms_hdmi_inject: Provide igt_descriptions Arkadiusz Hiler
2019-06-17 12:54 ` Ser, Simon
2019-06-18 10:36 ` [igt-dev] [PATCH v2 " Arkadiusz Hiler
2019-06-19 6:44 ` Ser, Simon
2019-06-17 10:54 ` [igt-dev] [PATCH i-g-t 3/5] tests/kms_plane_multiple: Describe the test Arkadiusz Hiler
2019-06-18 9:36 ` Kahola, Mika
2019-06-17 10:54 ` [igt-dev] [PATCH i-g-t 4/5] CONTRIBUTING: Rework a bit and update Arkadiusz Hiler
2019-06-20 13:49 ` Ser, Simon
2019-06-27 12:57 ` Arkadiusz Hiler
2019-06-27 14:00 ` Ser, Simon
2019-06-17 10:54 ` [igt-dev] [PATCH i-g-t 5/5] docs: Embed subtest descriptions in the documentation Arkadiusz Hiler
2019-06-20 8:20 ` Petri Latvala
2019-06-20 10:52 ` Arkadiusz Hiler
2019-06-20 11:05 ` Ser, Simon
2019-06-20 11:16 ` Arkadiusz Hiler
2019-06-20 11:11 ` Petri Latvala
2019-06-20 11:38 ` Arkadiusz Hiler
2019-06-20 12:16 ` Petri Latvala
2019-06-24 8:00 ` Ser, Simon
2019-06-27 12:52 ` Arkadiusz Hiler
2019-06-17 13:28 ` [igt-dev] ✓ Fi.CI.BAT: success for series starting with [i-g-t,1/5] lib/igt_core: Add support for subtest descriptions Patchwork
2019-06-17 19:59 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
2019-06-18 12:02 ` [igt-dev] ✓ Fi.CI.BAT: success for series starting with [i-g-t,1/5] lib/igt_core: Add support for subtest descriptions (rev2) Patchwork
2019-06-18 22:45 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
-- strict thread matches above, loose matches on Subject: below --
2019-07-01 12:21 [igt-dev] [PATCH i-g-t 1/5] lib/igt_core: Add support for subtest descriptions Arkadiusz Hiler
2019-07-03 13:08 ` Ser, Simon
2019-07-04 11:22 ` Arkadiusz Hiler
2019-07-04 11:33 ` Ser, Simon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190617105443.8264-1-arkadiusz.hiler@intel.com \
--to=arkadiusz.hiler@intel.com \
--cc=igt-dev@lists.freedesktop.org \
--cc=petri.latvala@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.