def test_project_fill_contracts_cache(write_project_file, MATH): write_project_file('contracts/Math.sol', MATH['source']) source_mtime = Project().get_source_modification_time() project = Project() compiled_contracts_object_id = id(project.compiled_contracts) # fill with code from the future -> no recompilation project.fill_contracts_cache(project.compiled_contracts, source_mtime + 10) assert id(project.compiled_contracts) == compiled_contracts_object_id # fill with code from the past -> recompilation project.fill_contracts_cache(project.compiled_contracts, source_mtime - 10) assert not id(project.compiled_contracts) == compiled_contracts_object_id
def main(ctx, config): """ Populus """ if not config and check_if_ini_config_file_exists(): click.echo("Attempting to upgrade legacy `populus.ini` config file") try: backup_ini_config_file_path = upgrade_legacy_config_file(os.getcwd()) except: click.echo( "The following error occured while trying to upgrade the legacy " "`populus.ini` config file:" ) raise else: click.echo( "Project configuration upgraded. New config file " "`populus.json` has been written. Old config file was renamed " "to `{0}`".format(backup_ini_config_file_path) ) project = Project(config) if not any(is_same_path(p, project.project_dir) for p in sys.path): # ensure that the project directory is in the sys.path sys.path.insert(0, project.project_dir) ctx.obj = {} ctx.obj['PROJECT'] = project
def test_upgrade_custom_key(project): legacy_config_file_path = get_legacy_json_config_file_path( project_dir=project.project_dir) shutil.copyfile(get_default_config_path(version=V3), legacy_config_file_path) os.remove(project.config_file_path) legacy_key = 'compilation.import_remapping' legacy_value = ['import-path-from-legacy=contracts'] upgraded_key = 'compilation.import_remappings' legacy_config = Config(load_config(legacy_config_file_path)) legacy_config[legacy_key] = legacy_value write_config(legacy_config, legacy_config_file_path) logger = logging.getLogger("test.test_upgrade_custom_key") upgrade_configs(project.project_dir, logger, FIRST_USER_CONFIG_VERSION) upgraded_project = Project( project_dir=project.project_dir, user_config_file_path=project.user_config_file_path) assert upgraded_project.config.get(upgraded_key) == legacy_value assert upgraded_project.project_config.get(upgraded_key) == legacy_value default_user_config = Config( load_user_default_config(version=FIRST_USER_CONFIG_VERSION)) assert upgraded_project.user_config.get( upgraded_key) == default_user_config.get(upgraded_key)
def test_reset_chain_on_empty_project_dir(project_dir, write_project_file): project = Project() data_dir = project.get_blockchain_data_dir('test-chain') ensure_path_exists(data_dir) chaindata_dir = project.get_blockchain_chaindata_dir('test-chain') dapp_dir = project.get_blockchain_dapp_dir('test-chain') nodekey_path = project.get_blockchain_nodekey_path('test-chain') geth_ipc_path = project.get_blockchain_ipc_path('test-chain') # sanity check assert os.path.exists(data_dir) assert not os.path.exists(chaindata_dir) assert not os.path.exists(dapp_dir) assert not os.path.exists(nodekey_path) assert not os.path.exists(geth_ipc_path) reset_chain(data_dir) assert os.path.exists(data_dir) assert not os.path.exists(chaindata_dir) assert not os.path.exists(dapp_dir) assert not os.path.exists(nodekey_path) assert not os.path.exists(geth_ipc_path)
def test_select_project_contract_helper(project_dir, write_project_file, input, expected_name): write_project_file('contracts/ContractA.sol', 'contract A { function A() {}}') write_project_file('contracts/ContractB.sol', 'contract B { function B() {}}') write_project_file('contracts/ContractC.sol', 'contract C { function C() {}}') project = Project() assert 'A' in project.compiled_contract_data assert 'B' in project.compiled_contract_data assert 'C' in project.compiled_contract_data @click.command() def wrapper(): contract_name = select_project_contract(project) print("~~{0}~~".format(contract_name)) runner = CliRunner() result = runner.invoke(wrapper, [], input="{0}\n".format(input)) assert result.exit_code == 0 expected = "~~{0}~~".format(expected_name) assert expected in result.output
def test_cli_select_chain_helper(project_dir, write_project_file, stdin, expected): project = Project(project_dir) project.config['chains.local_a.chain.class'] = 'populus.chain.TesterChain' project.config[ 'chains.local_a.web3.provider.class'] = 'web3.providers.ipc.IPCProvider' project.config['chains.local_a.web3.provider.settings.ipc_path'] = ( get_geth_ipc_path( get_local_chain_datadir(project.project_dir, 'local_a'))) project.config['chains.local_b.chain.class'] = 'populus.chain.TesterChain' project.config[ 'chains.local_b.web3.provider.class'] = 'web3.providers.ipc.IPCProvider' project.config['chains.local_b.web3.provider.settings.ipc_path'] = ( get_geth_ipc_path( get_local_chain_datadir(project.project_dir, 'local_b'))) project.config['chains.local_c.chain.class'] = 'populus.chain.TesterChain' project.config[ 'chains.local_c.web3.provider.class'] = 'web3.providers.ipc.IPCProvider' project.config['chains.local_c.web3.provider.settings.ipc_path'] = ( get_geth_ipc_path( get_local_chain_datadir(project.project_dir, 'local_c'))) @click.command() def wrapper(): chain_name = select_chain(project) print("~~{0}~~".format(chain_name)) runner = CliRunner() result = runner.invoke(wrapper, [], input=stdin) assert result.exit_code == 0 assert expected in result.output
def test_project_directory_properties(project_dir): project = Project() contracts_dir = get_contracts_dir(project_dir) assert is_same_path(project.contracts_dir, contracts_dir) build_dir = get_build_dir(project_dir) assert is_same_path(project.build_dir, build_dir) compiled_contracts_file_path = get_compiled_contracts_file_path( project_dir) assert is_same_path(project.compiled_contracts_file_path, compiled_contracts_file_path) blockchains_dir = get_blockchains_dir(project_dir) assert is_same_path(project.blockchains_dir, blockchains_dir) data_dir = get_data_dir(project_dir, 'some-test-chain-name') assert is_same_path( project.get_blockchain_data_dir('some-test-chain-name'), data_dir) chaindata_dir = get_chaindata_dir(data_dir) assert is_same_path( project.get_blockchain_chaindata_dir('some-test-chain-name'), chaindata_dir) geth_ipc_path = get_geth_ipc_path(data_dir) assert is_same_path( project.get_blockchain_ipc_path('some-test-chain-name'), geth_ipc_path)
def test_initialized(): """Crowdsale is properly initialized with given parameters.""" project_dir = DATACOIN_PATH project = Project(project_dir, create_config_file=True) with project.get_chain('tester') as chain: beneficiary = chain.web3.eth.accounts[3] multisig = chain.web3.eth.accounts[4] # Initialize crowdsale args = [beneficiary, multisig, 0] crowdsale, _ = chain.provider.get_or_deploy_contract('Crowdsale', deploy_args=args) # Initialize token args = [beneficiary] # Owner set token, _ = chain.provider.get_or_deploy_contract('DataCoin', deploy_args=args) assert crowdsale.call().tokenReward( ) == '0x0000000000000000000000000000000000000000' crowdsale.transact({"from": beneficiary}).setToken(token.address) assert crowdsale.call().tokenReward( ) != '0x0000000000000000000000000000000000000000' token.transact({ "from": beneficiary }).approve(crowdsale.address, 440000000) assert token.call().balanceOf(beneficiary) == 500000000 assert token.call().totalSupply() == 500000000 assert token.call().owner().lower() == beneficiary assert token.call().allowance(beneficiary, crowdsale.address) == 440000000 assert token.call().owner().lower() == crowdsale.call().beneficiary( ).lower()
def test_with_successful_deploy_sans_runtime_bytecode(project_dir, MATH): project = Project() chain = project.get_chain('testrpc') exports = [] with chain: Math = chain.web3.eth.contract( abi=MATH['abi'], code=MATH['code'], ) assert not Math.code_runtime @click.command() def wrapper(): math_contract = deploy_contract_and_verify( chain, contract_name='Math', base_contract_factory=Math, ) exports.append(math_contract) print("~~{0}~~".format(math_contract.address)) runner = CliRunner() result = runner.invoke(wrapper, []) assert result.exit_code == 0, str(result.output) + '\n' + str(result.exception) assert len(exports) == 1 math_contract = exports[0] expected = "~~{0}~~".format(math_contract.address) assert expected in result.output assert "Verified contract bytecode" not in result.output assert "No runtime available" in result.output
def test_deploying_contract_with_error_during_deploy_sanity_check(project_dir, THROWER): """ Just a sanity check that the `Thrower` contract can be successfully deployed. """ project = Project() chain = project.get_chain('testrpc') exports = [] with chain: Thrower = chain.web3.eth.contract(**THROWER) @click.command() def wrapper(): math_contract = deploy_contract_and_verify( chain, contract_name='Thrower', base_contract_factory=Thrower, deploy_arguments=[False], ) exports.append(math_contract) print("~~{0}~~".format(math_contract.address)) runner = CliRunner() result = runner.invoke(wrapper, []) assert result.exit_code == 0 assert "Verified contract bytecode" in result.output assert "No runtime available" not in result.output
def test_upgrade_to_user_config(project, from_legacy_version): shutil.copyfile( get_default_config_path(version=from_legacy_version), get_legacy_json_config_file_path(project_dir=project.project_dir)) os.remove(project.config_file_path) logger = logging.getLogger("test.test_upgrade_to_user_config") upgrade_configs(project.project_dir, logger, FIRST_USER_CONFIG_VERSION) upgraded_project = Project( project_dir=project.project_dir, user_config_file_path=project.user_config_file_path) expected_user_config = Config( load_user_default_config(FIRST_USER_CONFIG_VERSION)) expected_user_config.unref() expected_project_config = Config( load_default_config(FIRST_USER_CONFIG_VERSION)) expected_project_config.unref() assert upgraded_project.legacy_config_path is None assert upgraded_project.config == expected_user_config assert upgraded_project.user_config == expected_user_config assert upgraded_project.project_config == expected_project_config
def test_cli_select_chain_helper(project_dir, write_project_file, stdin, expected): write_project_file( 'populus.ini', '\n'.join(( "[chain:local_a]", # 0 "", "[chain:local_b]", # 1 "", "[chain:local_c]", # 2 "", "[chain:mainnet]", # 3 "", "[chain:morden]", # 4 "", "[chain:testrpc]", # 5 ))) project = Project() assert 'local_a' in project.config.chains assert 'local_b' in project.config.chains assert 'local_c' in project.config.chains @click.command() def wrapper(): chain_name = select_chain(project) print("~~{0}~~".format(chain_name)) runner = CliRunner() result = runner.invoke(wrapper, [], input=stdin) assert result.exit_code == 0 assert expected in result.output
def project(request, pytestconfig): project_dir = get_populus_option(cmdline_option="--populus-project", ini_option="populus_project", environ_var="PYTEST_POPULUS_PROJECT", pytestconfig=pytestconfig, default=pytestconfig.args[0]) if not os.path.exists(get_json_config_file_path(project_dir)): raise FileNotFoundError( "No populus project found for testing in {project_dir}".format( project_dir=project_dir)) contracts = request.config.cache.get(CACHE_KEY_CONTRACTS, None) mtime = request.config.cache.get(CACHE_KEY_MTIME, None) project = Project(project_dir, create_config_file=True) project.fill_contracts_cache(contracts, mtime) request.config.cache.set( CACHE_KEY_CONTRACTS, normalize_object_for_json(project.compiled_contract_data), ) request.config.cache.set( CACHE_KEY_MTIME, get_latest_mtime(project.get_all_source_file_paths()), ) return project
def test_project_tester_chain(project_dir): project = Project(project_dir) chain = project.get_chain('tester') with chain as running_tester_chain: web3 = running_tester_chain.web3 assert web3.version.node.startswith('TestRPC')
def test_project_tester_chain(project_dir): project = Project(project_dir) chain = project.get_chain('tester') with chain as running_tester_chain: web3 = running_tester_chain.web3 assert web3.clientVersion.startswith('EthereumTester')
def test_project_testrpc_chain(project_dir): project = Project(project_dir, create_config_file=True) chain = project.get_chain('testrpc') with chain as running_tester_chain: web3 = running_tester_chain.web3 assert web3.version.node.startswith('TestRPC')
def test_project_contract_factories_property(project_dir, write_project_file, MATH): write_project_file('contracts/Math.sol', MATH['source']) project = Project() with project.get_chain('testrpc') as chain: assert len(chain.contract_factories.Math.abi) == len(MATH['abi']) assert len(chain.contract_factories.Math.code) > 2 assert len(chain.contract_factories.Math.code_runtime) > 2
def test_project_temp_chain(project_dir): project = Project() chain = project.get_chain('temp') with chain as running_temp_chain: web3 = running_temp_chain.web3 assert hasattr(running_temp_chain, 'geth') assert web3.version.node.startswith('Geth')
def test_buy_tokens(): """Sending ETH successfully buys tokens.""" start = 1488294000 end = 1490112000 project_dir = DATACOIN_PATH project = Project(project_dir, create_config_file=True) with project.get_chain('tester') as chain: beneficiary = chain.web3.eth.accounts[3] multisig = chain.web3.eth.accounts[4] customer = chain.web3.eth.accounts[1] # Initialize crowdsale args = [beneficiary, multisig, 0] crowdsale, _ = chain.provider.get_or_deploy_contract('Crowdsale', deploy_args=args) # Initialize token args = [beneficiary] # Owner set token, _ = chain.provider.get_or_deploy_contract('DataCoin', deploy_args=args) assert crowdsale.call().tokenReward( ) == '0x0000000000000000000000000000000000000000' crowdsale.transact({"from": beneficiary}).setToken(token.address) assert crowdsale.call().tokenReward( ) != '0x0000000000000000000000000000000000000000' token.transact({ "from": beneficiary }).approve(crowdsale.address, 440000000) # Doing open crowdsale crowdsale.transact().setCurrent(start + 1) token.transact().setCurrent(start + 1) chain.web3.eth.sendTransaction({ "from": customer, "to": crowdsale.address, "value": Web3.toWei(20, "ether"), "gas": 250000, }) # We get ERC-20 event events = token.pastEvents("Transfer").get() assert len(events) == 1 e = events[0] assert e["args"]["to"].lower() == customer assert e["args"]["from"].lower() == beneficiary assert e["args"]["value"] == 24000 # We get crowdsale event events = crowdsale.pastEvents("FundTransfer").get() assert len(events) == 1 e = events[0] assert e["args"]["backer"].lower() == customer assert e["args"]["amount"] == Web3.toWei(20, "ether") assert e["args"]["amountRaised"] == Web3.toWei(20, "ether")
def local_chain(project_dir, write_project_file): write_project_file('populus.ini', '[chain:local]') project = Project() chain = project.get_chain('local') # create a new account create_new_account(chain.geth.data_dir, b'a-test-password') return chain
def local_chain(project_dir): project = Project() project.config['chains.local.chain.class'] = 'populus.chain.LocalGethChain' project.config['chains.local.web3.provider.class'] = 'web3.providers.ipc.IPCProvider' project.config['chains.local.contracts.backends.Memory.$ref'] = 'contracts.backends.Memory' project.write_config() chain = project.get_chain('local') return chain
def test_initializing_no_choices(project_dir, write_project_file): write_project_file('populus.ini', "[chain:local_a]") project = Project() with project.get_chain('local_a') as chain: project.config.set('chain:local_a', 'deploy_from', chain.web3.eth.coinbase) project.write_config() runner = CliRunner() result = runner.invoke( main, ['chain', 'init', 'local_a'], ) assert result.exit_code == 0, result.output + str(result.exception) updated_project = Project() assert 'registrar' in updated_project.config.chains['local_a'] assert 'deploy_from' in updated_project.config.chains['local_a']
def main(ctx, config): """ Populus """ project = Project(config) if not any(is_same_path(p, project.project_dir) for p in sys.path): # ensure that the project directory is in the sys.path sys.path.insert(0, project.project_dir) ctx.obj = {} ctx.obj['PROJECT'] = project
def main(ctx, config_file_path): """ Populus """ logger = get_logger_with_click_handler('populus') if not config_file_path and check_if_ini_config_file_exists(): logger.info("Attempting to upgrade legacy `populus.ini` config file") try: backup_ini_config_file_path = upgrade_legacy_config_file( os.getcwd()) except: logger.error( "The following error occured while trying to upgrade the legacy " "`populus.ini` config file:") raise else: logger.info( "Project configuration upgraded. New config file " "`populus.json` has been written. Old config file was renamed " "to `{0}`".format(backup_ini_config_file_path)) project = Project(config_file_path) config_version = project.config['version'] subcommand_bypasses_config_version = ctx.invoked_subcommand in { 'config', 'init' } if not subcommand_bypasses_config_version and config_version != LATEST_VERSION: old_config_version_msg = ( "================ warning =================\n" "Your populus config file is current at version {0}. " "The latest version is {1}. You can use the `populus config " "upgrade` command to upgrade your config file to the latest version\n" "================ warning =================\n\n".format( config_version, LATEST_VERSION, )) warnings.warn(DeprecationWarning(old_config_version_msg)) logger.warning(old_config_version_msg) proceed_msg = ( "Without and up-to-date configuration file Populus may not function " "correctly. Would you still like to proceed?") if not click.confirm(proceed_msg): ctx.exit(1) if not any(is_same_path(p, project.project_dir) for p in sys.path): # ensure that the project directory is in the sys.path sys.path.insert(0, project.project_dir) ctx.obj = {} ctx.obj['PROJECT'] = project
def test_project_morden_chain(project_dir): project = Project() chain = project.get_chain('morden') with chain as running_morden_chain: web3 = running_morden_chain.web3 assert web3.version.node.startswith('Geth') running_morden_chain.wait.for_block(block_number=1, timeout=180) block_1 = web3.eth.getBlock(1) assert block_1['hash'] == TESTNET_BLOCK_1_HASH
def project(request): contracts = request.config.cache.get(CACHE_KEY_CONTRACTS, None) mtime = request.config.cache.get(CACHE_KEY_MTIME, None) project = Project() project.fill_contracts_cache(contracts, mtime) request.config.cache.set(CACHE_KEY_CONTRACTS, project.compiled_contract_data) request.config.cache.set(CACHE_KEY_MTIME, project.get_source_modification_time()) return project
def local_chain(project_dir): project = Project() project.config['chains.local.chain.class'] = 'populus.chain.LocalGethChain' project.config[ 'chains.local.web3.provider.class'] = 'web3.providers.ipc.IPCProvider' project.config['chains.local.web3.provider.settings.ipc_path'] = ( get_geth_ipc_path(get_local_chain_datadir(project.project_dir, 'local'))) project.write_config() chain = project.get_chain('local') return chain
def test_initializing_local_chain(project_dir, write_project_file): write_project_file('populus.ini', "[chain:local_a]") project = Project() runner = CliRunner() chain = project.get_chain('local_a') deploy_from = force_text( create_new_account(chain.geth.data_dir, b'a-test-password')) with chain: chain.wait.for_unlock(chain.web3.eth.coinbase, timeout=30) funding_txn_hash = chain.web3.eth.sendTransaction({ 'from': chain.web3.eth.coinbase, 'to': deploy_from, 'value': int(chain.web3.toWei(10, 'ether')), }) chain.wait.for_receipt(funding_txn_hash, timeout=60) result = runner.invoke( main, ['chain', 'init'], input=(( "local_a\n" # choose chain. "{0}\n" # pick deploy account. "Y\n" # set account as default "a-test-password\n" # unlock account "".format(deploy_from)))) assert result.exit_code == 0, result.output + str(result.exception) updated_project = Project() assert 'registrar' in updated_project.config.chains['local_a'] assert 'deploy_from' in updated_project.config.chains['local_a']
def test_select_account_with_invalid_option(project_dir, stdin): project = Project() chain = project.get_chain('temp') @click.command() def wrapper(): account = select_account(chain) print("~~{0}~~".format(account)) with chain: runner = CliRunner() result = runner.invoke(wrapper, [], input="{0}\n".format(stdin)) assert result.exit_code != 0
def project(request): # This should probably be configurable using the `request` fixture but it's # unclear what needs to be configurable. # use pytest cache to preset the sessions project to recently compiled contracts contracts = request.config.cache.get(CACHE_KEY_CONTRACTS, None) mtime = request.config.cache.get(CACHE_KEY_MTIME, None) project = Project() project.fill_contracts_cache(contracts, mtime) request.config.cache.set(CACHE_KEY_CONTRACTS, project.compiled_contracts) request.config.cache.set(CACHE_KEY_MTIME, project.get_source_modification_time()) return project