From e874c92cefc088c786c16bc18f320beafe070a1e Mon Sep 17 00:00:00 2001
From: Kamil Páral <kparal@redhat.com>
Date: Mar 27 2018 14:41:06 +0000
Subject: distgit_directive: use correct branch name for Rawhide


Fixes https://pagure.io/taskotron/libtaskotron/issue/409

---

diff --git a/libtaskotron/directives/distgit_directive.py b/libtaskotron/directives/distgit_directive.py
index f50785e..c83d953 100644
--- a/libtaskotron/directives/distgit_directive.py
+++ b/libtaskotron/directives/distgit_directive.py
@@ -9,7 +9,7 @@ import os.path
 
 from libtaskotron.directives import BaseDirective
 from libtaskotron import file_utils, python_utils
-from libtaskotron.ext.fedora import rpm_utils
+from libtaskotron.ext.fedora import rpm_utils, yumrepoinfo
 import libtaskotron.exceptions as exc
 from libtaskotron.logger import log
 
@@ -147,6 +147,10 @@ class DistGitDirective(BaseDirective):
             nvr = params['nvr']
             package = rpm_utils.rpmformat(nvr, fmt='n')
             gitref = rpm_utils.get_dist_tag(nvr).replace('c', '')
+            rawhide_tag = yumrepoinfo.YumRepoInfo(resolve_baseurl=False).get(
+                'rawhide', 'tag')
+            if gitref == rawhide_tag:
+                gitref = 'master'
             namespace = 'rpms'
 
         # Assign defaults
diff --git a/libtaskotron/ext/fedora/yumrepoinfo.py b/libtaskotron/ext/fedora/yumrepoinfo.py
index 6c36548..7018e04 100644
--- a/libtaskotron/ext/fedora/yumrepoinfo.py
+++ b/libtaskotron/ext/fedora/yumrepoinfo.py
@@ -45,7 +45,8 @@ def get_yumrepoinfo(arch=None, filelist=None):
 class YumRepoInfo(object):
     '''This class is a wrapper for easily accessing repoinfo.conf file.'''
 
-    def __init__(self, arch=None, filelist=None, resolve_retry=3):
+    def __init__(self, arch=None, filelist=None, resolve_baseurl=True,
+                 resolve_retry=3):
         '''
         :param str arch: architecture for which to adjust repo URLs. By default
                     it refers to the architecture of the current machine. It's
@@ -54,22 +55,20 @@ class YumRepoInfo(object):
                         first available config file is used. If ``None``, then
                         the default list of locations is used.
         :type filelist: iterable of str
+        :param bool resolve_baseurl: if baseurl is a known redirect, resolve
+            it for each section during initialization. If this is ``False``,
+            you must call :meth:`_switch_to_mirror` manually.
         :param int resolve_retry: how many tries to retry resolving the URL
-                                  for each section in case the network request
-                                  fails (this only applies when your baseurl
-                                  is a known redirect)
+            for each section in case the network request fails
         :raise TaskotronConfigError: if no YUM repositories data is found (empty
                                      or non-existent config file). It's not
                                      raised if you specifically request no data
                                      to load (``filelist=[]``).
         :raise TaskotronRemoteError: if url resolving fails
         '''
-        if (config.get_config().profile == config.ProfileName.TESTING and
-            filelist is None):
-            # Under the testing profile we don't want to try to load any config
-            # files, they might not be available at all (T163). The unit test
-            # can provide its own with `filelist` - in that case, load it.
-            return
+        if config.get_config().profile == config.ProfileName.TESTING:
+            resolve_baseurl = False
+
         self.arch = arch_utils.basearch(arch)
         self.filelist = (filelist if filelist is not None else
             [os.path.join(confdir, 'yumrepoinfo.conf')
@@ -93,8 +92,8 @@ class YumRepoInfo(object):
         self._adjust_baseurl()
 
         # download.fp.o is a known redirect
-        if 'download.fedoraproject.org' in self.parser.get('DEFAULT',
-                                                           'baseurl'):
+        if resolve_baseurl and ('download.fedoraproject.org' in
+            self.parser.get('DEFAULT', 'baseurl')):
             self._switch_to_mirror()
 
     def repos(self):
@@ -256,14 +255,16 @@ class YumRepoInfo(object):
             return [t.strip() for t in itemlist.split(',')]
 
     def _adjust_baseurl(self):
-        '''We need to adjust baseurl if the requested arch is an alternate one for that repo.
+        '''We need to adjust baseurl if the requested arch is an alternate one
+        for that repo.
 
         This is supposed to be called only once during initialization.
         '''
         for section in self.parser.sections():
             if (self.parser.has_option(section, 'alternate_arches') and
-                    self.arch in self._getlist(section, 'alternate_arches')):
-                self.parser.set(section, 'baseurl', self.get(section, 'baseurl_altarch'))
+                self.arch in self._getlist(section, 'alternate_arches')):
+                self.parser.set(section, 'baseurl',
+                    self.get(section, 'baseurl_altarch'))
 
     def _switch_to_mirror(self):
         '''If the baseurl is a round-robin redirect (as in case of
diff --git a/testing/conf/yumrepoinfo.conf b/testing/conf/yumrepoinfo.conf
new file mode 100644
index 0000000..3dba166
--- /dev/null
+++ b/testing/conf/yumrepoinfo.conf
@@ -0,0 +1,92 @@
+## A Taskotron configuration file representing available YUM repositories inside
+## Fedora infrastructure.
+## This file is in a ConfigParser syntax, very similar to INI syntax known from
+## Windows.
+## There is a guide describing how to update this file after important Fedora
+## release events, please see:
+## https://fedoraproject.org/wiki/How_to_update_yumrepoinfo.conf_in_Taskotron
+
+[DEFAULT]
+# URLs to yum repos
+# Please note: 'download.fedoraproject.org' is a redirect that points you to a
+# random mirror every time. For faster and more reliable operation, pick a close
+# mirror from https://mirrors.fedoraproject.org and use it in 'baseurl' and 'baseurl_altarch'.
+baseurl = http://download.fedoraproject.org/pub/fedora/linux
+baseurl_altarch = http://download.fedoraproject.org/pub/fedora-secondary
+goldurl = %(baseurl)s/releases/%(path)s/Everything/%(arch)s/os
+updatesurl = %(baseurl)s/updates/%(path)s/Everything/%(arch)s
+rawhideurl = %(baseurl)s/%(path)s/Everything/%(arch)s/os
+
+# list of primary and alternate architectures. That decides whether baseurl or baseurl_altarch
+# is used when determining path.
+primary_arches = armhfp, x86_64
+alternate_arches = aarch64, i386, ppc64, ppc64le, s390x
+
+# a direct parent of this repo, essential for operations (dependencies)
+parent =
+
+# koji tag defaults to section name
+tag = %(__name__)s
+
+# release_status can be one of: obsolete, stable, branched or rawhide
+# for non-top-parent repos this is an empty string
+release_status =
+
+# Rawhide
+[rawhide]
+url = %(rawhideurl)s
+path = development/rawhide
+tag = f29
+release_status = rawhide
+
+# Fedora 28
+[f28]
+url = %(rawhideurl)s
+path = development/28
+release_status = branched
+
+[f28-updates]
+url = %(updatesurl)s
+path = 28
+parent = f28
+
+[f28-updates-testing]
+url = %(updatesurl)s
+path = testing/28
+parent = f28-updates
+
+# Fedora 27
+[f27]
+url = %(goldurl)s
+path = 27
+release_status = stable
+
+[f27-updates]
+url = %(updatesurl)s
+path = 27
+parent = f27
+updatesurl = %(baseurl)s/updates/%(path)s/%(arch)s
+
+[f27-updates-testing]
+url = %(updatesurl)s
+path = testing/27
+parent = f27-updates
+updatesurl = %(baseurl)s/updates/%(path)s/%(arch)s
+
+# Fedora 26
+[f26]
+url = %(goldurl)s
+path = 26
+release_status = stable
+
+[f26-updates]
+url = %(updatesurl)s
+path = 26
+parent = f26
+updatesurl = %(baseurl)s/updates/%(path)s/%(arch)s
+
+[f26-updates-testing]
+url = %(updatesurl)s
+path = testing/26
+parent = f26-updates
+updatesurl = %(baseurl)s/updates/%(path)s/%(arch)s
diff --git a/testing/conftest.py b/testing/conftest.py
index 47db3f1..97c0c23 100644
--- a/testing/conftest.py
+++ b/testing/conftest.py
@@ -54,3 +54,9 @@ def pytest_configure(config):
     logging.getLogger().setLevel(logging.NOTSET)
     # always use full formatter format
     libtaskotron.logger.stream_handler.setFormatter(libtaskotron.logger._formatter_full)
+
+    # load config files from a testing conf dir (default config files might
+    # not be available and we can't rely on their contents)
+    libtaskotron.config.CONF_DIRS = [
+        os.path.abspath(os.path.dirname(__file__) + '/conf')
+    ]
diff --git a/testing/test_distgit_directive.py b/testing/test_distgit_directive.py
index 4cc8800..2b19ee7 100644
--- a/testing/test_distgit_directive.py
+++ b/testing/test_distgit_directive.py
@@ -11,6 +11,7 @@ import mock
 from libtaskotron import file_utils
 from libtaskotron.directives import distgit_directive
 import libtaskotron.exceptions as exc
+from libtaskotron.ext.fedora import yumrepoinfo
 
 
 @pytest.mark.usefixtures('setup')
@@ -42,7 +43,7 @@ class TestDistGitDirective():
             path=path,
             gitref=self.ref_branch)
 
-    def test_download(self, monkeypatch):
+    def test_download(self):
         self.helper.process(self.ref_input, None)
 
         download_calls = self.mock_download.calls
@@ -51,7 +52,7 @@ class TestDistGitDirective():
         assert download_calls[0][1][2] == os.path.join(self.ref_input['target_dir'],
                                                        self.ref_path[0])
 
-    def test_localpath(self, monkeypatch):
+    def test_localpath(self):
         self.ref_input['localpath'] = self.ref_localpath
 
         self.helper.process(self.ref_input, None)
@@ -62,7 +63,7 @@ class TestDistGitDirective():
         assert download_calls[0][1][2] == os.path.join(self.ref_input['target_dir'],
                                                        self.ref_localpath[0])
 
-    def test_multiple_localpath(self, monkeypatch):
+    def test_multiple_localpath(self):
         ref_path = ['file1', 'file2']
         ref_localpath = ['file3', 'file4']
         self.ref_input['path'] = ref_path
@@ -180,3 +181,15 @@ class TestDistGitDirective():
         downloaded = self.helper.process(self.ref_input, None)
 
         assert len(downloaded) == 1
+
+    def test_gitref_rawhide(self):
+        '''On rawhide, gitref must be "master"'''
+        rawhide_tag = yumrepoinfo.YumRepoInfo().get('rawhide', 'tag')
+        self.ref_nvr = 'foo-1.2-3.%s' % rawhide_tag.replace('f', 'fc')
+        self.ref_input.update({'nvr': self.ref_nvr})
+        self.ref_branch = 'master'
+
+        self.helper.process(self.ref_input, None)
+
+        download_calls = self.mock_download.calls
+        assert download_calls[0][1][0] == self._get_url(self.ref_path[0])

