| # Copyright 2020 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| """Class for managing multiple SkiaGoldSessions.""" |
| |
| import json |
| import tempfile |
| |
| |
| class SkiaGoldSessionManager(object): |
| def __init__(self, working_dir, gold_properties): |
| """Abstract class to manage one or more skia_gold_session.SkiaGoldSessions. |
| |
| A separate session is required for each instance/corpus/keys_file |
| combination, so this class will lazily create them as necessary. |
| |
| Args: |
| working_dir: The working directory under which each individual |
| SkiaGoldSessions' working directory will be created. |
| gold_properties: A SkiaGoldProperties instance that will be used to create |
| any SkiaGoldSessions. |
| """ |
| self._working_dir = working_dir |
| self._gold_properties = gold_properties |
| self._sessions = {} |
| |
| def GetSkiaGoldSession(self, |
| keys_input, |
| corpus=None, |
| instance=None, |
| bucket=None): |
| """Gets a SkiaGoldSession for the given arguments. |
| |
| Lazily creates one if necessary. |
| |
| Args: |
| keys_input: A way of retrieving various comparison config data such as |
| corpus and debug information like the hardware/software configuration |
| the image was produced on. Can be either a dict or a filepath to a |
| file containing JSON to read. |
| corpus: A string containing the corpus the session is for. If None, the |
| corpus will be determined using available information. |
| instance: The name of the Skia Gold instance to interact with. If None, |
| will use whatever default the subclass sets. |
| bucket: Overrides the formulaic Google Storage bucket name generated by |
| goldctl |
| """ |
| instance = instance or self._GetDefaultInstance() |
| keys_dict = _GetKeysAsDict(keys_input) |
| keys_string = json.dumps(keys_dict, sort_keys=True) |
| if corpus is None: |
| corpus = keys_dict.get('source_type', instance) |
| # Use the string representation of the keys JSON as a proxy for a hash since |
| # dicts themselves are not hashable. |
| session = self._sessions.setdefault(instance, |
| {}).setdefault(corpus, {}).setdefault( |
| keys_string, None) |
| if not session: |
| working_dir = tempfile.mkdtemp(dir=self._working_dir) |
| keys_file = _GetKeysAsJson(keys_input, working_dir) |
| session = self.GetSessionClass()(working_dir, self._gold_properties, |
| keys_file, corpus, instance, bucket) |
| self._sessions[instance][corpus][keys_string] = session |
| return session |
| |
| @staticmethod |
| def _GetDefaultInstance(): |
| """Gets the default Skia Gold instance. |
| |
| Returns: |
| A string containing the default instance. |
| """ |
| return 'chrome' |
| |
| @staticmethod |
| def GetSessionClass(): |
| """Gets the SkiaGoldSession class to use for session creation. |
| |
| Returns: |
| A reference to a SkiaGoldSession class. |
| """ |
| raise NotImplementedError |
| |
| |
| def _GetKeysAsDict(keys_input): |
| """Converts |keys_input| into a dictionary. |
| |
| Args: |
| keys_input: A dictionary or a string pointing to a JSON file. The contents |
| of either should be Skia Gold config data. |
| |
| Returns: |
| A dictionary containing the Skia Gold config data. |
| """ |
| if isinstance(keys_input, dict): |
| return keys_input |
| assert isinstance(keys_input, str) |
| with open(keys_input) as f: |
| return json.load(f) |
| |
| |
| def _GetKeysAsJson(keys_input, session_work_dir): |
| """Converts |keys_input| into a JSON file on disk. |
| |
| Args: |
| keys_input: A dictionary or a string pointing to a JSON file. The contents |
| of either should be Skia Gold config data. |
| |
| Returns: |
| A string containing a filepath to a JSON file with containing |keys_input|'s |
| data. |
| """ |
| if isinstance(keys_input, str): |
| return keys_input |
| assert isinstance(keys_input, dict) |
| keys_file = tempfile.NamedTemporaryFile(suffix='.json', |
| dir=session_work_dir, |
| delete=False).name |
| with open(keys_file, 'w') as f: |
| json.dump(keys_input, f) |
| return keys_file |