def test_getitem(self): plugin_a = Plugin.wrap_function("test_plugin_a", "testing plugin a", lambda ctx: "execute a") plugin_b = Plugin.wrap_function("test_plugin_b", "testing plugin b", lambda ctx: "execute b") plugin_manager_a = PluginManager() plugin_manager_a.register(plugin_a) plugin_manager_a.register(plugin_b) plugin_a1 = Plugin.wrap_function("test_plugin_a", "testing plugin a 1", lambda ctx: "execute a 1") plugin_manager_b = PluginManager() plugin_manager_b.register(plugin_a1) plugin_mgr_chain = PluginManagerChain(plugin_manager_b, plugin_manager_a) plugin_mgr_chain.sys_prepare(None) # 优先获取最优先的插件 self.assertEquals(plugin_mgr_chain["test_plugin_a"].execute(None), "execute a 1") self.assertEquals(plugin_mgr_chain["test_plugin_b"].execute(None), "execute b") self.failUnlessException(PluginNotFoundException, PluginManagerChain.plugin, plugin_mgr_chain, "test_plugin_c")
def test_wrap_class(self): """测试wrap_class类方法 """ class TestPlugin(object): """testing plugin""" def __init__(self, a, b): self.a = a self.b = b def execute(self, context, arg): return "execute {0} {1}".format(arg, self.a + self.b) def sys_prepare(self, config): return "sys_prepare" def sys_cleanup(self, config): return "sys_cleanup" plugin = Plugin.wrap_class(TestPlugin, a=1, b=2) self.assertEquals(plugin.name, "TestPlugin") self.assertEquals(plugin.description, "testing plugin") self.assertEquals(plugin.sys_prepare(None), "sys_prepare") self.assertEquals(plugin.execute(None, "cat"), "execute cat 3") self.assertEquals(plugin.sys_cleanup(None), "sys_cleanup") # 复制一个TestPlugin并替换掉execute方法,检测参数错误 test_plugin = type("TestPluginA", tuple(), dict(TestPlugin.__dict__)) def execute(self): return "execute" setattr(test_plugin, "execute", execute) self.failUnlessException( InvalidPluginException, Plugin.wrap_class, test_plugin, 1, 2 ) test_plugin = type("TestPluginB", tuple(), dict(TestPlugin.__dict__)) def sys_prepare(self, config, x): return "sys_prepare" setattr(test_plugin, "sys_prepare", sys_prepare) self.failUnlessException( InvalidPluginException, Plugin.wrap_class, test_plugin, 1, 2 ) # 测试名称属性 test_plugin = type("TestPluginC", tuple(), dict(TestPlugin.__dict__)) test_plugin.name = "hehe" plugin = Plugin.wrap_class(test_plugin, 1, 2) self.assertEquals(plugin.name, "hehe")
def test_wrap_function(self): """测试wrap_function类方法 """ # 只包装一个execute函数的时候 plugin = Plugin.wrap_function( "testing", "testing plugin", lambda ctx, arg: "execute {}".format(arg)) self.failUnlessException( PluginUnPreparedException, Plugin.execute, plugin, None, "cat") plugin.sys_prepare(None) self.assertEquals(plugin.execute(None, "cat"), "execute cat") plugin.sys_cleanup(None) self.failUnlessException( PluginAlreadyDeadException, Plugin.execute, plugin, None) # 包装错误的函数对象 self.failUnlessException( InvalidPluginException, Plugin.wrap_function, "testing", "testing plugin", lambda: "hello" ) self.failUnlessException( InvalidPluginException, Plugin.wrap_function, "testing", "testing plugin", lambda ctx: "execute", lambda config, args: "sys_prepare" ) plugin = Plugin.wrap_function( "testing", "testing plugin", lambda ctx, arg: "execute {}".format(arg), lambda config: "sys_prepare a = {}".format(config["plugin"]["a"]), lambda config: "sys_cleanup", (Rule("arg", required=True, type=str, min=3, max=10),), (Rule("plugin.a", required=True, type=int, min=1, max=3),) ) cfg = Config({"plugin": {"a": -1}}) self.failUnlessException( InvalidArgumentException, plugin.sys_prepare, cfg) cfg = Config({"plugin": {"a": 1}}) self.assertEquals(plugin.sys_prepare(cfg), "sys_prepare a = 1") self.assertEquals(plugin.execute(None, "cat"), "execute cat") self.failUnlessException( InvalidArgumentException, plugin.execute, None, "c") self.assertEquals(plugin.sys_cleanup(None), "sys_cleanup")
def setUp(self): self.plugin_manager = PluginManager() self.plugin_a = Plugin.wrap_function( "test_plugin_a", "testing plugin a", lambda ctx: "execute a") self.plugin_b = Plugin.wrap_function( "test_plugin_b", "testing plugin b", lambda ctx: "execute b") self.plugin_manager.register(self.plugin_a) self.plugin_manager.register(self.plugin_b)
def __init__(self, config, *plugins): if plugins: self._plugins = plugins else: self._plugins = [ Plugin.wrap_function("plugin_a", "plugin a", lambda ctx: "plugin a"), Plugin.wrap_function("plugin_b", "plugin b", lambda ctx: "plugin b") ] self._config = config
def __init__(self, config, *plugins): if plugins: self._plugins = plugins else: self._plugins = [ Plugin.wrap_function( "plugin_a", "plugin a", lambda ctx: "plugin a"), Plugin.wrap_function( "plugin_b", "plugin b", lambda ctx: "plugin b") ] self._config = config
def setUp(self): self.plugin_manager = PluginManager() self.plugin_a = Plugin.wrap_function("test_plugin_a", "testing plugin a", lambda ctx: "execute a") self.plugin_b = Plugin.wrap_function("test_plugin_b", "testing plugin b", lambda ctx: "execute b") self.plugin_manager.register(self.plugin_a) self.plugin_manager.register(self.plugin_b)
def test_wrap_class(self): """测试wrap_class类方法 """ class TestPlugin(object): """testing plugin""" def __init__(self, a, b): self.a = a self.b = b def execute(self, context, arg): return "execute {0} {1}".format(arg, self.a + self.b) def sys_prepare(self, config): return "sys_prepare" def sys_cleanup(self, config): return "sys_cleanup" plugin = Plugin.wrap_class(TestPlugin, a=1, b=2) self.assertEquals(plugin.name, "TestPlugin") self.assertEquals(plugin.description, "testing plugin") self.assertEquals(plugin.sys_prepare(None), "sys_prepare") self.assertEquals(plugin.execute(None, "cat"), "execute cat 3") self.assertEquals(plugin.sys_cleanup(None), "sys_cleanup") # 复制一个TestPlugin并替换掉execute方法,检测参数错误 test_plugin = type("TestPluginA", tuple(), dict(TestPlugin.__dict__)) def execute(self): return "execute" setattr(test_plugin, "execute", execute) self.failUnlessException(InvalidPluginException, Plugin.wrap_class, test_plugin, 1, 2) test_plugin = type("TestPluginB", tuple(), dict(TestPlugin.__dict__)) def sys_prepare(self, config, x): return "sys_prepare" setattr(test_plugin, "sys_prepare", sys_prepare) self.failUnlessException(InvalidPluginException, Plugin.wrap_class, test_plugin, 1, 2) # 测试名称属性 test_plugin = type("TestPluginC", tuple(), dict(TestPlugin.__dict__)) test_plugin.name = "hehe" plugin = Plugin.wrap_class(test_plugin, 1, 2) self.assertEquals(plugin.name, "hehe")
def test_lifecycle(self): """测试Plugin的构造和生命周期 """ plugin = Plugin( name="testing", description="testing plugin", execute=lambda ctx, arg: "execute {}".format(arg), sys_prepare=lambda config: "sys_prepare", sys_cleanup=lambda config: "sys_cleanup", args_validator=None, config_validator=None ) self.assertEquals(plugin.sys_prepare(None), "sys_prepare") self.assertEquals(plugin.execute(None, "cat"), "execute cat") self.assertEquals(plugin.sys_cleanup(None), "sys_cleanup") # 已经cleanup之后再去执行会抛出PluginAlreadyDeadException self.failUnlessException( PluginAlreadyDeadException, Plugin.execute, plugin, None, "cat") # 重复执行sys_prepare操作会抛出PluginAlreadyPreparedException self.failUnlessException( PluginAlreadyPreparedException, Plugin.sys_prepare, plugin, None) plugin = Plugin( name="testing", description="testing plugin", execute=lambda ctx, arg: "execute {}".format(arg), sys_prepare=lambda config: "sys_prepare", sys_cleanup=lambda config: "sys_cleanup", args_validator=None, config_validator=None ) # 尚未执行初始化时执行会抛出PluginUnPreparedException self.failUnlessException( PluginUnPreparedException, Plugin.execute, plugin, None, "cat") # 尚未执行初始化时清理会抛出PluginUnPreparedException self.failUnlessException( PluginUnPreparedException, Plugin.sys_cleanup, plugin, None)
def test_replace(self): """测试插件替换 """ plugin_a = Plugin.wrap_function("test_plugin_a", "testing plugin a", lambda ctx: "execute new a") self.plugin_manager.replace(plugin_a) self.plugin_manager.sys_prepare(None) self.assertEquals(self.plugin_manager["test_plugin_a"].execute(None), "execute new a")
def test_wrap_function(self): """测试wrap_function类方法 """ # 只包装一个execute函数的时候 plugin = Plugin.wrap_function( "testing", "testing plugin", lambda ctx, arg: "execute {}".format(arg)) self.failUnlessException(PluginUnPreparedException, Plugin.execute, plugin, None, "cat") plugin.sys_prepare(None) self.assertEquals(plugin.execute(None, "cat"), "execute cat") plugin.sys_cleanup(None) self.failUnlessException(PluginAlreadyDeadException, Plugin.execute, plugin, None) # 包装错误的函数对象 self.failUnlessException(InvalidPluginException, Plugin.wrap_function, "testing", "testing plugin", lambda: "hello") self.failUnlessException(InvalidPluginException, Plugin.wrap_function, "testing", "testing plugin", lambda ctx: "execute", lambda config, args: "sys_prepare") plugin = Plugin.wrap_function( "testing", "testing plugin", lambda ctx, arg: "execute {}".format(arg), lambda config: "sys_prepare a = {}".format(config["plugin"]["a"]), lambda config: "sys_cleanup", (Rule("arg", required=True, type=str, min=3, max=10), ), (Rule("plugin.a", required=True, type=int, min=1, max=3), )) cfg = Config({"plugin": {"a": -1}}) self.failUnlessException(InvalidArgumentException, plugin.sys_prepare, cfg) cfg = Config({"plugin": {"a": 1}}) self.assertEquals(plugin.sys_prepare(cfg), "sys_prepare a = 1") self.assertEquals(plugin.execute(None, "cat"), "execute cat") self.failUnlessException(InvalidArgumentException, plugin.execute, None, "c") self.assertEquals(plugin.sys_cleanup(None), "sys_cleanup")
def setUp(self): # 构建测试所需要的插件 plugin_mgr = PluginManager() def add_one(ctx, num): return num + 1 add_one_plugin = Plugin.wrap_function("add_one", "add one", add_one) plugin_mgr.register(add_one_plugin) def add_two(ctx, num): return num + 2 add_two_plugin = Plugin.wrap_function("add_two", "add two", add_two) plugin_mgr.register(add_two_plugin) def add_three(ctx, num): value = num + 3 ctx["add_three"] = value add_three_plugin = Plugin.wrap_function("add_three", "add three", add_three) plugin_mgr.register(add_three_plugin) def division(ctx, a, b): return a / b division_plugin = Plugin.wrap_function("division", "division", division) plugin_mgr.register(division_plugin) def add_four(ctx, num): if num < 0: raise InvalidArgumentException("num must more than zero!") return num + 4 add_four_plugin = Plugin.wrap_function("add_four", "add four", add_four) plugin_mgr.register(add_four_plugin) plugin_mgr.sys_prepare(None) self.plugin_mgr = plugin_mgr
def test_replace(self): """测试插件替换 """ plugin_a = Plugin.wrap_function( "test_plugin_a", "testing plugin a", lambda ctx: "execute new a") self.plugin_manager.replace(plugin_a) self.plugin_manager.sys_prepare(None) self.assertEquals( self.plugin_manager["test_plugin_a"].execute(None), "execute new a")
def test_getitem(self): plugin_a = Plugin.wrap_function( "test_plugin_a", "testing plugin a", lambda ctx: "execute a" ) plugin_b = Plugin.wrap_function( "test_plugin_b", "testing plugin b", lambda ctx: "execute b" ) plugin_manager_a = PluginManager() plugin_manager_a.register(plugin_a) plugin_manager_a.register(plugin_b) plugin_a1 = Plugin.wrap_function( "test_plugin_a", "testing plugin a 1", lambda ctx: "execute a 1" ) plugin_manager_b = PluginManager() plugin_manager_b.register(plugin_a1) plugin_mgr_chain = PluginManagerChain( plugin_manager_b, plugin_manager_a) plugin_mgr_chain.sys_prepare(None) # 优先获取最优先的插件 self.assertEquals( plugin_mgr_chain["test_plugin_a"].execute(None), "execute a 1") self.assertEquals( plugin_mgr_chain["test_plugin_b"].execute(None), "execute b") self.failUnlessException( PluginNotFoundException, PluginManagerChain.plugin, plugin_mgr_chain, "test_plugin_c")
def setUp(self): # 构建测试所需要的插件 plugin_mgr = PluginManager() def add_one(ctx, num): return num + 1 add_one_plugin = Plugin.wrap_function("add_one", "add one", add_one) plugin_mgr.register(add_one_plugin) def add_two(ctx, num): return num + 2 add_two_plugin = Plugin.wrap_function("add_two", "add two", add_two) plugin_mgr.register(add_two_plugin) def add_three(ctx, num): value = num + 3 ctx["add_three"] = value add_three_plugin = Plugin.wrap_function( "add_three", "add three", add_three) plugin_mgr.register(add_three_plugin) def division(ctx, a, b): return a / b division_plugin = Plugin.wrap_function( "division", "division", division) plugin_mgr.register(division_plugin) def add_four(ctx, num): if num < 0: raise InvalidArgumentException("num must more than zero!") return num + 4 add_four_plugin = Plugin.wrap_function( "add_four", "add four", add_four) plugin_mgr.register(add_four_plugin) plugin_mgr.sys_prepare(None) self.plugin_mgr = plugin_mgr
def test_wrap_module(self): """测试wrap_module类方法 """ plugin_module = imp.new_module("test_plugin") plugin_module.execute = lambda ctx, arg: "execute {}".format(arg) plugin = Plugin.wrap_module(plugin_module) self.assertEquals(plugin.name, "test_plugin") plugin.sys_prepare(None) self.assertEquals(plugin.execute(None, "cat"), "execute cat") plugin_module.execute = lambda: "execute" self.failUnlessException(InvalidPluginException, Plugin.wrap_module, plugin_module)
def test_wrap_module(self): """测试wrap_module类方法 """ plugin_module = imp.new_module("test_plugin") plugin_module.execute = lambda ctx, arg: "execute {}".format(arg) plugin = Plugin.wrap_module(plugin_module) self.assertEquals(plugin.name, "test_plugin") plugin.sys_prepare(None) self.assertEquals(plugin.execute(None, "cat"), "execute cat") plugin_module.execute = lambda: "execute" self.failUnlessException( InvalidPluginException, Plugin.wrap_module, plugin_module )
def test_lifecycle(self): """测试Plugin的构造和生命周期 """ plugin = Plugin(name="testing", description="testing plugin", execute=lambda ctx, arg: "execute {}".format(arg), sys_prepare=lambda config: "sys_prepare", sys_cleanup=lambda config: "sys_cleanup", args_validator=None, config_validator=None) self.assertEquals(plugin.sys_prepare(None), "sys_prepare") self.assertEquals(plugin.execute(None, "cat"), "execute cat") self.assertEquals(plugin.sys_cleanup(None), "sys_cleanup") # 已经cleanup之后再去执行会抛出PluginAlreadyDeadException self.failUnlessException(PluginAlreadyDeadException, Plugin.execute, plugin, None, "cat") # 重复执行sys_prepare操作会抛出PluginAlreadyPreparedException self.failUnlessException(PluginAlreadyPreparedException, Plugin.sys_prepare, plugin, None) plugin = Plugin(name="testing", description="testing plugin", execute=lambda ctx, arg: "execute {}".format(arg), sys_prepare=lambda config: "sys_prepare", sys_cleanup=lambda config: "sys_cleanup", args_validator=None, config_validator=None) # 尚未执行初始化时执行会抛出PluginUnPreparedException self.failUnlessException(PluginUnPreparedException, Plugin.execute, plugin, None, "cat") # 尚未执行初始化时清理会抛出PluginUnPreparedException self.failUnlessException(PluginUnPreparedException, Plugin.sys_cleanup, plugin, None)
# cmd args parser cmd_parser = argparse.ArgumentParser(u"加1减2") cmd_parser.add_argument("--start-num", dest="start_num", help=u"起始值", default="0") # 插件 plugins = [ "multiply", ] plugin_manager = PluginManager() def multiply(ctx, a, b): return a * b plugin_manager.register( Plugin.wrap_function("multiply", "multiply number", multiply)) def add(ctx, a, b): return a + b plugin_manager.register(Plugin.wrap_function("add", "add number", add)) def minus(ctx, a, b): result = a - b with open(os.path.expanduser("~/test_workflow.txt"), "a") as f: f.write("{}\n".format(result)) return result plugin_manager.register(Plugin.wrap_function("minus", "minus number", minus)) # 配置
def test_execute(self): """测试Job运行 """ plugin_mgr_fixture = PluginMgrFixture(None) self.useFixture(plugin_mgr_fixture) plugin_mgr = plugin_mgr_fixture.plugin_manager plugin = Plugin.wrap_function( "test_job", "test job", lambda ctx, a, b, c: a + b + c) plugin_mgr.register(plugin) plugin_mgr.sys_prepare(None, "test_job") def add_one(ctx, x): ctx["a"] += x plugin = Plugin.wrap_function("add_one", "add one", add_one) plugin_mgr.register(plugin) plugin_mgr.sys_prepare(None, "add_one") ctx = Context(None, {}, {}, plugin_mgr, None) job = Job( "test_job", args=(1, 2, 3) ) self.assertEquals(job.execute(ctx), 6) # 当上下文中的参数是列表时,上下文中的参数取代列表 ctx = Context(None, {}, {"test_job": (-1, -2, -3)}, plugin_mgr, None) self.assertEquals(job.execute(ctx), -6) # 测试使用上下文中的变量 ctx = Context(None, {}, { "test_job": ("$a", "$b", "$c") }, plugin_mgr, None) ctx["a"], ctx["b"], ctx["c"] = 5, 6, 7 self.assertEquals(job.execute(ctx), 5 + 6 + 7) # 字符串 ctx = Context(None, {}, { "test_job": ("a", "b", "cd") }, plugin_mgr, None) self.assertEquals(job.execute(ctx), "abcd") # 字典参数 job = Job( "test_job", args={ "a": 1, "b": 2, "c": 3 } ) ctx = Context(None, {}, {}, plugin_mgr, None) self.assertEquals(job.execute(ctx), 6) # 如果context中同样包含参数,那么基于原先参数执行update操作 ctx = Context(None, {}, {"test_job": {"a": -1}}, plugin_mgr, None) self.assertEquals(job.execute(ctx), 4) # 替换Context中的参数 ctx = Context(None, {}, {"test_job": { "a": "$a", "b": "$b", "c": "$c" }}, plugin_mgr, None) ctx["a"], ctx["b"], ctx["c"] = -1, -2, -3 self.assertEquals(job.execute(ctx), -6) # 初始化参数类型与上下文参数类型不一致时,抛出InvalidArgumentException ctx = Context(None, {}, {"test_job": ("a", "b", "c")}, plugin_mgr, None) self.failUnlessException(InvalidArgumentException, Job.execute, job, ctx) # 同时指定了插件和可执行逻辑时抛出异常 self.failUnlessException( UnknownWitchToExecuteException, Job, "test_plugin", plugin="test_plugin", caller=lambda ctx: "hehe" ) # 仅指定可执行逻辑时的情况 job = Job("hehe", caller=lambda ctx, a, b, c: a * b * c) ctx = Context(None, {}, {"hehe": (5, 2, 3)}, plugin_mgr, None) self.assertEquals(job.execute(ctx), 30) # generator args def gen_args(context): for i in xrange(10): yield i, ctx = Context(None, {}, {}, plugin_mgr, None) ctx["a"] = 0 job = Job("hehe", plugin="add_one", args=gen_args) job.execute(ctx) self.assertEquals(ctx["a"], sum(xrange(0, 10)))
def test_execute(self): """测试Job运行 """ plugin_mgr_fixture = PluginMgrFixture(None) self.useFixture(plugin_mgr_fixture) plugin_mgr = plugin_mgr_fixture.plugin_manager plugin = Plugin.wrap_function("test_job", "test job", lambda ctx, a, b, c: a + b + c) plugin_mgr.register(plugin) plugin_mgr.sys_prepare(None, "test_job") def add_one(ctx, x): ctx["a"] += x plugin = Plugin.wrap_function("add_one", "add one", add_one) plugin_mgr.register(plugin) plugin_mgr.sys_prepare(None, "add_one") ctx = Context(None, {}, {}, plugin_mgr, None) job = Job("test_job", args=(1, 2, 3)) self.assertEquals(job.execute(ctx), 6) # 当上下文中的参数是列表时,上下文中的参数取代列表 ctx = Context(None, {}, {"test_job": (-1, -2, -3)}, plugin_mgr, None) self.assertEquals(job.execute(ctx), -6) # 测试使用上下文中的变量 ctx = Context(None, {}, {"test_job": ("$a", "$b", "$c")}, plugin_mgr, None) ctx["a"], ctx["b"], ctx["c"] = 5, 6, 7 self.assertEquals(job.execute(ctx), 5 + 6 + 7) # 字符串 ctx = Context(None, {}, {"test_job": ("a", "b", "cd")}, plugin_mgr, None) self.assertEquals(job.execute(ctx), "abcd") # 字典参数 job = Job("test_job", args={"a": 1, "b": 2, "c": 3}) ctx = Context(None, {}, {}, plugin_mgr, None) self.assertEquals(job.execute(ctx), 6) # 如果context中同样包含参数,那么基于原先参数执行update操作 ctx = Context(None, {}, {"test_job": {"a": -1}}, plugin_mgr, None) self.assertEquals(job.execute(ctx), 4) # 替换Context中的参数 ctx = Context(None, {}, {"test_job": { "a": "$a", "b": "$b", "c": "$c" }}, plugin_mgr, None) ctx["a"], ctx["b"], ctx["c"] = -1, -2, -3 self.assertEquals(job.execute(ctx), -6) # 初始化参数类型与上下文参数类型不一致时,抛出InvalidArgumentException ctx = Context(None, {}, {"test_job": ("a", "b", "c")}, plugin_mgr, None) self.failUnlessException(InvalidArgumentException, Job.execute, job, ctx) # 同时指定了插件和可执行逻辑时抛出异常 self.failUnlessException(UnknownWitchToExecuteException, Job, "test_plugin", plugin="test_plugin", caller=lambda ctx: "hehe") # 仅指定可执行逻辑时的情况 job = Job("hehe", caller=lambda ctx, a, b, c: a * b * c) ctx = Context(None, {}, {"hehe": (5, 2, 3)}, plugin_mgr, None) self.assertEquals(job.execute(ctx), 30) # generator args def gen_args(context): for i in xrange(10): yield i, ctx = Context(None, {}, {}, plugin_mgr, None) ctx["a"] = 0 job = Job("hehe", plugin="add_one", args=gen_args) job.execute(ctx) self.assertEquals(ctx["a"], sum(xrange(0, 10)))