123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- # -*- coding: utf-8 -*-
- # SPDX-License-Identifier: GPL-2.0+
- #
- # Copyright 2017 Google, Inc
- #
- 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,
- None)
- 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])
|