123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- import os
- import infra.basetest
- class TestSed(infra.basetest.BRTest):
- config = infra.basetest.BASIC_TOOLCHAIN_CONFIG + \
- """
- BR2_PACKAGE_BUSYBOX_SHOW_OTHERS=y
- BR2_PACKAGE_SED=y
- BR2_TARGET_ROOTFS_CPIO=y
- # BR2_TARGET_ROOTFS_TAR is not set
- """
- def check_gnu_sed(self):
- in_file = "testfile.txt"
- # We create a test file for this test.
- self.assertRunOk(f"echo 'This is a test' > {in_file}")
- # Check we have the GNU sed by testing a GNU extension likely
- # not present in other implementation. See:
- # https://www.gnu.org/software/sed/manual/sed.html#Extended-Commands
- # Note: we cannot search for "GNU sed" in sed --version,
- # because busybox sed --version outputs: "This is not GNU sed
- # version 4.0". The 'F' and 'Q' sed commands are known to be
- # unimplemented in BusyBox 1.36.1.
- expected_code = 123
- sed_script = f"F;Q {expected_code}"
- cmd = f"sed '{sed_script}' {in_file}"
- output, exit_code = self.emulator.run(cmd)
- self.assertEqual(exit_code, expected_code)
- self.assertEqual(output, [in_file])
- def check_sed_substitute(self):
- testfile_num = 5
- # We create few different test files for this test.
- cmd = f'for i in $(seq {testfile_num}) ; do '
- cmd += 'echo "=== $i Hello ===" > file$i.txt ; '
- cmd += 'done'
- self.assertRunOk(cmd)
- # We reformat file content, in-place.
- sed_script = "s/^=== \\([0-9]*\\) \\(Hello\\) ===$/\\2 \\1/"
- cmd = f"sed -i '{sed_script}' file[0-9]*.txt"
- self.assertRunOk(cmd)
- # We substitute numbers with the string "Buildroot". We use an
- # extended regular expression (with the '+'), so we test with
- # the '-r' option.
- sed_script = "s/[0-9]+/Buildroot/g"
- cmd = f"sed -r -i '{sed_script}' file[0-9]*.txt"
- self.assertRunOk(cmd)
- # Our previous text manipulations are expected to end up with
- # the "Hello Buildroot" string in all files.
- cmd = "cat file[0-9]*.txt"
- output, exit_code = self.emulator.run(cmd)
- self.assertEqual(exit_code, 0)
- self.assertEqual(output, ["Hello Buildroot"] * testfile_num)
- def check_sed_line_count(self):
- # We use the '=' command to count lines.
- line_count = 1234
- cmd = f"seq {line_count} | sed -n '$='"
- output, exit_code = self.emulator.run(cmd)
- self.assertEqual(exit_code, 0)
- self.assertEqual(int(output[0]), line_count)
- def check_sed_line_address(self):
- input_file = "strings.txt"
- expected_file = "expected.txt"
- # We create simple data for this test.
- strings = ["one", "two", "three", "four", "five"]
- content = '\\n'.join(strings)
- cmd = f"echo -e \"{content}\" > {input_file}"
- self.assertRunOk(cmd)
- # The manipulation in this tests are expected to extract the
- # first and last of the input. We create the expected data for
- # comparison.
- expected_output = [strings[0], strings[-1]]
- content = '\\n'.join(expected_output)
- cmd = f"echo -e \"{content}\" > {expected_file}"
- self.assertRunOk(cmd)
- # We remove lines between strings "two" and "four" included.
- cmd = f"sed '/two/,/four/d' {input_file} > output1.txt"
- self.assertRunOk(cmd)
- # We check output is the same as the expected data.
- cmd = f"cmp {expected_file} output1.txt"
- self.assertRunOk(cmd)
- # We redo the same manipulation using line number addresses.
- cmd = f"sed -n '1p;5p' {input_file} > output2.txt"
- self.assertRunOk(cmd)
- # We check again output is correct.
- cmd = f"cmp {expected_file} output2.txt"
- self.assertRunOk(cmd)
- def test_run(self):
- cpio_file = os.path.join(self.builddir, "images", "rootfs.cpio")
- self.emulator.boot(arch="armv5",
- kernel="builtin",
- options=["-initrd", cpio_file])
- self.emulator.login()
- # Check the program can execute
- self.assertRunOk("sed --version")
- self.check_gnu_sed()
- self.check_sed_substitute()
- self.check_sed_line_count()
- self.check_sed_line_address()
|