Move plugin specific tests into dedicated directory

This will prove beneficial when we also add tests for the policy engine
plugins. The increased locality is also nice to have.
This commit is contained in:
Evangelos Ribeiro Tzaras
2022-07-18 22:30:19 +02:00
committed by Guido Günther
parent 86a8f3ae22
commit 11ba83c16e
23 changed files with 163 additions and 107 deletions

View File

@@ -23,7 +23,7 @@
dummy_include = include_directories('.')
dummy_install_dir = join_paths(full_calls_plugin_libdir, 'dummy')
dummy_install_dir = join_paths(calls_provider_plugin_libdir, 'dummy')
dummy_plugin = configure_file(
input: 'dummy.plugin.in',

View File

@@ -21,7 +21,7 @@
# SPDX-License-Identifier: GPL-3.0-or-later
#
mm_install_dir = join_paths(full_calls_plugin_libdir, 'mm')
mm_install_dir = join_paths(calls_provider_plugin_libdir, 'mm')
mm_plugin = configure_file(
input: 'mm.plugin.in',

View File

@@ -23,7 +23,7 @@
subdir('libgdbofono')
ofono_install_dir = join_paths(full_calls_plugin_libdir, 'ofono')
ofono_install_dir = join_paths(calls_provider_plugin_libdir, 'ofono')
ofono_plugin = configure_file(
input: 'ofono.plugin.in',

View File

@@ -23,7 +23,7 @@
sip_include = include_directories('.')
sip_install_dir = join_paths(full_calls_plugin_libdir, 'sip')
sip_install_dir = join_paths(calls_provider_plugin_libdir, 'sip')
sip_plugin = configure_file(
input: 'sip.plugin.in',

View File

@@ -0,0 +1,12 @@
/*
* Copyright (C) 2018 Purism SPC
*
* SPDX-License-Identifier: GPL-3.0+
*/
#define add_calls_test(Object,object,name) \
g_test_add ("/Calls/" #Object "/" #name, Object##Fixture, NULL, \
test_dummy_##object##_set_up, \
test_dummy_##object##_##name, \
test_dummy_##object##_tear_down)

View File

@@ -0,0 +1,147 @@
#
# Copyright (C) 2022 Purism SPC
#
# This file is part of Calls.
#
# Calls 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 3 of the License, or
# (at your option) any later version.
#
# Calls 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 Calls. If not, see <http://www.gnu.org/licenses/>.
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
if get_option('tests')
test_env = [
'G_TEST_SRCDIR=@0@'.format(meson.current_source_dir()),
'G_TEST_BUILDDIR=@0@'.format(meson.current_build_dir()),
'G_DEBUG=gc-friendly,fatal-warnings',
'GSETTINGS_BACKEND=memory',
'PYTHONDONTWRITEBYTECODE=yes',
'MALLOC_CHECK_=2',
'NO_AT_BRIDGE=1',
'CALLS_SIP_TEST=1',
'CALLS_AUDIOSRC=audiotestsrc',
'CALLS_AUDIOSINK=fakesink',
'GSETTINGS_SCHEMA_DIR=@0@/data'.format(meson.project_build_root()),
]
test_cflags = [
'-DFOR_TESTING',
'-Wno-error=deprecated-declarations',
'-DPLUGIN_BUILDDIR="@0@"'.format(full_calls_plugin_builddir),
]
test_link_args = [
'-fPIC',
]
tests = [
[ 'provider', [] ],
[ 'origin', [ 'provider' ] ],
[ 'call', [ 'provider', 'origin' ] ],
]
foreach test : tests
name = test[0]
setup_bases = test[1]
setup_bases += name
test_sources = []
foreach base : setup_bases
test_sources += [ 'setup-' + base + '.c',
'setup-' + base + '.h' ]
endforeach
test_sources += [ 'test-' + name + '.c',
'common.h' ]
t = executable(name, test_sources,
dummy_sources,
c_args : test_cflags,
link_args: test_link_args,
pie: true,
link_with : [calls_vala, libcalls],
dependencies: calls_deps,
include_directories : [
calls_includes,
dummy_include,
]
)
test(name, t, env: test_env)
endforeach
test_sources = [ 'test-media.c' ]
test_sources += sip_sources
t = executable('media', test_sources,
c_args : test_cflags,
link_args: test_link_args,
pie: true,
link_with : [calls_vala, libcalls],
dependencies: [calls_deps, sip_deps],
include_directories : [
calls_includes,
sip_include,
]
)
test('media', t, env: test_env)
test_sources = [ 'test-sip.c' ]
test_sources += sip_sources
t = executable('sip', test_sources,
c_args : test_cflags,
link_args: test_link_args,
pie: true,
link_with : [calls_vala, libcalls],
dependencies: [calls_deps, sip_deps],
include_directories : [
calls_includes,
sip_include,
]
)
test('sip', t, env: test_env)
test_sources = [ 'test-srtp.c' ]
test_sources += sip_sources
t = executable('srtp', test_sources,
c_args : test_cflags,
link_args: test_link_args,
pie: true,
link_with : [calls_vala, libcalls],
dependencies: [calls_deps, sip_deps],
include_directories : [
calls_includes,
sip_include,
]
)
test('srtp', t, env: test_env)
test_sources = [ 'test-sdp-crypto.c' ]
test_sources += sip_sources
t = executable('sdp-crypto', test_sources,
c_args : test_cflags,
link_args: test_link_args,
pie: true,
link_with : [calls_vala, libcalls],
dependencies: [calls_deps, sip_deps],
include_directories : [
calls_includes,
sip_include,
]
)
test('sdp-crypto', t, env: test_env)
endif

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) 2018 Purism SPC
*
* SPDX-License-Identifier: GPL-3.0+
*/
#include "setup-call.h"
#include "calls-origin.h"
void
test_dummy_call_set_up (CallFixture *fixture,
gconstpointer user_data)
{
CallsOrigin *origin;
GList *calls;
test_dummy_origin_set_up (&fixture->parent, user_data);
origin = CALLS_ORIGIN (fixture->parent.dummy_origin);
calls_origin_dial (origin, TEST_CALL_NUMBER);
calls = calls_origin_get_calls (origin);
fixture->dummy_call = CALLS_DUMMY_CALL (calls->data);
g_list_free (calls);
}
void
test_dummy_call_tear_down (CallFixture *fixture,
gconstpointer user_data)
{
fixture->dummy_call = NULL;
test_dummy_origin_tear_down (&fixture->parent, user_data);
}

View File

@@ -0,0 +1,16 @@
/*
* Copyright (C) 2018 Purism SPC
*
* SPDX-License-Identifier: GPL-3.0+
*/
#include "setup-origin.h"
#include "calls-dummy-call.h"
typedef struct {
OriginFixture parent;
CallsDummyCall *dummy_call;
} CallFixture;
void test_dummy_call_set_up (CallFixture *fixture, gconstpointer user_data);
void test_dummy_call_tear_down (CallFixture *fixture, gconstpointer user_data);

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) 2018 Purism SPC
*
* SPDX-License-Identifier: GPL-3.0+
*/
#include "setup-origin.h"
#include "calls-provider.h"
void
test_dummy_origin_set_up (OriginFixture *fixture,
gconstpointer user_data)
{
GListModel *origins;
test_dummy_provider_set_up (&fixture->parent, user_data);
/* provider adds an origin with name "Dummy origin" by itself... */
calls_dummy_provider_add_origin (fixture->parent.dummy_provider,
TEST_ORIGIN_NAME);
origins = calls_provider_get_origins
(CALLS_PROVIDER (fixture->parent.dummy_provider));
fixture->dummy_origin = g_list_model_get_item (origins, 1);
}
void
test_dummy_origin_tear_down (OriginFixture *fixture,
gconstpointer user_data)
{
g_clear_object (&fixture->dummy_origin);
test_dummy_provider_tear_down (&fixture->parent, user_data);
}

View File

@@ -0,0 +1,20 @@
/*
* Copyright (C) 2018 Purism SPC
*
* SPDX-License-Identifier: GPL-3.0+
*/
#include "setup-provider.h"
#include "calls-dummy-origin.h"
#define TEST_ORIGIN_NAME "Test Dummy origin"
#define TEST_CALL_NUMBER "0123456789"
typedef struct {
ProviderFixture parent;
CallsDummyOrigin *dummy_origin;
} OriginFixture;
void test_dummy_origin_set_up (OriginFixture *fixture, gconstpointer user_data);
void test_dummy_origin_tear_down (OriginFixture *fixture, gconstpointer user_data);

View File

@@ -0,0 +1,22 @@
/*
* Copyright (C) 2018 Purism SPC
*
* SPDX-License-Identifier: GPL-3.0+
*/
#include "setup-provider.h"
void
test_dummy_provider_set_up (ProviderFixture *fixture,
gconstpointer user_data)
{
fixture->dummy_provider = calls_dummy_provider_new ();
}
void
test_dummy_provider_tear_down (ProviderFixture *fixture,
gconstpointer user_data)
{
g_clear_object (&fixture->dummy_provider);
}

View File

@@ -0,0 +1,14 @@
/*
* Copyright (C) 2018 Purism SPC
*
* SPDX-License-Identifier: GPL-3.0+
*/
#include "calls-dummy-provider.h"
typedef struct {
CallsDummyProvider *dummy_provider;
} ProviderFixture;
void test_dummy_provider_set_up (ProviderFixture *fixture, gconstpointer user_data);
void test_dummy_provider_tear_down (ProviderFixture *fixture, gconstpointer user_data);

View File

@@ -0,0 +1,82 @@
/*
* Copyright (C) 2018 Purism SPC
*
* SPDX-License-Identifier: GPL-3.0+
*/
#include "setup-call.h"
#include "calls-message-source.h"
#include "calls-call.h"
#include "calls-origin.h"
#include "common.h"
#include <gtk/gtk.h>
#include <string.h>
static void
test_dummy_call_object (CallFixture *fixture,
gconstpointer user_data)
{
g_assert_true (G_IS_OBJECT (fixture->dummy_call));
g_assert_true (CALLS_IS_MESSAGE_SOURCE (fixture->dummy_call));
g_assert_true (CALLS_IS_CALL (fixture->dummy_call));
}
static void
test_dummy_call_get_id (CallFixture *fixture,
gconstpointer user_data)
{
const char *id;
id = calls_call_get_id (CALLS_CALL (fixture->dummy_call));
g_assert_nonnull (id);
g_assert_cmpstr (id, ==, TEST_CALL_NUMBER);
}
static void
test_dummy_call_get_state (CallFixture *fixture,
gconstpointer user_data)
{
CallsCallState state;
state = calls_call_get_state (CALLS_CALL (fixture->dummy_call));
g_assert_true (state == CALLS_CALL_STATE_DIALING);
}
static gboolean
test_dummy_call_hang_up_idle_cb (CallsDummyOrigin *origin)
{
g_assert_null (calls_origin_get_calls (CALLS_ORIGIN (origin)));
return G_SOURCE_REMOVE;
}
static void
test_dummy_call_hang_up (CallFixture *fixture,
gconstpointer user_data)
{
calls_call_hang_up (CALLS_CALL (fixture->dummy_call));
// Mirror the dummy origin's use of an idle callback
g_idle_add ((GSourceFunc)test_dummy_call_hang_up_idle_cb,
fixture->parent.dummy_origin);
}
gint
main (gint argc,
gchar *argv[])
{
gtk_test_init (&argc, &argv, NULL);
#define add_test(name) add_calls_test(Call, call, name)
add_test(object);
add_test(get_id);
add_test(get_state);
add_test(hang_up);
#undef add_test
return g_test_run();
}

View File

@@ -0,0 +1,300 @@
/*
* Copyright (C) 2022 Purism SPC
*
* SPDX-License-Identifier: GPL-3.0+
*
* Author: Evangelos Ribeiro Tzaras <evangelos.tzaras@puri.sm>
*/
#include "calls-sip-call.h"
#include "calls-sip-media-manager.h"
#include "calls-srtp-utils.h"
#include "gst-rfc3551.h"
#include <gtk/gtk.h>
#include <gst/gst.h>
static gboolean
find_string_in_sdp_message (const char *sdp,
const char *string)
{
char **split_string = NULL;
gboolean found = FALSE;
split_string = g_strsplit (sdp, "\r\n", -1);
for (guint i = 0; split_string[i] != NULL; i++) {
if (g_strcmp0 (split_string[i], string) == 0) {
found = TRUE;
break;
}
}
g_strfreev (split_string);
return found;
}
static void
test_sip_media_manager_caps (void)
{
CallsSipMediaManager *manager = calls_sip_media_manager_default ();
char *sdp_message = NULL;
GList *codecs = NULL;
GList *crypto_attributes;
calls_srtp_crypto_attribute *attr;
attr = calls_srtp_crypto_attribute_new (1);
attr->tag = 1;
attr->crypto_suite = CALLS_SRTP_SUITE_AES_128_SHA1_80;
calls_srtp_crypto_attribute_init_keys (attr);
crypto_attributes = g_list_append (NULL, attr);
/* Check single codecs */
codecs = g_list_append (NULL, media_codec_by_name ("PCMA"));
g_debug ("Testing generated SDP messages");
/* PCMA RTP */
sdp_message =
calls_sip_media_manager_get_capabilities (manager, NULL, 40002, 40003, NULL, codecs);
g_assert_true (sdp_message);
g_assert_true (find_string_in_sdp_message (sdp_message,
"m=audio 40002 RTP/AVP 8"));
g_assert_true (find_string_in_sdp_message (sdp_message,
"a=rtpmap:8 PCMA/8000"));
g_assert_true (find_string_in_sdp_message (sdp_message,
"a=rtcp:40003"));
g_free (sdp_message);
g_debug ("PCMA RTP test OK");
/* PCMA SRTP */
sdp_message =
calls_sip_media_manager_get_capabilities (manager, NULL, 42002, 42003, crypto_attributes, codecs);
g_assert_true (sdp_message);
g_assert_true (find_string_in_sdp_message (sdp_message,
"m=audio 42002 RTP/SAVP 8"));
g_clear_pointer (&codecs, g_list_free);
g_free (sdp_message);
g_debug ("PCMA SRTP test OK");
/* G722 RTP */
/*
codecs = g_list_append (NULL, media_codec_by_name ("G722"));
sdp_message =
calls_sip_media_manager_get_capabilities (manager, NULL, 42042, 55543, NULL, codecs);
g_assert_true (sdp_message);
g_assert_true (find_string_in_sdp_message (sdp_message,
"m=audio 42042 RTP/AVP 9"));
g_assert_true (find_string_in_sdp_message (sdp_message,
"a=rtpmap:9 G722/8000"));
g_assert_true (find_string_in_sdp_message (sdp_message,
"a=rtcp:55543"));
g_clear_pointer (&codecs, g_list_free);
g_free (sdp_message);
g_debug ("G722 RTP test OK");
*/
/* G722 PCMU PCMA RTP (in this order) */
/* codecs = g_list_append (NULL, media_codec_by_name ("G722")); */
codecs = g_list_append (codecs, media_codec_by_name ("PCMU"));
codecs = g_list_append (codecs, media_codec_by_name ("PCMA"));
sdp_message =
calls_sip_media_manager_get_capabilities (manager, NULL, 33340, 33341, NULL, codecs);
g_assert_true (sdp_message);
g_assert_true (find_string_in_sdp_message (sdp_message,
"m=audio 33340 RTP/AVP 0 8"));
/*
g_assert_true (find_string_in_sdp_message (sdp_message,
"a=rtpmap:9 G722/8000"));
*/
g_assert_true (find_string_in_sdp_message (sdp_message,
"a=rtpmap:0 PCMU/8000"));
g_assert_true (find_string_in_sdp_message (sdp_message,
"a=rtpmap:8 PCMA/8000"));
g_clear_pointer (&codecs, g_list_free);
g_free (sdp_message);
g_debug ("multiple codecs RTP test OK");
/* GSM PCMA G722 PCMU SRTP (in this order) */
codecs = g_list_append (NULL, media_codec_by_name ("GSM"));
codecs = g_list_append (codecs, media_codec_by_name ("PCMA"));
/*
codecs = g_list_append (codecs, media_codec_by_name ("G722"));
*/
codecs = g_list_append (codecs, media_codec_by_name ("PCMU"));
sdp_message =
calls_sip_media_manager_get_capabilities (manager, NULL, 18098, 18099, crypto_attributes, codecs);
g_assert_true (sdp_message);
g_assert_true (find_string_in_sdp_message (sdp_message,
"m=audio 18098 RTP/SAVP 3 8 0"));
g_clear_pointer (&codecs, g_list_free);
g_free (sdp_message);
g_debug ("multiple codecs SRTP test OK");
/* no codecs */
g_test_expect_message ("CallsSipMediaManager", G_LOG_LEVEL_WARNING,
"No supported codecs found. Can't build meaningful SDP message");
sdp_message =
calls_sip_media_manager_get_capabilities (manager, NULL, 25048, 25049, NULL, NULL);
g_test_assert_expected_messages ();
g_assert_true (sdp_message);
g_assert_true (find_string_in_sdp_message (sdp_message,
"m=audio 0 RTP/AVP"));
g_free (sdp_message);
g_debug ("no codecs test OK");
g_list_free (crypto_attributes);
calls_srtp_crypto_attribute_free (attr);
}
static void
test_media_pipeline_states (void)
{
CallsSipMediaPipeline *pipeline = calls_sip_media_pipeline_new (NULL);
MediaCodecInfo *codec = media_codec_by_name ("PCMA");
g_assert_cmpint (calls_sip_media_pipeline_get_state (pipeline), ==,
CALLS_MEDIA_PIPELINE_STATE_NEED_CODEC);
calls_sip_media_pipeline_set_codec (pipeline, codec);
g_assert_cmpint (calls_sip_media_pipeline_get_state (pipeline), ==,
CALLS_MEDIA_PIPELINE_STATE_READY);
calls_sip_media_pipeline_start (pipeline);
g_assert_cmpint (calls_sip_media_pipeline_get_state (pipeline), ==,
CALLS_MEDIA_PIPELINE_STATE_PLAY_PENDING);
calls_sip_media_pipeline_pause (pipeline, TRUE);
g_assert_cmpint (calls_sip_media_pipeline_get_state (pipeline), ==,
CALLS_MEDIA_PIPELINE_STATE_PAUSE_PENDING);
calls_sip_media_pipeline_pause (pipeline, FALSE);
g_assert_cmpint (calls_sip_media_pipeline_get_state (pipeline), ==,
CALLS_MEDIA_PIPELINE_STATE_PLAY_PENDING);
calls_sip_media_pipeline_stop (pipeline);
g_assert_cmpint (calls_sip_media_pipeline_get_state (pipeline), ==,
CALLS_MEDIA_PIPELINE_STATE_STOP_PENDING);
g_assert_finalize_object (pipeline);
}
static void
test_media_pipeline_setup_codecs (void)
{
const char * const codec_names[] = {"PCMA", "PCMU", "GSM", "G722"};
for (uint i = 0; i < G_N_ELEMENTS (codec_names); i++) {
g_autoptr (CallsSipMediaPipeline) pipeline = calls_sip_media_pipeline_new (NULL);
MediaCodecInfo *codec = media_codec_by_name ("PCMA");
g_assert_cmpint (calls_sip_media_pipeline_get_state (pipeline), ==,
CALLS_MEDIA_PIPELINE_STATE_NEED_CODEC);
calls_sip_media_pipeline_set_codec (pipeline, codec);
g_assert_cmpint (calls_sip_media_pipeline_get_state (pipeline), ==,
CALLS_MEDIA_PIPELINE_STATE_READY);
}
}
static void
test_media_pipeline_start_no_codec (void)
{
g_autoptr (CallsSipMediaPipeline) pipeline = calls_sip_media_pipeline_new (NULL);
g_assert_cmpint (calls_sip_media_pipeline_get_state (pipeline), ==,
CALLS_MEDIA_PIPELINE_STATE_NEED_CODEC);
g_test_expect_message ("CallsSipMediaPipeline", G_LOG_LEVEL_WARNING,
"Cannot start pipeline because it's not ready");
calls_sip_media_pipeline_start (pipeline);
g_test_assert_expected_messages ();
g_test_expect_message ("CallsSipMediaPipeline", G_LOG_LEVEL_WARNING,
"Cannot pause or unpause pipeline because it's not currently active");
calls_sip_media_pipeline_pause (pipeline, TRUE);
g_test_assert_expected_messages ();
}
static void
test_media_pipeline_finalized_in_call (void)
{
CallsSipMediaManager *manager = calls_sip_media_manager_default ();
CallsSipMediaPipeline *pipeline = calls_sip_media_pipeline_new (NULL);
CallsSipCall *call = calls_sip_call_new ("sip:alice@example.org",
TRUE,
"127.0.0.1",
pipeline,
SIP_MEDIA_ENCRYPTION_NONE,
NULL);
g_object_unref (call);
g_assert_finalize_object (pipeline);
pipeline = calls_sip_media_manager_get_pipeline (manager);
call = calls_sip_call_new ("sip:bob@example.org",
TRUE,
"127.0.0.1",
pipeline,
SIP_MEDIA_ENCRYPTION_NONE,
NULL);
g_object_unref (call);
g_assert_finalize_object (pipeline);
}
int
main (int argc,
char *argv[])
{
CallsSipMediaManager *manager = calls_sip_media_manager_default ();
int ret;
gtk_test_init (&argc, &argv, NULL);
gst_init (NULL, NULL);
g_test_add_func ("/Calls/media/media_manager/capabilities", test_sip_media_manager_caps);
g_test_add_func ("/Calls/media/pipeline/states", test_media_pipeline_states);
g_test_add_func ("/Calls/media/pipeline/setup_codecs", test_media_pipeline_setup_codecs);
g_test_add_func ("/Calls/media/pipeline/start_no_codec", test_media_pipeline_start_no_codec);
g_test_add_func ("/Calls/media/pipeline/finalized_in_call", test_media_pipeline_finalized_in_call);
ret = g_test_run ();
g_assert_finalize_object (manager);
gst_deinit ();
return ret;
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright (C) 2018 Purism SPC
*
* SPDX-License-Identifier: GPL-3.0+
*/
#include "setup-origin.h"
#include "calls-message-source.h"
#include "calls-origin.h"
#include "common.h"
#include <gtk/gtk.h>
#include <string.h>
static void
test_dummy_origin_object (OriginFixture *fixture,
gconstpointer user_data)
{
g_assert_true (G_IS_OBJECT (fixture->dummy_origin));
g_assert_true (CALLS_IS_MESSAGE_SOURCE (fixture->dummy_origin));
g_assert_true (CALLS_IS_ORIGIN (fixture->dummy_origin));
}
static void
test_dummy_origin_get_name (OriginFixture *fixture,
gconstpointer user_data)
{
CallsOrigin *origin;
g_autofree char *name = NULL;
origin = CALLS_ORIGIN (fixture->dummy_origin);
name = calls_origin_get_name (origin);
g_assert_nonnull (name);
g_assert_cmpstr (name, ==, TEST_ORIGIN_NAME);
}
static void
add_call (guint *add_count)
{
++(*add_count);
}
static void
test_dummy_origin_calls (OriginFixture *fixture,
gconstpointer user_data)
{
static const guint ADDS = 2;
CallsOrigin *origin = CALLS_ORIGIN (fixture->dummy_origin);
guint i, add_count = 0;
gulong handler;
GList *calls;
handler = g_signal_connect_swapped (origin, "call-added",
G_CALLBACK (add_call), &add_count);
g_assert_cmpuint (handler, >, 0);
for (i = 1; i <= ADDS; ++i)
{
char number[8];
snprintf (number, 2, "%u", i);
calls_origin_dial (origin, number);
}
g_signal_handler_disconnect (origin, handler);
g_assert_cmpuint (add_count, ==, ADDS);
calls = calls_origin_get_calls (origin);
g_assert_cmpuint (g_list_length (calls), ==, add_count);
g_list_free (calls);
}
gint
main (gint argc,
gchar *argv[])
{
gtk_test_init (&argc, &argv, NULL);
#define add_test(name) add_calls_test(Origin, origin, name)
add_test(object);
add_test(get_name);
add_test(calls);
#undef add_test
return g_test_run();
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright (C) 2018 Purism SPC
*
* SPDX-License-Identifier: GPL-3.0+
*/
#include "setup-provider.h"
#include "calls-provider.h"
#include "calls-origin.h"
#include "calls-message-source.h"
#include "common.h"
#include <gtk/gtk.h>
#include <string.h>
static void
test_dummy_provider_object (ProviderFixture *fixture,
gconstpointer user_data)
{
g_assert_true (G_IS_OBJECT (fixture->dummy_provider));
g_assert_true (CALLS_IS_MESSAGE_SOURCE (fixture->dummy_provider));
g_assert_true (CALLS_IS_PROVIDER (fixture->dummy_provider));
}
static void
test_dummy_provider_get_name (ProviderFixture *fixture,
gconstpointer user_data)
{
CallsProvider *provider;
const gchar *name;
provider = CALLS_PROVIDER (fixture->dummy_provider);
name = calls_provider_get_name (provider);
g_assert_nonnull (name);
g_assert_cmpuint (strlen (name), >, 0U);
}
static void
test_dummy_provider_origins (ProviderFixture *fixture,
gconstpointer user_data)
{
GListModel *origins;
origins = calls_provider_get_origins
(CALLS_PROVIDER (fixture->dummy_provider));
g_assert_cmpuint (g_list_model_get_n_items (origins), ==, 1);
}
gint
main (gint argc,
gchar *argv[])
{
gtk_test_init (&argc, &argv, NULL);
#define add_test(name) add_calls_test(Provider, provider, name)
add_test(object);
add_test(get_name);
add_test(origins);
#undef add_test
return g_test_run();
}

View File

@@ -0,0 +1,177 @@
/*
* Copyright (C) 2022 Purism SPC
*
* SPDX-License-Identifier: GPL-3.0+
*
* Author: Evangelos Ribeiro Tzaras <evangelos.tzaras@puri.sm>
*/
#include "calls-sdp-crypto-context.h"
#include <gtk/gtk.h>
static void
test_crypto_manual (void)
{
g_autoptr (CallsSdpCryptoContext) ctx = NULL;
g_autofree guchar *offer_key = NULL;
g_autofree char *offer_key_b64 = NULL;
g_autofree char *offer_crypto_attr = NULL;
g_autofree char *offer_full = NULL;
g_autofree guchar *answer_key = NULL;
g_autofree char *answer_key_b64 = NULL;
g_autofree char *answer_crypto_attr = NULL;
g_autofree char *answer_full = NULL;
calls_srtp_crypto_attribute *offer_attr;
calls_srtp_crypto_attribute *answer_attr;
su_home_t home;
sdp_parser_t *sdp_parser_offer;
sdp_session_t *sdp_offer;
sdp_parser_t *sdp_parser_answer;
sdp_session_t *sdp_answer;
su_home_init (&home);
ctx = calls_sdp_crypto_context_new ();
offer_key = calls_srtp_generate_key_salt (30);
offer_key_b64 = g_base64_encode (offer_key, 30);
g_debug ("Offer key: %s", offer_key_b64);
offer_crypto_attr = g_strdup_printf ("a=crypto:1 AES_CM_128_HMAC_SHA1_32 inline:%s",
offer_key_b64);
offer_full = g_strdup_printf ("m=audio 21000 RTP/SAVP 0\r\n"
"%s",
offer_crypto_attr);
sdp_parser_offer = sdp_parse (&home, offer_full, -1, sdp_f_config);
sdp_offer = sdp_session (sdp_parser_offer);
g_assert_true (calls_sdp_crypto_context_set_remote_media (ctx, sdp_offer->sdp_media));
answer_key = calls_srtp_generate_key_salt (30);
answer_key_b64 = g_base64_encode (answer_key, 30);
g_debug ("Answer key: %s", answer_key_b64);
answer_crypto_attr = g_strdup_printf ("a=crypto:1 AES_CM_128_HMAC_SHA1_32 inline:%s",
answer_key_b64);
answer_full = g_strdup_printf ("m=audio 42000 RTP/SAVP 0\r\n"
"%s",
answer_crypto_attr);
sdp_parser_answer = sdp_parse (&home, answer_full, -1, sdp_f_config);
sdp_answer = sdp_session (sdp_parser_answer);
g_assert_true (calls_sdp_crypto_context_set_local_media (ctx, sdp_answer->sdp_media));
g_assert_true (calls_sdp_crypto_context_get_is_negotiated (ctx));
offer_attr = calls_sdp_crypto_context_get_remote_crypto (ctx);
g_assert_true (offer_attr);
g_assert_cmpuint (offer_attr->n_key_params, ==, 1);
g_assert_cmpstr (offer_attr->key_params[0].b64_keysalt, ==, offer_key_b64);
answer_attr = calls_sdp_crypto_context_get_local_crypto (ctx);
g_assert_true (answer_attr);
g_assert_cmpuint (answer_attr->n_key_params, ==, 1);
g_assert_cmpstr (answer_attr->key_params[0].b64_keysalt, ==, answer_key_b64);
g_assert_cmpint (offer_attr->tag, ==, answer_attr->tag);
g_assert_cmpint (offer_attr->crypto_suite, ==, answer_attr->crypto_suite);
sdp_parser_free (sdp_parser_offer);
sdp_parser_free (sdp_parser_answer);
su_home_deinit (&home);
}
static void
test_crypto_offer_answer (void)
{
g_autoptr (CallsSdpCryptoContext) ctx_offer = calls_sdp_crypto_context_new ();
g_autoptr (CallsSdpCryptoContext) ctx_answer = calls_sdp_crypto_context_new ();
g_autoptr (GList) attr_offer_list = NULL;
calls_srtp_crypto_attribute *attr_offer;
calls_srtp_crypto_attribute *attr_answer;
g_autofree char *attr_offer_str = NULL;
g_autofree char *attr_answer_str = NULL;
g_autofree char *media_line_offer = NULL;
g_autofree char *media_line_answer = NULL;
su_home_t home;
sdp_parser_t *sdp_parser_offer;
sdp_parser_t *sdp_parser_answer;
sdp_session_t *sdp_session_offer;
sdp_session_t *sdp_session_answer;
su_home_init (&home);
g_assert_cmpint (calls_sdp_crypto_context_get_state (ctx_offer), ==,
CALLS_CRYPTO_CONTEXT_STATE_INIT);
g_assert_cmpint (calls_sdp_crypto_context_get_state (ctx_answer), ==,
CALLS_CRYPTO_CONTEXT_STATE_INIT);
calls_sdp_crypto_context_generate_offer (ctx_offer);
g_assert_cmpint (calls_sdp_crypto_context_get_state (ctx_offer), ==,
CALLS_CRYPTO_CONTEXT_STATE_OFFER_LOCAL);
attr_offer_list =
calls_sdp_crypto_context_get_crypto_candidates (ctx_offer, FALSE);
attr_offer = attr_offer_list->data;
attr_offer_str = calls_srtp_print_sdp_crypto_attribute (attr_offer, NULL);
g_assert_true (attr_offer_str);
media_line_offer = g_strdup_printf ("m=audio 42024 RTP/SAVP 0\r\n%s",
attr_offer_str);
sdp_parser_offer = sdp_parse (&home, media_line_offer, -1, sdp_f_config);
sdp_session_offer = sdp_session (sdp_parser_offer);
calls_sdp_crypto_context_set_remote_media (ctx_answer,
sdp_session_offer->sdp_media);
g_assert_cmpint (calls_sdp_crypto_context_get_state (ctx_answer), ==,
CALLS_CRYPTO_CONTEXT_STATE_OFFER_REMOTE);
calls_sdp_crypto_context_generate_answer (ctx_answer);
g_assert_cmpint (calls_sdp_crypto_context_get_state (ctx_answer), ==,
CALLS_CRYPTO_CONTEXT_STATE_NEGOTIATION_SUCCESS);
g_assert_true (calls_sdp_crypto_context_get_is_negotiated (ctx_answer));
attr_answer = calls_sdp_crypto_context_get_remote_crypto (ctx_answer);
attr_answer_str = calls_srtp_print_sdp_crypto_attribute (attr_answer, NULL);
g_assert_true (attr_answer_str);
media_line_answer = g_strdup_printf ("m=audio 42124 RTP/SAVP 0\r\n%s",
attr_answer_str);
sdp_parser_answer = sdp_parse (&home, media_line_answer, -1, sdp_f_config);
sdp_session_answer = sdp_session (sdp_parser_answer);
calls_sdp_crypto_context_set_remote_media (ctx_offer,
sdp_session_answer->sdp_media);
g_assert_cmpint (calls_sdp_crypto_context_get_state (ctx_offer), ==,
CALLS_CRYPTO_CONTEXT_STATE_NEGOTIATION_SUCCESS);
g_assert_true (calls_sdp_crypto_context_get_is_negotiated (ctx_offer));
su_home_deinit (&home);
}
int
main (int argc,
char *argv[])
{
gtk_test_init (&argc, &argv, NULL);
g_test_add_func ("/Calls/SDP_crypto/manual", test_crypto_manual);
g_test_add_func ("/Calls/SDP_crypto/offer_answer", test_crypto_offer_answer);
return g_test_run ();
}

View File

@@ -0,0 +1,459 @@
/*
* Copyright (C) 2021-2022 Purism SPC
*
* SPDX-License-Identifier: GPL-3.0+
*
* Author: Evangelos Ribeiro Tzaras <evangelos.tzaras@puri.sm>
*/
#include "calls-provider.h"
#include "calls-sip-media-manager.h"
#include "calls-sip-provider.h"
#include "calls-sip-origin.h"
#include "calls-sip-util.h"
#include "calls-account.h"
#include "gst-rfc3551.h"
#include <gtk/gtk.h>
#include <gst/gst.h>
#include <sofia-sip/su_uniqueid.h>
#include <libpeas/peas.h>
typedef struct {
CallsSipProvider *provider;
CallsSipOrigin *origin_alice;
CallsSipOrigin *origin_bob;
CallsSipOrigin *origin_offline;
} SipFixture;
static gboolean is_call_test_done = FALSE;
static gboolean are_call_tests_done = FALSE;
static void
test_sip_provider_object (SipFixture *fixture,
gconstpointer user_data)
{
SipEngineState state;
g_assert_true (G_IS_OBJECT (fixture->provider));
g_assert_true (CALLS_IS_MESSAGE_SOURCE (fixture->provider));
g_assert_true (CALLS_IS_PROVIDER (fixture->provider));
g_assert_true (CALLS_IS_SIP_PROVIDER (fixture->provider));
g_object_get (fixture->provider,
"sip-state", &state,
NULL);
g_assert_cmpint (state, ==, SIP_ENGINE_READY);
}
static void
test_sip_provider_origins (SipFixture *fixture,
gconstpointer user_data)
{
GListModel *origins;
origins = calls_provider_get_origins (CALLS_PROVIDER (fixture->provider));
g_assert_cmpuint (g_list_model_get_n_items (origins), ==, 0);
}
static void
setup_sip_provider (SipFixture *fixture,
gconstpointer user_data)
{
CallsProvider *provider = g_object_new (CALLS_TYPE_SIP_PROVIDER, NULL);
fixture->provider = CALLS_SIP_PROVIDER (provider);
is_call_test_done = FALSE;
are_call_tests_done = FALSE;
}
static void
tear_down_sip_provider (SipFixture *fixture,
gconstpointer user_data)
{
g_clear_object (&fixture->provider);
}
static void
test_sip_origin_objects (SipFixture *fixture,
gconstpointer user_data)
{
CallsAccountState state_alice, state_bob, state_offline;
g_assert_true (G_IS_OBJECT (fixture->origin_alice));
g_assert_true (G_IS_OBJECT (fixture->origin_bob));
g_assert_true (G_IS_OBJECT (fixture->origin_offline));
g_assert_true (CALLS_IS_MESSAGE_SOURCE (fixture->origin_alice));
g_assert_true (CALLS_IS_MESSAGE_SOURCE (fixture->origin_bob));
g_assert_true (CALLS_IS_MESSAGE_SOURCE (fixture->origin_offline));
g_assert_true (CALLS_IS_ORIGIN (fixture->origin_alice));
g_assert_true (CALLS_IS_ORIGIN (fixture->origin_bob));
g_assert_true (CALLS_IS_ORIGIN (fixture->origin_offline));
g_assert_true (CALLS_IS_SIP_ORIGIN (fixture->origin_alice));
g_assert_true (CALLS_IS_SIP_ORIGIN (fixture->origin_bob));
g_assert_true (CALLS_IS_SIP_ORIGIN (fixture->origin_offline));
g_object_get (fixture->origin_alice,
"account-state", &state_alice,
NULL);
g_object_get (fixture->origin_bob,
"account-state", &state_bob,
NULL);
g_object_get (fixture->origin_offline,
"account-state", &state_offline,
NULL);
g_assert_cmpint (state_alice, ==, CALLS_ACCOUNT_STATE_ONLINE);
g_assert_cmpint (state_bob, ==, CALLS_ACCOUNT_STATE_ONLINE);
g_assert_cmpint (state_offline, ==, CALLS_ACCOUNT_STATE_OFFLINE);
}
static void
test_sip_origin_call_lists (SipFixture *fixture,
gconstpointer user_data)
{
g_autoptr (GList) calls_alice = NULL;
g_autoptr (GList) calls_bob = NULL;
g_autoptr (GList) calls_offline = NULL;
calls_alice = calls_origin_get_calls (CALLS_ORIGIN (fixture->origin_alice));
g_assert_null (calls_alice);
calls_bob = calls_origin_get_calls (CALLS_ORIGIN (fixture->origin_bob));
g_assert_null (calls_bob);
calls_offline = calls_origin_get_calls (CALLS_ORIGIN (fixture->origin_offline));
g_assert_null (calls_offline);
}
static gboolean
on_call_hangup_cb (gpointer user_data)
{
CallsCall *call = CALLS_CALL (user_data);
g_debug ("Hanging up call");
calls_call_hang_up (call);
return G_SOURCE_REMOVE;
}
static gboolean
on_call_answer_cb (gpointer user_data)
{
CallsCall *call = CALLS_CALL (user_data);
g_debug ("Answering incoming call");
calls_call_answer (call);
return G_SOURCE_REMOVE;
}
static void
on_autoreject_state_changed (CallsCall *call,
GParamSpec *pspec,
gpointer user_data)
{
CallsCallState state = calls_call_get_state (call);
g_assert_cmpint (state, ==, CALLS_CALL_STATE_DISCONNECTED);
g_object_unref (call);
is_call_test_done = TRUE;
}
static void
on_state_changed_cb (CallsCall *call,
CallsCallState new_state,
CallsCallState old_state,
gpointer user_data)
{
gboolean schedule_hangup = GPOINTER_TO_INT (user_data);
switch (old_state) {
case CALLS_CALL_STATE_INCOMING:
case CALLS_CALL_STATE_DIALING:
g_assert_cmpint (new_state, ==, CALLS_CALL_STATE_ACTIVE);
if (schedule_hangup)
g_idle_add ((GSourceFunc) on_call_hangup_cb, call);
break;
case CALLS_CALL_STATE_ACTIVE:
g_assert_cmpint (new_state, ==, CALLS_CALL_STATE_DISCONNECTED);
g_object_unref (call);
if (is_call_test_done)
are_call_tests_done = TRUE;
is_call_test_done = TRUE;
break;
default:
g_assert_not_reached ();
}
}
static gboolean
on_incoming_call_autoaccept_cb (CallsOrigin *origin,
CallsCall *call,
gpointer user_data)
{
CallsCallState state = calls_call_get_state (call);
g_assert_cmpint (state, ==, CALLS_CALL_STATE_INCOMING);
g_object_ref (call);
g_idle_add ((GSourceFunc) on_call_answer_cb, call);
g_signal_connect (call, "state-changed",
(GCallback) on_state_changed_cb, user_data);
return G_SOURCE_REMOVE;
}
static gboolean
on_incoming_call_autoreject_cb (CallsOrigin *origin,
CallsCall *call,
gpointer user_data)
{
CallsCallState state = calls_call_get_state (call);
g_assert_cmpint (state, ==, CALLS_CALL_STATE_INCOMING);
g_object_ref (call);
g_idle_add ((GSourceFunc) on_call_hangup_cb, call);
g_signal_connect (call, "notify::state",
G_CALLBACK (on_autoreject_state_changed),
NULL);
return G_SOURCE_REMOVE;
}
static gboolean
on_outgoing_call_cb (CallsOrigin *origin,
CallsCall *call,
gpointer user_data)
{
CallsCallState state = calls_call_get_state (call);
g_assert_cmpint (state, ==, CALLS_CALL_STATE_DIALING);
g_object_ref (call);
g_signal_connect (call, "state-changed",
(GCallback) on_state_changed_cb, user_data);
return G_SOURCE_REMOVE;
}
static void
test_sip_call_direct_calls (SipFixture *fixture,
gconstpointer user_data)
{
gint local_port_alice, local_port_bob;
g_autofree gchar *address_alice = NULL;
g_autofree gchar *address_bob = NULL;
gulong handler_alice, handler_bob;
g_object_get (fixture->origin_alice,
"local-port", &local_port_alice,
NULL);
address_alice = g_strdup_printf ("sip:alice@127.0.0.1:%d",
local_port_alice);
g_object_get (fixture->origin_bob,
"local-port", &local_port_bob,
NULL);
address_bob = g_strdup_printf ("sip:bob@127.0.0.1:%d",
local_port_bob);
/* Case 1: Bob calls Alice, Alice rejects call */
g_debug ("Call test: Stage 1");
handler_alice =
g_signal_connect (fixture->origin_alice,
"call-added",
G_CALLBACK (on_incoming_call_autoreject_cb),
NULL);
calls_origin_dial (CALLS_ORIGIN (fixture->origin_bob), address_alice);
while (!is_call_test_done)
g_main_context_iteration (NULL, TRUE);
is_call_test_done = FALSE;
are_call_tests_done = FALSE;
g_signal_handler_disconnect (fixture->origin_alice, handler_alice);
/* Case 2: Alice calls Bob, Bob accepts and hangs up shortly after */
g_debug ("Call test: Stage 2");
handler_alice =
g_signal_connect (fixture->origin_alice,
"call-added",
G_CALLBACK (on_outgoing_call_cb),
GINT_TO_POINTER (FALSE));
handler_bob =
g_signal_connect (fixture->origin_bob,
"call-added",
G_CALLBACK (on_incoming_call_autoaccept_cb),
GINT_TO_POINTER (TRUE));
calls_origin_dial (CALLS_ORIGIN (fixture->origin_alice), address_bob);
while (!are_call_tests_done)
g_main_context_iteration (NULL, TRUE);
is_call_test_done = FALSE;
are_call_tests_done = FALSE;
g_signal_handler_disconnect (fixture->origin_alice, handler_alice);
g_signal_handler_disconnect (fixture->origin_bob, handler_bob);
/* Case 3: Alice calls Bob, Bob accepts and Alice hangs up shortly after */
g_debug ("Call test: Stage 3");
handler_alice =
g_signal_connect (fixture->origin_alice,
"call-added",
G_CALLBACK (on_outgoing_call_cb),
GINT_TO_POINTER (TRUE));
handler_bob =
g_signal_connect (fixture->origin_bob,
"call-added",
G_CALLBACK (on_incoming_call_autoaccept_cb),
GINT_TO_POINTER (FALSE));
calls_origin_dial (CALLS_ORIGIN (fixture->origin_alice), address_bob);
while (!are_call_tests_done)
g_main_context_iteration (NULL, TRUE);
is_call_test_done = FALSE;
are_call_tests_done = FALSE;
g_signal_handler_disconnect (fixture->origin_alice, handler_alice);
g_signal_handler_disconnect (fixture->origin_bob, handler_bob);
}
static void
setup_sip_origins (SipFixture *fixture,
gconstpointer user_data)
{
setup_sip_provider (fixture, user_data);
fixture->origin_alice =
calls_sip_provider_add_origin_full (fixture->provider,
"sip1",
NULL,
"alice",
NULL,
NULL,
NULL,
0,
SIP_MEDIA_ENCRYPTION_NONE,
FALSE,
TRUE,
5060,
FALSE,
FALSE);
fixture->origin_bob =
calls_sip_provider_add_origin_full (fixture->provider,
"sip2",
NULL,
"bob",
NULL,
NULL,
NULL,
0,
SIP_MEDIA_ENCRYPTION_NONE,
FALSE,
TRUE,
5061,
FALSE,
FALSE);
fixture->origin_offline =
calls_sip_provider_add_origin_full (fixture->provider,
"sip3",
"sip.imaginary-host.org",
"username",
"password",
NULL,
"UDP",
0,
SIP_MEDIA_ENCRYPTION_NONE,
FALSE,
FALSE,
0,
FALSE,
FALSE);
}
static void
tear_down_sip_origins (SipFixture *fixture,
gconstpointer user_data)
{
tear_down_sip_provider (fixture, user_data);
}
int
main (int argc,
char *argv[])
{
int ret;
gtk_test_init (&argc, &argv, NULL);
gst_init (NULL, NULL);
#ifdef PLUGIN_BUILDDIR
peas_engine_add_search_path (peas_engine_get_default (), PLUGIN_BUILDDIR, NULL);
#endif
/* this is a workaround for an issue with sofia: https://github.com/freeswitch/sofia-sip/issues/58 */
su_random64 ();
g_test_add ("/Calls/SIP/provider_object", SipFixture, NULL,
setup_sip_provider, test_sip_provider_object, tear_down_sip_provider);
g_test_add ("/Calls/SIP/provider_origins", SipFixture, NULL,
setup_sip_provider, test_sip_provider_origins, tear_down_sip_provider);
g_test_add ("/Calls/SIP/origin_objects", SipFixture, NULL,
setup_sip_origins, test_sip_origin_objects, tear_down_sip_origins);
g_test_add ("/Calls/SIP/origin_call_lists", SipFixture, NULL,
setup_sip_origins, test_sip_origin_call_lists, tear_down_sip_origins);
g_test_add ("/Calls/SIP/calls_direct_call", SipFixture, NULL,
setup_sip_origins, test_sip_call_direct_calls, tear_down_sip_origins);
ret = g_test_run();
gst_deinit ();
return ret;
}

View File

@@ -0,0 +1,483 @@
/*
* Copyright (C) 2022 Purism SPC
*
* SPDX-License-Identifier: GPL-3.0+
*
* Author: Evangelos Ribeiro Tzaras <evangelos.tzaras@puri.sm>
*/
#include "calls-srtp-utils.h"
#include <gtk/gtk.h>
static void
assert_attr_eq (calls_srtp_crypto_attribute *a,
calls_srtp_crypto_attribute *b)
{
g_assert_cmpint (a->tag, ==, b->tag);
g_assert_cmpint (a->crypto_suite, ==, b->crypto_suite);
g_assert_cmpuint (a->n_key_params, ==, b->n_key_params);
for (guint i = 0; i < a->n_key_params; i++) {
g_assert_cmpstr (a->key_params[i].b64_keysalt, ==,
b->key_params[i].b64_keysalt);
g_assert_cmpuint (a->key_params[i].mki, ==,
b->key_params[i].mki);
g_assert_cmpuint (a->key_params[i].mki_length, ==,
b->key_params[i].mki_length);
}
g_assert_cmpint (a->unencrypted_srtp, ==, b->unencrypted_srtp);
g_assert_cmpint (a->unauthenticated_srtp, ==, b->unauthenticated_srtp);
g_assert_cmpint (a->unencrypted_srtcp, ==, b->unencrypted_srtcp);
g_assert_cmpint (a->kdr, ==, b->kdr);
g_assert_cmpint (a->fec_order, ==, b->fec_order);
g_assert_cmpint (a->window_size_hint, ==, b->window_size_hint);
}
static void
test_crypto_attribute_validity (void)
{
g_autoptr (calls_srtp_crypto_attribute) attr = NULL;
char *attr_str;
guchar *key_salt;
char *tmp_str;
/* single key parameter */
attr = calls_srtp_crypto_attribute_new (1);
attr->tag = 1;
attr->crypto_suite = CALLS_SRTP_SUITE_UNKNOWN;
g_assert_null (calls_srtp_print_sdp_crypto_attribute (attr, NULL));
attr->crypto_suite = CALLS_SRTP_SUITE_AES_128_SHA1_32;
key_salt = calls_srtp_generate_key_salt (30);
attr->key_params[0].b64_keysalt = g_base64_encode (key_salt, 30);
g_free (key_salt);
attr_str = calls_srtp_print_sdp_crypto_attribute (attr, NULL);
g_assert_true (attr_str);
g_free (attr_str);
/* tag out of bounds */
attr->tag = 0;
g_assert_null (calls_srtp_print_sdp_crypto_attribute (attr, NULL));
attr->tag = 1000000000;
g_assert_null (calls_srtp_print_sdp_crypto_attribute (attr, NULL));
attr->tag = 1;
/* lifetime out of bounds */
attr->key_params[0].lifetime = 49;
attr->key_params[0].lifetime_type = CALLS_SRTP_LIFETIME_AS_POWER_OF_TWO;
g_assert_null (calls_srtp_print_sdp_crypto_attribute (attr, NULL));
attr->key_params[0].lifetime = 1ULL << 48;
attr->key_params[0].lifetime_type = CALLS_SRTP_LIFETIME_AS_DECIMAL_NUMBER;
g_assert_null (calls_srtp_print_sdp_crypto_attribute (attr, NULL));
attr->key_params[0].lifetime = 0;
attr->key_params[0].lifetime_type = CALLS_SRTP_LIFETIME_UNSET;
/* MKI without length */
attr->key_params[0].mki = 1;
attr->key_params[0].mki_length = 0;
g_assert_null (calls_srtp_print_sdp_crypto_attribute (attr, NULL));
attr->key_params[0].mki_length = 129;
g_assert_null (calls_srtp_print_sdp_crypto_attribute (attr, NULL));
attr->key_params[0].mki = 0;
attr->key_params[0].mki_length = 4;
g_assert_null (calls_srtp_print_sdp_crypto_attribute (attr, NULL));
/* missing key */
attr->key_params[0].mki_length = 0;
g_clear_pointer (&attr->key_params[0].b64_keysalt, g_free);
g_assert_null (calls_srtp_print_sdp_crypto_attribute (attr, NULL));
/* wrong key length */
key_salt = calls_srtp_generate_key_salt (29);
attr->key_params[0].b64_keysalt = g_base64_encode (key_salt, 29);
g_free (key_salt);
g_assert_null (calls_srtp_print_sdp_crypto_attribute (attr, NULL));
calls_srtp_crypto_attribute_free (attr);
/* multiple key parameters */
attr = calls_srtp_crypto_attribute_new (4);
attr->tag = 12;
attr->crypto_suite = CALLS_SRTP_SUITE_AES_128_SHA1_80;
calls_srtp_crypto_attribute_init_keys (attr);
attr->key_params[0].lifetime = 31;
attr->key_params[0].lifetime_type = CALLS_SRTP_LIFETIME_AS_POWER_OF_TWO;
attr_str = calls_srtp_print_sdp_crypto_attribute (attr, NULL);
g_assert_true (attr_str);
g_free (attr_str);
calls_srtp_crypto_attribute_free (attr);
/* same key */
attr = calls_srtp_crypto_attribute_new (2);
attr->tag = 1;
tmp_str = attr->key_params[1].b64_keysalt;
attr->key_params[1].b64_keysalt = attr->key_params[0].b64_keysalt;
g_assert_null (calls_srtp_print_sdp_crypto_attribute (attr, NULL));
attr->key_params[1].b64_keysalt = tmp_str;
/* same MKI */
attr->key_params[0].mki = 1;
attr->key_params[1].mki = 1;
g_assert_null (calls_srtp_print_sdp_crypto_attribute (attr, NULL));
/* different MKI lengths */
attr->key_params[1].mki = 2;
attr->key_params[0].mki_length = 1;
attr->key_params[1].mki_length = 3;
g_assert_null (calls_srtp_print_sdp_crypto_attribute (attr, NULL));
g_assert_null (calls_srtp_print_sdp_crypto_attribute (NULL, NULL));
}
static void
test_parse (void)
{
g_autoptr (calls_srtp_crypto_attribute) attr_simple = NULL;
g_autoptr (calls_srtp_crypto_attribute) attr_parsed_simple = NULL;
g_autofree char *attr_simple_str = NULL;
g_autofree char *attr_simple_str_expected = NULL;
g_autoptr (calls_srtp_crypto_attribute) attr_multi = NULL;
g_autoptr (calls_srtp_crypto_attribute) attr_parsed_multi = NULL;
g_autofree char *attr_multi_str = NULL;
g_autofree char *attr_multi_str_expected = NULL;
g_autofree guchar *key_salt = NULL;
/* single key */
attr_simple = calls_srtp_crypto_attribute_new (1);
key_salt = calls_srtp_generate_key_salt (30);
attr_simple->tag = 1;
attr_simple->crypto_suite = CALLS_SRTP_SUITE_AES_128_SHA1_32;
attr_simple->key_params[0].b64_keysalt = g_base64_encode (key_salt, 30);
attr_simple_str = calls_srtp_print_sdp_crypto_attribute (attr_simple, NULL);
attr_simple_str_expected =
g_strdup_printf ("a=crypto:%d AES_CM_128_HMAC_SHA1_32 inline:%s",
attr_simple->tag,
attr_simple->key_params[0].b64_keysalt);
g_assert_cmpstr (attr_simple_str, ==, attr_simple_str_expected);
attr_parsed_simple = calls_srtp_parse_sdp_crypto_attribute (attr_simple_str, NULL);
assert_attr_eq (attr_simple, attr_parsed_simple);
/* multiple keys */
attr_multi = calls_srtp_crypto_attribute_new (2);
attr_multi->tag = 42;
attr_multi->crypto_suite = CALLS_SRTP_SUITE_AES_128_SHA1_80;
calls_srtp_crypto_attribute_init_keys (attr_multi);
attr_multi_str = calls_srtp_print_sdp_crypto_attribute (attr_multi, NULL);
attr_multi_str_expected =
g_strdup_printf ("a=crypto:%d AES_CM_128_HMAC_SHA1_80 "
"inline:%s|%" G_GUINT64_FORMAT ":%u;"
"inline:%s|%" G_GUINT64_FORMAT ":%u",
attr_multi->tag,
attr_multi->key_params[0].b64_keysalt,
attr_multi->key_params[0].mki,
attr_multi->key_params[0].mki_length,
attr_multi->key_params[1].b64_keysalt,
attr_multi->key_params[1].mki,
attr_multi->key_params[1].mki_length);
g_assert_cmpstr (attr_multi_str, ==, attr_multi_str_expected);
attr_parsed_multi = calls_srtp_parse_sdp_crypto_attribute (attr_multi_str, NULL);
assert_attr_eq (attr_multi, attr_parsed_multi);
}
static void
test_srtp_params (void)
{
calls_srtp_crypto_attribute *attr = calls_srtp_crypto_attribute_new (1);
const char *srtp_cipher;
const char *srtp_auth;
const char *srtcp_cipher;
const char *srtcp_auth;
GstSrtpCipherType srtp_cipher_enum;
GstSrtpAuthType srtp_auth_enum;
GstSrtpCipherType srtcp_cipher_enum;
GstSrtpAuthType srtcp_auth_enum;
attr->crypto_suite = CALLS_SRTP_SUITE_AES_128_SHA1_32;
attr->unencrypted_srtp = FALSE;
attr->unauthenticated_srtp = FALSE;
attr->unencrypted_srtcp = FALSE;
g_assert_true (calls_srtp_crypto_get_srtpdec_params (attr,
&srtp_cipher,
&srtp_auth,
&srtcp_cipher,
&srtcp_auth));
g_assert_cmpstr (srtp_cipher, ==, "aes-128-icm");
g_assert_cmpstr (srtp_auth, ==, "hmac-sha1-32");
g_assert_cmpstr (srtcp_cipher, ==, "aes-128-icm");
g_assert_cmpstr (srtcp_auth, ==, "hmac-sha1-32");
g_assert_true (calls_srtp_crypto_get_srtpenc_params (attr,
&srtp_cipher_enum,
&srtp_auth_enum,
&srtcp_cipher_enum,
&srtcp_auth_enum));
g_assert_cmpint (srtp_cipher_enum, ==, GST_SRTP_CIPHER_AES_128_ICM);
g_assert_cmpint (srtp_auth_enum, ==, GST_SRTP_AUTH_HMAC_SHA1_32);
g_assert_cmpint (srtcp_cipher_enum, ==, GST_SRTP_CIPHER_AES_128_ICM);
g_assert_cmpint (srtcp_auth_enum, ==, GST_SRTP_AUTH_HMAC_SHA1_32);
attr->crypto_suite = CALLS_SRTP_SUITE_AES_128_SHA1_32;
attr->unencrypted_srtp = TRUE;
attr->unauthenticated_srtp = FALSE;
attr->unencrypted_srtcp = FALSE;
g_assert_true (calls_srtp_crypto_get_srtpdec_params (attr,
&srtp_cipher,
&srtp_auth,
&srtcp_cipher,
&srtcp_auth));
g_assert_cmpstr (srtp_cipher, ==, "null");
g_assert_cmpstr (srtp_auth, ==, "hmac-sha1-32");
g_assert_cmpstr (srtcp_cipher, ==, "aes-128-icm");
g_assert_cmpstr (srtcp_auth, ==, "hmac-sha1-32");
g_assert_true (calls_srtp_crypto_get_srtpenc_params (attr,
&srtp_cipher_enum,
&srtp_auth_enum,
&srtcp_cipher_enum,
&srtcp_auth_enum));
g_assert_cmpint (srtp_cipher_enum, ==, GST_SRTP_CIPHER_NULL);
g_assert_cmpint (srtp_auth_enum, ==, GST_SRTP_AUTH_HMAC_SHA1_32);
g_assert_cmpint (srtcp_cipher_enum, ==, GST_SRTP_CIPHER_AES_128_ICM);
g_assert_cmpint (srtcp_auth_enum, ==, GST_SRTP_AUTH_HMAC_SHA1_32);
attr->crypto_suite = CALLS_SRTP_SUITE_AES_128_SHA1_32;
attr->unencrypted_srtp = FALSE;
attr->unauthenticated_srtp = TRUE;
attr->unencrypted_srtcp = FALSE;
g_assert_true (calls_srtp_crypto_get_srtpdec_params (attr,
&srtp_cipher,
&srtp_auth,
&srtcp_cipher,
&srtcp_auth));
g_assert_cmpstr (srtp_cipher, ==, "aes-128-icm");
g_assert_cmpstr (srtp_auth, ==, "null");
g_assert_cmpstr (srtcp_cipher, ==, "aes-128-icm");
g_assert_cmpstr (srtcp_auth, ==, "hmac-sha1-32");
g_assert_true (calls_srtp_crypto_get_srtpenc_params (attr,
&srtp_cipher_enum,
&srtp_auth_enum,
&srtcp_cipher_enum,
&srtcp_auth_enum));
g_assert_cmpint (srtp_cipher_enum, ==, GST_SRTP_CIPHER_AES_128_ICM);
g_assert_cmpint (srtp_auth_enum, ==, GST_SRTP_AUTH_NULL);
g_assert_cmpint (srtcp_cipher_enum, ==, GST_SRTP_CIPHER_AES_128_ICM);
g_assert_cmpint (srtcp_auth_enum, ==, GST_SRTP_AUTH_HMAC_SHA1_32);
attr->crypto_suite = CALLS_SRTP_SUITE_AES_128_SHA1_32;
attr->unencrypted_srtp = FALSE;
attr->unauthenticated_srtp = FALSE;
attr->unencrypted_srtcp = TRUE;
g_assert_true (calls_srtp_crypto_get_srtpdec_params (attr,
&srtp_cipher,
&srtp_auth,
&srtcp_cipher,
&srtcp_auth));
g_assert_cmpstr (srtp_cipher, ==, "aes-128-icm");
g_assert_cmpstr (srtp_auth, ==, "hmac-sha1-32");
g_assert_cmpstr (srtcp_cipher, ==, "null");
g_assert_cmpstr (srtcp_auth, ==, "null");
g_assert_true (calls_srtp_crypto_get_srtpenc_params (attr,
&srtp_cipher_enum,
&srtp_auth_enum,
&srtcp_cipher_enum,
&srtcp_auth_enum));
g_assert_cmpint (srtp_cipher_enum, ==, GST_SRTP_CIPHER_AES_128_ICM);
g_assert_cmpint (srtp_auth_enum, ==, GST_SRTP_AUTH_HMAC_SHA1_32);
g_assert_cmpint (srtcp_cipher_enum, ==, GST_SRTP_CIPHER_NULL);
g_assert_cmpint (srtcp_auth_enum, ==, GST_SRTP_AUTH_NULL);
attr->crypto_suite = CALLS_SRTP_SUITE_AES_128_SHA1_80;
attr->unencrypted_srtp = FALSE;
attr->unauthenticated_srtp = FALSE;
attr->unencrypted_srtcp = FALSE;
g_assert_true (calls_srtp_crypto_get_srtpdec_params (attr,
&srtp_cipher,
&srtp_auth,
&srtcp_cipher,
&srtcp_auth));
g_assert_cmpstr (srtp_cipher, ==, "aes-128-icm");
g_assert_cmpstr (srtp_auth, ==, "hmac-sha1-80");
g_assert_cmpstr (srtcp_cipher, ==, "aes-128-icm");
g_assert_cmpstr (srtcp_auth, ==, "hmac-sha1-80");
g_assert_true (calls_srtp_crypto_get_srtpenc_params (attr,
&srtp_cipher_enum,
&srtp_auth_enum,
&srtcp_cipher_enum,
&srtcp_auth_enum));
g_assert_cmpint (srtp_cipher_enum, ==, GST_SRTP_CIPHER_AES_128_ICM);
g_assert_cmpint (srtp_auth_enum, ==, GST_SRTP_AUTH_HMAC_SHA1_80);
g_assert_cmpint (srtcp_cipher_enum, ==, GST_SRTP_CIPHER_AES_128_ICM);
g_assert_cmpint (srtcp_auth_enum, ==, GST_SRTP_AUTH_HMAC_SHA1_80);
attr->crypto_suite = CALLS_SRTP_SUITE_AES_128_SHA1_80;
attr->unencrypted_srtp = TRUE;
attr->unauthenticated_srtp = FALSE;
attr->unencrypted_srtcp = FALSE;
g_assert_true (calls_srtp_crypto_get_srtpdec_params (attr,
&srtp_cipher,
&srtp_auth,
&srtcp_cipher,
&srtcp_auth));
g_assert_cmpstr (srtp_cipher, ==, "null");
g_assert_cmpstr (srtp_auth, ==, "hmac-sha1-80");
g_assert_cmpstr (srtcp_cipher, ==, "aes-128-icm");
g_assert_cmpstr (srtcp_auth, ==, "hmac-sha1-80");
g_assert_true (calls_srtp_crypto_get_srtpenc_params (attr,
&srtp_cipher_enum,
&srtp_auth_enum,
&srtcp_cipher_enum,
&srtcp_auth_enum));
g_assert_cmpint (srtp_cipher_enum, ==, GST_SRTP_CIPHER_NULL);
g_assert_cmpint (srtp_auth_enum, ==, GST_SRTP_AUTH_HMAC_SHA1_80);
g_assert_cmpint (srtcp_cipher_enum, ==, GST_SRTP_CIPHER_AES_128_ICM);
g_assert_cmpint (srtcp_auth_enum, ==, GST_SRTP_AUTH_HMAC_SHA1_80);
attr->crypto_suite = CALLS_SRTP_SUITE_AES_128_SHA1_80;
attr->unencrypted_srtp = FALSE;
attr->unauthenticated_srtp = TRUE;
attr->unencrypted_srtcp = FALSE;
g_assert_true (calls_srtp_crypto_get_srtpdec_params (attr,
&srtp_cipher,
&srtp_auth,
&srtcp_cipher,
&srtcp_auth));
g_assert_cmpstr (srtp_cipher, ==, "aes-128-icm");
g_assert_cmpstr (srtp_auth, ==, "null");
g_assert_cmpstr (srtcp_cipher, ==, "aes-128-icm");
g_assert_cmpstr (srtcp_auth, ==, "hmac-sha1-80");
g_assert_true (calls_srtp_crypto_get_srtpenc_params (attr,
&srtp_cipher_enum,
&srtp_auth_enum,
&srtcp_cipher_enum,
&srtcp_auth_enum));
g_assert_cmpint (srtp_cipher_enum, ==, GST_SRTP_CIPHER_AES_128_ICM);
g_assert_cmpint (srtp_auth_enum, ==, GST_SRTP_AUTH_NULL);
g_assert_cmpint (srtcp_cipher_enum, ==, GST_SRTP_CIPHER_AES_128_ICM);
g_assert_cmpint (srtcp_auth_enum, ==, GST_SRTP_AUTH_HMAC_SHA1_80);
attr->crypto_suite = CALLS_SRTP_SUITE_AES_128_SHA1_80;
attr->unencrypted_srtp = FALSE;
attr->unauthenticated_srtp = FALSE;
attr->unencrypted_srtcp = TRUE;
g_assert_true (calls_srtp_crypto_get_srtpdec_params (attr,
&srtp_cipher,
&srtp_auth,
&srtcp_cipher,
&srtcp_auth));
g_assert_cmpstr (srtp_cipher, ==, "aes-128-icm");
g_assert_cmpstr (srtp_auth, ==, "hmac-sha1-80");
g_assert_cmpstr (srtcp_cipher, ==, "null");
g_assert_cmpstr (srtcp_auth, ==, "null");
g_assert_true (calls_srtp_crypto_get_srtpenc_params (attr,
&srtp_cipher_enum,
&srtp_auth_enum,
&srtcp_cipher_enum,
&srtcp_auth_enum));
g_assert_cmpint (srtp_cipher_enum, ==, GST_SRTP_CIPHER_AES_128_ICM);
g_assert_cmpint (srtp_auth_enum, ==, GST_SRTP_AUTH_HMAC_SHA1_80);
g_assert_cmpint (srtcp_cipher_enum, ==, GST_SRTP_CIPHER_NULL);
g_assert_cmpint (srtcp_auth_enum, ==, GST_SRTP_AUTH_NULL);
attr->crypto_suite = CALLS_SRTP_SUITE_UNKNOWN;
g_assert_false (calls_srtp_crypto_get_srtpdec_params (attr,
&srtp_cipher,
&srtp_auth,
&srtcp_cipher,
&srtcp_auth));
g_assert_false (calls_srtp_crypto_get_srtpenc_params (attr,
&srtp_cipher_enum,
&srtp_auth_enum,
&srtcp_cipher_enum,
&srtcp_auth_enum));
calls_srtp_crypto_attribute_free (attr);
}
int
main (int argc,
char *argv[])
{
gtk_test_init (&argc, &argv, NULL);
g_test_add_func ("/Calls/SRTP-SDP/crypto_attribute_validity", test_crypto_attribute_validity);
g_test_add_func ("/Calls/SRTP-SDP/parse", test_parse);
g_test_add_func ("/Calls/SRTP/srtp_params", test_srtp_params);
return g_test_run ();
}