Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DRAFT] Stateful testing setup #67

Draft
wants to merge 23 commits into
base: main
Choose a base branch
from

Conversation

moodmosaic
Copy link

This is the skeleton to be used primarily for writing all stateful BNS-V2 tests. See each commit for details.

@BowTiedRadone BowTiedRadone force-pushed the stateful-tests branch 2 times, most recently from 633bf6e to c4977c9 Compare July 16, 2024 10:55
@Patotking12
Copy link
Collaborator

Hey guys! Thanks for this! This is huge and hopefully will take BNS to the limit, please let me know if you need anything

@moodmosaic
Copy link
Author

Hey @Patotking12, thanks! 👍 Given the number of invariant cases, you're more than welcome to add some of them.

Feel free to add invariants like @BowTiedRadone is doing here.

Keep each commit simple, adding just one invariant if possible. Avoid helper functions until you see the rule of three and need to refactor. From PoX-4, we learned to start with simple commits and make things more DRY later.

If you have any questions, we're happy to help. Thank you 🙏

moodmosaic and others added 10 commits July 18, 2024 12:30
To get started, it can be a good idea to write a simple (ice-breaker)
test, because there's always a little work involved in getting
everything up and running.

This can help us get things going next.

I first learned about this term in
https://blog.ploeh.dk/2013/03/11/auto-mocking-container/.
This test sets up invariants with GetLastTokenId and runs a stateful
property-based test. This helps check the correctness of BNS-V2
interactions.

This is our first stateful test to ensure everything works.

---

Sample output:

npx vitest run tests/BNS-V2.stateful.test.ts

 RUN  v1.5.0

using existing deployment plan

stdout | tests/BNS-V2.stateful.test.ts > executes BNS-V2 state interactions
Ӿ tx-sender  wallet_7     ✓                      get-last-token-id      0
Ӿ tx-sender  wallet_6     ✓                      get-last-token-id      0
Ӿ tx-sender  wallet_1     ✓                      get-last-token-id      0
Ӿ tx-sender  wallet_8     ✓                      get-last-token-id      0
Ӿ tx-sender  wallet_1     ✓                      get-last-token-id      0
Ӿ tx-sender  wallet_8     ✓                      get-last-token-id      0

 ✓ tests/BNS-V2.stateful.test.ts (1) 1684ms
   ✓ executes BNS-V2 state interactions 1682ms

 Test Files  1 passed (1)
      Tests  1 passed (1)
   Start at  17:27:32
   Duration  5.30s (transform 150ms, setup 108ms, collect 242ms, tests 1.68s)
This commit:
- Adds the GetOwnerNone invariant to the stateful testing. This checks that get-owner always returns none when the passed token ID is not yet minted.
- Adds the owners map to the model.
- Adds the newly generated invariant to the invariants list.
This commit:
- Adds the GetBnsFromIdNone invariant to the stateful testing. This checks that get-bns-from-id always returns none when the passed token ID is not yet minted.
- Adds the indexToName map, along with the Name type to the model.
- Adds the newly generated invariant to the invariants list.
This commit:
- Adds the GetPrimaryNameNone invariant to the stateful testing. This checks that get-primary-name always returns none if the checked address does not own any BNS.
- Adds the newly generated invariant to the invariants list.
This commit:
- Adds the GetNamespacePropertiesErr invariant to the stateful testing. This checks that get-namespace-properties always returns error 113 - ERR_NAMESPACE_NOT_FOUND if the namespace is not registered in the contract.
- Adds the namespaces map to the model.
- Adds the NamespaceProperties type
- Adds the newly generated invariant to the invariants list.
- Increases the columnWidth to 30 inside prettyConsoleLog for better logging readability.
This commit:
- Adds the GetNamespacePrice invariant. This checks that the namespace price based on its length is the right one, according to the NAMESPACE-PRICE-TIERS map from the contract.
- Adds the newly generated invariant to the invariants list.
This commit:
- Adds the CanNamespaceBeRegisteredTrue invariant. This checks that can-namespace-be-registered always returns (ok true) when namespace is not yet registered or its launchability period has passed since its reveal.
- Adds the burnBlockHeight to the model.
- Adds the newly generated invariant to the invariants list.
This commit:
- Adds the NamespacePreorder invariant. This calls the namespace-preorder function successfully.
- Adds the namespacePreorders and namespaceSinglePreorder maps to the model.
- Adds the newly generated invariant to the invariants list.
BowTiedRadone and others added 10 commits July 19, 2024 17:57
This commit:
- Adds the NamespaceReveal invariant. This calls the namespace-reveal function successfully.
- Updates types, making them compatible with the newly added invariant
- Adds the newly generated invariant to the invariants list.
This commit:
- Adds the GetIdFromBnsNone invariant.
- Adds the nameToIndex type to the model, which represents the local copy of the Clarity map name-to-index.
This commit:
- Adds the GetBnsInfoNone invariant to the stateful testing.
- Adds the nameProperties type to the model, which represents the local copy of the name-properties Clarity map.
This commit adds checks inside NamespaceReveal and CanNamespaceBeRegistered invariants. The checks are meant to verify the ustxBurned and the BNS contract TTLs.
This commit adds:
- the MngNamePreorder invariant, which successfully preorders a name, passing the hashed and salted fully-qualified name.
- the namePreorders and nameSInglePreorder maps to the model
This commit:
- Adds the weight logic to the invariant picking process.
- Increases the MngNamePreorder invariant's weight.
@@ -52,12 +52,12 @@ it("executes BNS-V2 state interactions", async () => {

fc.assert(
fc.property(
fc.array(fc.oneof(...invariants), { size: "+1" }),
fc.array(fc.oneof(...invariants), { size: "medium" }),
Copy link
Author

Choose a reason for hiding this comment

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

This size and number of runs below are an approximation, right?

}),
{ numRuns: 10000, verbose: fc.VerbosityLevel.VeryVerbose }
fc.property(
fc.array(fc.oneof(...invariants), { size: "+1" }),
Copy link
Author

Choose a reason for hiding this comment

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

Nice 👍 We should always use fc.array/fc.oneof instead of fc.commands. Explicit is better than implicit.

Using "--reporter=dot" when running the stateful tests will print logs live using this implementation.
This commit:
- Fixes the NamespaceReveal's check method. The previously malformed condition was preventing the invariant from being executed.
- Uses the wallet instead of the address for logging, assuring better readability.
This commit:
- Adds the NamespaceLaunch invariant to the stateful testing environment.
- Increases the probability of calling the NamespaceReveal invariant. This action results in increasing the frequency of NamespaceLaunch calls.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants