Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
119 commits
Select commit Hold shift + click to select a range
3290343
test: add hypothesis property tests for TLS and hook config models
raballew May 29, 2026
9045c2b
test: add hypothesis property tests for OciCredentials validation
raballew May 29, 2026
19e26a5
test: add hypothesis property tests for Metadata construction
raballew May 29, 2026
b96ea08
test: add hypothesis property tests for label selector parsing
raballew May 29, 2026
d0ddaa0
test: add hypothesis property tests for compression detection
raballew May 29, 2026
f5a44b8
test: add hypothesis property tests for enum roundtrips
raballew May 29, 2026
a8bb240
test: add programmatic API surface audit for public exports
raballew May 29, 2026
e92fb5f
fix: resolve ruff lint issues in API surface audit test
raballew May 29, 2026
070dcae
fix: activate dead leak assertion in test_no_init_leaks_private_symbols
raballew May 29, 2026
f5d0304
refactor: move api_surface_test.py to package root
raballew May 29, 2026
76df85d
fix: replace stdlib-only roundtrip tests with create_decompressor tests
raballew May 29, 2026
a93b455
feat: add external usage counting test for public exports
raballew May 29, 2026
b73fee0
refactor: address multiple medium-severity test quality findings
raballew May 29, 2026
4dac201
fix: handle ast.Import nodes in _collect_imported_names
raballew May 29, 2026
3c15d0a
fix: prevent prefix over-matching in _non_local_names
raballew May 29, 2026
51e83eb
refactor: extract shared label strategies into testing_strategies module
raballew May 29, 2026
4fea06f
test: add property-based tests for parse_oci_registry
raballew May 29, 2026
17382cf
test: add expression-based selector_contains tests
raballew May 29, 2026
2641230
style: fix import ordering in hypothesis test files
raballew May 29, 2026
b5b55b9
test: add unit tests for _collect_imported_names chain resolution
raballew May 29, 2026
14f0220
fix: selector_contains now matches labels against expression requirem…
raballew May 29, 2026
4ec8680
test: parametrize TestPackageSubmoduleDiscovery across all TRACKED_PA…
raballew May 29, 2026
88a237c
test: document assignment-based aliasing limitation in _collect_impor…
raballew May 29, 2026
5ac5b05
test: add tests for read_auth_file_credentials and resolve_oci_creden…
raballew May 29, 2026
df5fa4f
test: add cross-type operator coverage for _label_satisfies_expression
raballew May 29, 2026
4e2c900
test: add jumpstarter.config to TRACKED_PACKAGES for submodule discovery
raballew May 29, 2026
1a48db3
test: add codebase scan proving no assignment-based module aliasing e…
raballew May 29, 2026
e99e32a
test: add hypothesis fuzz tests for gRPC protobuf message serialization
raballew May 29, 2026
9f54bd7
test: add hypothesis fuzz tests for CRD schema validation
raballew May 29, 2026
086bb09
test: add hypothesis fuzz tests for CLI argument parsing
raballew May 29, 2026
e31512c
test: add hypothesis fuzz tests for serde, conditions, and decorators
raballew May 29, 2026
05bef81
refactor: replace hardcoded @settings with Hypothesis profiles
raballew May 29, 2026
a41d357
test: add hypothesis fuzz tests for kubernetes models, CRD negatives,…
raballew May 29, 2026
7ad9e06
test: add robustness fuzzing tests for all major public APIs
raballew May 29, 2026
14242b5
refactor: rename test_*.py files to *_test.py for naming consistency
raballew May 29, 2026
7e16ed2
Revert "refactor: rename test_*.py files to *_test.py for naming cons…
raballew May 29, 2026
7cf7dd2
test: add Go native fuzz tests and widen Python hypothesis strategies
raballew May 29, 2026
091abea
test: add robustness fuzz tests for CLI, admin, common, driver, and d…
raballew May 29, 2026
fdee462
feat: add fuzz testing infrastructure
raballew May 29, 2026
56a0856
test: add robustness fuzz tests for flashers, QEMU, and mitmproxy dri…
raballew May 29, 2026
6a64e8c
test: add robustness fuzz tests for dut-network, http-power, and netw…
raballew May 29, 2026
e1d9f0e
test: add robustness fuzz tests for adb, androidemulator, ble, compos…
raballew May 29, 2026
ee22999
test: add robustness fuzz tests for dutlink, gpiod, http, iscsi, noyi…
raballew May 29, 2026
bb65b67
test: add robustness fuzz tests for probe-rs, pyserial, renode, rides…
raballew May 29, 2026
9fe11f2
test: add robustness fuzz tests for snmp, ssh, ssh-mitm, ssh-mount, s…
raballew May 29, 2026
981f6cc
test: add robustness fuzz tests for tftp, tmt, vnc, yepkit drivers
raballew May 29, 2026
082c6bb
chore: update uv.lock with hypothesis dev dependencies
raballew May 29, 2026
ae0f93a
fix: address review findings for fuzz testing branch
raballew May 29, 2026
16abdfc
test: add deep gap fuzz tests for YAML config, compression, CLI, driv…
raballew May 29, 2026
0c69f76
fix: run fuzz tests per-file instead of stopping globally on first fa…
raballew May 29, 2026
0196672
fix: repair Python fuzz replay pipeline to persist findings
raballew Jun 1, 2026
c244ec6
test: add property assertions and new Go fuzz targets
raballew Jun 1, 2026
398e876
test: add property assertions to FuzzLeaseGetExporterSelector
raballew Jun 1, 2026
5300352
fix: use process group to kill HypoFuzz workers on timeout
raballew Jun 1, 2026
4862996
fix: handle malformed duration input with descriptive error message
raballew Jun 1, 2026
a257e22
fix: add return type annotation to _yaml_safe_load_or_error
raballew Jun 1, 2026
e56f38b
fix: define ALLOWED_PARSE_OCI_EXCEPTIONS to prevent NameError in robu…
raballew Jun 1, 2026
b45b874
fix: extract hardcoded fuzz test file names into ADDITIONAL_FUZZ_TEST…
raballew Jun 1, 2026
9936a80
fix: replace static PYTHON_FUZZ_DIRS with dynamic _discover_python_fu…
raballew Jun 1, 2026
905e1b1
refactor: rename outlier fuzz test files to match discovery patterns
raballew Jun 1, 2026
2ad4e49
refactor: remove Hypothesis database monkey-patching from conftest.py
raballew Jun 1, 2026
920da10
refactor: auto-discover Go fuzz targets instead of hardcoded list
raballew Jun 1, 2026
08b4dfd
refactor: consolidate 23 simple driver robustness tests into single m…
raballew Jun 1, 2026
0239261
fix: raise ValueError for unknown label selector operators
raballew Jun 1, 2026
451bd69
fix: handle ProcessLookupError race in HypoFuzz process cleanup
raballew Jun 1, 2026
a7e47ed
refactor: rename import-only robustness tests to import_test.py
raballew Jun 1, 2026
15d7dc0
fix: sanitize user input in CI fuzz workflow
raballew Jun 1, 2026
a67a5e6
fix: capture HypoFuzz stderr on final retry attempt
raballew Jun 1, 2026
0cd14bf
fix: validate example args before injecting into source files
raballew Jun 1, 2026
47b17b9
refactor: remove empty ALLOWED_*_EXCEPTIONS no-op patterns
raballew Jun 1, 2026
9e76b26
fix: remove global too_slow health check suppression from fuzz profile
raballew Jun 1, 2026
f089717
fix: align hypothesis version constraint to >=6.127.2 across all pack…
raballew Jun 1, 2026
7ae157e
test: add hypothesis tests for Jumpstarter condition and enum logic
raballew Jun 1, 2026
3d0ee7e
test: add subprocess-mocked tests for fuzz.py orchestration functions
raballew Jun 1, 2026
1ea666b
test: add Jumpstarter logic tests for deserialized protobuf messages
raballew Jun 1, 2026
5a8d232
fix: use positive AST allowlist in fuzz.py _is_safe_example_args
raballew Jun 1, 2026
1e4c1c5
fix: narrow and explicit exception types in driver robustness tests
raballew Jun 1, 2026
8c6d68f
fix: broaden hypothesis import guard to catch all setup failures
raballew Jun 1, 2026
eecf964
test: add targeted unit tests for _label_satisfies_expression
raballew Jun 1, 2026
e955a03
docs: fill in fuzz testing specification with requirements
raballew Jun 1, 2026
679eee0
test: add invariant assertions to robustness tests on successful cons…
raballew Jun 1, 2026
bfa0dc1
fix: narrow hypothesis configuration exception handling to ImportError
raballew Jun 1, 2026
5f65cd5
fix: validate fuzz.py time parameter rejects non-positive durations
raballew Jun 1, 2026
ceab5b1
refactor: extract shared ARBITRARY strategy to testing_strategies.py
raballew Jun 1, 2026
1289c43
refactor: centralize hypothesis profile definitions in conftest.py
raballew Jun 1, 2026
028c667
fix: add consistent deadline=None to CLI deep execution robustness tests
raballew Jun 1, 2026
4337950
fix: tighten Go fuzz target regex to match full signature
raballew Jun 1, 2026
1467510
fix: tighten CI fuzz duration validation regex
raballew Jun 1, 2026
fdec037
refactor: move hypofuzz and hypothesis[cli] to workspace root dev deps
raballew Jun 1, 2026
0ce8777
fix: replace push-to-main fuzz trigger with nightly schedule
raballew Jun 1, 2026
e380c50
test: add tests for example injection safety and comment preservation
raballew Jun 1, 2026
a70f034
chore: remove unused hypothesis dev dependency from 26 packages
raballew Jun 1, 2026
88002b4
fix: revert gratuitous formatting changes in 25 driver pyproject.toml…
raballew Jun 1, 2026
715bf2c
fix: align _label_satisfies_expression with Kubernetes semantics
raballew Jun 1, 2026
bea515d
test: expand driver_robustness_test.py to cover all 46 driver packages
raballew Jun 1, 2026
df49046
fix: reject ambiguous trailing bare numbers in parse_duration and har…
raballew Jun 1, 2026
cd2050a
fix: disambiguate FuzzValidateLeaseTags assertion conditions with ear…
raballew Jun 1, 2026
6963a87
chore: fix import ordering in robustness tests and sync uv.lock
raballew Jun 1, 2026
1179e23
fix: add jsonschema dev dependency to jumpstarter package
raballew Jun 1, 2026
9b47b22
fix: move cli_hypothesis_test.py to jumpstarter-cli package
raballew Jun 1, 2026
6d8451b
fix: add deadline=None and suppress_health_check to Hypothesis profiles
raballew Jun 1, 2026
7e1e514
fix: remove per-file deadline=None overrides now centralized in profile
raballew Jun 1, 2026
7dc07de
refactor: replace 16 inline ARBITRARY strategy copies with shared import
raballew Jun 1, 2026
2d59a5b
fix: update selector_contains docstring to reflect Kubernetes matchin…
raballew Jun 1, 2026
b0cbe4d
fix: guard against ZeroDivisionError in run_go_all with empty targets
raballew Jun 1, 2026
9ed26e4
fix: harden _extract_falsifying_examples regex to avoid premature mat…
raballew Jun 1, 2026
ca24445
fix: replace fragile parents[4] with root-finding in CRD hypothesis test
raballew Jun 1, 2026
0781868
fix: address LOW review findings for fuzz testing
raballew Jun 1, 2026
b66109c
fix: add push-to-main trigger and dynamic timeout for fuzz workflow
raballew Jun 1, 2026
ebb4a9b
test: add property tests for absent-key satisfying negative operators
raballew Jun 1, 2026
2df9ce3
fix: make MAX_EXAMPLES_PER_TEST configurable via --max-examples-per-test
raballew Jun 1, 2026
524d988
fix: use top-level click exception classes for type checker compatibi…
raballew Jun 1, 2026
80e4467
fix: continue running remaining Go fuzz targets after a failure
raballew Jun 1, 2026
dafba99
fix: use top-level click exception classes in remaining robustness tests
raballew Jun 1, 2026
d9086a3
fix: apply De Morgan's law in metadata fuzz test hex check
raballew Jun 1, 2026
36e92e2
fix: cast arbitrary-typed args in robustness tests for ty compatibility
raballew Jun 1, 2026
c5e8c0d
fix: propagate Python fuzzer failure status to exit code
raballew Jun 1, 2026
1af587d
fix: restrict fuzz workflow to main branch and scheduled runs
raballew Jun 1, 2026
dca1dfe
Revert "fix: restrict fuzz workflow to main branch and scheduled runs"
raballew Jun 1, 2026
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
143 changes: 143 additions & 0 deletions .github/workflows/fuzz.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
name: Fuzz Tests

on:
schedule:
- cron: "17 3 * * *"
push:
branches:
- main
paths:
- "python/**"
- "controller/**"
- "protocol/**"
- "scripts/fuzz.py"
- ".github/workflows/fuzz.yaml"
workflow_dispatch:
inputs:
fuzz_time:
description: "Fuzz duration per job (e.g. 30m, 2h, 6h)"
default: "30m"
pull_request:
paths:
- "python/**"
- "controller/**"
- "protocol/**"
- "scripts/fuzz.py"
- ".github/workflows/fuzz.yaml"

concurrency:
group: fuzz-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
matrix:
if: github.repository_owner == 'jumpstarter-dev'
runs-on: ubuntu-latest
outputs:
go_targets: ${{ steps.targets.outputs.go_targets }}
fuzz_time: ${{ steps.duration.outputs.time }}
timeout_minutes: ${{ steps.duration.outputs.timeout_minutes }}
steps:
- uses: actions/checkout@v4
- id: targets
run: echo "go_targets=$(python3 scripts/fuzz.py --list-go-targets)" >> "$GITHUB_OUTPUT"
- id: duration
env:
EVENT_NAME: ${{ github.event_name }}
FUZZ_TIME_INPUT: ${{ inputs.fuzz_time }}
run: |
if [ "$EVENT_NAME" = "schedule" ]; then
TIME_VAL="2h"
elif [ "$EVENT_NAME" = "push" ]; then
TIME_VAL="6h"
elif [ "$EVENT_NAME" = "workflow_dispatch" ]; then
if [ -z "$FUZZ_TIME_INPUT" ] || ! echo "$FUZZ_TIME_INPUT" | grep -qE '^([0-9]+h)([0-9]+m)?([0-9]+s)?$|^([0-9]+m)([0-9]+s)?$|^([0-9]+s)$|^[0-9]+$'; then
echo "::error::Invalid fuzz_time format: $FUZZ_TIME_INPUT"
exit 1
fi
TIME_VAL="$FUZZ_TIME_INPUT"
else
TIME_VAL="5m"
fi
echo "time=$TIME_VAL" >> "$GITHUB_OUTPUT"
TOTAL_SECONDS=0
REMAINING="$TIME_VAL"
if echo "$REMAINING" | grep -q 'h'; then
HOURS=$(echo "$REMAINING" | sed 's/h.*//')
REMAINING=$(echo "$REMAINING" | sed 's/[^h]*h//')
TOTAL_SECONDS=$((TOTAL_SECONDS + HOURS * 3600))
fi
if echo "$REMAINING" | grep -q 'm'; then
MINUTES=$(echo "$REMAINING" | sed 's/m.*//')
REMAINING=$(echo "$REMAINING" | sed 's/[^m]*m//')
TOTAL_SECONDS=$((TOTAL_SECONDS + MINUTES * 60))
fi
if echo "$REMAINING" | grep -qE '^[0-9]+s?$'; then
SECS=$(echo "$REMAINING" | sed 's/s//')
if [ -n "$SECS" ]; then
TOTAL_SECONDS=$((TOTAL_SECONDS + SECS))
fi
fi
TIMEOUT_MINUTES=$(( (TOTAL_SECONDS + 59) / 60 + 30 ))
echo "timeout_minutes=$TIMEOUT_MINUTES" >> "$GITHUB_OUTPUT"

fuzz-python:
needs: matrix
runs-on: ubuntu-latest
timeout-minutes: ${{ fromJson(needs.matrix.outputs.timeout_minutes) }}
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v6

- name: Fuzz Python
env:
FUZZ_TIME: ${{ needs.matrix.outputs.fuzz_time }}
run: python3 scripts/fuzz.py --time "$FUZZ_TIME" --python-only

- name: Upload Hypothesis examples
if: failure()
uses: actions/upload-artifact@v4
with:
name: hypothesis-examples
path: python/.hypothesis/
if-no-files-found: ignore

fuzz-go:
needs: matrix
runs-on: ubuntu-latest
timeout-minutes: ${{ fromJson(needs.matrix.outputs.timeout_minutes) }}
strategy:
fail-fast: false
matrix:
target: ${{ fromJson(needs.matrix.outputs.go_targets) }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: controller/go.mod
cache-dependency-path: controller/go.sum

- name: Restore Go fuzz cache
uses: actions/cache@v5
with:
path: ~/.cache/go-build/fuzz
key: go-fuzz-${{ matrix.target.name }}-${{ runner.os }}-${{ hashFiles('controller/**/*_fuzz_test.go') }}
restore-keys: |
go-fuzz-${{ matrix.target.name }}-${{ runner.os }}-

- name: Fuzz ${{ matrix.target.name }}
env:
FUZZ_TIME: ${{ needs.matrix.outputs.fuzz_time }}
GO_TARGET: ${{ matrix.target.name }}
run: python3 scripts/fuzz.py --time "$FUZZ_TIME" --go-target "$GO_TARGET"

- name: Upload crash reproducers
if: failure()
uses: actions/upload-artifact@v4
with:
name: go-crash-${{ matrix.target.name }}
path: controller/**/testdata/fuzz/${{ matrix.target.name }}/
if-no-files-found: ignore
19 changes: 19 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ help:
@echo " make e2e-full - Full setup + run (for CI or first time)"
@echo " make e2e-clean - Clean up e2e test environment (delete cluster, certs, etc.)"
@echo ""
@echo "Fuzz testing:"
@echo " make fuzz - Run all fuzz tests for FUZZ_TIME (default 30m)"
@echo " make fuzz-python - Run Python hypothesis fuzz tests for FUZZ_TIME"
@echo " make fuzz-go - Run Go native fuzz tests for FUZZ_TIME"
@echo " FUZZ_TIME=2h make fuzz - Override total fuzz duration"
@echo ""
@echo "Per-project targets:"
@echo " make build-<project> - Build specific project"
@echo " make test-<project> - Test specific project"
Expand Down Expand Up @@ -159,6 +165,19 @@ e2e-clean:
@echo "Note: You may need to manually remove the dex entry from /etc/hosts:"
@echo " sudo sed -i.bak '/dex.dex.svc.cluster.local/d' /etc/hosts"

# Fuzz testing
FUZZ_TIME ?= 30m

.PHONY: fuzz fuzz-python fuzz-go
fuzz:
@python3 scripts/fuzz.py --time $(FUZZ_TIME)

fuzz-python:
@python3 scripts/fuzz.py --time $(FUZZ_TIME) --python-only

fuzz-go:
@python3 scripts/fuzz.py --time $(FUZZ_TIME) --go-only

# Backward compatibility alias
.PHONY: test-e2e
test-e2e: e2e-run
Expand Down
3 changes: 3 additions & 0 deletions controller/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,6 @@ go.work
*~

goreleaser/

# Fuzz corpus (regressions are injected as f.Add() seeds in source)
**/testdata/fuzz/
61 changes: 61 additions & 0 deletions controller/api/v1alpha1/client_helpers_fuzz_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package v1alpha1

import (
"strings"
"testing"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
)

func FuzzClientUsernames(f *testing.F) {
f.Add("internal:", "my-client", "default", "uid-123", "", false)
f.Add("internal:", "client", "ns", "uid", "oidc:user@example.com", true)
f.Add("prefix:", "name", "namespace", "uid", "", false)
f.Add("", "name", "ns", "uid", "user", true)

f.Fuzz(func(t *testing.T, prefix, name, namespace, uid, customUsername string, hasCustom bool) {
c := &Client{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
UID: types.UID(uid),
},
}
if hasCustom {
c.Spec.Username = &customUsername
}

usernames := c.Usernames(prefix)

if len(usernames) == 0 {
t.Fatal("Usernames returned empty slice")
}

expectedInternal := prefix + c.InternalSubject()
if usernames[0] != expectedInternal {
t.Errorf("first username = %q, expected %q", usernames[0], expectedInternal)
}

if !strings.HasPrefix(usernames[0], prefix) {
t.Errorf("first username %q does not start with prefix %q", usernames[0], prefix)
}

internalSubject := c.InternalSubject()
if !strings.HasPrefix(internalSubject, "client:") {
t.Errorf("InternalSubject() = %q does not start with 'client:'", internalSubject)
}

if hasCustom {
if len(usernames) != 2 {
t.Errorf("expected 2 usernames with custom username, got %d", len(usernames))
} else if usernames[1] != customUsername {
t.Errorf("second username = %q, expected custom %q", usernames[1], customUsername)
}
} else {
if len(usernames) != 1 {
t.Errorf("expected 1 username without custom username, got %d", len(usernames))
}
}
})
}
107 changes: 107 additions & 0 deletions controller/api/v1alpha1/exporter_helpers_fuzz_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package v1alpha1

import (
"strings"
"testing"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
)

func FuzzExporterUsernames(f *testing.F) {
f.Add("internal:", "my-exporter", "default", "uid-123", "", false)
f.Add("internal:", "exporter", "ns", "uid", "custom-user", true)
f.Add("prefix:", "name", "namespace", "uid", "", false)
f.Add("", "name", "ns", "uid", "user", true)

f.Fuzz(func(t *testing.T, prefix, name, namespace, uid, customUsername string, hasCustom bool) {
e := &Exporter{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
UID: types.UID(uid),
},
}
if hasCustom {
e.Spec.Username = &customUsername
}

usernames := e.Usernames(prefix)

if len(usernames) == 0 {
t.Fatal("Usernames returned empty slice")
}

expectedInternal := prefix + e.InternalSubject()
if usernames[0] != expectedInternal {
t.Errorf("first username = %q, expected %q", usernames[0], expectedInternal)
}

if !strings.HasPrefix(usernames[0], prefix) {
t.Errorf("first username %q does not start with prefix %q", usernames[0], prefix)
}

if hasCustom {
if len(usernames) != 2 {
t.Errorf("expected 2 usernames with custom username, got %d", len(usernames))
} else if usernames[1] != customUsername {
t.Errorf("second username = %q, expected custom %q", usernames[1], customUsername)
}
} else {
if len(usernames) != 1 {
t.Errorf("expected 1 username without custom username, got %d", len(usernames))
}
}
})
}

func FuzzExporterToProtobuf(f *testing.F) {
f.Add("my-exporter", "default", "Available", "running fine")
f.Add("exp", "ns", "Offline", "")
f.Add("exp", "ns", "Unspecified", "msg")
f.Add("exp", "ns", "LeaseReady", "msg")
f.Add("exp", "ns", "UnknownStatus", "msg")

f.Fuzz(func(t *testing.T, name, namespace, statusValue, statusMessage string) {
e := &Exporter{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
Status: ExporterStatus{
ExporterStatusValue: statusValue,
StatusMessage: statusMessage,
},
}

pb := e.ToProtobuf()

expectedName := "namespaces/" + namespace + "/exporters/" + name
if pb.Name != expectedName {
t.Errorf("protobuf Name = %q, expected %q", pb.Name, expectedName)
}

if pb.StatusMessage != statusMessage {
t.Errorf("protobuf StatusMessage = %q, expected %q", pb.StatusMessage, statusMessage)
}
})
}

func FuzzExporterListToProtobuf(f *testing.F) {
f.Add("exp1", "exp2", "ns")

f.Fuzz(func(t *testing.T, name1, name2, namespace string) {
list := &ExporterList{
Items: []Exporter{
{ObjectMeta: metav1.ObjectMeta{Name: name1, Namespace: namespace}},
{ObjectMeta: metav1.ObjectMeta{Name: name2, Namespace: namespace}},
},
}

resp := list.ToProtobuf()

if len(resp.Exporters) != 2 {
t.Fatalf("expected 2 exporters in protobuf response, got %d", len(resp.Exporters))
}
})
}
Loading
Loading