Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Python version GenCrc32 code and unit test cases #101

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions edk2basetools/GenCrc32/GenCrc32.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
## @file
# Calculate Crc32 value and Verify Crc32 value for input data.
#
# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is new code, it should probably be "Copyright (c) 2024...." since it wasn't written in 2007.

# SPDX-License-Identifier: BSD-2-Clause-Patent
#
#

##
# Import Modules
#
import logging
import argparse
import sys
from binascii import crc32


parser = argparse.ArgumentParser(description='''
Calculate Crc32 value and Verify Crc32 value for input data.
''')
parser.add_argument("-e", "--encode", dest="EncodeInputFile",
help="Calculate andverify CRC32 value for the input file.")
parser.add_argument("-d", "--decode", dest="DecodeInputFile",
help="Verify CRC32 value for the input file.")
parser.add_argument("-o", "--output", dest="OutputFile",
help="Output file name.")
parser.add_argument("-s", "--silent", help="Returns only the exit code;\
informational and error messages are not displayed.")
parser.add_argument("--version", action="version", version='%(prog)s Version 2.0',
help="Show program's version number and exit.")

group = parser.add_mutually_exclusive_group()
group.add_argument("-v", "--verbose", action="store_true", help="Print information statements")
group.add_argument("-q", "--quiet", action="store_true", help="Disable all messages except fatal errors")


## Calculate the Crc32 and store it in the file
def CalculateCrc32(inputfile: str, outputfile: str, filebytes=b''):
logger = logging.getLogger('GenCrC32')
try:
if filebytes != b'':
InputData = filebytes
CrcCheckSum = crc32(InputData).to_bytes(4, byteorder="little")
else:
with open(inputfile, 'rb') as fin:
InputData = fin.read()
CrcCheckSum = crc32(InputData).to_bytes(4, byteorder="little")
with open(outputfile, 'wb') as fout:
fout.write(CrcCheckSum)
fout.write(InputData)
except Exception as err:
logger.error("Calculation failed!")
raise (err)
return CrcCheckSum


## Verify the CRC and checkout if the file is correct
def VerifyCrc32(inputfile: str, outputfile=""):
logger = logging.getLogger('GenCrC32')
try:
with open(inputfile, 'rb') as fin:
InputData = fin.read()
CurCrcCheckSum = InputData[0:4]
CalCrcCheckSum = CalculateCrc32('', '', InputData[4:])
if CurCrcCheckSum != CalCrcCheckSum:
logger.error("Invalid file!")
elif outputfile != "":
with open(outputfile, 'wb') as fout:
fout.write(InputData[4:])
except Exception as err:
logger.error("Verification failed!")
raise (err)


def main():
args = parser.parse_args()

logger = logging.getLogger('GenCrc32')
if args.quiet:
logger.setLevel(logging.CRITICAL)
if args.verbose:
logger.setLevel(logging.DEBUG)
lh = logging.StreamHandler(sys.stdout)
lf = logging.Formatter("%(levelname)-8s: %(message)s")
lh.setFormatter(lf)
logger.addHandler(lh)

try:
if not args.OutputFile:
parser.print_help()
logger.error("Missing options - outputfile!")
assert ()
if args.EncodeInputFile:
CalculateCrc32(args.EncodeInputFile, args.OutputFile)
elif args.DecodeInputFile:
VerifyCrc32(args.DecodeInputFile, args.OutputFile)
except Exception:
return 1
return 0


if __name__ == "__main__":
exit(main())
10 changes: 10 additions & 0 deletions edk2basetools/GenCrc32/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# @file
# Calculate the crc32 value of file.
#
# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##

# Import Modules
Binary file added edk2basetools/tests/GenCrc32/decode/PcdPeim
Binary file not shown.
Binary file added edk2basetools/tests/GenCrc32/decode/PcdPeim_crc32
Binary file not shown.
Binary file added edk2basetools/tests/GenCrc32/decode/S3Resume2Pei
Binary file not shown.
Binary file not shown.
1 change: 1 addition & 0 deletions edk2basetools/tests/GenCrc32/decode/demo
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is a test file for the GenCrc32 python tool~
1 change: 1 addition & 0 deletions edk2basetools/tests/GenCrc32/decode/demo_crc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
U@"�This is a test file for the GenCrc32 python tool~
Binary file added edk2basetools/tests/GenCrc32/encode/PcdPeim.efi
Binary file not shown.
Binary file added edk2basetools/tests/GenCrc32/encode/PcdPeim_crc32
Binary file not shown.
Binary file not shown.
Binary file not shown.
1 change: 1 addition & 0 deletions edk2basetools/tests/GenCrc32/encode/demo.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is a test file for the GenCrc32 python tool~
1 change: 1 addition & 0 deletions edk2basetools/tests/GenCrc32/encode/demo_crc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
U@"�This is a test file for the GenCrc32 python tool~
117 changes: 117 additions & 0 deletions edk2basetools/tests/GenCrc32/test_gencrc32.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
## @file
# Calculate Crc32 value and Verify Crc32 value for input data.
#
# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same command about the copyright line as above.

# SPDX-License-Identifier: BSD-2-Clause-Patent
#
#

## Import Modules
import shutil
import unittest
import tempfile
import os
import edk2basetools.GenCrc32.GenCrc32 as Gen
import filecmp
import struct as st


class TestGenCrc32(unittest.TestCase):
def setUp(self):
self.tmpdir = tempfile.mkdtemp()
self.binary_file = os.path.join(self.tmpdir, "Binary.bin")
self.create_inputfile()
self.decode_output_folder = os.path.join(os.path.dirname(__file__), r"decode\decode_result")
if not os.path.exists(self.decode_output_folder):
os.mkdir(self.decode_output_folder)
self.encode_output_folder = os.path.join(os.path.dirname(__file__), r"encode\encode_result")
if not os.path.exists(self.encode_output_folder):
os.mkdir(self.encode_output_folder)

def tearDown(self):
if os.path.exists(self.tmpdir):
shutil.rmtree(self.tmpdir)
# if os.path.exists(self.decode_output_folder):
# shutil.rmtree(self.decode_output_folder)
# if os.path.exists(self.encode_output_folder):
# shutil.rmtree(self.encode_output_folder)

def create_inputfile(self):
with open(self.binary_file, "wb") as fout:
for i in range(512):
fout.write(st.pack("<H", i))

def test_crc32encode(self):
inputfile = [
os.path.join(os.path.dirname(__file__), "encode", "demo.bin"),
os.path.join(os.path.dirname(__file__), "encode", "PcdPeim.efi"),
os.path.join(os.path.dirname(__file__), "encode", "S3Resume2Pei.efi")
]

outputfile = [
os.path.join(os.path.dirname(__file__), r"encode\encode_result", "demo_crc_py"),
os.path.join(os.path.dirname(__file__), r"encode\encode_result", "PcdPeim_crc32_py"),
os.path.join(os.path.dirname(__file__), r"encode\encode_result", "S3Resume2Pei_crc32_py")
]

expected_output = [
os.path.join(os.path.dirname(__file__), "encode", "demo_crc"),
os.path.join(os.path.dirname(__file__), "encode", "PcdPeim_crc32"),
os.path.join(os.path.dirname(__file__), "encode", "S3Resume2Pei_crc32")
]
for index, o in enumerate(inputfile):
output = outputfile[index]
try:
Gen.CalculateCrc32(o, output)
status = filecmp.cmp(output, expected_output[index])
except Exception:
self.assertTrue(False, msg="GenCrc32 encode function error")
self.assertEqual(status, 1)

def test_crc32decode(self):
inputfile = [
os.path.join(os.path.dirname(__file__), "decode", "demo_crc"),
os.path.join(os.path.dirname(__file__), "decode", "PcdPeim_crc32"),
os.path.join(os.path.dirname(__file__), "decode", "S3Resume2Pei_crc32")
]

outputfile = [
os.path.join(os.path.dirname(__file__), r"decode\decode_result", "demo_decode"),
os.path.join(os.path.dirname(__file__), r"decode\decode_result", "PcdPeim_decode"),
os.path.join(os.path.dirname(__file__), r"decode\decode_result", "S3Resume2Pei_decode")
]

expected_output = [
os.path.join(os.path.dirname(__file__), "decode", "demo"),
os.path.join(os.path.dirname(__file__), "decode", "PcdPeim"),
os.path.join(os.path.dirname(__file__), "decode", "S3Resume2Pei")
]

for index, o in enumerate(inputfile):
output = outputfile[index]
try:
Gen.VerifyCrc32(o, output)
status = filecmp.cmp(output, expected_output[index])
except Exception:
self.assertTrue(False, msg="GenCrc32 decode function error")
self.assertEqual(status, 1)

def test_CalculateCrc32_outputfile(self):
output = [
os.path.join(self.tmpdir, "Binary1.bin")
]

expected_output = [
os.path.join(self.tmpdir, "Binary1.bin")
]

for index, o in enumerate(output):
try:
Gen.CalculateCrc32(self.binary_file, o)
except Exception:
self.assertTrue(False, msg="GenCrc32 output file directory error")
self.assertTrue(os.path.exists(expected_output[index]))


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