2023-05-04 06:53:01 +00:00
|
|
|
|
|
|
|
# For testing.
|
|
|
|
#
|
|
|
|
# Concept: This module allows to trigger abnormal situations, to test the reaction of the software ("fault insertion testing").
|
|
|
|
# In the place in the software, where the fault shall be injected, add a condition like
|
|
|
|
# if (testsuite_faultinjection_is_triggered(TC_MY_TESTCASE_FOR_SOMETHING)):
|
|
|
|
# DoSomethingStrange()
|
|
|
|
# In normal software run, this condition is never fulfilled and does not disturb. If the related test case is activated,
|
|
|
|
# by setting testsuite_testcase_number = TC_MY_TESTCASE_FOR_SOMETHING below, the condition will fire and the fault is injected.
|
|
|
|
# A number of delay cycles can be configured with testsuite_delayCycles below.
|
2023-05-16 17:13:21 +00:00
|
|
|
#
|
|
|
|
# Detailled docu see doc/testing_and_simulation.md
|
|
|
|
|
2023-05-04 06:53:01 +00:00
|
|
|
|
2023-05-16 07:29:42 +00:00
|
|
|
from udplog import udplog_log
|
2023-05-16 17:13:21 +00:00
|
|
|
from configmodule import getConfigValue, getConfigValueBool
|
2023-05-16 07:29:42 +00:00
|
|
|
|
|
|
|
|
2023-05-04 06:53:01 +00:00
|
|
|
# The list of test cases. Each must have a unique test case ID.
|
|
|
|
TC_NOTHING_TO_TEST = 0
|
2023-05-15 20:34:49 +00:00
|
|
|
TC_EVSE_ResponseCode_SequenceError_for_SessionSetup = 1
|
2023-05-22 06:20:37 +00:00
|
|
|
TC_EVSE_ResponseCode_Failed_for_CableCheckRes = 2
|
|
|
|
TC_EVSE_ResponseCode_SequenceError_for_ServiceDiscoveryRes = 3
|
|
|
|
TC_EVSE_ResponseCode_SequenceError_for_ServicePaymentSelectionRes = 4
|
|
|
|
TC_EVSE_ResponseCode_SequenceError_for_ContractAuthenticationRes = 5
|
|
|
|
TC_EVSE_ResponseCode_ServiceSelectionInvalid_for_ChargeParameterDiscovery = 6
|
2023-05-15 20:34:49 +00:00
|
|
|
TC_EVSE_ResponseCode_Failed_for_PreChargeRes = 7
|
|
|
|
TC_EVSE_ResponseCode_Failed_for_PowerDeliveryRes = 8
|
|
|
|
TC_EVSE_ResponseCode_Failed_for_CurrentDemandRes = 9
|
|
|
|
TC_EVSE_Timeout_during_CableCheck = 10
|
|
|
|
TC_EVSE_Timeout_during_PreCharge = 11
|
|
|
|
TC_EVSE_Shutdown_during_PreCharge = 12
|
|
|
|
TC_EVSE_Shutdown_during_CurrentDemand = 13
|
|
|
|
TC_EVSE_Malfunction_during_CurrentDemand = 14
|
|
|
|
TC_EVSE_Timeout_during_CurrentDemand = 15
|
2023-05-20 09:07:02 +00:00
|
|
|
TC_EVSE_GoodCase = 16
|
|
|
|
TC_EVSE_LastTest = 17
|
2023-05-04 06:53:01 +00:00
|
|
|
|
|
|
|
|
2023-05-13 22:22:26 +00:00
|
|
|
# variables
|
|
|
|
testsuite_testcase_number = 0
|
|
|
|
testsuite_delayCycles = 0
|
2023-05-20 09:07:02 +00:00
|
|
|
testsuite_TcTitle = "(title not initialized)"
|
2023-05-04 06:53:01 +00:00
|
|
|
|
|
|
|
# Counter variable for delaying the trigger
|
|
|
|
testsuite_counter = 0
|
|
|
|
|
2023-05-20 09:07:02 +00:00
|
|
|
def testsuite_printToTestLog(s):
|
|
|
|
fileOut = open('testresults.txt', 'a') # open the result file for appending
|
|
|
|
print(s, file=fileOut)
|
|
|
|
fileOut.close()
|
|
|
|
|
2023-05-13 22:22:26 +00:00
|
|
|
def testsuite_getTcNumber():
|
2023-05-16 17:13:21 +00:00
|
|
|
if (testsuite_testcase_number==0):
|
|
|
|
return "(no tests)"
|
|
|
|
else:
|
2023-05-20 09:07:02 +00:00
|
|
|
return str(testsuite_testcase_number) + testsuite_TcTitle
|
2023-05-13 22:22:26 +00:00
|
|
|
|
2023-05-04 06:53:01 +00:00
|
|
|
def testsuite_faultinjection_is_triggered(context):
|
|
|
|
global testsuite_counter, testsuite_testcase_number, testsuite_delayCycles
|
|
|
|
isTestcaseFired = False
|
|
|
|
if (context==testsuite_testcase_number): # if the call context is matching the intended test case
|
|
|
|
testsuite_counter += 1 # count the number of matching calls
|
|
|
|
isTestcaseFired = testsuite_counter>=testsuite_delayCycles # and fire the test case if the intended number is reached
|
|
|
|
if (isTestcaseFired):
|
|
|
|
print("[TESTSUITE] Fired test case " + str(context) + " TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT")
|
2023-05-16 07:29:42 +00:00
|
|
|
s = "[TESTSUITE] Fired test case " + str(context)
|
|
|
|
udplog_log(s, "testsuite")
|
2023-05-04 06:53:01 +00:00
|
|
|
return isTestcaseFired
|
|
|
|
|
|
|
|
|
2023-05-13 22:22:26 +00:00
|
|
|
def testsuite_choose_testcase():
|
|
|
|
global testsuite_counter, testsuite_testcase_number, testsuite_delayCycles
|
2023-05-16 07:29:42 +00:00
|
|
|
global testsuite_observedResult
|
|
|
|
global testsuite_expectedResult
|
2023-05-20 09:07:02 +00:00
|
|
|
global testsuite_TcTitle
|
2023-05-16 07:29:42 +00:00
|
|
|
|
2023-05-16 17:13:21 +00:00
|
|
|
if (not getConfigValueBool("testsuite_enable")):
|
|
|
|
testsuite_testcase_number = TC_NOTHING_TO_TEST
|
|
|
|
return
|
|
|
|
|
2023-05-16 07:29:42 +00:00
|
|
|
try:
|
|
|
|
if (testsuite_expectedResult is None):
|
|
|
|
testsuite_expectedResult = ""
|
|
|
|
except:
|
|
|
|
testsuite_expectedResult = ""
|
|
|
|
|
|
|
|
# as first step, before choosing the next test case, check the result of the ongoing test case
|
|
|
|
if (testsuite_expectedResult!=""):
|
|
|
|
s = "ExpectedResult: " + testsuite_expectedResult
|
|
|
|
s = s + ", ObservedResult: " + testsuite_observedResult
|
|
|
|
if (testsuite_expectedResult!=testsuite_observedResult):
|
|
|
|
s = "FAIL " + s
|
|
|
|
else:
|
|
|
|
s = "PASS " + s
|
|
|
|
print(s)
|
|
|
|
udplog_log(s, "testsuite")
|
2023-05-20 09:07:02 +00:00
|
|
|
x = "Result for Testcase " + str(testsuite_testcase_number) + " " + testsuite_TcTitle
|
|
|
|
testsuite_printToTestLog(x)
|
|
|
|
testsuite_printToTestLog(s)
|
2023-05-13 22:22:26 +00:00
|
|
|
if (testsuite_testcase_number<TC_EVSE_LastTest):
|
|
|
|
testsuite_testcase_number+=1
|
|
|
|
print("[TESTSUITE] Setting up test case " + str(testsuite_testcase_number) + " TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT")
|
2023-05-16 07:29:42 +00:00
|
|
|
s = "[TESTSUITE] Setting up test case " + str(testsuite_testcase_number)
|
|
|
|
udplog_log(s, "testsuite")
|
2023-05-13 22:22:26 +00:00
|
|
|
testsuite_counter = 0
|
2023-05-16 07:29:42 +00:00
|
|
|
testsuite_delayCycles = 5 # just a default
|
|
|
|
testsuite_expectedResult = "" # just a default
|
|
|
|
testsuite_observedResult = "" # just a default
|
2023-05-20 09:07:02 +00:00
|
|
|
testsuite_TcTitle = "(title missing)" # just a default
|
2023-05-16 07:29:42 +00:00
|
|
|
|
|
|
|
# For each test case, configure the test parameters and the expected result
|
2023-05-13 22:22:26 +00:00
|
|
|
if (testsuite_testcase_number == TC_EVSE_Timeout_during_CableCheck):
|
|
|
|
testsuite_delayCycles=0 # immediately timeout
|
2023-05-16 07:29:42 +00:00
|
|
|
testsuite_expectedResult = "TSRS_SafeShutdownFinished"
|
2023-05-20 09:07:02 +00:00
|
|
|
testsuite_TcTitle = "Timeout during CableCheck shall lead to SafeShutdown"
|
|
|
|
|
|
|
|
if (testsuite_testcase_number == TC_EVSE_Timeout_during_PreCharge):
|
|
|
|
testsuite_delayCycles=0 # immediately timeout
|
|
|
|
testsuite_expectedResult = "TSRS_SafeShutdownFinished"
|
|
|
|
testsuite_TcTitle = "Timeout during PreCharge shall lead to SafeShutdown"
|
|
|
|
|
|
|
|
if (testsuite_testcase_number == TC_EVSE_Shutdown_during_PreCharge):
|
|
|
|
testsuite_delayCycles=2 # shutdown after 2 ok-cycles
|
|
|
|
testsuite_expectedResult = "TSRS_SafeShutdownFinished"
|
|
|
|
testsuite_TcTitle = "Shutdown during PreCharge shall lead to SafeShutdown"
|
|
|
|
|
|
|
|
if (testsuite_testcase_number == TC_EVSE_Shutdown_during_CurrentDemand):
|
|
|
|
testsuite_delayCycles=20 # shutdown after 20 ok-cycles
|
|
|
|
testsuite_expectedResult = "TSRS_SafeShutdownFinished"
|
|
|
|
testsuite_TcTitle = "Shutdown during CurrentDemand shall lead to SafeShutdown"
|
|
|
|
|
|
|
|
if (testsuite_testcase_number == TC_EVSE_Malfunction_during_CurrentDemand):
|
|
|
|
testsuite_delayCycles=5 # malfunction after 5 ok-cycles
|
|
|
|
testsuite_expectedResult = "TSRS_SafeShutdownFinished"
|
|
|
|
testsuite_TcTitle = "Malfunction during CurrentDemand shall lead to SafeShutdown"
|
|
|
|
|
|
|
|
if (testsuite_testcase_number == TC_EVSE_Timeout_during_CurrentDemand):
|
|
|
|
testsuite_delayCycles=30 # timeout after 30 ok-cycles
|
|
|
|
testsuite_expectedResult = "TSRS_SafeShutdownFinished"
|
|
|
|
testsuite_TcTitle = "Timeout during CurrentDemand shall lead to SafeShutdown"
|
|
|
|
|
2023-05-16 07:29:42 +00:00
|
|
|
if (testsuite_testcase_number == TC_EVSE_ResponseCode_SequenceError_for_SessionSetup):
|
|
|
|
testsuite_delayCycles=0 # immediately
|
|
|
|
testsuite_expectedResult = "TSRS_SafeShutdownFinished"
|
2023-05-20 09:07:02 +00:00
|
|
|
testsuite_TcTitle = "SequenceError in SessionSetup shall lead to SafeShutdown"
|
2023-05-16 07:29:42 +00:00
|
|
|
if (testsuite_testcase_number == TC_EVSE_ResponseCode_SequenceError_for_ServiceDiscoveryRes):
|
|
|
|
testsuite_delayCycles=0 # immediately
|
|
|
|
testsuite_expectedResult = "TSRS_SafeShutdownFinished"
|
2023-05-20 09:07:02 +00:00
|
|
|
testsuite_TcTitle = "SequenceError in ServiceDiscoveryRes shall lead to SafeShutdown"
|
2023-05-16 07:29:42 +00:00
|
|
|
if (testsuite_testcase_number == TC_EVSE_ResponseCode_SequenceError_for_ServicePaymentSelectionRes):
|
|
|
|
testsuite_delayCycles=0 # immediately
|
|
|
|
testsuite_expectedResult = "TSRS_SafeShutdownFinished"
|
2023-05-20 09:07:02 +00:00
|
|
|
testsuite_TcTitle = "SequenceError in ServicePaymentSelectionRes shall lead to SafeShutdown"
|
2023-05-16 07:29:42 +00:00
|
|
|
if (testsuite_testcase_number == TC_EVSE_ResponseCode_SequenceError_for_ContractAuthenticationRes):
|
|
|
|
testsuite_delayCycles=0 # immediately
|
|
|
|
testsuite_expectedResult = "TSRS_SafeShutdownFinished"
|
2023-05-20 09:07:02 +00:00
|
|
|
testsuite_TcTitle = "SequenceError in ContractAuthenticationRes shall lead to SafeShutdown"
|
2023-05-16 07:29:42 +00:00
|
|
|
if (testsuite_testcase_number == TC_EVSE_ResponseCode_ServiceSelectionInvalid_for_ChargeParameterDiscovery):
|
|
|
|
testsuite_delayCycles=0 # immediately
|
|
|
|
testsuite_expectedResult = "TSRS_SafeShutdownFinished"
|
2023-05-20 09:07:02 +00:00
|
|
|
testsuite_TcTitle = "ServiceSelectionInvalid in ChargeParameterDiscoveryshall lead to SafeShutdown"
|
|
|
|
|
|
|
|
if (testsuite_testcase_number == TC_EVSE_ResponseCode_Failed_for_CableCheckRes):
|
2023-05-22 06:20:37 +00:00
|
|
|
testsuite_delayCycles=0 # immediately in the first message
|
2023-05-20 09:07:02 +00:00
|
|
|
testsuite_expectedResult = "TSRS_SafeShutdownFinished"
|
|
|
|
testsuite_TcTitle = "Failed in CableCheckRes shall lead to SafeShutdown"
|
|
|
|
|
|
|
|
if (testsuite_testcase_number == TC_EVSE_ResponseCode_Failed_for_PreChargeRes):
|
|
|
|
testsuite_delayCycles=2 # after two ok cycles, we inject the fault in the third cycle
|
|
|
|
testsuite_expectedResult = "TSRS_SafeShutdownFinished"
|
|
|
|
testsuite_TcTitle = "Failed in PreChargeRes shall lead to SafeShutdown"
|
|
|
|
|
2023-05-16 07:29:42 +00:00
|
|
|
if (testsuite_testcase_number == TC_EVSE_ResponseCode_Failed_for_PowerDeliveryRes):
|
|
|
|
testsuite_delayCycles=0 # immediately
|
|
|
|
testsuite_expectedResult = "TSRS_SafeShutdownFinished"
|
2023-05-20 09:07:02 +00:00
|
|
|
testsuite_TcTitle = "Failed in PowerDeliveryRes shall lead to SafeShutdown"
|
|
|
|
|
|
|
|
if (testsuite_testcase_number == TC_EVSE_ResponseCode_Failed_for_CurrentDemandRes):
|
|
|
|
testsuite_delayCycles=10 # fire the fault after 10 ok-cycles
|
|
|
|
testsuite_expectedResult = "TSRS_SafeShutdownFinished"
|
|
|
|
testsuite_TcTitle = "Failed in CurrentDemandRes shall lead to SafeShutdown"
|
|
|
|
|
|
|
|
if (testsuite_testcase_number == TC_EVSE_GoodCase):
|
|
|
|
# Test case for the good case: Normal charging, no errors.
|
|
|
|
testsuite_delayCycles=0 # not relevant
|
|
|
|
testsuite_expectedResult = "TSRS_ChargingFinished"
|
|
|
|
testsuite_TcTitle = "Good case, normal charging without errors"
|
|
|
|
|
|
|
|
|
2023-05-16 07:29:42 +00:00
|
|
|
|
|
|
|
def testsuite_reportstatus(s):
|
|
|
|
# give the test status to the UDP, to inform the other side and to have it in the network log.
|
|
|
|
udplog_log(s, "testsuite")
|
|
|
|
pass
|
2023-05-13 22:22:26 +00:00
|
|
|
|
|
|
|
|
2023-05-16 07:29:42 +00:00
|
|
|
def testsuite_evaluateIpv4Packet(pkt):
|
|
|
|
# The testsuite listens to syslog messages which are coming from the other side,
|
|
|
|
# to know what is going on.
|
|
|
|
global testsuite_observedResult
|
|
|
|
if (len(pkt)>50):
|
|
|
|
protocol = pkt[23]
|
|
|
|
destinationport = pkt[36]*256 + pkt[37]
|
|
|
|
if ((protocol == 0x11) and (destinationport==0x0202)): # it is an UDP packet to the syslog port
|
|
|
|
baSyslog = pkt[46:]
|
|
|
|
strSyslog = ""
|
|
|
|
syslogLen = len(baSyslog)
|
|
|
|
if (syslogLen>100):
|
|
|
|
syslogLen=100
|
|
|
|
for i in range(0, syslogLen-1): # one less, remove the trailing 0x00
|
|
|
|
x = baSyslog[i]
|
|
|
|
if (x<0x20):
|
|
|
|
x=0x20 # make unprintable character to space.
|
|
|
|
strSyslog+=chr(x) # convert ASCII code to string
|
|
|
|
print("[Testsuite] received syslog packet: " + strSyslog)
|
|
|
|
if (strSyslog[0:5]=="TSRS_"):
|
|
|
|
# it is a TestSuiteReportStatus message.
|
|
|
|
testsuite_observedResult = strSyslog
|
|
|
|
|
2023-05-04 06:53:01 +00:00
|
|
|
if __name__ == "__main__":
|
|
|
|
print("Testing the mytestsuite")
|
|
|
|
print("nothing to do")
|