Skip to content
Snippets Groups Projects
Commit 99729e0f authored by Jonas Ladefoged Holm's avatar Jonas Ladefoged Holm Committed by Fabrice Le Goff
Browse files

Resolve "Functional Tests for ERS Messages"

parent 17e385a8
No related branches found
No related tags found
No related merge requests found
...@@ -12,4 +12,4 @@ unit_tests: ...@@ -12,4 +12,4 @@ unit_tests:
- tdaq - tdaq
script: script:
- source /afs/cern.ch/atlas/project/tdaq/cmake/cmake_tdaq/bin/cm_setup.sh nightly - source /afs/cern.ch/atlas/project/tdaq/cmake/cmake_tdaq/bin/cm_setup.sh nightly
- python -m unittest discover --top-level-directory "Script/" --start-directory "Script/UnitTests/" --pattern "Test_*.py" --verbose - python -m unittest discover --top-level-directory "Script/" --start-directory "Script/UnitTests/" --pattern "*Test.py" --verbose
\ No newline at end of file \ No newline at end of file
import unittest
from UnitTests.FunctionalTests import LocalCopy_Test, ERS_Test
suite = unittest.TestSuite()
loader = unittest.TestLoader()
suite.addTests(loader.loadTestsFromModule(LocalCopy_Test))
suite.addTests(loader.loadTestsFromModule(ERS_Test))
runner = unittest.TextTestRunner(verbosity=3)
print("\n==============================================================")
print("Running Functional Tests:")
print("==============================================================\n")
result = runner.run(suite)
\ No newline at end of file
import unittest
from UnitTests import BaseFileNameParser_Test
suite = unittest.TestSuite()
loader = unittest.TestLoader()
suite.addTests(loader.loadTestsFromModule(BaseFileNameParser_Test))
runner = unittest.TextTestRunner(verbosity=3)
print("\n==============================================================")
print("Running Unit Tests:")
print("==============================================================\n")
result = runner.run(suite)
\ No newline at end of file
import unittest
import signal
import shutil
import time
from subprocess import Popen
if __name__ == '__main__':
import sys
from os.path import dirname, abspath, join
# add CastorScript/Script to path so imports keeps working
SCRIPT_DIR = abspath(join(dirname(__file__), '../..'))
sys.path.append(SCRIPT_DIR)
from UnitTests.FunctionalTests.FuncTestUtils.DirUtils import createTmpDir
# I'm a developer, I want to see if the script is able to publish to ERS.
# However, I don't have access to a partition or an MTS stream.
# Because of this I want to redirect output to STDOUT in a file, to see that it works.
class TestERStoSTDOUT(unittest.TestCase):
@classmethod
def setUpClass(self):
# I create test directories and remember their locations.
## returns a dictionary over dirs like src des log config etc..
self.dirs = createTmpDir("/Script/UnitTests/FunctionalTests")
# I make a config file from the template (CastorScript/Configs)
# I find the config file and I open it
cfgTemplate = open(self.dirs["config"] + "/template.cfg", "r")
# I make a new file in CastorScript/tmp directory
cfgTest = open(self.dirs["tmp"] + "/funcTestConf.cfg", "w")
custom_cfg_lines = {
"LogDir: ": "LogDir: \'{}\'\n".format(self.dirs["log"]),
"DirList: ": "DirList: [\'{}\',]\n".format(self.dirs["src"]),
"CopyDir: ": "CopyDir: \'{}\'\n".format(self.dirs["des"]),
"ers_info: ": "ers_info: \'\'\n",
"ers_warning: ": "ers_warning: \'\'\n",
"ers_error: ": "ers_error: \'\'\n",
"ers_debug: ": "ers_debug: \'\'\n",
"ERSenabled: ": "ERSenabled: True\n"
}
# And I copy the content and replaces the directories with my own dirs
for line in cfgTemplate:
for key, value in custom_cfg_lines.iteritems():
if line.find(key) is not -1:
line = value
cfgTest.write(line)
cfgTest.close()
# Now I Run the script with config
self.output = open(self.dirs["tmp"] + "/" + "std.output", "a")
self.output.flush()
## TODO More cleanup
scriptcommand = ["python","-u", self.dirs["project"] + "/Script/CastorScript.py", self.dirs["tmp"] + "/funcTestConf.cfg" ]
self.castorscriptprocess = Popen(scriptcommand, stdout=self.output, stderr=self.output)
@classmethod
def tearDownClass(self):
self.output.close()
## remove directories and files
shutil.rmtree(self.dirs["tmp"])
## Test cases:
def test_subStringFoundInStdout(self):
# I wait for the messages to propagate
time.sleep(2)
# I stop the process to collect output
self.castorscriptprocess.send_signal(signal.SIGUSR2)
self.castorscriptprocess.wait()
self.output.close()
# I look at the file and observes that the substring is there.
self.output = open(self.dirs["tmp"] + "/" + "std.output", "r")
foundSubstring = False
for line in self.output:
if line.find("CastorScript is now logging to partition") > -1:
foundSubstring = True
# Now I know that ERS works, and I feel a bit safer
self.assertEqual(foundSubstring, True)
if __name__ == '__main__':
unittest.main()
from subprocess import Popen, PIPE
import time import time
from subprocess import Popen, PIPE
#For timing timeouts #For timing timeouts, timer starts with __init__ function
class Timer(): class Timer():
def __init__(self, seconds): def __init__(self, seconds):
self.startTime = time.time() self.startTime = time.time()
...@@ -19,8 +17,43 @@ class Timer(): ...@@ -19,8 +17,43 @@ class Timer():
def timesNotUp(self): def timesNotUp(self):
return not self.timesUp() return not self.timesUp()
#For checking a dir def createTmpDir(testLocation):
"""Creates the directories: tmp, des, src and log at the defined testLocation.
Testlocation is the relative path from the CastorScript folder to where the folders should be created.
returns a dictionary of paths to relevant directories: projectPath, configPath, tmpPath, srcPath, desPath and logPath."""
import os, shutil
dirs = {}
## Define folder structure
dirs["project"] = os.path.dirname(os.path.abspath(__name__))
thisDir = dirs["project"] + testLocation
dirs["tmp"] = thisDir + "/tmp"
dirs["config"] = dirs["project"] + "/Configs"
dirs["src"] = dirs["tmp"] + "/src"
dirs["des"] = dirs["tmp"] + "/des"
dirs["log"] = dirs["tmp"] + "/log"
# I create some folders
try:
os.makedirs(dirs["src"])
os.makedirs(dirs["des"])
os.makedirs(dirs["log"])
except:
shutil.rmtree(dirs["tmp"])
os.makedirs(dirs["src"])
os.makedirs(dirs["des"])
os.makedirs(dirs["log"])
return dirs
class DirectoryChecker(): class DirectoryChecker():
"""For checking the contents of a directory either once, or until a condition is met or timeout is reached."""
def __init__(self, dirPath): def __init__(self, dirPath):
self.dirPath = dirPath self.dirPath = dirPath
self.lsOutput = None self.lsOutput = None
...@@ -28,16 +61,18 @@ class DirectoryChecker(): ...@@ -28,16 +61,18 @@ class DirectoryChecker():
self.timerUtil = None self.timerUtil = None
def waitForAnyFile(self, seconds): def waitForAnyFile(self, seconds):
timeToTimeout = seconds "Waits for the specified amount of time for the dir to be empty, returns a tuple (bool: timedout, str: lsOutput)"
self.timerUtil = Timer(timeToTimeout) self.timerUtil = Timer(seconds)
while self.checkIfEmpty() and self.timerUtil.timesNotUp(): while self.checkIfEmpty() and self.timerUtil.timesNotUp():
pass pass
return (self.timerUtil.timedout, self.getLsOutput())
def waitForEmptyDir(self, seconds): def waitForEmptyDir(self, seconds):
timeToTimeout = seconds "Waits for the specified amount of time for the dir to contain files, returns a tuple (bool: timedout, str: lsOutput)"
self.timerUtil = Timer(timeToTimeout) self.timerUtil = Timer(seconds)
while self.checkIfNotEmpty() and self.timerUtil.timesNotUp(): while self.checkIfNotEmpty() and self.timerUtil.timesNotUp():
pass pass
return (self.timerUtil.timedout, self.getLsOutput())
def checkIfEmpty(self): def checkIfEmpty(self):
if len(self.getLsOutput()) > 1: if len(self.getLsOutput()) > 1:
...@@ -58,29 +93,4 @@ class DirectoryChecker(): ...@@ -58,29 +93,4 @@ class DirectoryChecker():
def getLsOutput(self): def getLsOutput(self):
self.lsOutput = str(Popen(["ls", self.dirPath],bufsize=-1, stdout=PIPE).communicate()[0]) self.lsOutput = str(Popen(["ls", self.dirPath],bufsize=-1, stdout=PIPE).communicate()[0])
return self.lsOutput return self.lsOutput
\ No newline at end of file
#Could be refactored
def findCastorScriptPids():
# first find all running instances with this command
# ps aux | grep CastorScript.py | grep -v grep | awk '{print $2}'
# it get list of processes
psCommand = Popen(["ps", "aux"], stdout=PIPE)
# finds castorscript processes
grepCommand = Popen(["grep", "CastorScript.py"], stdin=psCommand.stdout, stdout=PIPE)
psCommand.stdout.close()
# sorts grep out of the mix
grepvCommand = Popen(["grep", "-v", "grep"], stdin=grepCommand.stdout, stdout=PIPE)
grepCommand.stdout.close()
# and finally gets the PIDs
awkCommand = Popen(["awk", "{print $2}"], stdin=grepvCommand.stdout, stdout=PIPE)
grepvCommand.stdout.close()
pids = str(awkCommand.communicate()[0]).splitlines()
awkCommand.stdout.close()
return pids
\ No newline at end of file
import unittest
import signal
import shutil
from subprocess import Popen
if __name__ == '__main__':
import sys
from os.path import dirname, abspath, join
# add CastorScript/Script to path so imports keeps working
SCRIPT_DIR = abspath(join(dirname(__file__), '../..'))
sys.path.append(SCRIPT_DIR)
from UnitTests.FunctionalTests.FuncTestUtils.DirUtils import DirectoryChecker
from UnitTests.FunctionalTests.FuncTestUtils.DirUtils import createTmpDir
# I'm a developer, I want to see if the script can copy files.
class TestCanCopyFilesLocally(unittest.TestCase):
@classmethod
def setUpClass(self):
# I create test directories and remember their locations
## returns a dictionary over dirs like src des log config etc..
self.dirs = createTmpDir("/Script/UnitTests/FunctionalTests")
## Create test file
test_file = open('{}/file.data'.format(self.dirs["src"]), "w")
test_file.close()
# I make a config file from the template (CastorScript/Configs)
# I find the config file
# I open it
cfgTemplate = open(self.dirs["config"] + "/template.cfg", "r")
# I make a new file in CastorScript/tmp directory
cfgTest = open(self.dirs["tmp"] + "/funcTestConf.cfg", "w")
# And I copy the content and replaces the directories with my own dirs
custom_cfg_lines = {
"LogDir: ": "LogDir: \'{}\'\n".format(self.dirs["log"]),
"DirList: ": "DirList: [\'{}\',]\n".format(self.dirs["src"]),
"CopyDir: ": "CopyDir: \'{}\'\n".format(self.dirs["des"]),
}
# And I copy the content and replaces the directories with my own dirs
for line in cfgTemplate:
for key, value in custom_cfg_lines.iteritems():
if line.find(key) is not -1:
line = value
cfgTest.write(line)
cfgTest.close()
## Run the script with config
scriptcommand = ["python", self.dirs["project"] + "/Script/CastorScript.py", self.dirs["tmp"] + "/funcTestConf.cfg" ]
self.castorscriptprocess = Popen(scriptcommand)
@classmethod
def tearDownClass(self):
# stop process
self.castorscriptprocess.send_signal(signal.SIGUSR2)
self.castorscriptprocess.wait()
# remove directories and files
shutil.rmtree(self.dirs["tmp"])
# Test cases:
def test_localCopy_script_has_been_instanciated(self):
#test if the script runs by Instance
self.assertNotEqual(self.castorscriptprocess, None, msg="Castorscript, is not running; Subprocess is of type none")
def test_localCopy_can_produce_logfiles(self):
seconds = 10
timeout, output = DirectoryChecker(self.dirs["log"]).waitForAnyFile(seconds)
timeoutMessage = "Timeout, found no log files within a timeframe of " + str(seconds) + " seconds"
self.assertFalse(timeout, msg=timeoutMessage)
outNotFoundMessage = "No files ending with .out found in log directory, found:" + output
self.assertTrue(output.find(".out") > -1, msg=outNotFoundMessage)
def test_localCopy_can_copy_files_to_des_directory(self):
seconds = 4
timeout, output = DirectoryChecker(self.dirs["des"]).waitForAnyFile(seconds)
timeoutMessage = "Timeout, found no files within a timeframe of " + str(seconds) + " seconds"
self.assertFalse(timeout, msg=timeoutMessage)
dataNotFoundMessage = "No files ending with .data found in des directory, found:" + output
self.assertTrue(output.find(".data") > -1, msg=dataNotFoundMessage)
def test_localCopy_src_files_was_deleted(self):
seconds = 5
timeout, output = DirectoryChecker(self.dirs["src"]).waitForEmptyDir(seconds)
timeoutMessage = "Timeout, found no empty dir within a timeframe of " + str(seconds) + " seconds"
self.assertFalse(timeout, msg=timeoutMessage)
logsNotFoundMessage = "No files ending with .out found in log directory, found:" + output
self.assertTrue(output.find("file") == -1, msg=logsNotFoundMessage)
if __name__ == '__main__':
unittest.main()
import unittest
import os
import signal
import shutil
from subprocess import Popen
if __name__ == '__main__':
import sys
from os.path import dirname, abspath, join
# add CastorScript/Script to path so imports keeps working
SCRIPT_DIR = abspath(join(dirname(__file__), '..'))
sys.path.append(SCRIPT_DIR)
from UnitTests.testUtils import DirectoryChecker, findCastorScriptPids
# I'm a developer, I want to see if the script can copy files.
class TestCanCopyFilesLocally(unittest.TestCase):
@classmethod
def setUpClass(self):
self.timeout = False
# kill all processes of CastorScript
# kill the processes based on PID
for pid in findCastorScriptPids():
os.kill(int(pid), signal.SIGTERM)
# Define folder structure
self.thisdir = os.path.dirname(__file__)
self.tmp = "tmp"
self.src = self.tmp + "/src"
self.des = self.tmp + "/des"
self.log = self.tmp + "/log"
self.tmpPath = os.path.abspath(os.path.join(self.thisdir, self.tmp))
self.srcPath = os.path.abspath(os.path.join(self.thisdir, self.src))
self.desPath = os.path.abspath(os.path.join(self.thisdir, self.des))
self.logPath = os.path.abspath(os.path.join(self.thisdir, self.log))
# Setup the testcase tools
self.logDirUtil = DirectoryChecker(self.logPath)
self.srcDirUtil = DirectoryChecker(self.srcPath)
self.desDirUtil = DirectoryChecker(self.desPath)
# Setup the timers
self.timeToTimeout = 5
self.timerUtil = None
# I create some folders
try:
os.makedirs(self.srcPath)
os.makedirs(self.desPath)
os.makedirs(self.logPath)
except:
shutil.rmtree(self.tmpPath)
os.makedirs(self.srcPath)
os.makedirs(self.desPath)
os.makedirs(self.logPath)
# And I populate only the src folder with files to copy
for x in range(1):
open(self.srcPath + '/file' + str(x) + '.data', "w").close()
#open(self.desPath + '/file' + str(x) + '.data', "w").close()
#open(self.logPath + '/file' + str(x) + '.data', "w").close()
# I make a config file from the template (CastorScript/Configs)
# I find the config file
self.confTemplatePath = os.path.abspath(os.path.join(self.thisdir, "../../Configs"))
# I open it
cfgTemplate = open(self.confTemplatePath + "/template.cfg", "r")
# I make a new file in CastorScript/tmp directory
cfgTest = open(self.tmpPath + "/" + "funcTestConf.cfg", "w")
# And I copy the content and replaces the directories with my own dirs
for line in cfgTemplate:
if line.find("LogDir: ") > -1:
cfgTest.write("LogDir: \'" + self.logPath + "\'\n")
#print(line)
elif line.find("DirList: ") > -1:
cfgTest.write("DirList: [\'" + self.srcPath + "\',]\n")
#print(line)
elif line.find("CopyDir: ") > -1:
cfgTest.write("CopyDir: \'" + self.desPath + "\'\n")
#print(line)
else:
cfgTest.write(line)
#print(line)
cfgTest.close()
# Run the script with config
#NON SHELL
#self.castorscriptprocess = Popen(scriptcommand)
scriptcommand = ["python", self.thisdir + "/../CastorScript.py", self.tmpPath + "/funcTestConf.cfg" ]
self.castorscriptprocess = Popen(scriptcommand)
#Run in shell
#self.castorscriptprocess = Popen("python " + self.thisdir + "/../CastorScript.py " + self.tmpPath + "/funcTestConf.cfg", shell=True)
# To kill the process for debugging
#self.castorscriptprocess.kill()
@classmethod
def tearDownClass(self):
# stop process
self.castorscriptprocess.send_signal(signal.SIGUSR2)
self.castorscriptprocess.wait()
# remove directories and files
shutil.rmtree(self.tmpPath)
# Test cases:
def test_A_cs_should_be_instanciated(self):
#test if the script runs by Instance
self.assertNotEqual(self.castorscriptprocess, None, msg="Castorscript, is not running; Subprocess is of type none")
def test_B_cs_should_be_running_and_have_a_pid(self):
#test if the script runs by PID
self.assertIsNot(len(findCastorScriptPids()), 0, msg="No CastorScript PIDs found, so must not be running")
def test_C_cs_should_produce_logfiles(self):
self.timeToTimeout = 10
self.logDirUtil.waitForAnyFile(self.timeToTimeout)
self.timeout = self.logDirUtil.timerUtil.timedout
output = self.logDirUtil.lsOutput
timeoutMessage = "Timeout, found no log files within a timeframe of " + str(self.timeToTimeout) + " seconds"
self.assertFalse(self.timeout, msg=timeoutMessage)
outNotFoundMessage = "No files ending with .out found in log directory, found:" + output
self.assertTrue(output.find(".out") > -1, msg=outNotFoundMessage)
def test_D_cs_should_copy_files_to_des_directory(self):
self.timeToTimeout = 4
self.desDirUtil.waitForAnyFile(self.timeToTimeout)
self.timeout = self.desDirUtil.timerUtil.timedout
output = self.desDirUtil.lsOutput
timeoutMessage = "Timeout, found no files within a timeframe of " + str(self.timeToTimeout) + " seconds"
self.assertFalse(self.timeout, msg=timeoutMessage)
dataNotFoundMessage = "No files ending with .data found in des directory, found:" + output
self.assertTrue(output.find(".data") > -1, msg=dataNotFoundMessage)
def test_E_src_files_should_be_deleted(self):
self.timeToTimeout = 5
self.srcDirUtil.waitForEmptyDir(self.timeToTimeout)
self.timeout = self.srcDirUtil.timerUtil.timedout
output = self.srcDirUtil.lsOutput
timeoutMessage = "Timeout, found no empty dir within a timeframe of " + str(self.timeToTimeout) + " seconds"
self.assertFalse(self.timeout, msg=timeoutMessage)
self.assertTrue(output.find("file") == -1, msg="No files ending with .out found in log directory, found:" + output)
if __name__ == '__main__':
unittest.main()
...@@ -10,7 +10,9 @@ then ...@@ -10,7 +10,9 @@ then
source /afs/cern.ch/atlas/project/tdaq/cmake/cmake_tdaq/bin/cm_setup.sh nightly source /afs/cern.ch/atlas/project/tdaq/cmake/cmake_tdaq/bin/cm_setup.sh nightly
fi fi
python -m unittest discover -t $TOPDIR -s $STARTDIR -p "Test_*.py" -f --verbose #python -m unittest discover -t $TOPDIR -s $STARTDIR -p "*Test.py" -f --verbose
python Script/TestSuite_UnitTests.py
python Script/TestSuite_Functional.py
#for Gitlab CI: #for Gitlab CI we just find all files in unittest dir, as we just care if it fails or not, the setup above is only for local testing
# python -m unittest discover --top-level-directory "Script/" --start-directory "Script/UnitTests/" --pattern "Test_*.py" --verbose # python -m unittest discover --top-level-directory "Script/" --start-directory "Script/UnitTests/" --pattern "*Test.py" --verbose
\ No newline at end of file \ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment