blob: 4ba0c6682755304c19381de423b4be2d5179fd67 [file] [log] [blame]
# Copyright 2014 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.
"""Unittests for the filetype.py module."""
from __future__ import print_function
import os
import stat
from chromite.lib import cros_test_lib
from chromite.lib import osutils
from chromite.lib import filetype
from chromite.lib import unittest_lib
class SplitShebangTest(cros_test_lib.TestCase):
"""Test the SplitShebang function."""
def testSimpleCase(self):
"""Test a simple case."""
self.assertEquals(('/bin/sh', ''), filetype.SplitShebang('#!/bin/sh'))
def testCaseWithArguments(self):
"""Test a case with arguments."""
self.assertEquals(('/bin/sh', '-i -c "ls"'),
filetype.SplitShebang('#!/bin/sh -i -c "ls"'))
def testCaseWithEndline(self):
"""Test a case finished with a newline char."""
self.assertEquals(('/bin/sh', '-i'),
filetype.SplitShebang('#!/bin/sh -i\n'))
def testCaseWithSpaces(self):
"""Test a case with several spaces in the line."""
self.assertEquals(('/bin/sh', '-i'),
filetype.SplitShebang('#! /bin/sh -i \n'))
def testInvalidCases(self):
"""Thes invalid cases."""
self.assertRaises(ValueError, filetype.SplitShebang, '/bin/sh -i')
self.assertRaises(ValueError, filetype.SplitShebang, '#!')
self.assertRaises(ValueError, filetype.SplitShebang, '#!env python')
class FileTypeDecoderTest(cros_test_lib.TempDirTestCase):
"""Test the FileTypeDecoder class."""
def testSpecialFiles(self):
"""Tests special files, such as symlinks, directories and named pipes."""
somedir = os.path.join(self.tempdir, 'somedir')
osutils.SafeMakedirs(somedir)
self.assertEquals('inode/directory',
filetype.FileTypeDecoder.DecodeFile(somedir))
a_fifo = os.path.join(self.tempdir, 'a_fifo')
os.mknod(a_fifo, stat.S_IFIFO)
self.assertEquals('inode/special',
filetype.FileTypeDecoder.DecodeFile(a_fifo))
empty_file = os.path.join(self.tempdir, 'empty_file')
osutils.WriteFile(empty_file, '')
self.assertEquals('inode/empty',
filetype.FileTypeDecoder.DecodeFile(empty_file))
a_link = os.path.join(self.tempdir, 'a_link')
os.symlink('somewhere', a_link)
self.assertEquals('inode/symlink',
filetype.FileTypeDecoder.DecodeFile(a_link))
def testTextShebangFiles(self):
"""Test shebangs (#!) file decoding based on the executed path."""
# If the file has only one line is considered a "shebang" rather than a
# script.
shebang = os.path.join(self.tempdir, 'shebang')
osutils.WriteFile(shebang, "#!/bin/python --foo --bar\n")
self.assertEquals('text/shebang',
filetype.FileTypeDecoder.DecodeFile(shebang))
# A shebang with contents is considered a script.
script = os.path.join(self.tempdir, 'script')
osutils.WriteFile(script, "#!/bin/foobar --foo --bar\n\nexit 1\n")
self.assertEquals('text/script',
filetype.FileTypeDecoder.DecodeFile(script))
bash_script = os.path.join(self.tempdir, 'bash_script')
osutils.WriteFile(bash_script,
"#!/bin/bash --debug\n# Copyright\nexit 42\n")
self.assertEquals('text/script/bash',
filetype.FileTypeDecoder.DecodeFile(bash_script))
pyscript = os.path.join(self.tempdir, 'pyscript')
osutils.WriteFile(pyscript,
"#!/usr/bin/env PYTHONPATH=/foo python-2.7 -3\n# foo\n")
self.assertEquals('text/script/python',
filetype.FileTypeDecoder.DecodeFile(pyscript))
perlscript = os.path.join(self.tempdir, 'perlscript')
osutils.WriteFile(perlscript, "#!/usr/local/bin/perl\n#\n")
self.assertEquals('text/script/perl',
filetype.FileTypeDecoder.DecodeFile(perlscript))
def testTextPEMFiles(self):
"""Test decoding various PEM files."""
# A RSA private key (sample from update_engine unittest).
some_cert = os.path.join(self.tempdir, 'some_cert')
osutils.WriteFile(some_cert,
"""-----BEGIN CERTIFICATE-----
MIIDJTCCAo6gAwIBAgIJAP6IycaMXlqsMA0GCSqGSIb3DQEBBQUAMIGLMQswCQYD
VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTETMBEGA1UEChMKR29vZ2xlIElu
YzESMBAGA1UECxMJQ2hyb21lIE9TMRgwFgYDVQQDEw9PcGVuU1NMIFRlc3QgQ0Ex
JDAiBgkqhkiG9w0BCQEWFXNlY3VyaXR5QGNocm9taXVtLm9yZzAgFw0xMjA1MTcx
OTQ1MjJaGA8yMTEyMDExNDE5NDUyMlowgZ0xCzAJBgNVBAYTAlVTMRMwEQYDVQQI
EwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKEwpH
b29nbGUgSW5jMRIwEAYDVQQLEwlDaHJvbWUgT1MxEjAQBgNVBAMTCTEyNy4wLjAu
MTEkMCIGCSqGSIb3DQEJARYVc2VjdXJpdHlAY2hyb21pdW0ub3JnMIGfMA0GCSqG
SIb3DQEBAQUAA4GNADCBiQKBgQC5bxzyvNJFDmyThIGoFoZkN3rlQB8QoR80rS1u
8pLyqW5Vk2A0pNOvcxPrUHAUTgWhikqzymz4a4XoLxat53H/t/XmRYwZ9GVNZocz
Q4naWxtPyPqIBosMLnWu6FHUVO1lTdvhC6Pjw2i1S9Rq3dMsANU1IER4NR8XM+v6
qBg1XQIDAQABo3sweTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NM
IEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQU+biqy5tbRGlUNLsEtjmy
7v1eYqowHwYDVR0jBBgwFoAUC0E889mD7bn2fXcEtA3HvUimV+0wDQYJKoZIhvcN
AQEFBQADgYEA2fJxpGwDbnUF5Z3mvZ81/pk8fVQdJvV5U93EA29VE1SaFA5S5qYS
zP1Ue0MX+RqMLKjnH+E6yEoo+kYD9rzagnvORefbJeM92SiHgHPeSm8F1nQtGclj
p8izLBlcKgPHwQLKxELmbS/xvt4cyHaLSIy50lLrdJeKtXjqq4PbH3Y=
-----END CERTIFICATE-----
""")
self.assertEquals('text/pem/cert',
filetype.FileTypeDecoder.DecodeFile(some_cert))
# A RSA private key (sample from vboot_reference unittest).
rsa_key = os.path.join(self.tempdir, 'rsa_key')
osutils.WriteFile(rsa_key,
"""-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCdYBOJIJvGX9vC4E5XD1jb9zJ99FzR4G0n8HNyWy5ZKyy/hi80
ibXpy6QdWcm4wqTvmVjU+20sP4AgzKC65fKyFvvAHUiD4yGr1qWtg4YFUcBbUiXO
CQ66W3AC4g2Ju9C16AzMpBk043bQsUQvxILEumQqQ1VS33uM7Kq8dWpL6QIDAQAB
AoGAb12y1WIu+gWRtWkX5wHkRty6bWmEWbzwYcgFWlJuDQnBg9MICqy8/7Js85w7
ZLTRFQC2XRmDW0GggRVtVHUu9X2jwkHR9+TWza4xAtYcSwDl6VJTHX2ygptrG/n9
qPFinfvnpiP7b2WNjC53V3cnjg3m+1B5zrmFxsVLDMVLQhECQQDN7i1NWZFVNfYa
GT2GSgMpD0nPXA1HHUvFFgnI9xJkBCewHzega+PrrrpMKZZWLpc4YCm3PK9nI8Nk
EmJE5HwNAkEAw6OpiOgWdRaJWx3+XBsFOhz6K86xwV0NpVb6ocrBKU/t0OqP+gZh
B/YBDfwXPr2w5FCwozUs/MrBdoYR3WnsTQJABNn/pzrc+azzx1mg4XEM8gKyMnhw
t6QxDMugH2Pywvh2FuglX1orXHoZWYIBULZ4SZO6Z96+IyfsiocEWasoYQJBALZ/
onO7BM/+0Oz1osSq1Aps45Yf/0OAmW0mITDyIZR3IkJjvSEf+D3j5wHzqn91lmC1
QMFOpoO+ZBA7asjfuXUCQGmHgpC0BuD4S1QlcF0nrVHTG7Y8KZ18s9qPJS3csuGf
or10mrNRF3tyGy8e/sw88a74Q/6v/PgChZHmq6QjOOU=
-----END RSA PRIVATE KEY-----
""")
self.assertEquals('text/pem/rsa-private',
filetype.FileTypeDecoder.DecodeFile(rsa_key))
def testBinaryELFFiles(self):
"""Test decoding ELF files."""
liba_so = os.path.join(self.tempdir, 'liba.so')
unittest_lib.BuildELF(liba_so, ['func_a'])
self.assertEquals('binary/elf/dynamic-so',
filetype.FileTypeDecoder.DecodeFile(liba_so))
prog = os.path.join(self.tempdir, 'prog')
unittest_lib.BuildELF(prog,
undefined_symbols=['func_a'],
used_libs=['a'],
executable=True)
self.assertEquals('binary/elf/dynamic-bin',
filetype.FileTypeDecoder.DecodeFile(prog))
prog_static = os.path.join(self.tempdir, 'prog_static')
unittest_lib.BuildELF(prog_static, executable=True, static=True)
self.assertEquals('binary/elf/static',
filetype.FileTypeDecoder.DecodeFile(prog_static))
def testBinaryCompressedFiles(self):
"""Test decoding compressed files."""
compressed = os.path.join(self.tempdir, 'compressed')
# `echo hola | gzip -9`
osutils.WriteFile(compressed,
'\x1f\x8b\x08\x00<\xce\x07T\x02\x03\xcb\xc8\xcfI\xe4\x02'
'\x00x\xad\xdb\xd1\x05\x00\x00\x00')
self.assertEquals('binary/compressed/gzip',
filetype.FileTypeDecoder.DecodeFile(compressed))
# `echo hola | bzip2 -9`
osutils.WriteFile(compressed,
'BZh91AY&SY\xfa\xd4\xdb5\x00\x00\x01A\x00\x00\x10 D\xa0'
'\x00!\x83A\x9a\t\xa8qw$S\x85\t\x0f\xadM\xb3P')
self.assertEquals('binary/compressed/bzip2',
filetype.FileTypeDecoder.DecodeFile(compressed))
# `echo hola | xz -9`
osutils.WriteFile(
compressed,
'\xfd7zXZ\x00\x00\x04\xe6\xd6\xb4F\x02\x00!\x01\x16\x00\x00\x00t/\xe5'
'\xa3\x01\x00\x04hola\n\x00\x00\x00\x00\xdd\xb0\x00\xac6w~\x9d\x00\x01'
'\x1d\x05\xb8-\x80\xaf\x1f\xb6\xf3}\x01\x00\x00\x00\x00\x04YZ')
self.assertEquals('binary/compressed/xz',
filetype.FileTypeDecoder.DecodeFile(compressed))
def testBinaryMiscFiles(self):
"""Test for various binary file formats."""
# A timezone file.
some_timezone = os.path.join(self.tempdir, 'some_timezone')
osutils.WriteFile(
some_timezone,
'TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
'\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
'\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\x00\x00TZif2'
'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
'\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
'\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\x00\x00\nUTC0\n')
self.assertEquals('binary/tzfile',
filetype.FileTypeDecoder.DecodeFile(some_timezone))
# A x86 boot sector with just nops.
bootsec = os.path.join(self.tempdir, 'bootsec')
osutils.WriteFile(bootsec, '\x90' * 510 + '\x55\xaa')
self.assertEquals('binary/bootsector/x86',
filetype.FileTypeDecoder.DecodeFile(bootsec))