Refine lua tests for clarity

Add detailed comments to `test/lua/testlib.lua` to explain its intended
use.

Add descriptive group names to several of the test files so that all
tests aren't just "other". At a minimum, create a "per-frame" test group
so the affected test scripts document which tests are run on every frame
(rather than on initial file load). There could still be further
improvement in this area.

Add expected test counts to some test files which had none. This should
make it a bit easier to tell when a test isn't running the right number
of times.

`test/lua/proto.lua` was seemingly created by copying `dissector.lua`
and modifying it, but none of the proto-specific tests that were added
make use of or need the actual dissector which was copied, nor a capture
file to run over. Remove the unneeded dissector, refactor the remainder
to still run as intended, and change caller `test/suite_wslua.py` to use
the empty pcap for this test.
This commit is contained in:
David Perry 2023-07-04 15:38:05 -04:00 committed by AndersBroman
parent 85a7b9da3e
commit 7ef3acdaa5
11 changed files with 370 additions and 710 deletions

View File

@ -3,8 +3,16 @@
local testlib = require("testlib")
local FRAME = "frame"
local PER_FRAME = "per-frame"
local OTHER = "other"
local n_frames = 1
testlib.init({
[FRAME] = n_frames,
[PER_FRAME] = n_frames*43,
[OTHER] = 16,
})
------------- helper funcs ------------
local function toMacAddr(addrhex)
@ -34,9 +42,6 @@ end
--------------------------
local n_frames = 1
testlib.init({ [FRAME] = n_frames, [OTHER] = 0 })
testlib.testing(OTHER, "Field")
testlib.test(OTHER,"Field.new-0",pcall(makeField,"ip.src"))
@ -83,75 +88,74 @@ function tap.packet(pinfo,tvb)
testlib.countPacket(FRAME)
testlib.testing(FRAME,"Field")
testlib.test(OTHER,"Field__tostring-2", tostring(f_frame_proto) == "frame.protocols")
testlib.test(PER_FRAME,"Field__tostring-2", tostring(f_frame_proto) == "frame.protocols")
-- make sure can't create a Field inside tap
testlib.test(OTHER,"Field.new-5",not pcall(makeField,"ip.src"))
testlib.test(PER_FRAME,"Field.new-5",not pcall(makeField,"ip.src"))
testlib.test(OTHER,"Field__call-2",pcall(makeFieldInfo,f_eth_src))
testlib.test(PER_FRAME,"Field__call-2",pcall(makeFieldInfo,f_eth_src))
testlib.test(OTHER,"Field.name-3", f_frame_proto.name == "frame.protocols")
testlib.test(OTHER,"Field.name-4", f_eth_src.name == "eth.src")
testlib.test(PER_FRAME,"Field.name-3", f_frame_proto.name == "frame.protocols")
testlib.test(PER_FRAME,"Field.name-4", f_eth_src.name == "eth.src")
testlib.test(OTHER,"Field.display-3", f_frame_proto.display == "Protocols in frame")
testlib.test(OTHER,"Field.display-4", f_eth_src.display == "Source")
testlib.test(PER_FRAME,"Field.display-3", f_frame_proto.display == "Protocols in frame")
testlib.test(PER_FRAME,"Field.display-4", f_eth_src.display == "Source")
testlib.test(OTHER,"Field.type-6", f_frame_proto.type == ftypes.STRING)
testlib.test(OTHER,"Field.type-7", f_eth_src.type == ftypes.ETHER)
testlib.test(OTHER,"Field.type-8", f_ip_src.type == ftypes.IPv4)
testlib.test(OTHER,"Field.type-9", f_udp_srcport.type == ftypes.UINT16)
testlib.test(OTHER,"Field.type-10", f_dhcp_opt.type == ftypes.UINT8)
testlib.test(PER_FRAME,"Field.type-6", f_frame_proto.type == ftypes.STRING)
testlib.test(PER_FRAME,"Field.type-7", f_eth_src.type == ftypes.ETHER)
testlib.test(PER_FRAME,"Field.type-8", f_ip_src.type == ftypes.IPv4)
testlib.test(PER_FRAME,"Field.type-9", f_udp_srcport.type == ftypes.UINT16)
testlib.test(PER_FRAME,"Field.type-10", f_dhcp_opt.type == ftypes.UINT8)
testlib.testing(FRAME,"FieldInfo")
local finfo_udp_srcport = f_udp_srcport()
testlib.test(OTHER,"FieldInfo.name-1", finfo_udp_srcport.name == "udp.srcport")
testlib.test(OTHER,"FieldInfo.type-1", finfo_udp_srcport.type == ftypes.UINT16)
testlib.test(OTHER,"FieldInfo.little_endian-1", finfo_udp_srcport.little_endian == false)
-- the following should be true, but UDP doesn't set it right?
-- testlib.test(OTHER,"FieldInfo.big_endian-1", finfo_udp_srcport.big_endian == true)
testlib.test(OTHER,"FieldInfo.is_url-1", finfo_udp_srcport.is_url == false)
testlib.test(OTHER,"FieldInfo.offset-1", finfo_udp_srcport.offset == 34)
testlib.test(OTHER,"FieldInfo.source-1", finfo_udp_srcport.source == tvb)
testlib.test(PER_FRAME,"FieldInfo.name-1", finfo_udp_srcport.name == "udp.srcport")
testlib.test(PER_FRAME,"FieldInfo.type-1", finfo_udp_srcport.type == ftypes.UINT16)
testlib.test(PER_FRAME,"FieldInfo.little_endian-1", finfo_udp_srcport.little_endian == false)
testlib.test(PER_FRAME,"FieldInfo.big_endian-1", finfo_udp_srcport.big_endian == true)
testlib.test(PER_FRAME,"FieldInfo.is_url-1", finfo_udp_srcport.is_url == false)
testlib.test(PER_FRAME,"FieldInfo.offset-1", finfo_udp_srcport.offset == 34)
testlib.test(PER_FRAME,"FieldInfo.source-1", finfo_udp_srcport.source == tvb)
-- check ether addr
local fi_eth_src = f_eth_src()
testlib.test(OTHER,"FieldInfo.type-2", fi_eth_src.type == ftypes.ETHER)
testlib.test(OTHER,"FieldInfo.range-0",pcall(getFieldInfo,fi_eth_src,"range"))
testlib.test(PER_FRAME,"FieldInfo.type-2", fi_eth_src.type == ftypes.ETHER)
testlib.test(PER_FRAME,"FieldInfo.range-0",pcall(getFieldInfo,fi_eth_src,"range"))
local eth_macs = { f_eth_mac() }
local eth_src1 = tostring(f_eth_src().range)
local eth_src2 = tostring(tvb:range(6,6))
local eth_src3 = tostring(eth_macs[2].tvb)
testlib.test(OTHER,"FieldInfo.range-1", eth_src1 == eth_src2)
testlib.test(OTHER,"FieldInfo.range-2", eth_src1 == eth_src3)
testlib.test(OTHER,"FieldInfo.range-3",not pcall(setFieldInfo,fi_eth_src,"range",3))
testlib.test(OTHER,"FieldInfo.range-4", tostring(f_frame_encap_type().range) == "<EMPTY>")
testlib.test(PER_FRAME,"FieldInfo.range-1", eth_src1 == eth_src2)
testlib.test(PER_FRAME,"FieldInfo.range-2", eth_src1 == eth_src3)
testlib.test(PER_FRAME,"FieldInfo.range-3",not pcall(setFieldInfo,fi_eth_src,"range",3))
testlib.test(PER_FRAME,"FieldInfo.range-4", tostring(f_frame_encap_type().range) == "<EMPTY>")
testlib.test(OTHER,"FieldInfo.generated-1", f_frame_proto().generated == true)
testlib.test(OTHER,"FieldInfo.generated-2", eth_macs[2].generated == false)
testlib.test(OTHER,"FieldInfo.generated-3",not pcall(setFieldInfo,fi_eth_src,"generated",3))
testlib.test(PER_FRAME,"FieldInfo.generated-1", f_frame_proto().generated == true)
testlib.test(PER_FRAME,"FieldInfo.generated-2", eth_macs[2].generated == false)
testlib.test(PER_FRAME,"FieldInfo.generated-3",not pcall(setFieldInfo,fi_eth_src,"generated",3))
testlib.test(OTHER,"FieldInfo.name-1", fi_eth_src.name == "eth.src")
testlib.test(OTHER,"FieldInfo.name-2",not pcall(setFieldInfo,fi_eth_src,"name","3"))
testlib.test(PER_FRAME,"FieldInfo.name-1", fi_eth_src.name == "eth.src")
testlib.test(PER_FRAME,"FieldInfo.name-2",not pcall(setFieldInfo,fi_eth_src,"name","3"))
testlib.test(OTHER,"FieldInfo.label-1", fi_eth_src.label == tostring(fi_eth_src))
testlib.test(OTHER,"FieldInfo.label-2", fi_eth_src.label == toMacAddr(eth_src1))
testlib.test(OTHER,"FieldInfo.label-3",not pcall(setFieldInfo,fi_eth_src,"label","3"))
testlib.test(PER_FRAME,"FieldInfo.label-1", fi_eth_src.label == tostring(fi_eth_src))
testlib.test(PER_FRAME,"FieldInfo.label-2", fi_eth_src.label == toMacAddr(eth_src1))
testlib.test(PER_FRAME,"FieldInfo.label-3",not pcall(setFieldInfo,fi_eth_src,"label","3"))
testlib.test(OTHER,"FieldInfo.display-1", select(1, string.find(fi_eth_src.display, toMacAddr(eth_src1))) ~= nil)
testlib.test(OTHER,"FieldInfo.display-2",not pcall(setFieldInfo,fi_eth_src,"display","3"))
testlib.test(PER_FRAME,"FieldInfo.display-1", select(1, string.find(fi_eth_src.display, toMacAddr(eth_src1))) ~= nil)
testlib.test(PER_FRAME,"FieldInfo.display-2",not pcall(setFieldInfo,fi_eth_src,"display","3"))
testlib.test(OTHER,"FieldInfo.eq-1", eth_macs[2] == select(2, f_eth_mac()))
testlib.test(OTHER,"FieldInfo.eq-2", eth_macs[1] ~= fi_eth_src)
testlib.test(OTHER,"FieldInfo.eq-3", eth_macs[1] == f_eth_dst())
testlib.test(PER_FRAME,"FieldInfo.eq-1", eth_macs[2] == select(2, f_eth_mac()))
testlib.test(PER_FRAME,"FieldInfo.eq-2", eth_macs[1] ~= fi_eth_src)
testlib.test(PER_FRAME,"FieldInfo.eq-3", eth_macs[1] == f_eth_dst())
testlib.test(OTHER,"FieldInfo.offset-1", eth_macs[1].offset == 0)
testlib.test(OTHER,"FieldInfo.offset-2", -fi_eth_src == 6)
testlib.test(OTHER,"FieldInfo.offset-3",not pcall(setFieldInfo,fi_eth_src,"offset","3"))
testlib.test(PER_FRAME,"FieldInfo.offset-1", eth_macs[1].offset == 0)
testlib.test(PER_FRAME,"FieldInfo.offset-2", -fi_eth_src == 6)
testlib.test(PER_FRAME,"FieldInfo.offset-3",not pcall(setFieldInfo,fi_eth_src,"offset","3"))
testlib.test(OTHER,"FieldInfo.len-1", fi_eth_src.len == 6)
testlib.test(OTHER,"FieldInfo.len-2",not pcall(setFieldInfo,fi_eth_src,"len",6))
testlib.test(PER_FRAME,"FieldInfo.len-1", fi_eth_src.len == 6)
testlib.test(PER_FRAME,"FieldInfo.len-2",not pcall(setFieldInfo,fi_eth_src,"len",6))
testlib.pass(FRAME)
end

View File

@ -8,7 +8,7 @@
local testlib = require("testlib")
local OTHER = "other"
testlib.init( { [OTHER] = 0 } )
testlib.init( { [OTHER] = 23 } )
-- you can't compare (use the '==') userdata objects with numbers, so this function does it instead.
function checkeq(arg1,arg2)
@ -37,7 +37,7 @@ local testtbl = {
}
for i,t in ipairs(testtbl) do
testlib.init( { [t.name] = 0 } )
testlib.init( { [t.name] = 125+(t.name == "Int64" and 3 or 0) } )
testlib.testing(t.name, "class")
local obj = t.type

View File

@ -27,14 +27,14 @@ local taptests = {
testlib.init(taptests)
local pkt_fields = { [FRAME] = {}, [PDISS] = {} }
local function getAllFieldInfos(type)
local function getAllFieldInfos(group)
local fields = { all_field_infos() }
local fieldnames = {}
for i,v in ipairs(fields) do
fieldnames[i] = v.name
end
local pktnum = testlib.getPktCount(type)
pkt_fields[type][pktnum] = { ["num"] = #fields, ["fields"] = fieldnames }
local pktnum = testlib.getPktCount(group)
pkt_fields[group][pktnum] = { ["num"] = #fields, ["fields"] = fieldnames }
end
local function dumpAllFieldInfos()

View File

@ -4,23 +4,20 @@
local testlib = require("testlib")
local FRAME = "frame"
local PER_FRAME = "per-frame"
local OTHER = "other"
-- expected number of runs per type
-- note ip only runs 3 times because it gets removed
-- and dhcp only runs twice because the filter makes it run
-- once and then it gets replaced with a different one for the second time
local n_frames = 4
local taptests = { [FRAME]=n_frames, [OTHER]=44+n_frames*5 }
local taptests = {
[FRAME]=n_frames,
[PER_FRAME]=n_frames*5,
[OTHER]=44
}
testlib.init(taptests)
---------
-- the following are so we can use pcall (which needs a function to call)
local function makeNSTime(...)
local foo = NSTime(...)
end
local function setNSTime(nst,name,value)
nst[name] = value
end
@ -31,8 +28,8 @@ end
------------- test script ------------
testlib.testing(OTHER,"negative tests")
testlib.test(OTHER,"NSTime.new-1",not pcall(makeNSTime,"FooBARhowdy"))
testlib.test(OTHER,"NSTime.new-2",not pcall(makeNSTime,"ip","FooBARhowdy"))
testlib.test(OTHER,"NSTime.new-1",not pcall(NSTime,"FooBARhowdy"))
testlib.test(OTHER,"NSTime.new-2",not pcall(NSTime,"ip","FooBARhowdy"))
local tmptime = NSTime()
testlib.test(OTHER,"NSTime.set-3",pcall(setNSTime,tmptime,"secs",10))
testlib.test(OTHER,"NSTime.set-4",not pcall(setNSTime,tmptime,"foobar",1000))
@ -119,19 +116,19 @@ function tap.packet(pinfo,tvb,frame)
local fi_rel = f_frame_time_rel()
local fi_delta = f_frame_time_delta()
testlib.test(OTHER,"typeof-1", typeof(begin) == "NSTime")
testlib.test(OTHER,"typeof-2", typeof(fi_now()) == "NSTime")
testlib.test(PER_FRAME,"typeof-1", typeof(begin) == "NSTime")
testlib.test(PER_FRAME,"typeof-2", typeof(fi_now()) == "NSTime")
now = fi_now()
if testlib.getPktCount(FRAME) == 1 then
testlib.test(OTHER,"__eq-1", begin == fi_delta())
testlib.test(OTHER,"NSTime.secs-1", fi_delta().secs == 0)
testlib.test(OTHER,"NSTime.nsecs-1", fi_delta().nsecs == 0)
testlib.test(PER_FRAME,"__eq-1", begin == fi_delta())
testlib.test(PER_FRAME,"NSTime.secs-1", fi_delta().secs == 0)
testlib.test(PER_FRAME,"NSTime.nsecs-1", fi_delta().nsecs == 0)
begin = fi_now()
else
testlib.test(OTHER,"__sub__eq-1", now - previous == fi_delta())
testlib.test(OTHER,"__sub__eq-2", now - begin == fi_rel())
testlib.test(OTHER,"__add-1", (previous - begin) + (now - previous) == fi_rel())
testlib.test(PER_FRAME,"__sub__eq-1", now - previous == fi_delta())
testlib.test(PER_FRAME,"__sub__eq-2", now - begin == fi_rel())
testlib.test(PER_FRAME,"__add-1", (previous - begin) + (now - previous) == fi_rel())
end
previous = now

View File

@ -1,28 +1,25 @@
-- test script for Pinfo and Address functions
-- use with dhcp.pcap in test/captures directory
local major, minor, micro = get_version():match("(%d+)%.(%d+)%.(%d+)")
if major then
major = tonumber(major)
minor = tonumber(minor)
micro = tonumber(micro)
else
major = 99
minor = 99
micro = 99
end
------------- general test helper funcs ------------
local testlib = require("testlib")
local FRAME = "frame"
local DENIED = "denied"
local GETTER = "getter"
local SETTER = "setter"
local ADDR = "address"
local OTHER = "other"
-- expected number of runs per type
-- note ip only runs 3 times because it gets removed
-- and dhcp only runs twice because the filter makes it run
-- once and then it gets replaced with a different one for the second time
local n_frames = 4
local taptests = { [FRAME]=n_frames, [OTHER]=0 }
local taptests = {
[FRAME]=n_frames,
[DENIED]=n_frames*32,
[GETTER]=n_frames*39,
[SETTER]=n_frames*15,
[ADDR]=n_frames*6,
[OTHER]=n_frames*2,
}
testlib.init(taptests)
---------
@ -37,13 +34,6 @@ end
------------- test script ------------
----------------------------------
-- modify original test function, kinda sorta
local orig_test = test
test = function (...)
return orig_test(FRAME,...)
end
local tap = Listener.new()
@ -59,44 +49,42 @@ function tap.packet(pinfo,tvb)
testlib.testing(FRAME,"negative tests")
-- try to set read-only attributes
testlib.test(OTHER,"Pinfo.number-set-1",not pcall(setPinfo,pinfo,"number",0))
testlib.test(OTHER,"Pinfo.len-set-1",not pcall(setPinfo,pinfo,"len",0))
testlib.test(OTHER,"Pinfo.caplen-set-1",not pcall(setPinfo,pinfo,"caplen",0))
testlib.test(OTHER,"Pinfo.rel_ts-set-1",not pcall(setPinfo,pinfo,"rel_ts",0))
testlib.test(OTHER,"Pinfo.delta_ts-set-1",not pcall(setPinfo,pinfo,"delta_ts",0))
testlib.test(OTHER,"Pinfo.delta_dis_ts-set-1",not pcall(setPinfo,pinfo,"delta_dis_ts",0))
testlib.test(OTHER,"Pinfo.visited-set-1",not pcall(setPinfo,pinfo,"visited",0))
testlib.test(OTHER,"Pinfo.lo-set-1",not pcall(setPinfo,pinfo,"lo",0))
testlib.test(OTHER,"Pinfo.hi-set-1",not pcall(setPinfo,pinfo,"hi",0))
testlib.test(OTHER,"Pinfo.port_type-set-1",not pcall(setPinfo,pinfo,"port_type",0))
testlib.test(OTHER,"Pinfo.match-set-1",not pcall(setPinfo,pinfo,"match",0))
testlib.test(OTHER,"Pinfo.curr_proto-set-1",not pcall(setPinfo,pinfo,"curr_proto",0))
testlib.test(OTHER,"Pinfo.columns-set-1",not pcall(setPinfo,pinfo,"columns",0))
testlib.test(OTHER,"Pinfo.cols-set-1",not pcall(setPinfo,pinfo,"cols",0))
testlib.test(OTHER,"Pinfo.private-set-1",not pcall(setPinfo,pinfo,"private",0))
testlib.test(OTHER,"Pinfo.fragmented-set-1",not pcall(setPinfo,pinfo,"fragmented",0))
testlib.test(OTHER,"Pinfo.in_error_pkt-set-1",not pcall(setPinfo,pinfo,"in_error_pkt",0))
testlib.test(OTHER,"Pinfo.match_uint-set-1",not pcall(setPinfo,pinfo,"match_uint",0))
testlib.test(OTHER,"Pinfo.match_string-set-1",not pcall(setPinfo,pinfo,"match_string",0))
testlib.test(DENIED,"Pinfo.number-set-1",not pcall(setPinfo,pinfo,"number",0))
testlib.test(DENIED,"Pinfo.len-set-1",not pcall(setPinfo,pinfo,"len",0))
testlib.test(DENIED,"Pinfo.caplen-set-1",not pcall(setPinfo,pinfo,"caplen",0))
testlib.test(DENIED,"Pinfo.rel_ts-set-1",not pcall(setPinfo,pinfo,"rel_ts",0))
testlib.test(DENIED,"Pinfo.delta_ts-set-1",not pcall(setPinfo,pinfo,"delta_ts",0))
testlib.test(DENIED,"Pinfo.delta_dis_ts-set-1",not pcall(setPinfo,pinfo,"delta_dis_ts",0))
testlib.test(DENIED,"Pinfo.visited-set-1",not pcall(setPinfo,pinfo,"visited",0))
testlib.test(DENIED,"Pinfo.lo-set-1",not pcall(setPinfo,pinfo,"lo",0))
testlib.test(DENIED,"Pinfo.hi-set-1",not pcall(setPinfo,pinfo,"hi",0))
testlib.test(DENIED,"Pinfo.port_type-set-1",not pcall(setPinfo,pinfo,"port_type",0))
testlib.test(DENIED,"Pinfo.match-set-1",not pcall(setPinfo,pinfo,"match",0))
testlib.test(DENIED,"Pinfo.curr_proto-set-1",not pcall(setPinfo,pinfo,"curr_proto",0))
testlib.test(DENIED,"Pinfo.columns-set-1",not pcall(setPinfo,pinfo,"columns",0))
testlib.test(DENIED,"Pinfo.cols-set-1",not pcall(setPinfo,pinfo,"cols",0))
testlib.test(DENIED,"Pinfo.private-set-1",not pcall(setPinfo,pinfo,"private",0))
testlib.test(DENIED,"Pinfo.fragmented-set-1",not pcall(setPinfo,pinfo,"fragmented",0))
testlib.test(DENIED,"Pinfo.in_error_pkt-set-1",not pcall(setPinfo,pinfo,"in_error_pkt",0))
testlib.test(DENIED,"Pinfo.match_uint-set-1",not pcall(setPinfo,pinfo,"match_uint",0))
testlib.test(DENIED,"Pinfo.match_string-set-1",not pcall(setPinfo,pinfo,"match_string",0))
-- wrong type being set
testlib.test(OTHER,"Pinfo.src-set-1",not pcall(setPinfo,pinfo,"src","foobar"))
testlib.test(OTHER,"Pinfo.dst-set-1",not pcall(setPinfo,pinfo,"dst","foobar"))
testlib.test(OTHER,"Pinfo.dl_src-set-1",not pcall(setPinfo,pinfo,"dl_src","foobar"))
testlib.test(OTHER,"Pinfo.dl_dst-set-1",not pcall(setPinfo,pinfo,"dl_dst","foobar"))
testlib.test(OTHER,"Pinfo.net_src-set-1",not pcall(setPinfo,pinfo,"net_src","foobar"))
testlib.test(OTHER,"Pinfo.net_dst-set-1",not pcall(setPinfo,pinfo,"net_dst","foobar"))
testlib.test(OTHER,"Pinfo.src_port-set-1",not pcall(setPinfo,pinfo,"src_port","foobar"))
testlib.test(OTHER,"Pinfo.dst_port-set-1",not pcall(setPinfo,pinfo,"dst_port","foobar"))
if major > 1 or minor > 10 then
testlib.test(OTHER,"Pinfo.can_desegment-set-1",not pcall(setPinfo,pinfo,"can_desegment","foobar"))
end
testlib.test(OTHER,"Pinfo.desegment_len-set-1",not pcall(setPinfo,pinfo,"desegment_len","foobar"))
testlib.test(OTHER,"Pinfo.desegment_offset-set-1",not pcall(setPinfo,pinfo,"desegment_offset","foobar"))
testlib.test(DENIED,"Pinfo.src-set-1",not pcall(setPinfo,pinfo,"src","foobar"))
testlib.test(DENIED,"Pinfo.dst-set-1",not pcall(setPinfo,pinfo,"dst","foobar"))
testlib.test(DENIED,"Pinfo.dl_src-set-1",not pcall(setPinfo,pinfo,"dl_src","foobar"))
testlib.test(DENIED,"Pinfo.dl_dst-set-1",not pcall(setPinfo,pinfo,"dl_dst","foobar"))
testlib.test(DENIED,"Pinfo.net_src-set-1",not pcall(setPinfo,pinfo,"net_src","foobar"))
testlib.test(DENIED,"Pinfo.net_dst-set-1",not pcall(setPinfo,pinfo,"net_dst","foobar"))
testlib.test(DENIED,"Pinfo.src_port-set-1",not pcall(setPinfo,pinfo,"src_port","foobar"))
testlib.test(DENIED,"Pinfo.dst_port-set-1",not pcall(setPinfo,pinfo,"dst_port","foobar"))
testlib.test(DENIED,"Pinfo.can_desegment-set-1",not pcall(setPinfo,pinfo,"can_desegment","foobar"))
testlib.test(DENIED,"Pinfo.desegment_len-set-1",not pcall(setPinfo,pinfo,"desegment_len","foobar"))
testlib.test(DENIED,"Pinfo.desegment_offset-set-1",not pcall(setPinfo,pinfo,"desegment_offset","foobar"))
-- invalid attribute names
testlib.test(OTHER,"Pinfo.set-1",not pcall(setPinfo,pinfo,"foobar","foobar"))
testlib.test(OTHER,"Pinfo.get-12",not pcall(getPinfo,pinfo,"foobar"))
testlib.test(DENIED,"Pinfo.set-1",not pcall(setPinfo,pinfo,"foobar","foobar"))
testlib.test(DENIED,"Pinfo.get-12",not pcall(getPinfo,pinfo,"foobar"))
testlib.testing(FRAME,"basic getter tests")
@ -116,65 +104,63 @@ function tap.packet(pinfo,tvb)
dstport = 68
end
testlib.test(OTHER,"Pinfo.number-get-1",pinfo.number == testlib.getPktCount(FRAME))
testlib.test(OTHER,"Pinfo.len-get-1",pinfo.len == pktlen)
testlib.test(OTHER,"Pinfo.caplen-get-1",pinfo.caplen == pktlen)
testlib.test(OTHER,"Pinfo.visited-get-1",pinfo.visited == true)
testlib.test(OTHER,"Pinfo.lo-get-1",tostring(pinfo.lo) == srcip)
testlib.test(OTHER,"Pinfo.lo-get-2",typeof(pinfo.lo) == "Address")
testlib.test(OTHER,"Pinfo.hi-get-1",tostring(pinfo.hi) == dstip)
testlib.test(OTHER,"Pinfo.hi-get-2",typeof(pinfo.hi) == "Address")
testlib.test(OTHER,"Pinfo.port_type-get-1",pinfo.port_type == 3)
testlib.test(OTHER,"Pinfo.match-get-1",pinfo.match == 0)
testlib.test(OTHER,"Pinfo.curr_proto-get-1",tostring(pinfo.curr_proto) == "<Missing Protocol Name>")
testlib.test(OTHER,"Pinfo.columns-get-1",tostring(pinfo.columns) == "Columns")
testlib.test(OTHER,"Pinfo.columns-get-2",typeof(pinfo.columns) == "Columns")
testlib.test(OTHER,"Pinfo.cols-get-1",tostring(pinfo.cols) == "Columns")
testlib.test(OTHER,"Pinfo.cols-get-2",typeof(pinfo.cols) == "Columns")
testlib.test(OTHER,"Pinfo.private-get-1",type(pinfo.private) == "userdata")
testlib.test(OTHER,"Pinfo.fragmented-get-1",pinfo.fragmented == false)
testlib.test(GETTER,"Pinfo.number-get-1",pinfo.number == testlib.getPktCount(FRAME))
testlib.test(GETTER,"Pinfo.len-get-1",pinfo.len == pktlen)
testlib.test(GETTER,"Pinfo.caplen-get-1",pinfo.caplen == pktlen)
testlib.test(GETTER,"Pinfo.visited-get-1",pinfo.visited == true)
testlib.test(GETTER,"Pinfo.lo-get-1",tostring(pinfo.lo) == srcip)
testlib.test(GETTER,"Pinfo.lo-get-2",typeof(pinfo.lo) == "Address")
testlib.test(GETTER,"Pinfo.hi-get-1",tostring(pinfo.hi) == dstip)
testlib.test(GETTER,"Pinfo.hi-get-2",typeof(pinfo.hi) == "Address")
testlib.test(GETTER,"Pinfo.port_type-get-1",pinfo.port_type == 3)
testlib.test(GETTER,"Pinfo.match-get-1",pinfo.match == 0)
testlib.test(GETTER,"Pinfo.curr_proto-get-1",tostring(pinfo.curr_proto) == "<Missing Protocol Name>")
testlib.test(GETTER,"Pinfo.columns-get-1",tostring(pinfo.columns) == "Columns")
testlib.test(GETTER,"Pinfo.columns-get-2",typeof(pinfo.columns) == "Columns")
testlib.test(GETTER,"Pinfo.cols-get-1",tostring(pinfo.cols) == "Columns")
testlib.test(GETTER,"Pinfo.cols-get-2",typeof(pinfo.cols) == "Columns")
testlib.test(GETTER,"Pinfo.private-get-1",type(pinfo.private) == "userdata")
testlib.test(GETTER,"Pinfo.fragmented-get-1",pinfo.fragmented == false)
testlib.test(OTHER,"Pinfo.in_error_pkt-get-1",pinfo.in_error_pkt == false)
testlib.test(OTHER,"Pinfo.match_uint-get-1",pinfo.match_uint == 0)
testlib.test(OTHER,"Pinfo.match_string-get-1",pinfo.match_string == nil)
testlib.test(GETTER,"Pinfo.in_error_pkt-get-1",pinfo.in_error_pkt == false)
testlib.test(GETTER,"Pinfo.match_uint-get-1",pinfo.match_uint == 0)
testlib.test(GETTER,"Pinfo.match_string-get-1",pinfo.match_string == nil)
testlib.test(OTHER,"Pinfo.src-get-1",tostring(pinfo.src) == srcip)
testlib.test(OTHER,"Pinfo.src-get-2",typeof(pinfo.src) == "Address")
testlib.test(OTHER,"Pinfo.dst-get-1",tostring(pinfo.dst) == dstip)
testlib.test(OTHER,"Pinfo.dst-get-2",typeof(pinfo.dst) == "Address")
testlib.test(GETTER,"Pinfo.src-get-1",tostring(pinfo.src) == srcip)
testlib.test(GETTER,"Pinfo.src-get-2",typeof(pinfo.src) == "Address")
testlib.test(GETTER,"Pinfo.dst-get-1",tostring(pinfo.dst) == dstip)
testlib.test(GETTER,"Pinfo.dst-get-2",typeof(pinfo.dst) == "Address")
testlib.test(OTHER,"Pinfo.dl_src-get-1",typeof(pinfo.dl_src) == "Address")
testlib.test(OTHER,"Pinfo.dl_dst-get-1",typeof(pinfo.dl_dst) == "Address")
testlib.test(OTHER,"Pinfo.net_src-get-1",tostring(pinfo.net_src) == srcip)
testlib.test(OTHER,"Pinfo.net_src-get-2",typeof(pinfo.net_src) == "Address")
testlib.test(OTHER,"Pinfo.net_dst-get-1",tostring(pinfo.net_dst) == dstip)
testlib.test(OTHER,"Pinfo.net_dst-get-2",typeof(pinfo.net_dst) == "Address")
testlib.test(OTHER,"Pinfo.src_port-get-1",pinfo.src_port == srcport)
testlib.test(OTHER,"Pinfo.dst_port-get-1",pinfo.dst_port == dstport)
if major > 1 or minor > 10 then
testlib.test(OTHER,"Pinfo.can_desegment-get-1",pinfo.can_desegment == 0)
end
testlib.test(OTHER,"Pinfo.desegment_len-get-1",pinfo.desegment_len == 0)
testlib.test(OTHER,"Pinfo.desegment_offset-get-1",pinfo.desegment_offset == 0)
testlib.test(GETTER,"Pinfo.dl_src-get-1",typeof(pinfo.dl_src) == "Address")
testlib.test(GETTER,"Pinfo.dl_dst-get-1",typeof(pinfo.dl_dst) == "Address")
testlib.test(GETTER,"Pinfo.net_src-get-1",tostring(pinfo.net_src) == srcip)
testlib.test(GETTER,"Pinfo.net_src-get-2",typeof(pinfo.net_src) == "Address")
testlib.test(GETTER,"Pinfo.net_dst-get-1",tostring(pinfo.net_dst) == dstip)
testlib.test(GETTER,"Pinfo.net_dst-get-2",typeof(pinfo.net_dst) == "Address")
testlib.test(GETTER,"Pinfo.src_port-get-1",pinfo.src_port == srcport)
testlib.test(GETTER,"Pinfo.dst_port-get-1",pinfo.dst_port == dstport)
testlib.test(GETTER,"Pinfo.can_desegment-get-1",pinfo.can_desegment == 0)
testlib.test(GETTER,"Pinfo.desegment_len-get-1",pinfo.desegment_len == 0)
testlib.test(GETTER,"Pinfo.desegment_offset-get-1",pinfo.desegment_offset == 0)
testlib.test(OTHER,"pinfo.p2p_dir", pinfo.p2p_dir == P2P_DIR_UNKNOWN)
testlib.test(GETTER,"pinfo.p2p_dir", pinfo.p2p_dir == P2P_DIR_UNKNOWN)
if pinfo.number == 1 then
testlib.test(OTHER,"Pinfo.rel_ts-get-1",pinfo.rel_ts == 0)
testlib.test(OTHER,"Pinfo.delta_ts-get-1",pinfo.delta_ts == 0)
testlib.test(OTHER,"Pinfo.delta_dis_ts-get-1",pinfo.delta_dis_ts == 0)
testlib.test(GETTER,"Pinfo.rel_ts-get-1",pinfo.rel_ts == 0)
testlib.test(GETTER,"Pinfo.delta_ts-get-1",pinfo.delta_ts == 0)
testlib.test(GETTER,"Pinfo.delta_dis_ts-get-1",pinfo.delta_dis_ts == 0)
elseif pinfo.number == 2 then
testlib.test(OTHER,"Pinfo.rel_ts-get-1",pinfo.rel_ts == 0.000295)
testlib.test(OTHER,"Pinfo.delta_ts-get-1",pinfo.delta_ts == 0.000295)
testlib.test(OTHER,"Pinfo.delta_dis_ts-get-1",pinfo.delta_dis_ts == 0.000295)
testlib.test(GETTER,"Pinfo.rel_ts-get-1",pinfo.rel_ts == 0.000295)
testlib.test(GETTER,"Pinfo.delta_ts-get-1",pinfo.delta_ts == 0.000295)
testlib.test(GETTER,"Pinfo.delta_dis_ts-get-1",pinfo.delta_dis_ts == 0.000295)
elseif pinfo.number == 3 then
testlib.test(OTHER,"Pinfo.rel_ts-get-1",pinfo.rel_ts == 0.070031)
testlib.test(OTHER,"Pinfo.delta_ts-get-1",pinfo.delta_ts == 0.069736)
testlib.test(OTHER,"Pinfo.delta_dis_ts-get-1",pinfo.delta_dis_ts == 0.069736)
testlib.test(GETTER,"Pinfo.rel_ts-get-1",pinfo.rel_ts == 0.070031)
testlib.test(GETTER,"Pinfo.delta_ts-get-1",pinfo.delta_ts == 0.069736)
testlib.test(GETTER,"Pinfo.delta_dis_ts-get-1",pinfo.delta_dis_ts == 0.069736)
elseif pinfo.number == 4 then
testlib.test(OTHER,"Pinfo.rel_ts-get-1",pinfo.rel_ts == 0.070345)
testlib.test(OTHER,"Pinfo.delta_ts-get-1",pinfo.delta_ts == 0.000314)
testlib.test(OTHER,"Pinfo.delta_dis_ts-get-1",pinfo.delta_dis_ts == 0.000314)
testlib.test(GETTER,"Pinfo.rel_ts-get-1",pinfo.rel_ts == 0.070345)
testlib.test(GETTER,"Pinfo.delta_ts-get-1",pinfo.delta_ts == 0.000314)
testlib.test(GETTER,"Pinfo.delta_dis_ts-get-1",pinfo.delta_dis_ts == 0.000314)
end
@ -183,54 +169,47 @@ function tap.packet(pinfo,tvb)
local tmp = pinfo.src
pinfo.src = pinfo.dst
pinfo.dst = tmp
testlib.test(OTHER,"Pinfo.src-set-1",tostring(pinfo.src) == dstip)
testlib.test(OTHER,"Pinfo.src-set-1",typeof(pinfo.src) == "Address")
testlib.test(OTHER,"Pinfo.dst-set-1",tostring(pinfo.dst) == srcip)
testlib.test(OTHER,"Pinfo.dst-set-1",typeof(pinfo.dst) == "Address")
testlib.test(SETTER,"Pinfo.src-set-1",tostring(pinfo.src) == dstip)
testlib.test(SETTER,"Pinfo.src-set-1",typeof(pinfo.src) == "Address")
testlib.test(SETTER,"Pinfo.dst-set-1",tostring(pinfo.dst) == srcip)
testlib.test(SETTER,"Pinfo.dst-set-1",typeof(pinfo.dst) == "Address")
local dl_dst_val = tostring(pinfo.dl_dst)
local dl_src_val = tostring(pinfo.dl_src)
tmp = pinfo.dl_src
pinfo.dl_src = pinfo.dl_dst
pinfo.dl_dst = tmp
testlib.test(OTHER,"Pinfo.dl_src-set-1",tostring(pinfo.dl_src) == dl_dst_val)
testlib.test(OTHER,"Pinfo.dl_dst-set-1",tostring(pinfo.dl_dst) == dl_src_val)
testlib.test(SETTER,"Pinfo.dl_src-set-1",tostring(pinfo.dl_src) == dl_dst_val)
testlib.test(SETTER,"Pinfo.dl_dst-set-1",tostring(pinfo.dl_dst) == dl_src_val)
tmp = pinfo.net_src
pinfo.net_src = pinfo.net_dst
pinfo.net_dst = tmp
testlib.test(OTHER,"Pinfo.net_src-set-1",tostring(pinfo.net_src) == dstip)
testlib.test(OTHER,"Pinfo.net_src-set-1",typeof(pinfo.net_src) == "Address")
testlib.test(OTHER,"Pinfo.net_dst-set-1",tostring(pinfo.net_dst) == srcip)
testlib.test(OTHER,"Pinfo.net_dst-set-1",typeof(pinfo.net_dst) == "Address")
testlib.test(SETTER,"Pinfo.net_src-set-1",tostring(pinfo.net_src) == dstip)
testlib.test(SETTER,"Pinfo.net_src-set-1",typeof(pinfo.net_src) == "Address")
testlib.test(SETTER,"Pinfo.net_dst-set-1",tostring(pinfo.net_dst) == srcip)
testlib.test(SETTER,"Pinfo.net_dst-set-1",typeof(pinfo.net_dst) == "Address")
--[[
--there's a bug 9792 causing the pinfo.dst_port setter to actually set src_port
tmp = pinfo.src_port
pinfo.src_port = pinfo.dst_port
pinfo.dst_port = tmp
testlib.test(OTHER,"Pinfo.src_port-set-1",pinfo.src_port == dstport)
testlib.test(OTHER,"Pinfo.dst_port-set-1",pinfo.dst_port == srcport)
--]]
pinfo.src_port = pinfo.dst_port
testlib.test(OTHER,"Pinfo.src_port-set-1",pinfo.src_port == dstport)
testlib.test(SETTER,"Pinfo.src_port-set-1",pinfo.src_port == dstport)
testlib.test(SETTER,"Pinfo.dst_port-set-1",pinfo.dst_port == srcport)
if major > 1 or minor > 10 then
pinfo.can_desegment = 12
testlib.test(OTHER,"Pinfo.can_desegment-set-1",pinfo.can_desegment == 12)
end
pinfo.can_desegment = 12
testlib.test(SETTER,"Pinfo.can_desegment-set-1",pinfo.can_desegment == 12)
pinfo.desegment_len = 34
testlib.test(OTHER,"Pinfo.desegment_len-set-1",pinfo.desegment_len == 34)
testlib.test(SETTER,"Pinfo.desegment_len-set-1",pinfo.desegment_len == 34)
pinfo.desegment_offset = 45
testlib.test(OTHER,"Pinfo.desegment_offset-set-1",pinfo.desegment_offset == 45)
testlib.test(SETTER,"Pinfo.desegment_offset-set-1",pinfo.desegment_offset == 45)
testlib.testing(FRAME,"Address functions")
testlib.test(OTHER,"Address-eq-1", pinfo.lo == pinfo.dst)
testlib.test(OTHER,"Address-eq-2", pinfo.lo ~= pinfo.hi)
testlib.test(OTHER,"Address-lt-1", pinfo.lo < pinfo.hi)
testlib.test(OTHER,"Address-lt-2", pinfo.hi > pinfo.lo)
testlib.test(OTHER,"Address-le-1", pinfo.lo <= pinfo.hi)
testlib.test(OTHER,"Address-le-2", pinfo.lo <= pinfo.dst)
testlib.test(ADDR,"Address-eq-1", pinfo.lo == pinfo.dst)
testlib.test(ADDR,"Address-eq-2", pinfo.lo ~= pinfo.hi)
testlib.test(ADDR,"Address-lt-1", pinfo.lo < pinfo.hi)
testlib.test(ADDR,"Address-lt-2", pinfo.hi > pinfo.lo)
testlib.test(ADDR,"Address-le-1", pinfo.lo <= pinfo.hi)
testlib.test(ADDR,"Address-le-2", pinfo.lo <= pinfo.dst)
testlib.pass(FRAME)

View File

@ -1,21 +1,17 @@
----------------------------------------
-- script-name: proto.lua
-- This is based on the dissector.lua example script, which is also used for testing.
-- Unlike that one, this one is purely for testing even more things, notably
-- the Proto/ProtoField API.
-- Test the Proto/ProtoField API
----------------------------------------
------------- general test helper funcs ------------
local testlib = require("testlib")
local FRAME = "frame"
local OTHER = "other"
-- expected number of runs per type
-- note ip only runs 3 times because it gets removed
-- and dhcp only runs twice because the filter makes it run
-- once and then it gets replaced with a different one for the second time
local taptests = { [FRAME]=4, [OTHER]=48 }
local taptests = {
[OTHER]=48
}
testlib.init(taptests)
---------
@ -202,8 +198,7 @@ testlib.test(OTHER,"Proto.prefs_changed-get", not pcall(getValue,foo,"prefs_chan
testlib.test(OTHER,"Proto.prefs_changed-set", not pcall(setValue,foo,"prefs_changed","howdy"))
local function dummy_init()
--testlib.test(OTHER,"Proto.init-called",true)
return
testlib.test(OTHER,"Proto.init-called",true)
end
testlib.test(OTHER,"Proto.init-set", pcall(setValue,foo,"init",dummy_init))
@ -212,390 +207,5 @@ testlib.test(OTHER,"Proto.init-set", pcall(setValue,bar,"init",dummy_init))
testlib.test(OTHER,"Proto.init-get", not pcall(getValue,foo,"init"))
testlib.test(OTHER,"Proto.init-set", not pcall(setValue,foo,"init","howdy"))
local numinits = 0
function dns.init()
numinits = numinits + 1
if numinits == 2 then
testlib.getResults()
end
end
----------------------------------------
-- create some expert info fields
local ef_query = ProtoExpert.new("mydns.query.expert", "DNS query message",
expert.group.REQUEST_CODE, expert.severity.CHAT)
local ef_response = ProtoExpert.new("mydns.response.expert", "DNS response message",
expert.group.RESPONSE_CODE, expert.severity.CHAT)
local ef_ultimate = ProtoExpert.new("mydns.response.ultimate.expert", "DNS answer to life, the universe, and everything",
expert.group.COMMENTS_GROUP, expert.severity.NOTE)
-- some error expert info's
local ef_too_short = ProtoExpert.new("mydns.too_short.expert", "DNS message too short",
expert.group.MALFORMED, expert.severity.ERROR)
local ef_bad_query = ProtoExpert.new("mydns.query.missing.expert", "DNS query missing or malformed",
expert.group.MALFORMED, expert.severity.WARN)
-- register them
dns.experts = { ef_query, ef_too_short, ef_bad_query, ef_response, ef_ultimate }
----------------------------------------
-- we don't just want to display our protocol's fields, we want to access the value of some of them too!
-- There are several ways to do that. One is to just parse the buffer contents in Lua code to find
-- the values. But since ProtoFields actually do the parsing for us, and can be retrieved using Field
-- objects, it's kinda cool to do it that way. So let's create some Fields to extract the values.
-- The following creates the Field objects, but they're not 'registered' until after this script is loaded.
-- Also, these lines can't be before the 'dns.fields = ...' line above, because the Field.new() here is
-- referencing fields we're creating, and they're not "created" until that line above.
-- Furthermore, you cannot put these 'Field.new()' lines inside the dissector function.
-- Before Wireshark version 1.11, you couldn't even do this concept (of using fields you just created).
local questions_field = Field.new("mydns.num_questions")
local query_type_field = Field.new("mydns.query.type")
local query_class_field = Field.new("mydns.query.class")
local response_field = Field.new("mydns.flags.response")
-- here's a little helper function to access the response_field value later.
-- Like any Field retrieval, you can't retrieve a field's value until its value has been
-- set, which won't happen until we actually use our ProtoFields in TreeItem:add() calls.
-- So this isResponse() function can't be used until after the pf_flag_response ProtoField
-- has been used inside the dissector.
-- Note that calling the Field object returns a FieldInfo object, and calling that
-- returns the value of the field - in this case a boolean true/false, since we set the
-- "mydns.flags.response" ProtoField to ftype.BOOLEAN way earlier when we created the
-- pf_flag_response ProtoField. Clear as mud?
--
-- A shorter version of this function would be:
-- local function isResponse() return response_field()() end
-- but I though the below is easier to understand.
local function isResponse()
local response_fieldinfo = response_field()
return response_fieldinfo()
end
----------------------------------------
---- some constants for later use ----
-- the DNS header size
local DNS_HDR_LEN = 12
-- the smallest possible DNS query field size
-- has to be at least a label length octet, label character, label null terminator, 2-bytes type and 2-bytes class
local MIN_QUERY_LEN = 7
-- the UDP port number we want to associate with our protocol
local MYDNS_PROTO_UDP_PORT = 65333
----------------------------------------
-- some forward "declarations" of helper functions we use in the dissector
-- I don't usually use this trick, but it'll help reading/grok'ing this script I think
-- if we don't focus on them.
local byteArray2String, getQueryName
----------------------------------------
-- The following creates the callback function for the dissector.
-- It's the same as doing "dns.dissector = function (tvbuf,pkt,root)"
-- The 'tvbuf' is a Tvb object, 'pktinfo' is a Pinfo object, and 'root' is a TreeItem object.
-- Whenever Wireshark dissects a packet that our Proto is hooked into, it will call
-- this function and pass it these arguments for the packet it's dissecting.
function dns.dissector(tvbuf,pktinfo,root)
testlib.countPacket(FRAME)
-- We want to check that the packet size is rational during dissection, so let's get the length of the
-- packet buffer (Tvb).
-- Because DNS has no additonal payload data other than itself, and it rides on UDP without padding,
-- we can use tvb:len() or tvb:reported_len() here; but I prefer tvb:reported_length_remaining() as it's safer.
local pktlen = tvbuf:reported_length_remaining()
-- We start by adding our protocol to the dissection display tree.
-- A call to tree:add() returns the child created, so we can add more "under" it using that return value.
-- The second argument is how much of the buffer/packet this added tree item covers/represents - in this
-- case (DNS protocol) that's the remainder of the packet.
local tree = root:add(dns, tvbuf:range(0,pktlen))
-- now let's check it's not too short
if pktlen < DNS_HDR_LEN then
-- since we're going to add this protocol to a specific UDP port, we're going to
-- assume packets in this port are our protocol, so the packet being too short is an error
tree:add_expert_info(PI_MALFORMED, PI_ERROR, "packet too short")
return
end
-- Now let's add our transaction id under our dns protocol tree we just created.
-- The transaction id starts at offset 0, for 2 bytes length.
tree:add(pf_trasaction_id, tvbuf:range(0,2))
-- We'd like to put the transaction id number in the GUI row for this packet, in its
-- INFO column/cell. Firt we need the transaction id value, though. Since we just
-- dissected it with the previous code line, we could now get it using a Field's
-- FieldInfo extractor, but instead we'll get it directly from the TvbRange just
-- to show how to do that. We'll use Field/FieldInfo extractors later on...
local transid = tvbuf:range(0,2):uint()
pktinfo.cols.info:set("(".. transid ..")")
-- now let's add the flags, which are all in the packet bytes at offset 2 of length 2
-- instead of calling this again and again, let's just use a variable
local flagrange = tvbuf:range(2,2)
-- for our flags field, we want a sub-tree
local flag_tree = tree:add(pf_flags, flagrange)
-- I'm indenting this for calarity, because it's adding to the flag's child-tree
-- let's add the type of message (query vs. response)
local query_flag_tree = flag_tree:add(pf_flag_response, flagrange)
-- let's also add an expert info about it
if isResponse() then
query_flag_tree:add_proto_expert_info(ef_response, "It's a response!")
if transid == 42 then
tree:add_tvb_expert_info(ef_ultimate, tvbuf:range(0,2))
end
else
query_flag_tree:add_proto_expert_info(ef_query)
end
-- we now know if it's a response or query, so let's put that in the
-- GUI packet row, in the INFO column cell
-- this line of code uses a Lua trick for doing something similar to
-- the C/C++ 'test ? true : false' shorthand
pktinfo.cols.info:prepend(isResponse() and "Response " or "Query ")
flag_tree:add(pf_flag_opcode, flagrange)
if isResponse() then
flag_tree:add(pf_flag_authoritative, flagrange)
end
flag_tree:add(pf_flag_truncated, flagrange)
if isResponse() then
flag_tree:add(pf_flag_recursion_available, flagrange)
else
flag_tree:add(pf_flag_recursion_desired, flagrange)
end
flag_tree:add(pf_flag_z, flagrange)
if isResponse() then
flag_tree:add(pf_flag_authenticated, flagrange)
flag_tree:add(pf_flag_rcode, flagrange)
end
flag_tree:add(pf_flag_checking_disabled, flagrange)
-- now add more to the main mydns tree
tree:add(pf_num_questions, tvbuf:range(4,2))
tree:add(pf_num_answers, tvbuf:range(6,2))
-- another way to get a TvbRange is just to call the Tvb like this
tree:add(pf_num_authority_rr, tvbuf(8,2))
-- or if we're crazy, we can create a sub-TvbRange, from a sub-TvbRange of the TvbRange
tree:add(pf_num_additional_rr, tvbuf:range(10,2):range()())
local num_queries = questions_field()()
local pos = DNS_HDR_LEN
if num_queries > 0 then
-- let's create a sub-tree, using a plain text description (not a field from the packet)
local queries_tree = tree:add("Queries")
local pktlen_remaining = pktlen - pos
while num_queries > 0 and pktlen_remaining > 0 do
if pktlen_remaining < MIN_QUERY_LEN then
queries_tree:add_expert_info(PI_MALFORMED, PI_ERROR, "query field missing or too short")
return
end
-- we don't know how long this query field in total is, so we have to parse it first before
-- adding it to the tree, because we want to identify the correct bytes it covers
local label_count, name, name_len = getQueryName(tvbuf:range(pos,pktlen_remaining))
if not label_count then
q_tree:add_expert_info(PI_MALFORMED, PI_ERROR, name)
return
end
-- now add the first query to the 'Queries' child tree we just created
-- we're going to change the string generated by this later, after we figure out the subsequent fields.
-- the whole query field is the query name field length we just got, plus the 20byte type and 2-byte class
local q_tree = queries_tree:add(pf_query, tvbuf:range(pos, name_len + 4))
q_tree:add(pf_query_name, tvbuf:range(pos, name_len), name)
pos = pos + name_len
pktinfo.cols.info:append(" "..name)
-- the following tree items are generated by us, not encoded in the packet per se, so mark them as such
q_tree:add(pf_query_name_len, name_len):set_generated()
q_tree:add(pf_query_label_count, label_count):set_generated()
q_tree:add(pf_query_type, tvbuf:range(pos, 2))
q_tree:add(pf_query_class, tvbuf:range(pos + 2, 2))
pos = pos + 4
-- now change the query text
q_tree:set_text(name..": type "..query_type_field().display ..", class "..query_class_field().display)
pktlen_remaining = pktlen_remaining - (name_len + 4)
num_queries = num_queries - 1
end -- end of while loop
if num_queries > 0 then
-- we didn't process them all
queries_tree:add_expert_info(PI_MALFORMED, PI_ERROR, num_queries .. " query field(s) missing")
return
end
end
testlib.pass(FRAME)
-- tell wireshark how much of tvbuff we dissected
return pos
end
----------------------------------------
-- we want to have our protocol disseciton invoked for a specific UDP port,
-- so get the udp dissecotr table and add our protocol to it
local udp_encap_table = DissectorTable.get("udp.port")
udp_encap_table:add(MYDNS_PROTO_UDP_PORT, dns)
----------------------------------------
-- we also want to add the heuristic dissector, for any UDP protocol
-- first we need a heuristic dissection function
-- this is that function - when wireshark invokes this, it will pass in the same
-- things it passes in to the "dissector" function, but we only want to actually
-- dissect it if it's for us, and we need to return true if it's for us, or else false
-- figuring out if it's for us or not is not easy
-- we need to try as hard as possible, or else we'll think it's for us when it's
-- not and block other heuristic dissectors from getting their chanc
--
-- in practice, you'd never set a dissector like this to be heuristic, because there
-- just isn't enough information to safely detect if it's DNS or not
-- but I'm doing it to show how it would be done
--
-- Note: this heuristic stuff is new in 1.11.3
local function heur_dissect_dns(tvbuf,pktinfo,root)
if tvbuf:len() < DNS_HDR_LEN then
return false
end
local tvbr = tvbuf:range(0,DNS_HDR_LEN)
-- the first 2 bytes are tansaction id, which can be anything so no point in checking those
-- the next 2 bytes contain flags, a couple of which have some values we can check against
-- the opcode has to be 0, 1, 2, 4 or 5
-- the opcode field starts at bit offset 17 (in C-indexing), for 4 bits in length
local check = tvbr:bitfield(17,4)
if check == 3 or check > 5 then
return false
end
-- the rcode has to be 0-10, 16-22 (we're ignoring private use rcodes here)
-- the rcode field starts at bit offset 28 (in C-indexing), for 4 bits in length
check = tvbr:bitfield(28,4)
if check > 22 or (check > 10 and check < 16) then
return false
end
-- now let's verify the number of questions/answers are reasonable
check = tvbr:range(4,2):uint() -- num questions
if check > 100 then return false end
check = tvbr:range(6,2):uint() -- num answers
if check > 100 then return false end
check = tvbr:range(8,2):uint() -- num authority
if check > 100 then return false end
check = tvbr:range(10,2):uint() -- num additional
if check > 100 then return false end
-- don't do this line in your script - I'm just doing it so our testsuite can
-- verify this script
root:add("Heuristic dissector used"):set_generated()
-- ok, looks like it's ours, so go dissect it
-- note: calling the dissector directly like this is new in 1.11.3
-- also note that calling a Dissector objkect, as this does, means we don't
-- get back the return value of the dissector function we created previously
-- so it might be better to just call the function directly instead of doing
-- this, but this script is used for testing and this tests the call() function
dns.dissector(tvbuf,pktinfo,root)
-- since this is over a transport protocol, such as UDP, we can set the
-- conversation to make it sticky for our dissector, so that all future
-- packets to/from the same address:port pair will just call our dissector
-- function directly instead of this heuristic function
-- this is a new attribute of pinfo in 1.11.3
pktinfo.conversation = dns
return true
end
-- now register that heuristic dissector into the udp heuristic list
dns:register_heuristic("udp",heur_dissect_dns)
-- We're done!
-- our protocol (Proto) gets automatically registered after this script finishes loading
----------------------------------------
----------------------------------------
-- a helper function used later
-- note that it doesn't use "local" because it's already been declared as a local
-- variable way earlier in this script (as a form of forward declaration)
byteArray2String = function (barray, begin, length)
local word = {}
for i = 1, length do
word[i] = string.char(barray:get_index(begin))
begin = begin + 1
end
return table.concat(word)
end
----------------------------------------
-- DNS query names are not just null-terminated strings; they're actually a sequence of
-- 'labels', with a length octet before each one. So "foobar.com" is actually the
-- string "\06foobar\03com\00". We could create a ProtoField for label_length and label_name
-- or whatever, but since this is an example script I'll show how to do it in raw code.
-- This function is given the TvbRange object from the dissector() function, and needs to
-- parse it.
-- On success, it returns three things: the number of labels, the name string, and how
-- many bytes it covered of the buffer (which is always 2 more than the name length in this case).
-- On failure, it returns nil and the error message.
getQueryName = function (tvbr)
local label_count = 0
local name = ""
local len_remaining = tvbr:len()
if len_remaining < 2 then
-- it's too short
return nil, "invalid name"
end
local barray = tvbr:bytes() -- gets a ByteArray of the TvbRange
local pos = 0 -- unlike Lua, ByteArray uses 0-based indexing
-- get the first octet/label-length
local label_len = barray:get_index(pos)
if label_len == 0 then
return nil, "invalid initial label length of 0"
end
while label_len > 0 do
if label_len >= len_remaining then
return nil, "invalid label length of "..label_len
end
pos = pos + 1 -- move past label length octet
-- sadly, there's no current way to get a raw Lua string from a ByteArray (nor from Tvb for that matter)
-- so we need to do it one character at a time
-- append the label and a dot to name string
name = name .. byteArray2String(barray, pos, label_len) .. "."
len_remaining = len_remaining - (label_len + 1) -- subtract label and its length octet
label_count = label_count + 1
pos = pos + label_len -- move past label
label_len = barray:get_index(pos)
end
-- we appended an extra dot, so get rid of it
name = name:sub(1, -2)
return label_count, name, name:len() + 2
end
testlib.getResults()

View File

@ -1,15 +1,21 @@
----------------------------------------
-- script-name: protofield.lua
-- This is based on the dissector.lua example script, which is also used for testing.
-- Unlike that one, this one is purely for testing even more things, notably
-- the ProtoField API.
-- test the ProtoField API
----------------------------------------
local testlib = require("testlib")
local FRAME = "frame"
local PER_FRAME = "per-frame"
local OTHER = "other"
-- expected number of runs
local taptests = { [OTHER]=66 }
local n_frames = 4
local taptests = {
[FRAME]=n_frames,
[PER_FRAME]=n_frames*8,
[OTHER]=50,
}
testlib.init(taptests)
------------- test script ------------
@ -191,37 +197,40 @@ end
-- Test expected text with singular and plural forms
function test_proto.dissector(tvb, pinfo, tree)
local ti
testlib.countPacket(FRAME)
local tvb1 = ByteArray.new("00 00"):tvb("Tvb1")
ti = tree:add(test_proto.fields.time_field, tvb1())
testlib.test(OTHER,"Time: 0 secs", ti.text == "Time: 0 secs")
testlib.test(PER_FRAME,"Time: 0 secs", ti.text == "Time: 0 secs")
ti = tree:add(test_proto.fields.dist_field, tvb1())
testlib.test(OTHER,"Distance: 0 km", ti.text == "Distance: 0 km")
testlib.test(PER_FRAME,"Distance: 0 km", ti.text == "Distance: 0 km")
local tvb2 = ByteArray.new("00 01"):tvb("Tvb2")
ti = tree:add(test_proto.fields.time_field, tvb2())
testlib.test(OTHER,"Time: 1 sec", ti.text == "Time: 1 sec")
testlib.test(PER_FRAME,"Time: 1 sec", ti.text == "Time: 1 sec")
ti = tree:add(test_proto.fields.dist_field, tvb2())
testlib.test(OTHER,"Distance: 1 km", ti.text == "Distance: 1 km")
testlib.test(PER_FRAME,"Distance: 1 km", ti.text == "Distance: 1 km")
local tvb3 = ByteArray.new("ff ff"):tvb("Tvb3")
ti = tree:add(test_proto.fields.time_field, tvb3())
testlib.test(OTHER,"Time: 65535 secs", ti.text == "Time: 65535 secs")
testlib.test(PER_FRAME,"Time: 65535 secs", ti.text == "Time: 65535 secs")
ti = tree:add(test_proto.fields.dist_field, tvb3())
testlib.test(OTHER,"Distance: 65535 km", ti.text == "Distance: 65535 km")
testlib.test(PER_FRAME,"Distance: 65535 km", ti.text == "Distance: 65535 km")
ti = tree:add(test_proto.fields.filtered_field, tvb2())
-- Note that this file should be loaded in tshark twice. Once with a visible
-- tree (-V) and once without a visible tree.
if tree.visible then
-- Tree is visible so both fields should be referenced
testlib.test(OTHER,"Visible tree: Time is referenced", tree:referenced(test_proto.fields.time_field) == true)
testlib.test(OTHER,"Visible tree: Filtered field is referenced", tree:referenced(test_proto.fields.filtered_field) == true)
testlib.test(PER_FRAME,"Visible tree: Time is referenced", tree:referenced(test_proto.fields.time_field) == true)
testlib.test(PER_FRAME,"Visible tree: Filtered field is referenced", tree:referenced(test_proto.fields.filtered_field) == true)
else
-- Tree is not visible so only the field that appears in a filter should be referenced
testlib.test(OTHER,"Invisible tree: Time is NOT referenced", tree:referenced(test_proto.fields.time_field) == false)
testlib.test(OTHER,"Invisible tree: Filtered field is referenced", tree:referenced(test_proto.fields.filtered_field) == true)
testlib.test(PER_FRAME,"Invisible tree: Time is NOT referenced", tree:referenced(test_proto.fields.time_field) == false)
testlib.test(PER_FRAME,"Invisible tree: Filtered field is referenced", tree:referenced(test_proto.fields.filtered_field) == true)
end
testlib.pass(FRAME)
end
DissectorTable.get("udp.port"):add(65333, test_proto)
DissectorTable.get("udp.port"):add(65346, test_proto)

View File

@ -3,34 +3,22 @@
-- The first arg should be a number, for how many total args to expect,
-- including itself.
local function testing(...)
print("---- Testing "..tostring(...).." ----")
end
local testlib = require("testlib")
local function test(name, result)
io.stdout:write("test "..name.."...")
if result == true then
io.stdout:write("passed\n")
else
io.stdout:write("failed!\n")
error(name.." test failed!")
end
end
local ARGS = "args"
testlib.init({ [ARGS]=3 })
-----------------------------
testing("Command-line args")
testlib.testing("Command-line args")
local arg={...} -- get passed-in args
test("arg1", arg ~= nil and #arg > 0)
testlib.test(ARGS, "arg1", arg ~= nil and #arg > 0)
local numargs = tonumber(arg[1])
test("arg2", numargs ~= nil)
testlib.test(ARGS, "arg2", numargs ~= nil)
test("arg3", #arg == numargs)
print("\n-----------------------------\n")
print("All tests passed!\n\n")
testlib.test(ARGS, "arg3", #arg == numargs)
testlib.getResults()

View File

@ -3,11 +3,45 @@
--
-- Provides common functions for other lua test scripts to use.
----------------------------------------
--[[
This library aims to codify the most common practices used in testing
Wireshark's lua features. The intent is to reduce boilerplate code
so test scripts can focus on test cases.
Tests are nominally classified into named groups.
(In practice, most test files just use a single group called "other",
but this should be tidied up at some point.)
A test script must call testlib.init() with a table of
group names and the number of tests expected to be run in each group.
This number can be zero if you want to declare a group but don't
need to check that a specific number of tests is run.
Suggested use (abridged):
local testlib = require("testlib")
testlib.init({ other = 3 })
testlib.testing("other", "example tests")
testlib.test("other", "firsttest", 1+1 == 2)
testlib.test("other", "funccall", pcall(my_function, func_args), "function should succeed")
testlib.test("other", "funccall", not pcall(my_function2, func_args), "function expected to give error")
testlib.getResults()
For information on specific functions, keep reading.
--]]
----------------------------------------
-- This is the module object, which will be returned at the end of this file.
local M = {
["groups"] = {},
}
----------------------------------------
-- Initialize the test suite. Define one or more testing groups,
-- giving the expected number of tests to run for each.
-- (Telling it to "expect" zero tests for a group just skips
-- the check that a specific number of tests ran in that group.)
-- May be called repeatedly if you want to define group names
-- at runtime.
M.init = function(t)
for group, expected in pairs(t) do
M.groups[group] = {
@ -20,29 +54,37 @@ M.init = function(t)
end
end
-- Indicate a passed test in the named group
----------------------------------------
-- Indicate a passed test in the named group.
M.pass = function(group)
M.groups[group].passed = M.groups[group].passed + 1
M.groups[group].total = M.groups[group].total + 1
end
-- Indicate a failed test in the named group
----------------------------------------
-- Indicate a failed test in the named group.
M.fail = function(group)
M.groups[group].failed = M.groups[group].failed + 1
M.groups[group].total = M.groups[group].total + 1
end
-- Increment the number of packets tracked under the named group
----------------------------------------
-- There are some tests which track the number of packets they're testing.
-- Use this function to count a single packet as being "seen" by a group.
M.countPacket = function(group)
M.groups[group].packets = M.groups[group].packets + 1
end
-- Get the number of packets tracked under the named group
----------------------------------------
-- Get the number of packets that have been counted under the named group.
M.getPktCount = function(group)
return M.groups[group].packets
end
-- Print a banner reporting test progress
----------------------------------------
-- Print a banner reporting test progress.
-- Has no material affect on test progression, but is useful for
-- understanding the test results.
M.testing = function(group, msg)
if msg == nil then
msg, group = group, nil
@ -60,8 +102,12 @@ M.testing = function(group, msg)
end
end
-- Test a condition, report and track its status
----------------------------------------
-- Core function: test a condition, report and track its status.
-- The output format shown here is what was commonly used in test scripts,
-- but can be changed.
M.test = function(group, name, cond, msg)
-- io.stdout:write() doesn't add a newline like print() does
io.stdout:write(string.format("test %s --> %s-%d-%d...",
group, name, M.groups[group].total, M.groups[group].packets))
if cond then
@ -74,11 +120,26 @@ M.test = function(group, name, cond, msg)
if msg then
print(string.format("Got the following error: '%s'", msg))
end
-- Using error() causes the entire test script to abort.
-- This is how the lua test suite typically operates.
-- If a test script wants to continue with subsequent tests
-- after a failed test, this behaviour could be made
-- configurable in this module.
error(name .. " test failed!")
return false
end
end
-- Print the results of testing
----------------------------------------
-- Call this at the finale of a test script to output the results of testing.
-- This is where the number of tests run is compared to what was expected,
-- if applicable.
-- Scripts which run over empty.pcap will usually call this at the end of
-- the file.
-- Scripts which test by creating a protocol object will call this from
-- the object's .init() method *the second time it is called*.
-- Others usually call it in a tap listener's .draw() method,
-- which tshark calls once when it reaches the end of the pcap.
M.getResults = function()
local rv = true
print("\n===== Test Results =====")
@ -100,10 +161,14 @@ M.getResults = function()
end
if rv then
-- The python wrapper which performs our lua testing
-- expects to see this string in the output if there were no failures
-- expects to see this string in the output if there were no failures.
print("All tests passed!")
else
print("Some tests failed!")
end
return rv
end
----------------------------------------
-- That's the end of this library. Return the module we've created.
return M

View File

@ -1,9 +1,17 @@
-- test script for wslua utility functions
local testlib = require("testlib")
local OTHER = "other"
testlib.init( { [OTHER] = 0 } )
local GET_PREF = "get"
local SET_PREF = "set"
local RESET_PREF = "reset"
local OTHER = "other"
testlib.init( {
[GET_PREF] = 14,
[SET_PREF] = 37,
[RESET_PREF] = 11,
[OTHER] = 0
} )
local console_open
@ -13,98 +21,98 @@ local console_open
testlib.testing("get_preference")
success = pcall(get_preference)
testlib.test(OTHER,"get_preference-empty-0", not success)
testlib.test(OTHER,"get_preference-empty-1",get_preference("") == nil)
testlib.test(OTHER,"get_preference-unknown-0",get_preference("g") == nil)
testlib.test(OTHER,"get_preference-unknown-1",get_preference("gui") == nil)
testlib.test(OTHER,"get_preference-unknown-2",get_preference("gui.") == nil)
testlib.test(OTHER,"get_preference-unknown-3",get_preference("gui.ask") == nil)
testlib.test(OTHER,"get_preference-unknown-4",get_preference("ugi.ask_unsaved") == nil)
testlib.test(OTHER,"get_preference-uint-0",get_preference("gui.fileopen.preview") == 3)
testlib.test(OTHER,"get_preference-bool-0",get_preference("gui.ask_unsaved") == true)
testlib.test(OTHER,"get_preference-bool-1",get_preference("gui.interfaces_show_hidden") == false)
testlib.test(GET_PREF,"get_preference-empty-0", not success)
testlib.test(GET_PREF,"get_preference-empty-1",get_preference("") == nil)
testlib.test(GET_PREF,"get_preference-unknown-0",get_preference("g") == nil)
testlib.test(GET_PREF,"get_preference-unknown-1",get_preference("gui") == nil)
testlib.test(GET_PREF,"get_preference-unknown-2",get_preference("gui.") == nil)
testlib.test(GET_PREF,"get_preference-unknown-3",get_preference("gui.ask") == nil)
testlib.test(GET_PREF,"get_preference-unknown-4",get_preference("ugi.ask_unsaved") == nil)
testlib.test(GET_PREF,"get_preference-uint-0",get_preference("gui.fileopen.preview") == 3)
testlib.test(GET_PREF,"get_preference-bool-0",get_preference("gui.ask_unsaved") == true)
testlib.test(GET_PREF,"get_preference-bool-1",get_preference("gui.interfaces_show_hidden") == false)
-- gui.console_open is persistent (in the Windows registry) and for that
-- reason does not have a default value.
console_open = get_preference("gui.console_open")
testlib.test(OTHER,"get_preference-enum-0",console_open == "NEVER" or console_open == "AUTOMATIC" or console_open == "ALWAYS")
testlib.test(OTHER,"get_preference-string-0",get_preference("gui.window_title") == "")
testlib.test(OTHER,"get_preference-range-0",get_preference("http.tls.port") == "443")
testlib.test(GET_PREF,"get_preference-enum-0",console_open == "NEVER" or console_open == "AUTOMATIC" or console_open == "ALWAYS")
testlib.test(GET_PREF,"get_preference-string-0",get_preference("gui.window_title") == "")
testlib.test(GET_PREF,"get_preference-range-0",get_preference("http.tls.port") == "443")
success = pcall(get_preference, "user_dlt.encaps_table")
testlib.test(OTHER,"get_preference-uat-0", not success)
testlib.test(GET_PREF,"get_preference-uat-0", not success)
--------------------------
testlib.testing("set_preference")
success = pcall(set_preference)
testlib.test(OTHER,"set_preference-empty-0", not success)
testlib.test(OTHER,"set_preference-empty-1",set_preference("") == nil)
testlib.test(OTHER,"set_preference-unknown-0",set_preference("g") == nil)
testlib.test(OTHER,"set_preference-unknown-1",set_preference("gui") == nil)
testlib.test(OTHER,"set_preference-unknown-2",set_preference("gui.") == nil)
testlib.test(OTHER,"set_preference-unknown-3",set_preference("gui.ask") == nil)
testlib.test(OTHER,"set_preference-unknown-4",set_preference("ugi.ask_unsaved") == nil)
testlib.test(SET_PREF,"set_preference-empty-0", not success)
testlib.test(SET_PREF,"set_preference-empty-1",set_preference("") == nil)
testlib.test(SET_PREF,"set_preference-unknown-0",set_preference("g") == nil)
testlib.test(SET_PREF,"set_preference-unknown-1",set_preference("gui") == nil)
testlib.test(SET_PREF,"set_preference-unknown-2",set_preference("gui.") == nil)
testlib.test(SET_PREF,"set_preference-unknown-3",set_preference("gui.ask") == nil)
testlib.test(SET_PREF,"set_preference-unknown-4",set_preference("ugi.ask_unsaved") == nil)
success = pcall(set_preference,"gui.fileopen.preview")
testlib.test(OTHER,"set_preference-uint-0", not success)
testlib.test(SET_PREF,"set_preference-uint-0", not success)
success = pcall(set_preference,"gui.fileopen.preview",true)
testlib.test(OTHER,"set_preference-uint-1", not success)
testlib.test(SET_PREF,"set_preference-uint-1", not success)
success = pcall(set_preference,"gui.fileopen.preview","string")
testlib.test(OTHER,"set_preference-uint-2", not success)
testlib.test(OTHER,"set_preference-uint-3",set_preference("gui.fileopen.preview",3) == false)
testlib.test(OTHER,"set_preference-uint-4",set_preference("gui.fileopen.preview",42) == true)
testlib.test(OTHER,"set_preference-uint-4-get",get_preference("gui.fileopen.preview") == 42)
testlib.test(SET_PREF,"set_preference-uint-2", not success)
testlib.test(SET_PREF,"set_preference-uint-3",set_preference("gui.fileopen.preview",3) == false)
testlib.test(SET_PREF,"set_preference-uint-4",set_preference("gui.fileopen.preview",42) == true)
testlib.test(SET_PREF,"set_preference-uint-4-get",get_preference("gui.fileopen.preview") == 42)
success = pcall(set_preference,"gui.ask_unsaved")
testlib.test(OTHER,"set_preference-bool-0", not success)
testlib.test(SET_PREF,"set_preference-bool-0", not success)
success = pcall(set_preference,"gui.ask_unsaved",42)
testlib.test(OTHER,"set_preference-bool-1", not success)
testlib.test(SET_PREF,"set_preference-bool-1", not success)
success = pcall(set_preference,"gui.ask_unsaved","string")
testlib.test(OTHER,"set_preference-bool-2", not success)
testlib.test(OTHER,"set_preference-bool-3",set_preference("gui.ask_unsaved", true) == false)
testlib.test(OTHER,"set_preference-bool-4",set_preference("gui.ask_unsaved", false) == true)
testlib.test(SET_PREF,"set_preference-bool-2", not success)
testlib.test(SET_PREF,"set_preference-bool-3",set_preference("gui.ask_unsaved", true) == false)
testlib.test(SET_PREF,"set_preference-bool-4",set_preference("gui.ask_unsaved", false) == true)
success = pcall(set_preference,"gui.console_open")
testlib.test(OTHER,"set_preference-enum-0", not success)
testlib.test(SET_PREF,"set_preference-enum-0", not success)
success = pcall(set_preference,"gui.console_open",true)
testlib.test(OTHER,"set_preference-enum-1", not success)
testlib.test(SET_PREF,"set_preference-enum-1", not success)
-- false means unchanged
testlib.test(OTHER,"set_preference-enum-2",set_preference("gui.console_open",console_open) == false)
testlib.test(SET_PREF,"set_preference-enum-2",set_preference("gui.console_open",console_open) == false)
success = pcall(set_preference,"gui.window_title")
testlib.test(OTHER,"set_preference-string-0", not success)
testlib.test(SET_PREF,"set_preference-string-0", not success)
success = pcall(set_preference,"gui.window_title",true)
testlib.test(OTHER,"set_preference-string-1", not success)
testlib.test(OTHER,"set_preference-string-2",set_preference("gui.window_title","Title") == true)
testlib.test(OTHER,"set_preference-string-2-get",get_preference("gui.window_title") == "Title")
testlib.test(OTHER,"set_preference-string-3",set_preference("gui.window_title","Title") == false)
testlib.test(OTHER,"set_preference-string-4",set_preference("gui.window_title","") == true)
testlib.test(OTHER,"set_preference-string-4-get",get_preference("gui.window_title") == "")
testlib.test(OTHER,"set_preference-string-5",set_preference("gui.window_title","") == false)
testlib.test(SET_PREF,"set_preference-string-1", not success)
testlib.test(SET_PREF,"set_preference-string-2",set_preference("gui.window_title","Title") == true)
testlib.test(SET_PREF,"set_preference-string-2-get",get_preference("gui.window_title") == "Title")
testlib.test(SET_PREF,"set_preference-string-3",set_preference("gui.window_title","Title") == false)
testlib.test(SET_PREF,"set_preference-string-4",set_preference("gui.window_title","") == true)
testlib.test(SET_PREF,"set_preference-string-4-get",get_preference("gui.window_title") == "")
testlib.test(SET_PREF,"set_preference-string-5",set_preference("gui.window_title","") == false)
success = pcall(set_preference,"http.tls.port")
testlib.test(OTHER,"set_preference-range-0", not success)
testlib.test(SET_PREF,"set_preference-range-0", not success)
success = pcall(set_preference,"http.tls.port","65536") -- Number too big
testlib.test(OTHER,"set_preference-range-1", not success)
testlib.test(SET_PREF,"set_preference-range-1", not success)
success = pcall(set_preference,"http.tls.port","http") -- Syntax error
testlib.test(OTHER,"set_preference-range-2", not success)
testlib.test(OTHER,"set_preference-range-3",set_preference("http.tls.port","443") == false)
testlib.test(OTHER,"set_preference-range-4",set_preference("http.tls.port","443-444") == true)
testlib.test(OTHER,"set_preference-range-4-get",get_preference("http.tls.port") == "443-444")
testlib.test(OTHER,"set_preference-range-5",set_preference("http.tls.port","443-444") == false)
testlib.test(SET_PREF,"set_preference-range-2", not success)
testlib.test(SET_PREF,"set_preference-range-3",set_preference("http.tls.port","443") == false)
testlib.test(SET_PREF,"set_preference-range-4",set_preference("http.tls.port","443-444") == true)
testlib.test(SET_PREF,"set_preference-range-4-get",get_preference("http.tls.port") == "443-444")
testlib.test(SET_PREF,"set_preference-range-5",set_preference("http.tls.port","443-444") == false)
success = pcall(set_preference, "user_dlt.encaps_table")
testlib.test(OTHER,"set_preference-uat-0", not success)
testlib.test(SET_PREF,"set_preference-uat-0", not success)
--------------------------
testlib.testing("reset_preference")
success = pcall(set_preference)
testlib.test(OTHER,"reset_preference-empty-0", not success)
testlib.test(OTHER,"reset_preference-empty-1",reset_preference("") == nil)
testlib.test(OTHER,"reset_preference-unknown-0",reset_preference("unknown") == nil)
testlib.test(OTHER,"reset_preference-uint-0",reset_preference("gui.fileopen.preview") == true)
testlib.test(OTHER,"reset_preference-uint-0-get",get_preference("gui.fileopen.preview") == 3)
testlib.test(OTHER,"reset_preference-bool-0",reset_preference("gui.ask_unsaved") == true)
testlib.test(OTHER,"reset_preference-bool-0-get",get_preference("gui.ask_unsaved") == true)
testlib.test(OTHER,"reset_preference-string-0",reset_preference("gui.window_title") == true)
testlib.test(OTHER,"reset_preference-string-0-get",get_preference("gui.window_title") == "")
testlib.test(OTHER,"reset_preference-range-0",reset_preference("http.tls.port") == true)
testlib.test(OTHER,"reset_preference-range-0-get",get_preference("http.tls.port") == "443")
testlib.test(RESET_PREF,"reset_preference-empty-0", not success)
testlib.test(RESET_PREF,"reset_preference-empty-1",reset_preference("") == nil)
testlib.test(RESET_PREF,"reset_preference-unknown-0",reset_preference("unknown") == nil)
testlib.test(RESET_PREF,"reset_preference-uint-0",reset_preference("gui.fileopen.preview") == true)
testlib.test(RESET_PREF,"reset_preference-uint-0-get",get_preference("gui.fileopen.preview") == 3)
testlib.test(RESET_PREF,"reset_preference-bool-0",reset_preference("gui.ask_unsaved") == true)
testlib.test(RESET_PREF,"reset_preference-bool-0-get",get_preference("gui.ask_unsaved") == true)
testlib.test(RESET_PREF,"reset_preference-string-0",reset_preference("gui.window_title") == true)
testlib.test(RESET_PREF,"reset_preference-string-0-get",get_preference("gui.window_title") == "")
testlib.test(RESET_PREF,"reset_preference-range-0",reset_preference("http.tls.port") == true)
testlib.test(RESET_PREF,"reset_preference-range-0-get",get_preference("http.tls.port") == "443")
testlib.getResults()

View File

@ -195,9 +195,9 @@ class TestWslua:
'''wslua pinfo'''
check_lua_script('pinfo.lua', dhcp_pcap, True)
def test_wslua_proto(self, check_lua_script_verify):
def test_wslua_proto(self, check_lua_script):
'''wslua proto'''
check_lua_script_verify('proto.lua', dns_port_pcap, check_stage_1=True)
check_lua_script('proto.lua', empty_pcap, True)
def test_wslua_protofield_tree(self, check_lua_script):
'''wslua protofield with a tree'''