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

"""Test signer_payloads_client library."""

import mox
import os
import shutil
import socket
import tempfile
import unittest

import fixup_path
fixup_path.FixupPath()

from chromite.lib import cros_test_lib

from chromite.lib.paygen import gslib
from chromite.lib.paygen import gslock
from chromite.lib.paygen import signer_payloads_client
from chromite.lib.paygen import utils


# pylint: disable=W0212


class SignerPayloadsClientGoogleStorageTest(mox.MoxTestBase):
  """Test suite for the class SignerPayloadsClientGoogleStorage."""

  def setUp(self):
    """Setup for tests, and store off some standard expected values."""

    mox.MoxTestBase.setUp(self)

    self.hash_names = [
        '1.payload.hash',
        '2.payload.hash',
        '3.payload.hash']

    self.build_uri = ('gs://foo-bucket/foo-channel/foo-board/foo-version/'
                      'payloads/signing/foo-unique')

    # To make certain we don't self update while running tests.
    os.environ['CROSTOOLS_NO_SOURCE_UPDATE'] = '1'

  def createStandardClient(self):
    """Test helper method to create a client with standard arguments."""

    client = signer_payloads_client.SignerPayloadsClientGoogleStorage(
        'foo-channel',
        'foo-board',
        'foo-version',
        bucket='foo-bucket',
        unique='foo-unique')
    return client

  def testUris(self):
    """Test that the URIs on the client are correct."""

    client = self.createStandardClient()

    expected_build_uri = self.build_uri

    self.assertEquals(
        client.signing_base_dir,
        expected_build_uri)

    self.assertEquals(
        client.archive_uri,
        expected_build_uri + '/payload.hash.tar.bz2')

  def testCleanSignerFilesByKeyset(self):
    """Test the keyset specific cleanup works as expected."""

    hashes = ('hash-1', 'hash-2')
    keyset = 'foo-keys'

    lock_uri = ('gs://foo-bucket/tobesigned/45,foo-channel,foo-board,'
                'foo-version,payloads,signing,foo-unique,'
                'foo-keys.payload.signer.instructions.lock')

    signing_dir = ('gs://foo-bucket/foo-channel/foo-board/foo-version/'
                   'payloads/signing/foo-unique')

    expected_removals = (
      # Signing Request
      'gs://foo-bucket/tobesigned/45,foo-channel,foo-board,foo-version,'
      'payloads,signing,foo-unique,'
      'foo-keys.payload.signer.instructions',

      # Signing Instructions
      signing_dir + '/foo-keys.payload.signer.instructions',

      # Signed Results`
      signing_dir + '/1.payload.hash.foo-keys.signed.bin',
      signing_dir + '/1.payload.hash.foo-keys.signed.bin.md5',
      signing_dir + '/2.payload.hash.foo-keys.signed.bin',
      signing_dir + '/2.payload.hash.foo-keys.signed.bin.md5',
    )

    client = self.createStandardClient()

    self.mox.StubOutWithMock(gslock, 'Lock')
    self.mox.StubOutWithMock(gslib, 'Remove')

    # pylint: disable=E1101
    # Fail to acquire the lock the first time.
    gslock.Lock(lock_uri).AndRaise(gslock.LockNotAcquired())

    lock = self.mox.CreateMockAnything()

    gslock.Lock(lock_uri).AndReturn(lock)
    lock.__enter__().AndReturn(lock)
    lock.__exit__(
        mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(None)

    for uri in expected_removals:
      gslib.Remove(uri, ignore_no_match=True).InAnyOrder()

    self.mox.ReplayAll()

    client._CleanSignerFilesByKeyset(hashes, keyset)

    self.mox.VerifyAll()

  def testCleanSignerFiles(self):
    """Test that GS cleanup works as expected."""

    hashes = ('hash-1', 'hash-2')
    keysets = ('foo-keys-1', 'foo-keys-2')

    lock_uri1 = ('gs://foo-bucket/tobesigned/45,foo-channel,foo-board,'
                'foo-version,payloads,signing,foo-unique,'
                'foo-keys-1.payload.signer.instructions.lock')

    lock_uri2 = ('gs://foo-bucket/tobesigned/45,foo-channel,foo-board,'
                'foo-version,payloads,signing,foo-unique,'
                'foo-keys-2.payload.signer.instructions.lock')

    signing_dir = ('gs://foo-bucket/foo-channel/foo-board/foo-version/'
                   'payloads/signing/foo-unique')

    expected_removals = (
      # Signing Request
      'gs://foo-bucket/tobesigned/45,foo-channel,foo-board,foo-version,'
      'payloads,signing,foo-unique,'
      'foo-keys-1.payload.signer.instructions',

      'gs://foo-bucket/tobesigned/45,foo-channel,foo-board,foo-version,'
      'payloads,signing,foo-unique,'
      'foo-keys-2.payload.signer.instructions',

      # Signing Instructions
      signing_dir + '/foo-keys-1.payload.signer.instructions',
      signing_dir + '/foo-keys-2.payload.signer.instructions',

      # Signed Results
      signing_dir + '/1.payload.hash.foo-keys-1.signed.bin',
      signing_dir + '/1.payload.hash.foo-keys-1.signed.bin.md5',
      signing_dir + '/2.payload.hash.foo-keys-1.signed.bin',
      signing_dir + '/2.payload.hash.foo-keys-1.signed.bin.md5',
      signing_dir + '/1.payload.hash.foo-keys-2.signed.bin',
      signing_dir + '/1.payload.hash.foo-keys-2.signed.bin.md5',
      signing_dir + '/2.payload.hash.foo-keys-2.signed.bin',
      signing_dir + '/2.payload.hash.foo-keys-2.signed.bin.md5',
    )

    client = self.createStandardClient()

    self.mox.StubOutWithMock(gslock, 'Lock')
    self.mox.StubOutWithMock(gslib, 'Remove')


    lock1 = self.mox.CreateMockAnything()
    gslock.Lock(lock_uri1).AndReturn(lock1)
    lock1.__enter__().AndReturn(lock1)
    lock1.__exit__(
        mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(None)

    lock2 = self.mox.CreateMockAnything()
    gslock.Lock(lock_uri2).AndReturn(lock2)
    lock2.__enter__().AndReturn(lock2)
    lock2.__exit__(
        mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(None)

    for uri in expected_removals:
      gslib.Remove(uri, ignore_no_match=True).InAnyOrder()

    gslib.Remove(signing_dir, ignore_no_match=True, recurse=True).InAnyOrder()

    self.mox.ReplayAll()

    client._CleanSignerFiles(hashes, keysets)

    self.mox.VerifyAll()


  def testCreateInstructionsUri(self):
    """Test that the expected instructions URI is correct."""

    client = self.createStandardClient()

    signature_uri = client._CreateInstructionsURI('keyset_foo')

    expected_signature_uri = (
        self.build_uri +
        '/keyset_foo.payload.signer.instructions')

    self.assertEqual(signature_uri, expected_signature_uri)

  def testCreateHashNames(self):
    """Test that the expected hash names are generated."""

    client = self.createStandardClient()

    hash_names = client._CreateHashNames(3)

    expected_hash_names = self.hash_names

    self.assertEquals(hash_names, expected_hash_names)

  def testCreateSignatureURIs(self):
    """Test that the expected signature URIs are generated."""

    client = self.createStandardClient()

    signature_uris = client._CreateSignatureURIs(self.hash_names,
                                                 'keyset_foo')

    expected_signature_uris = [
        self.build_uri + '/1.payload.hash.keyset_foo.signed.bin',
        self.build_uri + '/2.payload.hash.keyset_foo.signed.bin',
        self.build_uri + '/3.payload.hash.keyset_foo.signed.bin',
        ]

    self.assertEquals(signature_uris, expected_signature_uris)

  def testCreateArchive(self):
    """Test that we can correctly archive up hash values for the signer."""

    client = self.createStandardClient()

    tmp_dir = None
    hashes = ['Hash 1', 'Hash 2', 'Hash 3']

    try:
      with tempfile.NamedTemporaryFile() as archive_file:
        client._CreateArchive(archive_file.name, hashes, self.hash_names)

        # Make sure the archive file created exists
        self.assertTrue(os.path.exists(archive_file.name))

        tmp_dir = tempfile.mkdtemp()

        cmd = ['tar', '-xjf', archive_file.name]
        utils.RunCommand(cmd,
                         redirect_stdout=True,
                         redirect_stderr=True,
                         cwd=tmp_dir)

        # Check that the expected (and only the expected) contents are present
        extracted_file_names = os.listdir(tmp_dir)
        self.assertEquals(len(extracted_file_names), len(self.hash_names))
        for name in self.hash_names:
          self.assertTrue(name in extracted_file_names)

        # Make sure each file has the expected contents
        for h, hash_name in zip(hashes, self.hash_names):
          with open(os.path.join(tmp_dir, hash_name), 'r') as f:
            self.assertEqual([h], f.readlines())

    finally:
      # Clean up at the end of the test
      if tmp_dir:
        shutil.rmtree(tmp_dir)

  def testCreateInstructions(self):
    """Test that we can correctly create signer instructions."""

    client = self.createStandardClient()

    instructions = client._CreateInstructions(self.hash_names, 'keyset_foo')

    expected_instructions = """
# Auto-generated instruction file for signing payload hashes.

[insns]
generate_metadata = false
keyset = keyset_foo
channel = foo

input_files = %s
output_names = @BASENAME@.@KEYSET@.signed

[general]
archive = metadata-disable.instructions
type = update_payload
board = foo-board

archive = payload.hash.tar.bz2

# We reuse version for version rev because we may not know the
# correct versionrev "R24-1.2.3"
version = foo-version
versionrev = foo-version
""" % " ".join(['1.payload.hash',
                '2.payload.hash',
                '3.payload.hash'])

    self.assertEquals(instructions, expected_instructions)

  def testSignerRequestUri(self):
    """Test that we can create signer request URI."""

    client = self.createStandardClient()

    instructions_uri = client._CreateInstructionsURI('foo_keyset')
    signer_request_uri = client._SignerRequestUri(instructions_uri)

    expected = ('gs://foo-bucket/tobesigned/45,foo-channel,foo-board,'
                'foo-version,payloads,signing,foo-unique,'
                'foo_keyset.payload.signer.instructions')

    self.assertEquals(signer_request_uri, expected)

  def testWaitForSignaturesInstant(self):
    """Test that we can correctly wait for a list of URIs to be created."""

    self.mox.StubOutWithMock(gslib, 'Exists')

    # Assert that each uri is tested exactly once.
    gslib.Exists('foo').InAnyOrder().AndReturn(True)
    gslib.Exists('bar').InAnyOrder().AndReturn(True)
    gslib.Exists('is').InAnyOrder().AndReturn(True)

    self.mox.ReplayAll()

    uris = ['foo', 'bar', 'is']

    client = self.createStandardClient()
    self.assertTrue(client._WaitForSignatures(uris))

    self.mox.VerifyAll()

  def testWaitForSignaturesNever(self):
    """Test that we can correctly timeout waiting for a list of URIs."""

    self.mox.StubOutWithMock(gslib, 'Exists')
    gslib.Exists(mox.IsA(str)).MultipleTimes().AndReturn(False)

    self.mox.ReplayAll()

    uris = ['foo', 'bar', 'is']

    client = self.createStandardClient()
    self.assertFalse(client._WaitForSignatures(uris, timeout=5))

    self.mox.VerifyAll()

  def testDownloadSignatures(self):
    """Test that we can correctly download a list of URIs."""

    uris = ['gs://chromeos-releases-test/sigining-test/foo',
            'gs://chromeos-releases-test/sigining-test/bar']

    client = self.createStandardClient()
    downloads = client._DownloadSignatures(uris)
    self.assertEquals(downloads, ['FooSig\r\n\r', 'BarSig'])


class SignerPayloadsClientIntegrationTest(mox.MoxTestBase):
  """Test suite integration with live signer servers."""

  @cros_test_lib.NetworkTest()
  def testGetHashSignatures(self):
    """Integration test that talks to the real signer with test hashes."""

    unique_id = "%s.%d" % (socket.gethostname(), os.getpid())
    clean_uri = ('gs://chromeos-releases/test-channel/%s/'
                 'crostools-client/**') % unique_id

    # Cleanup before we start
    gslib.Remove(clean_uri, ignore_no_match=True)

    try:
      # This is in the real production chromeos-releases, but the listed
      # build has never, and will never exist.
      client = signer_payloads_client.SignerPayloadsClientGoogleStorage(
          'test-channel',
          'crostools-client',
          'Rxx-Ryy')

      hashes = ['0' * 32,
                '1' * 32,
                ('29834370e415b3124a926c903906f18b'
                 '3d52e955147f9e6accd67e9512185a63')]

      keysets = ['update_signer']

      expected_sigs_hex = (
        ('ba4c7a86b786c609bf6e4c5fb9c47525608678caa532bea8acc457aa6dd32b43'
         '5f094b331182f2e167682916990c40ff7b6b0128de3fa45ad0fd98041ec36d6f'
         '63b867bcf219804200616590a41a727c2685b48340efb4b480f1ef448fc7bc3f'
         'b1c4b53209e950ecc721b07a52a41d9c025fd25602340c93d5295211308caa29'
         'a03ed18516cf61411c508097d5b47620d643ed357b05213b2b9fa3a3f938d6c4'
         'f52b85c3f9774edc376902458344d1c1cd72bc932f033c076c76fee2400716fe'
         '652306871ba923021ce245e0c778ad9e0e50e87a169b2aea338c4dc8b5c0c716'
         'aabfb6133482e8438b084a09503db27ca546e910f8938f7805a8a76a3b0d0241',),

        ('2d909ca5b33a7fb6f2323ca0bf9de2e4f2266c73da4b6948a517dffa96783e08'
         'ca36411d380f6e8a20011f599d8d73576b2a141a57c0873d089726e24f62c7e0'
         '346ba5fbde68414b0f874b627fb1557a6e9658c8fac96c54f458161ea770982b'
         'fa9fe514120635e5ccb32e8219b9069cb0bf8063fba48d60d649c5af203cccef'
         'ca5dbc2191f81f0215edbdee4ec8c1553e69b83036aca3e840227d317ff6cf8b'
         '968c973f698db1ce59f6871303dcdbe839400c5df4d2e6e505d68890010a4459'
         '6ca9fee77f4db6ea3448d98018437c319fc8c5f4603ef94b04e3a4eafa206b73'
         '91a2640d43128310285bc0f1c7e5060d37c433d663b1c6f01110b9a43f2a74f4',),

        ('23791c99ab937f1ae5d4988afc9ceca39c290ac90e3da9f243f9a0b1c86c3c32'
         'ab7241d43dfc233da412bab989cf02f15a01fe9ea4b2dc7dc9182117547836d6'
         '9310af3aa005ee3a6deb9602bc676dcc103bf3f7831d64ab844b4785c5c8b4b1'
         '4467e6b5ab6bf34c12f7534e0d5140151c8f28e8276e703dd6332c2bab9e7f4a'
         '495215998ff56e476b81bd6b8d765e1f87da50c22cd52c9afa8c43a6528ab898'
         '6d7a273d9136d5aff5c4d95985d16eeec7380539ef963e0784a0de42b42890df'
         'c83702179f69f5c6eca4630807fbc4ab6241017e0942b15feada0b240e9729bf'
         '33bf456bd419da63302477e147963550a45c6cf60925ff48ad7b309fa158dcb2',))

      expected_sigs = [[sig[0].decode('hex')] for sig in expected_sigs_hex]

      all_signatures = client.GetHashSignatures(hashes, keysets)

      self.assertEquals(all_signatures, expected_sigs)
      self.assertEquals(gslib.List(clean_uri), [])

    finally:
      # Cleanup when we are over
      gslib.Remove(clean_uri, ignore_no_match=True)


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