Skip to contentSkip to conversation

lib: Add tst_strstatus()

RFC PATCH New Cyril Hrubis 2 participants 5 messages Oct 12, 2017 – Oct 18, 2017 Library code

lore
Share & tools
lore
#0 lore raw

RFC PATCH 1/2 lib: Add tst_strstatus()

This function returns a string describing status as returned by 'wait()' call. This is expected to be used when we want to TBROK a test if child haven't terminated in an expected way.

The fucntion is not thread safe, since it uses static buffer, but I doubt that we actually care in this case and making it thread-safe would have complicated the nice and simple API.

---
 doc/test-writing-guidelines.txt    |  9 ++++++
 include/tst_test.h                 |  6 ++++
 lib/newlib_tests/.gitignore        |  1 +
 lib/newlib_tests/test_str_status.c | 49 ++++++++++++++++++++++++++++++
 lib/tst_status.c                   | 62 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 127 insertions(+)
 create mode 100644 lib/newlib_tests/test_str_status.c
 create mode 100644 lib/tst_status.c
doc/test-writing-guidelines.txt +9 -0
index 15d418954..edc1f602d 100644
@@ -449,6 +449,15 @@ translate 'errno' values to strings is preferred. You should not use the
 
 [source,c]
 -------------------------------------------------------------------------------
+const char *tst_strstatus(int status);
+-------------------------------------------------------------------------------
+
+Returns string describing the status as returned by 'wait()'.
+
+WARNING: This funciton is not thread safe.
+
+[source,c]
+-------------------------------------------------------------------------------
 void tst_set_timeout(unsigned int timeout);
 -------------------------------------------------------------------------------
 
include/tst_test.h +6 -0
index ad468e8cf..f9872d973 100644
@@ -186,6 +186,12 @@ extern int TEST_ERRNO;
  */
 const char *tst_strerrno(int err);
 const char *tst_strsig(int sig);
+/*
+ * Returns string describing status as returned by wait().
+ *
+ * BEWARE: Not thread safe.
+ */
+const char *tst_strstatus(int status);
 
 void tst_set_timeout(int timeout);
 
lib/newlib_tests/.gitignore +1 -0
index d47a6ea12..e10cbdb72 100644
@@ -17,3 +17,4 @@ test16
 tst_device
 tst_safe_fileops
 tst_res_hexd
+test_str_status
lib/newlib_tests/test_str_status.c new file +49 -0

49 lines not on this page · raw message

lib/tst_status.c new file +62 -0

62 lines not on this page · raw message

Signature · 1 line
2.13.5
#1 lore raw

RFC PATCH 2/2 syscalls: Make use of tst_strstatus()

---
 testcases/cve/stack_clash.c                       |  2 +-
 testcases/kernel/syscalls/fanotify/fanotify03.c   | 17 ++++-------------
 testcases/kernel/syscalls/madvise/madvise07.c     | 11 ++++++++---
 testcases/kernel/syscalls/madvise/madvise09.c     |  4 ++--
 testcases/kernel/syscalls/setrlimit/setrlimit04.c | 14 +++++---------
 5 files changed, 20 insertions(+), 28 deletions(-)
testcases/cve/stack_clash.c +1 -1
index 49c45ef74..f25e19b3f 100644
@@ -256,7 +256,7 @@ void stack_clash_test(void)
 		}
 	}
 
-	tst_brk(TBROK, "child did not exit gracefully");
+	tst_brk(TBROK, "Child %s", tst_strstatus(status));
 }
 
 static struct tst_test test = {
testcases/kernel/syscalls/fanotify/fanotify03.c +4 -13
index ea5c02a7b..400042081 100644
@@ -132,19 +132,10 @@ static void check_child(void)
 	}
 	SAFE_WAITPID(-1, &child_ret, 0);
 
-	if (WIFSIGNALED(child_ret)) {
-		tst_res(TFAIL, "child exited due to signal %d",
-			 WTERMSIG(child_ret));
-	} else if (WIFEXITED(child_ret)) {
-		if (WEXITSTATUS(child_ret) == 0)
-			tst_res(TPASS, "child exited correctly");
-		else
-			tst_res(TFAIL, "child exited with status %d",
-				 WEXITSTATUS(child_ret));
-	} else {
-		tst_res(TFAIL, "child exited for unknown reason (status %d)",
-			 child_ret);
-	}
+	if (WIFEXITED(child_ret) && WEXITSTATUS(child_ret) == 0)
+		tst_res(TPASS, "child exited correctly");
+	else
+		tst_res(TFAIL, "child %s", tst_strstatus(child_ret));
 }
 
 void test01(void)
testcases/kernel/syscalls/madvise/madvise07.c +8 -3
index ef9aa4a26..170642ada 100644
@@ -91,10 +91,15 @@ static void run(void)
 	}
 
 	SAFE_WAITPID(pid, &status, 0);
-	if (WIFSIGNALED(status) && WTERMSIG(status) == SIGBUS)
+	if (WIFSIGNALED(status) && WTERMSIG(status) == SIGBUS) {
 		tst_res(TPASS, "Received SIGBUS after accessing poisoned page");
-	else if (WIFEXITED(status) && WEXITSTATUS(status) == TBROK)
-		tst_res(TBROK, "Child exited abnormally");
+		return;
+	}
+
+	if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
+		return;
+
+	tst_res(TFAIL, "Child %s", tst_strstatus(status));
 }
 
 static struct tst_test test = {
testcases/kernel/syscalls/madvise/madvise09.c +2 -2
index 7ad76f795..4e887f5db 100644
@@ -305,8 +305,8 @@ retry:
 		goto retry;
 	}
 
-	if (WIFEXITED(status) && WEXITSTATUS(status))
-		tst_brk(TBROK, "Child exitted unexpectedly");
+	if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
+		tst_brk(TBROK, "Child %s", tst_strstatus(status));
 }
 
 static void setup(void)
testcases/kernel/syscalls/setrlimit/setrlimit04.c +5 -9
index e366298a1..5b6c958c3 100644
@@ -48,16 +48,12 @@ static void test_setrlimit(void)
 		SAFE_EXECLP("/bin/true", "/bin/true", NULL);
 	SAFE_WAITPID(child, &status, 0);
 
-	if (WIFEXITED(status)) {
-		if ((WEXITSTATUS(status) == 0))
-			tst_res(TPASS, "child process completed OK");
-		else
-			tst_res(TFAIL, "child process exited with %d",
-				WEXITSTATUS(status));
-	} else if (WIFSIGNALED(status)) {
-		tst_res(TFAIL, "child exited with signal %s",
-			tst_strsig(WTERMSIG(status)));
+	if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
+		tst_res(TPASS, "child process completed OK");
+		return;
 	}
+
+	tst_res(TFAIL, "child %s", tst_strstatus(status));
 }
 
 static struct tst_test test = {
Signature · 1 line
2.13.5
#2 lore raw

RFC PATCH 1/2 lib: Add tst_strstatus()

In reply to Cyril Hrubis

Hi Cyril,

I have tested this patch set, and it looks good to me.

Thanks,
Xiao Yang.

Quoted 188 lines · Cyril Hrubis

This function returns a string describing status as returned by 'wait()' call. This is expected to be used when we want to TBROK a test if child haven't terminated in an expected way.

The fucntion is not thread safe, since it uses static buffer, but I doubt that we actually care in this case and making it thread-safe would have complicated the nice and simple API.

---
  doc/test-writing-guidelines.txt    |  9 ++++++
  include/tst_test.h                 |  6 ++++
  lib/newlib_tests/.gitignore        |  1 +
  lib/newlib_tests/test_str_status.c | 49 ++++++++++++++++++++++++++++++
  lib/tst_status.c                   | 62 ++++++++++++++++++++++++++++++++++++++
  5 files changed, 127 insertions(+)

create mode 100644 lib/newlib_tests/test_str_status.c create mode 100644 lib/tst_status.c

doc/test-writing-guidelines.txt +9 -0
index 15d418954..edc1f602d 100644
@@ -449,6 +449,15 @@ translate 'errno' values to strings is preferred. You should not use the
 
  [source,c]
  -------------------------------------------------------------------------------
+const char *tst_strstatus(int status);
+-------------------------------------------------------------------------------
+
+Returns string describing the status as returned by 'wait()'.
+
+WARNING: This funciton is not thread safe.
+
+[source,c]
+-------------------------------------------------------------------------------
  void tst_set_timeout(unsigned int timeout);
  -------------------------------------------------------------------------------
 
include/tst_test.h +6 -0
index ad468e8cf..f9872d973 100644
@@ -186,6 +186,12 @@ extern int TEST_ERRNO;
   */
  const char *tst_strerrno(int err);
  const char *tst_strsig(int sig);
+/*
+ * Returns string describing status as returned by wait().
+ *
+ * BEWARE: Not thread safe.
+ */
+const char *tst_strstatus(int status);
 
  void tst_set_timeout(int timeout);
 
lib/newlib_tests/.gitignore +1 -0
index d47a6ea12..e10cbdb72 100644
@@ -17,3 +17,4 @@ test16
  tst_device
  tst_safe_fileops
  tst_res_hexd
+test_str_status
lib/newlib_tests/test_str_status.c new file +49 -0
new file mode 100644
index 000000000..706ec1144
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016 Cyril Hrubis<[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+/*
+ * The test should abort when oldlib function is called from newlib.
+ */
+
+#include "tst_test.h"
+
+static struct tcase {
+	int status;
+	const char *str;
+} tcases[] = {
+	{0x0100, "exitted with 1"},
+	{0x0001, "killed by SIGHUP"},
+	{0x137f, "is stopped"},
+	{0xffff, "is resumed"},
+	{0xff, "invalid status 0xff"},
+};
+
+static void do_test(unsigned int n)
+{
+	const char *str_status = tst_strstatus(tcases[n].status);
+
+	if (strcmp(str_status, tcases[n].str))
+		tst_res(TFAIL, "%s != %s", str_status, tcases[n].str);
+	else
+		tst_res(TPASS, "%s", str_status);
+}
+
+static struct tst_test test = {
+	.test = do_test,
+	.tcnt = ARRAY_SIZE(tcases),
+};
lib/tst_status.c new file +62 -0
new file mode 100644
index 000000000..4bd38e547
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2017 Cyril Hrubis<[email protected]>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see<http://www.gnu.org/licenses/>.
+ */
+
+#include<sys/types.h>
+#include<sys/wait.h>
+#include<stdio.h>
+#define TST_NO_DEFAULT_MAIN
+#include "tst_test.h"
+
+static char buf[32];
+
+const char *exited(int status)
+{
+	snprintf(buf, sizeof(buf), "exitted with %i", WEXITSTATUS(status));
+
+	return buf;
+}
+
+const char *signaled(int status)
+{
+	snprintf(buf, sizeof(buf), "killed by %s", tst_strsig(status));
+
+	return buf;
+}
+
+const char *invalid(int status)
+{
+	snprintf(buf, sizeof(buf), "invalid status 0x%x", status);
+
+	return buf;
+}
+
+const char *tst_strstatus(int status)
+{
+	if (WIFEXITED(status))
+		return exited(status);
+
+	if (WIFSIGNALED(status))
+		return signaled(status);
+
+	if (WIFSTOPPED(status))
+		return "is stopped";
+
+	if (WIFCONTINUED(status))
+		return "is resumed";
+
+	return invalid(status);
+}
#3 lore raw

RFC PATCH 1/2 lib: Add tst_strstatus()

In reply to Cyril Hrubis
Quoted 71 lines · Cyril Hrubis

This function returns a string describing status as returned by 'wait()' call. This is expected to be used when we want to TBROK a test if child haven't terminated in an expected way.

The fucntion is not thread safe, since it uses static buffer, but I doubt that we actually care in this case and making it thread-safe would have complicated the nice and simple API.

---
  doc/test-writing-guidelines.txt    |  9 ++++++
  include/tst_test.h                 |  6 ++++
  lib/newlib_tests/.gitignore        |  1 +
  lib/newlib_tests/test_str_status.c | 49 ++++++++++++++++++++++++++++++
  lib/tst_status.c                   | 62 ++++++++++++++++++++++++++++++++++++++
  5 files changed, 127 insertions(+)

create mode 100644 lib/newlib_tests/test_str_status.c create mode 100644 lib/tst_status.c

doc/test-writing-guidelines.txt +9 -0
index 15d418954..edc1f602d 100644
@@ -449,6 +449,15 @@ translate 'errno' values to strings is preferred. You should not use the
 
  [source,c]
  -------------------------------------------------------------------------------
+const char *tst_strstatus(int status);
+-------------------------------------------------------------------------------
+
+Returns string describing the status as returned by 'wait()'.
+
+WARNING: This funciton is not thread safe.
+
+[source,c]
+-------------------------------------------------------------------------------
  void tst_set_timeout(unsigned int timeout);
  -------------------------------------------------------------------------------
 
include/tst_test.h +6 -0
index ad468e8cf..f9872d973 100644
@@ -186,6 +186,12 @@ extern int TEST_ERRNO;
   */
  const char *tst_strerrno(int err);
  const char *tst_strsig(int sig);
+/*
+ * Returns string describing status as returned by wait().
+ *
+ * BEWARE: Not thread safe.
+ */
+const char *tst_strstatus(int status);
 
  void tst_set_timeout(int timeout);
 
lib/newlib_tests/.gitignore +1 -0
index d47a6ea12..e10cbdb72 100644
@@ -17,3 +17,4 @@ test16
  tst_device
  tst_safe_fileops
  tst_res_hexd
+test_str_status
lib/newlib_tests/test_str_status.c new file +0 -0
new file mode 100644
index 000000000..706ec1144

lib/newlib_tests/test_str_status.c line 2

Quoted 2 lines
lib/newlib_tests/test_str_status.c new file +2 -0
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016 Cyril Hrubis<[email protected]>

Hi Cyril,

The correct date is 2017 here.

Thanks,
Xiao Yang

Quoted 115 lines
lib/newlib_tests/test_str_status.c new file +47 -0
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+/*
+ * The test should abort when oldlib function is called from newlib.
+ */
+
+#include "tst_test.h"
+
+static struct tcase {
+	int status;
+	const char *str;
+} tcases[] = {
+	{0x0100, "exitted with 1"},
+	{0x0001, "killed by SIGHUP"},
+	{0x137f, "is stopped"},
+	{0xffff, "is resumed"},
+	{0xff, "invalid status 0xff"},
+};
+
+static void do_test(unsigned int n)
+{
+	const char *str_status = tst_strstatus(tcases[n].status);
+
+	if (strcmp(str_status, tcases[n].str))
+		tst_res(TFAIL, "%s != %s", str_status, tcases[n].str);
+	else
+		tst_res(TPASS, "%s", str_status);
+}
+
+static struct tst_test test = {
+	.test = do_test,
+	.tcnt = ARRAY_SIZE(tcases),
+};
lib/tst_status.c new file +62 -0
new file mode 100644
index 000000000..4bd38e547
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2017 Cyril Hrubis<[email protected]>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see<http://www.gnu.org/licenses/>.
+ */
+
+#include<sys/types.h>
+#include<sys/wait.h>
+#include<stdio.h>
+#define TST_NO_DEFAULT_MAIN
+#include "tst_test.h"
+
+static char buf[32];
+
+const char *exited(int status)
+{
+	snprintf(buf, sizeof(buf), "exitted with %i", WEXITSTATUS(status));
+
+	return buf;
+}
+
+const char *signaled(int status)
+{
+	snprintf(buf, sizeof(buf), "killed by %s", tst_strsig(status));
+
+	return buf;
+}
+
+const char *invalid(int status)
+{
+	snprintf(buf, sizeof(buf), "invalid status 0x%x", status);
+
+	return buf;
+}
+
+const char *tst_strstatus(int status)
+{
+	if (WIFEXITED(status))
+		return exited(status);
+
+	if (WIFSIGNALED(status))
+		return signaled(status);
+
+	if (WIFSTOPPED(status))
+		return "is stopped";
+
+	if (WIFCONTINUED(status))
+		return "is resumed";
+
+	return invalid(status);
+}
#4 lore raw

RFC PATCH 1/2 lib: Add tst_strstatus()

Hi!

Quoted 10 lines

lib/newlib_tests/test_str_status.c line 2

Quoted 8 lines
lib/newlib_tests/test_str_status.c new file +2 -0
new file mode 100644
index 000000000..706ec1144
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016 Cyril Hrubis<[email protected]>

Hi Cyril,

Quoted 2 lines

The correct date is 2017 here.

Ah right, and the top level comment in the test is wrong as well, will fix that.

Signature · 2 lines
Cyril Hrubis
[email protected]