예제 #1
0
파일: testartifacts.py 프로젝트: duelle/CTT
def createTestartifact(postRequest: POSTTestartifacts):
    """
    Creates Testartifacts for a Project
    """
    r = Response()

    try:
        # --------------------------------------|
        # GET/UPDATE RELATED DATA
        if not isinstance(postRequest.project_id, int):
            r = Response(response=f"Invalid Id: {postRequest.project_id}",
                         status='422',
                         mimetype="text/xml")
            r.headers["Content-Type"] = "text/xml; charset=utf-8"
            return r

        project = getProject(postRequest.project_id)

        if not project:
            r = Response(
                response=f"No project with Id: {postRequest.project_id}",
                status='404',
                mimetype="text/xml")
            r.headers["Content-Type"] = "text/xml; charset=utf-8"
            return r

        project.status = 'TAGENERATED'

        updateProject(project)

        # --------------------------------------|
        # OBJECT CREATION
        testartifact = Testartifact(
            status=project.status,
            project_id=project.id,
        )
        databaseSession.add(testartifact)
        databaseSession.flush()
        # --------------------------------------|
        # GENERATE OPERATION
        generate.run(project, testartifact)
        # --------------------------------------|

        newTestartifact = dbtestartifacts.getTestartifactForProject(
            project, True)

        r = Response(response=json.dumps(newTestartifact.to_dict()),
                     status='201',
                     mimetype="application/json")
        r.headers["Content-Type"] = "application/json; charset=utf-8"

        databaseSession.commit()
    except:
        databaseSession.rollback()
        raise
    finally:
        databaseSession.remove()

    return r
예제 #2
0
def createProject(postRequest: POSTProjects):
    """
    Handler function to create a new Project.

    Creates a new Project and initializes the project directory.
    It does this by cloning the repository specified in the request to the 
    general project directory specified in the radonCTTConfig
    """
    r = Response()

    if not postRequest.repository_url:
        r = Response(response='No repository url specified',
                     status='422',
                     mimetype="text/xml")
        r.headers["Content-Type"] = "text/xml; charset=utf-8"
        return r

    if not postRequest.servicetemplate_location:
        r = Response(response='No servicetemplate location specified',
                     status='422',
                     mimetype='text/xml')
        r.headers['Content-Type'] = 'text/xml; charset=utf-8'
        return r

    try:
        # --------------------------------------|
        # OBJECT CREATION
        newProject = Project(
            status='WAITING',
            repository_url=postRequest.repository_url,
            servicetemplate_location=postRequest.servicetemplate_location,
            project_path='NaN')
        databaseSession.add(newProject)
        databaseSession.flush()

        # --------------------------------------|
        # IMPORT OPERATION
        importation.run(newProject)
        # --------------------------------------|

        r = Response(response=json.dumps(newProject.to_dict()),
                     status='201',
                     mimetype="text/json")
        r.headers["Content-Type"] = "application/json; charset=utf-8"

        databaseSession.commit()
    except:
        databaseSession.rollback()
        raise
    finally:
        databaseSession.remove()

    return r
예제 #3
0
파일: loadTest.py 프로젝트: duelle/CTT
def generatePolicyTest(project, testartifact, policy):
    """
    This is a policy generator function for the loadTest performance policy type.
    It creates a PolicyTest to represent the performance policy and then calls node generator
    functions.

    Args:
        - project (Project): The Project you wish to generate testartifacts for
        - testartifact (Testartifact): The Testartifact object to use for test generation
        - policy (Dict) : This policies representation in the servicetemplate
    """

    # Define the node generator function layer
    functionSwitch = {
        # #################################################################
        # NODE TYPES ARE MAPPED TO NODE GENERATOR FUNCTIONS HERE
        # #################################################################

        # WebApplication
        'radon.nodes.docker.WebApplication': webApplication.generateNodeTest
    }

    #Create the PolicyTest resource representing this performance policy
    policyTest = PolicyTest(status=project.status,
                            project_id=project.id,
                            testartifact_id=testartifact.id,
                            policy=json.dumps(policy))
    databaseSession.add(policyTest)
    databaseSession.flush()

    #Generate a directory for the PolicyTest
    directory = os.path.dirname(
        f"{project.project_path}testartifacts{os.path.sep}{policyTest.id}{os.path.sep}"
    )
    if not os.path.exists(directory):
        os.makedirs(directory)

    #Call a node generator function for every node targeted by this performance policy
    for nodeName in parser.getNodeTemplates():
        node = parser.getNodeTemplates().get(nodeName)
        if (node['type'] in functionSwitch) and (nodeName
                                                 in policy['targets'][0]):
            nodeGeneratorFunc = functionSwitch[node['type']]
            nodeGeneratorFunc(project, testartifact, policyTest, policy, node)
예제 #4
0
def generatePolicyTest(project, testartifact, policy):
    """
    This is a >>>TERMINAL<<< generator function ->
    
    This is a policy generator function for the shellScript custom policy type.
    It creates a PolicyTest to represent the custom policy. It does not go any deeper in 
    the generator function layers.

    Args:
        - project (Project): The Project you wish to generate testartifacts for
        - testartifact (Testartifact): The Testartifact object to use for test generation
        - policy (Dict) : This policies representation in the servicetemplate
    """

    #Create the PolicyTest resource representing this performance policy
    policyTest = PolicyTest(status=project.status,
                            project_id=project.id,
                            testartifact_id=testartifact.id,
                            policy=json.dumps(policy))
    databaseSession.add(policyTest)
    databaseSession.flush()
예제 #5
0
파일: deployments.py 프로젝트: duelle/CTT
def createDeployment(postRequest: POSTDeployments):
    r = Response()

    try:
        # --------------------------------------|
        # GET/UPDATE RELATED DATA
        if not isinstance(postRequest.testartifact_id, int):
            r = Response(response='{}{}'.format('Invalid Id: ',
                                                postRequest.testartifact_id),
                         status='422',
                         mimetype="text/xml")
            r.headers["Content-Type"] = "text/xml; charset=utf-8"
            return r

        testartifact = getTestartifact(postRequest.testartifact_id, True)

        if not testartifact:
            r = Response(response='{}{}'.format('No testartifact with Id: ',
                                                postRequest.testartifact_id),
                         status='404',
                         mimetype="text/xml")
            r.headers["Content-Type"] = "text/xml; charset=utf-8"
            return r

        project = getProject(testartifact.project_id)

        if not project:
            r = Response(response='{}{}'.format('No project with Id: ',
                                                testartifact.project_id),
                         status='404',
                         mimetype="text/xml")
            r.headers["Content-Type"] = "text/xml; charset=utf-8"
            return r

        testartifact.status = 'DEPLOYED'
        project.status = 'DEPLOYED'

        updateTestartifact(testartifact)
        updateProject(project)

        # --------------------------------------|
        # OBJECT CREATION
        deployment = Deployment(
            status='DEPLOYED',
            project_id=project.id,
            testartifact_id=testartifact.id,
        )

        databaseSession.add(deployment)
        databaseSession.flush()
        # --------------------------------------|
        # DEPLOY OPERATION
        deploy.run(project, testartifact)
        # --------------------------------------|

        r = Response(response=json.dumps(deployment.to_dict()),
                     status='201',
                     mimetype="application/json")
        r.headers["Content-Type"] = "application/json; charset=utf-8"

        databaseSession.commit()
    except:
        databaseSession.rollback()
        raise
    finally:
        databaseSession.remove()

    return r
예제 #6
0
파일: executors.py 프로젝트: duelle/CTT
def createExecutor(postRequest: POSTExecutors):
    r = Response()

    try:
        # --------------------------------------|
        # GET/UPDATE RELATED DATA
        if not isinstance(postRequest.deployment_id, int):
            r = Response(response='{}{}'.format('Invalid Id: ',
                                                postRequest.deployment_id),
                         status='422',
                         mimetype="text/xml")
            r.headers["Content-Type"] = "text/xml; charset=utf-8"
            return r

        deployment = getDeployment(postRequest.deployment_id)

        if not deployment:
            r = Response(response='{}{}'.format('No deployment with Id: ',
                                                postRequest.deployment_id),
                         status='404',
                         mimetype="text/xml")
            r.headers["Content-Type"] = "text/xml; charset=utf-8"
            return r

        testartifact = getTestartifact(deployment.testartifact_id, True)

        if not testartifact:
            r = Response(response='{}{}'.format('No testartifact with Id: ',
                                                deployment.testartifact_id),
                         status='404',
                         mimetype="text/xml")
            r.headers["Content-Type"] = "text/xml; charset=utf-8"
            return r

        project = getProject(deployment.project_id)

        if not project:
            r = Response(response='{}{}'.format('No project with Id: ',
                                                deployment.project_id),
                         status='404',
                         mimetype="text/xml")
            r.headers["Content-Type"] = "text/xml; charset=utf-8"
            return r

        project.status = 'EXECUTED'
        testartifact.status = 'EXECUTED'
        deployment.status = 'EXECUTED'

        updateProject(project)
        updateTestartifact(testartifact)
        updateDeployment(deployment)

        # --------------------------------------|
        # OBJECT CREATION
        executor = Executor(
            status='EXECUTED',
            project_id=project.id,
            deployment_id=deployment.id,
        )
        databaseSession.add(executor)
        databaseSession.flush()

        result = Result(
            project_id=project.id,
            testartifact_id=testartifact.id,
            result_path=f"{project.project_path}results{os.path.sep}report.csv",
        )
        databaseSession.add(result)
        databaseSession.flush()
        # --------------------------------------|
        # EXECUTE OPERATION
        execute.run(project, deployment, testartifact)
        # --------------------------------------|
        # EVALUATE OPERATION
        evaluate.run(project, testartifact, result)
        # --------------------------------------|

        r = Response(response=json.dumps(result.to_dict()),
                     status='201',
                     mimetype="application/json")
        r.headers["Content-Type"] = "application/json; charset=utf-8"

        databaseSession.commit()
    except:
        databaseSession.rollback()
        raise
    finally:
        databaseSession.remove()

    return r
예제 #7
0
def generateTestForPolicyAverageResponseTimeRunnerPythonEventObjectCreated(project, testartifact, policyTest, policy, node):
    """
    This is a >>>TERMINAL<<< generator function for the lambdaFunction node type 
    and the averageReponseTime policy and the python runner and the object created event.
    It copies the related template and fills it with parameters from the policy and node.

    Args:
        - project (Project): The Project you wish to generate this NodeTest for
        - testartifact (Testartifact): The Testartifact object to use for test generation
        - policyTest (PolicyTest) : The PolicyTest responsible for this NodeTest
        - policy (Dict) : The policy represantation in the servicetemplate
        - node (Dict) : This nodes represantation in the servicetemplate
    """
    #Create a NodeTest to represent this node
    nodeTest = NodeTest(
        status= project.status,
        project_id= project.id,
        policy_test_id= policyTest.id,
        node = json.dumps(node),
        artifact_path= '',
    )
    databaseSession.add(nodeTest)
    databaseSession.flush()

    #Set the path this NodeTests artifacts will be placed in
    nodeTest.artifact_path = f"{project.project_path}testartifacts{os.path.sep}{policyTest.id}{os.path.sep}{nodeTest.id}{os.path.sep}"
    updateNodeTest(nodeTest)

    # Generate the NodeTests artifact directory
    directory = os.path.dirname(nodeTest.artifact_path)
    if not os.path.exists(directory):
        os.makedirs(directory)


    #Get the template parameters from the policy and node
    # +++TEMPLATE PARAMETERS+++
    # ARG 1 : REPEATS
    # ARG 2 : FUNCTION_NAME
    # ARG 3 : SOURCE_FILE_PREFIX
    # ARG 4 : SOURCE_FILE_POSTFIX
    # ARG 5 : BUCKET_NAME
    # ARG 6 : SOURCE_FILE_PATH
    # ARG 7 : RESULT_PATH
    # ARG 8 : UNIQUE_TEST_ID
    # +++++++++++++++++++++++++

    repeats = f"{policy['properties']['repeats']}"
    function_name = f"{node['properties']['function_name']}"
    source_file_prefix = f"{node['properties']['trigger_file_prefix']}"
    source_file_postfix = f"{node['properties']['trigger_file_postfix']}"
    bucket_name = f"{node['properties']['trigger_bucket_name']}"
    source_file_path = f"{project.project_path}{source_file_prefix}{source_file_postfix}"
    result_path = f"{nodeTest.artifact_path}"
    unique_test_id = f"{nodeTest.id}"

    # We need the absolute path to the template
    templatePath = f"{os.getcwd()}{os.path.sep}radonCTT{os.path.sep}templates{os.path.sep}averageResponseTime{os.path.sep}aws{os.path.sep}lambdaFunction{os.path.sep}python-object-create{os.path.sep}"

    # Copy the template into our NodeTest artifact directory
    distutils.dir_util.copy_tree(templatePath, nodeTest.artifact_path)

    # Fill the absolute path to the python runner into the python playbook and call with our arguments
    playbookPath = f"{nodeTest.artifact_path}artifacts{os.path.sep}create.yml"
    pythonRunnerPath = f"{nodeTest.artifact_path}artifacts{os.path.sep}run.py"
    pythonRunCommand = f"{pythonRunnerPath} {repeats} {function_name} {source_file_prefix} {source_file_postfix} {bucket_name} {source_file_path} {result_path} {unique_test_id}"

    # Read and edit
    with open(playbookPath) as instream:
        try:
            playbook = yaml.safe_load(instream)
            playbook[0]['tasks'][0]['script'] = pythonRunCommand
        except yaml.YAMLError as exc:
            print(exc)
    
    # Push edits
    with open(playbookPath, "w") as outstream:
        try:
            yaml.dump(playbook, outstream)
        except yaml.YAMLError as exc:
            print(exc)
예제 #8
0
def generateTestForPolicyLoadTestRunnerJmeter(project, testartifact,
                                              policyTest, policy, node):
    """
    This is a >>>TERMINAL<<< generator function for the WebApplication node type and the loadTest policy and the jmeter runner.

    Args:
        - project (Project): The Project you wish to generate this NodeTest for
        - testartifact (Testartifact): The Testartifact object to use for test generation
        - policyTest (PolicyTest) : The PolicyTest responsible for this NodeTest
        - policy (Dict) : The policy represantation in the servicetemplate
        - node (Dict) : This nodes represantation in the servicetemplate
    """
    #Create a NodeTest to represent this node
    nodeTest = NodeTest(
        status=project.status,
        project_id=project.id,
        policy_test_id=policyTest.id,
        node=json.dumps(node),
        artifact_path='',
    )
    databaseSession.add(nodeTest)
    databaseSession.flush()

    #Set the path this NodeTests artifacts will be placed in
    nodeTest.artifact_path = f"{project.project_path}testartifacts{os.path.sep}{policyTest.id}{os.path.sep}{nodeTest.id}{os.path.sep}"
    updateNodeTest(nodeTest)

    # Generate the NodeTests artifact directory
    directory = os.path.dirname(nodeTest.artifact_path)
    if not os.path.exists(directory):
        os.makedirs(directory)

    #Get information from the policy and node to create the testplan from a template
    # +++TEMPLATE PARAMETERS+++
    # 1 : THREADS
    # 2 : REPEATS
    # 3 : UPPER_BOUND
    # 4 : HOST
    # 5 : PORTS
    # +++++++++++++++++++++++++

    threads = f"{policy['properties']['threads']}"
    repeats = f"{policy['properties']['repeats']}"
    upper_bound = f"{policy['properties']['upper_bound']}"
    host = f"{node['properties']['host']}"
    ports = node.get('properties').get('ports')

    # We need the absolute path to the testplan template to copy it
    templatePath = f"{os.getcwd()}{os.path.sep}radonCTT{os.path.sep}templates{os.path.sep}loadTest{os.path.sep}webApplication{os.path.sep}jmeter-load-test{os.path.sep}"

    # Copy the testplan template into our NodeTest artifact directory
    distutils.dir_util.copy_tree(templatePath, nodeTest.artifact_path)

    # Fill the absolute path to the testplan into the playbook and call with our arguments
    playbookPath = f"{nodeTest.artifact_path}artifacts{os.path.sep}create.yml"
    testplanPath = f"{nodeTest.artifact_path}artifacts{os.path.sep}testplan.jmx"
    jmeterRunCommand = f"jmeter -n -t {testplanPath} -l {nodeTest.artifact_path}result.csv"

    # <<<<<<<<<<<<<<<<< PLAY BOOK EDITING >>>>>>>>>>>>>>>>>

    # Read and edit
    with open(playbookPath) as instream:
        try:
            playbook = yaml.safe_load(instream)
            playbook[0]['tasks'][0]['shell'] = jmeterRunCommand
        except yaml.YAMLError as exc:
            print(exc)

    # Push edits
    with open(playbookPath, "w") as outstream:
        try:
            yaml.dump(playbook, outstream)
        except yaml.YAMLError as exc:
            print(exc)

    # <<<<<<<<<<<<<<<<< TEST PLAN EDITING >>>>>>>>>>>>>>>>>
    tree = ET.parse(testplanPath)
    root = tree.getroot()

    # Write metadata to the testplan
    threadGroupHashTree = root[0][1]
    threadGroup = threadGroupHashTree[0]
    threadGroupController = threadGroup[1]
    subThreadGroupHashTree = threadGroupHashTree[1]

    durationAssertion = subThreadGroupHashTree[0]
    subThreadGroupHashTreeSeparator = subThreadGroupHashTree[1]
    httpSampler = subThreadGroupHashTree[2]

    # DURATION
    durationAssertionDuration = durationAssertion[0]
    durationAssertionDuration.text = upper_bound

    # LOOPS
    loopController = threadGroupController[1]
    loopController.text = repeats

    # THREADS
    threadGroupNumThreads = threadGroup[2]
    threadGroupNumThreads.text = threads

    # Create Samplers for every pathill NodeTestAverages into the list
    isFirstHttpSampler = True
    for port in ports:
        paths = ports.get(port)
        for path in paths:
            if isFirstHttpSampler:
                newHttpSampler = httpSampler
            else:
                newHttpSampler = copy.deepcopy(httpSampler)

            newSeparator = copy.deepcopy(subThreadGroupHashTreeSeparator)

            #Set the values in the HTTP Sampler
            httpSamplerHost = newHttpSampler[1]
            httpSamplerPort = newHttpSampler[2]
            httpSamplerPath = newHttpSampler[7]

            httpSamplerHost.text = f"{host}"
            httpSamplerPort.text = f"{port}"
            httpSamplerPath.text = f"{path}"

            if isFirstHttpSampler:
                isFirstHttpSampler = False
            else:
                subThreadGroupHashTree.append(newHttpSampler)
                subThreadGroupHashTree.append(newSeparator)

    #Write the changes to the file
    tree.write(testplanPath)