summaryrefslogtreecommitdiff
path: root/tests/test_stream.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_stream.c')
-rw-r--r--tests/test_stream.c419
1 files changed, 419 insertions, 0 deletions
diff --git a/tests/test_stream.c b/tests/test_stream.c
index 5134cfb50..d602d52fe 100644
--- a/tests/test_stream.c
+++ b/tests/test_stream.c
@@ -853,6 +853,421 @@ AST_TEST_DEFINE(stream_topology_channel_set)
return res;
}
+struct mock_channel_pvt {
+ unsigned int wrote;
+ unsigned int wrote_stream;
+ int stream_num;
+};
+
+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;
+}
+
+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;
+}
+
+static int mock_channel_hangup(struct ast_channel *chan)
+{
+ 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;
+ struct mock_channel_pvt pvt;
+ 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 = {
+ .properties = AST_CHAN_TP_MULTISTREAM,
+ .write = mock_channel_write,
+ .write_video = mock_channel_write,
+ .write_stream = mock_channel_write_stream,
+ .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;
+}
+
static int unload_module(void)
{
AST_TEST_UNREGISTER(stream_create);
@@ -869,6 +1284,8 @@ static int unload_module(void)
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);
+ AST_TEST_UNREGISTER(stream_write_non_multistream);
+ AST_TEST_UNREGISTER(stream_write_multistream);
return 0;
}
@@ -887,6 +1304,8 @@ static int load_module(void)
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);
+ AST_TEST_REGISTER(stream_write_non_multistream);
+ AST_TEST_REGISTER(stream_write_multistream);
return AST_MODULE_LOAD_SUCCESS;
}