// Package testutil has helpers shared by tests, chiefly locating BIND's // tools so integration tests can run against the real named-checkconf, // named-checkzone, named and rndc. // // Set JARL_BIND_ROOT to a directory containing an extracted BIND // installation (usr/sbin/named, usr/bin/named-checkconf, ... and the // libraries under usr/lib/x86_64-linux-gnu) to use binaries that are not // installed system-wide. See docs/development.md. package testutil import ( "os" "os/exec" "path/filepath" "testing" "jarl/internal/bind" ) // BindBinaries holds paths to the BIND binaries. type BindBinaries struct { Named, CheckConf, CheckZone, RNDC, TSIGKeygen, Dig string Env []string } // FindBind locates the BIND binaries, or returns nil if they are missing. func FindBind() *BindBinaries { b := &BindBinaries{} if root := os.Getenv("JARL_BIND_ROOT"); root != "" { b.Named = filepath.Join(root, "usr/sbin/named") b.RNDC = filepath.Join(root, "usr/sbin/rndc") b.TSIGKeygen = filepath.Join(root, "usr/sbin/tsig-keygen") b.CheckConf = filepath.Join(root, "usr/bin/named-checkconf") b.CheckZone = filepath.Join(root, "usr/bin/named-checkzone") b.Dig = filepath.Join(root, "usr/bin/dig") libs, _ := filepath.Glob(filepath.Join(root, "usr/lib/*-linux-gnu")) if len(libs) > 0 { b.Env = []string{"LD_LIBRARY_PATH=" + libs[0]} } if _, err := os.Stat(b.CheckConf); err != nil { return nil } return b } look := func(name string) string { if p, err := exec.LookPath(name); err == nil { return p } for _, dir := range []string{"/usr/sbin", "/usr/bin", "/sbin"} { p := filepath.Join(dir, name) if _, err := os.Stat(p); err == nil { return p } } return "" } b.CheckConf = look("named-checkconf") b.CheckZone = look("named-checkzone") b.Named = look("named") b.RNDC = look("rndc") b.TSIGKeygen = look("tsig-keygen") b.Dig = look("dig") if b.CheckConf == "" || b.CheckZone == "" { return nil } return b } // BindTools returns bind.Tools using the located binaries, skipping the // test when they are not available. func BindTools(t testing.TB) *bind.Tools { t.Helper() b := FindBind() if b == nil { t.Skip("BIND tools not found (install bind9-utils or set JARL_BIND_ROOT)") } return &bind.Tools{NamedCheckConf: b.CheckConf, NamedCheckZone: b.CheckZone, RNDC: b.RNDC, Env: b.Env} }