Commit a3f2dd6b authored by Michele Carignani's avatar Michele Carignani
Browse files

support Void clauses, refactoring and comply to linter

parent bc21212a
Loading
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
#!/env/python3
'''
Configurable aspects
'''

VERSION = "0.0.4"

@@ -25,9 +28,9 @@ DRY_RUN = False
# If QUIET is True, output on stdout is minimized
QUIET = False

# Prefix for the commit URL that may be added after each table. If the GIT_COMMIT
# Prefix for the commit URL that may be added after each table. If the GIT_URL_PREFIX
# is the empty string, nothing is added. The prefix is concatenated with the filename of
# the Robot file. NOTE: if the final slash is not present it will not be included.
# Example: 
# GIT_COMMIT = "http://acme.com/my/example/abcde/"
# GIT_URL_PREFIX = "http://acme.com/my/example/abcde/"
GIT_URL_PREFIX = "https://forge.etsi.org/rep/nfv/api-tests/raw/"
+94 −55
Original line number Diff line number Diff line
#!/env/python3
#
#  Usage: python3 create_sols.py ../../api-tests/   <commit-or-tag>
#
'''
Generates attachement for TST 010 based on index files in the api-tests repository

  Usage: python3 create_sols.py <path-to-api-tests>   <commit-or-tag>
'''

import os
import sys
@@ -13,16 +15,6 @@ import testspec
import config
import lib


def is_interface_heading(ref):
    return ref.lvl() == 3


def is_endpoint_heading(ref):
    return ref.lvl() == 4

def create_test_for_sol(solspec, all_tests_root, commit_id, output_dir):

indexes = {
    "SOL002" : 'sol_002_index.csv',
    "SOL003" : 'sol_003_index.csv',
@@ -41,40 +33,86 @@ def create_test_for_sol(solspec, all_tests_root, commit_id, output_dir):
    "SOL005" : 'Tests-SOL005-OsMaNfvo.docx',
}

    if not solspec in indexes:
        print("Error: Wrong SOL Specification: {}".format(solspec))
        return
def is_interface_heading(ref):
    '''Check if a reference has heading level 3'''
    return ref.lvl() == 3

    sol_index = None

    myf = open(indexes[solspec], 'r')
    sol_index = csv.reader(myf)
def is_endpoint_heading(ref):
    '''Predicate to check if a reference has heading level 4'''
    return ref.lvl() == 4

def generate_new_clause(row, ref, spec, all_tests_root, commit_id, solspec, current_folder):
    '''
    Generates a new clause, either Void or for a Test Suite (i.e. a .robot file)
    '''
    if  "Void" in row["fln"]:
        lib.generate_void_clause(ref, row["title"], spec, solspec)
    else:
        path = os.path.join(all_tests_root, solspec, current_folder, row["fln"])
        suite = TestSuiteBuilder().build(path)
        lib.gen_api_suite(ref, suite, spec, current_folder, commit_id, solspec)

def load_spec_index(root_dir, base_spec):
    '''
    Load the index from the file, parses the CSV and applies strip 
    '''

    spec_idx = None

    index_filename = open(os.path.join(root_dir, "indexes", indexes[base_spec]), 'r')
    spec_idx = csv.DictReader(
        index_filename,
        skipinitialspace=True, 
        fieldnames=["ref", "title", "fln"]
    )

    if sol_index is None:
        print("ERROR OPENING INDEX: {}".format(indexes[solspec]))
    if spec_idx is None:
        print("ERROR OPENING INDEX: {}".format(indexes[base_spec]))
        return []

    spec_idx = \
        (dict((k, v.strip()) for k, v in row.items() if v) for row in spec_idx if len(row) >= 3)

    return spec_idx

def create_test_for_sol(basedoc, spec_idx, all_tests_root, commit_id, output_dir):
    '''
    Loads index file for a base specification and iterates to produce 
    all clauses, 
    '''
    if not basedoc in indexes:
        print("Error: Wrong SOL Specification: {}".format(basedoc))
        return

    spec = testspec.TestSpec(templates[solspec])
    spec = testspec.TestSpec(templates[basedoc])
    current_folder = None

    for row in sol_index:
        if len(row) < 3:
            continue

        ref = lib.DocReference.from_str(row[0].strip())
    for item in spec_idx:
        try:
            ref = lib.DocReference.from_str(item["ref"])

            if is_interface_heading(ref):
            spec.add_heading_from_ref(row[1].strip(), ref)
            current_folder = row[2].strip()
                spec.add_heading_from_ref(item["title"], ref)
                if "Void" in item["fln"]:
                    spec.add_void_paragraph()
                else:
                    current_folder = item["fln"]

            elif is_endpoint_heading(ref):
            suite = TestSuiteBuilder().build(
                os.path.join(all_tests_root, solspec, current_folder, row[2].strip())
                if item["fln"] is None or current_folder is None:
                    print(item)
                    raise Exception()
                generate_new_clause(
                    item, ref, spec, all_tests_root, commit_id, basedoc, current_folder
                )
            lib.gen_api_suite(ref, suite, spec, current_folder, commit_id, solspec)

    outfn = os.path.join(output_dir,outnames[solspec])
    print("Writing {} definitions to: {}".format(solspec, outfn))
        except Exception as err:
            print(item, all_tests_root, basedoc, current_folder)
            raise err

    outfn = os.path.join(output_dir,outnames[basedoc])
    print("Writing {} definitions to: {}".format(basedoc, outfn))
    spec.save(outfn)

if __name__ == "__main__":
@@ -90,8 +128,9 @@ if __name__ == "__main__":

    print("Generating entire SOL tests")

    sol_specs = ["SOL002", "SOL003", "SOL005"]
    sol_specs = ["SOL002"] #, "SOL003", "SOL005"]

    for solspec in sol_specs:
        create_test_for_sol(solspec, ROOT, COMMIT_ID, "..")
        spec_index = load_spec_index(ROOT, solspec)
        create_test_for_sol(solspec, spec_index, ROOT, COMMIT_ID, "..")
+49 −20
Original line number Diff line number Diff line
#!/env/python3
'''
Utilities
'''

import os
import sys
@@ -18,15 +21,14 @@ DRY_RUN = config.DRY_RUN
QUIET = config.QUIET
BASE_SPEC = config.BASE_SPEC

class TestDoc():

    def __init__(self, src, doc_fn, doc_main_tit, commit_id, sol, api):
        self.src = src
        self.doc_fn = doc_fn
        self.doc_main_tit = doc_main_tit
        self.commit_id = commit_id
        self.sol = sol
        self.api = api
# class TestDoc():
#     def __init__(self, src, doc_fn, doc_main_tit, commit_id, sol, api):
#         self.src = src
#         self.doc_fn = doc_fn
#         self.doc_main_tit = doc_main_tit
#         self.commit_id = commit_id
#         self.sol = sol
#         self.api = api

class DocReference():

@@ -35,23 +37,28 @@ class DocReference():
        self._nums = [int(i) for i in sec_num_list]

    def lvl(self):
        '''Returns the level of depth of the reference'''
        return self._lvl

    def __str__(self):
        '''To string'''
        return ".".join([str(x) for x in self._nums])

    def next_ref(self):
        '''Calculates the next reference and returns it'''
        nums_cpy = self._nums.copy()
        nums_cpy[self._lvl - 1] = self._nums[self._lvl - 1] + 1
        return DocReference(nums_cpy)

    def sub_ref(self):
        '''Return the reference of the first sub-section'''
        nums_cpy = self._nums.copy()
        nums_cpy.append(1)
        return DocReference(nums_cpy)

    @staticmethod
    def from_str(string):
        '''Builds a reference from a string'''
        return DocReference(string.split("."))

def keyword_to_line(k):
@@ -67,16 +74,13 @@ def keywords_to_text(kws):
    '''
    return "\n".join(map(keyword_to_line, kws))

def gen_test(suite, this_test, spec, sec_ref, API, commit_id, sol):
def gen_test(this_test, spec, sec_ref, url):
    '''
    Generate the Docx part for an individual test
    '''

    ntp = TP(this_test.doc)

    log_line = ["++++ TD: ", sol, API, suite, this_test, ntp.tp_id or "No ID"]
    not QUIET and print(",".join([str(x) for x in log_line]))

    if DRY_RUN:
        return
    if ntp.tp_id is not None:
@@ -89,20 +93,34 @@ def gen_test(suite, this_test, spec, sec_ref, API, commit_id, sol):
    ntp.add_to_spec(
        spec, 
        keywords_to_text(this_test.keywords), 
        str(suite)+".robot", 
        commit_id, 
        sol, 
        API
        url
    )

def generate_void_clause(sec_ref, title, spec, sol):
    '''
    Generates a void clause. Generates Heading
    and a paragraph with text 'Void.'.
    '''
    print("++ Generating void clause: {} {} {}".format(sol, sec_ref, title))
    spec.add_sub_heading_from_ref(str(title), sec_ref, config.DOC_SUITE_LEVEL)
    spec.add_void_paragraph()

def gen_api_suite(sec_ref, suite, spec, workspace, commit_id, sol):
    '''
    Generates all tests in a Robot test suite (i.e .robot file). Generates Heading
    and a sub clause (heading + test description) for each test in the test suite.
    '''
    print("++ Generating test suite: {} {} {}".format(sol, sec_ref, suite))
    spec.add_sub_heading_from_ref(str(suite), sec_ref, config.DOC_SUITE_LEVEL)
    for i in suite.tests:
        gen_test(suite, i, spec, sec_ref, workspace, commit_id, sol)
        url = build_test_url(str(suite)+".robot", commit_id, sol, workspace)

def gen_doc(src, doc_fn, doc_main_tit, commit_id, sol, api):
        log_line = ["++++ TD: ", sol, workspace, suite, i]
        not QUIET and print(",".join([str(x) for x in log_line]))

        gen_test(i, spec, sec_ref,url)

def gen_doc(src, doc_fn, commit_id, sol):
    '''
    Converts a Robot test suite to a word document

@@ -174,3 +192,14 @@ def gen_doc(src, doc_fn, doc_main_tit, commit_id, sol, api):
    not QUIET and print("Saving to: " + doc_fn)
    not DRY_RUN and spec.save(doc_fn)
    not QUIET and print("Finished.")

def build_test_url(commit, sol, api, robot_file):
    '''Builds the URL structure'''
    
    configured_prefix = config.GIT_URL_PREFIX

    if  configured_prefix != "":
        return configured_prefix + commit+"/"+sol+"/"+api+"/"+robot_file
    
    return None
+29 −1
Original line number Diff line number Diff line
'''
Tests for lib.py
'''

import lib

from robot.api import TestSuiteBuilder
from testspec import TestSpec

def test_docreference():
    '''
    Test creation of a TestReference object
@@ -52,3 +54,29 @@ def test_subreference():

    assert tref.lvl() == 2
    assert str(tref) == "1.2"    

def test_gen_api_suite():
    '''
    Test generation of a Test Suite (i.e. Robot file) 
    '''

    sec_ref = lib.DocReference.from_str("6.4.5.1.1")
    suite = TestSuiteBuilder().build("../examples/SOL002/VNFConfiguration-API/Configuration.robot")
    spec = TestSpec("empty.docx")
    workspace = "Another-API"
    commit_id = "deadbeef"
    sol = "SOL002"

    lib.gen_api_suite(
        sec_ref, suite, spec, workspace, commit_id, sol
    )

    outfn = "../examples/test.docx"
    spec.save(outfn)

def test_build_test_url():
    '''
    Tests building the URL to a test
    '''
    url = lib.build_test_url("dead", "SOL002", "My-API", "My-File.robot") 
    assert url == "https://forge.etsi.org/rep/nfv/api-tests/raw/dead/SOL002/My-API/My-File.robot"
+28 −10
Original line number Diff line number Diff line
@@ -3,31 +3,49 @@ Tests for testpurpose.py
'''

import testpurpose
from robot.api import TestSuiteBuilder

def test_create_tp():
    '''
    Test creation of a TP object
    '''
    tp_doc = ''' Test ID: X.Y.Z.Y.W\\n\
    Title: my title\\n\
    tp_doc = ''' Test ID: X.Y.Z.Y.W
    Title: my title
    something: more'''

    tp = testpurpose.TP(tp_doc)
    ntp = testpurpose.TP(tp_doc)

    assert(tp.tp_id.strip() == "X.Y.Z.Y.W")
    assert(len(tp.tp_fields) == 3)
    assert ntp.tp_id.strip() == "X.Y.Z.Y.W"
    assert len(ntp.tp_fields) == 3


def test_create_tp_with_no_id():
    '''
    Test creation of a TP object with no TP object
    '''
    tp_doc = ''' Test suite: My suite\\n\
    Title: my title\\n\
    tp_doc = ''' Test suite: My suite
    Title: my title
    something: more'''

    tp = testpurpose.TP(tp_doc)
    ntp = testpurpose.TP(tp_doc)

    assert ntp.tp_id is None
    assert len(ntp.tp_fields) == 3

def test_create_tp_sol002_config_test():
    '''
    Test TP creation for an example test from SOL002
    '''

    suite = TestSuiteBuilder().build(
        "../examples/SOL002/VNFConfiguration-API/Configuration.robot"
    )

    ntp = testpurpose.TP(suite.tests[0].doc)
    assert ntp.tp_id == "6.3.1.1.1"
    assert ntp.get_field("Test title") == "Set a new VNF Configuration"
    assert ntp.get_field("Config ID") == "Config_prod_VE"
    assert ntp.get_field("Post-Conditions") == \
        "The configuration is successfully set in the VNF and it matches the issued configuration"

    assert(tp.tp_id == None)
    assert(len(tp.tp_fields) == 3)
Loading