gitee.com/liuxuezhan/go-micro-v1.18.0@v1.0.0/api/server/acme/certmagic/certmagic_test.go (about)

     1  package certmagic
     2  
     3  import (
     4  	"net/http"
     5  	"os"
     6  	"reflect"
     7  	"sort"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/go-acme/lego/v3/providers/dns/cloudflare"
    12  	"github.com/mholt/certmagic"
    13  	"gitee.com/liuxuezhan/go-micro-v1.18.0/api/server/acme"
    14  	cfstore "gitee.com/liuxuezhan/go-micro-v1.18.0/store/cloudflare"
    15  	"gitee.com/liuxuezhan/go-micro-v1.18.0/sync/lock/memory"
    16  )
    17  
    18  func TestCertMagic(t *testing.T) {
    19  	if len(os.Getenv("IN_TRAVIS_CI")) != 0 {
    20  		t.Skip("Travis doesn't let us bind :443")
    21  	}
    22  	l, err := New().NewListener()
    23  	if err != nil {
    24  		t.Fatal(err.Error())
    25  	}
    26  	l.Close()
    27  
    28  	c := cloudflare.NewDefaultConfig()
    29  	c.AuthEmail = ""
    30  	c.AuthKey = ""
    31  	c.AuthToken = "test"
    32  	c.ZoneToken = "test"
    33  
    34  	p, err := cloudflare.NewDNSProviderConfig(c)
    35  	if err != nil {
    36  		t.Fatal(err.Error())
    37  	}
    38  
    39  	l, err = New(acme.AcceptToS(true),
    40  		acme.CA(acme.LetsEncryptStagingCA),
    41  		acme.ChallengeProvider(p),
    42  	).NewListener()
    43  
    44  	if err != nil {
    45  		t.Fatal(err.Error())
    46  	}
    47  	l.Close()
    48  }
    49  
    50  func TestStorageImplementation(t *testing.T) {
    51  	apiToken, accountID := os.Getenv("CF_API_TOKEN"), os.Getenv("CF_ACCOUNT_ID")
    52  	kvID := os.Getenv("KV_NAMESPACE_ID")
    53  	if len(apiToken) == 0 || len(accountID) == 0 || len(kvID) == 0 {
    54  		t.Skip("No Cloudflare API keys available, skipping test")
    55  	}
    56  
    57  	var s certmagic.Storage
    58  	st := cfstore.NewStore(
    59  		cfstore.Token(apiToken),
    60  		cfstore.Account(accountID),
    61  		cfstore.Namespace(kvID),
    62  	)
    63  	s = &storage{
    64  		lock:  memory.NewLock(),
    65  		store: st,
    66  	}
    67  
    68  	// Test Lock
    69  	if err := s.Lock("test"); err != nil {
    70  		t.Fatal(err)
    71  	}
    72  
    73  	// Test Unlock
    74  	if err := s.Unlock("test"); err != nil {
    75  		t.Fatal(err)
    76  	}
    77  
    78  	// Test data
    79  	testdata := []struct {
    80  		key   string
    81  		value []byte
    82  	}{
    83  		{key: "/foo/a", value: []byte("lorem")},
    84  		{key: "/foo/b", value: []byte("ipsum")},
    85  		{key: "/foo/c", value: []byte("dolor")},
    86  		{key: "/foo/d", value: []byte("sit")},
    87  		{key: "/bar/a", value: []byte("amet")},
    88  		{key: "/bar/b", value: []byte("consectetur")},
    89  		{key: "/bar/c", value: []byte("adipiscing")},
    90  		{key: "/bar/d", value: []byte("elit")},
    91  		{key: "/foo/bar/a", value: []byte("sed")},
    92  		{key: "/foo/bar/b", value: []byte("do")},
    93  		{key: "/foo/bar/c", value: []byte("eiusmod")},
    94  		{key: "/foo/bar/d", value: []byte("tempor")},
    95  		{key: "/foo/bar/baz/a", value: []byte("incididunt")},
    96  		{key: "/foo/bar/baz/b", value: []byte("ut")},
    97  		{key: "/foo/bar/baz/c", value: []byte("labore")},
    98  		{key: "/foo/bar/baz/d", value: []byte("et")},
    99  		// a duplicate just in case there's any edge cases
   100  		{key: "/foo/a", value: []byte("lorem")},
   101  	}
   102  
   103  	// Test Store
   104  	for _, d := range testdata {
   105  		if err := s.Store(d.key, d.value); err != nil {
   106  			t.Fatal(err.Error())
   107  		}
   108  	}
   109  
   110  	// Test Load
   111  	for _, d := range testdata {
   112  		if value, err := s.Load(d.key); err != nil {
   113  			t.Fatal(err.Error())
   114  		} else {
   115  			if !reflect.DeepEqual(value, d.value) {
   116  				t.Fatalf("Load %s: expected %v, got %v", d.key, d.value, value)
   117  			}
   118  		}
   119  	}
   120  
   121  	// Test Exists
   122  	for _, d := range testdata {
   123  		if !s.Exists(d.key) {
   124  			t.Fatalf("%s should exist, but doesn't\n", d.key)
   125  		}
   126  	}
   127  
   128  	// Test List
   129  	if list, err := s.List("/", true); err != nil {
   130  		t.Fatal(err.Error())
   131  	} else {
   132  		var expected []string
   133  		for i, d := range testdata {
   134  			if i != len(testdata)-1 {
   135  				// Don't store the intentionally duplicated key
   136  				expected = append(expected, d.key)
   137  			}
   138  		}
   139  		sort.Strings(expected)
   140  		sort.Strings(list)
   141  		if !reflect.DeepEqual(expected, list) {
   142  			t.Fatalf("List: Expected %v, got %v\n", expected, list)
   143  		}
   144  	}
   145  	if list, err := s.List("/foo", false); err != nil {
   146  		t.Fatal(err.Error())
   147  	} else {
   148  		sort.Strings(list)
   149  		expected := []string{"/foo/a", "/foo/b", "/foo/bar", "/foo/c", "/foo/d"}
   150  		if !reflect.DeepEqual(expected, list) {
   151  			t.Fatalf("List: expected %s, got %s\n", expected, list)
   152  		}
   153  	}
   154  
   155  	// Test Stat
   156  	for _, d := range testdata {
   157  		info, err := s.Stat(d.key)
   158  		if err != nil {
   159  			t.Fatal(err.Error())
   160  		} else {
   161  			if info.Key != d.key {
   162  				t.Fatalf("Stat().Key: expected %s, got %s\n", d.key, info.Key)
   163  			}
   164  			if info.Size != int64(len(d.value)) {
   165  				t.Fatalf("Stat().Size: expected %d, got %d\n", len(d.value), info.Size)
   166  			}
   167  			if time.Since(info.Modified) > time.Minute {
   168  				t.Fatalf("Stat().Modified: expected time since last modified to be < 1 minute, got %v\n", time.Since(info.Modified))
   169  			}
   170  		}
   171  
   172  	}
   173  
   174  	// Test Delete
   175  	for _, d := range testdata {
   176  		if err := s.Delete(d.key); err != nil {
   177  			t.Fatal(err.Error())
   178  		}
   179  	}
   180  
   181  	// New interface doesn't return an error, so call it in case any log.Fatal
   182  	// happens
   183  	New(acme.Cache(s))
   184  }
   185  
   186  // Full test with a real zone, with  against LE staging
   187  func TestE2e(t *testing.T) {
   188  	apiToken, accountID := os.Getenv("CF_API_TOKEN"), os.Getenv("CF_ACCOUNT_ID")
   189  	kvID := os.Getenv("KV_NAMESPACE_ID")
   190  	if len(apiToken) == 0 || len(accountID) == 0 || len(kvID) == 0 {
   191  		t.Skip("No Cloudflare API keys available, skipping test")
   192  	}
   193  
   194  	testLock := memory.NewLock()
   195  	testStore := cfstore.NewStore(
   196  		cfstore.Token(apiToken),
   197  		cfstore.Account(accountID),
   198  		cfstore.Namespace(kvID),
   199  	)
   200  	testStorage := NewStorage(testLock, testStore)
   201  
   202  	conf := cloudflare.NewDefaultConfig()
   203  	conf.AuthToken = apiToken
   204  	conf.ZoneToken = apiToken
   205  	testChallengeProvider, err := cloudflare.NewDNSProviderConfig(conf)
   206  	if err != nil {
   207  		t.Fatal(err.Error())
   208  	}
   209  
   210  	testProvider := New(
   211  		acme.AcceptToS(true),
   212  		acme.Cache(testStorage),
   213  		acme.CA(acme.LetsEncryptStagingCA),
   214  		acme.ChallengeProvider(testChallengeProvider),
   215  		acme.OnDemand(false),
   216  	)
   217  
   218  	listener, err := testProvider.NewListener("*.micro.mu", "micro.mu")
   219  	if err != nil {
   220  		t.Fatal(err.Error())
   221  	}
   222  	go http.Serve(listener, http.NotFoundHandler())
   223  	time.Sleep(10 * time.Minute)
   224  }