[bitbake-devel] [RFC 3/5] bb.tests.fetch_git: initial set of tests for git fetcher
Olof Johansson
olof.johansson at axis.com
Thu Dec 12 16:48:56 UTC 2013
This commit introduces a set of whitebox unit tests for the git
fetcher, including some minor refactoring of the fetcher itself
to increase testability.
Signed-off-by: Olof Johansson <olof.johansson at axis.com>
---
bin/bitbake-selftest | 3 +-
lib/bb/fetch2/git.py | 31 +++++++--
lib/bb/tests/fetch_git.py | 164 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 190 insertions(+), 8 deletions(-)
create mode 100644 lib/bb/tests/fetch_git.py
diff --git a/bin/bitbake-selftest b/bin/bitbake-selftest
index 48a58fe..7f02fbf 100755
--- a/bin/bitbake-selftest
+++ b/bin/bitbake-selftest
@@ -25,10 +25,11 @@ try:
except RuntimeError as exc:
sys.exit(str(exc))
-tests = ["bb.tests.codeparser",
+tests = ["bb.tests.codeparser",
"bb.tests.cow",
"bb.tests.data",
"bb.tests.fetch",
+ "bb.tests.fetch_git",
"bb.tests.utils"]
for t in tests:
diff --git a/lib/bb/fetch2/git.py b/lib/bb/fetch2/git.py
index bd107db..81bf282 100644
--- a/lib/bb/fetch2/git.py
+++ b/lib/bb/fetch2/git.py
@@ -87,14 +87,10 @@ class Git(FetchMethod):
init git specific variable within url data
so that the git method like latest_revision() can work
"""
- if 'protocol' in ud.parm:
- ud.proto = ud.parm['protocol']
- elif not ud.host:
- ud.proto = 'file'
- else:
- ud.proto = "git"
- if not ud.proto in ('git', 'file', 'ssh', 'http', 'https', 'rsync'):
+ ud.proto = self._fetch_url_proto(ud)
+
+ if not self._valid_protocol(ud.proto):
raise bb.fetch2.ParameterError("Invalid protocol type", ud.url)
ud.nocheckout = ud.parm.get("nocheckout","0") == "1"
@@ -287,6 +283,27 @@ class Git(FetchMethod):
def supports_srcrev(self):
return True
+ def _fetch_url_proto(self, ud):
+ """
+ Identify protocol for Git URL.
+
+ The scheme prefix is used to couple the URL to this particular fetcher,
+ but it's not necessarily the git protocol we will use. If a protocol
+ URL parameter is supplied we will use that, otherwise we will use
+ git:// if the URL contains a hostname or file:// if it does not.
+
+ """
+ if 'protocol' in ud.parm:
+ return ud.parm['protocol']
+
+ if not ud.host:
+ return 'file'
+
+ return "git"
+
+ def _valid_protocol(self, proto):
+ return proto in ('git', 'file', 'ssh', 'http', 'https', 'rsync')
+
def _contains_ref(self, ud, d, name):
cmd = "%s branch --contains %s --list %s 2> /dev/null | wc -l" % (
ud.basecmd, ud.revisions[name], ud.branches[name])
diff --git a/lib/bb/tests/fetch_git.py b/lib/bb/tests/fetch_git.py
new file mode 100644
index 0000000..89af515
--- /dev/null
+++ b/lib/bb/tests/fetch_git.py
@@ -0,0 +1,164 @@
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# BitBake Tests for the git fetcher (fetch2/git.py)
+#
+# Copyright (C) 2013 Olof Johansson
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import unittest
+from mock import Mock, patch
+import bb.fetch2
+from bb.fetch2.git import Git
+
+def mock_ud(url):
+ """
+ Generate a FetchData like Mock object based on a URL.
+ """
+ ud = Mock()
+ (ud.type, ud.host, ud.path,
+ ud.user, ud.pswd, ud.parm) = bb.fetch2.decodeurl(url)
+ return ud
+
+
+class GitFetcherTest(unittest.TestCase):
+ def setUp(self):
+ bb.fetch2.FetchMethod = Mock()
+ self.fetcher = Git()
+
+
+ def tearDown(self):
+ pass
+
+
+ def test_supports(self):
+ ud = Mock()
+
+ ud.type = 'git'
+ self.assertTrue(self.fetcher.supports(ud, None))
+
+ ud.type = 'ssh'
+ self.assertFalse(self.fetcher.supports(ud, None))
+
+
+ @patch("bb.fetch2.git.Git.latest_revision")
+ def test_urldata_init(self, latest_rev):
+ class MockD(object):
+ """ Mock datasmart class. """
+ def __init__(self, **kwargs):
+ self.known = kwargs
+
+ def getVar(self, var, expand=False):
+ if var in self.known:
+ return self.known[var]
+
+
+ bb.fetch2.git.data.getVar = lambda var, d, expand: d.getVar(var, expand)
+
+ d = MockD(
+ DL_DIR='/tmp/dl_dir',
+ )
+
+ # Invalid protocol given as url parameter
+ with self.assertRaises(bb.fetch2.ParameterError):
+ ud = mock_ud("git://example.com/foo.git;protocol=gopher")
+ self.fetcher.urldata_init(ud, d)
+
+ # Unbalanced number of branch/name parameters
+ with self.assertRaises(bb.fetch2.ParameterError):
+ ud = mock_ud(
+ "git://example.com/foo.git;branch=master,foo;name=bar")
+ # The names are usually extracted in FetchMethod constructor
+ ud.names = ['bar']
+ self.fetcher.urldata_init(ud, d)
+
+ ud = mock_ud("git://example.com/foo.git;protocol=ssh")
+ ud.names = ['default']
+ ud.revisions = {'default': None}
+
+ latest_rev.return_value = 'asd'
+
+ self.fetcher.urldata_init(ud, d)
+
+ self.assertFalse(ud.nocheckout)
+ self.assertFalse(ud.rebaseable)
+ self.assertFalse(ud.bareclone)
+ self.assertEqual(ud.branches, {'default': 'master'})
+
+
+ def test_fetch_url_proto(self):
+ for url in [
+ ('git:///foo.git', 'file'),
+ ('git://example.com/foo.git', 'git'),
+ ('git://example.com/foo.git;protocol=ssh', 'ssh')
+ ]:
+ ud = mock_ud(url[0])
+ self.assertEqual(self.fetcher._fetch_url_proto(ud), url[1])
+
+
+ def test_valid_protocol(self):
+ for valid in ['git', 'file', 'ssh', 'http', 'https', 'rsync']:
+ self.assertTrue(self.fetcher._valid_protocol(valid))
+ for invalid in ['dns', '', None]:
+ self.assertFalse(self.fetcher._valid_protocol(invalid))
+
+
+ def test_contains_ref(self):
+ commit_sha1 = '8f453bb11d72afc90a986ac604b3477d97eaf9a8'
+
+ ud = Mock()
+ ud.basecmd = 'git'
+ ud.revisions = {'default': commit_sha1}
+ ud.branches = {'default': 'master'}
+
+ d = Mock()
+
+ bb.fetch2.git.runfetchcmd = Mock()
+
+ # Two output lines from git branch --contains; _contains_ref() == True
+ # Also, while we're at it, verify that ud.basecmd changes take effect.
+ ud.basecmd = 'sudo git'
+ bb.fetch2.git.runfetchcmd.return_value = '2'
+ self.assertTrue(self.fetcher._contains_ref(ud, d, 'default'))
+ bb.fetch2.git.runfetchcmd.assert_called_with(
+ "sudo git branch --contains %s --list %s 2> /dev/null | wc -l" % (
+ ud.revisions['default'], ud.branches['default']),
+ d, quiet=True)
+ ud.basecmd = 'git'
+
+ # No output from git branch --contains; _contains_ref() == False
+ bb.fetch2.git.runfetchcmd.return_value = '0'
+ self.assertFalse(self.fetcher._contains_ref(ud, d, 'default'))
+ bb.fetch2.git.runfetchcmd.assert_called_with(
+ "git branch --contains %s --list %s 2> /dev/null | wc -l" % (
+ ud.revisions['default'], ud.branches['default']),
+ d, quiet=True)
+
+ # Strange wc -l output should throw FetchError exception
+ with self.assertRaises(bb.fetch2.FetchError):
+ bb.fetch2.git.runfetchcmd.return_value = '0 1'
+ self.fetcher._contains_ref(ud, d, 'default')
+ bb.fetch2.git.runfetchcmd.assert_called_with(
+ "git branch --contains %s --list %s 2> /dev/null | wc -l" % (
+ ud.revisions['default'], ud.branches['default']),
+ d, quiet=True)
+
+
+ def test_supports_checksum(self):
+ self.assertFalse(self.fetcher.supports_checksum(None))
+
+
+ def test_supports_srcrev(self):
+ self.assertTrue(self.fetcher.supports_srcrev())
--
1.8.4.rc3
More information about the bitbake-devel
mailing list