#!/usr/bin/env python
# Copyright (c) 2012 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.

"""Unit tests for commit_queue.py."""

import logging
import os
import StringIO
import sys
import time
import traceback
import unittest

ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.join(ROOT_DIR, '..'))

import commit_queue
import context
import creds

from testing_support import auto_stub

# From /tests
import mocks


class Stop(Exception):
  pass


class PendingManagerMock(auto_stub.SimpleMock):
  def __init__(self, unit_test):
    super(PendingManagerMock, self).__init__(unit_test)
    self.context = context.Context(
        mocks.RietveldMock(unit_test), mocks.SvnCheckoutMock(unit_test), None)
    self.count = 0

  def load(self, *args, **kwargs):
    self._register_call(*args, **kwargs)

  def save(self, *args, **kwargs):
    self._register_call(*args, **kwargs)

  def close(self, *args, **kwargs):
    self._register_call(*args, **kwargs)

  def look_for_new_pending_commit(self, *args, **kwargs):
    self._register_call(*args, **kwargs)
    self.count += 1
    if self.count > 3:
      raise Stop()

  def process_new_pending_commit(self, *args, **kwargs):
    self._register_call(*args, **kwargs)

  def update_status(self, *args, **kwargs):
    self._register_call(*args, **kwargs)

  def scan_results(self, *args, **kwargs):
    self._register_call(*args, **kwargs)


class CredentialsMock(object):
  @staticmethod
  def get(user):
    return '1%s1' % user


class CommitQueueTest(auto_stub.TestCase):
  def setUp(self):
    super(CommitQueueTest, self).setUp()
    self.mock(sys, 'argv', ['commit_queue.py'])
    self.mock(sys, 'stdout', StringIO.StringIO())
    self.mock(sys, 'stderr', StringIO.StringIO())
    self.mock(commit_queue.projects, 'load_project', None)
    self.mock(commit_queue, 'SetupLogging', lambda _: None)
    # Setup logging attached to the mocked sys.stderr, printing
    # only the exception name to make tests less fragile.
    handler = logging.StreamHandler()
    formatter = logging.Formatter()
    formatter.formatException = lambda _: traceback.format_exc(0)
    handler.setFormatter(formatter)
    logging.getLogger().handlers = [handler]
    self._time = 1
    self.mock(time, 'time', self._get_time)
    self.mock(creds, 'Credentials', self._get_cred)

  def tearDown(self):
    try:
      if not self.has_failed():
        self._check('stdout', '')
        self._check('stderr', '')
    finally:
      super(CommitQueueTest, self).tearDown()

  def _check(self, pipe, expected):
    self.assertEqual(expected, self._pop(pipe))

  def _get_time(self):
    self._time += 10
    return self._time

  @staticmethod
  def _pop(pipe):
    data = getattr(sys, pipe).getvalue()
    setattr(sys, pipe, StringIO.StringIO())
    return data

  def _get_cred(self, pwd):
    rootdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    workdir = os.path.join(rootdir, 'workdir')
    self.assertEqual(os.path.join(workdir, '.gaia_pwd'), pwd)
    return CredentialsMock()

  def testHelp(self):
    sys.argv.append('--help')
    try:
      commit_queue.main()
      self.fail()
    except SystemExit as e:
      self.assertEqual(0, e.code)
    output = self._pop('stdout')
    # Cannot compare for the exact string since the formatting depends on the
    # screen size.
    self.assertIn('Minimum delay between each polling loop', output)
    self.assertIn('Run for real instead of dry-run mode which', output)
    self.assertLess(600, len(output), output)

  def testChromium(self):
    sys.argv.extend(('--project', 'chromium'))
    calls = []
    def load_project(*args):
      calls.append(args)
      return PendingManagerMock(self)

    self.mock(commit_queue.projects, 'load_project', load_project)
    try:
      commit_queue.main()
      self.fail()
    except Stop:
      pass
    self.assertEqual(1, len(calls))
    self.assertEqual('chromium', calls[0][0])
    self.assertEqual('commit-bot@chromium.org', calls[0][1])
    self.assertEqual(
        os.path.join(os.path.dirname(ROOT_DIR), 'workdir'), calls[0][2])
    self.assertEqual(None, calls[0][4])
    self._check(
        'stdout',
        'Using read-only Rietveld\n'
        'Using read-only checkout\n'
        'Using read-only chromium-status interface\n')
    self._check(
        'stderr',
        'CQ loop terminating\n'
        'Traceback (most recent call last):\n'
        'Stop\n\n'
        'Saving db...\ndb save successful.\n')

  def testDryRun(self):
    sys.argv.extend(('--project', 'chromium'))
    pc = PendingManagerMock(self)
    self.mock(
        commit_queue.projects,
        'load_project',
        lambda *args: pc)
    try:
      commit_queue.main()
      self.fail()
    except Stop:
      pass
    self.assertEqual(
        'ReadOnlyCheckout', pc.context.checkout.__class__.__name__)
    # Ugh.
    self.assertEqual(
        'RietveldMock', pc.context.rietveld.__class__.__name__)
    self._check(
        'stdout',
        'Using read-only Rietveld\n'
        'Using read-only checkout\n'
        'Using read-only chromium-status interface\n')
    self._check(
        'stderr',
        'CQ loop terminating\n'
        'Traceback (most recent call last):\n'
        'Stop\n\n'
        'Saving db...\ndb save successful.\n')


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