package kubernetes import ( "errors" "testing" composev1alpha3 "github.com/docker/compose-on-kubernetes/api/client/clientset/typed/compose/v1alpha3" composev1beta1 "github.com/docker/compose-on-kubernetes/api/client/clientset/typed/compose/v1beta1" composev1beta2 "github.com/docker/compose-on-kubernetes/api/client/clientset/typed/compose/v1beta2" "github.com/docker/compose-on-kubernetes/api/compose/v1alpha3" "github.com/docker/compose-on-kubernetes/api/compose/v1beta1" "github.com/docker/compose-on-kubernetes/api/compose/v1beta2" "gotest.tools/v3/assert" kerrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/kubernetes/fake" ) func testStack() Stack { return Stack{ Name: "test", Namespace: "test", ComposeFile: `version: "3.3" services: test: image: nginx secrets: test: file: testdata/secret configs: test: file: testdata/config `, Spec: &v1alpha3.StackSpec{ Configs: map[string]v1alpha3.ConfigObjConfig{ "test": {Name: "test", File: "testdata/config"}, }, Secrets: map[string]v1alpha3.SecretConfig{ "test": {Name: "test", File: "testdata/secret"}, }, }, } } func TestCreateChildResourcesV1Beta1(t *testing.T) { k8sclientSet := fake.NewSimpleClientset() stack := testStack() configs := k8sclientSet.CoreV1().ConfigMaps("test") secrets := k8sclientSet.CoreV1().Secrets("test") assert.NilError(t, createResources( stack, &stackV1Beta1{stacks: &fakeV1beta1Client{}}, configs, secrets)) c, err := configs.Get("test", metav1.GetOptions{}) assert.NilError(t, err) checkOwnerReferences(t, c.ObjectMeta, v1beta1.SchemeGroupVersion.String()) s, err := secrets.Get("test", metav1.GetOptions{}) assert.NilError(t, err) checkOwnerReferences(t, s.ObjectMeta, v1beta1.SchemeGroupVersion.String()) } func checkOwnerReferences(t *testing.T, objMeta metav1.ObjectMeta, stackVersion string) { t.Helper() assert.Equal(t, len(objMeta.OwnerReferences), 1) assert.Equal(t, objMeta.OwnerReferences[0].Name, "test") assert.Equal(t, objMeta.OwnerReferences[0].Kind, "Stack") assert.Equal(t, objMeta.OwnerReferences[0].APIVersion, stackVersion) } func TestCreateChildResourcesV1Beta2(t *testing.T) { k8sclientSet := fake.NewSimpleClientset() stack := testStack() configs := k8sclientSet.CoreV1().ConfigMaps("test") secrets := k8sclientSet.CoreV1().Secrets("test") assert.NilError(t, createResources( stack, &stackV1Beta2{stacks: &fakeV1beta2Client{}}, configs, secrets)) c, err := configs.Get("test", metav1.GetOptions{}) assert.NilError(t, err) checkOwnerReferences(t, c.ObjectMeta, v1beta2.SchemeGroupVersion.String()) s, err := secrets.Get("test", metav1.GetOptions{}) assert.NilError(t, err) checkOwnerReferences(t, s.ObjectMeta, v1beta2.SchemeGroupVersion.String()) } func TestCreateChildResourcesV1Alpha3(t *testing.T) { k8sclientSet := fake.NewSimpleClientset() stack := testStack() configs := k8sclientSet.CoreV1().ConfigMaps("test") secrets := k8sclientSet.CoreV1().Secrets("test") assert.NilError(t, createResources( stack, &stackV1Alpha3{stacks: &fakeV1alpha3Client{}}, configs, secrets)) c, err := configs.Get("test", metav1.GetOptions{}) assert.NilError(t, err) checkOwnerReferences(t, c.ObjectMeta, v1alpha3.SchemeGroupVersion.String()) s, err := secrets.Get("test", metav1.GetOptions{}) assert.NilError(t, err) checkOwnerReferences(t, s.ObjectMeta, v1alpha3.SchemeGroupVersion.String()) } func TestCreateChildResourcesWithStackCreationErrorV1Beta1(t *testing.T) { k8sclientSet := fake.NewSimpleClientset() stack := testStack() configs := k8sclientSet.CoreV1().ConfigMaps("test") secrets := k8sclientSet.CoreV1().Secrets("test") err := createResources( stack, &stackV1Beta1{stacks: &fakeV1beta1Client{errorOnCreate: true}}, configs, secrets) assert.Error(t, err, "some error") _, err = configs.Get("test", metav1.GetOptions{}) assert.Check(t, kerrors.IsNotFound(err)) _, err = secrets.Get("test", metav1.GetOptions{}) assert.Check(t, kerrors.IsNotFound(err)) } func TestCreateChildResourcesWithStackCreationErrorV1Beta2(t *testing.T) { k8sclientSet := fake.NewSimpleClientset() stack := testStack() configs := k8sclientSet.CoreV1().ConfigMaps("test") secrets := k8sclientSet.CoreV1().Secrets("test") err := createResources( stack, &stackV1Beta2{stacks: &fakeV1beta2Client{errorOnCreate: true}}, configs, secrets) assert.Error(t, err, "some error") _, err = configs.Get("test", metav1.GetOptions{}) assert.Check(t, kerrors.IsNotFound(err)) _, err = secrets.Get("test", metav1.GetOptions{}) assert.Check(t, kerrors.IsNotFound(err)) } func TestCreateChildResourcesWithStackCreationErrorV1Alpha3(t *testing.T) { k8sclientSet := fake.NewSimpleClientset() stack := testStack() configs := k8sclientSet.CoreV1().ConfigMaps("test") secrets := k8sclientSet.CoreV1().Secrets("test") err := createResources( stack, &stackV1Alpha3{stacks: &fakeV1alpha3Client{errorOnCreate: true}}, configs, secrets) assert.Error(t, err, "some error") _, err = configs.Get("test", metav1.GetOptions{}) assert.Check(t, kerrors.IsNotFound(err)) _, err = secrets.Get("test", metav1.GetOptions{}) assert.Check(t, kerrors.IsNotFound(err)) } type fakeV1beta1Client struct { errorOnCreate bool } func (c *fakeV1beta1Client) Create(s *v1beta1.Stack) (*v1beta1.Stack, error) { if c.errorOnCreate { return nil, errors.New("some error") } return s, nil } func (c *fakeV1beta1Client) Update(*v1beta1.Stack) (*v1beta1.Stack, error) { return nil, nil } func (c *fakeV1beta1Client) UpdateStatus(*v1beta1.Stack) (*v1beta1.Stack, error) { return nil, nil } func (c *fakeV1beta1Client) Delete(name string, options *metav1.DeleteOptions) error { return nil } func (c *fakeV1beta1Client) DeleteCollection(options *metav1.DeleteOptions, listOptions metav1.ListOptions) error { return nil } func (c *fakeV1beta1Client) Get(name string, options metav1.GetOptions) (*v1beta1.Stack, error) { return nil, kerrors.NewNotFound(v1beta1.SchemeGroupVersion.WithResource("stacks").GroupResource(), name) } func (c *fakeV1beta1Client) List(opts metav1.ListOptions) (*v1beta1.StackList, error) { return nil, nil } func (c *fakeV1beta1Client) Watch(opts metav1.ListOptions) (watch.Interface, error) { return nil, nil } func (c *fakeV1beta1Client) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (*v1beta1.Stack, error) { return nil, nil } func (c *fakeV1beta1Client) WithSkipValidation() composev1beta1.StackInterface { return c } type fakeV1beta2Client struct { errorOnCreate bool } func (c *fakeV1beta2Client) Create(s *v1beta2.Stack) (*v1beta2.Stack, error) { if c.errorOnCreate { return nil, errors.New("some error") } return s, nil } func (c *fakeV1beta2Client) Update(*v1beta2.Stack) (*v1beta2.Stack, error) { return nil, nil } func (c *fakeV1beta2Client) UpdateStatus(*v1beta2.Stack) (*v1beta2.Stack, error) { return nil, nil } func (c *fakeV1beta2Client) Delete(name string, options *metav1.DeleteOptions) error { return nil } func (c *fakeV1beta2Client) DeleteCollection(options *metav1.DeleteOptions, listOptions metav1.ListOptions) error { return nil } func (c *fakeV1beta2Client) Get(name string, options metav1.GetOptions) (*v1beta2.Stack, error) { return nil, kerrors.NewNotFound(v1beta1.SchemeGroupVersion.WithResource("stacks").GroupResource(), name) } func (c *fakeV1beta2Client) List(opts metav1.ListOptions) (*v1beta2.StackList, error) { return nil, nil } func (c *fakeV1beta2Client) Watch(opts metav1.ListOptions) (watch.Interface, error) { return nil, nil } func (c *fakeV1beta2Client) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (*v1beta2.Stack, error) { return nil, nil } func (c *fakeV1beta2Client) WithSkipValidation() composev1beta2.StackInterface { return c } type fakeV1alpha3Client struct { errorOnCreate bool } func (c *fakeV1alpha3Client) Create(s *v1alpha3.Stack) (*v1alpha3.Stack, error) { if c.errorOnCreate { return nil, errors.New("some error") } return s, nil } func (c *fakeV1alpha3Client) Update(*v1alpha3.Stack) (*v1alpha3.Stack, error) { return nil, nil } func (c *fakeV1alpha3Client) UpdateStatus(*v1alpha3.Stack) (*v1alpha3.Stack, error) { return nil, nil } func (c *fakeV1alpha3Client) Delete(name string, options *metav1.DeleteOptions) error { return nil } func (c *fakeV1alpha3Client) DeleteCollection(options *metav1.DeleteOptions, listOptions metav1.ListOptions) error { return nil } func (c *fakeV1alpha3Client) Get(name string, options metav1.GetOptions) (*v1alpha3.Stack, error) { return nil, kerrors.NewNotFound(v1beta1.SchemeGroupVersion.WithResource("stacks").GroupResource(), name) } func (c *fakeV1alpha3Client) List(opts metav1.ListOptions) (*v1alpha3.StackList, error) { return nil, nil } func (c *fakeV1alpha3Client) Watch(opts metav1.ListOptions) (watch.Interface, error) { return nil, nil } func (c *fakeV1alpha3Client) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (*v1alpha3.Stack, error) { return nil, nil } func (c *fakeV1alpha3Client) WithSkipValidation() composev1alpha3.StackInterface { return c }