/ruffus/test/test_ruffus_utility.py

https://code.google.com/p/ruffus/ · Python · 509 lines · 240 code · 112 blank · 157 comment · 14 complexity · 2b9b4e9bef0ac98ba33db1635b1097f4 MD5 · raw file

  1. #!/usr/bin/env python
  2. ################################################################################
  3. #
  4. # test_ruffus_utility.py
  5. #
  6. #
  7. # Copyright (c) 2009 Leo Goodstadt
  8. #
  9. # Permission is hereby granted, free of charge, to any person obtaining a copy
  10. # of this software and associated documentation files (the "Software"), to deal
  11. # in the Software without restriction, including without limitation the rights
  12. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. # copies of the Software, and to permit persons to whom the Software is
  14. # furnished to do so, subject to the following conditions:
  15. #
  16. # The above copyright notice and this permission notice shall be included in
  17. # all copies or substantial portions of the Software.
  18. #
  19. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25. # THE SOFTWARE.
  26. #################################################################################
  27. """
  28. test_ruffus_utility.py
  29. """
  30. # use simplejson in place of json for python < 2.6
  31. try:
  32. import json
  33. except ImportError:
  34. import simplejson
  35. json = simplejson
  36. import unittest, os,sys
  37. if __name__ != '__main__':
  38. raise Exception ("This is not a callable module [%s]" % __main__)
  39. exe_path = os.path.split(os.path.abspath(sys.argv[0]))[0]
  40. sys.path.insert(0, os.path.abspath(os.path.join(exe_path,"..", "..")))
  41. from ruffus import *
  42. from ruffus.ruffus_utility import *
  43. os.chdir(exe_path)
  44. import unittest, time
  45. #_________________________________________________________________________________________
  46. # get_nested_tasks_or_globs
  47. #_________________________________________________________________________________________
  48. class Test_get_nested_tasks_or_globs(unittest.TestCase):
  49. def setUp(self):
  50. exe_path = os.path.split(os.path.abspath(sys.argv[0]))[0]
  51. os.chdir(exe_path)
  52. # self.assertEqual(self.seq, range(10))
  53. # self.assert_(element in self.seq)
  54. # self.assertRaises(ValueError, random.sample, self.seq, 20)
  55. def check_equal (self, a,b):
  56. self.assertEqual(get_nested_tasks_or_globs(a), b)
  57. def test_get_nested_tasks_or_globs(self):
  58. #
  59. # test strings
  60. #
  61. self.check_equal("test", (set(), set(), set()))
  62. self.check_equal([("test1",), "test2", 3], (set(), set(), set()))
  63. #
  64. # test missing
  65. #
  66. self.check_equal((1,3, [5]), (set(), set(), set()))
  67. self.check_equal(None, (set(), set(), set()))
  68. #
  69. # test glob
  70. #
  71. self.check_equal([("test1.*",), "test?2", 3], (set(), set(['test1.*', 'test?2']), set()))
  72. #
  73. # test glob and string
  74. #
  75. self.check_equal([("test*1",), (("test3",),),"test2", 3], (set(), set(['test*1']), set()))
  76. #
  77. # test task function
  78. #
  79. self.check_equal(is_glob, (set([is_glob]), set([]), set()))
  80. self.check_equal([is_glob, [1, "this", ["that*", 5]], [(get_strings_in_nested_sequence,)]], (
  81. set([is_glob, get_strings_in_nested_sequence]), set(["that*"]), set()))
  82. #
  83. # test wrapper
  84. #
  85. self.check_equal(output_from(is_glob, ["what", 7], 5), (set([is_glob, "what"]), set([]), set()))
  86. #_________________________________________________________________________________________
  87. # replace_func_names_with_tasks
  88. #_________________________________________________________________________________________
  89. class Test_replace_func_names_with_tasks(unittest.TestCase):
  90. def setUp(self):
  91. exe_path = os.path.split(os.path.abspath(sys.argv[0]))[0]
  92. os.chdir(exe_path)
  93. # self.assertEqual(self.seq, range(10))
  94. # self.assert_(element in self.seq)
  95. # self.assertRaises(ValueError, random.sample, self.seq, 20)
  96. def check_equal (self, a,b, d):
  97. self.assertEqual(replace_func_names_with_tasks(a, d), b)
  98. def test_replace_func_names_with_tasks(self):
  99. func_or_name_to_task = {is_glob: "FF is_glob", "what" : "FF what", get_strings_in_nested_sequence: "FF get_strings_in_nested_sequence"}
  100. #
  101. # test strings
  102. #
  103. self.check_equal("test", "test", func_or_name_to_task)
  104. self.check_equal( [("test1",), "test2", 3],
  105. [("test1",), "test2", 3],
  106. func_or_name_to_task)
  107. #
  108. # test missing
  109. #
  110. self.check_equal((1,3, [5]), (1,3, [5]), func_or_name_to_task)
  111. self.check_equal(None, None, func_or_name_to_task)
  112. #
  113. # test task function
  114. #
  115. self.check_equal(is_glob, "FF is_glob", func_or_name_to_task)
  116. self.check_equal([is_glob, [1, "this", ["that*", 5]], [(get_strings_in_nested_sequence,)]],
  117. ["FF is_glob", [1, "this", ["that*", 5]], [("FF get_strings_in_nested_sequence",)]],
  118. func_or_name_to_task)
  119. #
  120. # test wrapper
  121. #
  122. self.check_equal(output_from(is_glob, ["what", 7], 5),
  123. ["FF is_glob", ["FF what", 7], 5],
  124. func_or_name_to_task)
  125. self.check_equal(output_from(is_glob),
  126. "FF is_glob",
  127. func_or_name_to_task)
  128. self.check_equal([1, output_from(is_glob, ["what", 7], 5)],
  129. [1, "FF is_glob", ["FF what", 7], 5],
  130. func_or_name_to_task)
  131. self.check_equal([1, output_from(is_glob), ["what", 7], 5],
  132. [1, "FF is_glob", ["what", 7], 5],
  133. func_or_name_to_task)
  134. #_________________________________________________________________________________________
  135. # non_str_sequence
  136. #_________________________________________________________________________________________
  137. class Test_non_str_sequence(unittest.TestCase):
  138. def test_non_str_sequence (self):
  139. """
  140. non_str_sequence()
  141. """
  142. test_str1 = "asfas"
  143. class inherited_str (str):
  144. #
  145. # use __new__ instead of init because str is immutable
  146. #
  147. def __new__( cls, a):
  148. obj = super( inherited_str, cls).__new__( inherited_str, a )
  149. return obj
  150. test_str2 = inherited_str("test")
  151. class inherited_list (list):
  152. def __init__ (self, *param):
  153. list.__init__(self, *param)
  154. test_str3 = list(test_str1)
  155. test_str4 = inherited_list(test_str2)
  156. self.assert_(not non_str_sequence(test_str1))
  157. self.assert_(not non_str_sequence(test_str2))
  158. self.assert_(non_str_sequence(test_str3))
  159. self.assert_(non_str_sequence(test_str4))
  160. #_________________________________________________________________________________________
  161. # get_strings_in_nested_sequence
  162. #_________________________________________________________________________________________
  163. class Test_get_strings_in_nested_sequence(unittest.TestCase):
  164. def test_get_strings_in_nested_sequence (self):
  165. """
  166. get_strings_in_nested_sequence()
  167. """
  168. class inherited_str (str):
  169. #
  170. # use __new__ instead of init because str is immutable
  171. #
  172. def __new__( cls, a):
  173. obj = super( inherited_str, cls).__new__( inherited_str, a )
  174. return obj
  175. class inherited_list (list):
  176. def __init__ (self, *param):
  177. list.__init__(self, *param)
  178. self.assertEqual(get_strings_in_nested_sequence("one"), ["one"])
  179. self.assertEqual(get_strings_in_nested_sequence(["one", "two"]), ["one", "two"])
  180. self.assertEqual(get_strings_in_nested_sequence(["one", 1, "two"]), ["one", "two"])
  181. self.assertEqual(get_strings_in_nested_sequence(["one", [1, ["two"]]]), ["one", "two"])
  182. self.assertEqual(get_strings_in_nested_sequence([inherited_str("one"), [1, ["two"]]]), [inherited_str("one"), "two"])
  183. self.assertEqual(get_strings_in_nested_sequence(inherited_list([inherited_str("one"), [1, ["two"]]])),
  184. inherited_list([inherited_str("one"), "two"]))
  185. #_________________________________________________________________________________________
  186. # get_first_strings_in_nested_sequence
  187. #_________________________________________________________________________________________
  188. class Test_get_first_strings_in_nested_sequence(unittest.TestCase):
  189. def test_get_first_strings_in_nested_sequence (self):
  190. """
  191. get_first_strings_in_nested_sequence()
  192. """
  193. class inherited_str (str):
  194. #
  195. # use __new__ instead of init because str is immutable
  196. #
  197. def __new__( cls, a):
  198. obj = super( inherited_str, cls).__new__( inherited_str, a )
  199. return obj
  200. class inherited_list (list):
  201. def __init__ (self, *param):
  202. list.__init__(self, *param)
  203. self.assertEqual(get_strings_in_nested_sequence("one", True), ["one"])
  204. self.assertEqual(get_strings_in_nested_sequence(["one", "two"], True), ["one", "two"])
  205. self.assertEqual(get_strings_in_nested_sequence(["one", 1, "two"], True), ["one", "two"])
  206. self.assertEqual(get_strings_in_nested_sequence(["one", [1, ["two"]]], True), ["one", "two"])
  207. self.assertEqual(get_strings_in_nested_sequence([inherited_str("one"), [1, ["two"]]], True), [inherited_str("one"), "two"])
  208. self.assertEqual(get_strings_in_nested_sequence(inherited_list([inherited_str("one"), [1, ["two"]]]), True),
  209. inherited_list([inherited_str("one"), "two"]))
  210. self.assertEqual(get_strings_in_nested_sequence(["one", [1, ["two"], "three"]], True), ["one", "two"])
  211. d = {"four" :4}
  212. self.assertEqual(get_strings_in_nested_sequence(["one", [1, [d, "two"], "three"]], True), ["one", "two"])
  213. self.assertEqual(get_strings_in_nested_sequence(None, True), [])
  214. self.assertEqual(get_strings_in_nested_sequence([], True), [])
  215. self.assertEqual(get_strings_in_nested_sequence([1,2,3, d], True), [])
  216. #_________________________________________________________________________________________
  217. # Test_compile_regex
  218. #_________________________________________________________________________________________
  219. class Test_compile_regex (unittest.TestCase):
  220. def test_compile_regex (self):
  221. compile_regex("Dummy Task", regex(".*"), Exception, "test1")
  222. # bad regex
  223. self.assertRaises(Exception, compile_regex, "Dummy Task", regex(".*)"), Exception, "test1")
  224. try:
  225. compile_regex("Dummy Task", regex(".*)"), Exception, "test1")
  226. except Exception, e:
  227. self.assertEqual(e.args, ('Dummy Task', "test1: regular expression regex('.*)') is malformed\n[sre_constants.error: (unbalanced parenthesis)]"))
  228. # bad number of items regex
  229. self.assertRaises(Exception, compile_regex, "Dummy Task", regex(".*", "o"), Exception, "test1")
  230. try:
  231. compile_regex("Dummy Task", regex(".*", "o"), Exception, "test1")
  232. except Exception, e:
  233. self.assertEqual(e.args, ('Dummy Task', "test1: regex('('.*', 'o')') is malformed\nregex(...) should only be used to wrap a single regular expression string"))
  234. # 0 number of items regex
  235. self.assertRaises(Exception, compile_regex, "Dummy Task", regex(), Exception, "test1")
  236. try:
  237. compile_regex("Dummy Task", regex(), Exception, "test1")
  238. except Exception, e:
  239. self.assertEqual(e.args, ('Dummy Task', 'test1: regex() is malformed\nregex(...) should be used to wrap a regular expression string'))
  240. # bad number of items suffix
  241. self.assertRaises(Exception, compile_suffix, "Dummy Task", suffix(".*", "o"), Exception, "test1")
  242. try:
  243. compile_suffix("Dummy Task", suffix(".*", "o"), Exception, "test1")
  244. except Exception, e:
  245. self.assertEqual(e.args, ('Dummy Task', "test1: suffix('('.*', 'o')') is malformed.\nsuffix(...) should only be used to wrap a single string matching the suffices of file names"))
  246. # 0 number of items suffix
  247. self.assertRaises(Exception, compile_suffix, "Dummy Task", suffix(), Exception, "test1")
  248. try:
  249. compile_suffix("Dummy Task", suffix(), Exception, "test1")
  250. except Exception, e:
  251. self.assertEqual(e.args, ('Dummy Task', 'test1: suffix() is malformed.\nsuffix(...) should be used to wrap a string matching the suffices of file names'))
  252. #_________________________________________________________________________________________
  253. # Test_check_files_io_parameters
  254. #_________________________________________________________________________________________
  255. class Test_check_files_io_parameters (unittest.TestCase):
  256. def test_check_files_io_parameters(self):
  257. class t_fake_task(object):
  258. def __init__ (self):
  259. self._action_type = None
  260. self._name = "fake task"
  261. fake_task = t_fake_task()
  262. single_job_params = [["input", "output"]]
  263. multiple_job_params = [["input1", "output1"], ["input2", "output2"]]
  264. check_files_io_parameters (fake_task, single_job_params, error_task_files)
  265. check_files_io_parameters (fake_task, multiple_job_params, error_task_files)
  266. #Bad format
  267. bad_single_job_params = ["input", "output"]
  268. self.assertRaises(error_task_files, check_files_io_parameters, fake_task, bad_single_job_params, error_task_files)
  269. #Missing output files for job
  270. bad_multiple_job_params = [["input1", "output1"], ["input2"]]
  271. self.assertRaises(error_task_files, check_files_io_parameters, fake_task, bad_multiple_job_params, error_task_files)
  272. #Missing input files for job
  273. bad_multiple_job_params = [["input1", "output1"], []]
  274. self.assertRaises(error_task_files, check_files_io_parameters, fake_task, bad_multiple_job_params, error_task_files)
  275. #Input or output file parameters should contain at least one or more file names strings
  276. bad_multiple_job_params = [[1, 2]]
  277. self.assertRaises(error_task_files, check_files_io_parameters, fake_task, bad_multiple_job_params, error_task_files)
  278. #_________________________________________________________________________________________
  279. # Test_get_first_string_in_nested_sequence
  280. #_________________________________________________________________________________________
  281. class Test_get_first_string_in_nested_sequence (unittest.TestCase):
  282. def test_get_first_string_in_nested_sequence(self):
  283. self.assertEqual(get_first_string_in_nested_sequence("a") , "a")
  284. self.assertEqual(get_first_string_in_nested_sequence(None) , None)
  285. self.assertEqual(get_first_string_in_nested_sequence(1) , None)
  286. self.assertEqual(get_first_string_in_nested_sequence((1,2)) , None)
  287. self.assertEqual(get_first_string_in_nested_sequence((1,2, "a")) , "a")
  288. self.assertEqual(get_first_string_in_nested_sequence((1,2, "a")) , "a")
  289. self.assertEqual(get_first_string_in_nested_sequence((1,[2,"b"], "a")) , "b")
  290. self.assertEqual(get_first_string_in_nested_sequence((1,set([2,"b"]), "a")) , "b")
  291. #_________________________________________________________________________________________
  292. # Test_check_parallel_parameters
  293. #_________________________________________________________________________________________
  294. class Test_check_parallel_parameters (unittest.TestCase):
  295. def test_check_parallel_parameters(self):
  296. class t_fake_task(object):
  297. def __init__ (self):
  298. self._action_type = None
  299. self._name = "fake task"
  300. fake_task = t_fake_task()
  301. single_job_params = [["input", "output"]]
  302. multiple_job_params = [["input1", "output1"], ["input2", "output2"]]
  303. check_parallel_parameters (fake_task, single_job_params, error_task_files)
  304. check_parallel_parameters (fake_task, multiple_job_params, error_task_files)
  305. #Bad format
  306. bad_single_job_params = ["input", "output"]
  307. self.assertRaises(error_task_parallel, check_parallel_parameters, fake_task, bad_single_job_params, error_task_parallel)
  308. #_________________________________________________________________________________________
  309. # expand_nested_tasks_or_globs
  310. #_________________________________________________________________________________________
  311. class Test_expand_nested_tasks_or_globs(unittest.TestCase):
  312. def setUp(self):
  313. exe_path = os.path.split(os.path.abspath(sys.argv[0]))[0]
  314. os.chdir(exe_path)
  315. t1 = task._task("module", "func1");
  316. t2 = task._task("module", "func2");
  317. t3 = task._task("module", "func3");
  318. self.tasks = [t1, t2, t3]
  319. # self.assertEqual(self.seq, range(10))
  320. # self.assert_(element in self.seq)
  321. # self.assertRaises(ValueError, random.sample, self.seq, 20)
  322. def check_equal (self, a,b):
  323. tasks, globs, runtime_data_names = get_nested_tasks_or_globs(a)
  324. func_or_name_to_task = dict(zip((non_str_sequence, get_strings_in_nested_sequence, "what"), self.tasks))
  325. task_or_glob_to_files = dict()
  326. #for f in func_or_name_to_task:
  327. # print f, task_or_glob_to_files[func_or_name_to_task[f]]
  328. task_or_glob_to_files[self.tasks[0] ] = ["t1a", "t1b"] # non_str_sequence
  329. task_or_glob_to_files[self.tasks[1] ] = ["t2"] # get_strings_in_nested_sequence
  330. task_or_glob_to_files[self.tasks[2] ] = ["t3"] # "what"
  331. task_or_glob_to_files["that*" ] = ["that1", "that2"]
  332. task_or_glob_to_files["test*1" ] = ["test11","test21"]
  333. task_or_glob_to_files["test1.*"] = ["test1.1", "test1.2"]
  334. task_or_glob_to_files["test?2" ] = ["test12"]
  335. param_a = replace_func_names_with_tasks(a, func_or_name_to_task)
  336. self.assertEqual(expand_nested_tasks_or_globs(param_a, task_or_glob_to_files), b)
  337. def test_expand_nested_tasks_or_globs(self):
  338. #
  339. # test strings
  340. #
  341. self.check_equal("test", "test")
  342. self.check_equal([("test1",), "test2", 3], [("test1",), "test2", 3])
  343. #
  344. # test missing
  345. #
  346. self.check_equal(None, None)
  347. #
  348. # test glob
  349. #
  350. self.check_equal([("test1.*",), "test?2", 3],
  351. [("test1.1","test1.2"), "test12", 3])
  352. self.check_equal(["test1.*", "test?2", 3],
  353. ["test1.1","test1.2", "test12", 3])
  354. #
  355. # test glob and string
  356. #
  357. self.check_equal([("test*1",), (("test3",),),"test2", 3],
  358. [("test11","test21"), (("test3",),),"test2", 3])
  359. #
  360. # test task function
  361. #
  362. self.check_equal(non_str_sequence, ["t1a", "t1b"])
  363. self.check_equal(get_strings_in_nested_sequence, ["t2"])
  364. self.check_equal([get_strings_in_nested_sequence, non_str_sequence], ["t2", "t1a", "t1b"])
  365. self.check_equal([non_str_sequence, [1, "this", ["that*", 5]], [(get_strings_in_nested_sequence,)]],
  366. ['t1a', 't1b', [1, 'this', ['that1', 'that2', 5]], [('t2',)]])
  367. #
  368. # test wrapper
  369. #
  370. self.check_equal(output_from(non_str_sequence, ["what", 7], 5),
  371. ['t1a', 't1b', ['t3', 7], 5])
  372. #
  373. #
  374. #_________________________________________________________________________________________
  375. # Test_regex_replace
  376. #_________________________________________________________________________________________
  377. class Test_regex_replace (unittest.TestCase):
  378. def helper (self, data, result):
  379. try_result = regex_replace("aaa.bbb.ccc.aaa",
  380. re.compile("([a-z]+)\.([a-z]+)\.([a-z]+)\.([a-z]+)"),
  381. data)
  382. self.assertEqual(try_result , result)
  383. def test_regex_replace(self):
  384. self.helper(r"\3.\2.\1", "ccc.bbb.aaa")
  385. self.helper(None, None)
  386. self.helper(1, 1)
  387. self.helper([r"\3.\2.\1", 1], ["ccc.bbb.aaa", 1])
  388. # note set is constructed with substituted results!
  389. self.helper([r"\3.\2.\1", 1, (set([r"\1\2", r"\4\2", "aaabbb"]), "whatever", {1:2, 3:4})],
  390. ['ccc.bbb.aaa', 1, (set(['aaabbb']), 'whatever', {1: 2, 3: 4})])
  391. #
  392. # debug parameter ignored if called as a module
  393. #
  394. if sys.argv.count("--debug"):
  395. sys.argv.remove("--debug")
  396. #sys.argv.append("Test_regex_replace")
  397. unittest.main()