From 858b1d1fcec2d928e4e73316f292e6d9e63a4899 Mon Sep 17 00:00:00 2001 From: Ulrich Date: Sun, 21 May 2023 20:06:29 +0200 Subject: [PATCH] some further classes, read-methods testcase/-suite --- basic/constants.py | 9 +++ model/testcase.py | 102 ++++++++++++++++++++++++-------- model/testsuite.py | 82 +++++++++++++++++++++++-- test/test_04config.py | 72 ++++++++++++++-------- test/test_26testsuite.py | 50 ++++++++++++++++ test/test_27testcase.py | 74 +++++++++++++++++++++++ tools/config_tool.py | 12 ++-- tools/data_const.py | 14 ++++- tools/filecsv_fcts.py | 125 +++++---------------------------------- tools/path_const.py | 2 + 10 files changed, 372 insertions(+), 170 deletions(-) create mode 100644 test/test_27testcase.py diff --git a/basic/constants.py b/basic/constants.py index 828154c..3fec058 100644 --- a/basic/constants.py +++ b/basic/constants.py @@ -236,6 +236,15 @@ SUBJECT_USECASES = SUBJECT_USECASE+"s" SUBJECT_REL = "release" SUBJECT_RELS = SUBJECT_REL+"s" +SUBJECT_TESTCASE = "testcase" +SUBJECT_TESTCASES = SUBJECT_TESTCASE+"s" + +SUBJECT_TESTSUITE = "testsuite" +SUBJECT_TESTSUITES = SUBJECT_TESTSUITE+"s" + +SUBJECT_TESTPLAN = "testplan" +SUBJECT_TESTPLANS = SUBJECT_TESTPLAN+"s" + """ in this subject-node are each kind of result of any component with the structure: * topic (db, cli, api, ...) diff --git a/model/testcase.py b/model/testcase.py index 49f6eef..e8ad45b 100644 --- a/model/testcase.py +++ b/model/testcase.py @@ -7,7 +7,7 @@ import os import basic.toolHandling import tools.job_const as J -import utils.data_const as D +import tools.data_const as D import basic.constants as B import model.entity import tools.config_tool @@ -20,6 +20,35 @@ import model.document import model.step import model.table +TABLE_NAMES = ["application", "ap_project", "ap_component"] +STORAGES = [model.entity.STORAGE_FILE, model.entity.STORAGE_DB] +""" used storage in priority sortage, so: if file then read_fcts / if db then select-fcts """ +DEFAULT_SYNC = model.entity.SYNC_FULL_GIT2DB + +TABLE_NAME = B.SUBJECT_APP +""" system-name for this entity """ +FIELD_ID = "tcid" +FIELD_NAME = D.FIELD_NAME +FIELD_DESCRIPTION = B.SUBJECT_DESCRIPTION +FIELD_REFERENCE = B.SUBJECT_REFERENCE +FIELD_PROJECT = B.SUBJECT_PROJECT +LIST_FIELDS = [FIELD_ID, FIELD_NAME, FIELD_DESCRIPTION, FIELD_REFERENCE, FIELD_PROJECT] +""" list of object-attributes """ + +SUB_USECASE = B.SUBJECT_USECASES +SUB_STORIES = B.SUBJECT_STORIES +SUB_STEPS = "steps" +SUB_TABLES = "tables" +LIST_SUBTABLES = [SUB_TABLES, SUB_STEPS, SUB_USECASE, SUB_STORIES] +LIST_SUB_DESCRIPT = [D.DATA_ATTR_USECASE_DESCR, D.DATA_ATTR_STORY_DESCR] + +FILE_EXTENSION = D.DFILE_TYPE_YML +UNIQUE_FIELDS = [FIELD_NAME] +""" unique business field as human identifer """ +IDENTIFYER_FIELDS = [FIELD_ID] +""" unique technical field as technical identifer """ + + class Testcase(model.entity.Entity): """ Generally this object can be stored as a file with data or in a database. @@ -43,7 +72,7 @@ class Testcase(model.entity.Entity): tables = {} steps = [] - def __init__(self, job, project="", name=""): + def __init__(self, job, project, name=""): """ to be initialized by readSpec :param job: @@ -53,9 +82,51 @@ class Testcase(model.entity.Entity): self.project = project if len(name) > 1: self.name = name - self.getEntity(job, name) + # self.getEntity(job, name) + + def read_unique_names(self, job, project, application, gran, args): + """ + reads the entity-names from file-storage + :param job: + :param opt. project: select-criteria if used and defined + :param opt. application: select-criteria if used and defined + :param opt. gran: granularity values testcase / testsuite / testplan + :param opt. args additional args + :return: list of entity-names + """ + path = os.path.join(job.conf[B.SUBJECT_PATH][B.ATTR_PATH_TDATA], getattr(job.par, B.SUBJECT_PROJECT), + B.SUBJECT_TESTCASES) + outList = self.getDirlist(job, path, "") + return outList def read_entity(self, job, name): + """ + reads the entity from the file-system + :param job: + :param name: + :return: + """ + # r = tools.config_tool.select_config_path(job, P.KEY_TESTCASE, "TC0001") + config = self.getConfig(job, P.KEY_TESTCASE, name, tools.config_tool.get_plain_filename(job, name)) + self.setAttributes(config, name, LIST_FIELDS, LIST_SUBTABLES) + for k in LIST_SUBTABLES: + if not hasattr(self, k): + continue + if "_"+k in config[name] and "_"+k+"-description" in LIST_SUB_DESCRIPT: + values = {} + if "_"+k+"-description" in config[name]: + for l in config[name]["_"+k]: + if l in config[name]["_"+k+"-description"]: + values[config[name]["_"+k][l]] = config[name]["_" + k + "-description"][l] + else: + values[config[name]["_"+k][l]] = "" + else: + for l in config[name]["_"+k]: + values[config[name]["_" + k][l]] = "" + setattr(self, k, values) + return self + + def xxread_entity(self, job, name): """ reads the entity from the file-system :param job: @@ -101,6 +172,8 @@ class Testcase(model.entity.Entity): pass if B.DATA_NODE_STEPS in tdata: for s in tdata[B.DATA_NODE_STEPS]: + if s in B.LIST_DATA_NODE: + continue step = model.step.Step(job, project=job.par.project, name=s) pass if B.DATA_NODE_TABLES in tdata: @@ -127,29 +200,6 @@ class Testcase(model.entity.Entity): raise Exception(B.EXCEPT_NOT_IMPLEMENT) - def get_schema(self, tableName="", tableObject=None): - dbtype = self.job.conf[B.TOPIC_NODE_DB][B.ATTR_TYPE] - dbi = basic.toolHandling.getDbTool(self.job, None, dbtype) - sql = dbi.getCreateTable("testcase") - sql += dbi.getSchemaAttribut("tcid", "id")+"," - sql += dbi.getSchemaAttribut("name", D.TYPE_STR)+"," - sql += dbi.getSchemaAttribut("description", D.TYPE_TEXT)+"," - sql += dbi.getSchemaAttribut("project", D.TYPE_STR)+"," - sql += dbi.getSchemaAttribut("usecase", D.TYPE_STR)+"," - sql += dbi.getSchemaAttribut("attributes", D.TYPE_TEXT)+"," - sql += self.getHistoryFields() - sql += ");\n" - sql += self.getHistoryIndex("testcase") - for attr in ["application", "story"]: - sql += dbi.getSchemaSubtable("tc", [{"attr":attr, "atype": D.TYPE_STR}])+"\n" - sql += dbi.getSchemaIndex(dbi.getIndexName("tc", attr), - dbi.getSubTableId(dbi.getSubTableName("tc", attr), attr))+"\n" - for attr in ["dtable", "step"]: - sql += dbi.getSchemaSubtable("tc", [{"attr":attr, "atype": D.TYPE_STR}, {"attr":"attributes", "atype": D.TYPE_TEXT}])+"\n" - sql += dbi.getSchemaIndex(dbi.getSubTableName("tc", attr), - dbi.getSubTableId(dbi.getSubTableName("tc", attr), attr))+"\n" - return sql - def select_testcase(job, project, testcase): """ to select a concrete testcase diff --git a/model/testsuite.py b/model/testsuite.py index dec2a49..beb6b20 100644 --- a/model/testsuite.py +++ b/model/testsuite.py @@ -7,7 +7,7 @@ import os import basic.toolHandling import tools.job_const as J -import utils.data_const as D +import tools.data_const as D import basic.constants as B import model.entity import tools.config_tool @@ -16,6 +16,31 @@ import tools.path_tool import tools.path_const as P import model.entity +TABLE_NAMES = ["application", "ap_project", "ap_component"] +STORAGES = [model.entity.STORAGE_FILE, model.entity.STORAGE_DB] +""" used storage in priority sortage, so: if file then read_fcts / if db then select-fcts """ +DEFAULT_SYNC = model.entity.SYNC_FULL_GIT2DB + +FIELD_ID = "tsid" +FIELD_NAME = D.FIELD_NAME +FIELD_DESCRIPTION = B.SUBJECT_DESCRIPTION +FIELD_REFERENCE = B.SUBJECT_REFERENCE +FIELD_PROJECT = B.SUBJECT_PROJECT +LIST_FIELDS = [FIELD_ID, FIELD_NAME, FIELD_DESCRIPTION, FIELD_REFERENCE, FIELD_PROJECT] +""" list of object-attributes """ + +SUB_USECASE = B.SUBJECT_USECASES +SUB_TESTCASES = B.SUBJECT_TESTCASES +SUB_STEPS = "steps" +LIST_SUBTABLES = [SUB_USECASE, SUB_STEPS, SUB_TESTCASES] +LIST_SUB_DESCRIPT = [D.DATA_ATTR_USECASE_DESCR] + +FILE_EXTENSION = D.DFILE_TYPE_YML +UNIQUE_FIELDS = [FIELD_NAME] +""" unique business field as human identifer """ +IDENTIFYER_FIELDS = [FIELD_ID] +""" unique technical field as technical identifer """ + class Testsuite(model.entity.Entity): name = "" @@ -26,23 +51,70 @@ class Testsuite(model.entity.Entity): tables = {} steps = [] - def __init__(self, job): + def __init__(self, job, project, name=""): """ to be initialized by readSpec :param job: """ self.job = job + self.project = project + if len(name) > 1: + self.name = name + + def read_unique_names(self, job, project, application, gran, args): + """ + reads the entity-names from file-storage + :param job: + :param opt. project: select-criteria if used and defined + :param opt. application: select-criteria if used and defined + :param opt. gran: granularity values testcase / testsuite / testplan + :param opt. args additional args + :return: list of entity-names + """ + path = os.path.join(job.conf[B.SUBJECT_PATH][B.ATTR_PATH_TDATA], getattr(job.par, B.SUBJECT_PROJECT), + B.SUBJECT_TESTSUITES) + outList = self.getDirlist(job, path, "") + return outList + + def read_entity(self, job, name): + """ + reads the entity from the file-system + :param job: + :param name: + :return: + """ + # r = tools.config_tool.select_config_path(job, P.KEY_TESTCASE, "TC0001") + config = self.getConfig(job, P.KEY_TESTSUITE, name, tools.config_tool.get_plain_filename(job, name)) + self.setAttributes(config, name, LIST_FIELDS, LIST_SUBTABLES) + for k in LIST_SUBTABLES: + if not hasattr(self, k): + continue + if "_"+k in config[name] and "_"+k+"-description" in LIST_SUB_DESCRIPT: + values = {} + if "_"+k+"-description" in config[name]: + for l in config[name]["_"+k]: + if l in config[name]["_"+k+"-description"]: + values[config[name]["_"+k][l]] = config[name]["_" + k + "-description"][l] + else: + values[config[name]["_"+k][l]] = "" + else: + for l in config[name]["_"+k]: + values[config[name]["_" + k][l]] = "" + setattr(self, k, values) + return self + def get_schema(self, tableName="", tableObject=None): + #TODO veraltet dbtype = self.job.conf[B.TOPIC_NODE_DB][B.ATTR_TYPE] dbi = basic.toolHandling.getDbTool(self.job, None, dbtype) sql = dbi.getCreateTable("testsuite") sql += dbi.getSchemaAttribut("tsid", "id")+"," sql += dbi.getSchemaAttribut("name", D.TYPE_STR)+"," - sql += dbi.getSchemaAttribut("description", D.TYPE_TEXT)+"," + sql += dbi.getSchemaAttribut(B.SUBJECT_REFERENCE, D.TYPE_TEXT)+"," sql += dbi.getSchemaAttribut("project", D.TYPE_STR)+"," sql += dbi.getSchemaAttribut("usecase", D.TYPE_STR)+"," - sql += dbi.getSchemaAttribut("attributes", D.TYPE_TEXT)+"," + sql += dbi.getSchemaAttribut(B.NODE_ATTRIBUTES, D.TYPE_TEXT)+"," sql += self.getHistoryFields() sql += ");\n" sql += self.getHistoryIndex("testsuite") @@ -51,7 +123,7 @@ class Testsuite(model.entity.Entity): sql += dbi.getSchemaIndex(dbi.getIndexName("ts", attr), dbi.getSubTableId(dbi.getSubTableName("ts", attr), attr))+"\n" for attr in ["dtable", "step"]: - sql += dbi.getSchemaSubtable("ts", [{"attr":attr, "atype": D.TYPE_STR}, {"attr":"attributes", "atype": D.TYPE_TEXT}])+"\n" + sql += dbi.getSchemaSubtable("ts", [{"attr":attr, "atype": D.TYPE_STR}, {"attr":B.NODE_ATTRIBUTES, "atype": D.TYPE_TEXT}])+"\n" sql += dbi.getSchemaIndex(dbi.getSubTableName("ts", attr), dbi.getSubTableId(dbi.getSubTableName("ts", attr), attr))+"\n" return sql diff --git a/test/test_04config.py b/test/test_04config.py index 54c569f..0f626a8 100644 --- a/test/test_04config.py +++ b/test/test_04config.py @@ -10,21 +10,23 @@ import basic.constants as B import unittest import os import inspect -import utils.config_tool -import utils.conn_tool + +import tools.config_tool +import tools.conn_tool import test.constants as T import test.testtools -import utils.path_const as P +import tools.path_const as P import basic.constants as B -TEST_FUNCTIONS = ["test_01getConfig", "test_02mergeAttributes", "test_03getAttributes"] -#TEST_FUNCTIONS = ["test_03getAttributes"] +TEST_FUNCTIONS = ["test_01getConfigPath", "test_02mergeAttributes", "test_03getAttributes", + "test_20getPlainName"] +TEST_FUNCTIONS = ["test_01getConfigPath"] verbose = False class MyTestCase(unittest.TestCase): mymsg = "--------------------------------------------------------------" - def test_01getConfig(self): + def test_01getConfigPath(self): global mymsg actfunction = str(inspect.currentframe().f_code.co_name) cnttest = 0 @@ -32,23 +34,32 @@ class MyTestCase(unittest.TestCase): return job = test.testtools.getJob() x = B.SUBJECT_APPS - r = utils.config_tool.getConfigPath(job, P.KEY_BASIC, x) + r = tools.config_tool.select_config_path(job, P.KEY_BASIC, x) self.assertIn(os.path.join(T.COMP_PATH, P.VAL_CONFIG, B.SUBJECT_APPS), r) cnttest += 1 x = "path" - r = utils.config_tool.getConfigPath(job, P.KEY_TOOL, x) - self.assertIn(os.path.join(T.PROG_PATH, P.VAL_UTIL, P.VAL_CONFIG), r) + r = tools.config_tool.select_config_path(job, P.KEY_TOOL, x) + self.assertIn(os.path.join(job.conf[B.SUBJECT_PATH][P.ATTR_PATH_COMPONENTS], P.VAL_CONFIG), r) cnttest += 1 x = "conn" - r = utils.config_tool.getConfigPath(job, P.KEY_TOOL, x) - self.assertIn(os.path.join(job.conf.getPath(P.ATTR_PATH_ENV)), r) + r = tools.config_tool.select_config_path(job, P.KEY_TOOL, x) + self.assertIn(os.path.join(job.conf[B.SUBJECT_PATH][P.ATTR_PATH_ENV]), r) cnttest += 1 - self.assertRaises(Exception, utils.config_tool.getConfigPath, (job, P.KEY_COMP, "TestX2")) + self.assertRaises(Exception, tools.config_tool.select_config_path, (job, P.KEY_COMP, "TestX2")) # self.assertEqual(r, None) cnttest += 1 - r = utils.config_tool.getConfigPath(job, P.KEY_COMP, "testcrm") - self.assertIn(os.path.join(job.conf.getPath(P.ATTR_PATH_COMPONENTS), "testcrm", "CONFIG"), r) - r = utils.config_tool.getConfig(job, P.KEY_TOOL, "path") + r = tools.config_tool.select_config_path(job, P.KEY_COMP, "testcrm") + self.assertIn(os.path.join(job.conf[B.SUBJECT_PATH][P.ATTR_PATH_COMPONENTS], "testcrm", "CONFIG"), r) + cnttest += 1 + r = tools.config_tool.select_config_path(job, P.KEY_TESTCASE, "TC0001") + self.assertIn(os.path.join(job.conf[B.SUBJECT_PATH][P.ATTR_PATH_TDATA], "TESTPROJ", B.SUBJECT_TESTCASES, "TC0001", "test"), r) + cnttest += 1 + r = tools.config_tool.select_config_path(job, P.KEY_TESTSUITE, "TST001") + self.assertIn(os.path.join(job.conf[B.SUBJECT_PATH][P.ATTR_PATH_TDATA], "TESTPROJ", B.SUBJECT_TESTSUITES, "TST001", "test"), r) + + + + r = tools.config_tool.getConfig(job, P.KEY_TOOL, "path") if verbose: print("pattern " + r["pattern"]["log"]) if verbose: print("pattern " + r["pattern"]["precond"]) MyTestCase.mymsg += "\n----- "+actfunction+" : "+str(cnttest) @@ -62,21 +73,21 @@ class MyTestCase(unittest.TestCase): return job = test.testtools.getJob() componentName = "testcm" - confs = utils.config_tool.getConfig(job, "comp", componentName) - conns = utils.conn_tool.getConnections(job, componentName) + confs = tools.config_tool.getConfig(job, "comp", componentName) + conns = tools.conn_tool.getConnections(job, componentName) self.assertEqual(confs["conf"][B.SUBJECT_INST][B.ATTR_INST_CNT], 1) self.assertEqual(conns[0][B.SUBJECT_INST][B.ATTR_INST_CNT], 2) self.assertNotIn(B.ATTR_INST_SGL, conns[0][B.SUBJECT_INST]) - confs["conf"] = utils.config_tool.mergeConn(job.m, confs["conf"], conns[0]) + confs["conf"] = tools.config_tool.mergeConn(job.m, confs["conf"], conns[0]) self.assertEqual(confs["conf"][B.SUBJECT_INST][B.ATTR_INST_CNT], 2) cnttest += 1 # it overwrites self.assertEqual(confs["conf"][B.SUBJECT_INST][B.ATTR_INST_SGL], "n") cnttest += 1 # it keep componentName = "testprddb" - confs = utils.config_tool.getConfig(job, "comp", componentName) - conns = utils.conn_tool.getConnections(job, componentName) + confs = tools.config_tool.getConfig(job, "comp", componentName) + conns = tools.conn_tool.getConnections(job, componentName) self.assertNotIn(B.ATTR_ARTS_TYPE, confs["conf"][B.SUBJECT_ARTS][B.TOPIC_NODE_DB]) - confs["conf"] = utils.config_tool.mergeConn(job.m, confs["conf"], conns[0]) + confs["conf"] = tools.config_tool.mergeConn(job.m, confs["conf"], conns[0]) self.assertIn(B.ATTR_ARTS_TYPE, confs["conf"][B.SUBJECT_ARTS][B.TOPIC_NODE_DB]) cnttest += 1 # new attribute MyTestCase.mymsg += "\n----- "+actfunction+" : "+str(cnttest) @@ -91,19 +102,32 @@ class MyTestCase(unittest.TestCase): job = test.testtools.getJob() comp = test.testtools.getComp(job, "testprddb") path = "db.product" - attrList = utils.config_tool.getAttributeList(comp, path, job) + attrList = tools.config_tool.getAttributeList(comp, path, job) self.assertIn(B.ATTR_ARTS_PATH, attrList) self.assertIn(B.ATTR_ARTS_RESET, attrList) cnttest += 2 # new attribute comp = test.testtools.getComp(job, "testrest") path = "file.xmlrest" - attrList = utils.config_tool.getAttributeList(comp, path, job) + attrList = tools.config_tool.getAttributeList(comp, path, job) #print(str(comp.conf["conn"])) #print(str(comp.conf[B.SUBJECT_ARTS])) #print(str(attrList)) MyTestCase.mymsg += "\n----- "+actfunction+" : "+str(cnttest) - + def test_20getPlainName(self): + global mymsg + actfunction = str(inspect.currentframe().f_code.co_name) + cnttest = 0 + if actfunction not in TEST_FUNCTIONS: + return + job = test.testtools.getJob() + for ext in tools.config_tool.CONFIG_FORMAT: + plain = tools.config_tool.get_plain_filename(job, "testfall." + ext) + self.assertEqual(plain, "testfall") + for ext in tools.config_tool.CONFIG_FORMAT: + plain = tools.config_tool.get_plain_filename(job, os.path.join(job.conf[B.SUBJECT_PATH][B.ATTR_PATH_PROGRAM], + P.ATTR_PATH_TDATA, "testfall." + ext)) + self.assertEqual(plain, "testfall") def test_zzz(self): print(MyTestCase.mymsg) diff --git a/test/test_26testsuite.py b/test/test_26testsuite.py index 57984ae..4810591 100644 --- a/test/test_26testsuite.py +++ b/test/test_26testsuite.py @@ -14,6 +14,9 @@ import model.testsuite HOME_PATH = test.constants.HOME_PATH PYTHON_CMD = "python" TEST_FUNCTIONS = ["test_10getEnvironments"] +TEST_FUNCTIONS = ["test_10getEntityNames", "test_11getEntities", "test_12getEntity", + "test_13writeEntity", "test_14insertEntity"] +TEST_FUNCTIONS = ["test_10getEntityNames", "test_12getEntity"] PROGRAM_NAME = "clean_workspace" @@ -36,6 +39,53 @@ class MyTestCase(unittest.TestCase): envs = model.testsuite.select_testsuites(job, projList, appList) print(str(envs)) + def test_10getEntityNames(self): + global mymsg + global jobObject + actfunction = str(inspect.currentframe().f_code.co_name) + cnttest = 0 + if actfunction not in TEST_FUNCTIONS: + return + job = test.testtools.getJob() + testsuite = model.testsuite.Testsuite(job, "TESTPROJ") + entityNames = testsuite.read_unique_names(job, "", "", "", {}) + self.assertEqual(type(entityNames), list) + #entityNames = project.select_unique_names(job, "", "", "", {}) + #self.assertEquals(type(entityNames), list) + + def test_11getEntities(self): + global mymsg + global jobObject + actfunction = str(inspect.currentframe().f_code.co_name) + cnttest = 0 + if actfunction not in TEST_FUNCTIONS: + return + job = test.testtools.getJob() + testsuite = model.testsuite.Testsuite(job, "TESTPROJ") + entityNames = [] + entityNames = testsuite.get_entities(job, storage=model.entity.STORAGE_FILE) + self.assertEqual(type(entityNames), list) + #entityNames = testsuite.get_entities(job, storage=model.entity.STORAGE_DB) + #self.assertEqual(type(entityNames), list) + + def test_12getEntity(self): + global mymsg + global jobObject + actfunction = str(inspect.currentframe().f_code.co_name) + cnttest = 0 + if actfunction not in TEST_FUNCTIONS: + return + job = test.testtools.getJob() + testsuite = model.testsuite.Testsuite(job, "TESTPROJ") + name = "TST001" + acttestsuite = testsuite.read_entity(job, name) + self.assertEqual(getattr(acttestsuite, model.testsuite.FIELD_NAME), name) + self.assertRaises(Exception, testsuite.read_entity, job, "xyzxyz") + # + #actrelease = release.select_entity(job, name) + #self.assertEqual(getattr(actrelease, model.release.FIELD_NAME), name) + #self.assertRaises(Exception, release.select_entity, job, ["xyzxyz"]) + if __name__ == '__main__': unittest.main() diff --git a/test/test_27testcase.py b/test/test_27testcase.py new file mode 100644 index 0000000..bbf5e47 --- /dev/null +++ b/test/test_27testcase.py @@ -0,0 +1,74 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# --------------------------------------------------------------------------------------------------------- +# Author : Ulrich Carmesin +# Source : gitea.ucarmesin.de +# --------------------------------------------------------------------------------------------------------- +import unittest +import inspect +import test.testtools +import basic.constants as B +import test.constants as T +import model.testcase +import model.entity + +HOME_PATH = test.constants.HOME_PATH +PYTHON_CMD = "python" +TEST_FUNCTIONS = ["test_10getEntityNames", "test_11getEntities", "test_12getEntity", + "test_13writeEntity", "test_14insertEntity"] +TEST_FUNCTIONS = ["test_10getEntityNames", "test_12getEntity"] +PROGRAM_NAME = "clean_workspace" + +class MyTestCase(unittest.TestCase): + mymsg = "--------------------------------------------------------------" + + + def test_10getEntityNames(self): + global mymsg + global jobObject + actfunction = str(inspect.currentframe().f_code.co_name) + cnttest = 0 + if actfunction not in TEST_FUNCTIONS: + return + job = test.testtools.getJob() + testcase = model.testcase.Testcase(job, "TESTPROJ") + entityNames = testcase.read_unique_names(job, "", "", "", {}) + self.assertEqual(type(entityNames), list) + #entityNames = project.select_unique_names(job, "", "", "", {}) + #self.assertEquals(type(entityNames), list) + + def test_11getEntities(self): + global mymsg + global jobObject + actfunction = str(inspect.currentframe().f_code.co_name) + cnttest = 0 + if actfunction not in TEST_FUNCTIONS: + return + job = test.testtools.getJob() + testcase = model.testcase.Testcase(job, "TESTPROJ") + entityNames = [] + entityNames = testcase.get_entities(job, storage=model.entity.STORAGE_FILE) + self.assertEqual(type(entityNames), list) + #entityNames = testcase.get_entities(job, storage=model.entity.STORAGE_DB) + #self.assertEqual(type(entityNames), list) + + def test_12getEntity(self): + global mymsg + global jobObject + actfunction = str(inspect.currentframe().f_code.co_name) + cnttest = 0 + if actfunction not in TEST_FUNCTIONS: + return + job = test.testtools.getJob() + testcase = model.testcase.Testcase(job, "TESTPROJ") + name = "TC0001" + acttestcase = testcase.read_entity(job, name) + self.assertEqual(getattr(acttestcase, model.testcase.FIELD_NAME), name) + self.assertRaises(Exception, testcase.read_entity, job, "xyzxyz") + # + #actrelease = release.select_entity(job, name) + #self.assertEqual(getattr(actrelease, model.release.FIELD_NAME), name) + #self.assertRaises(Exception, release.select_entity, job, ["xyzxyz"]) + +if __name__ == '__main__': + unittest.main() diff --git a/tools/config_tool.py b/tools/config_tool.py index cb451dd..c43dbca 100644 --- a/tools/config_tool.py +++ b/tools/config_tool.py @@ -79,9 +79,9 @@ def select_config_path(job, modul, name, subname=""): elif modul == P.KEY_BASIC: return getBasicPath(job, name) elif modul == P.KEY_TESTCASE: - return getTestPath(job, name, D.DFILE_TESTCASE_NAME) + return getTestPath(job, name, B.SUBJECT_TESTCASES, D.DFILE_TESTCASE_NAME) elif modul == P.KEY_TESTSUITE: - return getTestPath(job, name, D.DFILE_TESTSUITE_NAME) + return getTestPath(job, name, B.SUBJECT_TESTSUITES, D.DFILE_TESTSUITE_NAME) elif modul == P.KEY_CATALOG: return getCatalogPath(job, name) elif modul == P.KEY_USER: @@ -189,10 +189,10 @@ def getBasicPath(job, name): if path is not None: return path -def getTestPath(job, name, filename): +def getTestPath(job, name, subdir, filename): for format in CONFIG_FORMAT: pathname = os.path.join(job.conf[B.SUBJECT_PATH][P.ATTR_PATH_TDATA], job.par.project, - name, filename + "." + format) + subdir, name, filename + "." + format) if os.path.exists(pathname): return pathname @@ -211,6 +211,10 @@ def getCatalogPath(job, name): P.KEY_CATALOG, name)) if path is not None: return path + path = getExistingPath(job, os.path.join(job.conf[B.SUBJECT_PATH][P.ATTR_PATH_COMPONENTS], + P.KEY_CATALOG, P.VAL_TABLES, name)) + if path is not None: + return path path = getExistingPath(job, os.path.join(job.conf[B.SUBJECT_PATH][P.ATTR_PATH_PROGRAM], P.KEY_CATALOG, name)) if path is not None: diff --git a/tools/data_const.py b/tools/data_const.py index 15e7df5..f2a1ebc 100644 --- a/tools/data_const.py +++ b/tools/data_const.py @@ -73,12 +73,24 @@ DATA_ATTR_REF = "_ref" DATA_ATTR_TBL = "_table" DATA_ATTR_TYPE = "_type" DATA_ATTR_DLIM = "_dlim" +DATA_ATTR_NAME = "_"+FIELD_NAME +DATA_ATTR_DESCRIPTION = "_"+B.SUBJECT_DESCRIPTION +DATA_ATTR_REFERENCE = "_"+B.SUBJECT_REFERENCE +DATA_ATTR_PROJECT = "_"+B.SUBJECT_PROJECT +DATA_ATTR_USECASES = "_"+B.SUBJECT_USECASES +DATA_ATTR_USECASE_DESCR = DATA_ATTR_USECASES+"-description" +DATA_ATTR_STORIES = "_"+B.SUBJECT_STORIES +DATA_ATTR_STORY_DESCR = DATA_ATTR_STORIES+"-description" """ name of the table - it can be overwrite from the environment-attribut tablename """ LIST_DATA_ATTR = [DATA_ATTR_TYPE, DATA_ATTR_COUNT, DATA_ATTR_DATE, DATA_ATTR_CHAR, DATA_ATTR_COMP, - DATA_ATTR_REF, DATA_ATTR_IDS, DATA_ATTR_ALIAS, DATA_ATTR_KEY, DATA_ATTR_TBL, DATA_ATTR_DLIM] + DATA_ATTR_REF, DATA_ATTR_IDS, DATA_ATTR_ALIAS, DATA_ATTR_KEY, DATA_ATTR_TBL, DATA_ATTR_DLIM, + DATA_ATTR_NAME, DATA_ATTR_DESCRIPTION, DATA_ATTR_REFERENCE, DATA_ATTR_PROJECT, + DATA_ATTR_STORIES, DATA_ATTR_STORY_DESCR, DATA_ATTR_USECASES, DATA_ATTR_USECASE_DESCR] LIST_ATTR_CONST = ["DATA_ATTR_COUNT", "DATA_ATTR_DATE", "DATA_ATTR_CHAR", "DATA_ATTR_COMP", "DATA_ATTR_ALIAS", "DATA_ATTR_KEY"] +LIST_ATTR_MULTI = [DATA_ATTR_USECASES, DATA_ATTR_STORIES, DATA_ATTR_STORY_DESCR] + # attributes in testcase-specification HEAD_ATTR_DESCR = "decription" HEAD_ATTR_TARGET = "target" diff --git a/tools/filecsv_fcts.py b/tools/filecsv_fcts.py index 13dca20..e01292f 100644 --- a/tools/filecsv_fcts.py +++ b/tools/filecsv_fcts.py @@ -32,109 +32,6 @@ class FileFcts(tools.file_abstract.FileFcts): text = self.buildCsv(self.getMsg(), self.job, data, ttype) return text - def parseCsv_alt(self, msg, job, lines, ttype=""): - """ - - :param msg: - :param lines: - :param type: - :param job: - :return: - """ - tdata = {} - status = "start" - verbose = False - tableAttr = {} # table - tableDict = {} # table - for l in lines: - if verbose: print(ttype + "--" + status + " lines "+l) - fields = splitFields(l, D.CSV_DELIMITER, job) - # check empty line, comment - if (len(fields) < 1) or (len(l.strip().replace(D.CSV_DELIMITER,"")) < 1): - status = "start" - continue - if (fields[0][0:1] == "#"): - continue - a = fields[0].lower().split(":") - # keywords option, step, table - if verbose: print(str(a)+" -- "+str(fields)) - tableAttr = setTableAttribute(tableAttr, a[0], fields[1], job) - if a[0].lower() in D.LIST_DATA_ATTR: - status = "TABLE_ALIAS" - if a[0].lower() == D.DATA_ATTR_TYPE: - ttype = fields[1] - if a[0].lower() == D.DATA_ATTR_KEY: - ttype = D.CSV_SPECTYPE_KEYS - continue - if (a[0].lower() in [D.CSV_BLOCK_HEAD]): - if verbose: print(">> head "+l) - setTdataLine(tdata, fields, D.CSV_BLOCK_HEAD, job) - status = "start" - continue - elif (a[0].lower() == D.CSV_BLOCK_OPTION): - if verbose: print(">> option " + l) - setTdataLine(tdata, fields, D.CSV_BLOCK_OPTION, job) - status = "start" - continue - elif (a[0].lower() == D.CSV_BLOCK_STEP): - if verbose: print(">> step "+l) - step = basic.step.parseStep(job, fields) - if D.CSV_BLOCK_STEP not in tdata: - tdata[D.CSV_BLOCK_STEP] = [] - tdata[D.CSV_BLOCK_STEP].append(step) - status = "start" - continue - elif (a[0].lower() == D.CSV_BLOCK_IMPORT): - if verbose: print(">> includes " + l) - if D.CSV_BLOCK_IMPORT not in tdata: - tdata[D.CSV_BLOCK_IMPORT] = [] - tdata[D.CSV_BLOCK_IMPORT].append(fields[1]) - status = "start" - continue - elif (a[0].lower() == D.CSV_BLOCK_TABLES) or (a[0].lower() in D.CSV_HEADER_START): - if verbose: print(">> tables "+l) - h = a - h[0] = B.DATA_NODE_TABLES - if ttype == D.CSV_SPECTYPE_CONF: - del h[0] - tableDict = getTdataContent(msg, tdata, h) - setTableHeader(tableDict, tableAttr, fields, ttype, job) - status = D.CSV_SPECTYPE_DATA - elif (status == D.CSV_SPECTYPE_DATA): - tableDict = getTdataContent(msg, tdata, h) - if verbose: print(">> setTableData "+str(h)+" "+str(tableDict)) - setTableData(tableDict, fields, ttype, job) - elif (status == "TABLE_ALIAS") and D.DATA_ATTR_ALIAS in tdata: - alias = tdata[D.DATA_ATTR_ALIAS] - b = alias.split(":") - h = [B.DATA_NODE_TABLES] + b - tableDict = getTdataContent(msg, tdata, h) - tableDict[D.DATA_ATTR_ALIAS] = alias - fields = [alias] + fields - setTableHeader(tableDict, tableAttr, fields, ttype, job) - status = D.CSV_SPECTYPE_DATA - if ttype == D.CSV_SPECTYPE_CONF: - header = [] - for k in tdata: - if k in D.LIST_DATA_ATTR: - continue - if B.DATA_NODE_DATA in tdata[k]: - tdata[k].pop(B.DATA_NODE_DATA) - for f in tdata[k]: - if f in [B.DATA_NODE_HEADER, "_hit"] + D.LIST_DATA_ATTR: - continue - header.append(f) - tdata[k][B.DATA_NODE_HEADER] = header - header = [] - if B.DATA_NODE_TABLES in tdata and B.DATA_NODE_TABLES in tdata[B.DATA_NODE_TABLES]: - for k in tdata[B.DATA_NODE_TABLES][B.DATA_NODE_TABLES]: - if k in tdata[B.DATA_NODE_TABLES]: - if verbose: print("Error") - else: - tdata[B.DATA_NODE_TABLES][k] = tdata[B.DATA_NODE_TABLES][B.DATA_NODE_TABLES][k] - tdata[B.DATA_NODE_TABLES].pop(B.DATA_NODE_TABLES) - return tdata - def isEmptyLine(self, msg, job, line, fields): if (len(fields) < 1) or (len(line.strip().replace(D.CSV_DELIMITER, "")) < 1): status = "start" @@ -196,7 +93,7 @@ class FileFcts(tools.file_abstract.FileFcts): a = fields[0].lower().split(":") # keywords option, step, table if self.isBlock(msg, job, fields[0], D.CSV_BLOCK_ATTR, status): # a[0].lower() in D.LIST_DATA_ATTR: - tableAttr = setTableAttribute(tableAttr, a[0], fields[1], job) + tableAttr = setTableAttribute(job, tableAttr, a[0], fields) if ttype == "" and D.DATA_ATTR_TYPE in tableAttr: ttype = tableAttr[D.DATA_ATTR_TYPE] elif D.DATA_ATTR_TYPE in tableAttr and ttype != tableAttr[D.DATA_ATTR_TYPE]: @@ -441,12 +338,20 @@ def splitFields(line, delimiter, job): out.append(fields[i]) return out -def setTableAttribute(tableAttr, key, val, job): - for attr in D.LIST_DATA_ATTR: - if (key.lower() == attr): - tableAttr[attr] = val.strip() - tableAttr["_hit"] = True - return tableAttr +def setTableAttribute(job, tableAttr, key, val): + key = key.lower() + if key in D.LIST_DATA_ATTR: + if key in D.LIST_ATTR_MULTI: + values = {} + for i in range(1, len(val)): + if len(val[i].strip()) < 1: + continue + values["{:03d}".format(i)] = val[i].strip() + tableAttr[key] = values + else: + tableAttr[key] = val[1].strip() + tableAttr["_hit"] = True + return tableAttr tableAttr["_hit"] = False return tableAttr diff --git a/tools/path_const.py b/tools/path_const.py index 0e8ce71..6724371 100644 --- a/tools/path_const.py +++ b/tools/path_const.py @@ -25,6 +25,8 @@ KEY_TOOL = "tool" """ keyword for technical tools """ VAL_TOOLS = "tools" """ subdir for any technical tools """ +VAL_TABLES = "tables" +""" subdir for any technical tables """ VAL_TEST = "test" """ subdir for any unit-tests """ VAL_CONFIG = "config"