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)