@@ -1,3 +1,4 @@
pytest >= 7.2.0
pylint >= 2.15.10
-black >= 22.12.0
\ No newline at end of file
+black >= 22.12.0
+python-libarchive >= 4.2.1
\ No newline at end of file
new file mode 100644
@@ -0,0 +1,5 @@
+variables:
+{
+ UPDATE_VERSION = "1.0.0";
+ PRODUCT = "test device";
+}
\ No newline at end of file
new file mode 100644
@@ -0,0 +1,95 @@
+software =
+{
+ version = "@@UPDATE_VERSION@@";
+ description = "Firmware update for @@PRODUCT@@";
+
+ hardware-compatibility: [ "1.0", "1.2", "1.3"];
+
+ /* partitions tag is used to resize UBI partitions */
+ partitions: ( /* UBI Volumes */
+ {
+ name = "rootfs";
+ device = "mtd4";
+ size = 104896512; /* in bytes */
+ },
+ {
+ name = "data";
+ device = "mtd5";
+ size = 50448384; /* in bytes */
+ }
+ );
+
+
+ images: (
+ {
+ filename = "rootfs.ubifs";
+ volume = "rootfs";
+ encrypted = true;
+ },
+ {
+ filename = "swupdate.ext3.gz.u-boot";
+ volume = "fs_recovery";
+ encrypted = true;
+ },
+ {
+ filename = "sdcard.ext3.gz";
+ device = "/dev/mmcblk0p1";
+ compressed = "zlib";
+ encrypted = true;
+ },
+ {
+ filename = "bootlogo.bmp";
+ volume = "splash";
+ encrypted = true;
+ },
+ {
+ filename = "uImage.bin";
+ volume = "kernel";
+ encrypted = true;
+ },
+ {
+ filename = "fpga.txt";
+ type = "fpga";
+ encrypted = true;
+ },
+ {
+ filename = "bootloader-env";
+ type = "bootloader";
+ encrypted = true;
+ }
+ );
+
+ files: (
+ {
+ filename = "README";
+ path = "/README";
+ device = "/dev/mmcblk0p1";
+ filesystem = "vfat";
+ encrypted = true;
+ }
+ );
+
+ scripts: (
+ {
+ filename = "erase_at_end";
+ type = "lua";
+ encrypted = true;
+ },
+ {
+ filename = "display_info";
+ type = "lua";
+ encrypted = true;
+ }
+ );
+
+ bootenv: (
+ {
+ name = "vram";
+ value = "4M";
+ },
+ {
+ name = "addfb";
+ value = "setenv bootargs ${bootargs} omapfb.vram=1:2M,2:2M,3:2M omapdss.def_disp=lcd"
+ }
+ );
+}
\ No newline at end of file
new file mode 100644
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEA8e++KmilZGCc+906v/nQwbwipjiHHqfU6z/Zrr1Dbin2P4w6
+Pe2oabKa/2Ov2tKKylISBtXOyi4aVOiWyl2ZPhAj3B4EhqehwRb/2GwmqwsrL4Xq
+iJlNIVTfoMBi1ULy4hMWeVmdc3Z88/bf1WI2kfAK9nBqiDHWBILTNA+YtVv1XomP
+mYQi6W8FN8mdYMWgQy+C/T1p6WuDm9mlHQOHlzesoWIO6lkXTe7bsSb1DU4u886P
+CVoBCe0w2LnuzCTISiUXpgHKdlS9SrAfVvCdrGPBxlrt6DFe6QBsvSVZXd7EanLZ
+X75Um42wSHAWsAHPZlzVtRweBBKkF7fkIe4fvwIDAQABAoIBABkLOCQrsPMzDQ0F
+WY+FzJZBY1TRhSsnNGMluOLdtJ0yusrZOS4v678FPgYxy4JbSQKofDU47K8BFriz
+WuiXx8Uk5pFiihVmRNg4CUPd7iLGhTHmKuD4/YL1xjBdud1ZkMrWLv1gyWuqWETo
+yULNZ9izgG8CNATlI8JTyIkbFDOxnanQJwwEk+BRNqAwEgT8DMVgSyCmhjUVis81
+mDXxXDqGN/xSkRudfFuAgv3bx3aojV8v6+ehdA8w0eeKPhgJjDJYcLUh8yNZheO+
+MGd0WIkOBwZmt9m0knxkzil/Z75ZsRPc8wTw7PDSu0w8swc8EVdFHpJYbfxSyIdm
+IrQrzAECgYEA/61Pt6XgShHawta1k/Lr5Z6Bh4lXOX94RS2xFgIz7e2HqQd6QPUX
+h4vJnZ2W837XcFGsuajfF+roCAo8rZFGup3kpcIRnxc/hWRAsoB+/40u/IFwgHEQ
+FuUaxqK47VbCtkdEILQIBkMHNSEYO2Ko/n6nmoOXZkzDDK0CFqfP8bsCgYEA8j38
+1Hk9NaN2aZJVw83sYTshSLM7qoq23trSiwv1jliwheue2Epw9XT7CQF+5ktxwyvl
+CZ7Eu9BYcFcWZpPwAcCa5U1/jjC343maIvbeTBtV+aFg1UxlpsVu6S+lu8+CHVL0
+f9g+FYZsqkl03ZGbguRx/e48QJfiuqe9384ZV80CgYAkcxG9TbGG/bqhMjjaqbQF
+nS48I1FDCjAcNKJdT90VW1qOt1kvb4F2OnB4vuGpPvj5szsbkL6VS1De7I6v89kQ
+e7gABYW7l3Xfz2YFzJnOVtNO/ikKtpOjn+/MR6BzfX3uvIQy4VePhPi/E0PAG5Wa
+CnZcacwosmLQKM32auATRwKBgGUJk9Xvh6dCudYI0jrsPgbECfrvvxg/6UyEisKy
+R0aLGX2SLFvcmMbYdwhnlk1p9FZKjap4jWgk225n9JDubXHdqv2vWF+vVFPN2Ytx
+2oB1+mM3e1McHV31BXC/jeoLACNJAW/9es+xlMtl/heYbvumWyFl572tXEUsR9b8
+eLeVAoGAIYEHwYigSiuHBtCXLE4529w01x2sus00mzD7QOPBqTpGkTu5EGdcwyMJ
+7Y3en0uLC5MXnl5HhjBnmtHLYItxpEewxLprgjkPCdQM9/3NFAh3x0MFDvbXlnje
+hpkwhv8YXXqItzvOHRDZy4ZDQQSHEwrxvsQLmyLWmHdBC/6o/RQ=
+-----END RSA PRIVATE KEY-----
new file mode 100644
@@ -0,0 +1,85 @@
+software =
+{
+ version = "1.0.0";
+ description = "Firmware update for XXXXX Project";
+
+ hardware-compatibility: [ "1.0", "1.2", "1.3"];
+
+ /* partitions tag is used to resize UBI partitions */
+ partitions: ( /* UBI Volumes */
+ {
+ name = "rootfs";
+ device = "mtd4";
+ size = 104896512; /* in bytes */
+ },
+ {
+ name = "data";
+ device = "mtd5";
+ size = 50448384; /* in bytes */
+ }
+ );
+
+
+ images: (
+ {
+ filename = "rootfs.ubifs";
+ volume = "rootfs";
+ },
+ {
+ filename = "swupdate.ext3.gz.u-boot";
+ volume = "fs_recovery";
+ },
+ {
+ filename = "sdcard.ext3.gz";
+ device = "/dev/mmcblk0p1";
+ compressed = "zlib";
+ },
+ {
+ filename = "bootlogo.bmp";
+ volume = "splash";
+ },
+ {
+ filename = "uImage.bin";
+ volume = "kernel";
+ },
+ {
+ filename = "fpga.txt";
+ type = "fpga";
+ },
+ {
+ filename = "bootloader-env";
+ type = "bootloader";
+ }
+ );
+
+ files: (
+ {
+ filename = "README";
+ path = "/README";
+ device = "/dev/mmcblk0p1";
+ filesystem = "vfat"
+ }
+ );
+
+ scripts: (
+ {
+ filename = "erase_at_end";
+ type = "lua";
+ },
+ {
+ filename = "display_info";
+ type = "lua";
+ }
+ );
+
+ bootenv: (
+ {
+ name = "vram";
+ value = "4M";
+ },
+ {
+ name = "addfb";
+ value = "setenv bootargs ${bootargs} omapfb.vram=1:2M,2:2M,3:2M omapdss.def_disp=lcd"
+ }
+ );
+}
\ No newline at end of file
new file mode 100644
@@ -0,0 +1,85 @@
+software =
+{
+ version = "@@UPDATE_VERSION@@";
+ description = "Firmware update for @@PRODUCT@@";
+
+ hardware-compatibility: [ "1.0", "1.2", "1.3"];
+
+ /* partitions tag is used to resize UBI partitions */
+ partitions: ( /* UBI Volumes */
+ {
+ name = "rootfs";
+ device = "mtd4";
+ size = 104896512; /* in bytes */
+ },
+ {
+ name = "data";
+ device = "mtd5";
+ size = 50448384; /* in bytes */
+ }
+ );
+
+
+ images: (
+ {
+ filename = "rootfs.ubifs";
+ volume = "rootfs";
+ },
+ {
+ filename = "swupdate.ext3.gz.u-boot";
+ volume = "fs_recovery";
+ },
+ {
+ filename = "sdcard.ext3.gz";
+ device = "/dev/mmcblk0p1";
+ compressed = "zlib";
+ },
+ {
+ filename = "bootlogo.bmp";
+ volume = "splash";
+ },
+ {
+ filename = "uImage.bin";
+ volume = "kernel";
+ },
+ {
+ filename = "fpga.txt";
+ type = "fpga";
+ },
+ {
+ filename = "bootloader-env";
+ type = "bootloader";
+ }
+ );
+
+ files: (
+ {
+ filename = "README";
+ path = "/README";
+ device = "/dev/mmcblk0p1";
+ filesystem = "vfat"
+ }
+ );
+
+ scripts: (
+ {
+ filename = "erase_at_end";
+ type = "lua";
+ },
+ {
+ filename = "display_info";
+ type = "lua";
+ }
+ );
+
+ bootenv: (
+ {
+ name = "vram";
+ value = "4M";
+ },
+ {
+ name = "addfb";
+ value = "setenv bootargs ${bootargs} omapfb.vram=1:2M,2:2M,3:2M omapdss.def_disp=lcd"
+ }
+ );
+}
\ No newline at end of file
new file mode 100644
GIT binary patch
literal 4608
zcmd5=OK;;g5H?yYP^3NN)<X}g7(KMWMxox)E^<)TP8(o@7FoA@C<=oTNk>@85=7Zq
zXOZKc_J{PR^x9jm{R!>8hjK_iWNlK*K;48eB#OhwH#6UmLn9A)$V8}zP}p~oD83Qe
z@ODD9_7+VBv@c8OigBVC$eOpQ@A*gVbt>wnck;Z)uMP?2ahViVl8-y0@SIgwxTM<g
z-rGG*lqoH_kZH$S*U*uUy3b^DZ5W77lQNUTCI!J2)mUC?73Gyi=roDxe9$E>3G_OQ
z^Q^#C5+!L;&BRi$&`<ISHCU+or2c8He_CBB{8>RMa9JgQpU-FdYB^M?0CPea<4owK
zb;~@j7@uQOB5e*7#92k`hL9)MFw#J_AGnTTs)b?b%?ju3iwSe!#%#(a^QD}IaK4m-
zY}>bdyS9?l>TA`IWOzh3>C2LouIsE%qT~b3r+GU07sK#NY&tHWjeX)_i?BF09mh2s
z5;N)uelpkftSCTn6j>4R1OqK>2R>l|jSTG3z^9fMP_w4#oo1_J=2wbMI(<`F`siAp
z97e)*wQ0ZuEBK5LOB&~bv9m^>d(?r%g7ixbuG1uHU|X@_NK}uqERNFGs4yDcAY@9)
zIVIqVTjp8m=!kv8wS5}dzKbY{<G?VOLn(1h+wzEw9BO;9;TjQhBg3?8m)Y1LjIzjL
zLRee5m7l;VX+FyJC@X4X*PX+Q6!Xi5c!l}@=GNp4B1n&taRbtdPOoV>rfEZbe~4Kz
z!g}?lN&jkA$W0Bz4+g7Z1SYgRq~mD=)&lXWQ=`LfY+T<yVVBuv_q^zbz4LwprZ~Ya
zAr_Brm9`9PiDbqrn!!|4hMWG~y)o4Jzl}L)i8&qOYDmYVVU&e))5*hOBS~QMnGKUM
z%kLR(orJ)D5gjd)mT8Hz2KXsXCo=Z!^P1$&Eqjp)U_w~)5L!;fsl)`>a5>`Imv0x<
z8!gXp!6F@y92-x~^Cu=eEb)*c!nsZ;8-lry)40xzn}yyt&-OYUk>Sc5HwaPB3L!6T
zo#P_oMCP%Zb6k-?i{kc8mF=m_r_&jHd-hTjzfc?WUk<b%zVC&DzIJ-{qQAF>%a*zG
ze~-)X7r5@oZbS~=2BW+mI51axjHa^5M%x+ko`Ft!r~Je0Mc{k<{u8(=bUym{)4%@w
z?8i>`n|J%a|FQq>x6bFk?!S8EefRj4-udP47bjoHZfkaRg6%MG?{9UisBEO2ErExQ
z<W+lHw#KFSDtNfcIKV1xd@ON2-;uqfA0R#!dBql(B#(ArE4Y`+m{mSp<PTfftG^?A
ziEE9*rcV29Fv)BD7IE5|TgyGJejvB^qbvVE*nuCHxaucwJ6zJr8y@R_du-@j7pqtl
TErW|t?D!W42M6HChgALnY%KwO
literal 0
HcmV?d00001
new file mode 100644
GIT binary patch
literal 5632
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
literal 0
HcmV?d00001
new file mode 100644
GIT binary patch
literal 5120
zcmeHLZEO@p7(OvXXcfy3s75WzNeC3Wo&CJKV$rL;LK7$iiX<4)%<j%!*WTWpyL(5k
zO*LSM31H-h@PkN93<*(0qkn{m$cF^Q2x>%3AYv5_34sVCN`i_rv%R~$1?=|62|t`P
zd%N?_$Me3=J2TG|L_h@a0JH-TPY3{)C>IyWuM`IrzqpDc^`#P*aX(x*K>Oi0_nTH$
zJUWOi()M(_y{1V+wrUw!$H=5ZxY!xpSpzM^wAKvPFu3HAWn&xD%7i%<upm5-R(rY;
zQ-@)hv|BE#K?gB<#$p^~JB)_%hKfcy^+HP{t(w$~nT3v_7%9Uk;Hk(&&(bG(BNK(^
zdO!KfPa#Z=t6eBrXgLPKZ;y;LtJKwXfs9E?8k*QICTwLgj&6@&a!t$#P+~S6P4pRU
zV}SJJfEbO*634p}ldeN$oVT6~hXeXXb7L|xmE<#yOeFzPj0#cFGZXb{wp(GCFo{O<
zS2t3q(q}fO7&m#I&!lqy5*WJ|@{&x@s!=Th1x;5~UXo-^(o`KuI6rk+jtEK&sEQ&e
zS_EgH0L55T(_={CU<AdYNQlG`@A34uVe?|P*SOilqJBqUlLKt7Nx{^4h9L};;p=vf
zh13kr*n+Rk9rQs{anhGO7)Tk44_i4Kn(=G1X{t)94`exCGqPkXWZOt1RNP{mvX7Ds
zfGkFlB1UC^G*yjpoGu}x$-F2;G!aNhjHsN<DY~q1ydcWD2suqhx+3V<=$SbXPlS|I
zCYfOsGwbPFNsgUOLA%#yE@S?$b1T<LRuHQgX&<C=I`ttdjZ!}IokOf=laO`#{ps%%
zvUF1;=DP-~n-Ne$Ruf9+eXxp%%Z+>usuN@H_DOb`vFx7967lxM2_H;+g7uQM*nCTC
zz-3L56l@2XWT?Cj{rpxx81DH$mT({o+NcLQJt(dDf>I<mmAiYgQ8UQqQ|K|$dgczp
z^(G<7f4n*Zik7?uO&|C?Oy%g>7Z-ahx81UfQUGe2?mvV|L)nO8BG{mnw3!)$#n&Mw
zW5TSiumnjf*TOHJ%aezIAJnATHmf1MhlIN|rFt`CsOb05yqZu5E8McirJ6Rd#w{w|
zQ8g~-YG*zsRBBw-Hj+f=&U>f@?m545!!JuGyt_Ge;#&RWsVARkc~ffq;-}_wN1i-C
ztLxK!!^dC9*UdP3ZR3KOZxvSmaDB(BmZ^n3+YU^;(DnTA?rjs*SDDZQsXq!U8XBeE
zO<?f-f!?Pk^=$d;=ShVFAH8QvH&*RF%dH*k+&=u`@o$vJj$G;A@a;>RX4k$mY5&&i
zZ@|`LS9cx$@X=TF{_x@Pm(~vN>NCd;*T4OB?eY1wugTw^9N2nV@1HznW=n4KoWGa!
zElghA_c?p;!L^4D9&1=9bj)u^e%XM!YA)@4c;}T5?zypj|IXjfq(8ZO@a6k<TyEH~
z<;<y#=a#3pe|-4$v!A7ZJ^lFZi}K!eQ=U82c;do$^>d0G#Nwb`7#jzGYooV`Q8^%&
z7+mB8?<#IreTG8a3p<xH_%F_MCzf|JE0(s$yAw=D=b}VSDK{uCiF6N~8-a0gQ8F&U
zbsL3=^CJjGdPk#otl$`VHzuRTj-#A_w)PJDW(A4yP1`tuq;Y86y|tHryZ@O`c)|L*
zQ$N<N|0+~}v~K12$dYL*+0f2E7qvY?n^nYBtUBNB(e5h3V6h~8i&(c-gKyyGE9Seb
z`bboQa7=OGD@|2!#mKlM4~yDv447!&;CUB#&658OP)sg|MGZHmc*V&ORlr7hAn|e)
z*H|#ot)v>5N_(7F6b0u|q9<AvVpYQBRX@RS5%xwa#e;aXb~oAGwTP>`m&Ngpzij&S
M>4eAsiyMJ|0HBSaS^xk5
literal 0
HcmV?d00001
new file mode 100644
GIT binary patch
literal 6144
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
literal 0
HcmV?d00001
new file mode 100644
@@ -0,0 +1,201 @@
+# pylint: disable=C0114,C0116,W0621
+"""This file hosts integration tests to ensure tool creates valid SWUs"""
+from pathlib import Path
+import pytest
+import shutil
+
+import libarchive
+
+from swugenerator import main
+
+VALID_KEY = "390ad54490a4a5f53722291023c19e08ffb5c4677a59e958c96ffa6e641df040"
+VALID_IV = "d5d601bacfe13100b149177318ebc7a4"
+UPDATE_FILES = [
+ "rootfs.ubifs",
+ "swupdate.ext3.gz.u-boot",
+ "sdcard.ext3.gz",
+ "bootlogo.bmp",
+ "uImage.bin",
+ "fpga.txt",
+ "bootloader-env",
+ "README",
+ "erase_at_end",
+ "display_info",
+]
+
+
+@pytest.fixture()
+def input_directory(tmp_path_factory):
+ """Creates a directory to test"""
+ return tmp_path_factory.mktemp("input_files")
+
+
+@pytest.fixture()
+def output_directory(tmp_path_factory):
+ """Creates a directory to test"""
+ return tmp_path_factory.mktemp("output_files")
+
+
+@pytest.fixture()
+def artifactory(input_directory):
+ """Creates test files that match the filenames in the sw-description"""
+ for filename in UPDATE_FILES:
+ file = input_directory / filename
+ with file.open("w") as file_fd:
+ file_fd.write("THIS IS A TEST UPDATE FILE\n")
+ return input_directory.resolve()
+
+
+def copy_to_test_dir(filename, test_dir) -> Path:
+ """Helper function to copy integration test inputs to test directory"""
+ source_path = Path(__file__).parent / "test_data/integration_input" / filename
+ dest_path = test_dir / filename
+ shutil.copy(source_path, dest_path)
+ return dest_path.resolve()
+
+
+@pytest.fixture()
+def sw_description_template(input_directory):
+ """Copies sw-description template to test directory"""
+ filename = "sw-description.in"
+ return copy_to_test_dir(filename, input_directory)
+
+
+@pytest.fixture()
+def encrypted_sw_description_template(input_directory):
+ """Copies sw-description template to test directory"""
+ filename = "enc-sw-description.in"
+ return copy_to_test_dir(filename, input_directory)
+
+@pytest.fixture()
+def config_file(input_directory):
+ """Copies config file to test directory"""
+ filename = "config"
+ return copy_to_test_dir(filename, input_directory)
+
+
+@pytest.fixture()
+def signing_key(input_directory):
+ """Creates signing key"""
+ filename = "private.pem"
+ return copy_to_test_dir(filename, input_directory)
+
+
+@pytest.fixture()
+def encryption_key(input_directory):
+ """Creates encryption key"""
+ encryption_key_filename = "valid_key.txt"
+ encryption_key_path = input_directory / encryption_key_filename
+ with encryption_key_path.open("w") as key_key_fd:
+ key_key_fd.write(f"key={VALID_KEY}\niv={VALID_IV}")
+ return encryption_key_path
+
+
+def validate_swu(output_swu, encrypted=False):
+ """Helper function to validate the output file against a pre-generated output file"""
+ reference_swu = (
+ Path(__file__).parent / "test_data/integration_output" / output_swu.name
+ )
+ with libarchive.Archive(output_swu.open()) as output, libarchive.Archive(
+ reference_swu.open()
+ ) as reference:
+ for output_file, reference_file in zip(output, reference):
+ if output_file.pathname != reference_file.pathname:
+ print("Names do not match")
+ return False
+ if output_file.size != reference_file.size:
+ print("Sizes do not match")
+ return False
+ if not encrypted and output.read(output_file.size) != reference.read(output_file.size):
+ print("File contents are not equal")
+ return False
+ return True
+
+
+def test_basic_command_creates_valid_swu(
+ artifactory, sw_description_template, config_file, output_directory
+):
+ output_file = "output.swu"
+ command_args = [
+ "-s",
+ str(sw_description_template),
+ "-a",
+ str(artifactory),
+ "-c",
+ str(config_file),
+ "-o",
+ str((output_directory / output_file).resolve()),
+ "create",
+ ]
+ main.parse_args(command_args)
+ assert validate_swu(output_directory / output_file)
+
+
+def test_command_with_sign_flag_creates_valid_signed_swu(
+ artifactory, sw_description_template, config_file, signing_key, output_directory
+):
+ output_file = "signed_output.swu"
+ command_args = [
+ "-s",
+ str(sw_description_template),
+ "-a",
+ str(artifactory),
+ "-c",
+ str(config_file),
+ "-k",
+ f"RSA,{signing_key}",
+ "-o",
+ str((output_directory / output_file).resolve()),
+ "create",
+ ]
+ main.parse_args(command_args)
+ assert validate_swu(output_directory / output_file)
+
+
+def test_command_with_encryption_flag_creates_encrypted_swu(
+ artifactory, encrypted_sw_description_template, config_file, encryption_key, output_directory
+):
+ output_file = "output.swu.enc"
+ command_args = [
+ "-s",
+ str(encrypted_sw_description_template),
+ "-a",
+ str(artifactory),
+ "-c",
+ str(config_file),
+ "-K",
+ str(encryption_key),
+ "-o",
+ str((output_directory / output_file).resolve()),
+ "create",
+ ]
+ main.parse_args(command_args)
+ assert validate_swu(output_directory / output_file, encrypted=True)
+
+
+def test_command_with_sign_flag_and_encrypt_flag_creates_signed_encrypted_swu(
+ artifactory,
+ encrypted_sw_description_template,
+ config_file,
+ signing_key,
+ encryption_key,
+ output_directory,
+):
+ output_file = "signed_output.swu.enc"
+ command_args = [
+ "-s",
+ str(encrypted_sw_description_template),
+ "-a",
+ str(artifactory),
+ "-c",
+ str(config_file),
+ "-k",
+ f"RSA,{signing_key}",
+ "-K",
+ str(encryption_key),
+ "-o",
+ str((output_directory / output_file).resolve()),
+ "create",
+ ]
+ main.parse_args(command_args)
+ assert validate_swu(output_directory / output_file, encrypted=True)