porting all github actions from bluesky-social/indigo to tangled CI
at main 4.2 kB view raw
1package identity 2 3import ( 4 "context" 5 "log/slog" 6 "net/http" 7 "strings" 8 "sync" 9 "testing" 10 "time" 11 12 "github.com/bluesky-social/indigo/atproto/syntax" 13 "golang.org/x/time/rate" 14 15 "github.com/stretchr/testify/assert" 16) 17 18// NOTE: this hits the open internet! marked as skip below by default 19func testDirectoryLive(t *testing.T, d Directory) { 20 assert := assert.New(t) 21 ctx := context.Background() 22 23 handle := syntax.Handle("atproto.com") 24 did := syntax.DID("did:plc:ewvi7nxzyoun6zhxrhs64oiz") 25 pdsSuffix := "host.bsky.network" 26 27 resp, err := d.LookupHandle(ctx, handle) 28 assert.NoError(err) 29 assert.Equal(handle, resp.Handle) 30 assert.Equal(did, resp.DID) 31 assert.True(strings.HasSuffix(resp.PDSEndpoint(), pdsSuffix)) 32 dh, err := resp.DeclaredHandle() 33 assert.NoError(err) 34 assert.Equal(handle, dh) 35 pk, err := resp.PublicKey() 36 assert.NoError(err) 37 assert.NotNil(pk) 38 39 resp, err = d.LookupDID(ctx, did) 40 assert.NoError(err) 41 assert.Equal(handle, resp.Handle) 42 assert.Equal(did, resp.DID) 43 assert.True(strings.HasSuffix(resp.PDSEndpoint(), pdsSuffix)) 44 45 _, err = d.LookupHandle(ctx, syntax.Handle("fake-dummy-no-resolve.atproto.com")) 46 assert.ErrorIs(err, ErrHandleNotFound) 47 48 _, err = d.LookupDID(ctx, syntax.DID("did:web:fake-dummy-no-resolve.atproto.com")) 49 assert.ErrorIs(err, ErrDIDNotFound) 50 51 _, err = d.LookupDID(ctx, syntax.DID("did:plc:fake-dummy-no-resolve.atproto.com")) 52 assert.ErrorIs(err, ErrDIDNotFound) 53 54 _, err = d.LookupHandle(ctx, syntax.HandleInvalid) 55 assert.Error(err) 56} 57 58func TestBaseDirectory(t *testing.T) { 59 t.Skip("TODO: skipping live network test") 60 d := BaseDirectory{} 61 testDirectoryLive(t, &d) 62} 63 64func TestCacheDirectory(t *testing.T) { 65 t.Skip("TODO: skipping live network test") 66 inner := BaseDirectory{} 67 d := NewCacheDirectory(&inner, 1000, time.Hour*1, time.Hour*1, time.Hour*1) 68 for i := 0; i < 3; i = i + 1 { 69 testDirectoryLive(t, &d) 70 } 71} 72 73func TestCacheCoalesce(t *testing.T) { 74 t.Skip("TODO: skipping live network test") 75 76 assert := assert.New(t) 77 handle := syntax.Handle("atproto.com") 78 did := syntax.DID("did:plc:ewvi7nxzyoun6zhxrhs64oiz") 79 80 base := BaseDirectory{ 81 PLCURL: "https://plc.directory", 82 HTTPClient: http.Client{ 83 Timeout: time.Second * 15, 84 }, 85 // Limit the number of requests we can make to the PLC to 1 per second 86 PLCLimiter: rate.NewLimiter(1, 1), 87 TryAuthoritativeDNS: true, 88 SkipDNSDomainSuffixes: []string{".bsky.social"}, 89 } 90 dir := NewCacheDirectory(&base, 1000, time.Hour*1, time.Hour*1, time.Hour*1) 91 // All 60 routines launch at the same time, so they should all miss the cache initially 92 routines := 60 93 wg := sync.WaitGroup{} 94 95 // Cancel the context after 2 seconds, if we're coalescing correctly, we should only make 1 request 96 ctx, cancel := context.WithTimeout(context.Background(), time.Second*2) 97 defer cancel() 98 for i := 0; i < routines; i++ { 99 wg.Add(1) 100 go func() { 101 defer wg.Done() 102 ident, err := dir.LookupDID(ctx, did) 103 if err != nil { 104 slog.Error("Failed lookup", "error", err) 105 } 106 assert.NoError(err) 107 assert.Equal(handle, ident.Handle) 108 109 ident, err = dir.LookupHandle(ctx, handle) 110 if err != nil { 111 slog.Error("Failed lookup", "error", err) 112 } 113 assert.NoError(err) 114 assert.Equal(did, ident.DID) 115 }() 116 } 117 wg.Wait() 118} 119 120func TestFallbackDNS(t *testing.T) { 121 t.Skip("TODO: skipping live network test") 122 123 assert := assert.New(t) 124 ctx := context.Background() 125 handle := syntax.Handle("no-such-record.atproto.com") 126 dir := BaseDirectory{ 127 FallbackDNSServers: []string{"1.1.1.1:53", "8.8.8.8:53"}, 128 } 129 130 // valid DNS server 131 _, err := dir.LookupHandle(ctx, handle) 132 assert.Error(err) 133 assert.ErrorIs(err, ErrHandleNotFound) 134 135 // invalid DNS server syntax 136 dir.FallbackDNSServers = []string{"_"} 137 _, err = dir.LookupHandle(ctx, handle) 138 assert.Error(err) 139 assert.ErrorIs(err, ErrHandleResolutionFailed) 140} 141 142func TestResolveNSID(t *testing.T) { 143 t.Skip("TODO: skipping live network test") 144 assert := assert.New(t) 145 ctx := context.Background() 146 147 dir := BaseDirectory{} 148 // NOTE: this was a very short temporary NSID when rkey restriction was short 149 nsid := syntax.NSID("net.bnewbold.m") 150 did, err := dir.ResolveNSID(ctx, nsid) 151 152 assert.NoError(err) 153 assert.Equal(did, syntax.DID("did:plc:nhxcyu4ewwhl5pqil4dotqjo")) 154}