Commit 0d42376f authored by Arnaud Fontaine's avatar Arnaud Fontaine

ZODB Components: erp5_test_result: Migrate Documents from filesystem.

parent f2725631
...@@ -24,9 +24,8 @@ ...@@ -24,9 +24,8 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# #
############################################################################## ##############################################################################
from ERP5ProjectUnitTestDistributor import ERP5ProjectUnitTestDistributor from erp5.component.document.ERP5ProjectUnitTestDistributor import ERP5ProjectUnitTestDistributor
import json import json
from zLOG import LOG,INFO,ERROR
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions from Products.ERP5Type import Permissions
...@@ -53,7 +52,6 @@ class CloudPerformanceUnitTestDistributor(ERP5ProjectUnitTestDistributor): ...@@ -53,7 +52,6 @@ class CloudPerformanceUnitTestDistributor(ERP5ProjectUnitTestDistributor):
every test node. Like this, every test suite will be executed by every test node. Like this, every test suite will be executed by
every test node every test node
""" """
portal = self.getPortalObject()
test_node_module = self._getTestNodeModule() test_node_module = self._getTestNodeModule()
test_suite_module = self._getTestSuiteModule() test_suite_module = self._getTestSuiteModule()
test_node_list = [ test_node_list = [
...@@ -69,7 +67,7 @@ class CloudPerformanceUnitTestDistributor(ERP5ProjectUnitTestDistributor): ...@@ -69,7 +67,7 @@ class CloudPerformanceUnitTestDistributor(ERP5ProjectUnitTestDistributor):
test_node.setAggregateList(test_suite_list) test_node.setAggregateList(test_suite_list)
security.declarePublic("startTestSuite") security.declarePublic("startTestSuite")
def startTestSuite(self,title, computer_guid=None): def startTestSuite(self,title, computer_guid=None, **kw): # pylint: disable=super-on-old-class
""" """
give the list of test suite to start. We will take all test suites give the list of test suite to start. We will take all test suites
associated to the testnode. Then we add the test node title to the associated to the testnode. Then we add the test node title to the
...@@ -84,7 +82,7 @@ class CloudPerformanceUnitTestDistributor(ERP5ProjectUnitTestDistributor): ...@@ -84,7 +82,7 @@ class CloudPerformanceUnitTestDistributor(ERP5ProjectUnitTestDistributor):
return json.dumps(config_list) return json.dumps(config_list)
security.declarePublic("generateConfiguration") security.declarePublic("generateConfiguration")
def generateConfiguration(self, test_suite_title, batch_mode=0): def generateConfiguration(self, test_suite_title, batch_mode=0): # pylint: disable=super-on-old-class
""" """
return the list of configuration to create instances, in the case of ERP5 unit tests, return the list of configuration to create instances, in the case of ERP5 unit tests,
we will have only one configuration (unlike scalability tests). But for API consistency, we will have only one configuration (unlike scalability tests). But for API consistency,
...@@ -96,6 +94,6 @@ class CloudPerformanceUnitTestDistributor(ERP5ProjectUnitTestDistributor): ...@@ -96,6 +94,6 @@ class CloudPerformanceUnitTestDistributor(ERP5ProjectUnitTestDistributor):
return super(CloudPerformanceUnitTestDistributor, self) \ return super(CloudPerformanceUnitTestDistributor, self) \
.generateConfiguration("ERP5-Cloud-Reliability", batch_mode) .generateConfiguration("ERP5-Cloud-Reliability", batch_mode)
def _getTestSuiteFromTitle(self, suite_title): def _getTestSuiteFromTitle(self, suite_title): # pylint: disable=super-on-old-class
return super(CloudPerformanceUnitTestDistributor, return super(CloudPerformanceUnitTestDistributor,
self)._getTestSuiteFromTitle(suite_title.split("|")[0]) self)._getTestSuiteFromTitle(suite_title.split("|")[0])
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Document Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>default_reference</string> </key>
<value> <string>CloudPerformanceUnitTestDistributor</string> </value>
</item>
<item>
<key> <string>default_source_reference</string> </key>
<value> <string>Products.ERP5.Document.CloudPerformanceUnitTestDistributor</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>document.erp5.CloudPerformanceUnitTestDistributor</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Document Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>text_content_error_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>text_content_warning_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>erp5</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>validate</string> </value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>validated</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -25,15 +25,9 @@ ...@@ -25,15 +25,9 @@
# #
############################################################################## ##############################################################################
from Products.ERP5Type.XMLObject import XMLObject from Products.ERP5Type.XMLObject import XMLObject
from Products.ERP5.Tool.TaskDistributionTool import TaskDistributionTool
from DateTime import DateTime from DateTime import DateTime
from datetime import datetime
import json import json
import sys
import itertools
from copy import deepcopy
import random import random
import string
from zLOG import LOG,DEBUG,ERROR from zLOG import LOG,DEBUG,ERROR
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions from Products.ERP5Type import Permissions
...@@ -208,7 +202,6 @@ class ERP5ProjectUnitTestDistributor(XMLObject): ...@@ -208,7 +202,6 @@ class ERP5ProjectUnitTestDistributor(XMLObject):
which test suite migh be removed on test node with too many test suites which test suite migh be removed on test node with too many test suites
""" """
test_suite_module = self._getTestSuiteModule() test_suite_module = self._getTestSuiteModule()
portal = self.getPortalObject()
test_suite_list = test_suite_module.searchFolder(validation_state="validated", test_suite_list = test_suite_module.searchFolder(validation_state="validated",
specialise_uid=self.getUid()) specialise_uid=self.getUid())
all_test_suite_list = [] all_test_suite_list = []
...@@ -278,7 +271,7 @@ class ERP5ProjectUnitTestDistributor(XMLObject): ...@@ -278,7 +271,7 @@ class ERP5ProjectUnitTestDistributor(XMLObject):
if test_node.getValidationState() != 'validated': if test_node.getValidationState() != 'validated':
try: try:
test_node.validate() test_node.validate()
except e: except Exception, e:
LOG('Test Node Validate',ERROR,'%s' %e) LOG('Test Node Validate',ERROR,'%s' %e)
if test_node is None: if test_node is None:
test_node = test_node_module.newContent(portal_type="Test Node", title=title, computer_guid=computer_guid, test_node = test_node_module.newContent(portal_type="Test Node", title=title, computer_guid=computer_guid,
...@@ -346,7 +339,6 @@ class ERP5ProjectUnitTestDistributor(XMLObject): ...@@ -346,7 +339,6 @@ class ERP5ProjectUnitTestDistributor(XMLObject):
startTestSuite doc startTestSuite doc
""" """
test_node_module = self._getTestNodeModule() test_node_module = self._getTestNodeModule()
test_suite_module = self._getTestSuiteModule()
portal = self.getPortalObject() portal = self.getPortalObject()
config_list = [] config_list = []
tag = "%s_%s" % (self.getRelativeUrl(), title) tag = "%s_%s" % (self.getRelativeUrl(), title)
...@@ -389,7 +381,8 @@ class ERP5ProjectUnitTestDistributor(XMLObject): ...@@ -389,7 +381,8 @@ class ERP5ProjectUnitTestDistributor(XMLObject):
vcs_repository_list.append(repository_dict) vcs_repository_list.append(repository_dict)
config["vcs_repository_list"] = vcs_repository_list config["vcs_repository_list"] = vcs_repository_list
to_delete_key_list = [x for x,y in config.items() if y==None] to_delete_key_list = [x for x,y in config.items() if y==None]
[config.pop(x) for x in to_delete_key_list] for x in to_delete_key_list:
config.pop(x)
config_list.append(config) config_list.append(config)
LOG('ERP5ProjectUnitTestDistributor.startTestSuite, config_list',DEBUG,config_list) LOG('ERP5ProjectUnitTestDistributor.startTestSuite, config_list',DEBUG,config_list)
if batch_mode: if batch_mode:
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Document Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>default_reference</string> </key>
<value> <string>ERP5ProjectUnitTestDistributor</string> </value>
</item>
<item>
<key> <string>default_source_reference</string> </key>
<value> <string>Products.ERP5.Document.ERP5ProjectUnitTestDistributor</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>document.erp5.ERP5ProjectUnitTestDistributor</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Document Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>text_content_error_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>text_content_warning_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>erp5</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>validate</string> </value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>validated</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
# #
############################################################################## ##############################################################################
from Products.ERP5.Document.ERP5ProjectUnitTestDistributor import ERP5ProjectUnitTestDistributor from erp5.component.document.ERP5ProjectUnitTestDistributor import ERP5ProjectUnitTestDistributor
from Products.ZSQLCatalog.SQLCatalog import SimpleQuery from Products.ZSQLCatalog.SQLCatalog import SimpleQuery
from zLOG import LOG,ERROR from zLOG import LOG,ERROR
...@@ -33,7 +33,7 @@ from AccessControl import ClassSecurityInfo ...@@ -33,7 +33,7 @@ from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions from Products.ERP5Type import Permissions
import json import json
import jinja2 import jinja2
from Products.ERP5.Tool.TaskDistributionTool import TaskDistributionTool from erp5.component.tool.TaskDistributionTool import TaskDistributionTool
class ERP5ScalabilityDistributor(ERP5ProjectUnitTestDistributor, object): class ERP5ScalabilityDistributor(ERP5ProjectUnitTestDistributor, object):
security = ClassSecurityInfo() security = ClassSecurityInfo()
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
# #
############################################################################## ##############################################################################
from Products.ERP5.Document.ERP5ProjectUnitTestDistributor import ERP5ProjectUnitTestDistributor from erp5.component.document.ERP5ProjectUnitTestDistributor import ERP5ProjectUnitTestDistributor
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions from Products.ERP5Type import Permissions
......
...@@ -27,13 +27,12 @@ ...@@ -27,13 +27,12 @@
############################################################################## ##############################################################################
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions, PropertySheet from Products.ERP5Type import Permissions
from Products.ERP5.Document.Delivery import Delivery from Products.ERP5.Document.Delivery import Delivery
class TestResultLine(Delivery): class TestResultLine(Delivery):
"""Result of one single test run""" """Result of one single test run"""
# CMF Type Definition # CMF Type Definition
meta_type = 'ERP5 Test Result Line' meta_type = 'ERP5 Test Result Line'
portal_type = 'Test Result Line' portal_type = 'Test Result Line'
...@@ -44,6 +43,3 @@ class TestResultLine(Delivery): ...@@ -44,6 +43,3 @@ class TestResultLine(Delivery):
# Declarative security # Declarative security
security = ClassSecurityInfo() security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation) security.declareObjectProtected(Permissions.AccessContentsInformation)
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Document Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>default_reference</string> </key>
<value> <string>TestResultLine</string> </value>
</item>
<item>
<key> <string>default_source_reference</string> </key>
<value> <string>Products.ERP5.Document.TestResultLine</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>document.erp5.TestResultLine</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Document Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>text_content_error_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>text_content_warning_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>erp5</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>validate</string> </value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>validated</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -26,10 +26,9 @@ ...@@ -26,10 +26,9 @@
# #
############################################################################## ##############################################################################
import random
from DateTime import DateTime from DateTime import DateTime
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions, PropertySheet, Constraint, interfaces from Products.ERP5Type import Permissions
from Products.ERP5Type.Tool.BaseTool import BaseTool from Products.ERP5Type.Tool.BaseTool import BaseTool
from Products.ZSQLCatalog.SQLCatalog import SimpleQuery, NegatedQuery from Products.ZSQLCatalog.SQLCatalog import SimpleQuery, NegatedQuery
from zLOG import LOG, DEBUG from zLOG import LOG, DEBUG
...@@ -141,10 +140,10 @@ class TaskDistributionTool(BaseTool): ...@@ -141,10 +140,10 @@ class TaskDistributionTool(BaseTool):
title=test_name, title=test_name,
int_index=index) int_index=index)
reference_list_string = None reference_list_string = None
if type(revision) is str and '=' in revision: if isinstance(revision, str) and '=' in revision:
reference_list_string = revision reference_list_string = revision
int_index, reference = None, revision int_index, reference = None, revision
elif type(revision) is str: elif isinstance(revision, str):
# backward compatibility # backward compatibility
int_index, reference = revision, None int_index, reference = revision, None
else: else:
...@@ -230,7 +229,6 @@ class TaskDistributionTool(BaseTool): ...@@ -230,7 +229,6 @@ class TaskDistributionTool(BaseTool):
test_result = portal.restrictedTraverse(test_result_path) test_result = portal.restrictedTraverse(test_result_path)
if test_result.getSimulationState() != 'started': if test_result.getSimulationState() != 'started':
return return
started_list = []
for line in test_result.objectValues(portal_type="Test Result Line", for line in test_result.objectValues(portal_type="Test Result Line",
sort_on=[("int_index","ascending")]): sort_on=[("int_index","ascending")]):
test = line.getTitle() test = line.getTitle()
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Tool Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>default_reference</string> </key>
<value> <string>TaskDistributionTool</string> </value>
</item>
<item>
<key> <string>default_source_reference</string> </key>
<value> <string>Products.ERP5.Tool.TaskDistributionTool</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>tool.erp5.TaskDistributionTool</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Tool Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>text_content_error_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>text_content_warning_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>erp5</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>validate</string> </value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>validated</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
document.erp5.CloudPerformanceUnitTestDistributor
document.erp5.ERP5ProjectUnitTestDistributor
document.erp5.ERP5ScalabilityDistributor
document.erp5.GitlabRESTConnector
document.erp5.SlapOSAgentDistributor
document.erp5.TestNode document.erp5.TestNode
document.erp5.TestResultLine
document.erp5.TestSuite document.erp5.TestSuite
document.erp5.TestSuiteRepository document.erp5.TestSuiteRepository
\ No newline at end of file
document.erp5.ERP5ScalabilityDistributor
document.erp5.SlapOSAgentDistributor
document.erp5.GitlabRESTConnector
\ No newline at end of file
tool.erp5.TaskDistributionTool
\ No newline at end of file
...@@ -51,7 +51,7 @@ from Tool import CategoryTool, SimulationTool, RuleTool, IdTool, TemplateTool,\ ...@@ -51,7 +51,7 @@ from Tool import CategoryTool, SimulationTool, RuleTool, IdTool, TemplateTool,\
GadgetTool, ContributionRegistryTool, IntrospectionTool,\ GadgetTool, ContributionRegistryTool, IntrospectionTool,\
AcknowledgementTool, SolverTool,\ AcknowledgementTool, SolverTool,\
UrlRegistryTool, InterfaceTool,\ UrlRegistryTool, InterfaceTool,\
CertificateAuthorityTool, InotifyTool, TaskDistributionTool CertificateAuthorityTool, InotifyTool
import ERP5Site import ERP5Site
from Document import PythonScript, SQLMethod from Document import PythonScript, SQLMethod
object_classes = ( ERP5Site.ERP5Site, object_classes = ( ERP5Site.ERP5Site,
...@@ -80,7 +80,6 @@ portal_tools = ( CategoryTool.CategoryTool, ...@@ -80,7 +80,6 @@ portal_tools = ( CategoryTool.CategoryTool,
UrlRegistryTool.UrlRegistryTool, UrlRegistryTool.UrlRegistryTool,
CertificateAuthorityTool.CertificateAuthorityTool, CertificateAuthorityTool.CertificateAuthorityTool,
InotifyTool.InotifyTool, InotifyTool.InotifyTool,
TaskDistributionTool.TaskDistributionTool,
InterfaceTool.InterfaceTool, InterfaceTool.InterfaceTool,
) )
content_classes = () content_classes = ()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment