Skip to content

Commit

Permalink
Remove ginkgo from internal/controller unit tests
Browse files Browse the repository at this point in the history
Fix operator-framework#190

Signed-off-by: Todd Short <tshort@redhat.com>
  • Loading branch information
tmshort committed Nov 16, 2023
1 parent b55d472 commit 0feae9d
Show file tree
Hide file tree
Showing 3 changed files with 1,311 additions and 1,166 deletions.
323 changes: 171 additions & 152 deletions internal/controllers/admission_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package controllers_test

import (
"context"
"testing"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

operatorsv1alpha1 "github.com/operator-framework/operator-controller/api/v1alpha1"
Expand All @@ -19,159 +19,178 @@ func operator(spec operatorsv1alpha1.OperatorSpec) *operatorsv1alpha1.Operator {
}
}

var _ = Describe("Operator Spec Validations", func() {
var (
ctx context.Context
cancel context.CancelFunc
)
BeforeEach(func() {
ctx, cancel = context.WithCancel(context.Background())
})
AfterEach(func() {
cancel()
})
It("should fail if the spec is empty", func() {
err := cl.Create(ctx, operator(operatorsv1alpha1.OperatorSpec{}))
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("spec.packageName in body should match '^[a-z0-9]+(-[a-z0-9]+)*$'"))
})
It("should fail if package name length is greater than 48 characters", func() {
err := cl.Create(ctx, operator(operatorsv1alpha1.OperatorSpec{
PackageName: "this-is-a-really-long-package-name-that-is-greater-than-48-characters",
}))
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("Too long: may not be longer than 48"))
})
It("should fail if version is valid semver but length is greater than 64 characters", func() {
func TestOperatorSpecIsEmpty(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

err := cl.Create(ctx, operator(operatorsv1alpha1.OperatorSpec{}))
require.Error(t, err)
require.ErrorContains(t, err, "spec.packageName in body should match '^[a-z0-9]+(-[a-z0-9]+)*$'")
}

func TestOperatorLongPackageName(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

err := cl.Create(ctx, operator(operatorsv1alpha1.OperatorSpec{
PackageName: "this-is-a-really-long-package-name-that-is-greater-than-48-characters",
}))
require.Error(t, err)
require.ErrorContains(t, err, "Too long: may not be longer than 48")
}

func TestOperatorLongValidSemver(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

err := cl.Create(ctx, operator(operatorsv1alpha1.OperatorSpec{
PackageName: "package",
Version: "1234567890.1234567890.12345678901234567890123456789012345678901234",
}))
require.Error(t, err)
require.ErrorContains(t, err, "Too long: may not be longer than 64")
}

func TestOperatorInvalidSemver(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

invalidSemvers := []string{
"1.2.3.4",
"1.02.3",
"1.2.03",
"1.2.3-beta!",
"1.2.3.alpha",
"1..2.3",
"1.2.3-pre+bad_metadata",
"1.2.-3",
".1.2.3",
"<<1.2.3",
">>1.2.3",
">~1.2.3",
"==1.2.3",
"=!1.2.3",
"!1.2.3",
"1.Y",
">1.2.3 && <2.3.4",
">1.2.3;<2.3.4",
"1.2.3 - 2.3.4",
}
for _, invalidSemver := range invalidSemvers {
err := cl.Create(ctx, operator(operatorsv1alpha1.OperatorSpec{
PackageName: "package",
Version: "1234567890.1234567890.12345678901234567890123456789012345678901234",
Version: invalidSemver,
}))
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("Too long: may not be longer than 64"))
})
It("should fail if an invalid semver is given", func() {
invalidSemvers := []string{
"1.2.3.4",
"1.02.3",
"1.2.03",
"1.2.3-beta!",
"1.2.3.alpha",
"1..2.3",
"1.2.3-pre+bad_metadata",
"1.2.-3",
".1.2.3",
"<<1.2.3",
">>1.2.3",
">~1.2.3",
"==1.2.3",
"=!1.2.3",
"!1.2.3",
"1.Y",
">1.2.3 && <2.3.4",
">1.2.3;<2.3.4",
"1.2.3 - 2.3.4",
}
for _, invalidSemver := range invalidSemvers {
err := cl.Create(ctx, operator(operatorsv1alpha1.OperatorSpec{
PackageName: "package",
Version: invalidSemver,
}))

Expect(err).To(HaveOccurred(), "expected error for invalid semver %q", invalidSemver)
// Don't need to include the whole regex, this should be enough to match the MasterMinds regex
Expect(err.Error()).To(ContainSubstring("spec.version in body should match '^(\\s*(=||!=|>|<|>=|=>|<=|=<|~|~>|\\^)"))
}
})
It("should pass if a valid semver range given", func() {
validSemvers := []string{
">=1.2.3",
"=>1.2.3",
">= 1.2.3",
">=v1.2.3",
">= v1.2.3",
"<=1.2.3",
"=<1.2.3",
"=1.2.3",
"!=1.2.3",
"<1.2.3",
">1.2.3",
"~1.2.2",
"~>1.2.3",
"^1.2.3",
"1.2.3",
"v1.2.3",
"1.x",
"1.X",
"1.*",
"1.2.x",
"1.2.X",
"1.2.*",
">=1.2.3 <2.3.4",
">=1.2.3,<2.3.4",
">=1.2.3, <2.3.4",
"<1.2.3||>2.3.4",
"<1.2.3|| >2.3.4",
"<1.2.3 ||>2.3.4",
"<1.2.3 || >2.3.4",
">1.0.0,<1.2.3 || >2.1.0",
"<1.2.3-abc >2.3.4-def",
"<1.2.3-abc+def >2.3.4-ghi+jkl",
}
for _, validSemver := range validSemvers {
op := operator(operatorsv1alpha1.OperatorSpec{
PackageName: "package",
Version: validSemver,
})
err := cl.Create(ctx, op)
Expect(err).NotTo(HaveOccurred(), "expected success for semver range '%q': %w", validSemver, err)
err = cl.Delete(ctx, op)
Expect(err).NotTo(HaveOccurred(), "unexpected error deleting valid semver '%q': %w", validSemver, err)
}
})
It("should fail if an invalid channel name is given", func() {
invalidChannels := []string{
"spaces spaces",
"Capitalized",
"camelCase",
"many/invalid$characters+in_name",
"-start-with-hyphen",
"end-with-hyphen-",
".start-with-period",
"end-with-period.",
}
for _, invalidChannel := range invalidChannels {
err := cl.Create(ctx, operator(operatorsv1alpha1.OperatorSpec{
PackageName: "package",
Channel: invalidChannel,
}))
Expect(err).To(HaveOccurred(), "expected error for invalid channel '%q'", invalidChannel)
Expect(err.Error()).To(ContainSubstring("spec.channel in body should match '^[a-z0-9]+([\\.-][a-z0-9]+)*$'"))
}
})
It("should pass if a valid channel name is given", func() {
validChannels := []string{
"hyphenated-name",
"dotted.name",
"channel-has-version-1.0.1",
}
for _, validChannel := range validChannels {
op := operator(operatorsv1alpha1.OperatorSpec{
PackageName: "package",
Channel: validChannel,
})
err := cl.Create(ctx, op)
Expect(err).NotTo(HaveOccurred(), "unexpected error creating valid channel '%q': %w", validChannel, err)
err = cl.Delete(ctx, op)
Expect(err).NotTo(HaveOccurred(), "unexpected error deleting valid channel '%q': %w", validChannel, err)
}
})
It("should fail if an invalid channel name length", func() {
require.Errorf(t, err, "expected error for invalid semver %q", invalidSemver)
// Don't need to include the whole regex, this should be enough to match the MasterMinds regex
require.ErrorContains(t, err, "spec.version in body should match '^(\\s*(=||!=|>|<|>=|=>|<=|=<|~|~>|\\^)")
}
}

func TestOperatorValidSemver(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

validSemvers := []string{
">=1.2.3",
"=>1.2.3",
">= 1.2.3",
">=v1.2.3",
">= v1.2.3",
"<=1.2.3",
"=<1.2.3",
"=1.2.3",
"!=1.2.3",
"<1.2.3",
">1.2.3",
"~1.2.2",
"~>1.2.3",
"^1.2.3",
"1.2.3",
"v1.2.3",
"1.x",
"1.X",
"1.*",
"1.2.x",
"1.2.X",
"1.2.*",
">=1.2.3 <2.3.4",
">=1.2.3,<2.3.4",
">=1.2.3, <2.3.4",
"<1.2.3||>2.3.4",
"<1.2.3|| >2.3.4",
"<1.2.3 ||>2.3.4",
"<1.2.3 || >2.3.4",
">1.0.0,<1.2.3 || >2.1.0",
"<1.2.3-abc >2.3.4-def",
"<1.2.3-abc+def >2.3.4-ghi+jkl",
}
for _, validSemver := range validSemvers {
op := operator(operatorsv1alpha1.OperatorSpec{
PackageName: "package",
Version: validSemver,
})
err := cl.Create(ctx, op)
require.NoErrorf(t, err, "unexpected error for semver range '%q': %w", validSemver, err)
err = cl.Delete(ctx, op)
require.NoErrorf(t, err, "unexpected error deleting valid semver '%q': %w", validSemver, err)
}
}

func TestOperatorInvalidChannel(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

invalidChannels := []string{
"spaces spaces",
"Capitalized",
"camelCase",
"many/invalid$characters+in_name",
"-start-with-hyphen",
"end-with-hyphen-",
".start-with-period",
"end-with-period.",
}
for _, invalidChannel := range invalidChannels {
err := cl.Create(ctx, operator(operatorsv1alpha1.OperatorSpec{
PackageName: "package",
Channel: "longname01234567890123456789012345678901234567890",
Channel: invalidChannel,
}))
Expect(err).To(HaveOccurred(), "expected error for invalid channel length")
Expect(err.Error()).To(ContainSubstring("spec.channel: Too long: may not be longer than 48"))
})
})
require.Errorf(t, err, "expected error for invalid channel '%q'", invalidChannel)
require.ErrorContains(t, err, "spec.channel in body should match '^[a-z0-9]+([\\.-][a-z0-9]+)*$'")
}
}

func TestOperatorValidChannel(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

validChannels := []string{
"hyphenated-name",
"dotted.name",
"channel-has-version-1.0.1",
}
for _, validChannel := range validChannels {
op := operator(operatorsv1alpha1.OperatorSpec{
PackageName: "package",
Channel: validChannel,
})
err := cl.Create(ctx, op)
require.NoErrorf(t, err, "unexpected error creating valid channel '%q': %w", validChannel, err)
err = cl.Delete(ctx, op)
require.NoErrorf(t, err, "unexpected error deleting valid channel '%q': %w", validChannel, err)
}
}

func TestOperatorLongValidChannel(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

err := cl.Create(ctx, operator(operatorsv1alpha1.OperatorSpec{
PackageName: "package",
Channel: "longname01234567890123456789012345678901234567890",
}))

require.Error(t, err)
require.ErrorContains(t, err, "spec.channel: Too long: may not be longer than 48")
}
Loading

0 comments on commit 0feae9d

Please sign in to comment.