面向对象 suite

Python 的面向对象设计特性允许我们在设计和构建 suite definition 时考虑灵活性。 设计每个 suite 有不同的准则。让我们考虑如何以一种更面向对象的方式设计本教程的例子。我们以一些设计准则开始。

  • 默认变量(例如 ECF_HOME 等)必须设置,并与 suite 独立
  • 新的 suite 必须开启自动检测 job 生成。
  • 需要将 definition 保存到单独的文件。
  • 新的 suite 应该能够复用为上面要求而设计的代码

下面是一种可行的设计,使用单例模式和模板模式。

  1. import os
  2. import ecflow
  3. class DefaultVariables(object):
  4. """Provide the setup variables for each suite"""
  5. def add_to(self, node):
  6. """Adds ECF_INCLUDE,ECF_HOME to the input node"""
  7. node.add_variable("ECF_INCLUDE", os.path.join(os.getenv("HOME"), "course"))
  8. node.add_variable("ECF_HOME", os.path.join(os.getenv("HOME"), "course"))
  9. class BaseSuiteBuilder(object):
  10. """Abstract class. Add default variables to suite and enable job creation
  11. checking for any derived suite
  12. """
  13. def __init__(self, default_variables):
  14. self.defs = ecflow.Defs()
  15. # use derived class name as suite name
  16. self.suite = self.defs.add_suite(type(self).__name__)
  17. default_variables.add_to(self.suite)
  18. def _build_definition_hook(self):
  19. """Derived suite should override this function to build the suite
  20. Should not be called explicitly. How could we enforce this ?
  21. """
  22. pass
  23. def setup(self):
  24. """Template/skeleton function.
  25. Provides common algorithm for *all* derivatives
  26. Uses Hollywood principle.
  27. """
  28. # Build the suite
  29. self._build_definition_hook()
  30. # check job creation. Could use an assert
  31. job_check_result = self.defs.check_job_creation()
  32. if len(job_check_result) != 0:
  33. print "Job creation failed\n" + job_check_result
  34. # Check trigger expressions and limit references"
  35. print self.defs.check()
  36. # Allows definition creation to be separated from the load
  37. # Use the class name as the name of the definition file
  38. self.defs.save_as_defs( type(self).__name__ + ".def")
  39. class SuiteBuilder(BaseSuiteBuilder):
  40. """My example suite. Generates SuiteBuilder.def"""
  41. def __init__(self, default_variables):
  42. BaseSuiteBuilder.__init__(self, default_variables)
  43. def _build_definition_hook(self):
  44. f1 = self.suite.add_family("family")
  45. f1.add_task("task1")
  46. f1.add_task("task2")
  47. class TestSuite(BaseSuiteBuilder):
  48. """My test suite. Generates TestSuite.def"""
  49. def __init__(self, default_variables):
  50. BaseSuiteBuilder.__init__(self, default_variables)
  51. def _build_definition_hook(self):
  52. self.suite.add_task("task1")
  53. if __name__ == "__main__":
  54. my_suite = SuiteBuilder(DefaultVariables())
  55. my_suite.setup()
  56. my_test_suite = TestSuite(DefaultVariables())
  57. my_test_suite.setup()