Skip to content

Commit

Permalink
Updates from Sidechains-Tests Repo (#244)
Browse files Browse the repository at this point in the history
* deploy: update staging test plan PR#354

* ETCM-7127 automate scp keys - sidechains-tests PR#254

* fix: scp fixture didn't yield

* add: diff commits from old repo

* fix: slack alerts version

* fix devnet version add fixture to registration test

* fix: run devnet tests from master

issue:
- tests will fail because master code is v1.3.0, not compatible with v1.2.0. In v1.2.0 tag tests weren't migrated yet, so the easiest fix is to deploy 1.3.0 to devnet

* chore: devnet 1.3.0 deployment

* e2e-tests/ fix path to debug log

* e2e-tests/update pc smart contracts version for devnet

* debug

---------

Co-authored-by: Radosław Sporny <[email protected]>
  • Loading branch information
ladamesny and rsporny authored Nov 18, 2024
1 parent bf87b72 commit 1b1f868
Show file tree
Hide file tree
Showing 13 changed files with 128 additions and 28 deletions.
16 changes: 12 additions & 4 deletions .github/workflows/devnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ jobs:
- name: checkout code
uses: actions/checkout@v4
with:
ref: ${{ github.event_name == 'workflow_dispatch' && github.ref_name || 'v1.2.0' }}
ref: ${{ github.event_name == 'workflow_dispatch' && github.ref_name || 'master' }}

- name: Set deployment_version as env variable
run: echo "DEPLOYMENT_VERSION=$(jq -r .deployment_version ./config/substrate/devnet_nodes.json)" >> $GITHUB_ENV
run: echo "DEPLOYMENT_VERSION=$(jq -r .deployment_version ./E2E-tests/config/substrate/devnet_nodes.json)" >> $GITHUB_ENV

- name: Set XRay variables
run: |
Expand All @@ -89,7 +89,7 @@ jobs:
env:
EARTHLY_BUILD_ARGS: "CI_RUN=true"
FORCE_COLOR: 1
SLACK_REF_NAME: ${{ github.event_name == 'schedule' && format('{0}/v{1}', env.TEST_ENVIRONMENT, env.DEPLOYMENT_VERSION) || github.ref_name }}
SLACK_REF_NAME: ${{ github.event_name == 'schedule' && format('{0}/{1}', env.TEST_ENVIRONMENT, env.DEPLOYMENT_VERSION) || github.ref_name }}
LOG_LEVEL: ${{ inputs.log_level }}
KEYWORD: ${{ inputs.keyword }}
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
Expand Down Expand Up @@ -131,14 +131,22 @@ jobs:
--decrypt=true \
--markers="$MARKERS"
- name: Add Line Numbers and Timestamps to debug.log
if: always()
run: |
cd E2E-tests
awk '{print strftime("[%Y-%m-%d %H:%M:%S]"), $0}' debug.log > debug_with_timestamps.log
nl -ba -s ' ' -w 8 debug_with_timestamps.log > debug_with_timestamps_and_line_numbers.log
mv debug_with_timestamps_and_line_numbers.log debug.log
- name: Archive Debug Log
if: always()
uses: actions/upload-artifact@v4
with:
name: debug_log
retention-days: 15
overwrite: true
path: debug.log
path: E2E-tests/debug.log

- name: Setup Node
uses: actions/setup-node@v4
Expand Down
16 changes: 12 additions & 4 deletions .github/workflows/staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ jobs:
ref: ${{ github.event_name == 'workflow_dispatch' && github.ref_name || 'master' }}

- name: Set deployment_version as env variable
run: echo "DEPLOYMENT_VERSION=$(jq -r .deployment_version ./config/substrate/staging_nodes.json)" >> $GITHUB_ENV
run: echo "DEPLOYMENT_VERSION=$(jq -r .deployment_version ./E2E-tests/config/substrate/staging_nodes.json)" >> $GITHUB_ENV

- name: Set XRay variables
run: |
Expand All @@ -72,7 +72,7 @@ jobs:
elif [ ! -z "${{ inputs.execution }}" ]; then
echo "TEST_EXECUTION=${{ inputs.execution }}" >> $GITHUB_ENV
else
echo "TEST_PLAN=ETCM-8916" >> $GITHUB_ENV
echo "TEST_PLAN=ETCM-8562" >> $GITHUB_ENV
fi
- name: set report_to_xray env variable
Expand All @@ -90,7 +90,7 @@ jobs:
env:
EARTHLY_BUILD_ARGS: "CI_RUN=true"
FORCE_COLOR: 1
SLACK_REF_NAME: ${{ github.event_name == 'schedule' && format('{0}/v{1}', env.TEST_ENVIRONMENT, env.DEPLOYMENT_VERSION) || github.ref_name }}
SLACK_REF_NAME: ${{ github.event_name == 'schedule' && format('{0}/{1}', env.TEST_ENVIRONMENT, env.DEPLOYMENT_VERSION) || github.ref_name }}
LOG_LEVEL: ${{ inputs.log_level }}
KEYWORD: ${{ inputs.keyword }}
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
Expand Down Expand Up @@ -132,14 +132,22 @@ jobs:
--decrypt=true \
--markers="$MARKERS"
- name: Add Line Numbers and Timestamps to debug.log
if: always()
run: |
cd E2E-tests
awk '{print strftime("[%Y-%m-%d %H:%M:%S]"), $0}' debug.log > debug_with_timestamps.log
nl -ba -s ' ' -w 8 debug_with_timestamps.log > debug_with_timestamps_and_line_numbers.log
mv debug_with_timestamps_and_line_numbers.log debug.log
- name: Archive Debug Log
if: always()
uses: actions/upload-artifact@v4
with:
name: debug_log
retention-days: 15
overwrite: true
path: debug.log
path: E2E-tests/debug.log

- name: Setup Node
uses: actions/setup-node@v4
Expand Down
4 changes: 0 additions & 4 deletions E2E-tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,6 @@ Custom options:
Overrides node port
--init-timestamp=INIT_TIMESTAMP
Initial timestamp of the mainchain.
--qa-db-password=QA_DB_PASSWORD
Password override for test database.
--db-sync-password=DB_SYNC_PASSWORD
Password for db sync database
--latest-mc-epoch Parametrize committee tests to verify whole last MC epoch. Transforms sc_epoch param to range of SC epochs for last MC epoch.
--mc-epoch=MC_EPOCH MC epoch that parametrizes committee tests to verify the whole given MC epoch. Translates sc_epoch param to range of SC epochs for given MC epoch.
--sc-epoch=SC_EPOCH SC epoch that parametrizes committee tests, default: <last_sc_epoch>.
Expand Down
10 changes: 5 additions & 5 deletions E2E-tests/config/substrate/devnet_nodes.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"chain_id": 1,
"deployment_mc_epoch": 708,
"initial_pc_epoch": 4799622,
"deployment_mc_epoch": 755,
"initial_pc_epoch": 4810931,
"genesis_committee_hash_utxo": "0000000000000000000000000000000000000000000000000000000000000000#0",
"governance_authority": "0x76da17b2e3371ab7ca88ce0500441149f03cc5091009f99c99c080d9",
"deployment_version": "1.2.0-rc3",
"deployment_version": "1.3.0",
"test_environment": "devnet",
"committee_participation_tolerance": 0.21,
"nodes_config": {
Expand Down Expand Up @@ -63,7 +63,7 @@
"rotation_candidate": true,
"cardano_payment_addr": "addr_test1vr88zd5ywcdu07hqpnutd8umqyld34e6rrtzgu7m3rua67gg6clcz",
"keys_files": {
"cardano_payment_key": "/secrets/substrate/devnet/keys/eve/payment.skey.json.decrypted",
"cardano_payment_key": "./secrets/substrate/devnet/keys/eve/payment.skey.json.decrypted",
"spo_signing_key": "./secrets/substrate/devnet/keys/eve/cold.skey.json.decrypted",
"spo_public_key": "./secrets/substrate/devnet/keys/eve/cold.vkey.json.decrypted",
"partner_chain_signing_key": "./secrets/substrate/devnet/keys/eve/partner_chain.skey.json.decrypted"
Expand All @@ -81,7 +81,7 @@
"rotation_candidate": true,
"cardano_payment_addr": "addr_test1vrkp4j33xcysqfancc7fttdrwf86ztgpaqhhzu98vahnevqfng7r9",
"keys_files": {
"cardano_payment_key": "/secrets/substrate/devnet/keys/ferdie/payment.skey.json.decrypted",
"cardano_payment_key": "./secrets/substrate/devnet/keys/ferdie/payment.skey.json.decrypted",
"spo_signing_key": "./secrets/substrate/devnet/keys/ferdie/cold.skey.json.decrypted",
"spo_public_key": "./secrets/substrate/devnet/keys/ferdie/cold.vkey.json.decrypted",
"partner_chain_signing_key": "./secrets/substrate/devnet/keys/ferdie/partner_chain.skey.json.decrypted"
Expand Down
2 changes: 1 addition & 1 deletion E2E-tests/config/substrate/devnet_stack.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"ssh": "${stack_config[ssh]}"
},
"sidechain_main_cli": {
"cli": "/tools/partner-chains-smart-contracts-6.1.0/sidechain-cli",
"cli": "/tools/partner-chains-smart-contracts-6.2.2/pc-contracts-cli",
"ssh": "${stack_config[ssh]}"
},
"generate_signatures_cli": {
Expand Down
8 changes: 4 additions & 4 deletions E2E-tests/config/substrate/staging_nodes.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"chain_id": 1,
"deployment_mc_epoch": 744,
"deployment_mc_epoch": 749,
"genesis_committee_hash_utxo": "4e65eddc6132c1b9891d43f9d67a4a0a7b6e614b648f59dc97538f3f23eb96bf#1",
"governance_authority": "0x1f0977bc0f57c67ca6d77296c1b575fe05a6dc2c5fa38056ba63c50c",
"deployment_version": "v1.3.0-rc1",
"deployment_version": "v1.3.0",
"test_environment": "staging",
"nodes_config": {
"nodes": {
Expand All @@ -18,7 +18,7 @@
"rotation_candidate": true,
"cardano_payment_addr": "addr_test1vq6ywn0f007x32j47jrk5qy9hy3gknsvszrcpdqkeaye7pshu2w2t",
"keys_files": {
"cardano_payment_key": "/secrets/substrate/staging/keys/validator-1/payment.skey.json.decrypted",
"cardano_payment_key": "./secrets/substrate/staging/keys/validator-1/payment.skey.json.decrypted",
"spo_signing_key": "./secrets/substrate/staging/keys/validator-1/cold.skey.json.decrypted",
"spo_public_key": "./secrets/substrate/staging/keys/validator-1/cold.vkey.json.decrypted",
"partner_chain_signing_key": "./secrets/substrate/staging/keys/validator-1/partner_chain.skey.json.decrypted"
Expand Down Expand Up @@ -126,7 +126,7 @@
},
"governance_authority": {
"mainchain_address": "addr_test1vq0sjaaupatuvl9x6aefdsd4whlqtfku93068qzkhf3u2rqt9cnuq",
"mainchain_key": "/secrets/substrate/staging/keys/governance_authority/init.skey.json.decrypted"
"mainchain_key": "./secrets/substrate/staging/keys/governance_authority/init.skey.json.decrypted"
},
"selected_node": "validator-4",
"node": "${nodes_config[nodes][${nodes_config[selected_node]}]}",
Expand Down
3 changes: 2 additions & 1 deletion E2E-tests/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ pydantic==2.5.3
scalecodec==1.2.8
paramiko==3.4.0
pytest-json-ctrf==0.3.5
numpy==1.26.4
numpy==1.26.4
scp==0.15.0
14 changes: 13 additions & 1 deletion E2E-tests/src/run_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import yaml
from abc import ABC, abstractmethod
from config.api_config import SSH
from scp import SCPClient
import time


Expand Down Expand Up @@ -118,7 +119,8 @@ def load_key_from_yaml(self, path):
def connect(self):
logging.debug(f"SSH: Connecting to {self.host}:{self.port} as {self.user}")
try:
private_key = paramiko.RSAKey.from_private_key(io.StringIO(self.load_key_from_yaml(self.key_path)))
private_key_str = self.load_key_from_yaml(self.key_path)
private_key = paramiko.RSAKey.from_private_key(io.StringIO(private_key_str))
self.client.connect(self.host, self.port, self.user, pkey=private_key)
except paramiko.AuthenticationException as auth_err:
logging.error(f"Authentication failed: {auth_err}")
Expand Down Expand Up @@ -168,5 +170,15 @@ def run(self, command: str, timeout=120) -> Result:
finally:
self.close()

def scp(self, path, remote_path):
self.connect()
logging.debug(f"SCP: '{path}' INTO: {remote_path}")
try:
with SCPClient(self.client.get_transport()) as scp:
scp.put(path, remote_path=remote_path)
finally:
self.close()

def close(self):
self.client.close()
logging.debug(f"SSH: disconnected from {self.host}:{self.port} as {self.user}")
66 changes: 65 additions & 1 deletion E2E-tests/tests/committee/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from src.partner_chain_rpc import DParam
from src.pc_epoch_calculator import PartnerChainEpochCalculator
from src.pc_block_finder import BlockFinder
from src.run_command import RunnerFactory

block_finder: BlockFinder = None

Expand Down Expand Up @@ -554,4 +555,67 @@ def _get_pc_epoch_blocks(epoch, blocks_dict=blocks_dict, api=api):
blocks_dict[epoch][block] = api.get_block(block)
return blocks_dict[epoch]

yield _get_pc_epoch_blocks
yield _get_pc_epoch_blocks


@fixture
def candidate_skey_with_cli(config: ApiConfig, candidate: Candidates):
"""
Securely copy the candidate's Cardano payment key (a secret key used by the PCSC CLI to pay fees) to a temporary
directory on the remote machine and update the path in the configuration. The temporary directory is deleted after
the test completes.
This fixture is executed only if SSH is configured in the stack settings, implying that the PCSC CLI (which
requires the key to be present on the localhost) is installed on the remote machine. Therefore, the key is
implicitly copied using SCP.
WARNING: This fixture copies secret file to a remote host and should be used with caution.
NOTE: Ensure that the SSH settings are correctly configured in the stack config.
:param config: The API configuration object.
:param candidate: The candidate to register/deregister.
"""
if config.stack_config.ssh:
runner = RunnerFactory.get_runner(config.stack_config.ssh, "/bin/bash")
temp_dir = runner.run("mktemp -d").stdout.strip()
path = config.nodes_config.nodes[candidate.name].keys_files.cardano_payment_key
filename = path.split("/")[-1]
runner.scp(path, temp_dir)
config.nodes_config.nodes[candidate.name].keys_files.cardano_payment_key = f"{temp_dir}/{filename}"
yield
config.nodes_config.nodes[candidate.name].keys_files.cardano_payment_key = path
runner.run(f"rm -rf {temp_dir}")
else:
yield


@fixture
def governance_skey_with_cli(config: ApiConfig):
"""
Securely copy the governance authority's init skey (a secret key used by the PCSC CLI to authorize admin operations)
to a temporary directory on the remote machine and update the path in the configuration. The temporary directory is
deleted after the test completes.
This fixture is executed only if SSH is configured in the stack settings, implying that the PCSC CLI (which
requires the key to be present on the localhost) is installed on the remote machine. Therefore, the key is
implicitly copied using SCP.
WARNING: This fixture copies secret file to a remote host and should be used with caution.
NOTE: Ensure that the SSH settings are correctly configured in the stack config.
:param config: The API configuration object.
"""
if config.stack_config.ssh:
runner = RunnerFactory.get_runner(config.stack_config.ssh, "/bin/bash")
temp_dir = runner.run("mktemp -d").stdout.strip()
path = config.nodes_config.governance_authority.mainchain_key
filename = path.split("/")[-1]
runner.scp(path, temp_dir)
config.nodes_config.governance_authority.mainchain_key = f"{temp_dir}/{filename}"
yield
config.nodes_config.governance_authority.mainchain_key = path
runner.run(f"rm -rf {temp_dir}")
else:
yield
2 changes: 0 additions & 2 deletions E2E-tests/tests/committee/test_blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
@mark.skip_blockchain("pc_evm", reason="not implemented yet on pc_evm")
@mark.test_key('ETCM-7019')
@mark.block_reward
@mark.block_author
def test_block_beneficiaries_match_committee_seats(
api: BlockchainApi, config: ApiConfig, get_pc_epoch_committee, pc_epoch, get_pc_epoch_blocks
):
Expand Down Expand Up @@ -73,7 +72,6 @@ def test_block_beneficiaries_match_committee_seats(
@mark.skip_on_new_chain
@mark.test_key('ETCM-7020')
@mark.committee_rotation
@mark.block_author
def test_block_authors_match_committee_seats(
api: BlockchainApi,
config: ApiConfig,
Expand Down
2 changes: 2 additions & 0 deletions E2E-tests/tests/committee/test_permissioned_registrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
@mark.test_key('ETCM-7015')
@mark.registration
@mark.xdist_group(name="governance_action")
@mark.usefixtures("governance_skey_with_cli")
def test_add_permissioned_candidate(permissioned_candidate: PermissionedCandidates, api: BlockchainApi, db: Session):
"""Test addition of the permissioned candidate
Expand Down Expand Up @@ -65,6 +66,7 @@ def test_add_permissioned_candidate(permissioned_candidate: PermissionedCandidat
@mark.test_key('ETCM-7016')
@mark.registration
@mark.xdist_group(name="governance_action")
@mark.usefixtures("governance_skey_with_cli")
def test_remove_permissioned_candidate(permissioned_candidate: PermissionedCandidates, api: BlockchainApi, db: Session):
"""Test removal of the permissioned candidate
Expand Down
2 changes: 2 additions & 0 deletions E2E-tests/tests/committee/test_registrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
@mark.ariadne
@mark.test_key('ETCM-7017')
@mark.registration
@mark.usefixtures("candidate_skey_with_cli")
def test_register_candidate(candidate: Candidates, api: BlockchainApi, db: Session, config: ApiConfig):
"""Test registration of the trustless (SPO) candidate
Expand Down Expand Up @@ -60,6 +61,7 @@ def test_register_candidate(candidate: Candidates, api: BlockchainApi, db: Sessi
@mark.ariadne
@mark.test_key('ETCM-7018')
@mark.registration
@mark.usefixtures("candidate_skey_with_cli")
def test_deregister_candidate(candidate: Candidates, api: BlockchainApi, db: Session, config: ApiConfig):
"""Test deregistration of the trustless (SPO) candidate
Expand Down
11 changes: 10 additions & 1 deletion E2E-tests/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,15 @@ def pytest_configure(config: Config):
partner_chain_rpc_api = PartnerChainRpc(_config.nodes_config.node.rpc_url)
partner_chain_epoch_calc = PartnerChainEpochCalculator(_config)

logger = logging.getLogger()
logger.addFilter(TimestampFilter())


class TimestampFilter(logging.Filter):
def filter(self, record):
record.asctime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(record.created))
return True


def pytest_generate_tests(metafunc: Metafunc):
if "mc_epoch" in metafunc.fixturenames or "pc_epoch" in metafunc.fixturenames:
Expand Down Expand Up @@ -486,4 +495,4 @@ def _wait_until(condition, *args, timeout=10, poll_interval=10):
time.sleep(poll_interval)
raise TimeoutError(f"WAIT UNTIL function TIMED OUT after {timeout}s on {condition} with args {args}.")

yield _wait_until
yield _wait_until

0 comments on commit 1b1f868

Please sign in to comment.