1# SPDX-License-Identifier: GPL-2.0
2# Copyright (C) 2020 Bootlin
3# Author: Joao Marcos Costa <joaomarcos.costa@bootlin.com>
4
5import os
6import random
7import string
8import subprocess
9
10def sqfs_get_random_letters(size):
11    letters = []
12    for i in range(0, size):
13            letters.append(random.choice(string.ascii_letters))
14
15    return ''.join(letters)
16
17def sqfs_generate_file(path, size):
18    content = sqfs_get_random_letters(size)
19    file = open(path, "w")
20    file.write(content)
21    file.close()
22
23class Compression:
24    def __init__(self, name, files, sizes, block_size = 4096):
25        self.name = name
26        self.files = files
27        self.sizes = sizes
28        self.mksquashfs_opts = " -b " + str(block_size) + " -comp " + self.name
29
30    def add_opt(self, opt):
31        self.mksquashfs_opts += " " + opt
32
33    def gen_image(self, build_dir):
34        src = os.path.join(build_dir, "sqfs_src/")
35        os.mkdir(src)
36        for (f, s) in zip(self.files, self.sizes):
37            sqfs_generate_file(src + f, s)
38
39        # the symbolic link always targets the first file
40        os.symlink(self.files[0], src + "sym")
41
42        sqfs_img = os.path.join(build_dir, "sqfs-" + self.name)
43        i_o = src + " " + sqfs_img
44        opts = self.mksquashfs_opts
45        try:
46            subprocess.run(["mksquashfs " + i_o + opts], shell = True, check = True)
47        except:
48            print("mksquashfs error. Compression type: " + self.name)
49            raise RuntimeError
50
51    def clean_source(self, build_dir):
52        src = os.path.join(build_dir, "sqfs_src/")
53        for f in self.files:
54            os.remove(src + f)
55        os.remove(src + "sym")
56        os.rmdir(src)
57
58    def cleanup(self, build_dir):
59        self.clean_source(build_dir)
60        sqfs_img = os.path.join(build_dir, "sqfs-" + self.name)
61        os.remove(sqfs_img)
62
63files = ["blks_only", "blks_frag", "frag_only"]
64sizes = [4096, 5100, 100]
65gzip = Compression("gzip", files, sizes)
66zstd = Compression("zstd", files, sizes)
67lzo = Compression("lzo", files, sizes)
68
69# use fragment blocks for files larger than block_size
70gzip.add_opt("-always-use-fragments")
71zstd.add_opt("-always-use-fragments")
72
73# avoid fragments if lzo is used
74lzo.add_opt("-no-fragments")
75
76comp_opts = [gzip, zstd, lzo]
77