Coverage reporting utilities for test_runner. Coverage calculation works by having each test script subprocess write coverage files into a particular directory. These files contain the RPC commands invoked during testing, as well as a complete listing of RPC commands per `bitco
| 798 | |
| 799 | |
| 800 | class RPCCoverage(): |
| 801 | """ |
| 802 | Coverage reporting utilities for test_runner. |
| 803 | |
| 804 | Coverage calculation works by having each test script subprocess write |
| 805 | coverage files into a particular directory. These files contain the RPC |
| 806 | commands invoked during testing, as well as a complete listing of RPC |
| 807 | commands per `bitcoin-cli help` (`rpc_interface.txt`). |
| 808 | |
| 809 | After all tests complete, the commands run are combined and diff'd against |
| 810 | the complete list to calculate uncovered RPC commands. |
| 811 | |
| 812 | See also: test/functional/test_framework/coverage.py |
| 813 | |
| 814 | """ |
| 815 | def __init__(self): |
| 816 | self.dir = tempfile.mkdtemp(prefix="coverage") |
| 817 | self.flag = '--coveragedir=%s' % self.dir |
| 818 | |
| 819 | def report_rpc_coverage(self): |
| 820 | """ |
| 821 | Print out RPC commands that were unexercised by tests. |
| 822 | |
| 823 | """ |
| 824 | uncovered = self._get_uncovered_rpc_commands() |
| 825 | |
| 826 | if uncovered: |
| 827 | print("Uncovered RPC commands:") |
| 828 | print("".join((" - %s\n" % command) for command in sorted(uncovered))) |
| 829 | return False |
| 830 | else: |
| 831 | print("All RPC commands covered.") |
| 832 | return True |
| 833 | |
| 834 | def cleanup(self): |
| 835 | return shutil.rmtree(self.dir) |
| 836 | |
| 837 | def _get_uncovered_rpc_commands(self): |
| 838 | """ |
| 839 | Return a set of currently untested RPC commands. |
| 840 | |
| 841 | """ |
| 842 | # This is shared from `test/functional/test_framework/coverage.py` |
| 843 | reference_filename = 'rpc_interface.txt' |
| 844 | coverage_file_prefix = 'coverage.' |
| 845 | |
| 846 | coverage_ref_filename = os.path.join(self.dir, reference_filename) |
| 847 | coverage_filenames = set() |
| 848 | all_cmds = set() |
| 849 | # Consider RPC generate covered, because it is overloaded in |
| 850 | # test_framework/test_node.py and not seen by the coverage check. |
| 851 | # ELEMENTS: also consider `getdifficulty` and `getnetworkhashps` covered, which should be removed as they are meaningless on a signed-block chain |
| 852 | # ELEMENTS: also consider `pruneblockchain` covered since its test is temporarily disabled |
| 853 | covered_cmds = set({'generate', 'getdifficulty', 'getnetworkhashps', 'pruneblockchain'}) |
| 854 | |
| 855 | if not os.path.isfile(coverage_ref_filename): |
| 856 | raise RuntimeError("No coverage reference found") |
| 857 |