[asterisk-commits] mnicholson: testsuite/asterisk/trunk r149 - in /asterisk/trunk: asttest/self-...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Mar 25 13:45:14 CDT 2010


Author: mnicholson
Date: Thu Mar 25 13:45:10 2010
New Revision: 149

URL: http://svnview.digium.com/svn/testsuite?view=rev&rev=149
Log:
Modified watcherlib to match events out of order, and added a test for it

Added:
    asterisk/trunk/asttest/self-tests/watcherlib/
    asterisk/trunk/asttest/self-tests/watcherlib/test.lua   (with props)
    asterisk/trunk/lib/lua/watcher.lua
      - copied, changed from r138, asterisk/trunk/tests/span-alarms/watcher.lua
Removed:
    asterisk/trunk/tests/span-alarms/watcher.lua

Added: asterisk/trunk/asttest/self-tests/watcherlib/test.lua
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/asttest/self-tests/watcherlib/test.lua?view=auto&rev=149
==============================================================================
--- asterisk/trunk/asttest/self-tests/watcherlib/test.lua (added)
+++ asterisk/trunk/asttest/self-tests/watcherlib/test.lua Thu Mar 25 13:45:10 2010
@@ -1,0 +1,332 @@
+-- test matching various sequences of events
+
+require "watcher"
+
+dummy_manager = {}
+dummy_manager.__index = dummy_manager
+
+function dummy_manager:new()
+	local dm = {
+		handler = nil,
+		done = false,
+		events = {},
+	}
+
+	setmetatable(dm, self)
+	return dm
+end
+
+function dummy_manager:queue(event)
+	table.insert(self.events, event)
+end
+
+function dummy_manager:register_event(event, handler)
+	self.handler = handler
+end
+
+function dummy_manager:unregister_event(event, handler)
+	self.handler = nil
+end
+
+function dummy_manager:pump_messages()
+	return true
+end
+
+function dummy_manager:process_events()
+	if self.done then return end
+
+	for i, event in ipairs(self.events) do
+		self.handler(event)
+	end
+
+	self.done = true
+end
+
+function dummy_manager:resend()
+	self.done = false
+end
+
+function standard_dm()
+	local dm = dummy_manager:new()
+	for i=1,10 do
+		e = watcher.event.new("Event" .. i)
+		e["header1"] = "value1"
+		e["header2"] = "value2"
+		e["header3"] = "value3"
+		e["header4"] = "value4"
+		dm:queue(e)
+	end
+	return dm
+end
+
+function empty_dm()
+	return dummy_manager:new()
+end
+
+function expect_timeout(res, err)
+	if res or err ~= "timeout" then
+		fail("watcher did not timeout as expected\nres: " .. tostring(res) .. "\nerr: " .. tostring(err))
+	end
+
+	return res, err
+end
+
+function expect_success(res, err)
+	if not res then
+		fail("error running watcher: " .. err)
+	end
+
+	return res, err
+end
+
+function match_single_tree()
+	-- build a tree with 10 nodes ordered in a single branch ending with
+	-- one leaf, then match it
+
+	print("matching a single ordered tree of nodes")
+
+	local tree = watcher.etree:new(watcher.event.new("Event1"))
+	local etree = tree
+	for i=2,10 do
+		etree = etree:add(watcher.event.new("Event" .. i))
+	end
+
+	expect_success(watcher.watch(standard_dm(), tree, 2))
+end
+
+function match_multiple_trees()
+	-- build a tree two trees then match one of them
+
+	print("matching multiple trees of ordered tree of nodes")
+
+	function build_tree(start, finish)
+		local tree = watcher.etree:new(watcher.event.new("Event" .. start))
+		local etree = tree
+		for i=start+1,finish do
+			etree = etree:add(watcher.event.new("Event" .. i))
+		end
+	end
+
+	expect_success(watcher.watch(standard_dm(), {build_tree(5, 10), build_tree(1, 3)}, 2))
+end
+
+function match_branching_tree_1()
+	-- build a tree with a few nodes in a branching configuration
+
+	print("matching an ordered tree with branching nodes")
+	
+	-- build a tree with a few nodes in a branching configuration mixed in
+	-- with some out of order nodes
+
+	print("matching events with headers (1)")
+
+	local e = watcher.event.new
+
+	-- build the follwing tree
+	-- Event1
+	--    |-> {Event4, Event2}
+	--        |-> Event24
+	--        |-> Event5 -> {Event7, Event8} -> Event10
+	--    |-> Event3 -> Event12
+	--    |-> Event23
+	local tree = watcher.etree:new(watcher.event.new("Event1"))
+	local t2 = tree:add{e("Event4"), e("Event2")}
+	t2:add(e("Event24"))
+	t2:add(e("Event5"))	   
+	   :add{e("Event7"), e("Event8")}
+	   :add(e("Event10"))
+	tree:add(e("Event3"))
+	   :add(e("Event12"))
+	tree:add(e("Event23"))
+
+	expect_success(watcher.watch(standard_dm(), tree, 2))
+
+	local tree = watcher.etree:new(watcher.event.new("Event1"))
+	local etree = tree
+	for i=2,10 do
+		etree = etree:add(watcher.event.new("Event" .. i))
+	end
+
+	expect_success(watcher.watch(standard_dm(), tree, 2))
+end
+
+function match_out_of_order()
+	-- match 9 events out of order followed by a 10th event
+	
+	print("testing matching out of order")
+
+	-- build the events table with Event9 through Event1 in that order
+	local events = {}
+	for i=9,1,-1 do
+		table.insert(events, watcher.event.new("Event" .. i))
+	end
+
+	local tree = watcher.etree:new(events)
+	tree:add(watcher.event.new("Event10"))
+
+	expect_success(watcher.watch(standard_dm(), tree, 2))
+
+	-- check and make sure every event was actually matched
+	for i=1,9 do
+		if not tree.received[i] then
+			fail("tree.multi[" .. i .. "] is: " .. tostring(tree.multi[i]))
+		end
+	end
+end
+
+function match_branching_out_of_order_tree_1()
+	-- build a tree with a few nodes in a branching configuration mixed in
+	-- with some out of order nodes
+
+	print("matching an ordered tree with branching nodes and out of order nodes")
+
+	local e = watcher.event.new
+
+	-- build the follwing tree
+	-- Event1
+	--    |-> {Event4, Event2} -> Event5 -> {Event7, Event8} -> Event10
+	--    |-> Event3 -> Event12
+	--    |-> Event23
+	local tree = watcher.etree:new(watcher.event.new("Event1"))
+	tree:add{e("Event4"), e("Event2")}
+	   :add(e("Event5"))
+	   :add{e("Event7"), e("Event8")}
+	   :add(e("Event10"))
+	tree:add(e("Event3"))
+	   :add(e("Event12"))
+	tree:add(e("Event23"))
+
+	expect_success(watcher.watch(standard_dm(), tree, 2))
+end
+
+function match_headers_1()
+	-- build a tree with a few nodes in a branching configuration mixed in
+	-- with some out of order nodes
+
+	print("matching events with headers (1)")
+
+	local e = function(event)
+		local e = watcher.event.new(event)
+		e["header1"] = "value1"
+		e["header2"] = "value2"
+		e["header3"] = "value3"
+		e["header4"] = "value4"
+		return e
+	end
+
+	-- build the follwing tree
+	-- Event1
+	--    |-> {Event4, Event2} -> Event5 -> {Event7, Event8} -> Event10
+	--    |-> Event3 -> Event12
+	--    |-> Event23
+	local tree = watcher.etree:new(watcher.event.new("Event1"))
+	tree:add{e("Event4"), e("Event2")}
+	   :add(e("Event5"))
+	   :add{e("Event7"), e("Event8")}
+	   :add(e("Event10"))
+	tree:add(e("Event3"))
+	   :add(e("Event12"))
+	tree:add(e("Event23"))
+
+	expect_success(watcher.watch(standard_dm(), tree, 2))
+end
+
+function match_headers_2()
+	-- build a tree with a few nodes in a branching configuration mixed in
+	-- with some out of order nodes
+
+	print("matching events with headers (2)")
+
+	local e = function(event)
+		local e = watcher.event.new(event)
+		e["header1"] = "value1"
+		e["header2"] = "value2"
+		e["header3"] = "value3"
+		e["header4"] = "won't match"
+		return e
+	end
+
+	-- build the follwing tree
+	-- Event1
+	--    |-> {Event4, Event2} -> Event5 -> {Event7, Event8} -> Event10
+	--    |-> Event3 -> Event12
+	--    |-> Event24
+	local tree = watcher.etree:new(watcher.event.new("Event1"))
+	tree:add{e("Event4"), e("Event2")}
+	   :add(e("Event5"))
+	   :add{e("Event7"), e("Event8")}
+	   :add(e("Event10"))
+	tree:add(e("Event3"))
+	   :add(e("Event12"))
+	tree:add(e("Event23"))
+
+	expect_timeout(watcher.watch(standard_dm(), tree, 2))
+end
+
+function test_timeout_1()
+	-- build a tree starting with 'Event10' which will come last causing a
+	-- timeout
+
+	print("testing a timeout (1)")
+
+	local tree = watcher.etree:new(watcher.event.new("Event10"))
+	local etree = tree
+	for i=1,9 do
+		etree = etree:add(watcher.event.new("Event" .. i))
+	end
+
+	expect_timeout(watcher.watch(standard_dm(), tree, 2))
+end
+
+function test_timeout_2()
+	-- don't send any events causing a timeout
+
+	print("testing a timeout (2)")
+
+	local tree = watcher.etree:new(watcher.event.new("Event10"))
+	local etree = tree
+	for i=1,9 do
+		etree = etree:add(watcher.event.new("Event" .. i))
+	end
+
+	expect_timeout(watcher.watch(empty_dm(), tree, 2))
+end
+
+function match_with_function_1()
+	print("testing matching with a matching function (1)")
+
+	local tree = watcher.etree:new(function(e)
+		return true
+	end)
+
+	expect_success(watcher.watch(standard_dm(), tree, 2))
+end
+
+function match_with_function_2()
+	print("testing matching headers with a matching function (1)")
+
+	local event = watcher.event.new("Event3")
+	event["header1"] = function(value)
+		return value == "value1"
+	end
+
+	local tree = watcher.etree:new(event)
+
+	expect_success(watcher.watch(standard_dm(), tree, 2))
+end
+
+match_single_tree()
+match_multiple_trees()
+match_branching_tree_1()
+match_out_of_order()
+match_branching_out_of_order_tree_1()
+match_headers_1()
+match_headers_2()
+
+test_timeout_1()
+test_timeout_2()
+
+match_with_function_1()
+match_with_function_2()
+
+

Propchange: asterisk/trunk/asttest/self-tests/watcherlib/test.lua
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: asterisk/trunk/asttest/self-tests/watcherlib/test.lua
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: asterisk/trunk/asttest/self-tests/watcherlib/test.lua
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Copied: asterisk/trunk/lib/lua/watcher.lua (from r138, asterisk/trunk/tests/span-alarms/watcher.lua)
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/lib/lua/watcher.lua?view=diff&rev=149&p1=asterisk/trunk/tests/span-alarms/watcher.lua&r1=138&p2=asterisk/trunk/lib/lua/watcher.lua&r2=149
==============================================================================
--- asterisk/trunk/tests/span-alarms/watcher.lua (original)
+++ asterisk/trunk/lib/lua/watcher.lua Thu Mar 25 13:45:10 2010
@@ -14,6 +14,7 @@
 	local e = {
 		expect = expect,
 		c = nil, -- children
+		multi = {},
 		received = nil,
 	}
 
@@ -29,11 +30,25 @@
 	local result = ""
 	if not prefix then prefix = "" end
 
-	result = result .. prefix .. self.expect["Event"] .. "\n"
+	if getmetatable(self.expect) == nil
+	and type(self.expect) == 'table' then
+		result = result .. prefix .. "{"
+		for i, event in ipairs(self.expect) do
+			if i == 1 then
+				result = result .. event["Event"] 
+			else
+				result = result .. ", " .. event["Event"]
+			end
+		end
+
+		result = result .. "}\n"
+	else
+		result = result .. prefix .. self.expect["Event"] .. "\n"
+	end
 
 	if self.c then
 		for i, etree in ipairs(self.c) do
-			result = result .. etree:_print(prefix .. "   ")
+			result = result .. etree:_print(prefix .. "  ")
 		end
 	end
 
@@ -41,7 +56,7 @@
 end
 
 function etree:add(child)
-	if getmetatable(child) == ast.manager.message then
+	if getmetatable(child) ~= etree then
 		child = etree:new(child)
 	end
 
@@ -53,18 +68,44 @@
 	return child
 end
 
-function etree:check(e)
-	if type(self.expect) == 'function' then
-		local res = self.expect(e)
-		if res then
-			self.received = e
-		end
+function etree:check_all(e)
+	if getmetatable(self.expect) == nil
+	and type(self.expect) == 'table' then
+		local res = false
+		for i, expect in ipairs(self.expect) do
+			if not self.multi[i] and self:check(e, expect) then
+				self.multi[i] = e
+				res = true
+				break
+			end
+		end
+
+		self.received = self.multi
+		for i, _ in ipairs(self.expect) do
+			if not self.multi[i] then
+				self.received = nil
+			end
+		end
+
 		return res
 	end
 
-	if e["Event"] == self.expect["Event"] then
+	if self:check(e, self.expect) then
+		self.received = e
+		return true
+	end
+
+	return false
+end
+
+function etree:check(e, expect)
+	if type(expect) == 'function' then
+		return expect(e)
+	end
+
+	if e["Event"] == expect["Event"] then
 		local matched = true
-		for i, h in ipairs(self.expect.headers) do
+		for i, h in ipairs(expect.headers) do
 			local found = false
 			for i, h2 in ipairs(e.headers) do
 				if h[1] == h2[1] then
@@ -85,9 +126,6 @@
 				break
 			end
 		end
-		if matched then
-			self.received = e
-		end
 		return matched
 	end
 
@@ -96,7 +134,7 @@
 
 function etree:check_next(e)
 	if not self.received then
-		return self:check(e)
+		return self:check_all(e)
 	end
 	
 	if self.c then
@@ -111,21 +149,33 @@
 end
 
 function etree:matched()
+	-- if this node has not been matched, return false
 	if not self.received then
 		return false
 	end
 
+	-- if this node has been matched and has no children, return true
+	if not self.c then
+		return true
+	end
+
+	-- check if any of the children have been matched
 	if self.c then
 		for i, e in ipairs(self.c) do
-			if not e:matched() then
-				return false
-			end
-		end
-	end
-
-	return true
-end
-
+			if e:matched() then
+				return true
+			end
+		end
+	end
+
+	-- none of the children matched
+	return false
+end
+
+--- Watch the given manager connection for the given events within the given
+-- time period.
+-- @returns True on success and nil and an error message on failure.  Currently
+-- the only error message is "timeout".
 function watch(m, tree, timeout)
 	local rough_seconds = 0
 
@@ -152,7 +202,7 @@
 
 	m:register_event("", handle_events)
 	while not matched() do
-		if rough_seconds > timeout then
+		if timeout ~= 0 and rough_seconds >= timeout then
 			m:unregister_event("", handle_events)
 			return nil, "timeout"
 		end
@@ -164,6 +214,11 @@
 		end
 
 		m:process_events()
+
+		if timeout == 0 then
+			return nil, "timeout"
+		end
+
 		posix.sleep(1)
 
 		rough_seconds = rough_seconds + 1




More information about the asterisk-commits mailing list