From a192dab1e2ebd873f817d8cebf0fff6a2a11cc90 Mon Sep 17 00:00:00 2001 From: Filip Valder Date: Mon, 27 Mar 2017 15:09:58 +0200 Subject: [PATCH] return Unprocessable Entity in case of a commit hash which is not found within the repository --- module_build_service/scm.py | 14 +++++++++++-- tests/test_scm.py | 6 +++--- tests/test_views/test_views.py | 38 +++++++++++++++++++++++++++++----- 3 files changed, 48 insertions(+), 10 deletions(-) diff --git a/module_build_service/scm.py b/module_build_service/scm.py index 9964256c..652cb838 100644 --- a/module_build_service/scm.py +++ b/module_build_service/scm.py @@ -37,7 +37,7 @@ import shutil import datetime from module_build_service import log -from module_build_service.errors import Forbidden, ValidationError +from module_build_service.errors import Forbidden, ValidationError, UnprocessableEntity import module_build_service.utils @@ -157,7 +157,17 @@ class SCM(object): # perform checkouts SCM._run(module_clone_cmd, chdir=scmdir) if self.commit: - SCM._run(module_checkout_cmd, chdir=sourcedir) + try: + SCM._run(module_checkout_cmd, chdir=sourcedir) + except RuntimeError as e: + if (e.message.endswith( + " did not match any file(s) known to git.\\n\"") or + "fatal: reference is not a tree: " in e.message): + raise UnprocessableEntity( + "checkout: The requested commit hash was not found " + "within the repository. Perhaps you forgot to push. " + "The original message was: %s" % e.message) + raise timestamp = SCM._run(["git", "show" , "-s", "--format=%ct"], chdir=sourcedir)[1] dt = datetime.datetime.utcfromtimestamp(int(timestamp)) diff --git a/tests/test_scm.py b/tests/test_scm.py index 4b5edc59..afced120 100644 --- a/tests/test_scm.py +++ b/tests/test_scm.py @@ -28,7 +28,7 @@ import unittest from nose.tools import raises import module_build_service.scm -from module_build_service.errors import ValidationError +from module_build_service.errors import ValidationError, UnprocessableEntity repo_path = 'file://' + os.path.dirname(__file__) + "/scm_data/testrepo" @@ -83,7 +83,7 @@ class TestSCMModule(unittest.TestCase): sourcedir = scm.checkout(self.tempdir) scm.verify(sourcedir) - @raises(RuntimeError) + @raises(UnprocessableEntity) def test_verify_unknown_branch(self): scm = module_build_service.scm.SCM(repo_path, "unknown") sourcedir = scm.checkout(self.tempdir) @@ -102,7 +102,7 @@ class TestSCMModule(unittest.TestCase): sourcedir = scm.checkout(self.tempdir) scm.verify(sourcedir) - @raises(RuntimeError) + @raises(UnprocessableEntity) def test_verify_unknown_hash(self): target = '7035bd33614972ac66559ac1fdd019ff6027ad22' scm = module_build_service.scm.SCM(repo_path + "?#" + target, "master") diff --git a/tests/test_views/test_views.py b/tests/test_views/test_views.py index dc55d0b7..173864a7 100644 --- a/tests/test_views/test_views.py +++ b/tests/test_views/test_views.py @@ -24,16 +24,18 @@ import unittest import json import time import vcr + +import modulemd as _modulemd +import module_build_service.scm + from mock import patch, Mock, PropertyMock from shutil import copyfile from os import path, mkdir from os.path import dirname -import modulemd as _modulemd - from tests import app, init_data +from module_build_service.errors import UnprocessableEntity from module_build_service.models import ComponentBuild, ModuleBuild -import module_build_service.scm from module_build_service import conf @@ -43,8 +45,9 @@ anonymous_user = ('anonymous', set(['packager'])) base_dir = dirname(dirname(__file__)) cassette_dir = base_dir + '/vcr-request-data/' + class MockedSCM(object): - def __init__(self, mocked_scm, name, mmd_filenames, commit=None): + def __init__(self, mocked_scm, name, mmd_filenames, commit=None, checkout_raise=False): """ Adds default testing checkout, get_latest and name methods to mocked_scm SCM class. @@ -61,7 +64,15 @@ class MockedSCM(object): self.mmd_filenames = mmd_filenames self.checkout_id = 0 - self.mocked_scm.return_value.checkout = self.checkout + if checkout_raise: + self.mocked_scm.return_value.checkout.side_effect = \ + UnprocessableEntity( + "checkout: The requested commit hash was not found within " + "the repository. Perhaps you forgot to push. The original " + "message was: ") + else: + self.mocked_scm.return_value.checkout = self.checkout + self.mocked_scm.return_value.name = self.name self.mocked_scm.return_value.commit = self.commit self.mocked_scm.return_value.get_latest = self.get_latest @@ -711,3 +722,20 @@ class TestViews(unittest.TestCase): r3 = self.client.patch(url, data=json.dumps({'state': 'failed', 'owner': 'foo'})) self.assertEquals(r3.status_code, 400) self.assertIn("The request contains 'owner' parameter", json.loads(r3.data)['message']) + + @patch('module_build_service.auth.get_user', return_value=user) + @patch('module_build_service.scm.SCM') + def test_submit_build_commit_hash_not_found(self, mocked_scm, mocked_get_user): + MockedSCM(mocked_scm, 'testmodule', 'testmodule.yaml', + '7035bd33614972ac66559ac1fdd019ff6027ad22', checkout_raise=True) + + rv = self.client.post('/module-build-service/1/module-builds/', data=json.dumps( + {'branch': 'master', 'scmurl': 'git://pkgs.stg.fedoraproject.org/modules/' + 'testmodule.git?#7035bd33614972ac66559ac1fdd019ff6027ad22'})) + data = json.loads(rv.data) + self.assertIn("The requested commit hash was not found within the repository.", + data['message']) + self.assertIn("Perhaps you forgot to push. The original message was: ", + data['message']) + self.assertEquals(data['status'], 422) + self.assertEquals(data['error'], 'Unprocessable Entity')