# -*- coding: utf-8 -*-
# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Machine Manager module."""

from __future__ import division
from __future__ import print_function

import collections
import hashlib
import math
import os.path
import re
import sys
import threading
import time

import file_lock_machine
import image_chromeos
import test_flag
from cros_utils import command_executer
from cros_utils import logger

CHECKSUM_FILE = '/usr/local/osimage_checksum_file'


class BadChecksum(Exception):
  """Raised if all machines for a label don't have the same checksum."""


class BadChecksumString(Exception):
  """Raised if all machines for a label don't have the same checksum string."""


class MissingLocksDirectory(Exception):
  """Raised when cannot find/access the machine locks directory."""


class CrosCommandError(Exception):
  """Raised when an error occurs running command on DUT."""


class CrosMachine(object):
  """The machine class."""

  def __init__(self, name, chromeos_root, log_level, cmd_exec=None):
    self.name = name
    self.image = None
    # We relate a dut with a label if we reimage the dut using label or we
    # detect at the very beginning that the dut is running this label.
    self.label = None
    self.checksum = None
    self.locked = False
    self.released_time = time.time()
    self.test_run = None
    self.chromeos_root = chromeos_root
    self.log_level = log_level
    self.cpuinfo = None
    self.machine_id = None
    self.checksum_string = None
    self.meminfo = None
    self.phys_kbytes = None
    self.cooldown_wait_time = 0
    self.ce = cmd_exec or command_executer.GetCommandExecuter(
        log_level=self.log_level)
    self.SetUpChecksumInfo()

  def SetUpChecksumInfo(self):
    if not self.IsReachable():
      self.machine_checksum = None
      return
    self._GetMemoryInfo()
    self._GetCPUInfo()
    self._ComputeMachineChecksumString()
    self._GetMachineID()
    self.machine_checksum = self._GetMD5Checksum(self.checksum_string)
    self.machine_id_checksum = self._GetMD5Checksum(self.machine_id)

  def IsReachable(self):
    command = 'ls'
    ret = self.ce.CrosRunCommand(
        command, machine=self.name, chromeos_root=self.chromeos_root)
    if ret:
      return False
    return True

  def AddCooldownWaitTime(self, wait_time):
    self.cooldown_wait_time += wait_time

  def GetCooldownWaitTime(self):
    return self.cooldown_wait_time

  def _ParseMemoryInfo(self):
    line = self.meminfo.splitlines()[0]
    usable_kbytes = int(line.split()[1])
    # This code is from src/third_party/test/files/client/bin/base_utils.py
    # usable_kbytes is system's usable DRAM in kbytes,
    #   as reported by memtotal() from device /proc/meminfo memtotal
    #   after Linux deducts 1.5% to 9.5% for system table overhead
    # Undo the unknown actual deduction by rounding up
    #   to next small multiple of a big power-of-two
    #   eg  12GB - 5.1% gets rounded back up to 12GB
    mindeduct = 0.005  # 0.5 percent
    maxdeduct = 0.095  # 9.5 percent
    # deduction range 1.5% .. 9.5% supports physical mem sizes
    #    6GB .. 12GB in steps of .5GB
    #   12GB .. 24GB in steps of 1 GB
    #   24GB .. 48GB in steps of 2 GB ...
    # Finer granularity in physical mem sizes would require
    #   tighter spread between min and max possible deductions

    # increase mem size by at least min deduction, without rounding
    min_kbytes = int(usable_kbytes / (1.0 - mindeduct))
    # increase mem size further by 2**n rounding, by 0..roundKb or more
    round_kbytes = int(usable_kbytes / (1.0 - maxdeduct)) - min_kbytes
    # find least binary roundup 2**n that covers worst-cast roundKb
    mod2n = 1 << int(math.ceil(math.log(round_kbytes, 2)))
    # have round_kbytes <= mod2n < round_kbytes*2
    # round min_kbytes up to next multiple of mod2n
    phys_kbytes = min_kbytes + mod2n - 1
    phys_kbytes -= phys_kbytes % mod2n  # clear low bits
    self.phys_kbytes = phys_kbytes

  def _GetMemoryInfo(self):
    # TODO yunlian: when the machine in rebooting, it will not return
    # meminfo, the assert does not catch it either
    command = 'cat /proc/meminfo'
    ret, self.meminfo, _ = self.ce.CrosRunCommandWOutput(
        command, machine=self.name, chromeos_root=self.chromeos_root)
    assert ret == 0, 'Could not get meminfo from machine: %s' % self.name
    if ret == 0:
      self._ParseMemoryInfo()

  def _GetCPUInfo(self):
    command = 'cat /proc/cpuinfo'
    ret, self.cpuinfo, _ = self.ce.CrosRunCommandWOutput(
        command, machine=self.name, chromeos_root=self.chromeos_root)
    assert ret == 0, 'Could not get cpuinfo from machine: %s' % self.name

  def _ComputeMachineChecksumString(self):
    self.checksum_string = ''
    # Some lines from cpuinfo have to be excluded because they are not
    # persistent across DUTs.
    # MHz, BogoMIPS are dynamically changing values.
    # core id, apicid are identifiers assigned on startup
    # and may differ on the same type of machine.
    exclude_lines_list = ['MHz', 'BogoMIPS', 'bogomips', 'core id', 'apicid']
    for line in self.cpuinfo.splitlines():
      if not any(e in line for e in exclude_lines_list):
        self.checksum_string += line
    self.checksum_string += ' ' + str(self.phys_kbytes)

  def _GetMD5Checksum(self, ss):
    if ss:
      return hashlib.md5(ss.encode('utf-8')).hexdigest()
    return ''

  def _GetMachineID(self):
    command = 'dump_vpd_log --full --stdout'
    _, if_out, _ = self.ce.CrosRunCommandWOutput(
        command, machine=self.name, chromeos_root=self.chromeos_root)
    b = if_out.splitlines()
    a = [l for l in b if 'Product' in l]
    if a:
      self.machine_id = a[0]
      return
    command = 'ifconfig'
    _, if_out, _ = self.ce.CrosRunCommandWOutput(
        command, machine=self.name, chromeos_root=self.chromeos_root)
    b = if_out.splitlines()
    a = [l for l in b if 'HWaddr' in l]
    if a:
      self.machine_id = '_'.join(a)
      return
    a = [l for l in b if 'ether' in l]
    if a:
      self.machine_id = '_'.join(a)
      return
    assert 0, 'Could not get machine_id from machine: %s' % self.name

  def __str__(self):
    l = []
    l.append(self.name)
    l.append(str(self.image))
    l.append(str(self.checksum))
    l.append(str(self.locked))
    l.append(str(self.released_time))
    return ', '.join(l)


class MachineManager(object):
  """Lock, image and unlock machines locally for benchmark runs.

  This class contains methods and calls to lock, unlock and image
  machines and distribute machines to each benchmark run.  The assumption is
  that all of the machines for the experiment have been globally locked
  in the ExperimentRunner, but the machines still need to be locally
  locked/unlocked (allocated to benchmark runs) to prevent multiple benchmark
  runs within the same experiment from trying to use the same machine at the
  same time.
  """

  def __init__(self,
               chromeos_root,
               acquire_timeout,
               log_level,
               locks_dir,
               cmd_exec=None,
               lgr=None):
    self._lock = threading.RLock()
    self._all_machines = []
    self._machines = []
    self.image_lock = threading.Lock()
    self.num_reimages = 0
    self.chromeos_root = None
    self.machine_checksum = {}
    self.machine_checksum_string = {}
    self.acquire_timeout = acquire_timeout
    self.log_level = log_level
    self.locks_dir = locks_dir
    self.ce = cmd_exec or command_executer.GetCommandExecuter(
        log_level=self.log_level)
    self.logger = lgr or logger.GetLogger()

    if self.locks_dir and not os.path.isdir(self.locks_dir):
      raise MissingLocksDirectory('Cannot access locks directory: %s' %
                                  self.locks_dir)

    self._initialized_machines = []
    self.chromeos_root = chromeos_root

  def RemoveNonLockedMachines(self, locked_machines):
    for m in self._all_machines:
      if m.name not in locked_machines:
        self._all_machines.remove(m)

    for m in self._machines:
      if m.name not in locked_machines:
        self._machines.remove(m)

  def GetChromeVersion(self, machine):
    """Get the version of Chrome running on the DUT."""

    cmd = '/opt/google/chrome/chrome --version'
    ret, version, _ = self.ce.CrosRunCommandWOutput(
        cmd, machine=machine.name, chromeos_root=self.chromeos_root)
    if ret != 0:
      raise CrosCommandError("Couldn't get Chrome version from %s." %
                             machine.name)

    if ret != 0:
      version = ''
    return version.rstrip()

  def ImageMachine(self, machine, label):
    checksum = label.checksum

    if checksum and (machine.checksum == checksum):
      return
    chromeos_root = label.chromeos_root
    if not chromeos_root:
      chromeos_root = self.chromeos_root
    image_chromeos_args = [
        image_chromeos.__file__, '--no_lock',
        '--chromeos_root=%s' % chromeos_root,
        '--image=%s' % label.chromeos_image,
        '--image_args=%s' % label.image_args,
        '--remote=%s' % machine.name,
        '--logging_level=%s' % self.log_level
    ]
    if label.board:
      image_chromeos_args.append('--board=%s' % label.board)

    # Currently can't image two machines at once.
    # So have to serialized on this lock.
    save_ce_log_level = self.ce.log_level
    if self.log_level != 'verbose':
      self.ce.log_level = 'average'

    with self.image_lock:
      if self.log_level != 'verbose':
        self.logger.LogOutput('Pushing image onto machine.')
        self.logger.LogOutput('Running image_chromeos.DoImage with %s' %
                              ' '.join(image_chromeos_args))
      retval = 0
      if not test_flag.GetTestMode():
        retval = image_chromeos.DoImage(image_chromeos_args)
      if retval:
        cmd = 'reboot && exit'
        if self.log_level != 'verbose':
          self.logger.LogOutput('reboot & exit.')
        self.ce.CrosRunCommand(
            cmd, machine=machine.name, chromeos_root=self.chromeos_root)
        time.sleep(60)
        if self.log_level != 'verbose':
          self.logger.LogOutput('Pushing image onto machine.')
          self.logger.LogOutput('Running image_chromeos.DoImage with %s' %
                                ' '.join(image_chromeos_args))
        retval = image_chromeos.DoImage(image_chromeos_args)
      if retval:
        raise RuntimeError("Could not image machine: '%s'." % machine.name)

      self.num_reimages += 1
      machine.checksum = checksum
      machine.image = label.chromeos_image
      machine.label = label

    if not label.chrome_version:
      label.chrome_version = self.GetChromeVersion(machine)

    self.ce.log_level = save_ce_log_level
    return retval

  def ComputeCommonCheckSum(self, label):
    # Since this is used for cache lookups before the machines have been
    # compared/verified, check here to make sure they all have the same
    # checksum (otherwise the cache lookup may not be valid).
    base = None
    for machine in self.GetMachines(label):
      # Make sure the machine's checksums are calculated.
      if not machine.machine_checksum:
        machine.SetUpChecksumInfo()
      # Use the first machine as the basis for comparison.
      if not base:
        base = machine
      # Make sure this machine's checksum matches our 'common' checksum.
      if base.machine_checksum != machine.machine_checksum:
        # Found a difference. Fatal error.
        # Extract non-matching part and report it.
        for mismatch_index in range(len(base.checksum_string)):
          if (mismatch_index >= len(machine.checksum_string) or
              base.checksum_string[mismatch_index] !=
              machine.checksum_string[mismatch_index]):
            break
        # We want to show some context after the mismatch.
        end_ind = mismatch_index + 8
        # Print a mismatching string.
        raise BadChecksum(
            'Machine checksums do not match!\n'
            'Diff:\n'
            f'{base.name}: {base.checksum_string[:end_ind]}\n'
            f'{machine.name}: {machine.checksum_string[:end_ind]}\n'
            '\nCheck for matching /proc/cpuinfo and /proc/meminfo on DUTs.\n')
    self.machine_checksum[label.name] = base.machine_checksum

  def ComputeCommonCheckSumString(self, label):
    # The assumption is that this function is only called AFTER
    # ComputeCommonCheckSum, so there is no need to verify the machines
    # are the same here.  If this is ever changed, this function should be
    # modified to verify that all the machines for a given label are the
    # same.
    for machine in self.GetMachines(label):
      if machine.checksum_string:
        self.machine_checksum_string[label.name] = machine.checksum_string
        break

  def _TryToLockMachine(self, cros_machine):
    with self._lock:
      assert cros_machine, "Machine can't be None"
      for m in self._machines:
        if m.name == cros_machine.name:
          return
      locked = True
      if self.locks_dir:
        locked = file_lock_machine.Machine(cros_machine.name,
                                           self.locks_dir).Lock(
                                               True, sys.argv[0])
      if locked:
        self._machines.append(cros_machine)
        command = 'cat %s' % CHECKSUM_FILE
        ret, out, _ = self.ce.CrosRunCommandWOutput(
            command,
            chromeos_root=self.chromeos_root,
            machine=cros_machine.name)
        if ret == 0:
          cros_machine.checksum = out.strip()
      elif self.locks_dir:
        self.logger.LogOutput("Couldn't lock: %s" % cros_machine.name)

  # This is called from single threaded mode.
  def AddMachine(self, machine_name):
    with self._lock:
      for m in self._all_machines:
        assert m.name != machine_name, 'Tried to double-add %s' % machine_name

      if self.log_level != 'verbose':
        self.logger.LogOutput('Setting up remote access to %s' % machine_name)
        self.logger.LogOutput('Checking machine characteristics for %s' %
                              machine_name)
      cm = CrosMachine(machine_name, self.chromeos_root, self.log_level)
      if cm.machine_checksum:
        self._all_machines.append(cm)

  def RemoveMachine(self, machine_name):
    with self._lock:
      self._machines = [m for m in self._machines if m.name != machine_name]
      if self.locks_dir:
        res = file_lock_machine.Machine(machine_name,
                                        self.locks_dir).Unlock(True)
        if not res:
          self.logger.LogError("Could not unlock machine: '%s'." % machine_name)

  def ForceSameImageToAllMachines(self, label):
    machines = self.GetMachines(label)
    for m in machines:
      self.ImageMachine(m, label)
      m.SetUpChecksumInfo()

  def AcquireMachine(self, label):
    image_checksum = label.checksum
    machines = self.GetMachines(label)
    check_interval_time = 120
    with self._lock:
      # Lazily external lock machines
      while self.acquire_timeout >= 0:
        for m in machines:
          new_machine = m not in self._all_machines
          self._TryToLockMachine(m)
          if new_machine:
            m.released_time = time.time()
        if self.GetAvailableMachines(label):
          break
        sleep_time = max(1, min(self.acquire_timeout, check_interval_time))
        time.sleep(sleep_time)
        self.acquire_timeout -= sleep_time

      if self.acquire_timeout < 0:
        self.logger.LogFatal('Could not acquire any of the '
                             "following machines: '%s'" %
                             ', '.join(machine.name for machine in machines))


###      for m in self._machines:
###        if (m.locked and time.time() - m.released_time < 10 and
###            m.checksum == image_checksum):
###          return None
      unlocked_machines = [
          machine for machine in self.GetAvailableMachines(label)
          if not machine.locked
      ]
      for m in unlocked_machines:
        if image_checksum and m.checksum == image_checksum:
          m.locked = True
          m.test_run = threading.current_thread()
          return m
      for m in unlocked_machines:
        if not m.checksum:
          m.locked = True
          m.test_run = threading.current_thread()
          return m
      # This logic ensures that threads waiting on a machine will get a machine
      # with a checksum equal to their image over other threads. This saves time
      # when crosperf initially assigns the machines to threads by minimizing
      # the number of re-images.
      # TODO(asharif): If we centralize the thread-scheduler, we wont need this
      # code and can implement minimal reimaging code more cleanly.
      for m in unlocked_machines:
        if time.time() - m.released_time > 15:
          # The release time gap is too large, so it is probably in the start
          # stage, we need to reset the released_time.
          m.released_time = time.time()
        elif time.time() - m.released_time > 8:
          m.locked = True
          m.test_run = threading.current_thread()
          return m
    return None

  def GetAvailableMachines(self, label=None):
    if not label:
      return self._machines
    return [m for m in self._machines if m.name in label.remote]

  def GetMachines(self, label=None):
    if not label:
      return self._all_machines
    return [m for m in self._all_machines if m.name in label.remote]

  def ReleaseMachine(self, machine):
    with self._lock:
      for m in self._machines:
        if machine.name == m.name:
          assert m.locked, 'Tried to double-release %s' % m.name
          m.released_time = time.time()
          m.locked = False
          m.status = 'Available'
          break

  def Cleanup(self):
    with self._lock:
      # Unlock all machines (via file lock)
      for m in self._machines:
        res = file_lock_machine.Machine(m.name, self.locks_dir).Unlock(True)

        if not res:
          self.logger.LogError("Could not unlock machine: '%s'." % m.name)

  def __str__(self):
    with self._lock:
      l = ['MachineManager Status:'] + [str(m) for m in self._machines]
      return '\n'.join(l)

  def AsString(self):
    with self._lock:
      stringify_fmt = '%-30s %-10s %-4s %-25s %-32s'
      header = stringify_fmt % ('Machine', 'Thread', 'Lock', 'Status',
                                'Checksum')
      table = [header]
      for m in self._machines:
        if m.test_run:
          test_name = m.test_run.name
          test_status = m.test_run.timeline.GetLastEvent()
        else:
          test_name = ''
          test_status = ''

        try:
          machine_string = stringify_fmt % (m.name, test_name, m.locked,
                                            test_status, m.checksum)
        except ValueError:
          machine_string = ''
        table.append(machine_string)
      return 'Machine Status:\n%s' % '\n'.join(table)

  def GetAllCPUInfo(self, labels):
    """Get cpuinfo for labels, merge them if their cpuinfo are the same."""
    dic = collections.defaultdict(list)
    for label in labels:
      for machine in self._all_machines:
        if machine.name in label.remote:
          dic[machine.cpuinfo].append(label.name)
          break
    output_segs = []
    for key, v in dic.items():
      output = ' '.join(v)
      output += '\n-------------------\n'
      output += key
      output += '\n\n\n'
      output_segs.append(output)
    return ''.join(output_segs)

  def GetAllMachines(self):
    return self._all_machines


class MockCrosMachine(CrosMachine):
  """Mock cros machine class."""
  # pylint: disable=super-init-not-called

  MEMINFO_STRING = """MemTotal:        3990332 kB
MemFree:         2608396 kB
Buffers:          147168 kB
Cached:           811560 kB
SwapCached:            0 kB
Active:           503480 kB
Inactive:         628572 kB
Active(anon):     174532 kB
Inactive(anon):    88576 kB
Active(file):     328948 kB
Inactive(file):   539996 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:       5845212 kB
SwapFree:        5845212 kB
Dirty:              9384 kB
Writeback:             0 kB
AnonPages:        173408 kB
Mapped:           146268 kB
Shmem:             89676 kB
Slab:             188260 kB
SReclaimable:     169208 kB
SUnreclaim:        19052 kB
KernelStack:        2032 kB
PageTables:         7120 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     7840376 kB
Committed_AS:    1082032 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      364980 kB
VmallocChunk:   34359369407 kB
DirectMap4k:       45824 kB
DirectMap2M:     4096000 kB
"""

  CPUINFO_STRING = """processor: 0
vendor_id: GenuineIntel
cpu family: 6
model: 42
model name: Intel(R) Celeron(R) CPU 867 @ 1.30GHz
stepping: 7
microcode: 0x25
cpu MHz: 1300.000
cache size: 2048 KB
physical id: 0
siblings: 2
core id: 0
cpu cores: 2
apicid: 0
initial apicid: 0
fpu: yes
fpu_exception: yes
cpuid level: 13
wp: yes
flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer xsave lahf_lm arat epb xsaveopt pln pts dts tpr_shadow vnmi flexpriority ept vpid
bogomips: 2594.17
clflush size: 64
cache_alignment: 64
address sizes: 36 bits physical, 48 bits virtual
power management:

processor: 1
vendor_id: GenuineIntel
cpu family: 6
model: 42
model name: Intel(R) Celeron(R) CPU 867 @ 1.30GHz
stepping: 7
microcode: 0x25
cpu MHz: 1300.000
cache size: 2048 KB
physical id: 0
siblings: 2
core id: 1
cpu cores: 2
apicid: 2
initial apicid: 2
fpu: yes
fpu_exception: yes
cpuid level: 13
wp: yes
flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer xsave lahf_lm arat epb xsaveopt pln pts dts tpr_shadow vnmi flexpriority ept vpid
bogomips: 2594.17
clflush size: 64
cache_alignment: 64
address sizes: 36 bits physical, 48 bits virtual
power management:
"""

  def __init__(self, name, chromeos_root, log_level):
    self.name = name
    self.image = None
    self.checksum = None
    self.locked = False
    self.released_time = time.time()
    self.test_run = None
    self.chromeos_root = chromeos_root
    self.checksum_string = re.sub(r'\d', '', name)
    # In test, we assume "lumpy1", "lumpy2" are the same machine.
    self.machine_checksum = self._GetMD5Checksum(self.checksum_string)
    self.log_level = log_level
    self.label = None
    self.cooldown_wait_time = 0
    self.ce = command_executer.GetCommandExecuter(log_level=self.log_level)
    self._GetCPUInfo()

  def IsReachable(self):
    return True

  def _GetMemoryInfo(self):
    self.meminfo = self.MEMINFO_STRING
    self._ParseMemoryInfo()

  def _GetCPUInfo(self):
    self.cpuinfo = self.CPUINFO_STRING


class MockMachineManager(MachineManager):
  """Mock machine manager class."""

  def __init__(self, chromeos_root, acquire_timeout, log_level, locks_dir):
    super(MockMachineManager, self).__init__(chromeos_root, acquire_timeout,
                                             log_level, locks_dir)

  def _TryToLockMachine(self, cros_machine):
    self._machines.append(cros_machine)
    cros_machine.checksum = ''

  def AddMachine(self, machine_name):
    with self._lock:
      for m in self._all_machines:
        assert m.name != machine_name, 'Tried to double-add %s' % machine_name
      cm = MockCrosMachine(machine_name, self.chromeos_root, self.log_level)
      assert cm.machine_checksum, ('Could not find checksum for machine %s' %
                                   machine_name)
      # In Original MachineManager, the test is 'if cm.machine_checksum:' - if a
      # machine is unreachable, then its machine_checksum is None. Here we
      # cannot do this, because machine_checksum is always faked, so we directly
      # test cm.IsReachable, which is properly mocked.
      if cm.IsReachable():
        self._all_machines.append(cm)

  def GetChromeVersion(self, machine):
    return 'Mock Chrome Version R50'

  def AcquireMachine(self, label):
    for machine in self._all_machines:
      if not machine.locked:
        machine.locked = True
        return machine
    return None

  def ImageMachine(self, machine, label):
    if machine or label:
      return 0
    return 1

  def ReleaseMachine(self, machine):
    machine.locked = False

  def GetMachines(self, label=None):
    return self._all_machines

  def GetAvailableMachines(self, label=None):
    return self._all_machines

  def ForceSameImageToAllMachines(self, label=None):
    return 0

  def ComputeCommonCheckSum(self, label=None):
    common_checksum = 12345
    for machine in self.GetMachines(label):
      machine.machine_checksum = common_checksum
    self.machine_checksum[label.name] = common_checksum

  def GetAllMachines(self):
    return self._all_machines
