github.com/qiniu/go-sdk/v7@v7.27.0/storagev2/resolver/resolver_test.go (about)

     1  //go:build unit
     2  // +build unit
     3  
     4  package resolver_test
     5  
     6  import (
     7  	"context"
     8  	"net"
     9  	"os"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/qiniu/go-sdk/v7/storagev2/resolver"
    14  )
    15  
    16  func TestDefaultResolver(t *testing.T) {
    17  	ips, err := resolver.NewDefaultResolver().Resolve(context.Background(), "upload.qiniup.com")
    18  	if err != nil {
    19  		t.Fatalf("Unexpected error: %v", err)
    20  	} else if len(ips) == 0 {
    21  		t.Fatal("Unexpected empty ips")
    22  	}
    23  }
    24  
    25  type mockResolver struct {
    26  	m map[string][]net.IP
    27  	c map[string]int
    28  }
    29  
    30  func (mr *mockResolver) Resolve(ctx context.Context, host string) ([]net.IP, error) {
    31  	mr.c[host]++
    32  	return mr.m[host], nil
    33  }
    34  
    35  func (mr *mockResolver) FeedbackGood(context.Context, string, []net.IP) {}
    36  
    37  func (mr *mockResolver) FeedbackBad(context.Context, string, []net.IP) {}
    38  
    39  func TestCacheResolver(t *testing.T) {
    40  	tmpFile, err := os.CreateTemp("", "")
    41  	if err != nil {
    42  		t.Fatal(err)
    43  	}
    44  	defer os.Remove(tmpFile.Name())
    45  	defer tmpFile.Close()
    46  
    47  	mr := &mockResolver{m: map[string][]net.IP{"upload.qiniup.com": {net.IPv4(1, 1, 1, 1), net.IPv4(1, 1, 2, 2)}}, c: make(map[string]int)}
    48  	resolver, err := resolver.NewCacheResolver(mr, &resolver.CacheResolverConfig{
    49  		PersistentFilePath: tmpFile.Name(),
    50  		CacheRefreshAfter:  3 * time.Second,
    51  		CacheLifetime:      2 * time.Second,
    52  	})
    53  	if err != nil {
    54  		t.Fatal(err)
    55  	}
    56  	for i := 0; i < 10; i++ {
    57  		ips, err := resolver.Resolve(context.Background(), "upload.qiniup.com")
    58  		if err != nil {
    59  			t.Fatal(err)
    60  		}
    61  		if len(ips) != 2 || !ips[0].Equal(net.IPv4(1, 1, 1, 1)) || !ips[1].Equal(net.IPv4(1, 1, 2, 2)) {
    62  			t.Fatal("Unexpected ips")
    63  		}
    64  	}
    65  	if mr.c["upload.qiniup.com"] != 1 {
    66  		t.Fatal("Unexpected cache")
    67  	}
    68  
    69  	time.Sleep(1000 * time.Millisecond)
    70  	resolver.FeedbackGood(context.Background(), "upload.qiniup.com", []net.IP{net.IPv4(1, 1, 1, 1)})
    71  	time.Sleep(1500 * time.Millisecond)
    72  	ips, err := resolver.Resolve(context.Background(), "upload.qiniup.com")
    73  	if err != nil {
    74  		t.Fatal(err)
    75  	}
    76  	if len(ips) != 1 || !ips[0].Equal(net.IPv4(1, 1, 1, 1)) {
    77  		t.Fatal("Unexpected ips")
    78  	}
    79  	if mr.c["upload.qiniup.com"] != 1 {
    80  		t.Fatal("Unexpected cache")
    81  	}
    82  }
    83  
    84  func TestCacheResolverMaxLifetime(t *testing.T) {
    85  	tmpFile, err := os.CreateTemp("", "")
    86  	if err != nil {
    87  		t.Fatal(err)
    88  	}
    89  	defer os.Remove(tmpFile.Name())
    90  	defer tmpFile.Close()
    91  
    92  	mr := &mockResolver{
    93  		m: map[string][]net.IP{"upload.qiniup.com": {net.IPv4(1, 1, 1, 1)}},
    94  		c: make(map[string]int),
    95  	}
    96  	r, err := resolver.NewCacheResolver(mr, &resolver.CacheResolverConfig{
    97  		PersistentFilePath: tmpFile.Name(),
    98  		CacheRefreshAfter:  2 * time.Second,
    99  		CacheLifetime:      5 * time.Second,
   100  		CacheMaxLifetime:   3 * time.Second,
   101  	})
   102  	if err != nil {
   103  		t.Fatal(err)
   104  	}
   105  
   106  	// 首次解析,触发 DNS 查询
   107  	ips, err := r.Resolve(context.Background(), "upload.qiniup.com")
   108  	if err != nil {
   109  		t.Fatal(err)
   110  	}
   111  	if len(ips) != 1 || !ips[0].Equal(net.IPv4(1, 1, 1, 1)) {
   112  		t.Fatal("Unexpected ips")
   113  	}
   114  	if mr.c["upload.qiniup.com"] != 1 {
   115  		t.Fatalf("Expected 1 resolve call, got %d", mr.c["upload.qiniup.com"])
   116  	}
   117  
   118  	// 每隔 500ms 调用 FeedbackGood 延长缓存,持续 4 秒(超过 CacheMaxLifetime 3s)
   119  	for i := 0; i < 8; i++ {
   120  		time.Sleep(500 * time.Millisecond)
   121  		r.FeedbackGood(context.Background(), "upload.qiniup.com", []net.IP{net.IPv4(1, 1, 1, 1)})
   122  	}
   123  
   124  	// 此时 CacheMaxLifetime(3s)已过,FeedbackGood 无法继续推迟 RefreshAfter
   125  	// 下次 Resolve 应触发异步 DNS 重新查询
   126  	ips, err = r.Resolve(context.Background(), "upload.qiniup.com")
   127  	if err != nil {
   128  		t.Fatal(err)
   129  	}
   130  	if len(ips) != 1 || !ips[0].Equal(net.IPv4(1, 1, 1, 1)) {
   131  		t.Fatal("Unexpected ips")
   132  	}
   133  
   134  	// 等待异步刷新完成
   135  	time.Sleep(1 * time.Second)
   136  
   137  	if mr.c["upload.qiniup.com"] != 2 {
   138  		t.Fatalf("Expected 2 resolve calls after max lifetime, got %d", mr.c["upload.qiniup.com"])
   139  	}
   140  }