1a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)# Copyright 2013 The Chromium Authors. All rights reserved.
2a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
3a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)# found in the LICENSE file.
4a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci"""Request Handler to allow test mask updates."""
6a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
7a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)import webapp2
8a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)import re
9a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)import sys
10a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)import os
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
12a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)from common import constants
13a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)from common import image_tools
14a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)from common import ispy_utils
15a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
16a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)import gs_bucket
17a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
18a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
19a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)class UpdateMaskHandler(webapp2.RequestHandler):
20a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  """Request handler to allow test mask updates."""
21a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
22a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  def post(self):
23a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    """Accepts post requests.
24a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
25a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    This method will accept a post request containing device, site and
26a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    device_id parameters. This method takes the diff of the run
27a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    indicated by it's parameters and adds it to the mask of the run's
28a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    test. It will then delete the run it is applied to and redirect
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    to the device list view.
30a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    """
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    test_run = self.request.get('test_run')
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    expectation = self.request.get('expectation')
33a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
34a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    # Short-circuit if a parameter is missing.
35a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if not (test_run and expectation):
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      self.response.headers['Content-Type'] = 'json/application'
37a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      self.response.write(json.dumps(
38a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          {'error': '\'test_run\' and \'expectation\' must be '
39a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                    'supplied to update a mask.'}))
40a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      return
41a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    # Otherwise, set up the utilities.
42a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    self.bucket = gs_bucket.GoogleCloudStorageBucket(constants.BUCKET)
43a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    self.ispy = ispy_utils.ISpyUtils(self.bucket)
44a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    # Short-circuit if the failure does not exist.
45a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if not self.ispy.FailureExists(test_run, expectation):
46a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      self.response.headers['Content-Type'] = 'json/application'
47a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      self.response.write(json.dumps(
48a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        {'error': 'Could not update mask because failure does not exist.'}))
49a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      return
50a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    # Get the failure namedtuple (which also computes the diff).
51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    failure = self.ispy.GetFailure(test_run, expectation)
52a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    # Upload the new mask in place of the original.
53a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    self.ispy.UpdateImage(
54a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        ispy_utils.GetExpectationPath(expectation, 'mask.png'),
55a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        image_tools.ConvertDiffToMask(failure.diff))
56a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    # Now that there is no diff for the two images, remove the failure.
57a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    self.ispy.RemoveFailure(test_run, expectation)
58a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    # Redirect back to the sites list for the test run.
59a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    self.redirect('/?test_run=%s' % test_run)
60a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)