All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jerry Van Baren <gvb.uboot@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot-Users] [RFC PATCH] Add u-boot command regression tests.
Date: Fri, 23 Nov 2007 20:03:38 -0500	[thread overview]
Message-ID: <20071124010338.GA27628@cideas.com> (raw)

This uses PyUnit and python-serial <http://pyserial.sourceforge.net/>
to do unit testing on u-boot commands.

Signed-off-by: Gerald Van Baren <vanbaren@cideas.com>
---

...and now, for something completely different.

The concept here is to use PyUnit testing in conjunction with python
serial I/O (theoretically, ethernet-based command I/O could be handled
too).

This is a concept probably sufficiently implemented for the "help"
command and a good start for the "fdt" command.  

What does The List think?
* Useful to have regression tests for the u-boot commands?
* Implementation-wise, am I heading in the right direction?

Best regards,
gvb

 u-unit/.gitignore |    2 +
 u-unit/fdt.dts    |   30 +++++++++
 u-unit/fdt.py     |  171 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 u-unit/help.py    |   70 ++++++++++++++++++++++
 u-unit/ubootio.py |   55 +++++++++++++++++
 5 files changed, 328 insertions(+), 0 deletions(-)
 create mode 100644 u-unit/.gitignore
 create mode 100644 u-unit/fdt.dts
 create mode 100755 u-unit/fdt.py
 create mode 100755 u-unit/help.py
 create mode 100755 u-unit/ubootio.py

diff --git a/u-unit/.gitignore b/u-unit/.gitignore
new file mode 100644
index 0000000..88e6bec
--- /dev/null
+++ b/u-unit/.gitignore
@@ -0,0 +1,2 @@
+*.pyc
+*.dtb
diff --git a/u-unit/fdt.dts b/u-unit/fdt.dts
new file mode 100644
index 0000000..66efcdd
--- /dev/null
+++ b/u-unit/fdt.dts
@@ -0,0 +1,30 @@
+/dts-v1/;
+
+/ {
+	compatible = "fdt";
+	prop-int = <0xdeadbeef>;
+	prop-str = "hello world";
+
+	subnode at 1 {
+		compatible = "subnode1";
+		prop-int = <0x01234567>;
+
+		subsubnode {
+			compatible = "subsubnode1", "subsubnode";
+			prop-int = <0x12345678>;
+			prop-empty;
+		};
+	};
+
+	subnode at 2 {
+		linux,phandle = <0x2000>;
+		prop-int = <0x23456789>;
+
+		subsubnode at 0 {
+			linux,phandle = <0x2001>;
+			compatible = "subsubnode2", "subsubnode";
+			prop-empty;
+			prop-int = <0x3456789a>;
+		};
+	};
+};
diff --git a/u-unit/fdt.py b/u-unit/fdt.py
new file mode 100755
index 0000000..53c1117
--- /dev/null
+++ b/u-unit/fdt.py
@@ -0,0 +1,171 @@
+#!/usr/bin/python
+#
+# Test suite for the fdt u-boot command
+#
+
+import unittest
+import re
+import ubootio
+
+class FdtTestCase(unittest.TestCase):
+	"""
+	Run regression tests the "fdt" command and subcommands
+
+	This requires a test fdt blob to be loaded.
+
+	Subcommands to be tested...
+help fdt                                                      
+fdt addr   <addr> [<length>]        - Set the fdt location to <addr>
+fdt boardsetup                      - Do board-specific set up
+fdt move   <fdt> <newaddr> <length> - Copy the fdt to <addr>
+fdt print  <path> [<prop>]          - Recursive print starting at <path>
+fdt list   <path> [<prop>]          - Print one level starting at <path>
+fdt set    <path> <prop> [<val>]    - Set <property> [to <val>]
+fdt mknode <path> <node>            - Create a new node after <path>
+fdt rm     <path> [<prop>]          - Delete the node or <property>
+fdt chosen - Add/update the /chosen branch in the tree
+fdt env    - Add/replace the /u-boot-env branch in the tree
+fdt bd_t   - Add/replace the /bd_t branch in the tree
+	"""
+
+	#
+	# Configuration
+	#
+	scratchram	= "0x400000"
+	serverip	= "192.168.47.8"
+	ipaddr		= "192.168.47.214"
+
+
+	def setUp(self):
+		"""fdt test case setup."""
+
+		# Configuration
+		self.fdt_setup = "\
+set serverip " + self.serverip + " ; \
+set ipaddr " + self.ipaddr + " ; \
+tftp " + self.scratchram + " fdt.dtb ; \
+fdt address " + self.scratchram + "\n"
+
+		self.fdt_dts = """\
+/ {
+	compatible = "fdt";
+	prop-int = <0xdeadbeef>;
+	prop-str = "hello world";
+	subnode at 1 {
+		compatible = "subnode1";
+		prop-int = <0x01234567>;
+		subsubnode {
+			compatible = "subsubnode1", "subsubnode";
+			prop-int = <0x12345678>;
+			prop-empty;
+		};
+	};
+	subnode at 2 {
+		linux,phandle = <0x00002000>;
+		prop-int = <0x23456789>;
+		subsubnode at 0 {
+			linux,phandle = <0x00002001>;
+			compatible = "subsubnode2", "subsubnode";
+			prop-empty;
+			prop-int = <0x3456789a>;
+		};
+	};
+};"""
+		self.fdt_subnode2_dts = """\
+subnode at 2 {
+	linux,phandle = <0x00002000>;
+	prop-int = <0x23456789>;
+	subsubnode at 0 {
+		linux,phandle = <0x00002001>;
+		compatible = "subsubnode2", "subsubnode";
+		prop-empty;
+		prop-int = <0x3456789a>;
+	};
+};"""
+		self.fdt_list_dts = """\
+/ {
+	compatible = "fdt";
+	prop-int = <0xdeadbeef>;
+	prop-str = "hello world";
+	subnode at 1 {
+	};
+	subnode at 2 {
+	};
+};"""
+
+		self.re_dts = re.compile(self.fdt_dts)
+		self.re_subnode2_dts = re.compile(self.fdt_subnode2_dts)
+		self.re_list_dts = re.compile(self.fdt_list_dts)
+
+		self.IO = ubootio.uBootIO()
+
+		self.IO.sendcmd(self.fdt_setup);
+		n = self.IO.waitresponse()
+		if (n <= 0):
+			print "FAIL: Timeout"
+			raise AssertionError
+		s = self.IO.getresponse(n)
+
+		# Verify that the dtb was loaded.
+		if (not re.search("Bytes transferred =", s)):
+			print "FAIL: could not load the test dtb.\n", s
+			raise AssertionError
+
+	def tearDown(self):
+		pass
+
+	def testPrintRoot(self):
+		"""
+		Print starting@the root node.
+		"""
+		self.IO.sendcmd("fdt print /\n");
+		n = self.IO.waitresponse()
+		assert n > 0, "Timeout"
+
+		s = self.IO.getresponse(n)
+		assert self.re_dts.search(s), \
+			"fdt print did not match.\nIS:\n" + s + \
+			"SHOULD BE:\n" + fdt_dts
+
+	def testPrintUnspecified(self):
+		"""
+		Print with no node specified, defaults to the root node.
+		"""
+		self.IO.sendcmd("fdt print\n");
+		n = self.IO.waitresponse()
+		assert n > 0, "Timeout"
+
+		s = self.IO.getresponse(n)
+		assert self.re_dts.search(s), \
+			"fdt print did not match.\nIS:\n" + s + \
+			"SHOULD BE:\n" + fdt_dts
+
+	def testPrintSubnode(self):
+		"""
+		Print a subnode.
+		"""
+		self.IO.sendcmd("fdt p /subnode at 2\n");
+		n = self.IO.waitresponse()
+		assert n > 0, "Timeout"
+
+		s = self.IO.getresponse(n)
+		assert self.re_subnode2_dts.search(s), \
+			"fdt print did not match.\nIS:\n" + s + \
+			"SHOULD BE:\n" + fdt_subnode2_dts
+
+	def testListRoot(self):
+		"""
+		List starting at the root node.
+		"""
+		self.IO.sendcmd("fdt list\n");
+		n = self.IO.waitresponse()
+		assert n > 0, "Timeout"
+
+		s = self.IO.getresponse(n)
+		assert self.re_list_dts.search(s), \
+			"fdt list did not match.\nIS:\n" + s + \
+			"SHOULD BE:\n" + fdt_list_dts
+
+
+if __name__ == "__main__":
+	unittest.main()
diff --git a/u-unit/help.py b/u-unit/help.py
new file mode 100755
index 0000000..dbd0e0e
--- /dev/null
+++ b/u-unit/help.py
@@ -0,0 +1,70 @@
+#!/usr/bin/python
+#
+# Test suite for the fdt u-boot command
+#
+
+import unittest
+import re
+import ubootio
+
+class HelpTestCase(unittest.TestCase):
+        """ Run regression tests the "help" command """
+
+
+	def setUp(self):
+		"""help test case setup."""
+
+		self.IO = ubootio.uBootIO()
+
+
+	def testHelp(self):
+		"""
+		Run regression tests the "help" command
+
+		This runs the "help" command and verifies that it returns
+		information on a subset of the commands.
+		"""
+
+		# These commands should be on all configurations
+		tests = [ \
+			"askenv", \
+			"base", \
+			"boot", \
+			"cp", \
+			"crc32", \
+			"echo", \
+			"erase", \
+			"exit", \
+			"go", \
+			"help", \
+			"icrc32", \
+			"md", \
+			"mm", \
+			"mw", \
+			"nm", \
+			"printenv", \
+			"protect", \
+			"reset", \
+			"run", \
+			"saveenv", \
+			"setenv", \
+			"sleep", \
+			"test", \
+			"version", \
+			"=>" ]
+
+		self.IO.sendcmd("help\n")
+		n = self.IO.waitresponse()
+		if (n <= 0):
+			print "FAIL: Timeout"
+			testpassed = False
+		else:
+			s = self.IO.getresponse(n)
+			for test in tests:
+				if (not re.search(test, s)):
+					print "FAIL: ", test, " not found in\n", s
+					testpassed = False
+
+if __name__ == "__main__":
+        unittest.main()
+
diff --git a/u-unit/ubootio.py b/u-unit/ubootio.py
new file mode 100755
index 0000000..3dad300
--- /dev/null
+++ b/u-unit/ubootio.py
@@ -0,0 +1,55 @@
+#!/usr/bin/python
+#
+# I/O for the u-boot command regression tests
+#
+
+import serial
+import time
+import re
+
+
+class uBootIO:
+	#
+	# Configuration
+	#
+	chantimeout	= 0.5
+
+	def __init__(self):
+		self.chan = serial.Serial(0, 115200, timeout=5.0, rtscts=0, \
+			parity=serial.PARITY_NONE)
+
+
+	def waitresponse(self):
+		"""
+		Waits for a response from the target.
+
+		Returns the number of characters waiting to be received.
+		"""
+
+		n = -1
+		time.sleep(self.chantimeout)
+		while (self.chan.inWaiting() > n):
+			time.sleep(self.chantimeout)
+			n = self.chan.inWaiting()
+		if (n <= 0):
+			print "FAIL: Timeout"
+		return n
+
+	def getresponse(self, n):
+		"""
+		Returns the response from the target.
+
+		Post-processes the response for line ends (changes to newlines).
+		"""
+
+		canonical = re.compile("[\r\n]+")
+
+		s = self.chan.read(n)
+		return canonical.sub("\n", s)
+
+	def sendcmd(self, s):
+		"""
+		Send a command string to the target.
+		"""
+
+		self.chan.write(s)
-- 
1.5.3.4

             reply	other threads:[~2007-11-24  1:03 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-11-24  1:03 Jerry Van Baren [this message]
2007-11-25 23:29 ` [U-Boot-Users] [RFC PATCH] Add u-boot command regression tests Wolfgang Denk
2007-11-26 13:49   ` Jerry Van Baren
2007-11-26 14:09     ` Wolfgang Denk
2007-11-27 22:46       ` Robert Schwebel
2007-11-28  2:32         ` gvb.uboot
2007-11-28 17:13           ` Robert Schwebel
2007-11-27 23:30     ` Kumar Gala
2007-11-28  0:58       ` gvb.uboot
2007-11-28 18:11     ` Mike Frysinger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20071124010338.GA27628@cideas.com \
    --to=gvb.uboot@gmail.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.