source-controller/internal/index/digest_test.go

347 lines
6.6 KiB
Go

/*
Copyright 2022 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package index
import (
"bytes"
"errors"
"testing"
. "github.com/onsi/gomega"
"github.com/opencontainers/go-digest"
)
func TestWithIndex(t *testing.T) {
t.Run("sets the index", func(t *testing.T) {
g := NewWithT(t)
i := map[string]string{"foo": "bar"}
d := &Digester{}
WithIndex(i)(d)
g.Expect(d.index).To(Equal(i))
})
t.Run("resets the digests", func(t *testing.T) {
g := NewWithT(t)
i := map[string]string{"foo": "bar"}
d := &Digester{
digests: map[digest.Algorithm]digest.Digest{
digest.SHA256: "sha256:foo",
},
}
WithIndex(i)(d)
g.Expect(d.digests).To(BeEmpty())
})
}
func TestNewDigester(t *testing.T) {
t.Run("default", func(t *testing.T) {
g := NewWithT(t)
d := NewDigester()
g.Expect(d).ToNot(BeNil())
g.Expect(d.index).ToNot(BeNil())
g.Expect(d.digests).ToNot(BeNil())
})
t.Run("with index", func(t *testing.T) {
g := NewWithT(t)
i := map[string]string{"foo": "bar"}
d := NewDigester(WithIndex(i))
g.Expect(d).ToNot(BeNil())
g.Expect(d.index).To(Equal(i))
g.Expect(d.digests).ToNot(BeNil())
})
}
func TestDigester_Add(t *testing.T) {
t.Run("adds", func(t *testing.T) {
g := NewWithT(t)
d := NewDigester()
d.Add("foo", "bar")
g.Expect(d.index).To(HaveKeyWithValue("foo", "bar"))
})
t.Run("overwrites", func(t *testing.T) {
g := NewWithT(t)
d := NewDigester()
d.Add("foo", "bar")
d.Add("foo", "baz")
g.Expect(d.index).To(HaveKeyWithValue("foo", "baz"))
})
t.Run("resets digests", func(t *testing.T) {
g := NewWithT(t)
d := &Digester{
index: map[string]string{},
digests: map[digest.Algorithm]digest.Digest{
digest.SHA256: "sha256:foo",
},
}
d.Add("foo", "bar")
g.Expect(d.digests).To(BeEmpty())
})
}
func TestDigester_Delete(t *testing.T) {
t.Run("deletes", func(t *testing.T) {
g := NewWithT(t)
d := NewDigester()
d.Add("foo", "bar")
d.Delete("foo")
g.Expect(d.index).ToNot(HaveKey("foo"))
})
t.Run("resets digests", func(t *testing.T) {
g := NewWithT(t)
d := &Digester{
index: map[string]string{
"foo": "bar",
},
digests: map[digest.Algorithm]digest.Digest{
digest.SHA256: "sha256:foo",
},
}
d.Delete("nop")
g.Expect(d.digests).To(HaveLen(1))
d.Delete("foo")
g.Expect(d.digests).To(BeEmpty())
})
}
func TestDigester_Get(t *testing.T) {
g := NewWithT(t)
d := NewDigester()
d.Add("foo", "bar")
g.Expect(d.Get("foo")).To(Equal("bar"))
g.Expect(d.Get("bar")).To(BeEmpty())
}
func TestDigester_Has(t *testing.T) {
g := NewWithT(t)
d := NewDigester()
d.Add("foo", "bar")
g.Expect(d.Has("foo")).To(BeTrue())
g.Expect(d.Has("bar")).To(BeFalse())
}
func TestDigester_Index(t *testing.T) {
g := NewWithT(t)
i := map[string]string{
"foo": "bar",
"bar": "baz",
}
d := NewDigester(WithIndex(i))
iCopy := d.Index()
g.Expect(iCopy).To(Equal(i))
g.Expect(iCopy).ToNot(BeIdenticalTo(i))
}
func TestDigester_Len(t *testing.T) {
g := NewWithT(t)
d := NewDigester(WithIndex(map[string]string{
"foo": "bar",
"bar": "baz",
}))
g.Expect(d.Len()).To(Equal(2))
}
func TestDigester_String(t *testing.T) {
g := NewWithT(t)
d := NewDigester(WithIndex(map[string]string{
"foo": "bar",
"bar": "baz",
}))
g.Expect(d.String()).To(Equal(`bar baz
foo bar
`))
}
func TestDigester_WriteTo(t *testing.T) {
t.Run("writes", func(t *testing.T) {
g := NewWithT(t)
d := NewDigester(WithIndex(map[string]string{
"foo": "bar",
"bar": "baz",
}))
expect := `bar baz
foo bar
`
var buf bytes.Buffer
n, err := d.WriteTo(&buf)
g.Expect(n).To(Equal(int64(len(expect))))
g.Expect(err).ToNot(HaveOccurred())
g.Expect(buf.String()).To(Equal(expect))
})
t.Run("errors", func(t *testing.T) {
g := NewWithT(t)
d := NewDigester(WithIndex(map[string]string{
"foo": "bar",
"bar": "baz",
}))
w := &fakeWriter{
err: errors.New("write error"),
written: 5,
}
n, err := d.WriteTo(w)
g.Expect(err).To(HaveOccurred())
g.Expect(errors.Is(err, w.err)).To(BeTrue())
g.Expect(n).To(Equal(int64(w.written)))
})
}
func TestDigester_Digest(t *testing.T) {
t.Run("returns digest", func(t *testing.T) {
g := NewWithT(t)
d := NewDigester(WithIndex(map[string]string{
"foo": "bar",
"bar": "baz",
}))
expect := digest.SHA256.FromString(d.String())
g.Expect(d.Digest(digest.SHA256)).To(Equal(expect))
g.Expect(d.digests).To(HaveKeyWithValue(digest.SHA256, expect))
})
t.Run("returns cached digest", func(t *testing.T) {
g := NewWithT(t)
d := &Digester{
index: map[string]string{
"foo": "bar",
"bar": "baz",
},
digests: map[digest.Algorithm]digest.Digest{
digest.SHA256: "sha256:foo",
},
}
g.Expect(d.Digest(digest.SHA256)).To(Equal(d.digests[digest.SHA256]))
})
}
func TestDigester_Verify(t *testing.T) {
g := NewWithT(t)
d := NewDigester(WithIndex(map[string]string{
"foo": "bar",
}))
g.Expect(d.Verify(d.Digest(digest.SHA256))).To(BeTrue())
g.Expect(d.Verify(digest.SHA256.FromString("different"))).To(BeFalse())
}
func TestDigester_sortedKeys(t *testing.T) {
g := NewWithT(t)
d := NewDigester(WithIndex(map[string]string{
"c/d/e": "bar",
"a/b/c": "baz",
"f/g/h": "foo",
}))
g.Expect(d.sortedKeys()).To(Equal([]string{
"a/b/c",
"c/d/e",
"f/g/h",
}))
}
func TestDigester_reset(t *testing.T) {
g := NewWithT(t)
d := NewDigester()
d.digests = map[digest.Algorithm]digest.Digest{
digest.SHA256: "sha256:foo",
}
d.reset()
g.Expect(d.digests).To(BeEmpty())
}
func Test_writeLine(t *testing.T) {
t.Run("writes", func(t *testing.T) {
g := NewWithT(t)
var buf bytes.Buffer
n, err := writeLine(&buf, "foo", "bar")
g.Expect(n).To(Equal(8))
g.Expect(err).ToNot(HaveOccurred())
g.Expect(buf.String()).To(Equal(`foo bar
`))
})
t.Run("errors", func(t *testing.T) {
g := NewWithT(t)
w := &fakeWriter{
err: errors.New("write error"),
written: 5,
}
n, err := writeLine(w, "foo", "bar")
g.Expect(err).To(HaveOccurred())
g.Expect(errors.Is(err, w.err)).To(BeTrue())
g.Expect(n).To(Equal(w.written))
})
}
type fakeWriter struct {
written int
err error
}
func (f *fakeWriter) Write(p []byte) (n int, err error) {
return f.written, f.err
}