github.com/kubeshop/testkube@v1.17.23/internal/graphql/services/executors_test.go (about)

     1  package services
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
     9  	"k8s.io/apimachinery/pkg/runtime"
    10  	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
    11  	"sigs.k8s.io/controller-runtime/pkg/client/fake"
    12  
    13  	executorv1 "github.com/kubeshop/testkube-operator/api/executor/v1"
    14  	executorsclientv1 "github.com/kubeshop/testkube-operator/pkg/client/executors/v1"
    15  	"github.com/kubeshop/testkube/pkg/api/v1/testkube"
    16  )
    17  
    18  var (
    19  	srvMock    = NewMockService()
    20  	k8sObjects = []k8sclient.Object{
    21  		&executorv1.Executor{
    22  			TypeMeta: metav1.TypeMeta{
    23  				Kind:       "Executor",
    24  				APIVersion: "executor.testkube.io/v1",
    25  			},
    26  			ObjectMeta: metav1.ObjectMeta{
    27  				Name:      "sample",
    28  				Namespace: "default",
    29  				Labels: map[string]string{
    30  					"label-name": "label-value",
    31  				},
    32  			},
    33  			Spec: executorv1.ExecutorSpec{
    34  				Types:                []string{"curl/test"},
    35  				ExecutorType:         "job",
    36  				JobTemplate:          "",
    37  				JobTemplateReference: "",
    38  			},
    39  			Status: executorv1.ExecutorStatus{},
    40  		},
    41  	}
    42  	sample = testkube.ExecutorDetails{
    43  		Name: "sample",
    44  		Executor: &testkube.Executor{
    45  			ExecutorType:         "job",
    46  			Image:                "",
    47  			ImagePullSecrets:     nil,
    48  			Command:              nil,
    49  			Args:                 nil,
    50  			Types:                []string{"curl/test"},
    51  			Uri:                  "",
    52  			ContentTypes:         nil,
    53  			JobTemplate:          "",
    54  			JobTemplateReference: "",
    55  			Labels:               map[string]string{"label-name": "label-value"},
    56  			Features:             nil,
    57  			Meta:                 nil,
    58  		},
    59  	}
    60  	k8sObjects2 = []k8sclient.Object{
    61  		&executorv1.Executor{
    62  			TypeMeta: metav1.TypeMeta{
    63  				Kind:       "Executor",
    64  				APIVersion: "executor.testkube.io/v1",
    65  			},
    66  			ObjectMeta: metav1.ObjectMeta{
    67  				Name:      "sample",
    68  				Namespace: "default",
    69  				Labels: map[string]string{
    70  					"label-name": "label-value",
    71  				},
    72  			},
    73  			Spec: executorv1.ExecutorSpec{
    74  				Types:                []string{"other/test"},
    75  				ExecutorType:         "job",
    76  				JobTemplate:          "",
    77  				JobTemplateReference: "",
    78  			},
    79  			Status: executorv1.ExecutorStatus{},
    80  		},
    81  	}
    82  	sample2 = testkube.ExecutorDetails{
    83  		Name: "sample",
    84  		Executor: &testkube.Executor{
    85  			ExecutorType:         "job",
    86  			Image:                "",
    87  			ImagePullSecrets:     nil,
    88  			Command:              nil,
    89  			Args:                 nil,
    90  			Types:                []string{"other/test"},
    91  			Uri:                  "",
    92  			ContentTypes:         nil,
    93  			JobTemplate:          "",
    94  			JobTemplateReference: "",
    95  			Labels:               map[string]string{"label-name": "label-value"},
    96  			Features:             nil,
    97  			Meta:                 nil,
    98  		},
    99  	}
   100  )
   101  
   102  var (
   103  	client *executorsclientv1.ExecutorsClient
   104  	srv    ExecutorsService
   105  )
   106  
   107  func ResetMocks() {
   108  	srvMock.Reset()
   109  	client = getMockExecutorClient(k8sObjects)
   110  	srv = NewExecutorsService(srvMock, client)
   111  }
   112  
   113  func TestExecutorsService_List(t *testing.T) {
   114  	t.Run("should list all available executors when no selector passed", func(t *testing.T) {
   115  		ResetMocks()
   116  		result, err := srv.List("")
   117  		assert.NoError(t, err)
   118  		assert.Equal(t, result, []testkube.ExecutorDetails{sample})
   119  	})
   120  
   121  	t.Run("should list none executors when none matches selector", func(t *testing.T) {
   122  		ResetMocks()
   123  		result, err := srv.List("xyz=def")
   124  		assert.NoError(t, err)
   125  		assert.Equal(t, result, []testkube.ExecutorDetails{})
   126  	})
   127  
   128  	t.Run("should list executors matching the selector", func(t *testing.T) {
   129  		ResetMocks()
   130  		result, err := srv.List("label-name=label-value")
   131  		assert.NoError(t, err)
   132  		assert.Equal(t, result, []testkube.ExecutorDetails{sample})
   133  	})
   134  }
   135  
   136  func TestExecutorsService_SubscribeList(t *testing.T) {
   137  	t.Run("should cancel subscription when the context is canceled", func(t *testing.T) {
   138  		ResetMocks()
   139  		ctx, cancel := context.WithCancel(context.Background())
   140  		ch, err := srv.SubscribeList(ctx, "")
   141  		assert.NoError(t, err)
   142  		<-ch
   143  		cancel()
   144  		_, opened := <-ch
   145  		assert.False(t, opened)
   146  		assert.Len(t, srvMock.BusMock().ListQueues(), 0)
   147  	})
   148  
   149  	t.Run("should return initial list of executors", func(t *testing.T) {
   150  		ResetMocks()
   151  		ch, err := srv.SubscribeList(context.Background(), "")
   152  		assert.NoError(t, err)
   153  		result := <-ch
   154  		assert.Equal(t, result, []testkube.ExecutorDetails{sample})
   155  	})
   156  
   157  	t.Run("should subscribe for new entries", func(t *testing.T) {
   158  		ResetMocks()
   159  		ch, err := srv.SubscribeList(context.Background(), "")
   160  		assert.NoError(t, err)
   161  		result := <-ch
   162  		assert.Equal(t, result, []testkube.ExecutorDetails{sample})
   163  		assert.Len(t, srvMock.BusMock().ListQueues(), 1)
   164  	})
   165  
   166  	t.Run("should return new list of executors after events are triggered", func(t *testing.T) {
   167  		ResetMocks()
   168  		ch, err := srv.SubscribeList(context.Background(), "")
   169  		assert.NoError(t, err)
   170  		<-ch
   171  		client.Client = getMockExecutorClient(k8sObjects2).Client
   172  		assert.NoError(t, srvMock.BusMock().PublishTopic("events.executor.create", testkube.Event{
   173  			Type_:    testkube.EventCreated,
   174  			Resource: testkube.EventResourceExecutor,
   175  		}))
   176  		assert.Equal(t, <-ch, []testkube.ExecutorDetails{sample2})
   177  	})
   178  }
   179  
   180  func getMockExecutorClient(initObjects []k8sclient.Object) *executorsclientv1.ExecutorsClient {
   181  	scheme := runtime.NewScheme()
   182  	executorv1.AddToScheme(scheme)
   183  
   184  	fakeClient := fake.NewClientBuilder().
   185  		WithScheme(scheme).
   186  		WithObjects(initObjects...).
   187  		Build()
   188  	return executorsclientv1.NewClient(fakeClient, "")
   189  }