def setUpClass(cls): cls.tm1 = TM1Service(**config['tm1srv01']) cls.random_string = str(uuid.uuid4()) cls.all_dimension_names = cls.tm1.dimensions.get_all_names() cls.random_dimension = cls.tm1.dimensions.get(random.choice(cls.all_dimension_names)) cls.random_dimension_all_elements = cls.random_dimension.default_hierarchy.elements cls.random_dimension_elements = [element for element in cls.random_dimension_all_elements][0:2] # None process cls.p_none = Process(name=process_prefix + '_none_' + cls.random_string, datasource_type='None') # ACII process cls.p_ascii = Process(name=process_prefix + '_ascii_' + cls.random_string, datasource_type='ASCII', datasource_ascii_delimiter_type='Character', datasource_ascii_delimiter_char=',', datasource_ascii_header_records=2, datasource_ascii_quote_character='^', datasource_ascii_thousand_separator='~', prolog_procedure="sTestProlog = 'test prolog procedure'", metadata_procedure="sTestMeta = 'test metadata procedure'", data_procedure="sTestData = 'test data procedure'", epilog_procedure="sTestEpilog = 'test epilog procedure'", datasource_data_source_name_for_server=r'C:\Data\file.csv', datasource_data_source_name_for_client=r'C:\Data\file.csv') # Variables cls.p_ascii.add_variable('v_1', 'Numeric') cls.p_ascii.add_variable('v_2', 'Numeric') cls.p_ascii.add_variable('v_3', 'Numeric') cls.p_ascii.add_variable('v_4', 'Numeric') # Parameters cls.p_ascii.add_parameter('p_Year', 'year?', '2016') cls.p_ascii.add_parameter('p_Number', 'number?', 2) # View process cls.p_view = Process(name=process_prefix + '_view_' + cls.random_string, datasource_type='TM1CubeView', datasource_view='view1', datasource_data_source_name_for_client='Plan_BudgetPlan', datasource_data_source_name_for_server='Plan_BudgetPlan') # ODBC process cls.p_odbc = Process(name=process_prefix + '_odbc_' + cls.random_string, datasource_type='ODBC', datasource_password='******', datasource_user_name='user') # Subset process cls.subset_name = process_prefix + '_subset_' + cls.random_string cls.subset = Subset(dimension_name=cls.random_dimension.name, subset_name=cls.subset_name, elements=cls.random_dimension_elements) cls.tm1.dimensions.subsets.create(cls.subset, False) cls.p_subset = Process(name=process_prefix + '_subset_' + cls.random_string, datasource_type='TM1DimensionSubset', datasource_data_source_name_for_server=cls.subset.dimension_name, datasource_subset=cls.subset.name, metadata_procedure="sTest = 'abc';")
def setUpClass(cls): """ Establishes a connection to TM1 and creates TM! objects to use across all tests """ # Connection to TM1 cls.config = configparser.ConfigParser() cls.config.read(Path(__file__).parent.joinpath('config.ini')) cls.tm1 = TM1Service(**cls.config['tm1srv01']) cls.all_dimension_names = cls.tm1.dimensions.get_all_names() cls.random_dimension = cls.tm1.dimensions.get(random.choice(cls.all_dimension_names)) cls.random_dimension_all_elements = cls.random_dimension.default_hierarchy.elements cls.random_dimension_elements = [element for element in cls.random_dimension_all_elements][0:2] # Subset process cls.subset_name = cls.prefix + '_subset_' + cls.some_name cls.subset = Subset(dimension_name=cls.random_dimension.name, subset_name=cls.subset_name, elements=cls.random_dimension_elements) cls.tm1.dimensions.subsets.update_or_create(cls.subset, False) cls.p_subset = Process(name=cls.prefix + '_subset_' + cls.some_name, datasource_type='TM1DimensionSubset', datasource_data_source_name_for_server=cls.subset.dimension_name, datasource_subset=cls.subset.name, metadata_procedure="sTest = 'abc';") with open(Path(__file__).parent.joinpath('resources', 'Bedrock.Server.Wait.json'), 'r') as file: cls.p_bedrock_server_wait = Process.from_json(file.read())
def test1_get_last_process_message_from_message_log(self): # inject process with ItemReject p = Process(name=self.process_name1, prolog_procedure="ItemReject('TM1py Tests');") self.tm1.processes.create(p) try: self.tm1.processes.execute(p.name) except TM1pyException as e: if "ProcessCompletedWithMessages" in e._response: pass else: raise e # TM1 takes one second to write to the message-log time.sleep(1) log_entry = self.tm1.server.get_last_process_message_from_messagelog( p.name) regex = re.compile('TM1ProcessError_.*.log') self.assertTrue(regex.search(log_entry)) # inject process that does nothing and runs successfull p = Process(name=self.process_name2, prolog_procedure="sText = 'text';") self.tm1.processes.create(p) self.tm1.processes.execute(p.name) # TM1 takes one second to write to the message-log time.sleep(1) log_entry = self.tm1.server.get_last_process_message_from_messagelog( p.name) regex = re.compile('TM1ProcessError_.*.log') self.assertFalse(regex.search(log_entry))
def test_execute_process_with_return_compile_error(self): process = Process(name=str(uuid.uuid4())) process.prolog_procedure = "sText = 'text';sText = 2;" success, status, error_log_file = self.tm1.processes.execute_process_with_return(process) self.assertFalse(success) self.assertEqual(status, "Aborted") self.assertIsNotNone(error_log_file)
def test_execute_process_with_return_with_process_quit(self): process = Process(name=str(uuid.uuid4())) process.prolog_procedure = "sText = 'Something'; ProcessQuit;" success, status, error_log_file = self.tm1.processes.execute_process_with_return(process) self.assertFalse(success) self.assertEqual(status, "QuitCalled") self.assertIsNone(error_log_file)
def test_execute_process_with_return_with_process_break(self): process = Process(name=str(uuid.uuid4())) process.prolog_procedure = "sText = 'Something'; ProcessBreak;" success, status, error_log_file = self.tm1.processes.execute_process_with_return(process) self.assertTrue(success) self.assertEqual(status, "CompletedSuccessfully") self.assertIsNone(error_log_file)
def test_execute_process_with_return_with_item_reject(self): process = Process(name=str(uuid.uuid4())) process.epilog_procedure = "ItemReject('Not Relevant');" success, status, error_log_file = self.tm1.processes.execute_process_with_return(process) self.assertFalse(success) self.assertEqual(status, "CompletedWithMessages") self.assertIsNotNone(error_log_file)
def test_execute_process_with_return_success(self): process = Process(name=str(uuid.uuid4())) process.prolog_procedure = "Sleep(100);" success, status, error_log_file = self.tm1.processes.execute_process_with_return(process) self.assertTrue(success) self.assertEqual(status, "CompletedSuccessfully") self.assertIsNone(error_log_file)
def setUpClass(cls): """ Establishes a connection to TM1 and creates TM! objects to use across all tests """ # Connection to TM1 cls.config = configparser.ConfigParser() cls.config.read(Path(__file__).parent.joinpath('config.ini')) cls.tm1 = TM1Service(**cls.config['tm1srv01']) # Namings cls.dimension_name1 = PREFIX + "Dimension1" cls.dimension_name2 = PREFIX + "Dimension2" cls.cube_name = PREFIX + "Cube1" cls.process_name1 = PREFIX + "Process1" cls.process_name2 = PREFIX + "Process2" # create a simple cube with dimensions to test transactionlog methods if not cls.tm1.dimensions.exists(cls.dimension_name1): d = Dimension(cls.dimension_name1) h = Hierarchy(cls.dimension_name1, cls.dimension_name1) h.add_element('Total Years', 'Consolidated') h.add_element('No Year', 'Numeric') for year in range(1989, 2040, 1): h.add_element(str(year), 'Numeric') h.add_edge('Total Years', str(year), 1) d.add_hierarchy(h) cls.tm1.dimensions.update_or_create(d) if not cls.tm1.dimensions.exists(cls.dimension_name2): d = Dimension(cls.dimension_name2) h = Hierarchy(cls.dimension_name2, cls.dimension_name2) h.add_element('Value', 'Numeric') d.add_hierarchy(h) cls.tm1.dimensions.update_or_create(d) if not cls.tm1.cubes.exists(cls.cube_name): cube = Cube(cls.cube_name, [cls.dimension_name1, cls.dimension_name2]) cls.tm1.cubes.update_or_create(cube) # inject process with ItemReject cls.process1 = Process(name=cls.process_name1, prolog_procedure="ItemReject('TM1py Tests');") cls.tm1.processes.update_or_create(cls.process1) # inject process that does nothing and runs successful cls.process2 = Process(name=cls.process_name2, prolog_procedure="sText = 'text';") cls.tm1.processes.update_or_create(cls.process2) cls.tm1.server.activate_audit_log()
def test_execute_with_return_compile_error(self): process = Process(name=str(uuid.uuid4())) process.prolog_procedure = "sText = 'text';sText = 2;" if not self.tm1.processes.exists(process.name): self.tm1.processes.create(process) # with parameters success, status, error_log_file = self.tm1.processes.execute_with_return(process_name=process.name) self.assertFalse(success) self.assertEqual(status, "Aborted") self.assertIsNotNone(error_log_file) self.tm1.processes.delete(process.name)
def setup_class(cls): cls.tm1 = TM1Service(**config['tm1srv01']) # chore properties cls.chore_name1 = 'TM1py_unittest_chore_' + str(uuid.uuid4()) cls.chore_name2 = 'TM1py_unittest_chore_' + str(uuid.uuid4()) cls.start_time = datetime.now() cls.frequency_days = int(random.uniform(0, 355)) cls.frequency_hours = int(random.uniform(0, 23)) cls.frequency_minutes = int(random.uniform(0, 59)) cls.frequency_seconds = int(random.uniform(0, 59)) cls.frequency = ChoreFrequency(days=cls.frequency_days, hours=cls.frequency_hours, minutes=cls.frequency_minutes, seconds=cls.frequency_seconds) cls.tasks = [ChoreTask(0, process_name1, parameters=[{'Name': 'pRegion', 'Value': 'UK'}]), ChoreTask(1, process_name1, parameters=[{'Name': 'pRegion', 'Value': 'FR'}]), ChoreTask(2, process_name1, parameters=[{'Name': 'pRegion', 'Value': 'CH'}])] p1 = Process(name=process_name1) p1.add_parameter('pRegion', 'pRegion (String)', value='US') if cls.tm1.processes.exists(p1.name): cls.tm1.processes.delete(p1.name) cls.tm1.processes.create(p1) p2 = Process(name=process_name2) p2.add_parameter('pRegion', 'pRegion (String)', value='UK') if cls.tm1.processes.exists(p2.name): cls.tm1.processes.delete(p2.name) cls.tm1.processes.create(p2)
def test_execute_with_return_with_process_quit(self): process = Process(name=str(uuid.uuid4())) process.prolog_procedure = "sText = 'Something'; ProcessQuit;" if not self.tm1.processes.exists(process.name): self.tm1.processes.create(process) # with parameters success, status, error_log_file = self.tm1.processes.execute_with_return( process_name=process.name) self.assertFalse(success) self.assertEqual(status, "QuitCalled") self.assertIsNone(error_log_file) self.tm1.processes.delete(process.name)
def test_compile_success(self): p_good = Process(name=str(uuid.uuid4()), prolog_procedure="nPro = DimSiz('}Processes');") self.tm1.processes.create(p_good) errors = self.tm1.processes.compile(p_good.name) self.assertTrue(len(errors) == 0) self.tm1.processes.delete(p_good.name)
def test_get_error_log_file_content(self): process = Process(name=str(uuid.uuid4())) process.epilog_procedure = "ItemReject('Not Relevant');" if not self.tm1.processes.exists(process.name): self.tm1.processes.create(process) # with parameters success, status, error_log_file = self.tm1.processes.execute_with_return(process_name=process.name) self.assertFalse(success) self.assertEqual(status, "CompletedWithMessages") self.assertIsNotNone(error_log_file) content = self.tm1.processes.get_error_log_file_content(file_name=error_log_file) self.assertIn("Not Relevant", content) self.tm1.processes.delete(process.name)
def test_compile_process_with_errors(self): p_bad = Process(name=str(uuid.uuid4()), prolog_procedure="nPro = DimSize('}Processes');") errors = self.tm1.processes.compile_process(p_bad) self.assertTrue(len(errors) == 1) self.assertIn("Variable \"dimsize\" is undefined", errors[0]["Message"])
def test2_compile_process(self): p_good = Process(name=str(uuid.uuid4()), prolog_procedure="nPro = DimSiz('}Processes');") p_bad = Process(name=str(uuid.uuid4()), prolog_procedure="nPro = DimSize('}Processes');") self.tm1.processes.create(p_good) self.tm1.processes.create(p_bad) errors = self.tm1.processes.compile(p_good.name) self.assertTrue(len(errors) == 0) errors = self.tm1.processes.compile(p_bad.name) self.assertTrue(len(errors) == 1) self.assertIn("Variable \"dimsize\" is undefined", errors[0]["Message"]) self.tm1.processes.delete(p_good.name) self.tm1.processes.delete(p_bad.name)
def setUpClass(cls): # Namings cls.dimension_name1 = PREFIX + "Dimension1" cls.dimension_name2 = PREFIX + "Dimension2" cls.cube_name = PREFIX + "Cube1" cls.process_name1 = PREFIX + "Process1" cls.process_name2 = PREFIX + "Process2" # Connect to TM1 cls.tm1 = TM1Service(**config['tm1srv01']) # create a simple cube with dimensions to test transactionlog methods if not cls.tm1.dimensions.exists(cls.dimension_name1): d = Dimension(cls.dimension_name1) h = Hierarchy(cls.dimension_name1, cls.dimension_name1) h.add_element('Total Years', 'Consolidated') h.add_element('No Year', 'Numeric') for year in range(1989, 2040, 1): h.add_element(str(year), 'Numeric') h.add_edge('Total Years', str(year), 1) d.add_hierarchy(h) cls.tm1.dimensions.create(d) if not cls.tm1.dimensions.exists(cls.dimension_name2): d = Dimension(cls.dimension_name2) h = Hierarchy(cls.dimension_name2, cls.dimension_name2) h.add_element('Value', 'Numeric') d.add_hierarchy(h) cls.tm1.dimensions.create(d) if not cls.tm1.cubes.exists(cls.cube_name): cube = Cube(cls.cube_name, [cls.dimension_name1, cls.dimension_name2]) cls.tm1.cubes.create(cube) # inject process with ItemReject cls.process1 = Process(name=cls.process_name1, prolog_procedure="ItemReject('TM1py Tests');") cls.tm1.processes.create(cls.process1) # inject process that does nothing and runs successfull cls.process2 = Process(name=cls.process_name2, prolog_procedure="sText = 'text';") cls.tm1.processes.create(cls.process2)
def setup_class(cls): p1 = Process(name=process_name1) p1.add_parameter('pRegion', 'pRegion (String)', value='US') if cls.tm1.processes.exists(p1.name): cls.tm1.processes.delete(p1.name) cls.tm1.processes.create(p1) p2 = Process(name=process_name2) p2.add_parameter('pRegion', 'pRegion (String)', value='UK') if cls.tm1.processes.exists(p2.name): cls.tm1.processes.delete(p2.name) cls.tm1.processes.create(p2)
def setUpClass(cls): """ Establishes a connection to TM1 and creates objects to use across all tests """ # Connection to TM1 cls.config = configparser.ConfigParser() cls.config.read(Path(__file__).parent.joinpath('config.ini')) cls.tm1 = TM1Service(**cls.config['tm1srv01']) # create processes p1 = Process(name=PROCESS_NAME1) p1.add_parameter('pRegion', 'pRegion (String)', value='US') if cls.tm1.processes.exists(p1.name): cls.tm1.processes.delete(p1.name) cls.tm1.processes.create(p1) p2 = Process(name=PROCESS_NAME2) p2.add_parameter('pRegion', 'pRegion (String)', value='UK') if cls.tm1.processes.exists(p2.name): cls.tm1.processes.delete(p2.name) cls.tm1.processes.create(p2) # chore properties cls.start_time = datetime.now() cls.frequency_days = int(random.uniform(0, 355)) cls.frequency_hours = int(random.uniform(0, 23)) cls.frequency_minutes = int(random.uniform(0, 59)) cls.frequency_seconds = int(random.uniform(0, 59)) cls.frequency = ChoreFrequency(days=cls.frequency_days, hours=cls.frequency_hours, minutes=cls.frequency_minutes, seconds=cls.frequency_seconds) cls.tasks = [ ChoreTask(0, PROCESS_NAME1, parameters=[{ 'Name': 'pRegion', 'Value': 'UK' }]), ChoreTask(1, PROCESS_NAME1, parameters=[{ 'Name': 'pRegion', 'Value': 'FR' }]), ChoreTask(2, PROCESS_NAME1, parameters=[{ 'Name': 'pRegion', 'Value': 'CH' }]) ]
def load_bedrock_from_github(bedrock_process_name): """ Load bedrock from GitHub as TM1py.Process instance :param bedrock_process_name: :return: """ import requests from TM1py.Objects import Process url = 'https://raw.githubusercontent.com/MariusWirtz/bedrock/master/json/{}.json'.format(bedrock_process_name) process_as_json = requests.get(url).text return Process.from_json(process_as_json)
def load_all_bedrocks_from_github(): """ Load all Bedrocks from GitHub as TM1py.Process instances :return: """ import requests from TM1py.Objects import Process # Connect to Bedrock github repo and load the names of all Bedrocks url = "https://api.github.com/repos/MariusWirtz/bedrock/contents/json?ref=master" raw_github_data = requests.get(url).json() all_bedrocks = [entry['name'] for entry in raw_github_data] # instantiate TM1py.Process instances from github-json content url_to_bedrock = 'https://raw.githubusercontent.com/MariusWirtz/bedrock/master/json/{}' return [Process.from_json(requests.get(url_to_bedrock.format(bedrock)).text) for bedrock in all_bedrocks]
def execute_ti_code(self, lines_prolog, lines_epilog=None): """ Execute lines of code on the TM1 Server :param lines_prolog: list - where each element is a valid statement of TI code. :param lines_epilog: list - where each element is a valid statement of TI code. """ process_name = '}' + 'TM1py' + str(uuid.uuid4()) p = Process(name=process_name, prolog_procedure=Process.auto_generated_string + '\r\n'.join(lines_prolog), epilog_procedure=Process.auto_generated_string + '\r\n'.join(lines_epilog) if lines_epilog else '') self.create(p) try: return self.execute(process_name) pass except TM1pyException as e: raise e finally: self.delete(process_name)
def setUpClass(cls): """ Establishes a connection to TM1 and creates objects to use across all tests """ # Connection to TM1 cls.config = configparser.ConfigParser() cls.config.read(Path(__file__).parent.joinpath('config.ini')) cls.tm1 = TM1Service(**cls.config['tm1srv01']) # create processes p1 = Process(name=cls.process_name1) p1.add_parameter('pRegion', 'pRegion (String)', value='US') if cls.tm1.processes.exists(p1.name): cls.tm1.processes.delete(p1.name) cls.tm1.processes.create(p1) p2 = Process(name=cls.process_name2) p2.add_parameter('pRegion', 'pRegion (String)', value='UK') if cls.tm1.processes.exists(p2.name): cls.tm1.processes.delete(p2.name) cls.tm1.processes.create(p2)
def get_all(self): """ Get a processes from TM1 Server :return: List, instances of the TM1py.Process """ request = "/api/v1/Processes?$select=*,UIData,VariablesUIData," \ "DataSource/dataSourceNameForServer," \ "DataSource/dataSourceNameForClient," \ "DataSource/asciiDecimalSeparator," \ "DataSource/asciiDelimiterChar," \ "DataSource/asciiDelimiterType," \ "DataSource/asciiHeaderRecords," \ "DataSource/asciiQuoteCharacter," \ "DataSource/asciiThousandSeparator," \ "DataSource/view," \ "DataSource/query," \ "DataSource/userName," \ "DataSource/password," \ "DataSource/usesUnicode," \ "DataSource/subset" response = self._rest.GET(request, "") response_as_dict = response.json() return [Process.from_dict(p) for p in response_as_dict['value']]
def get(self, name_process): """ Get a process from TM1 Server :param name_process: :return: Instance of the TM1py.Process """ request = "/api/v1/Processes('{}')?$select=*,UIData,VariablesUIData," \ "DataSource/dataSourceNameForServer," \ "DataSource/dataSourceNameForClient," \ "DataSource/asciiDecimalSeparator," \ "DataSource/asciiDelimiterChar," \ "DataSource/asciiDelimiterType," \ "DataSource/asciiHeaderRecords," \ "DataSource/asciiQuoteCharacter," \ "DataSource/asciiThousandSeparator," \ "DataSource/view," \ "DataSource/query," \ "DataSource/userName," \ "DataSource/password," \ "DataSource/usesUnicode," \ "DataSource/subset".format(name_process) response = self._rest.GET(request, "") return Process.from_dict(response.json())
""" Create a TI process in TM1 """ from TM1py.Objects import Process from TM1py.Services import TM1Service # connection to TM1 Server with TM1Service(address='localhost', port=12354, user='******', password='******', ssl=True) as tm1: process_name = 'TM1py process' # create new Process in python p_ascii = Process(name=process_name, datasource_type='ASCII', datasource_ascii_delimiter_char=',', datasource_data_source_name_for_server=r'C:\Data\file.csv', datasource_data_source_name_for_client=r'C:\Data\file.csv') # variables p_ascii.add_variable('v_1', 'Numeric') p_ascii.add_variable('v_2', 'Numeric') p_ascii.add_variable('v_3', 'Numeric') p_ascii.add_variable('v_4', 'Numeric') # parameters p_ascii.add_parameter(name='pCompanyCode', prompt='', value='DE04') # code p_ascii.prolog_procedure = "sText = 'IBM Cognos TM1';" # create process on TM1 Server tm1.processes.create(p_ascii)
class TestProcessMethods(unittest.TestCase): tm1 = TM1Service(address=address, port=port, user=user, password=pwd, ssl=ssl) random_string = str(uuid.uuid4()) # None process p_none = Process(name=process_prefix + '_none_' + random_string, datasource_type='None') # ACII process p_ascii = Process( name=process_prefix + '_ascii_' + random_string, datasource_type='ASCII', datasource_ascii_delimiter_type='Character', datasource_ascii_delimiter_char=',', datasource_ascii_header_records=2, datasource_ascii_quote_character='^', datasource_ascii_thousand_separator='~', prolog_procedure="sTestProlog = 'test prolog procedure'", metadata_procedure="sTestMeta = 'test metadata procedure'", data_procedure="sTestData = 'test data procedure'", epilog_procedure="sTestEpilog = 'test epilog procedure'", datasource_data_source_name_for_server=r'C:\Data\file.csv', datasource_data_source_name_for_client=r'C:\Data\file.csv') # Variables p_ascii.add_variable('v_1', 'Numeric') p_ascii.add_variable('v_2', 'Numeric') p_ascii.add_variable('v_3', 'Numeric') p_ascii.add_variable('v_4', 'Numeric') # Parameters p_ascii.add_parameter('p_Year', 'year?', '2016') # View process p_view = Process(name=process_prefix + '_view_' + random_string, datasource_type='TM1CubeView', datasource_view='view1', datasource_data_source_name_for_client='Plan_BudgetPlan', datasource_data_source_name_for_server='Plan_BudgetPlan') # ODBC process p_odbc = Process(name=process_prefix + '_odbc_' + random_string, datasource_type='ODBC', datasource_password='******', datasource_user_name='user') # Subset process subset_name = process_prefix + '_subset_' + random_string subset = Subset(dimension_name='plan_business_unit', subset_name=subset_name, elements=['10110', '10120', '10200', '10210']) tm1.subsets.create(subset, False) p_subset = Process( name=process_prefix + '_subset_' + random_string, datasource_type='TM1DimensionSubset', datasource_data_source_name_for_server=subset.dimension_name, datasource_subset=subset.name, metadata_procedure="sTest = 'abc';") # Create Process def test1_create_process(self): self.tm1.processes.create(self.p_none) self.tm1.processes.create(self.p_ascii) self.tm1.processes.create(self.p_view) self.tm1.processes.create(self.p_odbc) self.tm1.processes.create(self.p_subset) # Get Process def test2_get_process(self): p1 = self.tm1.processes.get(self.p_ascii.name) self.assertEqual(p1.body, self.p_ascii.body) p2 = self.tm1.processes.get(self.p_none.name) self.assertEqual(p2.body, self.p_none.body) p3 = self.tm1.processes.get(self.p_view.name) self.assertEqual(p3.body, self.p_view.body) p4 = self.tm1.processes.get(self.p_odbc.name) p4.datasource_password = None self.p_odbc.datasource_password = None self.assertEqual(p4.body, self.p_odbc.body) p5 = self.tm1.processes.get(self.p_subset.name) self.assertEqual(p5.body, self.p_subset.body) # Update process def test3_update_process(self): # get p = self.tm1.processes.get(self.p_ascii.name) # modify p.data_procedure = "SaveDataAll;" # update on Server self.tm1.processes.update(p) # get again p_ascii_updated = self.tm1.processes.get(p.name) # assert self.assertNotEqual(p_ascii_updated.data_procedure, self.p_ascii.data_procedure) # Delete process def test4_delete_process(self): self.tm1.processes.delete(self.p_none.name) self.tm1.processes.delete(self.p_ascii.name) self.tm1.processes.delete(self.p_view.name) self.tm1.processes.delete(self.p_odbc.name) self.tm1.processes.delete(self.p_subset.name) self.tm1.subsets.delete(self.subset.dimension_name, self.subset_name, False) def test5_logout(self): self.tm1.logout()
class TestProcessService(unittest.TestCase): tm1: TM1Service prefix = 'TM1py_Tests_' some_name = "some_name" p_none = Process(name=prefix + '_none_' + some_name, datasource_type='None') p_ascii = Process( name=prefix + '_ascii_' + some_name, datasource_type='ASCII', datasource_ascii_delimiter_type='Character', datasource_ascii_delimiter_char=',', datasource_ascii_header_records=2, datasource_ascii_quote_character='^', datasource_ascii_thousand_separator='~', prolog_procedure="sTestProlog = 'test prolog procedure'", metadata_procedure="sTestMeta = 'test metadata procedure'", data_procedure="sTestData = 'test data procedure'", epilog_procedure="sTestEpilog = 'test epilog procedure'", datasource_data_source_name_for_server=r'C:\Data\file.csv', datasource_data_source_name_for_client=r'C:\Data\file.csv') p_ascii.add_variable('v_1', 'Numeric') p_ascii.add_variable('v_2', 'Numeric') p_ascii.add_variable('v_3', 'Numeric') p_ascii.add_variable('v_4', 'Numeric') p_ascii.add_parameter('p_Year', 'year?', '2016') p_ascii.add_parameter('p_Number', 'number?', 2) p_view = Process(name=prefix + '_view_' + some_name, datasource_type='TM1CubeView', datasource_view='view1', datasource_data_source_name_for_client='Plan_BudgetPlan', datasource_data_source_name_for_server='Plan_BudgetPlan') p_odbc = Process(name=prefix + '_odbc_' + some_name, datasource_type='ODBC', datasource_password='******', datasource_user_name='user') p_debug = Process( name=prefix + "_debug", datasource_type="None", prolog_procedure= "sleep(1);\r\nsleep(1);\r\nsleep(1);\r\nsleep(1);\r\nsleep(1);\r\nsleep(1);\r\n" ) subset: Subset subset_name: str p_subset: Process @classmethod def setUpClass(cls): """ Establishes a connection to TM1 and creates TM! objects to use across all tests """ # Connection to TM1 cls.config = configparser.ConfigParser() cls.config.read(Path(__file__).parent.joinpath('config.ini')) cls.tm1 = TM1Service(**cls.config['tm1srv01']) cls.all_dimension_names = cls.tm1.dimensions.get_all_names() cls.random_dimension = cls.tm1.dimensions.get( random.choice(cls.all_dimension_names)) cls.random_dimension_all_elements = cls.random_dimension.default_hierarchy.elements cls.random_dimension_elements = [ element for element in cls.random_dimension_all_elements ][0:2] # Subset process cls.subset_name = cls.prefix + '_subset_' + cls.some_name cls.subset = Subset(dimension_name=cls.random_dimension.name, subset_name=cls.subset_name, elements=cls.random_dimension_elements) cls.tm1.dimensions.subsets.update_or_create(cls.subset, False) cls.p_subset = Process( name=cls.prefix + '_subset_' + cls.some_name, datasource_type='TM1DimensionSubset', datasource_data_source_name_for_server=cls.subset.dimension_name, datasource_subset=cls.subset.name, metadata_procedure="sTest = 'abc';") with open( Path(__file__).parent.joinpath('resources', 'Bedrock.Server.Wait.json'), 'r') as file: cls.p_bedrock_server_wait = Process.from_json(file.read()) @classmethod def setUp(cls): cls.tm1.processes.update_or_create(cls.p_none) cls.tm1.processes.update_or_create(cls.p_ascii) cls.tm1.processes.update_or_create(cls.p_view) cls.tm1.processes.update_or_create(cls.p_odbc) cls.tm1.processes.update_or_create(cls.p_subset) cls.tm1.processes.update_or_create(cls.p_debug) @classmethod def tearDown(cls): cls.tm1.processes.delete(cls.p_none.name) cls.tm1.processes.delete(cls.p_ascii.name) cls.tm1.processes.delete(cls.p_view.name) cls.tm1.processes.delete(cls.p_odbc.name) cls.tm1.processes.delete(cls.p_subset.name) cls.tm1.processes.update_or_create(cls.p_debug) def test_update_or_create(self): if self.tm1.processes.exists(self.p_bedrock_server_wait.name): self.tm1.processes.delete(self.p_bedrock_server_wait.name) self.assertFalse( self.tm1.processes.exists(self.p_bedrock_server_wait.name)) self.tm1.processes.update_or_create(self.p_bedrock_server_wait) self.assertTrue( self.tm1.processes.exists(self.p_bedrock_server_wait.name)) temp_prolog = self.p_bedrock_server_wait.prolog_procedure self.p_bedrock_server_wait.prolog_procedure += "sleep(10);" self.tm1.processes.update_or_create(self.p_bedrock_server_wait) self.assertTrue( self.tm1.processes.exists(self.p_bedrock_server_wait.name)) self.p_bedrock_server_wait.prolog_procedure = temp_prolog self.tm1.processes.delete(self.p_bedrock_server_wait.name) def test_execute_process(self): if not self.tm1.processes.exists(self.p_bedrock_server_wait.name): self.tm1.processes.create(self.p_bedrock_server_wait) # with parameters argument start_time = time.time() self.tm1.processes.execute( self.p_bedrock_server_wait.name, parameters={"Parameters": [{ "Name": "pWaitSec", "Value": "3" }]}) elapsed_time = time.time() - start_time self.assertGreater(elapsed_time, 3) # with kwargs start_time = time.time() self.tm1.processes.execute(self.p_bedrock_server_wait.name, pWaitSec="1") elapsed_time = time.time() - start_time self.assertGreater(elapsed_time, 1) # without arguments self.tm1.processes.execute(self.p_bedrock_server_wait.name) @skip_if_insufficient_version(version="11.4") def test_execute_with_return_success(self): process = self.p_bedrock_server_wait if not self.tm1.processes.exists(process.name): self.tm1.processes.create(process) # with parameters success, status, error_log_file = self.tm1.processes.execute_with_return( process_name=process.name, pWaitSec=2) self.assertTrue(success) self.assertEqual(status, "CompletedSuccessfully") self.assertIsNone(error_log_file) # without parameters success, status, error_log_file = self.tm1.processes.execute_with_return( process_name=process.name) self.assertTrue(success) self.assertEqual(status, "CompletedSuccessfully") self.assertIsNone(error_log_file) def test_execute_with_return_compile_error(self): process = Process(name=str(uuid.uuid4())) process.prolog_procedure = "sText = 'text';sText = 2;" if not self.tm1.processes.exists(process.name): self.tm1.processes.create(process) # with parameters success, status, error_log_file = self.tm1.processes.execute_with_return( process_name=process.name) self.assertFalse(success) self.assertEqual(status, "Aborted") self.assertIsNotNone(error_log_file) self.tm1.processes.delete(process.name) def test_execute_with_return_with_item_reject(self): process = Process(name=str(uuid.uuid4())) process.epilog_procedure = "ItemReject('Not Relevant');" if not self.tm1.processes.exists(process.name): self.tm1.processes.create(process) # with parameters success, status, error_log_file = self.tm1.processes.execute_with_return( process_name=process.name) self.assertFalse(success) self.assertEqual(status, "CompletedWithMessages") self.assertIsNotNone(error_log_file) self.tm1.processes.delete(process.name) @skip_if_insufficient_version(version="11.4") def test_execute_with_return_with_process_break(self): process = Process(name=str(uuid.uuid4())) process.prolog_procedure = "sText = 'Something'; ProcessBreak;" if not self.tm1.processes.exists(process.name): self.tm1.processes.create(process) # with parameters success, status, error_log_file = self.tm1.processes.execute_with_return( process_name=process.name) self.assertTrue(success) self.assertEqual(status, "CompletedSuccessfully") self.assertIsNone(error_log_file) self.tm1.processes.delete(process.name) @skip_if_insufficient_version(version="11.4") def test_execute_with_return_with_process_quit(self): process = Process(name=str(uuid.uuid4())) process.prolog_procedure = "sText = 'Something'; ProcessQuit;" if not self.tm1.processes.exists(process.name): self.tm1.processes.create(process) # with parameters success, status, error_log_file = self.tm1.processes.execute_with_return( process_name=process.name) self.assertFalse(success) self.assertEqual(status, "QuitCalled") self.assertIsNone(error_log_file) self.tm1.processes.delete(process.name) def test_compile_success(self): p_good = Process(name=str(uuid.uuid4()), prolog_procedure="nPro = DimSiz('}Processes');") self.tm1.processes.create(p_good) errors = self.tm1.processes.compile(p_good.name) self.assertTrue(len(errors) == 0) self.tm1.processes.delete(p_good.name) def test_compile_with_errors(self): p_bad = Process(name=str(uuid.uuid4()), prolog_procedure="nPro = DimSize('}Processes');") self.tm1.processes.create(p_bad) errors = self.tm1.processes.compile(p_bad.name) self.assertTrue(len(errors) == 1) self.assertIn("Variable \"dimsize\" is undefined", errors[0]["Message"]) self.tm1.processes.delete(p_bad.name) @skip_if_insufficient_version(version="11.4") def test_execute_process_with_return_success(self): process = Process(name=str(uuid.uuid4())) process.prolog_procedure = "Sleep(100);" success, status, error_log_file = self.tm1.processes.execute_process_with_return( process) self.assertTrue(success) self.assertEqual(status, "CompletedSuccessfully") self.assertIsNone(error_log_file) def test_execute_process_with_return_compile_error(self): process = Process(name=str(uuid.uuid4())) process.prolog_procedure = "sText = 'text';sText = 2;" success, status, error_log_file = self.tm1.processes.execute_process_with_return( process) self.assertFalse(success) self.assertEqual(status, "Aborted") self.assertIsNotNone(error_log_file) def test_execute_process_with_return_with_item_reject(self): process = Process(name=str(uuid.uuid4())) process.epilog_procedure = "ItemReject('Not Relevant');" success, status, error_log_file = self.tm1.processes.execute_process_with_return( process) self.assertFalse(success) self.assertEqual(status, "CompletedWithMessages") self.assertIsNotNone(error_log_file) @skip_if_insufficient_version(version="11.4") def test_execute_process_with_return_with_process_break(self): process = Process(name=str(uuid.uuid4())) process.prolog_procedure = "sText = 'Something'; ProcessBreak;" success, status, error_log_file = self.tm1.processes.execute_process_with_return( process) self.assertTrue(success) self.assertEqual(status, "CompletedSuccessfully") self.assertIsNone(error_log_file) @skip_if_insufficient_version(version="11.4") def test_execute_process_with_return_with_process_quit(self): process = Process(name=str(uuid.uuid4())) process.prolog_procedure = "sText = 'Something'; ProcessQuit;" success, status, error_log_file = self.tm1.processes.execute_process_with_return( process) self.assertFalse(success) self.assertEqual(status, "QuitCalled") self.assertIsNone(error_log_file) def test_compile_process_success(self): p_good = Process(name=str(uuid.uuid4()), prolog_procedure="nPro = DimSiz('}Processes');") errors = self.tm1.processes.compile_process(p_good) self.assertTrue(len(errors) == 0) def test_compile_process_with_errors(self): p_bad = Process(name=str(uuid.uuid4()), prolog_procedure="nPro = DimSize('}Processes');") errors = self.tm1.processes.compile_process(p_bad) self.assertTrue(len(errors) == 1) self.assertIn("Variable \"dimsize\" is undefined", errors[0]["Message"]) def test_get_process(self): p_ascii_orig = copy.deepcopy(self.p_ascii) p_none_orig = copy.deepcopy(self.p_none) p_view_orig = copy.deepcopy(self.p_view) p_subset_orig = copy.deepcopy(self.p_subset) p_odbc_orig = copy.deepcopy(self.p_odbc) p1 = self.tm1.processes.get(p_ascii_orig.name) self.assertEqual(p1.body, p_ascii_orig.body) p2 = self.tm1.processes.get(p_none_orig.name) self.assertEqual(p2.body, p_none_orig.body) p3 = self.tm1.processes.get(p_view_orig.name) self.assertEqual(p3.body, p_view_orig.body) p4 = self.tm1.processes.get(p_odbc_orig.name) p4.datasource_password = None p_odbc_orig.datasource_password = None self.assertEqual(p4.body, p_odbc_orig.body) p5 = self.tm1.processes.get(p_subset_orig.name) self.assertEqual(p5.body, p_subset_orig.body) def test_update_process(self): # get p = self.tm1.processes.get(self.p_ascii.name) # modify p.data_procedure = "SaveDataAll;" # update on Server self.tm1.processes.update(p) # get again p_ascii_updated = self.tm1.processes.get(p.name) # assert self.assertNotEqual(p_ascii_updated.data_procedure, self.p_ascii.data_procedure) def test_get_error_log_file_content(self): process = Process(name=str(uuid.uuid4())) process.epilog_procedure = "ItemReject('Not Relevant');" if not self.tm1.processes.exists(process.name): self.tm1.processes.create(process) # with parameters success, status, error_log_file = self.tm1.processes.execute_with_return( process_name=process.name) self.assertFalse(success) self.assertEqual(status, "CompletedWithMessages") self.assertIsNotNone(error_log_file) content = self.tm1.processes.get_error_log_file_content( file_name=error_log_file) self.assertIn("Not Relevant", content) self.tm1.processes.delete(process.name) def test_get_last_message_from_processerrorlog(self): process = Process(name=str(uuid.uuid4())) process.epilog_procedure = "ItemReject('Not Relevant');" if not self.tm1.processes.exists(process.name): self.tm1.processes.create(process) # with parameters success, status, error_log_file = self.tm1.processes.execute_with_return( process_name=process.name) self.assertFalse(success) self.assertEqual(status, "CompletedWithMessages") self.assertIsNotNone(error_log_file) content = self.tm1.processes.get_last_message_from_processerrorlog( process_name=process.name) self.assertIn("Not Relevant", content) self.tm1.processes.delete(process.name) def test_delete_process(self): process = self.p_bedrock_server_wait process.name = str(uuid.uuid4()) if not self.tm1.processes.exists(process.name): self.tm1.processes.create(process) self.tm1.processes.delete(process.name) def test_search_string_in_name_no_match_startswith(self): process_names = self.tm1.processes.search_string_in_name( name_startswith="NotAProcessName") self.assertEqual([], process_names) def test_search_string_in_name_no_match_contains(self): process_names = self.tm1.processes.search_string_in_name( name_contains="NotAProcessName") self.assertEqual([], process_names) def test_search_string_in_name_startswith_happy_case(self): process_names = self.tm1.processes.search_string_in_name( name_startswith=self.p_ascii.name) self.assertEqual([self.p_ascii.name], process_names) def test_search_string_in_name_contains_happy_case(self): process_names = self.tm1.processes.search_string_in_name( name_contains=self.p_ascii.name) self.assertEqual([self.p_ascii.name], process_names) def test_search_string_in_name_contains_multiple(self): process_names = self.tm1.processes.search_string_in_name( name_contains=self.p_ascii.name.split("_")) self.assertEqual([self.p_ascii.name], process_names) def test_search_string_in_code(self): process_names = self.tm1.processes.search_string_in_code( "sTestProlog = 'test prolog procedure'") self.assertEqual([self.p_ascii.name], process_names) def test_search_string_in_code_space_insensitive(self): process_names = self.tm1.processes.search_string_in_code( "sTestProlog = 'test PROLOG procedure'") self.assertEqual([self.p_ascii.name], process_names) def test_get_all_names(self): self.assertNotEqual( self.tm1.processes.get_all_names(), self.tm1.processes.get_all_names(skip_control_processes=True)) self.assertNotEqual( '}', self.tm1.processes.get_all_names( skip_control_processes=True)[-1][0][0]) self.assertEqual('}', self.tm1.processes.get_all_names()[-1][0][0]) self.assertNotEqual( self.tm1.processes.get_all(), self.tm1.processes.get_all(skip_control_processes=True)) def test_ti_formula(self): result = self.tm1.processes.evaluate_ti_expression("2+2") self.assertEqual(4, int(result)) def test_ti_formula_no_code(self): with self.assertRaises(ValueError): result = self.tm1.processes.evaluate_ti_expression("") def test_debug_add_breakpoint(self): line_number = 4 result = self.tm1.processes.debug_process(self.p_debug.name) debug_id = result['ID'] time.sleep(0.1) break_point = ProcessDebugBreakpoint( breakpoint_id=1, breakpoint_type=BreakPointType. PROCESS_DEBUG_CONTEXT_LINE_BREAK_POINT, process_name=self.p_debug.name, procedure="Prolog", hit_mode=HitMode.BREAK_ALWAYS, line_number=line_number) self.tm1.processes.debug_add_breakpoint(debug_id, break_point) time.sleep(0.1) result = self.tm1.processes.debug_continue(debug_id=debug_id) self.assertEqual(line_number, result['CallStack'][0]['LineNumber']) time.sleep(0.1) result = self.tm1.processes.debug_step_out(debug_id=debug_id) self.assertEqual(1, len(result['Breakpoints'])) self.assertEqual(result["Status"], "Complete") def test_debug_remove_breakpoint(self): result = self.tm1.processes.debug_process(self.p_debug.name) debug_id = result['ID'] time.sleep(0.1) break_point = ProcessDebugBreakpoint( breakpoint_id=1, breakpoint_type=BreakPointType. PROCESS_DEBUG_CONTEXT_LINE_BREAK_POINT, process_name=self.p_debug.name, procedure="Prolog", hit_mode=HitMode.BREAK_ALWAYS, line_number=4) self.tm1.processes.debug_add_breakpoint(debug_id, break_point) time.sleep(0.1) break_point = ProcessDebugBreakpoint( breakpoint_id=2, breakpoint_type=BreakPointType. PROCESS_DEBUG_CONTEXT_LINE_BREAK_POINT, process_name=self.p_debug.name, procedure="Prolog", hit_mode=HitMode.BREAK_ALWAYS, line_number=5) self.tm1.processes.debug_add_breakpoint(debug_id, break_point) time.sleep(0.1) result = self.tm1.processes.debug_step_out(debug_id=debug_id) self.assertEqual(4, result['CallStack'][0]['LineNumber']) self.assertEqual(2, len(result['Breakpoints'])) time.sleep(0.1) self.tm1.processes.debug_remove_breakpoint(debug_id, breakpoint_id=2) time.sleep(0.1) result = self.tm1.processes.debug_step_out(debug_id=debug_id) self.assertEqual(1, len(result['Breakpoints'])) self.assertEqual(result["Status"], "Complete") @classmethod def tearDownClass(cls): cls.tm1.dimensions.subsets.delete( dimension_name=cls.subset.dimension_name, subset_name=cls.subset_name, private=False) cls.tm1.logout()
def setUpClass(cls): # Namings cls.expand_process_name = str(uuid.uuid4()) cls.expand_process_name_obf = str(uuid.uuid4()) cls.process_name = str(uuid.uuid4()) cls.process_name_obf = str(uuid.uuid4()) cls.dimension_name = str(uuid.uuid4()) cls.dimension_name_cloned = str(uuid.uuid4()) cls.cube_name = str(uuid.uuid4()) cls.cube_name_cloned = str(uuid.uuid4()) # Connect to TM1 cls.tm1 = TM1Service(**config['tm1srv01']) # create process prolog = "\r\nSaveDataAll;\r\nsText='abcABC';\r\n" epilog = "SaveDataAll;" cls.process = Process( name=cls.process_name, prolog_procedure=prolog, epilog_procedure=epilog) # create process with expand in TM1 if cls.tm1.processes.exists(cls.process.name): cls.tm1.processes.delete(cls.process.name) cls.tm1.processes.create(cls.process) # create process with expand prolog = "\r\nnRevenue = 20;\r\nsRevenue = EXPAND('%nrevenue%');\r\nIF(sRevenue @ <> '20.000');\r\n" \ "ProcessBreak;\r\nENDIF;" cls.expand_process = Process( name=cls.expand_process_name, prolog_procedure=prolog) # create process with expand in TM1 if cls.tm1.processes.exists(cls.expand_process.name): cls.tm1.processes.delete(cls.expand_process.name) cls.tm1.processes.create(cls.expand_process) # create dimension that we clone through obfuscated bedrock as part of the test if not cls.tm1.dimensions.exists(cls.dimension_name): d = Dimension(cls.dimension_name) h = Hierarchy(cls.dimension_name, cls.dimension_name) h.add_element('Total Years', 'Consolidated') h.add_element('No Year', 'Numeric') for year in range(1989, 2040, 1): h.add_element(str(year), 'Numeric') h.add_edge('Total Years', str(year), 1) d.add_hierarchy(h) cls.tm1.dimensions.create(d) # Create 2 Attributes through TI ti_statements = ["AttrInsert('{}','','Previous Year', 'S')".format(cls.dimension_name), "AttrInsert('{}','','Next Year', 'S');".format(cls.dimension_name)] ti = ';'.join(ti_statements) cls.tm1.processes.execute_ti_code(lines_prolog=ti) # create }ElementAttribute values cellset = {} for year in range(1989, 2040, 1): cellset[(str(year), 'Previous Year')] = year - 1 cellset[(str(year), 'Next Year')] = year + 1 cls.tm1.cubes.cells.write_values("}ElementAttributes_" + cls.dimension_name, cellset) # create a simple cube to be cloned through bedrock if not cls.tm1.cubes.exists(cls.cube_name): cube = Cube(cls.cube_name, ["}Dimensions", "}Cubes"], "[]=S:'TM1py';") cls.tm1.cubes.create(cube) # create bedrocks if they doesn't exist for bedrock in ("Bedrock.Dim.Clone", "Bedrock.Cube.Clone"): if not cls.tm1.processes.exists(bedrock): with open(os.path.join("resources", bedrock + ".json"), "r") as file: process = Process.from_json(file.read()) cls.tm1.processes.create(process)
def setUpClass(cls): """ Establishes a connection to TM1 and creates TM! objects to use across all tests """ # Connection to TM1 cls.config = configparser.ConfigParser() cls.config.read(Path(__file__).parent.joinpath('config.ini')) cls.tm1 = TM1Service(**cls.config['tm1srv01']) cls.some_name = "some_name" cls.all_dimension_names = cls.tm1.dimensions.get_all_names() cls.random_dimension = cls.tm1.dimensions.get( random.choice(cls.all_dimension_names)) cls.random_dimension_all_elements = cls.random_dimension.default_hierarchy.elements cls.random_dimension_elements = [ element for element in cls.random_dimension_all_elements ][0:2] # None process cls.p_none = Process(name=PROCESS_PREFIX + '_none_' + cls.some_name, datasource_type='None') # ACII process cls.p_ascii = Process( name=PROCESS_PREFIX + '_ascii_' + cls.some_name, datasource_type='ASCII', datasource_ascii_delimiter_type='Character', datasource_ascii_delimiter_char=',', datasource_ascii_header_records=2, datasource_ascii_quote_character='^', datasource_ascii_thousand_separator='~', prolog_procedure="sTestProlog = 'test prolog procedure'", metadata_procedure="sTestMeta = 'test metadata procedure'", data_procedure="sTestData = 'test data procedure'", epilog_procedure="sTestEpilog = 'test epilog procedure'", datasource_data_source_name_for_server=r'C:\Data\file.csv', datasource_data_source_name_for_client=r'C:\Data\file.csv') # Variables cls.p_ascii.add_variable('v_1', 'Numeric') cls.p_ascii.add_variable('v_2', 'Numeric') cls.p_ascii.add_variable('v_3', 'Numeric') cls.p_ascii.add_variable('v_4', 'Numeric') # Parameters cls.p_ascii.add_parameter('p_Year', 'year?', '2016') cls.p_ascii.add_parameter('p_Number', 'number?', 2) # View process cls.p_view = Process( name=PROCESS_PREFIX + '_view_' + cls.some_name, datasource_type='TM1CubeView', datasource_view='view1', datasource_data_source_name_for_client='Plan_BudgetPlan', datasource_data_source_name_for_server='Plan_BudgetPlan') # ODBC process cls.p_odbc = Process(name=PROCESS_PREFIX + '_odbc_' + cls.some_name, datasource_type='ODBC', datasource_password='******', datasource_user_name='user') # Subset process cls.subset_name = PROCESS_PREFIX + '_subset_' + cls.some_name cls.subset = Subset(dimension_name=cls.random_dimension.name, subset_name=cls.subset_name, elements=cls.random_dimension_elements) cls.tm1.dimensions.subsets.create(cls.subset, False) cls.p_subset = Process( name=PROCESS_PREFIX + '_subset_' + cls.some_name, datasource_type='TM1DimensionSubset', datasource_data_source_name_for_server=cls.subset.dimension_name, datasource_subset=cls.subset.name, metadata_procedure="sTest = 'abc';") with open( Path(__file__).parent.joinpath('resources', 'Bedrock.Server.Wait.json'), 'r') as file: cls.p_bedrock_server_wait = Process.from_json(file.read())