microsoft/qdk

Public

mirrored from https://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
logo

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

.github/workflows/fuzz.yml

226lines · modeblame

589390eaRobin Kuzmin3 years ago1name: fuzz
2run-name: Fuzz
3env:
e7bd0d97Stefan J. Wernli9 months ago4OWNER_RDPATH: ./source # Rel path to the dir that contains the fuzzing infra (contains "fuzz" dir).
5DURATION_SEC: 7200 # Fuzzing run duration in seconds.
6STDERR_LOG_FNAME: fuzz.stderr.log # File name to redirect the fuzzing run's stderr to.
7TMIN_LOG_FNAME: fuzz.tmin.log # File name to redirect the fuzzing input minimization log to.
8GH_ISSUE_TEMPLATE_RFPATH:
9.github/ISSUE_TEMPLATE/fuzz_bug_report.md
10# GitHub issue template rel file path.
11ARTIFACTS_RDPATH: fuzz/artifacts # Fuzzing artifacts rel dir path.
12SEEDS_RDPATH: fuzz/seed_inputs # Fuzzing seed inputs rel dir path.
13SEEDS_FNAME: list.txt # Fuzzing seed inputs list file name.
589390eaRobin Kuzmin3 years ago14on:
e7bd0d97Stefan J. Wernli9 months ago15workflow_dispatch: # Manual runs.
5c010e21Stefan J. Wernli3 years ago16push:
17branches:
e7bd0d97Stefan J. Wernli9 months ago18- main # Development runs against main branch.
5c010e21Stefan J. Wernli3 years ago19paths:
e7bd0d97Stefan J. Wernli9 months ago20- "source/compiler/**" # Run if the compiler was changed.
21- "source/fuzz/**" # Run if the fuzzing infra was changed.
22- ".github/ISSUE_TEMPLATE/fuzz_bug_report.md"
23# Run if the GitHub issue template was changed.
24- ".github/workflows/fuzz.yml" # Run if the workflow itself was changed.
25- "!source/compiler/qsc_eval/**" # Exclude the qsc_eval dir.
26- "!source/compiler/qsc_codegen/**" # Exclude the qsc_codegen dir.
589390eaRobin Kuzmin3 years ago27
28jobs:
29fuzz:
30name: Fuzzing
31strategy:
8d7ffb4fIan Davis1 years ago32fail-fast: false
589390eaRobin Kuzmin3 years ago33matrix:
e7bd0d97Stefan J. Wernli9 months ago34os:
35[ubuntu-latest] # Fuzzing is not supported on Win. The macos is temporarily removed
36# because of low availability.
8d7ffb4fIan Davis1 years ago37target_name: [qsharp, qasm]
589390eaRobin Kuzmin3 years ago38
8d7ffb4fIan Davis1 years ago39runs-on: ${{ matrix.os }}
40permissions:
41issues: write
589390eaRobin Kuzmin3 years ago42steps:
43- name: Install and Configure Tools
44run: |
45rustup install nightly # Install nightly toolchain.
46rustup default nightly # Make nightly toolchain default.
47cargo install cargo-fuzz # Install cargo-fuzz (fuzzing tool).
48
49- name: Checkout the Repo
9831093dSalman Chishti8 months ago50uses: actions/checkout@v6
589390eaRobin Kuzmin3 years ago51with:
52submodules: "true"
53
54- name: Gather the Seed Inputs
8d7ffb4fIan Davis1 years ago55if: matrix.target_name == 'qsharp'
7b3bd426Scott Carda1 years ago56working-directory: ${{ env.OWNER_RDPATH }}
589390eaRobin Kuzmin3 years ago57run: |
58# Clone the submodules of QDK:
59REPOS="Quantum Quantum-NC QuantumKatas QuantumLibraries iqsharp qdk-python qsharp-compiler qsharp-runtime"
60for REPO in $REPOS ; do
61git clone --depth 1 --single-branch --no-tags --recurse-submodules --shallow-submodules --jobs 4 \
8d7ffb4fIan Davis1 years ago62https://github.com/microsoft/$REPO.git $SEEDS_RDPATH/${{ matrix.target_name }}/$REPO
589390eaRobin Kuzmin3 years ago63done
64
65# Build a comma-separated list of all the .qs files in $SEEDS_FNAME file:
8d7ffb4fIan Davis1 years ago66find $SEEDS_RDPATH/${{ matrix.target_name }} -name "*.qs" | tr "\n" "," > \
67$SEEDS_RDPATH/${{ matrix.target_name }}/$SEEDS_FNAME
589390eaRobin Kuzmin3 years ago68
8446d5c5Ian Davis1 years ago69- name: Gather the Seed Inputs (qasm)
70if: matrix.target_name == 'qasm'
7b3bd426Scott Carda1 years ago71working-directory: ${{ env.OWNER_RDPATH }}
8446d5c5Ian Davis1 years ago72run: |
73# Clone openqasm repo for samples:
74git clone --depth 1 --single-branch --no-tags --recurse-submodules --shallow-submodules --jobs 4 \
75https://github.com/openqasm/openqasm.git $SEEDS_RDPATH/${{ matrix.target_name }}/openqasm
76
77
78# Build a comma-separated list of all the .qasm and .inc files in $SEEDS_FNAME file:
79find $SEEDS_RDPATH/${{ matrix.target_name }} -name "*.qasm" | tr "\n" "," > \
80$SEEDS_RDPATH/${{ matrix.target_name }}/$SEEDS_FNAME
81find $SEEDS_RDPATH/${{ matrix.target_name }} -name "*.inc" | tr "\n" "," > \
82$SEEDS_RDPATH/${{ matrix.target_name }}/$SEEDS_FNAME
83
589390eaRobin Kuzmin3 years ago84- name: Build and Run the Fuzz Target
7b3bd426Scott Carda1 years ago85working-directory: ${{ env.OWNER_RDPATH }}
589390eaRobin Kuzmin3 years ago86run: |
7b3bd426Scott Carda1 years ago87cargo fuzz build --fuzz-dir ./fuzz --release --sanitizer=none --features do_fuzz ${{ matrix.target_name }} # Build the fuzz target.
589390eaRobin Kuzmin3 years ago88
89# Run fuzzing for specified number of seconds and redirect the `stderr` to a file
90# whose name is specified by the STDERR_LOG_FNAME env var:
7b3bd426Scott Carda1 years ago91RUST_BACKTRACE=1 cargo fuzz run --fuzz-dir ./fuzz --release --sanitizer=none --features do_fuzz ${{ matrix.target_name }} -- \
8d7ffb4fIan Davis1 years ago92-seed_inputs=@$SEEDS_RDPATH/${{ matrix.target_name }}/$SEEDS_FNAME \
589390eaRobin Kuzmin3 years ago93-max_total_time=$DURATION_SEC \
94-rss_limit_mb=4096 \
f0a682a2Stefan J. Wernli3 years ago95-max_len=20000 \
589390eaRobin Kuzmin3 years ago962>$STDERR_LOG_FNAME
97# The `-rss_limit_mb` and `-max_len` work around running out of memory.
98
99- name: "If Fuzzing Failed: Collect Failure Info"
100if: failure()
7b3bd426Scott Carda1 years ago101working-directory: ${{ env.OWNER_RDPATH }}
589390eaRobin Kuzmin3 years ago102run: |
103# Extract from stderr log the panic message:
104PANIC_MESSAGE=`cat $STDERR_LOG_FNAME |
105grep "panicked at" | sed "s|thread '<unnamed>' panicked at '\([^']*\).*|\1|"`
106# Explanation:
107# `cat $STDERR_LOG_FNAME |`: Display the contents of the stderr log file and pass the contents
108# to the next command.
109# `grep "panicked at" |`: Filter out (drop) all the lines except the ones containing "panicked at",
110# the script expects that there is only one such line, pass that line to the next command. Line example:
111# thread '<unnamed>' panicked at 'global item should have type', . . ./compiler/qsc_frontend/src/typeck/rules.rs:300:26
112# `sed "s|thread '<unnamed>' panicked at '\([^']*\).*|\1|"`: `sed` - stream editor.
113# `s` after quote: search command. After `s` there are two sections, each between a pair of '|'.
114# First section:
115# In the incoming stream search for a sequence starting with "thread '<unnamed>' panicked at '"
116# (sequence from the beginning of the line until after the apostrophe where the panic message starts),
117# followed by zero or more ('*' after ']') non-apostrophe chars (`[^']`)
118# and memorize ( `\(`, `\)` ) that sequence of non-apostrophe chars (between apostrophes -
119# "global item should have type") as a memory item 1;
120# followed by zero or more ('*' after '.') arbitrary chars ('.') till the end of the line.
121# Second section (`\1`):
122# If the sequence specified by the first section is found, then replace that sequence (the whole line)
123# with the memory item 1 (`\1`), ending up in a panic message between the apostrophes.
124# PANIC_MESSAGE=`. . .`: The output of the command(s) between the backticks ('`') is saved in the
125# env var PANIC_MESSAGE.
126# If the failure is not panic-based then extract any ERROR message(s):
127if [ "$PANIC_MESSAGE" == "" ]; then
128PANIC_MESSAGE=`cat $STDERR_LOG_FNAME | grep "ERROR"`
129fi
130echo "PANIC_MESSAGE: '$PANIC_MESSAGE'" # Output the PANIC_MESSAGE var value to the log
131# (optional, for workflow failure analysis and sanity check).
132echo "PANIC_MESSAGE=$PANIC_MESSAGE" >> "$GITHUB_ENV" # Save the PANIC_MESSAGE var in the env, will be used in
133# the subsequent `run:` and `uses:` steps.
134
135# Determine the name of a file containing the input of interest (that triggers the panic/crash):
8d7ffb4fIan Davis1 years ago136if [ -e $ARTIFACTS_RDPATH/${{ matrix.target_name }}/crash-* ]; then # Panic and Stack Overflow Cases.
589390eaRobin Kuzmin3 years ago137TO_MINIMIZE_FNAME=crash-*;
8d7ffb4fIan Davis1 years ago138elif [ -e $ARTIFACTS_RDPATH/${{ matrix.target_name }}/oom-* ]; then # Out-of-Memory Case.
589390eaRobin Kuzmin3 years ago139TO_MINIMIZE_FNAME=oom-*;
140else
8d7ffb4fIan Davis1 years ago141echo -e "File to minimize not found.\nContents of artifacts dir \"$ARTIFACTS_RDPATH/${{ matrix.target_name }}/\":"
142ls $ARTIFACTS_RDPATH/${{ matrix.target_name }}/
589390eaRobin Kuzmin3 years ago143fi
144
145if [ "$TO_MINIMIZE_FNAME" != "" ]; then
146echo "TO_MINIMIZE_FNAME: $TO_MINIMIZE_FNAME"
147
148# Minimize the input:
7b3bd426Scott Carda1 years ago149( cargo fuzz --fuzz-dir ./fuzz tmin --release --sanitizer=none --features do_fuzz -r 10000 ${{ matrix.target_name }} $ARTIFACTS_RDPATH/${{ matrix.target_name }}/$TO_MINIMIZE_FNAME 2>&1 ) > \
589390eaRobin Kuzmin3 years ago150$TMIN_LOG_FNAME || MINIMIZATION_FAILED=1
151
152# Get the minimized input relative faile path:
153if [ "$MINIMIZATION_FAILED" == "1" ]; then
154# Minimization failed, get the latest successful minimized input relative faile path:
155MINIMIZED_INPUT_RFPATH=`
156cat $TMIN_LOG_FNAME | grep "CRASH_MIN: minimizing crash input: " | tail -n 1 |
8d7ffb4fIan Davis1 years ago157sed "s|^.*\($ARTIFACTS_RDPATH/${{ matrix.target_name }}/[^\']*\).*|\1|"`
589390eaRobin Kuzmin3 years ago158else
159# Minimization Succeeded, get the reported minimized input relative faile path::
160MINIMIZED_INPUT_RFPATH=`
161cat $TMIN_LOG_FNAME | grep "failed to minimize beyond" |
8d7ffb4fIan Davis1 years ago162sed "s|.*\($ARTIFACTS_RDPATH/${{ matrix.target_name }}/[^ ]*\).*|\1|" `
589390eaRobin Kuzmin3 years ago163fi
164echo "MINIMIZED_INPUT_RFPATH: $MINIMIZED_INPUT_RFPATH"
165echo "MINIMIZED_INPUT_RFPATH=$MINIMIZED_INPUT_RFPATH" >> "$GITHUB_ENV"
166
167# Extract the minimized input:
168MINIMIZED_INPUT=`cat $MINIMIZED_INPUT_RFPATH | tr "\n" "\r"`
169# Display the contents of the minimized input file and replace all the occurrences of '\n' with '\r'
170# so that the potentially multiline sequence can be "serialized" into the env var,
171# while preserving the information about the line breaks.
172else
173MINIMIZED_INPUT="(Input minimization failed, see the workflow logs and artifacts)"
174fi
175echo "MINIMIZED_INPUT: '$MINIMIZED_INPUT'"
176echo "MINIMIZED_INPUT=$MINIMIZED_INPUT" >> "$GITHUB_ENV"
177
178# Get the workflow agent system info:
179WF_AGENT_SYS_INFO="`uname -a`"
180echo "WF_AGENT_SYS_INFO: $WF_AGENT_SYS_INFO"
181echo "WF_AGENT_SYS_INFO=$WF_AGENT_SYS_INFO" >> "$GITHUB_ENV"
182echo "WF_AGENT_OS=${{ matrix.os }}" >> "$GITHUB_ENV"
183
c4d0dc6cRobin Kuzmin3 years ago184# Get the branch info:
185BRANCH_INFO=`git branch | grep '*'`
186echo "BRANCH_INFO: '$BRANCH_INFO'"
187echo "BRANCH_INFO=$BRANCH_INFO" >> "$GITHUB_ENV"
188
589390eaRobin Kuzmin3 years ago189# Get the commit info:
190COMMIT_INFO=`git log -1 | tr "\n" "\r"`
191echo "COMMIT_INFO: '$COMMIT_INFO'"
192echo "COMMIT_INFO=$COMMIT_INFO" >> "$GITHUB_ENV"
193
194# Get the last N bytes of the fuzzing stderr log into the env var
195# (N is such that the subsequent GitHub issue reporting does not overflow):
196STDERR_LOG=`tail -c 63488 $STDERR_LOG_FNAME | tr "\n" "\r"`
197echo "STDERR_LOG: '$STDERR_LOG'"
198echo "STDERR_LOG=$STDERR_LOG" >> "$GITHUB_ENV"
199
200- name: "If Fuzzing Failed: Upload Failure Artifacts"
201if: failure()
9831093dSalman Chishti8 months ago202uses: actions/upload-artifact@v6
589390eaRobin Kuzmin3 years ago203with:
8446d5c5Ian Davis1 years ago204name: ${{ matrix.target_name }}-fuzz-failure-artifacts
589390eaRobin Kuzmin3 years ago205path: |
206${{ env.OWNER_RDPATH }}/${{ env.STDERR_LOG_FNAME }}
207${{ env.OWNER_RDPATH }}/${{ env.TMIN_LOG_FNAME }}
8d7ffb4fIan Davis1 years ago208${{ env.OWNER_RDPATH }}/${{ env.ARTIFACTS_RDPATH }}/${{ matrix.target_name }}/*
209${{ env.OWNER_RDPATH }}/${{ env.SEEDS_RDPATH }}/${{ matrix.target_name }}/${{ env.SEEDS_FNAME }}
589390eaRobin Kuzmin3 years ago210if-no-files-found: error
211
4c4e9d5fRobin Kuzmin3 years ago212- name: "If Fuzzing Failed: Report GutHub Issue"
213if: failure()
214uses: JasonEtco/create-an-issue@v2
215env:
e7bd0d97Stefan J. Wernli9 months ago216GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4c4e9d5fRobin Kuzmin3 years ago217WORKFLOW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
218with:
219filename: ${{ env.GH_ISSUE_TEMPLATE_RFPATH }}
220# This issue template file uses a number of env vars collected above.
221id: create-issue
222
223- name: "If Fuzzing Failed: Log Issue Info"
224if: failure()
225run: |
226echo "Created issue #${{ steps.create-issue.outputs.number }} ${{ steps.create-issue.outputs.url }}"