# 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))