@@ -14,6 +14,7 @@ import (
1414 "os"
1515 "os/exec"
1616 "path/filepath"
17+ "reflect"
1718 "strconv"
1819 "strings"
1920 "testing"
@@ -84,6 +85,13 @@ exec docker run --log-driver=none --rm -i {{.ImageName}}:{{.Version}} "$@"
8485 "buf.build/community/mercari-grpc-federation" : {"eliza" : true , "petapis" : true },
8586 "buf.build/googlecloudplatform/bq-schema" : {"eliza" : true , "petapis" : true },
8687 }
88+ // allowedMissingRegistryDeps lists dependencies that are known to lack a registry config for
89+ // a given registry type. The key is "pluginRef -> depRef" (e.g. "buf.build/grpc/python:v1.59.1 -> buf.build/protocolbuffers/python:v24.4").
90+ // Only add entries here for old plugin versions where the dep predates registry config support.
91+ allowedMissingRegistryDeps = map [string ]bool {
92+ "buf.build/grpc/python:v1.59.1 -> buf.build/protocolbuffers/python:v24.4" : true ,
93+ "buf.build/grpc/python:v1.59.2 -> buf.build/protocolbuffers/python:v24.4" : true ,
94+ }
8795)
8896
8997func TestGeneration (t * testing.T ) {
@@ -455,6 +463,82 @@ func TestPyPIDependencies(t *testing.T) {
455463 }
456464}
457465
466+ func TestRegistryDepsHaveRegistryConfig (t * testing.T ) {
467+ t .Parallel ()
468+ plugins := loadAllPlugins (t )
469+ // Build a lookup map by "name:version".
470+ pluginByRef := make (map [string ]* plugin.Plugin , len (plugins ))
471+ for _ , p := range plugins {
472+ pluginByRef [p .String ()] = p
473+ }
474+ // registryType returns a string identifying which registry type is configured,
475+ // or "" if no registry is configured. Fails the test if any pointer field on
476+ // the registry struct is non-nil but not handled by the switch, so this test
477+ // stays up to date when new registry types are added to ExternalRegistryConfig.
478+ registryType := func (t * testing.T , p * plugin.Plugin ) string {
479+ t .Helper ()
480+ switch {
481+ case p .Registry .Go != nil :
482+ return "go"
483+ case p .Registry .NPM != nil :
484+ return "npm"
485+ case p .Registry .Maven != nil :
486+ return "maven"
487+ case p .Registry .Swift != nil :
488+ return "swift"
489+ case p .Registry .Python != nil :
490+ return "python"
491+ case p .Registry .Cargo != nil :
492+ return "cargo"
493+ case p .Registry .Nuget != nil :
494+ return "nuget"
495+ case p .Registry .Cmake != nil :
496+ return "cmake"
497+ default :
498+ rv := reflect .ValueOf (p .Registry )
499+ rt := reflect .TypeFor [bufremotepluginconfig.ExternalRegistryConfig ]()
500+ for i := range rt .NumField () {
501+ field := rt .Field (i )
502+ if field .Type .Kind () == reflect .Pointer && ! rv .Field (i ).IsNil () {
503+ assert .Failf (t , "unrecognized registry type" , "plugin %q has unrecognized registry type field %q - update registryType() in this test" , p .String (), field .Name )
504+ }
505+ }
506+ return ""
507+ }
508+ }
509+ // checkDeps recursively verifies that all transitive dependencies of p have the expected registry type.
510+ var checkDeps func (t * testing.T , p * plugin.Plugin , want string , visited map [string ]bool )
511+ checkDeps = func (t * testing.T , p * plugin.Plugin , want string , visited map [string ]bool ) {
512+ t .Helper ()
513+ for _ , dep := range p .Deps {
514+ if visited [dep .Plugin ] {
515+ continue
516+ }
517+ visited [dep .Plugin ] = true
518+ depPlugin , ok := pluginByRef [dep .Plugin ]
519+ require .Truef (t , ok , "dependency %q not found" , dep .Plugin )
520+ key := fmt .Sprintf ("%s -> %s" , p .String (), dep .Plugin )
521+ if registryType (t , depPlugin ) != want && ! allowedMissingRegistryDeps [key ] {
522+ assert .Failf (t , "missing registry config" ,
523+ "dependency %q of plugin %q has registry type %q, want %q" ,
524+ dep .Plugin , p .String (), registryType (t , depPlugin ), want ,
525+ )
526+ }
527+ checkDeps (t , depPlugin , want , visited )
528+ }
529+ }
530+ for _ , p := range plugins {
531+ rt := registryType (t , p )
532+ if rt == "" {
533+ continue
534+ }
535+ t .Run (fmt .Sprintf ("%s/%s@%s" , p .Identity .Owner (), p .Identity .Plugin (), p .PluginVersion ), func (t * testing.T ) {
536+ t .Parallel ()
537+ checkDeps (t , p , rt , make (map [string ]bool ))
538+ })
539+ }
540+ }
541+
458542func runPluginWithImage (ctx context.Context , t * testing.T , basedir string , pluginMeta * plugin.Plugin , image string , goPkgPrefix string ) string {
459543 t .Helper ()
460544 gendir := filepath .Join (basedir , "gen" )
0 commit comments