mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2025-12-19 16:31:27 +01:00
Set the git variables to ensure that any local gitconfig is not used or affected by the tests. Signed-off-by: Simon Glass <sjg@chromium.org>
255 lines
8.5 KiB
Python
255 lines
8.5 KiB
Python
# SPDX-License-Identifier: GPL-2.0+
|
|
#
|
|
# Copyright 2025 Simon Glass <sjg@chromium.org>
|
|
#
|
|
"""Functional tests for checking that patman behaves correctly"""
|
|
|
|
import os
|
|
import shutil
|
|
import tempfile
|
|
|
|
import pygit2
|
|
|
|
from u_boot_pylib import gitutil
|
|
from u_boot_pylib import terminal
|
|
from u_boot_pylib import tools
|
|
from u_boot_pylib import tout
|
|
|
|
|
|
class TestCommon:
|
|
"""Contains common test functions"""
|
|
leb = (b'Lord Edmund Blackadd\xc3\xabr <weasel@blackadder.org>'.
|
|
decode('utf-8'))
|
|
|
|
# Fake patchwork project ID for U-Boot
|
|
PROJ_ID = 6
|
|
PROJ_LINK_NAME = 'uboot'
|
|
SERIES_ID_FIRST_V3 = 31
|
|
SERIES_ID_SECOND_V1 = 456
|
|
SERIES_ID_SECOND_V2 = 457
|
|
TITLE_SECOND = 'Series for my board'
|
|
|
|
verbosity = False
|
|
preserve_outdirs = False
|
|
|
|
@classmethod
|
|
def setup_test_args(cls, preserve_indir=False, preserve_outdirs=False,
|
|
toolpath=None, verbosity=None, no_capture=False):
|
|
"""Accept arguments controlling test execution
|
|
|
|
Args:
|
|
preserve_indir (bool): not used by patman
|
|
preserve_outdirs (bool): Preserve the output directories used by
|
|
tests. Each test has its own, so this is normally only useful
|
|
when running a single test.
|
|
toolpath (str): not used by patman
|
|
verbosity (int): verbosity to use (0 means tout.INIT, 1 means means
|
|
tout.DEBUG)
|
|
no_capture (bool): True to output all captured text after capturing
|
|
completes
|
|
"""
|
|
del preserve_indir
|
|
cls.preserve_outdirs = preserve_outdirs
|
|
cls.toolpath = toolpath
|
|
cls.verbosity = verbosity
|
|
cls.no_capture = no_capture
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.repo = None
|
|
self.tmpdir = None
|
|
self.gitdir = None
|
|
|
|
def setUp(self):
|
|
"""Set up the test temporary dir and git dir"""
|
|
self.tmpdir = tempfile.mkdtemp(prefix='patman.')
|
|
self.gitdir = os.path.join(self.tmpdir, '.git')
|
|
tout.init(tout.DEBUG if self.verbosity else tout.INFO,
|
|
allow_colour=False)
|
|
|
|
def tearDown(self):
|
|
"""Delete the temporary dir"""
|
|
if self.preserve_outdirs:
|
|
print(f'Output dir: {self.tmpdir}')
|
|
else:
|
|
shutil.rmtree(self.tmpdir)
|
|
terminal.set_print_test_mode(False)
|
|
|
|
def make_commit_with_file(self, subject, body, fname, text):
|
|
"""Create a file and add it to the git repo with a new commit
|
|
|
|
Args:
|
|
subject (str): Subject for the commit
|
|
body (str): Body text of the commit
|
|
fname (str): Filename of file to create
|
|
text (str): Text to put into the file
|
|
"""
|
|
path = os.path.join(self.tmpdir, fname)
|
|
tools.write_file(path, text, binary=False)
|
|
index = self.repo.index
|
|
index.add(fname)
|
|
# pylint doesn't seem to find this
|
|
# pylint: disable=E1101
|
|
author = pygit2.Signature('Test user', 'test@email.com')
|
|
committer = author
|
|
tree = index.write_tree()
|
|
message = subject + '\n' + body
|
|
self.repo.create_commit('HEAD', author, committer, message, tree,
|
|
[self.repo.head.target])
|
|
|
|
def make_git_tree(self):
|
|
"""Make a simple git tree suitable for testing
|
|
|
|
It has four branches:
|
|
'base' has two commits: PCI, main
|
|
'first' has base as upstream and two more commits: I2C, SPI
|
|
'second' has base as upstream and three more: video, serial, bootm
|
|
'third4' has second as upstream and four more: usb, main, test, lib
|
|
|
|
Returns:
|
|
pygit2.Repository: repository
|
|
"""
|
|
os.environ['GIT_CONFIG_GLOBAL'] = '/dev/null'
|
|
os.environ['GIT_CONFIG_SYSTEM'] = '/dev/null'
|
|
|
|
repo = pygit2.init_repository(self.gitdir)
|
|
self.repo = repo
|
|
new_tree = repo.TreeBuilder().write()
|
|
|
|
common = ['git', f'--git-dir={self.gitdir}', 'config']
|
|
tools.run(*(common + ['user.name', 'Dummy']), cwd=self.gitdir)
|
|
tools.run(*(common + ['user.email', 'dumdum@dummy.com']),
|
|
cwd=self.gitdir)
|
|
|
|
# pylint doesn't seem to find this
|
|
# pylint: disable=E1101
|
|
author = pygit2.Signature('Test user', 'test@email.com')
|
|
committer = author
|
|
_ = repo.create_commit('HEAD', author, committer, 'Created master',
|
|
new_tree, [])
|
|
|
|
self.make_commit_with_file('Initial commit', '''
|
|
Add a README
|
|
|
|
''', 'README', '''This is the README file
|
|
describing this project
|
|
in very little detail''')
|
|
|
|
self.make_commit_with_file('pci: PCI implementation', '''
|
|
Here is a basic PCI implementation
|
|
|
|
''', 'pci.c', '''This is a file
|
|
it has some contents
|
|
and some more things''')
|
|
self.make_commit_with_file('main: Main program', '''
|
|
Hello here is the second commit.
|
|
''', 'main.c', '''This is the main file
|
|
there is very little here
|
|
but we can always add more later
|
|
if we want to
|
|
|
|
Series-to: u-boot
|
|
Series-cc: Barry Crump <bcrump@whataroa.nz>
|
|
''')
|
|
base_target = repo.revparse_single('HEAD')
|
|
self.make_commit_with_file('i2c: I2C things', '''
|
|
This has some stuff to do with I2C
|
|
''', 'i2c.c', '''And this is the file contents
|
|
with some I2C-related things in it''')
|
|
self.make_commit_with_file('spi: SPI fixes', f'''
|
|
SPI needs some fixes
|
|
and here they are
|
|
|
|
Signed-off-by: {self.leb}
|
|
|
|
Series-to: u-boot
|
|
Commit-notes:
|
|
title of the series
|
|
This is the cover letter for the series
|
|
with various details
|
|
END
|
|
''', 'spi.c', '''Some fixes for SPI in this
|
|
file to make SPI work
|
|
better than before''')
|
|
first_target = repo.revparse_single('HEAD')
|
|
|
|
target = repo.revparse_single('HEAD~2')
|
|
# pylint doesn't seem to find this
|
|
# pylint: disable=E1101
|
|
repo.reset(target.oid, pygit2.enums.ResetMode.HARD)
|
|
self.make_commit_with_file('video: Some video improvements', '''
|
|
Fix up the video so that
|
|
it looks more purple. Purple is
|
|
a very nice colour.
|
|
''', 'video.c', '''More purple here
|
|
Purple and purple
|
|
Even more purple
|
|
Could not be any more purple''')
|
|
self.make_commit_with_file('serial: Add a serial driver', f'''
|
|
Here is the serial driver
|
|
for my chip.
|
|
|
|
Cover-letter:
|
|
{self.TITLE_SECOND}
|
|
This series implements support
|
|
for my glorious board.
|
|
END
|
|
Series-to: u-boot
|
|
Series-links: {self.SERIES_ID_SECOND_V1}
|
|
''', 'serial.c', '''The code for the
|
|
serial driver is here''')
|
|
self.make_commit_with_file('bootm: Make it boot', '''
|
|
This makes my board boot
|
|
with a fix to the bootm
|
|
command
|
|
''', 'bootm.c', '''Fix up the bootm
|
|
command to make the code as
|
|
complicated as possible''')
|
|
second_target = repo.revparse_single('HEAD')
|
|
|
|
self.make_commit_with_file('usb: Try out the new DMA feature', '''
|
|
This is just a fix that
|
|
ensures that DMA is enabled
|
|
''', 'usb-uclass.c', '''Here is the USB
|
|
implementation and as you can see it
|
|
it very nice''')
|
|
self.make_commit_with_file('main: Change to the main program', '''
|
|
Here we adjust the main
|
|
program just a little bit
|
|
''', 'main.c', '''This is the text of the main program''')
|
|
self.make_commit_with_file('test: Check that everything works', '''
|
|
This checks that all the
|
|
various things we've been
|
|
adding actually work.
|
|
''', 'test.c', '''Here is the test code and it seems OK''')
|
|
self.make_commit_with_file('lib: Sort out the extra library', '''
|
|
The extra library is currently
|
|
broken. Fix it so that we can
|
|
use it in various place.
|
|
''', 'lib.c', '''Some library code is here
|
|
and a little more''')
|
|
third_target = repo.revparse_single('HEAD')
|
|
|
|
repo.branches.local.create('first', first_target)
|
|
repo.config.set_multivar('branch.first.remote', '', '.')
|
|
repo.config.set_multivar('branch.first.merge', '', 'refs/heads/base')
|
|
|
|
repo.branches.local.create('second', second_target)
|
|
repo.config.set_multivar('branch.second.remote', '', '.')
|
|
repo.config.set_multivar('branch.second.merge', '', 'refs/heads/base')
|
|
|
|
repo.branches.local.create('base', base_target)
|
|
|
|
repo.branches.local.create('third4', third_target)
|
|
repo.config.set_multivar('branch.third4.remote', '', '.')
|
|
repo.config.set_multivar('branch.third4.merge', '',
|
|
'refs/heads/second')
|
|
|
|
target = repo.lookup_reference('refs/heads/first')
|
|
repo.checkout(target, strategy=pygit2.GIT_CHECKOUT_FORCE)
|
|
target = repo.revparse_single('HEAD')
|
|
repo.reset(target.oid, pygit2.enums.ResetMode.HARD)
|
|
|
|
self.assertFalse(gitutil.check_dirty(self.gitdir, self.tmpdir))
|
|
return repo
|