[Launchpad-reviewers] [Merge] lp:~maxiberta/launchpad/lp-1729580 into lp:launchpad

2018-02-19 Thread noreply
The proposal to merge lp:~maxiberta/launchpad/lp-1729580 into lp:launchpad has 
been updated.

Status: Needs review => Merged

For more details, see:
https://code.launchpad.net/~maxiberta/launchpad/lp-1729580/+merge/337825
-- 
Your team Launchpad code reviewers is subscribed to branch lp:launchpad.

___
Mailing list: https://launchpad.net/~launchpad-reviewers
Post to : launchpad-reviewers@lists.launchpad.net
Unsubscribe : https://launchpad.net/~launchpad-reviewers
More help   : https://help.launchpad.net/ListHelp


Re: [Launchpad-reviewers] [Merge] lp:~maxiberta/launchpad/lp-1729580 into lp:launchpad

2018-02-19 Thread Maximiliano Bertacchini


Diff comments:

> === modified file 'lib/lp/snappy/browser/tests/test_snapbuild.py'
> --- lib/lp/snappy/browser/tests/test_snapbuild.py 2017-10-20 13:35:42 
> +
> +++ lib/lp/snappy/browser/tests/test_snapbuild.py 2018-02-16 21:53:15 
> +
> @@ -130,6 +130,38 @@
>  text=re.compile(
>  r"^\s*Store upload failed:\s+Scan failed.\s*$"
>  
> +def test_store_upload_status_failed_with_extended_error_message(self):
> +build = self.factory.makeSnapBuild(status=BuildStatus.FULLYBUILT)
> +job = getUtility(ISnapStoreUploadJobSource).create(build)
> +naked_job = removeSecurityProxy(job)
> +naked_job.job._status = JobStatus.FAILED
> +naked_job.error_message = "This should not be shown."
> +naked_job.error_messages = [
> +{"message": "Scan failed.", "link": "link1"},
> +{"message": "Classic not allowed.", "link": "link2"}]
> +build_view = create_initialized_view(build, "+index")
> +built_view = build_view()
> +self.assertThat(built_view, Not(soupmatchers.HTMLContains(
> +soupmatchers.Tag(
> +"store upload status", "li",
> +attrs={"id": "store-upload-status"},
> +text=re.compile('.*This should not be shown.*')
> +self.assertThat(built_view, soupmatchers.HTMLContains(
> +soupmatchers.Within(
> +soupmatchers.Tag(
> +"store upload status", "li",
> +attrs={"id": "store-upload-status"}),
> +soupmatchers.Within(
> +soupmatchers.Tag(
> +"store upload error messages", "ul",
> +attrs={"id": "store-upload-error-messages"}),
> +soupmatchers.Within(
> +soupmatchers.Tag(
> +"store upload error message", "li"),
> +soupmatchers.Tag(
> +"store upload error link", "a",
> +text="What does this mean?"))

Done.

> +
>  def test_store_upload_status_release_failed(self):
>  build = self.factory.makeSnapBuild(status=BuildStatus.FULLYBUILT)
>  job = getUtility(ISnapStoreUploadJobSource).create(build)
> 
> === modified file 'lib/lp/snappy/model/snapstoreclient.py'
> --- lib/lp/snappy/model/snapstoreclient.py2017-06-14 10:25:23 +
> +++ lib/lp/snappy/model/snapstoreclient.py2018-02-16 21:53:15 +
> @@ -316,7 +316,11 @@
>  elif "errors" in response_data:
>  error_message = "\n".join(
>  error["message"] for error in response_data["errors"])
> -raise ScanFailedResponse(error_message)
> +error_messages = [
> +{"message": error["message"], "link": error.get("link")}
> +for error in response_data["errors"]]

Good idea, done.

> +raise ScanFailedResponse(
> +error_message, messages=error_messages)
>  elif not response_data["can_release"]:
>  return response_data["url"], None
>  else:
> 
> === modified file 'lib/lp/snappy/templates/snapbuild-index.pt'
> --- lib/lp/snappy/templates/snapbuild-index.pt2017-04-03 12:35:03 
> +
> +++ lib/lp/snappy/templates/snapbuild-index.pt2018-02-16 21:53:15 
> +
> @@ -177,7 +177,15 @@
>condition="context/store_upload_status/enumvalue:FAILEDTOUPLOAD">
>Store upload failed:
> -  
> +   +condition="not: context/store_upload_error_messages"
> +replace="context/store_upload_error_message" />
> +  
> +
> +  
> +  What does this mean?

Nice!

> +
> +  
>
>  
>


-- 
https://code.launchpad.net/~maxiberta/launchpad/lp-1729580/+merge/337825
Your team Launchpad code reviewers is subscribed to branch lp:launchpad.

___
Mailing list: https://launchpad.net/~launchpad-reviewers
Post to : launchpad-reviewers@lists.launchpad.net
Unsubscribe : https://launchpad.net/~launchpad-reviewers
More help   : https://help.launchpad.net/ListHelp


Re: [Launchpad-reviewers] [Merge] lp:~maxiberta/launchpad/lp-1729580 into lp:launchpad

2018-02-19 Thread Colin Watson
Review: Approve



Diff comments:

> === modified file 'lib/lp/snappy/browser/tests/test_snapbuild.py'
> --- lib/lp/snappy/browser/tests/test_snapbuild.py 2017-10-20 13:35:42 
> +
> +++ lib/lp/snappy/browser/tests/test_snapbuild.py 2018-02-16 21:53:15 
> +
> @@ -14,7 +14,7 @@
>  from pymacaroons import Macaroon
>  import soupmatchers
>  from storm.locals import Store
> -from testtools.matchers import StartsWith
> +from testtools.matchers import Not, StartsWith

LP style is to always write this like this, even if it would fit on a single 
line:

from testtools.matchers import (
Not,
StartsWith,
)

>  import transaction
>  from zope.component import getUtility
>  from zope.security.interfaces import Unauthorized
> @@ -130,6 +130,38 @@
>  text=re.compile(
>  r"^\s*Store upload failed:\s+Scan failed.\s*$"
>  
> +def test_store_upload_status_failed_with_extended_error_message(self):
> +build = self.factory.makeSnapBuild(status=BuildStatus.FULLYBUILT)
> +job = getUtility(ISnapStoreUploadJobSource).create(build)
> +naked_job = removeSecurityProxy(job)
> +naked_job.job._status = JobStatus.FAILED
> +naked_job.error_message = "This should not be shown."
> +naked_job.error_messages = [
> +{"message": "Scan failed.", "link": "link1"},
> +{"message": "Classic not allowed.", "link": "link2"}]
> +build_view = create_initialized_view(build, "+index")
> +built_view = build_view()
> +self.assertThat(built_view, Not(soupmatchers.HTMLContains(
> +soupmatchers.Tag(
> +"store upload status", "li",
> +attrs={"id": "store-upload-status"},
> +text=re.compile('.*This should not be shown.*')
> +self.assertThat(built_view, soupmatchers.HTMLContains(
> +soupmatchers.Within(
> +soupmatchers.Tag(
> +"store upload status", "li",
> +attrs={"id": "store-upload-status"}),
> +soupmatchers.Within(
> +soupmatchers.Tag(
> +"store upload error messages", "ul",
> +attrs={"id": "store-upload-error-messages"}),
> +soupmatchers.Within(
> +soupmatchers.Tag(
> +"store upload error message", "li"),
> +soupmatchers.Tag(
> +"store upload error link", "a",
> +text="What does this mean?"))

Could you test the href attribute here too?

> +
>  def test_store_upload_status_release_failed(self):
>  build = self.factory.makeSnapBuild(status=BuildStatus.FULLYBUILT)
>  job = getUtility(ISnapStoreUploadJobSource).create(build)
> 
> === modified file 'lib/lp/snappy/model/snapstoreclient.py'
> --- lib/lp/snappy/model/snapstoreclient.py2017-06-14 10:25:23 +
> +++ lib/lp/snappy/model/snapstoreclient.py2018-02-16 21:53:15 +
> @@ -316,7 +316,11 @@
>  elif "errors" in response_data:
>  error_message = "\n".join(
>  error["message"] for error in response_data["errors"])
> -raise ScanFailedResponse(error_message)
> +error_messages = [
> +{"message": error["message"], "link": error.get("link")}
> +for error in response_data["errors"]]

Pedantically, if link is absent from the original error, should it perhaps be 
absent from the corresponding element of error_messages too?

> +raise ScanFailedResponse(
> +error_message, messages=error_messages)
>  elif not response_data["can_release"]:
>  return response_data["url"], None
>  else:
> 
> === modified file 'lib/lp/snappy/templates/snapbuild-index.pt'
> --- lib/lp/snappy/templates/snapbuild-index.pt2017-04-03 12:35:03 
> +
> +++ lib/lp/snappy/templates/snapbuild-index.pt2018-02-16 21:53:15 
> +
> @@ -177,7 +177,15 @@
>condition="context/store_upload_status/enumvalue:FAILEDTOUPLOAD">
>Store upload failed:
> -  
> +   +condition="not: context/store_upload_error_messages"
> +replace="context/store_upload_error_message" />
> +  
> +
> +  
> +  What does this mean?

Could you render this using widget_help_link instead?  It'd look a bit nicer 
that way (in general, but especially in the case where the error message 
doesn't end with a full stop).

> +
> +  
>
>  
>
> 
> === modified file 'lib/lp/snappy/tests/test_snapbuildjob.py'
> --- lib/lp/snappy/tests/test_snapbuildjob.py  2017-06-29 18:06:03 +
> +++ lib/lp/snappy/tests/test_snapbuildjob.py  

[Launchpad-reviewers] [Merge] lp:~maxiberta/launchpad/lp-1729580 into lp:launchpad

2018-02-15 Thread Maximiliano Bertacchini
Maximiliano Bertacchini has proposed merging lp:~maxiberta/launchpad/lp-1729580 
into lp:launchpad.

Commit message:
Expose extended error messages (with external link) for snap build jobs (LP: 
#1729580).

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~maxiberta/launchpad/lp-1729580/+merge/337825

Expose extended error messages (with external link) for snap build jobs (LP: 
#1729580).
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of 
lp:~maxiberta/launchpad/lp-1729580 into lp:launchpad.
=== modified file 'lib/lp/snappy/interfaces/snapbuild.py'
--- lib/lp/snappy/interfaces/snapbuild.py	2017-04-27 16:22:37 +
+++ lib/lp/snappy/interfaces/snapbuild.py	2018-02-15 22:12:44 +
@@ -40,6 +40,7 @@
 Choice,
 Datetime,
 Int,
+Text,
 TextLine,
 )
 
@@ -213,6 +214,15 @@
 "this snap build to the store."),
 required=False, readonly=True))
 
+store_upload_error_messages = exported(Text(
+title=_("Store upload error messages"),
+description=_(
+"A list of dict(message, link) where message is an error "
+"description and link, if any, is an external link to extra "
+"details, from the last attempt to upload this snap build "
+"to the store."),
+required=False, readonly=True))
+
 def getFiles():
 """Retrieve the build's `ISnapFile` records.
 

=== modified file 'lib/lp/snappy/interfaces/snapstoreclient.py'
--- lib/lp/snappy/interfaces/snapstoreclient.py	2017-06-14 10:25:23 +
+++ lib/lp/snappy/interfaces/snapstoreclient.py	2018-02-15 22:12:44 +
@@ -29,10 +29,12 @@
 
 class SnapStoreError(Exception):
 
-def __init__(self, message="", detail=None, can_retry=False):
+def __init__(
+self, message="", detail=None, messages=None, can_retry=False):
 super(SnapStoreError, self).__init__(message)
 self.message = message
 self.detail = detail
+self.messages = messages
 self.can_retry = can_retry
 
 

=== modified file 'lib/lp/snappy/model/snapbuild.py'
--- lib/lp/snappy/model/snapbuild.py	2018-01-23 10:59:44 +
+++ lib/lp/snappy/model/snapbuild.py	2018-02-15 22:12:44 +
@@ -456,6 +456,11 @@
 job = self.last_store_upload_job
 return job and job.error_message
 
+@property
+def store_upload_error_messages(self):
+job = self.last_store_upload_job
+return job and job.error_messages
+
 def scheduleStoreUpload(self):
 """See `ISnapBuild`."""
 if not self.snap.can_upload_to_store:

=== modified file 'lib/lp/snappy/model/snapbuildjob.py'
--- lib/lp/snappy/model/snapbuildjob.py	2017-06-29 16:58:01 +
+++ lib/lp/snappy/model/snapbuildjob.py	2018-02-15 22:12:44 +
@@ -232,6 +232,16 @@
 self.metadata["error_detail"] = detail
 
 @property
+def error_messages(self):
+"""See `ISnapStoreUploadJob`."""
+return self.metadata.get("error_messages")
+
+@error_messages.setter
+def error_messages(self, messages):
+"""See `ISnapStoreUploadJob`."""
+self.metadata["error_messages"] = messages
+
+@property
 def store_url(self):
 """See `ISnapStoreUploadJob`."""
 return self.metadata.get("store_url")
@@ -326,6 +336,7 @@
 self.attempt_count <= self.max_retries):
 raise RetryableSnapStoreError(e.message, detail=e.detail)
 self.error_message = str(e)
+self.error_messages = getattr(e, "messages", None)
 self.error_detail = getattr(e, "detail", None)
 if isinstance(e, UnauthorizedUploadResponse):
 mailer = SnapBuildMailer.forUnauthorizedUpload(self.snapbuild)

=== modified file 'lib/lp/snappy/model/snapstoreclient.py'
--- lib/lp/snappy/model/snapstoreclient.py	2017-06-14 10:25:23 +
+++ lib/lp/snappy/model/snapstoreclient.py	2018-02-15 22:12:44 +
@@ -316,7 +316,11 @@
 elif "errors" in response_data:
 error_message = "\n".join(
 error["message"] for error in response_data["errors"])
-raise ScanFailedResponse(error_message)
+error_messages = [
+{"message": error["message"], "link": error.get("link")}
+for error in response_data["errors"]]
+raise ScanFailedResponse(
+error_message, messages=error_messages)
 elif not response_data["can_release"]:
 return response_data["url"], None
 else:

=== modified file 'lib/lp/snappy/tests/test_snapbuildjob.py'
--- lib/lp/snappy/tests/test_snapbuildjob.py	2017-06-29 18:06:03 +
+++ lib/lp/snappy/tests/test_snapbuildjob.py	2018-02-15 22:12:44 +
@@ -31,7 +31,7 @@
 )
 from lp.snappy.interfaces.snapstoreclient import (
 BadRefreshResponse,
-BadScanStatusResponse,
+