tests: introduce NTestEnv utility functions
This commit is contained in:
parent
5fc1a362e0
commit
14f06e8c98
|
@ -226,4 +226,15 @@ GPIO 15 |Secondary UART TX; DUT 0 GPIO 13, I/O exp B 6 via 4K7 Also used as HS
|
||||||
GPIO 16 |I/O expander B 5 via 4K7 resistor, for deep-sleep tests
|
GPIO 16 |I/O expander B 5 via 4K7 resistor, for deep-sleep tests
|
||||||
ADC 0 |
|
ADC 0 |
|
||||||
|
|
||||||
|
# Probing the Test Environment from Tests
|
||||||
|
|
||||||
|
The `NTestEnv` module provides convenient functions for preflight checks
|
||||||
|
and limited adaptation of test programs.
|
||||||
|
|
||||||
|
## Test Configuration File
|
||||||
|
|
||||||
|
Our tests expect a `testenv.conf` in SPIFFS to provide parameters to
|
||||||
|
some tests. This file is a JSON map with the following keys:
|
||||||
|
|
||||||
|
- "DUT". Its value is either 0 or 1 indicating which DUT is running the
|
||||||
|
given test.
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"DUT": 0
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"DUT": 1
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
-- A series of convenient utility functions for use with NTest on NodeMCU
|
||||||
|
-- devices under test (DUTs).
|
||||||
|
|
||||||
|
local NTE = {}
|
||||||
|
|
||||||
|
-- Determine if the firmware has been built with a given module
|
||||||
|
function NTE.hasC(m)
|
||||||
|
-- this isn't great, but it's what we've got
|
||||||
|
local mstr = node.info('build_config').modules
|
||||||
|
return mstr:match("^"..m..",") -- first module in the list
|
||||||
|
or mstr:match(","..m.."$") -- last module in the list
|
||||||
|
or mstr:match(","..m..",") -- somewhere else
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Determine if a given Lua module is available for require-ing.
|
||||||
|
function NTE.hasL(m)
|
||||||
|
for _, l in ipairs(package.loaders) do
|
||||||
|
if type(l(m)) == "function" then return true end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Look up one (or more) feature keys in our configuration file,
|
||||||
|
-- returning the associated value (or a map from keys to values).
|
||||||
|
function NTE.getFeat(...)
|
||||||
|
-- Stream through our configuration file and extract the features attested
|
||||||
|
--
|
||||||
|
-- We expect the configuration file to attest features as keys in a dictionary
|
||||||
|
-- so that they can be efficiently probed here but also so that we can
|
||||||
|
-- parameterize features.
|
||||||
|
--
|
||||||
|
-- {
|
||||||
|
-- "feat1" : ... ,
|
||||||
|
-- "feat2" : ...
|
||||||
|
-- }
|
||||||
|
local reqFeats = { ... }
|
||||||
|
local decoder = sjson.decoder({
|
||||||
|
metatable = {
|
||||||
|
checkpath = function(_, p)
|
||||||
|
if #p > 1 then return true end -- something we're keeping
|
||||||
|
if #p == 0 then return true end -- root table
|
||||||
|
local thisFeat = p[1]
|
||||||
|
assert (type(thisFeat) == "string")
|
||||||
|
for _, v in ipairs(reqFeats) do
|
||||||
|
if v == thisFeat then return true end -- requested feature
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
}
|
||||||
|
})
|
||||||
|
local cfgf = file.open("testenv.conf", "r")
|
||||||
|
|
||||||
|
if cfgf == nil then return {} end -- no features if no config file
|
||||||
|
|
||||||
|
local cstr
|
||||||
|
repeat
|
||||||
|
cstr = cfgf:read(); decoder:write(cstr or "")
|
||||||
|
until (not cstr or #cstr == 0)
|
||||||
|
cfgf:close()
|
||||||
|
local givenFeats = decoder:result()
|
||||||
|
assert (type(givenFeats) == "table", "Malformed configuration file")
|
||||||
|
|
||||||
|
local res = {}
|
||||||
|
for _, v in ipairs(reqFeats) do
|
||||||
|
res[v] = givenFeats[v] or error("Missing required feature " .. v)
|
||||||
|
end
|
||||||
|
|
||||||
|
if #reqFeats == 1 then return res[reqFeats[1]] end
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
return NTE
|
Loading…
Reference in New Issue