Skip to content

Commit

Permalink
adding tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sudosammy committed Apr 14, 2024
1 parent 0462a8d commit 0a34684
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 52 deletions.
13 changes: 7 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,18 @@ require (
github.com/joho/godotenv v1.5.1
github.com/miekg/dns v1.1.58
github.com/radovskyb/watcher v1.0.7
golang.org/x/net v0.22.0
golang.org/x/net v0.24.0
)

require (
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/go-jose/go-jose/v4 v4.0.1 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
golang.org/x/crypto v0.21.0 // indirect
golang.org/x/mod v0.16.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/crypto v0.22.0 // indirect
golang.org/x/mod v0.17.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/tools v0.19.0 // indirect
golang.org/x/tools v0.20.0 // indirect
)
14 changes: 14 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
Expand Down Expand Up @@ -29,19 +31,31 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic=
golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw=
golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc=
golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY=
golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
78 changes: 39 additions & 39 deletions libknary/dns_test.go
Original file line number Diff line number Diff line change
@@ -1,56 +1,56 @@
package libknary

import (
"github.com/miekg/dns"
"net"
"os"
"strings"
"sync"
"testing"
"time"
)

// code for 3 functions below here is taken and modified from
// here: https://github.com/miekg/dns/blob/67373879ce327b5fd112d9301d0a4d62bad6b904/server_test.go
func GokuServer(w dns.ResponseWriter, req *dns.Msg) {
m := new(dns.Msg)
m.SetReply(req)

//no idea why m.Extra doesnt work but m.Answer does
//m.Extra = make([]dns.RR, 1)
m.Answer = make([]dns.RR, 1)
m.Answer[0] = &dns.A{Hdr: dns.RR_Header{Name: m.Question[0].Name, Rrtype: dns.TypeA, Class: dns.ClassANY}, A: net.IPv4(127, 0, 0, 1)}
w.WriteMsg(m)
}
"github.com/miekg/dns"
)

func RunLocalUDPServer(laddr string) (*dns.Server, string, error) {
server, l, _, err := RunLocalUDPServerWithFinChan(laddr)
func TestAcceptDNS(t *testing.T) {
// Set up test environment
os.Setenv("BIND_ADDR", "127.0.0.1")

return server, l, err
}
// Skip test if user can't bind to port 53
server := &dns.Server{Addr: os.Getenv("BIND_ADDR") + ":53", Net: "udp"}
err := server.ListenAndServe()

func RunLocalUDPServerWithFinChan(laddr string, opts ...func(*dns.Server)) (*dns.Server, string, chan error, error) {
pc, err := net.ListenPacket("udp", laddr)
if err != nil {
return nil, "", nil, err
// If err contains "permission denied", skip the test
if err != nil && strings.Contains(err.Error(), "permission denied") {
t.Skip("Test requires root privileges")
}
server := &dns.Server{PacketConn: pc, ReadTimeout: time.Hour, WriteTimeout: time.Hour}

waitLock := sync.Mutex{}
waitLock.Lock()
server.NotifyStartedFunc = waitLock.Unlock
// Create a wait group to synchronize goroutines
var wg sync.WaitGroup
wg.Add(1)

// fin must be buffered so the goroutine below won't block
// forever if fin is never read from. This always happens
// in RunLocalUDPServer and can happen in TestShutdownUDP.
fin := make(chan error, 1)
// Start the DNS server in a goroutine
go AcceptDNS(&wg)

for _, opt := range opts {
opt(server)
// Wait for the DNS server to start
time.Sleep(time.Second)

// Send a DNS query to the server
m := new(dns.Msg)
m.SetQuestion("example.com.", dns.TypeA)
c := new(dns.Client)
_, _, err = c.Exchange(m, "127.0.0.1")
if err != nil {
t.Errorf("Failed to send DNS query: %v", err)
}

go func() {
fin <- server.ActivateAndServe()
pc.Close()
}()
// Wait for the DNS server to finish
wg.Wait()
}

func TestInfoLog(t *testing.T) {
ipaddr := "127.0.0.1"
reverse := "example.com"
name := "example"
infoLog(ipaddr, reverse, name)

waitLock.Lock()
return server, pc.LocalAddr().String(), fin, nil
// There are no assertions in this test at the moment
}
31 changes: 31 additions & 0 deletions libknary/webhooks_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package libknary

import (
"net/http"
"net/http/httptest"
"os"
"testing"
)

func TestSendMsg(t *testing.T) {
// Create a test server to capture HTTP requests
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Verify the request URL and method
switch r.URL.String() {
case "/":
if r.Method != http.MethodPost {
t.Errorf("Expected POST request for Slack webhook, got %s", r.Method)
}
default:
t.Errorf("Unexpected request to URL: %s", r.URL.String())
}
}))

defer server.Close()

// Override the Slack webhook URL with the test server URL
os.Setenv("SLACK_WEBHOOK", server.URL)

// SLACK_WEBHOOK is set
sendMsg("Test message for Slack")
}
18 changes: 12 additions & 6 deletions libknary/zones.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package libknary
import (
"bufio"
"fmt"
"log"
"os"
"strconv"
"strings"
Expand Down Expand Up @@ -44,11 +43,8 @@ func LoadZone() (bool, error) {
}

if err := zp.Err(); err != nil {
if err != nil {
logger("ERROR", err.Error())
GiveHead(2)
log.Fatal(err)
}
logger("ERROR", err.Error())
return false, err
}

Printy("Monitoring "+strconv.Itoa(zoneCounter)+" items in zone", 1)
Expand All @@ -57,6 +53,11 @@ func LoadZone() (bool, error) {
}

func inZone(needle string, qType uint16) (map[int]dns.RR, bool) {
// if last character of needle isn't a period, add it
if needle[len(needle)-1] != '.' {
needle += "."
}

if val, ok := zoneMap[strings.ToLower(needle)]; ok {
// this (sub)domain is present in the zone file
// confirm whether one or many match the qType
Expand Down Expand Up @@ -102,6 +103,11 @@ func addZone(fqdn string, ttl int, qType string, value string) error {
}

func remZone(fqdn string) {
// if last character of fqdn isn't a period, add it
if fqdn[len(fqdn)-1] != '.' {
fqdn += "."
}

// this is pretty dodgy.
// we're hoping that the last zone added to the map is the one we want to delete
lastVal := len(zoneMap[fqdn]) - 1
Expand Down
81 changes: 81 additions & 0 deletions libknary/zones_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package libknary
import (
"os"
"testing"

"github.com/miekg/dns"
)

func TestLoadZone_WhenZoneFileExists_ReturnsTrueAndNoError(t *testing.T) {
Expand All @@ -22,6 +24,24 @@ func TestLoadZone_WhenZoneFileExists_ReturnsTrueAndNoError(t *testing.T) {
}
}

func TestLoadZone_WhenZoneFileInvalid_ReturnsError(t *testing.T) {
os.Setenv("ZONE_FILE", ".zone_test.txt")
// No trailing period
if err := os.WriteFile(".zone_test.txt", []byte("example.com IN A 192.0.2.1"), 0644); err != nil {
t.Fatal(err)
}
defer os.Remove(".zone_test.txt")

result, err := LoadZone()

if err == nil {
t.Errorf("Expected an error")
}
if result == true {
t.Error("Expected result to be false")
}
}

func TestLoadZone_WhenZoneFileDoesNotExist_ReturnsFalseAndError(t *testing.T) {
os.Setenv("ZONE_FILE", "nonexistent.txt")

Expand Down Expand Up @@ -50,3 +70,64 @@ func TestAddZone_WhenInvalidInput_ReturnsError(t *testing.T) {
t.Error("Expected an error")
}
}

func TestInZone_WhenZoneExists_ReturnsNoError(t *testing.T) {
fqdn := "example.com"
addZone(fqdn, 3600, "A", "192.0.2.1")

rr, foundInZone := inZone(fqdn, dns.TypeA)

if rr == nil {
t.Error("Expected RR not found")
}

if foundInZone != true {
t.Error("Expected zone not found")
}
}

func TestInZone_WhenZoneDoesNotExist_ReturnsNoError(t *testing.T) {
rr, foundInZone := inZone("not-exists.com", dns.TypeA)

if rr != nil {
t.Error("Unexpected RR found")
}

if foundInZone != false {
t.Error("Unexpected zone found")
}
}

func TestRemZone_WhenZoneExists_DeletesZoneAndReturnsNoError(t *testing.T) {
fqdn := "another-example.com"
err := addZone(fqdn, 3600, "A", "192.0.2.1")

if err != nil {
t.Errorf("Unexpected error: %v", err)
}

remZone(fqdn)

// Check if zone is deleted
_, foundInZone := inZone(fqdn, dns.TypeA)
if foundInZone == true {
t.Error("Expected zone not deleted")
}
}

func TestRemZone_WhenZoneDoesNotExist_DoesNotDeleteZoneAndReturnsNoError(t *testing.T) {
fqdn := "another-example.com"
err := addZone(fqdn, 3600, "A", "192.0.2.2")

if err != nil {
t.Errorf("Unexpected error: %v", err)
}

remZone("not-exists.com")

// Check if zone is not deleted
_, foundInZone := inZone(fqdn, dns.TypeA)
if foundInZone != true {
t.Error("Unexpected zone deleted")
}
}
9 changes: 8 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,14 @@ func main() {
// load lists, zone file & submit usage
libknary.LoadAllowlist()
libknary.LoadBlacklist()
libknary.LoadZone()

_, err = libknary.LoadZone()
if err != nil {
libknary.Printy("Error in zone file entries", 2)
libknary.GiveHead(2)
log.Fatal(err)
}

go libknary.UsageStats(VERSION)

if os.Getenv("HTTP") == "true" && os.Getenv("LETS_ENCRYPT") == "" && (os.Getenv("TLS_CRT") == "" || os.Getenv("TLS_KEY") == "") {
Expand Down

0 comments on commit 0a34684

Please sign in to comment.