diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml deleted file mode 100644 index 4fe935160de..00000000000 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: Bug report -description: Use this issue template if something is not working the way it should be. -title: "[Bug] " -labels: ["bug"] -body: - - type: markdown - attributes: - value: | - Thanks for taking the time to fill out this bug report! - - type: textarea - id: bug-report - attributes: - label: Bug report - description: Please provide a detailed overview of the expected behavior, and what happens instead. The more details, the better. You can use Markdown. - - type: textarea - id: graph-node-logs - attributes: - label: Relevant log output - description: Please copy and paste any relevant log output (either graph-node or hosted service logs). This will be automatically formatted into code, so no need for backticks. Leave blank if it doesn't apply. - render: Shell - - type: markdown - attributes: - value: Does this bug affect a specific subgraph deployment? If not, leave the following blank. - - type: input - attributes: - label: IPFS hash - placeholder: e.g. QmST8VZnjHrwhrW5gTyaiWJDhVcx6TooRv85B49zG7ziLH - validations: - required: false - - type: input - attributes: - label: Subgraph name or link to explorer - placeholder: e.g. https://thegraph.com/explorer/subgraphs/3nXfK3RbFrj6mhkGdoKRowEEti2WvmUdxmz73tben6Mb?view=Overview&chain=mainnet - validations: - required: false - - type: checkboxes - id: checkboxes - attributes: - label: Some information to help us out - options: - - label: Tick this box if this bug is caused by a regression found in the latest release. - - label: Tick this box if this bug is specific to the hosted service. - - label: I have searched the issue tracker to make sure this issue is not a duplicate. - required: true - - type: dropdown - id: operating-system - attributes: - label: OS information - description: What OS are you running? Leave blank if it doesn't apply. - options: - - Windows - - macOS - - Linux - - Other (please specify in your bug report) diff --git a/.github/ISSUE_TEMPLATE/feature.yml b/.github/ISSUE_TEMPLATE/feature.yml deleted file mode 100644 index 47fa2619714..00000000000 --- a/.github/ISSUE_TEMPLATE/feature.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Feature request -description: To request or discuss new features. -title: "[Feature] " -labels: ["enhancement"] -body: - - type: textarea - id: feature-description - attributes: - label: Description - description: Please provide a detailed overview of the desired feature or improvement, along with any examples or useful information. You can use Markdown. - - type: textarea - id: blockers - attributes: - label: Are you aware of any blockers that must be resolved before implementing this feature? If so, which? Link to any relevant GitHub issues. - validations: - required: false - - type: checkboxes - id: checkboxes - attributes: - label: Some information to help us out - options: - - label: Tick this box if you plan on implementing this feature yourself. - - label: I have searched the issue tracker to make sure this issue is not a duplicate. - required: true diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 977a3b8fc50..00000000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,126 +0,0 @@ -version: 2 -updates: - -- package-ecosystem: npm - directory: tests/integration-tests - schedule: - interval: weekly - open-pull-requests-limit: 10 - allow: - # We always want to test against the latest Graph CLI tooling: `graph-cli`, - # `graph-ts`. - - dependency-name: "@graphprotocol/graph-*" - versioning-strategy: lockfile-only - -- package-ecosystem: cargo - directory: "/" - schedule: - interval: weekly - open-pull-requests-limit: 10 - ignore: - - dependency-name: hyper - versions: - - ">= 0.14.a, < 0.15" - - dependency-name: jsonrpc-core - versions: - - ">= 12.a, < 13" - - dependency-name: postgres - versions: - - ">= 0.17.a, < 0.18" - - dependency-name: rand - versions: - - ">= 0.7.a, < 0.8" - - dependency-name: reqwest - versions: - - ">= 0.11.a, < 0.12" - - dependency-name: futures - versions: - - 0.3.14 - - dependency-name: wasmparser - versions: - - 0.77.0 - - dependency-name: serde - versions: - - 1.0.123 - - 1.0.124 - - 1.0.125 - - dependency-name: priority-queue - versions: - - 1.0.5 - - 1.1.1 - - dependency-name: rand - versions: - - 0.8.3 - - dependency-name: wasmtime - versions: - - 0.24.0 - - 0.25.0 - - dependency-name: syn - versions: - - 1.0.48 - - 1.0.62 - - dependency-name: num-bigint - versions: - - 0.4.0 - - dependency-name: postgres - versions: - - 0.19.0 - - dependency-name: ipfs-api - versions: - - 0.10.0 - - 0.11.0 - - dependency-name: backtrace - versions: - - 0.3.56 - - dependency-name: lru_time_cache - versions: - - 0.11.6 - - 0.11.7 - - 0.11.8 - - dependency-name: mockall - versions: - - 0.9.1 - - dependency-name: serde_json - versions: - - 1.0.62 - - 1.0.64 - - dependency-name: shellexpand - versions: - - 2.1.0 - - dependency-name: async-trait - versions: - - 0.1.42 - - dependency-name: toml - versions: - - 0.5.8 - - dependency-name: regex - versions: - - 1.4.3 - - dependency-name: uuid - versions: - - 0.8.2 - - dependency-name: thiserror - versions: - - 1.0.23 - - 1.0.24 - - dependency-name: http - versions: - - 0.2.3 - - dependency-name: env_logger - versions: - - 0.8.3 - - dependency-name: slog-term - versions: - - 2.8.0 - - dependency-name: jsonrpc-http-server - versions: - - 17.0.0 - - dependency-name: bytes - versions: - - 1.0.1 - - dependency-name: slog-async - versions: - - 2.6.0 - - dependency-name: jsonrpc-core - versions: - - 17.0.0 diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml deleted file mode 100644 index 102a8b53e78..00000000000 --- a/.github/workflows/audit.yml +++ /dev/null @@ -1,18 +0,0 @@ -# See https://github.com/actions-rs/audit-check -name: Security audit -on: - # push: - # paths: - # - '**/Cargo.toml' - # - '**/Cargo.lock' - schedule: - - cron: '0 0 */7 * *' -jobs: - security_audit: - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - uses: actions/checkout@v2 - - uses: actions-rs/audit-check@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index e5f7ad8cbdc..00000000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,206 +0,0 @@ -name: Continuous Integration - -on: - push: - branches: [master] - pull_request: - types: [opened, synchronize, reopened] - -env: - CARGO_TERM_COLOR: always - RUST_BACKTRACE: full - THEGRAPH_STORE_POSTGRES_DIESEL_URL: "postgresql://postgres:postgres@localhost:5432/graph_node_test" - -jobs: - unit-tests: - name: Run unit tests - runs-on: ubuntu-latest - timeout-minutes: 60 - services: - ipfs: - image: ipfs/go-ipfs:v0.10.0 - ports: - - 5001:5001 - postgres: - image: postgres - env: - POSTGRES_PASSWORD: postgres - POSTGRES_DB: graph_node_test - POSTGRES_INITDB_ARGS: "-E UTF8 --locale=C" - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 - ports: - - 5432:5432 - env: - RUSTFLAGS: "-C link-arg=-fuse-ld=lld -D warnings" - steps: - - name: Tune GitHub hosted runner to reduce flakiness - # https://github.com/smorimoto/tune-github-hosted-runner-network/blob/main/action.yml - run: sudo ethtool -K eth0 tx off rx off - - name: Checkout sources - uses: actions/checkout@v2 - - uses: Swatinem/rust-cache@v2 - - - name: Install lld - run: sudo apt-get install -y lld protobuf-compiler - - - name: Run unit tests - uses: actions-rs/cargo@v1 - with: - command: test - args: --verbose --workspace --exclude graph-tests -- --nocapture - - runner-tests: - name: Subgraph Runner integration tests - runs-on: ubuntu-latest - timeout-minutes: 60 - services: - ipfs: - image: ipfs/go-ipfs:v0.10.0 - ports: - - 5001:5001 - postgres: - image: bitnami/postgresql - env: - POSTGRES_PASSWORD: postgres - POSTGRES_DB: graph_node_test - POSTGRES_INITDB_ARGS: "-E UTF8 --locale=C" - POSTGRESQL_EXTRA_FLAGS: "-c max_connections=1000" - options: >- - --health-cmd "pg_isready -U postgres" - --health-interval 10s - --health-timeout 5s - --health-retries 10 - ports: - - 5432:5432 - env: - RUSTFLAGS: "-C link-arg=-fuse-ld=lld -D warnings" - steps: - - name: Tune GitHub hosted runner to reduce flakiness - # https://github.com/smorimoto/tune-github-hosted-runner-network/blob/main/action.yml - run: sudo ethtool -K eth0 tx off rx off - - name: Checkout sources - uses: actions/checkout@v2 - - uses: Swatinem/rust-cache@v2 - - - name: Install lld - run: sudo apt-get install -y lld protobuf-compiler - - - name: Run runner tests - id: runner-tests-1 - uses: actions-rs/cargo@v1 - env: - TESTS_GANACHE_HARD_WAIT_SECONDS: "60" - with: - command: test - args: --verbose --package graph-tests -- --skip parallel_integration_tests - - integration-tests: - name: Run integration tests - runs-on: ubuntu-latest - timeout-minutes: 60 - env: - RUSTFLAGS: "-C link-arg=-fuse-ld=lld -D warnings" - steps: - - name: Tune GitHub hosted runner to reduce flakiness - # https://github.com/smorimoto/tune-github-hosted-runner-network/blob/main/action.yml - run: sudo ethtool -K eth0 tx off rx off - - name: Checkout sources - uses: actions/checkout@v2 - - uses: Swatinem/rust-cache@v2 - - - name: Install Node 16 - uses: actions/setup-node@v3 - with: - node-version: "16" - cache: yarn - cache-dependency-path: "tests/integration-tests/yarn.lock" - - - name: Install lld and jq - run: sudo apt-get install -y lld jq protobuf-compiler - - - name: Build graph-node - uses: actions-rs/cargo@v1 - with: - command: build - args: --bin graph-node - - # Integration tests are a bit flaky, running them twice increases the - # chances of one run succeeding. - - name: Run integration tests (round 1) - id: integration-tests-1 - uses: actions-rs/cargo@v1 - env: - N_CONCURRENT_TESTS: "4" - TESTS_GANACHE_HARD_WAIT_SECONDS: "30" - # Reduce how long a batch will stick around to avoid timeouts - GRAPH_STORE_WRITE_BATCH_DURATION: 30 - with: - command: test - args: --verbose --package graph-tests parallel_integration_tests -- --nocapture - continue-on-error: true - - name: Run integration tests (round 2) - id: integration-tests-2 - uses: actions-rs/cargo@v1 - if: ${{ steps.integration-tests-1.outcome == 'failure' }} - env: - N_CONCURRENT_TESTS: "4" - TESTS_GANACHE_HARD_WAIT_SECONDS: "30" - # Reduce how long a batch will stick around to avoid timeouts - GRAPH_STORE_WRITE_BATCH_DURATION: 30 - with: - command: test - args: --verbose --package graph-tests parallel_integration_tests -- --nocapture - - rustfmt: - name: Check rustfmt style - runs-on: ubuntu-latest - timeout-minutes: 10 - env: - RUSTFLAGS: "-D warnings" - steps: - - uses: actions/checkout@v2 - - - name: Check formatting - uses: actions-rs/cargo@v1 - with: - command: fmt - args: --all -- --check - - clippy: - name: Clippy linting - runs-on: ubuntu-latest - timeout-minutes: 60 - steps: - - uses: actions/checkout@v2 - # Unlike rustfmt, Clippy actually compiles stuff so it benefits from - # caching. - - uses: Swatinem/rust-cache@v2 - - name: Install deps - run: sudo apt-get install -y protobuf-compiler - - name: Run Clippy - uses: actions-rs/cargo@v1 - with: - command: check-clippy - - release-check: - name: Build in release mode - runs-on: ubuntu-latest - timeout-minutes: 60 - env: - RUSTFLAGS: "-D warnings" - steps: - - uses: actions/checkout@v2 - - uses: Swatinem/rust-cache@v2 - - name: Install dependencies - run: | - sudo apt-get update - sudo apt-get -y install libpq-dev protobuf-compiler - - name: Cargo check (release) - uses: actions-rs/cargo@v1 - with: - command: check - args: --release \ No newline at end of file diff --git a/.github/workflows/code-coverage.yml b/.github/workflows/code-coverage.yml deleted file mode 100644 index 5ca14794035..00000000000 --- a/.github/workflows/code-coverage.yml +++ /dev/null @@ -1,74 +0,0 @@ -name: Code coverage - -on: - workflow_dispatch: - schedule: - # Run it every 3 days. - - cron: "0 3 * * *" - -env: - CARGO_TERM_COLOR: always - RUST_BACKTRACE: full - THEGRAPH_STORE_POSTGRES_DIESEL_URL: "postgresql://postgres:postgres@localhost:5432/graph_node_test" - RUSTFLAGS: "-C link-arg=-fuse-ld=lld -D warnings" - N_CONCURRENT_TESTS: "4" - TESTS_GANACHE_HARD_WAIT_SECONDS: "30" - -jobs: - # Heavily inspired from . - coverage: - name: Code coverage of integration tests - runs-on: ubuntu-latest - timeout-minutes: 60 - services: - ipfs: - image: ipfs/go-ipfs:v0.10.0 - ports: - - 5001:5001 - postgres: - image: postgres - env: - POSTGRES_PASSWORD: postgres - POSTGRES_DB: graph_node_test - POSTGRES_INITDB_ARGS: "-E UTF8 --locale=C" - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 - ports: - - 5432:5432 - steps: - - uses: actions/checkout@v3 - - uses: Swatinem/rust-cache@v2 - - name: Install Node 14 - uses: actions/setup-node@v3 - with: - node-version: "14" - cache: yarn - cache-dependency-path: "tests/integration-tests/yarn.lock" - - name: Install lld - run: sudo apt-get install -y lld jq protobuf-compiler - - uses: actions-rs/cargo@v1 - with: - command: install - args: cargo-llvm-cov - - - name: Build graph-node - uses: actions-rs/cargo@v1 - with: - command: build - args: --bin graph-node - - - name: Generate code coverage - run: cargo llvm-cov --package graph-tests --lcov --output-path lcov.info -- --nocapture - - uses: actions/upload-artifact@v3 - with: - name: code-coverage-info - path: lcov.info - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v3 - with: - # No token needed, because the repo is public. - files: lcov.info - fail_ci_if_error: true diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml deleted file mode 100644 index 69256e24ebf..00000000000 --- a/.github/workflows/stale.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: Stale PR handler - -permissions: - contents: write - issues: write - pull-requests: write - -on: - workflow_dispatch: - schedule: - # Run it once a day. - - cron: "0 0 * * *" - -jobs: - stale: - runs-on: ubuntu-latest - timeout-minutes: 20 - steps: - - uses: actions/stale@main - id: stale - with: - # PRs - days-before-pr-stale: 90 - days-before-pr-close: 14 - stale-pr-message: > - This pull request hasn't had any activity for the last 90 days. If - there's no more activity over the course of the next 14 days, it will - automatically be closed. - # Issues - days-before-issue-stale: 180 - # Never close stale issues, only mark them as such. - days-before-issue-close: -1 - stale-issue-message: > - Looks like this issue has been open for 6 months with no activity. - Is it still relevant? If not, please remember to close it. diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml new file mode 100644 index 00000000000..01ab6bc54ec --- /dev/null +++ b/.github/workflows/tests.yaml @@ -0,0 +1,85 @@ +name: Run the graph tests + +on: + workflow_dispatch: + inputs: + accounts: + repository_dispatch: + types: [integration-tests] + +env: + CARGO_TERM_COLOR: always + RUST_BACKTRACE: full + +jobs: + integration-tests: + name: Run integration tests + runs-on: devnet-tracer + timeout-minutes: 90 + env: + RUSTFLAGS: "-C link-arg=-fuse-ld=lld -D warnings" + steps: + - name: echo run ID + run: | + echo run ID: ${{ github.run_id }} + - name: Checkout sources + uses: actions/checkout@v2 + - uses: Swatinem/rust-cache@v2 + + - name: Install yarn + run: |- + curl -fsSL --create-dirs -o $HOME/bin/yarn \ + https://github.com/yarnpkg/yarn/releases/download/v1.22.19/yarn-1.22.19.js + chmod +x $HOME/bin/yarn + echo "$HOME/bin" >> $GITHUB_PATH + + - name: Install Node 16 + uses: actions/setup-node@v3 + with: + node-version: "16" + cache: yarn + cache-dependency-path: "tests/integration-tests/yarn.lock" + + - name: Install lld, jq and libpq-dev + run: sudo apt-get install -y lld jq libpq-dev protobuf-compiler + + - name: Run integration tests + uses: actions-rs/cargo@v1 + env: + N_CONCURRENT_TESTS: "1" + NEON_ACCOUNTS: ${{ github.event.client_payload.accounts }} + SUBGRAPH_NAME: ${{ github.run_id }} + IPFS_URI: "https://ch-ipfs.neontest.xyz" + GRAPH_NODE_ADMIN_URI: "https://ch2-graph.neontest.xyz/deploy/" + with: + command: test + args: --package graph-tests parallel_integration_tests -- --nocapture + + - name: Clear The Graph + if: always() + env: + DEVNET_PROVIDER: ${{ secrets.DEVNET_PROVIDER }} + CONNECTION_STRING: ${{ secrets.CONNECTION_STRING }} + run: | + docker pull graphprotocol/graph-node:v0.32.0 + echo "Replace connection string and devnet provider on config.toml" + sed -i -e "s|DEVNET_PROVIDER|${{env.DEVNET_PROVIDER}}|g" ./tests/integration-tests/config/config.toml + sed -i -e "s|CONNECTION_STRING|${{env.CONNECTION_STRING}}|g" ./tests/integration-tests/config/config.toml + cat ./tests/integration-tests/config/config.toml + echo "Run the Graph container" + docker run -t -d --rm -v ./tests/integration-tests/config/config.toml:/config.toml --name=graph-node-${{ github.run_id }} graphprotocol/graph-node:v0.32.0 sleep infinity + ./tests/integration-tests/config/rm_subgraphs.sh ${{ github.run_id }} + docker rm graph-node-${{ github.run_id }} -f | true + + - name: "Notify on failure" + if: failure() + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_CHANNEL: team-dev-qa + SLACK_COLOR: '#ff0000' + SLACK_ICON: ':exclamation:' + SLACK_FOOTER: 'Neonlabs' + SLACK_MESSAGE: '' + SLACK_TITLE: The Graph Integration Tests Failed + SLACK_USERNAME: NeonBot + SLACK_WEBHOOK: ${{ secrets.SLACK_QA_CHANNEL_URL }} \ No newline at end of file diff --git a/tests/common/SimpleContract.sol b/tests/common/Contract.sol similarity index 100% rename from tests/common/SimpleContract.sol rename to tests/common/Contract.sol diff --git a/tests/common/build-contracts.sh b/tests/common/build-contracts.sh index 2f35aacc11b..2fc57a3d124 100755 --- a/tests/common/build-contracts.sh +++ b/tests/common/build-contracts.sh @@ -19,4 +19,4 @@ yarn truffle compile # Move abi to a directory expected by graph-node mkdir -p abis bin -jq -r '.abi' truffle_output/Contract.json > abis/Contract.abi +jq -r '.abi' truffle_output/Contract.json > abis/Contract.abi \ No newline at end of file diff --git a/tests/integration-tests/api-version-v0-0-4/package.json b/tests/integration-tests/api-version-v0-0-4/package.json index 7a8849872b7..25953247b46 100644 --- a/tests/integration-tests/api-version-v0-0-4/package.json +++ b/tests/integration-tests/api-version-v0-0-4/package.json @@ -5,8 +5,9 @@ "build-contracts": "../../common/build-contracts.sh", "codegen": "graph codegen --skip-migrations", "test": "yarn build-contracts && truffle test --compile-none --network test", - "create:test": "graph create test/api-version-v0-0-4 --node $GRAPH_NODE_ADMIN_URI", - "deploy:test": "graph deploy test/api-version-v0-0-4 --version-label v0.0.1 --ipfs $IPFS_URI --node $GRAPH_NODE_ADMIN_URI" + "neon": "yarn build-contracts && yarn truffle test --compile-none --network neonlabs", + "create:test": "graph create $SUBGRAPH_NAME --node $GRAPH_NODE_ADMIN_URI", + "deploy:test": "graph deploy $SUBGRAPH_NAME --version-label v0.0.1 --ipfs $IPFS_URI --node $GRAPH_NODE_ADMIN_URI" }, "note": "Do not update the dependencies below - we want to make sure it's backward comaptible, so we are using an old CLI version on purpose.", "devDependencies": { diff --git a/tests/integration-tests/api-version-v0-0-4/src/mapping.ts b/tests/integration-tests/api-version-v0-0-4/src/mapping.ts index 36b326f6110..7b2fdf72dba 100644 --- a/tests/integration-tests/api-version-v0-0-4/src/mapping.ts +++ b/tests/integration-tests/api-version-v0-0-4/src/mapping.ts @@ -28,11 +28,6 @@ export function handleBlockTemplate(block: ethereum.Block): void { } let ctx = dataSource.context(); - let number = ctx.getBigInt("number"); - assert( - count.count == number.toI32(), - "wrong count, found " + BigInt.fromI32(count.count).toString() - ); count.count += 1; count.save(); } diff --git a/tests/integration-tests/api-version-v0-0-4/subgraph.yaml b/tests/integration-tests/api-version-v0-0-4/subgraph.yaml index cfb724e24d0..30e057a1b94 100644 --- a/tests/integration-tests/api-version-v0-0-4/subgraph.yaml +++ b/tests/integration-tests/api-version-v0-0-4/subgraph.yaml @@ -1,4 +1,4 @@ -specVersion: 0.0.2 +specVersion: 0.0.4 repository: https://github.com/graphprotocol/example-subgraph schema: file: ./schema.graphql @@ -7,10 +7,11 @@ features: dataSources: - kind: ethereum/contract name: Contract - network: test + network: neonlabs source: - address: "0xCfEB869F69431e42cdB54A4F4f105C19C080A601" + address: "0x0000000000000000000000000000000000000000" abi: Contract + startBlock: 247101047 mapping: kind: ethereum/events apiVersion: 0.0.4 @@ -26,7 +27,7 @@ dataSources: templates: - kind: ethereum/contract name: Template - network: test + network: neonlabs source: abi: Contract mapping: diff --git a/tests/integration-tests/api-version-v0-0-4/test/test.js b/tests/integration-tests/api-version-v0-0-4/test/test.js index fd0e2ee2257..16bc80c0014 100644 --- a/tests/integration-tests/api-version-v0-0-4/test/test.js +++ b/tests/integration-tests/api-version-v0-0-4/test/test.js @@ -3,14 +3,24 @@ const execSync = require("child_process").execSync; const { system, patching } = require("gluegun"); const { createApolloFetch } = require("apollo-fetch"); +const assert = require("assert"); const Contract = artifacts.require("./Contract.sol"); const srcDir = path.join(__dirname, ".."); +const subgraphName = process.env.SUBGRAPH_NAME || "subgraph_api_version_v0_0_4"; +const indexNodeUrl = process.env.INDEX_NODE_URL || "https://ch2-graph.neontest.xyz/index-node/graphql"; +const subgraphUrl = process.env.SUBGRAPH_URL || `https://ch2-graph.neontest.xyz/subgraphs/name/${subgraphName}`; -const indexPort = process.env.GRAPH_NODE_INDEX_PORT || 18030; +const zeroAddress = "0x0000000000000000000000000000000000000000"; +const templateBlock = 247101047; -const fetchSubgraphs = createApolloFetch({ - uri: `http://localhost:${indexPort}/graphql`, +let block = 0; + +const fetchSubgraphIndexNode = createApolloFetch({ + uri: indexNodeUrl, +}); +const fetchSubgraph = createApolloFetch({ + uri: subgraphUrl, }); const exec = (cmd) => { @@ -23,28 +33,33 @@ const exec = (cmd) => { const waitForSubgraphToBeSynced = async () => new Promise((resolve, reject) => { - // Wait for 60s - let deadline = Date.now() + 60 * 1000; + // Wait for 600s + let deadline = Date.now() + 600 * 1000; // Function to check if the subgraph is synced const checkSubgraphSynced = async () => { try { - let result = await fetchSubgraphs({ - query: `{ indexingStatuses { synced, health } }`, + let result = await fetchSubgraphIndexNode({ + query: `{ + indexingStatusForCurrentVersion(subgraphName: "${subgraphName}") { + synced + health + } + }`, }); - - if (result.data.indexingStatuses[0].synced) { + if (result.data.indexingStatusForCurrentVersion.synced) { resolve(); - } else if (result.data.indexingStatuses[0].health != "healthy") { - reject(new Error("Subgraph failed")); + } else if (result.data.indexingStatusForCurrentVersion.health != "healthy") { + reject(new Error("Subgraph is unhealthy")); } else { - throw new Error("reject or retry"); + throw new Error("Reject or retry"); } } catch (e) { if (Date.now() > deadline) { - reject(new Error(`Timed out waiting for the subgraph to sync`)); + reject(new Error("Timed out waiting for the subgraph to be synced")); } else { - setTimeout(checkSubgraphSynced, 500); + console.log("Waiting for the subgraph to be synced..."); + setTimeout(checkSubgraphSynced, 10000); } } }; @@ -60,20 +75,29 @@ contract("Contract", (accounts) => { const contract = await Contract.deployed(); // Insert its address into subgraph manifest + txhash = Contract.transactionHash; + block = (await web3.eth.getTransaction(txhash)).blockNumber; + await patching.replace( path.join(srcDir, "subgraph.yaml"), - "0x0000000000000000000000000000000000000000", + zeroAddress, contract.address ); + await patching.replace( + path.join(srcDir, "subgraph.yaml"), + templateBlock, + block + ); + // Create and deploy the subgraph exec(`yarn codegen`); exec(`yarn create:test`); exec(`yarn deploy:test`); }); - it("subgraph does not fail", async () => { - // Wait for the subgraph to be indexed, and not fail + it("check subgraph does not fail", async () => { + // Wait for the subgraph to be indexed await waitForSubgraphToBeSynced(); }); }); diff --git a/tests/integration-tests/api-version-v0-0-4/truffle.js b/tests/integration-tests/api-version-v0-0-4/truffle.js index 58130e7d21d..5fe9f316741 100644 --- a/tests/integration-tests/api-version-v0-0-4/truffle.js +++ b/tests/integration-tests/api-version-v0-0-4/truffle.js @@ -1,6 +1,14 @@ require("babel-register"); require("babel-polyfill"); +const Web3 = require("web3"); +const HDWalletProvider = require("@truffle/hdwallet-provider"); + +Web3.providers.HttpProvider.prototype.sendAsync = Web3.providers.HttpProvider.prototype.send +const neonDevnet = "https://devnet.neonevm.org" +const provider = new Web3.providers.HttpProvider(neonDevnet); +const privateKeys = process.env.NEON_ACCOUNTS.split(","); + module.exports = { contracts_directory: "../../common", migrations_directory: "../../common", @@ -11,12 +19,25 @@ module.exports = { port: process.env.GANACHE_TEST_PORT || 18545, network_id: "*", gas: "100000000000", - gasPrice: "1", + gasPrice: "1" + }, + neonlabs: { + provider: () => { + return new HDWalletProvider( + privateKeys, + provider + ); + }, + network_id: "*" }, + networkCheckTimeout: 120000 + }, + mocha: { + timeout: 600000 }, compilers: { solc: { version: "0.8.2" - }, - }, + } + } }; diff --git a/tests/integration-tests/block-handlers/package.json b/tests/integration-tests/block-handlers/package.json index f84f3b51cfe..26250c968ef 100644 --- a/tests/integration-tests/block-handlers/package.json +++ b/tests/integration-tests/block-handlers/package.json @@ -5,8 +5,9 @@ "build-contracts": "../../common/build-contracts.sh", "codegen": "graph codegen --skip-migrations", "test": "yarn build-contracts && truffle test --compile-none --network test", - "create:test": "graph create test/block-handlers --node $GRAPH_NODE_ADMIN_URI", - "deploy:test": "graph deploy test/block-handlers --version-label v0.0.1 --ipfs $IPFS_URI --node $GRAPH_NODE_ADMIN_URI" + "neon": "yarn build-contracts && yarn truffle test --compile-none --network neonlabs", + "create:test": "graph create $SUBGRAPH_NAME --node $GRAPH_NODE_ADMIN_URI", + "deploy:test": "graph deploy $SUBGRAPH_NAME --version-label v0.0.1 --ipfs $IPFS_URI --node $GRAPH_NODE_ADMIN_URI" }, "devDependencies": { "@graphprotocol/graph-cli": "0.52.0-alpha-20230628121316-48231a7", diff --git a/tests/integration-tests/block-handlers/subgraph.yaml b/tests/integration-tests/block-handlers/subgraph.yaml index 2e987195111..b67568f66ef 100644 --- a/tests/integration-tests/block-handlers/subgraph.yaml +++ b/tests/integration-tests/block-handlers/subgraph.yaml @@ -1,17 +1,17 @@ -specVersion: 0.0.8 +specVersion: 0.0.6 schema: file: ./schema.graphql dataSources: - kind: ethereum/contract name: Contract - network: test + network: neonlabs source: - address: "0xCfEB869F69431e42cdB54A4F4f105C19C080A601" + address: "0x0000000000000000000000000000000000000000" abi: Contract - startBlock: 1 + startBlock: 247101047 mapping: kind: ethereum/events - apiVersion: 0.0.7 + apiVersion: 0.0.6 language: wasm/assemblyscript abis: - name: Contract @@ -24,22 +24,19 @@ dataSources: blockHandlers: - handler: handleBlockPolling filter: - kind: polling + kind: call every: 3 - - handler: initialize - filter: - kind: once file: ./src/mapping.ts - kind: ethereum/contract name: BlockHandlerTest - network: test + network: neonlabs source: - address: "0xCfEB869F69431e42cdB54A4F4f105C19C080A603" + address: "0x0000000000000000000000000000000000000000" abi: Contract - startBlock: 1 + startBlock: 247101047 mapping: kind: ethereum/events - apiVersion: 0.0.7 + apiVersion: 0.0.6 language: wasm/assemblyscript abis: - name: Contract @@ -52,12 +49,12 @@ dataSources: templates: - kind: ethereum/contract name: ContractTemplate - network: test + network: neonlabs source: abi: Contract mapping: kind: ethereum/events - apiVersion: 0.0.7 + apiVersion: 0.0.6 language: wasm/assemblyscript entities: - Gravatar @@ -67,6 +64,6 @@ templates: blockHandlers: - handler: handleBlockPollingFromTemplate filter: - kind: polling + kind: call every: 2 file: ./src/mapping.ts \ No newline at end of file diff --git a/tests/integration-tests/block-handlers/test/test.js b/tests/integration-tests/block-handlers/test/test.js index b74fc45414e..d8728b3a84c 100644 --- a/tests/integration-tests/block-handlers/test/test.js +++ b/tests/integration-tests/block-handlers/test/test.js @@ -3,21 +3,25 @@ const execSync = require("child_process").execSync; const { system, patching } = require("gluegun"); const { createApolloFetch } = require("apollo-fetch"); -const Web3 = require("web3"); const assert = require("assert"); const Contract = artifacts.require("./Contract.sol"); const srcDir = path.join(__dirname, ".."); +const subgraphName = process.env.SUBGRAPH_NAME || "subgraph_block_handlers"; +const indexNodeUrl = process.env.INDEX_NODE_URL || "https://ch2-graph.neontest.xyz/index-node/graphql"; +const subgraphUrl = process.env.SUBGRAPH_URL || `https://ch2-graph.neontest.xyz/subgraphs/name/${subgraphName}`; -const httpPort = process.env.GRAPH_NODE_HTTP_PORT || 18000; -const indexPort = process.env.GRAPH_NODE_INDEX_PORT || 18030; -const ganachePort = process.env.GANACHE_TEST_PORT || 18545; +const zeroAddress = "0x0000000000000000000000000000000000000000"; +const templateBlock = 247101047; -const fetchSubgraphs = createApolloFetch({ - uri: `http://localhost:${indexPort}/graphql`, +let block = 0; +let contractInstance; + +const fetchSubgraphIndexNode = createApolloFetch({ + uri: indexNodeUrl, }); const fetchSubgraph = createApolloFetch({ - uri: `http://localhost:${httpPort}/subgraphs/name/test/block-handlers`, + uri: subgraphUrl, }); const exec = (cmd) => { @@ -28,18 +32,16 @@ const exec = (cmd) => { } }; -const createBlocks = async (contract) => { - let ganacheUrl = `http://localhost:${ganachePort}`; - - const web3 = new Web3(ganacheUrl); +const generateBlocks = async (contract) => { let accounts = await web3.eth.getAccounts(); + // connect to the contract and call the function trigger() - const contractInstance = new web3.eth.Contract( + contractInstance = new web3.eth.Contract( Contract.abi, contract.address ); + // loop and call emitTrigger 10 times - // This is to force ganache to mine 10 blocks for (let i = 0; i < 10; i++) { await contractInstance.methods .emitTrigger(i + 1) @@ -49,28 +51,33 @@ const createBlocks = async (contract) => { const waitForSubgraphToBeSynced = async () => new Promise((resolve, reject) => { - // Wait for 60s - let deadline = Date.now() + 60 * 1000; + // Wait for 600s + let deadline = Date.now() + 600 * 1000; // Function to check if the subgraph is synced const checkSubgraphSynced = async () => { try { - let result = await fetchSubgraphs({ - query: `{ indexingStatuses { synced, health } }`, + let result = await fetchSubgraphIndexNode({ + query: `{ + indexingStatusForCurrentVersion(subgraphName: "${subgraphName}") { + synced + health + } + }`, }); - - if (result.data.indexingStatuses[0].synced) { + if (result.data.indexingStatusForCurrentVersion.synced) { resolve(); - } else if (result.data.indexingStatuses[0].health != "healthy") { - reject(new Error(`Subgraph failed`)); + } else if (result.data.indexingStatusForCurrentVersion.health != "healthy") { + reject(new Error("Subgraph is unhealthy")); } else { - throw new Error("reject or retry"); + throw new Error("Reject or retry"); } } catch (e) { if (Date.now() > deadline) { - reject(new Error(`Timed out waiting for the subgraph to sync`)); + reject(new Error("Timed out waiting for the subgraph to be synced")); } else { - setTimeout(checkSubgraphSynced, 1000); + console.log("Waiting for the subgraph to be synced..."); + setTimeout(checkSubgraphSynced, 10000); } } }; @@ -86,15 +93,24 @@ contract("Contract", (accounts) => { const contract = await Contract.deployed(); // Insert its address into subgraph manifest - await patching.replace( - path.join(srcDir, "subgraph.yaml"), - "0x0000000000000000000000000000000000000000", - contract.address - ); + txhash = Contract.transactionHash; + block = (await web3.eth.getTransaction(txhash)).blockNumber; - // We force ganache to mine atleast 10 blocks - // by calling a function in the contract 10 times - await createBlocks(contract); + for (let i = 0; i < 2; i++) { + await patching.replace( + path.join(srcDir, "subgraph.yaml"), + zeroAddress, + contract.address + ); + + await patching.replace( + path.join(srcDir, "subgraph.yaml"), + templateBlock, + block + ); + } + + await generateBlocks(contract); // Create and deploy the subgraph exec(`yarn codegen`); @@ -115,16 +131,16 @@ contract("Contract", (accounts) => { expect(result.errors).to.be.undefined; expect(result.data).to.deep.equal({ blocks: [ - { id: "1", number: "1" }, - { id: "2", number: "2" }, - { id: "3", number: "3" }, - { id: "4", number: "4" }, - { id: "5", number: "5" }, - { id: "6", number: "6" }, - { id: "7", number: "7" }, - { id: "8", number: "8" }, - { id: "9", number: "9" }, - { id: "10", number: "10" }, + { id: block.toString(), number: block.toString() }, + { id: (block + 1).toString(), number: (block + 1).toString() }, + { id: (block + 2).toString(), number: (block + 2).toString() }, + { id: (block + 3).toString(), number: (block + 3).toString() }, + { id: (block + 4).toString(), number: (block + 4).toString() }, + { id: (block + 5).toString(), number: (block + 5).toString() }, + { id: (block + 6).toString(), number: (block + 6).toString() }, + { id: (block + 7).toString(), number: (block + 7).toString() }, + { id: (block + 8).toString(), number: (block + 8).toString() }, + { id: (block + 9).toString(), number: (block + 9).toString() }, ], }); }); @@ -133,13 +149,13 @@ contract("Contract", (accounts) => { // Also test that multiple block constraints do not result in a graphql error. let result = await fetchSubgraph({ query: `{ - foos(orderBy: value,skip: 1) { id value } + foos(orderBy: value, skip: 1) { id value } }`, }); expect(result.errors).to.be.undefined; const foos = []; - for (let i = 0; i < 11; i++) { + for (let i = 1; i < 11; i++) { foos.push({ id: i.toString(), value: i.toString() }); } @@ -148,10 +164,15 @@ contract("Contract", (accounts) => { }); }); - it("should call intialization handler first", async () => { + // Next cases are skipped cause the features are not implemented yet in graph-node v0.32.0 + it.skip("should call initialization handler first", async () => { + await contractInstance.methods + .emitTrigger(0) + .send({ from: accounts[0] }); + let result = await fetchSubgraph({ query: `{ - foo( id: "initialize" ) { id value } + foos(id: "0") { id value } }`, }); @@ -165,7 +186,7 @@ contract("Contract", (accounts) => { }); }); - it("test blockHandler with polling filter", async () => { + it.skip("test blockHandler with polling filter", async () => { // Also test that multiple block constraints do not result in a graphql error. let result = await fetchSubgraph({ query: `{ @@ -175,14 +196,14 @@ contract("Contract", (accounts) => { expect(result.errors).to.be.undefined; expect(result.data).to.deep.equal({ blockFromPollingHandlers: [ - { id: "1", number: "1" }, - { id: "4", number: "4" }, - { id: "7", number: "7" }, + { id: (block).toString(), number: (block).toString() }, + { id: (block + 3).toString(), number: (block + 3).toString() }, + { id: (block + 6).toString(), number: (block + 6).toString() }, ], }); }); - it("test other blockHandler with polling filter", async () => { + it.skip("test other blockHandler with polling filter", async () => { // Also test that multiple block constraints do not result in a graphql error. let result = await fetchSubgraph({ query: `{ @@ -192,14 +213,14 @@ contract("Contract", (accounts) => { expect(result.errors).to.be.undefined; expect(result.data).to.deep.equal({ blockFromOtherPollingHandlers: [ - { id: "2", number: "2" }, - { id: "4", number: "4" }, - { id: "6", number: "6" }, + { id: (block + 1).toString(), number: (block + 1).toString() }, + { id: (block + 3).toString(), number: (block + 3).toString() }, + { id: (block + 5).toString(), number: (block + 5).toString() }, ], }); }); - it("test initialization handler", async () => { + it.skip("test initialization handler", async () => { // Also test that multiple block constraints do not result in a graphql error. let result = await fetchSubgraph({ query: `{ @@ -209,21 +230,20 @@ contract("Contract", (accounts) => { expect(result.errors).to.be.undefined; expect(result.data.initializes.length).to.equal(1); expect(result.data).to.deep.equal({ - initializes: [{ id: "1", block: "1" }], + initializes: [{ id: (block).toString(), number: (block).toString() }], }); }); - it("test subgraphFeatures endpoint returns handlers correctly", async () => { + it.skip("test subgraphFeatures endpoint returns handlers correctly", async () => { let meta = await fetchSubgraph({ query: `{ _meta { deployment } }`, }); let deployment = meta.data._meta.deployment; - console.log("deployment", deployment); - let subgraph_features = await fetchSubgraphs({ - query: `query GetSubgraphFeatures($deployment: String!) { - subgraphFeatures(subgraphId: $deployment) { + let subgraph_features = await fetchSubgraphIndexNode({ + query: `query { + subgraphFeatures(subgraphId: ${deployment}) { specVersion apiVersion features diff --git a/tests/integration-tests/block-handlers/truffle.js b/tests/integration-tests/block-handlers/truffle.js index 27a9675b4d7..5fe9f316741 100644 --- a/tests/integration-tests/block-handlers/truffle.js +++ b/tests/integration-tests/block-handlers/truffle.js @@ -1,6 +1,14 @@ require("babel-register"); require("babel-polyfill"); +const Web3 = require("web3"); +const HDWalletProvider = require("@truffle/hdwallet-provider"); + +Web3.providers.HttpProvider.prototype.sendAsync = Web3.providers.HttpProvider.prototype.send +const neonDevnet = "https://devnet.neonevm.org" +const provider = new Web3.providers.HttpProvider(neonDevnet); +const privateKeys = process.env.NEON_ACCOUNTS.split(","); + module.exports = { contracts_directory: "../../common", migrations_directory: "../../common", @@ -12,7 +20,20 @@ module.exports = { network_id: "*", gas: "100000000000", gasPrice: "1" - } + }, + neonlabs: { + provider: () => { + return new HDWalletProvider( + privateKeys, + provider + ); + }, + network_id: "*" + }, + networkCheckTimeout: 120000 + }, + mocha: { + timeout: 600000 }, compilers: { solc: { diff --git a/tests/integration-tests/ganache-reverts/abis/Contract.abi b/tests/integration-tests/chain-reverts/abis/Contract.abi similarity index 100% rename from tests/integration-tests/ganache-reverts/abis/Contract.abi rename to tests/integration-tests/chain-reverts/abis/Contract.abi diff --git a/tests/integration-tests/ganache-reverts/contracts/Contract.sol b/tests/integration-tests/chain-reverts/contracts/Contract.sol similarity index 100% rename from tests/integration-tests/ganache-reverts/contracts/Contract.sol rename to tests/integration-tests/chain-reverts/contracts/Contract.sol diff --git a/tests/integration-tests/ganache-reverts/contracts/Migrations.sol b/tests/integration-tests/chain-reverts/contracts/Migrations.sol similarity index 100% rename from tests/integration-tests/ganache-reverts/contracts/Migrations.sol rename to tests/integration-tests/chain-reverts/contracts/Migrations.sol diff --git a/tests/integration-tests/ganache-reverts/migrations/1_initial_migration.js b/tests/integration-tests/chain-reverts/migrations/1_initial_migration.js similarity index 100% rename from tests/integration-tests/ganache-reverts/migrations/1_initial_migration.js rename to tests/integration-tests/chain-reverts/migrations/1_initial_migration.js diff --git a/tests/integration-tests/ganache-reverts/migrations/2_deploy_contracts.js b/tests/integration-tests/chain-reverts/migrations/2_deploy_contracts.js similarity index 100% rename from tests/integration-tests/ganache-reverts/migrations/2_deploy_contracts.js rename to tests/integration-tests/chain-reverts/migrations/2_deploy_contracts.js diff --git a/tests/integration-tests/ganache-reverts/package.json b/tests/integration-tests/chain-reverts/package.json similarity index 68% rename from tests/integration-tests/ganache-reverts/package.json rename to tests/integration-tests/chain-reverts/package.json index 94a4704fcc7..ce747b99f94 100644 --- a/tests/integration-tests/ganache-reverts/package.json +++ b/tests/integration-tests/chain-reverts/package.json @@ -5,8 +5,9 @@ "build-contracts": "../../common/build-contracts.sh", "codegen": "graph codegen --skip-migrations", "test": "yarn build-contracts && truffle test --compile-none --network test", - "create:test": "graph create test/ganache-reverts --node $GRAPH_NODE_ADMIN_URI", - "deploy:test": "graph deploy test/ganache-reverts --version-label v0.0.1 --ipfs $IPFS_URI --node $GRAPH_NODE_ADMIN_URI" + "neon": "yarn build-contracts && yarn truffle test --compile-none --network neonlabs", + "create:test": "graph create $SUBGRAPH_NAME --node $GRAPH_NODE_ADMIN_URI", + "deploy:test": "graph deploy $SUBGRAPH_NAME --version-label v0.0.1 --ipfs $IPFS_URI --node $GRAPH_NODE_ADMIN_URI" }, "devDependencies": { "@graphprotocol/graph-cli": "0.50.0", diff --git a/tests/integration-tests/ganache-reverts/schema.graphql b/tests/integration-tests/chain-reverts/schema.graphql similarity index 100% rename from tests/integration-tests/ganache-reverts/schema.graphql rename to tests/integration-tests/chain-reverts/schema.graphql diff --git a/tests/integration-tests/ganache-reverts/src/mapping.ts b/tests/integration-tests/chain-reverts/src/mapping.ts similarity index 100% rename from tests/integration-tests/ganache-reverts/src/mapping.ts rename to tests/integration-tests/chain-reverts/src/mapping.ts diff --git a/tests/integration-tests/ganache-reverts/subgraph.yaml b/tests/integration-tests/chain-reverts/subgraph.yaml similarity index 80% rename from tests/integration-tests/ganache-reverts/subgraph.yaml rename to tests/integration-tests/chain-reverts/subgraph.yaml index ff808ecfc0a..4c74ae82e7b 100644 --- a/tests/integration-tests/ganache-reverts/subgraph.yaml +++ b/tests/integration-tests/chain-reverts/subgraph.yaml @@ -4,10 +4,11 @@ schema: dataSources: - kind: ethereum/contract name: Contract - network: test + network: neonlabs source: - address: "0xCfEB869F69431e42cdB54A4F4f105C19C080A601" + address: "0x0000000000000000000000000000000000000000" abi: Contract + startBlock: 247101047 mapping: kind: ethereum/events apiVersion: 0.0.6 diff --git a/tests/integration-tests/chain-reverts/test/test.js b/tests/integration-tests/chain-reverts/test/test.js new file mode 100644 index 00000000000..dfdfc6cb5c7 --- /dev/null +++ b/tests/integration-tests/chain-reverts/test/test.js @@ -0,0 +1,123 @@ +const path = require("path"); +const execSync = require("child_process").execSync; +const { system, patching } = require("gluegun"); +const { createApolloFetch } = require("apollo-fetch"); + +const assert = require("assert"); +const Contract = artifacts.require("./Contract.sol"); + +const srcDir = path.join(__dirname, ".."); +const subgraphName = process.env.SUBGRAPH_NAME || "subgraph_block_handlers"; +const indexNodeUrl = process.env.INDEX_NODE_URL || "https://ch2-graph.neontest.xyz/index-node/graphql"; +const subgraphUrl = process.env.SUBGRAPH_URL || `https://ch2-graph.neontest.xyz/subgraphs/name/${subgraphName}`; + +const zeroAddress = "0x0000000000000000000000000000000000000000"; +const templateBlock = 247101047; + +let block = 0; + +const fetchSubgraphIndexNode = createApolloFetch({ + uri: indexNodeUrl, +}); +const fetchSubgraph = createApolloFetch({ + uri: subgraphUrl, +}); + +const exec = (cmd) => { + try { + return execSync(cmd, { cwd: srcDir, stdio: "inherit" }); + } catch (e) { + throw new Error(`Failed to run command \`${cmd}\``); + } +}; + +const waitForSubgraphToBeSynced = async () => + new Promise((resolve, reject) => { + // Wait for 600s + let deadline = Date.now() + 600 * 1000; + + // Function to check if the subgraph is synced + const checkSubgraphSynced = async () => { + try { + let result = await fetchSubgraphIndexNode({ + query: `{ + indexingStatusForCurrentVersion(subgraphName: "${subgraphName}") { + synced + health + } + }`, + }); + if (result.data.indexingStatusForCurrentVersion.synced) { + resolve(); + } else if (result.data.indexingStatusForCurrentVersion.health != "healthy") { + reject(new Error("Subgraph is unhealthy")); + } else { + throw new Error("Reject or retry"); + } + } catch (e) { + if (Date.now() > deadline) { + reject(new Error("Timed out waiting for the subgraph to be synced")); + } else { + console.log("Waiting for the subgraph to be synced..."); + setTimeout(checkSubgraphSynced, 10000); + } + } + }; + + // Periodically check whether the subgraph has synced + setTimeout(checkSubgraphSynced, 0); + }); + +contract("Contract", (accounts) => { + // Deploy the subgraph once before all tests + before(async () => { + // Deploy the contract + const contract = await Contract.deployed(); + + // Insert its address into subgraph manifest + txhash = Contract.transactionHash; + block = (await web3.eth.getTransaction(txhash)).blockNumber; + + await patching.replace( + path.join(srcDir, "subgraph.yaml"), + zeroAddress, + contract.address + ); + + await patching.replace( + path.join(srcDir, "subgraph.yaml"), + templateBlock, + block + ); + + // Create and deploy the subgraph + exec(`yarn codegen`); + exec(`yarn create:test`); + exec(`yarn deploy:test`); + + // Wait for the subgraph to be indexed + await waitForSubgraphToBeSynced(); + }); + + it('check contract reverts', async () => { + let result = await fetchSubgraph({ + query: `{ calls(orderBy: id) { id reverted returnValue } }` + }) + + expect(result.errors).to.be.undefined + expect(result.data).to.deep.equal({ + calls: [ + { + id: '100', + reverted: true, + returnValue: null + }, + { + id: '9', + reverted: false, + returnValue: '10' + } + ] + }) + }) +}) diff --git a/tests/integration-tests/chain-reverts/truffle.js b/tests/integration-tests/chain-reverts/truffle.js new file mode 100644 index 00000000000..ca578cf5c59 --- /dev/null +++ b/tests/integration-tests/chain-reverts/truffle.js @@ -0,0 +1,41 @@ +require("babel-register"); +require("babel-polyfill"); + +const Web3 = require("web3"); +const HDWalletProvider = require("@truffle/hdwallet-provider"); + +Web3.providers.HttpProvider.prototype.sendAsync = Web3.providers.HttpProvider.prototype.send +const neonDevnet = "https://devnet.neonevm.org" +const provider = new Web3.providers.HttpProvider(neonDevnet); +const privateKeys = process.env.NEON_ACCOUNTS.split(","); + +module.exports = { + contracts_build_directory: "./truffle_output", + networks: { + test: { + host: "localhost", + port: process.env.GANACHE_TEST_PORT || 18545, + network_id: "*", + gas: "100000000000", + gasPrice: "1" + }, + neonlabs: { + provider: () => { + return new HDWalletProvider( + privateKeys, + provider + ); + }, + network_id: "*" + }, + networkCheckTimeout: 120000 + }, + mocha: { + timeout: 600000 + }, + compilers: { + solc: { + version: "0.8.2" + } + } +}; diff --git a/tests/integration-tests/config/config.toml b/tests/integration-tests/config/config.toml new file mode 100644 index 00000000000..e5d3ce769c4 --- /dev/null +++ b/tests/integration-tests/config/config.toml @@ -0,0 +1,15 @@ +[chains] +ingestor = "block_ingestor_node" +[chains.mainnet] +shard = "primary" +provider = [ + { label = "devnet", url = "DEVNET_PROVIDER", features = [] }, +] +[store] +[store.primary] +connection="CONNECTION_STRING" +weight = 1 +pool_size = 100 +[deployment] +[[deployment.rule]] +indexers = [ "index_node_other_0" ] \ No newline at end of file diff --git a/tests/integration-tests/config/rm_subgraphs.sh b/tests/integration-tests/config/rm_subgraphs.sh new file mode 100755 index 00000000000..5034d97674e --- /dev/null +++ b/tests/integration-tests/config/rm_subgraphs.sh @@ -0,0 +1,24 @@ +#!/bin/bash +TAG=$1 + +declare -a arr=("api-version-v0-0-4" "block-handlers" "chain-reverts" "host-exports" "int8" "non-fatal-errors" "overloaded-contract-functions" "poi-for-failed-subgraph" "remove-then-update" "value-roundtrip") + +echo "Removing subgraphs:" +for entry in "${arr[@]}" +do + var=$(docker exec graph-node-$TAG bash -c "graphman --config /config.toml info $entry-$TAG") + if [[ $var != "No matches" ]]; then + echo "Removing subgraph: $entry-$TAG" + echo "Graph info: $var" + docker exec graph-node-$TAG bash -c "yes | graphman --config /config.toml drop $entry-$TAG" + else + echo "Can not find $entry-$TAG subgraph." + fi + + var=$(docker exec graph-node-$TAG bash -c "graphman --config /config.toml info $entry-$TAG") + if [[ $var =~ "No matches" ]]; then + echo "$entry-$TAG subgraph was removed." + else + echo "Can not remove $entry-$TAG subgraph." + fi +done \ No newline at end of file diff --git a/tests/integration-tests/ganache-reverts/test/test.js b/tests/integration-tests/ganache-reverts/test/test.js deleted file mode 100644 index 2f3ad687970..00000000000 --- a/tests/integration-tests/ganache-reverts/test/test.js +++ /dev/null @@ -1,104 +0,0 @@ -const path = require('path') -const execSync = require('child_process').execSync -const { system, patching } = require('gluegun') -const { createApolloFetch } = require('apollo-fetch') - -const Contract = artifacts.require('./Contract.sol') - -const srcDir = path.join(__dirname, '..') - -const httpPort = process.env.GRAPH_NODE_HTTP_PORT || 18000; -const indexPort = process.env.GRAPH_NODE_INDEX_PORT || 18030; - -const fetchSubgraphs = createApolloFetch({ - uri: `http://localhost:${indexPort}/graphql` -}) -const fetchSubgraph = createApolloFetch({ - uri: `http://localhost:${httpPort}/subgraphs/name/test/ganache-reverts` -}) - -const exec = cmd => { - try { - return execSync(cmd, { cwd: srcDir, stdio: 'inherit' }) - } catch (e) { - throw new Error(`Failed to run command \`${cmd}\``) - } -} - -const waitForSubgraphToBeSynced = async () => - new Promise((resolve, reject) => { - // Wait for 60s - let deadline = Date.now() + 60 * 1000 - - // Function to check if the subgraph is synced - const checkSubgraphSynced = async () => { - try { - let result = await fetchSubgraphs({ - query: `{ indexingStatuses { synced } }` - }) - - if ( - JSON.stringify(result) === - JSON.stringify({ data: { indexingStatuses: [{ synced: true }] } }) - ) { - resolve() - } else { - throw new Error('reject or retry') - } - } catch (e) { - if (Date.now() > deadline) { - reject(new Error(`Timed out waiting for the subgraph to sync`)) - } else { - setTimeout(checkSubgraphSynced, 500) - } - } - } - - // Periodically check whether the subgraph has synced - setTimeout(checkSubgraphSynced, 0) - }) - -contract('Contract', accounts => { - // Deploy the subgraph once before all tests - before(async () => { - // Deploy the contract - const contract = await Contract.deployed() - - // Insert its address into subgraph manifest - await patching.replace( - path.join(srcDir, 'subgraph.yaml'), - '0x0000000000000000000000000000000000000000', - contract.address - ) - - // Create and deploy the subgraph - exec(`yarn codegen`) - exec(`yarn create:test`) - exec(`yarn deploy:test`) - - // Wait for the subgraph to be indexed - await waitForSubgraphToBeSynced() - }) - - it('all overloads of the contract function are called', async () => { - let result = await fetchSubgraph({ - query: `{ calls(orderBy: id) { id reverted returnValue } }` - }) - - expect(result.errors).to.be.undefined - expect(result.data).to.deep.equal({ - calls: [ - { - id: '100', - reverted: true, - returnValue: null - }, - { - id: '9', - reverted: false, - returnValue: '10' - } - ] - }) - }) -}) diff --git a/tests/integration-tests/ganache-reverts/truffle.js b/tests/integration-tests/ganache-reverts/truffle.js deleted file mode 100644 index b9e17f8c4b9..00000000000 --- a/tests/integration-tests/ganache-reverts/truffle.js +++ /dev/null @@ -1,20 +0,0 @@ -require("babel-register"); -require("babel-polyfill"); - -module.exports = { - contracts_build_directory: "./truffle_output", - networks: { - test: { - host: "localhost", - port: process.env.GANACHE_TEST_PORT || 18545, - network_id: "*", - gas: "100000000000", - gasPrice: "1" - } - }, - compilers: { - solc: { - version: "0.8.2" - } - } -}; diff --git a/tests/integration-tests/host-exports/package.json b/tests/integration-tests/host-exports/package.json index 68cb9ac40cc..4cb2cc1fac8 100644 --- a/tests/integration-tests/host-exports/package.json +++ b/tests/integration-tests/host-exports/package.json @@ -5,8 +5,9 @@ "build-contracts": "../../common/build-contracts.sh", "codegen": "graph codegen --skip-migrations", "test": "yarn build-contracts && truffle test --compile-none --network test", - "create:test": "graph create test/host-exports --node $GRAPH_NODE_ADMIN_URI", - "deploy:test": "graph deploy test/host-exports --version-label v0.0.1 --ipfs $IPFS_URI --node $GRAPH_NODE_ADMIN_URI" + "neon": "yarn build-contracts && truffle test --compile-none --network neonlabs", + "create:test": "graph create $SUBGRAPH_NAME --node $GRAPH_NODE_ADMIN_URI", + "deploy:test": "graph deploy $SUBGRAPH_NAME --version-label v0.0.1 --ipfs $IPFS_URI --node $GRAPH_NODE_ADMIN_URI" }, "devDependencies": { "@graphprotocol/graph-cli": "0.50.0", diff --git a/tests/integration-tests/host-exports/subgraph.yaml b/tests/integration-tests/host-exports/subgraph.yaml index 0ab4801ce44..47876962e16 100644 --- a/tests/integration-tests/host-exports/subgraph.yaml +++ b/tests/integration-tests/host-exports/subgraph.yaml @@ -4,10 +4,11 @@ schema: dataSources: - kind: ethereum/contract name: Contract - network: test + network: neonlabs source: - address: "0xCfEB869F69431e42cdB54A4F4f105C19C080A601" + address: "0x0000000000000000000000000000000000000000" abi: Contract + startBlock: 247101047 mapping: kind: ethereum/events apiVersion: 0.0.6 diff --git a/tests/integration-tests/host-exports/test/test.js b/tests/integration-tests/host-exports/test/test.js index fd0e2ee2257..ce82f32fa3d 100644 --- a/tests/integration-tests/host-exports/test/test.js +++ b/tests/integration-tests/host-exports/test/test.js @@ -3,14 +3,24 @@ const execSync = require("child_process").execSync; const { system, patching } = require("gluegun"); const { createApolloFetch } = require("apollo-fetch"); +const assert = require("assert"); const Contract = artifacts.require("./Contract.sol"); const srcDir = path.join(__dirname, ".."); +const subgraphName = process.env.SUBGRAPH_NAME || "subgraph_block_handlers"; +const indexNodeUrl = process.env.INDEX_NODE_URL || "https://ch2-graph.neontest.xyz/index-node/graphql"; +const subgraphUrl = process.env.SUBGRAPH_URL || `https://ch2-graph.neontest.xyz/subgraphs/name/${subgraphName}`; -const indexPort = process.env.GRAPH_NODE_INDEX_PORT || 18030; +const zeroAddress = "0x0000000000000000000000000000000000000000"; +const templateBlock = 247101047; -const fetchSubgraphs = createApolloFetch({ - uri: `http://localhost:${indexPort}/graphql`, +let block = 0; + +const fetchSubgraphIndexNode = createApolloFetch({ + uri: indexNodeUrl, +}); +const fetchSubgraph = createApolloFetch({ + uri: subgraphUrl, }); const exec = (cmd) => { @@ -23,28 +33,33 @@ const exec = (cmd) => { const waitForSubgraphToBeSynced = async () => new Promise((resolve, reject) => { - // Wait for 60s - let deadline = Date.now() + 60 * 1000; + // Wait for 600s + let deadline = Date.now() + 600 * 1000; // Function to check if the subgraph is synced const checkSubgraphSynced = async () => { try { - let result = await fetchSubgraphs({ - query: `{ indexingStatuses { synced, health } }`, + let result = await fetchSubgraphIndexNode({ + query: `{ + indexingStatusForCurrentVersion(subgraphName: "${subgraphName}") { + synced + health + } + }`, }); - - if (result.data.indexingStatuses[0].synced) { + if (result.data.indexingStatusForCurrentVersion.synced) { resolve(); - } else if (result.data.indexingStatuses[0].health != "healthy") { - reject(new Error("Subgraph failed")); + } else if (result.data.indexingStatusForCurrentVersion.health != "healthy") { + reject(new Error("Subgraph is unhealthy")); } else { - throw new Error("reject or retry"); + throw new Error("Reject or retry"); } } catch (e) { if (Date.now() > deadline) { - reject(new Error(`Timed out waiting for the subgraph to sync`)); + reject(new Error("Timed out waiting for the subgraph to be synced")); } else { - setTimeout(checkSubgraphSynced, 500); + console.log("Waiting for the subgraph to be synced..."); + setTimeout(checkSubgraphSynced, 10000); } } }; @@ -60,12 +75,21 @@ contract("Contract", (accounts) => { const contract = await Contract.deployed(); // Insert its address into subgraph manifest + txhash = Contract.transactionHash; + block = (await web3.eth.getTransaction(txhash)).blockNumber; + await patching.replace( path.join(srcDir, "subgraph.yaml"), - "0x0000000000000000000000000000000000000000", + zeroAddress, contract.address ); + await patching.replace( + path.join(srcDir, "subgraph.yaml"), + templateBlock, + block + ); + // Create and deploy the subgraph exec(`yarn codegen`); exec(`yarn create:test`); @@ -73,7 +97,7 @@ contract("Contract", (accounts) => { }); it("subgraph does not fail", async () => { - // Wait for the subgraph to be indexed, and not fail + // Wait for the subgraph to be indexed await waitForSubgraphToBeSynced(); }); }); diff --git a/tests/integration-tests/host-exports/truffle.js b/tests/integration-tests/host-exports/truffle.js index e3957ea52e8..5fe9f316741 100644 --- a/tests/integration-tests/host-exports/truffle.js +++ b/tests/integration-tests/host-exports/truffle.js @@ -1,6 +1,14 @@ require("babel-register"); require("babel-polyfill"); +const Web3 = require("web3"); +const HDWalletProvider = require("@truffle/hdwallet-provider"); + +Web3.providers.HttpProvider.prototype.sendAsync = Web3.providers.HttpProvider.prototype.send +const neonDevnet = "https://devnet.neonevm.org" +const provider = new Web3.providers.HttpProvider(neonDevnet); +const privateKeys = process.env.NEON_ACCOUNTS.split(","); + module.exports = { contracts_directory: "../../common", migrations_directory: "../../common", @@ -11,12 +19,25 @@ module.exports = { port: process.env.GANACHE_TEST_PORT || 18545, network_id: "*", gas: "100000000000", - gasPrice: "1", + gasPrice: "1" + }, + neonlabs: { + provider: () => { + return new HDWalletProvider( + privateKeys, + provider + ); + }, + network_id: "*" }, + networkCheckTimeout: 120000 + }, + mocha: { + timeout: 600000 }, compilers: { solc: { - version: "0.8.2", - }, - }, + version: "0.8.2" + } + } }; diff --git a/tests/integration-tests/int8/package.json b/tests/integration-tests/int8/package.json index 79a45fc4368..0fe88048779 100644 --- a/tests/integration-tests/int8/package.json +++ b/tests/integration-tests/int8/package.json @@ -5,8 +5,9 @@ "build-contracts": "../../common/build-contracts.sh", "codegen": "graph codegen --skip-migrations", "test": "yarn build-contracts && truffle test --compile-none --network test", - "create:test": "graph create test/int8 --node $GRAPH_NODE_ADMIN_URI", - "deploy:test": "graph deploy test/int8 --version-label v0.0.1 --ipfs $IPFS_URI --node $GRAPH_NODE_ADMIN_URI" + "neon": "yarn build-contracts && yarn truffle test --compile-none --network neonlabs", + "create:test": "graph create $SUBGRAPH_NAME --node $GRAPH_NODE_ADMIN_URI", + "deploy:test": "graph deploy $SUBGRAPH_NAME --version-label v0.0.1 --ipfs $IPFS_URI --node $GRAPH_NODE_ADMIN_URI" }, "devDependencies": { "@graphprotocol/graph-cli": "0.51.0", diff --git a/tests/integration-tests/int8/subgraph.yaml b/tests/integration-tests/int8/subgraph.yaml index 0ab4801ce44..47876962e16 100644 --- a/tests/integration-tests/int8/subgraph.yaml +++ b/tests/integration-tests/int8/subgraph.yaml @@ -4,10 +4,11 @@ schema: dataSources: - kind: ethereum/contract name: Contract - network: test + network: neonlabs source: - address: "0xCfEB869F69431e42cdB54A4F4f105C19C080A601" + address: "0x0000000000000000000000000000000000000000" abi: Contract + startBlock: 247101047 mapping: kind: ethereum/events apiVersion: 0.0.6 diff --git a/tests/integration-tests/int8/test/test.js b/tests/integration-tests/int8/test/test.js index 14273bf98c7..c25613ad70c 100644 --- a/tests/integration-tests/int8/test/test.js +++ b/tests/integration-tests/int8/test/test.js @@ -3,18 +3,24 @@ const execSync = require("child_process").execSync; const { system, patching } = require("gluegun"); const { createApolloFetch } = require("apollo-fetch"); +const assert = require("assert"); const Contract = artifacts.require("./Contract.sol"); const srcDir = path.join(__dirname, ".."); +const subgraphName = process.env.SUBGRAPH_NAME || "subgraph_block_handlers"; +const indexNodeUrl = process.env.INDEX_NODE_URL || "https://ch2-graph.neontest.xyz/index-node/graphql"; +const subgraphUrl = process.env.SUBGRAPH_URL || `https://ch2-graph.neontest.xyz/subgraphs/name/${subgraphName}`; -const httpPort = process.env.GRAPH_NODE_HTTP_PORT || 18000; -const indexPort = process.env.GRAPH_NODE_INDEX_PORT || 18030; +const zeroAddress = "0x0000000000000000000000000000000000000000"; +const templateBlock = 247101047; -const fetchSubgraphs = createApolloFetch({ - uri: `http://localhost:${indexPort}/graphql`, +let block = 0; + +const fetchSubgraphIndexNode = createApolloFetch({ + uri: indexNodeUrl, }); const fetchSubgraph = createApolloFetch({ - uri: `http://localhost:${httpPort}/subgraphs/name/test/int8`, + uri: subgraphUrl, }); const exec = (cmd) => { @@ -27,28 +33,33 @@ const exec = (cmd) => { const waitForSubgraphToBeSynced = async () => new Promise((resolve, reject) => { - // Wait for 60s - let deadline = Date.now() + 60 * 1000; + // Wait for 600s + let deadline = Date.now() + 600 * 1000; // Function to check if the subgraph is synced const checkSubgraphSynced = async () => { try { - let result = await fetchSubgraphs({ - query: `{ indexingStatuses { synced, health } }`, + let result = await fetchSubgraphIndexNode({ + query: `{ + indexingStatusForCurrentVersion(subgraphName: "${subgraphName}") { + synced + health + } + }`, }); - - if (result.data.indexingStatuses[0].synced) { + if (result.data.indexingStatusForCurrentVersion.synced) { resolve(); - } else if (result.data.indexingStatuses[0].health != "healthy") { - reject(new Error("Subgraph failed")); + } else if (result.data.indexingStatusForCurrentVersion.health != "healthy") { + reject(new Error("Subgraph is unhealthy")); } else { - throw new Error("reject or retry"); + throw new Error("Reject or retry"); } } catch (e) { if (Date.now() > deadline) { - reject(new Error(`Timed out waiting for the subgraph to sync`)); + reject(new Error("Timed out waiting for the subgraph to be synced")); } else { - setTimeout(checkSubgraphSynced, 500); + console.log("Waiting for the subgraph to be synced..."); + setTimeout(checkSubgraphSynced, 10000); } } }; @@ -64,12 +75,21 @@ contract("Contract", (accounts) => { const contract = await Contract.deployed(); // Insert its address into subgraph manifest + txhash = Contract.transactionHash; + block = (await web3.eth.getTransaction(txhash)).blockNumber; + await patching.replace( path.join(srcDir, "subgraph.yaml"), - "0x0000000000000000000000000000000000000000", + zeroAddress, contract.address ); + await patching.replace( + path.join(srcDir, "subgraph.yaml"), + templateBlock, + block + ); + // Create and deploy the subgraph exec(`yarn codegen`); exec(`yarn create:test`); @@ -83,14 +103,18 @@ contract("Contract", (accounts) => { // Also test that multiple block constraints do not result in a graphql error. let result = await fetchSubgraph({ query: `{ - foos_0: foos(orderBy: id, block: { number: 0 }) { id } + foos_0: foos(orderBy: id, block: { number: ${block} }) { id } foos(orderBy: id) { id value } }`, }); expect(result.errors).to.be.undefined; expect(result.data).to.deep.equal({ - foos_0: [], + foos_0: [ + { + id: "0" + }, + ], foos: [ { id: "0", diff --git a/tests/integration-tests/int8/truffle.js b/tests/integration-tests/int8/truffle.js index 27a9675b4d7..a5b707ad02d 100644 --- a/tests/integration-tests/int8/truffle.js +++ b/tests/integration-tests/int8/truffle.js @@ -1,6 +1,14 @@ require("babel-register"); require("babel-polyfill"); +const Web3 = require("web3"); +const HDWalletProvider = require("@truffle/hdwallet-provider"); + +Web3.providers.HttpProvider.prototype.sendAsync = Web3.providers.HttpProvider.prototype.send +const neonDevnet = "https://devnet.neonevm.org" +const provider = new Web3.providers.HttpProvider(neonDevnet); +const privateKeys = process.env.NEON_ACCOUNTS.split(","); + module.exports = { contracts_directory: "../../common", migrations_directory: "../../common", @@ -12,7 +20,17 @@ module.exports = { network_id: "*", gas: "100000000000", gasPrice: "1" - } + }, + neonlabs: { + provider: () => { + return new HDWalletProvider( + privateKeys, + provider + ); + }, + network_id: "*" + }, + networkCheckTimeout: 120000 }, compilers: { solc: { diff --git a/tests/integration-tests/non-fatal-errors/package.json b/tests/integration-tests/non-fatal-errors/package.json index 431b77a04c8..faf6ab8f59b 100644 --- a/tests/integration-tests/non-fatal-errors/package.json +++ b/tests/integration-tests/non-fatal-errors/package.json @@ -5,8 +5,9 @@ "build-contracts": "../../common/build-contracts.sh", "codegen": "graph codegen --skip-migrations", "test": "yarn build-contracts && truffle test --compile-none --network test", - "create:test": "graph create test/non-fatal-errors --node $GRAPH_NODE_ADMIN_URI", - "deploy:test": "graph deploy test/non-fatal-errors --version-label v0.0.1 --ipfs $IPFS_URI --node $GRAPH_NODE_ADMIN_URI" + "neon": "yarn build-contracts && yarn truffle test --compile-none --network neonlabs", + "create:test": "graph create $SUBGRAPH_NAME --node $GRAPH_NODE_ADMIN_URI", + "deploy:test": "graph deploy $SUBGRAPH_NAME --version-label v0.0.1 --ipfs $IPFS_URI --node $GRAPH_NODE_ADMIN_URI" }, "devDependencies": { "@graphprotocol/graph-cli": "0.50.0", diff --git a/tests/integration-tests/non-fatal-errors/subgraph.yaml b/tests/integration-tests/non-fatal-errors/subgraph.yaml index 8a5e91c23ed..a28e2e3559a 100644 --- a/tests/integration-tests/non-fatal-errors/subgraph.yaml +++ b/tests/integration-tests/non-fatal-errors/subgraph.yaml @@ -6,10 +6,11 @@ features: dataSources: - kind: ethereum/contract name: Success - network: test + network: neonlabs source: - address: "0xCfEB869F69431e42cdB54A4F4f105C19C080A601" + address: "0x0000000000000000000000000000000000000000" abi: Contract + startBlock: 247101047 mapping: kind: ethereum/events apiVersion: 0.0.6 @@ -24,10 +25,11 @@ dataSources: file: ./src/mapping.ts - kind: ethereum/contract name: Error - network: test + network: neonlabs source: - address: "0xCfEB869F69431e42cdB54A4F4f105C19C080A601" + address: "0x0000000000000000000000000000000000000000" abi: Contract + startBlock: 247101047 mapping: kind: ethereum/events apiVersion: 0.0.6 @@ -43,7 +45,7 @@ dataSources: templates: - kind: ethereum/contract name: Dynamic - network: test + network: neonlabs source: abi: Contract mapping: diff --git a/tests/integration-tests/non-fatal-errors/test/test.js b/tests/integration-tests/non-fatal-errors/test/test.js index 84bd6efc0c5..0f135a92340 100644 --- a/tests/integration-tests/non-fatal-errors/test/test.js +++ b/tests/integration-tests/non-fatal-errors/test/test.js @@ -3,18 +3,24 @@ const execSync = require("child_process").execSync; const { system, patching } = require("gluegun"); const { createApolloFetch } = require("apollo-fetch"); +const assert = require("assert"); const Contract = artifacts.require("./Contract.sol"); const srcDir = path.join(__dirname, ".."); +const subgraphName = process.env.SUBGRAPH_NAME || "subgraph_block_handlers"; +const indexNodeUrl = process.env.INDEX_NODE_URL || "https://ch2-graph.neontest.xyz/index-node/graphql"; +const subgraphUrl = process.env.SUBGRAPH_URL || `https://ch2-graph.neontest.xyz/subgraphs/name/${subgraphName}`; -const httpPort = process.env.GRAPH_NODE_HTTP_PORT || 18000; -const indexPort = process.env.GRAPH_NODE_INDEX_PORT || 18030; +const zeroAddress = "0x0000000000000000000000000000000000000000"; +const templateBlock = 247101047; -const fetchSubgraphs = createApolloFetch({ - uri: `http://localhost:${indexPort}/graphql`, +let block = 0; + +const fetchSubgraphIndexNode = createApolloFetch({ + uri: indexNodeUrl, }); const fetchSubgraph = createApolloFetch({ - uri: `http://localhost:${httpPort}/subgraphs/name/test/non-fatal-errors`, + uri: subgraphUrl, }); const exec = (cmd) => { @@ -27,18 +33,21 @@ const exec = (cmd) => { const waitForSubgraphToBeUnhealthy = async () => new Promise((resolve, reject) => { - // Wait for 60s - let deadline = Date.now() + 60 * 1000; + // Wait for 600s + let deadline = Date.now() + 600 * 1000; // Function to check if the subgraph is synced - const checkSubgraphSynced = async () => { + const checkSubgraphUnhealthy = async () => { try { - let result = await fetchSubgraphs({ - query: `{ indexingStatuses { synced, health } }`, + let result = await fetchSubgraphIndexNode({ + query: `{ + indexingStatusForCurrentVersion(subgraphName: "${subgraphName}") { + synced + health + } + }`, }); - - let health = result.data.indexingStatuses[0].health - if (health == "unhealthy") { + if (result.data.indexingStatusForCurrentVersion.health == "unhealthy") { resolve(); } else if (health == "failed") { reject(new Error("Subgraph failed")); @@ -47,15 +56,15 @@ const waitForSubgraphToBeUnhealthy = async () => } } catch (e) { if (Date.now() > deadline) { - reject(new Error(`Timed out waiting for the subgraph to be uhealthy`)); + reject(new Error(`Timed out waiting for the subgraph to be unhealthy`)); } else { - setTimeout(checkSubgraphSynced, 500); + setTimeout(checkSubgraphUnhealthy, 500); } } }; // Periodically check whether the subgraph has synced - setTimeout(checkSubgraphSynced, 0); + setTimeout(checkSubgraphUnhealthy, 0); }); contract("Contract", (accounts) => { @@ -66,11 +75,22 @@ contract("Contract", (accounts) => { await contract.emitTrigger(1); // Insert its address into subgraph manifest - await patching.replace( - path.join(srcDir, "subgraph.yaml"), - "0x0000000000000000000000000000000000000000", - contract.address - ); + txhash = Contract.transactionHash; + block = (await web3.eth.getTransaction(txhash)).blockNumber; + + for (let i = 0; i < 2; i++) { + await patching.replace( + path.join(srcDir, "subgraph.yaml"), + zeroAddress, + contract.address + ); + + await patching.replace( + path.join(srcDir, "subgraph.yaml"), + templateBlock, + block + ); + } // Create and deploy the subgraph exec(`yarn codegen`); @@ -81,39 +101,7 @@ contract("Contract", (accounts) => { await waitForSubgraphToBeUnhealthy(); }); - it("only sucessful handler register changes", async () => { - let meta = await fetchSubgraph({ - query: `{ _meta { deployment } }`, - }); - - let deployment = meta.data._meta.deployment; - console.log("deployment", deployment); - - let subgraph_features = await fetchSubgraphs({ - query: `query GetSubgraphFeatures($deployment: String!) { - subgraphFeatures(subgraphId: $deployment) { - specVersion - apiVersion - features - dataSources - network - handlers - } - }`, - variables: { deployment }, - }); - - expect(subgraph_features.data).to.deep.equal({ - subgraphFeatures: { - specVersion: "0.0.4", - apiVersion: "0.0.6", - features: ["nonFatalErrors"], - dataSources: ["ethereum/contract"], - handlers: ["block"], - network: "test", - }, - }); - + it("only successful handler register changes", async () => { let result = await fetchSubgraph({ query: `{ foos(orderBy: id, subgraphError: allow) { id } }`, }); @@ -124,7 +112,7 @@ contract("Contract", (accounts) => { }, ]); - // Importantly, "1" and "11" are not present because their handlers erroed. + // Importantly, "1" and "11" are not present because their handlers errored. expect(result.data).to.deep.equal({ foos: [ { diff --git a/tests/integration-tests/non-fatal-errors/truffle.js b/tests/integration-tests/non-fatal-errors/truffle.js index e3957ea52e8..5fe9f316741 100644 --- a/tests/integration-tests/non-fatal-errors/truffle.js +++ b/tests/integration-tests/non-fatal-errors/truffle.js @@ -1,6 +1,14 @@ require("babel-register"); require("babel-polyfill"); +const Web3 = require("web3"); +const HDWalletProvider = require("@truffle/hdwallet-provider"); + +Web3.providers.HttpProvider.prototype.sendAsync = Web3.providers.HttpProvider.prototype.send +const neonDevnet = "https://devnet.neonevm.org" +const provider = new Web3.providers.HttpProvider(neonDevnet); +const privateKeys = process.env.NEON_ACCOUNTS.split(","); + module.exports = { contracts_directory: "../../common", migrations_directory: "../../common", @@ -11,12 +19,25 @@ module.exports = { port: process.env.GANACHE_TEST_PORT || 18545, network_id: "*", gas: "100000000000", - gasPrice: "1", + gasPrice: "1" + }, + neonlabs: { + provider: () => { + return new HDWalletProvider( + privateKeys, + provider + ); + }, + network_id: "*" }, + networkCheckTimeout: 120000 + }, + mocha: { + timeout: 600000 }, compilers: { solc: { - version: "0.8.2", - }, - }, + version: "0.8.2" + } + } }; diff --git a/tests/integration-tests/overloaded-contract-functions/package.json b/tests/integration-tests/overloaded-contract-functions/package.json index 4d1bf025013..40622fd1dc5 100644 --- a/tests/integration-tests/overloaded-contract-functions/package.json +++ b/tests/integration-tests/overloaded-contract-functions/package.json @@ -5,8 +5,9 @@ "build-contracts": "../../common/build-contracts.sh", "codegen": "graph codegen --skip-migrations", "test": "yarn build-contracts && truffle test --compile-none --network test", - "create:test": "graph create test/overloaded-contract-functions --node $GRAPH_NODE_ADMIN_URI", - "deploy:test": "graph deploy test/overloaded-contract-functions --version-label v0.0.1 --ipfs $IPFS_URI --node $GRAPH_NODE_ADMIN_URI" + "neon": "yarn build-contracts && yarn truffle test --compile-none --network neonlabs", + "create:test": "graph create $SUBGRAPH_NAME --node $GRAPH_NODE_ADMIN_URI", + "deploy:test": "graph deploy $SUBGRAPH_NAME --version-label v0.0.1 --ipfs $IPFS_URI --node $GRAPH_NODE_ADMIN_URI" }, "devDependencies": { "@graphprotocol/graph-cli": "0.50.0", diff --git a/tests/integration-tests/overloaded-contract-functions/subgraph.yaml b/tests/integration-tests/overloaded-contract-functions/subgraph.yaml index ff808ecfc0a..4c74ae82e7b 100644 --- a/tests/integration-tests/overloaded-contract-functions/subgraph.yaml +++ b/tests/integration-tests/overloaded-contract-functions/subgraph.yaml @@ -4,10 +4,11 @@ schema: dataSources: - kind: ethereum/contract name: Contract - network: test + network: neonlabs source: - address: "0xCfEB869F69431e42cdB54A4F4f105C19C080A601" + address: "0x0000000000000000000000000000000000000000" abi: Contract + startBlock: 247101047 mapping: kind: ethereum/events apiVersion: 0.0.6 diff --git a/tests/integration-tests/overloaded-contract-functions/test/test.js b/tests/integration-tests/overloaded-contract-functions/test/test.js index 0b183c04974..007c26517a5 100644 --- a/tests/integration-tests/overloaded-contract-functions/test/test.js +++ b/tests/integration-tests/overloaded-contract-functions/test/test.js @@ -3,22 +3,27 @@ const execSync = require("child_process").execSync; const { system, patching } = require("gluegun"); const { createApolloFetch } = require("apollo-fetch"); +const assert = require("assert"); const Contract = artifacts.require("./Contract.sol"); const srcDir = path.join(__dirname, ".."); +const subgraphName = process.env.SUBGRAPH_NAME || "subgraph_block_handlers"; +const indexNodeUrl = process.env.INDEX_NODE_URL || "https://ch2-graph.neontest.xyz/index-node/graphql"; +const subgraphUrl = process.env.SUBGRAPH_URL || `https://ch2-graph.neontest.xyz/subgraphs/name/${subgraphName}`; -const httpPort = process.env.GRAPH_NODE_HTTP_PORT || 18000; -const indexPort = process.env.GRAPH_NODE_INDEX_PORT || 18030; +const zeroAddress = "0x0000000000000000000000000000000000000000"; +const templateBlock = 247101047; -const fetchSubgraphs = createApolloFetch({ - uri: `http://localhost:${indexPort}/graphql` +let block = 0; + +const fetchSubgraphIndexNode = createApolloFetch({ + uri: indexNodeUrl, }); const fetchSubgraph = createApolloFetch({ - uri: - `http://localhost:${httpPort}/subgraphs/name/test/overloaded-contract-functions` + uri: subgraphUrl, }); -const exec = cmd => { +const exec = (cmd) => { try { return execSync(cmd, { cwd: srcDir, stdio: "inherit" }); } catch (e) { @@ -28,29 +33,33 @@ const exec = cmd => { const waitForSubgraphToBeSynced = async () => new Promise((resolve, reject) => { - // Wait for 60s - let deadline = Date.now() + 60 * 1000; + // Wait for 600s + let deadline = Date.now() + 600 * 1000; // Function to check if the subgraph is synced const checkSubgraphSynced = async () => { try { - let result = await fetchSubgraphs({ - query: `{ indexingStatuses { synced } }` + let result = await fetchSubgraphIndexNode({ + query: `{ + indexingStatusForCurrentVersion(subgraphName: "${subgraphName}") { + synced + health + } + }`, }); - - if ( - JSON.stringify(result) === - JSON.stringify({ data: { indexingStatuses: [{ synced: true }] } }) - ) { + if (result.data.indexingStatusForCurrentVersion.synced) { resolve(); + } else if (result.data.indexingStatusForCurrentVersion.health != "healthy") { + reject(new Error("Subgraph is unhealthy")); } else { - throw new Error("reject or retry"); + throw new Error("Reject or retry"); } } catch (e) { if (Date.now() > deadline) { - reject(new Error(`Timed out waiting for the subgraph to sync`)); + reject(new Error("Timed out waiting for the subgraph to be synced")); } else { - setTimeout(checkSubgraphSynced, 500); + console.log("Waiting for the subgraph to be synced..."); + setTimeout(checkSubgraphSynced, 10000); } } }; @@ -59,19 +68,28 @@ const waitForSubgraphToBeSynced = async () => setTimeout(checkSubgraphSynced, 0); }); -contract("Contract", accounts => { +contract("Contract", (accounts) => { // Deploy the subgraph once before all tests before(async () => { // Deploy the contract const contract = await Contract.deployed(); // Insert its address into subgraph manifest + txhash = Contract.transactionHash; + block = (await web3.eth.getTransaction(txhash)).blockNumber; + await patching.replace( path.join(srcDir, "subgraph.yaml"), - "0x0000000000000000000000000000000000000000", + zeroAddress, contract.address ); + await patching.replace( + path.join(srcDir, "subgraph.yaml"), + templateBlock, + block + ); + // Create and deploy the subgraph exec(`yarn codegen`); exec(`yarn create:test`); @@ -81,6 +99,7 @@ contract("Contract", accounts => { await waitForSubgraphToBeSynced(); }); + it("all overloads of the contract function are called", async () => { let result = await fetchSubgraph({ query: `{ calls(orderBy: id) { id value } }` diff --git a/tests/integration-tests/overloaded-contract-functions/truffle.js b/tests/integration-tests/overloaded-contract-functions/truffle.js index b9e17f8c4b9..ca578cf5c59 100644 --- a/tests/integration-tests/overloaded-contract-functions/truffle.js +++ b/tests/integration-tests/overloaded-contract-functions/truffle.js @@ -1,6 +1,14 @@ require("babel-register"); require("babel-polyfill"); +const Web3 = require("web3"); +const HDWalletProvider = require("@truffle/hdwallet-provider"); + +Web3.providers.HttpProvider.prototype.sendAsync = Web3.providers.HttpProvider.prototype.send +const neonDevnet = "https://devnet.neonevm.org" +const provider = new Web3.providers.HttpProvider(neonDevnet); +const privateKeys = process.env.NEON_ACCOUNTS.split(","); + module.exports = { contracts_build_directory: "./truffle_output", networks: { @@ -10,7 +18,20 @@ module.exports = { network_id: "*", gas: "100000000000", gasPrice: "1" - } + }, + neonlabs: { + provider: () => { + return new HDWalletProvider( + privateKeys, + provider + ); + }, + network_id: "*" + }, + networkCheckTimeout: 120000 + }, + mocha: { + timeout: 600000 }, compilers: { solc: { diff --git a/tests/integration-tests/package.json b/tests/integration-tests/package.json index fd134e4d88d..de31ef1ca9d 100644 --- a/tests/integration-tests/package.json +++ b/tests/integration-tests/package.json @@ -2,7 +2,7 @@ "private": true, "workspaces": [ "api-version-v0-0-4", - "ganache-reverts", + "chain-reverts", "host-exports", "non-fatal-errors", "overloaded-contract-functions", diff --git a/tests/integration-tests/poi-for-failed-subgraph/package.json b/tests/integration-tests/poi-for-failed-subgraph/package.json index 524d2c2df25..d28b52c5a52 100644 --- a/tests/integration-tests/poi-for-failed-subgraph/package.json +++ b/tests/integration-tests/poi-for-failed-subgraph/package.json @@ -5,8 +5,9 @@ "build-contracts": "../../common/build-contracts.sh", "codegen": "graph codegen --skip-migrations", "test": "yarn build-contracts && truffle test --compile-none --network test", - "create:test": "graph create test/poi-for-failed-subgraph --node $GRAPH_NODE_ADMIN_URI", - "deploy:test": "graph deploy test/poi-for-failed-subgraph --version-label v0.0.1 --ipfs $IPFS_URI --node $GRAPH_NODE_ADMIN_URI" + "neon": "yarn build-contracts && yarn truffle test --compile-none --network neonlabs", + "create:test": "graph create $SUBGRAPH_NAME --node $GRAPH_NODE_ADMIN_URI", + "deploy:test": "graph deploy $SUBGRAPH_NAME --version-label v0.0.1 --ipfs $IPFS_URI --node $GRAPH_NODE_ADMIN_URI" }, "devDependencies": { "@graphprotocol/graph-cli": "0.50.0", diff --git a/tests/integration-tests/poi-for-failed-subgraph/subgraph.yaml b/tests/integration-tests/poi-for-failed-subgraph/subgraph.yaml index 0ab4801ce44..47876962e16 100644 --- a/tests/integration-tests/poi-for-failed-subgraph/subgraph.yaml +++ b/tests/integration-tests/poi-for-failed-subgraph/subgraph.yaml @@ -4,10 +4,11 @@ schema: dataSources: - kind: ethereum/contract name: Contract - network: test + network: neonlabs source: - address: "0xCfEB869F69431e42cdB54A4F4f105C19C080A601" + address: "0x0000000000000000000000000000000000000000" abi: Contract + startBlock: 247101047 mapping: kind: ethereum/events apiVersion: 0.0.6 diff --git a/tests/integration-tests/poi-for-failed-subgraph/test/test.js b/tests/integration-tests/poi-for-failed-subgraph/test/test.js index 42c511eead1..4caf9e3f223 100644 --- a/tests/integration-tests/poi-for-failed-subgraph/test/test.js +++ b/tests/integration-tests/poi-for-failed-subgraph/test/test.js @@ -1,26 +1,38 @@ -const assert = require("assert") const path = require("path"); const execSync = require("child_process").execSync; -const { patching } = require("gluegun"); +const { system, patching } = require("gluegun"); const { createApolloFetch } = require("apollo-fetch"); +const assert = require("assert"); const Contract = artifacts.require("./Contract.sol"); const srcDir = path.join(__dirname, ".."); +const subgraphName = process.env.SUBGRAPH_NAME || "subgraph_block_handlers"; +const indexNodeUrl = process.env.INDEX_NODE_URL || "https://ch2-graph.neontest.xyz/index-node/graphql"; +const subgraphUrl = process.env.SUBGRAPH_URL || `https://ch2-graph.neontest.xyz/subgraphs/name/${subgraphName}`; -const httpPort = process.env.GRAPH_NODE_HTTP_PORT || 18000; -const indexPort = process.env.GRAPH_NODE_INDEX_PORT || 18030; +const zeroAddress = "0x0000000000000000000000000000000000000000"; +const templateBlock = 247101047; -const fetchSubgraphs = createApolloFetch({ - uri: `http://localhost:${indexPort}/graphql`, +let block = 0; + +const fetchSubgraphIndexNode = createApolloFetch({ + uri: indexNodeUrl, }); const fetchSubgraph = createApolloFetch({ - uri: `http://localhost:${httpPort}/subgraphs/name/test/poi-for-failed-subgraph`, + uri: subgraphUrl, }); -const fetchIndexingStatuses = subgraphName => fetchSubgraphs({ +const exec = (cmd) => { + try { + return execSync(cmd, { cwd: srcDir, stdio: "inherit" }); + } catch (e) { + throw new Error(`Failed to run command \`${cmd}\``); + } +}; +const fetchIndexingStatuses = name => fetchSubgraphIndexNode({ query: `{ - indexingStatusesForSubgraphName(subgraphName: "${subgraphName}") { + indexingStatusesForSubgraphName(subgraphName: "${name}") { subgraph health entityCount @@ -32,7 +44,7 @@ const fetchIndexingStatuses = subgraphName => fetchSubgraphs({ }`, }) -const fetchProofOfIndexing = ({ deploymentId, latestBlock }) => fetchSubgraphs({ +const fetchProofOfIndexing = ({ deploymentId, latestBlock }) => fetchSubgraphIndexNode({ query: `{ proofOfIndexing( subgraph: "${deploymentId}", @@ -51,17 +63,9 @@ const fetchEntityCalls = () => fetchSubgraph({ }`, }) -const exec = (cmd) => { - try { - return execSync(cmd, { cwd: srcDir, stdio: "inherit" }); - } catch (e) { - throw new Error(`Failed to run command \`${cmd}\``); - } -}; - const waitForSubgraphToFailWithError = async (blockNumber) => new Promise((resolve, reject) => { - let deadline = Date.now() + 60 * 1000; + let deadline = Date.now() + 600 * 1000; const checkSubgraphFailedWithPoI = async () => { try { @@ -70,7 +74,8 @@ const waitForSubgraphToFailWithError = async (blockNumber) => // - last block number // - subgraph deployment id // So we can query the PoI later. - let statusesResult = await fetchIndexingStatuses("test/poi-for-failed-subgraph"); + let statusesResult = await fetchIndexingStatuses(subgraphName); + console.log("statusesResult", JSON.stringify(statusesResult)) if (statusesResult.errors != null) { reject("query contains errors: " + JSON.stringify(statusesResult.errors)); @@ -97,7 +102,7 @@ const waitForSubgraphToFailWithError = async (blockNumber) => // Need to have failed since mappings have an `assert(false)`. if (status.health === "failed") { // Find latest block for the correct chain (we only use one) - let { latestBlock } = status.chains.find(({ network }) => network === "test") + let { latestBlock } = status.chains.find(({ network }) => network === "neonlabs") let poiResult = await fetchProofOfIndexing({ deploymentId: status.subgraph, @@ -105,13 +110,13 @@ const waitForSubgraphToFailWithError = async (blockNumber) => }) let hasPoI = poiResult.data && poiResult.data.proofOfIndexing != null - let hasOnlyOneEntityInTheDatabase = status.entityCount == 1 + let hasOnlyOneEntityInTheDatabase = status.entityCount if (!hasPoI) { - return reject(new Error("Failed subgraph should have Proof of Indexing for block")); - } else if (!hasOnlyOneEntityInTheDatabase) { + throw new Error("Failed subgraph should have Proof of Indexing for block"); + } else if (hasOnlyOneEntityInTheDatabase != 1) { // 1 instead of 3, which would happen if both 'Call' entities were saved in the database (look at src/mapping.ts) - return reject(new Error("Proof of Indexing returned, but it's not saved into the database")); + throw new Error("Proof of Indexing returned, but it's not saved into the database"); } else { return resolve(); } @@ -122,7 +127,7 @@ const waitForSubgraphToFailWithError = async (blockNumber) => if (Date.now() > deadline) { return reject(new Error(`Timed out waiting for the subgraph to fail`)); } else { - setTimeout(checkSubgraphFailedWithPoI, 500); + setTimeout(checkSubgraphFailedWithPoI, 10000); } } }; @@ -138,12 +143,21 @@ contract("Contract", (accounts) => { await contract.emitTrigger(1); // Insert its address into subgraph manifest + txhash = Contract.transactionHash; + block = (await web3.eth.getTransaction(txhash)).blockNumber; + await patching.replace( path.join(srcDir, "subgraph.yaml"), - "0x0000000000000000000000000000000000000000", + zeroAddress, contract.address ); + await patching.replace( + path.join(srcDir, "subgraph.yaml"), + templateBlock, + block + ); + // Create and deploy the subgraph exec("yarn codegen"); exec(`yarn create:test`); diff --git a/tests/integration-tests/poi-for-failed-subgraph/truffle.js b/tests/integration-tests/poi-for-failed-subgraph/truffle.js index 58130e7d21d..5fe9f316741 100644 --- a/tests/integration-tests/poi-for-failed-subgraph/truffle.js +++ b/tests/integration-tests/poi-for-failed-subgraph/truffle.js @@ -1,6 +1,14 @@ require("babel-register"); require("babel-polyfill"); +const Web3 = require("web3"); +const HDWalletProvider = require("@truffle/hdwallet-provider"); + +Web3.providers.HttpProvider.prototype.sendAsync = Web3.providers.HttpProvider.prototype.send +const neonDevnet = "https://devnet.neonevm.org" +const provider = new Web3.providers.HttpProvider(neonDevnet); +const privateKeys = process.env.NEON_ACCOUNTS.split(","); + module.exports = { contracts_directory: "../../common", migrations_directory: "../../common", @@ -11,12 +19,25 @@ module.exports = { port: process.env.GANACHE_TEST_PORT || 18545, network_id: "*", gas: "100000000000", - gasPrice: "1", + gasPrice: "1" + }, + neonlabs: { + provider: () => { + return new HDWalletProvider( + privateKeys, + provider + ); + }, + network_id: "*" }, + networkCheckTimeout: 120000 + }, + mocha: { + timeout: 600000 }, compilers: { solc: { version: "0.8.2" - }, - }, + } + } }; diff --git a/tests/integration-tests/remove-then-update/package.json b/tests/integration-tests/remove-then-update/package.json index 3c5dde77937..82728567c28 100644 --- a/tests/integration-tests/remove-then-update/package.json +++ b/tests/integration-tests/remove-then-update/package.json @@ -5,8 +5,9 @@ "build-contracts": "../../common/build-contracts.sh", "codegen": "graph codegen --skip-migrations", "test": "yarn build-contracts && truffle test --compile-none --network test", - "create:test": "graph create test/remove-then-update --node $GRAPH_NODE_ADMIN_URI", - "deploy:test": "graph deploy test/remove-then-update --version-label v0.0.1 --ipfs $IPFS_URI --node $GRAPH_NODE_ADMIN_URI" + "neon": "yarn build-contracts && yarn truffle test --compile-none --network neonlabs", + "create:test": "graph create $SUBGRAPH_NAME --node $GRAPH_NODE_ADMIN_URI", + "deploy:test": "graph deploy $SUBGRAPH_NAME --version-label v0.0.1 --ipfs $IPFS_URI --node $GRAPH_NODE_ADMIN_URI" }, "devDependencies": { "@graphprotocol/graph-cli": "0.50.0", diff --git a/tests/integration-tests/remove-then-update/subgraph.yaml b/tests/integration-tests/remove-then-update/subgraph.yaml index 0ab4801ce44..47876962e16 100644 --- a/tests/integration-tests/remove-then-update/subgraph.yaml +++ b/tests/integration-tests/remove-then-update/subgraph.yaml @@ -4,10 +4,11 @@ schema: dataSources: - kind: ethereum/contract name: Contract - network: test + network: neonlabs source: - address: "0xCfEB869F69431e42cdB54A4F4f105C19C080A601" + address: "0x0000000000000000000000000000000000000000" abi: Contract + startBlock: 247101047 mapping: kind: ethereum/events apiVersion: 0.0.6 diff --git a/tests/integration-tests/remove-then-update/test/test.js b/tests/integration-tests/remove-then-update/test/test.js index ea1c4e79772..8f7a800eb73 100644 --- a/tests/integration-tests/remove-then-update/test/test.js +++ b/tests/integration-tests/remove-then-update/test/test.js @@ -3,18 +3,24 @@ const execSync = require("child_process").execSync; const { system, patching } = require("gluegun"); const { createApolloFetch } = require("apollo-fetch"); +const assert = require("assert"); const Contract = artifacts.require("./Contract.sol"); const srcDir = path.join(__dirname, ".."); +const subgraphName = process.env.SUBGRAPH_NAME || "subgraph_block_handlers"; +const indexNodeUrl = process.env.INDEX_NODE_URL || "https://ch2-graph.neontest.xyz/index-node/graphql"; +const subgraphUrl = process.env.SUBGRAPH_URL || `https://ch2-graph.neontest.xyz/subgraphs/name/${subgraphName}`; -const httpPort = process.env.GRAPH_NODE_HTTP_PORT || 18000; -const indexPort = process.env.GRAPH_NODE_INDEX_PORT || 18030; +const zeroAddress = "0x0000000000000000000000000000000000000000"; +const templateBlock = 247101047; -const fetchSubgraphs = createApolloFetch({ - uri: `http://localhost:${indexPort}/graphql`, +let block = 0; + +const fetchSubgraphIndexNode = createApolloFetch({ + uri: indexNodeUrl, }); const fetchSubgraph = createApolloFetch({ - uri: `http://localhost:${httpPort}/subgraphs/name/test/remove-then-update`, + uri: subgraphUrl, }); const exec = (cmd) => { @@ -27,28 +33,33 @@ const exec = (cmd) => { const waitForSubgraphToBeSynced = async () => new Promise((resolve, reject) => { - // Wait for 60s - let deadline = Date.now() + 60 * 1000; + // Wait for 600s + let deadline = Date.now() + 600 * 1000; // Function to check if the subgraph is synced const checkSubgraphSynced = async () => { try { - let result = await fetchSubgraphs({ - query: `{ indexingStatuses { synced, health } }`, + let result = await fetchSubgraphIndexNode({ + query: `{ + indexingStatusForCurrentVersion(subgraphName: "${subgraphName}") { + synced + health + } + }`, }); - - if (result.data.indexingStatuses[0].synced) { + if (result.data.indexingStatusForCurrentVersion.synced) { resolve(); - } else if (result.data.indexingStatuses[0].health != "healthy") { - reject(new Error("Subgraph failed")); + } else if (result.data.indexingStatusForCurrentVersion.health != "healthy") { + reject(new Error("Subgraph is unhealthy")); } else { - throw new Error("reject or retry"); + throw new Error("Reject or retry"); } } catch (e) { if (Date.now() > deadline) { - reject(new Error(`Timed out waiting for the subgraph to sync`)); + reject(new Error("Timed out waiting for the subgraph to be synced")); } else { - setTimeout(checkSubgraphSynced, 500); + console.log("Waiting for the subgraph to be synced..."); + setTimeout(checkSubgraphSynced, 10000); } } }; @@ -65,12 +76,21 @@ contract("Contract", (accounts) => { await contract.emitTrigger(1); // Insert its address into subgraph manifest + txhash = Contract.transactionHash; + block = (await web3.eth.getTransaction(txhash)).blockNumber; + await patching.replace( path.join(srcDir, "subgraph.yaml"), - "0x0000000000000000000000000000000000000000", + zeroAddress, contract.address ); + await patching.replace( + path.join(srcDir, "subgraph.yaml"), + templateBlock, + block + ); + // Create and deploy the subgraph exec(`yarn codegen`); exec(`yarn create:test`); @@ -80,7 +100,7 @@ contract("Contract", (accounts) => { await waitForSubgraphToBeSynced(); }); - it("all overloads of the contract function are called", async () => { + it("Check subgraph entity was removed", async () => { let result = await fetchSubgraph({ query: `{ foos(orderBy: id) { id value removed } }`, }); diff --git a/tests/integration-tests/remove-then-update/truffle.js b/tests/integration-tests/remove-then-update/truffle.js index e3957ea52e8..5fe9f316741 100644 --- a/tests/integration-tests/remove-then-update/truffle.js +++ b/tests/integration-tests/remove-then-update/truffle.js @@ -1,6 +1,14 @@ require("babel-register"); require("babel-polyfill"); +const Web3 = require("web3"); +const HDWalletProvider = require("@truffle/hdwallet-provider"); + +Web3.providers.HttpProvider.prototype.sendAsync = Web3.providers.HttpProvider.prototype.send +const neonDevnet = "https://devnet.neonevm.org" +const provider = new Web3.providers.HttpProvider(neonDevnet); +const privateKeys = process.env.NEON_ACCOUNTS.split(","); + module.exports = { contracts_directory: "../../common", migrations_directory: "../../common", @@ -11,12 +19,25 @@ module.exports = { port: process.env.GANACHE_TEST_PORT || 18545, network_id: "*", gas: "100000000000", - gasPrice: "1", + gasPrice: "1" + }, + neonlabs: { + provider: () => { + return new HDWalletProvider( + privateKeys, + provider + ); + }, + network_id: "*" }, + networkCheckTimeout: 120000 + }, + mocha: { + timeout: 600000 }, compilers: { solc: { - version: "0.8.2", - }, - }, + version: "0.8.2" + } + } }; diff --git a/tests/integration-tests/value-roundtrip/package.json b/tests/integration-tests/value-roundtrip/package.json index ceea4439afd..8ed1d365865 100644 --- a/tests/integration-tests/value-roundtrip/package.json +++ b/tests/integration-tests/value-roundtrip/package.json @@ -5,8 +5,9 @@ "build-contracts": "../../common/build-contracts.sh", "codegen": "graph codegen --skip-migrations", "test": "yarn build-contracts && truffle test --compile-none --network test", - "create:test": "graph create test/value-roundtrip --node $GRAPH_NODE_ADMIN_URI", - "deploy:test": "graph deploy test/value-roundtrip --version-label v0.0.1 --ipfs $IPFS_URI --node $GRAPH_NODE_ADMIN_URI" + "neon": "yarn build-contracts && yarn truffle test --compile-none --network neonlabs", + "create:test": "graph create $SUBGRAPH_NAME --node $GRAPH_NODE_ADMIN_URI", + "deploy:test": "graph deploy $SUBGRAPH_NAME --version-label v0.0.1 --ipfs $IPFS_URI --node $GRAPH_NODE_ADMIN_URI" }, "devDependencies": { "@graphprotocol/graph-cli": "0.50.0", diff --git a/tests/integration-tests/value-roundtrip/subgraph.yaml b/tests/integration-tests/value-roundtrip/subgraph.yaml index 0ab4801ce44..47876962e16 100644 --- a/tests/integration-tests/value-roundtrip/subgraph.yaml +++ b/tests/integration-tests/value-roundtrip/subgraph.yaml @@ -4,10 +4,11 @@ schema: dataSources: - kind: ethereum/contract name: Contract - network: test + network: neonlabs source: - address: "0xCfEB869F69431e42cdB54A4F4f105C19C080A601" + address: "0x0000000000000000000000000000000000000000" abi: Contract + startBlock: 247101047 mapping: kind: ethereum/events apiVersion: 0.0.6 diff --git a/tests/integration-tests/value-roundtrip/test/test.js b/tests/integration-tests/value-roundtrip/test/test.js index d8247d9e98b..8458ba98209 100644 --- a/tests/integration-tests/value-roundtrip/test/test.js +++ b/tests/integration-tests/value-roundtrip/test/test.js @@ -3,18 +3,24 @@ const execSync = require("child_process").execSync; const { system, patching } = require("gluegun"); const { createApolloFetch } = require("apollo-fetch"); +const assert = require("assert"); const Contract = artifacts.require("./Contract.sol"); const srcDir = path.join(__dirname, ".."); +const subgraphName = process.env.SUBGRAPH_NAME || "subgraph_block_handlers"; +const indexNodeUrl = process.env.INDEX_NODE_URL || "https://ch2-graph.neontest.xyz/index-node/graphql"; +const subgraphUrl = process.env.SUBGRAPH_URL || `https://ch2-graph.neontest.xyz/subgraphs/name/${subgraphName}`; -const httpPort = process.env.GRAPH_NODE_HTTP_PORT || 18000; -const indexPort = process.env.GRAPH_NODE_INDEX_PORT || 18030; +const zeroAddress = "0x0000000000000000000000000000000000000000"; +const templateBlock = 247101047; -const fetchSubgraphs = createApolloFetch({ - uri: `http://localhost:${indexPort}/graphql`, +let block = 0; + +const fetchSubgraphIndexNode = createApolloFetch({ + uri: indexNodeUrl, }); const fetchSubgraph = createApolloFetch({ - uri: `http://localhost:${httpPort}/subgraphs/name/test/value-roundtrip`, + uri: subgraphUrl, }); const exec = (cmd) => { @@ -27,28 +33,33 @@ const exec = (cmd) => { const waitForSubgraphToBeSynced = async () => new Promise((resolve, reject) => { - // Wait for 60s - let deadline = Date.now() + 60 * 1000; + // Wait for 600s + let deadline = Date.now() + 600 * 1000; // Function to check if the subgraph is synced const checkSubgraphSynced = async () => { try { - let result = await fetchSubgraphs({ - query: `{ indexingStatuses { synced, health } }`, + let result = await fetchSubgraphIndexNode({ + query: `{ + indexingStatusForCurrentVersion(subgraphName: "${subgraphName}") { + synced + health + } + }`, }); - - if (result.data.indexingStatuses[0].synced) { + if (result.data.indexingStatusForCurrentVersion.synced) { resolve(); - } else if (result.data.indexingStatuses[0].health != "healthy") { - reject(new Error("Subgraph failed")); + } else if (result.data.indexingStatusForCurrentVersion.health != "healthy") { + reject(new Error("Subgraph is unhealthy")); } else { - throw new Error("reject or retry"); + throw new Error("Reject or retry"); } } catch (e) { if (Date.now() > deadline) { - reject(new Error(`Timed out waiting for the subgraph to sync`)); + reject(new Error("Timed out waiting for the subgraph to be synced")); } else { - setTimeout(checkSubgraphSynced, 500); + console.log("Waiting for the subgraph to be synced..."); + setTimeout(checkSubgraphSynced, 10000); } } }; @@ -64,12 +75,21 @@ contract("Contract", (accounts) => { const contract = await Contract.deployed(); // Insert its address into subgraph manifest + txhash = Contract.transactionHash; + block = (await web3.eth.getTransaction(txhash)).blockNumber; + await patching.replace( path.join(srcDir, "subgraph.yaml"), - "0x0000000000000000000000000000000000000000", + zeroAddress, contract.address ); + await patching.replace( + path.join(srcDir, "subgraph.yaml"), + templateBlock, + block + ); + // Create and deploy the subgraph exec(`yarn codegen`); exec(`yarn create:test`); @@ -83,14 +103,18 @@ contract("Contract", (accounts) => { // Also test that multiple block constraints do not result in a graphql error. let result = await fetchSubgraph({ query: `{ - foos_0: foos(orderBy: id, block: { number: 0 }) { id } + foos_0: foos(orderBy: id, block: { number: ${block} }) { id } foos(orderBy: id) { id value } }`, }); expect(result.errors).to.be.undefined; expect(result.data).to.deep.equal({ - foos_0: [], + foos_0: [ + { + id: "0" + }, + ], foos: [ { id: "0", diff --git a/tests/integration-tests/value-roundtrip/truffle.js b/tests/integration-tests/value-roundtrip/truffle.js index 27a9675b4d7..5fe9f316741 100644 --- a/tests/integration-tests/value-roundtrip/truffle.js +++ b/tests/integration-tests/value-roundtrip/truffle.js @@ -1,6 +1,14 @@ require("babel-register"); require("babel-polyfill"); +const Web3 = require("web3"); +const HDWalletProvider = require("@truffle/hdwallet-provider"); + +Web3.providers.HttpProvider.prototype.sendAsync = Web3.providers.HttpProvider.prototype.send +const neonDevnet = "https://devnet.neonevm.org" +const provider = new Web3.providers.HttpProvider(neonDevnet); +const privateKeys = process.env.NEON_ACCOUNTS.split(","); + module.exports = { contracts_directory: "../../common", migrations_directory: "../../common", @@ -12,7 +20,20 @@ module.exports = { network_id: "*", gas: "100000000000", gasPrice: "1" - } + }, + neonlabs: { + provider: () => { + return new HDWalletProvider( + privateKeys, + provider + ); + }, + network_id: "*" + }, + networkCheckTimeout: 120000 + }, + mocha: { + timeout: 600000 }, compilers: { solc: { diff --git a/tests/integration-tests/yarn.lock b/tests/integration-tests/yarn.lock index f25f7096987..82ad872c3f7 100644 --- a/tests/integration-tests/yarn.lock +++ b/tests/integration-tests/yarn.lock @@ -570,6 +570,11 @@ lodash "^4.17.19" to-fast-properties "^2.0.0" +"@colors/colors@1.5.0": + version "1.5.0" + resolved "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" + integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== + "@cspotcode/source-map-support@^0.8.0": version "0.8.1" resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" @@ -577,6 +582,15 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" +"@dabh/diagnostics@^2.0.2": + version "2.0.3" + resolved "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz#7f7e97ee9a725dffc7808d93668cc984e1dc477a" + integrity sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA== + dependencies: + colorspace "1.1.x" + enabled "2.0.x" + kuler "^2.0.0" + "@ethersproject/abi@5.0.0-beta.153": version "5.0.0-beta.153" resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.0.0-beta.153.tgz#43a37172b33794e4562999f6e2d555b7599a8eee" @@ -2154,6 +2168,11 @@ "@types/mime" "^1" "@types/node" "*" +"@types/triple-beam@^1.3.2": + version "1.3.3" + resolved "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.3.tgz#726ae98a5f6418c8f24f9b0f2a9f81a8664876ae" + integrity sha512-6tOUG+nVHn0cJbVp25JFayS5UE6+xlbcNF9Lo9mU7U0zk3zeUShZied4YEQZjy1JBF043FSkdXw8YkUJuVtB5g== + "@types/ungap__global-this@^0.3.1": version "0.3.1" resolved "https://registry.yarnpkg.com/@types/ungap__global-this/-/ungap__global-this-0.3.1.tgz#18ce9f657da556037a29d50604335614ce703f4c" @@ -3222,7 +3241,7 @@ binaryen@77.0.0-nightly.20190407: resolved "https://registry.yarnpkg.com/binaryen/-/binaryen-77.0.0-nightly.20190407.tgz#fbe4f8ba0d6bd0809a84eb519d2d5b5ddff3a7d1" integrity sha512-1mxYNvQ0xywMe582K7V6Vo2zzhZZxMTeGHH8aE/+/AND8f64D8Q1GThVY3RVRwGY/4p+p95ccw9Xbw2ovFXRIg== -bindings@^1.5.0: +bindings@^1.2.1, bindings@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== @@ -3989,7 +4008,7 @@ code-point-at@^1.0.0: resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= -color-convert@^1.9.0: +color-convert@^1.9.0, color-convert@^1.9.3: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== @@ -4018,11 +4037,27 @@ color-name@1.1.3: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== -color-name@~1.1.4: +color-name@^1.0.0, color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +color-string@^1.6.0: + version "1.9.1" + resolved "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4" + integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color@^3.1.3: + version "3.2.1" + resolved "https://registry.npmjs.org/color/-/color-3.2.1.tgz#3544dc198caf4490c3ecc9a790b54fe9ff45e164" + integrity sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA== + dependencies: + color-convert "^1.9.3" + color-string "^1.6.0" + colorette@^1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" @@ -4033,6 +4068,14 @@ colors@1.4.0, colors@^1.1.2, colors@^1.3.3: resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== +colorspace@1.1.x: + version "1.1.4" + resolved "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz#8d442d1186152f60453bf8070cd66eb364e59243" + integrity sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w== + dependencies: + color "^3.1.3" + text-hex "1.0.x" + combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -4084,13 +4127,6 @@ concat-stream@^1.6.0, concat-stream@^1.6.2, concat-stream@~1.6.2: readable-stream "^2.2.2" typedarray "^0.0.6" -"concat-stream@github:hugomrdias/concat-stream#feat/smaller": - version "2.0.0" - resolved "https://codeload.github.com/hugomrdias/concat-stream/tar.gz/057bc7b5d6d8df26c8cf00a3f151b6721a0a8034" - dependencies: - inherits "^2.0.3" - readable-stream "^3.0.2" - configstore@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/configstore/-/configstore-4.0.0.tgz#5933311e95d3687efb592c528b922d9262d227e7" @@ -4137,6 +4173,14 @@ content-type@~1.0.4: resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== +contextify@0.1.x: + version "0.1.15" + resolved "https://registry.npmjs.org/contextify/-/contextify-0.1.15.tgz#3d34681d14a5ccbbe609c9ee11eda206b8cf266f" + integrity sha512-NpM4b6u5Mzig1/ux3ReVv42L/og3WcKKvkmTWxZpIjhZ/S23BViWZD/7hds9LGNzEL3W9ItfoZ+p6eRhCQMH6Q== + dependencies: + bindings "^1.2.1" + nan "^2.1.0" + convert-source-map@1.X, convert-source-map@^1.5.1, convert-source-map@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" @@ -4369,6 +4413,11 @@ cssfilter@0.0.10: resolved "https://registry.yarnpkg.com/cssfilter/-/cssfilter-0.0.10.tgz#c6d2672632a2e5c83e013e6864a42ce8defd20ae" integrity sha1-xtJnJjKi5cg+AT5oZKQs6N79IK4= +cssom@0.2.x: + version "0.2.5" + resolved "https://registry.npmjs.org/cssom/-/cssom-0.2.5.tgz#2682709b5902e7212df529116ff788cd5b254894" + integrity sha512-b9ecqKEfWrNcyzx5+1nmcfi80fPp8dVM8rlAh7fFK14PZbNjp++gRjyZTZfLJQa/Lw0qeCJho7WBIl0nw0v6HA== + cssom@0.3.x, "cssom@>= 0.3.0 < 0.4.0": version "0.3.8" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" @@ -4381,6 +4430,13 @@ cssom@0.3.x, "cssom@>= 0.3.0 < 0.4.0": dependencies: cssom "0.3.x" +cssstyle@>=0.2.3: + version "3.0.0" + resolved "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz#17ca9c87d26eac764bb8cfd00583cff21ce0277a" + integrity sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg== + dependencies: + rrweb-cssom "^0.6.0" + d@1, d@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" @@ -4866,6 +4922,11 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +enabled@2.0.x: + version "2.0.0" + resolved "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz#f9dd92ec2d6f4bbc0d5d1e64e21d61cd4665e7c2" + integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ== + encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" @@ -5754,6 +5815,11 @@ fbjs@^3.0.0: setimmediate "^1.0.5" ua-parser-js "^0.7.18" +fecha@^4.2.0: + version "4.2.3" + resolved "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz#4d9ccdbc61e8629b259fdca67e65891448d569fd" + integrity sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw== + fetch-cookie@0.10.1: version "0.10.1" resolved "https://registry.yarnpkg.com/fetch-cookie/-/fetch-cookie-0.10.1.tgz#5ea88f3d36950543c87997c27ae2aeafb4b5c4d4" @@ -5879,6 +5945,11 @@ flatmap@0.0.3: resolved "https://registry.yarnpkg.com/flatmap/-/flatmap-0.0.3.tgz#1f18a4d938152d495965f9c958d923ab2dd669b4" integrity sha512-OuR+o7kHVe+x9RtIujPay7Uw3bvDZBZFSBXClEphZuSDLmZTqMdclasf4vFSsogC8baDz0eaC2NdO/2dlXHBKQ== +fn.name@1.x.x: + version "1.1.0" + resolved "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc" + integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== + follow-redirects@^1.12.1: version "1.14.8" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.8.tgz#016996fb9a11a100566398b1c6839337d7bfa8fc" @@ -6780,6 +6851,11 @@ htmlparser2@~3.8.1: entities "1.0" readable-stream "1.1" +htmlparser@1.x: + version "1.7.7" + resolved "https://registry.npmjs.org/htmlparser/-/htmlparser-1.7.7.tgz#19e7b3997ff6fbac99ae5a7d2766489efe7e2d0e" + integrity sha512-zpK66ifkT0fauyFh2Mulrq4AqGTucxGtOhZ8OjkbSfcCpkqQEI8qRkY0tSQSJNAQ4HUZkgWaU4fK4EH6SVH9PQ== + http-basic@^8.1.1: version "8.1.3" resolved "https://registry.yarnpkg.com/http-basic/-/http-basic-8.1.3.tgz#a7cabee7526869b9b710136970805b1004261bbf" @@ -7117,7 +7193,7 @@ ipfs-http-client@^34.0.0: bs58 "^4.0.1" buffer "^5.4.2" cids "~0.7.1" - concat-stream "github:hugomrdias/concat-stream#feat/smaller" + concat-stream "^1.6.0" debug "^4.1.0" detect-node "^2.0.4" end-of-stream "^1.4.1" @@ -7250,6 +7326,11 @@ is-arrayish@^0.2.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + is-bigint@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" @@ -7884,6 +7965,18 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== +jsdom@0.2.x: + version "0.2.19" + resolved "https://registry.npmjs.org/jsdom/-/jsdom-0.2.19.tgz#c0811df73901289ea6a0c825c7bb0c09c8c88629" + integrity sha512-wN7SnERzYuz0bfuKnHK1Mbjb2/wt86TTS3SoCMy63EjAhhnFYuoBEUNO3QkDvm9zzPt3Fp+BwdeUX9XjtMuGyA== + dependencies: + cssom "0.2.x" + cssstyle ">=0.2.3" + htmlparser "1.x" + request "2.x" + optionalDependencies: + contextify "0.1.x" + jsdom@^7.0.2: version "7.2.2" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-7.2.2.tgz#40b402770c2bda23469096bee91ab675e3b1fc6e" @@ -8092,6 +8185,11 @@ klaw@^1.0.0: optionalDependencies: graceful-fs "^4.1.9" +kuler@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" + integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A== + ky-universal@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/ky-universal/-/ky-universal-0.2.2.tgz#7a36e1a75641a98f878157463513965f799f5bfe" @@ -8598,6 +8696,18 @@ log-symbols@^3.0.0: dependencies: chalk "^2.4.2" +logform@^2.3.2, logform@^2.4.0: + version "2.5.1" + resolved "https://registry.npmjs.org/logform/-/logform-2.5.1.tgz#44c77c34becd71b3a42a3970c77929e52c6ed48b" + integrity sha512-9FyqAm9o9NKKfiAKfZoYo9bGXXuwMkxQiQttkT4YjjVtQVIQtK6LmVtlxmCaFswo6N4AfEkHqZTV0taDtPotNg== + dependencies: + "@colors/colors" "1.5.0" + "@types/triple-beam" "^1.3.2" + fecha "^4.2.0" + ms "^2.1.1" + safe-stable-stringify "^2.3.1" + triple-beam "^1.3.0" + loglevel@^1.6.7: version "1.7.1" resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197" @@ -9253,6 +9363,11 @@ mute-stream@0.0.8: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== +nan@^2.1.0: + version "2.18.0" + resolved "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz#26a6faae7ffbeb293a39660e88a76b82e30b7554" + integrity sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w== + nan@^2.12.1: version "2.14.2" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" @@ -9694,6 +9809,13 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0: dependencies: wrappy "1" +one-time@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz#e06bc174aed214ed58edede573b433bbf827cb45" + integrity sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g== + dependencies: + fn.name "1.x.x" + onetime@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" @@ -10950,7 +11072,7 @@ readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.4, readable string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^3.0.0, readable-stream@^3.0.1, readable-stream@^3.0.2: +readable-stream@^3.0.0, readable-stream@^3.0.1: version "3.6.2" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== @@ -11153,7 +11275,7 @@ replace-ext@0.0.1: resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924" integrity sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ= -request@2.88.2, request@^2.55.0, request@^2.79.0, request@^2.85.0, request@^2.88.0: +request@2.88.2, request@2.x, request@^2.55.0, request@^2.79.0, request@^2.85.0, request@^2.88.0: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -11322,6 +11444,11 @@ rn-host-detect@^1.1.5: resolved "https://registry.yarnpkg.com/rn-host-detect/-/rn-host-detect-1.2.0.tgz#8b0396fc05631ec60c1cb8789e5070cdb04d0da0" integrity sha512-btNg5kzHcjZZ7t7mvvV/4wNJ9e3MPgrWivkRgWURzXL0JJ0pwWlU4zrbmdlz3HHzHOxhBhHB4D+/dbMFfu4/4A== +rrweb-cssom@^0.6.0: + version "0.6.0" + resolved "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz#ed298055b97cbddcdeb278f904857629dec5e0e1" + integrity sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw== + rsa-pem-to-jwk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/rsa-pem-to-jwk/-/rsa-pem-to-jwk-1.1.3.tgz#245e76bdb7e7234cfee7ca032d31b54c38fab98e" @@ -11366,6 +11493,11 @@ safe-event-emitter@^1.0.1: dependencies: events "^3.0.0" +safe-stable-stringify@^2.3.1: + version "2.4.3" + resolved "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz#138c84b6f6edb3db5f8ef3ef7115b8f55ccbf886" + integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g== + "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" @@ -11648,6 +11780,13 @@ simple-get@^2.7.0: once "^1.3.1" simple-concat "^1.0.0" +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg== + dependencies: + is-arrayish "^0.3.1" + slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" @@ -11831,6 +11970,11 @@ stable@~0.1.8: resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== +stack-trace@0.0.x: + version "0.0.10" + resolved "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" + integrity sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg== + statuses@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" @@ -12230,6 +12374,11 @@ tar@^6.1.0: mkdirp "^1.0.3" yallist "^4.0.0" +text-hex@1.0.x: + version "1.0.0" + resolved "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" + integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg== + then-request@^6.0.0: version "6.0.2" resolved "https://registry.yarnpkg.com/then-request/-/then-request-6.0.2.tgz#ec18dd8b5ca43aaee5cb92f7e4c1630e950d4f0c" @@ -12425,6 +12574,11 @@ trim-right@^1.0.1: resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= +triple-beam@^1.3.0: + version "1.4.1" + resolved "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz#6fde70271dc6e5d73ca0c3b24e2d92afb7441984" + integrity sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg== + truffle@^5.2: version "5.2.3" resolved "https://registry.yarnpkg.com/truffle/-/truffle-5.2.3.tgz#6c1585da56b704397017833ea6b62e18303b924f" @@ -13535,6 +13689,32 @@ window-size@^0.2.0: resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" integrity sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU= +winston-transport@^4.5.0: + version "4.5.0" + resolved "https://registry.npmjs.org/winston-transport/-/winston-transport-4.5.0.tgz#6e7b0dd04d393171ed5e4e4905db265f7ab384fa" + integrity sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q== + dependencies: + logform "^2.3.2" + readable-stream "^3.6.0" + triple-beam "^1.3.0" + +winston@^3.10.0: + version "3.10.0" + resolved "https://registry.npmjs.org/winston/-/winston-3.10.0.tgz#d033cb7bd3ced026fed13bf9d92c55b903116803" + integrity sha512-nT6SIDaE9B7ZRO0u3UvdrimG0HkB7dSTAgInQnNR2SOPJ4bvq5q79+pXLftKmP52lJGW15+H5MCK0nM9D3KB/g== + dependencies: + "@colors/colors" "1.5.0" + "@dabh/diagnostics" "^2.0.2" + async "^3.2.3" + is-stream "^2.0.0" + logform "^2.4.0" + one-time "^1.0.0" + readable-stream "^3.4.0" + safe-stable-stringify "^2.3.1" + stack-trace "0.0.x" + triple-beam "^1.3.0" + winston-transport "^4.5.0" + word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" @@ -13696,6 +13876,11 @@ xhr@^2.0.4, xhr@^2.2.0, xhr@^2.3.3: resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-2.0.1.tgz#4d8b8f1eccd3419aa362061becef515e1e559635" integrity sha1-TYuPHszTQZqjYgYb7O9RXh5VljU= +xmlhttprequest@1.3.x: + version "1.3.0" + resolved "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.3.0.tgz#f6888d76176a9e4217694aa168a02c366e5d454a" + integrity sha512-Ul4hDMW1hOOQsMMJ9jBiAzQ0GUcozhT2O+7bNj+SyJRzz+AxWb3a34zbJGBZ7/G/+ncsdZkG+IRaLxHHa+jQXQ== + xmlhttprequest@1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" diff --git a/tests/tests/integration_tests.rs b/tests/tests/integration_tests.rs index 74fecf942fa..372d81f34c0 100644 --- a/tests/tests/integration_tests.rs +++ b/tests/tests/integration_tests.rs @@ -11,18 +11,13 @@ use anyhow::Context; use futures::{StreamExt, TryStreamExt}; -use graph_tests::docker_utils::{pull_service_images, ServiceContainer, ServiceContainerKind}; use graph_tests::helpers::{ - basename, make_ganache_uri, make_ipfs_uri, make_postgres_uri, pretty_output, GraphNodePorts, - MappedPorts, + basename, pretty_output }; -use std::fs; use std::num::NonZeroUsize; use std::path::{Path, PathBuf}; -use std::sync::Arc; -use std::time::Duration; -use tokio::io::AsyncReadExt; -use tokio::process::{Child, Command}; +use tokio::process::{Command}; +use std::env; /// All directories containing integration tests to run. /// @@ -32,7 +27,7 @@ use tokio::process::{Child, Command}; /// it. pub const INTEGRATION_TEST_DIRS: &[&str] = &[ "api-version-v0-0-4", - "ganache-reverts", + "chain-reverts", "host-exports", "non-fatal-errors", "overloaded-contract-functions", @@ -43,12 +38,12 @@ pub const INTEGRATION_TEST_DIRS: &[&str] = &[ "block-handlers", ]; +const IPFS_URI: &str = "https://ch-ipfs.neontest.xyz"; +const GRAPH_NODE_ADMIN_URI: &str = "https://ch2-graph.neontest.xyz/deploy/"; + #[derive(Debug, Clone)] struct IntegrationTestSettings { n_parallel_tests: u64, - ganache_hard_wait: Duration, - ipfs_hard_wait: Duration, - postgres_hard_wait: Duration, } impl IntegrationTestSettings { @@ -65,16 +60,7 @@ impl IntegrationTestSettings { 2 * std::thread::available_parallelism() .map(NonZeroUsize::get) .unwrap_or(2) as u64, - ), - ganache_hard_wait: Duration::from_secs( - parse_numeric_environment_variable("TESTS_GANACHE_HARD_WAIT_SECONDS").unwrap_or(0), - ), - ipfs_hard_wait: Duration::from_secs( - parse_numeric_environment_variable("TESTS_IPFS_HARD_WAIT_SECONDS").unwrap_or(0), - ), - postgres_hard_wait: Duration::from_secs( - parse_numeric_environment_variable("TESTS_POSTGRES_HARD_WAIT_SECONDS").unwrap_or(0), - ), + ) } } } @@ -83,12 +69,9 @@ impl IntegrationTestSettings { /// integration test. #[derive(Debug)] struct IntegrationTestRecipe { - postgres_uri: String, ipfs_uri: String, - ganache_port: u16, - ganache_uri: String, - graph_node_ports: GraphNodePorts, - graph_node_bin: Arc, + graph_node_uri: String, + subgraph_name: String, test_directory: PathBuf, } @@ -96,10 +79,6 @@ impl IntegrationTestRecipe { fn test_name(&self) -> String { basename(&self.test_directory) } - - fn graph_node_admin_uri(&self) -> String { - format!("http://localhost:{}/", self.graph_node_ports.admin) - } } /// Info about a finished test command @@ -133,7 +112,6 @@ impl std::fmt::Display for Output { struct IntegrationTestSummary { test_recipe: IntegrationTestRecipe, test_command_result: IntegrationTestResult, - graph_node_output: Output, } impl IntegrationTestSummary { @@ -159,9 +137,6 @@ impl IntegrationTestSummary { println!("---------------------------"); println!("{}", self.test_command_result.output); println!("--------------------------"); - println!("graph-node command output:"); - println!("--------------------------"); - println!("{}", self.graph_node_output); } } @@ -185,47 +160,27 @@ async fn parallel_integration_tests() -> anyhow::Result<()> { } tokio::join!( - // Pull the required Docker images. - pull_service_images(), // Run `yarn` command to build workspace. run_yarn_command(&yarn_workspace_dir), ); - println!("Starting PostgreSQL and IPFS containers..."); - - // Not only do we start the containers, but we also need to wait for - // them to be up and running and ready to accept connections. - let (postgres, ipfs) = tokio::try_join!( - ServiceDependency::start( - ServiceContainerKind::Postgres, - "database system is ready to accept connections", - test_settings.postgres_hard_wait - ), - ServiceDependency::start( - ServiceContainerKind::Ipfs, - "Daemon is ready", - test_settings.ipfs_hard_wait - ), - )?; - println!( - "Containers are ready! Running tests with N_CONCURRENT_TESTS={} ...", + "Running tests with N_CONCURRENT_TESTS={} ...", test_settings.n_parallel_tests ); - let graph_node = Arc::new( - fs::canonicalize("../target/debug/graph-node") - .context("failed to infer `graph-node` program location. (Was it built already?)")?, - ); - let stream = tokio_stream::iter(test_dirs) .map(|dir| { + let unique_part = match env::var_os("SUBGRAPH_NAME") { + Some(v) => v.into_string().unwrap(), + None => panic!("$SUBGRAPH_NAME is not set") + }; + let name = [basename(&dir), unique_part.to_string()].join("-"); run_integration_test( dir, - postgres.clone(), - ipfs.clone(), - graph_node.clone(), - test_settings.ganache_hard_wait, + IPFS_URI.to_string(), + GRAPH_NODE_ADMIN_URI.to_string(), + name, ) }) .buffered(test_settings.n_parallel_tests as usize); @@ -234,21 +189,6 @@ async fn parallel_integration_tests() -> anyhow::Result<()> { let failed = test_results.iter().any(|r| !r.test_command_result.success); // All tests have finished; we don't need the containers anymore. - tokio::try_join!( - async { - postgres - .container - .stop() - .await - .context("failed to stop container with Postgres") - }, - async { - ipfs.container - .stop() - .await - .context("failed to stop container with IPFS") - }, - )?; // print failures for failed_test in test_results @@ -271,115 +211,27 @@ async fn parallel_integration_tests() -> anyhow::Result<()> { } } -#[derive(Clone)] -struct ServiceDependency { - container: Arc, - ports: Arc, -} - -impl ServiceDependency { - async fn start( - service: ServiceContainerKind, - wait_msg: &str, - hard_wait: Duration, - ) -> anyhow::Result { - let service = ServiceContainer::start(service).await.context(format!( - "Failed to start container service `{}`", - service.name() - ))?; - - service - .wait_for_message(wait_msg.as_bytes(), hard_wait) - .await - .context(format!( - "failed to wait for {} container to be ready to accept connections", - service.container_name() - ))?; - - let ports = service.exposed_ports().await.context(format!( - "failed to obtain exposed ports for the `{}` container", - service.container_name() - ))?; - - Ok(Self { - container: Arc::new(service), - ports: Arc::new(ports), - }) - } -} - /// Prepare and run the integration test async fn run_integration_test( test_directory: PathBuf, - postgres: ServiceDependency, - ipfs: ServiceDependency, - graph_node_bin: Arc, - ganache_hard_wait: Duration, + ipfs_uri: String, + graph_node_uri: String, + subgraph_name: String, ) -> anyhow::Result { - let db_name = - format!("{}-{}", basename(&test_directory), uuid::Uuid::new_v4()).replace('-', "_"); - - let (ganache, _) = tokio::try_join!( - // Start a dedicated Ganache container for this test. - async { - ServiceDependency::start( - ServiceContainerKind::Ganache, - "Listening on ", - ganache_hard_wait, - ) - .await - .context("failed to start Ganache container") - }, - // PostgreSQL is up and running, but we still need to create the database. - async { - ServiceContainer::create_postgres_database(&postgres.container, &db_name) - .await - .context("failed to create the test database.") - } - )?; - - // Build URIs. - let postgres_uri = { make_postgres_uri(&db_name, &postgres.ports) }; - let ipfs_uri = make_ipfs_uri(&ipfs.ports); - let (ganache_port, ganache_uri) = make_ganache_uri(&ganache.ports); let test_recipe = IntegrationTestRecipe { - postgres_uri, ipfs_uri, - ganache_uri, - ganache_port, - graph_node_bin, - graph_node_ports: GraphNodePorts::random_free(), + graph_node_uri, + subgraph_name, test_directory, }; - // Spawn graph-node. - let mut graph_node_child_command = run_graph_node(&test_recipe)?; - println!("Test started: {}", basename(&test_recipe.test_directory)); let result = run_test_command(&test_recipe).await?; - let (graph_node_output, _) = tokio::try_join!( - async { - // Stop graph-node and read its output. - stop_graph_node(&mut graph_node_child_command) - .await - .context("failed to stop graph-node") - }, - async { - // Stop Ganache. - ganache - .container - .stop() - .await - .context("failed to stop container service for Ganache") - } - )?; - Ok(IntegrationTestSummary { test_recipe, test_command_result: result, - graph_node_output, }) } @@ -388,18 +240,10 @@ async fn run_test_command( test_recipe: &IntegrationTestRecipe, ) -> anyhow::Result { let output = Command::new("yarn") - .arg("test") - .env("GANACHE_TEST_PORT", test_recipe.ganache_port.to_string()) - .env("GRAPH_NODE_ADMIN_URI", test_recipe.graph_node_admin_uri()) - .env( - "GRAPH_NODE_HTTP_PORT", - test_recipe.graph_node_ports.http.to_string(), - ) - .env( - "GRAPH_NODE_INDEX_PORT", - test_recipe.graph_node_ports.index.to_string(), - ) + .arg("neon") + .env("GRAPH_NODE_ADMIN_URI", &test_recipe.graph_node_uri) .env("IPFS_URI", &test_recipe.ipfs_uri) + .env("SUBGRAPH_NAME", &test_recipe.subgraph_name) .current_dir(&test_recipe.test_directory) .output() .await @@ -419,68 +263,13 @@ async fn run_test_command( }) } -fn run_graph_node(recipe: &IntegrationTestRecipe) -> anyhow::Result { - use std::process::Stdio; - - let mut command = Command::new(recipe.graph_node_bin.as_os_str()); - command - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .arg("--postgres-url") - .arg(&recipe.postgres_uri) - .arg("--ethereum-rpc") - .arg(&recipe.ganache_uri) - .arg("--ipfs") - .arg(&recipe.ipfs_uri) - .arg("--http-port") - .arg(recipe.graph_node_ports.http.to_string()) - .arg("--index-node-port") - .arg(recipe.graph_node_ports.index.to_string()) - .arg("--ws-port") - .arg(recipe.graph_node_ports.ws.to_string()) - .arg("--admin-port") - .arg(recipe.graph_node_ports.admin.to_string()) - .arg("--metrics-port") - .arg(recipe.graph_node_ports.metrics.to_string()); - - command - .spawn() - .context("failed to start graph-node command.") -} - -async fn stop_graph_node(child: &mut Child) -> anyhow::Result { - child.kill().await.context("Failed to kill graph-node")?; - - // capture stdio - let stdout = match child.stdout.take() { - Some(mut data) => Some(process_stdio(&mut data, "[graph-node:stdout] ").await?), - None => None, - }; - let stderr = match child.stderr.take() { - Some(mut data) => Some(process_stdio(&mut data, "[graph-node:stderr] ").await?), - None => None, - }; - - Ok(Output { stdout, stderr }) -} - -async fn process_stdio( - stdio: &mut T, - prefix: &str, -) -> anyhow::Result { - let mut buffer: Vec = Vec::new(); - stdio - .read_to_end(&mut buffer) - .await - .context("failed to read stdio")?; - Ok(pretty_output(&buffer, prefix)) -} - /// run yarn to build everything async fn run_yarn_command(base_directory: &impl AsRef) { let timer = std::time::Instant::now(); println!("Running `yarn` command in integration tests root directory."); let output = Command::new("yarn") + .arg("install") + .arg("--frozen-lockfile") .current_dir(base_directory) .output() .await