refactor: use pinned golangci-lint Docker image for linting
All checks were successful
check / check (push) Successful in 1m37s
All checks were successful
check / check (push) Successful in 1m37s
Refactor Dockerfile to use a separate lint stage with a pinned golangci-lint v2.11.3 Docker image instead of installing golangci-lint via curl in the builder stage. This follows the pattern used by sneak/pixa. Changes: - Dockerfile: separate lint stage using golangci/golangci-lint:v2.11.3 (Debian-based, pinned by sha256) with COPY --from=lint dependency - Bump Go from 1.24 to 1.26.1 (golang:1.26.1-bookworm, pinned) - Bump golangci-lint from v1.64.8 to v2.11.3 - Migrate .golangci.yml from v1 to v2 format (same linters, format only) - All Docker images pinned by sha256 digest - Fix all lint issues from the v2 linter upgrade: - Add package comments to all packages - Add doc comments to all exported types, functions, and methods - Fix unchecked errors (errcheck) - Fix unused parameters (revive) - Fix gosec warnings (MaxBytesReader for form parsing) - Fix staticcheck suggestions (fmt.Fprintf instead of WriteString) - Rename DeliveryTask to Task to avoid stutter (delivery.Task) - Rename shadowed builtin 'max' parameter - Update README.md version requirements
This commit is contained in:
240
internal/delivery/export_test.go
Normal file
240
internal/delivery/export_test.go
Normal file
@@ -0,0 +1,240 @@
|
||||
package delivery
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"sneak.berlin/go/webhooker/internal/database"
|
||||
)
|
||||
|
||||
// Exported constants for test access.
|
||||
const (
|
||||
ExportDeliveryChannelSize = deliveryChannelSize
|
||||
ExportRetryChannelSize = retryChannelSize
|
||||
ExportDefaultFailureThreshold = defaultFailureThreshold
|
||||
ExportDefaultCooldown = defaultCooldown
|
||||
)
|
||||
|
||||
// ExportIsBlockedIP exposes isBlockedIP for testing.
|
||||
func ExportIsBlockedIP(ip net.IP) bool {
|
||||
return isBlockedIP(ip)
|
||||
}
|
||||
|
||||
// ExportBlockedNetworks exposes blockedNetworks.
|
||||
func ExportBlockedNetworks() []*net.IPNet {
|
||||
return blockedNetworks
|
||||
}
|
||||
|
||||
// ExportIsForwardableHeader exposes isForwardableHeader.
|
||||
func ExportIsForwardableHeader(name string) bool {
|
||||
return isForwardableHeader(name)
|
||||
}
|
||||
|
||||
// ExportTruncate exposes truncate for testing.
|
||||
func ExportTruncate(s string, maxLen int) string {
|
||||
return truncate(s, maxLen)
|
||||
}
|
||||
|
||||
// ExportDeliverHTTP exposes deliverHTTP for testing.
|
||||
func (e *Engine) ExportDeliverHTTP(
|
||||
ctx context.Context,
|
||||
webhookDB *gorm.DB,
|
||||
d *database.Delivery,
|
||||
task *Task,
|
||||
) {
|
||||
e.deliverHTTP(ctx, webhookDB, d, task)
|
||||
}
|
||||
|
||||
// ExportDeliverDatabase exposes deliverDatabase.
|
||||
func (e *Engine) ExportDeliverDatabase(
|
||||
webhookDB *gorm.DB, d *database.Delivery,
|
||||
) {
|
||||
e.deliverDatabase(webhookDB, d)
|
||||
}
|
||||
|
||||
// ExportDeliverLog exposes deliverLog for testing.
|
||||
func (e *Engine) ExportDeliverLog(
|
||||
webhookDB *gorm.DB, d *database.Delivery,
|
||||
) {
|
||||
e.deliverLog(webhookDB, d)
|
||||
}
|
||||
|
||||
// ExportDeliverSlack exposes deliverSlack for testing.
|
||||
func (e *Engine) ExportDeliverSlack(
|
||||
ctx context.Context,
|
||||
webhookDB *gorm.DB,
|
||||
d *database.Delivery,
|
||||
) {
|
||||
e.deliverSlack(ctx, webhookDB, d)
|
||||
}
|
||||
|
||||
// ExportProcessNewTask exposes processNewTask.
|
||||
func (e *Engine) ExportProcessNewTask(
|
||||
ctx context.Context, task *Task,
|
||||
) {
|
||||
e.processNewTask(ctx, task)
|
||||
}
|
||||
|
||||
// ExportProcessRetryTask exposes processRetryTask.
|
||||
func (e *Engine) ExportProcessRetryTask(
|
||||
ctx context.Context, task *Task,
|
||||
) {
|
||||
e.processRetryTask(ctx, task)
|
||||
}
|
||||
|
||||
// ExportProcessDelivery exposes processDelivery.
|
||||
func (e *Engine) ExportProcessDelivery(
|
||||
ctx context.Context,
|
||||
webhookDB *gorm.DB,
|
||||
d *database.Delivery,
|
||||
task *Task,
|
||||
) {
|
||||
e.processDelivery(ctx, webhookDB, d, task)
|
||||
}
|
||||
|
||||
// ExportGetCircuitBreaker exposes getCircuitBreaker.
|
||||
func (e *Engine) ExportGetCircuitBreaker(
|
||||
targetID string,
|
||||
) *CircuitBreaker {
|
||||
return e.getCircuitBreaker(targetID)
|
||||
}
|
||||
|
||||
// ExportParseHTTPConfig exposes parseHTTPConfig.
|
||||
func (e *Engine) ExportParseHTTPConfig(
|
||||
configJSON string,
|
||||
) (*HTTPTargetConfig, error) {
|
||||
return e.parseHTTPConfig(configJSON)
|
||||
}
|
||||
|
||||
// ExportParseSlackConfig exposes parseSlackConfig.
|
||||
func (e *Engine) ExportParseSlackConfig(
|
||||
configJSON string,
|
||||
) (*SlackTargetConfig, error) {
|
||||
return e.parseSlackConfig(configJSON)
|
||||
}
|
||||
|
||||
// ExportDoHTTPRequest exposes doHTTPRequest.
|
||||
func (e *Engine) ExportDoHTTPRequest(
|
||||
ctx context.Context,
|
||||
cfg *HTTPTargetConfig,
|
||||
event *database.Event,
|
||||
) (int, string, int64, error) {
|
||||
return e.doHTTPRequest(ctx, cfg, event)
|
||||
}
|
||||
|
||||
// ExportScheduleRetry exposes scheduleRetry.
|
||||
func (e *Engine) ExportScheduleRetry(
|
||||
task Task, delay time.Duration,
|
||||
) {
|
||||
e.scheduleRetry(task, delay)
|
||||
}
|
||||
|
||||
// ExportRecoverPendingDeliveries exposes
|
||||
// recoverPendingDeliveries.
|
||||
func (e *Engine) ExportRecoverPendingDeliveries(
|
||||
ctx context.Context,
|
||||
webhookDB *gorm.DB,
|
||||
webhookID string,
|
||||
) {
|
||||
e.recoverPendingDeliveries(
|
||||
ctx, webhookDB, webhookID,
|
||||
)
|
||||
}
|
||||
|
||||
// ExportRecoverWebhookDeliveries exposes
|
||||
// recoverWebhookDeliveries.
|
||||
func (e *Engine) ExportRecoverWebhookDeliveries(
|
||||
ctx context.Context, webhookID string,
|
||||
) {
|
||||
e.recoverWebhookDeliveries(ctx, webhookID)
|
||||
}
|
||||
|
||||
// ExportRecoverInFlight exposes recoverInFlight.
|
||||
func (e *Engine) ExportRecoverInFlight(
|
||||
ctx context.Context,
|
||||
) {
|
||||
e.recoverInFlight(ctx)
|
||||
}
|
||||
|
||||
// ExportStart exposes start for testing.
|
||||
func (e *Engine) ExportStart(ctx context.Context) {
|
||||
e.start(ctx)
|
||||
}
|
||||
|
||||
// ExportStop exposes stop for testing.
|
||||
func (e *Engine) ExportStop() {
|
||||
e.stop()
|
||||
}
|
||||
|
||||
// ExportDeliveryCh returns the delivery channel.
|
||||
func (e *Engine) ExportDeliveryCh() chan Task {
|
||||
return e.deliveryCh
|
||||
}
|
||||
|
||||
// ExportRetryCh returns the retry channel.
|
||||
func (e *Engine) ExportRetryCh() chan Task {
|
||||
return e.retryCh
|
||||
}
|
||||
|
||||
// NewTestEngine creates an Engine for unit tests without
|
||||
// database dependencies.
|
||||
func NewTestEngine(
|
||||
log *slog.Logger,
|
||||
client *http.Client,
|
||||
workers int,
|
||||
) *Engine {
|
||||
return &Engine{
|
||||
log: log,
|
||||
client: client,
|
||||
deliveryCh: make(chan Task, deliveryChannelSize),
|
||||
retryCh: make(chan Task, retryChannelSize),
|
||||
workers: workers,
|
||||
}
|
||||
}
|
||||
|
||||
// NewTestEngineSmallRetry creates an Engine with a tiny
|
||||
// retry channel buffer for overflow testing.
|
||||
func NewTestEngineSmallRetry(
|
||||
log *slog.Logger,
|
||||
) *Engine {
|
||||
return &Engine{
|
||||
log: log,
|
||||
retryCh: make(chan Task, 1),
|
||||
}
|
||||
}
|
||||
|
||||
// NewTestEngineWithDB creates an Engine with a real
|
||||
// database and dbManager for integration tests.
|
||||
func NewTestEngineWithDB(
|
||||
db *database.Database,
|
||||
dbMgr *database.WebhookDBManager,
|
||||
log *slog.Logger,
|
||||
client *http.Client,
|
||||
workers int,
|
||||
) *Engine {
|
||||
return &Engine{
|
||||
database: db,
|
||||
dbManager: dbMgr,
|
||||
log: log,
|
||||
client: client,
|
||||
deliveryCh: make(chan Task, deliveryChannelSize),
|
||||
retryCh: make(chan Task, retryChannelSize),
|
||||
workers: workers,
|
||||
}
|
||||
}
|
||||
|
||||
// NewTestCircuitBreaker creates a CircuitBreaker with
|
||||
// custom settings for testing.
|
||||
func NewTestCircuitBreaker(
|
||||
threshold int, cooldown time.Duration,
|
||||
) *CircuitBreaker {
|
||||
return &CircuitBreaker{
|
||||
state: CircuitClosed,
|
||||
threshold: threshold,
|
||||
cooldown: cooldown,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user