#!/usr/bin/env python
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Test gsutil.py."""


import __builtin__
import base64
import hashlib
import json
import os
import shutil
import subprocess
import sys
import tempfile
import unittest
import urllib2
import zipfile


# Add depot_tools to path
THIS_DIR = os.path.dirname(os.path.abspath(__file__))
DEPOT_TOOLS_DIR = os.path.dirname(THIS_DIR)
sys.path.append(DEPOT_TOOLS_DIR)

import gsutil


class TestError(Exception):
  pass


class Buffer(object):
  def __init__(self, data=None):
    self.data = data or ''

  def write(self, buf):
    self.data += buf

  def read(self, amount=None):
    if not amount:
      amount = len(self.data)
    result = self.data[:amount]
    self.data = self.data[amount:]
    return result


class FakeCall(object):
  def __init__(self):
    self.expectations = []

  def add_expectation(self, *args, **kwargs):
    returns = kwargs.pop('_returns', None)
    self.expectations.append((args, kwargs, returns))

  def __call__(self, *args, **kwargs):
    if not self.expectations:
      raise TestError('Got unexpected\n%s\n%s' % (args, kwargs))
    exp_args, exp_kwargs, exp_returns = self.expectations.pop(0)
    if args != exp_args or kwargs != exp_kwargs:
      message = 'Expected:\n  args: %s\n  kwargs: %s\n' % (exp_args, exp_kwargs)
      message += 'Got:\n  args: %s\n  kwargs: %s\n' % (args, kwargs)
      raise TestError(message)
    return exp_returns


class GsutilUnitTests(unittest.TestCase):
  def setUp(self):
    self.fake = FakeCall()
    self.tempdir = tempfile.mkdtemp()
    self.old_urlopen = getattr(urllib2, 'urlopen')
    self.old_call = getattr(subprocess, 'call')
    setattr(urllib2, 'urlopen', self.fake)
    setattr(subprocess, 'call', self.fake)

  def tearDown(self):
    self.assertEqual(self.fake.expectations, [])
    shutil.rmtree(self.tempdir)
    setattr(urllib2, 'urlopen', self.old_urlopen)
    setattr(subprocess, 'call', self.old_call)

  def test_download_gsutil(self):
    version = '4.2'
    filename = 'gsutil_%s.zip' % version
    full_filename = os.path.join(self.tempdir, filename)
    fake_file = 'This is gsutil.zip'
    fake_file2 = 'This is other gsutil.zip'
    url = '%s%s' % (gsutil.GSUTIL_URL, filename)
    self.fake.add_expectation(url, _returns=Buffer(fake_file))

    self.assertEquals(
        gsutil.download_gsutil(version, self.tempdir), full_filename)
    with open(full_filename, 'r') as f:
      self.assertEquals(fake_file, f.read())

    metadata_url = gsutil.API_URL + filename
    md5_calc = hashlib.md5()
    md5_calc.update(fake_file)
    b64_md5 = base64.b64encode(md5_calc.hexdigest())
    self.fake.add_expectation(metadata_url, _returns=Buffer(json.dumps({
        'md5Hash': b64_md5
    })))
    self.assertEquals(
        gsutil.download_gsutil(version, self.tempdir), full_filename)
    with open(full_filename, 'r') as f:
      self.assertEquals(fake_file, f.read())
    self.assertEquals(self.fake.expectations, [])

    self.fake.add_expectation(metadata_url, _returns=Buffer(json.dumps({
        'md5Hash': base64.b64encode('aaaaaaa')  # Bad MD5
    })))
    self.fake.add_expectation(url, _returns=Buffer(fake_file2))
    self.assertEquals(
        gsutil.download_gsutil(version, self.tempdir), full_filename)
    with open(full_filename, 'r') as f:
      self.assertEquals(fake_file2, f.read())
    self.assertEquals(self.fake.expectations, [])

  def test_ensure_gsutil_full(self):
    version = '4.2'
    gsutil_dir = os.path.join(self.tempdir, 'gsutil_%s' % version, 'gsutil')
    gsutil_bin = os.path.join(gsutil_dir, 'gsutil')
    os.makedirs(gsutil_dir)

    self.fake.add_expectation(
        [sys.executable, gsutil_bin, 'version'], stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT, _returns=1)

    with open(gsutil_bin, 'w') as f:
      f.write('Foobar')
    zip_filename = 'gsutil_%s.zip' % version
    url = '%s%s' % (gsutil.GSUTIL_URL, zip_filename)
    _, tempzip = tempfile.mkstemp()
    fake_gsutil = 'Fake gsutil'
    with zipfile.ZipFile(tempzip, 'w') as zf:
      zf.writestr('gsutil/gsutil', fake_gsutil)
    with open(tempzip, 'rb') as f:
      self.fake.add_expectation(url, _returns=Buffer(f.read()))
    self.fake.add_expectation(
        [sys.executable, gsutil_bin, 'version'], stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT, _returns=1)

    # This should delete the old bin and rewrite it with 'Fake gsutil'
    self.assertRaises(
        gsutil.InvalidGsutilError, gsutil.ensure_gsutil, version, self.tempdir)
    self.assertTrue(os.path.isdir(os.path.join(self.tempdir, '.cache_dir')))
    self.assertTrue(os.path.exists(gsutil_bin))
    with open(gsutil_bin, 'r') as f:
      self.assertEquals(f.read(), fake_gsutil)
    self.assertEquals(self.fake.expectations, [])

  def test_ensure_gsutil_short(self):
    version = '4.2'
    gsutil_dir = os.path.join(self.tempdir, 'gsutil_%s' % version, 'gsutil')
    gsutil_bin = os.path.join(gsutil_dir, 'gsutil')
    os.makedirs(gsutil_dir)

    # Mock out call().
    self.fake.add_expectation(
        [sys.executable, gsutil_bin, 'version'],
        stdout=subprocess.PIPE, stderr=subprocess.STDOUT, _returns=0)

    with open(gsutil_bin, 'w') as f:
      f.write('Foobar')
    self.assertEquals(
        gsutil.ensure_gsutil(version, self.tempdir), gsutil_bin)

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