-
-
Notifications
You must be signed in to change notification settings - Fork 739
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
Better tests #813
Better tests #813
Conversation
- Fixed a logic error in `NopCommand`
- fixed calculation of tcache in gef - added tests for `gef.heap` - improved tests for `heap` command - fixes #641
- fixed test `highlight` for 32b - fixed test `pattern_search` for x86
- added tests for `pie`
- added test for smart eval - more function tests
- added static `ptrsize` for ppc & ppc64 in gef
- removed auto demangle for now
- added doc for testing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
forgot to submit this
Co-authored-by: Grazfather <grazfather@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, that's a lot of files :)
I think I went through all of them now and basically everything looks good to me logic-wise - thankfully most of the tests are very similar to how they used to be.
Also my linter has a lot of complaints about too many or too little blank lines but I didnt feel like it would be useful to add them all to this review. If you want I could just commit them myself (just the blank line stuff - not more not less ;) )
I like that the deprecated api is being tested now as well but maybe we can even add a way to test that GEF doesnt use deprecated functions anywhere (so kind of the opposite of the current deprecated tests). But this doesn't need to be part of this PR.
I marked very few lines too rethink and then i'm happy with this PR.
.github/PULL_REQUEST_TEMPLATE.md
Outdated
@@ -27,5 +27,5 @@ | |||
- [] My PR was done against the `dev` branch, not `master`. | |||
- [] My code follows the code style of this project. | |||
- [] My change includes a change to the documentation, if required. | |||
- [] My change adds tests as appropriate. | |||
- [] If my change adds new code, [adequate tests](docs/testing.md) must be added. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- [] If my change adds new code, [adequate tests](docs/testing.md) must be added. | |
- [] If my change adds new code, [adequate tests](docs/testing.md) have been added. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"have to be" or "have been"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good call.
res = gdb_start_silent_cmd("cs --show-opcodes --length 5 $pc") | ||
self.assertNoException(res) | ||
self.assertTrue(len(res.splitlines()) >= 5) | ||
res = res[res.find("→ "):] # jump to the output buffer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't this just removeuntil
?
) | ||
|
||
|
||
class RegressionRegisterOrder(GefUnitTestGeneric): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we shouldn't name tests like this, even though it was a regression. It should be named something like "RegisterOrder". We don't need a regressions directory, even, we just need a policy where things we found to have regressed are added to where they should have original been.
from tests.utils import GefUnitTestGeneric | ||
|
||
|
||
class TestGefConfigUnit(GefUnitTestGeneric): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm surprised we only have one test. We should at a lot more here. Missing configs, converting types e.g. T
->True
, etc. Can be done later.
pass | ||
|
||
|
||
def test_cmd_gef_missing(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we going to write these?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
later
cmd = "functions" | ||
res = gdb_run_cmd(cmd) | ||
self.assertNoException(res) | ||
self.assertIn("$_heap", res) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's test for them all? _base
, _bss
, _got
, _heap
, _stack
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that's what was already there
Line 191 in 283690a
def test_cmd_functions(self): |
|
||
def test_cmd_entry_break(self): | ||
res = gdb_run_cmd("entry-break") | ||
self.assertNoException(res) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add test that if we run it 2x it says, "gdb is already running", although maybe that string should change.,.. should it say, "target is already running"?
|
||
|
||
def _target(name: str, extension: str = ".out") -> Path: | ||
def _target(name: str, extension: str = ".out") -> pathlib.Path: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have people import and use this function, so it shouldn't be named with a leading underscore. Maybe get_target_path
or something?
res = gdb_test_python_method("gef.arch.arch, gef.arch.mode", before="reset_architecture()") | ||
res = (res.splitlines()[-1]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
res = gdb_test_python_method("gef.arch.arch, gef.arch.mode", before="reset_architecture()") | |
res = (res.splitlines()[-1]) | |
res = gdb_test_python_method("gef.arch.arch, gef.arch.mode", before="reset_architecture()")[-1] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why removing the .splitlines
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I messed up. I mostly just noticed the superfluous ()
around the second line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only 1 that needs to be addressed (in pattern.py). The rest are just code quality suggestions.
tests/commands/pattern.py
Outdated
self.assertIn("Found at offset 16 (little-endian search) likely", res) | ||
res = gdb_start_silent_cmd("pattern search -n 4 caaaaaaa") | ||
self.assertNoException(res) | ||
self.assertNotIn("Found at offset 9 (little-endian search) likely", res) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self.assertNotIn("Found at offset 9 (little-endian search) likely", res) | |
self.assertNotIn("Found at offset", res) |
In the old code, it is self.assertNotIn("Found at offset", res)
I think it should not have a specific offset 9
. In the case where the command actually behaves wrongly, say outputs Found at offset 10...
, this assertion won't catch it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test is incorrect, it should be a assertIn
. Offsets are easy to calculate. I will fix
] | ||
res = gdb_run_cmd("set-permission $sp", before=before, after=after, target=target) | ||
matches = re.match(r"(?:.*match_before)(.+)(?:match_before.*)", res, flags=re.DOTALL) | ||
if not matches: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yea I think the group must be there, otherwise it won't match at all
tests/utils.py
Outdated
if "is deprecated and will be removed in a feature release." in buf: | ||
lines = [l for l in buf.splitlines() | ||
if "is deprecated and will be removed in a feature release." in l] | ||
deprecated_api_names = set([x.split()[1] for x in lines]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
deprecated_api_names = set([x.split()[1] for x in lines]) | |
deprecated_api_names = {x.split()[1] for x in lines} |
tests/api/deprecated.py
Outdated
for cmd in old_stuff: | ||
with pytest.warns(Warning) as record: | ||
res = gdb_test_python_method(cmd) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for cmd in old_stuff: | |
with pytest.warns(Warning) as record: | |
res = gdb_test_python_method(cmd) | |
for meth in old_stuff: | |
with pytest.warns(Warning) as record: | |
res = gdb_test_python_method(meth) |
because are testing a method instead of a command here
commit 430d9d3 Author: hugsy <hugsy@users.noreply.github.com> Date: Sun Jun 26 09:53:07 2022 -0700 Allow new file format (#849) * New abstraction class for fileformat, but defaults to GEF. This allows PE/MachO fileformat to be supported via gef-extras * 🐛 fixes - moved prompt init after gef initial loading - added a `__str__` for `FileFormat` - `FileFormat` also requires a section member * [CI] Fixed missing import commit d594eb3 Author: hugsy <hugsy@users.noreply.github.com> Date: Sun Jun 26 09:43:05 2022 -0700 Fix 850 (#851) * Make sure GefSetting `on_write` hooks are called even on creation * Removed `SettingHookType`, not useful * in `GefSetting` replaced `dict` with `super` * Added loading counter commit a2a4bfa Author: hugsy <hugsy@users.noreply.github.com> Date: Sun Jun 26 09:42:25 2022 -0700 Minor update to unittest of `print-format` after #843 (#852) commit 9834252 Author: hugsy <hugsy@users.noreply.github.com> Date: Sat Jun 25 14:08:13 2022 -0700 Better `gef-remote` - part 2: Remote Qemu (#846) * - rewrite of `gef-remote` to properly manager remote session - removed unused functions (& tests) * fixes gef's got function fails in remote debug sessions #806 * fully restore `qemu-user` + `test` * added more `__str__` for clarity * better __str__ * better __str__ * better __str__ * last changes to `__str__` * add `qemu_user` support * stupid typo * stupid typo * qemu-system works too * [gef-remote] Updated the docs * Apply suggestions from code review * Update docs/commands/gef-remote.md commit 546f4b1 Author: hugsy <hugsy@users.noreply.github.com> Date: Sat Jun 25 09:11:28 2022 -0700 Better `gef-remote` : rewrite and add `remote` full support (#830) * - rewrite of `gef-remote` to properly manager remote session * removed unused functions (& tests) * fixes gef's got function fails in remote debug sessions #806 * fully restore `qemu-user` + `test` * added more `__str__` for clarity * better `__str__` for more classes, making them more meaningful commit 343cd23 Author: Dreg <dreg@fr33project.org> Date: Fri Jun 24 15:40:12 2022 +0200 Fix typo in patch byte help (#848) `WORD` -> `BYTE` commit 1e8f55f Author: Dreg <dreg@fr33project.org> Date: Fri Jun 24 06:26:20 2022 +0200 `print-format` and `patch byte` commands can work together (#843) commit f890579 Author: hugsy <hugsy@users.noreply.github.com> Date: Mon Jun 20 12:51:28 2022 -0700 `master` -> `main` (#845) commit 0fcd20a Author: Dreg <dreg@fr33project.org> Date: Mon Jun 20 00:37:15 2022 +0200 keep x86 and x86_64 FLAGS Register when calls to mprotect. Added pushfd, popfd, pushfq, popfq instructions (#844) commit bf959a3 Author: hugsy <hugsy@users.noreply.github.com> Date: Sun Jun 19 14:18:15 2022 -0700 Type hinting fixes - part 2 (#839) * make `@deprecated` more informative on what must be changed * - `gef.binary` is being set only from the `newobjfile` handler - removed useless `get_elf_headers` - more pythonic gef.doc * simplified command/function registration * fixed `functions` command * [ci] roper was never executing correctly * Don't delete the `gef` object on `exit_handler` so we can still use it to get info even when the current debugging has exited * more type hinting fixes, now down to 75 * - make all tests run in a tempdir (in tmp) - fixed gef install to use the tempdir config setting, not gef-extras dir * Formatting issues * add the possibility to specify read/write callbacks to `GefSetting` * [gef] updated unicode code strings to glyphs * allow directories inside `extra_plugin_dir` to act as python package * command examples can be provided as a list of strings * Allowing context disassembler to be monkey-patched commit dbf2372 Author: hugsy <hugsy@users.noreply.github.com> Date: Sat Jun 18 11:40:58 2022 -0700 Remove `ida-interact` (#842) from GEF, entirely moved to GEF-Extras * removed all last parts of `ida-interact`, everything is moved to `gef-extras` * [docs] added a page to track command/function deprecation commit 1c295fc Author: hugsy <hugsy@blah.cat> Date: Fri Jun 17 09:40:45 2022 -0700 restoring temporarily rtfd for redirection to the new docs commit a78915d Author: hugsy <hugsy@blah.cat> Date: Fri Jun 17 07:42:14 2022 -0700 remove rtfd cfg file commit f375efc Merge: d463f7d 8ee281d Author: hugsy <hugsy@blah.cat> Date: Thu Jun 16 14:19:09 2022 -0700 Merge branch 'dev' of github.com:hugsy/gef into dev commit 8ee281d Author: hugsy <hugsy@users.noreply.github.com> Date: Thu Jun 16 09:30:52 2022 -0700 Update README.md commit d463f7d Author: hugsy <hugsy@blah.cat> Date: Tue Jun 14 11:02:06 2022 -0700 [docs] hardcoded emojis instead of md commit 37ddf86 Author: hugsy <hugsy@users.noreply.github.com> Date: Tue Jun 14 10:29:20 2022 -0700 Updated `gef-extras.sh` installation script Force script to pip-install the requirements of `gef-extras` commit c671bed Author: hugsy <hugsy@users.noreply.github.com> Date: Tue Jun 14 10:10:09 2022 -0700 Update install.md commit ca67ced Author: hugsy <hugsy@blah.cat> Date: Mon Jun 13 20:03:33 2022 -0700 :bug: Last doc fixes, GEF API is now generated from Actions commit 5b468d0 Author: hugsy <hugsy@blah.cat> Date: Mon Jun 13 19:16:39 2022 -0700 :bug: forcing docs to run the same version than gdb commit d836054 Author: hugsy <hugsy@blah.cat> Date: Mon Jun 13 19:07:36 2022 -0700 Squashed commit of the following: [docs] make actions regenerate the api file [docs] regenerated gef api file [docs] cleanup commit a7d8fa5 Author: hugsy <hugsy@blah.cat> Date: Mon Jun 13 14:50:35 2022 -0700 Updated documentation appearance commit dca3cb1 Author: hugsy <hugsy@users.noreply.github.com> Date: Mon Jun 13 13:46:35 2022 -0700 Update generate-docs.yml commit d7d64a2 Author: hugsy <hugsy@users.noreply.github.com> Date: Mon Jun 13 13:43:21 2022 -0700 Update generate-docs.yml commit a89f91c Author: hugsy <hugsy@users.noreply.github.com> Date: Mon Jun 13 13:37:37 2022 -0700 Move 3rd party to extras (#841) * moved keystone, capstone, unicorn and ropper to gef-extras * moved test files to extras * moved docs * [docs] removed references to 3rd party packages * [actions] mlc -> lychee * updated PR & contrib templates and fixed actions command for lychee * moved requirements.txt to tests/ so people don't think there's a need to install any package * no need for readthedocs anymore * replaced references to rtfd to gh-pages commit 7f45550 Author: hugsy <hugsy@users.noreply.github.com> Date: Sun May 22 08:14:12 2022 -0700 Type Hinting Fixes - Part 1 (#827) * better linting, by creating a proper .editorconfig & pylintrc * major drop of linting errors, from 786 errors to 145 * using Py3.6 `__init_subclass__` allows to remove the use of `abc` and `@register_architecture` * using `__init_subclass__` to create base class for commands * using `__init_subclass__` to create base class for functions commit e50af77 Author: Khaotic <6080590+khaoticdude@users.noreply.github.com> Date: Sat Apr 9 10:36:53 2022 -0500 Improve identifying Stack Canaries (#833) commit d540abd Author: hugsy <hugsy@blah.cat> Date: Mon Mar 7 10:52:17 2022 -0800 pushing urgent fix for #831 (even tho `get_arch` will be deprecated after #827) commit 93f3010 Merge: 7817bea 6e3cd5c Author: hugsy <hugsy@blah.cat> Date: Fri Mar 4 09:35:13 2022 -0800 Merge branch 'dev' of github.com:hugsy/gef into dev commit 7817bea Author: hugsy <hugsy@blah.cat> Date: Fri Mar 4 09:35:06 2022 -0800 [docs] http -> https because apparently it's a big deal for debugging stuff commit 6e3cd5c Author: hugsy <hugsy@users.noreply.github.com> Date: Sat Feb 26 12:29:58 2022 -0800 Update gef.md commit 0954a16 Author: hugsy <hugsy@users.noreply.github.com> Date: Sat Feb 26 12:25:53 2022 -0800 New subcommand `gef install` (#825) * Adding new command `gef install` * added doc * added tests * test: changing `remote` with `skel` because `remote` uses an external dependency (`rpyc`) * PR review additions commit 18c40b6 Author: Boris-Chengbiao Zhou <bobo1239@web.de> Date: Tue Feb 22 05:18:33 2022 +0100 Add mechanism to let architectures specify whether they support a gdb arch (#822) * Fix gdb arch parsing for auto-detected archs * Add mechanism to let architectures specify whether they support a gdb arch * Add documentation about adding architectures and supports_gdb_arch() * Address review comments commit 2b7f315 Author: Ebubekir Türker <35612408+ebubekirtrkr@users.noreply.github.com> Date: Mon Feb 14 23:30:43 2022 +0300 remove unnecessary warnings (#824) * remove unnecessary warnings commit 18c7ba4 Author: hugsy <hugsy@users.noreply.github.com> Date: Sun Feb 13 18:38:44 2022 -0800 Better tests (#813) * first shot at refactoring ci testing * - Added skeleton for most missing command test modules - Fixed a logic error in `NopCommand` * [ci] added tests for `nop` * [ci] extra test for nop for memory check * added benchmarking capability, can be triggered directly from `pytest` * - fixed `pcustom` command test for 32b - fixed calculation of tcache in gef - added tests for `gef.heap` - improved tests for `heap` command - fixes #641 * [ci] cmd/heap - adjusted tcachebins indexes for 32b * damnit * - fixed linting - fixed test `highlight` for 32b - fixed test `pattern_search` for x86 * last fixes for tonight * fixed `pattern` and `heap` tests for good * - add 3rd party module check for `capstone`, `keystone`, `unicorn` and `ropper` * added `test_func_update_gef` * `make test` doesn't execute benchmark * - fixed errors in the `pie` subcommands - added tests for `pie` * `theme` added more tests * - improved tests for `pattern` and `edit-flags` * [ci] created cases for all arches for bin tests in `tests/heap.py` * fixed `heap` tests for good * - added ci test for `glibcarena` - fixed `theme` missing comma (original PR #808 by @mrshu ) - added missing values for `theme` * - added tests for deprecated API - added test for smart eval - more function tests * started `gef` test module * - added tests for `syscall-args` and `is-syscall` * - fixed `syscall-args` to also get catchpoints + tests * - test `show_last_exception` * make sure `syscall-args` test collects the ABI files from `gef-extras` * linting * only enable `syscall-args` test for x86 * `syscall-args` fixed typo in i686 test * Fix RISCV arch detection (#790) * Add RISCV alias so arch can be determined by ELF * Add ptrsize property to RISCV arch * Allow riscv tests to run * Update tests/api/gef_arch.py Co-authored-by: Grazfather <grazfather@gmail.com> * fix: make shebang lines portable (#814) * fix: make shebang lines portable * fix: SC2006, SC2086, SC2016, SC2059 * make `heap` tests work universally * disabling capstone/keystone/unicorn for some arches for now * - fixed tests for ppc64 - added static `ptrsize` for ppc & ppc64 in gef * - `BIN_LS` -> `_target("default")` - removed auto demangle for now * - disable pytest `--pdb` from makefile - added doc for testing * Apply suggestions from code review Co-authored-by: Grazfather <grazfather@gmail.com> * fixing ci * [tests] use camel case for format string helper test class * [tests] added docstring to `GefFuncDeprecatedApi` * [tests] `edit-flags` are only for known arches for now * PR review changes * PR review last batch Co-authored-by: Grazfather <grazfather@gmail.com> Co-authored-by: theguy147 <37738506+theguy147@users.noreply.github.com> commit 37bb542 Author: hugsy <hugsy@users.noreply.github.com> Date: Sun Feb 13 10:54:28 2022 -0800 Add class factory support for `pcustom` (#819) * [pcustom] add class factory support instead of creating a static class, class factories allow to generate a `ctypes.Structure` class with information from the runtime, which can drastically simplify (and unify) classes declaration (from on libc version, architecture, ptrsize, etc.) * [pcustom] added doc for class factory * linting * [pcustom] completed the documentation for class factory * Better filter of external attribute in the `Structure.__init__` to catch both classes and class factory methods * Apply suggestions from code review Co-authored-by: Grazfather <grazfather@gmail.com> commit 82b2570 Author: hugsy <hugsy@users.noreply.github.com> Date: Sun Feb 13 09:52:18 2022 -0800 Remove `ida-interact` (#817) * remove `ida-interact` from gef, replaced by a better version in `gef-extras` * Fix double loading of external plugins (#816) `register_external_command` was receiving an instance of a class for each new external script. This lead to a double initialization when calling `gef.gdb.load(cls)`. Fixed by registering directly a class (just like `register_command`) * [lint] removed `xmlrpclib` unused import * restored doctstring of `IdaInteractCommand` * restoring python path insertion for python plugins for extra pacakges commit d86e7a0 Author: hugsy <hugsy@blah.cat> Date: Wed Feb 9 13:04:48 2022 -0800 Minor follow-up of #821 commit 8c0f625 Author: hugsy <hugsy@users.noreply.github.com> Date: Tue Feb 8 17:59:08 2022 -0800 - create `gef.ui.libc_args_table` (#821) - make the old `libc_args_definitions` dict point to `gef.ui.libc_args_table` commit 4365d9c Author: hugsy <hugsy@users.noreply.github.com> Date: Fri Feb 4 09:55:08 2022 -0800 Fix double loading of external plugins (#816) `register_external_command` was receiving an instance of a class for each new external script. This lead to a double initialization when calling `gef.gdb.load(cls)`. Fixed by registering directly a class (just like `register_command`) commit d1fa00f Author: theguy147 <37738506+theguy147@users.noreply.github.com> Date: Tue Feb 1 19:28:30 2022 +0100 fix: make shebang lines portable (#814) * fix: make shebang lines portable * fix: SC2006, SC2086, SC2016, SC2059 commit c078733 Author: Grazfather <grazfather@gmail.com> Date: Tue Feb 1 10:57:08 2022 -0500 Fix RISCV arch detection (#790) * Add RISCV alias so arch can be determined by ELF * Add ptrsize property to RISCV arch * Allow riscv tests to run commit 48d39bb Author: code-byter <10854537+code-byter@users.noreply.github.com> Date: Mon Jan 31 05:36:52 2022 +0100 Update gef config parameters of gef-extras installation script (#807)
Description/Motivation/Screenshots
It's all in the title: the tests until now were messy, wildly incomplete and also too many times inaccurate which lead to some bugs being missed. This PR won't fix it all but it's a start, and I'm making this PR ready for review because it gets big:
runtests.py
doesn't exist any longer, now test has its own dedicated module, in a proper hierarchy (for example, I tried to match one command = one test file intests/commands
). This explains the big number of files here, it's mostly the old one big file split into many smallerhelpers.py
is renamedutils.py
and was added more helpers functionsheap
command was approximate at best ,pie
,ksymaddr
,pcustom
,is-syscall
,syscall-args
and more didn't have a single test. now they dopytest
instead of reinventing the wheel which allows us to test easily by command specificly, class, or even marker (checkoutpytest -k
)pytest -k benchmark
). note at it's at its beginning , some improvements can be made.assertNoException
will display apytest
warning if it encounters a deprecation warning during the testgef.py
well plenty of bugs fixedNote: there's now 120 tests so the testing is slower. the longest commands were marked
slow
so you can discard them withpytest -k "not slow"
How Has This Been Tested?
make test
Checklist
dev
branch, notmaster
.