diff --git a/.travis.yml b/.travis.yml index e8d8e4af..5de3ac99 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,7 @@ language: python python: - "2.7" +before_install: + - sudo apt-get update -qq + - sudo apt-get install -qq diffstat script: cd tests; python suite.py diff --git a/osc/commandline.py b/osc/commandline.py index e896c515..51103e8f 100644 --- a/osc/commandline.py +++ b/osc/commandline.py @@ -3511,6 +3511,158 @@ Please submit there instead, or use --nodevelproject to force direct submission. run_pager(rdiff) + def _get_branch_parent(self, prj): + m = re.match('^home:[^:]+:branches:(.+)', prj) + # OBS_Maintained is a special case + if m and prj.find(':branches:OBS_Maintained:') == -1: + return m.group(1) + return None + + def _prdiff_skip_package(self, opts, pkg): + if opts.exclude and re.search(opts.exclude, pkg): + return True + + if opts.include and not re.search(opts.include, pkg): + return True + + return False + + def _prdiff_output_diff(self, opts, rdiff): + if opts.diffstat: + print + p = subprocess.Popen("diffstat", + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + close_fds=True) + p.stdin.write(rdiff) + p.stdin.close() + diffstat = "".join(p.stdout.readlines()) + print diffstat + elif opts.unified: + print + print rdiff + #run_pager(rdiff) + + def _prdiff_output_matching_requests(self, opts, requests, + srcprj, pkg): + """ + Search through the given list of requests and output any + submitrequests which target pkg and originate from srcprj. + """ + for req in requests: + for action in req.get_actions('submit'): + if action.src_project != srcprj: + continue + + if action.tgt_package != pkg: + continue + + print + print req.list_view() + break + + @cmdln.alias('projectdiff') + @cmdln.alias('projdiff') + @cmdln.option('-r', '--requests', action='store_true', + help='show open requests for any packages with differences') + @cmdln.option('-e', '--exclude', metavar='REGEXP', dest='exclude', + help='skip packages matching REGEXP') + @cmdln.option('-i', '--include', metavar='REGEXP', dest='include', + help='only consider packages matching REGEXP') + @cmdln.option('-n', '--show-not-in-old', action='store_true', + help='show packages only in the new project') + @cmdln.option('-o', '--show-not-in-new', action='store_true', + help='show packages only in the old project') + @cmdln.option('-u', '--unified', action='store_true', + help='show full unified diffs of differences') + @cmdln.option('-d', '--diffstat', action='store_true', + help='show diffstat of differences') + + def do_prdiff(self, subcmd, opts, *args): + """${cmd_name}: Server-side diff of two projects + + Compares two projects and either summarises or outputs the + differences in full. In the second form, a project is compared + with one of its branches inside a home:$USER project (the branch + is treated as NEWPRJ). The home branch is optional if the current + working directory is a checked out copy of it. + + Usage: + osc prdiff [OPTIONS] OLDPRJ NEWPRJ + osc prdiff [OPTIONS] [home:$USER:branch:$PRJ] + + ${cmd_option_list} + """ + + if len(args) > 2: + raise oscerr.WrongArgs('Too many arguments.') + + if len(args) == 0: + if is_project_dir(os.curdir): + newprj = Project('.', getPackageList=False).name + oldprj = self._get_branch_parent(newprj) + if oldprj is None: + raise oscerr.WrongArgs('Current directory is not a valid home branch.') + else: + raise oscerr.WrongArgs('Current directory is not a project.') + elif len(args) == 1: + newprj = args[0] + oldprj = self._get_branch_parent(newprj) + if oldprj is None: + raise oscerr.WrongArgs('Single-argument form must be for a home branch.') + elif len(args) == 2: + oldprj, newprj = args + else: + raise RuntimeError('BUG in argument parsing, please report.\n' + 'args: ' + repr(args)) + + if opts.diffstat and opts.unified: + print >>sys.stderr, 'error - cannot specify both --diffstat and --unified' + sys.exit(1) + + apiurl = self.get_api_url() + + old_packages = meta_get_packagelist(apiurl, oldprj) + new_packages = meta_get_packagelist(apiurl, newprj) + + if opts.requests: + requests = get_request_list(apiurl, project=oldprj, + req_state=('new', 'review')) + + for pkg in old_packages: + if self._prdiff_skip_package(opts, pkg): + continue + + if pkg not in new_packages: + if opts.show_not_in_new: + print "old only: %s" % pkg + continue + + rdiff = server_diff_noex( + apiurl, + oldprj, pkg, None, + newprj, pkg, None, + unified=True, missingok=False, meta=False, expand=True + ) + + if rdiff: + print "differs: %s" % pkg + self._prdiff_output_diff(opts, rdiff) + + if opts.requests: + self._prdiff_output_matching_requests(opts, requests, + newprj, pkg) + else: + print "identical: %s" % pkg + + for pkg in new_packages: + if self._prdiff_skip_package(opts, pkg): + continue + + if pkg not in old_packages: + if opts.show_not_in_old: + print "new only: %s" % pkg + @cmdln.hide(1) @cmdln.alias('in') def do_install(self, subcmd, opts, *args): diff --git a/tests/common.py b/tests/common.py index f56541bf..fd1d7dce 100644 --- a/tests/common.py +++ b/tests/common.py @@ -106,8 +106,11 @@ def addExpectedRequest(method, url, **kwargs): class OscTestCase(unittest.TestCase): def setUp(self, copytree=True): - osc.core.conf.get_config(override_conffile=os.path.join(self._get_fixtures_dir(), 'oscrc'), + oscrc = os.path.join(self._get_fixtures_dir(), 'oscrc') + osc.core.conf.get_config(override_conffile=oscrc, override_no_keyring=True, override_no_gnome_keyring=True) + os.environ['OSC_CONFIG'] = oscrc + self.tmpdir = tempfile.mkdtemp(prefix='osc_test') if copytree: shutil.copytree(os.path.join(self._get_fixtures_dir(), 'osctest'), os.path.join(self.tmpdir, 'osctest')) diff --git a/tests/prdiff_fixtures/common-two-diff b/tests/prdiff_fixtures/common-two-diff new file mode 100644 index 00000000..a06ddea3 --- /dev/null +++ b/tests/prdiff_fixtures/common-two-diff @@ -0,0 +1,10 @@ +Index: common-two +=================================================================== +--- common-two 2013-01-18 19:18:38.225983117 +0000 ++++ common-two 2013-01-18 19:19:27.882082325 +0000 +@@ -1,4 +1,5 @@ + line one + line two + line three ++an extra line + last line diff --git a/tests/prdiff_fixtures/home:user:branches:some:project/.osc/_apiurl b/tests/prdiff_fixtures/home:user:branches:some:project/.osc/_apiurl new file mode 100644 index 00000000..0afeace7 --- /dev/null +++ b/tests/prdiff_fixtures/home:user:branches:some:project/.osc/_apiurl @@ -0,0 +1 @@ +http://localhost diff --git a/tests/prdiff_fixtures/home:user:branches:some:project/.osc/_packages b/tests/prdiff_fixtures/home:user:branches:some:project/.osc/_packages new file mode 100644 index 00000000..e1711ef4 --- /dev/null +++ b/tests/prdiff_fixtures/home:user:branches:some:project/.osc/_packages @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/tests/prdiff_fixtures/home:user:branches:some:project/.osc/_project b/tests/prdiff_fixtures/home:user:branches:some:project/.osc/_project new file mode 100644 index 00000000..b83a395a --- /dev/null +++ b/tests/prdiff_fixtures/home:user:branches:some:project/.osc/_project @@ -0,0 +1 @@ +home:user:branches:some:project diff --git a/tests/prdiff_fixtures/home:user:branches:some:project/common-two b/tests/prdiff_fixtures/home:user:branches:some:project/common-two new file mode 100644 index 00000000..ade1e2d8 --- /dev/null +++ b/tests/prdiff_fixtures/home:user:branches:some:project/common-two @@ -0,0 +1,5 @@ +line one +line two +line three +an extra line +last line \ No newline at end of file diff --git a/tests/prdiff_fixtures/home:user:branches:some:project/directory b/tests/prdiff_fixtures/home:user:branches:some:project/directory new file mode 100644 index 00000000..f29d4543 --- /dev/null +++ b/tests/prdiff_fixtures/home:user:branches:some:project/directory @@ -0,0 +1,6 @@ + + + + + + diff --git a/tests/prdiff_fixtures/new:prj/common-two b/tests/prdiff_fixtures/new:prj/common-two new file mode 100644 index 00000000..ade1e2d8 --- /dev/null +++ b/tests/prdiff_fixtures/new:prj/common-two @@ -0,0 +1,5 @@ +line one +line two +line three +an extra line +last line \ No newline at end of file diff --git a/tests/prdiff_fixtures/new:prj/directory b/tests/prdiff_fixtures/new:prj/directory new file mode 100644 index 00000000..f29d4543 --- /dev/null +++ b/tests/prdiff_fixtures/new:prj/directory @@ -0,0 +1,6 @@ + + + + + + diff --git a/tests/prdiff_fixtures/no-requests b/tests/prdiff_fixtures/no-requests new file mode 100644 index 00000000..aef429f1 --- /dev/null +++ b/tests/prdiff_fixtures/no-requests @@ -0,0 +1,2 @@ + + diff --git a/tests/prdiff_fixtures/old:prj/common-two b/tests/prdiff_fixtures/old:prj/common-two new file mode 100644 index 00000000..48365a30 --- /dev/null +++ b/tests/prdiff_fixtures/old:prj/common-two @@ -0,0 +1,4 @@ +line one +line two +line three +last line \ No newline at end of file diff --git a/tests/prdiff_fixtures/old:prj/directory b/tests/prdiff_fixtures/old:prj/directory new file mode 100644 index 00000000..a9db4b70 --- /dev/null +++ b/tests/prdiff_fixtures/old:prj/directory @@ -0,0 +1,6 @@ + + + + + + diff --git a/tests/prdiff_fixtures/oscrc b/tests/prdiff_fixtures/oscrc new file mode 100644 index 00000000..a30e040c --- /dev/null +++ b/tests/prdiff_fixtures/oscrc @@ -0,0 +1,103 @@ +[general] +# URL to access API server, e.g. https://api.opensuse.org +# you also need a section [https://api.opensuse.org] with the credentials +apiurl = http://localhost +# Downloaded packages are cached here. Must be writable by you. +#packagecachedir = /var/tmp/osbuild-packagecache +# Wrapper to call build as root (sudo, su -, ...) +#su-wrapper = su -c +# rootdir to setup the chroot environment +# can contain %(repo)s, %(arch)s, %(project)s and %(package)s for replacement, e.g. +# /srv/oscbuild/%(repo)s-%(arch)s or +# /srv/oscbuild/%(repo)s-%(arch)s-%(project)s-%(package)s +#build-root = /var/tmp/build-root +# compile with N jobs (default: "getconf _NPROCESSORS_ONLN") +#build-jobs = N +# build-type to use - values can be (depending on the capabilities of the 'build' script) +# empty - chroot build +# kvm - kvm VM build (needs build-device, build-swap, build-memory) +# xen - xen VM build (needs build-device, build-swap, build-memory) +# experimental: +# qemu - qemu VM build +# lxc - lxc build +#build-type = +# build-device is the disk-image file to use as root for VM builds +# e.g. /var/tmp/FILE.root +#build-device = /var/tmp/FILE.root +# build-swap is the disk-image to use as swap for VM builds +# e.g. /var/tmp/FILE.swap +#build-swap = /var/tmp/FILE.swap +# build-memory is the amount of memory used in the VM +# value in MB - e.g. 512 +#build-memory = 512 +# build-vmdisk-rootsize is the size of the disk-image used as root in a VM build +# values in MB - e.g. 4096 +#build-vmdisk-rootsize = 4096 +# build-vmdisk-swapsize is the size of the disk-image used as swap in a VM build +# values in MB - e.g. 1024 +#build-vmdisk-swapsize = 1024 +# Numeric uid:gid to assign to the "abuild" user in the build-root +# or "caller" to use the current users uid:gid +# This is convenient when sharing the buildroot with ordinary userids +# on the host. +# This should not be 0 +# build-uid = +# extra packages to install when building packages locally (osc build) +# this corresponds to osc build's -x option and can be overridden with that +# -x '' can also be given on the command line to override this setting, or +# you can have an empty setting here. +#extra-pkgs = vim gdb strace +# build platform is used if the platform argument is omitted to osc build +#build_repository = openSUSE_Factory +# default project for getpac or bco +#getpac_default_project = openSUSE:Factory +# alternate filesystem layout: have multiple subdirs, where colons were. +#checkout_no_colon = 0 +# local files to ignore with status, addremove, .... +#exclude_glob = .osc CVS .svn .* _linkerror *~ #*# *.orig *.bak *.changes.* +# keep passwords in plaintext. If you see this comment, your osc +# already uses the encrypted password, and only keeps them in plain text +# for backwards compatibility. Default will change to 0 in future releases. +# You can remove the plaintext password without harm, if you do not need +# backwards compatibility. +#plaintext_passwd = 1 +# limit the age of requests shown with 'osc req list'. +# this is a default only, can be overridden by 'osc req list -D NNN' +# Use 0 for unlimted. +#request_list_days = 0 +# show info useful for debugging +#debug = 1 +# show HTTP traffic useful for debugging +#http_debug = 1 +# Skip signature verification of packages used for build. +#no_verify = 1 +# jump into the debugger in case of errors +#post_mortem = 1 +# print call traces in case of errors +#traceback = 1 +# use KDE/Gnome/MacOS/Windows keyring for credentials if available +#use_keyring = 1 +# check for unversioned/removed files before commit +#check_filelist = 1 +# check for pending requests after executing an action (e.g. checkout, update, commit) +#check_for_request_on_action = 0 +# what to do with the source package if the submitrequest has been accepted. If +# nothing is specified the API default is used +#submitrequest_on_accept_action = cleanup|update|noupdate +#review requests interactively (default: off) +#request_show_review = 1 +# Directory with executables to validate sources, esp before committing +#source_validator_directory = /usr/lib/osc/source_validators + +[http://localhost] +user=Admin +pass=opensuse +# set aliases for this apiurl +# aliases = foo, bar +# email used in .changes, unless the one from osc meta prj will be used +# email = +# additional headers to pass to a request, e.g. for special authentication +#http_headers = Host: foofoobar, +# User: mumblegack +# Force using of keyring for this API +#keyring = 1 diff --git a/tests/prdiff_fixtures/osctest/.osc/_apiurl b/tests/prdiff_fixtures/osctest/.osc/_apiurl new file mode 100644 index 00000000..0afeace7 --- /dev/null +++ b/tests/prdiff_fixtures/osctest/.osc/_apiurl @@ -0,0 +1 @@ +http://localhost diff --git a/tests/prdiff_fixtures/osctest/.osc/_packages b/tests/prdiff_fixtures/osctest/.osc/_packages new file mode 100644 index 00000000..e1711ef4 --- /dev/null +++ b/tests/prdiff_fixtures/osctest/.osc/_packages @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/tests/prdiff_fixtures/osctest/.osc/_project b/tests/prdiff_fixtures/osctest/.osc/_project new file mode 100644 index 00000000..b83a395a --- /dev/null +++ b/tests/prdiff_fixtures/osctest/.osc/_project @@ -0,0 +1 @@ +home:user:branches:some:project diff --git a/tests/prdiff_fixtures/osctest/common-one/.osc/_apiurl b/tests/prdiff_fixtures/osctest/common-one/.osc/_apiurl new file mode 100644 index 00000000..0afeace7 --- /dev/null +++ b/tests/prdiff_fixtures/osctest/common-one/.osc/_apiurl @@ -0,0 +1 @@ +http://localhost diff --git a/tests/prdiff_fixtures/osctest/common-one/.osc/_files b/tests/prdiff_fixtures/osctest/common-one/.osc/_files new file mode 100644 index 00000000..4b6dcca0 --- /dev/null +++ b/tests/prdiff_fixtures/osctest/common-one/.osc/_files @@ -0,0 +1,4 @@ + + + + diff --git a/tests/prdiff_fixtures/osctest/common-one/.osc/_meta b/tests/prdiff_fixtures/osctest/common-one/.osc/_meta new file mode 100644 index 00000000..38045198 --- /dev/null +++ b/tests/prdiff_fixtures/osctest/common-one/.osc/_meta @@ -0,0 +1,10 @@ + + blah + foo + + + + + + + diff --git a/tests/prdiff_fixtures/osctest/common-one/.osc/_osclib_version b/tests/prdiff_fixtures/osctest/common-one/.osc/_osclib_version new file mode 100644 index 00000000..d3827e75 --- /dev/null +++ b/tests/prdiff_fixtures/osctest/common-one/.osc/_osclib_version @@ -0,0 +1 @@ +1.0 diff --git a/tests/prdiff_fixtures/osctest/common-one/.osc/_package b/tests/prdiff_fixtures/osctest/common-one/.osc/_package new file mode 100644 index 00000000..089880f8 --- /dev/null +++ b/tests/prdiff_fixtures/osctest/common-one/.osc/_package @@ -0,0 +1 @@ +common-one \ No newline at end of file diff --git a/tests/prdiff_fixtures/osctest/common-one/.osc/_project b/tests/prdiff_fixtures/osctest/common-one/.osc/_project new file mode 100644 index 00000000..b83a395a --- /dev/null +++ b/tests/prdiff_fixtures/osctest/common-one/.osc/_project @@ -0,0 +1 @@ +home:user:branches:some:project diff --git a/tests/prdiff_fixtures/osctest/common-one/.osc/common-one.spec b/tests/prdiff_fixtures/osctest/common-one/.osc/common-one.spec new file mode 100644 index 00000000..99bed787 --- /dev/null +++ b/tests/prdiff_fixtures/osctest/common-one/.osc/common-one.spec @@ -0,0 +1 @@ +contents are irrelevant diff --git a/tests/prdiff_fixtures/osctest/common-one/common-one.spec b/tests/prdiff_fixtures/osctest/common-one/common-one.spec new file mode 100644 index 00000000..99bed787 --- /dev/null +++ b/tests/prdiff_fixtures/osctest/common-one/common-one.spec @@ -0,0 +1 @@ +contents are irrelevant diff --git a/tests/prdiff_fixtures/osctest/common-two/.osc/_apiurl b/tests/prdiff_fixtures/osctest/common-two/.osc/_apiurl new file mode 100644 index 00000000..0afeace7 --- /dev/null +++ b/tests/prdiff_fixtures/osctest/common-two/.osc/_apiurl @@ -0,0 +1 @@ +http://localhost diff --git a/tests/prdiff_fixtures/osctest/common-two/.osc/_files b/tests/prdiff_fixtures/osctest/common-two/.osc/_files new file mode 100644 index 00000000..63b65f21 --- /dev/null +++ b/tests/prdiff_fixtures/osctest/common-two/.osc/_files @@ -0,0 +1,4 @@ + + + + diff --git a/tests/prdiff_fixtures/osctest/common-two/.osc/_meta b/tests/prdiff_fixtures/osctest/common-two/.osc/_meta new file mode 100644 index 00000000..3d41ffd3 --- /dev/null +++ b/tests/prdiff_fixtures/osctest/common-two/.osc/_meta @@ -0,0 +1,10 @@ + + blah + foo + + + + + + + diff --git a/tests/prdiff_fixtures/osctest/common-two/.osc/_osclib_version b/tests/prdiff_fixtures/osctest/common-two/.osc/_osclib_version new file mode 100644 index 00000000..d3827e75 --- /dev/null +++ b/tests/prdiff_fixtures/osctest/common-two/.osc/_osclib_version @@ -0,0 +1 @@ +1.0 diff --git a/tests/prdiff_fixtures/osctest/common-two/.osc/_package b/tests/prdiff_fixtures/osctest/common-two/.osc/_package new file mode 100644 index 00000000..2ff38288 --- /dev/null +++ b/tests/prdiff_fixtures/osctest/common-two/.osc/_package @@ -0,0 +1 @@ +common-two \ No newline at end of file diff --git a/tests/prdiff_fixtures/osctest/common-two/.osc/_project b/tests/prdiff_fixtures/osctest/common-two/.osc/_project new file mode 100644 index 00000000..b83a395a --- /dev/null +++ b/tests/prdiff_fixtures/osctest/common-two/.osc/_project @@ -0,0 +1 @@ +home:user:branches:some:project diff --git a/tests/prdiff_fixtures/osctest/common-two/.osc/common-two.spec b/tests/prdiff_fixtures/osctest/common-two/.osc/common-two.spec new file mode 100644 index 00000000..99bed787 --- /dev/null +++ b/tests/prdiff_fixtures/osctest/common-two/.osc/common-two.spec @@ -0,0 +1 @@ +contents are irrelevant diff --git a/tests/prdiff_fixtures/osctest/common-two/common-two.spec b/tests/prdiff_fixtures/osctest/common-two/common-two.spec new file mode 100644 index 00000000..99bed787 --- /dev/null +++ b/tests/prdiff_fixtures/osctest/common-two/common-two.spec @@ -0,0 +1 @@ +contents are irrelevant diff --git a/tests/prdiff_fixtures/request b/tests/prdiff_fixtures/request new file mode 100644 index 00000000..2355cbbe --- /dev/null +++ b/tests/prdiff_fixtures/request @@ -0,0 +1,16 @@ + + + + + + + update + + + + + + - Fix it to work +- Improve support for something + + diff --git a/tests/prdiff_fixtures/some:project/.osc/_apiurl b/tests/prdiff_fixtures/some:project/.osc/_apiurl new file mode 100644 index 00000000..0afeace7 --- /dev/null +++ b/tests/prdiff_fixtures/some:project/.osc/_apiurl @@ -0,0 +1 @@ +http://localhost diff --git a/tests/prdiff_fixtures/some:project/.osc/_packages b/tests/prdiff_fixtures/some:project/.osc/_packages new file mode 100644 index 00000000..c4c8b110 --- /dev/null +++ b/tests/prdiff_fixtures/some:project/.osc/_packages @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/tests/prdiff_fixtures/some:project/.osc/_project b/tests/prdiff_fixtures/some:project/.osc/_project new file mode 100644 index 00000000..f9a316e5 --- /dev/null +++ b/tests/prdiff_fixtures/some:project/.osc/_project @@ -0,0 +1 @@ +some:project diff --git a/tests/prdiff_fixtures/some:project/common-two b/tests/prdiff_fixtures/some:project/common-two new file mode 100644 index 00000000..ade1e2d8 --- /dev/null +++ b/tests/prdiff_fixtures/some:project/common-two @@ -0,0 +1,5 @@ +line one +line two +line three +an extra line +last line \ No newline at end of file diff --git a/tests/prdiff_fixtures/some:project/directory b/tests/prdiff_fixtures/some:project/directory new file mode 100644 index 00000000..f29d4543 --- /dev/null +++ b/tests/prdiff_fixtures/some:project/directory @@ -0,0 +1,6 @@ + + + + + + diff --git a/tests/suite.py b/tests/suite.py index 8e5142cb..0987b37c 100644 --- a/tests/suite.py +++ b/tests/suite.py @@ -21,6 +21,7 @@ import test_package_status import test_project_status import test_request import test_setlinkrev +import test_prdiff suite = unittest.TestSuite() suite.addTests(test_addfiles.suite()) @@ -36,6 +37,7 @@ suite.addTests(test_package_status.suite()) suite.addTests(test_project_status.suite()) suite.addTests(test_request.suite()) suite.addTests(test_setlinkrev.suite()) +suite.addTests(test_prdiff.suite()) if have_xmlrunner: result = xmlrunner.XMLTestRunner(output=os.path.join(os.getcwd(), 'junit-xml-results')).run(suite) diff --git a/tests/test_prdiff.py b/tests/test_prdiff.py new file mode 100644 index 00000000..b82fc5e6 --- /dev/null +++ b/tests/test_prdiff.py @@ -0,0 +1,272 @@ +import osc.commandline +import osc.core +import osc.oscerr +import os +import re +import sys +import urllib2 +from common import GET, POST, OscTestCase, addExpectedRequest, EXPECTED_REQUESTS + + +FIXTURES_DIR = os.path.join(os.getcwd(), 'prdiff_fixtures') +API_URL = 'http://localhost/' +UPSTREAM = 'some:project' +BRANCH = 'home:user:branches:' + UPSTREAM + +def rdiff_url(pkg, oldprj, newprj): + return API_URL + 'source/%s/%s?unified=1&opackage=%s&oproject=%s&cmd=diff&expand=1&filelimit=0' % \ + (newprj, pkg, pkg, oldprj.replace(':', '%3A')) + +def request_url(prj): + return API_URL + 'search/request?match=%%28state%%2F%%40name%%3D%%27new%%27+or+state%%2F%%40name%%3D%%27review%%27%%29+and+%%28action%%2Ftarget%%2F%%40project%%3D%%27%s%%27+or+submit%%2Ftarget%%2F%%40project%%3D%%27%s%%27+or+action%%2Fsource%%2F%%40project%%3D%%27%s%%27+or+submit%%2Fsource%%2F%%40project%%3D%%27%s%%27%%29' % \ + tuple([prj.replace(':', '%3A')] * 4) + +def GET_PROJECT_PACKAGES(*projects): + def decorator(test_method): + def wrapped_test_method(*args): + for project in projects: + addExpectedRequest('GET', API_URL + 'source/' + project, + file='%s/directory' % project) + test_method(*args) + # "rename" method otherwise we cannot specify a TestCaseClass.testName + # cmdline arg when using unittest.main() + wrapped_test_method.__name__ = test_method.__name__ + return wrapped_test_method + return decorator + +def POST_RDIFF(oldprj, newprj): + def decorator(test_method): + def wrapped_test_method(*args): + addExpectedRequest('POST', rdiff_url('common-one', oldprj, newprj), exp='', text='') + addExpectedRequest('POST', rdiff_url('common-two', oldprj, newprj), exp='', file='common-two-diff') + addExpectedRequest('POST', rdiff_url('common-three', oldprj, newprj), exp='', text='') + test_method(*args) + # "rename" method otherwise we cannot specify a TestCaseClass.testName + # cmdline arg when using unittest.main() + wrapped_test_method.__name__ = test_method.__name__ + return wrapped_test_method + return decorator + +def suite(): + import unittest + return unittest.makeSuite(TestProjectDiff) + +class TestProjectDiff(OscTestCase): + diff_hdr = 'Index: %s\n===================================================================' + def _get_fixtures_dir(self): + return FIXTURES_DIR + + def _change_to_tmpdir(self, *args): + os.chdir(os.path.join(self.tmpdir, *args)) + + def _run_prdiff(self, *args): + """Runs osc prdiff, returning captured STDOUT as a string.""" + cli = osc.commandline.Osc() + argv = ['osc', 'prdiff'] + argv.extend(args) + cli.main(argv=argv) + return sys.stdout.getvalue() + + + def testPrdiffTooManyArgs(self): + def runner(): + self._run_prdiff('one', 'two', 'superfluous-arg') + self.assertRaises(osc.oscerr.WrongArgs, runner) + + + @GET_PROJECT_PACKAGES(UPSTREAM, BRANCH) + @POST_RDIFF(UPSTREAM, BRANCH) + @POST(rdiff_url('only-in-new', UPSTREAM, BRANCH), exp='', text='') + def testPrdiffZeroArgs(self): + exp = """identical: common-one +differs: common-two +identical: common-three +identical: only-in-new +""" + def runner(): + self._run_prdiff() + + os.chdir('/tmp') + self.assertRaises(osc.oscerr.WrongArgs, runner) + + self._change_to_tmpdir(FIXTURES_DIR, UPSTREAM) + self.assertRaises(osc.oscerr.WrongArgs, runner) + + self._change_to_tmpdir(FIXTURES_DIR, BRANCH) + out = self._run_prdiff() + self.assertEqualMultiline(out, exp) + + + @GET_PROJECT_PACKAGES(UPSTREAM, BRANCH) + @POST_RDIFF(UPSTREAM, BRANCH) + @POST(rdiff_url('only-in-new', UPSTREAM, BRANCH), exp='', text='') + def testPrdiffOneArg(self): + self._change_to_tmpdir() + exp = """identical: common-one +differs: common-two +identical: common-three +identical: only-in-new +""" + out = self._run_prdiff('home:user:branches:some:project') + self.assertEqualMultiline(out, exp) + + + @GET_PROJECT_PACKAGES('old:prj', 'new:prj') + @POST_RDIFF('old:prj', 'new:prj') + def testPrdiffTwoArgs(self): + self._change_to_tmpdir() + exp = """identical: common-one +differs: common-two +identical: common-three +""" + out = self._run_prdiff('old:prj', 'new:prj') + self.assertEqualMultiline(out, exp) + + + @GET_PROJECT_PACKAGES('old:prj', 'new:prj') + @POST_RDIFF('old:prj', 'new:prj') + def testPrdiffOldOnly(self): + self._change_to_tmpdir() + exp = """identical: common-one +differs: common-two +identical: common-three +old only: only-in-old +""" + out = self._run_prdiff('--show-not-in-new', 'old:prj', 'new:prj') + self.assertEqualMultiline(out, exp) + + + @GET_PROJECT_PACKAGES('old:prj', 'new:prj') + @POST_RDIFF('old:prj', 'new:prj') + def testPrdiffNewOnly(self): + self._change_to_tmpdir() + exp = """identical: common-one +differs: common-two +identical: common-three +new only: only-in-new +""" + out = self._run_prdiff('--show-not-in-old', 'old:prj', 'new:prj') + self.assertEqualMultiline(out, exp) + + + @GET_PROJECT_PACKAGES('old:prj', 'new:prj') + @POST_RDIFF('old:prj', 'new:prj') + def testPrdiffDiffstat(self): + self._change_to_tmpdir() + exp = """identical: common-one +differs: common-two + + common-two | 1 + + 1 file changed, 1 insertion(+) + +identical: common-three +""" + out = self._run_prdiff('--diffstat', 'old:prj', 'new:prj') + self.assertEqualMultiline(out, exp) + + + @GET_PROJECT_PACKAGES('old:prj', 'new:prj') + @POST_RDIFF('old:prj', 'new:prj') + def testPrdiffUnified(self): + self._change_to_tmpdir() + exp = """identical: common-one +differs: common-two + +Index: common-two +=================================================================== +--- common-two\t2013-01-18 19:18:38.225983117 +0000 ++++ common-two\t2013-01-18 19:19:27.882082325 +0000 +@@ -1,4 +1,5 @@ + line one + line two + line three ++an extra line + last line + +identical: common-three +""" + out = self._run_prdiff('--unified', 'old:prj', 'new:prj') + self.assertEqualMultiline(out, exp) + + + @GET_PROJECT_PACKAGES('old:prj', 'new:prj') + @POST(rdiff_url('common-two', 'old:prj', 'new:prj'), exp='', file='common-two-diff') + @POST(rdiff_url('common-three', 'old:prj', 'new:prj'), exp='', text='') + def testPrdiffInclude(self): + self._change_to_tmpdir() + exp = """differs: common-two +identical: common-three +""" + out = self._run_prdiff('--include', 'common-t', + 'old:prj', 'new:prj') + self.assertEqualMultiline(out, exp) + + + @GET_PROJECT_PACKAGES('old:prj', 'new:prj') + @POST(rdiff_url('common-two', 'old:prj', 'new:prj'), exp='', file='common-two-diff') + @POST(rdiff_url('common-three', 'old:prj', 'new:prj'), exp='', text='') + def testPrdiffExclude(self): + self._change_to_tmpdir() + exp = """differs: common-two +identical: common-three +""" + out = self._run_prdiff('--exclude', 'one', 'old:prj', 'new:prj') + self.assertEqualMultiline(out, exp) + + + @GET_PROJECT_PACKAGES('old:prj', 'new:prj') + @POST(rdiff_url('common-two', 'old:prj', 'new:prj'), exp='', file='common-two-diff') + def testPrdiffIncludeExclude(self): + self._change_to_tmpdir() + exp = """differs: common-two +""" + out = self._run_prdiff('--include', 'common-t', + '--exclude', 'three', + 'old:prj', 'new:prj') + self.assertEqualMultiline(out, exp) + + + @GET_PROJECT_PACKAGES(UPSTREAM, BRANCH) + @GET(request_url(UPSTREAM), exp='', file='request') + @POST(rdiff_url('common-one', UPSTREAM, BRANCH), exp='', text='') + @POST(rdiff_url('common-two', UPSTREAM, BRANCH), exp='', file='common-two-diff') + @POST(rdiff_url('common-three', UPSTREAM, BRANCH), exp='', file='common-two-diff') + @POST(rdiff_url('only-in-new', UPSTREAM, BRANCH), exp='', text='') + def testPrdiffRequestsMatching(self): + self._change_to_tmpdir() + exp = """identical: common-one +differs: common-two + +148023 State:new By:user When:2013-01-11T11:04:14 + submit: home:user:branches:some:project/common-two -> some:project + Descr: - Fix it to work - Improve support for something + +differs: common-three +identical: only-in-new +""" + out = self._run_prdiff('--requests', UPSTREAM, BRANCH) + self.assertEqualMultiline(out, exp) + + + # Reverse the direction of the diff. + @GET_PROJECT_PACKAGES(BRANCH, UPSTREAM) + @GET(request_url(BRANCH), exp='', file='no-requests') + @POST(rdiff_url('common-one', BRANCH, UPSTREAM), exp='', text='') + @POST(rdiff_url('common-two', BRANCH, UPSTREAM), exp='', file='common-two-diff') + @POST(rdiff_url('common-three', BRANCH, UPSTREAM), exp='', file='common-two-diff') + @POST(rdiff_url('only-in-new', BRANCH, UPSTREAM), exp='', text='') + def testPrdiffRequestsSwitched(self): + self._change_to_tmpdir() + exp = """identical: common-one +differs: common-two +differs: common-three +identical: only-in-new +""" + out = self._run_prdiff('--requests', BRANCH, UPSTREAM) + self.assertEqualMultiline(out, exp) + + + +if __name__ == '__main__': + import unittest + unittest.main()