patman: Add a functional test
The existing test (patman --test) only covers basic checkpatch output. We have had some problems with unicode processing and could use test coverage for the various tags patman supports. Add a new functional test which runs most of the patman flow on a few test commits and checks that the results are correct. See the documentation in the test for a description of what it does. Signed-off-by: Simon Glass <sjg@chromium.org> Tested-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
This commit is contained in:
parent
a44f4fb72b
commit
6e87ae1c07
242
tools/patman/func_test.py
Normal file
242
tools/patman/func_test.py
Normal file
@ -0,0 +1,242 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2017 Google, Inc
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
import contextlib
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
import gitutil
|
||||
import patchstream
|
||||
import settings
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def capture():
|
||||
import sys
|
||||
from cStringIO import StringIO
|
||||
oldout,olderr = sys.stdout, sys.stderr
|
||||
try:
|
||||
out=[StringIO(), StringIO()]
|
||||
sys.stdout,sys.stderr = out
|
||||
yield out
|
||||
finally:
|
||||
sys.stdout,sys.stderr = oldout, olderr
|
||||
out[0] = out[0].getvalue()
|
||||
out[1] = out[1].getvalue()
|
||||
|
||||
|
||||
class TestFunctional(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.tmpdir = tempfile.mkdtemp(prefix='patman.')
|
||||
|
||||
def tearDown(self):
|
||||
shutil.rmtree(self.tmpdir)
|
||||
|
||||
@staticmethod
|
||||
def GetPath(fname):
|
||||
return os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])),
|
||||
'test', fname)
|
||||
|
||||
@classmethod
|
||||
def GetText(self, fname):
|
||||
return open(self.GetPath(fname)).read()
|
||||
|
||||
@classmethod
|
||||
def GetPatchName(self, subject):
|
||||
fname = re.sub('[ :]', '-', subject)
|
||||
return fname.replace('--', '-')
|
||||
|
||||
def CreatePatchesForTest(self, series):
|
||||
cover_fname = None
|
||||
fname_list = []
|
||||
for i, commit in enumerate(series.commits):
|
||||
clean_subject = self.GetPatchName(commit.subject)
|
||||
src_fname = '%04d-%s.patch' % (i + 1, clean_subject[:52])
|
||||
fname = os.path.join(self.tmpdir, src_fname)
|
||||
shutil.copy(self.GetPath(src_fname), fname)
|
||||
fname_list.append(fname)
|
||||
if series.get('cover'):
|
||||
src_fname = '0000-cover-letter.patch'
|
||||
cover_fname = os.path.join(self.tmpdir, src_fname)
|
||||
fname = os.path.join(self.tmpdir, src_fname)
|
||||
shutil.copy(self.GetPath(src_fname), fname)
|
||||
|
||||
return cover_fname, fname_list
|
||||
|
||||
def testBasic(self):
|
||||
"""Tests the basic flow of patman
|
||||
|
||||
This creates a series from some hard-coded patches build from a simple
|
||||
tree with the following metadata in the top commit:
|
||||
|
||||
Series-to: u-boot
|
||||
Series-prefix: RFC
|
||||
Series-cc: Stefan Brüns <stefan.bruens@rwth-aachen.de>
|
||||
Cover-letter-cc: Lord Mëlchett <clergy@palace.gov>
|
||||
Series-version: 2
|
||||
Series-changes: 4
|
||||
- Some changes
|
||||
|
||||
Cover-letter:
|
||||
test: A test patch series
|
||||
This is a test of how the cover
|
||||
leter
|
||||
works
|
||||
END
|
||||
|
||||
and this in the first commit:
|
||||
|
||||
Series-notes:
|
||||
some notes
|
||||
about some things
|
||||
from the first commit
|
||||
END
|
||||
|
||||
Commit-notes:
|
||||
Some notes about
|
||||
the first commit
|
||||
END
|
||||
|
||||
with the following commands:
|
||||
|
||||
git log -n2 --reverse >/path/to/tools/patman/test/test01.txt
|
||||
git format-patch --subject-prefix RFC --cover-letter HEAD~2
|
||||
mv 00* /path/to/tools/patman/test
|
||||
|
||||
It checks these aspects:
|
||||
- git log can be processed by patchstream
|
||||
- emailing patches uses the correct command
|
||||
- CC file has information on each commit
|
||||
- cover letter has the expected text and subject
|
||||
- each patch has the correct subject
|
||||
- dry-run information prints out correctly
|
||||
- unicode is handled correctly
|
||||
- Series-to, Series-cc, Series-prefix, Cover-letter
|
||||
- Cover-letter-cc, Series-version, Series-changes, Series-notes
|
||||
- Commit-notes
|
||||
"""
|
||||
process_tags = True
|
||||
ignore_bad_tags = True
|
||||
stefan = u'Stefan Brüns <stefan.bruens@rwth-aachen.de>'
|
||||
rick = 'Richard III <richard@palace.gov>'
|
||||
mel = u'Lord Mëlchett <clergy@palace.gov>'
|
||||
ed = u'Lond Edmund Blackaddër <weasel@blackadder.org'
|
||||
fred = 'Fred Bloggs <f.bloggs@napier.net>'
|
||||
add_maintainers = [stefan, rick]
|
||||
dry_run = True
|
||||
in_reply_to = mel
|
||||
count = 2
|
||||
settings.alias = {
|
||||
'fdt': ['simon'],
|
||||
'u-boot': ['u-boot@lists.denx.de'],
|
||||
'simon': [ed],
|
||||
'fred': [fred],
|
||||
}
|
||||
|
||||
text = self.GetText('test01.txt')
|
||||
series = patchstream.GetMetaDataForTest(text)
|
||||
cover_fname, args = self.CreatePatchesForTest(series)
|
||||
with capture() as out:
|
||||
patchstream.FixPatches(series, args)
|
||||
if cover_fname and series.get('cover'):
|
||||
patchstream.InsertCoverLetter(cover_fname, series, count)
|
||||
series.DoChecks()
|
||||
cc_file = series.MakeCcFile(process_tags, cover_fname,
|
||||
not ignore_bad_tags, add_maintainers)
|
||||
cmd = gitutil.EmailPatches(series, cover_fname, args,
|
||||
dry_run, not ignore_bad_tags, cc_file,
|
||||
in_reply_to=in_reply_to, thread=None)
|
||||
series.ShowActions(args, cmd, process_tags)
|
||||
cc_lines = open(cc_file).read().splitlines()
|
||||
os.remove(cc_file)
|
||||
|
||||
lines = out[0].splitlines()
|
||||
#print '\n'.join(lines)
|
||||
self.assertEqual('Cleaned %s patches' % len(series.commits), lines[0])
|
||||
self.assertEqual('Change log missing for v2', lines[1])
|
||||
self.assertEqual('Change log missing for v3', lines[2])
|
||||
self.assertEqual('Change log for unknown version v4', lines[3])
|
||||
self.assertEqual("Alias 'pci' not found", lines[4])
|
||||
self.assertIn('Dry run', lines[5])
|
||||
self.assertIn('Send a total of %d patches' % count, lines[7])
|
||||
line = 8
|
||||
for i, commit in enumerate(series.commits):
|
||||
self.assertEqual(' %s' % args[i], lines[line + 0])
|
||||
line += 1
|
||||
while 'Cc:' in lines[line]:
|
||||
line += 1
|
||||
self.assertEqual('To: u-boot@lists.denx.de', lines[line])
|
||||
self.assertEqual('Cc: %s' % stefan.encode('utf-8'), lines[line + 1])
|
||||
self.assertEqual('Version: 3', lines[line + 2])
|
||||
self.assertEqual('Prefix:\t RFC', lines[line + 3])
|
||||
self.assertEqual('Cover: 4 lines', lines[line + 4])
|
||||
line += 5
|
||||
self.assertEqual(' Cc: %s' % mel.encode('utf-8'), lines[line + 0])
|
||||
self.assertEqual(' Cc: %s' % rick, lines[line + 1])
|
||||
self.assertEqual(' Cc: %s' % fred, lines[line + 2])
|
||||
self.assertEqual(' Cc: %s' % ed.encode('utf-8'), lines[line + 3])
|
||||
expected = ('Git command: git send-email --annotate '
|
||||
'--in-reply-to="%s" --to "u-boot@lists.denx.de" '
|
||||
'--cc "%s" --cc-cmd "%s --cc-cmd %s" %s %s'
|
||||
% (in_reply_to, stefan, sys.argv[0], cc_file, cover_fname,
|
||||
' '.join(args))).encode('utf-8')
|
||||
line += 4
|
||||
self.assertEqual(expected, lines[line])
|
||||
|
||||
self.assertEqual(('%s %s, %s' % (args[0], rick, stefan))
|
||||
.encode('utf-8'), cc_lines[0])
|
||||
self.assertEqual(('%s %s, %s, %s, %s' % (args[1], fred, rick, stefan,
|
||||
ed)).encode('utf-8'), cc_lines[1])
|
||||
|
||||
expected = '''
|
||||
This is a test of how the cover
|
||||
leter
|
||||
works
|
||||
|
||||
some notes
|
||||
about some things
|
||||
from the first commit
|
||||
|
||||
Changes in v4:
|
||||
- Some changes
|
||||
|
||||
Simon Glass (2):
|
||||
pci: Correct cast for sandbox
|
||||
fdt: Correct cast for sandbox in fdtdec_setup_memory_size()
|
||||
|
||||
cmd/pci.c | 3 ++-
|
||||
fs/fat/fat.c | 1 +
|
||||
lib/efi_loader/efi_memory.c | 1 +
|
||||
lib/fdtdec.c | 3 ++-
|
||||
4 files changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
--\x20
|
||||
2.7.4
|
||||
|
||||
'''
|
||||
lines = open(cover_fname).read().splitlines()
|
||||
#print '\n'.join(lines)
|
||||
self.assertEqual(
|
||||
'Subject: [RFC PATCH v3 0/2] test: A test patch series',
|
||||
lines[3])
|
||||
self.assertEqual(expected.splitlines(), lines[7:])
|
||||
|
||||
for i, fname in enumerate(args):
|
||||
lines = open(fname).read().splitlines()
|
||||
#print '\n'.join(lines)
|
||||
subject = [line for line in lines if line.startswith('Subject')]
|
||||
self.assertEqual('Subject: [RFC %d/%d]' % (i + 1, count),
|
||||
subject[0][:18])
|
||||
if i == 0:
|
||||
# Check that we got our commit notes
|
||||
self.assertEqual('---', lines[17])
|
||||
self.assertEqual('Some notes about', lines[18])
|
||||
self.assertEqual('the first commit', lines[19])
|
@ -424,6 +424,19 @@ def GetMetaData(start, count):
|
||||
"""
|
||||
return GetMetaDataForList('HEAD~%d' % start, None, count)
|
||||
|
||||
def GetMetaDataForTest(text):
|
||||
"""Process metadata from a file containing a git log. Used for tests
|
||||
|
||||
Args:
|
||||
text:
|
||||
"""
|
||||
series = Series()
|
||||
ps = PatchStream(series, is_log=True)
|
||||
for line in text.splitlines():
|
||||
ps.ProcessLine(line)
|
||||
ps.Finalize()
|
||||
return series
|
||||
|
||||
def FixPatch(backup_dir, fname, series, commit):
|
||||
"""Fix up a patch file, by adding/removing as required.
|
||||
|
||||
|
@ -82,11 +82,13 @@ if __name__ != "__main__":
|
||||
# Run our meagre tests
|
||||
elif options.test:
|
||||
import doctest
|
||||
import func_test
|
||||
|
||||
sys.argv = [sys.argv[0]]
|
||||
suite = unittest.TestLoader().loadTestsFromTestCase(test.TestPatch)
|
||||
result = unittest.TestResult()
|
||||
suite.run(result)
|
||||
for module in (test.TestPatch, func_test.TestFunctional):
|
||||
suite = unittest.TestLoader().loadTestsFromTestCase(module)
|
||||
suite.run(result)
|
||||
|
||||
for module in ['gitutil', 'settings']:
|
||||
suite = doctest.DocTestSuite(module)
|
||||
|
23
tools/patman/test/0000-cover-letter.patch
Normal file
23
tools/patman/test/0000-cover-letter.patch
Normal file
@ -0,0 +1,23 @@
|
||||
From 5ab48490f03051875ab13d288a4bf32b507d76fd Mon Sep 17 00:00:00 2001
|
||||
From: Simon Glass <sjg@chromium.org>
|
||||
Date: Sat, 27 May 2017 20:52:11 -0600
|
||||
Subject: [RFC 0/2] *** SUBJECT HERE ***
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
*** BLURB HERE ***
|
||||
|
||||
Simon Glass (2):
|
||||
pci: Correct cast for sandbox
|
||||
fdt: Correct cast for sandbox in fdtdec_setup_memory_size()
|
||||
|
||||
cmd/pci.c | 3 ++-
|
||||
fs/fat/fat.c | 1 +
|
||||
lib/efi_loader/efi_memory.c | 1 +
|
||||
lib/fdtdec.c | 3 ++-
|
||||
4 files changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
--
|
||||
2.7.4
|
||||
|
48
tools/patman/test/0001-pci-Correct-cast-for-sandbox.patch
Normal file
48
tools/patman/test/0001-pci-Correct-cast-for-sandbox.patch
Normal file
@ -0,0 +1,48 @@
|
||||
From b9da5f937bd5ea4931ea17459bf79b2905d9594d Mon Sep 17 00:00:00 2001
|
||||
From: Simon Glass <sjg@chromium.org>
|
||||
Date: Sat, 15 Apr 2017 15:39:08 -0600
|
||||
Subject: [RFC 1/2] pci: Correct cast for sandbox
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This gives a warning with some native compilers:
|
||||
|
||||
cmd/pci.c:152:11: warning: format ‘%llx’ expects argument of type
|
||||
‘long long unsigned int’, but argument 3 has type
|
||||
‘u64 {aka long unsigned int}’ [-Wformat=]
|
||||
|
||||
Fix it with a cast.
|
||||
|
||||
Signed-off-by: Simon Glass <sjg@chromium.org>
|
||||
Series-notes:
|
||||
some notes
|
||||
about some things
|
||||
from the first commit
|
||||
END
|
||||
|
||||
Commit-notes:
|
||||
Some notes about
|
||||
the first commit
|
||||
END
|
||||
---
|
||||
cmd/pci.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/cmd/pci.c b/cmd/pci.c
|
||||
index 41b4fff..fe27b4f 100644
|
||||
--- a/cmd/pci.c
|
||||
+++ b/cmd/pci.c
|
||||
@@ -150,7 +150,8 @@ int pci_bar_show(struct udevice *dev)
|
||||
if ((!is_64 && size_low) || (is_64 && size)) {
|
||||
size = ~size + 1;
|
||||
printf(" %d %#016llx %#016llx %d %s %s\n",
|
||||
- bar_id, base, size, is_64 ? 64 : 32,
|
||||
+ bar_id, (unsigned long long)base,
|
||||
+ (unsigned long long)size, is_64 ? 64 : 32,
|
||||
is_io ? "I/O" : "MEM",
|
||||
prefetchable ? "Prefetchable" : "");
|
||||
}
|
||||
--
|
||||
2.7.4
|
||||
|
@ -0,0 +1,73 @@
|
||||
From 5ab48490f03051875ab13d288a4bf32b507d76fd Mon Sep 17 00:00:00 2001
|
||||
From: Simon Glass <sjg@chromium.org>
|
||||
Date: Sat, 15 Apr 2017 15:39:08 -0600
|
||||
Subject: [RFC 2/2] fdt: Correct cast for sandbox in fdtdec_setup_memory_size()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This gives a warning with some native compilers:
|
||||
|
||||
lib/fdtdec.c:1203:8: warning: format ‘%llx’ expects argument of type
|
||||
‘long long unsigned int’, but argument 3 has type
|
||||
‘long unsigned int’ [-Wformat=]
|
||||
|
||||
Fix it with a cast.
|
||||
|
||||
Signed-off-by: Simon Glass <sjg@chromium.org>
|
||||
Series-to: u-boot
|
||||
Series-prefix: RFC
|
||||
Series-cc: Stefan Brüns <stefan.bruens@rwth-aachen.de>
|
||||
Cover-letter-cc: Lord Mëlchett <clergy@palace.gov>
|
||||
Series-version: 3
|
||||
Patch-cc: fred
|
||||
Series-changes: 4
|
||||
- Some changes
|
||||
|
||||
Cover-letter:
|
||||
test: A test patch series
|
||||
This is a test of how the cover
|
||||
leter
|
||||
works
|
||||
END
|
||||
---
|
||||
fs/fat/fat.c | 1 +
|
||||
lib/efi_loader/efi_memory.c | 1 +
|
||||
lib/fdtdec.c | 3 ++-
|
||||
3 files changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/fs/fat/fat.c b/fs/fat/fat.c
|
||||
index a71bad1..ba169dc 100644
|
||||
--- a/fs/fat/fat.c
|
||||
+++ b/fs/fat/fat.c
|
||||
@@ -1,3 +1,4 @@
|
||||
+
|
||||
/*
|
||||
* fat.c
|
||||
*
|
||||
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
|
||||
index db2ae19..05f75d1 100644
|
||||
--- a/lib/efi_loader/efi_memory.c
|
||||
+++ b/lib/efi_loader/efi_memory.c
|
||||
@@ -1,3 +1,4 @@
|
||||
+
|
||||
/*
|
||||
* EFI application memory management
|
||||
*
|
||||
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
|
||||
index c072e54..942244f 100644
|
||||
--- a/lib/fdtdec.c
|
||||
+++ b/lib/fdtdec.c
|
||||
@@ -1200,7 +1200,8 @@ int fdtdec_setup_memory_size(void)
|
||||
}
|
||||
|
||||
gd->ram_size = (phys_size_t)(res.end - res.start + 1);
|
||||
- debug("%s: Initial DRAM size %llx\n", __func__, (u64)gd->ram_size);
|
||||
+ debug("%s: Initial DRAM size %llx\n", __func__,
|
||||
+ (unsigned long long)gd->ram_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
2.7.4
|
||||
|
56
tools/patman/test/test01.txt
Normal file
56
tools/patman/test/test01.txt
Normal file
@ -0,0 +1,56 @@
|
||||
commit b9da5f937bd5ea4931ea17459bf79b2905d9594d
|
||||
Author: Simon Glass <sjg@chromium.org>
|
||||
Date: Sat Apr 15 15:39:08 2017 -0600
|
||||
|
||||
pci: Correct cast for sandbox
|
||||
|
||||
This gives a warning with some native compilers:
|
||||
|
||||
cmd/pci.c:152:11: warning: format ‘%llx’ expects argument of type
|
||||
‘long long unsigned int’, but argument 3 has type
|
||||
‘u64 {aka long unsigned int}’ [-Wformat=]
|
||||
|
||||
Fix it with a cast.
|
||||
|
||||
Signed-off-by: Simon Glass <sjg@chromium.org>
|
||||
Series-notes:
|
||||
some notes
|
||||
about some things
|
||||
from the first commit
|
||||
END
|
||||
|
||||
Commit-notes:
|
||||
Some notes about
|
||||
the first commit
|
||||
END
|
||||
|
||||
commit 5ab48490f03051875ab13d288a4bf32b507d76fd
|
||||
Author: Simon Glass <sjg@chromium.org>
|
||||
Date: Sat Apr 15 15:39:08 2017 -0600
|
||||
|
||||
fdt: Correct cast for sandbox in fdtdec_setup_memory_size()
|
||||
|
||||
This gives a warning with some native compilers:
|
||||
|
||||
lib/fdtdec.c:1203:8: warning: format ‘%llx’ expects argument of type
|
||||
‘long long unsigned int’, but argument 3 has type
|
||||
‘long unsigned int’ [-Wformat=]
|
||||
|
||||
Fix it with a cast.
|
||||
|
||||
Signed-off-by: Simon Glass <sjg@chromium.org>
|
||||
Series-to: u-boot
|
||||
Series-prefix: RFC
|
||||
Series-cc: Stefan Brüns <stefan.bruens@rwth-aachen.de>
|
||||
Cover-letter-cc: Lord Mëlchett <clergy@palace.gov>
|
||||
Series-version: 3
|
||||
Patch-cc: fred
|
||||
Series-changes: 4
|
||||
- Some changes
|
||||
|
||||
Cover-letter:
|
||||
test: A test patch series
|
||||
This is a test of how the cover
|
||||
leter
|
||||
works
|
||||
END
|
Loading…
Reference in New Issue
Block a user