#!/usr/bin/env python

'''
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
'''

from unittest import TestCase
import unittest
from Heartbeat import Heartbeat
from ActionQueue import ActionQueue
from AgentConfig import AgentConfig
import socket
import os
import time
from mock.mock import patch, MagicMock, call
import StringIO
import sys
import logging


class TestHeartbeat(TestCase):
  def setUp(self):
    # disable stdout
    out = StringIO.StringIO()
    sys.stdout = out


  def tearDown(self):
    # enable stdout
    sys.stdout = sys.__stdout__


  def test_build(self):
    config = AgentConfig("", "")
    config.set('agent', 'prefix', 'tmp')
    dummy_controller = MagicMock()
    actionQueue = ActionQueue(config, dummy_controller)
    heartbeat = Heartbeat(actionQueue, config)
    result = heartbeat.build({}, 100)
    print "Heartbeat: " + str(result)
    self.assertEquals(result['hostname'] != '', True,
                      "hostname should not be empty")
    self.assertEquals(result['responseId'], 100)
    self.assertEquals('componentStatus' not in result, True,
                      "Heartbeat should contain componentStatus")
    self.assertEquals(result['reports'] is not None, True,
                      "Heartbeat should contain reports")
    self.assertEquals(result['timestamp'] >= 1353679373880L, True)
    self.assertEquals(len(result['nodeStatus']), 2)
    self.assertEquals(result['nodeStatus']['cause'], "NONE")
    self.assertEquals(result['nodeStatus']['status'], "HEALTHY")
    # result may or may NOT have an agentEnv structure in it
    self.assertEquals((len(result) is 5) or (len(result) is 6), True)
    self.assertEquals(not heartbeat.reports, True,
                      "Heartbeat should not contain task in progress")


  @patch.object(ActionQueue, "result")
  def test_build_long_result(self, result_mock):
    config = AgentConfig("", "")
    config.set('agent', 'prefix', 'tmp')
    dummy_controller = MagicMock()
    actionQueue = ActionQueue(config, dummy_controller)
    result_mock.return_value = {
      'reports': [{'status': 'IN_PROGRESS',
                   'stderr': 'Read from /tmp/errors-3.txt',
                   'stdout': 'Read from /tmp/output-3.txt',
                   'clusterName': u'cc',
                   'roleCommand': u'INSTALL',
                   'serviceName': u'HDFS',
                   'role': u'DATANODE',
                   'actionId': '1-1',
                   'taskId': 3,
                   'exitcode': 777},

                  {'status': 'COMPLETED',
                   'stderr': 'stderr',
                   'stdout': 'out',
                   'clusterName': 'clusterName',
                   'roleCommand': 'UPGRADE',
                   'serviceName': 'serviceName',
                   'role': 'role',
                   'actionId': 17,
                   'taskId': 'taskId',
                   'exitcode': 0},

                  {'status': 'FAILED',
                   'stderr': 'stderr',
                   'stdout': 'out',
                   'clusterName': u'cc',
                   'roleCommand': u'INSTALL',
                   'serviceName': u'HDFS',
                   'role': u'DATANODE',
                   'actionId': '1-1',
                   'taskId': 3,
                   'exitcode': 13},

                  {'status': 'COMPLETED',
                   'stderr': 'stderr',
                   'stdout': 'out',
                   'clusterName': u'cc',
                   'configurationTags': {'global': {'tag': 'v1'}},
                   'roleCommand': u'INSTALL',
                   'serviceName': u'HDFS',
                   'role': u'DATANODE',
                   'actionId': '1-1',
                   'taskId': 3,
                   'exitcode': 0}

      ],
      'componentStatus': [
        {'status': 'HEALTHY', 'componentName': 'DATANODE', 'reportResult' : True},
        {'status': 'UNHEALTHY', 'componentName': 'NAMENODE', 'reportResult' : True},
        {'status': 'UNHEALTHY', 'componentName': 'HBASE_MASTER', 'reportResult' : False},
      ],
    }
    heartbeat = Heartbeat(actionQueue, config)
    hb = heartbeat.build({}, 10)
    hb['hostname'] = 'hostname'
    hb['timestamp'] = 'timestamp'
    hb['fqdn'] = 'fqdn'
    expected = {'nodeStatus':
                  {'status': 'HEALTHY',
                   'cause': 'NONE'},
                'timestamp': 'timestamp', 'hostname': 'hostname', 'fqdn': 'fqdn',
                'responseId': 10, 'reports': [
      {'status': 'IN_PROGRESS', 'roleCommand': u'INSTALL',
       'serviceName': u'HDFS', 'role': u'DATANODE', 'actionId': '1-1',
       'stderr': 'Read from /tmp/errors-3.txt',
       'stdout': 'Read from /tmp/output-3.txt', 'clusterName': u'cc',
       'taskId': 3, 'exitcode': 777},
      {'status': 'COMPLETED', 'roleCommand': 'UPGRADE',
       'serviceName': 'serviceName', 'role': 'role', 'actionId': 17,
       'stderr': 'stderr', 'stdout': 'out', 'clusterName': 'clusterName',
       'taskId': 'taskId', 'exitcode': 0},
      {'status': 'FAILED', 'roleCommand': u'INSTALL', 'serviceName': u'HDFS',
       'role': u'DATANODE', 'actionId': '1-1', 'stderr': 'stderr',
       'stdout': 'out', 'clusterName': u'cc', 'taskId': 3, 'exitcode': 13},
      {'status': 'COMPLETED', 'stdout': 'out',
       'configurationTags': {'global': {'tag': 'v1'}}, 'taskId': 3,
       'exitcode': 0, 'roleCommand': u'INSTALL', 'clusterName': u'cc',
       'serviceName': u'HDFS', 'role': u'DATANODE', 'actionId': '1-1',
       'stderr': 'stderr'}],  'componentStatus': [
      {'status': 'HEALTHY', 'componentName': 'DATANODE'},
      {'status': 'UNHEALTHY', 'componentName': 'NAMENODE'}]}
    self.assertEquals(hb, expected)


if __name__ == "__main__":
  logging.basicConfig(format='%(asctime)s %(message)s', level=logging.DEBUG)
  unittest.main()
