{"id":20302576,"url":"https://github.com/asterisk/testsuite","last_synced_at":"2025-04-06T04:10:08.368Z","repository":{"id":29305039,"uuid":"32838214","full_name":"asterisk/testsuite","owner":"asterisk","description":"The official Asterisk Test Suite repository.","archived":false,"fork":false,"pushed_at":"2025-03-28T14:49:00.000Z","size":11222,"stargazers_count":35,"open_issues_count":7,"forks_count":47,"subscribers_count":14,"default_branch":"master","last_synced_at":"2025-03-30T03:04:29.179Z","etag":null,"topics":["testing"],"latest_commit_sha":null,"homepage":"https://www.asterisk.org","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/asterisk.png","metadata":{"files":{"readme":"README.txt","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-03-25T02:38:11.000Z","updated_at":"2025-03-28T14:49:05.000Z","dependencies_parsed_at":"2023-02-14T23:46:48.578Z","dependency_job_id":"e6263145-c7fb-4273-b635-200c929be5ec","html_url":"https://github.com/asterisk/testsuite","commit_stats":{"total_commits":2604,"total_committers":74,"mean_commits":"35.189189189189186","dds":0.7980030721966206,"last_synced_commit":"4d6b2062ab9eff57bb5b88a62046c0607596e7f1"},"previous_names":[],"tags_count":95,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asterisk%2Ftestsuite","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asterisk%2Ftestsuite/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asterisk%2Ftestsuite/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asterisk%2Ftestsuite/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/asterisk","download_url":"https://codeload.github.com/asterisk/testsuite/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247430868,"owners_count":20937874,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["testing"],"created_at":"2024-11-14T16:32:35.382Z","updated_at":"2025-04-06T04:10:08.349Z","avatar_url":"https://github.com/asterisk.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"================================================================================\n===                                                                          ===\n===                           Asterisk Test Suite                            ===\n===                                                                          ===\n===                         http://www.asterisk.org/                         ===\n===                  Copyright (C) 2010 - 2015, Digium, Inc.                 ===\n===                                                                          ===\n================================================================================\n\n--------------------------------------------------------------------------------\n--- 0) Table of Contents\n--------------------------------------------------------------------------------\n\n    Using the Test Suite:\n        1) Introduction\n        2) Test Suite System Requirements\n        3) Running the Test Suite\n        4) External control of the Test Suite\n\n    Writing Tests:\n        5) Test Anatomy\n        6) Test Configuration\n        7) Tests in Python\n        8) Tests in Lua\n        9) Custom Tests\n\n--------------------------------------------------------------------------------\n--------------------------------------------------------------------------------\n\n--------------------------------------------------------------------------------\n--- 1) Introduction\n--------------------------------------------------------------------------------\n\nOver the years as the Asterisk code base has expanded, the need for more tools\nto control the quality of the code has increased. Luckily some of these tools\nhave been implemented and the return on that investment has paid dividends\nimmediately.\n\nThere are four parts to code testing:\n\n  1) Testing with our eyes\n\n  2) Bottom-Up testing using unit tests within Asterisk\n\n  3) Top-Down testing using an external test suite\n\n  4) Tests running constantly using a continuous integration framework\n\n\nWith the introduction of Gerrit (https://gerrit.asterisk.org) code is\nnow peer reviewed to a greater extent prior to being merged and the number of\npre-commit bugs being found is tremendous. Gerrit satisfies the first\npart: Testing with our eyes.\n\nBut where peer reviewing fails is in the ability to verify that regressions are\nnot being introduced into the code. Whenever you solve a complex issue, the\nchances that a regression is introduced somewhere else is elevated. A way of\nminimizing those regressions is through automated testing.\n\nAutomated testing improves the quality of code at any part of the development\ncycle and reduces the number of regressions being introduced. Whenever a part\nof the system is being worked on and bugs are being resolved, developers are\nencouraged to write tests in order to verify that the same issue does not creep\nback into the code, and that changes in other locations do not disrupt the\nexpected results in that area.\n\nThe next two directions satisfy the bottom-up testing and top-down testing\nmethods:\n\nAutomated testing for Asterisk is approached from two directions.  The first is\nbottom-up unit testing.  Those tests are implemented within Asterisk in the C\nprogramming language, using the Asterisk C APIs.  These tests are enabled by\nturning on the TEST_FRAMEWORK compile time option in menuselect.  The CLI\ncommands related to the test framework all begin with \"test\".\n\nThe second approach is top down using tests developed outside of Asterisk.\nThis test suite is the collection of top-down functionality tests. The test\nsuite is made up as a collection of scripts that test some portion of Asterisk\nfunctionality given a set of preconditions, and then provide a pass/fail result\nvia a predefined method of doing so.\n\nThe fourth part ties parts two and three together by making sure that whenever\nsomething is introduced that breaks one of the tests, that it gets resolved\nimmediately and not at some point in the future through bug reporting. This is\ndone with Bamboo. You can see the history and current status of the tests\nbeing run by visiting http://bamboo.asterisk.org.\n\nThis document will focus on how you can setup the Asterisk Test Suite in order\nto run the same automated external tests on your own development system. You\nare also encouraged to write your own automated tests to verify parts of your\nown system remain in working order, and to contribute those tests back to the\nAsterisk project so they may be run in the automated testing framework.\n\n--------------------------------------------------------------------------------\n--------------------------------------------------------------------------------\n\n--------------------------------------------------------------------------------\n--- 2) Test Suite System Requirements\n--------------------------------------------------------------------------------\n\nRequired:\n        - python \u003e= 2.6.5\n        - python-yaml\n        - git-core\n\nYou can execute the contrib/scripts/install_prereq script to install\nthe needed libraries and python modules for the testsuite.\n\nNote: Many commands below will install files into system directories;\nif you are executing these commands as an unprivileged user, you might\nneed to use 'sudo' or similar.\n\nOptional (needed by specific tests):\n        - bash\n        - SIPp\n            - Download the latest unstable release\n            - http://sipp.sourceforge.net/snapshots/\n            - Compile the version with pcap and OpenSSL support using:\n                  $ make pcapplay_ossl\n            - Install sipp into a directory in the execution path:\n                  $ cp sipp /usr/local/bin\n        - asttest\n            - include with the test suite\n            - Install from the asttest directory\n                  $ cd asttest\n                  $ make\n                  $ make install\n        - Python modules\n            - starpy\n                - Install starpy from the addons directory\n                  $ cd addons\n                  $ make update\n                  $ make install\n            - python-twisted\n            - python-lxml\n        - pjsua\n            - Download and build pjproject 1.x from source\n            - http://www.pjsip.org/download.htm\n            - On an x86-32 machine, run the configure script as follows:\n              $ ./configure\n            - On an x86-64 machine, run the configure script as follows:\n              $ ./configure CFLAGS=-fPIC\n            - There are tests in the testsuite that require IPv6\n\t      support in pjsua, so create a pjlib/include/pj/config_site.h\n              file and add the line\n\n              #define PJ_HAS_IPV6 1\n            - Build\n              $ make dep \u0026\u0026 make\n            - On an x86-32 machine, copy the\n              'pjsua-x86-unknown-linux-gnu' executable found in the\n              pjsip-apps/bin/ directory to a directory located in the\n              execution path, and name it 'pjsua'.\n              $ cp pjsip-apps/bin/pjsua-x86-unknown-linux-gnu /usr/local/bin/pjsua\n            - On an x86-64 machine, copy the\n              'pjsua-x86_64-unknown-linux-gnu' executable found in the\n              pjsip-apps/bin/ directory to a directory located in the\n              execution path, and name it 'pjsua'.\n              $ cp pjsip-apps/bin/pjsua-x86_64-unknown-linux-gnu /usr/local/bin/pjsua\n        - pjsua python bindings\n            - Go to pjsip-apps/src/python directory\n            - Run 'sudo python ./setup.py install' or just 'sudo make install'\n        - libpcap and yappcap\n            - Install the libpcap development library package for your system\n              (libpcap-dev for Debian-based distros, pcap-devel for Red Hat)\n\t    - Install cython\n            - Download yappcap from:\n              https://github.com/otherwiseguy/yappcap/tarball/master\n            - tar -xvzf otherwiseguy-yappcap*.tar.gz\n            - cd otherwiseguy-yappcap*\n            - make \u0026\u0026 sudo make install\n\t    - Note that if you install these packages, you'll need to\n              execute tests in the testsuite using an account with\n              privileges to do raw packet captures ('root', of course,\n              but other accounts may work on your system).\n\n--------------------------------------------------------------------------------\n--------------------------------------------------------------------------------\n\n--------------------------------------------------------------------------------\n--- 3) Running the Test Suite\n--------------------------------------------------------------------------------\n\nGet the Asterisk source tree you want to test:\n    $ git clone https://gerrit.asterisk.org/asterisk\n    $ cd asterisk\n\nBuild and install it.\n    $ ./configure \u0026\u0026 make\n    $ make install\n\nCheck out the test suite:\n    $ git clone http://gerrit.asterisk.org/testsuite\n    $ cd testsuite\n\nList the tests:\n    $ ./runtests.py -l\n\n       ******************************************\n       *** Listing the tests will also tell   ***\n       *** you which dependencies are missing ***\n       ******************************************\n\nRun the tests:\n    $ ./runtests.py\n\nRun multiple iterations:\n    $ ./runtests.py --number 5\n\nRun a specific test:\n    $ ./runtests.py -t tests/pbx/dialplan\n\nFor more syntax information:\n    $ ./runtests.py --help\n\nAs an alternative to the above, you can use run-local:\n\nGet the Asterisk source tree you want to test:\n    $ git clone https://gerrit.asterisk.org/asterisk\n    $ cd asterisk\n\nOptionally configure and make it:\n    $ ./configure \u0026\u0026 make\n\nCheck out the test suite:\n    $ git clone http://gerrit.asterisk.org/testsuite\n    $ cd testsuite\n\nSetup the test environment:\n    $ ./run-local setup\n\nRun tests:\n    $ ./run-local run # Add here any of runtests.py's parameters.\n\n--------------------------------------------------------------------------------\n--------------------------------------------------------------------------------\n\n--------------------------------------------------------------------------------\n--- 4) External control of the Test Suite\n--------------------------------------------------------------------------------\n\nThe Test Suite can be controlled externally using the SIGUSR1 and SIGTERM\nsignals.\n    - SIGUSR1 will instruct the Test Suite to stop running any further tests\n      after the current running test completes. Any tests not executed will be\n      marked as skipped.\n    - SIGTERM will attempt to immediately stop execution of the current test,\n      marking it as failed. The Test Suite will stop running any further tests,\n      marking any test not executed as skipped.\n\n--------------------------------------------------------------------------------\n--------------------------------------------------------------------------------\n\n--------------------------------------------------------------------------------\n--- 5) Test Anatomy\n--------------------------------------------------------------------------------\n\na) File layout\n\n        Adding a test to the test suite is very easy to do.  Every test lives\nwithin its own directory within the tests directory.  Within that directory,\nthere must be an executable called \"run-test\".  The test directory may contain\nanything else that the test needs to do its job.  A test configuration file may\nalso exist that includes parameters that will be read by the top level test\nscript.\n\n        /tests\n          /mynewtest\n             -\u003e run-test\n             -\u003e test-config.yaml\n             ...\n        /configs\n          -\u003e asterisk.options.conf.inc\n          -\u003e logger.conf\n          -\u003e logger.general.conf.inc\n          ...\n\n        To have a test included in the test suite, it must be added to the\n\"tests.yaml\" file that lives in the tests directory.  This configuration file\ndetermines the order that the tests are considered for execution by the top\nlevel test suite application.\n\n        The purpose of the 'configs' directory is to define global settings for\nAsterisk.  Tests will inherit these settings every time the testsuite creates\nsandbox instances of Asterisk.  Additionally, tests have the ability to override\nthese setting, however it is NOT recommended they do so.  If you wanted to add a\nsetting to logger.conf [logfiles], you could create a 'logger.logfiles.conf.inc'\nfile for your test and the global Asterisk logger.conf will automatically\ninclude it. The filename convention is \u003casterisk module\u003e.\u003ccategory\u003e.conf.inc.\nAgain, settings in 'asterisk.options.conf.inc' would be included in\nasterisk.conf [options] category.  Config files may contain replaceable\nparameters that map to the entries in the [directories] section of the\nasterisk.conf file.  Use the \"\u003c\u003cdirectory\u003e\u003e\" syntax to have the token\nreplaced with the actual value of that entry.  For instance:\n\npriv_key_file = \u003c\u003castetcdir\u003e\u003e/privkey1.pem\nmight become\npriv_key_file = /tmp/asterisk-testsuite/ad41368488ddbac785d54e5689db3b8e/run_5/ast1/etc/asterisk/privkey1.pem\n\n\nb) Preconditions\n\n        When the \"run-test\" application is executed, it can assume that the\nsystem has a fresh install of Asterisk with files installed into their default\nlocations.  This includes a fresh set of sample configuration files in the\n/etc/asterisk directory.\n\n        For increased portability the shebang (#!) for \"run-test\" MUST begin\nwith \"#!/usr/bin/env\".  For exmaple: a test written in Python would have\n\"#!/usr/bin/env python\" for the shebang.\n\nc) Test configuration files\n\n        All configuration files will now be stored in the 'configs/ast%d'\ndirectory, depending on how many Asterisk instances your test uses, you create\nadditional 'ast%d' sub folders.  If you only use 1 Asterisk instance, all files\nwill be copied to 'configs/ast1'.\n\nFor example, we can see the 'basic-call' test below will use 2 Asterisk\ninstances.  However, assume both instances have the same extensions.conf file,\ninstead duplicating data by copying it into 'ast1' and 'ast2', shared\nconfiguration files SHOULD be copied into the root 'configs' directory.\n\n    basic-call/\n        configs/\n            ast1/\n                sip.conf\n                ...\n            ast2/\n                sip.conf\n                ...\n            extensions.conf\n        run-test\n\nSince each Asterisk instance required difference SIP settings, each 'ast%d'\nfolder will have a different sip.conf file.\n\nYou can also copy arbitrary files like sound, key and certificate files into\nany of the entries in the asterisk.conf \"directories\" category using its\nentry name name.  All intermediate directories will be created if they\ndon't already exist.\n\nFor example, to have a certificate and keys copied to an Asterisk instance's\n'/var/lib/asterisk/keys' directory, you'd place it in...\n\n    basic-call/\n        files/\n            common/\n                astvarlibdir/\n                    keys/\n                        ca.crt\n            ast1/\n                astvarlibdir/\n                    keys/\n                        instance1-key.pem\n                ...\n            ast2/\n                astvarlibdir/\n                    keys/\n                        instance2-key.pem\n\nSince 'astvarlibdir' is defined in asterisk.conf as '/var/lib/asterisk',\nthis would copy 'ca.crt' to both instance's '/var/lib/asterisk/keys/' directory,\n'instance1-key.pem' to instance 1's '/var/lib/asterisk/keys/' directory and\n'instance2-key.pem' to instance 2's '/var/lib/asterisk/keys/' directory.\n\nIf you have files that can be shared among multiple tests, you can create a\ndirectory following the same structure as above in some parent directory and\ndirect each test to include it with the 'base-files-path' parameter in\nits test-config.yaml file.  See sample-yaml/test-config.yaml.sample for\nmore info.\n\nd) Test Execution\n\n        The \"run-test\" executable will be run by a top level application in the\ntest suite called \"runtests.py\".  When \"run-test\" is executed, it will be\nprovided a standard set of arguments which are defined here:\n\n        -v \u003cAsterisk version\u003e       # Will always be provided\n\ne) Logging, Pass/Fail Reporting\n\n        All test output, including failure details, should be send to STDOUT.\nIf the test has failed, the \"run-test\" executable should exit with a non-zero\nreturn code.  A return code of zero is considered a success.\n\n--------------------------------------------------------------------------------\n--------------------------------------------------------------------------------\n\n--------------------------------------------------------------------------------\n--- 6) Test Configuration\n--------------------------------------------------------------------------------\n\n        Test configuration lives in a file called \"test-config.yaml\".  The\nformat for the configuration file is YAML.  More information on YAML can be\nfound at http://www.yaml.org/.\n\n\n\n#\n# Example test configuration file - test-config.yaml\n#\n# All elements are required unless explicitly noted as OPTIONAL.  If marked\n# GLOBAL, those elements are only processed if they exist in the top level\n# test-config.yaml file, which applies global options across the test.\n#\n\n# The global settings section, which defines which test configuration to execute\n# and other non-test specific information\nglobal-settings: # GLOBAL\n    # The active test configuration.  The value must match a subsequent key\n    # in this file, which defines the global settings to apply to the test execution\n    # run.\n    test-configuration: config-pessimistic # GLOBAL\n\n    # The following sequence defines for any test configuration the available pre-\n    # and post-test conditions.  The 'name' field specifies how the test configurations\n    # refer to the pre- and post-test conditions in order to activate them.\n    condition-definitions: # GLOBAL\n            -\n                name: 'threads'\n                # A pre-test condition, which specifies that the object will be evaluated\n                # prior to test execution\n                pre:\n                    # The fully qualified Python typename of the object to create using\n                    # introspection\n                    typename: 'asterisk.ThreadTestCondition.ThreadPreTestCondition'\n                post:\n                    typename: 'asterisk.ThreadTestCondition.ThreadPostTestCondition'\n                    # The fully qualified Python typename of the object to pass to the evaluate\n                    # function of this object\n                    related-type: 'asterisk.ThreadTestCondition.ThreadPreTestCondition'\n            -\n                name: 'sip-dialogs'\n                pre:\n                    typename: 'asterisk.SipDialogTestCondition.SipDialogPreTestCondition'\n                post:\n                    typename: 'asterisk.SipDialogTestCondition.SipDialogPostTestCondition'\n            -\n                name: 'locks'\n                pre:\n                    typename: 'asterisk.LockTestCondition.LockTestCondition'\n                post:\n                    typename: 'asterisk.LockTestCondition.LockTestCondition'\n            -\n                name: 'file-descriptors'\n                pre:\n                    typename: 'asterisk.FdTestCondition.FdPreTestCondition'\n                post:\n                    typename: 'asterisk.FdTestCondition.FdPostTestCondition'\n                    related-type: 'asterisk.FdTestCondition.FdPreTestCondition'\n            -\n                name: 'channels'\n                pre:\n                    typename: 'asterisk.ChannelTestCondition.ChannelTestCondition'\n                post:\n                    typename: 'asterisk.ChannelTestCondition.ChannelTestCondition'\n\n# A global test definition.  This name can be anything, but must be referenced\n# by the global-settings.test-configuration key.\nconfig-pessimistic: # GLOBAL\n    # A list of tests to explicitly exclude from execution.  This overrides the\n    # test listsing in the tests.yaml files.\n    exclude-tests: # GLOBAL\n        # The name of a test to exclude.  Name matching is done using the Python\n        # in operator.\n        - 'authenticate_invalid_password'\n    properties:\n        # The test conditions to apply to all tests.  See specific configuration\n        # information for the test conditions in the individual test configuration\n        # section below.\n        testconditions:\n            - name: 'threads'\n            - name: 'sip-dialogs'\n            - name: 'locks'\n            - name: 'file-descriptors'\n            - name: 'channels'\n\n# The testinfo section contains information that describes the purpose of an\n# individual test\ntestinfo:\n    skip : 'Brief reason for skipping test' # OPTIONAL\n    summary     : 'Put a short one liner summary of the test here'\n    issues      : |\n        # List of issue numbers associated with this test\n        # OPTIONAL\n        - mantis : '12345'\n        - mantis : '10101'\n    description : |\n        'Put a more verbose description of the test here.  This may span\n        multiple lines.'\n\n# The properties section contains information about requirements and\n# dependencies for this test.\nproperties:\n    buildoption : 'TEST_FRAMEWORK' # OPTIONAL - Asterisk compilation flag\n    features:\n        # List features the Asterisk version under test must support for this test\n        # to execute.  All features must be satisfied for the test to run.\n        - 'digiumphones'\n        - 'cert'\n    dependencies : |   # OPTIONAL\n        # List dependencies that must be met for this test to run\n        #\n        # Checking for an 'app' dependency behaves like the 'which' command\n        - app : 'bash'\n        - app : 'sipp'\n\n        # A 'python' dependency is a python module.  An attempt will be made to\n        # import a module by this name to determine whether the dependency is\n        # met.\n        - python : 'yaml'\n\n        # A 'module' dependency is an Asterisk module that must be loaded by\n        # Asterisk in order for this test to execute.  If the module is not loaded,\n        # the test will not execute.\n        - module : 'app_dial'\n\n        # 'custom' dependency can be anything.  Checking for this dependency is\n        # done by calling a corresponding method in the Dependency class in\n        # runtests.py.  For example, if the dependency is 'ipv6', then the\n        # depend_ipv6() method is called to determine if the dependency is met.\n        - custom : 'ipv6'\n        - custom : 'fax'\n    testconditions: # OPTIONAL\n        #\n        # List of overrides for pre-test and post-test conditions.  If a condition is\n        # defined for a test, the configuration of that condition in the test overrides\n        # the setting defined in the global test configuration file.\n        #\n        -   # Check for thread usage in Asterisk.  Any threads present in Asterisk after test\n            # execution - and any threads that were detected prior to test execution\n            # that are no longer present - will be flagged as a test error.\n            name: 'threads'\n            #\n            # Disable execution of this condition.  This setting applies to any defined condition.\n            # Any other value but 'False' will result in the condition being executed.\n            enabled: 'False'\n            #\n            # Execute the condition, but expect the condition to fail\n            expectedResult: 'Fail'\n            #\n            # The thread test condition allows for certain detected threads to be\n            # ignored.  This is a list of the thread names, as reported by the CLI\n            # command 'core show threads'\n            ignoredThreads:\n                - 'netconsole'\n                - 'pbx_thread'\n        #\n        -   # Check for SIP dialog usage.  This looks for any SIP dialogs present\n            # in the system before and after a run; if any are present and are not\n            # scheduled for destruction, an error is raised.\n            name: 'sip-dialogs'\n            #\n            # In addition to checking for scheduled destruction, a test can request that\n            # certain entries should appear in the SIP history.  If the entries do not\n            # appear, an error is raised.\n            sipHistoryRequirements:\n                - 'NewChan'\n                - 'Hangup'\n        #\n        -   # Check for held locks in Asterisk after test execution.  A lock is determined to\n            # be in potential error if threads are detected holding mutexes and waiting on\n            # other threads that are also holding mutexes.\n            name: 'locks'\n        #\n        -   # Check for active channels in Asterisk.  If active channels are detected, flag\n            # an error\n            name: 'channels'\n            #\n            # The number of allowed active channels that can exist when the condition is checked.\n            # If the number of channels detected is greater than this value, an error is raised.\n            # By default, this value is 0.\n            allowedchannels: 1\n        #\n        -   # Check for active file descriptors in Asterisk.  File descriptors detected before\n            # test execution are tracked throughout the test; if any additional file descriptors\n            # after test execution are detected, the test condition fails.\n            name: 'file-descriptors'\n    tags: # OPTIONAL\n        #\n        # List of tags used to select a subset of tests to run.  A test must have all tags to run.\n        #\n        -   core # This test is part of the core support level.\n        -   voicemail # This test involves voicemail functionality.\n\n\n--------------------------------------------------------------------------------\n--------------------------------------------------------------------------------\n\n--------------------------------------------------------------------------------\n--- 7) Tests in Python\n--------------------------------------------------------------------------------\n\n        There are some python modules included in lib/python/ which are intended\nto help with writing tests in python.  Python code in the testsuite should be\nformatted according to PEP8: http://www.python.org/dev/peps/pep-0008/.\n\n--------------------------------------------------------------------------------\n--------------------------------------------------------------------------------\n\n--------------------------------------------------------------------------------\n--- 8) Tests in Lua\n--------------------------------------------------------------------------------\n\n        The asttest framework included in the asttest directory provides a lot\nof functionality to make it easy to write Asterisk tests in Lua.  Take a look at\nthe asttest README as well as some of the existing Lua tests for more\ninformation.\n\n--------------------------------------------------------------------------------\n--------------------------------------------------------------------------------\n\n--------------------------------------------------------------------------------\n--- 9) Custom Tests\n--------------------------------------------------------------------------------\n\n        The testsuite supports automatic use of custom tests.  This feature is\nactivated by creating tests/custom/tests.yaml to list your tests and/or folders\nof tests.  Any files created in tests/custom will be ignored by the Asterisk\ntestsuite repository.  This folder is designed to be used for tests that are\nnot appropriate for inclusion in the common testsuite.  This can include tests\nspecific for your business, clients or Asterisk based product.\n\n--------------------------------------------------------------------------------\n--------------------------------------------------------------------------------\n\n================================================================================\n================================================================================\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasterisk%2Ftestsuite","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fasterisk%2Ftestsuite","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasterisk%2Ftestsuite/lists"}