Fix path for asset storage (#144)

Define locations for keys and secondary zones, 'n stuff.

Add a bunch of tests as well.
This commit is contained in:
Miek Gieben 2016-04-30 21:56:43 +01:00
parent e635b4e773
commit e34e414e7f
6 changed files with 277 additions and 0 deletions

28
core/dns/storage.go Normal file
View file

@ -0,0 +1,28 @@
package dns
import (
"path/filepath"
"github.com/miekg/coredns/core/assets"
)
var storage = Storage(assets.Path())
// Storage is a root directory and facilitates
// forming file paths derived from it.
type Storage string
// Zones gets the directory that stores zones data.
func (s Storage) Zones() string {
return filepath.Join(string(s), "zones")
}
// Zone returns the path to the folder containing assets for domain.
func (s Storage) Zone(domain string) string {
return filepath.Join(s.Zones(), domain)
}
// SecondaryZoneFile returns the path to domain's secondary zone file (when fetched).
func (s Storage) SecondaryZoneFile(domain string) string {
return filepath.Join(s.Zone(domain), "db."+domain)
}

20
core/dns/storage_test.go Normal file
View file

@ -0,0 +1,20 @@
package dns
import (
"path/filepath"
"testing"
)
func TestStorage(t *testing.T) {
storage = Storage("./le_test")
if expected, actual := filepath.Join("le_test", "zones"), storage.Zones(); actual != expected {
t.Errorf("Expected Zones() to return '%s' but got '%s'", expected, actual)
}
if expected, actual := filepath.Join("le_test", "zones", "test.com"), storage.Zone("test.com"); actual != expected {
t.Errorf("Expected Site() to return '%s' but got '%s'", expected, actual)
}
if expected, actual := filepath.Join("le_test", "zones", "test.com", "db.test.com"), storage.SecondaryZoneFile("test.com"); actual != expected {
t.Errorf("Expected SecondaryZoneFile() to return '%s' but got '%s'", expected, actual)
}
}

View file

@ -0,0 +1,125 @@
package msg
import "testing"
func TestSplit255(t *testing.T) {
xs := split255("abc")
if len(xs) != 1 && xs[0] != "abc" {
t.Errorf("Failure to split abc")
}
s := ""
for i := 0; i < 255; i++ {
s += "a"
}
xs = split255(s)
if len(xs) != 1 && xs[0] != s {
t.Errorf("failure to split 255 char long string")
}
s += "b"
xs = split255(s)
if len(xs) != 2 || xs[1] != "b" {
t.Errorf("failure to split 256 char long string: %d", len(xs))
}
for i := 0; i < 255; i++ {
s += "a"
}
xs = split255(s)
if len(xs) != 3 || xs[2] != "a" {
t.Errorf("failure to split 510 char long string: %d", len(xs))
}
}
func TestGroup(t *testing.T) {
// Key are in the wrong order, but for this test it does not matter.
sx := Group(
[]Service{
{Host: "127.0.0.1", Group: "g1", Key: "b/sub/dom1/skydns/test"},
{Host: "127.0.0.2", Group: "g2", Key: "a/dom1/skydns/test"},
},
)
// Expecting to return the shortest key with a Group attribute.
if len(sx) != 1 {
t.Fatalf("failure to group zeroth set: %v", sx)
}
if sx[0].Key != "a/dom1/skydns/test" {
t.Fatalf("failure to group zeroth set: %v, wrong Key", sx)
}
// Groups disagree, so we will not do anything.
sx = Group(
[]Service{
{Host: "server1", Group: "g1", Key: "region1/skydns/test"},
{Host: "server2", Group: "g2", Key: "region1/skydns/test"},
},
)
if len(sx) != 2 {
t.Fatalf("failure to group first set: %v", sx)
}
// Group is g1, include only the top-level one.
sx = Group(
[]Service{
{Host: "server1", Group: "g1", Key: "a/dom/region1/skydns/test"},
{Host: "server2", Group: "g2", Key: "a/subdom/dom/region1/skydns/test"},
},
)
if len(sx) != 1 {
t.Fatalf("failure to group second set: %v", sx)
}
// Groupless services must be included.
sx = Group(
[]Service{
{Host: "server1", Group: "g1", Key: "a/dom/region1/skydns/test"},
{Host: "server2", Group: "g2", Key: "a/subdom/dom/region1/skydns/test"},
{Host: "server2", Group: "", Key: "b/subdom/dom/region1/skydns/test"},
},
)
if len(sx) != 2 {
t.Fatalf("failure to group third set: %v", sx)
}
// Empty group on the highest level: include that one also.
sx = Group(
[]Service{
{Host: "server1", Group: "g1", Key: "a/dom/region1/skydns/test"},
{Host: "server1", Group: "", Key: "b/dom/region1/skydns/test"},
{Host: "server2", Group: "g2", Key: "a/subdom/dom/region1/skydns/test"},
},
)
if len(sx) != 2 {
t.Fatalf("failure to group fourth set: %v", sx)
}
// Empty group on the highest level: include that one also, and the rest.
sx = Group(
[]Service{
{Host: "server1", Group: "g5", Key: "a/dom/region1/skydns/test"},
{Host: "server1", Group: "", Key: "b/dom/region1/skydns/test"},
{Host: "server2", Group: "g5", Key: "a/subdom/dom/region1/skydns/test"},
},
)
if len(sx) != 3 {
t.Fatalf("failure to group fith set: %v", sx)
}
// One group.
sx = Group(
[]Service{
{Host: "server1", Group: "g6", Key: "a/dom/region1/skydns/test"},
},
)
if len(sx) != 1 {
t.Fatalf("failure to group sixth set: %v", sx)
}
// No group, once service
sx = Group(
[]Service{
{Host: "server1", Key: "a/dom/region1/skydns/test"},
},
)
if len(sx) != 1 {
t.Fatalf("failure to group seventh set: %v", sx)
}
}

View file

@ -0,0 +1,85 @@
/*
Copyright 2012 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package singleflight
import (
"errors"
"fmt"
"sync"
"sync/atomic"
"testing"
"time"
)
func TestDo(t *testing.T) {
var g Group
v, err := g.Do("key", func() (interface{}, error) {
return "bar", nil
})
if got, want := fmt.Sprintf("%v (%T)", v, v), "bar (string)"; got != want {
t.Errorf("Do = %v; want %v", got, want)
}
if err != nil {
t.Errorf("Do error = %v", err)
}
}
func TestDoErr(t *testing.T) {
var g Group
someErr := errors.New("Some error")
v, err := g.Do("key", func() (interface{}, error) {
return nil, someErr
})
if err != someErr {
t.Errorf("Do error = %v; want someErr", err)
}
if v != nil {
t.Errorf("unexpected non-nil value %#v", v)
}
}
func TestDoDupSuppress(t *testing.T) {
var g Group
c := make(chan string)
var calls int32
fn := func() (interface{}, error) {
atomic.AddInt32(&calls, 1)
return <-c, nil
}
const n = 10
var wg sync.WaitGroup
for i := 0; i < n; i++ {
wg.Add(1)
go func() {
v, err := g.Do("key", fn)
if err != nil {
t.Errorf("Do error: %v", err)
}
if v.(string) != "bar" {
t.Errorf("got %q; want %q", v, "bar")
}
wg.Done()
}()
}
time.Sleep(100 * time.Millisecond) // let goroutines above block
c <- "bar"
wg.Wait()
if got := atomic.LoadInt32(&calls); got != 1 {
t.Errorf("number of calls = %d; want 1", got)
}
}

View file

@ -0,0 +1,11 @@
package test
import "testing"
func TestTempFile(t *testing.T) {
_, f, e := TempFile(t, ".", "test")
if e != nil {
t.Fatalf("failed to create temp file: %s", e)
}
defer f()
}

View file

@ -0,0 +1,8 @@
package test
import "testing"
func TestA(t *testing.T) {
// should not crash
A("miek.nl. IN A 127.0.0.1")
}