From 623e6c7f1796cf7450a0e4b76b8e2b0774801de5 Mon Sep 17 00:00:00 2001 From: Andrew Meyer Date: Thu, 23 Sep 2021 17:22:42 -0700 Subject: [PATCH] fixup; backwards compat --- postal/fakes/mapping_resolver.go | 16 +- postal/internal/dependency_mappings.go | 8 +- postal/internal/dependency_mappings_test.go | 7 +- postal/internal/fakes/binding_resolver.go | 18 +- postal/service.go | 19 +- postal/service_test.go | 258 +------------------- servicebindings/resolver.go | 56 +++-- servicebindings/resolver_test.go | 46 ++-- 8 files changed, 96 insertions(+), 332 deletions(-) diff --git a/postal/fakes/mapping_resolver.go b/postal/fakes/mapping_resolver.go index 2e7c7b6d..09a8b0a5 100644 --- a/postal/fakes/mapping_resolver.go +++ b/postal/fakes/mapping_resolver.go @@ -4,26 +4,28 @@ import "sync" type MappingResolver struct { FindDependencyMappingCall struct { - sync.Mutex + mutex sync.Mutex CallCount int Receives struct { - SHA256 string + SHA256 string + PlatformDir string } Returns struct { String string Error error } - Stub func(string) (string, error) + Stub func(string, string) (string, error) } } -func (f *MappingResolver) FindDependencyMapping(param1 string) (string, error) { - f.FindDependencyMappingCall.Lock() - defer f.FindDependencyMappingCall.Unlock() +func (f *MappingResolver) FindDependencyMapping(param1 string, param2 string) (string, error) { + f.FindDependencyMappingCall.mutex.Lock() + defer f.FindDependencyMappingCall.mutex.Unlock() f.FindDependencyMappingCall.CallCount++ f.FindDependencyMappingCall.Receives.SHA256 = param1 + f.FindDependencyMappingCall.Receives.PlatformDir = param2 if f.FindDependencyMappingCall.Stub != nil { - return f.FindDependencyMappingCall.Stub(param1) + return f.FindDependencyMappingCall.Stub(param1, param2) } return f.FindDependencyMappingCall.Returns.String, f.FindDependencyMappingCall.Returns.Error } diff --git a/postal/internal/dependency_mappings.go b/postal/internal/dependency_mappings.go index 6f1bc068..dd8930a2 100644 --- a/postal/internal/dependency_mappings.go +++ b/postal/internal/dependency_mappings.go @@ -7,7 +7,7 @@ import ( //go:generate faux --interface BindingResolver --output fakes/binding_resolver.go type BindingResolver interface { - Resolve(typ string, provider string) ([]servicebindings.Binding, error) + Resolve(typ string, provider string, platformDir string) ([]servicebindings.Binding, error) } type DependencyMappingResolver struct { @@ -20,9 +20,9 @@ func NewDependencyMappingResolver(bindingResolver BindingResolver) DependencyMap } } -// FindDependencyMapping looks up if there is a matching dependency mapping at the given binding path -func (d DependencyMappingResolver) FindDependencyMapping(sha256 string) (string, error) { - bindings, err := d.bindingResolver.Resolve("dependency-mapping", "") +// FindDependencyMapping looks up if there is a matching dependency mapping +func (d DependencyMappingResolver) FindDependencyMapping(sha256 string, platformDir string) (string, error) { + bindings, err := d.bindingResolver.Resolve("dependency-mapping", "", platformDir) if err != nil { return "", fmt.Errorf("failed to resolve 'dependency-mapping' binding: %w", err) } diff --git a/postal/internal/dependency_mappings_test.go b/postal/internal/dependency_mappings_test.go index 8698c540..dc7ae033 100644 --- a/postal/internal/dependency_mappings_test.go +++ b/postal/internal/dependency_mappings_test.go @@ -66,15 +66,18 @@ func testDependencyMappings(t *testing.T, context spec.G, it spec.S) { context("given a set of bindings and a dependency", func() { it("finds a matching dependency mappings in the platform bindings if there is one", func() { - boundDependency, err := resolver.FindDependencyMapping("some-sha") + boundDependency, err := resolver.FindDependencyMapping("some-sha", "some-platform-dir") Expect(err).ToNot(HaveOccurred()) + Expect(bindingResolver.ResolveCall.Receives.Typ).To(Equal("dependency-mapping")) + Expect(bindingResolver.ResolveCall.Receives.Provider).To(BeEmpty()) + Expect(bindingResolver.ResolveCall.Receives.PlatformDir).To(Equal("some-platform-dir")) Expect(boundDependency).To(Equal("dependency-mapping-entry.tgz")) }) }) context("given a set of bindings and a dependency", func() { it("returns an empty DependencyMapping if there is no match", func() { - boundDependency, err := resolver.FindDependencyMapping("unmatched-sha") + boundDependency, err := resolver.FindDependencyMapping("unmatched-sha", "") Expect(err).ToNot(HaveOccurred()) Expect(boundDependency).To(Equal("")) }) diff --git a/postal/internal/fakes/binding_resolver.go b/postal/internal/fakes/binding_resolver.go index 5b39b9c6..8edce015 100644 --- a/postal/internal/fakes/binding_resolver.go +++ b/postal/internal/fakes/binding_resolver.go @@ -8,28 +8,30 @@ import ( type BindingResolver struct { ResolveCall struct { - sync.Mutex + mutex sync.Mutex CallCount int Receives struct { - Typ string - Provider string + Typ string + Provider string + PlatformDir string } Returns struct { BindingSlice []servicebindings.Binding Error error } - Stub func(string, string) ([]servicebindings.Binding, error) + Stub func(string, string, string) ([]servicebindings.Binding, error) } } -func (f *BindingResolver) Resolve(param1 string, param2 string) ([]servicebindings.Binding, error) { - f.ResolveCall.Lock() - defer f.ResolveCall.Unlock() +func (f *BindingResolver) Resolve(param1 string, param2 string, param3 string) ([]servicebindings.Binding, error) { + f.ResolveCall.mutex.Lock() + defer f.ResolveCall.mutex.Unlock() f.ResolveCall.CallCount++ f.ResolveCall.Receives.Typ = param1 f.ResolveCall.Receives.Provider = param2 + f.ResolveCall.Receives.PlatformDir = param3 if f.ResolveCall.Stub != nil { - return f.ResolveCall.Stub(param1, param2) + return f.ResolveCall.Stub(param1, param2, param3) } return f.ResolveCall.Returns.BindingSlice, f.ResolveCall.Returns.Error } diff --git a/postal/service.go b/postal/service.go index 658bc146..f205e3e9 100644 --- a/postal/service.go +++ b/postal/service.go @@ -30,7 +30,7 @@ type Transport interface { // MappingResolver serves as the interface that looks up platform binding provided // dependency mappings given a SHA256 type MappingResolver interface { - FindDependencyMapping(SHA256 string) (string, error) + FindDependencyMapping(SHA256 string, platformDir string) (string, error) } // Service provides a mechanism for resolving and installing dependencies given @@ -40,12 +40,12 @@ type Service struct { mappingResolver MappingResolver } -// NewService creates an instance of a Servicel given a Transport. -func NewService(transport Transport, platformDir string) Service { +// NewService creates an instance of a Service given a Transport. +func NewService(transport Transport) Service { return Service{ transport: transport, mappingResolver: internal.NewDependencyMappingResolver( - servicebindings.NewResolver(platformDir), + servicebindings.NewResolver(), ), } } @@ -143,8 +143,8 @@ func (s Service) Resolve(path, id, version, stack string) (Dependency, error) { // the given dependency mapping URI to fetch the dependency. The dependency is // validated against the checksum value provided on the Dependency and will // error if there are inconsistencies in the fetched result. -func (s Service) Deliver(dependency Dependency, cnbPath, layerPath string) error { - dependencyMappingURI, err := s.mappingResolver.FindDependencyMapping(dependency.SHA256) +func (s Service) Deliver(dependency Dependency, cnbPath, layerPath, platformPath string) error { + dependencyMappingURI, err := s.mappingResolver.FindDependencyMapping(dependency.SHA256, platformPath) if err != nil { return fmt.Errorf("failure checking for dependency mappings: %s", err) } @@ -179,13 +179,6 @@ func (s Service) Deliver(dependency Dependency, cnbPath, layerPath string) error return nil } -// Install will invoke Deliver. -// -// Deprecated: Use Deliver instead. -func (s Service) Install(dependency Dependency, cnbPath, layerPath string) error { - return s.Deliver(dependency, cnbPath, layerPath) -} - // GenerateBillOfMaterials will generate a list of BOMEntry values given a // collection of Dependency values. func (s Service) GenerateBillOfMaterials(dependencies ...Dependency) []packit.BOMEntry { diff --git a/postal/service_test.go b/postal/service_test.go index af811154..d071a259 100644 --- a/postal/service_test.go +++ b/postal/service_test.go @@ -92,7 +92,7 @@ strip-components = 1 mappingResolver = &fakes.MappingResolver{} - service = postal.NewService(transport, "").WithDependencyMappingResolver(mappingResolver) + service = postal.NewService(transport).WithDependencyMappingResolver(mappingResolver) }) context("Resolve", func() { @@ -369,6 +369,7 @@ version = "this is super not semver" }, "some-cnb-path", layerPath, + "some-platform-dir", ) } }) @@ -384,6 +385,7 @@ version = "this is super not semver" Expect(transport.DropCall.Receives.Root).To(Equal("some-cnb-path")) Expect(transport.DropCall.Receives.Uri).To(Equal("some-entry.tgz")) + Expect(mappingResolver.FindDependencyMappingCall.Receives.PlatformDir).To(Equal("some-platform-dir")) files, err := filepath.Glob(fmt.Sprintf("%s/*", layerPath)) Expect(err).NotTo(HaveOccurred()) @@ -451,6 +453,7 @@ version = "this is super not semver" }, "some-cnb-path", layerPath, + "", ) } }) @@ -508,6 +511,7 @@ version = "this is super not semver" }, "some-cnb-path", layerPath, + "", ) } }) @@ -628,6 +632,7 @@ version = "this is super not semver" }, "some-cnb-path", layerPath, + "", ) Expect(err).To(MatchError(ContainSubstring("checksum does not match"))) @@ -711,257 +716,6 @@ version = "this is super not semver" }) }) - context("Install", func() { - var ( - dependencySHA string - layerPath string - install func() error - ) - - it.Before(func() { - var err error - layerPath, err = os.MkdirTemp("", "layer") - Expect(err).NotTo(HaveOccurred()) - - buffer := bytes.NewBuffer(nil) - zw := gzip.NewWriter(buffer) - tw := tar.NewWriter(zw) - - Expect(tw.WriteHeader(&tar.Header{Name: "./some-dir", Mode: 0755, Typeflag: tar.TypeDir})).To(Succeed()) - _, err = tw.Write(nil) - Expect(err).NotTo(HaveOccurred()) - - nestedFile := "./some-dir/some-file" - Expect(tw.WriteHeader(&tar.Header{Name: nestedFile, Mode: 0755, Size: int64(len(nestedFile))})).To(Succeed()) - _, err = tw.Write([]byte(nestedFile)) - Expect(err).NotTo(HaveOccurred()) - - for _, file := range []string{"./first", "./second", "./third"} { - Expect(tw.WriteHeader(&tar.Header{Name: file, Mode: 0755, Size: int64(len(file))})).To(Succeed()) - _, err = tw.Write([]byte(file)) - Expect(err).NotTo(HaveOccurred()) - } - - linkName := "./symlink" - linkDest := "./first" - Expect(tw.WriteHeader(&tar.Header{Name: linkName, Mode: 0777, Size: int64(0), Typeflag: tar.TypeSymlink, Linkname: linkDest})).To(Succeed()) - _, err = tw.Write([]byte{}) - Expect(err).NotTo(HaveOccurred()) - - Expect(tw.Close()).To(Succeed()) - Expect(zw.Close()).To(Succeed()) - - sum := sha256.Sum256(buffer.Bytes()) - dependencySHA = hex.EncodeToString(sum[:]) - - transport.DropCall.Returns.ReadCloser = io.NopCloser(buffer) - - install = func() error { - return service.Install(postal.Dependency{ - ID: "some-entry", - Stacks: []string{"some-stack"}, - URI: "some-entry.tgz", - SHA256: dependencySHA, - Version: "1.2.3", - }, "some-cnb-path", - layerPath, - ) - } - }) - - it.After(func() { - Expect(os.RemoveAll(layerPath)).To(Succeed()) - }) - - it("downloads the dependency and unpackages it into the path", func() { - err := install() - - Expect(err).NotTo(HaveOccurred()) - - Expect(transport.DropCall.Receives.Root).To(Equal("some-cnb-path")) - Expect(transport.DropCall.Receives.Uri).To(Equal("some-entry.tgz")) - - files, err := filepath.Glob(fmt.Sprintf("%s/*", layerPath)) - Expect(err).NotTo(HaveOccurred()) - Expect(files).To(ConsistOf([]string{ - filepath.Join(layerPath, "first"), - filepath.Join(layerPath, "second"), - filepath.Join(layerPath, "third"), - filepath.Join(layerPath, "some-dir"), - filepath.Join(layerPath, "symlink"), - })) - - info, err := os.Stat(filepath.Join(layerPath, "first")) - Expect(err).NotTo(HaveOccurred()) - Expect(info.Mode()).To(Equal(os.FileMode(0755))) - }) - - context("when there is a dependency mapping via binding", func() { - it.Before(func() { - mappingResolver.FindDependencyMappingCall.Returns.String = "dependency-mapping-entry.tgz" - }) - - it("looks up the dependency from the platform binding and downloads that instead", func() { - err := install() - - Expect(err).NotTo(HaveOccurred()) - - Expect(mappingResolver.FindDependencyMappingCall.Receives.SHA256).To(Equal(dependencySHA)) - Expect(transport.DropCall.Receives.Root).To(Equal("some-cnb-path")) - Expect(transport.DropCall.Receives.Uri).To(Equal("dependency-mapping-entry.tgz")) - - files, err := filepath.Glob(fmt.Sprintf("%s/*", layerPath)) - Expect(err).NotTo(HaveOccurred()) - Expect(files).To(ConsistOf([]string{ - filepath.Join(layerPath, "first"), - filepath.Join(layerPath, "second"), - filepath.Join(layerPath, "third"), - filepath.Join(layerPath, "some-dir"), - filepath.Join(layerPath, "symlink"), - })) - - info, err := os.Stat(filepath.Join(layerPath, "first")) - Expect(err).NotTo(HaveOccurred()) - Expect(info.Mode()).To(Equal(os.FileMode(0755))) - }) - }) - - context("failure cases", func() { - context("when the transport cannot fetch a dependency", func() { - it.Before(func() { - transport.DropCall.Returns.Error = errors.New("there was an error") - }) - - it("returns an error", func() { - err := install() - - Expect(err).To(MatchError("failed to fetch dependency: there was an error")) - }) - }) - - context("when the file contents are empty", func() { - it.Before(func() { - // This is a FLAC header - buffer := bytes.NewBuffer([]byte("\x66\x4C\x61\x43\x00\x00\x00\x22")) - transport.DropCall.Returns.ReadCloser = io.NopCloser(buffer) - - sum := sha256.Sum256(buffer.Bytes()) - dependencySHA = hex.EncodeToString(sum[:]) - }) - - it("fails to create a gzip reader", func() { - err := install() - - Expect(err).To(MatchError(ContainSubstring("unsupported archive type"))) - }) - }) - - context("when the file contents are malformed", func() { - it.Before(func() { - buffer := bytes.NewBuffer(nil) - gzipWriter := gzip.NewWriter(buffer) - - _, err := gzipWriter.Write([]byte("something")) - Expect(err).NotTo(HaveOccurred()) - - Expect(gzipWriter.Close()).To(Succeed()) - - transport.DropCall.Returns.ReadCloser = io.NopCloser(buffer) - - sum := sha256.Sum256(buffer.Bytes()) - dependencySHA = hex.EncodeToString(sum[:]) - }) - - it("fails to create a tar reader", func() { - err := install() - - Expect(err).To(MatchError(ContainSubstring("failed to read tar response"))) - }) - }) - - context("when the file checksum does not match", func() { - it("fails to create a tar reader", func() { - err := service.Install(postal.Dependency{ - ID: "some-entry", - Stacks: []string{"some-stack"}, - URI: "some-entry.tgz", - SHA256: "this is not a valid checksum", - Version: "1.2.3", - }, "some-cnb-path", - layerPath, - ) - - Expect(err).To(MatchError(ContainSubstring("checksum does not match"))) - }) - }) - - context("when it does not have permission to write into directory on container", func() { - it.Before(func() { - Expect(os.Chmod(layerPath, 0000)).To(Succeed()) - }) - - it.After(func() { - Expect(os.Chmod(layerPath, 0755)).To(Succeed()) - }) - - it("fails to make a dir", func() { - err := install() - - Expect(err).To(MatchError(ContainSubstring("failed to create archived directory"))) - }) - }) - - context("when it does not have permission to write into directory that it decompressed", func() { - var testDir string - it.Before(func() { - testDir = filepath.Join(layerPath, "some-dir") - Expect(os.MkdirAll(testDir, os.ModePerm)).To(Succeed()) - Expect(os.Chmod(testDir, 0000)).To(Succeed()) - }) - - it.After(func() { - Expect(os.Chmod(testDir, 0755)).To(Succeed()) - }) - - it("fails to make a file", func() { - err := install() - - Expect(err).To(MatchError(ContainSubstring("failed to create archived file"))) - }) - }) - - context("when it is given a broken symlink", func() { - it.Before(func() { - buffer := bytes.NewBuffer(nil) - zw := gzip.NewWriter(buffer) - tw := tar.NewWriter(zw) - - linkName := "symlink" - Expect(tw.WriteHeader(&tar.Header{Name: linkName, Mode: 0777, Size: int64(0), Typeflag: tar.TypeSymlink, Linkname: "some-file"})).To(Succeed()) - _, err := tw.Write([]byte{}) - Expect(err).NotTo(HaveOccurred()) - - Expect(tw.Close()).To(Succeed()) - Expect(zw.Close()).To(Succeed()) - - Expect(os.WriteFile(filepath.Join(layerPath, "some-file"), nil, 0644)).To(Succeed()) - Expect(os.Symlink("some-file", filepath.Join(layerPath, "symlink"))).To(Succeed()) - - sum := sha256.Sum256(buffer.Bytes()) - dependencySHA = hex.EncodeToString(sum[:]) - - transport.DropCall.Returns.ReadCloser = io.NopCloser(buffer) - }) - - it("fails to extract the symlink", func() { - err := install() - - Expect(err).To(MatchError(ContainSubstring("failed to extract symlink"))) - }) - }) - }) - }) - context("GenerateBillOfMaterials", func() { it("returns a list of BOMEntry values", func() { diff --git a/servicebindings/resolver.go b/servicebindings/resolver.go index ca30d0ec..3c5bc887 100644 --- a/servicebindings/resolver.go +++ b/servicebindings/resolver.go @@ -37,31 +37,22 @@ type Resolver struct { bindings []Binding } -// NewResolver returns a new service binding resolver. The location of the bindings is given by one of the following, in -// the following order of precedence: -// -// 1. SERVICE_BINDING_ROOT environment variable -// 2. CNB_BINDINGS environment variable, if above is not set -// 3. `/bindings`, if both above are not set -func NewResolver(platformDir string) *Resolver { - root := os.Getenv("SERVICE_BINDING_ROOT") - if root == "" { - root = os.Getenv("CNB_BINDINGS") - } - - if root == "" { - root = filepath.Join(platformDir, "bindings") - } - - return &Resolver{ - bindingRoot: root, - } +// NewResolver returns a new service binding resolver. +func NewResolver() *Resolver { + return &Resolver{} } // Resolve returns all bindings matching the given type and optional provider (case-insensitive). To match on type only, // provider may be an empty string. Returns an error if there are problems loading bindings from the file system. -func (r *Resolver) Resolve(typ string, provider string) ([]Binding, error) { - if r.bindings == nil { +// +// The location of bindings is given by one of the following, in order of precedence: +// +// 1. SERVICE_BINDING_ROOT environment variable +// 2. CNB_BINDINGS environment variable, if above is not set +// 3. `/bindings`, if both above are not set +func (r *Resolver) Resolve(typ string, provider string, platformDir string) ([]Binding, error) { + if newRoot := bindingRoot(platformDir); r.bindingRoot != newRoot { + r.bindingRoot = newRoot bindings, err := loadBindings(r.bindingRoot) if err != nil { return nil, fmt.Errorf("failed to load bindings from '%s': %w", r.bindingRoot, err) @@ -82,8 +73,15 @@ func (r *Resolver) Resolve(typ string, provider string) ([]Binding, error) { // ResolveOne returns a single binding matching the given type and optional provider (case-insensitive). To match on // type only, provider may be an empty string. Returns an error if the number of matched bindings is not exactly one, or // if there are problems loading bindings from the file system. -func (r *Resolver) ResolveOne(typ string, provider string) (Binding, error) { - bindings, err := r.Resolve(typ, provider) +// +// The location of bindings is given by one of the following, in order of precedence: +// +// 1. SERVICE_BINDING_ROOT environment variable +// 2. CNB_BINDINGS environment variable, if above is not set +// 3. `/bindings`, if both above are not set + +func (r *Resolver) ResolveOne(typ string, provider string, platformDir string) (Binding, error) { + bindings, err := r.Resolve(typ, provider, platformDir) if err != nil { return Binding{}, err } @@ -120,6 +118,18 @@ func loadBindings(bindingRoot string) ([]Binding, error) { return bindings, nil } +func bindingRoot(platformDir string) string { + root := os.Getenv("SERVICE_BINDING_ROOT") + if root == "" { + root = os.Getenv("CNB_BINDINGS") + } + + if root == "" { + root = filepath.Join(platformDir, "bindings") + } + return root +} + // According to the legacy spec (https://github.com/buildpacks/spec/blob/main/extensions/bindings.md), a legacy binding // has a `metadata` directory within the binding path. func isLegacyBinding(bindingRoot string, name string) (bool, error) { diff --git a/servicebindings/resolver_test.go b/servicebindings/resolver_test.go index 086383b0..9e9123b3 100644 --- a/servicebindings/resolver_test.go +++ b/servicebindings/resolver_test.go @@ -14,7 +14,7 @@ import ( func testResolver(t *testing.T, context spec.G, it spec.S) { var Expect = NewWithT(t).Expect - context("NewResolver", func() { + context("binding root precedence", func() { var ( bindingRootK8s string bindingRootCNB string @@ -63,9 +63,9 @@ func testResolver(t *testing.T, context spec.G, it spec.S) { }) it("resolves bindings from SERVICE_BINDING_ROOT", func() { - resolver := servicebindings.NewResolver(platformDir) + resolver := servicebindings.NewResolver() - bindings, err := resolver.Resolve("some-type", "") + bindings, err := resolver.Resolve("some-type", "", platformDir) Expect(err).NotTo(HaveOccurred()) Expect(bindings).To(ConsistOf( servicebindings.Binding{ @@ -84,9 +84,9 @@ func testResolver(t *testing.T, context spec.G, it spec.S) { }) it("resolves bindings from SERVICE_BINDING_ROOT", func() { - resolver := servicebindings.NewResolver(platformDir) + resolver := servicebindings.NewResolver() - bindings, err := resolver.Resolve("some-type", "") + bindings, err := resolver.Resolve("some-type", "", platformDir) Expect(err).NotTo(HaveOccurred()) Expect(bindings).To(ConsistOf( servicebindings.Binding{ @@ -111,9 +111,9 @@ func testResolver(t *testing.T, context spec.G, it spec.S) { }) it("resolves bindings from CNB_BINDINGS", func() { - resolver := servicebindings.NewResolver(platformDir) + resolver := servicebindings.NewResolver() - bindings, err := resolver.Resolve("some-type", "") + bindings, err := resolver.Resolve("some-type", "", platformDir) Expect(err).NotTo(HaveOccurred()) Expect(bindings).To(ConsistOf( servicebindings.Binding{ @@ -132,9 +132,9 @@ func testResolver(t *testing.T, context spec.G, it spec.S) { }) it("resolves bindings from platform dir", func() { - resolver := servicebindings.NewResolver(platformDir) + resolver := servicebindings.NewResolver() - bindings, err := resolver.Resolve("some-type", "") + bindings, err := resolver.Resolve("some-type", "", platformDir) Expect(err).NotTo(HaveOccurred()) Expect(bindings).To(ConsistOf( servicebindings.Binding{ @@ -159,7 +159,7 @@ func testResolver(t *testing.T, context spec.G, it spec.S) { Expect(err).NotTo(HaveOccurred()) Expect(os.Setenv("SERVICE_BINDING_ROOT", bindingRoot)).To(Succeed()) - resolver = servicebindings.NewResolver("") + resolver = servicebindings.NewResolver() err = os.MkdirAll(filepath.Join(bindingRoot, "binding-1A"), os.ModePerm) Expect(err).NotTo(HaveOccurred()) @@ -214,7 +214,7 @@ func testResolver(t *testing.T, context spec.G, it spec.S) { context("Resolve", func() { it("resolves by type only (case-insensitive)", func() { - bindings, err := resolver.Resolve("TyPe-1", "") + bindings, err := resolver.Resolve("TyPe-1", "", "") Expect(err).NotTo(HaveOccurred()) Expect(bindings).To(ConsistOf( @@ -242,7 +242,7 @@ func testResolver(t *testing.T, context spec.G, it spec.S) { }) it("resolves by type and provider (case-insensitive)", func() { - bindings, err := resolver.Resolve("TyPe-1", "PrOvIdEr-1B") + bindings, err := resolver.Resolve("TyPe-1", "PrOvIdEr-1B", "") Expect(err).NotTo(HaveOccurred()) Expect(bindings).To(ConsistOf( @@ -269,7 +269,7 @@ func testResolver(t *testing.T, context spec.G, it spec.S) { err = os.WriteFile(filepath.Join(bindingRoot, "binding-metadata", "metadata"), nil, os.ModePerm) Expect(err).NotTo(HaveOccurred()) - bindings, err := resolver.Resolve("type-metadata", "") + bindings, err := resolver.Resolve("type-metadata", "", "") Expect(err).NotTo(HaveOccurred()) Expect(bindings).To(ConsistOf( @@ -288,7 +288,7 @@ func testResolver(t *testing.T, context spec.G, it spec.S) { err := os.MkdirAll(filepath.Join(bindingRoot, "bad-binding"), os.ModePerm) Expect(err).NotTo(HaveOccurred()) - _, err = resolver.Resolve("bad-type", "") + _, err = resolver.Resolve("bad-type", "", "") Expect(err).To(MatchError(HavePrefix("failed to load bindings from '%s': failed to read binding 'bad-binding': missing 'type'", bindingRoot))) }) @@ -299,7 +299,7 @@ func testResolver(t *testing.T, context spec.G, it spec.S) { err = os.WriteFile(filepath.Join(bindingRoot, "some-binding", "type"), []byte("some-type"), os.ModePerm) Expect(err).NotTo(HaveOccurred()) - bindings, err := resolver.Resolve("some-type", "") + bindings, err := resolver.Resolve("some-type", "", "") Expect(err).NotTo(HaveOccurred()) Expect(bindings).To(ConsistOf( @@ -320,14 +320,14 @@ func testResolver(t *testing.T, context spec.G, it spec.S) { err = os.WriteFile(filepath.Join(bindingRoot, "bad-binding", "type"), []byte("bad-type"), 000) Expect(err).NotTo(HaveOccurred()) - _, err = resolver.Resolve("bad-type", "") + _, err = resolver.Resolve("bad-type", "", "") Expect(err).To(MatchError(HavePrefix("failed to load bindings from '%s': failed to read binding 'bad-binding': open %s: permission denied", bindingRoot, filepath.Join(bindingRoot, "bad-binding", "type")))) }) }) context("ResolveOne", func() { it("resolves one binding (case-insensitive)", func() { - binding, err := resolver.ResolveOne("TyPe-2", "") + binding, err := resolver.ResolveOne("TyPe-2", "", "") Expect(err).NotTo(HaveOccurred()) Expect(binding).To(Equal(servicebindings.Binding{ Name: "binding-2", @@ -342,12 +342,12 @@ func testResolver(t *testing.T, context spec.G, it spec.S) { }) it("returns an error if no matches", func() { - _, err := resolver.ResolveOne("non-existent-type", "non-existent-provider") + _, err := resolver.ResolveOne("non-existent-type", "non-existent-provider", "") Expect(err).To(MatchError("found 0 bindings for type 'non-existent-type' and provider 'non-existent-provider' but expected exactly 1")) }) it("returns an error if more than one match", func() { - _, err := resolver.ResolveOne("TyPe-1", "") + _, err := resolver.ResolveOne("TyPe-1", "", "") Expect(err).To(MatchError("found 2 bindings for type 'TyPe-1' and provider '' but expected exactly 1")) }) }) @@ -372,7 +372,7 @@ func testResolver(t *testing.T, context spec.G, it spec.S) { err = os.WriteFile(filepath.Join(bindingRoot, "binding-legacy", "secret", "password"), nil, os.ModePerm) Expect(err).NotTo(HaveOccurred()) - bindings, err := resolver.Resolve("type-legacy", "") + bindings, err := resolver.Resolve("type-legacy", "", "") Expect(err).NotTo(HaveOccurred()) Expect(bindings).To(ConsistOf( @@ -402,7 +402,7 @@ func testResolver(t *testing.T, context spec.G, it spec.S) { err = os.WriteFile(filepath.Join(bindingRoot, "binding-legacy", "metadata", "some-key"), nil, os.ModePerm) Expect(err).NotTo(HaveOccurred()) - bindings, err := resolver.Resolve("type-legacy", "") + bindings, err := resolver.Resolve("type-legacy", "", "") Expect(err).NotTo(HaveOccurred()) Expect(bindings).To(ConsistOf( @@ -422,7 +422,7 @@ func testResolver(t *testing.T, context spec.G, it spec.S) { err := os.MkdirAll(filepath.Join(bindingRoot, "bad-binding", "metadata"), os.ModePerm) Expect(err).NotTo(HaveOccurred()) - _, err = resolver.Resolve("bad-type", "") + _, err = resolver.Resolve("bad-type", "", "") Expect(err).To(MatchError(HavePrefix("failed to load bindings from '%s': failed to read binding 'bad-binding': missing 'kind'", bindingRoot))) }) @@ -433,7 +433,7 @@ func testResolver(t *testing.T, context spec.G, it spec.S) { err = os.WriteFile(filepath.Join(bindingRoot, "bad-binding", "metadata", "kind"), []byte("bad-type"), os.ModePerm) Expect(err).NotTo(HaveOccurred()) - _, err = resolver.Resolve("bad-type", "") + _, err = resolver.Resolve("bad-type", "", "") Expect(err).To(MatchError(HavePrefix("failed to load bindings from '%s': failed to read binding 'bad-binding': missing 'provider'", bindingRoot))) }) })