forked from sonic-net/sonic-gnmi
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpure.mk
More file actions
329 lines (305 loc) · 10.3 KB
/
pure.mk
File metadata and controls
329 lines (305 loc) · 10.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
# pure.mk - Simple CI for pure packages without SONiC dependencies
# Usage: make -f pure.mk ci
#
# This makefile supports testing packages that don't require CGO or SONiC dependencies.
# Add new pure packages to PURE_PACKAGES below.
#
# Goal: Eventually all packages should be pure unless they absolutely
# require CGO dependencies. All CGO/SONiC dependencies should be properly quarantined.
# Go configuration
GO ?= go
GOROOT ?= $(shell $(GO) env GOROOT)
# Pure packages (no CGO/SONiC dependencies)
# Add new packages here as they become pure-compatible.
PURE_PACKAGES := \
internal/exec \
pkg/gnoi/debug \
pkg/bypass \
internal/diskspace \
internal/hash \
internal/download \
internal/firmware \
pkg/interceptors \
pkg/server/operational-handler \
pkg/gnoi/file \
pkg/exec \
pkg/gnoi/os \
pkg/gnoi/system
# Future packages to make pure:
# TODO: sonic-gnmi-standalone/pkg/workflow
# TODO: sonic-gnmi-standalone/pkg/client/config
# TODO: sonic-gnmi-standalone/internal/checksum
# TODO: sonic-gnmi-standalone/internal/download
# TODO: common_utils (parts that don't need CGO)
# TODO: gnoi_client/config
# TODO: transl_utils (isolate from translib dependencies)
# TODO: pkg/interceptors/dpuproxy (needs gRPC infrastructure mocking)
# You can test specific packages by setting PACKAGES=pkg/specific/package
PACKAGES ?= $(PURE_PACKAGES)
# Default target
.DEFAULT_GOAL := ci
# Clean up any build artifacts
.PHONY: clean
clean:
@echo "Cleaning pure build artifacts..."
$(GO) clean -cache -testcache
@for pkg in $(PACKAGES); do \
rm -f $$pkg/coverage.out $$pkg/coverage.html; \
done
# Format check - ensure code is properly formatted
.PHONY: fmt-check
fmt-check:
@echo "Checking Go code formatting for pure packages..."
@for pkg in $(PACKAGES); do \
echo "Checking $$pkg..."; \
files=$$($(GOROOT)/bin/gofmt -l $$pkg/*.go 2>/dev/null || true); \
if [ -n "$$files" ]; then \
echo "The following files need formatting in $$pkg:"; \
echo "$$files"; \
echo "Please run 'make -f pure.mk fmt' or 'gofmt -w $$pkg/*.go'"; \
exit 1; \
fi; \
done
@echo "All files are properly formatted."
# Format code
.PHONY: fmt
fmt:
@echo "Formatting Go code for pure packages..."
@for pkg in $(PACKAGES); do \
echo "Formatting $$pkg..."; \
$(GOROOT)/bin/gofmt -w $$pkg/*.go 2>/dev/null || true; \
done
# Vet - static analysis
.PHONY: vet
vet:
@echo "Running go vet on pure packages..."
@for pkg in $(PACKAGES); do \
echo "Vetting $$pkg..."; \
cd $$pkg && $(GO) vet ./...; \
cd - >/dev/null; \
done
# Test - run all tests with coverage
.PHONY: test
test:
@echo "Running tests for pure packages..."
@for pkg in $(PACKAGES); do \
echo ""; \
echo "=== Testing $$pkg ==="; \
cd $$pkg && $(GO) test -gcflags="all=-N -l" -v -race -coverprofile=coverage.out -covermode=atomic ./...; \
if [ -f coverage.out ]; then \
echo "Coverage for $$pkg:"; \
$(GO) tool cover -func=coverage.out; \
fi; \
cd - >/dev/null; \
done
# Generate coverage files for Azure pipeline integration
.PHONY: azure-coverage
azure-coverage:
@echo "Generating coverage files for Azure pipeline..."
@for pkg in $(PACKAGES); do \
echo "Testing $$pkg..."; \
pkgname=$$(echo $$pkg | tr '/' '-'); \
$(GO) test -gcflags="all=-N -l" -race -coverprofile=coverage-pure-$$pkgname.txt -covermode=atomic -v ./$$pkg; \
done
@echo "Coverage files generated for Azure pipeline"
# Test with coverage report
.PHONY: test-coverage
test-coverage: test
@echo "Generating HTML coverage reports..."
@for pkg in $(PACKAGES); do \
if [ -f $$pkg/coverage.out ]; then \
echo "Generating coverage report for $$pkg..."; \
cd $$pkg && $(GO) tool cover -html=coverage.out -o coverage.html; \
echo "Coverage report generated: $$pkg/coverage.html"; \
cd - >/dev/null; \
fi; \
done
# Generate XML coverage report for Azure pipelines
.PHONY: coverage-xml
coverage-xml: test
@echo "Generating XML coverage report for Azure..."
@if command -v gocov >/dev/null 2>&1 && command -v gocov-xml >/dev/null 2>&1; then \
echo "Converting coverage to XML format..."; \
rm -f coverage-*.out; \
for pkg in $(PACKAGES); do \
if [ -f $$pkg/coverage.out ]; then \
pkgname=$$(echo $$pkg | tr '/' '-'); \
cp $$pkg/coverage.out coverage-$$pkgname.out; \
fi; \
done; \
if ls coverage-*.out >/dev/null 2>&1; then \
gocov convert coverage-*.out | gocov-xml -source $(shell pwd) > coverage.xml; \
rm -f coverage-*.out; \
echo "XML coverage report generated: coverage.xml"; \
else \
echo "No coverage files found"; \
fi; \
else \
echo "Warning: gocov and gocov-xml not available"; \
echo "Install with: go install github.com/axw/gocov/gocov@latest"; \
echo " go install github.com/AlekSi/gocov-xml@latest"; \
fi
# Build test - ensure the package builds
.PHONY: build-test
build-test:
@echo "Testing build of pure packages..."
@for pkg in $(PACKAGES); do \
echo "Building $$pkg..."; \
cd $$pkg && $(GO) build -v ./...; \
cd - >/dev/null; \
done
# Lint check using basic go tools
.PHONY: lint
lint: fmt-check
@echo "Basic linting complete for pure packages"
# Benchmark tests
.PHONY: bench
bench:
@echo "Running benchmarks for pure packages..."
@for pkg in $(PACKAGES); do \
echo "Benchmarking $$pkg..."; \
cd $$pkg && $(GO) test -bench=. -benchmem ./...; \
cd - >/dev/null; \
done
# Module verification
.PHONY: mod-verify
mod-verify:
@echo "Verifying go modules..."
$(GO) mod verify
@echo "Checking if go.mod needs tidying..."
@if ! $(GO) mod tidy -diff >/dev/null 2>&1; then \
echo "Warning: go.mod could be tidied, but continuing CI..."; \
else \
echo "Go modules are clean"; \
fi
# Security scan using gosec if available
.PHONY: security
security:
@echo "Running security scan on pure packages..."
@if command -v gosec >/dev/null 2>&1; then \
for pkg in $(PACKAGES); do \
echo "Scanning $$pkg..."; \
cd $$pkg && gosec ./...; \
cd - >/dev/null; \
done; \
else \
echo "gosec not available, skipping security scan"; \
echo "Install with: go install github.com/securecodewarrior/gosec/v2/cmd/gosec@latest"; \
fi
# List vanilla packages
.PHONY: list-packages
list-packages:
@echo "Pure packages:"
@for pkg in $(PURE_PACKAGES); do \
echo " - $$pkg"; \
done
@echo ""
@echo "Currently testing packages:"
@for pkg in $(PACKAGES); do \
echo " - $$pkg"; \
done
# Full CI pipeline
.PHONY: ci
ci: clean lint build-test test
@echo ""
@echo "============================================="
@echo "✅ Pure CI completed successfully!"
@echo "============================================="
@echo "Tested packages:"
@for pkg in $(PACKAGES); do \
echo " - $$pkg"; \
done
@echo ""
@echo "Components validated:"
@echo " - Code formatting"
@echo " - Build verification"
@echo " - Unit tests with race detection"
@echo " - Test coverage analysis"
@echo ""
@echo "This validates that these packages can be developed"
@echo "and tested without SONiC/CGO dependencies."
# JUnit XML output for Azure Pipelines test reporting
# Note: The Azure pipeline now calls gotestsum directly with set -euo pipefail
# This target is kept for local testing convenience
.PHONY: junit-xml
junit-xml: clean
@echo "Installing gotestsum for JUnit XML generation..."
@if ! command -v gotestsum >/dev/null 2>&1; then \
$(GO) install gotest.tools/gotestsum@v1.11.0; \
fi
@echo "Installing gocov tools for coverage conversion..."
@if ! command -v gocov >/dev/null 2>&1; then \
$(GO) install github.com/axw/gocov/gocov@v1.1.0; \
fi
@if ! command -v gocov-xml >/dev/null 2>&1; then \
$(GO) install github.com/AlekSi/gocov-xml@v1.1.0; \
fi
@echo "Running pure package tests with JUnit XML output..."
@mkdir -p test-results
@export PATH=$(PATH):$(shell $(GO) env GOPATH)/bin && \
gotestsum --junitfile test-results/junit-pure.xml \
--format testname \
-- -v -race -coverprofile=test-results/coverage-pure.txt \
-covermode=atomic \
$(addprefix ./,$(PACKAGES))
@echo "Converting coverage to Cobertura XML format..."
@export PATH=$(PATH):$(shell $(GO) env GOPATH)/bin && \
if [ -f test-results/coverage-pure.txt ]; then \
gocov convert test-results/coverage-pure.txt | gocov-xml -source $(shell pwd) > test-results/coverage-pure.xml; \
echo "Coverage XML generated: test-results/coverage-pure.xml"; \
fi
@echo ""
@echo "============================================="
@echo "✅ JUnit XML generation completed!"
@echo "============================================="
@echo "Files generated:"
@echo " - test-results/junit-pure.xml (JUnit test results)"
@echo " - test-results/coverage-pure.txt (Coverage data)"
@echo " - test-results/coverage-pure.xml (Cobertura coverage for Azure)"
@echo ""
@echo "Tested packages:"
@for pkg in $(PACKAGES); do \
echo " - $$pkg"; \
done
# Quick check for development
.PHONY: quick
quick: fmt-check vet build-test
@echo "Quick validation complete for pure packages"
# Help target
.PHONY: help
help:
@echo "Pure CI Makefile for SONiC gNMI"
@echo ""
@echo "This makefile supports testing packages without CGO or SONiC dependencies."
@echo "The goal is to eventually make all packages pure by properly"
@echo "quarantining CGO/SONiC dependencies."
@echo ""
@echo "Available targets:"
@echo " ci - Full CI pipeline (default)"
@echo " junit-xml - Generate JUnit XML for Azure Pipelines"
@echo " quick - Quick validation (fmt, vet, build)"
@echo " test - Run tests with coverage"
@echo " test-coverage - Generate HTML coverage reports"
@echo " coverage-xml - Generate XML coverage for Azure"
@echo " fmt - Format code"
@echo " fmt-check - Check code formatting"
@echo " vet - Run static analysis"
@echo " lint - Run linting checks"
@echo " build-test - Test package builds"
@echo " bench - Run benchmarks"
@echo " security - Run security scan (requires gosec)"
@echo " mod-verify - Verify go modules"
@echo " list-packages - List pure packages"
@echo " clean - Clean build artifacts"
@echo " help - Show this help"
@echo ""
@echo "Examples:"
@echo " make -f pure.mk ci"
@echo " make -f pure.mk quick"
@echo " make -f pure.mk test-coverage"
@echo " make -f pure.mk PACKAGES=pkg/server/operational-handler ci"
@echo ""
@echo "Currently pure packages:"
@for pkg in $(PURE_PACKAGES); do \
echo " - $$pkg"; \
done