diff --git a/lua_tests/expectnmcu/core.tcl b/lua_tests/expectnmcu/core.tcl new file mode 100644 index 0000000000..9827ab0bfd --- /dev/null +++ b/lua_tests/expectnmcu/core.tcl @@ -0,0 +1,55 @@ +namespace eval expectnmcu::core { +} + +# Establish a serial connection to the device via socat +proc ::expectnmcu::core::connect { dev baud } { + spawn "socat" "STDIO" "${dev},b${baud},rawer,crnl" + close -onexec 1 -i ${spawn_id} + return ${spawn_id} +} + +# Use DTR/RTS signaling to reboot the device +## I'm not sure why we have to keep resetting the mode, but so it goes. +proc ::expectnmcu::core::reboot { dev baud } { + set victimfd [open "${dev}"] + fconfigure ${victimfd} -mode ${baud},n,8,1 -ttycontrol {DTR 0 RTS 1} + sleep 0.1 + fconfigure ${victimfd} -mode ${baud},n,8,1 -ttycontrol {DTR 0 RTS 0} + close ${victimfd} +} + +proc ::expectnmcu::core::waitboot { victim } { + expect { + -i ${victim} "Formatting file system" { + set timeout 60 + exp_continue + } + -i ${victim} "powered by Lua" { } + timeout { return -code error "Timeout" } + } + # Catch nwf's system bootup, in case we're testing an existing system, + # rather than a blank firmware. + expect { + -i ${victim} "Reset delay!" { send "got:stop()\n" ; expect "> " } + -i ${victim} "> " { } + timeout { return -code error "Timeout" } + } +} + +proc ::expectnmcu::core::send_exp_prompt { sid cmd } { + send -i ${sid} -- "${cmd}\n" + expect { + -i ${sid} -ex "\n> " { } + timeout { return -code error "Timeout" } + } +} + +proc ::expectnmcu::core::send_exp_prompt_c { sid cmd } { + send -i ${sid} -- "${cmd}\n" + expect { + -i ${sid} -ex "\n>> " { } + timeout { return -code error "Timeout" } + } +} + +package provide expectnmcu::core 1.0 diff --git a/lua_tests/expectnmcu/pkgIndex.tcl b/lua_tests/expectnmcu/pkgIndex.tcl new file mode 100644 index 0000000000..5b74575461 --- /dev/null +++ b/lua_tests/expectnmcu/pkgIndex.tcl @@ -0,0 +1,11 @@ +# Tcl package index file, version 1.1 +# This file is generated by the "pkg_mkIndex" command +# and sourced either when an application starts up or +# by a "package unknown" script. It invokes the +# "package ifneeded" command to set up package-related +# information so that packages will be loaded automatically +# in response to "package require" commands. When this +# script is sourced, the variable $dir must contain the +# full path name of this file's directory. + +package ifneeded expectnmcu::core 1.0 [list source [file join $dir core.tcl]] diff --git a/lua_tests/tls-test.expect b/lua_tests/tls-test.expect index 3aa2cc585d..bc92f228a0 100644 --- a/lua_tests/tls-test.expect +++ b/lua_tests/tls-test.expect @@ -8,7 +8,7 @@ # overridden with the -ip command line option. # # A typical invocation looks like: -# ./tls-test.expect -serial /dev/ttyUSB3 -wifi "$(cat wificmd)" +# TCLLIBPATH=./expectnmcu ./tls-test.expect -serial /dev/ttyUSB3 -wifi "$(cat wificmd)" # # where the file `wificmd` contains something like # wifi.setmode(wifi.STATION); wifi.sta.config({...}); wifi.sta.connect() @@ -18,10 +18,11 @@ # For debugging the test itself, it may be useful to invoke expect with -d, # which will give a great deal of diagnostic information about the expect state # machine's internals: -# expect -d ./tls-test.expect ... +# TCLLIBPATH=./expectnmcu expect -d ./tls-test.expect ... package require struct::stack +package require expectnmcu::core ::struct::stack ulogstack proc pushulog { new } { @@ -30,20 +31,6 @@ proc pushulog { new } { } proc populog { } { log_user [ulogstack pop] } -proc send_exp_prompt { sid cmd } { - send -i ${sid} -- "${cmd}\n" - expect { - -i ${sid} -ex "\n> " { } - } -} - -proc send_exp_prompt_c { sid cmd } { - send -i ${sid} -- "${cmd}\n" - expect { - -i ${sid} -ex "\n>> " { } - } -} - proc genectls { curve pfx } { exec "openssl" "ecparam" "-genkey" "-name" ${curve} "-out" "${pfx}.key" exec "openssl" "req" "-new" "-sha256" "-subj" "/CN=${curve}" "-key" "${pfx}.key" "-out" "${pfx}.csr" @@ -51,14 +38,14 @@ proc genectls { curve pfx } { } proc preptls { victim } { - send_exp_prompt_c ${victim} "function tlsbasic(id,port,host)" - send_exp_prompt_c ${victim} " local c = tls.createConnection()" - send_exp_prompt_c ${victim} " c:on(\"receive\", function(sck, d) print(\"RECV\",id,d) end)" - send_exp_prompt_c ${victim} " c:on(\"connection\", function(sck) print(\"CONN\",id); sck:send(\"GET / HTTP/1.0\\r\\n\\r\\n\") end)" - send_exp_prompt_c ${victim} " c:on(\"disconnection\", function(sck) print(\"DISC\",id) end)" - send_exp_prompt_c ${victim} " c:connect(port,host)" - send_exp_prompt_c ${victim} " return c" - send_exp_prompt ${victim} "end" + ::expectnmcu::core::send_exp_prompt_c ${victim} "function tlsbasic(id,port,host)" + ::expectnmcu::core::send_exp_prompt_c ${victim} " local c = tls.createConnection()" + ::expectnmcu::core::send_exp_prompt_c ${victim} " c:on(\"receive\", function(sck, d) print(\"RECV\",id,d) end)" + ::expectnmcu::core::send_exp_prompt_c ${victim} " c:on(\"connection\", function(sck) print(\"CONN\",id); sck:send(\"GET / HTTP/1.0\\r\\n\\r\\n\") end)" + ::expectnmcu::core::send_exp_prompt_c ${victim} " c:on(\"disconnection\", function(sck) print(\"DISC\",id) end)" + ::expectnmcu::core::send_exp_prompt_c ${victim} " c:connect(port,host)" + ::expectnmcu::core::send_exp_prompt_c ${victim} " return c" + ::expectnmcu::core::send_exp_prompt ${victim} "end" } # Basic connectivity test, including disconnection of localsid. @@ -81,7 +68,7 @@ proc basicconntest { id localsid victimsid victimconn } { populog expect { -i ${victimsid} "RECV\t${id}\tabracadabra" { - send_exp_prompt ${victimsid} "${victimconn}:send(\"test 1 2 3 4\")" + ::expectnmcu::core::send_exp_prompt ${victimsid} "${victimconn}:send(\"test 1 2 3 4\")" } } pushulog 0 @@ -120,36 +107,11 @@ if {[catch {array set cmdopts [cmdline::getoptions ::argv $cmd_parameters $cmd_u send_user "===> Note: Serial port is ${cmdopts(serial)}; debug is ${cmdopts(debug)} <===\n" -spawn "socat" "STDIO" "${cmdopts(serial)},rawer,crnl" -set victim ${spawn_id} -close -onexec 1 -i ${victim} - -# Use DTR/RTS signaling to reboot the device -## I'm not sure why we have to keep resetting the mode, but so it goes. -set victimfd [open "${cmdopts(serial)}"] -fconfigure ${victimfd} -mode 115200,n,8,1 -ttycontrol {DTR 0 RTS 1} -sleep 0.1 -fconfigure ${victimfd} -mode 115200,n,8,1 -ttycontrol {DTR 0 RTS 0} -close ${victimfd} +set victim [::expectnmcu::core::connect ${cmdopts(serial)} 115200] +::expectnmcu::core::reboot ${cmdopts(serial)} 115200 # Wait for the system to boot -expect { - -i ${victim} "Formatting file system" { - set timeout 60 - exp_continue - } - -i ${victim} "powered by Lua" { } - timeout { - send_user "\n===> Did not see boot sequence; bailing out <===\n" - exit 0 - } -} -# Catch nwf's system bootup, in case we're testing an existing system, -# rather than a blank firmware. -expect { - -i ${victim} "Reset delay!" { send "got:stop()\n" ; expect "> " } - -i ${victim} "> " { } -} +::expectnmcu::core::waitboot ${victim} send_user "\n===> Machine has booted <===\n" # Program a routine for TLS connections @@ -158,7 +120,7 @@ preptls ${victim} # Connect the board to the network if {[expr 0 < [string length ${cmdopts(wifi)}]]} { - send_exp_prompt ${victim} ${cmdopts(wifi)} + ::expectnmcu::core::send_exp_prompt ${victim} ${cmdopts(wifi)} } for {set i 0} {${i} < 10} {incr i} { @@ -193,34 +155,34 @@ if {[expr 0 < [string length ${cmdopts(ip)}]]} { close } -send_exp_prompt ${victim} "tls.setDebug(2)" -send_exp_prompt ${victim} "tls.cert.verify(false)" +::expectnmcu::core::send_exp_prompt ${victim} "tls.setDebug(2)" +::expectnmcu::core::send_exp_prompt ${victim} "tls.cert.verify(false)" send_user "\n===> TEST SSL 256v1, no verify <===\n" spawn -noecho "socat" "STDIO,cfmakeraw" "OPENSSL-LISTEN:12345,verify=0,certificate=${fntls256v1}.crt,key=${fntls256v1}.key,reuseaddr" -send_exp_prompt ${victim} "c = tlsbasic(0,12345,\"${myip}\")" +::expectnmcu::core::send_exp_prompt ${victim} "c = tlsbasic(0,12345,\"${myip}\")" basicconntest 0 ${spawn_id} ${victim} "c" send_user "\n===> TEST SSL 384r1, no verify <===\n" spawn -noecho "socat" "STDIO,cfmakeraw" "OPENSSL-LISTEN:12345,verify=0,certificate=${fntls384r1}.crt,key=${fntls384r1}.key,reuseaddr" -send_exp_prompt ${victim} "c = tlsbasic(1,12345,\"${myip}\")" +::expectnmcu::core::send_exp_prompt ${victim} "c = tlsbasic(1,12345,\"${myip}\")" basicconntest 1 ${spawn_id} ${victim} "c" send_user "\n===> TEST SSL 384r1, verify <===\n" set cert [open "${fntls384r1}.crt"] -send_exp_prompt_c ${victim} "tls.cert.verify(\[\[" +::expectnmcu::core::send_exp_prompt_c ${victim} "tls.cert.verify(\[\[" while { [gets $cert line] >= 0 } { - send_exp_prompt_c ${victim} $line + ::expectnmcu::core::send_exp_prompt_c ${victim} $line } -send_exp_prompt ${victim} "]])" +::expectnmcu::core::send_exp_prompt ${victim} "]])" close ${cert} -send_exp_prompt ${victim} "tls.cert.verify(true)" +::expectnmcu::core::send_exp_prompt ${victim} "tls.cert.verify(true)" spawn -noecho "socat" "STDIO,cfmakeraw" "OPENSSL-LISTEN:12345,verify=0,certificate=${fntls384r1}.crt,key=${fntls384r1}.key,reuseaddr" -send_exp_prompt ${victim} "c = tlsbasic(2,12345,\"${myip}\")" +::expectnmcu::core::send_exp_prompt ${victim} "c = tlsbasic(2,12345,\"${myip}\")" basicconntest 2 ${spawn_id} ${victim} "c" send_user "\n===> TESTS OK <===\n"