fix dns race condition
continuous-integration/drone/pr Build is passing Details

This commit is contained in:
Elizabeth Hunt 2024-04-02 20:26:24 -06:00
parent ce393a5ac1
commit 385d4a84eb
Signed by: simponic
GPG Key ID: 2909B9A7FF6213EE
2 changed files with 34 additions and 22 deletions

View File

@ -12,7 +12,7 @@ steps:
trigger: trigger:
event: event:
- push - pull_request
--- ---
kind: pipeline kind: pipeline
@ -20,6 +20,11 @@ type: docker
name: deploy name: deploy
steps: steps:
- name: run tests
image: golang
commands:
- go build
- go test -p 1 -v ./...
- name: docker - name: docker
image: plugins/docker image: plugins/docker
settings: settings:

View File

@ -21,10 +21,10 @@ func destroy(conn *sql.DB, path string) {
} }
func randomPort() int { func randomPort() int {
return rand.Intn(3000) + 10000 return rand.Intn(3000) + 1024
} }
func setup() (*sql.DB, *dns.Server, int, *string, func()) { func setup() (*sql.DB, *dns.Server, *string, *sync.Mutex, func()) {
randomDb := utils.RandomId() randomDb := utils.RandomId()
dnsPort := randomPort() dnsPort := randomPort()
@ -35,32 +35,35 @@ func setup() (*sql.DB, *dns.Server, int, *string, func()) {
} }
database.FindOrSaveUser(testDb, testUser) database.FindOrSaveUser(testDb, testUser)
waitLock := &sync.Mutex{}
server := hcdns.MakeServer(&args.Arguments{ server := hcdns.MakeServer(&args.Arguments{
DnsPort: dnsPort, DnsPort: dnsPort,
}, testDb) }, testDb)
server.NotifyStartedFunc = func() {
waitLock.Unlock()
}
waitLock.Lock()
waitGroup := sync.WaitGroup{}
waitGroup.Add(1)
go func() { go func() {
server.ListenAndServe() server.ListenAndServe()
waitGroup.Done()
}() }()
waitLock.Lock()
address := fmt.Sprintf("127.0.0.1:%d", dnsPort) address := fmt.Sprintf("127.0.0.1:%d", dnsPort)
return testDb, server, dnsPort, &address, func() { return testDb, server, &address, waitLock, func() {
server.Shutdown()
testDb.Close() testDb.Close()
os.Remove(randomDb) os.Remove(randomDb)
server.Shutdown()
waitGroup.Wait()
} }
} }
func TestWhenCNAMEIsResolved(t *testing.T) { func TestWhenCNAMEIsResolved(t *testing.T) {
t.Log("TestWhenCNAMEIsResolved") t.Log("TestWhenCNAMEIsResolved")
testDb, _, _, addr, cleanup := setup() testDb, _, addr, lock, cleanup := setup()
defer cleanup() defer cleanup()
defer lock.Unlock()
cname := &database.DNSRecord{ cname := &database.DNSRecord{
ID: "1", ID: "1",
@ -85,8 +88,8 @@ func TestWhenCNAMEIsResolved(t *testing.T) {
qtype := dns.TypeA qtype := dns.TypeA
domain := dns.Fqdn(cname.Name) domain := dns.Fqdn(cname.Name)
client := new(dns.Client) client := &dns.Client{}
message := new(dns.Msg) message := &dns.Msg{}
message.SetQuestion(domain, qtype) message.SetQuestion(domain, qtype)
in, _, err := client.Exchange(message, *addr) in, _, err := client.Exchange(message, *addr)
@ -135,13 +138,14 @@ func TestWhenCNAMEIsResolved(t *testing.T) {
func TestWhenNoRecordNxDomain(t *testing.T) { func TestWhenNoRecordNxDomain(t *testing.T) {
t.Log("TestWhenNoRecordNxDomain") t.Log("TestWhenNoRecordNxDomain")
_, _, _, addr, cleanup := setup() _, _, addr, lock, cleanup := setup()
defer cleanup() defer cleanup()
defer lock.Unlock()
qtype := dns.TypeA qtype := dns.TypeA
domain := dns.Fqdn("nonexistant.example.com.") domain := dns.Fqdn("nonexistant.example.com.")
client := new(dns.Client) client := &dns.Client{}
message := new(dns.Msg) message := &dns.Msg{}
message.SetQuestion(domain, qtype) message.SetQuestion(domain, qtype)
in, _, err := client.Exchange(message, *addr) in, _, err := client.Exchange(message, *addr)
@ -162,8 +166,9 @@ func TestWhenNoRecordNxDomain(t *testing.T) {
func TestWhenUnresolvingCNAME(t *testing.T) { func TestWhenUnresolvingCNAME(t *testing.T) {
t.Log("TestWhenUnresolvingCNAME") t.Log("TestWhenUnresolvingCNAME")
testDb, _, _, addr, cleanup := setup() testDb, _, addr, lock, cleanup := setup()
defer cleanup() defer cleanup()
defer lock.Unlock()
cname := &database.DNSRecord{ cname := &database.DNSRecord{
ID: "1", ID: "1",
@ -178,8 +183,8 @@ func TestWhenUnresolvingCNAME(t *testing.T) {
qtype := dns.TypeA qtype := dns.TypeA
domain := dns.Fqdn(cname.Name) domain := dns.Fqdn(cname.Name)
client := new(dns.Client) client := &dns.Client{}
message := new(dns.Msg) message := &dns.Msg{}
message.SetQuestion(domain, qtype) message.SetQuestion(domain, qtype)
in, _, err := client.Exchange(message, *addr) in, _, err := client.Exchange(message, *addr)
@ -216,8 +221,9 @@ func TestWhenUnresolvingCNAME(t *testing.T) {
func TestWhenUnresolvingCNAMEWithMaxDepth(t *testing.T) { func TestWhenUnresolvingCNAMEWithMaxDepth(t *testing.T) {
t.Log("TestWhenUnresolvingCNAMEWithMaxDepth") t.Log("TestWhenUnresolvingCNAMEWithMaxDepth")
testDb, _, _, addr, cleanup := setup() testDb, _, addr, lock, cleanup := setup()
defer cleanup() defer cleanup()
defer lock.Unlock()
cname := &database.DNSRecord{ cname := &database.DNSRecord{
ID: "1", ID: "1",
@ -232,8 +238,8 @@ func TestWhenUnresolvingCNAMEWithMaxDepth(t *testing.T) {
qtype := dns.TypeA qtype := dns.TypeA
domain := dns.Fqdn(cname.Name) domain := dns.Fqdn(cname.Name)
client := new(dns.Client) client := &dns.Client{}
message := new(dns.Msg) message := &dns.Msg{}
message.SetQuestion(domain, qtype) message.SetQuestion(domain, qtype)
in, _, err := client.Exchange(message, *addr) in, _, err := client.Exchange(message, *addr)
@ -245,6 +251,7 @@ func TestWhenUnresolvingCNAMEWithMaxDepth(t *testing.T) {
if len(in.Answer) > 0 { if len(in.Answer) > 0 {
t.Fatalf("expected 0 answers, got %d", len(in.Answer)) t.Fatalf("expected 0 answers, got %d", len(in.Answer))
} }
if in.Rcode != dns.RcodeServerFailure { if in.Rcode != dns.RcodeServerFailure {
t.Fatalf("expected SERVFAIL, got %d", in.Rcode) t.Fatalf("expected SERVFAIL, got %d", in.Rcode)
} }