#!/usr/bin/env python

# Copyright 2012 Hewlett-Packard Development Company, L.P.
#
# Licensed 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.

import os

from tests.base import AnsibleZuulTestCase


class TestOpenStack(AnsibleZuulTestCase):
    # A temporary class to experiment with how openstack can use
    # Zuulv3

    tenant_config_file = 'config/openstack/main.yaml'

    def test_nova_master(self):
        A = self.fake_gerrit.addFakeChange('openstack/nova', 'master', 'A')
        A.addApproval('code-review', 2)
        self.fake_gerrit.addEvent(A.addApproval('approved', 1))
        self.waitUntilSettled()
        self.assertEqual(self.getJobFromHistory('python27').result,
                         'SUCCESS')
        self.assertEqual(self.getJobFromHistory('python35').result,
                         'SUCCESS')
        self.assertEqual(A.data['status'], 'MERGED')
        self.assertEqual(A.reported, 2,
                         "A should report start and success")
        self.assertEqual(self.getJobFromHistory('python27').node,
                         'ubuntu-xenial')

    def test_nova_mitaka(self):
        self.create_branch('openstack/nova', 'stable/mitaka')
        A = self.fake_gerrit.addFakeChange('openstack/nova',
                                           'stable/mitaka', 'A')
        A.addApproval('code-review', 2)
        self.fake_gerrit.addEvent(A.addApproval('approved', 1))
        self.waitUntilSettled()
        self.assertEqual(self.getJobFromHistory('python27').result,
                         'SUCCESS')
        self.assertEqual(self.getJobFromHistory('python35').result,
                         'SUCCESS')
        self.assertEqual(A.data['status'], 'MERGED')
        self.assertEqual(A.reported, 2,
                         "A should report start and success")
        self.assertEqual(self.getJobFromHistory('python27').node,
                         'ubuntu-trusty')

    def test_dsvm_keystone_repo(self):
        self.launch_server.keep_jobdir = True
        A = self.fake_gerrit.addFakeChange('openstack/nova', 'master', 'A')
        self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
        self.waitUntilSettled()

        self.assertHistory([
            dict(name='dsvm', result='SUCCESS', changes='1,1')])
        build = self.getJobFromHistory('dsvm')

        # Check that a change to nova triggered a keystone clone
        launcher_git_dir = os.path.join(self.launcher_src_root,
                                        'openstack', 'keystone', '.git')
        self.assertTrue(os.path.exists(launcher_git_dir),
                        msg='openstack/keystone should be cloned.')

        jobdir_git_dir = os.path.join(build.jobdir.src_root,
                                      'openstack', 'keystone', '.git')
        self.assertTrue(os.path.exists(jobdir_git_dir),
                        msg='openstack/keystone should be cloned.')

    def test_dsvm_nova_repo(self):
        self.launch_server.keep_jobdir = True
        A = self.fake_gerrit.addFakeChange('openstack/keystone', 'master', 'A')
        self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
        self.waitUntilSettled()

        self.assertHistory([
            dict(name='dsvm', result='SUCCESS', changes='1,1')])
        build = self.getJobFromHistory('dsvm')

        # Check that a change to keystone triggered a nova clone
        launcher_git_dir = os.path.join(self.launcher_src_root,
                                        'openstack', 'nova', '.git')
        self.assertTrue(os.path.exists(launcher_git_dir),
                        msg='openstack/nova should be cloned.')

        jobdir_git_dir = os.path.join(build.jobdir.src_root,
                                      'openstack', 'nova', '.git')
        self.assertTrue(os.path.exists(jobdir_git_dir),
                        msg='openstack/nova should be cloned.')
