Files
headscale/tools/bump/images_test.go
T
Kristoffer Dalby 08c7ca0fa2 tools/bump: bump the remaining container base images
Debian is resolved from the numeric tags, which exist only for released
versions: forky-slim is published today and is testing. Distroless
follows that same release rather than its own repository names, since
gcr answers for base-debian99 as readily as for base-debian13.
2026-09-25 15:52:26 +02:00

116 lines
2.8 KiB
Go

package main
import (
"regexp"
"testing"
)
func TestImageRefPatterns(t *testing.T) {
tests := []struct {
name string
content string
want string
bumped string
}{
{
name: "alpine",
content: "FROM alpine:3.23\nRUN true\n",
want: "3.23",
bumped: "FROM alpine:3.24\nRUN true\n",
},
{
name: "debian slim",
content: "FROM debian:trixie-slim\n",
want: "trixie-slim",
bumped: "FROM debian:3.24\n",
},
{
name: "node alpine",
content: "FROM node:24-alpine\n",
want: "24-alpine",
bumped: "FROM node:3.24\n",
},
{
// The Rust tag folds the version and the Debian codename together,
// so it has to be captured and replaced as one value.
name: "rust on debian",
content: "FROM rust:1.95-trixie AS builder\n",
want: "1.95-trixie",
bumped: "FROM rust:3.24 AS builder\n",
},
}
refs := map[string]*regexp.Regexp{
"alpine": alpineRef,
"debian slim": debianRef,
"node alpine": nodeRef,
"rust on debian": rustRef,
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
re := refs[test.name]
m := re.FindStringSubmatch(test.content)
if m == nil {
t.Fatalf("pattern did not match %q", test.content)
}
if m[2] != test.want {
t.Errorf("captured %q, want %q", m[2], test.want)
}
if got := re.ReplaceAllString(test.content, "${1}3.24"); got != test.bumped {
t.Errorf("rewrite = %q, want %q", got, test.bumped)
}
})
}
}
// The Rust builder and the runtime stage live in the same file; matching the
// wrong one would rewrite a Debian tag with a Rust version.
func TestImageRefsDoNotCrossMatch(t *testing.T) {
const tailscaleRS = "FROM rust:1.95-trixie AS builder\nRUN true\nFROM debian:trixie-slim\n"
if got := rustRef.FindStringSubmatch(tailscaleRS)[2]; got != "1.95-trixie" {
t.Errorf("rustRef captured %q", got)
}
if got := debianRef.FindStringSubmatch(tailscaleRS)[2]; got != "trixie-slim" {
t.Errorf("debianRef captured %q", got)
}
}
func TestDistrolessRef(t *testing.T) {
const goreleaser = " base_image: gcr.io/distroless/base-debian13\n" +
" base_image: gcr.io/distroless/base-debian13:debug\n"
got := distrolessRef.ReplaceAllString(goreleaser, "${1}14")
want := " base_image: gcr.io/distroless/base-debian14\n" +
" base_image: gcr.io/distroless/base-debian14:debug\n"
if got != want {
t.Errorf("rewrite =\n%q\nwant\n%q", got, want)
}
}
func TestIsEvenMajor(t *testing.T) {
tests := []struct {
in string
want bool
}{
{in: "24", want: true},
{in: "26", want: true},
{in: "25"},
{in: "lts"},
}
for _, test := range tests {
t.Run(test.in, func(t *testing.T) {
if got := isEvenMajor(test.in); got != test.want {
t.Errorf("isEvenMajor(%q) = %v, want %v", test.in, got, test.want)
}
})
}
}