From 7f21fdee68bae3e5a04a101c2223f8a442bafb3c Mon Sep 17 00:00:00 2001 From: cemturker Date: Wed, 18 Nov 2020 18:51:22 +0100 Subject: [PATCH] Change test structure into tabledriven Review change Update README.md --- README.md | 3 ++ core/condition.go | 6 +-- core/dns.go | 4 +- core/dns_test.go | 108 +++++++++++++++++++++++++++++++++++++------ core/service_test.go | 28 ----------- 5 files changed, 102 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index 063a852d..8c82b70e 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,8 @@ Note that you can also add environment variables in the configuration file (i.e. | `services[].graphql` | Whether to wrap the body in a query param (`{"query":"$body"}`) | `false` | | `services[].body` | Request body | `""` | | `services[].headers` | Request headers | `{}` | +| `services[].dns.query-type` | Query type for DNS | `""` | +| `services[].dns.query-name` | Query name for DNS | `""` | | `services[].alerts[].type` | Type of alert. Valid types: `slack`, `pagerduty`, `twilio`, `mattermost`, `custom` | Required `""` | | `services[].alerts[].enabled` | Whether to enable the alert | `false` | | `services[].alerts[].failure-threshold` | Number of failures in a row needed before triggering the alert | `3` | @@ -164,6 +166,7 @@ Here are some examples of conditions you can use: | Placeholder | Description | Example of resolved value | |:-------------------------- |:--------------------------------------------------------------- |:------------------------- | | `[STATUS]` | Resolves into the HTTP status of the request | 404 +| `[DNS_RCODE]` | Resolves into the DNS status of the response | NOERROR | `[RESPONSE_TIME]` | Resolves into the response time the request took, in ms | 10 | `[IP]` | Resolves into the IP of the target host | 192.168.0.232 | `[BODY]` | Resolves into the response body. Supports JSONPath. | `{"name":"john.doe"}` diff --git a/core/condition.go b/core/condition.go index 1cd732a4..792b788a 100644 --- a/core/condition.go +++ b/core/condition.go @@ -20,10 +20,10 @@ const ( // Values that could replace the placeholder: 127.0.0.1, 10.0.0.1, ... IPPlaceHolder = "[IP]" - // DNSRCode is a place holder for DNS_RCODE + // DNSRCodePlaceHolder is a place holder for DNS_RCODE // // Values that could be NOERROR, FORMERR, SERVFAIL, NXDOMAIN, NOTIMP and REFUSED - DNSRCode = "[DNS_RCODE]" + DNSRCodePlaceHolder = "[DNS_RCODE]" // ResponseTimePlaceHolder is a placeholder for the request response time, in milliseconds. // @@ -148,7 +148,7 @@ func sanitizeAndResolve(list []string, result *Result) []string { element = result.IP case ResponseTimePlaceHolder: element = strconv.Itoa(int(result.Duration.Milliseconds())) - case DNSRCode: + case DNSRCodePlaceHolder: element = result.DNSRCode case BodyPlaceHolder: element = body diff --git a/core/dns.go b/core/dns.go index 7654e191..6958502e 100644 --- a/core/dns.go +++ b/core/dns.go @@ -20,7 +20,7 @@ const ( ) type DNS struct { - // QueryType is the type for the DNS records like A,AAAA, CNAME... + // QueryType is the type for the DNS records like A, AAAA, CNAME... QueryType string `yaml:"query-type"` // QueryName is the query for DNS QueryName string `yaml:"query-name"` @@ -77,7 +77,7 @@ func (d *DNS) query(url string, result *Result) { result.Body = []byte(ns.Ns) } default: - result.Body = []byte("not supported") + result.Body = []byte("query type is not supported yet") } } } diff --git a/core/dns_test.go b/core/dns_test.go index 3261c72e..a2137425 100644 --- a/core/dns_test.go +++ b/core/dns_test.go @@ -5,22 +5,102 @@ import ( ) func TestIntegrationQuery(t *testing.T) { - dns := DNS{ - QueryType: "A", - QueryName: "example.com", - } - result := &Result{} - dns.validateAndSetDefault() - dns.query("8.8.8.8", result) - if len(result.Errors) != 0 { - t.Errorf("there should be no error Errors:%v", result.Errors) + tests := []struct { + name string + inputDNS DNS + inputURL string + expectedDNSCode string + expectedBody string + }{ + { + name: "test DNS with type A", + inputDNS: DNS{ + QueryType: "A", + QueryName: "example.com", + }, + inputURL: "8.8.8.8", + expectedDNSCode: "NOERROR", + expectedBody: "93.184.216.34", + }, + { + name: "test DNS with type AAAA", + inputDNS: DNS{ + QueryType: "AAAA", + QueryName: "example.com", + }, + inputURL: "8.8.8.8", + expectedDNSCode: "NOERROR", + expectedBody: "2606:2800:220:1:248:1893:25c8:1946", + }, + { + name: "test DNS with type CNAME", + inputDNS: DNS{ + QueryType: "CNAME", + QueryName: "example.com", + }, + inputURL: "8.8.8.8", + expectedDNSCode: "NOERROR", + expectedBody: "", + }, + { + name: "test DNS with type MX", + inputDNS: DNS{ + QueryType: "MX", + QueryName: "example.com", + }, + inputURL: "8.8.8.8", + expectedDNSCode: "NOERROR", + expectedBody: ".", + }, + { + name: "test DNS with type NS", + inputDNS: DNS{ + QueryType: "NS", + QueryName: "example.com", + }, + inputURL: "8.8.8.8", + expectedDNSCode: "NOERROR", + expectedBody: "b.iana-servers.net.", + }, } - if result.DNSRCode != "NOERROR" { - t.Errorf("DNSRCode '%s' should have been NOERROR", result.DNSRCode) - } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + dns := test.inputDNS + result := &Result{} + dns.validateAndSetDefault() + dns.query(test.inputURL, result) + if len(result.Errors) != 0 { + t.Errorf("there should be no error Errors:%v", result.Errors) + } + if result.DNSRCode != test.expectedDNSCode { + t.Errorf("DNSRCodePlaceHolder '%s' should have been %s", result.DNSRCode, test.expectedDNSCode) + } - if string(result.Body) != "93.184.216.34" { - t.Errorf("expected result %s", "93.184.216.34") + if string(result.Body) != test.expectedBody { + t.Errorf("got %s, expected result %s,", string(result.Body), test.expectedBody) + } + }) } } + +func TestService_ValidateAndSetDefaultsWithNoDNSQueryName(t *testing.T) { + defer func() { recover() }() + dns := &DNS{ + QueryType: "A", + QueryName: "", + } + dns.validateAndSetDefault() + t.Fatal("Should've panicked because service`s dns didn't have a query name, which is a mandatory field for dns") +} + +func TestService_ValidateAndSetDefaultsWithInvalidDNSQueryType(t *testing.T) { + defer func() { recover() }() + dns := &DNS{ + QueryType: "B", + QueryName: "example.com", + } + dns.validateAndSetDefault() + t.Fatal("Should've panicked because service`s dns query type is invalid, it needs to be a valid query name like A, AAAA, CNAME...") +} diff --git a/core/service_test.go b/core/service_test.go index 1f00996d..ba0a5d33 100644 --- a/core/service_test.go +++ b/core/service_test.go @@ -72,34 +72,6 @@ func TestService_ValidateAndSetDefaultsWithNoConditions(t *testing.T) { t.Fatal("Should've panicked because service didn't have at least 1 condition") } -func TestService_ValidateAndSetDefaultsWithNoDNSQueryName(t *testing.T) { - defer func() { recover() }() - service := &Service{ - Name: "", - URL: "http://example.com", - DNS: &DNS{ - QueryType: "A", - QueryName: "", - }, - } - service.ValidateAndSetDefaults() - t.Fatal("Should've panicked because service`s dns didn't have a query name, which is a mandatory field for dns") -} - -func TestService_ValidateAndSetDefaultsWithInvalidDNSQueryType(t *testing.T) { - defer func() { recover() }() - service := &Service{ - Name: "", - URL: "http://example.com", - DNS: &DNS{ - QueryType: "B", - QueryName: "example.com", - }, - } - service.ValidateAndSetDefaults() - t.Fatal("Should've panicked because service`s dns query type is invalid, it needs to be a valid query name like A, AAAA, CNAME...") -} - func TestService_ValidateAndSetDefaultsWithDNS(t *testing.T) { conditionSuccess := Condition("[DNS_RCODE] == NOERROR") service := &Service{