From: "Daniel P. Berrangé" <berrange@redhat.com>
To: Daniel Xu <dxu@dxuuu.xyz>
Cc: michael.roth@amd.com, kkostiuk@redhat.com,
marcandre.lureau@gmail.com, qemu-devel@nongnu.org
Subject: Re: [PATCH v3 4/4] qga: test: Add tests for `merge-output` flag
Date: Wed, 1 Mar 2023 09:07:12 +0000 [thread overview]
Message-ID: <Y/8VwOClKyHfWWqH@redhat.com> (raw)
In-Reply-To: <46322f524542aa2147939efc1e814c9d1d273919.1677617035.git.dxu@dxuuu.xyz>
On Tue, Feb 28, 2023 at 01:48:04PM -0700, Daniel Xu wrote:
> This commit adds a test to ensure `merge-output` functions as expected.
> We also add a negative test to ensure we haven't regressed previous
> functionality.
>
> Signed-off-by: Daniel Xu <dxu@dxuuu.xyz>
> ---
> tests/unit/test-qga.c | 157 +++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 140 insertions(+), 17 deletions(-)
>
> diff --git a/tests/unit/test-qga.c b/tests/unit/test-qga.c
> index b4e0a14573..717f3d1103 100644
> --- a/tests/unit/test-qga.c
> +++ b/tests/unit/test-qga.c
> @@ -755,6 +755,31 @@ static void test_qga_fsfreeze_status(gconstpointer fix)
> g_assert_cmpstr(status, ==, "thawed");
> }
>
> +static QDict *wait_for_guest_exec_completion(int fd, int64_t pid)
> +{
> + QDict *ret = NULL;
> + int64_t now;
> + bool exited;
> + QDict *val;
> +
> + now = g_get_monotonic_time();
> + do {
> + ret = qmp_fd(fd,
> + "{'execute': 'guest-exec-status',"
> + " 'arguments': { 'pid': %" PRId64 " } }", pid);
> + g_assert_nonnull(ret);
> + val = qdict_get_qdict(ret, "return");
> + exited = qdict_get_bool(val, "exited");
> + if (!exited) {
> + qobject_unref(ret);
> + }
> + } while (!exited &&
> + g_get_monotonic_time() < now + 5 * G_TIME_SPAN_SECOND);
> + g_assert(exited);
> +
> + return ret;
> +}
> +
> static void test_qga_guest_exec(gconstpointer fix)
> {
> const TestFixture *fixture = fix;
> @@ -762,9 +787,8 @@ static void test_qga_guest_exec(gconstpointer fix)
> QDict *val;
> const gchar *out;
> g_autofree guchar *decoded = NULL;
> - int64_t pid, now, exitcode;
> + int64_t pid, exitcode;
> gsize len;
> - bool exited;
>
> /* exec 'echo foo bar' */
> ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {"
> @@ -777,23 +801,10 @@ static void test_qga_guest_exec(gconstpointer fix)
> g_assert_cmpint(pid, >, 0);
> qobject_unref(ret);
>
> - /* wait for completion */
> - now = g_get_monotonic_time();
> - do {
> - ret = qmp_fd(fixture->fd,
> - "{'execute': 'guest-exec-status',"
> - " 'arguments': { 'pid': %" PRId64 " } }", pid);
> - g_assert_nonnull(ret);
> - val = qdict_get_qdict(ret, "return");
> - exited = qdict_get_bool(val, "exited");
> - if (!exited) {
> - qobject_unref(ret);
> - }
> - } while (!exited &&
> - g_get_monotonic_time() < now + 5 * G_TIME_SPAN_SECOND);
> - g_assert(exited);
> + ret = wait_for_guest_exec_completion(fixture->fd, pid);
>
> /* check stdout */
> + val = qdict_get_qdict(ret, "return");
> exitcode = qdict_get_int(val, "exitcode");
> g_assert_cmpint(exitcode, ==, 0);
> out = qdict_get_str(val, "out-data");
> @@ -802,6 +813,114 @@ static void test_qga_guest_exec(gconstpointer fix)
> g_assert_cmpstr((char *)decoded, ==, "\" test_str \"");
> }
>
> +static void test_qga_guest_exec_output_no_merge(gconstpointer fix)
> +{
> + const TestFixture *fixture = fix;
> + g_autoptr(QDict) ret = NULL;
> + QDict *val;
> + const gchar *out, *err;
> + g_autofree guchar *out_decoded = NULL;
> + g_autofree guchar *err_decoded = NULL;
> + int64_t pid, exitcode;
> + gsize len;
> +
> + /* exec 'echo foo bar' */
> + ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {"
> + " 'path': '/bin/bash',"
> + " 'arg': [ '-c', 'for i in $(seq 4); do if (( $i %% 2 )); then echo stdout; else echo stderr 1>&2; fi; done;' ],"
> + " 'capture-output': true } }");
Surely /bin/bash isn't going to exist on most (all?) Windows deployments,
and so this test will fail on Windows builds ?
> + g_assert_nonnull(ret);
> + qmp_assert_no_error(ret);
> + val = qdict_get_qdict(ret, "return");
> + pid = qdict_get_int(val, "pid");
> + g_assert_cmpint(pid, >, 0);
> + qobject_unref(ret);
> +
> + ret = wait_for_guest_exec_completion(fixture->fd, pid);
> +
> + val = qdict_get_qdict(ret, "return");
> + exitcode = qdict_get_int(val, "exitcode");
> + g_assert_cmpint(exitcode, ==, 0);
> +
> + /* check stdout */
> + out = qdict_get_str(val, "out-data");
> + out_decoded = g_base64_decode(out, &len);
> + g_assert_cmpint(len, ==, 14);
> + g_assert_cmpstr((char *)out_decoded, ==, "stdout\nstdout\n");
> +
> + /* check stderr */
> + err = qdict_get_try_str(val, "err-data");
> + err_decoded = g_base64_decode(err, &len);
> + g_assert_cmpint(len, ==, 14);
> + g_assert_cmpstr((char *)err_decoded, ==, "stderr\nstderr\n");
> +}
> +
> +#if defined(G_OS_WIN32)
> +static void test_qga_guest_exec_output_merge(gconstpointer fix)
> +{
> + const TestFixture *fixture = fix;
> + g_autoptr(QDict) ret = NULL;
> + QDict *val;
> + const gchar *class, *desc;
> + g_autofree guchar *decoded = NULL;
> +
> + /* exec 'echo foo bar' */
> + ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {"
> + " 'path': '/bin/bash',"
> + " 'arg': [ '-c', 'for i in $(seq 4); do if (( $i %% 2 )); then echo stdout; else echo stderr 1>&2; fi; done;' ],"
Looks odd to be invoking bash, though in this case its harmless as we
don't get that far. Still would suggest using 'cmd.exe' as the
example though.
> + " 'capture-output': true,"
> + " 'merge-output': true } }");
> +
> + g_assert_nonnull(ret);
> + val = qdict_get_qdict(ret, "error");
> + g_assert_nonnull(val);
> + class = qdict_get_str(val, "class");
> + desc = qdict_get_str(val, "desc");
> + g_assert_cmpstr(class, ==, "GenericError");
> + g_assert_cmpint(strlen(desc), >, 0);
> +}
> +#else
> +static void test_qga_guest_exec_output_merge(gconstpointer fix)
> +{
> + const TestFixture *fixture = fix;
> + g_autoptr(QDict) ret = NULL;
> + QDict *val;
> + const gchar *out, *err;
> + g_autofree guchar *decoded = NULL;
> + int64_t pid, exitcode;
> + gsize len;
> +
> + /* exec 'echo foo bar' */
> + ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {"
> + " 'path': '/bin/bash',"
> + " 'arg': [ '-c', 'for i in $(seq 4); do if (( $i %% 2 )); then echo stdout; else echo stderr 1>&2; fi; done;' ],"
> + " 'capture-output': true,"
> + " 'merge-output': true } }");
> + g_assert_nonnull(ret);
> + qmp_assert_no_error(ret);
> + val = qdict_get_qdict(ret, "return");
> + pid = qdict_get_int(val, "pid");
> + g_assert_cmpint(pid, >, 0);
> + qobject_unref(ret);
> +
> + ret = wait_for_guest_exec_completion(fixture->fd, pid);
> +
> + val = qdict_get_qdict(ret, "return");
> + exitcode = qdict_get_int(val, "exitcode");
> + g_assert_cmpint(exitcode, ==, 0);
> +
> + /* check stdout */
> + out = qdict_get_str(val, "out-data");
> + decoded = g_base64_decode(out, &len);
> + g_assert_cmpint(len, ==, 28);
> + g_assert_cmpstr((char *)decoded, ==, "stdout\nstderr\nstdout\nstderr\n");
> +
> + /* check stderr */
> + err = qdict_get_try_str(val, "err-data");
> + g_assert_null(err);
> +}
> +#endif
> +
> static void test_qga_guest_exec_invalid(gconstpointer fix)
> {
> const TestFixture *fixture = fix;
> @@ -972,6 +1091,10 @@ int main(int argc, char **argv)
> g_test_add_data_func("/qga/blockedrpcs", NULL, test_qga_blockedrpcs);
> g_test_add_data_func("/qga/config", NULL, test_qga_config);
> g_test_add_data_func("/qga/guest-exec", &fix, test_qga_guest_exec);
> + g_test_add_data_func("/qga/guest-exec-output-no-merge", &fix,
> + test_qga_guest_exec_output_no_merge);
> + g_test_add_data_func("/qga/guest-exec-output-merge", &fix,
> + test_qga_guest_exec_output_merge);
> g_test_add_data_func("/qga/guest-exec-invalid", &fix,
> test_qga_guest_exec_invalid);
> g_test_add_data_func("/qga/guest-get-osinfo", &fix,
> --
> 2.39.1
>
>
With regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
prev parent reply other threads:[~2023-03-01 9:07 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-02-28 20:48 [PATCH v3 0/4] qga: Add optional `merge-output` flag to guest-exec QAPI Daniel Xu
2023-02-28 20:48 ` [PATCH v3 1/4] crypto/luks: Initialize stack variable to silence warning Daniel Xu
2023-03-01 8:53 ` Daniel P. Berrangé
2023-02-28 20:48 ` [PATCH v3 2/4] qemu-keymap: Fix memory leaks Daniel Xu
2023-03-01 7:34 ` Marc-André Lureau
2023-02-28 20:48 ` [PATCH v3 3/4] qga: Add optional `merge-output` flag to guest-exec qapi Daniel Xu
2023-03-01 9:03 ` Daniel P. Berrangé
2023-03-01 16:00 ` Daniel Xu
2023-02-28 20:48 ` [PATCH v3 4/4] qga: test: Add tests for `merge-output` flag Daniel Xu
2023-03-01 9:07 ` Daniel P. Berrangé [this message]
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=Y/8VwOClKyHfWWqH@redhat.com \
--to=berrange@redhat.com \
--cc=dxu@dxuuu.xyz \
--cc=kkostiuk@redhat.com \
--cc=marcandre.lureau@gmail.com \
--cc=michael.roth@amd.com \
--cc=qemu-devel@nongnu.org \
/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.