#!/usr/bin/python
# pylint: disable=missing-docstring

import unittest

import common
from autotest_lib.client.common_lib import error
from autotest_lib.frontend import setup_django_environment
from autotest_lib.frontend.afe import frontend_test_utils
from autotest_lib.frontend.afe import models, model_logic


class AclGroupTest(unittest.TestCase,
                   frontend_test_utils.FrontendTestMixin):
    def setUp(self):
        self._frontend_common_setup()


    def tearDown(self):
        self._frontend_common_teardown()


    def _check_acls(self, host, acl_name_list):
        actual_acl_names = [acl_group.name for acl_group
                            in host.aclgroup_set.all()]
        self.assertEquals(set(actual_acl_names), set(acl_name_list))


    def test_on_host_membership_change(self):
        host1, host2 = self.hosts[1:3]
        everyone_acl = models.AclGroup.objects.get(name='Everyone')

        host1.aclgroup_set.clear()
        self._check_acls(host1, [])
        host2.aclgroup_set.add(everyone_acl)
        self._check_acls(host2, ['Everyone', 'my_acl'])

        models.AclGroup.on_host_membership_change()

        self._check_acls(host1, ['Everyone'])
        self._check_acls(host2, ['my_acl'])


class HostTest(unittest.TestCase,
               frontend_test_utils.FrontendTestMixin):
    def setUp(self):
        self._frontend_common_setup()


    def tearDown(self):
        self._frontend_common_teardown()


    def _get_attributes(self, host):
        models.Host.objects.populate_relationships(
                [host], models.HostAttribute, 'attribute_list')
        return dict((attribute.attribute, attribute.value)
                    for attribute in host.attribute_list)

    def test_delete_attribute(self):
        previous_config = models.RESPECT_STATIC_ATTRIBUTES
        models.RESPECT_STATIC_ATTRIBUTES = False
        host1 = models.Host.objects.create(hostname='test_host1')
        host1.set_attribute('test_attribute1', 'test_value1')

        attributes = self._get_attributes(host1)
        self.assertEquals(attributes['test_attribute1'], 'test_value1')

        host1.set_or_delete_attribute('test_attribute1', None)
        attributes = self._get_attributes(host1)
        self.assertNotIn('test_attribute1', attributes.keys())

        models.RESPECT_STATIC_ATTRIBUTES = previous_config


    def test_delete_static_attribute(self):
        previous_config = models.RESPECT_STATIC_ATTRIBUTES
        models.RESPECT_STATIC_ATTRIBUTES = True
        host1 = models.Host.objects.create(hostname='test_host1')
        host1.set_attribute('test_attribute1', 'test_value1')
        self._set_static_attribute(host1, 'test_attribute1', 'test_value1')

        self.assertRaises(
                error.UnmodifiableAttributeException,
                host1.set_or_delete_attribute,
                'test_attribute1', None)

        models.RESPECT_STATIC_ATTRIBUTES = previous_config


    def test_set_attribute(self):
        previous_config = models.RESPECT_STATIC_ATTRIBUTES
        models.RESPECT_STATIC_ATTRIBUTES = False
        host1 = models.Host.objects.create(hostname='test_host1')
        host1.set_attribute('test_attribute1', 'test_value1')

        host1.set_or_delete_attribute('test_attribute1', 'test_new_value1')

        attributes = self._get_attributes(host1)
        self.assertEquals(attributes['test_attribute1'], 'test_new_value1')

        models.RESPECT_STATIC_ATTRIBUTES = previous_config


    def test_set_static_attribute(self):
        previous_config = models.RESPECT_STATIC_ATTRIBUTES
        models.RESPECT_STATIC_ATTRIBUTES = True
        host1 = models.Host.objects.create(hostname='test_host1')
        host1.set_attribute('test_attribute1', 'test_value1')
        self._set_static_attribute(host1, 'test_attribute1', 'test_value1')

        self.assertRaises(
                error.UnmodifiableAttributeException,
                host1.set_or_delete_attribute,
                'test_attribute1', 'test_value2')

        models.RESPECT_STATIC_ATTRIBUTES = previous_config


    def test_add_host_previous_one_time_host(self):
        # ensure that when adding a host which was previously used as a one-time
        # host, the status isn't reset, since this can interfere with the
        # scheduler.
        host = models.Host.create_one_time_host('othost')
        self.assertEquals(host.invalid, True)
        self.assertEquals(host.status, models.Host.Status.READY)

        host.status = models.Host.Status.RUNNING
        host.save()

        host2 = models.Host.add_object(hostname='othost')
        self.assertEquals(host2.id, host.id)
        self.assertEquals(host2.status, models.Host.Status.RUNNING)


    def test_check_board_labels_allowed(self):
        host = models.Host.create_one_time_host('othost')
        # First check with host with no board label.
        self.assertEqual(host.check_board_labels_allowed([host]), None)

        # Second check with host with board label
        label = models.Label.add_object(name='board:test')
        label.host_set.add(host)
        self.assertRaises(model_logic.ValidationError,
                          host.check_board_labels_allowed, [host],
                          ['board:new_board'])


class SpecialTaskUnittest(unittest.TestCase,
                          frontend_test_utils.FrontendTestMixin):
    def setUp(self):
        self._frontend_common_setup()


    def tearDown(self):
        self._frontend_common_teardown()


    def _create_task(self):
        return models.SpecialTask.objects.create(
                host=self.hosts[0], task=models.SpecialTask.Task.VERIFY,
                requested_by=models.User.current_user())


    def test_execution_path(self):
        task = self._create_task()
        self.assertEquals(task.execution_path(), 'hosts/host1/1-verify')


    def test_status(self):
        task = self._create_task()
        self.assertEquals(task.status, 'Queued')

        task.update_object(is_active=True)
        self.assertEquals(task.status, 'Running')

        task.update_object(is_active=False, is_complete=True, success=True)
        self.assertEquals(task.status, 'Completed')

        task.update_object(success=False)
        self.assertEquals(task.status, 'Failed')


    def test_activate(self):
        task = self._create_task()
        task.activate()
        self.assertTrue(task.is_active)
        self.assertFalse(task.is_complete)


    def test_finish(self):
        task = self._create_task()
        task.activate()
        task.finish(True)
        self.assertFalse(task.is_active)
        self.assertTrue(task.is_complete)
        self.assertTrue(task.success)


    def test_requested_by_from_queue_entry(self):
        job = self._create_job(hosts=[0])
        task = models.SpecialTask.objects.create(
                host=self.hosts[0], task=models.SpecialTask.Task.VERIFY,
                queue_entry=job.hostqueueentry_set.all()[0])
        self.assertEquals(task.requested_by.login, 'autotest_system')


class HostQueueEntryUnittest(unittest.TestCase,
                             frontend_test_utils.FrontendTestMixin):
    def setUp(self):
        self._frontend_common_setup()


    def tearDown(self):
        self._frontend_common_teardown()


    def test_execution_path(self):
        entry = self._create_job(hosts=[1]).hostqueueentry_set.all()[0]
        entry.execution_subdir = 'subdir'
        entry.save()

        self.assertEquals(entry.execution_path(), '1-autotest_system/subdir')


class ModelWithInvalidTest(unittest.TestCase,
                           frontend_test_utils.FrontendTestMixin):
    def setUp(self):
        self._frontend_common_setup()


    def tearDown(self):
        self._frontend_common_teardown()


    def test_model_with_invalid_delete(self):
        self.assertFalse(self.hosts[0].invalid)
        self.hosts[0].delete()
        self.assertTrue(self.hosts[0].invalid)
        self.assertTrue(models.Host.objects.get(id=self.hosts[0].id))


    def test_model_with_invalid_delete_queryset(self):
        for host in self.hosts:
            self.assertFalse(host.invalid)

        hosts = models.Host.objects.all()
        hosts.delete()
        self.assertEqual(hosts.count(), len(self.hosts))

        for host in hosts:
            self.assertTrue(host.invalid)


    def test_cloned_queryset_delete(self):
        """
        Make sure that a cloned queryset maintains the custom delete()
        """
        to_delete = ('host1', 'host2')

        for host in self.hosts:
            self.assertFalse(host.invalid)

        hosts = models.Host.objects.all().filter(hostname__in=to_delete)
        hosts.delete()
        all_hosts = models.Host.objects.all()
        self.assertEqual(all_hosts.count(), len(self.hosts))

        for host in all_hosts:
            if host.hostname in to_delete:
                self.assertTrue(
                        host.invalid,
                        '%s.invalid expected to be True' % host.hostname)
            else:
                self.assertFalse(
                        host.invalid,
                        '%s.invalid expected to be False' % host.hostname)


    def test_normal_delete(self):
        job = self._create_job(hosts=[1])
        self.assertEqual(1, models.Job.objects.all().count())

        job.delete()
        self.assertEqual(0, models.Job.objects.all().count())


    def test_normal_delete_queryset(self):
        self._create_job(hosts=[1])
        self._create_job(hosts=[2])

        self.assertEqual(2, models.Job.objects.all().count())

        models.Job.objects.all().delete()
        self.assertEqual(0, models.Job.objects.all().count())


class SerializationTest(unittest.TestCase,
                        frontend_test_utils.FrontendTestMixin):
    def setUp(self):
        self._frontend_common_setup(fill_data=False)


    def tearDown(self):
        self._frontend_common_teardown()


    def _get_example_response(self):
        return {'hosts': [{'aclgroup_set': [{'description': '',
                                             'id': 1,
                                             'name': 'Everyone',
                                             'users': [{
                                                 'access_level': 100,
                                                 'id': 1,
                                                 'login': 'autotest_system',
                                                 'reboot_after': 0,
                                                 'reboot_before': 1,
                                                 'show_experimental': False}]}],
                           'dirty': True,
                           'hostattribute_set': [],
                           'hostname': '100.107.2.163',
                           'id': 2,
                           'invalid': False,
                           'labels': [{'id': 7,
                                       'invalid': False,
                                       'kernel_config': '',
                                       'name': 'power:battery',
                                       'only_if_needed': False,
                                       'platform': False},
                                      {'id': 9,
                                       'invalid': False,
                                       'kernel_config': '',
                                       'name': 'hw_video_acc_h264',
                                       'only_if_needed': False,
                                       'platform': False},
                                      {'id': 10,
                                       'invalid': False,
                                       'kernel_config': '',
                                       'name': 'hw_video_acc_enc_h264',
                                       'only_if_needed': False,
                                       'platform': False},
                                      {'id': 11,
                                       'invalid': False,
                                       'kernel_config': '',
                                       'name': 'webcam',
                                       'only_if_needed': False,
                                       'platform': False},
                                      {'id': 12,
                                       'invalid': False,
                                       'kernel_config': '',
                                       'name': 'touchpad',
                                       'only_if_needed': False,
                                       'platform': False},
                                      {'id': 13,
                                       'invalid': False,
                                       'kernel_config': '',
                                       'name': 'spring',
                                       'only_if_needed': False,
                                       'platform': False},
                                      {'id': 14,
                                       'invalid': False,
                                       'kernel_config': '',
                                       'name': 'board:daisy',
                                       'only_if_needed': False,
                                       'platform': True},
                                      {'id': 15,
                                       'invalid': False,
                                       'kernel_config': '',
                                       'name': 'board_freq_mem:daisy_1.7GHz',
                                       'only_if_needed': False,
                                       'platform': False},
                                      {'id': 16,
                                       'invalid': False,
                                       'kernel_config': '',
                                       'name': 'bluetooth',
                                       'only_if_needed': False,
                                       'platform': False},
                                      {'id': 17,
                                       'invalid': False,
                                       'kernel_config': '',
                                       'name': 'gpu_family:mali',
                                       'only_if_needed': False,
                                       'platform': False},
                                      {'id': 19,
                                       'invalid': False,
                                       'kernel_config': '',
                                       'name': 'ec:cros',
                                       'only_if_needed': False,
                                       'platform': False},
                                      {'id': 20,
                                       'invalid': False,
                                       'kernel_config': '',
                                       'name': 'storage:mmc',
                                       'only_if_needed': False,
                                       'platform': False},
                                      {'id': 21,
                                       'invalid': False,
                                       'kernel_config': '',
                                       'name': 'hw_video_acc_vp8',
                                       'only_if_needed': False,
                                       'platform': False},
                                      {'id': 22,
                                       'invalid': False,
                                       'kernel_config': '',
                                       'name': 'video_glitch_detection',
                                       'only_if_needed': False,
                                       'platform': False},
                                      {'id': 23,
                                       'invalid': False,
                                       'kernel_config': '',
                                       'name': 'pool:suites',
                                       'only_if_needed': False,
                                       'platform': False},
                                      {'id': 25,
                                       'invalid': False,
                                       'kernel_config': '',
                                       'name': 'daisy-board-name',
                                       'only_if_needed': False,
                                       'platform': False}],
                           'leased': False,
                           'lock_reason': '',
                           'lock_time': None,
                           'locked': False,
                           'protection': 0,
                           'shard': {'hostname': '1', 'id': 1},
                           'status': 'Ready',
                           'synch_id': None}],
                'jobs': [{'control_file': 'some control file\n\n\n',
                          'control_type': 2,
                          'created_on': '2014-09-04T13:09:35',
                          'dependency_labels': [{'id': 14,
                                                 'invalid': False,
                                                 'kernel_config': '',
                                                 'name': 'board:daisy',
                                                 'only_if_needed': False,
                                                 'platform': True},
                                                {'id': 23,
                                                 'invalid': False,
                                                 'kernel_config': '',
                                                 'name': 'pool:suites',
                                                 'only_if_needed': False,
                                                 'platform': False},
                                                {'id': 25,
                                                 'invalid': False,
                                                 'kernel_config': '',
                                                 'name': 'daisy-board-name',
                                                 'only_if_needed': False,
                                                 'platform': False}],
                          'email_list': '',
                          'hostqueueentry_set': [{'aborted': False,
                                                  'active': False,
                                                  'complete': False,
                                                  'deleted': False,
                                                  'execution_subdir': '',
                                                  'finished_on': None,
                                                  'id': 5,
                                                  'meta_host': {
                                                      'id': 14,
                                                      'invalid': False,
                                                      'kernel_config': '',
                                                      'name': 'board:daisy',
                                                      'only_if_needed': False,
                                                      'platform': True},
                                                  'host_id': None,
                                                  'started_on': None,
                                                  'status': 'Queued'}],
                          'id': 5,
                          'jobkeyval_set': [{'id': 10,
                                             'job_id': 5,
                                             'key': 'suite',
                                             'value': 'dummy'},
                                            {'id': 11,
                                             'job_id': 5,
                                             'key': 'build',
                                             'value': 'daisy-release'},
                                            {'id': 12,
                                             'job_id': 5,
                                             'key': 'experimental',
                                             'value': 'False'}],
                          'max_runtime_hrs': 72,
                          'max_runtime_mins': 1440,
                          'name': 'daisy-experimental',
                          'owner': 'autotest',
                          'parse_failed_repair': True,
                          'priority': 40,
                          'reboot_after': 0,
                          'reboot_before': 1,
                          'run_reset': True,
                          'run_verify': False,
                          'shard': {'hostname': '1', 'id': 1},
                          'synch_count': 1,
                          'test_retry': 0,
                          'timeout': 24,
                          'timeout_mins': 1440,
                          'require_ssp': None},
                         {'control_file': 'some control file\n\n\n',
                          'control_type': 2,
                          'created_on': '2014-09-04T13:09:35',
                          'dependency_labels': [{'id': 14,
                                                 'invalid': False,
                                                 'kernel_config': '',
                                                 'name': 'board:daisy',
                                                 'only_if_needed': False,
                                                 'platform': True},
                                                {'id': 23,
                                                 'invalid': False,
                                                 'kernel_config': '',
                                                 'name': 'pool:suites',
                                                 'only_if_needed': False,
                                                 'platform': False},
                                                {'id': 25,
                                                 'invalid': False,
                                                 'kernel_config': '',
                                                 'name': 'daisy-board-name',
                                                 'only_if_needed': False,
                                                 'platform': False}],
                          'email_list': '',
                          'hostqueueentry_set': [{'aborted': False,
                                                  'active': False,
                                                  'complete': False,
                                                  'deleted': False,
                                                  'execution_subdir': '',
                                                  'finished_on': None,
                                                  'id': 7,
                                                  'meta_host': {
                                                      'id': 14,
                                                      'invalid': False,
                                                      'kernel_config': '',
                                                      'name': 'board:daisy',
                                                      'only_if_needed': False,
                                                      'platform': True},
                                                  'host_id': None,
                                                  'started_on': None,
                                                  'status': 'Queued'}],
                          'id': 7,
                          'jobkeyval_set': [{'id': 16,
                                             'job_id': 7,
                                             'key': 'suite',
                                             'value': 'dummy'},
                                            {'id': 17,
                                             'job_id': 7,
                                             'key': 'build',
                                             'value': 'daisy-release'},
                                            {'id': 18,
                                             'job_id': 7,
                                             'key': 'experimental',
                                             'value': 'False'}],
                          'max_runtime_hrs': 72,
                          'max_runtime_mins': 1440,
                          'name': 'daisy-experimental',
                          'owner': 'autotest',
                          'parse_failed_repair': True,
                          'priority': 40,
                          'reboot_after': 0,
                          'reboot_before': 1,
                          'run_reset': True,
                          'run_verify': False,
                          'shard': {'hostname': '1', 'id': 1},
                          'synch_count': 1,
                          'test_retry': 0,
                          'timeout': 24,
                          'timeout_mins': 1440,
                          'require_ssp': None}]}


    def test_response(self):
        heartbeat_response = self._get_example_response()
        hosts_serialized = heartbeat_response['hosts']
        jobs_serialized = heartbeat_response['jobs']

        # Persisting is automatically done inside deserialize
        hosts = [models.Host.deserialize(host) for host in hosts_serialized]
        jobs = [models.Job.deserialize(job) for job in jobs_serialized]

        generated_heartbeat_response = {
            'hosts': [host.serialize() for host in hosts],
            'jobs': [job.serialize() for job in jobs]
        }
        example_response = self._get_example_response()
        # For attribute-like objects, we don't care about its id.
        for r in [generated_heartbeat_response, example_response]:
            for job in r['jobs']:
                for keyval in job['jobkeyval_set']:
                    keyval.pop('id')
            for host in r['hosts']:
                for attribute in host['hostattribute_set']:
                    keyval.pop('id')
        self.assertEqual(generated_heartbeat_response, example_response)


    def test_update(self):
        job = self._create_job(hosts=[1])
        serialized = job.serialize(include_dependencies=False)
        serialized['owner'] = 'some_other_owner'

        job.update_from_serialized(serialized)
        self.assertEqual(job.owner, 'some_other_owner')

        serialized = job.serialize()
        self.assertRaises(
            ValueError,
            job.update_from_serialized, serialized)


    def test_sync_aborted(self):
        job = self._create_job(hosts=[1])
        serialized = job.serialize()

        serialized['hostqueueentry_set'][0]['aborted'] = True
        serialized['hostqueueentry_set'][0]['status'] = 'Running'

        models.Job.deserialize(serialized)

        job = models.Job.objects.get(pk=job.id)
        self.assertTrue(job.hostqueueentry_set.all()[0].aborted)
        self.assertEqual(job.hostqueueentry_set.all()[0].status, 'Queued')


if __name__ == '__main__':
    unittest.main()
