1#!/usr/bin/env vpython3 2# Copyright 2020 The Chromium Authors 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5"""Tests for gold_utils.""" 6 7#pylint: disable=protected-access 8 9import contextlib 10import os 11import tempfile 12import unittest 13 14from pylib.constants import host_paths 15from pylib.utils import gold_utils 16 17with host_paths.SysPath(host_paths.BUILD_PATH): 18 from skia_gold_common import unittest_utils 19 20import mock # pylint: disable=import-error 21from pyfakefs import fake_filesystem_unittest # pylint: disable=import-error 22 23createSkiaGoldArgs = unittest_utils.createSkiaGoldArgs 24 25 26def assertArgWith(test, arg_list, arg, value): 27 i = arg_list.index(arg) 28 test.assertEqual(arg_list[i + 1], value) 29 30 31class AndroidSkiaGoldSessionDiffTest(fake_filesystem_unittest.TestCase): 32 def setUp(self): 33 self.setUpPyfakefs() 34 self._working_dir = tempfile.mkdtemp() 35 self._json_keys = tempfile.NamedTemporaryFile(delete=False).name 36 37 @mock.patch.object(gold_utils.AndroidSkiaGoldSession, '_RunCmdForRcAndOutput') 38 def test_commandCommonArgs(self, cmd_mock): 39 cmd_mock.return_value = (None, None) 40 args = createSkiaGoldArgs(git_revision='a', local_pixel_tests=False) 41 sgp = gold_utils.AndroidSkiaGoldProperties(args) 42 session = gold_utils.AndroidSkiaGoldSession(self._working_dir, 43 sgp, 44 self._json_keys, 45 'corpus', 46 instance='instance') 47 session.Diff('name', 'png_file', None) 48 call_args = cmd_mock.call_args[0][0] 49 self.assertIn('diff', call_args) 50 assertArgWith(self, call_args, '--corpus', 'corpus') 51 # TODO(skbug.com/10610): Remove the -public once we go back to using the 52 # non-public instance, or add a second test for testing that the correct 53 # instance is chosen if we decide to support both depending on what the 54 # user is authenticated for. 55 assertArgWith(self, call_args, '--instance', 'instance-public') 56 assertArgWith(self, call_args, '--input', 'png_file') 57 assertArgWith(self, call_args, '--test', 'name') 58 # TODO(skbug.com/10611): Re-add this assert and remove the check for the 59 # absence of the directory once we switch back to using the proper working 60 # directory. 61 # assertArgWith(self, call_args, '--work-dir', self._working_dir) 62 self.assertNotIn(self._working_dir, call_args) 63 i = call_args.index('--out-dir') 64 # The output directory should be a subdirectory of the working directory. 65 self.assertIn(self._working_dir, call_args[i + 1]) 66 67 68class AndroidSkiaGoldSessionDiffLinksTest(fake_filesystem_unittest.TestCase): 69 class FakeArchivedFile: 70 def __init__(self, path): 71 self.name = path 72 73 def Link(self): 74 return 'file://' + self.name 75 76 class FakeOutputManager: 77 def __init__(self): 78 self.output_dir = tempfile.mkdtemp() 79 80 @contextlib.contextmanager 81 def ArchivedTempfile(self, image_name, _, __): 82 filepath = os.path.join(self.output_dir, image_name) 83 yield AndroidSkiaGoldSessionDiffLinksTest.FakeArchivedFile(filepath) 84 85 def setUp(self): 86 self.setUpPyfakefs() 87 self._working_dir = tempfile.mkdtemp() 88 self._json_keys = tempfile.NamedTemporaryFile(delete=False).name 89 self._timestamp_patcher = mock.patch.object(gold_utils, '_GetTimestamp') 90 self._timestamp_mock = self._timestamp_patcher.start() 91 self.addCleanup(self._timestamp_patcher.stop) 92 93 def test_outputManagerUsed(self): 94 self._timestamp_mock.return_value = 'ts0' 95 args = createSkiaGoldArgs(git_revision='a', local_pixel_tests=True) 96 sgp = gold_utils.AndroidSkiaGoldProperties(args) 97 session = gold_utils.AndroidSkiaGoldSession(self._working_dir, sgp, 98 self._json_keys, None, None) 99 with open(os.path.join(self._working_dir, 'input-inputhash.png'), 'w') as f: 100 f.write('input') 101 with open(os.path.join(self._working_dir, 'closest-closesthash.png'), 102 'w') as f: 103 f.write('closest') 104 with open(os.path.join(self._working_dir, 'diff.png'), 'w') as f: 105 f.write('diff') 106 107 output_manager = AndroidSkiaGoldSessionDiffLinksTest.FakeOutputManager() 108 session._StoreDiffLinks('foo', output_manager, self._working_dir) 109 110 copied_input = os.path.join(output_manager.output_dir, 'given_foo_ts0.png') 111 copied_closest = os.path.join(output_manager.output_dir, 112 'closest_foo_ts0.png') 113 copied_diff = os.path.join(output_manager.output_dir, 'diff_foo_ts0.png') 114 with open(copied_input) as f: 115 self.assertEqual(f.read(), 'input') 116 with open(copied_closest) as f: 117 self.assertEqual(f.read(), 'closest') 118 with open(copied_diff) as f: 119 self.assertEqual(f.read(), 'diff') 120 121 self.assertEqual(session.GetGivenImageLink('foo'), 'file://' + copied_input) 122 self.assertEqual(session.GetClosestImageLink('foo'), 123 'file://' + copied_closest) 124 self.assertEqual(session.GetDiffImageLink('foo'), 'file://' + copied_diff) 125 126 def test_diffLinksDoNotClobber(self): 127 """Tests that multiple calls to store links does not clobber files.""" 128 129 def side_effect(): 130 side_effect.count += 1 131 return f'ts{side_effect.count}' 132 133 side_effect.count = -1 134 self._timestamp_mock.side_effect = side_effect 135 136 args = createSkiaGoldArgs(git_revision='a', local_pixel_tests=True) 137 sgp = gold_utils.AndroidSkiaGoldProperties(args) 138 session = gold_utils.AndroidSkiaGoldSession(self._working_dir, sgp, 139 self._json_keys, None, None) 140 with open(os.path.join(self._working_dir, 'input-inputhash.png'), 'w') as f: 141 f.write('first input') 142 with open(os.path.join(self._working_dir, 'closest-closesthash.png'), 143 'w') as f: 144 f.write('first closest') 145 with open(os.path.join(self._working_dir, 'diff.png'), 'w') as f: 146 f.write('first diff') 147 148 output_manager = AndroidSkiaGoldSessionDiffLinksTest.FakeOutputManager() 149 session._StoreDiffLinks('foo', output_manager, self._working_dir) 150 151 # Store links normally once. 152 first_copied_input = os.path.join(output_manager.output_dir, 153 'given_foo_ts0.png') 154 first_copied_closest = os.path.join(output_manager.output_dir, 155 'closest_foo_ts0.png') 156 first_copied_diff = os.path.join(output_manager.output_dir, 157 'diff_foo_ts0.png') 158 with open(first_copied_input) as f: 159 self.assertEqual(f.read(), 'first input') 160 with open(first_copied_closest) as f: 161 self.assertEqual(f.read(), 'first closest') 162 with open(first_copied_diff) as f: 163 self.assertEqual(f.read(), 'first diff') 164 165 with open(os.path.join(self._working_dir, 'input-inputhash.png'), 'w') as f: 166 f.write('second input') 167 with open(os.path.join(self._working_dir, 'closest-closesthash.png'), 168 'w') as f: 169 f.write('second closest') 170 with open(os.path.join(self._working_dir, 'diff.png'), 'w') as f: 171 f.write('second diff') 172 173 self.assertEqual(session.GetGivenImageLink('foo'), 174 'file://' + first_copied_input) 175 self.assertEqual(session.GetClosestImageLink('foo'), 176 'file://' + first_copied_closest) 177 self.assertEqual(session.GetDiffImageLink('foo'), 178 'file://' + first_copied_diff) 179 180 # Store links again and check that the new data is surfaced. 181 session._StoreDiffLinks('foo', output_manager, self._working_dir) 182 183 second_copied_input = os.path.join(output_manager.output_dir, 184 'given_foo_ts1.png') 185 second_copied_closest = os.path.join(output_manager.output_dir, 186 'closest_foo_ts1.png') 187 second_copied_diff = os.path.join(output_manager.output_dir, 188 'diff_foo_ts1.png') 189 with open(second_copied_input) as f: 190 self.assertEqual(f.read(), 'second input') 191 with open(second_copied_closest) as f: 192 self.assertEqual(f.read(), 'second closest') 193 with open(second_copied_diff) as f: 194 self.assertEqual(f.read(), 'second diff') 195 196 self.assertEqual(session.GetGivenImageLink('foo'), 197 'file://' + second_copied_input) 198 self.assertEqual(session.GetClosestImageLink('foo'), 199 'file://' + second_copied_closest) 200 self.assertEqual(session.GetDiffImageLink('foo'), 201 'file://' + second_copied_diff) 202 203 # Check to make sure the first images still exist on disk and are unchanged. 204 with open(first_copied_input) as f: 205 self.assertEqual(f.read(), 'first input') 206 with open(first_copied_closest) as f: 207 self.assertEqual(f.read(), 'first closest') 208 with open(first_copied_diff) as f: 209 self.assertEqual(f.read(), 'first diff') 210 211 212if __name__ == '__main__': 213 unittest.main(verbosity=2) 214