#!/usr/bin/python
#

# Copyright (C) 2012, 2013 Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


"""Script for testing qa.qa_config"""

import unittest
import tempfile
import shutil
import os
import operator

from ganeti import utils
from ganeti import serializer
from ganeti import constants
from ganeti import compat

from qa import qa_config
from qa import qa_error

import testutils


class TestTestEnabled(unittest.TestCase):
  def testSimple(self):
    for name in ["test", ["foobar"], ["a", "b"]]:
      self.assertTrue(qa_config.TestEnabled(name, _cfg={}))

    for default in [False, True]:
      self.assertFalse(qa_config.TestEnabled("foo", _cfg={
        "tests": {
          "default": default,
          "foo": False,
          },
        }))

      self.assertTrue(qa_config.TestEnabled("bar", _cfg={
        "tests": {
          "default": default,
          "bar": True,
          },
        }))

  def testEitherWithDefault(self):
    names = qa_config.Either("one")

    self.assertTrue(qa_config.TestEnabled(names, _cfg={
      "tests": {
        "default": True,
        },
      }))

    self.assertFalse(qa_config.TestEnabled(names, _cfg={
      "tests": {
        "default": False,
        },
      }))

  def testEither(self):
    names = [qa_config.Either(["one", "two"]),
             qa_config.Either("foo"),
             "hello",
             ["bar", "baz"]]

    self.assertTrue(qa_config.TestEnabled(names, _cfg={
      "tests": {
        "default": True,
        },
      }))

    self.assertFalse(qa_config.TestEnabled(names, _cfg={
      "tests": {
        "default": False,
        },
      }))

    for name in ["foo", "bar", "baz", "hello"]:
      self.assertFalse(qa_config.TestEnabled(names, _cfg={
        "tests": {
          "default": True,
          name: False,
          },
        }))

    self.assertFalse(qa_config.TestEnabled(names, _cfg={
      "tests": {
        "default": True,
        "one": False,
        "two": False,
        },
      }))

    self.assertTrue(qa_config.TestEnabled(names, _cfg={
      "tests": {
        "default": True,
        "one": False,
        "two": True,
        },
      }))

    self.assertFalse(qa_config.TestEnabled(names, _cfg={
      "tests": {
        "default": True,
        "one": True,
        "two": True,
        "foo": False,
        },
      }))

  def testEitherNestedWithAnd(self):
    names = qa_config.Either([["one", "two"], "foo"])

    self.assertTrue(qa_config.TestEnabled(names, _cfg={
      "tests": {
        "default": True,
        },
      }))

    for name in ["one", "two"]:
      self.assertFalse(qa_config.TestEnabled(names, _cfg={
        "tests": {
          "default": True,
          "foo": False,
          name: False,
          },
        }))

  def testCallable(self):
    self.assertTrue(qa_config.TestEnabled([lambda: True], _cfg={}))

    for value in [None, False, "", 0]:
      self.assertFalse(qa_config.TestEnabled(lambda: value, _cfg={}))


class TestQaConfigLoad(unittest.TestCase):
  def setUp(self):
    self.tmpdir = tempfile.mkdtemp()

  def tearDown(self):
    shutil.rmtree(self.tmpdir)

  def testLoadNonExistent(self):
    filename = utils.PathJoin(self.tmpdir, "does.not.exist")
    self.assertRaises(EnvironmentError, qa_config._QaConfig.Load, filename)

  @staticmethod
  def _WriteConfig(filename, data):
    utils.WriteFile(filename, data=serializer.DumpJson(data))

  def _CheckLoadError(self, filename, data, expected):
    self._WriteConfig(filename, data)

    try:
      qa_config._QaConfig.Load(filename)
    except qa_error.Error, err:
      self.assertTrue(str(err).startswith(expected))
    else:
      self.fail("Exception was not raised")

  def testFailsValidation(self):
    filename = utils.PathJoin(self.tmpdir, "qa.json")
    testconfig = {}

    check_fn = compat.partial(self._CheckLoadError, filename, testconfig)

    # No cluster name
    check_fn("Cluster name is required")

    testconfig["name"] = "cluster.example.com"

    # No nodes
    check_fn("Need at least one node")

    testconfig["nodes"] = [
      {
        "primary": "xen-test-0",
        "secondary": "192.0.2.1",
        },
      ]

    # No instances
    check_fn("Need at least one instance")

    testconfig["instances"] = [
      {
        "name": "xen-test-inst1",
        },
      ]

    # Missing "disk" and "disk-growth"
    check_fn("Config option 'disks'")

    testconfig["disks"] = []

    # Minimal accepted configuration
    self._WriteConfig(filename, testconfig)
    result = qa_config._QaConfig.Load(filename)
    self.assertTrue(result.get("nodes"))

    # Non-existent instance check script
    testconfig[qa_config._INSTANCE_CHECK_KEY] = \
      utils.PathJoin(self.tmpdir, "instcheck")
    check_fn("Can't find instance check script")
    del testconfig[qa_config._INSTANCE_CHECK_KEY]

    # No enabled hypervisor
    testconfig[qa_config._ENABLED_HV_KEY] = None
    check_fn("No hypervisor is enabled")

    # Unknown hypervisor
    testconfig[qa_config._ENABLED_HV_KEY] = ["#unknownhv#"]
    check_fn("Unknown hypervisor(s) enabled:")
    del testconfig[qa_config._ENABLED_HV_KEY]

    # Invalid path for virtual cluster base directory
    testconfig[qa_config._VCLUSTER_MASTER_KEY] = "value"
    testconfig[qa_config._VCLUSTER_BASEDIR_KEY] = "./not//normalized/"
    check_fn("Path given in option 'vcluster-basedir' must be")

    # Inconsistent virtual cluster settings
    testconfig.pop(qa_config._VCLUSTER_MASTER_KEY)
    testconfig[qa_config._VCLUSTER_BASEDIR_KEY] = "/tmp"
    check_fn("All or none of the")

    testconfig[qa_config._VCLUSTER_MASTER_KEY] = "master.example.com"
    testconfig.pop(qa_config._VCLUSTER_BASEDIR_KEY)
    check_fn("All or none of the")

    # Accepted virtual cluster settings
    testconfig[qa_config._VCLUSTER_MASTER_KEY] = "master.example.com"
    testconfig[qa_config._VCLUSTER_BASEDIR_KEY] = "/tmp"

    self._WriteConfig(filename, testconfig)
    result = qa_config._QaConfig.Load(filename)
    self.assertEqual(result.GetVclusterSettings(),
                     ("master.example.com", "/tmp"))


class TestQaConfigWithSampleConfig(unittest.TestCase):
  """Tests using C{qa-sample.json}.

  This test case serves two purposes:

    - Ensure shipped C{qa-sample.json} file is considered a valid QA
      configuration
    - Test some functions of L{qa_config._QaConfig} without having to
      mock a whole configuration file

  """
  def setUp(self):
    filename = "%s/qa/qa-sample.json" % testutils.GetSourceDir()

    self.config = qa_config._QaConfig.Load(filename)

  def testGetEnabledHypervisors(self):
    self.assertEqual(self.config.GetEnabledHypervisors(),
                     [constants.DEFAULT_ENABLED_HYPERVISOR])

  def testGetDefaultHypervisor(self):
    self.assertEqual(self.config.GetDefaultHypervisor(),
                     constants.DEFAULT_ENABLED_HYPERVISOR)

  def testGetInstanceCheckScript(self):
    self.assertTrue(self.config.GetInstanceCheckScript() is None)

  def testGetAndGetItem(self):
    self.assertEqual(self.config["nodes"], self.config.get("nodes"))

  def testGetMasterNode(self):
    self.assertEqual(self.config.GetMasterNode(), self.config["nodes"][0])

  def testGetVclusterSettings(self):
    # Shipped default settings should be to not use a virtual cluster
    self.assertEqual(self.config.GetVclusterSettings(), (None, None))

    self.assertFalse(qa_config.UseVirtualCluster(_cfg=self.config))


class TestQaConfig(unittest.TestCase):
  def setUp(self):
    filename = \
      testutils.TestDataFilename("qa-minimal-nodes-instances-only.json")

    self.config = qa_config._QaConfig.Load(filename)

  def testExclusiveStorage(self):
    self.assertRaises(AssertionError, self.config.GetExclusiveStorage)

    for value in [False, True, 0, 1, 30804, ""]:
      self.config.SetExclusiveStorage(value)
      self.assertEqual(self.config.GetExclusiveStorage(), bool(value))

  def testIsTemplateSupported(self):
    enabled_dts = self.config.GetEnabledDiskTemplates()
    for e_s in [False, True]:
      self.config.SetExclusiveStorage(e_s)
      for template in constants.DISK_TEMPLATES:
        if (template not in enabled_dts or
            e_s and template not in constants.DTS_EXCL_STORAGE):
          self.assertFalse(self.config.IsTemplateSupported(template))
        else:
          self.assertTrue(self.config.IsTemplateSupported(template))

  def testInstanceConversion(self):
    self.assertTrue(isinstance(self.config["instances"][0],
                               qa_config._QaInstance))

  def testNodeConversion(self):
    self.assertTrue(isinstance(self.config["nodes"][0],
                               qa_config._QaNode))

  def testAcquireAndReleaseInstance(self):
    self.assertFalse(compat.any(map(operator.attrgetter("used"),
                                    self.config["instances"])))

    inst = qa_config.AcquireInstance(_cfg=self.config)
    self.assertTrue(inst.used)
    self.assertTrue(inst.disk_template is None)

    inst.Release()

    self.assertFalse(inst.used)
    self.assertTrue(inst.disk_template is None)

    self.assertFalse(compat.any(map(operator.attrgetter("used"),
                                    self.config["instances"])))

  def testAcquireInstanceTooMany(self):
    # Acquire all instances
    for _ in range(len(self.config["instances"])):
      inst = qa_config.AcquireInstance(_cfg=self.config)
      self.assertTrue(inst.used)
      self.assertTrue(inst.disk_template is None)

    # The next acquisition must fail
    self.assertRaises(qa_error.OutOfInstancesError,
                      qa_config.AcquireInstance, _cfg=self.config)

  def testAcquireNodeNoneAdded(self):
    self.assertFalse(compat.any(map(operator.attrgetter("added"),
                                    self.config["nodes"])))

    # First call must return master node
    node = qa_config.AcquireNode(_cfg=self.config)
    self.assertEqual(node, self.config.GetMasterNode())

    # Next call with exclusion list fails
    self.assertRaises(qa_error.OutOfNodesError, qa_config.AcquireNode,
                      exclude=[node], _cfg=self.config)

  def testAcquireNodeTooMany(self):
    # Mark all nodes as marked (master excluded)
    for node in self.config["nodes"]:
      if node != self.config.GetMasterNode():
        node.MarkAdded()

    nodecount = len(self.config["nodes"])

    self.assertTrue(nodecount > 1)

    acquired = []

    for _ in range(nodecount):
      node = qa_config.AcquireNode(exclude=acquired, _cfg=self.config)
      if node == self.config.GetMasterNode():
        self.assertFalse(node.added)
      else:
        self.assertTrue(node.added)
      self.assertEqual(node.use_count, 1)
      acquired.append(node)

    self.assertRaises(qa_error.OutOfNodesError, qa_config.AcquireNode,
                      exclude=acquired, _cfg=self.config)

  def testAcquireNodeOrder(self):
    # Mark all nodes as marked (master excluded)
    for node in self.config["nodes"]:
      if node != self.config.GetMasterNode():
        node.MarkAdded()

    nodecount = len(self.config["nodes"])

    for iterations in [0, 1, 3, 100, 127, 7964]:
      acquired = []

      for i in range(iterations):
        node = qa_config.AcquireNode(_cfg=self.config)
        self.assertTrue(node.use_count > 0)
        self.assertEqual(node.use_count, (i / nodecount + 1))
        acquired.append((node.use_count, node.primary, node))

      # Check if returned nodes were in correct order
      key_fn = lambda (a, b, c): (a, utils.NiceSortKey(b), c)
      self.assertEqual(acquired, sorted(acquired, key=key_fn))

      # Release previously acquired nodes
      qa_config.ReleaseManyNodes(map(operator.itemgetter(2), acquired))

      # Check if nodes were actually released
      for node in self.config["nodes"]:
        self.assertEqual(node.use_count, 0)
        self.assertTrue(node.added or node == self.config.GetMasterNode())


class TestRepresentation(unittest.TestCase):
  def _Check(self, target, part):
    self.assertTrue(part in repr(target).split())

  def testQaInstance(self):
    inst = qa_config._QaInstance("inst1.example.com", [])
    self._Check(inst, "name=inst1.example.com")
    self._Check(inst, "nicmac=[]")

    # Default values
    self._Check(inst, "disk_template=None")
    self._Check(inst, "used=None")

    # Use instance
    inst.Use()
    self._Check(inst, "used=True")

    # Disk template
    inst.SetDiskTemplate(constants.DT_DRBD8)
    self._Check(inst, "disk_template=%s" % constants.DT_DRBD8)

    # Release instance
    inst.Release()
    self._Check(inst, "used=False")
    self._Check(inst, "disk_template=None")

  def testQaNode(self):
    node = qa_config._QaNode("primary.example.com", "192.0.2.1")
    self._Check(node, "primary=primary.example.com")
    self._Check(node, "secondary=192.0.2.1")
    self._Check(node, "added=False")
    self._Check(node, "use_count=0")

    # Mark as added
    node.MarkAdded()
    self._Check(node, "added=True")

    # Use node
    for i in range(1, 5):
      node.Use()
      self._Check(node, "use_count=%s" % i)

    # Release node
    for i in reversed(range(1, 5)):
      node.Release()
      self._Check(node, "use_count=%s" % (i - 1))

    self._Check(node, "use_count=0")

    # Mark as added
    node.MarkRemoved()
    self._Check(node, "added=False")


if __name__ == "__main__":
  testutils.GanetiTestProgram()
