mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			220 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			220 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
#!/usr/bin/env python3
 | 
						|
 | 
						|
from dataclasses import asdict
 | 
						|
import unittest
 | 
						|
 | 
						|
from textwrap import dedent
 | 
						|
 | 
						|
from unittest_helpers import FIXTURE_DIR, load_fixture
 | 
						|
 | 
						|
# NOTE: This test file file only works with scripts/ added to PYTHONPATH so pylint can't find the imports
 | 
						|
# pragma pylint: disable=import-error
 | 
						|
from externalTests.parse_eth_gas_report import parse_report, ReportParsingError, ReportValidationError
 | 
						|
# pragma pylint: enable=import-error
 | 
						|
 | 
						|
ETH_GAS_REPORT_GNOSIS_RST_PATH = FIXTURE_DIR / 'eth_gas_report_gnosis.rst'
 | 
						|
ETH_GAS_REPORT_GNOSIS_RST_CONTENT = load_fixture(ETH_GAS_REPORT_GNOSIS_RST_PATH)
 | 
						|
 | 
						|
 | 
						|
class TestEthGasReport(unittest.TestCase):
 | 
						|
    def setUp(self):
 | 
						|
        self.maxDiff = 10000
 | 
						|
 | 
						|
    def test_parse_report(self):
 | 
						|
        parsed_report = parse_report(ETH_GAS_REPORT_GNOSIS_RST_CONTENT)
 | 
						|
 | 
						|
        expected_report = {
 | 
						|
            'solc_version': '0.8.10',
 | 
						|
            'optimize': True,
 | 
						|
            'runs': 200,
 | 
						|
            'block_limit': 100000000,
 | 
						|
            'total_method_gas': 57826 * 6 + 53900 * 2 + 51567 * 8 + 94816 * 85 + 201944 * 49 + 105568 * 52,
 | 
						|
            'total_deployment_gas': 283516 + 525869 + 733462,
 | 
						|
            'contracts': {
 | 
						|
                'DelegateCallTransactionGuard': {
 | 
						|
                    'total_method_gas': 0,
 | 
						|
                    'min_deployment_gas': 283510,
 | 
						|
                    'max_deployment_gas': 283522,
 | 
						|
                    'avg_deployment_gas': 283516,
 | 
						|
                    'methods': None,
 | 
						|
                },
 | 
						|
                'ERC1155Token': {
 | 
						|
                    'total_method_gas': 57826 * 6 + 53900 * 2,
 | 
						|
                    'min_deployment_gas': None,
 | 
						|
                    'max_deployment_gas': None,
 | 
						|
                    'avg_deployment_gas': 525869,
 | 
						|
                    'methods': {
 | 
						|
                        'mint(address,uint256,uint256,bytes)': {
 | 
						|
                            'total_gas': 57826 * 6,
 | 
						|
                            'min_gas': 47934,
 | 
						|
                            'max_gas': 59804,
 | 
						|
                            'avg_gas': 57826,
 | 
						|
                            'call_count': 6
 | 
						|
                        },
 | 
						|
                        'safeTransferFrom(address,address,uint256,uint256,bytes)': {
 | 
						|
                            'total_gas': 53900 * 2,
 | 
						|
                            'min_gas': 53900,
 | 
						|
                            'max_gas': 53900,
 | 
						|
                            'avg_gas': 53900,
 | 
						|
                            'call_count': 2,
 | 
						|
                        },
 | 
						|
                    },
 | 
						|
                },
 | 
						|
                'ERC20Token': {
 | 
						|
                    'total_method_gas': 51567 * 8,
 | 
						|
                    'min_deployment_gas': None,
 | 
						|
                    'max_deployment_gas': None,
 | 
						|
                    'avg_deployment_gas': 733462,
 | 
						|
                    'methods': {
 | 
						|
                        'transfer(address,uint256)': {
 | 
						|
                            'total_gas': 51567 * 8,
 | 
						|
                            'min_gas': 51567,
 | 
						|
                            'max_gas': 51567,
 | 
						|
                            'avg_gas': 51567,
 | 
						|
                            'call_count': 8,
 | 
						|
                        },
 | 
						|
                    },
 | 
						|
                },
 | 
						|
                'GnosisSafe': {
 | 
						|
                    'total_method_gas': 94816 * 85 + 201944 * 49,
 | 
						|
                    'min_deployment_gas': None,
 | 
						|
                    'max_deployment_gas': None,
 | 
						|
                    'avg_deployment_gas': None,
 | 
						|
                    'methods': {
 | 
						|
                        'execTransaction(address,uint256,bytes,uint8,uint256,uint256,uint256,address,address,bytes)': {
 | 
						|
                            'total_gas': 94816 * 85,
 | 
						|
                            'min_gas': 59563,
 | 
						|
                            'max_gas': 151736,
 | 
						|
                            'avg_gas': 94816,
 | 
						|
                            'call_count': 85,
 | 
						|
                        },
 | 
						|
                        'setup(address[],uint256,address,bytes,address,address,uint256,address)': {
 | 
						|
                            'total_gas': 201944 * 49,
 | 
						|
                            'min_gas': 167642,
 | 
						|
                            'max_gas': 263690,
 | 
						|
                            'avg_gas': 201944,
 | 
						|
                            'call_count': 49,
 | 
						|
                        },
 | 
						|
                    },
 | 
						|
                },
 | 
						|
                'GnosisSafeProxyFactory': {
 | 
						|
                    'total_method_gas': 105568 * 52,
 | 
						|
                    'min_deployment_gas': None,
 | 
						|
                    'max_deployment_gas': None,
 | 
						|
                    'avg_deployment_gas': None,
 | 
						|
                    'methods': {
 | 
						|
                        'createProxy(address,bytes)': {
 | 
						|
                            'total_gas': 105568 * 52,
 | 
						|
                            'min_gas': 105568,
 | 
						|
                            'max_gas': 105580,
 | 
						|
                            'avg_gas': 105568,
 | 
						|
                            'call_count': 52,
 | 
						|
                        },
 | 
						|
                    },
 | 
						|
                },
 | 
						|
            }
 | 
						|
        }
 | 
						|
        self.assertEqual(asdict(parsed_report), expected_report)
 | 
						|
 | 
						|
    def test_parse_report_should_fail_if_report_is_empty(self):
 | 
						|
        text_report = ""
 | 
						|
        with self.assertRaises(ReportValidationError) as manager:
 | 
						|
            parse_report(text_report)
 | 
						|
        self.assertEqual(str(manager.exception), "Report header not found.")
 | 
						|
 | 
						|
    def test_parse_report_should_fail_if_report_has_no_header(self):
 | 
						|
        text_report = dedent("""
 | 
						|
            | Methods                                            |
 | 
						|
            | ERC1155Token · mint() · 1 · 3 · 2 ·          6 · - |
 | 
						|
            | Deployments           ·           · % of limit ·   │
 | 
						|
            | ERC1155Token          · - · - · 5 ·        1 % · - |
 | 
						|
        """).strip('\n')
 | 
						|
        with self.assertRaises(ReportValidationError) as manager:
 | 
						|
            parse_report(text_report)
 | 
						|
        self.assertEqual(str(manager.exception), "Report header not found.")
 | 
						|
 | 
						|
    def test_parse_report_should_fail_if_data_rows_have_no_headers(self):
 | 
						|
        text_report = dedent("""
 | 
						|
            | ERC1155Token · mint() · 1 · 3 · 2 · 6 · - |
 | 
						|
        """).strip('\n')
 | 
						|
        expected_message = dedent("""
 | 
						|
            Parsing error on line 1: Found data row without a section header.
 | 
						|
            | ERC1155Token | mint() | 1 | 3 | 2 | 6 | - |
 | 
						|
        """).strip('\n')
 | 
						|
 | 
						|
        with self.assertRaises(ReportParsingError) as manager:
 | 
						|
            parse_report(text_report)
 | 
						|
        self.assertEqual(str(manager.exception), expected_message)
 | 
						|
 | 
						|
    def test_parse_report_should_fail_if_report_has_more_than_one_header(self):
 | 
						|
        text_report = dedent("""
 | 
						|
            | Solc version: 0.8.10 · Optimizer enabled: true  · Runs: 200 · Block limit: 100000000 gas |
 | 
						|
            | Solc version: 0.8.9  · Optimizer enabled: false · Runs: 111 · Block limit: 999999999 gas |
 | 
						|
        """).strip('\n')
 | 
						|
        expected_message = dedent("""
 | 
						|
            Parsing error on line 2: Duplicate report header.
 | 
						|
            | Solc version: 0.8.9  | Optimizer enabled: false | Runs: 111 | Block limit: 999999999 gas |
 | 
						|
        """).strip('\n')
 | 
						|
 | 
						|
        with self.assertRaises(ReportParsingError) as manager:
 | 
						|
            parse_report(text_report)
 | 
						|
        self.assertEqual(str(manager.exception), expected_message)
 | 
						|
 | 
						|
    def test_parse_report_should_fail_if_row_matching_same_method_call_appears_twice(self):
 | 
						|
        text_report = dedent("""
 | 
						|
            | Methods                                               |
 | 
						|
            | ERC1155Token · mint() · 47934 · 59804 · 57826 · 6 · - |
 | 
						|
            | ERC1155Token · mint() · 11111 · 22222 · 33333 · 4 · - |
 | 
						|
        """).strip('\n')
 | 
						|
        expected_message = dedent("""
 | 
						|
            Parsing error on line 3: Duplicate method row for 'ERC1155Token.mint()'.
 | 
						|
            | ERC1155Token | mint() | 11111 | 22222 | 33333 | 4 | - |
 | 
						|
        """).strip('\n')
 | 
						|
 | 
						|
        with self.assertRaises(ReportParsingError) as manager:
 | 
						|
            parse_report(text_report)
 | 
						|
        self.assertEqual(str(manager.exception), expected_message)
 | 
						|
 | 
						|
    def test_parse_report_should_fail_if_row_matching_same_contract_deployment_appears_twice(self):
 | 
						|
        text_report = dedent("""
 | 
						|
            | Deployments          ·        · % of limit ·   │
 | 
						|
            | ERC1155Token · - · - · 525869 ·      0.5 % · - |
 | 
						|
            | ERC1155Token · - · - · 111111 ·      0.6 % · - |
 | 
						|
        """).strip('\n')
 | 
						|
        expected_message = dedent("""
 | 
						|
            Parsing error on line 3: Duplicate contract deployment row for 'ERC1155Token'.
 | 
						|
            | ERC1155Token | - | - | 111111 |      0.6 % | - |
 | 
						|
        """).strip('\n')
 | 
						|
 | 
						|
        with self.assertRaises(ReportParsingError) as manager:
 | 
						|
            parse_report(text_report)
 | 
						|
        self.assertEqual(str(manager.exception), expected_message)
 | 
						|
 | 
						|
    def test_parse_report_should_fail_if_method_row_appears_under_deployments_header(self):
 | 
						|
        text_report = dedent("""
 | 
						|
            | Deployments           ·                       · % of limit ·   │
 | 
						|
            | ERC1155Token · mint() · 47934 · 59804 · 57826 ·          6 · - |
 | 
						|
        """).strip('\n')
 | 
						|
        expected_message = dedent("""
 | 
						|
            Parsing error on line 2: Expected a table row with deployment details.
 | 
						|
            | ERC1155Token | mint() | 47934 | 59804 | 57826 |          6 | - |
 | 
						|
        """).strip('\n')
 | 
						|
 | 
						|
        with self.assertRaises(ReportParsingError) as manager:
 | 
						|
            parse_report(text_report)
 | 
						|
        self.assertEqual(str(manager.exception), expected_message)
 | 
						|
 | 
						|
    def test_parse_report_should_fail_if_deployment_row_appears_under_methods_header(self):
 | 
						|
        text_report = dedent("""
 | 
						|
            | Methods                               |
 | 
						|
            | ERC1155Token · - · - · 525869 · 5 · - |
 | 
						|
        """).strip('\n')
 | 
						|
        expected_message = dedent("""
 | 
						|
            Parsing error on line 2: Expected a table row with method details.
 | 
						|
            | ERC1155Token | - | - | 525869 | 5 | - |
 | 
						|
        """).strip('\n')
 | 
						|
 | 
						|
        with self.assertRaises(ReportParsingError) as manager:
 | 
						|
            parse_report(text_report)
 | 
						|
        self.assertEqual(str(manager.exception), expected_message)
 |