builder/build/dockerfile_build_test.go
Rama main · réplica de lectura del repositorio original.
package build
import (
"reflect"
"strings"
"testing"
)
// capability_id: rainbond.dockerfile-build.proxy-env-inheritance
func TestBuildKitProxyEnvVars(t *testing.T) {
tests := []struct {
name string
env map[string]string
want map[string]string
}{
{
name: "inherits configured proxy variables only",
env: map[string]string{
"HTTP_PROXY": "http://proxy.example:8080",
"HTTPS_PROXY": "http://proxy.example:8443",
"NO_PROXY": "localhost,127.0.0.1",
"UNRELATED_ENV": "must-not-be-propagated",
},
want: map[string]string{
"HTTP_PROXY": "http://proxy.example:8080",
"HTTPS_PROXY": "http://proxy.example:8443",
"NO_PROXY": "localhost,127.0.0.1",
},
},
{
name: "leaves buildkit environment unchanged without proxy configuration",
env: map[string]string{
"UNRELATED_ENV": "must-not-be-propagated",
},
want: map[string]string{},
},
{
name: "skips empty proxy variables",
env: map[string]string{
"HTTP_PROXY": "http://proxy.example:8080",
"HTTPS_PROXY": "",
"NO_PROXY": "",
},
want: map[string]string{
"HTTP_PROXY": "http://proxy.example:8080",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
for _, name := range []string{"HTTP_PROXY", "HTTPS_PROXY", "NO_PROXY"} {
t.Setenv(name, "")
}
for name, value := range tt.env {
t.Setenv(name, value)
}
got := make(map[string]string)
for _, env := range buildKitProxyEnvVars() {
got[env.Name] = env.Value
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("buildKitProxyEnvVars() = %#v, want %#v", got, tt.want)
}
})
}
}
// TestLocalBuildKitCacheArgsContainServiceID 验证生成的本地 layer cache 参数
// 使用 buildctl 的 --import-cache / --export-cache(而非 buildx 的
// --cache-from / --cache-to),且缓存路径包含 serviceID。
func TestLocalBuildKitCacheArgsContainServiceID(t *testing.T) {
const serviceID = "svc-abc123"
args := localBuildKitCacheArgs(serviceID)
for _, invalid := range []string{"--cache-from", "--cache-to"} {
for _, a := range args {
if a == invalid {
t.Errorf("args contain %q, which buildctl does not support", invalid)
}
}
}
from := flagValue(t, args, "--import-cache")
to := flagValue(t, args, "--export-cache")
wantDir := "/cache/buildkit/" + serviceID
if !strings.Contains(from, wantDir) {
t.Errorf("--import-cache %q does not contain cache dir %q", from, wantDir)
}
if !strings.Contains(to, wantDir) {
t.Errorf("--export-cache %q does not contain cache dir %q", to, wantDir)
}
if !strings.Contains(from, "type=local") || !strings.Contains(from, "src=") {
t.Errorf("--import-cache %q is not a local source spec", from)
}
if !strings.Contains(to, "type=local") || !strings.Contains(to, "dest=") || !strings.Contains(to, "mode=max") {
t.Errorf("--export-cache %q is not a local mode=max dest spec", to)
}
}
// flagValue 返回 args 中紧跟在 flag 之后的值,找不到则 fail。
func flagValue(t *testing.T, args []string, flag string) string {
t.Helper()
for i, a := range args {
if a == flag {
if i+1 >= len(args) {
t.Fatalf("flag %q has no following value in args %#v", flag, args)
}
return args[i+1]
}
}
t.Fatalf("flag %q not found in args %#v", flag, args)
return ""
}