def test_createdir_EAbuffer(self): try: print "--------------------------------------" print "TC 016: Create a dir with EA buffer. Verify that the EA's were applied to the dir" expected_status = 'STATUS_SUCCESS' print "Expected status : ",expected_status print "Creating a session and tree connect." conv_obj=utils.Convenience() chan, tree = self.tree_connect() print "Session and tree connect successful." print "trying to create a directory" create_tmp,create_resp = conv_obj.create(chan,tree,'CreateDir10', access=pike.smb2.FILE_READ_EA | pike.smb2.FILE_READ_ATTRIBUTES, name_offset = None, name_length = None, options=pike.smb2.FILE_DIRECTORY_FILE, extended_attr={"Author":"Prayas"}) file = create_tmp.result() print "Directory create successful with EA buffer set" print "Querying the file and checking EA size value" info = chan.query_file_info(file,pike.smb2.FILE_ALL_INFORMATION) ea_size = info.ea_information.ea_size print "The ea size of file is :",ea_size if isinstance(file,pike.model.Open): actual_status = "STATUS_SUCCESS" except Exception as e: actual_status = str(e) print "Actual status:",actual_status print "Matching the actual_status and expected_status" self.assertRegexpMatches(actual_status,expected_status) print "TC 016 has passed."
def test_03_flush_with_invalid_structure_size(self): try: print "\n--------------------Flush_TC 03 --------------------" print "Verify SMB2_FLUSH with invalid structure size." expected_status = 'STATUS_INVALID_PARAMETER' print "Expected Status: ",expected_status print "Creating session and tree connect..." chan, tree = self.tree_connect() print "Session setup and Tree connect is successful." print "Create a file Flush3.txt for testing flush request:" file_handle = chan.create(tree, "Flush3.txt", disposition=pike.smb2.FILE_OPEN_IF).result() print "File created." print "Sending Flush request..." conv_obj=utils.Convenience() flush_packet = conv_obj.flush(chan,tree,structure_size=20,file_id = file_handle.file_id) res = conv_obj.transceive(chan,flush_packet) print "Flush request is successful." print "Close the file handle:" chan.close(file_handle) print "File handle closed." actual_status = str(res[0].status) except Exception as e: actual_status = str(e) print "Actual status: ",actual_status self.assertIn(expected_status,actual_status,"\nTC 03 failed.") print "TC 03 Passed"
def test_createdir_writeattr(self): try: print "--------------------------------------------------" print "TC 004 -Set this flag(FILE_WRITE_ATTRIBUTES) only and read attributes of the directory" expected_status = "STATUS_ACCESS_DENIED" print "Expected status:",expected_status print "Creating a session and tree connect." chan, tree = self.tree_connect() conv_obj = utils.Convenience() print "Session and tree connect successful." print "Creating a directory." file_handle = chan.create(tree,'CreateDir004', access=pike.smb2.FILE_WRITE_ATTRIBUTES,options=pike.smb2.FILE_DIRECTORY_FILE,disposition=pike.smb2.FILE_CREATE).result() print "Directory created successfully." print "Querying the directory to read the attributes" query_packet = conv_obj.query_file_info(chan, file_handle, pike.smb2.FILE_ALL_INFORMATION) res = conv_obj.transceive(chan, query_packet) info = res[0] print "Query is successful" print "Close the file handle" chan.close(file_handle) print "File handle closed successfully" actual_status = str(info.status) except Exception as e: actual_status = str(e) print "Actual status:",actual_status print "Matching the actual_status and expected_status" self.assertRegexpMatches(actual_status,expected_status) print "TC 004 has passed."
def test_02_flush_for_STATUS_FILE_CLOSED(self): try: print "\n--------------------Flush_TC 02 --------------------" print "Close create file handle and verify SMB2_FLUSH response." expected_status = 'STATUS_FILE_CLOSED' print "Expected Status: ",expected_status print "Creating session and tree connect..." chan, tree = self.tree_connect() print "Session setup and Tree connect is successful." print "Create a file Flush2.txt for testing flush request:" file_handle = chan.create(tree, "Flush2.txt", disposition=pike.smb2.FILE_OPEN_IF).result() print "File created." print "Close the file handle:" chan.close(file_handle) print "File handle closed." print "Sending Flush request..." conv_obj=utils.Convenience() flush_packet = conv_obj.flush(chan,tree,file_id = file_handle.file_id,structure_size=24) res = conv_obj.transceive(chan,flush_packet) print "Flush request is successful." chan.close(file_handle) actual_status = str(res[0].status) except Exception as e: actual_status = str(e) print "Actual status: ",actual_status self.assertIn(expected_status,actual_status,"\nTC 02 failed.") print "TC 02 Passed"
def test_13_flush_STATUS_ACCESS_DENIED_for_FILE_WRITE_ATTRIBUTES(self): try: print "\n--------------------Flush_TC 13 --------------------" print "Verify SMB2_FLUSH when create desired access is FILE_WRITE_ATTRIBUTES." expected_status = 'STATUS_ACCESS_DENIED' print "Expected Status: ",expected_status print "Creating session and tree connect..." chan, tree = self.tree_connect() print "Session setup and Tree connect is successful." print "Create a file Flush13.txt for testing flush request:" file_handle = chan.create(tree, "Flush13.txt", access = pike.smb2.FILE_WRITE_ATTRIBUTES,disposition=pike.smb2.FILE_OPEN_IF).result() print "File created." print "Sending Flush request..." conv_obj=utils.Convenience() flush_packet = conv_obj.flush(chan,tree,file_id = file_handle.file_id,structure_size=24) res = conv_obj.transceive(chan,flush_packet) print "Flush request is successful." print "Close the file handle:" chan.close(file_handle) print "File handle closed." actual_status = str(res[0].status) except Exception as e: actual_status = str(e) print "Actual status: ",actual_status self.assertIn(expected_status,actual_status,"\nTC 13 failed.") print "TC 13 Passed"
def test_12_flush_for_WRITE_DATA(self): try: print "\n--------------------Flush_TC 12 --------------------" print "Verify SMB2_FLUSH when create desired access is FILE_WRITE_DATA." buffer = "testing123" expected_status = "STATUS_SUCCESS" print "Expected Status: ",expected_status print "Creating session and tree connect..." chan, tree = self.tree_connect() print "Session setup and Tree connect is successful." print "Create a file Flush12.txt for testing flush request:" file_handle = chan.create(tree, "Flush12.txt", access = pike.smb2.FILE_WRITE_DATA,disposition=pike.smb2.FILE_OPEN_IF).result() print "File created." print "Sending Write request..." bytes_written = chan.write(file_handle, 0, buffer) self.assertEqual(bytes_written, len(buffer)) print "Write request completed." print "Sending Flush request..." conv_obj=utils.Convenience() flush_packet = conv_obj.flush(chan,tree,file_id = file_handle.file_id,structure_size=24) res = conv_obj.transceive(chan,flush_packet) print "Flush request is successful." print "Close the file handle:" chan.close(file_handle) print "File handle closed." actual_status = str(res[0].status) except Exception as e: actual_status = str(e) print "Actual status: ",actual_status self.assertIn(expected_status,actual_status,"\nTC 12 failed.") print "TC 12 Passed"
def test_04_echo_with_valid_reserved_value(self): try: print "\n--------------------ECHO_TC 04 --------------------" print "Test case to verify echo request with valid reserved value." expected_status = 'STATUS_SUCCESS' print "Expected status: ",expected_status print "Sending Negotiate request..." conn = pike.model.Client().connect(self.server, self.port).negotiate() print "Negotiate successful." print "Sending Session setup request..." chan = conn.session_setup(self.creds) print "Session setup successful." print "Sending Echo request..." conv_obj=utils.Convenience() echo_packet = conv_obj.echo(chan,reserved=0) res = conv_obj.transceive(chan,echo_packet) print "Echo request is successfully processed." actual_status = str(res[0].status) except Exception as e: actual_status = str(e) print "Actual status: ",actual_status self.assertIn(expected_status,actual_status,"\nTC 04 failed.") print "TC 04 Passed"
def test_02_echo_with_invalid_struct_size(self): try: print "\n--------------------ECHO_TC 02 --------------------" print "Test case to verify echo request with invalid structure size." expected_status = 'STATUS_INVALID_PARAMETER' print "Expected status: ",expected_status print "Sending Negotiate request..." conn = pike.model.Client().connect(self.server, self.port).negotiate() print "Negotiate successful." print "Sending Session setup request..." chan = conn.session_setup(self.creds) print "Session setup successful." print "Sending Echo request..." conv_obj=utils.Convenience() echo_packet = conv_obj.echo(chan,structure_size=5) res = conv_obj.transceive(chan,echo_packet) print "Echo request is successfully processed." actual_status = str(res[0].status) except Exception as e: actual_status = str(e) print "Actual status: ",actual_status self.assertIn(expected_status,actual_status,"\nTC 02 failed.") print "TC 02 Passed"
def test_opendir(self): file = '' conv_obj = utils.Convenience() conn = pike.model.Client().connect(self.server, self.port).negotiate() chan = conn.session_setup(self.creds) tree = ET.parse("../test/Create_Open_Directory_Testbed.xml") for tc in tree.getiterator('TC'): for tags in (tc): for cmd in (tags): if cmd.tag == "TreeConnectRequest": tree_conn = '' smb_res = '' structure_size = TreeConnectRequest(cmd).StructureSize reserved = TreeConnectRequest(cmd).Reserved pathoffset = TreeConnectRequest(cmd).PathOffset pathlength = TreeConnectRequest(cmd).PathLength path = TreeConnectRequest(cmd).Buffer Tree_connect_list = [] if structure_size == ' ': structure_size = 9 Tree_connect_list.append(structure_size) else: Tree_connect_list.append(structure_size) if reserved == ' ': reserved = 0 Tree_connect_list.append(reserved) else: Tree_connect_list.append(reserved) if pathoffset == ' ': pathoffset = 72 Tree_connect_list.append(pathoffset) else: Tree_connect_list.append(pathoffset) if pathlength == ' ': pathlength = 0 Tree_connect_list.append(pathlength) else: Tree_connect_list.append(pathlength) Tree_connect_list = map(int, Tree_connect_list) if path != ' ': if isinstance(path, unicode): Tree_connect_list.append(path) else: Tree_connect_list.append(path) else: path = self.share Tree_connect_list.append(path) try: treeconnectpacket = conv_obj.tree_connect( chan, self.server, *Tree_connect_list) smb_res = conv_obj.transceive( chan, treeconnectpacket)[0] tree_conn = pike.model.Tree( chan.session, path, smb_res) except Exception as e: pass elif cmd.tag == "CreateContextRequest": cc_max_access = None if CreateContextRequest( cmd).CreateContextMaximalAccess is None else eval( CreateContextRequest( cmd).CreateContextMaximalAccess) cc_ext_attr = {} if CreateContextRequest( cmd ).CreateContextExtendedAttribute is None else eval( CreateContextRequest( cmd).CreateContextExtendedAttribute) cc_sd_attr = {} if CreateContextRequest( cmd ).CreateContextSecurityDescriptor is None else eval( CreateContextRequest( cmd).CreateContextSecurityDescriptor) cc_alloc_size = 0 if CreateContextRequest( cmd).CreateContextAllocationSize is None else eval( CreateContextRequest( cmd).CreateContextAllocationSize) cc_durable = False if CreateContextRequest( cmd).CreateContextDurableRequest is None else eval( CreateContextRequest( cmd).CreateContextDurableRequest) elif cmd.tag == "CreateRequest": #code for default parameters structure_size = 57 if CreateRequest( cmd).StructureSize is None else int( CreateRequest(cmd).StructureSize) security_flags = 0 if CreateRequest( cmd).SecurityFlags is None else int( CreateRequest(cmd).SecurityFlags) requested_oplock_level = pike.smb2.SMB2_OPLOCK_LEVEL_NONE if CreateRequest( cmd).RequestedOplockLevel is None else eval( CreateRequest(cmd).RequestedOplockLevel) impersonation_level = 0 if CreateRequest( cmd).ImpersonationLevel is None else int( CreateRequest(cmd).ImpersonationLevel) smb_create_flags = 0 if CreateRequest( cmd).SmbCreateFlags is None else int( CreateRequest(cmd).SmbCreateFlags) reserved = 0 if CreateRequest( cmd).Reserved is None else int( CreateRequest(cmd).Reserved) desired_access = eval(CreateRequest(cmd).DesiredAccess) file_attributes = pike.smb2.FILE_ATTRIBUTE_NORMAL if CreateRequest( cmd).FileAttributes is None else eval( CreateRequest(cmd).FileAttributes) share_access = pike.smb2.FILE_SHARE_READ if CreateRequest( cmd).ShareAccess is None else eval( CreateRequest(cmd).ShareAccess) create_disposition = pike.smb2.FILE_CREATE create_options = 0 if CreateRequest( cmd).CreateOptions is None else eval( CreateRequest(cmd).CreateOptions) name_offset = None if CreateRequest( cmd).NameOffset is None else int( CreateRequest(cmd).NameOffset) name_length = None if CreateRequest( cmd).NameLength is None else int( CreateRequest(cmd).NameLength) create_contexts_offset = None if CreateRequest( cmd).CreateContextsOffset is None else int( CreateRequest(cmd).CreateContextsOffset) create_contexts_length = None if CreateRequest( cmd).CreateContextsLength is None else int( CreateRequest(cmd).CreateContextsLength) create_buffer = CreateRequest(cmd).Buffer file_handle, create_resp = conv_obj.create( chan, tree_conn, create_buffer, structure_size=structure_size, security_flags=security_flags, oplock_level=requested_oplock_level, impersonation_level=impersonation_level, smb_create_flags=smb_create_flags, reserved=reserved, access=desired_access, attributes=file_attributes, share=share_access, disposition=create_disposition, options=create_options, name_offset=name_offset, name_length=name_length, create_contexts_offset=create_contexts_offset, create_contexts_length=create_contexts_length, maximal_access=cc_max_access, extended_attr=cc_ext_attr, allocation_size=cc_alloc_size, durable=cc_durable, security_desc_attr=cc_sd_attr) file = file_handle.result() if isinstance(file, pike.model.Open): chan.close(file)
def test_execute(self): """ Parse the XML files specified in tc.config file, and run test cases based on the inputs specified in XML files """ #Get testcases from xml file fail = 0 Execute.file = '' Execute.file1 = '' print "---------------------" conv_obj = utils.Convenience() tc = self.param share_all = pike.smb2.FILE_SHARE_WRITE | pike.smb2.FILE_SHARE_READ mainfiledata = '' maintestdata = '' r = tc.find('Result') cmd = r.find('Cmd') cmdcheck = cmd.text return_status = r.find('ReturnStatus') validation_mechanism = r.find('ValidationMechanism') expected_result = Result(r) desc = tc.find('Desc') print desc.text for tags in (tc): for cmd in (tags): if cmd.tag == "NegotiateRequest": negoutput = NegotiateRequest(cmd).param() negoutput = filter(lambda x: x != None, list(negoutput)) negoutput = filter(lambda x: x != ' ', list(negoutput)) StructureSize = int(NegotiateRequest(cmd).StructureSize) Capabilities = str(NegotiateRequest(cmd).Capabilities) ClientGuid = NegotiateRequest(cmd).ClientGuid Dialects = NegotiateRequest(cmd).Dialects conn = pike.model.Client().connect(self.server, self.port).negotiate() negotiateresp = conn.negotiate_response elif cmd.tag == "NegotiateResponse": neg_res_output = NegotiateResponse(cmd).param() smbnegotiate_resp = conn.negotiate_response elif cmd.tag == "SessionSetupRequest": sessoutput = SessionSetupRequest(cmd).param() Execute.chan = conn.session_setup(self.creds) elif cmd.tag == "SessionSetupResponse": ses_resp_output = SessionSetupResponse(cmd).param() elif cmd.tag == "LOGOFFRequest": logoffreq_output = LOGOFFRequest(cmd).param() elif cmd.tag == "LOGOFFResponse": logoffresp_output = LOGOFFResponse(cmd).param() elif cmd.tag == "TreeConnectRequest": tree_conn = '' smb_res = '' if cmdcheck == "Tree_Connect" or cmdcheck == "Create" or cmdcheck == "Lock": tree_connect_request = TreeConnectRequest(cmd).param() tree_connect_request = filter( lambda x: x != None, list(tree_connect_request)) tree_connect_request = filter( lambda x: x != ' ', list(tree_connect_request)) structure_size = TreeConnectRequest(cmd).StructureSize reserved = TreeConnectRequest(cmd).Reserved pathoffset = TreeConnectRequest(cmd).PathOffset pathlength = TreeConnectRequest(cmd).PathLength path = TreeConnectRequest(cmd).Buffer Tree_connect_list = [] if structure_size == ' ': structure_size = 9 Tree_connect_list.append(structure_size) else: Tree_connect_list.append(structure_size) if reserved == ' ': reserved = 0 Tree_connect_list.append(reserved) else: Tree_connect_list.append(reserved) if pathoffset == ' ': pathoffset = 72 Tree_connect_list.append(pathoffset) else: Tree_connect_list.append(pathoffset) if pathlength == ' ': pathlength = 0 Tree_connect_list.append(pathlength) else: Tree_connect_list.append(pathlength) Tree_connect_list = map(int, Tree_connect_list) if path != ' ': if isinstance(path, unicode): Tree_connect_list.append(path) else: Tree_connect_list.append(path) else: path = self.share Tree_connect_list.append(path) try: treeconnectpacket = conv_obj.tree_connect( Execute.chan, self.server, *Tree_connect_list) smb_res = conv_obj.transceive( Execute.chan, treeconnectpacket)[0] tree_conn = pike.model.Tree( Execute.chan.session, path, smb_res) except Exception as e: self.statuscheck( expected_result, str(e), "Tree Connect", tc.find('Desc').text.split(' ')[0]) if cmdcheck == "Tree_Connect": if tree_conn != '': self.statuscheck( expected_result, str(smb_res.status), "Tree Connect", tc.find('Desc').text.split(' ')[0]) else: tree_conn = Execute.chan.tree_connect(self.share) path = tree_conn.path elif cmd.tag == "TreeConnectResponse": tree_connresp_output = TreeConnectResponse(cmd).param() elif cmd.tag == "TreeDisconnectRequest": tree_disconnect_request = TreeDisconnectRequest( cmd).param() tree_disconnect_request = filter( lambda x: x is not None, list(tree_disconnect_request)) tree_disconnect_request = filter( lambda x: x != ' ', list(tree_disconnect_request)) structure_size = TreeDisconnectRequest(cmd).StructureSize reserved = TreeDisconnectRequest(cmd).Reserved tree_disconnect_list = [structure_size, reserved] tree_disconnect_list = [ item if item != ' ' else 0 for item in tree_disconnect_list ] tree_disconnect_list = map(int, tree_disconnect_list) elif cmd.tag == "TreeDisconnectResponse": tree_disconnect_resp_output = TreeDisconnectResponse( cmd).param() elif cmd.tag == "TestBed": testbed = cmd.text test_bed_file = str(testbed) elif cmd.tag == "CreateContextRequest": cc_max_access = None if CreateContextRequest( cmd).CreateContextMaximalAccess is None else eval( CreateContextRequest( cmd).CreateContextMaximalAccess) cc_ext_attr = {} if CreateContextRequest( cmd).CreateContextExtendedAttribute is None else eval( CreateContextRequest( cmd).CreateContextExtendedAttribute) cc_sd_attr = {} if CreateContextRequest( cmd).CreateContextSecurityDescriptor is None else eval( CreateContextRequest( cmd).CreateContextSecurityDescriptor) cc_alloc_size = 0 if CreateContextRequest( cmd).CreateContextAllocationSize is None else eval( CreateContextRequest( cmd).CreateContextAllocationSize) cc_durable = False if CreateContextRequest( cmd).CreateContextDurableRequest is None else eval( CreateContextRequest( cmd).CreateContextDurableRequest) elif cmd.tag == "CreateRequest": if cmdcheck == "Create" or cmdcheck == "Lock": create_val = tc.find('CreateValidation') val_list = create_val.find('ValidationList').text val_list = [] if val_list is None else val_list.split( ',') if isinstance(Execute.file, pike.model.Open): try: stat = True print "Second Create..." if Execute.file.oplock_level == pike.smb2.SMB2_OPLOCK_LEVEL_BATCH or Execute.file.oplock_level == pike.smb2.SMB2_OPLOCK_LEVEL_EXCLUSIVE: Execute.file.on_oplock_break( lambda level: level) Execute.file1, create_response1 = self.CreatePacket( conv_obj, Execute.chan, tree_conn, path, smb_res, expected_result, cmd, cmdcheck, return_status, share_all, create_contexts_maximal_access= cc_max_access, ext_attr=cc_ext_attr, alloc_size=cc_alloc_size, durable=cc_durable, Tree_connect_list=Tree_connect_list, security_desc_attr=cc_sd_attr) print "Second create has passed." if not isinstance(cc_durable, pike.model.Open): stat = self.create_validation( conv_obj, Execute.chan, tree_conn, tc, Execute.file, Execute.file1, create_val, val_list, create_response) if stat: print "Create validation has Passed." else: print "Create validation has Failed." except Exception as e: self.statuscheck( expected_result, str(e), "Create second handle", tc.find('Desc').text.split('-')[0]) fail = 1 else: try: print "First Create for Testing..." Execute.file, create_response = self.CreatePacket( conv_obj, Execute.chan, tree_conn, path, smb_res, expected_result, cmd, cmdcheck, return_status, share_all, create_contexts_maximal_access= cc_max_access, ext_attr=cc_ext_attr, alloc_size=cc_alloc_size, durable=cc_durable, Tree_connect_list=Tree_connect_list, security_desc_attr=cc_sd_attr) print "First create has passed." except Exception as e: self.statuscheck( expected_result, str(e), "Create first handle", tc.find('Desc').text.split('-')[0]) fail = 1 else: Execute.file = self.CreatePacket( conv_obj, Execute.chan, tree_conn, path, smb_res, expected_result, cmd, cmdcheck, return_status, share_all) create_buffer = CreateRequest(cmd).Buffer elif cmd.tag == "CreateResponse": create_resp = CreateResponse(cmd).param() elif cmd.tag == "ReadRequest": if isinstance(Execute.file1, pike.model.Open): self.ReadPacket(cmd, tc, conv_obj, return_status, Execute.chan, create_buffer, Execute.file1, expected_result, mainfiledata, maintestdata) else: self.ReadPacket(cmd, tc, conv_obj, return_status, Execute.chan, create_buffer, Execute.file, expected_result, mainfiledata, maintestdata) elif cmd.tag == "ReadResponse": Read_Response = ReadResponse(cmd).param() elif cmd.tag == "WriteRequest": if fail == 0: if isinstance(Execute.file1, pike.model.Open): self.WritePacket(cmd, tc, conv_obj, return_status, Execute.chan, Execute.file1, expected_result) else: self.WritePacket(cmd, tc, conv_obj, return_status, Execute.chan, Execute.file, expected_result) elif cmd.tag == "WriteResponse": write_response = WriteResponse(cmd).param() elif cmd.tag == "LockRequest": stat = True if isinstance(Execute.file1, pike.model.Open): try: print "Second Lock for testing..." lock_status = self.LockPacket( cmd, conv_obj, return_status, Execute.chan, Execute.file1, expected_result) self.statuscheck( expected_result, lock_status, "Second Lock", tc.find('Desc').text.split(' ')[0]) except Exception as e: print "Lock2 validation Failed due to : ", str(e) self.statuscheck( expected_result, e, "Second Lock", tc.find('Desc').text.split(' ')[0]) fail = 1 elif fail == 0: try: print "First Lock for testing..." lock_status = self.LockPacket( cmd, conv_obj, return_status, Execute.chan, Execute.file, expected_result) stat = self.lock_validation( tc, cmd, conv_obj, lock_status, Execute.chan, Execute.file, expected_result) if stat == False: self.statuscheck( expected_result, lock_status, "First Lock", tc.find('Desc').text.split(' ')[0]) fail = 1 else: print "First Lock has Passed." except Exception as e: self.statuscheck( expected_result, str(e), "First Lock", tc.find('Desc').text.split(' ')[0]) fail = 1 elif cmd.tag == "LockResponse": lock_response = LockResponse(cmd).param() if fail != 0: break if return_status.text == "STATUS_SUCCESS": if cmdcheck == 'Read': #MD5 from local file data checksum1 = self.verifychecksum(mainfiledata) #MD5 from server data checksum2 = self.verifychecksum(maintestdata) self.assertEqual(checksum1, checksum2) print "Verified the md5 sum for this positive test case" elif cmdcheck == 'Create' and Execute.file1 == '' and fail == 0: print "Verifying create status" self.statuscheck(expected_result, str(create_response[0].result().status), "Create", tc.find('Desc').text.split(' ')[0])
def __init__(self, *args, **kwargs): super(QueryTest, self).__init__(*args, **kwargs) self.chan = None self.tree = None self.conv_obj = utils.Convenience()