Files
wireplumber/tests/wp/json-utils.c
George Kiagiadakis 42b64bfc28 spa-json: rename _from_string() to _wrap_string() and add new "from" variants
The previous naming convention was confusing because it did not make
it explicit that the string is not being copied. We had this wrong already
in the Lua bindings and thanks to some miracle it hasn't backfired so far
(it was using the "wrap" behaviour with a string that doesn't stay alive).

In some places we actually need the "copy" behaviour and in some other
places we need the "wrap" behaviour, so let's have both variants available.
2023-11-14 12:36:10 +02:00

348 lines
11 KiB
C

/* WirePlumber
*
* Copyright © 2023 Collabora Ltd.
* @author George Kiagiadakis <george.kiagiadakis@collabora.com>
*
* SPDX-License-Identifier: MIT
*/
#include "../common/test-log.h"
static void
test_match_rules_update_properties (void)
{
static const gchar * const rules_json_string =
"["
" {"
" matches = ["
" {"
" device.name = \"~alsa_card.*\""
" }"
" ]"
" actions = {"
" update-props = {"
" api.alsa.use-acp = true"
" api.acp.auto-port = false"
" }"
" }"
" }"
" {"
" matches = ["
" {"
" node.name = \"alsa_output.0.my-alsa-device\""
" }"
" ]"
" actions = {"
" update-props = {"
" audio.rate = 96000"
" node.description = \"My ALSA Node\""
" media.class = null"
" }"
" }"
" }"
"]";
g_autoptr (WpSpaJson) rules = wp_spa_json_new_wrap_stringn (rules_json_string,
strlen (rules_json_string));
g_assert_nonnull (rules);
/* Unmatched */
{
g_autoptr (WpProperties) match_props = NULL;
match_props = wp_properties_new (
"device.name", "unmatched-device-name",
NULL);
g_assert_cmpint (wp_json_utils_match_rules_update_properties (rules, match_props), ==, 0);
}
/* Match regex with props filled */
{
g_autoptr (WpProperties) match_props = NULL;
const gchar *str = NULL;
match_props = wp_properties_new (
"device.name", "alsa_card_0.my-alsa-device",
NULL);
g_assert_nonnull (match_props);
str = wp_properties_get (match_props, "device.name");
g_assert_cmpstr (str, ==, "alsa_card_0.my-alsa-device");
str = wp_properties_get (match_props, "api.alsa.use-acp");
g_assert_null (str);
str = wp_properties_get (match_props, "api.acp.auto-port");
g_assert_null (str);
g_assert_cmpint (wp_json_utils_match_rules_update_properties (rules, match_props), ==, 2);
str = wp_properties_get (match_props, "device.name");
g_assert_cmpstr (str, ==, "alsa_card_0.my-alsa-device");
str = wp_properties_get (match_props, "api.alsa.use-acp");
g_assert_cmpstr (str, ==, "true");
str = wp_properties_get (match_props, "api.acp.auto-port");
g_assert_cmpstr (str, ==, "false");
}
/* Match equal with props filled */
{
g_autoptr (WpProperties) match_props = NULL;
const gchar *str = NULL;
match_props = wp_properties_new (
"node.name", "alsa_output.0.my-alsa-device",
NULL);
g_assert_nonnull (match_props);
str = wp_properties_get (match_props, "node.name");
g_assert_cmpstr (str, ==, "alsa_output.0.my-alsa-device");
str = wp_properties_get (match_props, "audio.rate");
g_assert_null (str);
str = wp_properties_get (match_props, "node.description");
g_assert_null (str);
str = wp_properties_get (match_props, "media.class");
g_assert_null (str);
g_assert_cmpint (wp_json_utils_match_rules_update_properties (rules, match_props), ==, 2);
str = wp_properties_get (match_props, "node.name");
g_assert_cmpstr (str, ==, "alsa_output.0.my-alsa-device");
str = wp_properties_get (match_props, "audio.rate");
g_assert_cmpstr (str, ==, "96000");
str = wp_properties_get (match_props, "node.description");
g_assert_cmpstr (str, ==, "My ALSA Node");
str = wp_properties_get (match_props, "media.class");
g_assert_null (str);
}
/* Match equal with 1 prop updated */
{
g_autoptr (WpProperties) match_props = NULL;
const gchar *str = NULL;
match_props = wp_properties_new (
"node.name", "alsa_output.0.my-alsa-device",
"audio.rate", "96000",
"node.description", "Test",
NULL);
g_assert_nonnull (match_props);
str = wp_properties_get (match_props, "node.name");
g_assert_cmpstr (str, ==, "alsa_output.0.my-alsa-device");
str = wp_properties_get (match_props, "audio.rate");
g_assert_cmpstr (str, ==, "96000");
str = wp_properties_get (match_props, "node.description");
g_assert_cmpstr (str, ==, "Test");
str = wp_properties_get (match_props, "media.class");
g_assert_null (str);
g_assert_cmpint (wp_json_utils_match_rules_update_properties (rules, match_props), ==, 1);
str = wp_properties_get (match_props, "node.name");
g_assert_cmpstr (str, ==, "alsa_output.0.my-alsa-device");
str = wp_properties_get (match_props, "audio.rate");
g_assert_cmpstr (str, ==, "96000");
str = wp_properties_get (match_props, "node.description");
g_assert_cmpstr (str, ==, "My ALSA Node");
str = wp_properties_get (match_props, "media.class");
g_assert_null (str);
}
/* Match equal with prop deleted */
{
g_autoptr (WpProperties) match_props = NULL;
const gchar *str = NULL;
match_props = wp_properties_new (
"node.name", "alsa_output.0.my-alsa-device",
"media.class", "Audio/Sink",
"audio.rate", "48000",
"node.description", "Test",
NULL);
g_assert_nonnull (match_props);
str = wp_properties_get (match_props, "node.name");
g_assert_cmpstr (str, ==, "alsa_output.0.my-alsa-device");
str = wp_properties_get (match_props, "audio.rate");
g_assert_cmpstr (str, ==, "48000");
str = wp_properties_get (match_props, "node.description");
g_assert_cmpstr (str, ==, "Test");
str = wp_properties_get (match_props, "media.class");
g_assert_cmpstr (str, ==, "Audio/Sink");
g_assert_cmpint (wp_json_utils_match_rules_update_properties (rules, match_props), ==, 3);
str = wp_properties_get (match_props, "node.name");
g_assert_cmpstr (str, ==, "alsa_output.0.my-alsa-device");
str = wp_properties_get (match_props, "audio.rate");
g_assert_cmpstr (str, ==, "96000");
str = wp_properties_get (match_props, "node.description");
g_assert_cmpstr (str, ==, "My ALSA Node");
str = wp_properties_get (match_props, "media.class");
g_assert_null (str);
}
}
static gboolean
match_rules_cb (gpointer data, const gchar * action, WpSpaJson * value,
GError ** error)
{
WpProperties *match_props = data;
if (g_str_equal (action, "update-props")) {
wp_properties_update_from_json (match_props, value);
}
else if (g_str_equal (action, "set-answer")) {
g_autofree gchar *str = wp_spa_json_to_string (value);
wp_properties_set (match_props, "answer.universe", str);
}
else if (g_str_equal (action, "generate-error")) {
g_autofree gchar *str = wp_spa_json_parse_string (value);
g_set_error (error, WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_OPERATION_FAILED,
"error: %s", str);
return FALSE;
}
else if (g_str_equal (action, "set-description")) {
g_autofree gchar *str = wp_spa_json_parse_string (value);
wp_properties_set (match_props, "device.description", str);
}
return TRUE;
}
static void
test_match_rules (void)
{
static const gchar * const rules_json_string =
"["
" {"
" matches = ["
" {"
" device.name = \"~alsa_card.*\""
" }"
" ]"
" actions = {"
" update-props = {"
" device.name = alsa_card.1"
" api.acp.auto-port = false"
" }"
" set-answer = 42"
" }"
" }"
" {"
" matches = ["
" {"
" test.error = true"
" }"
" ]"
" actions = {"
" generate-error = \"test.error is true\""
" }"
" }"
" {"
" matches = ["
" {"
" device.name = \"alsa_card.1\""
" }"
" ]"
" actions = {"
" set-description = \"My ALSA Device\""
" }"
" }"
"]";
g_autoptr (WpSpaJson) rules = wp_spa_json_new_wrap_stringn (rules_json_string,
strlen (rules_json_string));
g_assert_nonnull (rules);
/* no error */
{
g_autoptr (GError) error = NULL;
g_autoptr (WpProperties) match_props = NULL;
const gchar *str = NULL;
match_props = wp_properties_new (
"device.name", "alsa_card.0",
"test.error", "false",
NULL);
str = wp_properties_get (match_props, "device.name");
g_assert_cmpstr (str, ==, "alsa_card.0");
str = wp_properties_get (match_props, "api.acp.auto-port");
g_assert_null (str);
str = wp_properties_get (match_props, "answer.universe");
g_assert_null (str);
str = wp_properties_get (match_props, "test.error");
g_assert_cmpstr (str, ==, "false");
str = wp_properties_get (match_props, "device.description");
g_assert_null (str);
g_assert_true (wp_json_utils_match_rules (rules, match_props, match_rules_cb,
match_props, &error));
g_assert_no_error (error);
str = wp_properties_get (match_props, "device.name");
g_assert_cmpstr (str, ==, "alsa_card.1");
str = wp_properties_get (match_props, "api.acp.auto-port");
g_assert_cmpstr (str, ==, "false");
str = wp_properties_get (match_props, "answer.universe");
g_assert_cmpstr (str, ==, "42");
str = wp_properties_get (match_props, "test.error");
g_assert_cmpstr (str, ==, "false");
str = wp_properties_get (match_props, "device.description");
g_assert_cmpstr (str, ==, "My ALSA Device");
}
/* with error */
{
g_autoptr (GError) error = NULL;
g_autoptr (WpProperties) match_props = NULL;
const gchar *str = NULL;
match_props = wp_properties_new (
"device.name", "alsa_card.256",
"test.error", "true",
NULL);
str = wp_properties_get (match_props, "device.name");
g_assert_cmpstr (str, ==, "alsa_card.256");
str = wp_properties_get (match_props, "api.acp.auto-port");
g_assert_null (str);
str = wp_properties_get (match_props, "answer.universe");
g_assert_null (str);
str = wp_properties_get (match_props, "test.error");
g_assert_cmpstr (str, ==, "true");
str = wp_properties_get (match_props, "device.description");
g_assert_null (str);
g_assert_false (wp_json_utils_match_rules (rules, match_props, match_rules_cb,
match_props, &error));
g_assert_error (error, WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_OPERATION_FAILED);
g_assert_cmpstr (error->message, ==, "error: test.error is true");
str = wp_properties_get (match_props, "device.name");
g_assert_cmpstr (str, ==, "alsa_card.1");
str = wp_properties_get (match_props, "api.acp.auto-port");
g_assert_cmpstr (str, ==, "false");
str = wp_properties_get (match_props, "answer.universe");
g_assert_cmpstr (str, ==, "42");
str = wp_properties_get (match_props, "test.error");
g_assert_cmpstr (str, ==, "true");
str = wp_properties_get (match_props, "device.description");
g_assert_null (str);
}
}
gint
main (gint argc, gchar *argv[])
{
g_test_init (&argc, &argv, NULL);
g_log_set_writer_func (wp_log_writer_default, NULL, NULL);
g_test_add_func ("/wp/json-utils/match_rules_update_props",
test_match_rules_update_properties);
g_test_add_func ("/wp/json-utils/match_rules", test_match_rules);
return g_test_run ();
}