Merge branch 'master' into feature/cmake

This commit is contained in:
Angus Gratton
2018-08-30 18:52:31 +08:00
committed by Angus Gratton
35 changed files with 31787 additions and 1546 deletions

View File

@@ -28,9 +28,9 @@ if test_fw_path and test_fw_path not in sys.path:
sys.path.insert(0, test_fw_path)
# When running on local machine execute the following before running this script
# > export TEST_FW_PATH='~/esp/esp-idf/tools/tiny-test-fw'
# > make print_flash_cmd | tail -n 1 > build/download.config
# > make app bootloader
# > make print_flash_cmd | tail -n 1 > build/download.config
# > export TEST_FW_PATH=~/esp/esp-idf/tools/tiny-test-fw
import TinyFW
import IDF
@@ -39,7 +39,7 @@ import IDF
expath = os.path.dirname(os.path.realpath(__file__))
client = imp.load_source("client", expath + "/scripts/client.py")
@IDF.idf_example_test(env_tag="Example_WIFI", ignore=True)
@IDF.idf_example_test(env_tag="Example_WIFI")
def test_examples_protocol_http_server_simple(env, extra_data):
# Acquire DUT
dut1 = env.get_dut("http_server", "examples/protocols/http_server/simple")
@@ -47,21 +47,23 @@ def test_examples_protocol_http_server_simple(env, extra_data):
# Get binary file
binary_file = os.path.join(dut1.app.binary_path, "simple.bin")
bin_size = os.path.getsize(binary_file)
IDF.log_performance("http_server_bin_size", "{}KB".format(bin_size//1024))
IDF.check_performance("http_server_bin_size", bin_size//1024)
IDF.log_performance("http_server_bin_size", "{}KB".format(bin_size/1024))
IDF.check_performance("http_server_bin_size", bin_size/1024)
# Upload binary and start testing
print "Starting http_server simple test app"
dut1.start_app()
# Parse IP address of STA
got_ip = dut1.expect(re.compile(r"(?:[\s\S]*)Got IP: (\d+.\d+.\d+.\d+)"), timeout=30)[0]
got_port = dut1.expect(re.compile(r"(?:[\s\S]*)Starting server on port: (\d+)"))[0]
print "Waiting to connect with AP"
got_ip = dut1.expect(re.compile(r"(?:[\s\S]*)Got IP: (\d+.\d+.\d+.\d+)"), timeout=120)[0]
got_port = dut1.expect(re.compile(r"(?:[\s\S]*)Starting server on port: (\d+)"), timeout=30)[0]
print "Got IP : " + got_ip
print "Got Port : " + got_port
# Expected Logs
dut1.expect("Registering URI handlers")
dut1.expect("Registering URI handlers", timeout=30)
# Run test script
# If failed raise appropriate exception
@@ -70,24 +72,24 @@ def test_examples_protocol_http_server_simple(env, extra_data):
raise RuntimeError
# Acquire host IP. Need a way to check it
host_ip = dut1.expect(re.compile(r"(?:[\s\S]*)Found header => Host: (\d+.\d+.\d+.\d+)"))[0]
host_ip = dut1.expect(re.compile(r"(?:[\s\S]*)Found header => Host: (\d+.\d+.\d+.\d+)"), timeout=30)[0]
# Match additional headers sent in the request
dut1.expect("Found header => Test-Header-2: Test-Value-2")
dut1.expect("Found header => Test-Header-1: Test-Value-1")
dut1.expect("Found URL query parameter => query1=value1")
dut1.expect("Found URL query parameter => query3=value3")
dut1.expect("Found URL query parameter => query2=value2")
dut1.expect("Request headers lost")
dut1.expect("Found header => Test-Header-2: Test-Value-2", timeout=30)
dut1.expect("Found header => Test-Header-1: Test-Value-1", timeout=30)
dut1.expect("Found URL query parameter => query1=value1", timeout=30)
dut1.expect("Found URL query parameter => query3=value3", timeout=30)
dut1.expect("Found URL query parameter => query2=value2", timeout=30)
dut1.expect("Request headers lost", timeout=30)
print "Test /ctrl PUT handler and realtime handler de/registration"
if not client.test_put_handler(got_ip, got_port):
raise RuntimeError
dut1.expect("Unregistering /hello and /echo URIs")
dut1.expect("Registering /hello and /echo URIs")
dut1.expect("Unregistering /hello and /echo URIs", timeout=30)
dut1.expect("Registering /hello and /echo URIs", timeout=30)
# Generate random data of 10KB
random_data = ''.join(string.printable[random.randint(0,len(string.printable))-1] for _ in range(1024*10))
random_data = ''.join(string.printable[random.randint(0,len(string.printable))-1] for _ in range(10*1024))
print "Test /echo POST handler with random data"
if not client.test_post_handler(got_ip, got_port, random_data):
raise RuntimeError
@@ -96,19 +98,19 @@ def test_examples_protocol_http_server_simple(env, extra_data):
print "Test /hello with custom query : " + query
if not client.test_custom_uri_query(got_ip, got_port, query):
raise RuntimeError
dut1.expect("Found URL query => " + query)
dut1.expect("Found URL query => " + query, timeout=30)
query = "abcd+1234%20xyz"
print "Test /hello with custom query : " + query
if not client.test_custom_uri_query(got_ip, got_port, query):
raise RuntimeError
dut1.expect("Found URL query => " + query)
dut1.expect("Found URL query => " + query, timeout=30)
query = "abcd\nyz"
print "Test /hello with invalid query"
if client.test_custom_uri_query(got_ip, got_port, query):
raise RuntimeError
dut1.expect("400 Bad Request - Server unable to understand request due to invalid syntax")
dut1.expect("400 Bad Request - Server unable to understand request due to invalid syntax", timeout=30)
if __name__ == '__main__':
test_examples_protocol_http_server_simple()

View File

@@ -14,117 +14,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import socket
import httplib
import argparse
class Session:
def __init__(self, addr, port):
self.client = socket.create_connection((addr, int(port)))
self.target = addr
def send_get(self, path, headers=None):
request = "GET " + path + " HTTP/1.1\r\nHost: " + self.target
if headers:
for field, value in headers.iteritems():
request += "\r\n"+field+": "+value
request += "\r\n\r\n"
self.client.send(request);
def send_put(self, path, data, headers=None):
request = "PUT " + path + " HTTP/1.1\r\nHost: " + self.target
if headers:
for field, value in headers.iteritems():
request += "\r\n"+field+": "+value
request += "\r\nContent-Length: " + str(len(data)) +"\r\n\r\n"
self.client.send(request)
self.client.send(data)
def send_post(self, path, data, headers=None):
request = "POST " + path + " HTTP/1.1\r\nHost: " + self.target
if headers:
for field, value in headers.iteritems():
request += "\r\n"+field+": "+value
request += "\r\nContent-Length: " + str(len(data)) +"\r\n\r\n"
self.client.send(request)
self.client.send(data)
def read_resp_hdrs(self):
state = 'nothing'
resp_read = ''
while True:
char = self.client.recv(1)
if char == '\r' and state == 'nothing':
state = 'first_cr'
elif char == '\n' and state == 'first_cr':
state = 'first_lf'
elif char == '\r' and state == 'first_lf':
state = 'second_cr'
elif char == '\n' and state == 'second_cr':
state = 'second_lf'
else:
state = 'nothing'
resp_read += char
if state == 'second_lf':
break;
# Handle first line
line_hdrs = resp_read.splitlines()
line_comp = line_hdrs[0].split()
self.status = line_comp[1]
del line_hdrs[0]
self.encoding = ''
self.content_type = ''
headers = dict()
# Process other headers
for h in range(len(line_hdrs)):
line_comp = line_hdrs[h].split(':')
if line_comp[0] == 'Content-Length':
self.content_len = int(line_comp[1])
if line_comp[0] == 'Content-Type':
self.content_type = line_comp[1].lstrip()
if line_comp[0] == 'Transfer-Encoding':
self.encoding = line_comp[1].lstrip()
if len(line_comp) == 2:
headers[line_comp[0]] = line_comp[1].lstrip()
return headers
def read_resp_data(self):
read_data = ''
if self.encoding != 'chunked':
while len(read_data) != self.content_len:
read_data += self.client.recv(self.content_len)
self.content_len = 0
else:
chunk_data_buf = ''
while (True):
# Read one character into temp buffer
read_ch = self.client.recv(1)
# Check CRLF
if (read_ch == '\r'):
read_ch = self.client.recv(1)
if (read_ch == '\n'):
# If CRLF decode length of chunk
chunk_len = int(chunk_data_buf, 16)
# Keep adding to contents
self.content_len += chunk_len
read_data += self.client.recv(chunk_len)
chunk_data_buf = ''
# Fetch remaining CRLF
if self.client.recv(2) != "\r\n":
# Error in packet
return None
if not chunk_len:
# If last chunk
break
continue
chunk_data_buf += '\r'
# If not CRLF continue appending
# character to chunked data buffer
chunk_data_buf += read_ch
return read_data
def close(self):
self.client.close()
def verbose_print(verbosity, *args):
if (verbosity):
print ''.join(str(elems) for elems in args)
@@ -133,7 +25,7 @@ def test_get_handler(ip, port, verbosity = False):
verbose_print(verbosity, "======== GET HANDLER TEST =============")
# Establish HTTP connection
verbose_print(verbosity, "Connecting to => " + ip + ":" + port)
sess = Session(ip, port)
sess = httplib.HTTPConnection(ip + ":" + port)
uri = "/hello?query1=value1&query2=value2&query3=value3"
# GET hello response
@@ -142,13 +34,14 @@ def test_get_handler(ip, port, verbosity = False):
verbose_print(verbosity, "Sending additional headers : ")
for k, v in test_headers.iteritems():
verbose_print(verbosity, "\t", k, ": ", v)
sess.send_get(uri, test_headers)
resp_hdrs = sess.read_resp_hdrs()
resp_data = sess.read_resp_data()
sess.request("GET", url=uri, headers=test_headers)
resp = sess.getresponse()
resp_hdrs = resp.getheaders()
resp_data = resp.read()
try:
if resp_hdrs["Custom-Header-1"] != "Custom-Value-1":
if resp.getheader("Custom-Header-1") != "Custom-Value-1":
return False
if resp_hdrs["Custom-Header-2"] != "Custom-Value-2":
if resp.getheader("Custom-Header-2") != "Custom-Value-2":
return False
except:
return False
@@ -156,7 +49,7 @@ def test_get_handler(ip, port, verbosity = False):
verbose_print(verbosity, "vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv")
verbose_print(verbosity, "Server response to GET /hello")
verbose_print(verbosity, "Response Headers : ")
for k, v in resp_hdrs.iteritems():
for k, v in resp_hdrs:
verbose_print(verbosity, "\t", k, ": ", v)
verbose_print(verbosity, "Response Data : " + resp_data)
verbose_print(verbosity, "========================================\n")
@@ -169,12 +62,12 @@ def test_post_handler(ip, port, msg, verbosity = False):
verbose_print(verbosity, "======== POST HANDLER TEST ============")
# Establish HTTP connection
verbose_print(verbosity, "Connecting to => " + ip + ":" + port)
sess = Session(ip, port)
sess = httplib.HTTPConnection(ip + ":" + port)
# POST message to /echo and get back response
sess.send_post("/echo", msg)
resp_hdrs = sess.read_resp_hdrs()
resp_data = sess.read_resp_data()
sess.request("POST", url="/echo", body=msg)
resp = sess.getresponse()
resp_data = resp.read()
verbose_print(verbosity, "Server response to POST /echo (" + msg + ")")
verbose_print(verbosity, "vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv")
verbose_print(verbosity, resp_data)
@@ -188,30 +81,28 @@ def test_put_handler(ip, port, verbosity = False):
verbose_print(verbosity, "======== PUT HANDLER TEST =============")
# Establish HTTP connection
verbose_print(verbosity, "Connecting to => " + ip + ":" + port)
sess = Session(ip, port)
sess = httplib.HTTPConnection(ip + ":" + port)
# PUT message to /ctrl to disable /hello URI handler
verbose_print(verbosity, "Disabling /hello handler")
sess.send_put("/ctrl", "0")
sess.read_resp_hdrs()
if sess.content_len:
sess.read_resp_data()
sess.request("PUT", url="/ctrl", body="0")
resp = sess.getresponse()
resp.read()
sess.send_get("/hello")
sess.read_resp_hdrs()
resp_data1 = sess.read_resp_data()
sess.request("GET", url="/hello")
resp = sess.getresponse()
resp_data1 = resp.read()
verbose_print(verbosity, "Response on GET /hello : " + resp_data1)
# PUT message to /ctrl to enable /hello URI handler
verbose_print(verbosity, "Enabling /hello handler")
sess.send_put("/ctrl", "1")
sess.read_resp_hdrs()
if sess.content_len:
sess.read_resp_data()
sess.request("PUT", url="/ctrl", body="1")
resp = sess.getresponse()
resp.read()
sess.send_get("/hello")
sess.read_resp_hdrs()
resp_data2 = sess.read_resp_data()
sess.request("GET", url="/hello")
resp = sess.getresponse()
resp_data2 = resp.read()
verbose_print(verbosity, "Response on GET /hello : " + resp_data2)
# Close HTTP connection
@@ -222,14 +113,14 @@ def test_custom_uri_query(ip, port, query, verbosity = False):
verbose_print(verbosity, "======== GET HANDLER TEST =============")
# Establish HTTP connection
verbose_print(verbosity, "Connecting to => " + ip + ":" + port)
sess = Session(ip, port)
sess = httplib.HTTPConnection(ip + ":" + port)
uri = "/hello?" + query
# GET hello response
verbose_print(verbosity, "Sending GET to URI : ", uri)
sess.send_get(uri, {})
resp_hdrs = sess.read_resp_hdrs()
resp_data = sess.read_resp_data()
sess.request("GET", url=uri, headers={})
resp = sess.getresponse()
resp_data = resp.read()
verbose_print(verbosity, "vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv")
verbose_print(verbosity, "Server response to GET /hello")
@@ -253,6 +144,9 @@ if __name__ == '__main__':
port = args['port']
msg = args['msg']
test_get_handler (ip, port, True)
test_post_handler(ip, port, msg, True)
test_put_handler (ip, port, True)
if not test_get_handler (ip, port, True):
print "Failed!"
if not test_post_handler(ip, port, msg, True):
print "Failed!"
if not test_put_handler (ip, port, True):
print "Failed!"