Skip to content

Commit

Permalink
update dns tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Tommi2Day committed Sep 4, 2024
1 parent 788fd1a commit d4be938
Show file tree
Hide file tree
Showing 10 changed files with 322 additions and 219 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Go Library

## [v1.14.10 - 2024-09-04]
### Changed
- update dns tests

## [v1.14.9 - 2024-08-31]
### Changed
- dns test docker creation error handling
Expand Down
230 changes: 134 additions & 96 deletions dblib/tns_dns_docker_test.go
Original file line number Diff line number Diff line change
@@ -1,159 +1,197 @@
package dblib

import (
"context"
"fmt"
"net"
"os"
"time"

"github.com/tommi2day/gomodules/common"
"github.com/tommi2day/gomodules/netlib"
"github.com/tommi2day/gomodules/test"

"github.com/ory/dockertest/v3"
"github.com/ory/dockertest/v3/docker"
"github.com/tommi2day/gomodules/common"
)

"github.com/tommi2day/gomodules/test"
const (
dblibDNSContainerTimeout = 10
dblibNetworkName = "dblib-dns"
dblibNetworkPrefix = "172.24.0"
dblibRepoTag = "9.20"
dblibDNSPort = 9054
dblibTestAddr = racaddr
)

var (
dblibDNSContainerName string
dblibDNSContainer *dockertest.Resource
dblibDNSNetwork *dockertest.Network
dblibDNSNetworkCreated = false
dblibDNSServer = "127.0.0.1"
)

const dblibDNSContainerTimeout = 10
const dblibNetworkName = "dblib-dns"
const dblibNetworkPrefix = "172.24.0"
const dblibRepoTag = "9.20"

var dblibDNSContainerName string
var dblibDNSContainer *dockertest.Resource
var dblibDNSNetwork *dockertest.Network
var dblibNetworkCreated = false
var dblibDNSServer = ""
var dblibDNSPort = 0

// prepareDNSContainer create a Bind9 Docker Container
func prepareDNSContainer() (container *dockertest.Resource, err error) {
if os.Getenv("SKIP_DNS") != "" {
err = fmt.Errorf("skipping DNS Container in CI environment")
// prepareDBlibDNSContainer create a Bind9 Docker Container
func prepareDBlibDNSContainer() (container *dockertest.Resource, err error) {
if os.Getenv("SKIP_DB_DNS") != "" {
return nil, fmt.Errorf("skipping DB DNS Container in CI environment")
}

dblibDNSContainerName = getContainerName()
pool, err := common.GetDockerPool()
if err != nil {
return nil, err
}

err = setupNetwork(pool)
if err != nil {
return nil, err
}

container, err = buildAndRunContainer(pool)
if err != nil {
return
}
dblibDNSContainerName = os.Getenv("DNS_CONTAINER_NAME")
if dblibDNSContainerName == "" {
dblibDNSContainerName = "dblib-bind9"

time.Sleep(10 * time.Second)

err = validateContainerIP(container)
if err != nil {
return
}
var pool *dockertest.Pool
pool, err = common.GetDockerPool()

err = waitForDNSServer(pool)
if err != nil {
return
}

err = testDNSResolution()
return
}

func getContainerName() string {
name := os.Getenv("DBDNS_CONTAINER_NAME")
if name == "" {
name = "dblib-bind9"
}
return name
}

func setupNetwork(pool *dockertest.Pool) error {
networks, err := pool.NetworksByName(dblibNetworkName)
if err != nil || len(networks) == 0 {
dblibDNSNetwork, err = pool.CreateNetwork(dblibNetworkName, func(options *docker.CreateNetworkOptions) {
options.Name = dblibNetworkName
options.CheckDuplicate = true
options.IPAM = &docker.IPAMOptions{
Driver: "default",
Config: []docker.IPAMConfig{{
Subnet: dblibNetworkPrefix + ".0/24",
Gateway: dblibNetworkPrefix + ".1",
}},
}
options.EnableIPv6 = false
// options.Internal = true
})
if err != nil {
err = fmt.Errorf("could not create Network: %s:%s", dblibNetworkName, err)
return
return createNetwork(pool)
}
dblibDNSNetwork = &networks[0]
return nil
}

func createNetwork(pool *dockertest.Pool) error {
var err error
dblibDNSNetwork, err = pool.CreateNetwork(dblibNetworkName, func(options *docker.CreateNetworkOptions) {
options.Name = dblibNetworkName
options.CheckDuplicate = true
options.IPAM = &docker.IPAMOptions{
Driver: "default",
Config: []docker.IPAMConfig{{
Subnet: dblibNetworkPrefix + ".0/24",
Gateway: dblibNetworkPrefix + ".1",
}},
}
dblibNetworkCreated = true
} else {
dblibDNSNetwork = &networks[0]
options.EnableIPv6 = false
})
if err != nil {
return fmt.Errorf("could not create Network: %s:%s", dblibNetworkName, err)
}
dblibDNSNetworkCreated = true
return nil
}

func buildAndRunContainer(pool *dockertest.Pool) (*dockertest.Resource, error) {
vendorImagePrefix := os.Getenv("VENDOR_IMAGE_PREFIX")

fmt.Printf("Try to build and start docker container %s\n", dblibDNSContainerName)
fmt.Printf("Try to build and start docker container %s\n", dblibDNSContainerName)
buildArgs := []docker.BuildArg{
{
Name: "VENDOR_IMAGE_PREFIX",
Value: vendorImagePrefix,
},
{
Name: "BIND9_VERSION",
Value: dblibRepoTag,
},
{Name: "VENDOR_IMAGE_PREFIX", Value: vendorImagePrefix},
{Name: "BIND9_VERSION", Value: dblibRepoTag},
}
container, err = pool.BuildAndRunWithBuildOptions(

dockerContextDir := test.TestDir + "/docker/oracle-dns"
return pool.BuildAndRunWithBuildOptions(
&dockertest.BuildOptions{
BuildArgs: buildArgs,
ContextDir: test.TestDir + "/docker/oracle-dns",
ContextDir: dockerContextDir,
Dockerfile: "Dockerfile",
},
&dockertest.RunOptions{
Hostname: dblibDNSContainerName,
Name: dblibDNSContainerName,
Networks: []*dockertest.Network{dblibDNSNetwork},
ExposedPorts: []string{"53/tcp", "53/udp", "953/tcp"},
ExposedPorts: []string{"9054/tcp"},
// need fixed mapping here
PortBindings: map[docker.Port][]docker.PortBinding{
"9054/tcp": {
{HostIP: "0.0.0.0", HostPort: fmt.Sprintf("%d", dblibDNSPort)},
},
},
}, func(config *docker.HostConfig) {
// set AutoRemove to true so that stopped container goes away by itself
config.AutoRemove = true
config.AutoRemove = false
config.RestartPolicy = docker.RestartPolicy{Name: "no"}
})
}

if err != nil || container == nil {
err = fmt.Errorf("error starting oracle-dns docker container: %v", err)
return
}
// ip := container.Container.NetworkSettings.Networks[dblibNetworkName].IPAddress
func validateContainerIP(container *dockertest.Resource) error {
ip := container.GetIPInNetwork(dblibDNSNetwork)
if ip != dblibNetworkPrefix+".2" {
err = fmt.Errorf("internal ip not as expected: %s", ip)
return
}

fmt.Printf("DB DNS Container IP: %s\n", ip)
return nil
}

// func waitForDNSServer(pool *dockertest.Pool, container *dockertest.Resource) error {
func waitForDNSServer(pool *dockertest.Pool) error {
pool.MaxWait = dblibDNSContainerTimeout * time.Second
dblibDNSServer, dblibDNSPort = common.GetContainerHostAndPort(container, "53/tcp")
if dblibDNSPort == 0 || dblibDNSServer == "" {
err = fmt.Errorf("could not get host/port of dns container")
return
}
fmt.Printf("Wait to successfully connect to DNS to %s:%d (max %ds)...\n", dblibDNSServer, dblibDNSPort, dblibDNSContainerTimeout)
start := time.Now()
var c net.Conn
if err = pool.Retry(func() error {
c, err = net.Dial("tcp", fmt.Sprintf("%s:%d", dblibDNSServer, dblibDNSPort))
err := pool.Retry(func() error {
c, err := net.Dial("udp", fmt.Sprintf("%s:%d", dblibDNSServer, dblibDNSPort))
if err != nil {
fmt.Printf("Err:%s\n", err)
return err
}
return err
}); err != nil {
err = fmt.Errorf("could not connect to DNS Container: %d", err)
return
_ = c.Close()
return nil
})

if err != nil {
return fmt.Errorf("could not connect to DB DNS Container: %v", err)
}
_ = c.Close()

// wait 10s to init container
time.Sleep(10 * time.Second)
elapsed := time.Since(start)
fmt.Printf("DNS Container is available after %s\n", elapsed.Round(time.Millisecond))
if dblibDNSServer == "localhost" {
dblibDNSServer = "127.0.0.1"
}
// fmt.Printf("DNS Container is available after %s\n", elapsed.Round(time.Millisecond))
// test dns
fmt.Println("DB DNS Container is ready after ", elapsed.Round(time.Millisecond))
return nil
}

func testDNSResolution() error {
dns := netlib.NewResolver(dblibDNSServer, dblibDNSPort, true)
ips, e := dns.Resolver.LookupHost(context.Background(), racaddr)
if e != nil || len(ips) == 0 {
err = fmt.Errorf("could not resolve DNS for %s on %s:%d: %v", racaddr, dblibDNSServer, dblibDNSPort, e)
return
dns.IPv4Only = true
s := "/udp"
if dns.TCP {
s = "/tcp"
}
fmt.Println("DNS Container is ready after ", elapsed.Round(time.Millisecond), ", host ", racaddr, "resolved to", ips[0])
err = nil
return
fmt.Printf("resolve on %s:%d%s\n", dns.Nameserver, dns.Port, s)
ips, err := dns.LookupIP(dblibTestAddr)
if err != nil || len(ips) == 0 {
return fmt.Errorf("could not resolve DNS for %s: %v", dblibTestAddr, err)
}
fmt.Printf("Host %s resolved to %s\n", dblibTestAddr, ips[0])
return nil
}

func destroyDNSContainer(container *dockertest.Resource) {
if container != nil {
common.DestroyDockerContainer(container)
}

if dblibNetworkCreated && dblibDNSNetwork != nil {
if dblibDNSNetworkCreated && dblibDNSNetwork != nil {
_ = dblibDNSNetwork.Close()
}
}
21 changes: 13 additions & 8 deletions dblib/tns_dns_test.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
package dblib

import (
"fmt"
"os"
"testing"

"github.com/tommi2day/gomodules/netlib"

log "github.com/sirupsen/logrus"

"github.com/tommi2day/gomodules/common"

"github.com/tommi2day/gomodules/netlib"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

Expand All @@ -29,20 +30,24 @@ func TestMain(m *testing.M) {
var err error

test.InitTestDirs()
if os.Getenv("SKIP_DNS") != "" {
if os.Getenv("SKIP_DB_DNS") != "" {
fmt.Println("Skipping DB DNS Container in CI environment")
return
}
dblibDNSContainer, err = prepareDNSContainer()
dblibDNSServer = common.GetStringEnv("DNS_HOST", dblibDNSServer)
dblibDNSContainer, err = prepareDBlibDNSContainer()

if err != nil || dblibDNSContainer == nil {
_ = os.Setenv("SKIP_DNS", "true")
log.Errorf("prepareDNSContainer failed: %s", err)
_ = os.Setenv("SKIP_DB_DNS", "true")
log.Errorf("prepareNetlibDNSContainer failed: %s", err)
destroyDNSContainer(dblibDNSContainer)
}

code := m.Run()
destroyDNSContainer(dblibDNSContainer)
os.Exit(code)
}

func TestRACInfo(t *testing.T) {
var err error
test.InitTestDirs()
Expand All @@ -53,8 +58,8 @@ func TestRACInfo(t *testing.T) {
err = common.WriteStringToFile(tnsAdmin+"/racinfo.ini", racinfoini)
require.NoErrorf(t, err, "Create test racinfo.ini failed")

if os.Getenv("SKIP_DNS") != "" {
t.Skip("Skipping DNS testing in CI environment")
if os.Getenv("SKIP_DB_DNS") != "" {
t.Skip("Skipping DB DNS testing")
}
// use DNS from Docker
DNSConfig = netlib.NewResolver(dblibDNSServer, dblibDNSPort, true)
Expand Down
Loading

0 comments on commit d4be938

Please sign in to comment.