Files
libguestfs/tests/events/test-libvirt-auth-callbacks.c
Richard W.M. Jones 6d32773e81 tests: Run the tests in parallel.
Before this change the tests ran in about 12m34 and afterwards in
about 6m20, although the real change is more dramatic if you only run
tests from the tests/ subdirectory (as language tests still run serially).

This breaks valgrinding for now, which I intend to fix properly later.
2021-03-18 16:28:55 +00:00

178 lines
5.4 KiB
C

/* libguestfs
* Copyright (C) 2014 Red Hat Inc.
*
* 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <error.h>
#include <libvirt/libvirt.h>
#include "guestfs.h"
#include "guestfs-utils.h"
#define EXPECT_OK 1
#define EXPECT_FAIL -1
struct auth_data {
const char *username;
const char *password;
};
static void do_test (const char *prog, const char *libvirt_uri, const struct auth_data *auth_data, int expected);
static void auth_callback (guestfs_h *g, void *opaque, uint64_t event, int event_handle, int flags, const char *buf, size_t buf_len, const uint64_t *array, size_t array_len);
int
main (int argc, char *argv[])
{
unsigned long ver;
const char *srcdir;
char *cwd;
char *test_uri;
virInitialize ();
/* Check that the version of libvirt we are linked against
* supports the new test-driver auth feature.
*/
virGetVersion (&ver, NULL, NULL);
if (ver < 1002001)
error (77, 0, "test skipped because libvirt is too old (%lu)", ver);
/* $srcdir must have been passed (by automake). */
srcdir = getenv ("srcdir");
if (!srcdir)
error (EXIT_FAILURE, 0,
"environment variable $srcdir is not defined.\n"
"Normally it is defined by automake. If you are running the\n"
"tests directly, set $srcdir to point to the source tests/events\n"
"directory.");
cwd = getcwd (NULL, 0);
if (cwd == NULL)
error (EXIT_FAILURE, errno, "getcwd");
if (asprintf (&test_uri, "test://%s/%s/events/libvirt-auth.xml",
cwd, srcdir) == -1)
error (EXIT_FAILURE, errno, "asprintf");
free (cwd);
/* Perform the tests. */
struct auth_data ad1 = { .username = "rich", .password = "123456" };
do_test (argv[0], test_uri, &ad1, EXPECT_OK);
struct auth_data ad2 = { .username = "rich", .password = "654321" };
do_test (argv[0], test_uri, &ad2, EXPECT_FAIL);
struct auth_data ad3 = { .username = "jane", .password = NULL };
do_test (argv[0], test_uri, &ad3, EXPECT_OK);
struct auth_data ad4 = { .username = "nouser", .password = "123456" };
do_test (argv[0], test_uri, &ad4, EXPECT_FAIL);
free (test_uri);
exit (EXIT_SUCCESS);
}
static void
do_test (const char *prog, const char *libvirt_uri,
const struct auth_data *auth_data,
int expected)
{
guestfs_h *g;
const char *creds[] =
{ "authname", "passphrase", "noechoprompt", NULL };
int r, eh;
g = guestfs_create ();
if (!g)
error (EXIT_FAILURE, errno, "guestfs_create");
r = guestfs_set_libvirt_supported_credentials (g, (char **) creds);
if (r == -1)
exit (EXIT_FAILURE);
eh = guestfs_set_event_callback (g, auth_callback,
GUESTFS_EVENT_LIBVIRT_AUTH, 0,
(void *) auth_data);
if (eh == -1)
exit (EXIT_FAILURE);
r = guestfs_add_domain (g, "test",
GUESTFS_ADD_DOMAIN_LIBVIRTURI, libvirt_uri,
GUESTFS_ADD_DOMAIN_READONLY, 1,
-1);
if (r != expected)
error (EXIT_FAILURE, 0,
"test failed: u=%s p=%s: got %d expected %d",
auth_data->username, auth_data->password ? : "(none)",
r, expected);
guestfs_close (g);
}
static void
auth_callback (guestfs_h *g, void *opaque,
uint64_t event, int event_handle,
int flags,
const char *buf, size_t buf_len,
const uint64_t *array, size_t array_len)
{
CLEANUP_FREE_STRING_LIST char **creds = NULL;
const struct auth_data *auth_data = opaque;
size_t i;
int r;
const char *reply;
size_t len;
/* Ask libguestfs what credentials libvirt is demanding. */
creds = guestfs_get_libvirt_requested_credentials (g);
if (creds == NULL)
exit (EXIT_FAILURE);
/* Try to answer from the authentication data. */
for (i = 0; creds[i] != NULL; ++i) {
if (STREQ (creds[i], "authname")) {
reply = auth_data->username;
len = strlen (reply);
}
else if (STREQ (creds[i], "passphrase") ||
STREQ (creds[i], "noechoprompt")) {
if (!auth_data->password)
error (EXIT_FAILURE, 0,
"test failed: libvirt asked for a password, but auth_data->password == NULL");
reply = auth_data->password;
len = strlen (reply);
}
else {
error (EXIT_FAILURE, 0,
"test failed: libvirt asked for '%s' which is not in creds list\n(This is probably a libvirt bug)",
creds[i]);
abort (); /* keeps GCC happy since error(3) is not marked noreturn */
}
r = guestfs_set_libvirt_requested_credential (g, i,
reply, len);
if (r == -1)
exit (EXIT_FAILURE);
}
}