A container registry that uses the AT Protocol for manifest storage and S3 for blob storage. atcr.io
docker container atproto go

fix lint and unit tests

evan.jarrett.net aad9ebfc 7ba42080

verified
+41 -52
+6 -6
pkg/atproto/client.go
··· 104 104 pdsEndpoint: pdsEndpoint, 105 105 did: did, 106 106 clientProvider: NewBasicAuthClientProvider(pdsEndpoint, did, accessToken), 107 - httpClient: &http.Client{}, 107 + httpClient: &http.Client{Timeout: 30 * time.Second}, 108 108 } 109 109 } 110 110 ··· 121 121 pdsEndpoint: pdsEndpoint, 122 122 did: did, 123 123 clientProvider: NewOAuthClientProvider(sessionProvider), 124 - httpClient: &http.Client{}, 124 + httpClient: &http.Client{Timeout: 30 * time.Second}, 125 125 } 126 126 } 127 127 ··· 259 259 // Note: This is a sync endpoint that returns raw binary data 260 260 func (c *Client) GetBlob(ctx context.Context, cid string) ([]byte, error) { 261 261 // Public endpoint - no auth required 262 - client := &xrpc.Client{Host: c.pdsEndpoint} 262 + client := &xrpc.Client{Host: c.pdsEndpoint, Client: c.httpClient} 263 263 data, err := comatproto.SyncGetBlob(ctx, client, cid, c.did) 264 264 if err != nil { 265 265 var xrpcErr *xrpc.Error ··· 294 294 } 295 295 296 296 // Public endpoint - no auth required 297 - client := &xrpc.Client{Host: c.pdsEndpoint} 297 + client := &xrpc.Client{Host: c.pdsEndpoint, Client: c.httpClient} 298 298 var result ListReposByCollectionResult 299 299 err := client.LexDo(ctx, "GET", "", "com.atproto.sync.listReposByCollection", params, nil, &result) 300 300 if err != nil { ··· 318 318 } 319 319 320 320 // Public endpoint - no auth required 321 - client := &xrpc.Client{Host: c.pdsEndpoint} 321 + client := &xrpc.Client{Host: c.pdsEndpoint, Client: c.httpClient} 322 322 var result struct { 323 323 Records []Record `json:"records"` 324 324 Cursor string `json:"cursor,omitempty"` ··· 352 352 // The actor parameter can be a DID or handle 353 353 func (c *Client) GetActorProfile(ctx context.Context, actor string) (*ActorProfile, error) { 354 354 // Public endpoint - doesn't require auth 355 - client := &xrpc.Client{Host: c.pdsEndpoint} 355 + client := &xrpc.Client{Host: c.pdsEndpoint, Client: c.httpClient} 356 356 357 357 resp, err := appbsky.ActorGetProfile(ctx, client, actor) 358 358 if err != nil {
-16
pkg/hold/admin/auth.go
··· 112 112 http.Error(w, "Internal server error", http.StatusInternalServerError) 113 113 } 114 114 } 115 - 116 - // renderError renders an error page 117 - func (ui *AdminUI) renderError(w http.ResponseWriter, r *http.Request, message string, statusCode int) { 118 - w.Header().Set("Content-Type", "text/html; charset=utf-8") 119 - w.WriteHeader(statusCode) 120 - 121 - data := struct { 122 - PageData 123 - Error string 124 - }{ 125 - PageData: ui.newPageData(r, "Error", ""), 126 - Error: message, 127 - } 128 - 129 - ui.renderTemplate(w, "pages/error.html", data) 130 - }
+4 -1
pkg/hold/admin/handlers_crew_io.go
··· 67 67 68 68 enc := json.NewEncoder(w) 69 69 enc.SetIndent("", " ") 70 - enc.Encode(export) 70 + if err := enc.Encode(export); err != nil { 71 + slog.Error("Failed to encode crew export", "error", err) 72 + return 73 + } 71 74 72 75 session := getSessionFromContext(ctx) 73 76 slog.Info("Crew exported via admin panel",
-1
pkg/hold/config.go
··· 292 292 293 293 return storageCfg 294 294 } 295 -
+6
pkg/hold/config_test.go
··· 8 8 "time" 9 9 ) 10 10 11 + func init() { 12 + // Point metadata endpoint to a closed listener so it fails instantly instead of 13 + // waiting 2s for the real 169.254.169.254 to timeout on non-cloud machines. 14 + metadataEndpoint = "http://127.0.0.1:1" 15 + } 16 + 11 17 // setupEnv sets environment variables for testing and returns a cleanup function 12 18 func setupEnv(t *testing.T, vars map[string]string) func() { 13 19 // Save original env
+4 -1
pkg/hold/metadata.go
··· 13 13 Region string 14 14 } 15 15 16 + // metadataEndpoint is the cloud metadata service URL. Package-level var for test override. 17 + var metadataEndpoint = "http://169.254.169.254" 18 + 16 19 // DetectCloudMetadata queries the instance metadata service (169.254.169.254) 17 20 // Currently supports UpCloud. Others can be added via PR. 18 21 func DetectCloudMetadata(ctx context.Context) (*CloudMetadata, error) { ··· 32 35 33 36 // detectUpCloud queries UpCloud's metadata service 34 37 func detectUpCloud(ctx context.Context) (*CloudMetadata, error) { 35 - req, err := http.NewRequestWithContext(ctx, "GET", "http://169.254.169.254/metadata/v1.json", nil) 38 + req, err := http.NewRequestWithContext(ctx, "GET", metadataEndpoint+"/metadata/v1.json", nil) 36 39 if err != nil { 37 40 return nil, err 38 41 }
+1
pkg/hold/pds/captain_test.go
··· 40 40 t.Fatalf("Failed to initialize test repo: %v", err) 41 41 } 42 42 43 + t.Cleanup(func() { pds.Close() }) 43 44 return pds, ctx 44 45 } 45 46
+4 -8
pkg/hold/pds/delete_test.go
··· 150 150 151 151 func TestDeleteBlueskyPosts_NoPosts(t *testing.T) { 152 152 // Create a test PDS with records index 153 - pds, cleanup := setupTestPDSWithIndex(t, "did:plc:testowner") 154 - defer cleanup() 153 + pds := setupTestPDSWithIndex(t, "did:plc:testowner") 155 154 156 155 ctx := sharedCtx 157 156 ··· 168 167 169 168 func TestListBlueskyPostsForUser_NoPosts(t *testing.T) { 170 169 // Create a test PDS with records index 171 - pds, cleanup := setupTestPDSWithIndex(t, "did:plc:testowner") 172 - defer cleanup() 170 + pds := setupTestPDSWithIndex(t, "did:plc:testowner") 173 171 174 172 ctx := sharedCtx 175 173 ··· 186 184 187 185 func TestDeleteAndListBlueskyPosts_WithPosts(t *testing.T) { 188 186 // Create a test PDS with records index 189 - pds, cleanup := setupTestPDSWithIndex(t, "did:plc:testowner") 190 - defer cleanup() 187 + pds := setupTestPDSWithIndex(t, "did:plc:testowner") 191 188 192 189 ctx := sharedCtx 193 190 ··· 276 273 277 274 func TestDeleteUserData_IncludesPosts(t *testing.T) { 278 275 // Create a test PDS with records index 279 - pds, cleanup := setupTestPDSWithIndex(t, "did:plc:testowner") 280 - defer cleanup() 276 + pds := setupTestPDSWithIndex(t, "did:plc:testowner") 281 277 282 278 ctx := sharedCtx 283 279
+9 -18
pkg/hold/pds/layer_test.go
··· 287 287 288 288 // setupTestPDSWithIndex creates a PDS with file-based database (enables RecordsIndex) 289 289 // and bootstraps it with the given owner. Required for quota tests. 290 - func setupTestPDSWithIndex(t *testing.T, ownerDID string) (*HoldPDS, func()) { 290 + func setupTestPDSWithIndex(t *testing.T, ownerDID string) *HoldPDS { 291 291 t.Helper() 292 292 293 293 ctx := sharedCtx ··· 321 321 t.Fatalf("Failed to backfill records index: %v", err) 322 322 } 323 323 324 - cleanup := func() { 325 - pds.Close() 326 - } 327 - 328 - return pds, cleanup 324 + t.Cleanup(func() { pds.Close() }) 325 + return pds 329 326 } 330 327 331 328 // addCrewMemberWithTier adds a crew member with a specific tier ··· 349 346 350 347 func TestGetQuotaForUserWithTier_OwnerUnlimited(t *testing.T) { 351 348 ownerDID := "did:plc:owner123" 352 - pds, cleanup := setupTestPDSWithIndex(t, ownerDID) 353 - defer cleanup() 349 + pds := setupTestPDSWithIndex(t, ownerDID) 354 350 355 351 ctx := sharedCtx 356 352 ··· 423 419 func TestGetQuotaForUserWithTier_CrewWithDefaultTier(t *testing.T) { 424 420 ownerDID := "did:plc:owner456" 425 421 crewDID := "did:plc:crew123" 426 - pds, cleanup := setupTestPDSWithIndex(t, ownerDID) 427 - defer cleanup() 422 + pds := setupTestPDSWithIndex(t, ownerDID) 428 423 429 424 ctx := sharedCtx 430 425 ··· 498 493 func TestGetQuotaForUserWithTier_CrewWithExplicitTier(t *testing.T) { 499 494 ownerDID := "did:plc:owner789" 500 495 crewDID := "did:plc:bosuncrew456" 501 - pds, cleanup := setupTestPDSWithIndex(t, ownerDID) 502 - defer cleanup() 496 + pds := setupTestPDSWithIndex(t, ownerDID) 503 497 504 498 ctx := sharedCtx 505 499 ··· 566 560 func TestGetQuotaForUserWithTier_NoQuotaManager(t *testing.T) { 567 561 ownerDID := "did:plc:ownerabc" 568 562 crewDID := "did:plc:crewabc" 569 - pds, cleanup := setupTestPDSWithIndex(t, ownerDID) 570 - defer cleanup() 563 + pds := setupTestPDSWithIndex(t, ownerDID) 571 564 572 565 ctx := sharedCtx 573 566 ··· 608 601 func TestGetQuotaForUserWithTier_DisabledQuotas(t *testing.T) { 609 602 ownerDID := "did:plc:ownerdef" 610 603 crewDID := "did:plc:crewdef" 611 - pds, cleanup := setupTestPDSWithIndex(t, ownerDID) 612 - defer cleanup() 604 + pds := setupTestPDSWithIndex(t, ownerDID) 613 605 614 606 ctx := sharedCtx 615 607 ··· 655 647 func TestGetQuotaForUserWithTier_DeduplicatesBlobs(t *testing.T) { 656 648 ownerDID := "did:plc:ownerghi" 657 649 crewDID := "did:plc:crewghi" 658 - pds, cleanup := setupTestPDSWithIndex(t, ownerDID) 659 - defer cleanup() 650 + pds := setupTestPDSWithIndex(t, ownerDID) 660 651 661 652 ctx := sharedCtx 662 653
+6
pkg/hold/pds/server.go
··· 4 4 "context" 5 5 "database/sql" 6 6 "fmt" 7 + "io" 7 8 "log/slog" 8 9 "os" 9 10 "path/filepath" ··· 386 387 if p.recordsIndex != nil { 387 388 if err := p.recordsIndex.Close(); err != nil { 388 389 return fmt.Errorf("failed to close records index: %w", err) 390 + } 391 + } 392 + if closer, ok := p.carstore.(io.Closer); ok { 393 + if err := closer.Close(); err != nil { 394 + return fmt.Errorf("failed to close carstore: %w", err) 389 395 } 390 396 } 391 397 return nil
+1 -1
pkg/hold/pds/status_test.go
··· 288 288 // Run tests 289 289 code := m.Run() 290 290 291 - // Cleanup is automatic with t.TempDir() 291 + sharedPDS.Close() 292 292 os.Exit(code) 293 293 }