1# -*- coding: utf-8 -*-
2# Copyright 2019 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Module to get the settings from experiment file."""
7
8from __future__ import print_function
9
10from cros_utils import logger
11from cros_utils import misc
12from download_images import ImageDownloader
13
14
15class Settings(object):
16  """Class representing settings (a set of fields) from an experiment file."""
17
18  def __init__(self, name, settings_type):
19    self.name = name
20    self.settings_type = settings_type
21    self.fields = {}
22    self.parent = None
23
24  def SetParentSettings(self, settings):
25    """Set the parent settings which these settings can inherit from."""
26    self.parent = settings
27
28  def AddField(self, field):
29    name = field.name
30    if name in self.fields:
31      raise SyntaxError('Field %s defined previously.' % name)
32    self.fields[name] = field
33
34  def SetField(self, name, value, append=False):
35    if name not in self.fields:
36      raise SyntaxError("'%s' is not a valid field in '%s' settings" %
37                        (name, self.settings_type))
38    if append:
39      self.fields[name].Append(value)
40    else:
41      self.fields[name].Set(value)
42
43  def GetField(self, name):
44    """Get the value of a field with a given name."""
45    if name not in self.fields:
46      raise SyntaxError(
47          "Field '%s' not a valid field in '%s' settings." % (name, self.name))
48    field = self.fields[name]
49    if not field.assigned and field.required:
50      raise SyntaxError("Required field '%s' not defined in '%s' settings." %
51                        (name, self.name))
52    return self.fields[name].Get()
53
54  def Inherit(self):
55    """Inherit any unset values from the parent settings."""
56    for name in self.fields:
57      if (not self.fields[name].assigned and self.parent and
58          name in self.parent.fields and self.parent.fields[name].assigned):
59        self.fields[name].Set(self.parent.GetField(name), parse=False)
60
61  def Override(self, settings):
62    """Override settings with settings from a different object."""
63    for name in settings.fields:
64      if name in self.fields and settings.fields[name].assigned:
65        self.fields[name].Set(settings.GetField(name), parse=False)
66
67  def Validate(self):
68    """Check that all required fields have been set."""
69    for name in self.fields:
70      if not self.fields[name].assigned and self.fields[name].required:
71        raise SyntaxError('Field %s is invalid.' % name)
72
73  def GetXbuddyPath(self, path_str, autotest_path, debug_path, board,
74                    chromeos_root, log_level, download_debug):
75    prefix = 'remote'
76    l = logger.GetLogger()
77    if (path_str.find('trybot') < 0 and path_str.find('toolchain') < 0 and
78        path_str.find(board) < 0 and path_str.find(board.replace('_', '-'))):
79      xbuddy_path = '%s/%s/%s' % (prefix, board, path_str)
80    else:
81      xbuddy_path = '%s/%s' % (prefix, path_str)
82    image_downloader = ImageDownloader(l, log_level)
83    # Returns three variables: image, autotest_path, debug_path
84    return image_downloader.Run(
85        misc.CanonicalizePath(chromeos_root), xbuddy_path, autotest_path,
86        debug_path, download_debug)
87