Jelajahi Sumber

docs: 增加模糊测试转换率在线文档

RyanCW 2 hari lalu
induk
melakukan
18137e8d35

+ 47 - 0
.github/workflows/static.yml

@@ -0,0 +1,47 @@
+# 部署静态内容到 GitHub Pages
+name: 部署 Fuzz 覆盖率报告到 Pages
+
+on:
+  # 当 main 或 next 分支有新提交时自动部署
+  push:
+    branches: ["main", "next"]
+
+  # 允许在 Actions 页面手动触发
+  workflow_dispatch:
+
+# 授予 GITHUB_TOKEN 部署 Pages 所需权限
+permissions:
+  contents: read
+  pages: write
+  id-token: write
+
+# 同一时间只保留一个 Pages 部署任务,不中断正在进行的部署
+concurrency:
+  group: "pages"
+  cancel-in-progress: false
+
+jobs:
+  # 单一部署任务
+  deploy:
+    environment:
+      name: github-pages
+      url: ${{ steps.deployment.outputs.page_url }}
+    runs-on: ubuntu-latest
+    steps:
+      - name: 检出触发分支代码
+        uses: actions/checkout@v4
+        with:
+          ref: ${{ github.ref_name }}
+
+      - name: 配置 GitHub Pages
+        uses: actions/configure-pages@v5
+
+      - name: 上传 Fuzz 覆盖率页面产物
+        uses: actions/upload-pages-artifact@v3
+        with:
+          # 仅上传静态 HTML 目录,避免把整个仓库上传到 Pages
+          path: './test/fuzzer/coverage/html'
+
+      - name: 部署到 GitHub Pages
+        id: deployment
+        uses: actions/deploy-pages@v4

+ 1 - 1
scripts/ci/runCoverage.sh

@@ -82,7 +82,7 @@ scientific="${RYANJSON_SNPRINTF_SUPPORT_SCIENTIFIC:-true}"
 caseName="strict_${strictKey}__head_${addAtHead}__sci_${scientific}"
 
 # 覆盖率目录固定为 coverage/fuzz,每次执行前清理,保证只保留最新结果
-coverageRoot="coverage/fuzz"
+coverageRoot="test/fuzzer/coverage"
 rm -rf "${coverageRoot}"
 profileRoot="${coverageRoot}/profiles"
 mkdir -p "${profileRoot}"

+ 1 - 0
test/externalModule/FreeRTOS-Kernel

@@ -0,0 +1 @@
+Subproject commit 0adc196d4bd52a2d91102b525b0aafc1e14a2386

+ 1 - 0
test/externalModule/unity

@@ -0,0 +1 @@
+Subproject commit d1fe18bd54434efd1ac0dad035d3ab0f8591e086

TEMPAT SAMPAH
test/fuzzer/coverage/coverage.profdata


+ 99 - 0
test/fuzzer/coverage/html/control.js

@@ -0,0 +1,99 @@
+
+function next_uncovered(selector, reverse, scroll_selector) {
+  function visit_element(element) {
+    element.classList.add("seen");
+    element.classList.add("selected");
+
+    if (!scroll_selector) {
+      scroll_selector = "tr:has(.selected) td.line-number"
+    }
+
+    const scroll_to = document.querySelector(scroll_selector);
+    if (scroll_to) {
+      scroll_to.scrollIntoView({behavior: "smooth", block: "center", inline: "end"});
+    }
+  }
+
+  function select_one() {
+    if (!reverse) {
+      const previously_selected = document.querySelector(".selected");
+
+      if (previously_selected) {
+        previously_selected.classList.remove("selected");
+      }
+
+      return document.querySelector(selector + ":not(.seen)");
+    } else {
+      const previously_selected = document.querySelector(".selected");
+
+      if (previously_selected) {
+        previously_selected.classList.remove("selected");
+        previously_selected.classList.remove("seen");
+      }
+
+      const nodes = document.querySelectorAll(selector + ".seen");
+      if (nodes) {
+        const last = nodes[nodes.length - 1]; // last
+        return last;
+      } else {
+        return undefined;
+      }
+    }
+  }
+
+  function reset_all() {
+    if (!reverse) {
+      const all_seen = document.querySelectorAll(selector + ".seen");
+
+      if (all_seen) {
+        all_seen.forEach(e => e.classList.remove("seen"));
+      }
+    } else {
+      const all_seen = document.querySelectorAll(selector + ":not(.seen)");
+
+      if (all_seen) {
+        all_seen.forEach(e => e.classList.add("seen"));
+      }
+    }
+
+  }
+
+  const uncovered = select_one();
+
+  if (uncovered) {
+    visit_element(uncovered);
+  } else {
+    reset_all();
+
+    const uncovered = select_one();
+
+    if (uncovered) {
+      visit_element(uncovered);
+    }
+  }
+}
+
+function next_line(reverse) {
+  next_uncovered("td.uncovered-line", reverse)
+}
+
+function next_region(reverse) {
+  next_uncovered("span.red.region", reverse);
+}
+
+function next_branch(reverse) {
+  next_uncovered("span.red.branch", reverse);
+}
+
+document.addEventListener("keypress", function(event) {
+  const reverse = event.shiftKey;
+  if (event.code == "KeyL") {
+    next_line(reverse);
+  }
+  if (event.code == "KeyB") {
+    next_branch(reverse);
+  }
+  if (event.code == "KeyR") {
+    next_region(reverse);
+  }
+});

File diff ditekan karena terlalu besar
+ 0 - 0
test/fuzzer/coverage/html/coverage/root/grow/RyanJson/RyanJson/RyanJson.c.html


File diff ditekan karena terlalu besar
+ 0 - 0
test/fuzzer/coverage/html/coverage/root/grow/RyanJson/RyanJson/RyanJson.h.html


File diff ditekan karena terlalu besar
+ 0 - 0
test/fuzzer/coverage/html/coverage/root/grow/RyanJson/RyanJson/RyanJsonConfig.h.html


File diff ditekan karena terlalu besar
+ 0 - 0
test/fuzzer/coverage/html/coverage/root/grow/RyanJson/RyanJson/RyanJsonInternal.h.html


File diff ditekan karena terlalu besar
+ 0 - 0
test/fuzzer/coverage/html/coverage/root/grow/RyanJson/RyanJson/RyanJsonItem.c.html


File diff ditekan karena terlalu besar
+ 0 - 0
test/fuzzer/coverage/html/coverage/root/grow/RyanJson/RyanJson/RyanJsonParse.c.html


File diff ditekan karena terlalu besar
+ 0 - 0
test/fuzzer/coverage/html/coverage/root/grow/RyanJson/RyanJson/RyanJsonPrint.c.html


File diff ditekan karena terlalu besar
+ 0 - 0
test/fuzzer/coverage/html/coverage/root/grow/RyanJson/RyanJson/RyanJsonUtils.c.html


File diff ditekan karena terlalu besar
+ 0 - 0
test/fuzzer/coverage/html/index.html


+ 194 - 0
test/fuzzer/coverage/html/style.css

@@ -0,0 +1,194 @@
+.red {
+  background-color: #f004;
+}
+.cyan {
+  background-color: cyan;
+}
+html {
+  scroll-behavior: smooth;
+}
+body {
+  font-family: -apple-system, sans-serif;
+}
+pre {
+  margin-top: 0px !important;
+  margin-bottom: 0px !important;
+}
+.source-name-title {
+  padding: 5px 10px;
+  border-bottom: 1px solid #8888;
+  background-color: #0002;
+  line-height: 35px;
+}
+.centered {
+  display: table;
+  margin-left: left;
+  margin-right: auto;
+  border: 1px solid #8888;
+  border-radius: 3px;
+}
+.expansion-view {
+  margin-left: 0px;
+  margin-top: 5px;
+  margin-right: 5px;
+  margin-bottom: 5px;
+  border: 1px solid #8888;
+  border-radius: 3px;
+}
+table {
+  border-collapse: collapse;
+}
+.light-row {
+  border: 1px solid #8888;
+  border-left: none;
+  border-right: none;
+}
+.light-row-bold {
+  border: 1px solid #8888;
+  border-left: none;
+  border-right: none;
+  font-weight: bold;
+}
+.column-entry {
+  text-align: left;
+}
+.column-entry-bold {
+  font-weight: bold;
+  text-align: left;
+}
+.column-entry-yellow {
+  text-align: left;
+  background-color: #ff06;
+}
+.column-entry-red {
+  text-align: left;
+  background-color: #f004;
+}
+.column-entry-gray {
+  text-align: left;
+  background-color: #fff4;
+}
+.column-entry-green {
+  text-align: left;
+  background-color: #0f04;
+}
+.line-number {
+  text-align: right;
+}
+.covered-line {
+  text-align: right;
+  color: #06d;
+}
+.uncovered-line {
+  text-align: right;
+  color: #d00;
+}
+.uncovered-line.selected {
+  color: #f00;
+  font-weight: bold;
+}
+.region.red.selected {
+  background-color: #f008;
+  font-weight: bold;
+}
+.branch.red.selected {
+  background-color: #f008;
+  font-weight: bold;
+}
+.tooltip {
+  position: relative;
+  display: inline;
+  background-color: #bef;
+  text-decoration: none;
+}
+.tooltip span.tooltip-content {
+  position: absolute;
+  width: 100px;
+  margin-left: -50px;
+  color: #FFFFFF;
+  background: #000000;
+  height: 30px;
+  line-height: 30px;
+  text-align: center;
+  visibility: hidden;
+  border-radius: 6px;
+}
+.tooltip span.tooltip-content:after {
+  content: '';
+  position: absolute;
+  top: 100%;
+  left: 50%;
+  margin-left: -8px;
+  width: 0; height: 0;
+  border-top: 8px solid #000000;
+  border-right: 8px solid transparent;
+  border-left: 8px solid transparent;
+}
+:hover.tooltip span.tooltip-content {
+  visibility: visible;
+  opacity: 0.8;
+  bottom: 30px;
+  left: 50%;
+  z-index: 999;
+}
+th, td {
+  vertical-align: top;
+  padding: 2px 8px;
+  border-collapse: collapse;
+  border-right: 1px solid #8888;
+  border-left: 1px solid #8888;
+  text-align: left;
+}
+td pre {
+  display: inline-block;
+  text-decoration: inherit;
+}
+td:first-child {
+  border-left: none;
+}
+td:last-child {
+  border-right: none;
+}
+tr:hover {
+  background-color: #eee;
+}
+tr:last-child {
+  border-bottom: none;
+}
+tr:has(> td >a:target), tr:has(> td.uncovered-line.selected) {
+  background-color: #8884;
+}
+a {
+  color: inherit;
+}
+.control {
+  position: fixed;
+  top: 0em;
+  right: 0em;
+  padding: 1em;
+  background: #FFF8;
+}
+@media (prefers-color-scheme: dark) {
+  body {
+    background-color: #222;
+    color: whitesmoke;
+  }
+  tr:hover {
+    background-color: #111;
+  }
+  .covered-line {
+    color: #39f;
+  }
+  .uncovered-line {
+    color: #f55;
+  }
+  .tooltip {
+    background-color: #068;
+  }
+  .control {
+    background: #2228;
+  }
+  tr:has(> td >a:target), tr:has(> td.uncovered-line.selected) {
+    background-color: #8884;
+  }
+}

TEMPAT SAMPAH
test/fuzzer/coverage/profiles/coverage.profraw


+ 14 - 0
test/fuzzer/coverage/report.txt

@@ -0,0 +1,14 @@
+Filename                      Regions    Missed Regions     Cover   Functions  Missed Functions  Executed       Lines      Missed Lines     Cover    Branches   Missed Branches     Cover    MC/DC Conditions    Missed Conditions     Cover
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+RyanJsonUtils.c                   387                 0   100.00%          21                 0   100.00%         304                 0   100.00%         142                 0   100.00%                   0                    0         -
+RyanJsonParse.c                   846                 0   100.00%          14                 0   100.00%         495                 0   100.00%         412                 0   100.00%                   0                    0         -
+RyanJsonItem.c                    675                 0   100.00%          45                 0   100.00%         369                 0   100.00%         230                 0   100.00%                   0                    0         -
+RyanJson.c                        376                 0   100.00%          11                 0   100.00%         287                 0   100.00%         204                 0   100.00%                   0                    0         -
+RyanJsonPrint.c                   612                 0   100.00%          10                 0   100.00%         318                 0   100.00%         303                 0   100.00%                   0                    0         -
+
+Files which contain no functions:
+RyanJsonInternal.h                  0                 0         -           0                 0         -           0                 0         -           0                 0         -                   0                    0         -
+RyanJson.h                          0                 0         -           0                 0         -           0                 0         -           0                 0         -                   0                    0         -
+RyanJsonConfig.h                    0                 0         -           0                 0         -           0                 0         -           0                 0         -                   0                    0         -
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+TOTAL                            2896                 0   100.00%         101                 0   100.00%        1773                 0   100.00%        1291                 0   100.00%                   0                    0         -

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini