007c32a58d
Memory Scripts * tests * cleanermemtest * files * tests
225 lines
7.6 KiB
YAML
225 lines
7.6 KiB
YAML
---
|
|
# https://taskfile.dev
|
|
|
|
version: "3"
|
|
|
|
vars:
|
|
COVERAGE_FILE: "{{.OUT_DIR}}/coverage.out"
|
|
BENCH_FILE: "{{.OUT_DIR}}/bench.out"
|
|
TEST_FILE: "{{.OUT_DIR}}/test.out"
|
|
INTERNAL: "./internal/..."
|
|
API: "./api/..."
|
|
PKG: "./pkg/..."
|
|
CMD: "./cmd/..."
|
|
CPU_COUNT:
|
|
sh: |
|
|
# First try nproc (Linux)
|
|
if command -v nproc >/dev/null 2>&1; then
|
|
nproc
|
|
# Fall back to sysctl (macOS)
|
|
elif [ "$(uname)" = "Darwin" ]; then
|
|
sysctl -n hw.ncpu
|
|
# Fall back to Windows approach
|
|
elif [ "$(uname)" = "Windows" ] || [ "$(uname)" = "MINGW"* ]; then
|
|
echo "$NUMBER_OF_PROCESSORS"
|
|
else
|
|
echo "4" # Default fallback value
|
|
fi
|
|
TEST_PARALLEL:
|
|
sh: echo $(( {{.CPU_COUNT}} ))
|
|
# yamllint disable-line rule:line-length
|
|
EXCLUDED_FILES: ".gen.go|internal/serviceconfig/observability/prometheus/generator/main.go|internal/cognitoauth/middleware.go|internal/cognitoauth/token.go|internal/cognitoauth/auth.go|internal/cognitoauth/handler.go|internal/cognitoauth/models.go|api/queryAPI/authHandlers.go|api/queryAPI/homehandler.go"
|
|
|
|
tasks:
|
|
mocks:generate:
|
|
run: once
|
|
cmds:
|
|
- rm -rf mocks/*
|
|
- go tool mockery --log-level=""
|
|
functional:
|
|
- mkdir -p {{.OUT_DIR}}
|
|
- task: wait
|
|
- |
|
|
GOMAXPROCS={{.TEST_PARALLEL}} go test -parallel {{.CPU_COUNT}} \
|
|
-coverpkg={{.INTERNAL}},{{.API}},{{.PKG}} \
|
|
-coverprofile={{.COVERAGE_FILE}} \
|
|
./...
|
|
- task: coverage
|
|
race: GOMAXPROCS={{.TEST_PARALLEL}} go test -parallel {{.CPU_COUNT}} -race ./...
|
|
graph: psrecord "task test:functional" --plot out/test.png --interval 0.1 --include-children
|
|
wait: docker wait $(docker ps -q --filter "label=org.testcontainers.ryuk=true") 2>/dev/null || true
|
|
mem:
|
|
vars:
|
|
NUM_RESULTS: 5
|
|
RESULTS_FILE: "{{ .OUT_DIR }}/mem.out"
|
|
cmds:
|
|
- |
|
|
YELLOW='\033[0;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
get_memory_usage() {
|
|
local profile_file=$1
|
|
if [ ! -f "$profile_file" ] || [ ! -s "$profile_file" ]; then
|
|
return
|
|
fi
|
|
|
|
local mem_mb=$(go tool pprof -top "{{ .RESULTS_FILE }}" 2>/dev/null | \
|
|
grep -E "^\s*[0-9]" | head -1 | \
|
|
awk '{print $1}' | \
|
|
sed 's/MB//g' | sed 's/KB//g' | sed 's/GB//g' | \
|
|
sed 's/[^0-9.]//g')
|
|
|
|
if go tool pprof -top "{{ .RESULTS_FILE }}" 2>/dev/null | head -1 | grep -q "KB"; then
|
|
mem_mb=$(echo "$mem_mb / 1024" | bc -l 2>/dev/null || echo "0")
|
|
fi
|
|
|
|
if go tool pprof -top "{{ .RESULTS_FILE }}" 2>/dev/null | head -1 | grep -q "GB"; then
|
|
mem_mb=$(echo "$mem_mb * 1024" | bc -l 2>/dev/null || echo "0")
|
|
fi
|
|
|
|
echo "${mem_mb:-0}"
|
|
}
|
|
|
|
test_package() {
|
|
local pkg=$1
|
|
local pkg_short=$(basename "$pkg")
|
|
local profile="{{ .OUT_DIR }}/mem_${pkg_short}_$(date +%s).prof"
|
|
|
|
echo -e "${YELLOW}Testing:${NC} $pkg ... "
|
|
|
|
# Run test with memory profiling (with timeout)
|
|
if timeout 120 go test -memprofile="$profile" "$pkg" >/dev/null 2>&1; then
|
|
local mem_usage=$(get_memory_usage "$profile")
|
|
echo -e "✅ ${mem_usage} MB"
|
|
echo "$mem_usage|$pkg" >> "{{ .RESULTS_FILE }}"
|
|
else
|
|
echo -e "❌ FAILED/TIMEOUT"
|
|
echo "0|$pkg" >> "{{ .RESULTS_FILE }}"
|
|
fi
|
|
}
|
|
|
|
echo -e "${BLUE}Go Test Memory Usage Analysis${NC}"
|
|
echo -e "${BLUE}==============================${NC}"
|
|
echo "Profile directory: out/"
|
|
echo ""
|
|
echo "Running tests with memory profiling..."
|
|
echo ""
|
|
|
|
for pkg in $(go list ./... 2>/dev/null || echo "."); do
|
|
task test:wait
|
|
test_package "$pkg"
|
|
done
|
|
|
|
if [ ! -f "{{ .RESULTS_FILE }}" ] || [ ! -s "{{ .RESULTS_FILE }}" ]; then
|
|
exit 1
|
|
fi
|
|
|
|
echo ""
|
|
echo -e "${BLUE}Memory Usage Rankings:${NC}"
|
|
echo -e "${BLUE}=====================${NC}"
|
|
|
|
{
|
|
echo "MEMORY(MB)|PACKAGE"
|
|
echo "----------|--------"
|
|
sort -t'|' -k1 -nr "{{ .RESULTS_FILE }}" | head -{{ .NUM_RESULTS }}
|
|
} | column -t -s'|'
|
|
|
|
echo ""
|
|
echo -e "${BLUE}Summary:${NC}"
|
|
|
|
total_mem=$(awk -F'|' '{sum+=$1} END {printf "%.2f", sum}' "{{ .RESULTS_FILE }}")
|
|
total_packages=$(wc -l < "{{ .RESULTS_FILE }}")
|
|
|
|
echo "Total packages tested: $total_packages"
|
|
echo "Total memory usage: ${total_mem} MB"
|
|
perf:
|
|
vars:
|
|
NUM_RESULTS: 5
|
|
cmds:
|
|
- |
|
|
GOMAXPROCS={{.TEST_PARALLEL}} go test -parallel {{.CPU_COUNT}} -count=1 -json ./... \
|
|
> {{.TEST_FILE}}
|
|
- |
|
|
echo -e "🐢 TOP {{.NUM_RESULTS}} SLOWEST INDIVIDUAL PACKAGE RUNS:"
|
|
jq -r 'select(.Action == "pass" and .Test == null) | "\(.Elapsed)s \(.Package)"' "{{.TEST_FILE}}" | \
|
|
sort -rn | head -n {{.NUM_RESULTS}}
|
|
|
|
echo -e "\n📉 TOP {{.NUM_RESULTS}} SLOWEST TESTS:"
|
|
jq -r 'select(.Action == "pass" and .Test != null) | "\(.Elapsed)s \(.Test) (\(.Package))"' "{{.TEST_FILE}}" | \
|
|
sort -rn | head -n {{.NUM_RESULTS}}
|
|
|
|
SLOWEST_PKG=$(jq -r 'select(.Action == "pass") | [.Package, .Elapsed] | @tsv' "{{.TEST_FILE}}" |
|
|
awk '{pkg[$1] += $2} END {for (p in pkg) print pkg[p] "s " p}' |
|
|
sort -rn | head -n 1 | awk '{print $2}')
|
|
|
|
echo -e "\n🔎 TOP {{.NUM_RESULTS}} SLOWEST TESTS IN SLOWEST PACKAGE ($SLOWEST_PKG):"
|
|
jq -r --arg pkg "$SLOWEST_PKG" \
|
|
'select(.Action == "pass" and .Test != null and .Package == $pkg) | "\(.Elapsed)s \(.Test)"' "{{.TEST_FILE}}" |
|
|
sort -rn | head -n {{.NUM_RESULTS}}
|
|
bench:
|
|
vars:
|
|
TMP_FILE: "{{.OUT_DIR}}/coverage.tmp"
|
|
FILTER_COVERAGE_FILE: "{{.OUT_DIR}}/filtered_coverage.out"
|
|
cmds:
|
|
- go test -run ^Benchmark -bench=. ./... > {{.BENCH_FILE}}
|
|
- benchstat {{.BENCH_FILE}}
|
|
unit:short:
|
|
deps:
|
|
- mocks:generate
|
|
cmds:
|
|
- mkdir -p {{.OUT_DIR}}
|
|
- |
|
|
go test -parallel {{.TEST_PARALLEL}} -short \
|
|
{{.INTERNAL}} {{.API}} {{.CLI_ARGS}}
|
|
coverage:
|
|
internal: true
|
|
vars:
|
|
TMP_FILE: "{{.OUT_DIR}}/coverage.tmp"
|
|
FILTER_COVERAGE_FILE: "{{.OUT_DIR}}/filtered_coverage.out"
|
|
cmds:
|
|
- grep -v -E "{{.EXCLUDED_FILES}}" {{.COVERAGE_FILE}} > {{.FILTER_COVERAGE_FILE}}
|
|
- go tool cover -func={{.FILTER_COVERAGE_FILE}} > {{.TMP_FILE}}
|
|
- |
|
|
COVERAGE=$(grep total: {{.TMP_FILE}} | awk '{print $NF}' | sed 's/%//')
|
|
echo "Coverage Threshold: {{.COVERAGE_THRESHOLD}}%"
|
|
echo "Total Coverage: $COVERAGE%"
|
|
|
|
FAIL=false
|
|
if (( $(echo "$COVERAGE < {{.COVERAGE_THRESHOLD}}" | bc -l) )); then
|
|
echo "❌ Error: Total Coverage below Coverage Threshold"
|
|
FAIL=true
|
|
fi
|
|
|
|
echo "Function Coverage Threshold: {{.FUNCTION_COVERAGE_THRESHOLD}}%"
|
|
|
|
awk -v threshold="{{.FUNCTION_COVERAGE_THRESHOLD}}" '
|
|
!/total:/ {
|
|
line = $0;
|
|
coverage = $NF;
|
|
gsub(/%/, "", coverage);
|
|
|
|
if (coverage + 0 < threshold + 0) {
|
|
if (!printed_header) {
|
|
print "❌ Error: The following functions have coverage below " threshold "%:";
|
|
printed_header = 1;
|
|
}
|
|
print line;
|
|
exit_code = 1;
|
|
}
|
|
}
|
|
END {
|
|
exit exit_code;
|
|
}
|
|
' {{.TMP_FILE}}
|
|
|
|
if [ $? -eq 1 ]; then
|
|
FAIL=true
|
|
fi
|
|
|
|
if [ "$FAIL" = true ]; then
|
|
exit 1
|
|
fi
|
|
|
|
echo "✅ All coverage checks passed!"
|