Skip to content
This repository has been archived by the owner on Sep 14, 2023. It is now read-only.

feat: add extrinsic integration test #211

Merged
merged 12 commits into from
Sep 16, 2022
Merged

Conversation

kratico
Copy link
Contributor

@kratico kratico commented Sep 7, 2022

Description

Add a simple extrinsic integration test that depends on the polkadot binary.

The polkadot binary is copied from the polkadot docker image.

How Has This Been Tested?

  • validate that the test workflow action has run the effect/extrinsic.test.ts test
  • check the test workflow logs to validate that the polkadot node was started during the test

image

@kratico kratico added the WIP label Sep 7, 2022

await ctx.step({
name: "account balance",
ignore: true,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've disabled this step because I'm getting the following error

  account balance ... FAILED (5ms)
    error: InvalidStateError: readyState not OPEN
              ws.send(JSON.stringify(egressMessage));
                 ^
        at WebSocket.send (deno:ext/websocket/01_websocket.js:288:15)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very interesting –– seems I have some reproducing to do :)

Comment on lines 14 to 15
docker run -d --entrypoint /bin/sh --rm -it --name tmp parity/polkadot:latest
docker cp tmp:/usr/bin/polkadot /usr/local/bin
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The polkadot docker image is ubuntu based so it seems to be compatible with the GH workflow runner.

Perhaps there is a better alternative to get the polkadot binary 🤔

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pepoviola any recommendation? Should we include a runner-compatible Polkadot bin in the Capi repo? Any thoughts would be greatly appreciated.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @harrysolovay / @kratico, getting the binary from the latest image is a nice way to get the binary. Other way is to download the binary from the polkadot repo, as we do in the setup command in zombienet ( https://github.com/paritytech/zombienet/blob/main/src/cli.ts#L120-L141).

Looking forward, we have the task to create a zombienet action to publish to the marketplace, then you will be able to just use the action and receive a json with the network info (relaychain validators and parachains).
Thanks!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the input @pepoviola –– will look forward to that action! :)

// For some reason, logs come in through `stderr`
console.log(blue(`Piping node logs:`));

const encoder = new TextDecoder();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The initialization cost of TextDecoders is quite low. Imo not worth the overhead of a const definition.

@kratico kratico removed the WIP label Sep 8, 2022
@kratico kratico marked this pull request as draft September 8, 2022 11:47
@kratico kratico force-pushed the feat/extrinsic-integration-test branch from 596dbe1 to 3bfbc5b Compare September 8, 2022 14:42
Comment on lines +14 to +15
curl -L -o /usr/local/bin/polkadot https://github.com/paritytech/polkadot/releases/download/v0.9.28/polkadot
chmod +x /usr/local/bin/polkadot
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀 Thanks for the tip @pepoviola

@kratico kratico marked this pull request as ready for review September 12, 2022 12:05
@@ -0,0 +1,72 @@
import { assertEquals, assertObjectMatch } from "../deps/std/testing/asserts.ts";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@harrysolovay Do you have a suggestion for this file location/name?

It seems to be more an integration test than a unit test.
Perhaps it would be better to create a new folder ./e2e-test/.. in the project root.

Thoughts?

@kratico kratico force-pushed the feat/extrinsic-integration-test branch from 3ac7195 to 70413e7 Compare September 12, 2022 15:48
while (!isPortAvailable(port)) {
port++;
}
port = getRandomPort();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@harrysolovay added a random port so it's less likely to have the race condition in parallel tests

port,
() => {
process.kill("SIGKILL");
process.close();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.close releases Deno’s memory associated with the process but it doesn't .kill the process

@kratico kratico force-pushed the feat/extrinsic-integration-test branch from 70413e7 to f35116f Compare September 13, 2022 19:05
@@ -65,6 +65,7 @@ export const { run } = (new class Runtime implements RunContext {
if (val.exit) {
const applied = () => val.exit!(resolved);
cleanup.set(val, applied);
this.#cache.delete(k);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@harrysolovay perhaps this is fixed in your refactor.
This removes the RpcClient atom from the cache because it has an exit fn.

Is the following statement correct?
Atoms that have been cleaned up should no longer be cached

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of this will change considerably in the next few days. Will look forward to syncing about this with you & @jainkrati.

@kratico kratico force-pushed the feat/extrinsic-integration-test branch 2 times, most recently from d1ab1ce to 8a5d306 Compare September 13, 2022 20:48
@kratico kratico force-pushed the feat/extrinsic-integration-test branch from 8a5d306 to c471549 Compare September 13, 2022 20:50
Copy link
Contributor

@harrysolovay harrysolovay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking pretty good! Two thoughts:

  • Might be good to add some comments + related issues for anything that is temporary (such as the semi-thread-safe means of getting an open port)
  • The isPortAvailable also calls close without actually killing the process (thank you for pointing out this issue). Can you please sig-kill it as well?

},
});

await U.throwIfError(await root.run());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to await U.throwIf...

extrinsicEvents.push("inBlock");
} else if (event.params.result.finalized) {
extrinsicEvents.push("finalized");
stop();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it not implicitly stop?

Copy link
Contributor Author

@kratico kratico Sep 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I double checked it and the stop() needs to be called explicitly or await root.run() will not resolve/reject.

Is there an extrinsic event that signals that there will be no more events?

if so, sendAndWatchExtrinsic could implicitly call stop

import * as C from "../mod.ts";
import * as t from "../test-util/mod.ts";
import * as U from "../util/mod.ts";
import { SendAndWatchExtrinsicProps } from "./mod.ts";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can delete this line and then access SendAndWatchExtrinsicProps from the namespace below:

async function collectExtrinsicEvents(
  { config, palletName, methodName, args }: Pick<
-   SendAndWatchExtrinsicProps,
+   C.SendAndWatchExtrinsicProps,

},
});

async function collectExtrinsicEvents(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an awesome utility. Mentioning in #215.

test-util/config.ts Outdated Show resolved Hide resolved
test-util/config.ts Outdated Show resolved Hide resolved
return randomPort;
}

interface WaitForPortOptions {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These options don't seem to be supplied to the waitForPort call. Any reason to keep this declaration and the optional param on 107?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right.
These options can be re-added when needed, so I'll remove them.

@kratico
Copy link
Contributor Author

kratico commented Sep 14, 2022

@harrysolovay

  • Might be good to add some comments + related issues for anything that is temporary (such as the semi-thread-safe means of getting an open port)

Will do

  • The isPortAvailable also calls close without actually killing the process (thank you for pointing out this issue). Can you please sig-kill it as well?

The .close in isPortAvailable is for closing a Deno.listener not a Deno.Process.
Searched for related issues and it seems that .close is enough to free up listener resources.

Copy link
Contributor

@harrysolovay harrysolovay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM –– please add any lessons / areas for improvement to #215

@kratico kratico merged commit 0b29d5c into main Sep 16, 2022
@kratico kratico deleted the feat/extrinsic-integration-test branch September 16, 2022 12:12
harrysolovay added a commit that referenced this pull request Oct 19, 2022
* feat: add extrinsic transfer test

* ci: add polkadot binary to test workflow

* chore: initialize text encoder insider the for loop

* ci: download polkadot from github releases

* revert: test-util/config.ts white spacing

* feat: add polkadot process gracefull kill/close

* feat: add random port to launch polkadot in tests

* feat: add waitForPort to launch polkadot in tests

* feat: add collectExtrinsicEvents helper

* fix: runtime cache on cleanup

* Apply suggestions from code review

Co-authored-by: Harry Solovay <[email protected]>

* Apply suggestions from code review

Co-authored-by: Harry Solovay <[email protected]>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants