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

stabilize tests #2561

Merged
merged 11 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/actions/get_exclude_dirs/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ runs:
examples/experimental/test/end_to_end/http_server/http_outcall_fetch
examples/experimental/test/end_to_end/http_server/ic_evm_rpc
examples/experimental/test/end_to_end/http_server/multi_deploy
examples/experimental/test/property/candid_rpc/opt
examples/experimental/test/property/candid_rpc/stable_b_tree_map
') }}"

SLOW_EXCLUSIONS="${{ format('
Expand All @@ -49,7 +51,6 @@ runs:
examples/experimental/test/end_to_end/http_server/autoreload
examples/experimental/test/end_to_end/http_server/large_files
examples/experimental/test/end_to_end/http_server/open_value_sharing
examples/experimental/test/property/candid_rpc/stable_b_tree_map
') }}"

EXCLUDE_DIRS=""
Expand Down
50 changes: 50 additions & 0 deletions .github/actions/retry_command/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: 'Command with retries'
description: 'Run any command with exponential backoff retries'

inputs:
command:
description: 'Command to execute'
required: true
working-directory:
description: 'Directory where to run the command'
required: false
default: '.'
max-attempts:
description: 'Maximum number of retry attempts'
required: false
default: '5'
initial-delay:
description: 'Initial delay in seconds before first retry'
required: false
default: '1'
max-delay:
description: 'Maximum delay in seconds between retries'
required: false
default: '60'

runs:
using: 'composite'
steps:
- shell: bash
run: |
attempt=1
max_attempts=${{ inputs.max-attempts }}
delay=${{ inputs.initial-delay }}
max_delay=${{ inputs.max-delay }}

until cd ${{ inputs.working-directory }} && ${{ inputs.command }}; do
if [ $attempt -ge $max_attempts ]; then
echo "Command failed after $attempt attempts"
exit 1
fi

attempt=$(($attempt + 1))
echo "Command failed, retrying in $delay seconds... (attempt $attempt/$max_attempts)"
sleep $delay

# Exponential backoff with a configurable maximum
delay=$(( delay * 2 ))
if [ $delay -gt $max_delay ]; then
delay=$max_delay
fi
done
5 changes: 3 additions & 2 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,9 @@ jobs:

- uses: ./.github/actions/setup_dfx

- name: Install dependencies
run: npm install
- uses: ./.github/actions/retry_command
with:
command: 'npm install'

- name: Analyze benchmarks
run: npx tsx scripts/analyze_benchmarks/index.ts
Expand Down
11 changes: 8 additions & 3 deletions .github/workflows/benchmark_parallel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,16 @@ jobs:

- uses: ./.github/actions/setup_dfx

- run: npm install
- uses: ./.github/actions/retry_command
with:
command: 'npm install'

- run: npm link

- run: npm install
working-directory: ${{ matrix.test.path }}
- uses: ./.github/actions/retry_command
with:
command: 'npm install'
working-directory: ${{ matrix.test.path }}

- run: npm link azle
working-directory: ${{ matrix.test.path }}
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/build_templates.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ jobs:

- uses: ./.github/actions/setup_dfx

- run: npm install
- uses: ./.github/actions/retry_command
with:
command: 'npm install'

- name: Install global dependencies
run: |
Expand Down
12 changes: 7 additions & 5 deletions .github/workflows/maintenance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ jobs:

- uses: ./.github/actions/setup_dfx

- run: npm install
- uses: ./.github/actions/retry_command
with:
command: 'npm install'

# Run global prettier/lint fixes
- name: Run Prettier
Expand Down Expand Up @@ -99,10 +101,10 @@ jobs:

# Update package-lock.json in test directory
- name: Update package-lock.json
working-directory: ${{ matrix.test.path }}
run: |
rm -f package-lock.json
npm install
uses: ./.github/actions/retry_command
with:
command: 'npm install'
working-directory: ${{ matrix.test.path }}

- name: Create branch name
id: create-branch-name
Expand Down
21 changes: 15 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,23 @@ jobs:

- uses: ./.github/actions/setup_dfx

- run: npm install
- uses: ./.github/actions/retry_command
with:
command: 'npm install'

- name: Install global dependencies
run: |
AZLE_VERBOSE=true npx azle install-global-dependencies --rust --wasi2ic

- name: Update version and build templates
- name: Update version
run: |
VERSION=${{ inputs.release-version }}
sed -E -i "s/(\"version\": \")(.*)(\")/\1$VERSION\3/" package.json
sed -E -i "s/(\"version\": \")(.*)(\")/\1$VERSION\3/" dfx_extension/extension.json
npm install

- uses: ./.github/actions/retry_command
with:
command: 'npm install'

- name: Build stable template
run: npx azle template
Expand Down Expand Up @@ -105,15 +110,19 @@ jobs:

- uses: ./.github/actions/setup_dfx

- run: npm install
- uses: ./.github/actions/retry_command
with:
command: 'npm install'

- name: Update azle version
working-directory: ${{ matrix.test.path }}
run: |
sed -E -i "s/(\"azle\": \")(.*)(\")/\1${{ inputs.release-version }}\3/" package.json

- run: npm install
working-directory: ${{ matrix.test.path }}
- uses: ./.github/actions/retry_command
with:
command: 'npm install'
working-directory: ${{ matrix.test.path }}

- name: Start dfx with artificial delay 0
working-directory: ${{ matrix.test.path }}
Expand Down
10 changes: 7 additions & 3 deletions .github/workflows/run_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,19 @@ jobs:
if: matrix.os == 'macos-latest'
run: sudo networksetup -setdnsservers Ethernet 9.9.9.9

- run: npm install
- uses: ./.github/actions/retry_command
with:
command: 'npm install'

- run: npm link
if: matrix.azle_source == 'repo'

- run: npm run lint

- run: npm install
working-directory: ${{ matrix.test.path }}
- uses: ./.github/actions/retry_command
with:
command: 'npm install'
working-directory: ${{ matrix.test.path }}

- run: npm link azle
if: matrix.azle_source == 'repo'
Expand Down
10 changes: 10 additions & 0 deletions src/lib/stable/stable_structures/stable_json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ export const stableJson = StableJson();
* @returns The converted value safe for JSON string serialization
*/
export function jsonReplacer(_key: string, value: any): any {
if (typeof value === 'undefined') {
return {
__undefined__: '__undefined__'
};
}

if (typeof value === 'bigint') {
return {
__bigint__: value.toString()
Expand Down Expand Up @@ -153,6 +159,10 @@ export function jsonReplacer(_key: string, value: any): any {
*/
export function jsonReviver(_key: string, value: any): any {
if (typeof value === 'object' && value !== null) {
if (typeof value.__undefined__ === 'string') {
return undefined;
}

if (typeof value.__bigint__ === 'string') {
return BigInt(value.__bigint__);
}
Expand Down
14 changes: 0 additions & 14 deletions test/property/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import './set_experimental';

import { execSync } from 'child_process';
// @ts-ignore
import libraryDeepEqual from 'deep-is';
import fc from 'fast-check';
import { existsSync, mkdirSync, writeFileSync } from 'fs';

Expand Down Expand Up @@ -132,15 +130,3 @@ export const shortArrayConstraints = {
minLength: 5,
maxLength: 20
};

export function deepEqual(a: any, b: any): boolean {
const result = libraryDeepEqual(a, b);

if (result === false) {
console.info('deepEqual returned false');
console.info('deepEqual value a', a);
console.info('deepEqual value b', b);
}

return result;
}
13 changes: 9 additions & 4 deletions test/property/test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,17 @@ export async function runTests(
// TODO is is better test framework conformity to call this assertEqual? I'll hold off for now, it should be easy to search for all testEquality and change it, easier than assertEqual I think
// TODO so based on this I think I've actually seen this in other testing frameworks, assertEquals will take two and make sure they are equals, and assert will take one boolean. Right now we have test instead of assert but it would be easy to change
export function testEquality<T = any>(actual: T, expected: T): AzleResult {
if (deepEqual(actual, expected)) {
// We have historically had issues with various deepEqual implementations most tracing back to subtle differences in versions etc that have caused false negatives.
// Our jsonStringify takes out a lot of the possible oddities by serializing them into a more standard format.
// So until we convert this to jest and use it's various equality functions, this should be good enough.
const actualJsonString = jsonStringify(actual);
const expectedJsonString = jsonStringify(expected);
const actualJson = JSON.parse(actualJsonString);
const expectedJson = JSON.parse(expectedJsonString);
if (deepEqual(actualJson, expectedJson)) {
return { Ok: { isSuccessful: true } };
} else {
const message = `Expected: ${jsonStringify(
expected
)}, Received: ${jsonStringify(actual)}`;
const message = `Expected: ${expectedJson}, Received: ${actualJson}`;
return { Ok: { isSuccessful: false, message } };
}
}
Expand Down
Loading