From e10a8eed6419901b6adec5001d993aa9994fbf83 Mon Sep 17 00:00:00 2001 From: aviau <alexandre@alexandreviau.net> Date: Fri, 8 Apr 2016 11:10:12 -0400 Subject: [PATCH] Removed unused test files Change-Id: Ie7520115bdac4a4b26963872d3d64a61a8f0d32c Tuleap: #350 --- Makefile.am | 14 - configure.ac | 1 - test/.gitignore | 4 - test/Makefile.am | 65 --- test/accounttest.cpp | 51 -- test/accounttest.h | 43 -- test/audiobuffertest.cpp | 94 ---- test/audiobuffertest.h | 62 --- test/audiocodectest.cpp | 122 ----- test/audiocodectest.h | 67 --- test/audiolayertest.cpp | 98 ---- test/audiolayertest.h | 73 --- test/configurationtest.cpp | 46 -- test/configurationtest.h | 60 --- test/constants.h | 33 -- test/dring-sample.yml | 199 -------- test/history-sample.tpl | 30 -- test/historytest.cpp | 96 ---- test/historytest.h | 93 ---- test/hooktest.cpp | 36 -- test/hooktest.h | 46 -- test/instantmessagingtest.cpp | 284 ----------- test/instantmessagingtest.h | 66 --- test/iptest.cpp | 83 ---- test/iptest.h | 59 --- test/main.cpp | 145 ------ test/numbercleanertest.cpp | 122 ----- test/numbercleanertest.h | 80 --- test/resamplertest.cpp | 229 --------- test/resamplertest.h | 142 ------ test/ringbufferpooltest.cpp | 213 -------- test/ringbufferpooltest.h | 80 --- test/run_tests.sh | 4 - test/scripts/presence_test.py | 219 --------- test/scripts/stress_test.py | 421 ---------------- test/sdesnegotiatortest.cpp | 226 --------- test/sdesnegotiatortest.h | 101 ---- test/sdptest.cpp | 297 ----------- test/sdptest.h | 126 ----- test/sippxml/test_1.xml | 157 ------ test/sippxml/test_2.xml | 161 ------ test/sippxml/test_3.xml | 187 ------- test/sippxml/test_4.xml | 122 ----- test/siptest.cpp | 431 ---------------- test/siptest.h | 94 ---- test/test_utils.h | 28 -- test/tlsSample/ca.crt | 22 - test/tlsSample/cert.crt | 23 - test/tlsSample/certwithkey.pem | 35 -- test/tlsSample/corruptedkey.pem | 29 -- test/tlsSample/expired.crt | 19 - test/tlsSample/fake.crt | Bin 4546 -> 0 bytes test/tlsSample/keyonly.pem | 32 -- test/tlstest.cpp | 82 ---- test/tlstest.h | 60 --- test/waveSample/M1F1-int16WE-AFsp.wav | Bin 47134 -> 0 bytes tools/sippxml/account_uac_send_hangup.xml | 147 ------ .../sippxml/account_uac_send_peer_hungup.xml | 155 ------ .../sippxml/account_uas_receive_transfer.xml | 101 ---- tools/sippxml/account_uas_recv_hangup.xml | 119 ----- .../sippxml/account_uas_recv_peer_hungup.xml | 127 ----- tools/sippxml/account_uas_recv_transfered.xml | 132 ----- tools/sippxml/account_uas_register.xml | 63 --- tools/sippxml/accountcalluac.xml | 186 ------- tools/sippxml/accountcalluas.xml | 159 ------ tools/sippxml/g711a.pcap | Bin 73184 -> 0 bytes tools/sippxml/ip2ip_uac_send_hangup.xml | 98 ---- tools/sippxml/ip2ip_uac_send_peer_hungup.xml | 92 ---- tools/sippxml/ip2ip_uas_recv_hangup.xml | 87 ---- tools/sippxml/ip2ip_uas_recv_hold_offhold.xml | 187 ------- tools/sippxml/ip2ip_uas_recv_peer_hungup.xml | 78 --- tools/sippxml/ip2ipcalluac.xml | 85 ---- tools/sippxml/ip2ipcalluas.xml | 80 --- tools/sippxml/simpleServiceRoute.xml | 85 ---- tools/sippxml/sippusage.txt | 460 ------------------ tools/sippxml/tempscript.sh | 5 - tools/sippxml/testEarlyMedia.xml | 107 ---- tools/sippxml/testsuiteuac.sh | 383 --------------- tools/sippxml/uac_register_diff_contact.xml | 55 --- tools/sippxml/uac_register_no_cvs_300.xml | 110 ----- tools/sippxml/uac_register_no_cvs_400.xml | 110 ----- tools/sippxml/uas_register_diff_contact.xml | 55 --- tools/sippxml/voice | Bin 252 -> 0 bytes 83 files changed, 8978 deletions(-) delete mode 100644 test/.gitignore delete mode 100644 test/Makefile.am delete mode 100644 test/accounttest.cpp delete mode 100644 test/accounttest.h delete mode 100644 test/audiobuffertest.cpp delete mode 100644 test/audiobuffertest.h delete mode 100644 test/audiocodectest.cpp delete mode 100644 test/audiocodectest.h delete mode 100644 test/audiolayertest.cpp delete mode 100644 test/audiolayertest.h delete mode 100644 test/configurationtest.cpp delete mode 100644 test/configurationtest.h delete mode 100644 test/constants.h delete mode 100644 test/dring-sample.yml delete mode 100644 test/history-sample.tpl delete mode 100644 test/historytest.cpp delete mode 100644 test/historytest.h delete mode 100644 test/hooktest.cpp delete mode 100644 test/hooktest.h delete mode 100644 test/instantmessagingtest.cpp delete mode 100644 test/instantmessagingtest.h delete mode 100644 test/iptest.cpp delete mode 100644 test/iptest.h delete mode 100644 test/main.cpp delete mode 100644 test/numbercleanertest.cpp delete mode 100644 test/numbercleanertest.h delete mode 100644 test/resamplertest.cpp delete mode 100644 test/resamplertest.h delete mode 100644 test/ringbufferpooltest.cpp delete mode 100644 test/ringbufferpooltest.h delete mode 100755 test/run_tests.sh delete mode 100755 test/scripts/presence_test.py delete mode 100755 test/scripts/stress_test.py delete mode 100644 test/sdesnegotiatortest.cpp delete mode 100644 test/sdesnegotiatortest.h delete mode 100644 test/sdptest.cpp delete mode 100644 test/sdptest.h delete mode 100644 test/sippxml/test_1.xml delete mode 100644 test/sippxml/test_2.xml delete mode 100644 test/sippxml/test_3.xml delete mode 100644 test/sippxml/test_4.xml delete mode 100644 test/siptest.cpp delete mode 100644 test/siptest.h delete mode 100644 test/test_utils.h delete mode 100644 test/tlsSample/ca.crt delete mode 100644 test/tlsSample/cert.crt delete mode 100644 test/tlsSample/certwithkey.pem delete mode 100644 test/tlsSample/corruptedkey.pem delete mode 100644 test/tlsSample/expired.crt delete mode 100644 test/tlsSample/fake.crt delete mode 100644 test/tlsSample/keyonly.pem delete mode 100644 test/tlstest.cpp delete mode 100644 test/tlstest.h delete mode 100644 test/waveSample/M1F1-int16WE-AFsp.wav delete mode 100644 tools/sippxml/account_uac_send_hangup.xml delete mode 100644 tools/sippxml/account_uac_send_peer_hungup.xml delete mode 100644 tools/sippxml/account_uas_receive_transfer.xml delete mode 100644 tools/sippxml/account_uas_recv_hangup.xml delete mode 100644 tools/sippxml/account_uas_recv_peer_hungup.xml delete mode 100644 tools/sippxml/account_uas_recv_transfered.xml delete mode 100644 tools/sippxml/account_uas_register.xml delete mode 100644 tools/sippxml/accountcalluac.xml delete mode 100644 tools/sippxml/accountcalluas.xml delete mode 100644 tools/sippxml/g711a.pcap delete mode 100644 tools/sippxml/ip2ip_uac_send_hangup.xml delete mode 100644 tools/sippxml/ip2ip_uac_send_peer_hungup.xml delete mode 100644 tools/sippxml/ip2ip_uas_recv_hangup.xml delete mode 100644 tools/sippxml/ip2ip_uas_recv_hold_offhold.xml delete mode 100644 tools/sippxml/ip2ip_uas_recv_peer_hungup.xml delete mode 100644 tools/sippxml/ip2ipcalluac.xml delete mode 100644 tools/sippxml/ip2ipcalluas.xml delete mode 100644 tools/sippxml/simpleServiceRoute.xml delete mode 100644 tools/sippxml/sippusage.txt delete mode 100644 tools/sippxml/tempscript.sh delete mode 100644 tools/sippxml/testEarlyMedia.xml delete mode 100644 tools/sippxml/testsuiteuac.sh delete mode 100644 tools/sippxml/uac_register_diff_contact.xml delete mode 100644 tools/sippxml/uac_register_no_cvs_300.xml delete mode 100644 tools/sippxml/uac_register_no_cvs_400.xml delete mode 100644 tools/sippxml/uas_register_diff_contact.xml delete mode 100644 tools/sippxml/voice diff --git a/Makefile.am b/Makefile.am index aed0bdd4a3..11fccbf362 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,20 +4,6 @@ include globals.mak SOURCES= -if BUILD_TEST -TESTS_DIR=test -unittest: - @(cd test; make) - @echo "" - @echo "NOTICE: Unitary tests successfully build" - @echo "Go in the test directory to run them" - @echo "" -else -unittest: - @echo "Ring WARNING:" - @echo " -- You need the cppunit devel package to compile the unitary tests." -endif - ACLOCAL_AMFLAGS = -I m4 SUBDIRS = src ringtones man $(TESTS_DIR) doc bin diff --git a/configure.ac b/configure.ac index 951db4bdef..e85cbd6f3d 100644 --- a/configure.ac +++ b/configure.ac @@ -638,7 +638,6 @@ AC_CONFIG_FILES([Makefile \ src/media/video/test/Makefile \ src/security/Makefile \ src/upnp/Makefile \ - test/Makefile \ ringtones/Makefile \ man/Makefile \ doc/Makefile \ diff --git a/test/.gitignore b/test/.gitignore deleted file mode 100644 index e600a6bd4d..0000000000 --- a/test/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -test -cppunitresults.xml -im:testfile1.txt -im:testfile2.txt diff --git a/test/Makefile.am b/test/Makefile.am deleted file mode 100644 index 3ccfc38bc6..0000000000 --- a/test/Makefile.am +++ /dev/null @@ -1,65 +0,0 @@ -include ../globals.mak - -TESTS_ENVIRONMENT = CODECS_PATH="$(top_builddir)/src/audio/codecs" -check_PROGRAMS = test - -TESTS = run_tests.sh - -test_CXXFLAGS = -DWORKSPACE=\"$(top_srcdir)/test/\" @PTHREAD_CFLAGS@ -test_LDADD = $(top_builddir)/src/libring.la \ - $(top_builddir)/src/libring_la-logger.lo \ - @CPPUNIT_LIBS@ @YAMLCPP_LIBS@ @PJPROJECT_LIBS@ - -if BUILD_INSTANT_MESSAGING -test_LDADD += @EXPAT_LIBS@ -endif - -EXTRA_DIST = dring-sample.yml history-sample.tpl tlsSample run_tests.sh -test_SOURCES = constants.h \ - test_utils.h \ - main.cpp \ - accounttest.h \ - accounttest.cpp \ - audiocodectest.h \ - audiocodectest.cpp \ - audiolayertest.h \ - audiolayertest.cpp \ - configurationtest.h \ - configurationtest.cpp \ - historytest.h \ - historytest.cpp \ - numbercleanertest.h \ - numbercleanertest.cpp \ - siptest.h \ - siptest.cpp \ - sdptest.h \ - sdptest.cpp \ - ringbufferpooltest.h \ - ringbufferpooltest.cpp \ - resamplertest.h \ - resamplertest.cpp \ - hooktest.h \ - hooktest.cpp \ - audiobuffertest.h \ - audiobuffertest.cpp \ - iptest.h \ - iptest.cpp - -if BUILD_SDES -test_SOURCES+=sdesnegotiatortest.h \ - sdesnegotiatortest.cpp -endif - -if BUILD_INSTANT_MESSAGING -test_SOURCES+=instantmessagingtest.h \ - instantmessagingtest.cpp -endif - -if BUILD_TLS -test_SOURCES+=tlstest.h \ - tlstest.cpp -endif - -clean-local: - rm -rf cppunitresults.xml im:testfile1.txt im:testfile2.txt \ - sample_echocancel_500ms_8kHz_16bit.raw diff --git a/test/accounttest.cpp b/test/accounttest.cpp deleted file mode 100644 index 06c2096580..0000000000 --- a/test/accounttest.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Julien Bonjean <julien.bonjean@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <cppunit/extensions/HelperMacros.h> -#include <map> - -#include "account.h" -#include "account_schema.h" -#include "accounttest.h" -#include "manager.h" -#include "configurationmanager_interface.h" -#include "logger.h" - -namespace ring { namespace test { - -void AccountTest::TestAddRemove() -{ - RING_DBG("-------------------- %s --------------------\n", __PRETTY_FUNCTION__); - - auto details = DRing::getAccountTemplate(); - details[Conf::CONFIG_ACCOUNT_TYPE] = "SIP"; - details[Conf::CONFIG_ACCOUNT_ENABLE] = "false"; - details[Conf::CONFIG_LOCAL_INTERFACE] = "default"; - details[Conf::CONFIG_LOCAL_PORT] = "5060"; - - auto accountId = Manager::instance().addAccount(details); - CPPUNIT_ASSERT(not accountId.empty()); - CPPUNIT_ASSERT(Manager::instance().hasAccount(accountId)); - - Manager::instance().removeAccount(accountId); - CPPUNIT_ASSERT(!Manager::instance().hasAccount(accountId)); -} - -}} // namespace ring::test diff --git a/test/accounttest.h b/test/accounttest.h deleted file mode 100644 index fe6de3ffd0..0000000000 --- a/test/accounttest.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Julien Bonjean <julien.bonjean@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef ACCOUNTTEST_H_ -#define ACCOUNTTEST_H_ - -#include <cppunit/TestFixture.h> -#include <cppunit/extensions/HelperMacros.h> - -namespace ring { namespace test { - -class AccountTest : public CppUnit::TestFixture { - - CPPUNIT_TEST_SUITE(AccountTest); - CPPUNIT_TEST(TestAddRemove); - CPPUNIT_TEST_SUITE_END(); - - public: - void TestAddRemove(); -}; -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(AccountTest, "AccountTest"); -CPPUNIT_TEST_SUITE_REGISTRATION(AccountTest); - -}} // namespace ring::test - -#endif /* ACCOUNTTEST_H_ */ diff --git a/test/audiobuffertest.cpp b/test/audiobuffertest.cpp deleted file mode 100644 index d8ba8dcd08..0000000000 --- a/test/audiobuffertest.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Adrien Beraud <adrienberaud@gmail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <string> -#include "audiobuffertest.h" -#include "audio/audiobuffer.h" -#include "logger.h" -#include "test_utils.h" - -namespace ring { namespace test { - -void AudioBufferTest::testAudioBufferConstructors() -{ - TITLE(); - - ring::AudioSample test_samples2[] = {10, 11, 12, 13, 14, 15, 16, 17}; - - AudioBuffer empty_buf(0, AudioFormat::MONO()); - CPPUNIT_ASSERT(empty_buf.frames() == 0); - CPPUNIT_ASSERT(empty_buf.channels() == 1); - CPPUNIT_ASSERT(empty_buf.getChannel(0)->size() == 0); - - AudioBuffer test_buf1(8, AudioFormat::STEREO()); - CPPUNIT_ASSERT(test_buf1.frames() == 8); - CPPUNIT_ASSERT(test_buf1.channels() == 2); - CPPUNIT_ASSERT(test_buf1.getChannel(0)->size() == 8); - CPPUNIT_ASSERT(test_buf1.getChannel(1)->size() == 8); - CPPUNIT_ASSERT(test_buf1.getChannel(2) == NULL); - - AudioBuffer test_buf3(test_samples2, 4, AudioFormat::STEREO()); - CPPUNIT_ASSERT(test_buf3.frames() == 4); - CPPUNIT_ASSERT(test_buf3.channels() == 2); - CPPUNIT_ASSERT(test_buf3.getChannel(0)->size() == 4); -} - -void AudioBufferTest::testAudioBufferMix() -{ - TITLE(); - - ring::AudioSample test_samples1[] = {18, 19, 20, 21, 22, 23, 24, 25}; - ring::AudioSample test_samples2[] = {10, 11, 12, 13, 14, 15, 16, 17, 18}; - - AudioBuffer test_buf1(test_samples1, 4, AudioFormat::STEREO()); - CPPUNIT_ASSERT(test_buf1.channels() == 2); - test_buf1.setChannelNum(1); - CPPUNIT_ASSERT(test_buf1.channels() == 1); - test_buf1.setChannelNum(2); - CPPUNIT_ASSERT(test_buf1.channels() == 2); - CPPUNIT_ASSERT(test_buf1.getChannel(1)->size() == 4); - CPPUNIT_ASSERT((*test_buf1.getChannel(1))[0] == 0); - test_buf1.setChannelNum(1); - test_buf1.setChannelNum(2, true); - CPPUNIT_ASSERT((*test_buf1.getChannel(1))[0] == test_samples1[0]); - - AudioBuffer test_buf2(0, AudioFormat::MONO()); - test_buf2.deinterleave(test_samples2, 3, 3); - CPPUNIT_ASSERT((*test_buf2.getChannel(0))[2] == test_samples2[6]); - CPPUNIT_ASSERT((*test_buf2.getChannel(1))[1] == test_samples2[4]); - CPPUNIT_ASSERT((*test_buf2.getChannel(2))[0] == test_samples2[2]); - CPPUNIT_ASSERT(test_buf2.capacity() == 9); - - ring::AudioSample *output = new ring::AudioSample[test_buf2.capacity()]; - test_buf2.interleave(output); - CPPUNIT_ASSERT(std::equal(test_samples2, test_samples2 + sizeof test_samples2 / sizeof *test_samples2, output)); - //CPPUNIT_ASSERT(std::equal(std::begin(test_samples2), std::end(test_samples2), std::begin(output))); C++11 - - test_buf1.mix(test_buf2); - CPPUNIT_ASSERT(test_buf1.channels() == 2); - CPPUNIT_ASSERT(test_buf1.frames() == 4); - CPPUNIT_ASSERT((*test_buf1.getChannel(0))[0] == test_samples1[0]+test_samples2[0]); - CPPUNIT_ASSERT((*test_buf1.getChannel(1))[0] == test_samples1[0]+test_samples2[1]); -} - - -AudioBufferTest::AudioBufferTest() : CppUnit::TestCase("Audio Buffer Tests") {} - -}} // namespace ring::test diff --git a/test/audiobuffertest.h b/test/audiobuffertest.h deleted file mode 100644 index 5661d2f923..0000000000 --- a/test/audiobuffertest.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Adrien Beraud <adrienberaud@gmail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef AUDIOBUFFER_TEST_ -#define AUDIOBUFFER_TEST_ - -// Cppunit import -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/TestCaller.h> -#include <cppunit/TestCase.h> -#include <cppunit/TestSuite.h> - -/* - * @file audiobuffertest.cpp - * @brief Regroups unit tests related to an audio buffer. - */ - -namespace ring { namespace test { - -class AudioBufferTest : public CppUnit::TestCase { - - /* - * Use cppunit library macros to add unit test the factory - */ - CPPUNIT_TEST_SUITE(AudioBufferTest); - CPPUNIT_TEST(testAudioBufferConstructors); - CPPUNIT_TEST(testAudioBufferMix); - CPPUNIT_TEST_SUITE_END(); - - public: - - AudioBufferTest(); - - void testAudioBufferConstructors(); - - void testAudioBufferMix(); -}; - -/* Register our test module */ -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(AudioBufferTest, "AudioBufferTest"); -CPPUNIT_TEST_SUITE_REGISTRATION(AudioBufferTest); - -}} // namespace ring::test - -#endif // AUDIOBUFFER_TEST_ diff --git a/test/audiocodectest.cpp b/test/audiocodectest.cpp deleted file mode 100644 index 9fbfa79061..0000000000 --- a/test/audiocodectest.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -/* - * ebail - 2015/02/18 - * testCodecs unit test is based on audiocodecfactory - * we are not using it anymore - * we should make this unit test work with libav - * this test is disabled for the moment - * */ -#if 0 - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "audiocodectest.h" -#include "audio/codecs/audiocodecfactory.h" -#include "plugin_manager.h" - -#include "test_utils.h" -#include "ring_types.h" // for AudioSample - -#include <cmath> -#include <climits> - -namespace ring { namespace test { - - -/* - * Detect the power of a signal for a given frequency. - * Adapted from: - * http://netwerkt.wordpress.com/2011/08/25/goertzel-filter/ - */ -static double -goertzelFilter(AudioSample *samples, double freq, unsigned N, double sample_rate) -{ - double s_prev = 0.0; - double s_prev2 = 0.0; - const double normalizedfreq = freq / sample_rate; - double coeff = 2 * cos(M_2_PI * normalizedfreq); - for (unsigned i = 0; i < N; i++) { - double s = samples[i] + coeff * s_prev - s_prev2; - s_prev2 = s_prev; - s_prev = s; - } - - return s_prev2 * s_prev2 + s_prev * s_prev - coeff * s_prev * s_prev2; -} - -void AudioCodecTest::testCodecs() -{ - TITLE(); - - PluginManager pluginMgr; - AudioCodecFactory factory(pluginMgr); - const auto payloadTypes = factory.getCodecList(); - - std::vector<std::shared_ptr<AudioCodec>> codecs; - - for (auto p : payloadTypes) - codecs.push_back(factory.getCodec(p)); - - std::vector<std::vector<AudioSample>> sine = {}; - std::vector<std::vector<AudioSample>> pcm; - - unsigned sampleRate = 0; - double referencePower = 0.0; - - for (auto c : codecs) { - - // generate the sine tone if rate has changed - if (sampleRate != c->getCurrentClockRate()) { - sampleRate = c->getCurrentClockRate(); - const unsigned nbSamples = sampleRate * 0.02; // 20 ms worth of samples - sine = {std::vector<AudioSample>(nbSamples)}; - pcm = {std::vector<AudioSample>(nbSamples)}; - - const float theta = M_2_PI * frequency_ / sampleRate; - - for (unsigned i = 0; i < nbSamples; ++i) { - sine[0][i] = SHRT_MAX * sin(theta * i); - sine[0][i] >>= 3; /* attenuate it a bit */ - } - - /* Store the raw signal's power detected at 440 Hz, this is much cheaper - * than an FFT */ - referencePower = goertzelFilter(sine[0].data(), frequency_, sine[0].size(), sampleRate); - } - - std::vector<uint8_t> data(RAW_BUFFER_SIZE); - - const size_t encodedBytes = c->encode(sine, data.data(), sine[0].size()); - - unsigned decoded = c->decode(pcm, data.data(), encodedBytes); - CPPUNIT_ASSERT(decoded == sine[0].size()); - - const auto decodedPower = goertzelFilter(pcm[0].data(), frequency_, pcm[0].size(), sampleRate); - const auto decodedRatio = decodedPower / referencePower; - CPPUNIT_ASSERT(decodedRatio > 0.0); - } -} - -}} // namespace ring::test -#endif diff --git a/test/audiocodectest.h b/test/audiocodectest.h deleted file mode 100644 index 9baae40b5a..0000000000 --- a/test/audiocodectest.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -/* - * @file audiocodectest.h - * @brief For every available audio codec, encode a buffer, decode it, - * and analyze the signal to ensure that it's similar to what was - * encoded. - */ - -#ifndef AUDIO_CODEC_TEST_ -#define AUDIO_CODEC_TEST_ - -// Cppunit import -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/TestCaller.h> -#include <cppunit/TestCase.h> -#include <cppunit/TestSuite.h> - -namespace ring { namespace test { - -class AudioCodecTest: public CppUnit::TestFixture { - - /* - * Use cppunit library macros to add unit test the factory - */ - CPPUNIT_TEST_SUITE(AudioCodecTest); - /* - * ebail - 2015/02/18 - * testCodecs unit test is based on audiocodecfactory - * we are not using it anymore - * we should make this unit test work with libav - * this test is disabled for the moment - * */ - //CPPUNIT_TEST(testCodecs); - CPPUNIT_TEST_SUITE_END(); - - static const short frequency_ = 440; - - public: - void testCodecs(); -}; - -/* Register our test module */ -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(AudioCodecTest, "AudioCodecTest"); -CPPUNIT_TEST_SUITE_REGISTRATION(AudioCodecTest); - -}} // namespace ring::test - -#endif // AUDIO_CODEC_TEST_ diff --git a/test/audiolayertest.cpp b/test/audiolayertest.cpp deleted file mode 100644 index eac4a97f9d..0000000000 --- a/test/audiolayertest.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "audiolayertest.h" - -#include "logger.h" -#include "manager.h" -#include "audio/alsa/alsalayer.h" -#include "audio/pulseaudio/pulselayer.h" -#include "test_utils.h" -#include <unistd.h> - -namespace ring { namespace test { - -AudioLayerTest::AudioLayerTest() : manager_(0), pulselayer_(0), layer_(0) -{} - -void AudioLayerTest::testAudioLayerConfig() -{ - TITLE(); - - CPPUNIT_ASSERT(Manager::instance().audioPreference.getAlsaSmplrate() == 44100); - - // alsa preferences - CPPUNIT_ASSERT(Manager::instance().audioPreference.getAlsaCardin() == 0); - CPPUNIT_ASSERT(Manager::instance().audioPreference.getAlsaCardout() == 0); - CPPUNIT_ASSERT(Manager::instance().audioPreference.getAlsaCardring() == 0); - CPPUNIT_ASSERT(Manager::instance().audioPreference.getAlsaPlugin() == "default"); - - // pulseaudio preferences - CPPUNIT_ASSERT(Manager::instance().audioPreference.getPulseDevicePlayback() == "alsa_output.pci-0000_00_1b.0.analog-stereo"); - CPPUNIT_ASSERT(Manager::instance().audioPreference.getPulseDeviceRecord() == "alsa_input.pci-0000_00_1b.0.analog-stereo"); - CPPUNIT_ASSERT(Manager::instance().audioPreference.getPulseDeviceRingtone() == "alsa_output.pci-0000_00_1b.0.analog-stereo"); - - CPPUNIT_ASSERT(Manager::instance().audioPreference.getVolumemic() == 1.0); - CPPUNIT_ASSERT(Manager::instance().audioPreference.getVolumespkr() == 1.0); - - // TODO: Fix tests - //CPPUNIT_ASSERT ( (int) Manager::instance().getAudioDriver()->getSampleRate() == sampling_rate); -} - -void AudioLayerTest::testAudioLayerSwitch() -{ - TITLE(); - - bool wasAlsa = dynamic_cast<AlsaLayer*>(Manager::instance().getAudioDriver().get()) != 0; - - for (int i = 0; i < 2; i++) { - RING_DBG("iter - %i", i); - if (wasAlsa) - Manager::instance().setAudioManager(PULSEAUDIO_API_STR); - else - Manager::instance().setAudioManager(ALSA_API_STR); - - if (wasAlsa) - CPPUNIT_ASSERT(dynamic_cast<PulseLayer*>(Manager::instance().getAudioDriver().get())); - else - CPPUNIT_ASSERT(dynamic_cast<AlsaLayer*>(Manager::instance().getAudioDriver().get())); - - wasAlsa = dynamic_cast<AlsaLayer*>(Manager::instance().getAudioDriver().get()) != 0; - const struct timespec req = {0, 100000000}; - nanosleep(&req, 0); - } -} - -void AudioLayerTest::testPulseConnect() -{ - TITLE(); - - if (dynamic_cast<AlsaLayer*>(Manager::instance().getAudioDriver().get())) { - Manager::instance().setAudioManager(PULSEAUDIO_API_STR); - const struct timespec req = {0, 100000000}; - nanosleep(&req, 0); - } - - pulselayer_ = dynamic_cast<PulseLayer*>(Manager::instance().getAudioDriver().get()); - - CPPUNIT_ASSERT(pulselayer_); -} - -}} // namespace ring::test diff --git a/test/audiolayertest.h b/test/audiolayertest.h deleted file mode 100644 index 9fff17549b..0000000000 --- a/test/audiolayertest.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -/* - * @file audiorecorderTest.cpp - * @brief Regroups unitary tests related to the plugin manager. - */ - -#ifndef AUDIOLAYER_TEST_ -#define AUDIOLAYER_TEST_ - -// Cppunit import -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/TestCaller.h> -#include <cppunit/TestCase.h> -#include <cppunit/TestSuite.h> - -#include "noncopyable.h" - -namespace ring { - -class Manager; -class PulseLayer; - -} // namespace ring - -namespace ring { namespace test { - -class AudioLayerTest: public CppUnit::TestFixture { - - CPPUNIT_TEST_SUITE(AudioLayerTest); - CPPUNIT_TEST(testAudioLayerConfig); - //CPPUNIT_TEST(testPulseConnect); - //TODO: this test ends the test sequence when using on a alsa only system - //CPPUNIT_TEST(testAudioLayerSwitch); - CPPUNIT_TEST_SUITE_END(); - - public: - AudioLayerTest(); - void testAudioLayerConfig(); - void testPulseConnect(); - void testAudioLayerSwitch(); - - private: - NON_COPYABLE(AudioLayerTest); - - Manager* manager_; - PulseLayer* pulselayer_; - int layer_; -}; -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(AudioLayerTest, "AudioLayerTest"); -CPPUNIT_TEST_SUITE_REGISTRATION(AudioLayerTest); - -}} // namespace ring::test - -#endif // AUDIOLAYER_TEST_ diff --git a/test/configurationtest.cpp b/test/configurationtest.cpp deleted file mode 100644 index b0e4865ea7..0000000000 --- a/test/configurationtest.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "configurationtest.h" -#include "fileutils.h" -#include "config/yamlparser.h" - -namespace ring { namespace test { - -void ConfigurationTest::testNodeParse() -{ - YAML::Node node = YAML::Load("[{a: 0, b: 1, c: 2}, {a: 0, b: 1, c: 2}]"); - auto result = yaml_utils::parseVectorMap(node, {"a", "b", "c"}); - CPPUNIT_ASSERT(result[1]["b"] == "1"); -} - -void ConfigurationTest::test_expand_path(void){ - const std::string pattern_1 = "~"; - const std::string pattern_2 = "~/x"; - const std::string pattern_3 = "~foo/x"; // deliberately broken, - // tilde should not be expanded - std::string home = fileutils::get_home_dir(); - - CPPUNIT_ASSERT(fileutils::expand_path(pattern_1) == home); - CPPUNIT_ASSERT(fileutils::expand_path(pattern_2) == home.append("/x")); - CPPUNIT_ASSERT(fileutils::expand_path(pattern_3) == "~foo/x"); -} - -}} // namespace ring::test diff --git a/test/configurationtest.h b/test/configurationtest.h deleted file mode 100644 index 4d8f117044..0000000000 --- a/test/configurationtest.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -/* - * @file configurationTest.cpp - * @brief Regroups unitary tests related to the user configuration. - * Check if the default configuration has been successfully loaded - */ - -#ifndef CONFIGURATION_TEST_ -#define CONFIGURATION_TEST_ - -// Cppunit import -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/TestCaller.h> -#include <cppunit/TestCase.h> -#include <cppunit/TestSuite.h> - -namespace ring { namespace test { - -class ConfigurationTest: public CppUnit::TestFixture { - - /* - * Use cppunit library macros to add unit test the factory - */ - CPPUNIT_TEST_SUITE(ConfigurationTest); - CPPUNIT_TEST(testNodeParse); - CPPUNIT_TEST(test_expand_path); - CPPUNIT_TEST_SUITE_END(); - - public: - - void testNodeParse(); - void test_expand_path(); -}; - -/* Register our test module */ -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(ConfigurationTest, "ConfigurationTest"); -CPPUNIT_TEST_SUITE_REGISTRATION(ConfigurationTest); - -}} // namespace ring::test - -#endif // CONFIGURATION_TEST_ diff --git a/test/constants.h b/test/constants.h deleted file mode 100644 index 020cad47ae..0000000000 --- a/test/constants.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef CONSTANTS_H_ -#define CONSTANTS_H_ - -#define HISTORY_SAMPLE WORKSPACE "history-sample.tpl" -#define HISTORY_SAMPLE_BAK HISTORY_SAMPLE ".bak" - -#define CONFIG_SAMPLE WORKSPACE "dring-sample.yml" -#define CONFIG_SAMPLE_BAK CONFIG_SAMPLE ".bak" - -#define HISTORY_SAMPLE_SIZE 3 -#define HISTORY_LIMIT 30 - -#endif /* CONSTANTS_H_ */ diff --git a/test/dring-sample.yml b/test/dring-sample.yml deleted file mode 100644 index 67832297bf..0000000000 --- a/test/dring-sample.yml +++ /dev/null @@ -1,199 +0,0 @@ ---- -accounts: -- alias: SFL test - audioCodecs: 0/3/8/9/110/111/112/ - autoAnswer: false - credential: - - Account.password: 1234 - Account.realm: - Account.username: sfltest - displayName: - dtmfType: overrtp - enable: false - hasCustomUserAgent: true - hostname: localhost - id: Account:1334389473 - interface: default - keepAlive: false - mailbox: - port: 5060 - publishAddr: 0.0.0.0 - publishPort: 5060 - registrationexpire: 600 - ringtoneEnabled: true - ringtonePath: /usr/share/ring/ringtones/default.wav - sameasLocal: true - serviceRoute: - srtp: - enable: false - keyExchange: - rtpFallback: false - stunEnabled: false - stunServer: - tls: - calist: - certificate: - ciphers: - enable: false - method: TLSv1 - password: - privateKey: - requireCertif: true - server: - timeout: 2 - tlsPort: 5061 - verifyClient: true - verifyServer: true - type: SIP - useragent: SFLphone-test - username: sfltest - videoCodecs: - - bitrate: 400 - enabled: true - name: H263-2000 - parameters: - - bitrate: 400 - enabled: true - name: H264 - parameters: profile-level-id=428014 - - bitrate: 400 - enabled: true - name: MP4V-ES - parameters: - - bitrate: 400 - enabled: true - name: VP8 - parameters: - videoEnabled: true - videoPortMax: 65534 - videoPortMin: 49152 - zrtp: - displaySas: true - displaySasOnce: false - helloHashEnabled: true - notSuppWarning: true -- alias: IP2IP - audioCodecs: 0/3/8/9/110/111/112/ - autoAnswer: false - credential: - - Account.password: - Account.realm: - Account.username: - displayName: - dtmfType: true - enable: true - hasCustomUserAgent: true - hostname: - id: IP2IP - interface: default - keepAlive: false - mailbox: - port: 5060 - publishAddr: - publishPort: 5060 - registrationexpire: 60 - ringtoneEnabled: true - ringtonePath: /usr/share/ring/ringtones/default.wav - sameasLocal: true - serviceRoute: - srtp: - enable: false - keyExchange: sdes - rtpFallback: false - stunEnabled: false - stunServer: - tls: - calist: - certificate: - ciphers: - enable: false - method: TLSv1 - password: - privateKey: - requireCertif: true - server: - timeout: 2 - tlsPort: 5061 - verifyClient: true - verifyServer: true - type: SIP - useragent: SFLphone-test - username: - videoCodecs: - - bitrate: 400 - enabled: true - name: H263-2000 - parameters: - - bitrate: 400 - enabled: true - name: H264 - parameters: profile-level-id=428014 - - bitrate: 400 - enabled: true - name: MP4V-ES - parameters: - - bitrate: 400 - enabled: true - name: VP8 - parameters: - videoEnabled: true - videoPortMax: 65534 - videoPortMin: 49152 - zrtp: - displaySas: true - displaySasOnce: false - helloHashEnabled: true - notSuppWarning: true -preferences: - historyLimit: 30 - historyMaxCalls: 20 - md5Hash: false - order: Account:1375906657/Account:1328115463/Account:1328115393/Account:1328115062/Account:1316122317/Account:1316122284/Account:1316121900/Account:1316121889/Account:1316121691/Account:1316121662/Account:1316121661/Account:1316121654/Account:1316121611/Account:1316121607/Account:1316121605/Account:1316121602/Account:1312584532/Account:1312398082/Account:1312398066/Account:1309188361/Account:1309187807/Account:1309187723/Account:1309187670/Account:1309187609/Account:1309187081/Account:1308839853/Account:1308839662/Account:1308839447/Account:1308839359/Account:1308839335/Account:1308838875/Account:1308838713/Account:1308838236/Account:1307975440/Account:1307975347/Account:1307974800/Account:1307974672/Account:1307974527/Account:1303487773/Account:1303247743/Account:1302895321/Account:1302892836/Account:1302891834/Account:1302882519/Account:1302207377/Account:1302207262/Account:1302204136/Account:1302204108/Account:1294850905/Account:1294850775/Account:1294850618/Account:1294849651/Account:1294849602/Account:1294849310/Account:1288964768/Account:1288964603/Account:1288964434/Account:1288964141/Account:1288964134/ - portNum: 5060 - registrationexpire: 180 - searchBarDisplay: true - zoneToneChoice: North America -voipPreferences: - playDtmf: true - playTones: true - pulseLength: 250 - symmetric: true - zidFile: true -hooks: - iax2Enabled: false - numberAddPrefix: - numberEnabled: false - sipEnabled: false - urlCommand: x-www-browser - urlSipField: X-sflphone-url -audio: - alsa: - cardIn: 0 - cardOut: 0 - cardRing: 0 - plugin: default - smplRate: 44100 - alwaysRecording: false - audioApi: pulseaudio - echoCancel: false - noiseReduce: true - pulse: - devicePlayback: alsa_output.pci-0000_00_1b.0.analog-stereo - deviceRecord: alsa_input.pci-0000_00_1b.0.analog-stereo - deviceRingtone: alsa_output.pci-0000_00_1b.0.analog-stereo - recordPath: ~ - volumeMic: 1.0 - volumeSpkr: 1.0 -video: - devices: - - channel: Camera 1 - name: Integrated Camera - rate: 30 - size: 640x480 -shortcuts: - hangUp: - pickUp: - popupWindow: - toggleHold: - togglePickupHangup: -... diff --git a/test/history-sample.tpl b/test/history-sample.tpl deleted file mode 100644 index ec7fcdf0dc..0000000000 --- a/test/history-sample.tpl +++ /dev/null @@ -1,30 +0,0 @@ -accountid= -confid= -callid=Account:1239059899 -peer_name=Emmanuel Milou -peer_number=136 -recordfile= -timestamp_start=747638685 -timestamp_stop=747638765 -state=outgoing - -accountid=empty -confid= -callid= -peer_name=Savoir-faire Linux -peer_number=514-276-5468 -recordfile= -timestamp_start=144562000 -timestamp_stop=144562458 -state=missed - -accountid= -confid= -callid=Account:43789459478 -peer_name= -peer_number=5143848557 -recordfile= -timestamp_start=775354456 -timestamp_stop=775354987 -state=incoming - diff --git a/test/historytest.cpp b/test/historytest.cpp deleted file mode 100644 index e388529397..0000000000 --- a/test/historytest.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <cstdlib> - -#include "historytest.h" -#include "history/history.h" -#include "logger.h" -#include "constants.h" - -namespace ring { namespace test { - -namespace { -void restore() -{ - if (system("mv " HISTORY_SAMPLE_BAK " " HISTORY_SAMPLE) < 0) - RING_ERR("Restoration of %s failed", HISTORY_SAMPLE); -} - -void backup() -{ - if (system("cp " HISTORY_SAMPLE " " HISTORY_SAMPLE_BAK) < 0) - RING_ERR("Backup of %s failed", HISTORY_SAMPLE); -} -} - -void HistoryTest::setUp() -{ - backup(); - history_ = new History; - history_->setPath(HISTORY_SAMPLE); -} - - -void HistoryTest::test_create_path() -{ - RING_DBG("-------------------- HistoryTest::test_set_path --------------------\n"); - - std::string path(HISTORY_SAMPLE); - CPPUNIT_ASSERT(history_->path_ == path); -} - -void HistoryTest::test_load_from_file() -{ - RING_DBG("-------------------- HistoryTest::test_load_from_file --------------------\n"); - - bool res = history_->load(HISTORY_LIMIT); - CPPUNIT_ASSERT(res); -} - -void HistoryTest::test_load_items() -{ - RING_DBG("-------------------- HistoryTest::test_load_items --------------------\n"); - bool res = history_->load(HISTORY_LIMIT); - CPPUNIT_ASSERT(res); - CPPUNIT_ASSERT(history_->numberOfItems() == HISTORY_SAMPLE_SIZE); -} - -void HistoryTest::test_save_to_file() -{ - RING_DBG("-------------------- HistoryTest::test_save_to_file --------------------\n"); - CPPUNIT_ASSERT(history_->save()); -} - -void HistoryTest::test_get_serialized() -{ - RING_DBG("-------------------- HistoryTest::test_get_serialized --------------------\n"); - bool res = history_->load(HISTORY_LIMIT); - CPPUNIT_ASSERT(res); - CPPUNIT_ASSERT(history_->getSerialized().size() == HISTORY_SAMPLE_SIZE); -} - -void HistoryTest::tearDown() -{ - delete history_; - restore(); -} - -}} // namespace ring::test diff --git a/test/historytest.h b/test/historytest.h deleted file mode 100644 index 7b270d3caf..0000000000 --- a/test/historytest.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -// Cppunit import -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/TestCaller.h> -#include <cppunit/TestCase.h> -#include <cppunit/TestSuite.h> - -// Application import -#include "noncopyable.h" - -/* - * @file historyTest.h - * @brief Regroups unitary tests related to the phone number cleanup function. - */ - -#ifndef HISTORY_TEST_ -#define HISTORY_TEST_ - -namespace ring { -class History; -} // namespace ring - -namespace ring { namespace test { - -class HistoryTest : public CppUnit::TestCase { - - /** - * Use cppunit library macros to add unit test the factory - */ - CPPUNIT_TEST_SUITE(HistoryTest); - CPPUNIT_TEST(test_create_path); - CPPUNIT_TEST(test_load_from_file); - CPPUNIT_TEST(test_load_items); - CPPUNIT_TEST(test_get_serialized); - CPPUNIT_TEST_SUITE_END(); - - public: - HistoryTest() : CppUnit::TestCase("History Tests"), history_(0) {} - - /* - * Code factoring - Common resources can be initialized here. - * This method is called by unitcpp before each test - */ - void setUp(); - - void test_create_path(); - - void test_load_from_file(); - - void test_load_items(); - - void test_save_to_file(); - - void test_get_serialized(); - - /* - * Code factoring - Common resources can be released here. - * This method is called by unitcpp after each test - */ - void tearDown(); - - private: - NON_COPYABLE(HistoryTest); - ring::History *history_; -}; - -/* Register our test module */ -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(HistoryTest, "HistoryTest"); -CPPUNIT_TEST_SUITE_REGISTRATION(HistoryTest); - - -}} // namespace ring::test - -#endif // HISTORY_TEST_ diff --git a/test/hooktest.cpp b/test/hooktest.cpp deleted file mode 100644 index e57ce63716..0000000000 --- a/test/hooktest.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Julien Bonjean <julien.bonjean@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "hooktest.h" -#include "hooks/urlhook.h" - -namespace ring { namespace test { - -void HookTest::RunHookWithNoArgs() -{ - CPPUNIT_ASSERT(!UrlHook::runAction("ls", "")); -} - -void HookTest::RunHookWithArgs() -{ - CPPUNIT_ASSERT(!UrlHook::runAction("ls", "-l")); -} - -}} // namespace ring::test diff --git a/test/hooktest.h b/test/hooktest.h deleted file mode 100644 index b021c01659..0000000000 --- a/test/hooktest.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2013-2016 Savoir-faire Linux Inc. - * - * Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef HOOKTEST_H_ -#define HOOKTEST_H_ - -#include <cppunit/TestFixture.h> -#include <cppunit/extensions/HelperMacros.h> - -namespace ring { namespace test { - -class HookTest : public CppUnit::TestFixture { - - CPPUNIT_TEST_SUITE(HookTest); - CPPUNIT_TEST(RunHookWithNoArgs); - CPPUNIT_TEST(RunHookWithArgs); - CPPUNIT_TEST_SUITE_END(); - - public: - void RunHookWithNoArgs(); - void RunHookWithArgs(); -}; - -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(HookTest, "HookTest"); -CPPUNIT_TEST_SUITE_REGISTRATION(HookTest); - -}} // namespace ring::test - -#endif /* HOOKTEST_H_ */ diff --git a/test/instantmessagingtest.cpp b/test/instantmessagingtest.cpp deleted file mode 100644 index 3a6158f00b..0000000000 --- a/test/instantmessagingtest.cpp +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <iostream> -#include <fstream> -#include <expat.h> -#include "test_utils.h" - -#include "instantmessagingtest.h" -#include "im/instant_messaging.h" -#include "logger.h" - -#define MAXIMUM_SIZE 10 -#define DELIMITER_CHAR "\n\n" - -namespace ring { namespace InstantMessaging { namespace test { - -void InstantMessagingTest::testSaveSingleMessage() -{ - TITLE(); - std::string callID = "testfile1.txt"; - std::string filename = "im:"; - - // Open a file stream and try to write in it - CPPUNIT_ASSERT(saveMessage("Bonjour, c'est un test d'archivage de message", "Manu", callID, std::ios::out)); - - filename.append(callID); - // Read it to check it has been successfully written - std::ifstream testfile(filename.c_str(), std::ios::in); - CPPUNIT_ASSERT(testfile.is_open()); - - std::string input; - while (!testfile.eof()) { - std::string tmp; - std::getline(testfile, tmp); - input.append(tmp); - } - - testfile.close(); - CPPUNIT_ASSERT(input == "[Manu] Bonjour, c'est un test d'archivage de message"); -} - -void InstantMessagingTest::testSaveMultipleMessage() -{ - TITLE(); - - std::string callID = "testfile2.txt"; - std::string filename = "im:"; - - // Open a file stream and try to write in it - CPPUNIT_ASSERT(saveMessage("Bonjour, c'est un test d'archivage de message", "Manu", callID, std::ios::out)); - CPPUNIT_ASSERT(saveMessage("Cool", "Alex", callID, std::ios::out || std::ios::app)); - - filename.append(callID); - // Read it to check it has been successfully written - std::ifstream testfile(filename.c_str(), std::ios::in); - CPPUNIT_ASSERT(testfile.is_open()); - - std::string input; - while (!testfile.eof()) { - std::string tmp; - std::getline(testfile, tmp); - input.append(tmp); - } - - testfile.close(); - printf("%s\n", input.c_str()); - CPPUNIT_ASSERT(input == "[Manu] Bonjour, c'est un test d'archivage de message[Alex] Cool"); -} - -static inline char* duplicateString(char dst[], const char src[], size_t len) -{ - memcpy(dst, src, len); - dst[len] = 0; - return dst; -} - -static void XMLCALL startElementCallback(void *userData, const char *name, const char **atts) -{ - - std::cout << "startElement " << name << std::endl; - - int *nbEntry = (int *) userData; - - char attribute[50]; - char value[50]; - - for (const char **att = atts; *att; att += 2) { - - const char **val = att+1; - - duplicateString(attribute, *att, strlen(*att)); - std::cout << "att: " << attribute << std::endl; - - duplicateString(value, *val, strlen(*val)); - std::cout << "val: " << value << std::endl; - - if (strcmp(attribute, "uri") == 0) { - if ((strcmp(value, "sip:alex@example.com") == 0) || - (strcmp(value, "sip:manu@example.com") == 0)) - CPPUNIT_ASSERT(true); - else - CPPUNIT_ASSERT(false); - } - } - - *nbEntry += 1; -} - -static void XMLCALL -endElementCallback(void * /*userData*/, const char * /*name*/) -{} - -void InstantMessagingTest::testGenerateXmlUriList() -{ - std::cout << std::endl; - - // Create a test list with two entries - UriList list; - - UriEntry entry1; - entry1[IM_XML_URI] = "\"sip:alex@example.com\""; - - UriEntry entry2; - entry2[IM_XML_URI] = "\"sip:manu@example.com\""; - - list.push_front(entry1); - list.push_front(entry2); - - std::string buffer = generateXmlUriList(list); - CPPUNIT_ASSERT(buffer.size() != 0); - - std::cout << buffer << std::endl; - - // parse the resuling xml (further tests are performed in callbacks) - XML_Parser parser = XML_ParserCreate(NULL); - int nbEntry = 0; - XML_SetUserData(parser, &nbEntry); - XML_SetElementHandler(parser, startElementCallback, endElementCallback); - - if (XML_Parse(parser, buffer.c_str(), buffer.size(), 1) == XML_STATUS_ERROR) { - RING_ERR("%s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser)); - CPPUNIT_ASSERT(false); - } - - XML_ParserFree(parser); - CPPUNIT_ASSERT(nbEntry == 4); -} - -void InstantMessagingTest::testXmlUriListParsing() -{ - std::string xmlbuffer = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; - xmlbuffer.append("<resource-lists xmlns=\"urn:ietf:params:xml:ns:resource-lists\" xmlns:cp=\"urn:ietf:params:xml:ns:copycontrol\">"); - xmlbuffer.append("<list>"); - xmlbuffer.append("<entry uri=\"sip:alex@example.com\" cp:copyControl=\"to\" />"); - xmlbuffer.append("<entry uri=\"sip:manu@example.com\" cp:copyControl=\"to\" />"); - xmlbuffer.append("</list>"); - xmlbuffer.append("</resource-lists>"); - - - UriList list = parseXmlUriList(xmlbuffer); - CPPUNIT_ASSERT(list.size() == 2); - - // An iterator over xml attribute - UriEntry::iterator iterAttr; - - // An iterator over list entries - for (auto &entry : list) { - iterAttr = entry.find(IM_XML_URI); - - CPPUNIT_ASSERT((iterAttr->second == std::string("sip:alex@example.com")) or - (iterAttr->second == std::string("sip:manu@example.com"))); - } -} - -void InstantMessagingTest::testGetTextArea() -{ - - std::string formatedText = "--boundary Content-Type: text/plain"; - formatedText.append("Here is the text area"); - - formatedText.append("--boundary Content-Type: application/resource-lists+xml"); - formatedText.append("Content-Disposition: recipient-list"); - formatedText.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); - formatedText.append("<resource-lists xmlns=\"urn:ietf:params:xml:ns:resource-lists\" xmlns:cp=\"urn:ietf:params:xml:ns:copycontrol\">"); - formatedText.append("<list>"); - formatedText.append("<entry uri=\"sip:alex@example.com\" cp:copyControl=\"to\" />"); - formatedText.append("<entry uri=\"sip:manu@example.com\" cp:copyControl=\"to\" />"); - formatedText.append("</list>"); - formatedText.append("</resource-lists>"); - formatedText.append("--boundary--"); - - std::string message(findTextMessage(formatedText)); - RING_DBG("Message %s", message.c_str()); - - CPPUNIT_ASSERT(message == "Here is the text area"); -} - -void InstantMessagingTest::testGetUriListArea() -{ - std::string formatedText = "--boundary Content-Type: text/plain"; - formatedText.append("Here is the text area"); - - formatedText.append("--boundary Content-Type: application/resource-lists+xml"); - formatedText.append("Content-Disposition: recipient-list"); - formatedText.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); - formatedText.append("<resource-lists xmlns=\"urn:ietf:params:xml:ns:resource-lists\" xmlns:cp=\"urn:ietf:params:xml:ns:copycontrol\">"); - formatedText.append("<list>"); - formatedText.append("<entry uri=\"sip:alex@example.com\" cp:copyControl=\"to\" />"); - formatedText.append("<entry uri=\"sip:manu@example.com\" cp:copyControl=\"to\" />"); - formatedText.append("</list>"); - formatedText.append("</resource-lists>"); - formatedText.append("--boundary--"); - - std::string urilist = findTextUriList(formatedText); - - CPPUNIT_ASSERT(urilist.compare("<?xml version=\"1.0\" encoding=\"UTF-8\"?><resource-lists xmlns=\"urn:ietf:params:xml:ns:resource-lists\" xmlns:cp=\"urn:ietf:params:xml:ns:copycontrol\"><list><entry uri=\"sip:alex@example.com\" cp:copyControl=\"to\" /><entry uri=\"sip:manu@example.com\" cp:copyControl=\"to\" /></list></resource-lists>") == 0); - - std::cout << "urilist: " << urilist << std::endl; - - UriList list = parseXmlUriList(urilist); - CPPUNIT_ASSERT(list.size() == 2); - - // order may be important, for example to identify message sender - UriEntry entry = list.front(); - CPPUNIT_ASSERT(entry.size() == 2); - - UriEntry::iterator iterAttr = entry.find(IM_XML_URI); - - if (iterAttr == entry.end()) { - RING_ERR("Did not find attribute"); - CPPUNIT_ASSERT(false); - } - - std::string from = iterAttr->second; - CPPUNIT_ASSERT(from == "sip:alex@example.com"); -} - -void InstantMessagingTest::testIllFormatedMessage() -{ - bool exceptionCaught = false; - - // SHOULD BE: Content-Type: text/plain - std::string formatedText = "--boundary Content-Ty"; - formatedText.append("Here is the text area"); - - formatedText.append("--boundary Content-Type: application/resource-lists+xml"); - formatedText.append("Content-Disposition: recipient-list"); - formatedText.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); - formatedText.append("<resource-lists xmlns=\"urn:ietf:params:xml:ns:resource-lists\" xmlns:cp=\"urn:ietf:params:xml:ns:copycontrol\">"); - formatedText.append("<list>"); - formatedText.append("<entry uri=\"sip:alex@example.com\" cp:copyControl=\"to\" />"); - formatedText.append("<entry uri=\"sip:manu@example.com\" cp:copyControl=\"to\" />"); - formatedText.append("</list>"); - formatedText.append("</resource-lists>"); - formatedText.append("--boundary--"); - - try { - std::string message = findTextMessage(formatedText); - } catch (const InstantMessageException &e) { - exceptionCaught = true; - } - - CPPUNIT_ASSERT(exceptionCaught); -} - -}}} // namespace ring::InstantMessaging::test diff --git a/test/instantmessagingtest.h b/test/instantmessagingtest.h deleted file mode 100644 index b9a2560176..0000000000 --- a/test/instantmessagingtest.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -// Cppunit import -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/TestCaller.h> -#include <cppunit/TestCase.h> -#include <cppunit/TestSuite.h> - -/* - * @file instantmessagingtest.h - * @brief Unit tests related to the instant messaging module - */ - -#ifndef INSTANTMANAGER_TEST_ -#define INSTANTMANAGER_TEST_ - -namespace ring { namespace InstantMessaging { namespace test { - -class InstantMessagingTest : public CppUnit::TestCase { - CPPUNIT_TEST_SUITE(InstantMessagingTest); - CPPUNIT_TEST(testSaveSingleMessage); - CPPUNIT_TEST(testSaveMultipleMessage); - CPPUNIT_TEST(testGenerateXmlUriList); - CPPUNIT_TEST(testXmlUriListParsing); - CPPUNIT_TEST(testGetTextArea); - CPPUNIT_TEST(testGetUriListArea); - CPPUNIT_TEST(testIllFormatedMessage); - CPPUNIT_TEST_SUITE_END(); - - public: - InstantMessagingTest() : CppUnit::TestCase("Instant messaging module Tests") {} - - void testSaveSingleMessage(); - void testSaveMultipleMessage(); - void testGenerateXmlUriList(); - void testXmlUriListParsing(); - void testGetTextArea(); - void testGetUriListArea(); - void testIllFormatedMessage(); -}; - -/* Register our test module */ -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(InstantMessagingTest, "InstantMessagingTest"); -CPPUNIT_TEST_SUITE_REGISTRATION(InstantMessagingTest); - -}}} // namespace ring::InstantMessaging::test - -#endif diff --git a/test/iptest.cpp b/test/iptest.cpp deleted file mode 100644 index 92c1273bd2..0000000000 --- a/test/iptest.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <string> -#include "iptest.h" -#include "ip_utils.h" -#include "logger.h" -#include "test_utils.h" - -namespace ring { namespace test { - -void IpTest::testIpAddr() -{ - TITLE(); - - IpAddr ip = {"8.8.8.8"}; - CPPUNIT_ASSERT(ip); - CPPUNIT_ASSERT(ip.toString() == "8.8.8.8"); - CPPUNIT_ASSERT(ip.getPort() == 0); - CPPUNIT_ASSERT(ip.isIpv4()); - CPPUNIT_ASSERT(not ip.isIpv6()); - CPPUNIT_ASSERT(not ip.isLoopback()); - CPPUNIT_ASSERT(not ip.isPrivate()); - CPPUNIT_ASSERT(not ip.isUnspecified()); - - IpAddr ip_2 = ip.toString(); - CPPUNIT_ASSERT(ip_2 == ip); - - ip = IpAddr(); - CPPUNIT_ASSERT(not ip); - CPPUNIT_ASSERT(ip.isUnspecified()); - CPPUNIT_ASSERT(not ip.isIpv4()); - CPPUNIT_ASSERT(not ip.isIpv6()); - CPPUNIT_ASSERT(ip.getPort() == 0); - - ip = IpAddr("8.8.8.8:42"); - CPPUNIT_ASSERT(ip); - CPPUNIT_ASSERT(ip.toString() == "8.8.8.8"); - CPPUNIT_ASSERT(ip.getPort() == 42); - - pj_sockaddr_set_port(ip.pjPtr(), 5042); - CPPUNIT_ASSERT(ip.getPort() == 5042); - -#if HAVE_IPV6 - const in6_addr native_ip = {{ - 0x3f, 0xfe, 0x05, 0x01, - 0x00, 0x08, 0x00, 0x00, - 0x02, 0x60, 0x97, 0xff, - 0xfe, 0x40, 0xef, 0xab - }}; - ip = IpAddr(native_ip); - CPPUNIT_ASSERT(ip); - CPPUNIT_ASSERT(ip == IpAddr("3ffe:0501:0008:0000:0260:97ff:fe40:efab")); - CPPUNIT_ASSERT(not ip.isIpv4()); - CPPUNIT_ASSERT(ip.isIpv6()); - - CPPUNIT_ASSERT(IpAddr::isValid("3ffe:0501:0008:0000:0260:97ff:fe40:efab")); - CPPUNIT_ASSERT(IpAddr::isValid("[3ffe:0501:0008:0000:0260:97ff:fe40:efab]")); - CPPUNIT_ASSERT(IpAddr::isValid("[3ffe:0501:0008:0000:0260:97ff:fe40:efab]:4242")); - CPPUNIT_ASSERT(IpAddr::isValid("[3ffe:501:8::260:97ff:fe40:efab]:4242")); -#endif -} - -IpTest::IpTest() : CppUnit::TestCase("IP Tests") {} - -}} // namespace ring::test diff --git a/test/iptest.h b/test/iptest.h deleted file mode 100644 index 33728185fc..0000000000 --- a/test/iptest.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef IP_TEST_ -#define IP_TEST_ - -// Cppunit import -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/TestCaller.h> -#include <cppunit/TestCase.h> -#include <cppunit/TestSuite.h> - -/* - * @file audiobuffertest.cpp - * @brief Regroups unit tests related to an audio buffer. - */ - -namespace ring { namespace test { - -class IpTest : public CppUnit::TestCase { - - /* - * Use cppunit library macros to add unit test the factory - */ - CPPUNIT_TEST_SUITE(IpTest); - CPPUNIT_TEST(testIpAddr); - CPPUNIT_TEST_SUITE_END(); - - public: - - IpTest(); - - void testIpAddr(); -}; - -/* Register our test module */ -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(IpTest, "IpTest"); -CPPUNIT_TEST_SUITE_REGISTRATION(IpTest); - -}} // namespace ring::test - -#endif // IP_TEST_ diff --git a/test/main.cpp b/test/main.cpp deleted file mode 100644 index 3db78303d5..0000000000 --- a/test/main.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Julien Bonjean <julien.bonjean@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "logger.h" -#include "manager.h" -#include "constants.h" -#include "fileutils.h" - -#include <cstdlib> - -#include <cppunit/CompilerOutputter.h> -#include <cppunit/XmlOutputter.h> -#include <cppunit/extensions/TestFactoryRegistry.h> -#include <cppunit/ui/text/TextTestRunner.h> - -namespace { - void restore() - { - if (system("mv " CONFIG_SAMPLE_BAK " " CONFIG_SAMPLE) < 0) - RING_ERR("Restoration of %s failed", CONFIG_SAMPLE); - } - void backup() - { - if (system("cp " CONFIG_SAMPLE " " CONFIG_SAMPLE_BAK) < 0) - RING_ERR("Backup of %s failed", CONFIG_SAMPLE); - } -} - -void cleanup() -{ - int ret = system("killall sipp"); - std::cerr << "Killed all sip processes with status " << ret << std::endl; -} - -int main(int argc, char* argv[]) -{ - atexit(cleanup); - printf("\nRing Daemon Test Suite, by Savoir-faire Linux 2004-2016\n\n"); - setConsoleLog(true); - setDebugMode(true); - ring::fileutils::FileHandle f(ring::fileutils::create_pidfile()); - if (f.fd == -1) { - fprintf(stderr, "An dring instance is already running, quitting...\n"); - return 1; - } - - int argvIndex = 1; - bool xmlOutput = false; - - if (argc > 1) { - if (strcmp("--help", argv[1]) == 0) { - argvIndex++; - - CPPUNIT_NS::Test* suite = CPPUNIT_NS::TestFactoryRegistry::getRegistry("All Tests").makeTest(); - - int testSuiteCount = suite->getChildTestCount(); - printf("Usage: test [OPTIONS] [TEST_SUITE]\n"); - printf("\nOptions:\n"); - printf(" --xml - Output results in an XML file, instead of standard output.\n"); - printf(" --debug - Debug mode\n"); - printf(" --help - Print help\n"); - printf("\nAvailable test suites:\n"); - - for (int i = 0; i < testSuiteCount; i++) { - printf(" - %s\n", suite->getChildTestAt(i)->getName().c_str()); - } - - return 0; - } else if (strcmp("--debug", argv[1]) == 0) { - argvIndex++; - - setDebugMode(true); - RING_INFO("Debug mode activated"); - - } else if (strcmp("--xml", argv[1]) == 0) { - argvIndex++; - - xmlOutput = true; - RING_INFO("Using XML output"); - } - } - - // Default test suite : all tests - std::string testSuiteName = "All Tests"; - - if (argvIndex < argc) { - testSuiteName = argv[argvIndex]; - argvIndex++; - } - - printf("\n\n=== SFLphone initialization ===\n\n"); - backup(); - ring::Manager::instance().init(CONFIG_SAMPLE); - - // Get the top level suite from the registry - printf("\n\n=== Test Suite: %s ===\n\n", testSuiteName.c_str()); - CPPUNIT_NS::Test *suite = CPPUNIT_NS::TestFactoryRegistry::getRegistry(testSuiteName).makeTest(); - - if (suite->getChildTestCount() == 0) { - RING_ERR("Invalid test suite name: %s", testSuiteName.c_str()); - restore(); - return 1; - } - - // Adds the test to the list of test to run - CppUnit::TextTestRunner runner; - runner.addTest(suite); - /* Specify XML output */ - std::ofstream outfile("cppunitresults.xml"); - - if (xmlOutput) { - CppUnit::XmlOutputter* outputter = new CppUnit::XmlOutputter(&runner.result(), outfile); - runner.setOutputter(outputter); - } else { - // Change the default outputter to a compiler error format outputter - runner.setOutputter(new CppUnit::CompilerOutputter(&runner.result(), std::cerr)); - } - - // Run the tests. - bool wasSuccessful = runner.run(); - - printf("=== Test suite ending ===\n"); - ring::Manager::instance().finish(); - - restore(); - - return wasSuccessful ? 0 : 1; -} diff --git a/test/numbercleanertest.cpp b/test/numbercleanertest.cpp deleted file mode 100644 index d39625d2ed..0000000000 --- a/test/numbercleanertest.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <cstdio> -#include <sstream> -#include <dlfcn.h> - -#include "logger.h" - -#include "numbercleanertest.h" - -#define NUMBER_TEST_1 "514 333 4444" -#define NUMBER_TEST_2 "514-333-4444" -#define NUMBER_TEST_3 "(514) 333 4444" -#define NUMBER_TEST_4 "(514)-333-4444" -#define NUMBER_TEST_5 "(514) 333-4444" -#define NUMBER_TEST_6 "514 333 4444" -#define NUMBER_TEST_7 "ext 136" -#define NUMBER_TEST_8 "514 333 4444 ext. 136" -#define NUMBER_TEST_9 "514 333 4444 ext 136" -#define NUMBER_TEST_10 "136" - -#define VALID_NUMBER "5143334444" -#define VALID_PREPENDED_NUMBER "95143334444" -#define VALID_EXTENSION "136" - -namespace ring { namespace test { - -void NumberCleanerTest::test_format_1(void) -{ - RING_DBG("-------------------- NumberCleanerTest::test_format_1 --------------------\n"); - CPPUNIT_ASSERT(NumberCleaner::clean(NUMBER_TEST_1) == VALID_NUMBER); -} - -void NumberCleanerTest::test_format_2(void) -{ - RING_DBG("-------------------- NumberCleanerTest::test_format_2 --------------------\n"); - - CPPUNIT_ASSERT(NumberCleaner::clean(NUMBER_TEST_2) == VALID_NUMBER); -} - -void NumberCleanerTest::test_format_3(void) -{ - RING_DBG("-------------------- NumberCleanerTest::test_format_3 --------------------\n"); - - CPPUNIT_ASSERT(NumberCleaner::clean(NUMBER_TEST_3) == VALID_NUMBER); -} - -void NumberCleanerTest::test_format_4(void) -{ - RING_DBG("-------------------- NumberCleanerTest::test_format_4 --------------------\n"); - - CPPUNIT_ASSERT(NumberCleaner::clean(NUMBER_TEST_4) == VALID_NUMBER); -} - -void NumberCleanerTest::test_format_5(void) -{ - RING_DBG("-------------------- NumberCleanerTest::test_format_5 --------------------\n"); - - CPPUNIT_ASSERT(NumberCleaner::clean(NUMBER_TEST_5) == VALID_NUMBER); -} - -void NumberCleanerTest::test_format_6(void) -{ - RING_DBG("-------------------- NumberCleanerTest::test_format_6 --------------------\n"); - - CPPUNIT_ASSERT(NumberCleaner::clean(NUMBER_TEST_6) == VALID_NUMBER); -} - -void NumberCleanerTest::test_format_7(void) -{ - RING_DBG("-------------------- NumberCleanerTest::test_format_7 --------------------\n"); - - CPPUNIT_ASSERT(NumberCleaner::clean(NUMBER_TEST_7) == VALID_EXTENSION); -} - -void NumberCleanerTest::test_format_8(void) -{ - RING_DBG("-------------------- NumberCleanerTest::test_format_8 --------------------\n"); - - CPPUNIT_ASSERT(NumberCleaner::clean(NUMBER_TEST_8) == VALID_NUMBER); -} - -void NumberCleanerTest::test_format_9(void) -{ - RING_DBG("-------------------- NumberCleanerTest::test_format_9 --------------------\n"); - - CPPUNIT_ASSERT(NumberCleaner::clean(NUMBER_TEST_9) == VALID_NUMBER); -} - -void NumberCleanerTest::test_format_10(void) -{ - RING_DBG("-------------------- NumberCleanerTest::test_format_10 --------------------\n"); - - CPPUNIT_ASSERT(NumberCleaner::clean(NUMBER_TEST_1, "9") == VALID_PREPENDED_NUMBER); -} - -void NumberCleanerTest::test_format_11(void) -{ - RING_DBG("-------------------- NumberCleanerTest::test_format_11 --------------------\n"); - - CPPUNIT_ASSERT(NumberCleaner::clean(NUMBER_TEST_10, "9") == VALID_EXTENSION); -} - -}} // namespace ring::test diff --git a/test/numbercleanertest.h b/test/numbercleanertest.h deleted file mode 100644 index 3990105f1a..0000000000 --- a/test/numbercleanertest.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -// Cppunit import -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/TestCaller.h> -#include <cppunit/TestCase.h> -#include <cppunit/TestSuite.h> - -// Application import -#include "numbercleaner.h" -// #include "../src/conference.h" -/* - * @file numbercleanerTest.cpp - * @brief Regroups unitary tests related to the phone number cleanup function. - */ - -#ifndef _NUMBERCLEANER_TEST_ -#define _NUMBERCLEANER_TEST_ - -namespace ring { namespace test { - -class NumberCleanerTest : public CppUnit::TestCase { - - /** - * Use cppunit library macros to add unit test the factory - */ - CPPUNIT_TEST_SUITE(NumberCleanerTest); - CPPUNIT_TEST(test_format_1); - CPPUNIT_TEST(test_format_2); - CPPUNIT_TEST(test_format_3); - CPPUNIT_TEST(test_format_4); - CPPUNIT_TEST(test_format_5); - CPPUNIT_TEST(test_format_6); - /*CPPUNIT_TEST (test_format_7); - CPPUNIT_TEST (test_format_8); - CPPUNIT_TEST (test_format_9);*/ - CPPUNIT_TEST(test_format_10); - CPPUNIT_TEST_SUITE_END(); - - public: - NumberCleanerTest() : CppUnit::TestCase("Hook Manager Tests") {} - - void test_format_1(); - void test_format_2(); - void test_format_3(); - void test_format_4(); - void test_format_5(); - void test_format_6(); - void test_format_7(); - void test_format_8(); - void test_format_9(); - void test_format_10(); - void test_format_11(); -}; - -/* Register our test module */ -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(NumberCleanerTest, "NumberCleanerTest"); -CPPUNIT_TEST_SUITE_REGISTRATION(NumberCleanerTest); - -}} // namespace ring::test - -#endif diff --git a/test/resamplertest.cpp b/test/resamplertest.cpp deleted file mode 100644 index 235bd75ad0..0000000000 --- a/test/resamplertest.cpp +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <iostream> -#include <iterator> -#include <algorithm> -#include <math.h> - -#include "resamplertest.h" - -namespace ring { namespace test { - -ResamplerTest::ResamplerTest() : - CppUnit::TestCase("Resampler module test"), inputBuffer(MAX_BUFFER_LENGTH, AudioFormat::MONO()), outputBuffer(MAX_BUFFER_LENGTH, AudioFormat::MONO()) -{} - -void ResamplerTest::setUp() -{ - -} - -void ResamplerTest::tearDown() -{ - -} - -namespace { - template <typename T> - void print_buffer(T &buffer) - { -#ifdef VERBOSE - std::copy(buffer.begin(), buffer.end(), - std::ostream_iterator<ring::AudioSample>(std::cout, ", ")); - std::cout << std::endl; -#endif - } -} - -void ResamplerTest::testUpsamplingRamp() -{ - // generate input samples and store them in inputBuffer - generateRamp(); - - std::cout << "Test Upsampling Ramp" << std::endl; - Resampler resampler(44100); - - performUpsampling(resampler); - - AudioBuffer tmpInputBuffer(TMP_LOWSMPLR_BUFFER_LENGTH, AudioFormat::MONO()); - AudioBuffer tmpOutputBuffer(TMP_HIGHSMPLR_BUFFER_LENGTH, AudioFormat(16000, 1)); - - tmpInputBuffer.copy(inputBuffer); - std::cout << "Input Buffer" << std::endl; - print_buffer(*tmpInputBuffer.getChannel(0)); - - tmpOutputBuffer.copy(outputBuffer); - std::cout << "Output Buffer" << std::endl; - print_buffer(*tmpOutputBuffer.getChannel(0)); -} - -void ResamplerTest::testDownsamplingRamp() -{ - generateRamp(); - - std::cout << "Test Downsampling Ramp" << std::endl; - Resampler resampler(44100); - - performDownsampling(resampler); - - AudioBuffer tmpInputBuffer(TMP_HIGHSMPLR_BUFFER_LENGTH, AudioFormat(16000, 1)); - AudioBuffer tmpOutputBuffer(TMP_LOWSMPLR_BUFFER_LENGTH, AudioFormat::MONO()); - - tmpInputBuffer.copy(inputBuffer); - std::cout << "Input Buffer" << std::endl; - print_buffer(*tmpInputBuffer.getChannel(0)); - - tmpOutputBuffer.copy(outputBuffer); - std::cout << "Output Buffer" << std::endl; - print_buffer(*tmpOutputBuffer.getChannel(0)); -} - -void ResamplerTest::testUpsamplingTriangle() -{ - generateTriangularSignal(); - - std::cout << "Test Upsampling Triangle" << std::endl; - Resampler resampler(44100); - - performUpsampling(resampler); - - AudioBuffer tmpInputBuffer(TMP_LOWSMPLR_BUFFER_LENGTH, AudioFormat::MONO()); - AudioBuffer tmpOutputBuffer(TMP_HIGHSMPLR_BUFFER_LENGTH, AudioFormat(16000, 1)); - - tmpInputBuffer.copy(inputBuffer); - std::cout << "Input Buffer" << std::endl; - print_buffer(*tmpInputBuffer.getChannel(0)); - - tmpOutputBuffer.copy(outputBuffer); - std::cout << "Output Buffer" << std::endl; - print_buffer(*tmpOutputBuffer.getChannel(0)); -} - -void ResamplerTest::testDownsamplingTriangle() -{ - generateTriangularSignal(); - - std::cout << "Test Downsampling Triangle" << std::endl; - Resampler resampler(44100); - - performDownsampling(resampler); - - AudioBuffer tmpInputBuffer(TMP_HIGHSMPLR_BUFFER_LENGTH, AudioFormat(16000, 1)); - AudioBuffer tmpOutputBuffer(TMP_LOWSMPLR_BUFFER_LENGTH, AudioFormat::MONO()); - - tmpInputBuffer.copy(inputBuffer); - std::cout << "Input Buffer" << std::endl; - print_buffer(*tmpInputBuffer.getChannel(0)); - - tmpOutputBuffer.copy(outputBuffer); - std::cout << "Output Buffer" << std::endl; - print_buffer(*tmpOutputBuffer.getChannel(0)); -} -void ResamplerTest::testUpsamplingSine() -{ - // generate input samples and store them in inputBuffer - generateSineSignal(); - - std::cout << "Test Upsampling Sine" << std::endl; - Resampler resampler(44100); - - performUpsampling(resampler); - - AudioBuffer tmpInputBuffer(TMP_LOWSMPLR_BUFFER_LENGTH, AudioFormat::MONO()); - AudioBuffer tmpOutputBuffer(TMP_HIGHSMPLR_BUFFER_LENGTH, AudioFormat(16000, 1)); - - tmpInputBuffer.copy(inputBuffer); - std::cout << "Input Buffer" << std::endl; - print_buffer(*tmpInputBuffer.getChannel(0)); - - tmpOutputBuffer.copy(outputBuffer); - std::cout << "Output Buffer" << std::endl; - print_buffer(*tmpOutputBuffer.getChannel(0)); -} - -void ResamplerTest::testDownsamplingSine() -{ - // generate input samples and store them in inputBuffer - generateSineSignal(); - - std::cout << "Test Downsampling Sine" << std::endl; - Resampler resampler(44100); - - performDownsampling(resampler); - - AudioBuffer tmpInputBuffer(TMP_HIGHSMPLR_BUFFER_LENGTH, AudioFormat(16000, 1)); - AudioBuffer tmpOutputBuffer(TMP_LOWSMPLR_BUFFER_LENGTH, AudioFormat::MONO()); - - tmpInputBuffer.copy(inputBuffer); - std::cout << "Input Buffer" << std::endl; - print_buffer(*tmpInputBuffer.getChannel(0)); - - tmpOutputBuffer.copy(outputBuffer); - std::cout << "Output Buffer" << std::endl; - print_buffer(*tmpOutputBuffer.getChannel(0)); -} - -void ResamplerTest::generateRamp() -{ - std::vector<ring::AudioSample>* buf = inputBuffer.getChannel(0); - for (size_t i = 0; i < buf->size(); ++i) - (*buf)[i] = i; -} - -void ResamplerTest::generateTriangularSignal() -{ - std::vector<ring::AudioSample>* buf = inputBuffer.getChannel(0); - for (size_t i = 0; i < buf->size(); ++i) - (*buf)[i] = i * 10; -} - -void ResamplerTest::generateSineSignal() -{ - std::vector<ring::AudioSample>* buf = inputBuffer.getChannel(0); - for (size_t i = 0; i < buf->size(); ++i) - (*buf)[i] = (ring::AudioSample) (1000.0 * sin(i)); -} - -void ResamplerTest::performUpsampling(Resampler &resampler) -{ - AudioBuffer tmpInputBuffer(TMP_LOWSMPLR_BUFFER_LENGTH, AudioFormat::MONO()); - AudioBuffer tmpOutputBuffer(TMP_HIGHSMPLR_BUFFER_LENGTH, AudioFormat(16000, 1)); - - for (size_t i = 0, j = 0; i < (inputBuffer.frames() / 2); i += tmpInputBuffer.frames(), j += tmpOutputBuffer.frames()) { - tmpInputBuffer.copy(inputBuffer, i); - resampler.resample(tmpInputBuffer, tmpOutputBuffer); - outputBuffer.copy(tmpOutputBuffer, -1, 0, j); - } -} - -void ResamplerTest::performDownsampling(Resampler &resampler) -{ - AudioBuffer tmpInputBuffer(TMP_HIGHSMPLR_BUFFER_LENGTH, AudioFormat(16000, 1)); - AudioBuffer tmpOutputBuffer(TMP_LOWSMPLR_BUFFER_LENGTH, AudioFormat::MONO()); - - for (size_t i = 0, j = 0; i < inputBuffer.frames(); i += tmpInputBuffer.frames(), j += tmpOutputBuffer.frames()) { - tmpInputBuffer.copy(inputBuffer, i); - resampler.resample(tmpInputBuffer, tmpOutputBuffer); - outputBuffer.copy(tmpOutputBuffer, -1, 0, j); - } -} - -}} // namespace ring::test diff --git a/test/resamplertest.h b/test/resamplertest.h deleted file mode 100644 index 6cb2a11e0b..0000000000 --- a/test/resamplertest.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) 2012-2016 Savoir-faire Linux Inc. - * - * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef _RESAMPLER_TEST_ -#define _RESAMPLER_TEST_ - -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/TestCaller.h> -#include <cppunit/TestCase.h> -#include <cppunit/TestSuite.h> - -#include "audio/resampler.h" -#include "noncopyable.h" - -#define MAX_BUFFER_LENGTH 40000 -#define TMP_LOWSMPLR_BUFFER_LENGTH 160 -#define TMP_HIGHSMPLR_BUFFER_LENGTH 320 - -namespace ring { namespace test { - -class ResamplerTest : public CppUnit::TestCase { - - /** - * Use cppunit library macros to add unit test the factory - */ - CPPUNIT_TEST_SUITE(ResamplerTest); - CPPUNIT_TEST(testUpsamplingRamp); - CPPUNIT_TEST(testDownsamplingRamp); - CPPUNIT_TEST(testUpsamplingTriangle); - CPPUNIT_TEST(testDownsamplingTriangle); - CPPUNIT_TEST(testUpsamplingSine); - CPPUNIT_TEST(testDownsamplingSine); - CPPUNIT_TEST_SUITE_END(); - - public: - ResamplerTest(); - - /* - * Code factoring - Common resources can be initialized here. - * This method is called by unitcpp before each test - */ - void setUp(); - - /* - * Code factoring - Common resources can be released here. - * This method is called by unitcpp after each test - */ - void tearDown(); - - /* - * Generate a ramp and upsamples it form 8kHz to 16kHz - */ - void testUpsamplingRamp(); - - /* - * Generate a ramp and downsamples it from 16kHz to 8kHz - */ - void testDownsamplingRamp(); - - /* - * Generate a triangular signal and upsamples it from 8kHz to 16kHz - */ - void testUpsamplingTriangle(); - - /* - * Generate a triangular signal and downsamples it from 16kHz to 8kHz - */ - void testDownsamplingTriangle(); - - /* - * Generate a sine signal and upsamples it from 8kHz to 16kHz - */ - void testUpsamplingSine(); - - /* - * Generate a sine signal and downsamples it from 16kHz to 8kHz - */ - void testDownsamplingSine(); - -private: - NON_COPYABLE(ResamplerTest); - - /* - * Generate a ramp to be stored in inputBuffer - */ - void generateRamp(); - - /* - * Generate a triangular signal to be stored in inputBuffer - */ - void generateTriangularSignal(); - - /* - * Generate a sine signal to be stored in inputBuffer - */ - void generateSineSignal(); - - /* - * Perform upsampling on the whole input buffer - */ - void performUpsampling(ring::Resampler &resampler); - - /* - * Perform downsampling on the whold input buffer - */ - void performDownsampling(ring::Resampler &resampler); - - /** - * Used to store input samples - */ - ring::AudioBuffer inputBuffer; - - /** - * Used to receive output samples - */ - ring::AudioBuffer outputBuffer; -}; - -/* Register the test module */ -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(ResamplerTest, "ResamplerTest"); -CPPUNIT_TEST_SUITE_REGISTRATION(ResamplerTest); - -}} // namespace ring::test - -#endif // _RESAMPLER_TEST_ diff --git a/test/ringbufferpooltest.cpp b/test/ringbufferpooltest.cpp deleted file mode 100644 index 43de28703b..0000000000 --- a/test/ringbufferpooltest.cpp +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <string> -#include <memory> - -#include "ringbufferpooltest.h" -#include "audio/ringbufferpool.h" -#include "audio/ringbuffer.h" -#include "logger.h" -#include "test_utils.h" - -namespace ring { namespace test { - -void RingBufferPoolTest::testBindUnbindBuffer() -{ - TITLE(); - - std::string test_id1 = "bind unbind 1"; - std::string test_id2 = "bind unbind 2"; - - // bind test_id1 with RingBufferPool::DEFAULT_ID (test_id1 not already created) - rbPool_->bindCallID(test_id1, RingBufferPool::DEFAULT_ID); - - // unbind test_id1 with RingBufferPool::DEFAULT_ID - rbPool_->unBindCallID(test_id1, RingBufferPool::DEFAULT_ID); - - rbPool_->bindCallID(test_id1, RingBufferPool::DEFAULT_ID); - rbPool_->bindCallID(test_id1, RingBufferPool::DEFAULT_ID); - - rbPool_->bindCallID(test_id2, RingBufferPool::DEFAULT_ID); - rbPool_->bindCallID(test_id2, RingBufferPool::DEFAULT_ID); - - // bind test_id1 with test_id2 (both testid1 and test_id2 already created) - // calling it twice not supposed to break anything - rbPool_->bindCallID(test_id1, test_id2); - rbPool_->bindCallID(test_id1, test_id2); - - rbPool_->unBindCallID(test_id1, test_id2); - rbPool_->unBindCallID(test_id1, test_id2); - - rbPool_->unBindCallID(RingBufferPool::DEFAULT_ID, test_id2); - rbPool_->unBindCallID(RingBufferPool::DEFAULT_ID, test_id2); - - rbPool_->unBindCallID(RingBufferPool::DEFAULT_ID, test_id1); - - // test unbind all function - rbPool_->bindCallID(RingBufferPool::DEFAULT_ID, test_id1); - rbPool_->bindCallID(RingBufferPool::DEFAULT_ID, test_id2); - rbPool_->bindCallID(test_id1, test_id2); - - rbPool_->unBindAll(test_id2); -} - -void RingBufferPoolTest::testGetPutData() -{ - TITLE(); - - std::string test_id = "incoming rtp session"; - - auto mainRingBuffer = rbPool_->getRingBuffer(RingBufferPool::DEFAULT_ID); - auto testRingBuffer = rbPool_->createRingBuffer(test_id); - - rbPool_->bindCallID(test_id, RingBufferPool::DEFAULT_ID); - - ring::AudioSample test_sample1 = 12; - ring::AudioSample test_sample2 = 13; - - AudioBuffer test_input1(&test_sample1, 1, AudioFormat::MONO()); - AudioBuffer test_input2(&test_sample2, 1, AudioFormat::MONO()); - AudioBuffer test_output(100, AudioFormat::MONO()); - - // get by test_id without preleminary put - CPPUNIT_ASSERT(rbPool_->getData(test_output, test_id) == 0); - - // put by RingBufferPool::DEFAULT_ID, get by test_id - mainRingBuffer->put(test_input1); - CPPUNIT_ASSERT(rbPool_->getData(test_output, test_id) == 1); - CPPUNIT_ASSERT(test_sample1 == (*test_output.getChannel(0))[0]); - - // get by RingBufferPool::DEFAULT_ID without preleminary put - CPPUNIT_ASSERT(rbPool_->getData(test_output, RingBufferPool::DEFAULT_ID) == 0); - - // put by test_id, get by RingBufferPool::DEFAULT_ID - testRingBuffer->put(test_input2); - CPPUNIT_ASSERT(rbPool_->getData(test_output, RingBufferPool::DEFAULT_ID) == 1); - CPPUNIT_ASSERT(test_sample2 == (*test_output.getChannel(0))[0]); - - rbPool_->unBindCallID(test_id, RingBufferPool::DEFAULT_ID); -} - -void RingBufferPoolTest::testGetAvailableData() -{ - TITLE(); - std::string test_id = "getData putData"; - std::string false_id = "false id"; - - auto mainRingBuffer = rbPool_->getRingBuffer(RingBufferPool::DEFAULT_ID); - auto testRingBuffer = rbPool_->createRingBuffer(test_id); - - rbPool_->bindCallID(test_id, RingBufferPool::DEFAULT_ID); - - ring::AudioSample test_sample1 = 12; - ring::AudioSample test_sample2 = 13; - - AudioBuffer test_input1(&test_sample1, 1, AudioFormat::MONO()); - AudioBuffer test_input2(&test_sample2, 1, AudioFormat::MONO()); - AudioBuffer test_output(1, AudioFormat::MONO()); - AudioBuffer test_output_large(100, AudioFormat::MONO()); - - // put by RingBufferPool::DEFAULT_ID get by test_id without preleminary put - CPPUNIT_ASSERT(rbPool_->availableForGet(test_id) == 0); - CPPUNIT_ASSERT(rbPool_->getAvailableData(test_output, test_id) == 0); - - // put by RingBufferPool::DEFAULT_ID, get by test_id - mainRingBuffer->put(test_input1); - CPPUNIT_ASSERT(rbPool_->availableForGet(test_id) == 1); - - // get by RingBufferPool::DEFAULT_ID without preliminary input - CPPUNIT_ASSERT(rbPool_->availableForGet(test_id) == 0); - CPPUNIT_ASSERT(rbPool_->getData(test_output_large, test_id) == 0); - - // put by test_id get by test_id - testRingBuffer->put(test_input2); - CPPUNIT_ASSERT(rbPool_->availableForGet(test_id) == 1); - CPPUNIT_ASSERT(rbPool_->getData(test_output_large, test_id) == 1); - CPPUNIT_ASSERT(rbPool_->availableForGet(test_id) == 0); - CPPUNIT_ASSERT((*test_output_large.getChannel(0))[0] == test_sample2); - - // get by false id - CPPUNIT_ASSERT(rbPool_->getData(test_output_large, false_id) == 0); - - rbPool_->unBindCallID(test_id, RingBufferPool::DEFAULT_ID); -} - -void RingBufferPoolTest::testDiscardFlush() -{ - TITLE(); - std::string test_id = "flush discard"; - - auto mainRingBuffer = rbPool_->getRingBuffer(RingBufferPool::DEFAULT_ID); - auto testRingBuffer = rbPool_->createRingBuffer(test_id); - - rbPool_->bindCallID(test_id, RingBufferPool::DEFAULT_ID); - - ring::AudioSample test_sample1 = 12; - AudioBuffer test_input1(&test_sample1, 1, AudioFormat::MONO()); - - testRingBuffer->put(test_input1); - rbPool_->discard(1, RingBufferPool::DEFAULT_ID); - - rbPool_->discard(1, test_id); - - mainRingBuffer->put(test_input1); - - rbPool_->discard(1, test_id); - - rbPool_->unBindCallID(test_id, RingBufferPool::DEFAULT_ID); -} - -void RingBufferPoolTest::testConference() -{ - TITLE(); - - std::string test_id1 = "participant A"; - std::string test_id2 = "participant B"; - - auto mainRingBuffer = rbPool_->getRingBuffer(RingBufferPool::DEFAULT_ID); - auto testRingBuffer1 = rbPool_->createRingBuffer(test_id1); - auto testRingBuffer2 = rbPool_->createRingBuffer(test_id2); - - // test bind Participant A with default - rbPool_->bindCallID(test_id1, RingBufferPool::DEFAULT_ID); - - // test bind Participant B with default - rbPool_->bindCallID(test_id2, RingBufferPool::DEFAULT_ID); - - // test bind Participant A with Participant B - rbPool_->bindCallID(test_id1, test_id2); - - ring::AudioSample testint = 12; - AudioBuffer testbuf(&testint, 1, AudioFormat::MONO()); - - // put data test ring buffers - mainRingBuffer->put(testbuf); - - // put data test ring buffers - testRingBuffer1->put(testbuf); - testRingBuffer2->put(testbuf); -} - -RingBufferPoolTest::RingBufferPoolTest() - : CppUnit::TestCase("Audio Layer Tests") , rbPool_(new RingBufferPool) -{} - -}} // namespace ring::test diff --git a/test/ringbufferpooltest.h b/test/ringbufferpooltest.h deleted file mode 100644 index 7db0312954..0000000000 --- a/test/ringbufferpooltest.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef RINGBUFFERPOOL_TEST_ -#define RINGBUFFERPOOL_TEST_ - -// Cppunit import -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/TestCaller.h> -#include <cppunit/TestCase.h> -#include <cppunit/TestSuite.h> - -#include <memory> - -/* - * @file audiorecorderTest.cpp - * @brief Regroups unit tests related to the main buffer. - */ - -namespace ring { -class RingBufferPool; -} // namespace ring - -namespace ring { namespace test { - -class RingBufferPoolTest : public CppUnit::TestCase { - - /* - * Use cppunit library macros to add unit test the factory - */ - CPPUNIT_TEST_SUITE(RingBufferPoolTest); - CPPUNIT_TEST(testBindUnbindBuffer); - CPPUNIT_TEST(testGetPutData); - CPPUNIT_TEST(testDiscardFlush); - CPPUNIT_TEST(testConference); - CPPUNIT_TEST_SUITE_END(); - - public: - - RingBufferPoolTest(); - - void testBindUnbindBuffer(); - - void testGetPutData(); - - void testGetAvailableData(); - - void testDiscardFlush(); - - void testConference(); - - private: - - std::unique_ptr<ring::RingBufferPool> rbPool_; -}; - -/* Register our test module */ -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(RingBufferPoolTest, "RingBufferPoolTest"); -CPPUNIT_TEST_SUITE_REGISTRATION(RingBufferPoolTest); - -}} // namespace ring::test - -#endif // RINGBUFFERPOOL_TEST_ diff --git a/test/run_tests.sh b/test/run_tests.sh deleted file mode 100755 index 9c48398b37..0000000000 --- a/test/run_tests.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -# print out env first for debugging -env -CODECS_PATH="../src/audio/codecs" exec ./test --xml diff --git a/test/scripts/presence_test.py b/test/scripts/presence_test.py deleted file mode 100755 index 81a4a1aed0..0000000000 --- a/test/scripts/presence_test.py +++ /dev/null @@ -1,219 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -print "\ -# --SFLPhone-- #\n\ -# #\n\ -# copyright: Savoir-faire Linux (2013) #\n\ -# author: Patrick keroulas <patrick.keroulas@savoirfairelinux.com> #\n\ -# description: This script sends a sequence of methods to the daemon #\n\ -# through the dbus to test the presence feature of SFLPhone. #\n\ -# SET THE PARAMS IS THE 'data' SECTION OF THIS SCRIPT BEFORE #\n\ -# YOU EXECUTE IT. 'The normal mode process the tasks #\n\ -# in order while the random mode generates a random sequence #\n\ -# A Freeswitch server must be setup since it supports PUBLISH #\n\ -# requests and Asterisk doesn't. #\n\ -# The user must have 2 valid accounts. This script will #\n\ -# use the first account in the list and the IP2IP account. #\n\ -# This is a self subscribe test, set another buddy IP if needed#\n\ -#\n" - - - -import time, sys, gobject -from random import randint -import dbus, dbus.mainloop.glib -import logging, commands - - -#----------------- logger to file and stdout ------------------------------ -f = '%(asctime)s - %(name)s - %(levelname)s - %(message)s' -logfile = 'sflphone_doombot.log' -logging.basicConfig(filename=logfile,level=logging.INFO,format=f) # log to file -logger = logging.getLogger() -ch = logging.StreamHandler(sys.stdout) #log to console -ch.setLevel(logging.INFO) -formatter = logging.Formatter(f) -ch.setFormatter(formatter) -logger.addHandler(ch) - -#------------------ Initialise DBUS ------------------------------ -dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) -bus = dbus.SessionBus() -presenceManagerBus = bus.get_object('cx.ring.Ring', '/cx/ring/Ring/PresenceManager') -presenceManager = dbus.Interface(presenceManagerBus, dbus_interface='cx.ring.Ring.PresenceManager') -configurationManagerBus = bus.get_object('cx.ring.Ring', '/cx/ring/Ring/ConfigurationManager') -configurationManager = dbus.Interface(configurationManagerBus, dbus_interface='cx.ring.Ring.ConfigurationManager') - - -#------------------------- General purpose functions ---------------------------- - -#Get the first non-IP2IP account -def get_first_account(): - accounts = configurationManager.getAccountList() - for i, v in enumerate(accounts): - if v != "IP2IP": - details = configurationManager.getAccountDetails(v) - if details["Account.type"] == True or details["Account.type"] == "SIP": - return v - return "IP2IP" - -def get_account_list(): - accounts = configurationManager.getAccountList() - result = [] - for i, v in enumerate(accounts): - if v != "IP2IP": - details = configurationManager.getAccountDetails(v) - if details["Account.type"] == True or details["Account.type"] == "SIP": - result.append(v) - return result - -def registerSend(arg): - configurationManager.sendRegister(arg['acc'],arg['enable']) - logging.info('> REGISTER : '+ str(arg)) - -#------------------------- Presence functions ---------------------------- - -def presSubscribe(arg): - presenceManager.subscribeBuddy(arg['acc'],arg['buddy'],arg['flag']) - logging.info('> SUBSCRIBE to ' + str(arg)) - -def presSend(arg): - presenceManager.publish(arg['acc'],arg['status'],arg['note']) - logging.info('> PUBLISH ' + str(arg)) - -def presSubApprove(arg): - presenceManager.answerServerRequest(arg['uri'],arg['flag']) - logging.info('> APPROVE subscription from' + str(arg)) - -def newPresSubCientNotificationHandler(acc, uri, status, activity): - logging.info("< SIGNAL : Notification for acc:"+str(acc)+", from:"+str(uri)+" (status:" + str(status)+ ", "+ str(activity)+ ").") - -def newPresSubServerRequestHandler(uri): - logging.info("< SIGNAL : PresenceSubscription request from " +str(uri)) - subscriber_uri = uri - -def subcriptionStateChangedHandler(acc,uri,flag): - logging.info("< SIGNAL : new subscriptionState request for acc:"+str(acc)+" uri " +str(uri) + " flag:" + str(flag)) - -def serverErrorHandler(acc, error, msg): - logging.info("< SIGNAL : error from server:"+str(error)+" . "+str(msg)) - -def randbool(): - return bool(randint(0,1)) - -#--------------------------- Data ------------------------------- - -TEST_DURATION = 30 # in sec -acc_1 = get_account_list()[0] -print 'acc_1 : ' + str(acc_1) -acc_2 = get_account_list()[1] -print 'acc_2 : ' + str(acc_2) -IP2IP = 'IP2IP' -server_ip = '192.95.9.63' # asterisk test server - -host_user = '6001' -host_ip = '192.168.50.196' -host_uri = '<sip:'+host_user+'@'+server_ip+'>' - -buddy_uri_1 = '<sip:6001@'+server_ip+'>' -buddy_uri_2 = '<sip:6002@'+server_ip+'>' -buddy_ip = host_ip # self subscribing -buddy_ip_uri = '<sip:'+buddy_ip+'>' # IP2IP -subscriber_uri = '' - -#---------------------------- Sequence ---------------------------- - -start_time = 0 -task_count = 0 -task_N = 0 - -SEQ_MODE_NORMAL = 0 -SEQ_MODE_RANDOM = 1 -sequence_mode = SEQ_MODE_NORMAL - - -# regular test -task_list = [ - - (registerSend,{'acc':acc_1, 'enable':True}), - (presSubscribe, {'acc':acc_1,'buddy':buddy_uri_1,'flag':True}), - - (registerSend,{'acc':acc_2, 'enable':True}), - (presSubscribe, {'acc':acc_2,'buddy':buddy_uri_2,'flag':True}), - - (presSend, {'acc':acc_2,'status':randbool(),'note':buddy_uri_1+'is here!'}), - (presSend, {'acc':acc_1,'status':randbool(),'note':buddy_uri_2+'is here'}), - - (presSubscribe, {'acc':acc_1,'buddy':'<sip:6003@192.95.9.63>','flag':True}), - - (registerSend,{'acc':acc_1, 'enable':False}), - (presSubscribe, {'acc':acc_2,'buddy':buddy_uri_2,'flag':False}), - - (registerSend,{'acc':acc_2, 'enable':False}), - (presSubscribe, {'acc':acc_1,'buddy':buddy_uri_1,'flag':False}), -] - - -""" -# simple sub -task_list = [ - - (presSubscribe, {'acc':acc_2,'buddy':buddy_uri_2,'flag':True}), - (presSubscribe, {'acc':acc_2,'buddy':'<sip:6003@192.95.9.63>','flag':True}), -] -""" - -""" -# IP2IP -task_list = [ - (presSubscribe, {'acc': IP2IP,'buddy':buddy_ip_uri,'flag':True}), - (presSend, {'acc': IP2IP,'status':randbool(),'note':'This notify should not be recieved'}), - (presSubApprove, {'uri':subscriber_uri,'flag':randbool()}), - (presSend, {'acc': IP2IP,'status':randbool(),'note':'Oh yeah!'}), - (presSubscribe, {'acc': IP2IP,'buddy':buddy_ip_uri,'flag':False}), -] -""" - - -def run(): - - if sequence_mode == SEQ_MODE_NORMAL: - global task_count - task_index = task_count%task_N - task_count += 1 - if task_count == task_N+1: # one loop - return - - elif sequence_mode == SEQ_MODE_RANDOM: - task_index = randint(0,task_N-1) - - task_list[task_index][0](task_list[task_index][1]) - - if(int(time.time()-start_time) < TEST_DURATION): - gobject.timeout_add(2000, run) # const time step in ms - #gobject.timeout_add(randint(50,2000), run) # random time step in ms - else: - logging.info("Test sequence finished") - # TODO clear dbus sessio. Unfortunately stackoverflow.com is down today - - -if __name__ == '__main__': - - try: - # dbus signal monitor - presenceManagerBus.connect_to_signal("newBuddyNotification", newPresSubCientNotificationHandler, dbus_interface='cx.ring.Ring.PresenceManager') - presenceManagerBus.connect_to_signal("newServerSubscriptionRequest", newPresSubServerRequestHandler, dbus_interface='cx.ring.Ring.PresenceManager') - presenceManagerBus.connect_to_signal("subcriptionStateChanged", subcriptionStateChangedHandler, dbus_interface='cx.ring.Ring.PresenceManager') - presenceManagerBus.connect_to_signal("serverError", serverErrorHandler, dbus_interface='cx.ring.Ring.PresenceManager') - - start_time = time.time() - task_N = len(task_list) - #sequence_mode = SEQ_MODE_RANDOM - - run() - - except Exception as e: - print e - - loop = gobject.MainLoop() - loop.run() diff --git a/test/scripts/stress_test.py b/test/scripts/stress_test.py deleted file mode 100755 index 4d4a608f7f..0000000000 --- a/test/scripts/stress_test.py +++ /dev/null @@ -1,421 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -print "\ -# --SFLphone-- #\n\ -# /¯¯¯¯\ /¯¯¯¯\ /¯¯¯¯\ /¯¯¯\_/¯¯¯\ /¯¯¯¯¯\ /¯¯¯¯\ |¯¯¯¯¯¯¯| #\n\ -# / /¯\ | / /\ \ /\ \| /¯\ /¯\ | | |¯| | | /\ | ¯¯| |¯¯ #\n\ -# / / / |/ | | | | | || | | | | | | ¯ < | | | | | | #\n\ -# / /__/ / | ¯ | ¯ || | | | | | | |¯| | | |_| | | | #\n\ -# |______/ \_____/ \____/ |_| |_| |_| \_____/ \____/ |_| #\n\ -# #\n\ -# _Version 2.0_ #\n\ -# #\n\ -# copyright: Savoir-faire Linux (2012-2013) #\n\ -# author: Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> #\n\ -# description: This script perform stress tests to trigger rare race #\n\ -# conditions or ASSERT caused by excessive load. This script #\n\ -# should, in theory, never crash or end the sflphone daemon #\n" - -import dbus -import time -import sys -import os -from random import randint - -#---------------------------------------------------------------------# -# # -# Variables # -# # -#---------------------------------------------------------------------# - -#Initialise DBUS -bus = dbus.SessionBus() -callManagerBus = None -callManager = None -configurationManagerBus = None -configurationManager = None -instanceManagerBus = None -instanceManager = None - -#SFLphone -first_account = None -first_iax_account = None -first_account_number = None - -#GDB observer -gdbScriptPath = os.path.dirname(os.path.abspath(__file__))+"/gdb_wrapper.py" -gdbWrapperCommand = "gdb -x "+gdbScriptPath+" > /dev/null 2> /dev/null &" - -#Numbers -sip_number_1 = "7001" -sip_number_2 = "7000" -sip_unreg = "7002" - -#Messages -global_info = "" - - -#---------------------------------------------------------------------# -# # -# Initialization # -# # -#---------------------------------------------------------------------# - -#Start the GDB plugin -def start_daemon(): - #os.system(gdbWrapperCommand) - #time.sleep(10) - reInit() - -#Stop the daemon normally, do it 3 time to be sure it will unregister everyone -def stop_daemon(): - print("Stopping daemon") - try: - instanceManager.Unregister(123) - instanceManager.Unregister(123) - instanceManager.Unregister(123) - except: - #Nothing, it is normal - print("") - -#Connect DBUS -def reInit(): - try: - global callManagerBus,callManager,configurationManagerBus,configurationManager,instanceManagerBus,instanceManager - callManagerBus = bus.get_object('cx.ring.Ring', '/cx/ring/Ring/CallManager') - callManager = dbus.Interface(callManagerBus, dbus_interface='cx.ring.Ring.CallManager') - configurationManagerBus = bus.get_object('cx.ring.Ring', '/cx/ring/Ring/ConfigurationManager') - configurationManager = dbus.Interface(configurationManagerBus, dbus_interface='cx.ring.Ring.ConfigurationManager') - instanceManagerBus = bus.get_object('cx.ring.Ring', '/cx/ring/Ring/Instance') - instanceManager = dbus.Interface(instanceManagerBus , dbus_interface='cx.ring.Ring.Instance') - instanceManager.Register(123,"doombot") - global first_account,first_iax_account,first_account_number - first_account = get_first_account() - first_iax_account = get_first_iax_account() - first_account_number = get_account_number(first_account) - except dbus.exceptions.DBusException: - time.sleep(0.5) - reInit() - -#---------------------------------------------------------------------# -# # -# Tools # -# # -#---------------------------------------------------------------------# - -#Get the first non-IP2IP account -def get_first_account(): - accounts = configurationManager.getAccountList() - for i, v in enumerate(accounts): - if v != "IP2IP": - details = configurationManager.getAccountDetails(v) - if (details["Account.type"] == True or details["Account.type"] == "SIP") \ - and details['Account.registrationStatus'] == "REGISTERED": - return v - return "IP2IP" - -#Get the first IAX account -def get_first_iax_account(): - accounts = configurationManager.getAccountList() - for i, v in enumerate(accounts): - if v != "IP2IP": - details = configurationManager.getAccountDetails(v) - if details["Account.type"] != True and details["Account.type"] != "SIP": - return v - return "IP2IP" - -def get_account_number(account): - details = configurationManager.getAccountDetails(account) - return details["Account.username"] - -def answer_all_calls(): - calls = callManager.getCallList() - for i, v in enumerate(calls): - details = callManager.getCallDetails(v) - if details["CALL_STATE"] == "INCOMING": - callManager.accept(v) - -#Return true is the account is registered -def check_account_state(account): - details = configurationManager.getAccountDetails(account) - #details = {'test':1,'test2':2,'registrationStatus':3} - return details['Account.registrationStatus'] == "REGISTERED" - -#Meta test, common for all tests -def meta_test(test_func): - retCode = 0 - for y in range(0,15): - for x in range(0,10): - try: - ret = test_func() - if ret and ret['code'] > 0: - #print " \033[0;33m"+ret['error']+"\033[0m" - retCode = 1 - sys.stdout.write('X') - except dbus.exceptions.DBusException: - retCode = 1 - sys.stdout.write('X') - reInit() - sys.stdout.write('#') - sys.stdout.flush() - if retCode == 0: - sys.stdout.write(' \033[92m(Success)\033[0m\n') - else: - sys.stdout.write(' \033[91m(Failure)\033[0m\n') - return retCode - -#Add a new test -suits = {} -def add_to_suit(test_suite_name,test_name,test_func): - if not test_suite_name in suits: - suits[test_suite_name] = [] - suits[test_suite_name].append({'test_name':test_name,'test_func':test_func}) - -# Run tests -def run(): - counter = 1 - results = {} - for k in suits.keys(): - print "\n\033[1mExecuting \""+str(k)+"\" tests suit:\033[0m ("+str(counter)+"/"+str(len(suits))+")" - for i, v in enumerate(suits[k]): - #Start SFLphone - start_daemon() - sys.stdout.write(" ["+str(i+1)+"/"+str(len(suits[k]))+"] Testing \""+v['test_name']+"\": ") - sys.stdout.flush() - - #Run the test - retval = meta_test(v['test_func']) - if not k in results: - results[k] = 0 - if retval > 0: - results[k]= results[k] + 1 - - #Stop SFLphone - stop_daemon() - time.sleep(15) - try: - #Try to read the GDB wrapper report - with open('/tmp/doombotReport') as report: - print "Test results:" - print report.read() - except IOError: - print 'Report not found' - counter = counter + 1 - - #Print the test summary - print "\n\n\033[1mSummary:\033[0m" - totaltests = 0 - totalsuccess = 0 - for k in suits.keys(): - print " Suit \""+k+"\": "+str(len(suits[k])-results[k])+"/"+str(len(suits[k])) - totaltests = totaltests + len(suits[k]) - totalsuccess = totalsuccess + len(suits[k])-results[k] - - print "\nTotal: "+str(totalsuccess)+"/"+str(totaltests)+", "+str(totaltests-totalsuccess)+" failures" - - - - -#---------------------------------------------------------------------# -# # -# Unit Tests # -# # -#---------------------------------------------------------------------# - -# This unit case test the basic senario of calling asterisk/freeswitch and then hanging up -# It call itself to make the test simpler, this also test answering up as a side bonus -def stress_answer_hangup_server(): - details = configurationManager.getAccountDetails(first_account) - callManager.placeCall(first_account,sip_number_2) - time.sleep(0.05) - calls = callManager.getCallList() - - # Check if the call worked - if len(calls) < 2: - if not check_account_state(first_account): - #TODO Try to register again instead of failing - return {'code':2,'error':"Unit test \"stress_answer_hangup_server\" failed: Account went unregistered"} - else: - return {'code':1,'error':"Unit test \"stress_answer_hangup_server\" failed: Error while placing call, there is "+str(len(calls))+" calls"} - else: - #Accept the calls - for i, v in enumerate(calls): - time.sleep(0.05) - callManager.accept(v) - callManager.accept(v) - callManager.accept(v) - callManager.accept(v) - callManager.placeCall(first_account,sip_number_2) - - #Hang up - callManager.hangUp(calls[0]) - calls = callManager.getCallList() - for i, v in enumerate(calls): - callManager.hangUp(v) - return {'code':0,'error':""} -add_to_suit("Place call",'Place, answer and hangup',stress_answer_hangup_server) - - - -# This test is similar to stress_answer_hangup_server, but test using IP2IP calls -def stress_answer_hangup_IP2IP(): - callManager.placeCall(first_account,"sip:127.0.0.1") - time.sleep(0.05) - calls = callManager.getCallList() - - # Check if the call worked - if len(calls) < 2: - if not check_account_state(first_account): - #TODO Try to register again instead of failing - return {'code':2,'error':"\nUnit test \"stress_answer_hangup_server\" failed: Account went unregistered"} - else: - return {'code':1,'error':"\nUnit test \"stress_answer_hangup_server\" failed: Error while placing call, there is "+str(len(calls))+" calls"} - else: - #Accept the calls - for i, v in enumerate(calls): - time.sleep(0.05) - callManager.accept(v) - #Hang up - callManager.hangUp(calls[0]) - return {'code':0,'error':""} -add_to_suit("Place call",'Place, answer and hangup (IP2IP)',stress_answer_hangup_IP2IP) - -# Test various type of transfers between various type of calls -# Use both localhost, SIP and IAX -def stress_transfers(): - for i in range(0,50): #repeat the tests - for j in range(0,3): # alternate between IP2IP, SIP and IAX - for k in range(0,2): #alternate between classic transfer and attended one - acc1 = "" - if j == 0: - acc1 = first_account - elif j == 1: - acc1 = "IP2IP" - else: - acc1 = first_iax_account - acc2 = "" - if i%3 == 0: #Use the first loop to shuffle second account type - acc2 = first_account - global_info = "Using SIP Account" - elif i%3 == 1: - acc2 = "IP2IP" - global_info = "Using IP2IP" - else: - acc2 = first_iax_account - global_info = "Using IAX account" - #print "ACC1"+acc1+" ACC2 "+acc2+ " FIRST IAX "+ first_iax_account +" FISRT "+first_account - destination_number = "" - if acc2 == "IP2IP": - destination_number = "sip:127.0.0.1" - else: - destination_number = configurationManager.getAccountDetails(acc2)["Account.username"] - callManager.placeCall(acc1,destination_number) - second_call = None - if k == 1: - callManager.placeCall(acc1,sip_number_1) - answer_all_calls() - - if k == 1: - first_call = None - calls = callManager.getCallList() - for i, v in enumerate(calls): - if first_call == None: - first_call = v - else: - callManager.attendedTransfer(v,first_call) - else: - calls = callManager.getCallList() - for i, v in enumerate(calls): - callManager.transfer(v,destination_number) -#add_to_suit("Transfer",'Make calls and transfer them',stress_transfers) - - -# This test make as tons or calls, then hangup them all as fast as it can -def stress_concurent_calls(): - for i in range(0,5): #repeat the tests - for j in range(0,3): # alternate between IP2IP, SIP and IAX - acc1 = "" - if j == 0: - acc1 = first_account - global_info = "Using SIP" - elif j == 1: - acc1 = "IP2IP" - global_info = "Using IP2IP" - else: - acc1 = first_iax_account - global_info = "Using IAX" - acc2 = "" - if i%3 == 0: #Use the first loop to shuffle second account type - acc2 = first_account - elif i%3 == 1: - acc2 = "IP2IP" - else: - acc2 = first_iax_account - #print "ACC1"+acc1+" ACC2 "+acc2+ " FIRST IAX "+ first_iax_account +" FISRT "+first_account - destination_number = "" - if acc2 == "IP2IP": - destination_number = "sip:127.0.0.1" - else: - destination_number = configurationManager.getAccountDetails(acc2)["Account.username"] - callManager.placeCall(acc1,destination_number) - calls = callManager.getCallList() - for i, v in enumerate(calls): - callManager.hangUp(v) -add_to_suit("Place call",'Many simultanious calls (IP2IP)',stress_concurent_calls) - -# Test if SFLPhone can handle more than 50 simultanious IP2IP call over localhost -# Using localhost to save bandwidth, this is about concurent calls, not network load -#def stress_concurent_calls(): - - ## Create 50 calls - #for i in range(0,50): - #callManager.placeCall(first_account,str(randint(100000000,100000000000)),"sip:127.0.0.1") - - ##TODO check if the could is right - - ## Accept all calls that worked - #calls = callManager.getCallList() - #for i, v in enumerate(calls): - #callManager.accept(v) - - ## Hang up all calls - #for i, v in enumerate(calls): - #callManager.hangUp(v) - #return {'code':0,'error':""} -#add_to_suit("Place call",'Many simultanious calls (IP2IP)',stress_concurent_calls) - - -# Test if a call can be put and removed from hold multiple time -def stress_hold_unhold_server(): - # Hang up everything left - calls = callManager.getCallList() - for i, v in enumerate(calls): - callManager.hangUp(v) - - #Place a call - callManager.placeCall(first_account,first_account_number) - calls = callManager.getCallList() - if len(calls) < 1: - return {'code':5,'error':"\nUnit test \"stress_hold_unhold\" failed: The call is gone"} - call = calls[0] - - #Hold and unhold it - for i in range(0,10): - callManager.hold(call) - details = callManager.getCallDetails(call) - if not 'CALL_STATE' in details: - return {'code':1,'error':"\nUnit test \"stress_hold_unhold\" failed: The call is gone (hold)"} - if not details['CALL_STATE'] == "HOLD": - return {'code':2,'error':"\nUnit test \"stress_hold_unhold\" failed: The call should be on hold, but is "+details['CALL_STATE']} - callManager.unhold(call) - details = callManager.getCallDetails(call) - if not 'CALL_STATE' in details: - return {'code':3,'error':"\nUnit test \"stress_hold_unhold\" failed: The call is gone (unhold)"} - if not details['CALL_STATE'] == "CURRENT": - return {'code':4,'error':"\nUnit test \"stress_hold_unhold\" failed: The call should be current, but is "+details['CALL_STATE']} - return {'code':0,'error':""} -add_to_suit("Hold call",'Hold and unhold',stress_hold_unhold_server) - -#Run the tests -run() -#kate: space-indent off; tab-indents on; mixedindent off; indent-width 4;tab-width 4; diff --git a/test/sdesnegotiatortest.cpp b/test/sdesnegotiatortest.cpp deleted file mode 100644 index 82aa0337f1..0000000000 --- a/test/sdesnegotiatortest.cpp +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <cstddef> -#include <stdio.h> -#include <sstream> -#include <cstddef> -#include <string> -#include <cstring> -#include <math.h> -#include <dlfcn.h> -#include <iostream> -#include <sstream> - -#include "sdesnegotiatortest.h" -#include "sip/pattern.h" -#include "sip/sdes_negotiator.h" - -#include <unistd.h> -#include "test_utils.h" -#include "logger.h" - -namespace ring { namespace test { - -using std::cout; -using std::endl; - -void SdesNegotiatorTest::testTagPattern() -{ - TITLE(); - std::string subject = "a=crypto:4"; - - ring::Pattern pattern("^a=crypto:(?P<tag>[0-9]{1,9})", false); - pattern.updateSubject(subject); - - CPPUNIT_ASSERT(pattern.matches()); - CPPUNIT_ASSERT(pattern.group("tag").compare("4") == 0); -} - - -void SdesNegotiatorTest::testCryptoSuitePattern() -{ - TITLE(); - std::string subject = "AES_CM_128_HMAC_SHA1_80"; - - ring::Pattern pattern("(?P<cryptoSuite>AES_CM_128_HMAC_SHA1_80|" \ - "AES_CM_128_HMAC_SHA1_32|" \ - "F8_128_HMAC_SHA1_80|" \ - "[A-Za-z0-9_]+)", false); - pattern.updateSubject(subject); - - CPPUNIT_ASSERT(pattern.matches()); - CPPUNIT_ASSERT(pattern.group("cryptoSuite").compare("AES_CM_128_HMAC_SHA1_80") == 0); -} - - -void SdesNegotiatorTest::testKeyParamsPattern() -{ - TITLE(); - - std::string subject = "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32"; - - ring::Pattern pattern("(?P<srtpKeyMethod>inline|[A-Za-z0-9_]+)\\:" \ - "(?P<srtpKeyInfo>[A-Za-z0-9\x2B\x2F\x3D]+)\\|" \ - "(2\\^(?P<lifetime>[0-9]+)\\|" \ - "(?P<mkiValue>[0-9]+)\\:" \ - "(?P<mkiLength>[0-9]{1,3})\\;?)?", true); - - pattern.updateSubject(subject); - - pattern.matches(); - CPPUNIT_ASSERT(pattern.group("srtpKeyMethod").compare("inline:")); - CPPUNIT_ASSERT(pattern.group("srtpKeyInfo").compare("d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj") - == 0); - CPPUNIT_ASSERT(pattern.group("lifetime").compare("20") == 0); - CPPUNIT_ASSERT(pattern.group("mkiValue").compare("1") == 0); - CPPUNIT_ASSERT(pattern.group("mkiLength").compare("32") == 0); -} - - -void SdesNegotiatorTest::testKeyParamsPatternWithoutMKI() -{ - TITLE(); - - std::string subject("inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj"); - - ring::Pattern pattern("(?P<srtpKeyMethod>inline|[A-Za-z0-9_]+)\\:" \ - "(?P<srtpKeyInfo>[A-Za-z0-9\x2B\x2F\x3D]+)" \ - "(\\|2\\^(?P<lifetime>[0-9]+)\\|" \ - "(?P<mkiValue>[0-9]+)\\:" \ - "(?P<mkiLength>[0-9]{1,3})\\;?)?", true); - - pattern.updateSubject(subject); - pattern.matches(); - CPPUNIT_ASSERT(pattern.group("srtpKeyMethod").compare("inline:")); - CPPUNIT_ASSERT(pattern.group("srtpKeyInfo").compare("d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj") - == 0); -} - - -/** - * Make sure that all the fields can be extracted - * properly from the syntax. - */ -void SdesNegotiatorTest::testNegotiation() -{ - TITLE(); - - // Add a new SDES crypto line to be processed. - std::vector<std::string> remoteOffer; - remoteOffer.push_back("a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwd|2^20|1:32"); - remoteOffer.push_back("a=crypto:2 AES_CM_128_HMAC_SHA1_32 inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32"); - - // Register the local capabilities. - std::vector<ring::CryptoSuiteDefinition> localCapabilities; - - for (int i = 0; i < 3; ++i) - localCapabilities.push_back(ring::CryptoSuites[i]); - - ring::SdesNegotiator sdesnego(localCapabilities, remoteOffer); - - CPPUNIT_ASSERT(sdesnego.negotiate()); -} - -/** - * Make sure that unproperly formatted crypto lines are rejected. - */ -void SdesNegotiatorTest::testComponent() -{ - TITLE(); - - // Register the local capabilities. - std::vector<ring::CryptoSuiteDefinition> capabilities; - - // Support all the CryptoSuites - for (int i = 0; i < 3; i++) - capabilities.push_back(ring::CryptoSuites[i]); - - // Make sure that if a component is missing, negotiate will fail - std::string cryptoLine("a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:|2^20|1:32"); - std::vector<std::string> cryptoOffer; - cryptoOffer.push_back(cryptoLine); - - ring::SdesNegotiator negotiator(capabilities, cryptoOffer); - CPPUNIT_ASSERT(!negotiator.negotiate()); -} - -/** - * Make sure that most simple case does not fail. - */ -void SdesNegotiatorTest::testMostSimpleCase() -{ - TITLE(); - - // Register the local capabilities. - std::vector<ring::CryptoSuiteDefinition> capabilities; - - // Support all the CryptoSuites - for (int i = 0; i < 3; i++) - capabilities.push_back(ring::CryptoSuites[i]); - - // Make sure taht this case works (since it's default for most application) - std::string cryptoLine("a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwd"); - std::vector<std::string> cryptoOffer; - cryptoOffer.push_back(cryptoLine); - - ring::SdesNegotiator negotiator(capabilities, cryptoOffer); - - CPPUNIT_ASSERT(negotiator.negotiate()); - - CPPUNIT_ASSERT(negotiator.getCryptoSuite() == "AES_CM_128_HMAC_SHA1_80"); - CPPUNIT_ASSERT(negotiator.getKeyMethod() == "inline"); - CPPUNIT_ASSERT(negotiator.getKeyInfo() == "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwd"); - CPPUNIT_ASSERT(negotiator.getLifeTime().empty()); - CPPUNIT_ASSERT(negotiator.getMkiValue().empty()); - CPPUNIT_ASSERT(negotiator.getMkiLength().empty()); - CPPUNIT_ASSERT(negotiator.getAuthTagLength() == "80"); -} - - -void SdesNegotiatorTest::test32ByteKeyLength() -{ - TITLE(); - - // Register the local capabilities. - std::vector<ring::CryptoSuiteDefinition> capabilities; - - //Support all the CryptoSuites - for (int i = 0; i < 3; i++) - capabilities.push_back(ring::CryptoSuites[i]); - - std::string cryptoLine("a=crypto:1 AES_CM_128_HMAC_SHA1_32 inline:AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwd"); - std::vector<std::string> cryptoOffer; - cryptoOffer.push_back(cryptoLine); - - ring::SdesNegotiator negotiator(capabilities, cryptoOffer); - - CPPUNIT_ASSERT(negotiator.negotiate()); - - CPPUNIT_ASSERT(negotiator.getCryptoSuite() == "AES_CM_128_HMAC_SHA1_32"); - CPPUNIT_ASSERT(negotiator.getKeyMethod() == "inline"); - CPPUNIT_ASSERT(negotiator.getKeyInfo() == "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwd"); - CPPUNIT_ASSERT(negotiator.getLifeTime().empty()); - CPPUNIT_ASSERT(negotiator.getMkiValue().empty()); - CPPUNIT_ASSERT(negotiator.getMkiLength().empty()); - CPPUNIT_ASSERT(negotiator.getAuthTagLength() == "32"); -} - -}} // namespace ring::test diff --git a/test/sdesnegotiatortest.h b/test/sdesnegotiatortest.h deleted file mode 100644 index 9eafa45d88..0000000000 --- a/test/sdesnegotiatortest.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -// Cppunit import -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/TestCaller.h> -#include <cppunit/TestCase.h> -#include <cppunit/TestSuite.h> - -#include <cstddef> -#include <stdio.h> -#include <sstream> - -#include <vector> - -// pjsip import -#include <pjsip.h> -#include <pjlib.h> -#include <pjsip_ua.h> -#include <pjlib-util.h> -#include <pjnath/stun_config.h> - -#include "noncopyable.h" - -/* - * @file sdesnegotiationTest.cpp - * @brief Regroups unitary tests related to the plugin manager. - */ - -#ifndef __SDESNEGOTIATOR_TEST_H__ -#define __SDESNEGOTIATOR_TEST_H__ - -#include "sip/sdes_negotiator.h" // for CryptoSuiteDefinition - -namespace ring { namespace test { - -class Pattern; - -class SdesNegotiatorTest : public CppUnit::TestCase { - - /* - * Use cppunit library macros to add unit test the factory - */ - CPPUNIT_TEST_SUITE(SdesNegotiatorTest); - CPPUNIT_TEST(testTagPattern); - CPPUNIT_TEST(testCryptoSuitePattern); - CPPUNIT_TEST(testKeyParamsPattern); - CPPUNIT_TEST(testKeyParamsPatternWithoutMKI); - CPPUNIT_TEST(testNegotiation); - CPPUNIT_TEST(testMostSimpleCase); - CPPUNIT_TEST(test32ByteKeyLength); - CPPUNIT_TEST_SUITE_END(); - - public: - /* - * Code factoring - Common resources can be released here. - * This method is called by unitcpp after each test - */ - void testTagPattern(); - - void testCryptoSuitePattern(); - - void testKeyParamsPattern(); - - void testKeyParamsPatternCiscoStyle(); - - void testKeyParamsPatternWithoutMKI(); - - void testNegotiation(); - - void testComponent(); - - void testMostSimpleCase(); - - void test32ByteKeyLength(); -}; - -/* Register our test module */ -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(SdesNegotiatorTest, "SdesNegotiatorTest"); -CPPUNIT_TEST_SUITE_REGISTRATION(SdesNegotiatorTest); - -}} // namespace ring::test - -#endif // __SDESNEGOTIATOR_TEST_H__ diff --git a/test/sdptest.cpp b/test/sdptest.cpp deleted file mode 100644 index 5dd5802345..0000000000 --- a/test/sdptest.cpp +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -/* - * ebail - 2015/02/18 - * unit test is based on old SDP manager code - * this test is disabled for the moment - * */ -#if 0 -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include "sdptest.h" -#include <iostream> -#include <cstring> - -#include "audio/codecs/audiocodec.h" - -namespace ring { namespace test { - -enum session_type { - REMOTE_OFFER, - LOCAL_OFFER, -}; - -static const char *sdp_answer1 = "v=0\r\n" - "o=bob 2890844730 2890844730 IN IP4 host.example.com\r\n" - "s= \r\n" - "c=IN IP4 host.example.com\r\n" - "t=0 0\r\n" - "m=audio 49920 RTP/AVP 0\r\n" - "a=rtpmap:0 PCMU/8000\r\n" - "m=video 53002 RTP/AVP 32\r\n" - "a=rtpmap:32 MPV/90000\r\n"; - -static const char *sdp_offer1 = "v=0\r\n" - "o=bob 2890844730 2890844730 IN IP4 host.example.com\r\n" - "s= \r\n" - "c=IN IP4 host.example.com\r\n" - "t=0 0\r\n" - "m=audio 49920 RTP/AVP 0\r\n" - "a=rtpmap:0 PCMU/8000\r\n" - "m=video 53002 RTP/AVP 32\r\n" - "a=rtpmap:32 MPV/90000\r\n"; - -static const char *sdp_answer2 = "v=0\r\n" - "o=bob 2890844730 2890844730 IN IP4 host.example.com\r\n" - "s= \r\n" - "c=IN IP4 host.example.com\r\n" - "t=0 0\r\n" - "m=audio 49920 RTP/AVP 3 97 9\r\n" - "a=rtpmap:3 GSM/8000\r\n" - "a=rtpmap:97 iLBC/8000\r\n" - "a=rtpmap:9 G722/8000\r\n" - "m=video 53002 RTP/AVP 32\r\n" - "a=rtpmap:32 MPV/90000\r\n"; - -static const char *sdp_offer2 = "v=0\r\n" - "o=bob 2890844730 2890844730 IN IP4 host.example.com\r\n" - "s= \r\n" - "c=IN IP4 host.example.com\r\n" - "t=0 0\r\n" - "m=audio 49920 RTP/AVP 3 97 9\r\n" - "a=rtpmap:3 GSM/8000\r\n" - "a=rtpmap:97 iLBC/8000\r\n" - "a=rtpmap:9 G722/8000\r\n" - "m=video 53002 RTP/AVP 32\r\n" - "a=rtpmap:32 MPV/90000\r\n"; - -static const char *sdp_reinvite = "v=0\r\n" - "o=bob 2890844730 2890844730 IN IP4 host.example.com\r\n" - "s= \r\n" - "c=IN IP4 host.exampleReinvite.com\r\n" - "t=0 0\r\n" - "m=audio 42445 RTP/AVP 0\r\n" - "a=rtpmap:0 PCMU/8000\r\n" - "m=video 53002 RTP/AVP 32\r\n" - "a=rtpmap:32 MPV/90000\r\n"; - -static const char *const LOCALHOST = "127.0.0.1"; - -void SDPTest::setUp() -{ - session_.reset(new Sdp("123456789")); -} - -void SDPTest::tearDown() -{ - session_.reset(); -} - -void SDPTest::receiveAnswerAfterInitialOffer(const pjmedia_sdp_session* remote) -{ - CPPUNIT_ASSERT(pjmedia_sdp_neg_get_state(session_->negotiator_) == PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER); - CPPUNIT_ASSERT(pjmedia_sdp_neg_set_remote_answer(session_->memPool_.get(), session_->negotiator_, remote) == PJ_SUCCESS); - CPPUNIT_ASSERT(pjmedia_sdp_neg_get_state(session_->negotiator_) == PJMEDIA_SDP_NEG_STATE_WAIT_NEGO); -} - -namespace { -std::vector<std::map<std::string, std::string> > - createVideoCodecs() { - std::vector<std::map<std::string, std::string> > videoCodecs; -#ifdef RING_VIDEO - std::map<std::string, std::string> codec; - codec["name"] = "H264"; - codec["enabled"] = "true"; - videoCodecs.push_back(codec); - codec["name"] = "H263"; - videoCodecs.push_back(codec); -#endif - return videoCodecs; - } -} - -void SDPTest::testInitialOfferFirstCodec() -{ - std::cout << "------------ SDPTest::testInitialOfferFirstCodec --------------" << std::endl; - - CPPUNIT_ASSERT(session_->getPublishedIP().empty()); - CPPUNIT_ASSERT(session_->getRemoteIP().empty()); - - std::vector<int> codecSelection; - - codecSelection.push_back(PAYLOAD_CODEC_ULAW); - codecSelection.push_back(PAYLOAD_CODEC_ALAW); - codecSelection.push_back(PAYLOAD_CODEC_G722); - - std::vector<std::map<std::string, std::string> > videoCodecs(createVideoCodecs()); - - session_->setPublishedIP(LOCALHOST); - session_->setLocalPublishedAudioPort(49567); - - session_->createOffer(codecSelection, videoCodecs); - - pjmedia_sdp_session *remoteAnswer; - pjmedia_sdp_parse(session_->memPool_.get(), (char*) sdp_answer1, strlen(sdp_answer1), &remoteAnswer); - - receiveAnswerAfterInitialOffer(remoteAnswer); - session_->startNegotiation(); - - session_->setMediaTransportInfoFromRemoteSdp(); - - CPPUNIT_ASSERT(session_->getPublishedIP() == LOCALHOST); - CPPUNIT_ASSERT(session_->getRemoteIP() == "host.example.com"); -} - -void SDPTest::testInitialAnswerFirstCodec() -{ - std::cout << "------------ SDPTest::testInitialAnswerFirstCodec -------------" << std::endl; - - CPPUNIT_ASSERT(session_->getPublishedIP().empty()); - CPPUNIT_ASSERT(session_->getRemoteIP().empty()); - - std::vector<int> codecSelection; - pjmedia_sdp_session *remoteOffer; - - codecSelection.push_back(PAYLOAD_CODEC_ULAW); - codecSelection.push_back(PAYLOAD_CODEC_ALAW); - codecSelection.push_back(PAYLOAD_CODEC_G722); - - pjmedia_sdp_parse(session_->memPool_.get(), (char*) sdp_offer1, strlen(sdp_offer1), &remoteOffer); - - session_->setPublishedIP(LOCALHOST); - session_->setLocalPublishedAudioPort(49567); - - session_->receiveOffer(remoteOffer, codecSelection, createVideoCodecs()); - - session_->startNegotiation(); - - session_->setMediaTransportInfoFromRemoteSdp(); - - CPPUNIT_ASSERT(session_->getPublishedIP() == LOCALHOST); - CPPUNIT_ASSERT(session_->getRemoteIP() == "host.example.com"); -} - -void SDPTest::testInitialOfferLastCodec() -{ - std::cout << "------------ SDPTest::testInitialOfferLastCodec --------------------" << std::endl; - - CPPUNIT_ASSERT(session_->getPublishedIP().empty()); - CPPUNIT_ASSERT(session_->getRemoteIP().empty()); - - std::vector<int> codecSelection; - - codecSelection.push_back(PAYLOAD_CODEC_ULAW); - codecSelection.push_back(PAYLOAD_CODEC_ALAW); - codecSelection.push_back(PAYLOAD_CODEC_G722); - - session_->setPublishedIP(LOCALHOST); - session_->setLocalPublishedAudioPort(49567); - - session_->createOffer(codecSelection, createVideoCodecs()); - - pjmedia_sdp_session *remoteAnswer; - pjmedia_sdp_parse(session_->memPool_.get(), (char*) sdp_answer2, strlen(sdp_answer2), &remoteAnswer); - - receiveAnswerAfterInitialOffer(remoteAnswer); - session_->startNegotiation(); - - session_->setMediaTransportInfoFromRemoteSdp(); - - CPPUNIT_ASSERT(session_->getPublishedIP() == LOCALHOST); - CPPUNIT_ASSERT(session_->getRemoteIP() == "host.example.com"); -} - -void SDPTest::testInitialAnswerLastCodec() -{ - std::cout << "------------ SDPTest::testInitialAnswerLastCodec ------------" << std::endl; - - CPPUNIT_ASSERT(session_->getPublishedIP().empty()); - CPPUNIT_ASSERT(session_->getRemoteIP().empty()); - - std::vector<int> codecSelection; - pjmedia_sdp_session *remoteOffer; - - codecSelection.push_back(PAYLOAD_CODEC_ULAW); - codecSelection.push_back(PAYLOAD_CODEC_ALAW); - codecSelection.push_back(PAYLOAD_CODEC_G722); - - pjmedia_sdp_parse(session_->memPool_.get(), (char*)sdp_offer2, strlen(sdp_offer2), &remoteOffer); - - session_->setPublishedIP(LOCALHOST); - session_->setLocalPublishedAudioPort(49567); - - session_->receiveOffer(remoteOffer, codecSelection, createVideoCodecs()); - - session_->startNegotiation(); - - session_->setMediaTransportInfoFromRemoteSdp(); - - CPPUNIT_ASSERT(session_->getPublishedIP() == LOCALHOST); - CPPUNIT_ASSERT(session_->getRemoteIP() == "host.example.com"); -} - - -void SDPTest::testReinvite() -{ - std::cout << "------------ SDPTest::testReinvite --------------------" << std::endl; - - CPPUNIT_ASSERT(session_->getPublishedIP().empty()); - CPPUNIT_ASSERT(session_->getRemoteIP().empty()); - - std::vector<int> codecSelection; - codecSelection.push_back(PAYLOAD_CODEC_ULAW); - codecSelection.push_back(PAYLOAD_CODEC_ALAW); - codecSelection.push_back(PAYLOAD_CODEC_G722); - - session_->setPublishedIP(LOCALHOST); - session_->setLocalPublishedAudioPort(49567); - - std::vector<std::map<std::string, std::string> > videoCodecs(createVideoCodecs()); - session_->createOffer(codecSelection, videoCodecs); - - pjmedia_sdp_session *remoteAnswer; - // pjmedia_sdp_parse(session_->memPool_.get(), test[0].offer_answer[0].sdp2, strlen(test[0].offer_answer[0].sdp2), &remoteAnswer); - pjmedia_sdp_parse(session_->memPool_.get(), (char*) sdp_answer1, strlen(sdp_answer1), &remoteAnswer); - - receiveAnswerAfterInitialOffer(remoteAnswer); - session_->startNegotiation(); - - session_->setMediaTransportInfoFromRemoteSdp(); - - CPPUNIT_ASSERT(session_->getPublishedIP() == LOCALHOST); - CPPUNIT_ASSERT(session_->getRemoteIP() == "host.example.com"); - std::vector<ring::AudioCodec*> codecs(session_->getSessionAudioMedia()); - ring::AudioCodec *codec = codecs[0]; - CPPUNIT_ASSERT(codec and codec->getMimeSubtype() == "PCMU"); - - pjmedia_sdp_session *reinviteOffer; - pjmedia_sdp_parse(session_->memPool_.get(), (char*) sdp_reinvite, strlen(sdp_reinvite), &reinviteOffer); - session_->receiveOffer(reinviteOffer, codecSelection, videoCodecs); - - session_->startNegotiation(); - session_->setMediaTransportInfoFromRemoteSdp(); - - CPPUNIT_ASSERT(session_->getRemoteIP() == "host.exampleReinvite.com"); -} - -}} // namespace ring::test -#endif diff --git a/test/sdptest.h b/test/sdptest.h deleted file mode 100644 index fd36a935ba..0000000000 --- a/test/sdptest.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -/* - * @file sdptest.h - * @brief Regroups unitary tests related to the SDP session - */ - -#ifndef _SDP_TEST_ -#define _SDP_TEST_ - -// Cppunit import -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/TestCaller.h> -#include <cppunit/TestCase.h> -#include <cppunit/TestSuite.h> - -#include <exception> -#include <string> -#include <memory> - -#include <pj/pool.h> -#include <pjmedia/sdp.h> -#include <pjmedia/sdp_neg.h> -#include <pjmedia/errno.h> -#include <pjsip/sip_transport.h> -#include <pjlib.h> -#include <pjsip_ua.h> - -#include "sip/sdp.h" -#include "noncopyable.h" - -namespace ring { namespace test { -/* - * ebail - 2015/02/18 - * unit test is based on old SDP manager code - * this test is disabled for the moment - * */ -#if 0 - -class SdpSessionException : public std::exception { - public: - SdpSessionException(const std::string& str="") throw() : errstr(str) {} - - virtual ~SdpSessionException() throw() {} - - virtual const char *what() const throw() { - std::string expt("SdpSession: SdpSessionException occurred: "); - expt.append(errstr); - return expt.c_str(); - } - private: - std::string errstr; -}; - - -class SDPTest : public CppUnit::TestCase { - - /** - * Use cppunit library macros to add unit test the factory - */ - CPPUNIT_TEST_SUITE(SDPTest); - CPPUNIT_TEST(testInitialOfferLastCodec); - CPPUNIT_TEST(testInitialAnswerLastCodec); - CPPUNIT_TEST(testInitialOfferLastCodec); - CPPUNIT_TEST(testInitialAnswerLastCodec); - CPPUNIT_TEST(testReinvite); - CPPUNIT_TEST_SUITE_END(); - - public: - SDPTest() : CppUnit::TestCase("SDP module Tests") {} - - /** - * Code factoring - Common resources can be initialized here. - * This method is called by unitcpp before each test - */ - void setUp(); - - /** - * Code factoring - Common resources can be released here. - * This method is called by unitcpp after each test - */ - void tearDown(); - - void testInitialOfferFirstCodec(); - - void testInitialAnswerFirstCodec(); - - void testInitialOfferLastCodec(); - - void testInitialAnswerLastCodec(); - - void testReinvite(); - - private: - NON_COPYABLE(SDPTest); - void receiveAnswerAfterInitialOffer(const pjmedia_sdp_session* remote); - - std::unique_ptr<Sdp> session_; -}; - -/* Register our test module */ -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(SDPTest, "SDPTest"); -CPPUNIT_TEST_SUITE_REGISTRATION(SDPTest); - -}} // namespace ring::test - -#endif -#endif //_SDP_TEST_ diff --git a/test/sippxml/test_1.xml b/test/sippxml/test_1.xml deleted file mode 100644 index 7092639357..0000000000 --- a/test/sippxml/test_1.xml +++ /dev/null @@ -1,157 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> -<!DOCTYPE scenario SYSTEM "sipp.dtd"> - -<!-- This program is free software; you can redistribute it and/or --> -<!-- modify it under the terms of the GNU General Public License as --> -<!-- published by the Free Software Foundation; either version 2 of the --> -<!-- License, or (at your option) any later version. --> -<!-- --> -<!-- This program is distributed in the hope that it will be useful, --> -<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of --> -<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --> -<!-- GNU General Public License for more details. --> -<!-- --> -<!-- You should have received a copy of the GNU General Public License --> -<!-- along with this program; if not, write to the --> -<!-- Free Software Foundation, Inc., --> -<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --> -<!-- --> -<!-- Sipp default 'uas' scenario. --> -<!-- --> - -<scenario name="UAS responder put on hold then hungup"> - - <!-- This scenario implies a second call made by the uac which implies --> - <!-- This call to be put on hold automatically --> - - <recv request="INVITE" crlf="true"> - </recv> - - <send> - <![CDATA[ - - SIP/2.0 180 Ringing - [last_Via:] - [last_From:] - [last_To:];tag=[pid]SIPpTag01[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <send retrans="500"> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[pid]SIPpTag01[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv request="ACK" - optional="true" - rtd="true" - crlf="true"> - </recv> - - - <!-- Here process a second invite with updated sdp, this call is placed on HOLD --> - <!-- TODO: parse in sdp: Media Attribute (a): sendonly --> - <recv request="INVITE" crlf="true"> - </recv> - - <send> - <![CDATA[ - - SIP/2.0 100 Trying - [last_Via:] - [last_From:] - [last_To:];tag=[pid]SIPpTag01[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <send retrans="500"> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[pid]SIPpTag01[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv request="ACK" - optional="true" - rtd="true" - crlf="true"> - </recv> - - <!-- expect to be hung up immediately --> - <recv request="BYE"> - </recv> - - <send> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <!-- Keep the call open for a while in case the 200 is lost to be --> - <!-- able to retransmit it if we receive the BYE again. --> - <timewait milliseconds="4000"/> - - - <!-- definition of the response time repartition table (unit is ms) --> - <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/> - - <!-- definition of the call length repartition table (unit is ms) --> - <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/> - -</scenario> - diff --git a/test/sippxml/test_2.xml b/test/sippxml/test_2.xml deleted file mode 100644 index fa3b9c129e..0000000000 --- a/test/sippxml/test_2.xml +++ /dev/null @@ -1,161 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> -<!DOCTYPE scenario SYSTEM "sipp.dtd"> - -<!-- This program is free software; you can redistribute it and/or --> -<!-- modify it under the terms of the GNU General Public License as --> -<!-- published by the Free Software Foundation; either version 2 of the --> -<!-- License, or (at your option) any later version. --> -<!-- --> -<!-- This program is distributed in the hope that it will be useful, --> -<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of --> -<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --> -<!-- GNU General Public License for more details. --> -<!-- --> -<!-- You should have received a copy of the GNU General Public License --> -<!-- along with this program; if not, write to the --> -<!-- Free Software Foundation, Inc., --> -<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --> -<!-- --> -<!-- Sipp default 'uac' scenario. --> -<!-- --> - -<scenario name="Two simultaneous outgoing call Sipstone UAC"> - <!-- In client mode (sipp placing calls), the Call-ID MUST be --> - <!-- generated by sipp. To do so, use [call_id] keyword. --> - <send retrans="500"> - <![CDATA[ - - INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] - From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number] - To: sut <sip:[service]@[remote_ip]:[remote_port]> - Call-ID: [call_id] - CSeq: 1 INVITE - Contact: sip:sipp@[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Performance Test - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv response="100" optional="true"> - </recv> - - <recv response="180" optional="true"> - </recv> - - <recv response="183" optional="true"> - </recv> - - <!-- By adding rrs="true" (Record Route Sets), the route sets --> - <!-- are saved and used for following messages sent. Useful to test --> - <!-- against stateful SIP proxies/B2BUAs. --> - <recv response="200" rtd="true"> - </recv> - - <!-- Packet lost can be simulated in any send/recv message by --> - <!-- by adding the 'lost = "10"'. Value can be [1-100] percent. --> - <send> - <![CDATA[ - - ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] - From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number] - To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param] - Call-ID: [call_id] - CSeq: 1 ACK - Contact: sip:sipp@[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Performance Test - Content-Length: 0 - - ]]> - </send> - - <!-- Here is where the call is put on hold --> - <recv request="INVITE" crlf="true"> - </recv> - - <send> - <![CDATA[ - - SIP/2.0 100 Trying - [last_Via:] - [last_From:] - [last_To:];tag=[pid]SIPpTag01[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <send retrans="500"> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[pid]SIPpTag01[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv request="ACK" - rtd="true" - crlf="true"> - </recv> - - <!-- The 'crlf' option inserts a blank line in the statistics report. --> - <send retrans="500"> - <![CDATA[ - - BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] - From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number] - To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param] - Call-ID: [call_id] - CSeq: 2 BYE - Contact: sip:sipp@[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Performance Test - Content-Length: 0 - - ]]> - </send> - - <recv response="200" crlf="true"> - </recv> - - <!-- definition of the response time repartition table (unit is ms) --> - <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/> - - <!-- definition of the call length repartition table (unit is ms) --> - <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/> - -</scenario> - diff --git a/test/sippxml/test_3.xml b/test/sippxml/test_3.xml deleted file mode 100644 index bae7eaa2bc..0000000000 --- a/test/sippxml/test_3.xml +++ /dev/null @@ -1,187 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE scenario SYSTEM "sipp.dtd"> - - -<scenario name="UAS HOLD/OFFHOLD"> - - <!-- Receive a new call --> - - <recv request="INVITE" crlf="true"> - <action> - <ereg regexp="sendrecv" search_in="body" check_it="true" assign_to="1"/> - <log message="Media is [$1]"/> - </action> - </recv> - - <send> - <![CDATA[ - - SIP/2.0 180 Ringing - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <send retrans="500"> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> -</send> - - <recv request="ACK" optional="true" rtd="true" crlf="true"> - </recv> - - <!-- This call is now on HOLD: sendonly tell to PBX to send music on hold--> - - <recv request="INVITE" crlf="true"> - <action> - <ereg regexp="sendonly" search_in="body" check_it="true" assign_to="2"/> - <log message="Media is [$2]"/> - </action> - </recv> - - <send> - <![CDATA[ - - SIP/2.0 180 Ringing - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <send retrans="500"> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv request="ACK" optional="true" rtd="true" crlf="true"> - </recv> - - <!-- OFFHOLD this call --> - - <recv request="INVITE" crlf="true"> - <action> - <ereg regexp="sendrecv" search_in="body" check_it="true" assign_to="3"/> - <log message="Media is [$3]"/> - </action> - </recv> - - - <send> - <![CDATA[ - - SIP/2.0 180 Ringing - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <send retrans="500"> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv request="ACK" optional="true" rtd="true" crlf="true"> - </recv> - - <!-- Hangup this call --> - - <recv request="BYE"> - </recv> - - <send> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <pause milliseconds="4000"/> - - - <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/> - - <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/> - -</scenario> diff --git a/test/sippxml/test_4.xml b/test/sippxml/test_4.xml deleted file mode 100644 index d241bfe3b6..0000000000 --- a/test/sippxml/test_4.xml +++ /dev/null @@ -1,122 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> -<!DOCTYPE scenario SYSTEM "sipp.dtd"> - -<!-- This program is free software; you can redistribute it and/or --> -<!-- modify it under the terms of the GNU General Public License as --> -<!-- published by the Free Software Foundation; either version 2 of the --> -<!-- License, or (at your option) any later version. --> -<!-- --> -<!-- This program is distributed in the hope that it will be useful, --> -<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of --> -<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --> -<!-- GNU General Public License for more details. --> -<!-- --> -<!-- You should have received a copy of the GNU General Public License --> -<!-- along with this program; if not, write to the --> -<!-- Free Software Foundation, Inc., --> -<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --> -<!-- --> -<!-- Sipp default 'uac' scenario. --> -<!-- --> - -<scenario name="Basic Sipstone UAC"> - <!-- In client mode (sipp placing calls), the Call-ID MUST be --> - <!-- generated by sipp. To do so, use [call_id] keyword. -- - <send retrans="500"> - <![CDATA[ - - INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] - From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number] - To: sut <sip:[service]@[remote_ip]:[remote_port]> - Call-ID: [call_id] - CSeq: 1 INVITE - Contact: sip:sipp@[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Performance Test - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv response="100" - optional="true"> - </recv> - - <recv response="180" optional="true"> - </recv> - - <recv response="183" optional="true"> - </recv> - - <!-- By adding rrs="true" (Record Route Sets), the route sets --> - <!-- are saved and used for following messages sent. Useful to test --> - <!-- against stateful SIP proxies/B2BUAs. --> - <recv response="200" rtd="true"> - <action> - <ereg regexp="a=rtpmap:0 PCMU/8000" search_in="body" check_it="true" assign_to="1" /> - <log message="Custom header is [$1]"/> - </action> - </recv> - - <!-- Packet lost can be simulated in any send/recv message by --> - <!-- by adding the 'lost = "10"'. Value can be [1-100] percent. --> - <send> - <![CDATA[ - - ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] - From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number] - To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param] - Call-ID: [call_id] - CSeq: 1 ACK - Contact: sip:sipp@[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Performance Test - Content-Length: 0 - - ]]> - </send> - - <!-- This delay can be customized by the -d command-line option --> - <!-- or by adding a 'milliseconds = "value"' option here. --> - <pause/> - - <!-- The 'crlf' option inserts a blank line in the statistics report. --> - <send retrans="500"> - <![CDATA[ - - BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] - From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number] - To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param] - Call-ID: [call_id] - CSeq: 2 BYE - Contact: sip:sipp@[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Performance Test - Content-Length: 0 - - ]]> - </send> - - <recv response="200" crlf="true"> - </recv> - - <!-- definition of the response time repartition table (unit is ms) --> - <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/> - - <!-- definition of the call length repartition table (unit is ms) --> - <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/> - -</scenario> - diff --git a/test/siptest.cpp b/test/siptest.cpp deleted file mode 100644 index c3a4078533..0000000000 --- a/test/siptest.cpp +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -/* - * ebail - 2015/02/18 - * unit test is deprecated - * this test is disabled for the moment - * */ -#if 0 - -#include <unistd.h> -#include <cstdlib> -#include <cstdio> -#include <iostream> -#include <fstream> - -#include <pthread.h> -#include <string> - -#include "siptest.h" -#include "manager.h" -#include "sip/sipvoiplink.h" -#include "sip/sip_utils.h" -#include "sip/sipcall.h" - -// anonymous namespace -namespace { -pthread_mutex_t count_mutex; -pthread_cond_t count_nb_thread; -int counter = 0; -} - -namespace ring { namespace test { - -void *sippThreadWithCount(void *str) -{ - pthread_mutex_lock(&count_mutex); - counter++; - pthread_mutex_unlock(&count_mutex); - - std::string *command = (std::string *)(str); - - std::cout << "SIPTest: " << command << std::endl; - - // Set up the sipp instance in this thread in order to catch return value - // 0: All calls were successful - // 1: At least one call failed - // 97: exit on internal command. Calls may have been processed - // 99: Normal exit without calls processed - // -1: Fatal error - // -2: Fatal error binding a socket - int i = system(command->c_str()); - - CPPUNIT_ASSERT(i); - - pthread_mutex_lock(&count_mutex); - counter--; - - if (counter == 0) - pthread_cond_signal(&count_nb_thread); - - pthread_mutex_unlock(&count_mutex); - - pthread_exit(NULL); -} - - -void *sippThread(void *str) -{ - std::string *command = static_cast<std::string *>(str); - std::cout << "SIPTest: " << command << std::endl; - - // Set up the sipp instance in this thread in order to catch return value - // 0: All calls were successful - // 1: At least one call failed - // 97: exit on internal command. Calls may have been processed - // 99: Normal exit without calls processed - // -1: Fatal error - // -2: Fatal error binding a socket - int i = system(command->c_str()); - - std::stringstream output; - output << i; - - std::cout << "SIPTest: Command executed by system returned: " << output.str() << std::endl; - pthread_exit(NULL); -} - - -void SIPTest::setUp() -{ - pthread_mutex_lock(&count_mutex); - counter = 0; - pthread_mutex_unlock(&count_mutex); -} - -void SIPTest::tearDown() -{ - // in order to stop any currently running threads - std::cout << "SIPTest: Clean all remaining sipp instances" << std::endl; - int ret = system("killall sipp"); - - if (!ret) - std::cout << "SIPTest: Error from system call, killall sipp" << std::endl; -} - - -void SIPTest::testSimpleOutgoingIpCall() -{ - pthread_t thethread; - - // command to be executed by the thread, user agent server waiting for a call - std::string command("sipp -sn uas -i 127.0.0.1 -p 5068 -m 1 -bg"); - - int rc = pthread_create(&thethread, NULL, sippThread, &command); - - if (rc) - std::cout << "SIPTest: RING_ERR; return code from pthread_create()" << std::endl; - - std::string testaccount("IP2IP"); - std::string testcallid("callid1234"); - std::string testcallnumber("sip:test@127.0.0.1:5068"); - - CPPUNIT_ASSERT(!Manager::instance().hasCurrentCall()); - - // start a new call sending INVITE message to sipp instance - Manager::instance().outgoingCall(testaccount, testcallid, testcallnumber); - - // must sleep here until receiving 180 and 200 message from peer - sleep(2); - - CPPUNIT_ASSERT(Manager::instance().hasCurrentCall()); - CPPUNIT_ASSERT(Manager::instance().getCurrentCallId() == testcallid); - - Manager::instance().hangupCall(testcallid); - - rc = pthread_join(thethread, NULL); - - if (rc) - std::cout << "SIPTest: RING_ERR; return code from pthread_join(): " << rc << std::endl; - else - std::cout << "SIPTest: completed join with thread" << std::endl; -} - - -void SIPTest::testSimpleIncomingIpCall() -{ - pthread_t thethread; - - // command to be executed by the thread, user agent client which initiate a call and hangup - std::string command("sipp -sn uac 127.0.0.1 -i 127.0.0.1 -p 5062 -m 1i -bg"); - - int rc = pthread_create(&thethread, NULL, sippThread, &command); - - if (rc) - std::cout << "SIPTest: RING_ERR; return code from pthread_create()" << std::endl; - - // sleep a while to make sure that sipp insdtance is initialized and dring received - // the incoming invite. - sleep(2); - - CPPUNIT_ASSERT(Manager::instance().callFactory.callCount<SIPCall>() == 1); - - // Answer this call - const auto& calls = Manager::instance().callFactory.getAllCalls<SIPCall>(); - const auto call = *calls.cbegin(); - CPPUNIT_ASSERT(Manager::instance().answerCall(call->getCallId())); - - sleep(1); - - rc = pthread_join(thethread, NULL); - - if (rc) - std::cout << "SIPTest: RING_ERR; return code from pthread_join(): " << rc << std::endl; - else - std::cout << "SIPTest: completed join with thread" << std::endl; -} - - -void SIPTest::testTwoOutgoingIpCall() -{ - // This scenario expect to be put on hold before hangup - std::string firstCallCommand("sipp -sf tools/sippxml/test_1.xml -i 127.0.0.1 -p 5062 -m 1"); - - // The second call uses the default user agent scenario - std::string secondCallCommand("sipp -sn uas -i 127.0.0.1 -p 5064 -m 1"); - - pthread_t firstCallThread; - int rc = pthread_create(&firstCallThread, NULL, sippThread, &firstCallCommand); - - if (rc) - std::cout << "SIPTest: RING_ERR; return code from pthread_create()" << std::endl; - - pthread_t secondCallThread; - rc = pthread_create(&secondCallThread, NULL, sippThread, &secondCallCommand); - - if (rc) - std::cout << "SIPTest: RING_ERR; return code from pthread_create()" << std::endl; - - sleep(1); - - std::string testAccount("IP2IP"); - - std::string firstCallID("callid1234"); - std::string firstCallNumber("sip:test@127.0.0.1:5062"); - - std::string secondCallID("callid2345"); - std::string secondCallNumber("sip:test@127.0.0.1:5064"); - - CPPUNIT_ASSERT(!Manager::instance().hasCurrentCall()); - - // start a new call sending INVITE message to sipp instance - // this call should be put on hold when making the second call - Manager::instance().outgoingCall(testAccount, firstCallID, firstCallNumber); - - // must sleep here until receiving 180 and 200 message from peer - sleep(1); - - Manager::instance().outgoingCall(testAccount, secondCallID, secondCallNumber); - - sleep(1); - - Manager::instance().hangupCall(firstCallID); - - rc = pthread_join(firstCallThread, NULL); - - if (rc) - std::cout << "SIPTest: RING_ERR; return code from pthread_join(): " << rc << std::endl; - - std::cout << "SIPTest: completed join with thread" << std::endl; - - Manager::instance().hangupCall(secondCallID); - - rc = pthread_join(secondCallThread, NULL); - - if (rc) - std::cout << "SIPTest: RING_ERR; return code from pthread_join(): " << rc << std::endl; - else - std::cout << "SIPTest: completed join with thread" << std::endl; -} - -void SIPTest::testTwoIncomingIpCall() -{ - pthread_mutex_init(&count_mutex, NULL); - pthread_cond_init(&count_nb_thread, NULL); - - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - - // the first call is supposed to be put on hold when answering teh second incoming call - std::string firstCallCommand("sipp -sf tools/sippxml/test_2.xml 127.0.0.1 -i 127.0.0.1 -p 5064 -m 1 > testfile1.txt -bg"); - - // command to be executed by the thread, user agent client which initiate a call and hangup - std::string secondCallCommand("sipp -sn uac 127.0.0.1 -i 127.0.0.1 -p 5062 -m 1 -d 250 > testfile2.txt -bg"); - - pthread_t firstCallThread; - int rc = pthread_create(&firstCallThread, &attr, sippThreadWithCount, &firstCallCommand); - - if (rc) - std::cout << "SIPTest: RING_ERR; return code from pthread_create()" << std::endl; - - // sleep a while to make sure that sipp insdtance is initialized and dring received - // the incoming invite. - sleep(1); - - CPPUNIT_ASSERT(Manager::instance().callFactory.callCount<SIPCall>() == 1); - - // Answer this call - auto calls = Manager::instance().callFactory.getCallIDs<SIPCall>(); - auto iterCallId = calls.cbegin(); - const auto& firstCallId = *iterCallId; - CPPUNIT_ASSERT(Manager::instance().answerCall(firstCallId)); - - sleep(1); - pthread_t secondCallThread; - rc = pthread_create(&secondCallThread, &attr, sippThread, &secondCallCommand); - - if (rc) - std::cout << "SIPTest: Error; return code from pthread_create()" << std::endl; - - sleep(1); - - CPPUNIT_ASSERT(Manager::instance().callFactory.callCount<SIPCall>() == 2); - calls = Manager::instance().callFactory.getCallIDs<SIPCall>(); - iterCallId = calls.cbegin(); - if (*iterCallId == firstCallId) - ++iterCallId; - - std::string secondCallID(*iterCallId); - - CPPUNIT_ASSERT(Manager::instance().answerCall(secondCallID)); - - sleep(2); - - pthread_mutex_lock(&count_mutex); - - while (counter > 0) - pthread_cond_wait(&count_nb_thread, &count_mutex); - - pthread_mutex_unlock(&count_mutex); - - pthread_mutex_destroy(&count_mutex); - pthread_cond_destroy(&count_nb_thread); -} - - -void SIPTest::testHoldIpCall() -{ - std::string callCommand("sipp -sf tools/sippxml/test_3.xml -i 127.0.0.1 -p 5062 -m 1 -bg"); - - pthread_t callThread; - int rc = pthread_create(&callThread, NULL, sippThread, (void *)(&callCommand)); - - if (rc) - std::cout << "SIPTest: RING_ERR; return code from pthread_create(): " << rc << std::endl; - else - std::cout << "SIPTest: completed thread creation" << std::endl; - - - std::string testAccount("IP2IP"); - - std::string testCallID("callid1234"); - std::string testCallNumber("sip:test@127.0.0.1:5062"); - - Manager::instance().outgoingCall(testAccount, testCallID, testCallNumber); - - sleep(1); - - Manager::instance().onHoldCall(testCallID); - - sleep(1); - - Manager::instance().offHoldCall(testCallID); - - sleep(1); - - Manager::instance().hangupCall(testCallID); -} - -void SIPTest::testSIPURI() -{ - std::string foo("<sip:17771234567@callcentric.com>"); - sip_utils::stripSipUriPrefix(foo); - CPPUNIT_ASSERT(foo == "17771234567"); -} - -void SIPTest::testParseDisplayName() -{ - // 1st element is input, 2nd is expected output - const char *test_set[][2] = { - {"\nFrom: \"A. G. Bell\" <sip:agb@bell-telephone.com> ;tag=a48s", "A. G. Bell"}, - {"\nFrom: \"A. G. Bell2\" <sip:agb@bell-telephone.com> ;tag=a48s\r\nOtherLine: \"bla\"\r\n", "A. G. Bell2"}, - {"\nf: Anonymous <sip:c8oqz84zk7z@privacy.org>;tag=hyh8", "Anonymous"}, - {"\nFrom: \"Alejandro Perez\" <sip:1111@10.0.0.1>;tag=3a7516a63bdbo0", "Alejandro Perez"}, - {"\nFrom: \"Malformed <sip:1111@10.0.0.1>;tag=3a6a63bdbo0", ""}, - {"\nTo: <sip:1955@10.0.0.1>;tag=as6fbade41", ""}, - {"\nFrom: \"1000\" <sip:1000@sip.example.es>;tag=as775338f3", "1000"}, - {"\nFrom: 1111_9532323 <sip:1111_9532323@sip.example.es>;tag=caa3a61", "1111_9532323"}, - {"\nFrom: \"4444_953111111\" <sip:4444_111111@sip.example.es>;tag=2b00632co0", "4444_953111111"}, - {"\nFrom: <sip:6926666@4.4.4.4>;tag=4421-D9700", ""}, - {"\nFrom: <sip:pinger@sipwise.local>;tag=01f516a4", ""}, - {"\nFrom: sip:pinger@sipwise.local;tag=01f516a4", ""}, - {"\nFrom: ", ""}, - {"\nFrom: \"\xb1""Alejandro P\xc3\xa9rez\" <sip:1111@10.0.0.1>;tag=3a7516a63bdbo0", "\xef\xbf\xbd""Alejandro P\xc3\xa9rez"}, - {"\nFrom: \"Alejandro P\xc3\xa9rez\" <sip:1111@10.0.0.1>;tag=3a7516a63bdbo0", "Alejandro P\xc3\xa9rez"}, - {"\nFrom: sip:+1212555@server.example.com;tag=887s", ""}}; - - for (const auto &t : test_set) { - const std::string str(sip_utils::parseDisplayName(t[0])); - CPPUNIT_ASSERT_MESSAGE(std::string("\"") + str + "\" should be \"" + - t[1] + "\", input on next line: " + t[0], - str == t[1]); - } -} - -void SIPTest::testIncomingIpCallSdp() -{ - // command to be executed by the thread, user agent client which initiate a call and hangup - std::string command("sipp -sf tools/sippxml/test_4.xml 127.0.0.1 -i 127.0.0.1 -p 5062 -m 1i -bg"); - - pthread_t thethread; - int rc = pthread_create(&thethread, NULL, sippThread, (void *)(&command)); - - if (rc) - std::cout << "SIPTest: RING_ERR; return code from pthread_create()" << std::endl; - - // sleep a while to make sure that sipp insdtance is initialized and dring received - // the incoming invite. - sleep(2); - - CPPUNIT_ASSERT(Manager::instance().callFactory.callCount<SIPCall>() == 1); - - // Answer this call - const auto& calls = Manager::instance().callFactory.getAllCalls<SIPCall>(); - - // TODO: hmmm, should IP2IP call be stored in call list.... - CPPUNIT_ASSERT(Manager::instance().getCallList().empty()); - - // Answer this call - CPPUNIT_ASSERT(Manager::instance().answerCall((*calls.cbegin())->getCallId())); - - sleep(1); - - rc = pthread_join(thethread, NULL); - - if (rc) - std::cout << "SIPTest: RING_ERR; return code from pthread_join(): " << rc << std::endl; - else - std::cout << "SIPTest: completed join with thread" << std::endl; -} - -}} // namespace ring::test -#endif diff --git a/test/siptest.h b/test/siptest.h deleted file mode 100644 index 25018ea94a..0000000000 --- a/test/siptest.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -// Cppunit import -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/TestCaller.h> -#include <cppunit/TestCase.h> -#include <cppunit/TestSuite.h> - -// Application import -#include "manager.h" - -/* - * @file siptest.h - * @brief Regroups unitary tests related to the SIP module - */ - -#ifndef _SIP_TEST_ -#define _SIP_TEST_ - -namespace ring { namespace test { - -class SIPTest : public CppUnit::TestCase { - - /** - * Use cppunit library macros to add unit test the factory - */ - CPPUNIT_TEST_SUITE(SIPTest); - CPPUNIT_TEST ( testSimpleOutgoingIpCall ); - CPPUNIT_TEST ( testParseDisplayName ); - // CPPUNIT_TEST ( testSimpleIncomingIpCall ); - // CPPUNIT_TEST ( testTwoOutgoingIpCall ); - // CPPUNIT_TEST ( testTwoIncomingIpCall ); - // CPPUNIT_TEST ( testHoldIpCall); - // CPPUNIT_TEST ( testIncomingIpCallSdp ); - CPPUNIT_TEST_SUITE_END(); - - public: - SIPTest() : CppUnit::TestCase("SIP module Tests") {} - - /* - * Code factoring - Common resources can be initialized here. - * This method is called by unitcpp before each test - */ - void setUp(); - - /* - * Code factoring - Common resources can be released here. - * This method is called by unitcpp after each test - */ - void tearDown(); - - - void testSimpleOutgoingIpCall(void); - - void testSimpleIncomingIpCall(void); - - void testTwoOutgoingIpCall(void); - - void testTwoIncomingIpCall(void); - - void testHoldIpCall(void); - - void testIncomingIpCallSdp(void); - - void testSIPURI(); - - void testParseDisplayName(); -}; - -/* Register our test module */ -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(SIPTest, "SIPTest"); -CPPUNIT_TEST_SUITE_REGISTRATION(SIPTest); - -}} // namespace ring::test - -#endif diff --git a/test/test_utils.h b/test/test_utils.h deleted file mode 100644 index 52289acbd0..0000000000 --- a/test/test_utils.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef TEST_UTILS_H_ -#define TEST_UTILS_H_ - -#include "logger.h" - -#define TITLE() RING_DBG("Starting test..."); fflush(stderr) - -#endif // TEST_UTILS_H_ diff --git a/test/tlsSample/ca.crt b/test/tlsSample/ca.crt deleted file mode 100644 index 5f5b490606..0000000000 --- a/test/tlsSample/ca.crt +++ /dev/null @@ -1,22 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDtzCCAm+gAwIBAgIEU3EhUTANBgkqhkiG9w0BAQsFADBLMQswCQYDVQQGEwJD -QTEYMBYGA1UEChMPU2F2b2lyRmFpcmVUZXN0MREwDwYDVQQHEwhNb250cmVhbDEP -MA0GA1UECBMGUXVlYmVjMB4XDTE0MDUxMjE5MzAyOVoXDTE1MDUxMjE5MzAzM1ow -SzELMAkGA1UEBhMCQ0ExGDAWBgNVBAoTD1Nhdm9pckZhaXJlVGVzdDERMA8GA1UE -BxMITW9udHJlYWwxDzANBgNVBAgTBlF1ZWJlYzCCAVIwDQYJKoZIhvcNAQEBBQAD -ggE/ADCCAToCggExAKOMxKvsloBIWBNVTvMXTnvmXoCvSJpH0FNjJnFySUY9x7ld -p/oWdVU7SJQn1u1nKwuP27NWLX3ICRZo2ziRbBNfI0DaUcNX+sg/G2Ftzr5Z86oP -n4LOTuAaRrAHELTJafGnFdl7v5t3OAElRy7ICkQhmqdPJndvOaAREmyZXIkbn+bF -zO369/UBRF26Z9sYwwV65bZZ6eHw2wTuHXyDLKA+Qcj7HMhE4Zu1ySFtjDZYo6OD -ygPZDyOiftm+o8noZyMaLI+r3KY0W14QnGnLSSLVE+CbVErBU+lZ7LjODpn8bsa7 -hOV74r0xRux2VrWfDpIVulpm+gDxKQK1eTR7ENJKPBsfcDCblflVZHoY87TYckWW -98zGRdehSSoJhJotexIecrybZW6T3QycsbeALnECAwEAAaNDMEEwDwYDVR0TAQH/ -BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwQAMB0GA1UdDgQWBBQeTMJ8HtoXRp316pus -7AMDEDq8CDANBgkqhkiG9w0BAQsFAAOCATEAWRKyaKLC7VRVshITdvsMoleV+5ek -xH3riJmw/x1Peosu2ijehEUc+cHFRA0/wFyY93YzsmVyR6lrdL3f8KOD+k6u/s0z -hhAoYoVeZTwZ7wGN2yz8oVUcM/NlVA//DTqU/RYjm19cLKR4YIWglbPmWHNh/rI8 -vOi2IbhubsXXCgi0lL3G7Lz8//sEkxlhh3y9j1dmygtIL8rX8GlJsLZPbGELQrQF -8mHuIfMMOFMXqV9Os2gStKYpNh/to2fdE5elxGjegluDJ6wXH3Wsoth35j7woaRj -HZ2SovMUz7IPklsk1QNaRb08LxJUHVpJffsRIpJMvUFl7nxWIT/ZEaV3aY4lc0ks -PL0i952R2ddVR7O0g7hkuYT72lVE+Vw9+HrEdWDkOSnBxvKSTn7zjzmnGA== ------END CERTIFICATE----- diff --git a/test/tlsSample/cert.crt b/test/tlsSample/cert.crt deleted file mode 100644 index 7697f26082..0000000000 --- a/test/tlsSample/cert.crt +++ /dev/null @@ -1,23 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDyzCCAoOgAwIBAgIEU3EusDANBgkqhkiG9w0BAQsFADBLMQswCQYDVQQGEwJD -QTEYMBYGA1UEChMPU2F2b2lyRmFpcmVUZXN0MREwDwYDVQQHEwhNb250cmVhbDEP -MA0GA1UECBMGUXVlYmVjMB4XDTE0MDUxMjIwMjcyOFoXDTE1MDUxMjIwMjczMVow -UjELMAkGA1UEBhMCQ0ExHzAdBgNVBAoTFlNhdm9pckZhaXJlQ2VydGlmaWNhdGUx -ETAPBgNVBAcTCE1vbnRyZWFsMQ8wDQYDVQQIEwZRdWViZWMwggFSMA0GCSqGSIb3 -DQEBAQUAA4IBPwAwggE6AoIBMQCjjMSr7JaASFgTVU7zF0575l6Ar0iaR9BTYyZx -cklGPce5Xaf6FnVVO0iUJ9btZysLj9uzVi19yAkWaNs4kWwTXyNA2lHDV/rIPxth -bc6+WfOqD5+Czk7gGkawBxC0yWnxpxXZe7+bdzgBJUcuyApEIZqnTyZ3bzmgERJs -mVyJG5/mxczt+vf1AURdumfbGMMFeuW2Wenh8NsE7h18gyygPkHI+xzIROGbtckh -bYw2WKOjg8oD2Q8jon7ZvqPJ6GcjGiyPq9ymNFteEJxpy0ki1RPgm1RKwVPpWey4 -zg6Z/G7Gu4Tle+K9MUbsdla1nw6SFbpaZvoA8SkCtXk0exDSSjwbH3Awm5X5VWR6 -GPO02HJFlvfMxkXXoUkqCYSaLXsSHnK8m2Vuk90MnLG3gC5xAgMBAAGjUDBOMAwG -A1UdEwEB/wQCMAAwHQYDVR0OBBYEFB5Mwnwe2hdGnfXqm6zsAwMQOrwIMB8GA1Ud -IwQYMBaAFB5Mwnwe2hdGnfXqm6zsAwMQOrwIMA0GCSqGSIb3DQEBCwUAA4IBMQAP -W4x5JU7vBBWgJdpqy5YMr9yu9HICwrUpUC4uq7GmhFs91mJpSAu1MIb9c1Iy4XBX -cJV65R30NIJY+tBxxss+DP458UwSjBHRs2aFsBMkJOpzXmjlUl3QifoLCbLtPYv0 -Q741zCU5k9c2qzSNoEfxoKugP2J31aVNsfl4NMxuC7xsrXGtuJK3yp8MIIXdFTq8 -lTrSZ1nltQxdU/Tg8nlKT1ikzew9cI6BmPyWXzHoVaP6PJruYUZsVyGX+408JFvO -tqyY6XiSn4jpTgDkz743youZTdB85qlnc2AIGOTWnmwEjqjR13GpuQTY/i0c6C8Z -R1rSKjmCujH2rbnPnk7qRt7qSgsyC/lm3NLC7BtAeLxqCyOtbjhfsbIadHALoAlh -85PWqpJyTXqvuihJFdu9 ------END CERTIFICATE----- diff --git a/test/tlsSample/certwithkey.pem b/test/tlsSample/certwithkey.pem deleted file mode 100644 index 6dc6e28ce1..0000000000 --- a/test/tlsSample/certwithkey.pem +++ /dev/null @@ -1,35 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIICXAIBAAKBgQCpHOrS9GBJFtH0hhT0/vM2Bh1vAiB3d4L4E4u9IXphzg/F4K/d -0MvgxWrQY38HRQtqj+CfczWqCpVivQsQCVvSB2YVckbgotFF6j1qdP3wzGex64WY -TEiZabJSCWGAnUtWCgvhCBRL0PzuaDfMAttN5qRNYZsgqWT1KhiyECCHCwIDAQAB -AoGBAI/w4xbnlkTfvZkpvxDBKHYlQkxIPSYyfTF2QYybwDUbVWWR118v5zjMEByL -c4XWiN8M054kS9sN4xUF3zKpJJMABaDVs+Mr7tDF8l+j767L730DYdAX8yH37nrK -H+myW7hvBwuYjssEiybgPpVfiVd48DiN9K/aIbr74tLSvYuRAkEA1p20d+gmeUJS -eYbpOusYGHAVBwM7xuWyrwyEcewzXxgZRhVzUTcP4T2Uk7iQRMqW/wDTaEpxGVtb -DFh/eot0dQJBAMm5ADFfvfQ0DVkSodZCc9UCQ80eTtrvL+xnGdEpKDARWwYbHM6P -wBx5VIJelj4mMmkfUPjqMHs47k3R5luunX8CQHkrFr3wAvDJQhk80ychnjwF48lO -yQwVmVl9XrWXHrXcvEA2UiITTVLk2qLAPCuqma+lPraN+ObRDkmdGXQNkhUCQBwg -cYhw4xmT0HClCm/HoEMJJ88H9NLOGw6Jaa4iYPoi0WBOk3uxy4Ws3T24Vpaf2NOT -jETI0q27yG6NX+NUu50CQGYj8frp0aDMO7Fxnz4dODuBeVpiT5UH+YcaEaan4plJ -Sgn2eo7jHktyEXVGmmemIJbpPiJmQT549RcX+M9c4iQ= ------END RSA PRIVATE KEY----- ------BEGIN CERTIFICATE----- -MIIDUzCCATsCAQEwDQYJKoZIhvcNAQEFBQAwOjEcMBoGA1UEAxMTQXN0ZXJpc2sg -UHJpdmF0ZSBDQTEaMBgGA1UEChMRQXN0ZXJpc2sgdGVzdCBQQlgwHhcNMTQwMzA1 -MTk0MTU2WhcNMTUwMzA1MTk0MTU2WjApMQ0wCwYDVQQDEwRwY2FsMRgwFgYDVQQK -Ew9Bc3RlcmlzayBTZXJ2ZXIwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKkc -6tL0YEkW0fSGFPT+8zYGHW8CIHd3gvgTi70hemHOD8Xgr93Qy+DFatBjfwdFC2qP -4J9zNaoKlWK9CxAJW9IHZhVyRuCi0UXqPWp0/fDMZ7HrhZhMSJlpslIJYYCdS1YK -C+EIFEvQ/O5oN8wC203mpE1hmyCpZPUqGLIQIIcLAgMBAAEwDQYJKoZIhvcNAQEF -BQADggIBACBcy6n+S2SIOdCTiMr7A7xcHQB2pTHVgnp0twqxWyYmun3k+uIyTweE -IKCaZXvnz0+kW5Oo6dDcTZaXZkRhLdDWCXYcWGE2fDA16ZwUXUBRpf8t1wrssEud -m+eBP7DQ8sNmUBuTiSZtFqyY4HYN426+ehbocByU7A7iRQ41dXKJJktNAUg5DQwh -bK4sWU4ktIWrQnlSKLe8O+1FSv3WqDgXeDcBhC49zgFEUy9BDUKmfnnCk1cLSmTq -8sGtYVcV8NbD5Cp9+uOf8/rQ3TndPLdS4RQy7QEEdI+ZOuVoMwd05rYQH9sWfQxy -WOTRuXqVOE5SsTy5yyRVI0lQ+71UoykaQeUsS9GNmVEfd0cAVSqI6T/58JEuesm8 -QlDFRtnAmBeqmGtGE62W68W3DjgeO7LlDMmOKtevWAH1pSUK6EgCph4tFOc2Csts -Ckve/t/WLoioEFubpWGNZ2LUe+qp4PcBsySAc3eUjjd8/e47BDn44L1DPfbzWE4i -QphIEwnsRjNqkrCKUYnvNjQtDTng8X/syeRJdX/2m4XICD5+DkawHfNW0nUs5MIk -wQ+DBESGDJRQymj14LVcQObuslZrkcPyCqf2O2hGP1Zvc+6SvQpjsEHUFZVMixli -Qwq9G4UcQDEmzR1ivmELX7tkpUOFdyIDlf6UvaIkSRpV0+EnShUo ------END CERTIFICATE----- diff --git a/test/tlsSample/corruptedkey.pem b/test/tlsSample/corruptedkey.pem deleted file mode 100644 index 9352ff819b..0000000000 --- a/test/tlsSample/corruptedkey.pem +++ /dev/null @@ -1,29 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIFfQIBAAKCATEAo4zEq+yWgEhYE1VO8xdOe+ZegK9ImkfQU2MmcXJJRj3HuV2n -+hZ1VTtIlCfW7WcrC4/bs1YtfcgJFmjbOJFsE18jQNpRw1f6yD8bYW3Ovlnzqg+f -gs5O4BpGsAcQtMlp8acV2Xu/m3c4ASVHLsgKRCGap08md285oBESbJlciRuf5sXM -7fr39QFEXbpn2xjDBXrltlnp4fDbBO4dfIMsoD5ByPscyEThm7XJIW2MNlijo4PK -A9kPI6J+2b6jyehnIxosj6vcpjRbXhCcactJItUT4JtUSsFT6VnsuM4OmfxuxruE -5XvivTFG7HZWtZ8OkhW6Wmb6APEpArV5NHsQ0ko8Gx9wMJuV+VVkehjztNhyRZb3 -zMZF16FJKgmEmi17Eh5yvJtlbpPdDJyxt4AucQIDAQABAoIBMAPbCLPo4u9pRTJH -e5H9haskFixAdZy1frLIjpp0EEgoorG7BH+/0cpNmHttqQJ1wS0Hmi1TJcVmVtiB -ZlGiFAMs5f7cZrsNMutPmYylcw9HvZfPwHnr9S4RUINL11f7u5Sn1LsI0M6Qc/CK -kseDyy2/qcalprz6c4puFLrVMuuen9YvriWVquWv+h4AISwrl+ESU9+QTzaUTSUu -CCwyNXECgZkAyhiZTp/xziLtNfiYQMRZk6OYk2IW5co0t8P1jo+VDaKehFuFhQsx -6hNG6k2n3dA5MeZK4O+n5I0SGkc+MYyAWOtI0q7IiSFUn9PMwZXO91rBDG5VxFpT -srD5m86BQhfmMqpeWQgAXT/ZM1q4me4gtg9PAyJDVHLs5MV49szcH2YAVzWCLJ7e -/o9Xne7jOhUGRVzGpwZ8gP0CgZkAzywuNe+K51nFED+WSHmSw73eqxmFsdm7FHg0 -O9RykMT3vfXx1fMPQU01BbsA0w+NH/lAtgwxSSzHZPAAOYl6iB29BXErbqBpJsOz -1afqXlEAiQcA3uOgPWMWnORcLfdwvze8lndHYvQ6bu85CoPl/mv+PBNp9fJLvxMr -Xr1V8DPYUeWTPr8IOSDQ8qWXO5s/wtqOZxynR4UCgZkAtcV+Tqupz+C2Pu8D8m0o -rJRerWFyeuhulkLY4IrgY806io3PACVbldAU3rVOIUIhz3H1M3AbMIR6HcyqceKP -pmqpq2Wt1Tl3ZfIYnp3h87VbIZUz61HbKkPnnm4U8J+SW0vFZIq/2R+OepREqZ73 -KQmH5aexq4la7UF4VXNZIZya/dWQ6hVTON8wzUqKcjlq1IRn4N8CqPkCgZkAhW6t -LKvlyO/2jmqF/pPexRerLIQ5qbzUU3DAI7DHQRq7favEYMo1jxeNCO3SsB2aBXfi -B95+d+TRX998JZK4SqbssW6cTJogX4k4cGm/95MwRxEtrGDrOd5yGAa0oB54jY/2 -dOrKHZ+zavPEx1MAdQdVLZhLbM7rnltYWaKUkSqzLrwwQ/+B6lmKel3Qs+FgBb4C -bcL0sokCgZkAnKmzmzSLb1Hg2fMVXP+xtQJIwv2/2eDcOXfC+X5qoNK/KxSXF/co -U16nAVY4VwOrYLjUuOh1N8yhwj+7DrTx8F2Q4sWvoXcbBmJv46fJlsVMByuyiWPv -4q3rPEf1eQ6MBj0D9iY+JtvJmtPT0vQQa6O2gl2qFlbmlc8PCSj4hI5d19ePcQlg -ypRMPut1kF4EDNV6vcrnukA= ------END RSA PRIVATE KEY----- diff --git a/test/tlsSample/expired.crt b/test/tlsSample/expired.crt deleted file mode 100644 index 59e7b84e3b..0000000000 --- a/test/tlsSample/expired.crt +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDDTCCAcWgAwIBAgIEU3FIpjANBgkqhkiG9w0BAQsFADAAMB4XDTE0MDUxMjIy -MTgxNVoXDTE0MDUxMzIyMTgxN1owADCCAVIwDQYJKoZIhvcNAQEBBQADggE/ADCC -AToCggExAKOMxKvsloBIWBNVTvMXTnvmXoCvSJpH0FNjJnFySUY9x7ldp/oWdVU7 -SJQn1u1nKwuP27NWLX3ICRZo2ziRbBNfI0DaUcNX+sg/G2Ftzr5Z86oPn4LOTuAa -RrAHELTJafGnFdl7v5t3OAElRy7ICkQhmqdPJndvOaAREmyZXIkbn+bFzO369/UB -RF26Z9sYwwV65bZZ6eHw2wTuHXyDLKA+Qcj7HMhE4Zu1ySFtjDZYo6ODygPZDyOi -ftm+o8noZyMaLI+r3KY0W14QnGnLSSLVE+CbVErBU+lZ7LjODpn8bsa7hOV74r0x -Rux2VrWfDpIVulpm+gDxKQK1eTR7ENJKPBsfcDCblflVZHoY87TYckWW98zGRdeh -SSoJhJotexIecrybZW6T3QycsbeALnECAwEAAaMvMC0wDAYDVR0TAQH/BAIwADAd -BgNVHQ4EFgQUHkzCfB7aF0ad9eqbrOwDAxA6vAgwDQYJKoZIhvcNAQELBQADggEx -AGmzz8Ta1v1MUYzUk1DE03rAG4Sh9Nyr7Jesj8jtWSFho+RzQISKAY7AfayGflmQ -NJndYp0H3B6AvhujRptNRQ0ybI/p4wV0PSVCBT8jGf83d3fCOZOC/45neg9KUVTJ -5Xtap5knIvQRCCfLIrAAUgYgjhOxfCAB56rDyRK6zEJ+lC2AJpweRMtXTGI/CbDl -BS7knAE30h6NChWLIjDFRvrLjupPMArrTOg92DGrdUsZF8OqisO/Eba0j+LE17q+ -jb3Ga3fW828CWJUQZNi1LuQCSRnyS90+yv0cK7oeyp2BAaTVDT0AY+VSMD5v+2Cb -Wv/J5lITKF3ees0x3NNquMcHvYfEqNfqFc1bubYut8isKwM67JVgCnvUPwKEm4fh -E8NXJ7eYiHS1/RCRqA8g/ZY= ------END CERTIFICATE----- diff --git a/test/tlsSample/fake.crt b/test/tlsSample/fake.crt deleted file mode 100644 index c66393ae02dd83a704ee7038ed9fe7b7d79d6c54..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4546 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 HoD!M<5}&*4 diff --git a/test/tlsSample/keyonly.pem b/test/tlsSample/keyonly.pem deleted file mode 100644 index ba2fc011aa..0000000000 --- a/test/tlsSample/keyonly.pem +++ /dev/null @@ -1,32 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIFfQIBAAKCATEAo4zEq+yWgEhYE1VO8xdOe+ZegK9ImkfQU2MmcXJJRj3HuV2n -+hZ1VTtIlCfW7WcrC4/bs1YtfcgJFmjbOJFsE18jQNpRw1f6yD8bYW3Ovlnzqg+f -gs5O4BpGsAcQtMlp8acV2Xu/m3c4ASVHLsgKRCGap08md285oBESbJlciRuf5sXM -7fr39QFEXbpn2xjDBXrltlnp4fDbBO4dfIMsoD5ByPscyEThm7XJIW2MNlijo4PK -A9kPI6J+2b6jyehnIxosj6vcpjRbXhCcactJItUT4JtUSsFT6VnsuM4OmfxuxruE -5XvivTFG7HZWtZ8OkhW6Wmb6APEpArV5NHsQ0ko8Gx9wMJuV+VVkehjztNhyRZb3 -zMZF16FJKgmEmi17Eh5yvJtlbpPdDJyxt4AucQIDAQABAoIBMAPbCLPo4u9pRTJH -e5H9haskFixAdZy1frLIjpp0EEgoorG7BH+/0cpNmHttqQJ1wS0Hmi1TJcVmVtiB -ZlGiFAMs5f7cZrsNMutPmYylcw9HvZfPwHnr9S4RUINL11f7u5Sn1LsI0M6Qc/CK -+W+f5aYPiL7S/dwo8hnU7TNENktBLHbbSOZ/WSMcgYkYIOSoY8iYShwPaJUb99fY -0RgdY+ehoC+cswm65p9S5B/emjVtZU6Zb45L+LVmMHMiAxRR//Wpl1GzgG+wHmcu -KZ+a6oyCCdIoT5Mf7otdUBL+aTV13K8oW3vt+TdlA7EEPU3f6dsctB7H/kmE0jHh -kseDyy2/qcalprz6c4puFLrVMuuen9YvriWVquWv+h4AISwrl+ESU9+QTzaUTSUu -CCwyNXECgZkAyhiZTp/xziLtNfiYQMRZk6OYk2IW5co0t8P1jo+VDaKehFuFhQsx -6hNG6k2n3dA5MeZK4O+n5I0SGkc+MYyAWOtI0q7IiSFUn9PMwZXO91rBDG5VxFpT -srD5m86BQhfmMqpeWQgAXT/ZM1q4me4gtg9PAyJDVHLs5MV49szcH2YAVzWCLJ7e -/o9Xne7jOhUGRVzGpwZ8gP0CgZkAzywuNe+K51nFED+WSHmSw73eqxmFsdm7FHg0 -O9RykMT3vfXx1fMPQU01BbsA0w+NH/lAtgwxSSzHZPAAOYl6iB29BXErbqBpJsOz -1afqXlEAiQcA3uOgPWMWnORcLfdwvze8lndHYvQ6bu85CoPl/mv+PBNp9fJLvxMr -Xr1V8DPYUeWTPr8IOSDQ8qWXO5s/wtqOZxynR4UCgZkAtcV+Tqupz+C2Pu8D8m0o -rJRerWFyeuhulkLY4IrgY806io3PACVbldAU3rVOIUIhz3H1M3AbMIR6HcyqceKP -pmqpq2Wt1Tl3ZfIYnp3h87VbIZUz61HbKkPnnm4U8J+SW0vFZIq/2R+OepREqZ73 -KQmH5aexq4la7UF4VXNZIZya/dWQ6hVTON8wzUqKcjlq1IRn4N8CqPkCgZkAhW6t -LKvlyO/2jmqF/pPexRerLIQ5qbzUU3DAI7DHQRq7favEYMo1jxeNCO3SsB2aBXfi -B95+d+TRX998JZK4SqbssW6cTJogX4k4cGm/95MwRxEtrGDrOd5yGAa0oB54jY/2 -dOrKHZ+zavPEx1MAdQdVLZhLbM7rnltYWaKUkSqzLrwwQ/+B6lmKel3Qs+FgBb4C -bcL0sokCgZkAnKmzmzSLb1Hg2fMVXP+xtQJIwv2/2eDcOXfC+X5qoNK/KxSXF/co -U16nAVY4VwOrYLjUuOh1N8yhwj+7DrTx8F2Q4sWvoXcbBmJv46fJlsVMByuyiWPv -4q3rPEf1eQ6MBj0D9iY+JtvJmtPT0vQQa6O2gl2qFlbmlc8PCSj4hI5d19ePcQlg -ypRMPut1kF4EDNV6vcrnukA= ------END RSA PRIVATE KEY----- diff --git a/test/tlstest.cpp b/test/tlstest.cpp deleted file mode 100644 index 858cda5eac..0000000000 --- a/test/tlstest.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -/* - * ebail - 2015/02/18 - * unit test is based on old SDP manager code - * this test is disabled for the moment - * */ -#if 0 - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include "tlstest.h" -#include "account.h" -#include "test_utils.h" -#include "logger.h" - -#include "sip/tlsvalidator.h" - -namespace ring { namespace test { - -void TlsTest::testKey() -{ - TITLE(); - - const char *validKey = WORKSPACE "tlsSample/keyonly.pem"; - const char *validCertWithKey = WORKSPACE "tlsSample/certwithkey.pem"; - const char *corruptedKey = WORKSPACE "tlsSample/corruptedkey.pem"; - - CPPUNIT_ASSERT(containsPrivateKey(validKey) == 0); - - CPPUNIT_ASSERT(containsPrivateKey(validCertWithKey) == 0); - - CPPUNIT_ASSERT(containsPrivateKey(corruptedKey) != 0); -} - -void TlsTest::testCertificate() -{ - TITLE(); - - const char *validCa = WORKSPACE "tlsSample/ca.crt"; - const char *validCertificate = WORKSPACE "tlsSample/cert.crt"; - const char *fakeCertificate = WORKSPACE "tlsSample/fake.crt"; - const char *expiredCertificate = WORKSPACE "tlsSample/expired.crt"; - - CPPUNIT_ASSERT(certificateIsValid(NULL, validCa) == 0); - - CPPUNIT_ASSERT(certificateIsValid(validCa, validCertificate) == 0); - - // This is a png - CPPUNIT_ASSERT(certificateIsValid(NULL, fakeCertificate) != 0); - - // This would need a CA to be valid - CPPUNIT_ASSERT(certificateIsValid(NULL, validCertificate) != 0); - - // This is an invalid CA - CPPUNIT_ASSERT(certificateIsValid(validCertificate, validCertificate) != 0); - - // This certificate is expired - CPPUNIT_ASSERT(certificateIsValid(NULL, expiredCertificate) != 0); -} - -}} // namespace ring::test -#endif diff --git a/test/tlstest.h b/test/tlstest.h deleted file mode 100644 index e5f5150d26..0000000000 --- a/test/tlstest.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -/* - * @file tsltest.cpp - * @brief Tests TLS setup. - * Check if certificate is valid - */ - -#ifndef TLS_TEST_ -#define TLS_TEST_ - -// Cppunit import -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/TestCaller.h> -#include <cppunit/TestCase.h> -#include <cppunit/TestSuite.h> - -namespace ring { namespace test { - -class TlsTest: public CppUnit::TestFixture { - - /* - * Use cppunit library macros to add unit test the factory - */ - CPPUNIT_TEST_SUITE(TlsTest); - CPPUNIT_TEST(testKey); - CPPUNIT_TEST(testCertificate); - CPPUNIT_TEST(testHostname); - CPPUNIT_TEST_SUITE_END(); - - public: - void testKey(); - void testCertificate(); - void testHostname(); -}; -/* Register our test module */ -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(TlsTest, "TlsTest"); -CPPUNIT_TEST_SUITE_REGISTRATION(TlsTest); - -}} // namespace ring::test - -#endif // TLS_TEST_ diff --git a/test/waveSample/M1F1-int16WE-AFsp.wav b/test/waveSample/M1F1-int16WE-AFsp.wav deleted file mode 100644 index 6df1c305809b5cee7a8fa4b07e28ee4dcbe524cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47134 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 H{{II6AUsA{ diff --git a/tools/sippxml/account_uac_send_hangup.xml b/tools/sippxml/account_uac_send_hangup.xml deleted file mode 100644 index 8971769c59..0000000000 --- a/tools/sippxml/account_uac_send_hangup.xml +++ /dev/null @@ -1,147 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> -<!DOCTYPE scenario SYSTEM "sipp.dtd"> - -<!-- This program is free software; you can redistribute it and/or --> -<!-- modify it under the terms of the GNU General Public License as --> -<!-- published by the Free Software Foundation; either version 2 of the --> -<!-- License, or (at your option) any later version. --> -<!-- --> -<!-- This program is distributed in the hope that it will be useful, --> -<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of --> -<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --> -<!-- GNU General Public License for more details. --> -<!-- --> -<!-- You should have received a copy of the GNU General Public License --> -<!-- along with this program; if not, write to the --> -<!-- Free Software Foundation, Inc., --> -<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --> - - -<scenario name="accountcall_client"> - - <pause milliseconds="200"/> - - <send retrans="500"> - <![CDATA[ - - INVITE sip:2000@[remote_ip] SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];rport;branch=[branch] - From: <sip:27182@[remote_ip]:[remote_port]>;tag=[call_number] - To: <sip:2000@[remote_ip]:[remote_port]> - Call-ID: [call_id] - CSeq: 3 INVITE - Contact: sip:27182@[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Functional Test - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv response="401" auth="true"> - </recv> - - <pause milliseconds="200"/> - - <send> - <![CDATA[ - - ACK sip:27182@[remote_ip] SIP/2.0 - Max-Forwards: 70 - Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] - From: <sip:27182@[remote_ip]:[remote_port]>;tag=[call_number] - To: <sip:2000@[remote_ip]:[remote_port]> - Call-ID: [call_id] - CSeq: 4 ACK - Subject: Functional Test - Content-Length: 0 - - ]]> - </send> - - <send retrans="500"> - <![CDATA[ - - INVITE sip:2000@[remote_ip] SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];rport;branch=[branch] - From: <sip:27182@:[remote_ip]:[remote_port]>;tag=[call_number] - To: <sip:2000@[remote_ip]:[remote_port]> - Call-ID: [call_id] - CSeq: 5 INVITE - Contact: sip:27182@[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Functional Test - Content-Type: application/sdp - Content-Length: [len] - [authentication username=27182 password=1234] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv response="100"> - </recv> - - <recv response="180"> - </recv> - - - <recv response="200"> - </recv> - - <send> - <![CDATA[ - - ACK sip:2000@192.168.50.79 SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] - From: <sip:27182@[local_ip]:[local_port]>;tag=[call_number] - To: <sip:2000@192.168.50.79:[remote_port]> - Call-ID: [call_id] - CSeq: 5 ACK - Contact: sip:27182@[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Functional Test - Content-Length: 0 - - ]]> - </send> - - <send retrans="500"> - <![CDATA[ - - BYE sip:2000@192.168.50.79 SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] - From: <sip:27182@[local_ip]:[local_port]>;tag=[call_number] - To: <sip:2000@192.168.50.79:[remote_port]> - Call-ID: [call_id] - CSeq: 6 BYE - Contact: sip:27182@[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Functional Test - Content-Length: 0 - - ]]> - </send> - - <recv response="200"> - </recv> - - <pause milliseconds="1000"/> - -</scenario> diff --git a/tools/sippxml/account_uac_send_peer_hungup.xml b/tools/sippxml/account_uac_send_peer_hungup.xml deleted file mode 100644 index 716da9dd6d..0000000000 --- a/tools/sippxml/account_uac_send_peer_hungup.xml +++ /dev/null @@ -1,155 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> -<!DOCTYPE scenario SYSTEM "sipp.dtd"> - -<!-- This program is free software; you can redistribute it and/or --> -<!-- modify it under the terms of the GNU General Public License as --> -<!-- published by the Free Software Foundation; either version 2 of the --> -<!-- License, or (at your option) any later version. --> -<!-- --> -<!-- This program is distributed in the hope that it will be useful, --> -<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of --> -<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --> -<!-- GNU General Public License for more details. --> -<!-- --> -<!-- You should have received a copy of the GNU General Public License --> -<!-- along with this program; if not, write to the --> -<!-- Free Software Foundation, Inc., --> -<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --> - - -<scenario name="accountcall_client"> - - <pause milliseconds="200"/> - - <send retrans="500"> - <![CDATA[ - - INVITE sip:2000@[remote_ip] SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];rport;branch=[branch] - From: <sip:27182@[remote_ip]>;tag=[call_number] - To: <sip:2000@[remote_ip]> - Call-ID: [call_id] - CSeq: 3 INVITE - Contact: sip:27182@[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Functional Test - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv response="401" auth="true"> - </recv> - - <pause milliseconds="200"/> - - <send> - <![CDATA[ - - ACK sip:27182@[remote_ip] SIP/2.0 - Max-Forwards: 70 - Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] - From: <sip:27182@[remote_ip]>;tag=[call_number] - To: <sip:2000@[remote_ip]> - Call-ID: [call_id] - CSeq: 4 ACK - Subject: Functional Test - Content-Length: 0 - - ]]> - </send> - - <send retrans="500"> - <![CDATA[ - - INVITE sip:2000@[remote_ip] SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];rport;branch=[branch] - From: <sip:27182@:[remote_ip]>;tag=[call_number] - To: <sip:2000@[remote_ip]> - Call-ID: [call_id] - CSeq: 5 INVITE - Contact: sip:27182@[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Functional Test - Content-Type: application/sdp - Content-Length: [len] - [authentication username=27182 password=1234] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv response="100"> - </recv> - - <recv response="180"> - </recv> - - - <recv response="200"> - </recv> - - <send> - <![CDATA[ - - ACK sip:2000@192.168.50.79 SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] - From: <sip:27182@[remote_ip]>;tag=[call_number] - To: <sip:2000@[remote_ip]> - Call-ID: [call_id] - CSeq: 5 ACK - Contact: sip:27182@[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Functional Test - Content-Length: 0 - - ]]> - </send> - - <recv request="BYE"> - </recv> - - - <send retrans="500"> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <pause milliseconds="1000"/> - -</scenario> diff --git a/tools/sippxml/account_uas_receive_transfer.xml b/tools/sippxml/account_uas_receive_transfer.xml deleted file mode 100644 index 80a875fbf7..0000000000 --- a/tools/sippxml/account_uas_receive_transfer.xml +++ /dev/null @@ -1,101 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> -<!DOCTYPE scenario SYSTEM "sipp.dtd"> - -<!-- This program is free software; you can redistribute it and/or --> -<!-- modify it under the terms of the GNU General Public License as --> -<!-- published by the Free Software Foundation; either version 2 of the --> -<!-- License, or (at your option) any later version. --> -<!-- --> -<!-- This program is distributed in the hope that it will be useful, --> -<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of --> -<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --> -<!-- GNU General Public License for more details. --> -<!-- --> -<!-- You should have received a copy of the GNU General Public License --> -<!-- along with this program; if not, write to the --> -<!-- Free Software Foundation, Inc., --> -<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --> - - -<scenario name="accountcall_client"> - - <recv request="INVITE"> - </recv> - - <send> - <![CDATA[ - - SIP/2.0 180 Ringing - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <send retrans="500"> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv request="ACK"> - </recv> - - <recv request="INVITE"> - </recv> - - <pause milliseconds="200"> - </recv> - - <send retrans="500"> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv request="ACK"> - </recv> - - -</scenario> diff --git a/tools/sippxml/account_uas_recv_hangup.xml b/tools/sippxml/account_uas_recv_hangup.xml deleted file mode 100644 index 94bea47042..0000000000 --- a/tools/sippxml/account_uas_recv_hangup.xml +++ /dev/null @@ -1,119 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> -<!DOCTYPE scenario SYSTEM "sipp.dtd"> - -<!-- This program is free software; you can redistribute it and/or --> -<!-- modify it under the terms of the GNU General Public License as --> -<!-- published by the Free Software Foundation; either version 2 of the --> -<!-- License, or (at your option) any later version. --> -<!-- --> -<!-- This program is distributed in the hope that it will be useful, --> -<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of --> -<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --> -<!-- GNU General Public License for more details. --> -<!-- --> -<!-- You should have received a copy of the GNU General Public License --> -<!-- along with this program; if not, write to the --> -<!-- Free Software Foundation, Inc., --> -<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --> - - -<scenario name="accountcall_client"> - - <recv request="INVITE"> - </recv> - - <send> - <![CDATA[ - - SIP/2.0 180 Ringing - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <pause milliseconds="200"/> - - <send retrans="500"> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv request="ACK"> - </recv> - - <recv request="INVITE"> - </recv> - - <send retrans="500"> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv request="ACK"> - </recv> - - <send retrans="500"> - <![CDATA[ - - BYE sip:2000@192.168.50.79 SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] - From: <sip:27182@[local_ip]:[local_port]>;tag=[call_number] - To: <sip:2000@192.168.50.79:[remote_port]> - Call-ID: [call_id] - CSeq: 6 BYE - Contact: sip:27182@[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Functional Test - Content-Length: 0 - - ]]> - </send> - - <recv response="200"> - </recv> - -</scenario> diff --git a/tools/sippxml/account_uas_recv_peer_hungup.xml b/tools/sippxml/account_uas_recv_peer_hungup.xml deleted file mode 100644 index c91230c7fc..0000000000 --- a/tools/sippxml/account_uas_recv_peer_hungup.xml +++ /dev/null @@ -1,127 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> -<!DOCTYPE scenario SYSTEM "sipp.dtd"> - -<!-- This program is free software; you can redistribute it and/or --> -<!-- modify it under the terms of the GNU General Public License as --> -<!-- published by the Free Software Foundation; either version 2 of the --> -<!-- License, or (at your option) any later version. --> -<!-- --> -<!-- This program is distributed in the hope that it will be useful, --> -<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of --> -<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --> -<!-- GNU General Public License for more details. --> -<!-- --> -<!-- You should have received a copy of the GNU General Public License --> -<!-- along with this program; if not, write to the --> -<!-- Free Software Foundation, Inc., --> -<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --> - - -<scenario name="accountcall_client"> - - <recv request="INVITE"> - </recv> - - <send> - <![CDATA[ - - SIP/2.0 180 Ringing - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <send retrans="500"> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv request="ACK"> - </recv> - - <recv request="INVITE"> - </recv> - - <pause milliseconds="200"> - </recv> - - <send retrans="500"> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv request="ACK"> - </recv> - - <recv request="BYE"> - </recv> - - <send retrans="500"> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - -</scenario> diff --git a/tools/sippxml/account_uas_recv_transfered.xml b/tools/sippxml/account_uas_recv_transfered.xml deleted file mode 100644 index 8e67f3cec2..0000000000 --- a/tools/sippxml/account_uas_recv_transfered.xml +++ /dev/null @@ -1,132 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> -<!DOCTYPE scenario SYSTEM "sipp.dtd"> - -<!-- This program is free software; you can redistribute it and/or --> -<!-- modify it under the terms of the GNU General Public License as --> -<!-- published by the Free Software Foundation; either version 2 of the --> -<!-- License, or (at your option) any later version. --> -<!-- --> -<!-- This program is distributed in the hope that it will be useful, --> -<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of --> -<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --> -<!-- GNU General Public License for more details. --> -<!-- --> -<!-- You should have received a copy of the GNU General Public License --> -<!-- along with this program; if not, write to the --> -<!-- Free Software Foundation, Inc., --> -<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --> - - -<scenario name="accountcall_client"> - - <recv request="INVITE"> - </recv> - - <send> - <![CDATA[ - - SIP/2.0 180 Ringing - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <send retrans="500"> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv request="ACK"> - </recv> - - <recv request="INVITE"> - </recv> - - <pause milliseconds="200"> - </recv> - - <send retrans="500"> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv request="ACK"> - </recv> - - - <!-- - - <recv request="BYE"> - </recv> - - <send retrans="500"> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - --> - -</scenario> diff --git a/tools/sippxml/account_uas_register.xml b/tools/sippxml/account_uas_register.xml deleted file mode 100644 index e4ebb81227..0000000000 --- a/tools/sippxml/account_uas_register.xml +++ /dev/null @@ -1,63 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> -<!DOCTYPE scenario SYSTEM "sipp.dtd"> - -<!-- This program is free software; you can redistribute it and/or --> -<!-- modify it under the terms of the GNU General Public License as --> -<!-- published by the Free Software Foundation; either version 2 of the --> -<!-- License, or (at your option) any later version. --> -<!-- --> -<!-- This program is distributed in the hope that it will be useful, --> -<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of --> -<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --> -<!-- GNU General Public License for more details. --> -<!-- --> -<!-- You should have received a copy of the GNU General Public License --> -<!-- along with this program; if not, write to the --> -<!-- Free Software Foundation, Inc., --> -<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --> - - -<scenario name="accountcall_client"> - - <send retrans="500"> - <![CDATA[ - - REGISTER sip:[remote_ip] SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];rport;branch=[branch] - Max-Forwards: 70 - From: <sip:27182@[remote_ip]>;tag=[call_number] - To: <sip:27182@[remote_ip]> - Call-ID: REG///[call_id] - CSeq: 1 REGISTER - Contact: <sip:27182@[local_ip]:[local_port]> - Content-Length: 0 - Expires: 300 - - ]]> - </send> - - <recv response="401" auth="true"> - </recv> - - <send retrans="500"> - <![CDATA[ - - REGISTER sip:[remote_ip] SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];rport;branch=[branch] - Max-Forwards: 70 - From: <sip:27182@[remote_ip]>;tag=[call_number] - To: <sip:27182@[remote_ip]> - Call-ID: REG///[call_id] - CSeq: 2 REGISTER - Contact: <sip:27182@[local_ip]:[local_port]> - Content-Length: 0 - Expires: 300 - [authentication username=27182 password=1234] - - ]]> - </send> - - <recv response="200"> - </recv> - -</scenario> diff --git a/tools/sippxml/accountcalluac.xml b/tools/sippxml/accountcalluac.xml deleted file mode 100644 index a5ba5ac283..0000000000 --- a/tools/sippxml/accountcalluac.xml +++ /dev/null @@ -1,186 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> -<!DOCTYPE scenario SYSTEM "sipp.dtd"> - -<!-- This program is free software; you can redistribute it and/or --> -<!-- modify it under the terms of the GNU General Public License as --> -<!-- published by the Free Software Foundation; either version 2 of the --> -<!-- License, or (at your option) any later version. --> -<!-- --> -<!-- This program is distributed in the hope that it will be useful, --> -<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of --> -<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --> -<!-- GNU General Public License for more details. --> -<!-- --> -<!-- You should have received a copy of the GNU General Public License --> -<!-- along with this program; if not, write to the --> -<!-- Free Software Foundation, Inc., --> -<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --> - - -<scenario name="accountcall_client"> - - <send retrans="500"> - <![CDATA[ - - REGISTER sip:[remote_ip] SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];rport;branch=[branch] - Max-Forward: 70 - From: <sip:27182@[remote_ip]:[remote_port]>;tag=[call_number] - To: <sip:27182@[remote_ip]:[remote_port]> - Call-ID: REG///[call_id] - CSeq: 1 REGISTER - Contact: <sip:27182@[remote_ip]:[remote_port]> - Content-Length: 0 - Expires: 300 - - ]]> - </send> - - <recv response="401" auth="true"> - </recv> - - <send retrans="500"> - <![CDATA[ - - REGISTER sip:[remote_ip] SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];rport;branch=[branch] - Max-Forwards: 70 - From: <sip:27182@[remote_ip]:[remote_port]>;tag=[call_number] - To: <sip:27182@[remote_ip]:[remote_port]> - Call-ID: REG///[call_id] - CSeq: 2 REGISTER - Contact: <sip:27182@[remote_ip]:[remote_port]> - Content-Length: 0 - Expires: 300 - [authentication username=27182 password=1234] - - ]]> - </send> - - <recv response="200"> - </recv> - - <pause milliseconds="200"/> - - <send retrans="500"> - <![CDATA[ - - INVITE sip:2000@[remote_ip] SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];rport;branch=[branch] - From: <sip:27182@[remote_ip]:[remote_port]>;tag=[call_number] - To: <sip:2000@[remote_ip]:[remote_port]> - Call-ID: [call_id] - CSeq: 3 INVITE - Contact: sip:27182@[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Functional Test - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv response="401" auth="true"> - </recv> - - <pause milliseconds="200"/> - - <send> - <![CDATA[ - - ACK sip:27182@[remote_ip] SIP/2.0 - Max-Forwards: 70 - Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] - From: <sip:27182@[remote_ip]:[remote_port]>;tag=[call_number] - To: <sip:2000@[remote_ip]:[remote_port]> - Call-ID: [call_id] - CSeq: 4 ACK - Subject: Functional Test - Content-Length: 0 - - ]]> - </send> - - <send retrans="500"> - <![CDATA[ - - INVITE sip:2000@[remote_ip] SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];rport;branch=[branch] - From: <sip:27182@:[remote_ip]:[remote_port]>;tag=[call_number] - To: <sip:2000@[remote_ip]:[remote_port]> - Call-ID: [call_id] - CSeq: 5 INVITE - Contact: sip:27182@[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Functional Test - Content-Type: application/sdp - Content-Length: [len] - [authentication username=27182 password=1234] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv response="100"> - </recv> - - <recv response="180"> - </recv> - - - <recv response="200"> - </recv> - - <send> - <![CDATA[ - - ACK sip:2000@192.168.50.79 SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] - From: <sip:27182@[local_ip]:[local_port]>;tag=[call_number] - To: <sip:2000@192.168.50.79:[remote_port]> - Call-ID: [call_id] - CSeq: 5 ACK - Contact: sip:27182@[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Functional Test - Content-Length: 0 - - ]]> - </send> - - <send retrans="500"> - <![CDATA[ - - BYE sip:2000@192.168.50.79 SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] - From: <sip:27182@[local_ip]:[local_port]>;tag=[call_number] - To: <sip:2000@192.168.50.79:[remote_port]> - Call-ID: [call_id] - CSeq: 6 BYE - Contact: sip:27182@[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Functional Test - Content-Length: 0 - - ]]> - </send> - - - <pause milliseconds="1000"/> - -</scenario> diff --git a/tools/sippxml/accountcalluas.xml b/tools/sippxml/accountcalluas.xml deleted file mode 100644 index 82158ef0a5..0000000000 --- a/tools/sippxml/accountcalluas.xml +++ /dev/null @@ -1,159 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> -<!DOCTYPE scenario SYSTEM "sipp.dtd"> - -<!-- This program is free software; you can redistribute it and/or --> -<!-- modify it under the terms of the GNU General Public License as --> -<!-- published by the Free Software Foundation; either version 2 of the --> -<!-- License, or (at your option) any later version. --> -<!-- --> -<!-- This program is distributed in the hope that it will be useful, --> -<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of --> -<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --> -<!-- GNU General Public License for more details. --> -<!-- --> -<!-- You should have received a copy of the GNU General Public License --> -<!-- along with this program; if not, write to the --> -<!-- Free Software Foundation, Inc., --> -<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --> - - -<scenario name="branch_server"> - <recv request="REGISTER"> - </recv> - - <send> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - Expires: 300 - - ]]> - </send> - - <!-- Set variable 3 if the ua is of the form ua2... --> - <recv request="INVITE" crlf="true"> - <action> - <ereg regexp="ua2" - search_in="hdr" - header="From: " - assign_to="3"/> - </action> - </recv> - - <!-- send 180 then trying if variable 3 is set --> - <send next="1" test="3"> - <![CDATA[ - - SIP/2.0 180 Ringing - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <!-- if not, send a 403 error then skip to wait for a BYE --> - <send next="2"> - <![CDATA[ - - SIP/2.0 403 Error - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <label id="1"/> - - <send> - <![CDATA[ - - SIP/2.0 100 Trying - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <send retrans="500"> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Type: application/sdp - Content-Length: 136 - - v=0 - o=user1 53655765 2353687637 IN IP4 127.0.0.1 - s=- - t=0 0 - c=IN IP4 [media_ip] - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv request="ACK" - optional="true" - rtd="true" - crlf="true"> - </recv> - - <label id="2"/> - - <recv request="BYE"> - </recv> - - <send> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <!-- Keep the call open for a while in case the 200 is lost to be --> - <!-- able to retransmit it if we receive the BYE again. --> - <pause milliseconds="4000"/> - - <!-- Definition of the response time repartition table (unit is ms) --> - <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/> - - <!-- Definition of the call length repartition table (unit is ms) --> - <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/> - -</scenario> diff --git a/tools/sippxml/g711a.pcap b/tools/sippxml/g711a.pcap deleted file mode 100644 index bafea386f396eacbd14871f0156aed76df0166ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73184 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 T6i`DDw0|NmEeSMNm{tS;yh}BP diff --git a/tools/sippxml/ip2ip_uac_send_hangup.xml b/tools/sippxml/ip2ip_uac_send_hangup.xml deleted file mode 100644 index 5c9673644d..0000000000 --- a/tools/sippxml/ip2ip_uac_send_hangup.xml +++ /dev/null @@ -1,98 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> -<!DOCTYPE scenario SYSTEM "sipp.dtd"> - -<!-- This program is free software; you can redistribute it and/or --> -<!-- modify it under the terms of the GNU General Public License as --> -<!-- published by the Free Software Foundation; either version 2 of the --> -<!-- License, or (at your option) any later version. --> -<!-- --> -<!-- This program is distributed in the hope that it will be useful, --> -<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of --> -<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --> -<!-- GNU General Public License for more details. --> -<!-- --> -<!-- You should have received a copy of the GNU General Public License --> -<!-- along with this program; if not, write to the --> -<!-- Free Software Foundation, Inc., --> -<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --> - - -<scenario name="accountcall_client"> - - <send retrans="500"> - <![CDATA[ - - INVITE sip:[remote_ip] SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];rport;branch=[branch] - From: <sip:[remote_ip]:[remote_port]>;tag=[call_number] - To: <sip:[remote_ip]:[remote_port]> - Call-ID: [call_id] - CSeq: 1 INVITE - Contact: sip:[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Functional Test - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv response="100" optional="true"> - </recv> - - <recv response="180"> - </recv> - - - <recv response="200"> - <action> - <ereg regexp="tag=.*" search_in="hdr" header="To:" check_it="true" assign_to="1" /> - </action> - </recv> - - <send> - <![CDATA[ - - ACK sip:[remote_ip] SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] - From: <sip:[local_ip]:[local_port]>;tag=[call_number] - To: <sip:[remote_ip]:[remote_port]>;tag=[$1] - Call-ID: [call_id] - CSeq: 2 ACK - Contact: sip:[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Functional Test - Content-Length: 0 - - ]]> - </send> - - <send retrans="500"> - <![CDATA[ - - BYE sip:[remote_ip] SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] - From: <sip:[local_ip]:[local_port]>;tag=[call_number] - To: <sip:[remote_ip]:[remote_port]>;tag=[$1] - Call-ID: [call_id] - CSeq: 3 BYE - Contact: sip:[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Functional Test - Content-Length: 0 - - ]]> - </send> - - <recv response="200"> - </recv> - -</scenario> diff --git a/tools/sippxml/ip2ip_uac_send_peer_hungup.xml b/tools/sippxml/ip2ip_uac_send_peer_hungup.xml deleted file mode 100644 index 048b0d8a06..0000000000 --- a/tools/sippxml/ip2ip_uac_send_peer_hungup.xml +++ /dev/null @@ -1,92 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> -<!DOCTYPE scenario SYSTEM "sipp.dtd"> - -<!-- This program is free software; you can redistribute it and/or --> -<!-- modify it under the terms of the GNU General Public License as --> -<!-- published by the Free Software Foundation; either version 2 of the --> -<!-- License, or (at your option) any later version. --> -<!-- --> -<!-- This program is distributed in the hope that it will be useful, --> -<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of --> -<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --> -<!-- GNU General Public License for more details. --> -<!-- --> -<!-- You should have received a copy of the GNU General Public License --> -<!-- along with this program; if not, write to the --> -<!-- Free Software Foundation, Inc., --> -<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --> - - -<scenario name="accountcall_client"> - - <send retrans="1000"> - <![CDATA[ - - INVITE sip:[remote_ip] SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];rport;branch=[branch] - From: <sip:[remote_ip]:[remote_port]>;tag=[call_number] - To: <sip:[remote_ip]:[remote_port]> - Call-ID: [call_id] - CSeq: 1 INVITE - Contact: sip:[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Functional Test - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv response="100" optional="true"> - </recv> - - <recv response="180"> - </recv> - - <recv response="200"> - </recv> - - <send> - <![CDATA[ - - ACK sip:192.168.50.79 SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] - From: <sip:[local_ip]:[local_port]>;tag=[call_number] - To: <sip:[remote_ip]:[remote_port]> - Call-ID: [call_id] - CSeq: 2 ACK - Contact: sip:[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Functional Test - Content-Length: 0 - - ]]> - </send> - - <recv request="BYE"> - </recv> - - <send> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - -</scenario> diff --git a/tools/sippxml/ip2ip_uas_recv_hangup.xml b/tools/sippxml/ip2ip_uas_recv_hangup.xml deleted file mode 100644 index 45023d08fa..0000000000 --- a/tools/sippxml/ip2ip_uas_recv_hangup.xml +++ /dev/null @@ -1,87 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE scenario SYSTEM "sipp.dtd"> - - -<scenario name="Basic UAS responder"> - - <recv request="INVITE" crlf="true"> - </recv> - - - <send> - <![CDATA[ - - SIP/2.0 180 Ringing - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <send retrans="500"> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <!-- tag from From: header is required to build the To: header in - -- Bye request. --> - - <recv request="ACK"> - <action> - <ereg regexp="tag=.*" search_in="hdr" header="From:" check_it="true" assign_to="1" /> - </action> - </recv> - - <pause milliseconds="500"/> - - <send retrans="500"> - <![CDATA[ - - BYE sip:[service] SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];rport;branch=[branch] - From: <sip:[local_ip]:[local_port]>;tag=[call_number] - To: <sip:[remote_ip]:[remote_port]>;[$1] - [last_Call-ID:] - CSeq: [cseq] BYE - Contact: <sip:test@[local_ip]:[local_port]> - Max-Forwards: 70 - Subject: Functional Test - Content-Length: 0 - - ]]> - </send> - - <recv response="200"> - </recv> - - <pause milliseconds="1000"/> - - - <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/> - - <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/> - -</scenario> diff --git a/tools/sippxml/ip2ip_uas_recv_hold_offhold.xml b/tools/sippxml/ip2ip_uas_recv_hold_offhold.xml deleted file mode 100644 index bae7eaa2bc..0000000000 --- a/tools/sippxml/ip2ip_uas_recv_hold_offhold.xml +++ /dev/null @@ -1,187 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE scenario SYSTEM "sipp.dtd"> - - -<scenario name="UAS HOLD/OFFHOLD"> - - <!-- Receive a new call --> - - <recv request="INVITE" crlf="true"> - <action> - <ereg regexp="sendrecv" search_in="body" check_it="true" assign_to="1"/> - <log message="Media is [$1]"/> - </action> - </recv> - - <send> - <![CDATA[ - - SIP/2.0 180 Ringing - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <send retrans="500"> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> -</send> - - <recv request="ACK" optional="true" rtd="true" crlf="true"> - </recv> - - <!-- This call is now on HOLD: sendonly tell to PBX to send music on hold--> - - <recv request="INVITE" crlf="true"> - <action> - <ereg regexp="sendonly" search_in="body" check_it="true" assign_to="2"/> - <log message="Media is [$2]"/> - </action> - </recv> - - <send> - <![CDATA[ - - SIP/2.0 180 Ringing - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <send retrans="500"> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv request="ACK" optional="true" rtd="true" crlf="true"> - </recv> - - <!-- OFFHOLD this call --> - - <recv request="INVITE" crlf="true"> - <action> - <ereg regexp="sendrecv" search_in="body" check_it="true" assign_to="3"/> - <log message="Media is [$3]"/> - </action> - </recv> - - - <send> - <![CDATA[ - - SIP/2.0 180 Ringing - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <send retrans="500"> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv request="ACK" optional="true" rtd="true" crlf="true"> - </recv> - - <!-- Hangup this call --> - - <recv request="BYE"> - </recv> - - <send> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <pause milliseconds="4000"/> - - - <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/> - - <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/> - -</scenario> diff --git a/tools/sippxml/ip2ip_uas_recv_peer_hungup.xml b/tools/sippxml/ip2ip_uas_recv_peer_hungup.xml deleted file mode 100644 index 0d9da874ba..0000000000 --- a/tools/sippxml/ip2ip_uas_recv_peer_hungup.xml +++ /dev/null @@ -1,78 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE scenario SYSTEM "sipp.dtd"> - - -<scenario name="Basic UAS responder"> - - <recv request="INVITE" crlf="true"> - </recv> - - - <send> - <![CDATA[ - - SIP/2.0 180 Ringing - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <send retrans="500"> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> -</send> - - <recv request="ACK" optional="true" rtd="true" crlf="true"> - </recv> - - <recv request="INVITE" optional="true"> - </recv> - - <recv request="BYE"> - </recv> - - <send> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - - <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/> - - <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/> - -</scenario> diff --git a/tools/sippxml/ip2ipcalluac.xml b/tools/sippxml/ip2ipcalluac.xml deleted file mode 100644 index 7d146cec2b..0000000000 --- a/tools/sippxml/ip2ipcalluac.xml +++ /dev/null @@ -1,85 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE scenario SYSTEM "sipp.dtd"> - - -<scenario name="Basic Sipstone UAC"> - - <send retrans="500"> - <![CDATA[ - - INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] - From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[call_number] - To: sut <sip:[service]@[remote_ip]:[remote_port]> - Call-ID: [call_id] - CSeq: 1 INVITE - Contact: sip:sipp@[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Performance Test - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv response="100" - optional="true"> - </recv> - - <recv response="180" optional="true"> - </recv> - - <recv response="200" rtd="true"> - </recv> - - <send> - <![CDATA[ - - ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] - From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[call_number] - To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param] - Call-ID: [call_id] - CSeq: 1 ACK - Contact: sip:sipp@[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Performance Test - Content-Length: 0 - - ]]> - </send> - - <pause/> - - <send retrans="500"> - <![CDATA[ - - BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] - From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[call_number] - To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param] - Call-ID: [call_id] - CSeq: 2 BYE - Contact: sip:sipp@[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Performance Test - Content-Length: 0 - - ]]> - </send> - - <recv response="200" crlf="true"> - </recv> - - <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/> - - <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/> - -</scenario> diff --git a/tools/sippxml/ip2ipcalluas.xml b/tools/sippxml/ip2ipcalluas.xml deleted file mode 100644 index 08d17440ea..0000000000 --- a/tools/sippxml/ip2ipcalluas.xml +++ /dev/null @@ -1,80 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE scenario SYSTEM "sipp.dtd"> - - -<scenario name="Basic UAS responder"> - - <recv request="INVITE" crlf="true"> - </recv> - - - <send> - <![CDATA[ - - SIP/2.0 180 Ringing - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <send retrans="500"> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv request="ACK" - optional="true" - rtd="true" - crlf="true"> - </recv> - - <recv request="BYE"> - </recv> - - <send> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <pause milliseconds="4000"/> - - - <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/> - - <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/> - -</scenario> diff --git a/tools/sippxml/simpleServiceRoute.xml b/tools/sippxml/simpleServiceRoute.xml deleted file mode 100644 index c200717631..0000000000 --- a/tools/sippxml/simpleServiceRoute.xml +++ /dev/null @@ -1,85 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE scenario SYSTEM "sipp.dtd"> - -<scenario name="Basic Sipstone UAC"> - - <send retrans="500"> - <![CDATA[ - - INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] - From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[call_number] - To: sut <sip:[service]@[remote_ip]:[remote_port]> - Call-ID: [call_id] - CSeq: 1 INVITE - Contact: sip:sipp@[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Performance Test - Content-Type: application/sdp - Content-Length: [len] - Route: <sip:sipp@[local_ip]:[local_port]> - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv response="100" - optional="true"> - </recv> - - <recv response="183" optional="true"> - </recv> - - <recv response="200" rtd="true"> - </recv> - - <send> - <![CDATA[ - - ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] - From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[call_number] - To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param] - Call-ID: [call_id] - CSeq: 1 ACK - Contact: sip:sipp@[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Performance Test - Content-Length: 0 - - ]]> - </send> - - <pause/> - - <send retrans="500"> - <![CDATA[ - - BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] - From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[call_number] - To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param] - Call-ID: [call_id] - CSeq: 2 BYE - Contact: sip:sipp@[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Performance Test - Content-Length: 0 - - ]]> - </send> - - <recv response="200" crlf="true"> - </recv> - - <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/> - - <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/> - -</scenario> diff --git a/tools/sippxml/sippusage.txt b/tools/sippxml/sippusage.txt deleted file mode 100644 index f1a5190882..0000000000 --- a/tools/sippxml/sippusage.txt +++ /dev/null @@ -1,460 +0,0 @@ -Usage: - - sipp remote_host[:remote_port] [options] - - Available options: - - -v : Display version and copyright information. - - -aa : Enable automatic 200 OK answer for INFO, UPDATE and - NOTIFY messages. - - -auth_uri : Force the value of the URI for authentication. - By default, the URI is composed of - remote_ip:remote_port. - - -base_cseq : Start value of [cseq] for each call. - - -bg : Launch SIPp in background mode. - - -bind_local : Bind socket to local IP address, i.e. the local IP - address is used as the source IP address. If SIPp runs - in server mode it will only listen on the local IP - address instead of all IP addresses. - - -buff_size : Set the send and receive buffer size. - - -calldebug_file : Set the name of the call debug file. - - -calldebug_overwrite: Overwrite the call debug file (default true). - - -cid_str : Call ID string (default %u-%p@%s). %u=call_number, - %s=ip_address, %p=process_number, %%=% (in any order). - - -ci : Set the local control IP address - - -cp : Set the local control port number. Default is 8888. - - -d : Controls the length of calls. More precisely, this - controls the duration of 'pause' instructions in the - scenario, if they do not have a 'milliseconds' section. - Default value is 0 and default unit is milliseconds. - - -deadcall_wait : How long the Call-ID and final status of calls should be - kept to improve message and error logs (default unit is - ms). - - -default_behaviors: Set the default behaviors that SIPp will use. Possbile - values are: - - all Use all default behaviors - - none Use no default behaviors - - bye Send byes for aborted calls - - abortunexp Abort calls on unexpected messages - - pingreply Reply to ping requests - If a behavior is prefaced with a -, then it is turned - off. Example: all,-bye - - - -error_file : Set the name of the error log file. - - -error_overwrite : Overwrite the error log file (default true). - - -f : Set the statistics report frequency on screen. Default is - 1 and default unit is seconds. - - -fd : Set the statistics dump log report frequency. Default is - 60 and default unit is seconds. - - -i : Set the local IP address for 'Contact:','Via:', and - 'From:' headers. Default is primary host IP address. - - - -inf : Inject values from an external CSV file during calls into - the scenarios. - First line of this file say whether the data is to be - read in sequence (SEQUENTIAL), random (RANDOM), or user - (USER) order. - Each line corresponds to one call and has one or more - ';' delimited data fields. Those fields can be referred - as [field0], [field1], ... in the xml scenario file. - Several CSV files can be used simultaneously (syntax: - -inf f1.csv -inf f2.csv ...) - - -infindex : file field - Create an index of file using field. For example -inf - users.csv -infindex users.csv 0 creates an index on the - first key. - - -ip_field : Set which field from the injection file contains the IP - address from which the client will send its messages. - If this option is omitted and the '-t ui' option is - present, then field 0 is assumed. - Use this option together with '-t ui' - - -l : Set the maximum number of simultaneous calls. Once this - limit is reached, traffic is decreased until the number - of open calls goes down. Default: - (3 * call_duration (s) * rate). - - -log_file : Set the name of the log actions log file. - - -log_overwrite : Overwrite the log actions log file (default true). - - -lost : Set the number of packets to lose by default (scenario - specifications override this value). - - -rtcheck : Select the retransmisison detection method: full - (default) or loose. - - -m : Stop the test and exit when 'calls' calls are processed - - -mi : Set the local media IP address (default: local primary - host IP address) - - -master : 3pcc extended mode: indicates the master number - - -max_recv_loops : Set the maximum number of messages received read per - cycle. Increase this value for high traffic level. The - default value is 1000. - - -max_sched_loops : Set the maximum number of calsl run per event loop. - Increase this value for high traffic level. The default - value is 1000. - - -max_reconnect : Set the the maximum number of reconnection. - - -max_retrans : Maximum number of UDP retransmissions before call ends on - timeout. Default is 5 for INVITE transactions and 7 for - others. - - -max_invite_retrans: Maximum number of UDP retransmissions for invite - transactions before call ends on timeout. - - -max_non_invite_retrans: Maximum number of UDP retransmissions for non-invite - transactions before call ends on timeout. - - -max_log_size : What is the limit for error and message log file sizes. - - -max_socket : Set the max number of sockets to open simultaneously. - This option is significant if you use one socket per - call. Once this limit is reached, traffic is distributed - over the sockets already opened. Default value is 50000 - - -mb : Set the RTP echo buffer size (default: 2048). - - -message_file : Set the name of the message log file. - - -message_overwrite: Overwrite the message log file (default true). - - -mp : Set the local RTP echo port number. Default is 6000. - - -nd : No Default. Disable all default behavior of SIPp which - are the following: - - On UDP retransmission timeout, abort the call by - sending a BYE or a CANCEL - - On receive timeout with no ontimeout attribute, abort - the call by sending a BYE or a CANCEL - - On unexpected BYE send a 200 OK and close the call - - On unexpected CANCEL send a 200 OK and close the call - - On unexpected PING send a 200 OK and continue the call - - On any other unexpected message, abort the call by - sending a BYE or a CANCEL - - - -nr : Disable retransmission in UDP mode. - - -nostdin : Disable stdin. - - - -p : Set the local port number. Default is a random free port - chosen by the system. - - -pause_msg_ign : Ignore the messages received during a pause defined in - the scenario - - -periodic_rtd : Reset response time partition counters each logging - interval. - - -plugin : Load a plugin. - - -r : Set the call rate (in calls per seconds). This value can - bechanged during test by pressing '+','_','*' or '/'. - Default is 10. - pressing '+' key to increase call rate by 1 * - rate_scale, - pressing '-' key to decrease call rate by 1 * - rate_scale, - pressing '*' key to increase call rate by 10 * - rate_scale, - pressing '/' key to decrease call rate by 10 * - rate_scale. - If the -rp option is used, the call rate is calculated - with the period in ms given by the user. - - -rp : Specify the rate period for the call rate. Default is 1 - second and default unit is milliseconds. This allows - you to have n calls every m milliseconds (by using -r n - -rp m). - Example: -r 7 -rp 2000 ==> 7 calls every 2 seconds. - -r 10 -rp 5s => 10 calls every 5 seconds. - - -rate_scale : Control the units for the '+', '-', '*', and '/' keys. - - -rate_increase : Specify the rate increase every -fd units (default is - seconds). This allows you to increase the load for each - independent logging period. - Example: -rate_increase 10 -fd 10s - ==> increase calls by 10 every 10 seconds. - - -rate_max : If -rate_increase is set, then quit after the rate - reaches this value. - Example: -rate_increase 10 -rate_max 100 - ==> increase calls by 10 until 100 cps is hit. - - -no_rate_quit : If -rate_increase is set, do not quit after the rate - reaches -rate_max. - - -recv_timeout : Global receive timeout. Default unit is milliseconds. If - the expected message is not received, the call times out - and is aborted. - - -send_timeout : Global send timeout. Default unit is milliseconds. If a - message is not sent (due to congestion), the call times - out and is aborted. - - -sleep : How long to sleep for at startup. Default unit is - seconds. - - -reconnect_close : Should calls be closed on reconnect? - - -reconnect_sleep : How long (in milliseconds) to sleep between the close and - reconnect? - - -ringbuffer_files: How many error/message files should be kept after - rotation? - - -ringbuffer_size : How large should error/message files be before they get - rotated? - - -rsa : Set the remote sending address to host:port for sending - the messages. - - -rtp_echo : Enable RTP echo. RTP/UDP packets received on port defined - by -mp are echoed to their sender. - RTP/UDP packets coming on this port + 2 are also echoed - to their sender (used for sound and video echo). - - -rtt_freq : freq is mandatory. Dump response times every freq calls - in the log file defined by -trace_rtt. Default value is - 200. - - -s : Set the username part of the resquest URI. Default is - 'service'. - - -sd : Dumps a default scenario (embeded in the sipp executable) - - -sf : Loads an alternate xml scenario file. To learn more - about XML scenario syntax, use the -sd option to dump - embedded scenarios. They contain all the necessary help. - - -shortmessage_file: Set the name of the short message log file. - - -shortmessage_overwrite: Overwrite the short message log file (default true). - - -oocsf : Load out-of-call scenario. - - -oocsn : Load out-of-call scenario. - - -skip_rlimit : Do not perform rlimit tuning of file descriptor limits. - Default: false. - - -slave : 3pcc extended mode: indicates the slave number - - -slave_cfg : 3pcc extended mode: indicates the file where the master - and slave addresses are stored - - -sn : Use a default scenario (embedded in the sipp executable). - If this option is omitted, the Standard SipStone UAC - scenario is loaded. - Available values in this version: - - - 'uac' : Standard SipStone UAC (default). - - 'uas' : Simple UAS responder. - - 'regexp' : Standard SipStone UAC - with regexp and - variables. - - 'branchc' : Branching and conditional branching in - scenarios - client. - - 'branchs' : Branching and conditional branching in - scenarios - server. - - Default 3pcc scenarios (see -3pcc option): - - - '3pcc-C-A' : Controller A side (must be started after - all other 3pcc scenarios) - - '3pcc-C-B' : Controller B side. - - '3pcc-A' : A side. - - '3pcc-B' : B side. - - - -stat_delimiter : Set the delimiter for the statistics file - - -stf : Set the file name to use to dump statistics - - -t : Set the transport mode: - - u1: UDP with one socket (default), - - un: UDP with one socket per call, - - ui: UDP with one socket per IP address The IP - addresses must be defined in the injection file. - - t1: TCP with one socket, - - tn: TCP with one socket per call, - - l1: TLS with one socket, - - ln: TLS with one socket per call, - - c1: u1 + compression (only if compression plugin - loaded), - - cn: un + compression (only if compression plugin - loaded). This plugin is not provided with sipp. - - - -timeout : Global timeout. Default unit is seconds. If this option - is set, SIPp quits after nb units (-timeout 20s quits - after 20 seconds). - - -timeout_error : SIPp fails if the global timeout is reached is set - (-timeout option required). - - -timer_resol : Set the timer resolution. Default unit is milliseconds. - This option has an impact on timers precision.Small - values allow more precise scheduling but impacts CPU - usage.If the compression is on, the value is set to - 50ms. The default value is 10ms. - - -sendbuffer_warn : Produce warnings instead of errors on SendBuffer - failures. - - -trace_msg : Displays sent and received SIP messages in <scenario file - name>_<pid>_messages.log - - -trace_shortmsg : Displays sent and received SIP messages as CSV in - <scenario file name>_<pid>_shortmessages.log - - -trace_screen : Dump statistic screens in the - <scenario_name>_<pid>_ s.log file when quitting - SIPp. Useful to get a final status report in background - mode (-bg option). - - -trace_err : Trace all unexpected messages in <scenario file - name>_<pid>_errors.log. - - -trace_calldebug : Dumps debugging information about aborted calls to - <scenario_name>_<pid>_calldebug.log file. - - -trace_stat : Dumps all statistics in <scenario_name>_<pid>.csv file. - Use the '-h stat' option for a detailed description of - the statistics file content. - - -trace_counts : Dumps individual message counts in a CSV file. - - -trace_rtt : Allow tracing of all response times in <scenario file - name>_<pid>_rtt.csv. - - -trace_logs : Allow tracing of <log> actions in <scenario file - name>_<pid>_logs.log. - - -users : Instead of starting calls at a fixed rate, begin 'users' - calls at startup, and keep the number of calls constant. - - -watchdog_interval: Set gap between watchdog timer firings. Default is 400. - - -watchdog_reset : If the watchdog timer has not fired in more than this - time period, then reset the max triggers counters. - Default is 10 minutes. - - -watchdog_minor_threshold: If it has been longer than this period between watchdog - executions count a minor trip. Default is 500. - - -watchdog_major_threshold: If it has been longer than this period between watchdog - executions count a major trip. Default is 3000. - - -watchdog_major_maxtriggers: How many times the major watchdog timer can be tripped - before the test is terminated. Default is 10. - - -watchdog_minor_maxtriggers: How many times the minor watchdog timer can be tripped - before the test is terminated. Default is 120. - - -ap : Set the password for authentication challenges. Default - is 'password - - -tls_cert : Set the name for TLS Certificate file. Default is - 'cacert.pem - - -tls_key : Set the name for TLS Private Key file. Default is - 'cakey.pem' - - -tls_crl : Set the name for Certificate Revocation List file. If not - specified, X509 CRL is not activated. - - -3pcc : Launch the tool in 3pcc mode ("Third Party call - control"). The passed ip address is depending on the - 3PCC role. - - When the first twin command is 'sendCmd' then this is - the address of the remote twin socket. SIPp will try to - connect to this address:port to send the twin command - (This instance must be started after all other 3PCC - scenarii). - Example: 3PCC-C-A scenario. - - When the first twin command is 'recvCmd' then this is - the address of the local twin socket. SIPp will open - this address:port to listen for twin command. - Example: 3PCC-C-B scenario. - - -tdmmap : Generate and handle a table of TDM circuits. - A circuit must be available for the call to be placed. - Format: -tdmmap {0-3}{99}{5-8}{1-31} - - -key : keyword value - Set the generic parameter named "keyword" to "value". - - -set : variable value - Set the global variable parameter named "variable" to - "value". - - -dynamicStart : variable value - Set the start offset of dynamic_id varaiable - - -dynamicMax : variable value - Set the maximum of dynamic_id variable - - -dynamicStep : variable value - Set the increment of dynamic_id variable - -Signal handling: - - SIPp can be controlled using posix signals. The following signals - are handled: - USR1: Similar to press 'q' keyboard key. It triggers a soft exit - of SIPp. No more new calls are placed and all ongoing calls - are finished before SIPp exits. - Example: kill -SIGUSR1 732 - USR2: Triggers a dump of all statistics screens in - <scenario_name>_<pid>_screens.log file. Especially useful - in background mode to know what the current status is. - Example: kill -SIGUSR2 732 - -Exit code: - - Upon exit (on fatal error or when the number of asked calls (-m - option) is reached, sipp exits with one of the following exit - code: - 0: All calls were successful - 1: At least one call failed - 97: exit on internal command. Calls may have been processed - 99: Normal exit without calls processed - -1: Fatal error - - -Example: - - Run sipp with embedded server (uas) scenario: - ./sipp -sn uas - On the same host, run sipp with embedded client (uac) scenario - ./sipp -sn uac 127.0.0.1 diff --git a/tools/sippxml/tempscript.sh b/tools/sippxml/tempscript.sh deleted file mode 100644 index 090a058ed8..0000000000 --- a/tools/sippxml/tempscript.sh +++ /dev/null @@ -1,5 +0,0 @@ -SERVERPORT=5064 - -sipp -sf account_uas_register_bis.xml 192.168.50.79 -i 192.168.50.182 -p ${SERVERPORT} -l 1 -m 1 - -sipp -sf account_uas_receive_transfer.xml 192.168.50.79 -i 192.168.50.182 -p ${SERVERPORT} -l 1 \ No newline at end of file diff --git a/tools/sippxml/testEarlyMedia.xml b/tools/sippxml/testEarlyMedia.xml deleted file mode 100644 index 7909bebecd..0000000000 --- a/tools/sippxml/testEarlyMedia.xml +++ /dev/null @@ -1,107 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE scenario SYSTEM "sipp.dtd"> - -<!-- sudo sipp -sf testEarlyMedia.xml 127.0.0.1 -i 127.0.0.1 -p 5062 -l 1 -m 1 -mp 6000 --> - -<scenario name="Basic UAS responder"> - - <recv request="INVITE" crlf="true"> - </recv> - - - <send> - <![CDATA[ - - SIP/2.0 100 Ringing - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <send> - <![CDATA[ - - SIP/2.0 183 Trying - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <!-- Play a pre-recorded PCAP file (RTP stream) --> - <nop> - <action> - <exec play_pcap_audio="g711a.pcap"/> - </action> - </nop> - - <!-- Pause 8 seconds, which is approximately the duration of the --> - <!-- PCAP file --> - <pause milliseconds="8000"/> - - <send retrans="500"> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: [len] - - ]]> - </send> - - <recv request="ACK" - optional="true" - rtd="true" - crlf="true"> - </recv> - - <recv request="BYE"> - </recv> - - <send> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <pause milliseconds="4000"/> - - - <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/> - - <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/> - -</scenario> diff --git a/tools/sippxml/testsuiteuac.sh b/tools/sippxml/testsuiteuac.sh deleted file mode 100644 index 5635003582..0000000000 --- a/tools/sippxml/testsuiteuac.sh +++ /dev/null @@ -1,383 +0,0 @@ -#!/bin/bash - - -LOCALPORT=5062 -LOCALIP_lo=127.0.0.1 -LOCALIP_eth0=192.168.50.182 - -REMOTEADDR_lo=127.0.0.1:5060 -REMOTEADDR_ast=192.168.50.79 - -# SCENARIO 1 Test 1 -function test_ip2ip_send_hangup { - - # start sflphoned - # /usr/lib/sflphone/sflphoned& - - # start sipp server to receive calls from sflphone - sipp -sf ip2ip_uas_recv_peer_hungup.xml ${REMOTEADDR_lo} -i ${LOCALIP_lo} -p ${LOCALPORT} - - # wait some time to make sure sflphoned is started - # sleep 1; - - # run python client and script to make calls - # python ../tools/pysflphone/pysflphone_testdbus.py & - - # kill every one - # bashtrap -} - -# SCENARIO 1 Test 2 -function test_ip2ip_send_peer_hungup { - - # start sflphoned - # /usr/lib/sflphone/sflphoned& - - # start sipp server to receive calls from sflphone and then hangup - sipp -sf ip2ip_uas_recv_hangup.xml ${REMOTEADDR_lo} -s ${REMOTEADDR_lo} -i ${LOCALIP_lo} -p ${LOCALPORT} - - # wait some time to make sure sflphoned is started - # sleep 1; - - # run python client and script to make calls - # python ../tools/pysflphone/pysflphone_testdbus.py & - - # kill every one - bashtrap -} - - -# SCENARIO 1 Test 3 -function test_ip2ip_recv_hangup { - - # start sflphoned - # /usr/lib/sflphone/sflphoned& - - # wait some time to make sure sflphoned is started - # sleep 1; - - # python ../tools/pysflphone/pysflphone_testdbus.py & - - # wait some time to make sure client is bound - # sleep 1; - - # start sipp client and send calls - sipp -sf ip2ip_uac_send_peer_hungup.xml ${REMOTEADDR_lo} -i ${LOCALIP_lo} -p ${LOCALPORT} -l 1 -m 10 - - # kill every one - # bashtrap -} - - -# SCENARIO 1 Test 4 -function test_ip2ip_recv_peer_hungup { - - # start sflphoned - # /usr/lib/sflphone/sflphoned& - - # wait some time to make sure sflphoned is started - # sleep 1; - - # python ../tools/pysflphone/pysflphone_testdbus.py & - - # wait some time to make sure client is bound - # sleep 1; - - # start sipp client and send calls - sipp -sf ip2ip_uac_send_hangup.xml ${REMOTEADDR_lo} -i ${LOCALIP_lo} -p ${LOCALPORT} -l 1 -m 10 - - # kill every one - # bashtrap -} - - -# SCENARIO 2 Test 1 -function test_account_send_hangup { - - # start sflphoned - # /usr/lib/sflphone/sflphoned& - - # wait some time to make sure sflphoned is started - # sleep 1; - - # python ../tools/pysflphone/pysflphone_testdbus.py & - - # wait some time to make sure client is bound - # sleep 1; - - # process only one registration - sipp -sf account_uas_register.xml ${REMOTEADDR_ast} -i ${LOCALIP_eth0} -p ${LOCALPORT} -l 1 -m 1 - - # start sipp client and send calls - sipp -sf account_uas_recv_peer_hungup.xml ${REMOTEADDR_ast} -i ${LOCALIP_eth0} -p ${LOCALPORT} -l 1 - - # kill every one - # bashtrap -} - -# SCENARIO 2 Test 2 -function test_account_send_peer_hungup { - - # start sflphoned - # /usr/lib/sflphone/sflphoned& - - # wait some time to make sure sflphoned is started - # sleep 1; - - # python ../tools/pysflphone/pysflphone_testdbus.py & - - # wait some time to make sure client is bound - # sleep 1; - - # process only one registration - sipp -sf account_uas_register.xml ${REMOTEADDR_ast} -i ${LOCALIP_eth0} -p ${LOCALPORT} -l 1 -m 1 - - # start sipp client and send calls - sipp -sf account_uas_recv_hangup.xml ${REMOTEADDR_ast} -i ${LOCALIP_eth0} -p ${LOCALPORT} -l 1 - - # kill every one - # bashtrap -} - -# SCENARIO 2 Test 3 -function test_account_recv_hangup { - - # start sflphoned - # /usr/lib/sflphone/sflphoned& - - # wait some time to make sure sflphoned is started - # sleep 1; - - # python ../tools/pysflphone/pysflphone_testdbus.py & - - # wait some time to make sure client is bound - # sleep 1; - - # process only one registration - sipp -sf account_uas_register.xml ${REMOTEADDR_ast} -i ${LOCALIP_eth0} -p ${LOCALPORT} -l 1 -m 1 - - # start sipp client and send calls - sipp -sf account_uac_send_peer_hungup.xml ${REMOTEADDR_ast} -i ${LOCALIP_eth0} -p ${LOCALPORT} -l 1 -m 10 - # kill every one - # bashtrap -} - -# SCENARIO 2 Test 4 -function test_account_recv_peer_hungup { - - # start sflphoned - # /usr/lib/sflphone/sflphoned& - - # wait some time to make sure sflphoned is started - # sleep 1; - - # python ../tools/pysflphone/pysflphone_testdbus.py & - - # wait some time to make sure client is bound - # sleep 1; - - # process only one registration - sipp -sf account_uas_register.xml ${REMOTEADDR_ast} -i ${LOCALIP_eth0} -p ${LOCALPORT} -l 1 -m 1 - - # start sipp client and send calls - sipp -sf account_uac_send_hangup.xml ${REMOTEADDR_ast} -i ${LOCALIP_eth0} -p ${LOCALPORT} -l 1 -m 10 - - # kill every one - # bashtrap -} - -# SCENARIO 3 Test 1 -function test_ip2ip_send_hold_offhold { - - # start sflphoned - # /usr/lib/sflphone/sflphoned& - - # wait some time to make sure sflphoned is started - # sleep 1; - - # python ../tools/pysflphone/pysflphone_testdbus.py & - - # wait some time to make sure client is bound - # sleep 1; - - # start sipp client and send calls - sipp -sf ip2ip_uas_recv_hold_offhold.xml ${REMOTEADDR_lo} -i ${LOCALIP_lo} -p ${LOCALPORT} - # kill every one - # bashtrap -} - -# SCENARIO 4 Test 1 -function test_account_send_transfer { - - # start sflphoned - # /usr/lib/sflphone/sflphoned& - - # wait some time to make sure sflphoned is started - # sleep 1; - - # python ../tools/pysflphone/pysflphone_testdbus.py & - - # wait some time to make sure client is bound - # sleep 1; - - # process only one registration - sipp -sf account_uas_register.xml ${REMOTEADDR_ast} -i ${LOCALIP_eth0} -p ${LOCALPORT} -l 1 -m 1 - - # start sipp client and send calls - sipp -sf account_uas_recv_transfered.xml ${REMOTEADDR_ast} -i ${LOCALIP_eth0} -p ${LOCALPORT} -l 1 - - # kill every one - # bashtrap -} - - -# SCENARIO 5 Test 1 -function test_ip2ip_send_refused { - - # start sflphoned - # /usr/lib/sflphone/sflphoned& - - # start sipp server to receive calls from sflphone and then hangup - sipp -sf ip2ip_uac_send_refused.xml ${REMOTEADDR_lo} -s ${REMOTEADDR_lo} -i ${LOCALIP_lo} -p ${LOCALPORT} -l 1 - - # wait some time to make sure sflphoned is started - # sleep 1; - - # run python client and script to make calls - # python ../tools/pysflphone/pysflphone_testdbus.py & - - # kill every one - bashtrap -} - - -# SCENARIO 6 Test 1 -function test_mult_ip2ip_send_hangup { - - # start sflphoned - # /usr/lib/sflphone/sflphoned& - - # start sipp server to receive calls from sflphone - sipp -sf ip2ip_uac_send_hangup.xml 127.0.0.1:5060 -i 127.0.0.1 -p 5062 -l 1 -m 10 - sipp -sf ip2ip_uac_send_hangup.xml 127.0.0.1:5060 -i 127.0.0.1 -p 5064 -l 1 -m 10 - sipp -sf ip2ip_uac_send_hangup.xml 127.0.0.1:5060 -i 127.0.0.1 -p 5066 -l 1 -m 10 - # sipp -sf ip2ip_uac_send_hangup.xml ${REMOTEADDR_lo} -i ${LOCALIP_lo} -p ${LOCALPORT} -l 1 -m 10 - - # wait some time to make sure sflphoned is started - # sleep 1; - - # run python client and script to make calls - # python ../tools/pysflphone/pysflphone_testdbus.py & - - # kill every one - # bashtrap -} - - -# SCENARIO 6 Test 2 -function test_mult_ip2ip_recv_peer_hangup { - - # start sflphoned - # /usr/lib/sflphone/sflphoned& - - # start sipp server to receive calls from sflphone - sipp -sf ip2ip_uac_send_hangup.xml 127.0.0.1 -i 127.0.0.1:5060 -p 5062 - sipp -sf ip2ip_uac_send_hangup.xml 127.0.0.1 -i 127.0.0.1:5060 -p 5064 - sipp -sf ip2ip_uac_send_hangup.xml 127.0.0.1 -i 127.0.0.1:5060 -p 5066 - # sipp -sf ip2ip_uas_recv_peer_hungup.xml ${REMOTEADDR_lo} -i ${LOCALIP_lo} -p ${LOCALPORT} - - # wait some time to make sure sflphoned is started - # sleep 1; - - # run python client and script to make calls - # python ../tools/pysflphone/pysflphone_testdbus.py & - - # kill every one - # bashtrap -} - - -# function called if CTRL-C detected -bashtrap() -{ - killall sipp - killall sflphoned -} - - -# ============================ Test Suite ============================ - - - -# SCENARIO 1: (IP2IP) Normal flow calls - -# Test 1: - Send an IP2IP call -# - Hangup -test_ip2ip_send_hangup - -# Test 2: - Send an IP2IP call -# - Peer Hangup -# test_ip2ip_send_peer_hungup - -# Test 3: - Receive an IP2IP call -# - Hangup -# test_ip2ip_recv_hangup - -# Test 4: - Receive an IP2IP call -# - Peer Hangup -# test_ip2ip_recv_peer_hungup - - - -# SCENARIO 2: (ACCOUNT) Normal flow calls - -# Test 1: - Send an ACCOUNT call -# - Hangup -# test_account_send_hangup - -# Test 2: - Send an ACCOUNT call -# - Peer Hangup -# test_account_send_peer_hungup - -# Test 3: - Receive an ACCOUNT call -# - Hangup -# test_account_recv_hangup - -# Test 4: - Receive an ACCOUNT call -# - Peer Hangup -# test_account_recv_peer_hungup - - - -# SCENARIO 3: Hold/offHold calls (Account) - -# Test 1: - Send an IP2IP call -# - Put this call on HOLD -# - Off HOLD this call -# - Hangup -# test_ip2ip_send_hold_offhold - - - -# SCENARIO 4: Transfer calls (Account) - -# Test 1: - Send an IP2IP call -# - Transfer this call to another sipp instance -# - Hangup -# test_account_send_transfer - - -#SCENARIO 5: Refuse call (IP2IP) - -# Test 1: - Receive a call -# - Refuse (hangup without answer) -# test_ip2ip_send_refused - - -#SCENARIO 6: Multiple simultaneous Call - -# Test 1: - -# test_mult_ip2ip_send_hangup - -# Test 2: - -# test_mult_ip2ip_recv_peer_hangup \ No newline at end of file diff --git a/tools/sippxml/uac_register_diff_contact.xml b/tools/sippxml/uac_register_diff_contact.xml deleted file mode 100644 index c07d8a05f8..0000000000 --- a/tools/sippxml/uac_register_diff_contact.xml +++ /dev/null @@ -1,55 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-2" ?> - -<!-- Use with CSV file struct like: 3000;192.168.1.106;[authentication username=3000 password=3000]; - (user part of uri, server address, auth tag in each line) ---> - -<scenario name="register_client"> - <send retrans="500"> - <![CDATA[ - - REGISTER sip:127.0.0.1 SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] - From: <sip:[field0]@[field1]>;tag=[call_number] - To: <sip:[field0]@[field1]> - Call-ID: [call_id] - CSeq: [cseq] REGISTER - Contact: sip:[field0]@[local_ip]:[local_port] - Max-Forwards: 10 - Expires: 120 - User-Agent: SIPp/Win32 - Content-Length: 0 - - ]]> - </send> - - <!-- asterisk --> - <recv response="200"> - <action> - <ereg regexp=".*" search_in="hdr" header="Contact:" check_it="true" assign_to="1" /> - </action> - </recv> - - <send retrans="500"> - <![CDATA[ - - REGISTER sip:127.0.0.1 SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] - From: <sip:[field0]@[field1]>;tag=[call_number] - To: <sip:[field0]@[field1]> - Call-ID: [call_id] - CSeq: [cseq] REGISTER - Contact: [$1] - Max-Forwards: 10 - Expires: 120 - User-Agent: SIPp/Win32 - Content-Length: 0 - - ]]> - </send> - - <recv response="200"> - </recv> - - -</scenario> diff --git a/tools/sippxml/uac_register_no_cvs_300.xml b/tools/sippxml/uac_register_no_cvs_300.xml deleted file mode 100644 index f22ae377a8..0000000000 --- a/tools/sippxml/uac_register_no_cvs_300.xml +++ /dev/null @@ -1,110 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-2" ?> - -<!-- Use with CSV file struct like: 3000;192.168.1.106;[authentication username=3000 password=3000]; - (user part of uri, server address, auth tag in each line) ---> - -<scenario name="register_client"> - <send retrans="500"> - <![CDATA[ - - REGISTER sip:127.0.0.1 SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] - From: <sip:300@127.0.0.1>;tag=[call_number] - To: <sip:300@127.0.0.1> - Call-ID: [call_id] - CSeq: [cseq] REGISTER - Contact: sip:300@[local_ip]:[local_port] - Max-Forwards: 10 - Expires: 120 - User-Agent: SIPp/Win32 - Content-Length: 0 - - ]]> - </send> - - <!-- asterisk --> - <recv response="200"> - <!-- - <action> - <ereg regexp=".*" search_in="hdr" header="Contact:" check_it="true" assign_to="1" /> - </action> - --> - </recv> - - <!-- - <recv request="INVITE" crlf="true"> - </recv> - - <send> - <![CDATA[ - - SIP/2.0 180 Ringing - [last_Via:] - [last_From:] - [last_To:];tag=[pid]SIPpTag01[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <send retrans="500"> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[pid]SIPpTag01[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv request="ACK" - optional="true" - rtd="true" - crlf="true"> - </recv> - - <recv request="BYE"> - </recv> - - <send> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <timewait milliseconds="4000"/> - - - <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/> - - <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/> - --> - -</scenario> diff --git a/tools/sippxml/uac_register_no_cvs_400.xml b/tools/sippxml/uac_register_no_cvs_400.xml deleted file mode 100644 index ccceacdf77..0000000000 --- a/tools/sippxml/uac_register_no_cvs_400.xml +++ /dev/null @@ -1,110 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-2" ?> - -<!-- Use with CSV file struct like: 3000;192.168.1.106;[authentication username=3000 password=3000]; - (user part of uri, server address, auth tag in each line) ---> - -<scenario name="register_client"> - <send retrans="500"> - <![CDATA[ - - REGISTER sip:127.0.0.1 SIP/2.0 - Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] - From: <sip:300@127.0.0.1>;tag=[call_number] - To: <sip:400@127.0.0.1> - Call-ID: [call_id] - CSeq: [cseq] REGISTER - Contact: sip:300@[local_ip]:[local_port] - Max-Forwards: 10 - Expires: 120 - User-Agent: SIPp/Win32 - Content-Length: 0 - - ]]> - </send> - - <!-- asterisk --> - <recv response="200"> - <!-- - <action> - <ereg regexp=".*" search_in="hdr" header="Contact:" check_it="true" assign_to="1" /> - </action> - --> - </recv> - - <!-- - <recv request="INVITE" crlf="true"> - </recv> - - <send> - <![CDATA[ - - SIP/2.0 180 Ringing - [last_Via:] - [last_From:] - [last_To:];tag=[pid]SIPpTag01[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <send retrans="500"> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[pid]SIPpTag01[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 - a=rtpmap:0 PCMU/8000 - - ]]> - </send> - - <recv request="ACK" - optional="true" - rtd="true" - crlf="true"> - </recv> - - <recv request="BYE"> - </recv> - - <send> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:[local_ip]:[local_port];transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <timewait milliseconds="4000"/> - - - <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/> - - <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/> - --> - -</scenario> diff --git a/tools/sippxml/uas_register_diff_contact.xml b/tools/sippxml/uas_register_diff_contact.xml deleted file mode 100644 index 3e74a7ba4c..0000000000 --- a/tools/sippxml/uas_register_diff_contact.xml +++ /dev/null @@ -1,55 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-2" ?> -<!DOCTYPE scenario SYSTEM "sipp.dtd"> - -<scenario name="UAS REGISTER + SUBSCRIBE/noresource"> - <!-- By adding rrs="true" (Record Route Sets), the route sets --> - <!-- are saved and used for following messages sent. Useful to test --> - <!-- against stateful SIP proxies/B2BUAs. --> - <recv request="REGISTER" crlf="true"> - </recv> - - <!-- The '[last_*]' keyword is replaced automatically by the --> - <!-- specified header if it was present in the last message received --> - <!-- (except if it was a retransmission). If the header was not --> - <!-- present or if no message has been received, the '[last_*]' --> - <!-- keyword is discarded, and all bytes until the end of the line --> - <!-- are also discarded. --> - <!-- --> - <!-- If the specified header was present several times in the --> - <!-- message, all occurences are concatenated (CRLF seperated) --> - <!-- to be used in place of the '[last_*]' keyword. --> - - <send> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:127.0.0.50:5060;transport=[transport]> - Content-Length: 0 - - ]]> - </send> - - <recv request="REGISTER" crl="true"> - </recv> - - <send> - <![CDATA[ - - SIP/2.0 200 OK - [last_Via:] - [last_From:] - [last_To:];tag=[call_number] - [last_Call-ID:] - [last_CSeq:] - Contact: <sip:sip:127.0.0.50:5060;transport=[transport]> - Content-Length: 0 - ]]> - </send> - -</scenario> - diff --git a/tools/sippxml/voice b/tools/sippxml/voice deleted file mode 100644 index c881cf2d1b97c326d0f5d78ad4beebde51bd4b15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 252 zcmca|c+)~A1{MYwxWmf8z{tSBu=mF!?{oH?3|AN!z?gwW+4blJiIuF12W&YQTp1XS zF)%nVI0*h(&ebW9!qq9kb?K329K$9%=LQA^2bbET4YjQQCVY8R_TXvkquejAK33kn zT=?jB&Yk}+Ui?1){_@SMrT4NDvLC*>Q(Kgp9u*Xtlb-nWb<*7@QSW}ddwJ*S?R$5g zzbbn9@aoOVA9Xiw-gtlSPFmj2wD%7#yuN$!$E*7f?_RzC_vz(l*Dt^R@-?eGH~Gh{ z{M>@Niu%|0s;*x+f9cizcQ>A0zkcre)w55o-hBVPIw>!{A~XBrqq@7#&KEws`Ytas F7yv}Kj_v>e -- GitLab