• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2021 The Chromium Authors
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4"""Shared helper functions for r/w of variations seed in local state."""
5
6import json
7import logging
8import os
9
10_THIS_DIR = os.path.dirname(os.path.abspath(__file__))
11_SRC_DIR = os.path.join(_THIS_DIR, os.path.pardir, os.path.pardir)
12
13# Constants around the Local State file and variation keys.
14_LOCAL_STATE_FILE_NAME = 'Local State'
15LOCAL_STATE_SEED_NAME = 'variations_compressed_seed'
16LOCAL_STATE_SEED_SIGNATURE_NAME = 'variations_seed_signature'
17
18
19def load_test_seed_from_file(hardcoded_seed_path):
20  """Reads and parses the test variations seed.
21
22  There are 2 types of seeds used by this smoke test:
23  1. A provided seed under test, and when the test is running with this seed,
24     it's running as a TRY job and is triggered by the finch_smoke_test recipe
25     to test the Finch GCL config changes. The interface between the recipe and
26     this test is a json file named variations_seed located at the root of
27     the checkout.
28  2. A hard-coded seed, and when the test is running with this seed, it's
29     running on CI continuously to prevent regressions to this test itself.
30
31  The function tries to use provided seed first. If the provided seed doesn't
32  exist, the function will fallback to a hard-coded seed as input arg.
33
34  Args:
35    seed_json_path (str): Path to provided hard-coded seed.
36
37  Returns:
38    A tuple of two strings: the compressed seed and the seed signature.
39  """
40  # Provided seed path.
41  path_seed = get_test_seed_file_path(hardcoded_seed_path)
42
43  logging.info('Parsing test seed from "%s"', path_seed)
44
45  with open(path_seed, 'r') as f:
46    seed_json = json.load(f)
47
48  return (seed_json.get(LOCAL_STATE_SEED_NAME, None),
49          seed_json.get(LOCAL_STATE_SEED_SIGNATURE_NAME, None))
50
51
52def get_test_seed_file_path(hardcoded_seed_path):
53  """Gets the file path to the test seed.
54
55  There are 2 types of seeds used by this smoke test:
56  1. A provided seed under test, and when the test is running with this seed,
57     it's running as a TRY job and is triggered by the finch_smoke_test recipe
58     to test the Finch GCL config changes. The interface between the recipe and
59     this test is a json file named variations_seed located at the root of
60     the checkout.
61  2. A hard-coded seed, and when the test is running with this seed, it's
62     running on CI continuously to prevent regressions to this test itself.
63
64  The function tries to use provided seed first. If the provided seed doesn't
65  exist, the function will fallback to a hard-coded seed as input arg.
66
67  Args:
68    hardcoded_seed_path (str): Path to provided hard-coded seed.
69  Returns:
70    A path to the location of the seed.
71  """
72  path_seed = os.path.abspath(os.path.join(_SRC_DIR, 'variations_seed'))
73
74  if not os.path.isfile(path_seed):
75    path_seed = hardcoded_seed_path
76
77  return path_seed
78
79
80def get_current_seed(user_data_dir):
81  """Gets the current seed.
82
83  Args:
84    user_data_dir (str): Path to the user data directory used to launch Chrome.
85
86  Returns:
87    A tuple of two strings: the compressed seed and the seed signature.
88  """
89  with open(os.path.join(user_data_dir, _LOCAL_STATE_FILE_NAME)) as f:
90    local_state = json.load(f)
91
92  return local_state.get(LOCAL_STATE_SEED_NAME,
93                         None), local_state.get(LOCAL_STATE_SEED_SIGNATURE_NAME,
94                                                None)
95
96
97def update_local_state(user_data_dir, update_dict):
98  """Updates local state file under user data dir with given dict.
99
100  Args:
101    user_data_dir (str): Path to the user data directory used to launch Chrome.
102    update_dict (dict): A dict used to update current local state file.
103  """
104  with open(os.path.join(user_data_dir, _LOCAL_STATE_FILE_NAME)) as f:
105    local_state = json.load(f)
106
107  local_state.update(update_dict)
108
109  with open(os.path.join(user_data_dir, _LOCAL_STATE_FILE_NAME), 'w') as f:
110    json.dump(local_state, f)
111
112
113def inject_test_seed(seed, signature, user_data_dir):
114  """Injects the given test seed.
115
116  Args:
117    seed (str): A variations seed.
118    signature (str): A seed signature.
119    user_data_dir (str): Path to the user data directory used to launch Chrome.
120
121  Returns:
122    bool: Whether the injection succeeded.
123  """
124  seed_dict = {
125      LOCAL_STATE_SEED_NAME: seed,
126      LOCAL_STATE_SEED_SIGNATURE_NAME: signature,
127  }
128  update_local_state(user_data_dir, seed_dict)
129  current_seed, current_signature = get_current_seed(user_data_dir)
130  if current_seed != seed or current_signature != signature:
131    return False
132  return True
133