* prune util/log and user logger Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org> * plaintext logger Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org> * add newline Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
		
			
				
	
	
		
			229 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			229 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package certmagic
 | 
						|
 | 
						|
import (
 | 
						|
	"net"
 | 
						|
	"net/http"
 | 
						|
	"os"
 | 
						|
	"reflect"
 | 
						|
	"sort"
 | 
						|
	"testing"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"github.com/go-acme/lego/v3/providers/dns/cloudflare"
 | 
						|
	"github.com/mholt/certmagic"
 | 
						|
	"github.com/micro/go-micro/v2/api/server/acme"
 | 
						|
	cfstore "github.com/micro/go-micro/v2/store/cloudflare"
 | 
						|
	"github.com/micro/go-micro/v2/sync/lock/memory"
 | 
						|
)
 | 
						|
 | 
						|
func TestCertMagic(t *testing.T) {
 | 
						|
	if len(os.Getenv("IN_TRAVIS_CI")) != 0 {
 | 
						|
		t.Skip("Travis doesn't let us bind :443")
 | 
						|
	}
 | 
						|
	l, err := NewProvider().Listen()
 | 
						|
	if err != nil {
 | 
						|
		if _, ok := err.(*net.OpError); ok {
 | 
						|
			t.Skip("Run under non privileged user")
 | 
						|
		}
 | 
						|
		t.Fatal(err.Error())
 | 
						|
	}
 | 
						|
	l.Close()
 | 
						|
 | 
						|
	c := cloudflare.NewDefaultConfig()
 | 
						|
	c.AuthEmail = ""
 | 
						|
	c.AuthKey = ""
 | 
						|
	c.AuthToken = "test"
 | 
						|
	c.ZoneToken = "test"
 | 
						|
 | 
						|
	p, err := cloudflare.NewDNSProviderConfig(c)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err.Error())
 | 
						|
	}
 | 
						|
 | 
						|
	l, err = NewProvider(acme.AcceptToS(true),
 | 
						|
		acme.CA(acme.LetsEncryptStagingCA),
 | 
						|
		acme.ChallengeProvider(p),
 | 
						|
	).Listen()
 | 
						|
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err.Error())
 | 
						|
	}
 | 
						|
	l.Close()
 | 
						|
}
 | 
						|
 | 
						|
func TestStorageImplementation(t *testing.T) {
 | 
						|
	apiToken, accountID := os.Getenv("CF_API_TOKEN"), os.Getenv("CF_ACCOUNT_ID")
 | 
						|
	kvID := os.Getenv("KV_NAMESPACE_ID")
 | 
						|
	if len(apiToken) == 0 || len(accountID) == 0 || len(kvID) == 0 {
 | 
						|
		t.Skip("No Cloudflare API keys available, skipping test")
 | 
						|
	}
 | 
						|
 | 
						|
	var s certmagic.Storage
 | 
						|
	st := cfstore.NewStore(
 | 
						|
		cfstore.Token(apiToken),
 | 
						|
		cfstore.Account(accountID),
 | 
						|
		cfstore.Namespace(kvID),
 | 
						|
	)
 | 
						|
	s = &storage{
 | 
						|
		lock:  memory.NewLock(),
 | 
						|
		store: st,
 | 
						|
	}
 | 
						|
 | 
						|
	// Test Lock
 | 
						|
	if err := s.Lock("test"); err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
 | 
						|
	// Test Unlock
 | 
						|
	if err := s.Unlock("test"); err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
 | 
						|
	// Test data
 | 
						|
	testdata := []struct {
 | 
						|
		key   string
 | 
						|
		value []byte
 | 
						|
	}{
 | 
						|
		{key: "/foo/a", value: []byte("lorem")},
 | 
						|
		{key: "/foo/b", value: []byte("ipsum")},
 | 
						|
		{key: "/foo/c", value: []byte("dolor")},
 | 
						|
		{key: "/foo/d", value: []byte("sit")},
 | 
						|
		{key: "/bar/a", value: []byte("amet")},
 | 
						|
		{key: "/bar/b", value: []byte("consectetur")},
 | 
						|
		{key: "/bar/c", value: []byte("adipiscing")},
 | 
						|
		{key: "/bar/d", value: []byte("elit")},
 | 
						|
		{key: "/foo/bar/a", value: []byte("sed")},
 | 
						|
		{key: "/foo/bar/b", value: []byte("do")},
 | 
						|
		{key: "/foo/bar/c", value: []byte("eiusmod")},
 | 
						|
		{key: "/foo/bar/d", value: []byte("tempor")},
 | 
						|
		{key: "/foo/bar/baz/a", value: []byte("incididunt")},
 | 
						|
		{key: "/foo/bar/baz/b", value: []byte("ut")},
 | 
						|
		{key: "/foo/bar/baz/c", value: []byte("labore")},
 | 
						|
		{key: "/foo/bar/baz/d", value: []byte("et")},
 | 
						|
		// a duplicate just in case there's any edge cases
 | 
						|
		{key: "/foo/a", value: []byte("lorem")},
 | 
						|
	}
 | 
						|
 | 
						|
	// Test Store
 | 
						|
	for _, d := range testdata {
 | 
						|
		if err := s.Store(d.key, d.value); err != nil {
 | 
						|
			t.Fatal(err.Error())
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// Test Load
 | 
						|
	for _, d := range testdata {
 | 
						|
		if value, err := s.Load(d.key); err != nil {
 | 
						|
			t.Fatal(err.Error())
 | 
						|
		} else {
 | 
						|
			if !reflect.DeepEqual(value, d.value) {
 | 
						|
				t.Fatalf("Load %s: expected %v, got %v", d.key, d.value, value)
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// Test Exists
 | 
						|
	for _, d := range testdata {
 | 
						|
		if !s.Exists(d.key) {
 | 
						|
			t.Fatalf("%s should exist, but doesn't\n", d.key)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// Test List
 | 
						|
	if list, err := s.List("/", true); err != nil {
 | 
						|
		t.Fatal(err.Error())
 | 
						|
	} else {
 | 
						|
		var expected []string
 | 
						|
		for i, d := range testdata {
 | 
						|
			if i != len(testdata)-1 {
 | 
						|
				// Don't store the intentionally duplicated key
 | 
						|
				expected = append(expected, d.key)
 | 
						|
			}
 | 
						|
		}
 | 
						|
		sort.Strings(expected)
 | 
						|
		sort.Strings(list)
 | 
						|
		if !reflect.DeepEqual(expected, list) {
 | 
						|
			t.Fatalf("List: Expected %v, got %v\n", expected, list)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	if list, err := s.List("/foo", false); err != nil {
 | 
						|
		t.Fatal(err.Error())
 | 
						|
	} else {
 | 
						|
		sort.Strings(list)
 | 
						|
		expected := []string{"/foo/a", "/foo/b", "/foo/bar", "/foo/c", "/foo/d"}
 | 
						|
		if !reflect.DeepEqual(expected, list) {
 | 
						|
			t.Fatalf("List: expected %s, got %s\n", expected, list)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// Test Stat
 | 
						|
	for _, d := range testdata {
 | 
						|
		info, err := s.Stat(d.key)
 | 
						|
		if err != nil {
 | 
						|
			t.Fatal(err.Error())
 | 
						|
		} else {
 | 
						|
			if info.Key != d.key {
 | 
						|
				t.Fatalf("Stat().Key: expected %s, got %s\n", d.key, info.Key)
 | 
						|
			}
 | 
						|
			if info.Size != int64(len(d.value)) {
 | 
						|
				t.Fatalf("Stat().Size: expected %d, got %d\n", len(d.value), info.Size)
 | 
						|
			}
 | 
						|
			if time.Since(info.Modified) > time.Minute {
 | 
						|
				t.Fatalf("Stat().Modified: expected time since last modified to be < 1 minute, got %v\n", time.Since(info.Modified))
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
	}
 | 
						|
 | 
						|
	// Test Delete
 | 
						|
	for _, d := range testdata {
 | 
						|
		if err := s.Delete(d.key); err != nil {
 | 
						|
			t.Fatal(err.Error())
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// New interface doesn't return an error, so call it in case any log.Fatal
 | 
						|
	// happens
 | 
						|
	NewProvider(acme.Cache(s))
 | 
						|
}
 | 
						|
 | 
						|
// Full test with a real zone, with  against LE staging
 | 
						|
func TestE2e(t *testing.T) {
 | 
						|
	apiToken, accountID := os.Getenv("CF_API_TOKEN"), os.Getenv("CF_ACCOUNT_ID")
 | 
						|
	kvID := os.Getenv("KV_NAMESPACE_ID")
 | 
						|
	if len(apiToken) == 0 || len(accountID) == 0 || len(kvID) == 0 {
 | 
						|
		t.Skip("No Cloudflare API keys available, skipping test")
 | 
						|
	}
 | 
						|
 | 
						|
	testLock := memory.NewLock()
 | 
						|
	testStore := cfstore.NewStore(
 | 
						|
		cfstore.Token(apiToken),
 | 
						|
		cfstore.Account(accountID),
 | 
						|
		cfstore.Namespace(kvID),
 | 
						|
	)
 | 
						|
	testStorage := NewStorage(testLock, testStore)
 | 
						|
 | 
						|
	conf := cloudflare.NewDefaultConfig()
 | 
						|
	conf.AuthToken = apiToken
 | 
						|
	conf.ZoneToken = apiToken
 | 
						|
	testChallengeProvider, err := cloudflare.NewDNSProviderConfig(conf)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err.Error())
 | 
						|
	}
 | 
						|
 | 
						|
	testProvider := NewProvider(
 | 
						|
		acme.AcceptToS(true),
 | 
						|
		acme.Cache(testStorage),
 | 
						|
		acme.CA(acme.LetsEncryptStagingCA),
 | 
						|
		acme.ChallengeProvider(testChallengeProvider),
 | 
						|
		acme.OnDemand(false),
 | 
						|
	)
 | 
						|
 | 
						|
	listener, err := testProvider.Listen("*.micro.mu", "micro.mu")
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err.Error())
 | 
						|
	}
 | 
						|
	go http.Serve(listener, http.NotFoundHandler())
 | 
						|
	time.Sleep(10 * time.Minute)
 | 
						|
}
 |