chromium/chrome/tools/build/win/makecab_test.py

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

import makecab

from StringIO import StringIO
import sys
import time
import unittest

# Test flag parsing.
class ParseFlagsTest(unittest.TestCase):
  def testInputOnly(self):
    flags = makecab.ParseFlags(['/V1', '/D', 'CompressionType=LZX', 'foo.txt'])
    self.assertEquals(flags.input, 'foo.txt')
    self.assertEquals(flags.output, 'foo.tx_')
    self.assertEquals(flags.output_dir, '.')

  def testInputOutput(self):
    flags = makecab.ParseFlags(['bar.txt', 'd/foo.cab'])
    self.assertEquals(flags.input, 'bar.txt')
    self.assertEquals(flags.output, 'd/foo.cab')
    self.assertEquals(flags.output_dir, '.')

  def testInputOutdir(self):
    flags = makecab.ParseFlags(['/L', 'outdir', 'baz.txt'])
    self.assertEquals(flags.input, 'baz.txt')
    self.assertEquals(flags.output, 'baz.tx_')
    self.assertEquals(flags.output_dir, 'outdir')

  def testInputOutputOutdir(self):
    flags = makecab.ParseFlags(['/L', 'outdir', 'foo.txt', 'd/foo.cab'])
    self.assertEquals(flags.input, 'foo.txt')
    self.assertEquals(flags.output, 'd/foo.cab')
    self.assertEquals(flags.output_dir, 'outdir')

  def testHelp(self):
    self.assertEquals(makecab.ParseFlags(['foo.txt', '--help']), None)

  def assertFlagParseError(self, flags, expected_message_part):
    with self.assertRaises(makecab.FlagParseError) as context:
      makecab.ParseFlags(flags)
    self.assertIn(expected_message_part, context.exception.message)

  def testErrors(self):
    for f in ['/D', '/L']:
      self.assertFlagParseError([f], 'argument needed after')
    self.assertFlagParseError(['/asdf'], 'unknown flag')
    self.assertFlagParseError(['in', 'out', 'what'], 'too many paths')
    self.assertFlagParseError([], 'no input file')

# Test that compression doesn't throw, and on Windows also check that
# expand.exe is able to recover input data.
class WriteCabTest(unittest.TestCase):
  def testWellCompressingInput(self):
    input_data = 'a' * (4 << 15)
    output = StringIO()
    mtime = time.mktime((2018, 1, 8,  16, 00, 00,  0, 8, -1))
    makecab.WriteCab(output, StringIO(input_data), 'a.txt',
                     len(input_data), mtime)
    if sys.platform == 'win32':
      import os, shutil, subprocess, tempfile
      temp_dir = tempfile.mkdtemp(suffix='.makecab_test')
      try:
        cab_path = os.path.join(temp_dir, 'file.cab')
        out_path = os.path.join(temp_dir, 'file.out')
        open(cab_path, 'wb').write(output.getvalue())
        FNULL = open(os.devnull, 'w')
        subprocess.check_call(['expand.exe', cab_path, out_path], stdout=FNULL)
        self.assertEquals(input_data, open(out_path, 'rb').read())
      finally:
        shutil.rmtree(temp_dir)


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