# EMACS settings: -*- tab-width: 2; indent-tabs-mode: t; python-indent-offset: 2 -*-
# vim: tabstop=2:shiftwidth=2:noexpandtab
# kate: tab-width 2; replace-tabs off; indent-width 2;
#
# ==============================================================================
# Authors: Patrick Lehmann
#
# Python Class: TODO
#
# License:
# ==============================================================================
# Copyright 2007-2016 Technische Universitaet Dresden - Germany
# Chair of VLSI-Design, Diagnostics and Architecture
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
#
#
# load dependencies
from collections import OrderedDict
from datetime import datetime
from enum import Enum, unique
__api__ = [
'SimulationStatus', 'CompileStatus',
'ElementBase',
'GroupBase', 'TestGroup', 'SynthesisGroup',
'SuiteMixIn', 'TestSuite', 'SynthesisSuite',
'TestBase', 'TestCase', 'Synthesis'
]
__all__ = __api__
@unique
[docs]class SimulationStatus(Enum):
Unknown = 0
DryRun = 1
SystemError = 5
InternalError = 6
AnalyzeError = 7
ElaborationError = 8
SimulationError = 9
SimulationFailed = 10
SimulationNoAsserts = 15
SimulationSuccess = 20
SimulationGUIRun = 30
@unique
[docs]class CompileStatus(Enum):
Unknown = 0
DryRun = 1
SystemError = 5
InternalError = 6
CompileError = 7
CompileFailed = 10
CompileSuccess = 20
[docs]class ElementBase:
def __init__(self, name, parent):
self._name = name
self._parent = parent
@property
def Name(self): return self._name
@property
def Parent(self): return self._parent
def __str__(self):
return "{0!s}.{1}".format(self._parent, self._name)
[docs]class GroupBase(ElementBase):
def __init__(self, name, parent):
super().__init__(name, parent)
self._groups = OrderedDict()
self._tests = OrderedDict()
def __getitem__(self, item):
try: return self._tests[item]
except KeyError: return self._groups[item]
def __len__(self):
return sum([len(group) for group in self._groups.values()]) + len(self._tests)
@property
def Groups(self): return self._groups
@property
def Count(self): return len(self)
[docs]class TestGroup(GroupBase):
def __setitem__(self, key, value):
if isinstance(value, TestGroup): self._groups[key] = value
elif isinstance(value, TestCase): self._tests[key] = value
else: raise ValueError("Parameter 'value' is not of type TestGroup or TestCase")
@property
def TestCases(self): return self._tests
@property
def PassedCount(self):
return sum([tg.PassedCount for tg in self._groups.values()]) \
+ sum([1 for tc in self._tests.values() if tc.Status is SimulationStatus.SimulationSuccess])
@property
def NoAssertsCount(self):
return sum([tg.NoAssertsCount for tg in self._groups.values()]) \
+ sum([1 for tc in self._tests.values() if tc.Status is SimulationStatus.SimulationNoAsserts])
@property
def DryRunCount(self):
return sum([tg.DryRunCount for tg in self._groups.values()]) \
+ sum([1 for tc in self._tests.values() if tc.Status is SimulationStatus.DryRun])
@property
def FailedCount(self):
return sum([tg.FailedCount for tg in self._groups.values()]) \
+ sum([1 for tc in self._tests.values() if tc.Status is SimulationStatus.SimulationFailed])
@property
def ErrorCount(self):
errors = (SimulationStatus.SystemError, SimulationStatus.InternalError, SimulationStatus.AnalyzeError, SimulationStatus.ElaborationError, SimulationStatus.SimulationError)
return sum([tg.ErrorCount for tg in self._groups.values()]) \
+ sum([1 for tc in self._tests.values() if tc.Status in errors])
[docs]class SynthesisGroup(GroupBase):
def __setitem__(self, key, value):
if isinstance(value, SynthesisGroup): self._groups[key] = value
elif isinstance(value, Synthesis): self._tests[key] = value
else: raise ValueError("Parameter 'value' is not of type SynthesisGroup or Synthesis")
@property
def Synthesises(self): return self._tests
@property
def SuccessCount(self):
return sum([tg.SuccessCount for tg in self._groups.values()]) \
+ sum([1 for tc in self._tests.values() if tc.Status is CompileStatus.CompileSuccess])
@property
def DryRunCount(self):
return sum([tg.DryRunCount for tg in self._groups.values()]) \
+ sum([1 for tc in self._tests.values() if tc.Status is CompileStatus.DryRun])
@property
def FailedCount(self):
return sum([tg.FailedCount for tg in self._groups.values()]) \
+ sum([1 for tc in self._tests.values() if tc.Status is CompileStatus.CompileFailed])
@property
def ErrorCount(self):
errors = (CompileStatus.SystemError, CompileStatus.InternalError, CompileStatus.CompileError)
return sum([tg.ErrorCount for tg in self._groups.values()]) \
+ sum([1 for tc in self._tests.values() if tc.Status in errors])
[docs]class SuiteMixIn:
def __init__(self):
self._startedAt = datetime.now()
self._endedAt = None
self._initRuntime = None
self._overallRuntime = None
def __str__(self):
return self._name
[docs] def StartTimer(self):
now = datetime.now()
self._initRuntime = now - self._startedAt
self._startedAt = now
[docs] def StopTimer(self):
self._endedAt = datetime.now()
self._overallRuntime = self._endedAt - self._startedAt
@property
def StartTime(self): return self._startedAt
@property
def EndTime(self): return self._endedAt
@property
def InitializationTime(self): return self._initRuntime.microseconds
@property
def OverallRunTime(self): return self._overallRuntime.seconds
[docs]class TestSuite(TestGroup, SuiteMixIn):
def __init__(self):
super().__init__("PoC", None)
SuiteMixIn.__init__(self)
@property
def IsAllPassed(self):
return (self.Count == self.PassedCount + self.NoAssertsCount + self.DryRunCount)
[docs] def AddTestCase(self, testCase):
cur = self
testbenchPath = testCase.Testbench.Path
for item in testbenchPath[:-2]:
try:
testGroup = cur[item.Name]
except KeyError:
testGroup = TestGroup(item.Name, cur)
cur[item.Name] = testGroup
cur = testGroup
testCaseName = testbenchPath[-2].Name
cur[testCaseName] = testCase
[docs]class SynthesisSuite(SynthesisGroup, SuiteMixIn):
def __init__(self):
super().__init__("PoC", None)
SuiteMixIn.__init__(self)
@property
def IsAllSuccess(self):
return (self.Count == self.SuccessCount)
[docs] def AddSynthesis(self, synthesis):
cur = self
netlistPath = synthesis.Netlist.Path
for item in netlistPath[:-2]:
try:
synthGroup = cur[item.Name]
except KeyError:
synthGroup = SynthesisGroup(item.Name, cur)
cur[item.Name] = synthGroup
cur = synthGroup
synthesisName = netlistPath[-2].Name
cur[synthesisName] = synthesis
[docs]class TestBase(ElementBase):
def __init__(self, test):
super().__init__(test.Parent.Name, None)
self._test = test
self._group = None
self._status = None
self._warnings = []
self._errors = []
self._startedAt = None
self._endedAt = None
self._overallRuntime = None
@property
def Parent(self): return self._parent
@Parent.setter
def Parent(self, value): self._parent = value
@property
def TestGroup(self): return self._group
@TestGroup.setter
def TestGroup(self, value): self._group = value
@property
def Status(self): return self._status
@Status.setter
def Status(self, value): self._status = value
[docs] def StartTimer(self):
self._startedAt = datetime.now()
[docs] def StopTimer(self):
self._endedAt = datetime.now()
self._overallRuntime = self._endedAt - self._startedAt
@property
def OverallRunTime(self): return self._overallRuntime.seconds
[docs]class TestCase(TestBase):
def __init__(self, testbench):
super().__init__(testbench)
self._status = SimulationStatus.Unknown
@property
def Testbench(self): return self._test
[docs] def UpdateStatus(self, testResult):
if (testResult is testResult.NotRun): self._status = SimulationStatus.Unknown
elif (testResult is testResult.DryRun): self._status = SimulationStatus.DryRun
elif (testResult is testResult.Error): self._status = SimulationStatus.SimulationError
elif (testResult is testResult.Failed): self._status = SimulationStatus.SimulationFailed
elif (testResult is testResult.NoAsserts): self._status = SimulationStatus.SimulationNoAsserts
elif (testResult is testResult.Passed): self._status = SimulationStatus.SimulationSuccess
elif (testResult is testResult.GUIRun): self._status = SimulationStatus.SimulationGUIRun
else: raise ValueError("Unsupported value in 'testResult'.")
[docs]class Synthesis(TestBase):
def __init__(self, synthesis):
super().__init__(synthesis)
self._status = CompileStatus.Unknown
@property
def Netlist(self): return self._test
[docs] def UpdateStatus(self, synthResult):
if (synthResult is synthResult.NotRun): self._status = CompileStatus.Unknown
if (synthResult is synthResult.DryRun): self._status = CompileStatus.DryRun
elif (synthResult is synthResult.Error): self._status = CompileStatus.CompileError
elif (synthResult is synthResult.Success): self._status = CompileStatus.CompileSuccess
else: raise IndentationError("Wuhu2")