#!/usr/bin/python
#
# Copyright (c) 2012 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.

"""Unit tests for server/cros/dynamic_suite/host_spec.py."""

import mox
import unittest

from autotest_lib.server.cros.dynamic_suite import host_spec
from autotest_lib.server.cros.dynamic_suite.fakes import FakeHost


class HostSpecTest(mox.MoxTestBase):
    """Unit tests for dynamic_suite.host_spec module.

    @var _BOARD: fake board to reimage
    """


    _BOARD = 'board'
    _SPECS = [host_spec.HostSpec([_BOARD]),
              host_spec.HostSpec([_BOARD, 'pool:bvt']),
              host_spec.HostSpec([_BOARD], ['label1'])]


    def testOrderSpecsByComplexity(self):
        """Should return new host spec list with simpler entries later."""
        reordered = host_spec.order_by_complexity(self._SPECS)

        for spec in self._SPECS[1:]:
            self.assertTrue(spec in reordered[:-1])
        self.assertEquals(self._SPECS[0], reordered[-1])


    def testSpecSubsets(self):
        """Validate HostSpec subset checks."""
        self.assertTrue(self._SPECS[0].is_subset(self._SPECS[1]))
        self.assertTrue(self._SPECS[0].is_subset(self._SPECS[2]))
        self.assertFalse(self._SPECS[1].is_subset(self._SPECS[2]))
        self.assertFalse(self._SPECS[2].is_subset(self._SPECS[1]))
        self.assertFalse(self._SPECS[1].is_subset(self._SPECS[0]))
        self.assertFalse(self._SPECS[2].is_subset(self._SPECS[0]))


    def testTrivialSpec(self):
        """Validate that HostSpecs are correctly marked as trivial."""
        self.assertTrue(self._SPECS[0].is_trivial)
        self.assertTrue(self._SPECS[1].is_trivial)
        self.assertFalse(self._SPECS[2].is_trivial)


class HostGroupTest(mox.MoxTestBase):
    """Unit tests for dynamic_suite.host_spec.HostGroup derived classes.
    """


    def testCanConstructExplicit(self):
        """Should be able to make an ExplicitHostGroup."""
        host_list = [FakeHost('h1'), FakeHost('h2'), FakeHost('h3')]
        hosts_per_spec = {host_spec.HostSpec(['l1']): host_list[:1],
                          host_spec.HostSpec(['l2']): host_list[1:]}
        group = host_spec.ExplicitHostGroup(hosts_per_spec)
        for host in host_list:
            self.assertTrue(host.hostname in group.as_args()['hosts'])


    def testExplicitEnforcesHostUniqueness(self):
        """Should fail to make ExplicitHostGroup with duplicate hosts."""
        host_list = [FakeHost('h1'), FakeHost('h2'), FakeHost('h3')]
        hosts_per_spec = {host_spec.HostSpec(['l1']): host_list[:1],
                          host_spec.HostSpec(['l2']): host_list}
        self.assertRaises(ValueError,
                          host_spec.ExplicitHostGroup, hosts_per_spec)


    def testCanConstructByMetahostsWithDependencies(self):
        """Should be able to make a HostGroup from labels."""
        labels = ['meta_host', 'dep1', 'dep2']
        num = 3
        group = host_spec.MetaHostGroup(labels, num)
        args = group.as_args()
        self.assertEquals(labels[:1] * num, args['meta_hosts'])
        self.assertEquals(labels[1:], args['dependencies'])


    def testExplicitCanTrackSuccess(self):
        """Track success/failure in an ExplicitHostGroup."""
        host_list = [FakeHost('h1'), FakeHost('h2'), FakeHost('h3')]
        specs = [host_spec.HostSpec(['l1']), host_spec.HostSpec(['l2'])]
        hosts_per_spec = {specs[0]: host_list[:1], specs[1]: host_list[1:]}
        group = host_spec.ExplicitHostGroup(hosts_per_spec)

        # Reimage just the one host that satisfies specs[0].
        group.mark_host_success(host_list[0].hostname)
        self.assertTrue(group.enough_hosts_succeeded())
        self.assertTrue(specs[1] in group.doomed_specs)

        # Reimage some host that satisfies specs[1].
        group.mark_host_success(host_list[2].hostname)
        self.assertTrue(group.enough_hosts_succeeded())
        self.assertFalse(group.doomed_specs)


    def testExplicitCanTrackSuccessWithSupersets(self):
        """Track success/failure in an ExplicitHostGroup with supersets."""
        host_list = [FakeHost('h1'), FakeHost('h2'), FakeHost('h3')]
        specs = [host_spec.HostSpec(['l1']),
                 host_spec.HostSpec(['l2']),
                 host_spec.HostSpec(['l2', 'l1'])]
        hosts_per_spec = {specs[0]: host_list[:1],
                          specs[1]: host_list[1:2],
                          specs[2]: host_list[2:]}
        group = host_spec.ExplicitHostGroup(hosts_per_spec)

        # Reimage just the one host that satisfies specs[2].
        # Because satisfying specs[2] statisfies all the specs, we should have
        # no doomed specs.
        group.mark_host_success(host_list[2].hostname)
        self.assertTrue(group.enough_hosts_succeeded())
        self.assertFalse(group.doomed_specs)


    def testExplicitCanTrackUnsatisfiedSpecs(self):
        """Track unsatisfiable HostSpecs in ExplicitHostGroup."""
        group = host_spec.ExplicitHostGroup()
        satisfiable_spec = host_spec.HostSpec(['l2'])
        unsatisfiable_spec = host_spec.HostSpec(['l1'], ['e1'])
        group.add_host_for_spec(unsatisfiable_spec, None)
        group.add_host_for_spec(satisfiable_spec, FakeHost('h1'))
        self.assertTrue(unsatisfiable_spec in group.unsatisfied_specs)
        self.assertTrue(satisfiable_spec not in group.unsatisfied_specs)


    def testExplicitOneHostEnoughToSatisfySpecs(self):
        """One host is enough to satisfy a HostSpec in ExplicitHostGroup."""
        satisfiable_spec = host_spec.HostSpec(['l1'])
        group = host_spec.ExplicitHostGroup()
        group.add_host_for_spec(satisfiable_spec, FakeHost('h1'))
        group.add_host_for_spec(satisfiable_spec, None)
        self.assertTrue(satisfiable_spec not in group.unsatisfied_specs)

        group = host_spec.ExplicitHostGroup()
        group.add_host_for_spec(satisfiable_spec, None)
        group.add_host_for_spec(satisfiable_spec, FakeHost('h1'))
        self.assertTrue(satisfiable_spec not in group.unsatisfied_specs)


    def testExplicitSubsetSpecSatisfiedIfAnyAre(self):
        """Ensures that any satisfied spec also satisfies a subset HostSpec."""
        specs = [host_spec.HostSpec(['l1'], ['l3']),
                 host_spec.HostSpec(['l1'], ['l3', 'l4']),
                 host_spec.HostSpec(['l1'], ['l5', 'l4']),
                 host_spec.HostSpec(['l1'], ['l2', 'l3', 'l4'])]
        group = host_spec.ExplicitHostGroup()
        group.add_host_for_spec(specs[0], None)
        group.add_host_for_spec(specs[1], FakeHost('h1'))
        group.add_host_for_spec(specs[2], FakeHost('h2'))
        group.add_host_for_spec(specs[3], None)

        self.assertTrue(specs[0] not in group.unsatisfied_specs)
        self.assertTrue(specs[1] not in group.unsatisfied_specs)
        self.assertTrue(specs[2] not in group.unsatisfied_specs)
        self.assertTrue(specs[3] in group.unsatisfied_specs)


    def testMetaCanTrackSuccess(self):
        """Track success/failure in a MetaHostGroup."""
        labels = ['meta_host', 'dep1', 'dep2']
        num = 3
        group = host_spec.MetaHostGroup(labels, num)

        self.assertFalse(group.enough_hosts_succeeded())

        group.mark_host_success('h1')
        self.assertTrue(group.enough_hosts_succeeded())
