# -*- coding: utf-8 -*-
# Copyright 2015 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Tests the gce module."""

from __future__ import print_function

import os
import sys

from googleapiclient.errors import HttpError
from googleapiclient.http import HttpMockSequence
from oauth2client.client import GoogleCredentials

from chromite.lib import cros_test_lib
from chromite.lib import gce
from chromite.lib import osutils


assert sys.version_info >= (3, 6), 'This module requires Python 3.6+'


class GceTest(cros_test_lib.MockTempDirTestCase):
  """Unit tests for the gce module."""

  _PROJECT = 'foo-project'
  _ZONE = 'foo-zone'

  def setUp(self):
    self.json_key_file = os.path.join(self.tempdir, 'service_account.json')
    osutils.Touch(self.json_key_file)
    for cmd in ('from_stream', 'create_scoped'):
      self.PatchObject(GoogleCredentials, cmd, autospec=True)
    self.PatchObject(gce.GceContext, 'GetZoneRegion', autospec=True,
                     return_value=self._ZONE)

  @cros_test_lib.NetworkTest()
  def testGetImage(self):
    """Tests that GetImage returns the correct image."""
    good_http = HttpMockSequence([
        ({'status': '200',}, '{"name": "foo-image"}',),
    ])

    # Assert that GetImage does not complain if an image is found.
    self.PatchObject(gce.GceContext, '_BuildRetriableRequest', autospec=True,
                     side_effect=self._MockOutBuildRetriableRequest(good_http))
    gce_context = gce.GceContext.ForServiceAccount(self._PROJECT, self._ZONE,
                                                   self.json_key_file)
    self.assertDictEqual(gce_context.GetImage('foo-image'),
                         dict(name='foo-image'))

  @cros_test_lib.NetworkTest()
  def testGetImageRaisesIfImageNotFound(self):
    """Tests that GetImage raies exception when image is not found."""
    bad_http = HttpMockSequence([
        ({'status': '404',}, 'Image not found.',),
    ])

    # Assert that GetImage raises if image is not found.
    self.PatchObject(gce.GceContext, '_BuildRetriableRequest', autospec=True,
                     side_effect=self._MockOutBuildRetriableRequest(bad_http))
    gce_context = gce.GceContext.ForServiceAccount(self._PROJECT, self._ZONE,
                                                   self.json_key_file)
    with self.assertRaises(gce.ResourceNotFoundError):
      gce_context.GetImage('not-exising-image')

  @cros_test_lib.NetworkTest()
  def testRetryOnServerErrorHttpRequest(self):
    """Tests that 500 errors are retried."""

    # Fake http sequence that does not return 200 until the third trial.
    mock_http = HttpMockSequence([
        ({'status': '502'}, 'Server error'),
        ({'status': '502'}, 'Server error'),
        ({'status': '200'}, '{"name":"foo-image"}'),
    ])

    self.PatchObject(gce.GceContext, '_BuildRetriableRequest', autospec=True,
                     side_effect=self._MockOutBuildRetriableRequest(mock_http))

    # Disable retry and expect the request to fail.
    gce.GceContext.RETRIES = 0
    gce_context = gce.GceContext.ForServiceAccount(self._PROJECT, self._ZONE,
                                                   self.json_key_file)
    with self.assertRaises(HttpError):
      gce_context.GetImage('foo-image')

    # Enable retry and expect the request to succeed.
    gce.GceContext.RETRIES = 2
    gce_context = gce.GceContext.ForServiceAccount(self._PROJECT, self._ZONE,
                                                   self.json_key_file)
    self.assertDictEqual(gce_context.GetImage('foo-image'),
                         dict(name='foo-image'))

  def _MockOutBuildRetriableRequest(self, mock_http):
    """Returns a mock closure of _BuildRetriableRequest.

    Fake a GceContext._BuildRetriableRequest() that always uses |mock_http| as
    transport.
    """
    def _BuildRetriableRequest(_self, num_retries, _http, _thread_safe,
                               _credentials, *args, **kwargs):
      return gce.RetryOnServerErrorHttpRequest(num_retries, mock_http, *args,
                                               **kwargs)
    return _BuildRetriableRequest
