#!/usr/bin/python
#

# Copyright (C) 2009 Google Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.


"""Script for unittesting the confd client module"""


import socket
import unittest

from ganeti import confd
from ganeti import constants
from ganeti import errors

import ganeti.confd.client

import testutils


class ResettableMock(object):
  def __init__(self, *args, **kwargs):
    self.Reset()

  def Reset(self):
    pass


class MockLogger(ResettableMock):
  def Reset(self):
    self.debug_count = 0
    self.warn_count = 0
    self.error_count = 0

  def debug(string):
    self.debug_count += 1

  def warning(string):
    self.warn_count += 1

  def error(string):
    self.error_count += 1

class MockConfdAsyncUDPClient(ResettableMock):
  def Reset(self):
    self.send_count = 0
    self.last_address = ''
    self.last_port = -1
    self.last_sent = ''

  def enqueue_send(self, address, port, payload):
    self.send_count += 1
    self.last_payload = payload
    self.last_port = port
    self.last_address = address

class MockCallback(ResettableMock):
  def Reset(self):
    self.call_count = 0
    self.last_up = None

  def __call__(self, up):
    """Callback

    @type up: L{ConfdUpcallPayload}
    @param up: upper callback

    """
    self.call_count += 1
    self.last_up = up


class MockTime(ResettableMock):
  def Reset(self):
    self.mytime  = 1254213006.5175071

  def time(self):
    return self.mytime

  def increase(self, delta):
    self.mytime += delta


class _BaseClientTest:
  """Base class for client tests"""
  mc_list = None
  new_peers = None
  family = None

  def setUp(self):
    self.mock_time = MockTime()
    confd.client.time = self.mock_time
    confd.client.ConfdAsyncUDPClient = MockConfdAsyncUDPClient
    self.logger = MockLogger()
    hmac_key = "mykeydata"
    self.callback = MockCallback()
    self.client = confd.client.ConfdClient(hmac_key, self.mc_list,
                                           self.callback, logger=self.logger)

  def testRequest(self):
    req1 = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING)
    req2 = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING)
    self.assertNotEqual(req1.rsalt, req2.rsalt)
    self.assertEqual(req1.protocol, constants.CONFD_PROTOCOL_VERSION)
    self.assertEqual(req2.protocol, constants.CONFD_PROTOCOL_VERSION)
    self.assertRaises(errors.ConfdClientError, confd.client.ConfdClientRequest,
                      type=-33)

  def testClientSend(self):
    req = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING)
    self.client.SendRequest(req)
    # Cannot send the same request twice
    self.assertRaises(errors.ConfdClientError, self.client.SendRequest, req)
    req2 = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING)
    # Coverage is too big
    self.assertRaises(errors.ConfdClientError, self.client.SendRequest,
                      req2, coverage=15)
    self.assertEquals(self.client._socket.send_count,
                      constants.CONFD_DEFAULT_REQ_COVERAGE)
    # Send with max coverage
    self.client.SendRequest(req2, coverage=-1)
    self.assertEquals(self.client._socket.send_count,
                      constants.CONFD_DEFAULT_REQ_COVERAGE + len(self.mc_list))
    self.assert_(self.client._socket.last_address in self.mc_list)


  def testClientExpire(self):
    req = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING)
    self.client.SendRequest(req)
    # Make a couple of seconds pass ;)
    self.mock_time.increase(2)
    # Now sending the second request
    req2 = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING)
    self.client.SendRequest(req2)
    self.mock_time.increase(constants.CONFD_CLIENT_EXPIRE_TIMEOUT - 1)
    # First request should be expired, second one should not
    self.client.ExpireRequests()
    self.assertEquals(self.callback.call_count, 1)
    self.assertEquals(self.callback.last_up.type, confd.client.UPCALL_EXPIRE)
    self.assertEquals(self.callback.last_up.salt, req.rsalt)
    self.assertEquals(self.callback.last_up.orig_request, req)
    self.mock_time.increase(3)
    self.assertEquals(self.callback.call_count, 1)
    self.client.ExpireRequests()
    self.assertEquals(self.callback.call_count, 2)
    self.assertEquals(self.callback.last_up.type, confd.client.UPCALL_EXPIRE)
    self.assertEquals(self.callback.last_up.salt, req2.rsalt)
    self.assertEquals(self.callback.last_up.orig_request, req2)

  def testClientCascadeExpire(self):
    req = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING)
    self.client.SendRequest(req)
    self.mock_time.increase(constants.CONFD_CLIENT_EXPIRE_TIMEOUT +1)
    req2 = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING)
    self.client.SendRequest(req2)
    self.assertEquals(self.callback.call_count, 1)

  def testUpdatePeerList(self):
    self.client.UpdatePeerList(self.new_peers)
    self.assertEquals(self.client._peers, self.new_peers)
    req = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING)
    self.client.SendRequest(req)
    self.assertEquals(self.client._socket.send_count, len(self.new_peers))
    self.assert_(self.client._socket.last_address in self.new_peers)

  def testSetPeersFamily(self):
    self.client._SetPeersAddressFamily()
    self.assertEquals(self.client._family, self.family)
    mixed_peers = ["192.0.2.99", "2001:db8:beef::13"]
    self.client.UpdatePeerList(mixed_peers)
    self.assertRaises(errors.ConfdClientError,
                      self.client._SetPeersAddressFamily)


class TestIP4Client(unittest.TestCase, _BaseClientTest):
  """Client tests"""
  mc_list = ["192.0.2.1",
             "192.0.2.2",
             "192.0.2.3",
             "192.0.2.4",
             "192.0.2.5",
             "192.0.2.6",
             "192.0.2.7",
             "192.0.2.8",
             "192.0.2.9",
            ]
  new_peers = ["198.51.100.1", "198.51.100.2"]
  family = socket.AF_INET

  def setUp(self):
    unittest.TestCase.setUp(self)
    _BaseClientTest.setUp(self)


class TestIP6Client(unittest.TestCase, _BaseClientTest):
  """Client tests"""
  mc_list = ["2001:db8::1",
             "2001:db8::2",
             "2001:db8::3",
             "2001:db8::4",
             "2001:db8::5",
             "2001:db8::6",
             "2001:db8::7",
             "2001:db8::8",
             "2001:db8::9",
            ]
  new_peers = ["2001:db8:beef::11", "2001:db8:beef::12"]
  family = socket.AF_INET6

  def setUp(self):
    unittest.TestCase.setUp(self)
    _BaseClientTest.setUp(self)


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