Update registrar unit tests to match them of cri-o

- Add the test framework abstraction
- Update the unit tests to run with ginkgo

Signed-off-by: Sascha Grunert <sgrunert@suse.com>
This commit is contained in:
Sascha Grunert
2019-04-03 12:32:49 +02:00
parent 4bda5378b1
commit 88b0e74e0b
3 changed files with 254 additions and 99 deletions

View File

@ -30,7 +30,6 @@ BASHINSTALLDIR=${PREFIX}/share/bash-completion/completions
ZSHINSTALLDIR=${PREFIX}/share/zsh/site-functions
SELINUXOPT ?= $(shell test -x /usr/sbin/selinuxenabled && selinuxenabled && echo -Z)
PACKAGES ?= $(shell $(GO) list -tags "${BUILDTAGS}" ./... | grep -v github.com/containers/libpod/vendor | grep -v e2e | grep -v system )
COMMIT_NO ?= $(shell git rev-parse HEAD 2> /dev/null || true)
GIT_COMMIT ?= $(if $(shell git status --porcelain --untracked-files=no),${COMMIT_NO}-dirty,${COMMIT_NO})
@ -172,7 +171,13 @@ testunit: libpodimage ## Run unittest on the built image
${CONTAINER_RUNTIME} run -e STORAGE_OPTIONS="--storage-driver=vfs" -e TESTFLAGS -e CGROUP_MANAGER=cgroupfs -e OCI_RUNTIME -e TRAVIS -t --privileged --rm -v ${CURDIR}:/go/src/${PROJECT} ${LIBPOD_IMAGE} make localunit
localunit: test/goecho/goecho varlink_generate
$(GO) test -tags "$(BUILDTAGS)" -cover $(PACKAGES)
ginkgo \
-r \
--skipPackage test/e2e,pkg/apparmor \
--cover \
--covermode atomic \
--tags "$(BUILDTAGS)" \
--succinct
$(MAKE) -C contrib/cirrus/packer test
ginkgo:

View File

@ -1,119 +1,213 @@
package registrar
package registrar_test
import (
"reflect"
"testing"
"github.com/containers/libpod/pkg/registrar"
. "github.com/containers/libpod/test/framework"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
func TestReserve(t *testing.T) {
r := NewRegistrar()
obj := "test1"
if err := r.Reserve("test", obj); err != nil {
t.Fatal(err)
}
if err := r.Reserve("test", obj); err != nil {
t.Fatal(err)
}
obj2 := "test2"
err := r.Reserve("test", obj2)
if err == nil {
t.Fatalf("expected error when reserving an already reserved name to another object")
}
if err != ErrNameReserved {
t.Fatal("expected `ErrNameReserved` error when attempting to reserve an already reserved name")
}
// TestRegistrar runs the created specs
func TestRegistrar(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Registrar")
}
func TestRelease(t *testing.T) {
r := NewRegistrar()
obj := "testing"
// nolint: gochecknoglobals
var t *TestFramework
if err := r.Reserve("test", obj); err != nil {
t.Fatal(err)
}
r.Release("test")
r.Release("test") // Ensure there is no panic here
var _ = BeforeSuite(func() {
t = NewTestFramework(NilFunc, NilFunc)
t.Setup()
})
if err := r.Reserve("test", obj); err != nil {
t.Fatal(err)
}
}
var _ = AfterSuite(func() {
t.Teardown()
})
func TestGetNames(t *testing.T) {
r := NewRegistrar()
obj := "testing"
names := []string{"test1", "test2"}
// The actual test suite
var _ = t.Describe("Registrar", func() {
// Constant test data needed by some tests
const (
testKey = "testKey"
testName = "testName"
anotherKey = "anotherKey"
)
for _, name := range names {
if err := r.Reserve(name, obj); err != nil {
t.Fatal(err)
}
}
r.Reserve("test3", "other")
// The system under test
var sut *registrar.Registrar
names2, err := r.GetNames(obj)
if err != nil {
t.Fatal(err)
// Prepare the system under test and register a test name and key before
// each test
BeforeEach(func() {
sut = registrar.NewRegistrar()
Expect(sut.Reserve(testName, testKey)).To(BeNil())
})
t.Describe("Reserve", func() {
It("should succeed to reserve a new registrar", func() {
// Given
// When
err := sut.Reserve("name", "key")
// Then
Expect(err).To(BeNil())
})
It("should succeed to reserve a registrar twice", func() {
// Given
// When
err := sut.Reserve(testName, testKey)
// Then
Expect(err).To(BeNil())
})
It("should fail to reserve an already reserved registrar", func() {
// Given
// When
err := sut.Reserve(testName, anotherKey)
// Then
Expect(err).NotTo(BeNil())
Expect(err).To(Equal(registrar.ErrNameReserved))
})
})
t.Describe("Release", func() {
It("should succeed to release a registered registrar multiple times", func() {
// Given
// When
// Then
sut.Release(testName)
sut.Release(testName)
})
It("should succeed to release a unknown registrar multiple times", func() {
// Given
// When
// Then
sut.Release(anotherKey)
sut.Release(anotherKey)
})
It("should succeed to release and re-register a registrar", func() {
// Given
// When
sut.Release(testName)
err := sut.Reserve(testName, testKey)
// Then
Expect(err).To(BeNil())
})
})
t.Describe("GetNames", func() {
It("should succeed to retrieve a single name for a registrar", func() {
// Given
// When
names, err := sut.GetNames(testKey)
// Then
Expect(err).To(BeNil())
Expect(len(names)).To(Equal(1))
Expect(names[0]).To(Equal(testName))
})
It("should succeed to retrieve all names for a registrar", func() {
// Given
testNames := []string{"test1", "test2"}
for _, name := range testNames {
Expect(sut.Reserve(name, anotherKey)).To(BeNil())
}
if !reflect.DeepEqual(names, names2) {
t.Fatalf("Exepected: %v, Got: %v", names, names2)
}
}
// When
names, err := sut.GetNames(anotherKey)
func TestDelete(t *testing.T) {
r := NewRegistrar()
obj := "testing"
names := []string{"test1", "test2"}
for _, name := range names {
if err := r.Reserve(name, obj); err != nil {
t.Fatal(err)
}
// Then
Expect(err).To(BeNil())
Expect(len(names)).To(Equal(2))
Expect(names).To(Equal(testNames))
})
})
t.Describe("GetNames", func() {
It("should succeed to retrieve a single name for a registrar", func() {
// Given
// When
names, err := sut.GetNames(testKey)
// Then
Expect(err).To(BeNil())
Expect(len(names)).To(Equal(1))
Expect(names[0]).To(Equal(testName))
})
It("should succeed to retrieve all names for a registrar", func() {
// Given
anotherKey := "anotherKey"
testNames := []string{"test1", "test2"}
for _, name := range testNames {
Expect(sut.Reserve(name, anotherKey)).To(BeNil())
}
r.Reserve("test3", "other")
r.Delete(obj)
// When
names, err := sut.GetNames(anotherKey)
_, err := r.GetNames(obj)
if err == nil {
t.Fatal("expected error getting names for deleted key")
}
// Then
Expect(err).To(BeNil())
Expect(len(names)).To(Equal(2))
Expect(names).To(Equal(testNames))
})
})
if err != ErrNoSuchKey {
t.Fatal("expected `ErrNoSuchKey`")
}
}
t.Describe("Delete", func() {
It("should succeed to delete a registrar", func() {
// Given
// When
sut.Delete(testKey)
func TestGet(t *testing.T) {
r := NewRegistrar()
obj := "testing"
name := "test"
// Then
names, err := sut.GetNames(testKey)
Expect(len(names)).To(BeZero())
Expect(err).To(Equal(registrar.ErrNoSuchKey))
})
})
_, err := r.Get(name)
if err == nil {
t.Fatal("expected error when key does not exist")
}
if err != ErrNameNotReserved {
t.Fatal(err)
}
t.Describe("Get", func() {
It("should succeed to get a key for a registrar", func() {
// Given
// When
key, err := sut.Get(testName)
if err := r.Reserve(name, obj); err != nil {
t.Fatal(err)
}
// Then
Expect(err).To(BeNil())
Expect(key).To(Equal(testKey))
})
if _, err = r.Get(name); err != nil {
t.Fatal(err)
}
It("should fail to get a key for a not existing registrar", func() {
// Given
// When
key, err := sut.Get("notExistingName")
r.Delete(obj)
_, err = r.Get(name)
if err == nil {
t.Fatal("expected error when key does not exist")
}
if err != ErrNameNotReserved {
t.Fatal(err)
}
}
// Then
Expect(key).To(BeEmpty())
Expect(err).To(Equal(registrar.ErrNameNotReserved))
})
})
t.Describe("GetAll", func() {
It("should succeed to get all names", func() {
// Given
// When
names := sut.GetAll()
// Then
Expect(len(names)).To(Equal(1))
Expect(len(names[testKey])).To(Equal(1))
Expect(names[testKey][0]).To(Equal(testName))
})
})
})

View File

@ -0,0 +1,56 @@
package framework
import (
"fmt"
"github.com/onsi/ginkgo"
"github.com/onsi/gomega"
)
// TestFramework is used to support commonnly used test features
type TestFramework struct {
setup func(*TestFramework) error
teardown func(*TestFramework) error
TestError error
}
// NewTestFramework creates a new test framework instance for a given `setup`
// and `teardown` function
func NewTestFramework(
setup func(*TestFramework) error,
teardown func(*TestFramework) error,
) *TestFramework {
return &TestFramework{
setup,
teardown,
fmt.Errorf("error"),
}
}
// NilFn is a convenience function which simply does nothing
func NilFunc(f *TestFramework) error {
return nil
}
// Setup is the global initialization function which runs before each test
// suite
func (t *TestFramework) Setup() {
// Global initialization for the whole framework goes in here
// Setup the actual test suite
gomega.Expect(t.setup(t)).To(gomega.Succeed())
}
// Teardown is the global deinitialization function which runs after each test
// suite
func (t *TestFramework) Teardown() {
// Global deinitialization for the whole framework goes in here
// Teardown the actual test suite
gomega.Expect(t.teardown(t)).To(gomega.Succeed())
}
// Describe is a convenience wrapper around the `ginkgo.Describe` function
func (t *TestFramework) Describe(text string, body func()) bool {
return ginkgo.Describe("libpod: "+text, body)
}