aboutsummaryrefslogtreecommitdiffstats
path: root/testcases/VIM/OpenStack/CI
# Copyright 2016-2017 Spirent Communications.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# pylint: disable=invalid-name
'''
@author Spirent Communications

This test automates the RFC2889 tests using the Spirent
TestCenter REST APIs. This test supports Python 3.4

'''
import argparse
import logging
import os

# Logger Configuration
logger = logging.getLogger(__name__)


def create_dir(path):
    """Create the directory as specified in path """
    if not os.path.exists(path):
        try:
            os.makedirs(path)
        except OSError as e:
            logger.error("Failed to create directory %s: %s", path, str(e))
            raise


def write_query_results_to_csv(results_path, csv_results_file_prefix,
                               query_results):
    """ Write the results of the query to the CSV """
    create_dir(results_path)
    filec = os.path.join(results_path, csv_results_file_prefix + ".csv")
    with open(filec, "wb") as f:
        f.write(query_results["Columns"].replace(" ", ",") + "\n")
        for row in (query_results["Output"].replace("} {", ",").
                    replace("{", "").replace("}", "").split(",")):
            f.write(row.replace(" ", ",") + "\n")


def positive_int(value):
    """ Positive Integer type for Arguments """
    ivalue = int(value)
    if ivalue <= 0:
        raise argparse.ArgumentTypeError(
            "%s is an invalid positive int value" % value)
    return ivalue


def percent_float(value):
    """ Floating type for Arguments """
    pvalue = float(value)
    if pvalue < 0.0 or pvalue > 100.0:
        raise argparse.ArgumentTypeError(
            "%s not in range [0.0, 100.0]" % pvalue)
    return pvalue

# pylint: disable=too-many-statements
def main():
    """ Read the arguments, Invoke Test and Return the results"""
    parser = argparse.ArgumentParser()
    # Required parameters
    required_named = parser.add_argument_group("required named arguments")
    required_named.add_argument("--lab_server_addr",
                                required=True,
                                help=("The IP address of the "
                                      "Spirent Lab Server"),
                                dest="lab_server_addr")
    required_named.add_argument("--license_server_addr",
                                required=True,
                                help=("The IP address of the Spirent "
                                      "License Server"),
                                dest="license_server_addr")
    required_named.add_argument("--location_list",
                                required=True,
                                help=("A comma-delimited list of test port "
                                      "locations"),
                                dest="location_list")
    # Optional parameters
    optional_named = parser.add_argument_group("optional named arguments")
    optional_named.add_argument("--metric",
                                required=False,
                                help=("One among - Forwarding,\
                                      Address Caching and Learning"),
                                choices=["forwarding", "caching",
                                         "learning"],
                                default="forwarding",
                                dest="metric")
    optional_named.add_argument("--test_session_name",
                                required=False,
                                default="Rfc2889Ses",
                                help=("The friendly name to identify "
                                      "the Spirent Lab Server test session"),
                                dest="test_session_name")
    optional_named.add_argument("--test_user_name",
                                required=False,
                                default="Rfc2889Usr",
                                help=("The friendly name to identify the "
                                      "Spirent Lab Server test user"),
                                dest="test_user_name")
    optional_named.add_argument("--results_dir",
                                required=False,
                                default="./Results",
                                help="The directory to copy results to",
                                dest="results_dir")
    optional_named.add_argument("--csv_results_file_prefix",
                                required=False,
                                default="Rfc2889MaxFor",
                                help="The prefix for the CSV results files",
                                dest="csv_results_file_prefix")
    optional_named.add_argument("--num_trials",
                                type=positive_int,
                                required=False,
                                default=1,
                                help=("The number of trials to execute during "
                                      "the test"),
                                dest="num_trials")
    optional_named.add_argument("--trial_duration_sec",
                                type=positive_int,
                                required=False,
                                default=60,
                                help=("The duration of each trial executed "
                                      "during the test"),
                                dest="trial_duration_sec")
    optional_named.add_argument("--traffic_pattern",
                                required=False,
                                choices=["BACKBONE", "MESH", "PAIR"],
                                default="MESH",
                                help="The traffic pattern between endpoints",
                                dest="traffic_pattern")
    optional_named.add_argument("--frame_size_list",
                                type=lambda s: [int(item)
                                                for item in s.split(',')],
                                required=False,
                                default=[256],
                                help="A comma-delimited list of frame sizes",
                                dest="frame_size_list")
    optional_named.add_argument("--min_learning_rate",
                                type=positive_int,
                                required=False,
                                default=1488,
                                help="Lowest learning rate for test",
                                dest="min_learning_rate")
    optional_named.add_argument("--max_learning_rate",
                                type=positive_int,
                                required=False,
                                default=14880,
                                help="Highest learning rate for test",
                                dest="max_learning_rate")
    optional_named.add_argument("--min_num_addrs",
                                type=positive_int,
                                required=False,
                                default=1,
                                help="lowest number of addrs sent to DUT",
                                dest="min_num_addrs")
    optional_named.add_argument("--max_num_addrs",
                                type=positive_int,
                                required=False,
                                default=1000,
                                help="Highest number of addrs sent to DUT",
                                dest="max_num_addrs")
    optional_named.add_argument("--ac_learning_rate",
                                type=positive_int,
                                required=False,
                                default=1000,
                                help="Number of learning frames per sec",
                                dest="ac_learning_rate")
    optional_named.add_argument("--frame_size",
                                type=positive_int,
                                required=False,
                                default=64,
                                help="Frame size for address test",
                                dest="frame_size")
    parser.add_argument("-v",
                        "--verbose",
                        required=False,
                        default=True,
                        help="More output during operation when present",
                        action="store_true",
                        dest="verbose")
    args = parser.parse_args()

    if args.verbose:
        logger.debug("Creating results directory")
    create_dir(args.results_dir)
    locationList = [str(item) for item in args.location_list.split(',')]

    session_name = args.test_session_name
    user_name = args.test_user_name

    # pylint: disable=import-error
    try:
        # Load Spirent REST Library
        from stcrestclient import stchttp

        stc = stchttp.StcHttp(args.lab_server_addr)
        session_id = stc.new_session(user_name, session_name)
        stc.join_session(session_id)
    except RuntimeError as e:
        logger.error(e)
        raise

    # Retrieve and display the server information
    if args.verbose:
        logger.debug("SpirentTestCenter system version: %s",
                     stc.get("system1", "version"))

    try:
        if args.verbose:
            logger.debug("Bring up license server")
        license_mgr = stc.get("system1", "children-licenseservermanager")
        if args.verbose:
            logger.debug("license_mgr = %s", license_mgr)
        stc.create("LicenseServer", under=license_mgr, attributes={
            "server": args.license_server_addr})

        # Create the root project object
        if args.verbose:
            logger.debug("Creating project ...")
        project = stc.get("System1", "children-Project")

        # Create ports
        if args.verbose:
            logger.debug("Creating ports ...")

        for location in locationList:
            stc.perform("CreateAndReservePorts", params={"locationList":
                                                         location,
                                                         "RevokeOwner":
                                                         "FALSE"})

        port_list_get = stc.get("System1.project", "children-port")

        if args.verbose:
            logger.debug("Adding Host Gen PArams")
        gen_params = stc.create("EmulatedDeviceGenParams",
                                under=project,
                                attributes={"Port": port_list_get})

        # Create the DeviceGenEthIIIfParams object
        stc.create("DeviceGenEthIIIfParams",
                   under=gen_params)
        # Configuring Ipv4 interfaces
        stc.create("DeviceGenIpv4IfParams",
                   under=gen_params)

        stc.perform("DeviceGenConfigExpand",
                    params={"DeleteExisting": "No",
                            "GenParams": gen_params})

        if args.verbose:
            logger.debug("Set up the RFC2889 test...")

        if args.metric == "learning":
            stc.perform("Rfc2889SetupAddressLearningRateTestCommand",
                        params={"FrameSize": args.frame_size,
                                "MinLearningRate": args.min_learning_rate,
                                "MaxLearningRate": args.max_learning_rate,
                                "NumOfTrials": args.num_trials})
        elif args.metric == "caching":
            stc.perform("Rfc2889SetupAddressCachingCapacityTestCommand",
                        params={"FrameSize": args.frame_size,
                                "MinNumAddrs": args.min_num_addrs,
                                "MaxNumAddrs": args.max_num_addrs,
                                "LearningRate": args.ac_learning_rate,
                                "NumOfTrials": args.num_trials})
        else:
            stc.perform("Rfc2889SetupMaxForwardingRateTestCommand",
                        params={"Duration": args.trial_duration_sec,
                                "FrameSizeList": args.frame_size_list,
                                "NumOfTrials": args.num_trials,
                                "TrafficPattern": args.traffic_pattern})

        # Save the configuration
        stc.perform("SaveToTcc", params={"Filename": "2889.tcc"})
        # Connect to the hardware...
        stc.perform("AttachPorts", params={"portList": stc.get(
            "system1.project", "children-port"), "autoConnect": "TRUE"})
        # Apply configuration.
        if args.verbose:
            logger.debug("Apply configuration...")
        stc.apply()

        if args.verbose:
            logger.debug("Starting the sequencer...")
        stc.perform("SequencerStart")

        # Wait for sequencer to finish
        logger.info(
            "Starting test... Please wait for the test to complete...")
        stc.wait_until_complete()
        logger.info("The test has completed... Saving results...")

        # Determine what the results database filename is...
        lab_server_resultsdb = stc.get(
            "system1.project.TestResultSetting", "CurrentResultFileName")

        if args.verbose:
            logger.debug("The lab server results database is %s",
                         lab_server_resultsdb)

        if args.metric == "learning":
            resultsdict = (
                stc.perform("QueryResult",
                            params={
                                "DatabaseConnectionString":
                                lab_server_resultsdb,
                                "ResultPath":
                                ("RFC2889AddressLearningRateTestResultDetailed"
                                 "SummaryView")}))
        elif args.metric == "caching":
            resultsdict = (
                stc.perform("QueryResult",
                            params={
                                "DatabaseConnectionString":
                                lab_server_resultsdb,
                                "ResultPath":
                                ("RFC2889AddressCachingCapacityTestResult"
                                 "DetailedSummaryView")}))
        else:
            resultsdict = (
                stc.perform("QueryResult",
                            params={
                                "DatabaseConnectionString":
                                lab_server_resultsdb,
                                "ResultPath":
                                ("RFC2889MaxForwardingRateTestResultDetailed"
                                 "SummaryView")}))

        if args.verbose:
            logger.debug("resultsdict[\"Columns\"]: %s",
                         resultsdict["Columns"])
            logger.debug("resultsdict[\"Output\"]: %s", resultsdict["Output"])
            logger.debug("Result paths: %s",
                         stc.perform("GetTestResultSettingPaths"))

        # Write results to csv
        if args.verbose:
            logger.debug("Writing CSV file to results directory %s",
                         args.results_dir)
        write_query_results_to_csv(
            args.results_dir, args.csv_results_file_prefix, resultsdict)

    except RuntimeError as err:
        logger.error(err)

    if args.verbose:
        logger.debug("Destroy session on lab server")

    stc.end_session()

    logger.info("Test complete!")

if __name__ == "__main__":
    main()
AgeCommit message (Collapse)AuthorFilesLines
2016-03-18Add criteria and version when pushing the results into test DBMorgan Richomme1-12/+25
JIRA: FUNCTEST-151 Change-Id: Iac36f28db5f2203d7b2977a2bb973534fe167bac Signed-off-by: Morgan Richomme <morgan.richomme@orange.com>
2016-03-15Add exception handling for output processingJuha Kosonen1-2/+9
Handle the exception if parsed result in report cannot be converted to a numeric value. JIRA: FUNCTEST-149 Change-Id: Ibb259abdaa800761ee8dd2270c6bc2529081242d Signed-off-by: Juha Kosonen <juha.kosonen@nokia.com>
2016-03-04Rally and Tempest pre-installed in the Docker image.jose.lausuch1-1/+1
Also, upgrade Rally to version 0.3.1 JIRA: FUNCTEST-147 Change-Id: I6aa15a7c282462058b7786c7dc7174d48c905d3a Signed-off-by: jose.lausuch <jose.lausuch@ericsson.com>
2016-02-24Add jenkins build tag for result apiboucherv1-1/+3
Ex: jenkins-functest-compass-intel-pod8-daily-master-19 this will bring together all tests passed on the same functest run JIRA: FUNCTEST-140 Change-Id: I3c1cd8137184509ee5fdeeb2df5399d4c71e3f67 Signed-off-by: boucherv <valentin.boucher@orange.com>
2016-02-23remove "print" in tempest to avoid having a message "None" in the outputjose.lausuch1-1/+1
Change-Id: If2008fa7ed1bce1b5acc40cad82c21afa55ec4e5 Signed-off-by: jose.lausuch <jose.lausuch@ericsson.com>
2016-02-12Rally live migration case selectionJuha Kosonen3-44/+61
Execute live migration cases only if the feature is enabled in Tempest configuration file. Change-Id: Ie88da2a8f6a4e22cbc96d6aa1f749d555ac58d84 Signed-off-by: Juha Kosonen <juha.kosonen@nokia.com>
2016-02-11Merge "Push results without extra formating"Morgan Richomme1-5/+7
2016-02-11Push results without extra formatingMorgan Richomme1-5/+7
Change-Id: I70713a30cec556ca7cd32122b9c10cf4c1732c3f Signed-off-by: Morgan Richomme <morgan.richomme@orange.com>
2016-02-11Enadled --serial option for run_tests.shViktor Tikkanen1-2/+11
It could be useful to execute e.g. Tempest test cases in a single thread in order to troubleshoot possible concurrency problems. Change-Id: I5e5fc190fb4483ff075a8f837a8d4116ece90c80 Signed-off-by: Viktor Tikkanen <viktor.tikkanen@nokia.com>
2016-02-10Add -n|--no-clean flag to vPing,Tempest,Rally,vIMS scriptsjose.lausuch3-0/+19
Use --no-clean flag in run_tests.sh to tell the test scripts to cleanup or not the resources Change-Id: I597eca5199e1eaf16b1f03a223222d33e4adf170 Signed-off-by: jose.lausuch <jose.lausuch@ericsson.com>
2016-02-10Create Rally summary report also for verbose modejose.lausuch1-24/+36
Also: - Fix percentage format of summary - Get the percentage from the row 'total' JIRA: FUNCTEST-134 Change-Id: Ifb45523921b4096c3242578cf4ddc6b084e8bbb2 Signed-off-by: jose.lausuch <jose.lausuch@ericsson.com>
2016-02-10Push rally summary results into DBMorgan Richomme2-49/+53
json produced by Rally are pushed to rally_details Change-Id: I2f057093307cb395f5c5ffd42c3d228b05133a09 Signed-off-by: Morgan Richomme <morgan.richomme@orange.com>
2016-02-09Merge "Remove obsolete public network definitions"Morgan Richomme1-5/+10
2016-02-09Create Rally output summary at the end of the testsjose.lausuch1-8/+85
Added template to start pushing results to DB JIRA: FUNCTEST-134 Change-Id: Ibc04eae8478827146947df2bcf3460b8c7ef0bc7 Signed-off-by: jose.lausuch <jose.lausuch@ericsson.com>
2016-02-09Remove obsolete public network definitionsJuha Kosonen1-5/+10
Use functest_utils.py routines in run_rally-cert.py to retrive external network name instead of static definition in config_functest.yaml. Also change the network name and id setting in task arguments. Change-Id: Iced9e9a28e79d6ac6ddd2f9f593481949f5fc8a0 Signed-off-by: Juha Kosonen <juha.kosonen@nokia.com>
2016-02-08Used sed instead of crudini for updating regexViktor Tikkanen1-2/+1
It seems that crudini has limitations regarding quotation marks so sed tool is used instead in order to replace ssh_user_regex parameter into tempest.conf file. Change-Id: I8587b3e6b0c15930407ab90bf05f00086348edf6 Signed-off-by: Viktor Tikkanen <viktor.tikkanen@nokia.com>
2016-02-08Merge "Added configuration of ssh_user_regex parameter"Morgan Richomme1-0/+5
2016-02-08Added configuration of ssh_user_regex parameterViktor Tikkanen1-0/+5
Some Rally versions don't set correctly SSH user name into tempest.conf file so that e.g. test_server_basicops test case of Tempest suite fails with "Please login as 'cirros' user, not as root" error. This change ensures that correct SSH user info will be used for Cirros images created by Rally. Change-Id: I90dcad0024f2034ef3ed20d2c6981e675213558d Signed-off-by: Viktor Tikkanen <viktor.tikkanen@nokia.com>
2016-02-05Reduce the number of iterations to ten in rally scenariosJuha Kosonen11-95/+98
Change-Id: Ibefc3f5eeb57ff6a1daa0be26f482ed0376a0d40 Signed-off-by: Juha Kosonen <juha.kosonen@nokia.com>
2016-02-04Merge "Fix success status parsing of rally results"Morgan Richomme1-8/+6
2016-02-04Fix success status parsing of rally resultsJuha Kosonen1-8/+6
Change-Id: I6053bce6cc919af7ac34a16843b2583e45f01ac2 Signed-off-by: Juha Kosonen <juha.kosonen@nokia.com>
2016-02-02Consider volumes and floatingips as defaults in clean_openstackjose.lausuch2-18/+56
Change-Id: I3ffc864768a7c474ee1063eecee1e2085de807b5 Signed-off-by: jose.lausuch <jose.lausuch@ericsson.com>