Custom checks

ecu.test can be extended with custom checks for packages, projects and analysis packages. Custom checks are implemented as Python classes and loaded from UserPyModules.

Overview

Custom checks are discovered by the module-level constant MODULE_TYPE and by the matching base class:

  • 'PACKAGE_CHECK' with AbstractPackageCheck

  • 'PROJECT_CHECK' with AbstractProjectCheck

  • 'ANALYSIS_PACKAGE_CHECK' with AbstractAnalysisPackageCheck

Info

The interface is included in the ecu.test Interface Python Library ecutest-interface.

Location and structure

Place custom check modules in the workspace below UserPyModules.

The class must provide:

  • GetName()

  • Run(item) returning a list of CheckResult entries

Minimal package check example

from tts.interface.customCheck import AbstractPackageCheck, CheckResult

MODULE_TYPE = 'PACKAGE_CHECK'


class MyPackageCheck(AbstractPackageCheck):
    def __init__(self, internalApi):
        self._internalApi = internalApi

    def GetName(self):
        return 'MyPackageCheck'

    def Run(self, package):
        checkResults = []
        if len(package.GetDescription()) == 0:
            checkResults.append(CheckResult('Description must not be empty!'))
        return checkResults

Check results and severities

Each finding is represented by CheckResult.

Supported severities are:

  • note

  • warning

  • error

  • exception

ID and origin fields

CheckResult also supports the optional fields id and origin.

  • id identifies the finding type. It can be set by user code (e.g. invalid-var-name, deprecated-parameter).

  • origin Namespace of the library workspace or ‘internal’ for built-in checks. It is set by ecu.test.

Example with id

from tts.interface.customCheck import CheckResult, Severity

result = CheckResult(
        'Variable name does not match naming convention.',
        severity=Severity.WARNING,
        id='invalid-var-name',
)

Optional fixes

Custom checks may provide fixes shown in the same check dialog context menu. Fixes are defined by Fix and return FixResult. The callback receives the checked item and a progress object.

import os

from tts.interface.customCheck import AbstractPackageCheck, CheckResult

MODULE_TYPE = 'PACKAGE_CHECK'


class DesignerPackageCheck(AbstractPackageCheck):
    def __init__(self, internalApi):
        self._internalApi = internalApi

    def GetName(self):
        return 'MyDesignerPackageCheck'

    def InsertDesigner(self, package, progress):
        progress.SetCaption('Applying fix...')
        package.Attributes.SetValue('Designer', os.getlogin())
        return FixResult(Result.FIXED, 'Fix applied.')

    def Run(self, package):
        checkResults = []
        if 'Designer' not in package.Attributes.GetNamesAndValues():
            checkResults.append(
                 CheckResult(
                     'Designer must not be empty!',
                     severity=Severity.WARNING,
                     fixes=[
                         Fix('Insert currently logged in user', self.InsertDesigner),
                     ],
                 )
            )

Info

ecu.test contains templates for custom checks that can be copied into the workspace when starting the application.