2017-02-07 12:56:41 +00:00
/*
* Asterisk - - An open source telephony toolkit .
*
* Copyright ( C ) 2017 , Digium , Inc .
*
* Joshua Colp < jcolp @ digium . com >
*
* See http : //www.asterisk.org for more information about
* the Asterisk project . Please do not directly contact
* any of the maintainers of this project for assistance ;
* the project provides a web site , mailing lists and IRC
* channels for your use .
*
* This program is free software , distributed under the terms of
* the GNU General Public License Version 2. See the LICENSE file
* at the top of the source tree .
*/
/*!
* \ file
* \ brief Media Stream API Unit Tests
*
* \ author Joshua Colp < jcolp @ digium . com >
*
*/
/*** MODULEINFO
< depend > TEST_FRAMEWORK < / depend >
< support_level > core < / support_level >
* * */
# include "asterisk.h"
# include "asterisk/test.h"
# include "asterisk/module.h"
# include "asterisk/stream.h"
# include "asterisk/format.h"
# include "asterisk/format_cap.h"
2017-02-13 17:00:42 +00:00
# include "asterisk/format_cache.h"
2017-02-14 18:33:57 +00:00
# include "asterisk/channel.h"
2017-02-07 12:56:41 +00:00
AST_TEST_DEFINE ( stream_create )
{
2017-02-16 14:28:33 +00:00
RAII_VAR ( struct ast_stream * , stream , NULL , ast_stream_free ) ;
2017-02-07 12:56:41 +00:00
switch ( cmd ) {
case TEST_INIT :
info - > name = " stream_create " ;
info - > category = " /main/stream/ " ;
info - > summary = " stream create unit test " ;
info - > description =
" Test that creating a stream results in a stream with the expected values " ;
return AST_TEST_NOT_RUN ;
case TEST_EXECUTE :
break ;
}
2017-02-16 14:28:33 +00:00
stream = ast_stream_alloc ( " test " , AST_MEDIA_TYPE_AUDIO ) ;
2017-02-07 12:56:41 +00:00
if ( ! stream ) {
ast_test_status_update ( test , " Failed to create media stream given proper arguments \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_get_state ( stream ) ! = AST_STREAM_STATE_INACTIVE ) {
ast_test_status_update ( test , " Newly created stream does not have expected inactive stream state \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_get_type ( stream ) ! = AST_MEDIA_TYPE_AUDIO ) {
ast_test_status_update ( test , " Newly created stream does not have expected audio media type \n " ) ;
return AST_TEST_FAIL ;
}
if ( strcmp ( ast_stream_get_name ( stream ) , " test " ) ) {
ast_test_status_update ( test , " Newly created stream does not have expected name of test \n " ) ;
return AST_TEST_FAIL ;
}
return AST_TEST_PASS ;
}
AST_TEST_DEFINE ( stream_create_no_name )
{
2017-02-16 14:28:33 +00:00
RAII_VAR ( struct ast_stream * , stream , NULL , ast_stream_free ) ;
2017-02-07 12:56:41 +00:00
switch ( cmd ) {
case TEST_INIT :
info - > name = " stream_create_no_name " ;
info - > category = " /main/stream/ " ;
info - > summary = " stream create (without a name) unit test " ;
info - > description =
" Test that creating a stream with no name works " ;
return AST_TEST_NOT_RUN ;
case TEST_EXECUTE :
break ;
}
2017-02-16 14:28:33 +00:00
stream = ast_stream_alloc ( NULL , AST_MEDIA_TYPE_AUDIO ) ;
2017-02-07 12:56:41 +00:00
if ( ! stream ) {
ast_test_status_update ( test , " Failed to create media stream given proper arguments \n " ) ;
return AST_TEST_FAIL ;
}
return AST_TEST_PASS ;
}
AST_TEST_DEFINE ( stream_set_type )
{
2017-02-16 14:28:33 +00:00
RAII_VAR ( struct ast_stream * , stream , NULL , ast_stream_free ) ;
2017-02-07 12:56:41 +00:00
switch ( cmd ) {
case TEST_INIT :
info - > name = " stream_set_type " ;
info - > category = " /main/stream/ " ;
info - > summary = " stream type setting unit test " ;
info - > description =
" Test that changing the type of a stream works " ;
return AST_TEST_NOT_RUN ;
case TEST_EXECUTE :
break ;
}
2017-02-16 14:28:33 +00:00
stream = ast_stream_alloc ( " test " , AST_MEDIA_TYPE_AUDIO ) ;
2017-02-07 12:56:41 +00:00
if ( ! stream ) {
ast_test_status_update ( test , " Failed to create media stream given proper arguments \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_get_type ( stream ) ! = AST_MEDIA_TYPE_AUDIO ) {
ast_test_status_update ( test , " Newly created stream does not have expected audio media type \n " ) ;
return AST_TEST_FAIL ;
}
ast_stream_set_type ( stream , AST_MEDIA_TYPE_VIDEO ) ;
if ( ast_stream_get_type ( stream ) ! = AST_MEDIA_TYPE_VIDEO ) {
ast_test_status_update ( test , " Changed stream does not have expected video media type \n " ) ;
return AST_TEST_FAIL ;
}
return AST_TEST_PASS ;
}
AST_TEST_DEFINE ( stream_set_formats )
{
2017-02-16 14:28:33 +00:00
RAII_VAR ( struct ast_stream * , stream , NULL , ast_stream_free ) ;
2017-02-07 12:56:41 +00:00
RAII_VAR ( struct ast_format_cap * , caps , NULL , ao2_cleanup ) ;
switch ( cmd ) {
case TEST_INIT :
info - > name = " stream_set_formats " ;
info - > category = " /main/stream/ " ;
info - > summary = " stream formats setting unit test " ;
info - > description =
" Test that changing the formats of a stream works " ;
return AST_TEST_NOT_RUN ;
case TEST_EXECUTE :
break ;
}
caps = ast_format_cap_alloc ( AST_FORMAT_CAP_FLAG_DEFAULT ) ;
if ( ! caps ) {
ast_test_status_update ( test , " Failed to create a format capabilities structure for testing \n " ) ;
return AST_TEST_FAIL ;
}
2017-02-16 14:28:33 +00:00
stream = ast_stream_alloc ( " test " , AST_MEDIA_TYPE_AUDIO ) ;
2017-02-07 12:56:41 +00:00
if ( ! stream ) {
ast_test_status_update ( test , " Failed to create media stream given proper arguments \n " ) ;
return AST_TEST_FAIL ;
}
ast_stream_set_formats ( stream , caps ) ;
if ( ast_stream_get_formats ( stream ) ! = caps ) {
ast_test_status_update ( test , " Changed stream does not have expected formats \n " ) ;
return AST_TEST_FAIL ;
}
ast_stream_set_formats ( stream , NULL ) ;
if ( ast_stream_get_formats ( stream ) ) {
ast_test_status_update ( test , " Retrieved formats from stream despite removing them \n " ) ;
return AST_TEST_FAIL ;
}
return AST_TEST_PASS ;
}
AST_TEST_DEFINE ( stream_set_state )
{
2017-02-16 14:28:33 +00:00
RAII_VAR ( struct ast_stream * , stream , NULL , ast_stream_free ) ;
2017-02-07 12:56:41 +00:00
switch ( cmd ) {
case TEST_INIT :
info - > name = " stream_set_state " ;
info - > category = " /main/stream/ " ;
info - > summary = " stream state setting unit test " ;
info - > description =
" Test that changing the state of a stream works " ;
return AST_TEST_NOT_RUN ;
case TEST_EXECUTE :
break ;
}
2017-02-16 14:28:33 +00:00
stream = ast_stream_alloc ( " test " , AST_MEDIA_TYPE_AUDIO ) ;
2017-02-07 12:56:41 +00:00
if ( ! stream ) {
ast_test_status_update ( test , " Failed to create media stream given proper arguments \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_get_state ( stream ) ! = AST_STREAM_STATE_INACTIVE ) {
ast_test_status_update ( test , " Newly created stream does not have expected inactive stream state \n " ) ;
return AST_TEST_FAIL ;
}
ast_stream_set_state ( stream , AST_STREAM_STATE_SENDRECV ) ;
if ( ast_stream_get_state ( stream ) ! = AST_STREAM_STATE_SENDRECV ) {
ast_test_status_update ( test , " Changed stream does not have expected sendrecv state \n " ) ;
return AST_TEST_FAIL ;
}
return AST_TEST_PASS ;
}
2017-02-13 17:00:42 +00:00
AST_TEST_DEFINE ( stream_topology_create )
{
2017-02-16 14:28:33 +00:00
RAII_VAR ( struct ast_stream_topology * , topology , NULL , ast_stream_topology_free ) ;
2017-02-13 17:00:42 +00:00
switch ( cmd ) {
case TEST_INIT :
info - > name = " stream_topology_create " ;
info - > category = " /main/stream/ " ;
info - > summary = " stream topology creation unit test " ;
info - > description =
" Test that creating a stream topology works " ;
return AST_TEST_NOT_RUN ;
case TEST_EXECUTE :
break ;
}
2017-02-16 14:28:33 +00:00
topology = ast_stream_topology_alloc ( ) ;
2017-02-13 17:00:42 +00:00
if ( ! topology ) {
ast_test_status_update ( test , " Failed to create media stream topology \n " ) ;
return AST_TEST_FAIL ;
}
return AST_TEST_PASS ;
}
AST_TEST_DEFINE ( stream_topology_clone )
{
2017-02-16 14:28:33 +00:00
RAII_VAR ( struct ast_stream_topology * , topology , NULL , ast_stream_topology_free ) ;
RAII_VAR ( struct ast_stream_topology * , cloned , NULL , ast_stream_topology_free ) ;
2017-02-13 17:00:42 +00:00
struct ast_stream * audio_stream , * video_stream ;
switch ( cmd ) {
case TEST_INIT :
info - > name = " stream_topology_clone " ;
info - > category = " /main/stream/ " ;
info - > summary = " stream topology cloning unit test " ;
info - > description =
" Test that cloning a stream topology results in a clone with the same contents " ;
return AST_TEST_NOT_RUN ;
case TEST_EXECUTE :
break ;
}
2017-02-16 14:28:33 +00:00
topology = ast_stream_topology_alloc ( ) ;
2017-02-13 17:00:42 +00:00
if ( ! topology ) {
ast_test_status_update ( test , " Failed to create media stream topology \n " ) ;
return AST_TEST_FAIL ;
}
2017-02-16 14:28:33 +00:00
audio_stream = ast_stream_alloc ( " audio " , AST_MEDIA_TYPE_AUDIO ) ;
2017-02-13 17:00:42 +00:00
if ( ! audio_stream ) {
ast_test_status_update ( test , " Failed to create an audio stream for testing stream topology \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_topology_append_stream ( topology , audio_stream ) = = - 1 ) {
ast_test_status_update ( test , " Failed to append valid audio stream to stream topology \n " ) ;
2017-02-16 14:28:33 +00:00
ast_stream_free ( audio_stream ) ;
2017-02-13 17:00:42 +00:00
return AST_TEST_FAIL ;
}
2017-02-16 14:28:33 +00:00
video_stream = ast_stream_alloc ( " video " , AST_MEDIA_TYPE_VIDEO ) ;
2017-02-13 17:00:42 +00:00
if ( ! video_stream ) {
ast_test_status_update ( test , " Failed to create a video stream for testing stream topology \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_topology_append_stream ( topology , video_stream ) = = - 1 ) {
ast_test_status_update ( test , " Failed to append valid video stream to stream topology \n " ) ;
2017-02-16 14:28:33 +00:00
ast_stream_free ( video_stream ) ;
2017-02-13 17:00:42 +00:00
return AST_TEST_FAIL ;
}
cloned = ast_stream_topology_clone ( topology ) ;
if ( ! cloned ) {
ast_test_status_update ( test , " Failed to clone a perfectly good stream topology \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_topology_get_count ( cloned ) ! = ast_stream_topology_get_count ( topology ) ) {
ast_test_status_update ( test , " Cloned stream topology does not contain same number of streams as original \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_get_type ( ast_stream_topology_get_stream ( cloned , 0 ) ) ! = ast_stream_get_type ( ast_stream_topology_get_stream ( topology , 0 ) ) ) {
ast_test_status_update ( test , " Cloned audio stream does not contain same type as original \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_get_type ( ast_stream_topology_get_stream ( cloned , 1 ) ) ! = ast_stream_get_type ( ast_stream_topology_get_stream ( topology , 1 ) ) ) {
ast_test_status_update ( test , " Cloned video stream does not contain same type as original \n " ) ;
return AST_TEST_FAIL ;
}
return AST_TEST_PASS ;
}
AST_TEST_DEFINE ( stream_topology_append_stream )
{
2017-02-16 14:28:33 +00:00
RAII_VAR ( struct ast_stream_topology * , topology , NULL , ast_stream_topology_free ) ;
2017-02-13 17:00:42 +00:00
struct ast_stream * audio_stream , * video_stream ;
int position ;
switch ( cmd ) {
case TEST_INIT :
info - > name = " stream_topology_append_stream " ;
info - > category = " /main/stream/ " ;
info - > summary = " stream topology stream appending unit test " ;
info - > description =
" Test that appending streams to a stream topology works " ;
return AST_TEST_NOT_RUN ;
case TEST_EXECUTE :
break ;
}
2017-02-16 14:28:33 +00:00
topology = ast_stream_topology_alloc ( ) ;
2017-02-13 17:00:42 +00:00
if ( ! topology ) {
ast_test_status_update ( test , " Failed to create media stream topology \n " ) ;
return AST_TEST_FAIL ;
}
2017-02-16 14:28:33 +00:00
audio_stream = ast_stream_alloc ( " audio " , AST_MEDIA_TYPE_AUDIO ) ;
2017-02-13 17:00:42 +00:00
if ( ! audio_stream ) {
ast_test_status_update ( test , " Failed to create an audio stream for testing stream topology \n " ) ;
return AST_TEST_FAIL ;
}
position = ast_stream_topology_append_stream ( topology , audio_stream ) ;
if ( position = = - 1 ) {
ast_test_status_update ( test , " Failed to append valid audio stream to stream topology \n " ) ;
2017-02-16 14:28:33 +00:00
ast_stream_free ( audio_stream ) ;
2017-02-13 17:00:42 +00:00
return AST_TEST_FAIL ;
} else if ( position ! = 0 ) {
ast_test_status_update ( test , " Appended audio stream to stream topology but position is '%d' instead of 0 \n " ,
position ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_topology_get_count ( topology ) ! = 1 ) {
ast_test_status_update ( test , " Appended an audio stream to the stream topology but stream count is '%d' on it, not 1 \n " ,
ast_stream_topology_get_count ( topology ) ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_topology_get_stream ( topology , 0 ) ! = audio_stream ) {
ast_test_status_update ( test , " Appended an audio stream to the stream topology but returned stream doesn't match \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_get_position ( audio_stream ) ! = 0 ) {
ast_test_status_update ( test , " Appended audio stream says it is at position '%d' instead of 0 \n " ,
ast_stream_get_position ( audio_stream ) ) ;
return AST_TEST_FAIL ;
}
2017-02-16 14:28:33 +00:00
video_stream = ast_stream_alloc ( " video " , AST_MEDIA_TYPE_VIDEO ) ;
2017-02-13 17:00:42 +00:00
if ( ! video_stream ) {
ast_test_status_update ( test , " Failed to create a video stream for testing stream topology \n " ) ;
return AST_TEST_FAIL ;
}
position = ast_stream_topology_append_stream ( topology , video_stream ) ;
if ( position = = - 1 ) {
ast_test_status_update ( test , " Failed to append valid video stream to stream topology \n " ) ;
2017-02-16 14:28:33 +00:00
ast_stream_free ( video_stream ) ;
2017-02-13 17:00:42 +00:00
return AST_TEST_FAIL ;
} else if ( position ! = 1 ) {
ast_test_status_update ( test , " Appended video stream to stream topology but position is '%d' instead of 1 \n " ,
position ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_topology_get_count ( topology ) ! = 2 ) {
ast_test_status_update ( test , " Appended a video stream to the stream topology but stream count is '%d' on it, not 2 \n " ,
ast_stream_topology_get_count ( topology ) ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_topology_get_stream ( topology , 1 ) ! = video_stream ) {
ast_test_status_update ( test , " Appended a video stream to the stream topology but returned stream doesn't match \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_get_position ( video_stream ) ! = 1 ) {
ast_test_status_update ( test , " Appended video stream says it is at position '%d' instead of 1 \n " ,
ast_stream_get_position ( video_stream ) ) ;
return AST_TEST_FAIL ;
}
return AST_TEST_PASS ;
}
AST_TEST_DEFINE ( stream_topology_set_stream )
{
2017-02-16 14:28:33 +00:00
RAII_VAR ( struct ast_stream_topology * , topology , NULL , ast_stream_topology_free ) ;
2017-02-13 17:00:42 +00:00
struct ast_stream * audio_stream , * video_stream ;
switch ( cmd ) {
case TEST_INIT :
info - > name = " stream_topology_set_stream " ;
info - > category = " /main/stream/ " ;
info - > summary = " stream topology stream setting unit test " ;
info - > description =
" Test that setting streams at a specific position in a topology works " ;
return AST_TEST_NOT_RUN ;
case TEST_EXECUTE :
break ;
}
2017-02-16 14:28:33 +00:00
topology = ast_stream_topology_alloc ( ) ;
2017-02-13 17:00:42 +00:00
if ( ! topology ) {
ast_test_status_update ( test , " Failed to create media stream topology \n " ) ;
return AST_TEST_FAIL ;
}
2017-02-16 14:28:33 +00:00
audio_stream = ast_stream_alloc ( " audio " , AST_MEDIA_TYPE_AUDIO ) ;
2017-02-13 17:00:42 +00:00
if ( ! audio_stream ) {
ast_test_status_update ( test , " Failed to create an audio stream for testing stream topology \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_topology_set_stream ( topology , 0 , audio_stream ) ) {
ast_test_status_update ( test , " Failed to set an audio stream to a position where it is permitted \n " ) ;
2017-02-16 14:28:33 +00:00
ast_stream_free ( audio_stream ) ;
2017-02-13 17:00:42 +00:00
return AST_TEST_FAIL ;
}
if ( ast_stream_topology_get_count ( topology ) ! = 1 ) {
ast_test_status_update ( test , " Set an audio stream on the stream topology but stream count is '%d' on it, not 1 \n " ,
ast_stream_topology_get_count ( topology ) ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_topology_get_stream ( topology , 0 ) ! = audio_stream ) {
ast_test_status_update ( test , " Set an audio stream on the stream topology but returned stream doesn't match \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_get_position ( audio_stream ) ! = 0 ) {
ast_test_status_update ( test , " Set audio stream says it is at position '%d' instead of 0 \n " ,
ast_stream_get_position ( audio_stream ) ) ;
return AST_TEST_FAIL ;
}
2017-02-16 14:28:33 +00:00
video_stream = ast_stream_alloc ( " video " , AST_MEDIA_TYPE_VIDEO ) ;
2017-02-13 17:00:42 +00:00
if ( ! video_stream ) {
ast_test_status_update ( test , " Failed to create a video stream for testing stream topology \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_topology_set_stream ( topology , 0 , video_stream ) ) {
ast_test_status_update ( test , " Failed to set a video stream to a position where it is permitted \n " ) ;
2017-02-16 14:28:33 +00:00
ast_stream_free ( video_stream ) ;
2017-02-13 17:00:42 +00:00
return AST_TEST_FAIL ;
}
if ( ast_stream_topology_get_count ( topology ) ! = 1 ) {
ast_test_status_update ( test , " Set a video stream on the stream topology but stream count is '%d' on it, not 1 \n " ,
ast_stream_topology_get_count ( topology ) ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_topology_get_stream ( topology , 0 ) ! = video_stream ) {
ast_test_status_update ( test , " Set a video stream on the stream topology but returned stream doesn't match \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_get_position ( video_stream ) ! = 0 ) {
ast_test_status_update ( test , " Set video stream says it is at position '%d' instead of 0 \n " ,
ast_stream_get_position ( video_stream ) ) ;
return AST_TEST_FAIL ;
}
2017-02-16 14:28:33 +00:00
audio_stream = ast_stream_alloc ( " audio " , AST_MEDIA_TYPE_AUDIO ) ;
2017-02-13 17:00:42 +00:00
if ( ! audio_stream ) {
ast_test_status_update ( test , " Failed to create an audio stream for testing stream topology \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_topology_set_stream ( topology , 1 , audio_stream ) ) {
ast_test_status_update ( test , " Failed to set an audio stream to a position where it is permitted \n " ) ;
2017-02-16 14:28:33 +00:00
ast_stream_free ( audio_stream ) ;
2017-02-13 17:00:42 +00:00
return AST_TEST_FAIL ;
}
if ( ast_stream_topology_get_count ( topology ) ! = 2 ) {
ast_test_status_update ( test , " Set an audio stream on the stream topology but stream count is '%d' on it, not 2 \n " ,
ast_stream_topology_get_count ( topology ) ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_topology_get_stream ( topology , 1 ) ! = audio_stream ) {
ast_test_status_update ( test , " Set an audio stream on the stream topology but returned stream doesn't match \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_get_position ( audio_stream ) ! = 1 ) {
ast_test_status_update ( test , " Set audio stream says it is at position '%d' instead of 1 \n " ,
ast_stream_get_position ( audio_stream ) ) ;
return AST_TEST_FAIL ;
}
return AST_TEST_PASS ;
}
AST_TEST_DEFINE ( stream_topology_create_from_format_cap )
{
2017-02-16 14:28:33 +00:00
RAII_VAR ( struct ast_stream_topology * , topology , NULL , ast_stream_topology_free ) ;
2017-02-13 17:00:42 +00:00
RAII_VAR ( struct ast_format_cap * , caps , NULL , ao2_cleanup ) ;
switch ( cmd ) {
case TEST_INIT :
info - > name = " stream_topology_create_from_format_cap " ;
info - > category = " /main/stream/ " ;
info - > summary = " stream topology creation from format capabilities unit test " ;
info - > description =
" Test that creating a stream topology from format capabilities results in the expected streams " ;
return AST_TEST_NOT_RUN ;
case TEST_EXECUTE :
break ;
}
caps = ast_format_cap_alloc ( AST_FORMAT_CAP_FLAG_DEFAULT ) ;
if ( ! caps ) {
ast_test_status_update ( test , " Could not allocate an empty format capabilities structure \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_format_cap_append ( caps , ast_format_ulaw , 0 ) ) {
ast_test_status_update ( test , " Failed to append a ulaw format to capabilities for stream topology creation \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_format_cap_append ( caps , ast_format_alaw , 0 ) ) {
ast_test_status_update ( test , " Failed to append an alaw format to capabilities for stream topology creation \n " ) ;
return AST_TEST_FAIL ;
}
topology = ast_stream_topology_create_from_format_cap ( caps ) ;
if ( ! topology ) {
ast_test_status_update ( test , " Failed to create a stream topology using a perfectly good format capabilities \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_topology_get_count ( topology ) ! = 1 ) {
ast_test_status_update ( test , " Expected a stream topology with 1 stream but it has %d streams \n " ,
ast_stream_topology_get_count ( topology ) ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_get_type ( ast_stream_topology_get_stream ( topology , 0 ) ) ! = AST_MEDIA_TYPE_AUDIO ) {
ast_test_status_update ( test , " Produced stream topology has a single stream of type %s instead of audio \n " ,
ast_codec_media_type2str ( ast_stream_get_type ( ast_stream_topology_get_stream ( topology , 0 ) ) ) ) ;
return AST_TEST_FAIL ;
}
2017-02-16 14:28:33 +00:00
ast_stream_topology_free ( topology ) ;
2017-02-13 17:00:42 +00:00
topology = NULL ;
ast_format_cap_append ( caps , ast_format_h264 , 0 ) ;
topology = ast_stream_topology_create_from_format_cap ( caps ) ;
if ( ! topology ) {
ast_test_status_update ( test , " Failed to create a stream topology using a perfectly good format capabilities \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_topology_get_count ( topology ) ! = 2 ) {
ast_test_status_update ( test , " Expected a stream topology with 2 streams but it has %d streams \n " ,
ast_stream_topology_get_count ( topology ) ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_get_type ( ast_stream_topology_get_stream ( topology , 0 ) ) ! = AST_MEDIA_TYPE_AUDIO ) {
ast_test_status_update ( test , " Produced stream topology has a first stream of type %s instead of audio \n " ,
ast_codec_media_type2str ( ast_stream_get_type ( ast_stream_topology_get_stream ( topology , 0 ) ) ) ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_get_type ( ast_stream_topology_get_stream ( topology , 1 ) ) ! = AST_MEDIA_TYPE_VIDEO ) {
ast_test_status_update ( test , " Produced stream topology has a second stream of type %s instead of video \n " ,
ast_codec_media_type2str ( ast_stream_get_type ( ast_stream_topology_get_stream ( topology , 1 ) ) ) ) ;
return AST_TEST_FAIL ;
}
return AST_TEST_PASS ;
}
2017-02-14 18:33:57 +00:00
AST_TEST_DEFINE ( stream_topology_get_first_stream_by_type )
{
2017-02-16 14:28:33 +00:00
RAII_VAR ( struct ast_stream_topology * , topology , NULL , ast_stream_topology_free ) ;
2017-02-14 18:33:57 +00:00
struct ast_stream * first_stream , * second_stream , * third_stream , * fourth_stream ;
switch ( cmd ) {
case TEST_INIT :
info - > name = " stream_topology_get_first_stream_by_type " ;
info - > category = " /main/stream/ " ;
info - > summary = " stream topology getting first stream by type unit test " ;
info - > description =
" Test that getting the first stream by type from a topology actually returns the first stream " ;
return AST_TEST_NOT_RUN ;
case TEST_EXECUTE :
break ;
}
2017-02-16 14:28:33 +00:00
topology = ast_stream_topology_alloc ( ) ;
2017-02-14 18:33:57 +00:00
if ( ! topology ) {
ast_test_status_update ( test , " Failed to create media stream topology \n " ) ;
return AST_TEST_FAIL ;
}
2017-02-16 14:28:33 +00:00
first_stream = ast_stream_alloc ( " audio " , AST_MEDIA_TYPE_AUDIO ) ;
2017-02-14 18:33:57 +00:00
if ( ! first_stream ) {
ast_test_status_update ( test , " Failed to create an audio stream for testing stream topology \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_topology_append_stream ( topology , first_stream ) = = - 1 ) {
ast_test_status_update ( test , " Failed to append a perfectly good stream to a topology \n " ) ;
2017-02-16 14:28:33 +00:00
ast_stream_free ( first_stream ) ;
2017-02-14 18:33:57 +00:00
return AST_TEST_FAIL ;
}
2017-02-16 14:28:33 +00:00
second_stream = ast_stream_alloc ( " audio2 " , AST_MEDIA_TYPE_AUDIO ) ;
2017-02-14 18:33:57 +00:00
if ( ! second_stream ) {
ast_test_status_update ( test , " Failed to create a second audio stream for testing stream topology \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_topology_append_stream ( topology , second_stream ) = = - 1 ) {
ast_test_status_update ( test , " Failed to append a perfectly good stream to a topology \n " ) ;
2017-02-16 14:28:33 +00:00
ast_stream_free ( second_stream ) ;
2017-02-14 18:33:57 +00:00
return AST_TEST_FAIL ;
}
2017-02-16 14:28:33 +00:00
third_stream = ast_stream_alloc ( " video " , AST_MEDIA_TYPE_VIDEO ) ;
2017-02-14 18:33:57 +00:00
if ( ! third_stream ) {
ast_test_status_update ( test , " Failed to create a video stream for testing stream topology \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_topology_append_stream ( topology , third_stream ) = = - 1 ) {
ast_test_status_update ( test , " Failed to append a perfectly good stream to a topology \n " ) ;
2017-02-16 14:28:33 +00:00
ast_stream_free ( third_stream ) ;
2017-02-14 18:33:57 +00:00
return AST_TEST_FAIL ;
}
2017-02-16 14:28:33 +00:00
fourth_stream = ast_stream_alloc ( " video2 " , AST_MEDIA_TYPE_VIDEO ) ;
2017-02-14 18:33:57 +00:00
if ( ! fourth_stream ) {
ast_test_status_update ( test , " Failed to create a second video stream for testing stream topology \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_topology_append_stream ( topology , fourth_stream ) = = - 1 ) {
ast_test_status_update ( test , " Failed to append a perfectly good stream to a topology \n " ) ;
2017-02-16 14:28:33 +00:00
ast_stream_free ( fourth_stream ) ;
2017-02-14 18:33:57 +00:00
return AST_TEST_FAIL ;
}
if ( ast_stream_topology_get_first_stream_by_type ( topology , AST_MEDIA_TYPE_AUDIO ) ! = first_stream ) {
ast_test_status_update ( test , " Retrieved first audio stream from topology but it is not the correct one \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_topology_get_first_stream_by_type ( topology , AST_MEDIA_TYPE_VIDEO ) ! = third_stream ) {
ast_test_status_update ( test , " Retrieved first video stream from topology but it is not the correct one \n " ) ;
return AST_TEST_FAIL ;
}
return AST_TEST_PASS ;
}
static const struct ast_channel_tech mock_channel_tech = {
} ;
AST_TEST_DEFINE ( stream_topology_create_from_channel_nativeformats )
{
2017-02-16 14:28:33 +00:00
RAII_VAR ( struct ast_stream_topology * , topology , NULL , ast_stream_topology_free ) ;
2017-02-14 18:33:57 +00:00
RAII_VAR ( struct ast_format_cap * , caps , NULL , ao2_cleanup ) ;
struct ast_channel * mock_channel ;
enum ast_test_result_state res = AST_TEST_FAIL ;
struct ast_str * codec_have_buf = ast_str_alloca ( AST_FORMAT_CAP_NAMES_LEN ) ;
struct ast_str * codec_wanted_buf = ast_str_alloca ( AST_FORMAT_CAP_NAMES_LEN ) ;
switch ( cmd ) {
case TEST_INIT :
info - > name = " stream_topology_create_from_channel_nativeformats " ;
info - > category = " /main/stream/ " ;
info - > summary = " stream topology creation from channel native formats unit test " ;
info - > description =
" Test that creating a stream topology from the setting of channel nativeformats results in the expected streams " ;
return AST_TEST_NOT_RUN ;
case TEST_EXECUTE :
break ;
}
caps = ast_format_cap_alloc ( AST_FORMAT_CAP_FLAG_DEFAULT ) ;
if ( ! caps ) {
ast_test_status_update ( test , " Could not allocate an empty format capabilities structure \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_format_cap_append ( caps , ast_format_ulaw , 0 ) ) {
ast_test_status_update ( test , " Failed to append a ulaw format to capabilities for channel nativeformats \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_format_cap_append ( caps , ast_format_alaw , 0 ) ) {
ast_test_status_update ( test , " Failed to append an alaw format to capabilities for channel nativeformats \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_format_cap_append ( caps , ast_format_h264 , 0 ) ) {
ast_test_status_update ( test , " Failed to append an h264 format to capabilities for channel nativeformats \n " ) ;
return AST_TEST_FAIL ;
}
mock_channel = ast_channel_alloc ( 0 , AST_STATE_DOWN , NULL , NULL , NULL , NULL , NULL , NULL , NULL , 0 , " TestChannel " ) ;
if ( ! mock_channel ) {
ast_test_status_update ( test , " Failed to create a mock channel for testing \n " ) ;
return AST_TEST_FAIL ;
}
ast_channel_tech_set ( mock_channel , & mock_channel_tech ) ;
ast_channel_nativeformats_set ( mock_channel , caps ) ;
if ( ! ast_channel_get_stream_topology ( mock_channel ) ) {
ast_test_status_update ( test , " Set nativeformats with ulaw, alaw, and h264 on channel but it did not create a topology \n " ) ;
goto end ;
}
if ( ast_stream_topology_get_count ( ast_channel_get_stream_topology ( mock_channel ) ) ! = 2 ) {
ast_test_status_update ( test , " Set nativeformats on a channel to ulaw, alaw, and h264 and received '%d' streams instead of expected 2 \n " ,
ast_stream_topology_get_count ( ast_channel_get_stream_topology ( mock_channel ) ) ) ;
goto end ;
}
if ( ast_stream_get_type ( ast_stream_topology_get_stream ( ast_channel_get_stream_topology ( mock_channel ) , 0 ) ) ! = AST_MEDIA_TYPE_AUDIO ) {
ast_test_status_update ( test , " First stream on channel is of %s when it should be audio \n " ,
ast_codec_media_type2str ( ast_stream_get_type ( ast_stream_topology_get_stream ( ast_channel_get_stream_topology ( mock_channel ) , 0 ) ) ) ) ;
goto end ;
}
ast_format_cap_remove_by_type ( caps , AST_MEDIA_TYPE_VIDEO ) ;
if ( ! ast_format_cap_identical ( ast_stream_get_formats ( ast_stream_topology_get_stream ( ast_channel_get_stream_topology ( mock_channel ) , 0 ) ) , caps ) ) {
ast_test_status_update ( test , " Formats on audio stream of channel are '%s' when they should be '%s' \n " ,
ast_format_cap_get_names ( ast_stream_get_formats ( ast_stream_topology_get_stream ( ast_channel_get_stream_topology ( mock_channel ) , 0 ) ) , & codec_have_buf ) ,
ast_format_cap_get_names ( caps , & codec_wanted_buf ) ) ;
goto end ;
}
if ( ast_stream_get_type ( ast_stream_topology_get_stream ( ast_channel_get_stream_topology ( mock_channel ) , 1 ) ) ! = AST_MEDIA_TYPE_VIDEO ) {
ast_test_status_update ( test , " Second stream on channel is of type %s when it should be video \n " ,
ast_codec_media_type2str ( ast_stream_get_type ( ast_stream_topology_get_stream ( ast_channel_get_stream_topology ( mock_channel ) , 1 ) ) ) ) ;
goto end ;
}
ast_format_cap_remove_by_type ( caps , AST_MEDIA_TYPE_AUDIO ) ;
if ( ast_format_cap_append ( caps , ast_format_h264 , 0 ) ) {
ast_test_status_update ( test , " Failed to append h264 video codec to capabilities for capabilities comparison \n " ) ;
goto end ;
}
if ( ! ast_format_cap_identical ( ast_stream_get_formats ( ast_stream_topology_get_stream ( ast_channel_get_stream_topology ( mock_channel ) , 1 ) ) , caps ) ) {
ast_test_status_update ( test , " Formats on video stream of channel are '%s' when they should be '%s' \n " ,
ast_format_cap_get_names ( ast_stream_get_formats ( ast_stream_topology_get_stream ( ast_channel_get_stream_topology ( mock_channel ) , 1 ) ) , & codec_wanted_buf ) ,
ast_format_cap_get_names ( caps , & codec_wanted_buf ) ) ;
goto end ;
}
res = AST_TEST_PASS ;
end :
ast_channel_unlock ( mock_channel ) ;
ast_hangup ( mock_channel ) ;
return res ;
}
2017-02-24 21:30:33 +00:00
struct mock_channel_pvt {
int mallocd ;
unsigned int wrote ;
unsigned int wrote_stream ;
int stream_num ;
int frame_limit ;
int frame_count ;
int streams ;
int frames_per_read ;
2017-03-07 11:22:18 +00:00
unsigned int indicated_change_request ;
unsigned int indicated_changed ;
2017-02-24 21:30:33 +00:00
} ;
static struct ast_frame * mock_channel_read ( struct ast_channel * chan )
{
struct mock_channel_pvt * pvt = ast_channel_tech_pvt ( chan ) ;
struct ast_frame f = { 0 , } ;
struct ast_frame * head_frame = NULL ;
struct ast_frame * tail_frame = NULL ;
int i ;
if ( pvt - > frames_per_read = = 0 ) {
pvt - > frames_per_read = 1 ;
}
for ( i = 0 ; i < pvt - > frames_per_read & & pvt - > frame_count < pvt - > frame_limit ; i + + ) {
struct ast_frame * fr ;
if ( pvt - > frame_count % 2 = = 0 ) {
f . frametype = AST_FRAME_VOICE ;
f . subclass . format = ast_format_ulaw ;
} else {
f . frametype = AST_FRAME_VIDEO ;
f . subclass . format = ast_format_h264 ;
}
f . seqno = pvt - > frame_count ;
f . stream_num = pvt - > frame_count % pvt - > streams ;
pvt - > frame_count + + ;
fr = ast_frdup ( & f ) ;
if ( ! head_frame ) {
head_frame = fr ;
} else {
tail_frame - > frame_list . next = fr ;
}
tail_frame = fr ;
}
return ( head_frame ) ;
}
static int mock_channel_write ( struct ast_channel * chan , struct ast_frame * fr )
{
struct mock_channel_pvt * pvt = ast_channel_tech_pvt ( chan ) ;
pvt - > wrote = 1 ;
return 0 ;
}
2017-03-07 11:22:18 +00:00
static int mock_channel_indicate ( struct ast_channel * chan , int condition , const void * data , size_t datalen )
{
struct mock_channel_pvt * pvt = ast_channel_tech_pvt ( chan ) ;
if ( condition = = AST_CONTROL_STREAM_TOPOLOGY_REQUEST_CHANGE ) {
pvt - > indicated_change_request = 1 ;
} else if ( condition = = AST_CONTROL_STREAM_TOPOLOGY_CHANGED ) {
pvt - > indicated_changed = 1 ;
}
return 0 ;
}
2017-02-24 21:30:33 +00:00
static int mock_channel_write_stream ( struct ast_channel * chan , int stream_num , struct ast_frame * fr )
{
struct mock_channel_pvt * pvt = ast_channel_tech_pvt ( chan ) ;
pvt - > wrote_stream = 1 ;
pvt - > stream_num = stream_num ;
return 0 ;
}
2017-02-14 18:33:57 +00:00
static const struct ast_channel_tech mock_stream_channel_tech = {
2017-02-24 21:30:33 +00:00
. read_stream = mock_channel_read ,
. write_stream = mock_channel_write_stream ,
2017-02-14 18:33:57 +00:00
} ;
AST_TEST_DEFINE ( stream_topology_channel_set )
{
2017-02-16 14:28:33 +00:00
RAII_VAR ( struct ast_stream_topology * , topology , NULL , ast_stream_topology_free ) ;
2017-02-14 18:33:57 +00:00
struct ast_channel * mock_channel ;
enum ast_test_result_state res = AST_TEST_PASS ;
switch ( cmd ) {
case TEST_INIT :
info - > name = " stream_topology_channel_set " ;
info - > category = " /main/stream/ " ;
info - > summary = " stream topology setting on a channel unit test " ;
info - > description =
" Test that setting a stream topology on a channel works " ;
return AST_TEST_NOT_RUN ;
case TEST_EXECUTE :
break ;
}
2017-02-16 14:28:33 +00:00
topology = ast_stream_topology_alloc ( ) ;
2017-02-14 18:33:57 +00:00
if ( ! topology ) {
ast_test_status_update ( test , " Failed to create media stream topology \n " ) ;
return AST_TEST_FAIL ;
}
mock_channel = ast_channel_alloc ( 0 , AST_STATE_DOWN , NULL , NULL , NULL , NULL , NULL , NULL , NULL , 0 , " TestChannel " ) ;
if ( ! mock_channel ) {
ast_test_status_update ( test , " Failed to create a mock channel for testing \n " ) ;
return AST_TEST_FAIL ;
}
ast_channel_tech_set ( mock_channel , & mock_stream_channel_tech ) ;
ast_channel_set_stream_topology ( mock_channel , topology ) ;
if ( ast_channel_get_stream_topology ( mock_channel ) ! = topology ) {
ast_test_status_update ( test , " Set an explicit stream topology on a channel but the returned one did not match it \n " ) ;
res = AST_TEST_FAIL ;
}
topology = NULL ;
ast_channel_unlock ( mock_channel ) ;
ast_hangup ( mock_channel ) ;
return res ;
}
2017-02-24 21:30:33 +00:00
static int mock_channel_hangup ( struct ast_channel * chan )
2017-02-22 11:00:57 +00:00
{
struct mock_channel_pvt * pvt = ast_channel_tech_pvt ( chan ) ;
2017-02-24 21:30:33 +00:00
if ( pvt - > mallocd ) {
ast_free ( pvt ) ;
}
2017-02-22 11:00:57 +00:00
ast_channel_tech_pvt_set ( chan , NULL ) ;
return 0 ;
}
static const struct ast_channel_tech mock_channel_old_write_tech = {
. write = mock_channel_write ,
. write_video = mock_channel_write ,
. hangup = mock_channel_hangup ,
} ;
AST_TEST_DEFINE ( stream_write_non_multistream )
{
RAII_VAR ( struct ast_format_cap * , caps , NULL , ao2_cleanup ) ;
struct ast_channel * mock_channel ;
2017-02-24 21:30:33 +00:00
struct mock_channel_pvt pvt = { 0 , } ;
2017-02-22 11:00:57 +00:00
enum ast_test_result_state res = AST_TEST_FAIL ;
struct ast_frame frame = { 0 , } ;
switch ( cmd ) {
case TEST_INIT :
info - > name = " stream_write_non_multistream " ;
info - > category = " /main/stream/ " ;
info - > summary = " stream writing to non-multistream capable channel test " ;
info - > description =
" Test that writing frames to a non-multistream channel works as expected " ;
return AST_TEST_NOT_RUN ;
case TEST_EXECUTE :
break ;
}
caps = ast_format_cap_alloc ( AST_FORMAT_CAP_FLAG_DEFAULT ) ;
if ( ! caps ) {
ast_test_status_update ( test , " Could not allocate an empty format capabilities structure \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_format_cap_append ( caps , ast_format_ulaw , 0 ) ) {
ast_test_status_update ( test , " Failed to append a ulaw format to capabilities for channel nativeformats \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_format_cap_append ( caps , ast_format_h264 , 0 ) ) {
ast_test_status_update ( test , " Failed to append an h264 format to capabilities for channel nativeformats \n " ) ;
return AST_TEST_FAIL ;
}
mock_channel = ast_channel_alloc ( 0 , AST_STATE_DOWN , NULL , NULL , NULL , NULL , NULL , NULL , NULL , 0 , " TestChannel " ) ;
if ( ! mock_channel ) {
ast_test_status_update ( test , " Failed to create a mock channel for testing \n " ) ;
return AST_TEST_FAIL ;
}
ast_channel_tech_set ( mock_channel , & mock_channel_old_write_tech ) ;
ast_channel_nativeformats_set ( mock_channel , caps ) ;
pvt . wrote = 0 ;
ast_channel_tech_pvt_set ( mock_channel , & pvt ) ;
ast_channel_unlock ( mock_channel ) ;
frame . frametype = AST_FRAME_VOICE ;
frame . subclass . format = ast_format_ulaw ;
if ( ast_write ( mock_channel , & frame ) ) {
ast_test_status_update ( test , " Failed to write a ulaw frame to the mock channel when it should be fine \n " ) ;
goto end ;
}
if ( ! pvt . wrote ) {
ast_test_status_update ( test , " Successfully wrote a frame of ulaw but it never reached the channel driver \n " ) ;
goto end ;
}
pvt . wrote = 0 ;
if ( ! ast_write_stream ( mock_channel , 2 , & frame ) | | pvt . wrote ) {
ast_test_status_update ( test , " Successfully wrote a frame of ulaw to a non-existent stream \n " ) ;
goto end ;
}
frame . frametype = AST_FRAME_VIDEO ;
frame . subclass . format = ast_format_h264 ;
if ( ast_write ( mock_channel , & frame ) ) {
ast_test_status_update ( test , " Failed to write an h264 frame to the mock channel when it should be fine \n " ) ;
goto end ;
}
if ( ! pvt . wrote ) {
ast_test_status_update ( test , " Successfully wrote a frame of h264 but it never reached the channel driver \n " ) ;
goto end ;
}
res = AST_TEST_PASS ;
end :
ast_hangup ( mock_channel ) ;
return res ;
}
static const struct ast_channel_tech mock_channel_write_stream_tech = {
. write = mock_channel_write ,
. write_video = mock_channel_write ,
. write_stream = mock_channel_write_stream ,
2017-02-24 21:30:33 +00:00
. read_stream = mock_channel_read ,
2017-02-22 11:00:57 +00:00
. hangup = mock_channel_hangup ,
} ;
AST_TEST_DEFINE ( stream_write_multistream )
{
RAII_VAR ( struct ast_format_cap * , caps , NULL , ao2_cleanup ) ;
RAII_VAR ( struct ast_stream_topology * , topology , NULL , ast_stream_topology_free ) ;
struct ast_stream * stream ;
struct ast_channel * mock_channel ;
struct mock_channel_pvt pvt = { 0 , } ;
enum ast_test_result_state res = AST_TEST_FAIL ;
struct ast_frame frame = { 0 , } ;
switch ( cmd ) {
case TEST_INIT :
info - > name = " stream_write_multistream " ;
info - > category = " /main/stream/ " ;
info - > summary = " stream writing to multistream capable channel test " ;
info - > description =
" Test that writing frames to a multistream channel works as expected " ;
return AST_TEST_NOT_RUN ;
case TEST_EXECUTE :
break ;
}
topology = ast_stream_topology_alloc ( ) ;
if ( ! topology ) {
ast_test_status_update ( test , " Failed to create media stream topology \n " ) ;
return AST_TEST_FAIL ;
}
stream = ast_stream_alloc ( " audio " , AST_MEDIA_TYPE_AUDIO ) ;
if ( ! stream ) {
ast_test_status_update ( test , " Failed to create an audio stream for testing multistream writing \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_topology_append_stream ( topology , stream ) = = - 1 ) {
ast_test_status_update ( test , " Failed to append a perfectly good stream to a topology \n " ) ;
ast_stream_free ( stream ) ;
return AST_TEST_FAIL ;
}
stream = ast_stream_alloc ( " audio2 " , AST_MEDIA_TYPE_AUDIO ) ;
if ( ! stream ) {
ast_test_status_update ( test , " Failed to create an audio stream for testing multistream writing \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_topology_append_stream ( topology , stream ) = = - 1 ) {
ast_test_status_update ( test , " Failed to append a perfectly good stream to a topology \n " ) ;
ast_stream_free ( stream ) ;
return AST_TEST_FAIL ;
}
stream = ast_stream_alloc ( " video " , AST_MEDIA_TYPE_VIDEO ) ;
if ( ! stream ) {
ast_test_status_update ( test , " Failed to create a video stream for testing multistream writing \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_topology_append_stream ( topology , stream ) = = - 1 ) {
ast_test_status_update ( test , " Failed to append a perfectly good stream to a topology \n " ) ;
ast_stream_free ( stream ) ;
return AST_TEST_FAIL ;
}
stream = ast_stream_alloc ( " video2 " , AST_MEDIA_TYPE_VIDEO ) ;
if ( ! stream ) {
ast_test_status_update ( test , " Failed to create a video stream for testing multistream writing \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_stream_topology_append_stream ( topology , stream ) = = - 1 ) {
ast_test_status_update ( test , " Failed to append a perfectly good stream to a topology \n " ) ;
ast_stream_free ( stream ) ;
return AST_TEST_FAIL ;
}
caps = ast_format_cap_alloc ( AST_FORMAT_CAP_FLAG_DEFAULT ) ;
if ( ! caps ) {
ast_test_status_update ( test , " Could not allocate an empty format capabilities structure \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_format_cap_append ( caps , ast_format_ulaw , 0 ) ) {
ast_test_status_update ( test , " Failed to append a ulaw format to capabilities for channel nativeformats \n " ) ;
return AST_TEST_FAIL ;
}
if ( ast_format_cap_append ( caps , ast_format_h264 , 0 ) ) {
ast_test_status_update ( test , " Failed to append an h264 format to capabilities for channel nativeformats \n " ) ;
return AST_TEST_FAIL ;
}
mock_channel = ast_channel_alloc ( 0 , AST_STATE_DOWN , NULL , NULL , NULL , NULL , NULL , NULL , NULL , 0 , " TestChannel " ) ;
if ( ! mock_channel ) {
ast_test_status_update ( test , " Failed to create a mock channel for testing \n " ) ;
return AST_TEST_FAIL ;
}
ast_channel_tech_set ( mock_channel , & mock_channel_write_stream_tech ) ;
ast_channel_set_stream_topology ( mock_channel , topology ) ;
ast_channel_nativeformats_set ( mock_channel , caps ) ;
topology = NULL ;
ast_channel_tech_pvt_set ( mock_channel , & pvt ) ;
ast_channel_unlock ( mock_channel ) ;
frame . frametype = AST_FRAME_VOICE ;
frame . subclass . format = ast_format_ulaw ;
pvt . stream_num = - 1 ;
if ( ast_write ( mock_channel , & frame ) ) {
ast_test_status_update ( test , " Failed to write a ulaw frame to the mock channel when it should be fine \n " ) ;
goto end ;
}
if ( pvt . wrote ) {
ast_test_status_update ( test , " Successfully wrote a frame of ulaw but it ended up on the old write callback instead of write_stream \n " ) ;
goto end ;
}
if ( ! pvt . wrote_stream ) {
ast_test_status_update ( test , " Successfully wrote a frame of ulaw but it never reached the channel driver \n " ) ;
goto end ;
}
if ( pvt . stream_num ! = 0 ) {
ast_test_status_update ( test , " Successfully wrote a frame of ulaw to the default stream but it ended up on stream %d and not 0 \n " ,
pvt . stream_num ) ;
goto end ;
}
pvt . wrote_stream = 0 ;
pvt . stream_num = - 1 ;
if ( ast_write_stream ( mock_channel , 0 , & frame ) ) {
ast_test_status_update ( test , " Failed to write a ulaw frame to the first audio stream \n " ) ;
goto end ;
}
if ( pvt . wrote ) {
ast_test_status_update ( test , " Successfully wrote a frame of ulaw to the first audio stream but it ended up on the old write callback instead of write_stream \n " ) ;
goto end ;
}
if ( ! pvt . wrote_stream ) {
ast_test_status_update ( test , " Successfully wrote a frame of ulaw to the first audio stream but it never reached the channel driver \n " ) ;
goto end ;
}
if ( pvt . stream_num ! = 0 ) {
ast_test_status_update ( test , " Successfully wrote a frame of ulaw to the first audio stream but it ended up on stream %d and not 0 \n " ,
pvt . stream_num ) ;
goto end ;
}
pvt . wrote_stream = 0 ;
pvt . stream_num = - 1 ;
if ( ast_write_stream ( mock_channel , 1 , & frame ) ) {
ast_test_status_update ( test , " Failed to write a ulaw frame to the second audio stream \n " ) ;
goto end ;
}
if ( pvt . wrote ) {
ast_test_status_update ( test , " Successfully wrote a frame of ulaw to the second audio stream but it ended up on the old write callback instead of write_stream \n " ) ;
goto end ;
}
if ( ! pvt . wrote_stream ) {
ast_test_status_update ( test , " Successfully wrote a frame of ulaw to the second audio stream but it never reached the channel driver \n " ) ;
goto end ;
}
if ( pvt . stream_num ! = 1 ) {
ast_test_status_update ( test , " Successfully wrote a frame of ulaw to the second audio stream but it ended up on stream %d and not 1 \n " ,
pvt . stream_num ) ;
goto end ;
}
pvt . wrote_stream = 0 ;
pvt . stream_num = - 1 ;
frame . frametype = AST_FRAME_VIDEO ;
frame . subclass . format = ast_format_h264 ;
if ( ast_write ( mock_channel , & frame ) ) {
ast_test_status_update ( test , " Failed to write an h264 frame to the mock channel when it should be fine \n " ) ;
goto end ;
}
if ( pvt . wrote ) {
ast_test_status_update ( test , " Successfully wrote a frame of h264 but it ended up on the old write callback instead of write_stream \n " ) ;
goto end ;
}
if ( ! pvt . wrote_stream ) {
ast_test_status_update ( test , " Successfully wrote a frame of h264 but it never reached the channel driver \n " ) ;
goto end ;
}
if ( pvt . stream_num ! = 2 ) {
ast_test_status_update ( test , " Successfully wrote a frame of h264 to the default stream but it ended up on stream %d and not 2 \n " ,
pvt . stream_num ) ;
goto end ;
}
pvt . wrote_stream = 0 ;
pvt . stream_num = - 1 ;
if ( ast_write_stream ( mock_channel , 2 , & frame ) ) {
ast_test_status_update ( test , " Failed to write an h264 frame to the first video stream \n " ) ;
goto end ;
}
if ( pvt . wrote ) {
ast_test_status_update ( test , " Successfully wrote a frame of h264 to the first video stream but it ended up on the old write callback instead of write_stream \n " ) ;
goto end ;
}
if ( ! pvt . wrote_stream ) {
ast_test_status_update ( test , " Successfully wrote a frame of h264 to the first video stream but it never reached the channel driver \n " ) ;
goto end ;
}
if ( pvt . stream_num ! = 2 ) {
ast_test_status_update ( test , " Successfully wrote a frame of h264 to the first video stream but it ended up on stream %d and not 2 \n " ,
pvt . stream_num ) ;
goto end ;
}
pvt . wrote_stream = 0 ;
pvt . stream_num = - 1 ;
if ( ast_write_stream ( mock_channel , 3 , & frame ) ) {
ast_test_status_update ( test , " Failed to write an h264 frame to the second video stream \n " ) ;
goto end ;
}
if ( pvt . wrote ) {
ast_test_status_update ( test , " Successfully wrote a frame of h264 to the second video stream but it ended up on the old write callback instead of write_stream \n " ) ;
goto end ;
}
if ( ! pvt . wrote_stream ) {
ast_test_status_update ( test , " Successfully wrote a frame of h264 to the second video stream but it never reached the channel driver \n " ) ;
goto end ;
}
if ( pvt . stream_num ! = 3 ) {
ast_test_status_update ( test , " Successfully wrote a frame of h264 to the second video stream but it ended up on stream %d and not 3 \n " ,
pvt . stream_num ) ;
goto end ;
}
pvt . wrote_stream = 0 ;
pvt . stream_num = - 1 ;
if ( ! ast_write_stream ( mock_channel , 9 , & frame ) ) {
ast_test_status_update ( test , " Successfully wrote a frame of h264 to a non-existent stream \n " ) ;
goto end ;
}
if ( pvt . wrote ) {
ast_test_status_update ( test , " Successfully wrote a frame of h264 to a non-existent stream and it ended up on the old write callback \n " ) ;
goto end ;
}
if ( pvt . wrote_stream ) {
ast_test_status_update ( test , " Successfully wrote a frame of h264 to a non-existent stream and it ended up on the write_stream callback \n " ) ;
goto end ;
}
res = AST_TEST_PASS ;
end :
ast_hangup ( mock_channel ) ;
return res ;
}
2017-02-24 21:30:33 +00:00
static int load_stream_readqueue ( struct ast_channel * chan , int frames )
{
struct mock_channel_pvt * pvt = ast_channel_tech_pvt ( chan ) ;
struct ast_frame f = { 0 , } ;
struct ast_frame * frame = NULL ;
int i ;
while ( ( frame = AST_LIST_REMOVE_HEAD ( ast_channel_readq ( chan ) , frame_list ) ) )
ast_frfree ( frame ) ;
for ( i = 0 ; i < frames ; i + + ) {
if ( pvt - > frame_count % 2 = = 0 ) {
f . frametype = AST_FRAME_VOICE ;
f . subclass . format = ast_format_ulaw ;
} else {
f . frametype = AST_FRAME_VIDEO ;
f . subclass . format = ast_format_h264 ;
}
f . stream_num = pvt - > frame_count % pvt - > streams ;
f . seqno = pvt - > frame_count ;
ast_queue_frame ( chan , ast_frdup ( & f ) ) ;
pvt - > frame_count + + ;
}
return 0 ;
}
static struct ast_channel * make_channel ( struct ast_test * test , int streams ,
struct ast_channel_tech * tech )
{
RAII_VAR ( struct ast_format_cap * , caps , NULL , ao2_cleanup ) ;
struct ast_channel * mock_channel = NULL ;
struct mock_channel_pvt * pvt = NULL ;
struct ast_stream_topology * topology = NULL ;
struct ast_stream * stream ;
enum ast_test_result_state res = AST_TEST_PASS ;
int i ;
mock_channel = ast_channel_alloc ( 0 , AST_STATE_DOWN , NULL , NULL , NULL , NULL , NULL , NULL , NULL , 0 , " TestChannel " ) ;
ast_test_validate_cleanup ( test , mock_channel , res , done ) ;
ast_channel_tech_set ( mock_channel , tech ) ;
if ( tech - > read_stream ) {
topology = ast_stream_topology_alloc ( ) ;
ast_test_validate_cleanup ( test , topology , res , done ) ;
for ( i = 0 ; i < streams ; i + + ) {
stream = ast_stream_alloc ( ( i % 2 ? " video " : " audio " ) , ( i % 2 ? AST_MEDIA_TYPE_VIDEO : AST_MEDIA_TYPE_AUDIO ) ) ;
ast_test_validate_cleanup ( test , stream , res , done ) ;
ast_test_validate_cleanup ( test , ast_stream_topology_append_stream ( topology , stream ) = = i , res , done ) ;
}
ast_test_validate_cleanup ( test , ast_stream_topology_get_count ( topology ) = = streams , res , done ) ;
ast_channel_set_stream_topology ( mock_channel , topology ) ;
topology = NULL ;
} else {
caps = ast_format_cap_alloc ( AST_FORMAT_CAP_FLAG_DEFAULT ) ;
ast_test_validate_cleanup ( test , caps , res , done ) ;
ast_test_validate_cleanup ( test , ast_format_cap_append ( caps , ast_format_ulaw , 0 ) = = 0 , res , done ) ;
ast_test_validate_cleanup ( test , ast_format_cap_append ( caps , ast_format_h264 , 0 ) = = 0 , res , done ) ;
ast_channel_nativeformats_set ( mock_channel , caps ) ;
}
pvt = ast_calloc ( 1 , sizeof ( * pvt ) ) ;
ast_test_validate_cleanup ( test , pvt , res , done ) ;
pvt - > mallocd = 1 ;
ast_channel_tech_pvt_set ( mock_channel , pvt ) ;
ast_channel_unlock ( mock_channel ) ;
done :
ast_stream_topology_free ( topology ) ;
if ( res = = AST_TEST_FAIL & & mock_channel ) {
ast_hangup ( mock_channel ) ;
}
return mock_channel ;
}
enum CHANNEL_READ_TYPE {
CHANNEL_READ ,
CHANNEL_READ_STREAM
} ;
static struct ast_frame * read_from_chan ( enum CHANNEL_READ_TYPE rt , struct ast_channel * chan )
{
if ( rt = = CHANNEL_READ_STREAM ) {
return ast_read_stream ( chan ) ;
} else {
return ast_read ( chan ) ;
}
}
static enum ast_test_result_state read_test ( struct ast_test * test , struct ast_channel_tech * tech ,
enum CHANNEL_READ_TYPE rt , int streams , int frames , int frames_per_read , int expected_nulls )
{
struct ast_channel * mock_channel ;
struct mock_channel_pvt * pvt ;
struct ast_frame * fr = NULL ;
enum ast_test_result_state res = AST_TEST_PASS ;
int i = 0 ;
int null_frames = 0 ;
ast_test_status_update ( test , " ChanType: %s ReadType: %s Streams: %d Frames: %d Frames per read: %d Expected Nulls: %d \n " ,
tech - > read_stream ? " MULTI " : " NON-MULTI " ,
rt = = CHANNEL_READ_STREAM ? " STREAM " : " NON-STREAM " ,
streams , frames , frames_per_read , expected_nulls ) ;
mock_channel = make_channel ( test , 4 , tech ) ;
ast_test_validate_cleanup ( test , mock_channel , res , done ) ;
pvt = ast_channel_tech_pvt ( mock_channel ) ;
pvt - > frame_count = 0 ;
pvt - > frame_limit = frames ;
pvt - > streams = streams ;
pvt - > frames_per_read = frames_per_read ;
load_stream_readqueue ( mock_channel , frames / 2 ) ;
ast_channel_fdno_set ( mock_channel , 0 ) ;
while ( ( fr = read_from_chan ( rt , mock_channel ) ) ) {
ast_channel_fdno_set ( mock_channel , 0 ) ;
if ( fr - > frametype ! = AST_FRAME_NULL ) {
ast_test_validate_cleanup ( test , i = = fr - > seqno , res , done ) ;
ast_test_validate_cleanup ( test , fr - > frametype = = ( i % 2 ? AST_FRAME_VIDEO : AST_FRAME_VOICE ) , res , done ) ;
ast_test_validate_cleanup ( test , fr - > stream_num = = ( i % streams ) , res , done ) ;
ast_frfree ( fr ) ;
} else {
null_frames + + ;
}
fr = NULL ;
i + + ;
}
ast_test_validate_cleanup ( test , i = = frames , res , done ) ;
ast_test_validate_cleanup ( test , null_frames = = expected_nulls , res , done ) ;
done :
ast_test_status_update ( test , " Frames read: %d NULL frames: %d \n " , i , null_frames ) ;
ast_hangup ( mock_channel ) ;
return res ;
}
AST_TEST_DEFINE ( stream_read_non_multistream )
{
struct ast_channel_tech tech = {
. read = mock_channel_read ,
. hangup = mock_channel_hangup ,
} ;
enum ast_test_result_state res = AST_TEST_PASS ;
switch ( cmd ) {
case TEST_INIT :
info - > name = " stream_read_non_multistream " ;
info - > category = " /main/stream/ " ;
info - > summary = " stream reading from non-multistream capable channel test " ;
info - > description =
" Test that reading frames from a non-multistream channel works as expected " ;
return AST_TEST_NOT_RUN ;
case TEST_EXECUTE :
break ;
}
res = read_test ( test , & tech , CHANNEL_READ , 2 , 16 , 1 , 0 ) ;
ast_test_validate ( test , res = = AST_TEST_PASS , " non multi, non read stream, 2 stream " ) ;
res = read_test ( test , & tech , CHANNEL_READ_STREAM , 2 , 16 , 1 , 0 ) ;
ast_test_validate ( test , res = = AST_TEST_PASS , " non multi, read stream, 2 stream " ) ;
res = read_test ( test , & tech , CHANNEL_READ , 2 , 16 , 3 , 0 ) ;
ast_test_validate ( test , res = = AST_TEST_PASS , " non multi, non read stream, 2 stream, 3 frames per read " ) ;
res = read_test ( test , & tech , CHANNEL_READ_STREAM , 2 , 16 , 3 , 0 ) ;
ast_test_validate ( test , res = = AST_TEST_PASS , " non multi, read stream, 2 stream, 3 frames per read " ) ;
return res ;
}
AST_TEST_DEFINE ( stream_read_multistream )
{
struct ast_channel_tech tech = {
. read_stream = mock_channel_read ,
. write_stream = mock_channel_write_stream ,
. hangup = mock_channel_hangup ,
} ;
enum ast_test_result_state res = AST_TEST_PASS ;
switch ( cmd ) {
case TEST_INIT :
info - > name = " stream_read_multistream " ;
info - > category = " /main/stream/ " ;
info - > summary = " stream reading from multistream capable channel test " ;
info - > description =
" Test that reading frames from a multistream channel works as expected " ;
return AST_TEST_NOT_RUN ;
case TEST_EXECUTE :
break ;
}
res = read_test ( test , & tech , CHANNEL_READ , 2 , 16 , 1 , 0 ) ;
ast_test_validate ( test , res = = AST_TEST_PASS , " multi, non read stream, 2 stream " ) ;
res = read_test ( test , & tech , CHANNEL_READ_STREAM , 2 , 16 , 1 , 0 ) ;
ast_test_validate ( test , res = = AST_TEST_PASS , " multi, read stream, 2 stream " ) ;
res = read_test ( test , & tech , CHANNEL_READ , 4 , 16 , 1 , 8 ) ;
ast_test_validate ( test , res = = AST_TEST_PASS , " multi, non read stream, 4 stream " ) ;
res = read_test ( test , & tech , CHANNEL_READ_STREAM , 4 , 16 , 1 , 0 ) ;
ast_test_validate ( test , res = = AST_TEST_PASS , " multi, read stream, 4 stream " ) ;
res = read_test ( test , & tech , CHANNEL_READ , 2 , 16 , 3 , 0 ) ;
ast_test_validate ( test , res = = AST_TEST_PASS , " multi, non read stream, 2 stream, 3 frames per read " ) ;
res = read_test ( test , & tech , CHANNEL_READ_STREAM , 2 , 16 , 3 , 0 ) ;
ast_test_validate ( test , res = = AST_TEST_PASS , " multi, read stream, 2 stream, 3 frames per read " ) ;
res = read_test ( test , & tech , CHANNEL_READ , 4 , 16 , 3 , 8 ) ;
ast_test_validate ( test , res = = AST_TEST_PASS , " multi, non read stream, 4 stream, 3 frames per read " ) ;
res = read_test ( test , & tech , CHANNEL_READ_STREAM , 4 , 16 , 3 , 0 ) ;
ast_test_validate ( test , res = = AST_TEST_PASS , " multi, read stream, 4 stream, 3 frames per read " ) ;
return res ;
}
2017-03-07 11:22:18 +00:00
AST_TEST_DEFINE ( stream_topology_change_request_from_application_non_multistream )
{
struct ast_channel_tech tech = {
. read = mock_channel_read ,
. indicate = mock_channel_indicate ,
. hangup = mock_channel_hangup ,
} ;
struct ast_channel * mock_channel ;
struct mock_channel_pvt * pvt ;
enum ast_test_result_state res = AST_TEST_PASS ;
int change_res ;
RAII_VAR ( struct ast_stream_topology * , topology , NULL , ast_stream_topology_free ) ;
switch ( cmd ) {
case TEST_INIT :
info - > name = " stream_topology_change_request_from_application_non_multistream " ;
info - > category = " /main/stream/ " ;
info - > summary = " stream topology changing on non-multistream channel test " ;
info - > description =
" Test that an application trying to change the stream topology of a non-multistream channel gets a failure " ;
return AST_TEST_NOT_RUN ;
case TEST_EXECUTE :
break ;
}
mock_channel = make_channel ( test , 1 , & tech ) ;
ast_test_validate_cleanup ( test , mock_channel , res , done ) ;
pvt = ast_channel_tech_pvt ( mock_channel ) ;
pvt - > indicated_change_request = 0 ;
pvt - > indicated_changed = 0 ;
topology = ast_stream_topology_alloc ( ) ;
ast_test_validate_cleanup ( test , topology , res , done ) ;
change_res = ast_channel_request_stream_topology_change ( mock_channel , topology ) ;
ast_test_validate_cleanup ( test , change_res = = - 1 , res , done ) ;
ast_test_validate_cleanup ( test , ! pvt - > indicated_change_request , res , done ) ;
change_res = ast_channel_stream_topology_changed ( mock_channel , topology ) ;
ast_test_validate_cleanup ( test , change_res = = - 1 , res , done ) ;
ast_test_validate_cleanup ( test , ! pvt - > indicated_changed , res , done ) ;
done :
ast_hangup ( mock_channel ) ;
return res ;
}
AST_TEST_DEFINE ( stream_topology_change_request_from_channel_non_multistream )
{
struct ast_channel_tech tech = {
. read_stream = mock_channel_read ,
. write_stream = mock_channel_write_stream ,
. indicate = mock_channel_indicate ,
. hangup = mock_channel_hangup ,
} ;
struct ast_channel * mock_channel ;
struct mock_channel_pvt * pvt ;
enum ast_test_result_state res = AST_TEST_PASS ;
RAII_VAR ( struct ast_stream_topology * , topology , NULL , ast_stream_topology_free ) ;
struct ast_frame request_change = {
. frametype = AST_FRAME_CONTROL ,
. subclass . integer = AST_CONTROL_STREAM_TOPOLOGY_REQUEST_CHANGE ,
} ;
struct ast_frame * fr = NULL ;
switch ( cmd ) {
case TEST_INIT :
info - > name = " stream_topology_change_request_from_channel_non_multistream " ;
info - > category = " /main/stream/ " ;
info - > summary = " channel requesting stream topology change to non-multistream application test " ;
info - > description =
" Test that a channel requesting a stream topology change from a non-multistream application does not work " ;
return AST_TEST_NOT_RUN ;
case TEST_EXECUTE :
break ;
}
mock_channel = make_channel ( test , 1 , & tech ) ;
ast_test_validate_cleanup ( test , mock_channel , res , done ) ;
pvt = ast_channel_tech_pvt ( mock_channel ) ;
pvt - > indicated_changed = 0 ;
topology = ast_stream_topology_alloc ( ) ;
ast_test_validate_cleanup ( test , topology , res , done ) ;
request_change . data . ptr = topology ;
ast_queue_frame ( mock_channel , & request_change ) ;
fr = ast_read ( mock_channel ) ;
ast_test_validate_cleanup ( test , fr , res , done ) ;
ast_test_validate_cleanup ( test , fr = = & ast_null_frame , res , done ) ;
ast_test_validate_cleanup ( test , pvt - > indicated_changed , res , done ) ;
done :
if ( fr ) {
ast_frfree ( fr ) ;
}
ast_hangup ( mock_channel ) ;
return res ;
}
AST_TEST_DEFINE ( stream_topology_change_request_from_application )
{
struct ast_channel_tech tech = {
. read_stream = mock_channel_read ,
. write_stream = mock_channel_write_stream ,
. indicate = mock_channel_indicate ,
. hangup = mock_channel_hangup ,
} ;
struct ast_channel * mock_channel ;
struct mock_channel_pvt * pvt ;
enum ast_test_result_state res = AST_TEST_PASS ;
int change_res ;
RAII_VAR ( struct ast_stream_topology * , topology , NULL , ast_stream_topology_free ) ;
switch ( cmd ) {
case TEST_INIT :
info - > name = " stream_topology_change_request_from_application " ;
info - > category = " /main/stream/ " ;
info - > summary = " stream topology change request from application test " ;
info - > description =
" Test that an application changing the stream topology of a multistream capable channel receives success " ;
return AST_TEST_NOT_RUN ;
case TEST_EXECUTE :
break ;
}
mock_channel = make_channel ( test , 1 , & tech ) ;
ast_test_validate_cleanup ( test , mock_channel , res , done ) ;
pvt = ast_channel_tech_pvt ( mock_channel ) ;
pvt - > indicated_change_request = 0 ;
pvt - > indicated_changed = 0 ;
topology = ast_stream_topology_alloc ( ) ;
ast_test_validate_cleanup ( test , topology , res , done ) ;
change_res = ast_channel_request_stream_topology_change ( mock_channel , topology ) ;
ast_test_validate_cleanup ( test , ! change_res , res , done ) ;
ast_test_validate_cleanup ( test , pvt - > indicated_change_request , res , done ) ;
change_res = ast_channel_stream_topology_changed ( mock_channel , topology ) ;
ast_test_validate_cleanup ( test , ! change_res , res , done ) ;
ast_test_validate_cleanup ( test , pvt - > indicated_changed , res , done ) ;
done :
ast_hangup ( mock_channel ) ;
return res ;
}
AST_TEST_DEFINE ( stream_topology_change_request_from_channel )
{
struct ast_channel_tech tech = {
. read_stream = mock_channel_read ,
. write_stream = mock_channel_write_stream ,
. indicate = mock_channel_indicate ,
. hangup = mock_channel_hangup ,
} ;
struct ast_channel * mock_channel ;
struct mock_channel_pvt * pvt ;
enum ast_test_result_state res = AST_TEST_PASS ;
RAII_VAR ( struct ast_stream_topology * , topology , NULL , ast_stream_topology_free ) ;
struct ast_frame request_change = {
. frametype = AST_FRAME_CONTROL ,
. subclass . integer = AST_CONTROL_STREAM_TOPOLOGY_REQUEST_CHANGE ,
} ;
struct ast_frame * fr = NULL ;
switch ( cmd ) {
case TEST_INIT :
info - > name = " stream_topology_change_request_from_channel " ;
info - > category = " /main/stream/ " ;
info - > summary = " channel requesting stream topology change to multistream application test " ;
info - > description =
" Test that a channel requesting a stream topology change from a multistream application works " ;
return AST_TEST_NOT_RUN ;
case TEST_EXECUTE :
break ;
}
mock_channel = make_channel ( test , 1 , & tech ) ;
ast_test_validate_cleanup ( test , mock_channel , res , done ) ;
pvt = ast_channel_tech_pvt ( mock_channel ) ;
pvt - > indicated_changed = 0 ;
topology = ast_stream_topology_alloc ( ) ;
ast_test_validate_cleanup ( test , topology , res , done ) ;
request_change . data . ptr = topology ;
ast_queue_frame ( mock_channel , & request_change ) ;
fr = ast_read_stream ( mock_channel ) ;
ast_test_validate_cleanup ( test , fr , res , done ) ;
ast_test_validate_cleanup ( test , fr - > frametype = = AST_FRAME_CONTROL , res , done ) ;
ast_test_validate_cleanup ( test , fr - > subclass . integer = = AST_CONTROL_STREAM_TOPOLOGY_REQUEST_CHANGE , res , done ) ;
ast_test_validate_cleanup ( test , ! pvt - > indicated_changed , res , done ) ;
done :
if ( fr ) {
ast_frfree ( fr ) ;
}
ast_hangup ( mock_channel ) ;
return res ;
}
2017-02-07 12:56:41 +00:00
static int unload_module ( void )
{
AST_TEST_UNREGISTER ( stream_create ) ;
AST_TEST_UNREGISTER ( stream_create_no_name ) ;
AST_TEST_UNREGISTER ( stream_set_type ) ;
AST_TEST_UNREGISTER ( stream_set_formats ) ;
AST_TEST_UNREGISTER ( stream_set_state ) ;
2017-02-13 17:00:42 +00:00
AST_TEST_UNREGISTER ( stream_topology_create ) ;
AST_TEST_UNREGISTER ( stream_topology_clone ) ;
AST_TEST_UNREGISTER ( stream_topology_clone ) ;
AST_TEST_UNREGISTER ( stream_topology_append_stream ) ;
AST_TEST_UNREGISTER ( stream_topology_set_stream ) ;
AST_TEST_UNREGISTER ( stream_topology_create_from_format_cap ) ;
2017-02-14 18:33:57 +00:00
AST_TEST_UNREGISTER ( stream_topology_get_first_stream_by_type ) ;
AST_TEST_UNREGISTER ( stream_topology_create_from_channel_nativeformats ) ;
AST_TEST_UNREGISTER ( stream_topology_channel_set ) ;
2017-02-22 11:00:57 +00:00
AST_TEST_UNREGISTER ( stream_write_non_multistream ) ;
AST_TEST_UNREGISTER ( stream_write_multistream ) ;
2017-02-24 21:30:33 +00:00
AST_TEST_UNREGISTER ( stream_read_non_multistream ) ;
AST_TEST_UNREGISTER ( stream_read_multistream ) ;
2017-03-07 11:22:18 +00:00
AST_TEST_UNREGISTER ( stream_topology_change_request_from_application_non_multistream ) ;
AST_TEST_UNREGISTER ( stream_topology_change_request_from_channel_non_multistream ) ;
AST_TEST_UNREGISTER ( stream_topology_change_request_from_application ) ;
AST_TEST_UNREGISTER ( stream_topology_change_request_from_channel ) ;
2017-02-07 12:56:41 +00:00
return 0 ;
}
static int load_module ( void )
{
AST_TEST_REGISTER ( stream_create ) ;
AST_TEST_REGISTER ( stream_create_no_name ) ;
AST_TEST_REGISTER ( stream_set_type ) ;
AST_TEST_REGISTER ( stream_set_formats ) ;
AST_TEST_REGISTER ( stream_set_state ) ;
2017-02-13 17:00:42 +00:00
AST_TEST_REGISTER ( stream_topology_create ) ;
AST_TEST_REGISTER ( stream_topology_clone ) ;
AST_TEST_REGISTER ( stream_topology_append_stream ) ;
AST_TEST_REGISTER ( stream_topology_set_stream ) ;
AST_TEST_REGISTER ( stream_topology_create_from_format_cap ) ;
2017-02-14 18:33:57 +00:00
AST_TEST_REGISTER ( stream_topology_get_first_stream_by_type ) ;
AST_TEST_REGISTER ( stream_topology_create_from_channel_nativeformats ) ;
AST_TEST_REGISTER ( stream_topology_channel_set ) ;
2017-02-22 11:00:57 +00:00
AST_TEST_REGISTER ( stream_write_non_multistream ) ;
AST_TEST_REGISTER ( stream_write_multistream ) ;
2017-02-24 21:30:33 +00:00
AST_TEST_REGISTER ( stream_read_non_multistream ) ;
AST_TEST_REGISTER ( stream_read_multistream ) ;
2017-03-07 11:22:18 +00:00
AST_TEST_REGISTER ( stream_topology_change_request_from_application_non_multistream ) ;
AST_TEST_REGISTER ( stream_topology_change_request_from_channel_non_multistream ) ;
AST_TEST_REGISTER ( stream_topology_change_request_from_application ) ;
AST_TEST_REGISTER ( stream_topology_change_request_from_channel ) ;
2017-02-07 12:56:41 +00:00
return AST_MODULE_LOAD_SUCCESS ;
}
AST_MODULE_INFO_STANDARD ( ASTERISK_GPL_KEY , " Media Stream API test module " ) ;