github.com/kubeshop/testkube@v1.17.23/pkg/repository/result/mongo_integration_test.go (about)

     1  //go:build integration
     2  
     3  package result
     4  
     5  import (
     6  	"context"
     7  	"fmt"
     8  	random "math/rand"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/stretchr/testify/assert"
    13  
    14  	"github.com/kubeshop/testkube/pkg/utils/test"
    15  
    16  	"github.com/kubeshop/testkube/pkg/datefilter"
    17  	"github.com/kubeshop/testkube/pkg/repository/storage"
    18  
    19  	"github.com/stretchr/testify/require"
    20  
    21  	"github.com/kubeshop/testkube/pkg/api/v1/testkube"
    22  	"github.com/kubeshop/testkube/pkg/rand"
    23  )
    24  
    25  const (
    26  	mongoDns    = "mongodb://localhost:27017"
    27  	mongoDbName = "testkube-test"
    28  )
    29  
    30  func TestStorage_Integration(t *testing.T) {
    31  	test.IntegrationTest(t)
    32  	assert := require.New(t)
    33  
    34  	repository, err := getRepository()
    35  	assert.NoError(err)
    36  
    37  	err = repository.ResultsColl.Drop(context.TODO())
    38  	assert.NoError(err)
    39  
    40  	oneDayAgo := time.Now().Add(-24 * time.Hour)
    41  	twoDaysAgo := time.Now().Add(-48 * time.Hour)
    42  	defaultName := "name"
    43  	err = repository.insertExecutionResult(defaultName, testkube.FAILED_ExecutionStatus, time.Now(), map[string]string{"key1": "value1", "key2": "value2"})
    44  	assert.NoError(err)
    45  	err = repository.insertExecutionResult(defaultName, testkube.FAILED_ExecutionStatus, time.Now(), map[string]string{"key1": "value1", "key2": "value2"})
    46  	assert.NoError(err)
    47  	err = repository.insertExecutionResult(defaultName, testkube.FAILED_ExecutionStatus, time.Now(), map[string]string{"key3": "value3", "key4": "value4"})
    48  	assert.NoError(err)
    49  	err = repository.insertExecutionResult(defaultName, testkube.FAILED_ExecutionStatus, time.Now(), map[string]string{"key3": "value3", "key4": "value4"})
    50  	assert.NoError(err)
    51  	err = repository.insertExecutionResult(defaultName, testkube.PASSED_ExecutionStatus, time.Now(), map[string]string{"key1": "value1", "key4": "value4"})
    52  	assert.NoError(err)
    53  	err = repository.insertExecutionResult(defaultName, testkube.QUEUED_ExecutionStatus, time.Now(), map[string]string{"key1": "value1", "key3": "value3"})
    54  	assert.NoError(err)
    55  	err = repository.insertExecutionResult(defaultName, testkube.RUNNING_ExecutionStatus, time.Now(), map[string]string{"key5": "value5", "key6": "value6"})
    56  	assert.NoError(err)
    57  	err = repository.insertExecutionResult(defaultName, testkube.FAILED_ExecutionStatus, oneDayAgo, map[string]string{"key1": "value1", "key5": "value5"})
    58  	assert.NoError(err)
    59  	err = repository.insertExecutionResult(defaultName, testkube.FAILED_ExecutionStatus, oneDayAgo, map[string]string{"key1": "value1", "key6": "value6"})
    60  	assert.NoError(err)
    61  	err = repository.insertExecutionResult(defaultName, testkube.FAILED_ExecutionStatus, oneDayAgo, map[string]string{"key2": "value2", "key4": "value4"})
    62  	assert.NoError(err)
    63  	err = repository.insertExecutionResult(defaultName, testkube.FAILED_ExecutionStatus, oneDayAgo, map[string]string{"key2": "value2", "key5": "value5"})
    64  	assert.NoError(err)
    65  	err = repository.insertExecutionResult(defaultName, testkube.PASSED_ExecutionStatus, oneDayAgo, map[string]string{"key7": "value7", "key8": "value8"})
    66  	assert.NoError(err)
    67  	err = repository.insertExecutionResult(defaultName, testkube.QUEUED_ExecutionStatus, oneDayAgo, map[string]string{"key7": "value7", "key8": "value8"})
    68  	assert.NoError(err)
    69  	err = repository.insertExecutionResult(defaultName, testkube.RUNNING_ExecutionStatus, oneDayAgo, map[string]string{"key7": "value7", "key8": "value8"})
    70  	assert.NoError(err)
    71  	err = repository.insertExecutionResult(defaultName, testkube.FAILED_ExecutionStatus, twoDaysAgo, map[string]string{"key7": "value7", "key8": "value8"})
    72  	assert.NoError(err)
    73  	err = repository.insertExecutionResult(defaultName, testkube.FAILED_ExecutionStatus, twoDaysAgo, map[string]string{"key1": "value1", "key2": "value2"})
    74  	assert.NoError(err)
    75  	err = repository.insertExecutionResult(defaultName, testkube.FAILED_ExecutionStatus, twoDaysAgo, map[string]string{"key1": "value1", "key2": "value2"})
    76  	assert.NoError(err)
    77  	err = repository.insertExecutionResult(defaultName, testkube.FAILED_ExecutionStatus, twoDaysAgo, map[string]string{"key1": "value1", "key2": "value2"})
    78  	assert.NoError(err)
    79  	err = repository.insertExecutionResult(defaultName, testkube.PASSED_ExecutionStatus, twoDaysAgo, map[string]string{"key3": "value3", "key6": "value6"})
    80  	assert.NoError(err)
    81  	err = repository.insertExecutionResult(defaultName, testkube.QUEUED_ExecutionStatus, twoDaysAgo, map[string]string{"key3": "value3", "key5": "value5"})
    82  	assert.NoError(err)
    83  	err = repository.insertExecutionResult(defaultName, testkube.RUNNING_ExecutionStatus, twoDaysAgo, map[string]string{"key4": "value4", "key6": "value6"})
    84  	assert.NoError(err)
    85  
    86  	numberOfLabels := 8
    87  
    88  	t.Run("filter with status should return only executions with that status", func(t *testing.T) {
    89  
    90  		executions, err := repository.GetExecutions(context.Background(), NewExecutionsFilter().WithStatus(string(testkube.FAILED_ExecutionStatus)))
    91  		assert.NoError(err)
    92  		assert.Len(executions, 12)
    93  		assert.Equal(*executions[0].ExecutionResult.Status, testkube.FAILED_ExecutionStatus)
    94  	})
    95  
    96  	t.Run("filter with different statuses should return only executions with those statuses", func(t *testing.T) {
    97  
    98  		executions, err := repository.GetExecutions(context.Background(), NewExecutionsFilter().WithStatus(
    99  			string(testkube.FAILED_ExecutionStatus)+","+string(testkube.PASSED_ExecutionStatus)))
   100  		assert.NoError(err)
   101  		assert.Len(executions, 15)
   102  	})
   103  
   104  	t.Run("filter with status should return only totals with that status", func(t *testing.T) {
   105  		filteredTotals, err := repository.GetExecutionTotals(context.Background(), false, NewExecutionsFilter().WithStatus(string(testkube.FAILED_ExecutionStatus)))
   106  
   107  		assert.NoError(err)
   108  		assert.Equal(int32(12), filteredTotals.Results)
   109  		assert.Equal(int32(12), filteredTotals.Failed)
   110  		assert.Equal(int32(0), filteredTotals.Passed)
   111  		assert.Equal(int32(0), filteredTotals.Queued)
   112  		assert.Equal(int32(0), filteredTotals.Running)
   113  	})
   114  
   115  	t.Run("getting totals without filters should return all the executions", func(t *testing.T) {
   116  		totals, err := repository.GetExecutionTotals(context.Background(), false)
   117  
   118  		assert.NoError(err)
   119  		assert.Equal(int32(21), totals.Results)
   120  		assert.Equal(int32(12), totals.Failed)
   121  		assert.Equal(int32(3), totals.Passed)
   122  		assert.Equal(int32(3), totals.Queued)
   123  		assert.Equal(int32(3), totals.Running)
   124  	})
   125  
   126  	dateFilter := datefilter.NewDateFilter(oneDayAgo.Format(datefilter.DateFormatISO8601), "")
   127  	assert.True(dateFilter.IsStartValid)
   128  
   129  	t.Run("filter with startDate should return only executions after that day", func(t *testing.T) {
   130  		executions, err := repository.GetExecutions(context.Background(), NewExecutionsFilter().WithStartDate(dateFilter.Start))
   131  		assert.NoError(err)
   132  		assert.Len(executions, 14)
   133  		assert.True(executions[0].StartTime.After(dateFilter.Start) || executions[0].StartTime.Equal(dateFilter.Start))
   134  	})
   135  
   136  	t.Run("filter with labels should return only filters with given labels", func(t *testing.T) {
   137  
   138  		executions, err := repository.GetExecutions(context.Background(), NewExecutionsFilter().WithSelector("key1=value1,key2=value2"))
   139  		assert.NoError(err)
   140  		assert.Len(executions, 5)
   141  	})
   142  
   143  	t.Run("filter with labels should return only filters with existing labels", func(t *testing.T) {
   144  
   145  		executions, err := repository.GetExecutions(context.Background(), NewExecutionsFilter().WithSelector("key1"))
   146  		assert.NoError(err)
   147  		assert.Len(executions, 9)
   148  	})
   149  
   150  	t.Run("getting totals with filter by date start date should return only the results after this date", func(t *testing.T) {
   151  		totals, err := repository.GetExecutionTotals(context.Background(), false, NewExecutionsFilter().WithStartDate(dateFilter.Start))
   152  
   153  		assert.NoError(err)
   154  		assert.Equal(int32(14), totals.Results)
   155  		assert.Equal(int32(8), totals.Failed)
   156  		assert.Equal(int32(2), totals.Passed)
   157  		assert.Equal(int32(2), totals.Queued)
   158  		assert.Equal(int32(2), totals.Running)
   159  	})
   160  
   161  	dateFilter = datefilter.NewDateFilter("", oneDayAgo.Format(datefilter.DateFormatISO8601))
   162  	assert.True(dateFilter.IsEndValid)
   163  
   164  	t.Run("filter with endDate should return only executions before that day", func(t *testing.T) {
   165  
   166  		executions, err := repository.GetExecutions(context.Background(), NewExecutionsFilter().WithEndDate(dateFilter.End))
   167  		assert.NoError(err)
   168  		assert.Len(executions, 7)
   169  		assert.True(executions[0].StartTime.Before(dateFilter.End) || executions[0].StartTime.Equal(dateFilter.End))
   170  	})
   171  
   172  	t.Run("getting totals with filter by date start date should return only the results before this date", func(t *testing.T) {
   173  		totals, err := repository.GetExecutionTotals(context.Background(), false, NewExecutionsFilter().WithEndDate(dateFilter.End))
   174  
   175  		assert.NoError(err)
   176  		assert.Equal(int32(7), totals.Results)
   177  		assert.Equal(int32(4), totals.Failed)
   178  		assert.Equal(int32(1), totals.Passed)
   179  		assert.Equal(int32(1), totals.Queued)
   180  		assert.Equal(int32(1), totals.Running)
   181  	})
   182  
   183  	t.Run("filter with test name that doesn't exist should return 0 results", func(t *testing.T) {
   184  
   185  		executions, err := repository.GetExecutions(context.Background(), NewExecutionsFilter().WithTestName("noneExisting"))
   186  		assert.NoError(err)
   187  		assert.Empty(executions)
   188  	})
   189  
   190  	t.Run("getting totals with test name that doesn't exist should return 0 results", func(t *testing.T) {
   191  		totals, err := repository.GetExecutionTotals(context.Background(), false, NewExecutionsFilter().WithTestName("noneExisting"))
   192  
   193  		assert.NoError(err)
   194  		assert.Equal(int32(0), totals.Results)
   195  		assert.Equal(int32(0), totals.Failed)
   196  		assert.Equal(int32(0), totals.Passed)
   197  		assert.Equal(int32(0), totals.Queued)
   198  		assert.Equal(int32(0), totals.Running)
   199  	})
   200  
   201  	t.Run("filter with ccombined filter should return corresponding results", func(t *testing.T) {
   202  		filter := NewExecutionsFilter().
   203  			WithStatus(string(testkube.PASSED_ExecutionStatus)).
   204  			WithStartDate(twoDaysAgo).
   205  			WithEndDate(oneDayAgo).
   206  			WithTestName(defaultName)
   207  
   208  		executions, err := repository.GetExecutions(context.Background(), filter)
   209  
   210  		assert.NoError(err)
   211  		assert.Len(executions, 2)
   212  	})
   213  
   214  	t.Run("getting totals with ccombined filter should return corresponding results", func(t *testing.T) {
   215  		filter := NewExecutionsFilter().
   216  			WithStatus(string(testkube.PASSED_ExecutionStatus)).
   217  			WithStartDate(twoDaysAgo).
   218  			WithEndDate(oneDayAgo).
   219  			WithTestName(defaultName)
   220  		totals, err := repository.GetExecutionTotals(context.Background(), false, filter)
   221  
   222  		assert.NoError(err)
   223  		assert.Equal(int32(2), totals.Results)
   224  		assert.Equal(int32(0), totals.Failed)
   225  		assert.Equal(int32(2), totals.Passed)
   226  		assert.Equal(int32(0), totals.Queued)
   227  		assert.Equal(int32(0), totals.Running)
   228  	})
   229  
   230  	name := "someDifferentName"
   231  	err = repository.insertExecutionResult(name, testkube.RUNNING_ExecutionStatus, twoDaysAgo, nil)
   232  	assert.NoError(err)
   233  
   234  	t.Run("filter with test name should return result only for that test name", func(t *testing.T) {
   235  
   236  		executions, err := repository.GetExecutions(context.Background(), NewExecutionsFilter().WithTestName(name))
   237  		assert.NoError(err)
   238  		assert.Len(executions, 1)
   239  		assert.Equal(executions[0].TestName, name)
   240  	})
   241  
   242  	t.Run("getting totals with test name should return result only for that test name", func(t *testing.T) {
   243  		totals, err := repository.GetExecutionTotals(context.Background(), false, NewExecutionsFilter().WithTestName(name))
   244  
   245  		assert.NoError(err)
   246  		assert.Equal(int32(1), totals.Results)
   247  		assert.Equal(int32(0), totals.Failed)
   248  		assert.Equal(int32(0), totals.Passed)
   249  		assert.Equal(int32(0), totals.Queued)
   250  		assert.Equal(int32(1), totals.Running)
   251  	})
   252  
   253  	t.Run("test executions should be sorted with most recent first", func(t *testing.T) {
   254  		executions, err := repository.GetExecutions(context.Background(), NewExecutionsFilter())
   255  		assert.NoError(err)
   256  		assert.NotEmpty(executions)
   257  		assert.True(executions[0].StartTime.After(executions[len(executions)-1].StartTime), "executions are not sorted with the most recent first")
   258  	})
   259  
   260  	t.Run("getting labels should return all available labels", func(t *testing.T) {
   261  		labels, err := repository.GetLabels(context.Background())
   262  		assert.NoError(err)
   263  		assert.Len(labels, numberOfLabels)
   264  	})
   265  
   266  }
   267  
   268  func TestLabels_Integration(t *testing.T) {
   269  	test.IntegrationTest(t)
   270  	assert := require.New(t)
   271  
   272  	repository, err := getRepository()
   273  	assert.NoError(err)
   274  
   275  	err = repository.ResultsColl.Drop(context.TODO())
   276  	assert.NoError(err)
   277  
   278  	t.Run("getting labels when there are no labels should return empty map", func(t *testing.T) {
   279  		labels, err := repository.GetLabels(context.Background())
   280  		assert.NoError(err)
   281  		assert.Len(labels, 0)
   282  	})
   283  }
   284  
   285  func TestTestExecutionsMetrics_Integration(t *testing.T) {
   286  	test.IntegrationTest(t)
   287  	assert := require.New(t)
   288  
   289  	repository, err := getRepository()
   290  	assert.NoError(err)
   291  
   292  	err = repository.ResultsColl.Drop(context.TODO())
   293  	assert.NoError(err)
   294  
   295  	testName := "example-test"
   296  
   297  	err = repository.insertExecutionResult(testName, testkube.FAILED_ExecutionStatus, time.Now().Add(48*-time.Hour), map[string]string{"key1": "value1", "key2": "value2"})
   298  	assert.NoError(err)
   299  	err = repository.insertExecutionResult(testName, testkube.PASSED_ExecutionStatus, time.Now().Add(-time.Hour), map[string]string{"key1": "value1", "key2": "value2"})
   300  	assert.NoError(err)
   301  	err = repository.insertExecutionResult(testName, testkube.PASSED_ExecutionStatus, time.Now().Add(10*-time.Minute), map[string]string{"key3": "value3", "key4": "value4"})
   302  	assert.NoError(err)
   303  	err = repository.insertExecutionResult(testName, testkube.PASSED_ExecutionStatus, time.Now().Add(10*-time.Minute), map[string]string{"key3": "value3", "key4": "value4"})
   304  	assert.NoError(err)
   305  	err = repository.insertExecutionResult(testName, testkube.PASSED_ExecutionStatus, time.Now().Add(-time.Minute), map[string]string{"key3": "value3", "key4": "value4"})
   306  	assert.NoError(err)
   307  	err = repository.insertExecutionResult(testName, testkube.FAILED_ExecutionStatus, time.Now().Add(-time.Minute), map[string]string{"key1": "value1", "key2": "value2"})
   308  	assert.NoError(err)
   309  	err = repository.insertExecutionResult(testName, testkube.PASSED_ExecutionStatus, time.Now().Add(-time.Minute), map[string]string{"key1": "value1", "key2": "value2"})
   310  	assert.NoError(err)
   311  	err = repository.insertExecutionResult(testName, testkube.PASSED_ExecutionStatus, time.Now().Add(-time.Minute), map[string]string{"key3": "value3", "key4": "value4"})
   312  	assert.NoError(err)
   313  	err = repository.insertExecutionResult(testName, testkube.PASSED_ExecutionStatus, time.Now().Add(-time.Minute), map[string]string{"key3": "value3", "key4": "value4"})
   314  	assert.NoError(err)
   315  	err = repository.insertExecutionResult(testName, testkube.PASSED_ExecutionStatus, time.Now().Add(-time.Minute), map[string]string{"key3": "value3", "key4": "value4"})
   316  	assert.NoError(err)
   317  	err = repository.insertExecutionResult(testName, testkube.FAILED_ExecutionStatus, time.Now().Add(-time.Minute), map[string]string{"key1": "value1", "key2": "value2"})
   318  	assert.NoError(err)
   319  	err = repository.insertExecutionResult(testName, testkube.PASSED_ExecutionStatus, time.Now().Add(-time.Minute), map[string]string{"key1": "value1", "key2": "value2"})
   320  	assert.NoError(err)
   321  	err = repository.insertExecutionResult(testName, testkube.PASSED_ExecutionStatus, time.Now().Add(-time.Minute), map[string]string{"key3": "value3", "key4": "value4"})
   322  	assert.NoError(err)
   323  	err = repository.insertExecutionResult(testName, testkube.PASSED_ExecutionStatus, time.Now().Add(-time.Minute), map[string]string{"key3": "value3", "key4": "value4"})
   324  	assert.NoError(err)
   325  	err = repository.insertExecutionResult(testName, testkube.PASSED_ExecutionStatus, time.Now().Add(-time.Minute), map[string]string{"key3": "value3", "key4": "value4"})
   326  	assert.NoError(err)
   327  	err = repository.insertExecutionResult(testName, testkube.FAILED_ExecutionStatus, time.Now().Add(-time.Minute), map[string]string{"key1": "value1", "key2": "value2"})
   328  	assert.NoError(err)
   329  	err = repository.insertExecutionResult(testName, testkube.PASSED_ExecutionStatus, time.Now().Add(-time.Minute), map[string]string{"key1": "value1", "key2": "value2"})
   330  	assert.NoError(err)
   331  	err = repository.insertExecutionResult(testName, testkube.PASSED_ExecutionStatus, time.Now().Add(-time.Minute), map[string]string{"key3": "value3", "key4": "value4"})
   332  	assert.NoError(err)
   333  	err = repository.insertExecutionResult(testName, testkube.FAILED_ExecutionStatus, time.Now().Add(-time.Minute), map[string]string{"key3": "value3", "key4": "value4"})
   334  	assert.NoError(err)
   335  	err = repository.insertExecutionResult(testName, testkube.PASSED_ExecutionStatus, time.Now().Add(-time.Minute), map[string]string{"key3": "value3", "key4": "value4"})
   336  	assert.NoError(err)
   337  
   338  	metrics, err := repository.GetTestMetrics(context.Background(), testName, 100, 100)
   339  	assert.NoError(err)
   340  
   341  	t.Run("getting execution metrics for test data", func(t *testing.T) {
   342  		assert.NoError(err)
   343  		assert.Equal(int32(20), metrics.TotalExecutions)
   344  		assert.Equal(int32(5), metrics.FailedExecutions)
   345  		assert.Len(metrics.Executions, 20)
   346  	})
   347  
   348  	t.Run("getting pass/fail ratio", func(t *testing.T) {
   349  		assert.Equal(float64(75), metrics.PassFailRatio)
   350  	})
   351  
   352  	t.Run("getting percentiles of execution duration", func(t *testing.T) {
   353  		assert.Contains(metrics.ExecutionDurationP50, "1m0")
   354  		assert.Contains(metrics.ExecutionDurationP90, "10m0")
   355  		assert.Contains(metrics.ExecutionDurationP99, "48h0m0s")
   356  	})
   357  
   358  	t.Run("limit should limit executions", func(t *testing.T) {
   359  		metrics, err := repository.GetTestMetrics(context.Background(), testName, 1, 100)
   360  		assert.NoError(err)
   361  		assert.Equal(1, len(metrics.Executions))
   362  	})
   363  
   364  	t.Run("filter last n days should limit executions", func(t *testing.T) {
   365  		metrics, err := repository.GetTestMetrics(context.Background(), testName, 100, 1)
   366  		assert.NoError(err)
   367  		assert.Equal(int32(19), metrics.TotalExecutions)
   368  	})
   369  }
   370  
   371  func getRepository() (*MongoRepository, error) {
   372  	db, err := storage.GetMongoDatabase(mongoDns, mongoDbName, storage.TypeMongoDB, false, nil)
   373  	repository := NewMongoRepository(db, true, false)
   374  	return repository, err
   375  }
   376  
   377  func (r *MongoRepository) insertExecutionResult(testName string, execStatus testkube.ExecutionStatus, startTime time.Time, labels map[string]string) error {
   378  	return r.Insert(context.Background(),
   379  		testkube.Execution{
   380  			Id:              rand.Name(),
   381  			TestName:        testName,
   382  			Name:            "dummyName",
   383  			TestType:        "test/curl",
   384  			StartTime:       startTime,
   385  			EndTime:         time.Now(),
   386  			Duration:        time.Since(startTime).String(),
   387  			ExecutionResult: &testkube.ExecutionResult{Status: &execStatus},
   388  			Labels:          labels,
   389  		})
   390  }
   391  
   392  func TestUpdateOutput_Integration(t *testing.T) {
   393  	test.IntegrationTest(t)
   394  
   395  	repository, err := getRepository()
   396  	assert.NoError(t, err)
   397  
   398  	testName := "example-test"
   399  	executionID := "example-execution"
   400  
   401  	err = repository.insertExecutionResult(testName, testkube.FAILED_ExecutionStatus, time.Now(), map[string]string{"key1": "value1", "key2": "value2"})
   402  	assert.NoError(t, err)
   403  
   404  	randomString := func(len int) string {
   405  		bytes := make([]byte, len)
   406  		for i := 0; i < len; i++ {
   407  			bytes[i] = byte(65 + random.Intn(25))
   408  		}
   409  		return string(bytes)
   410  	}
   411  
   412  	t.Run("valid input", func(t *testing.T) {
   413  		result := testkube.Execution{
   414  			Id:       executionID,
   415  			Name:     executionID,
   416  			TestName: testName,
   417  			ExecutionResult: &testkube.ExecutionResult{
   418  				Output: "",
   419  			},
   420  		}
   421  		err = repository.UpdateResult(context.Background(), testName, result)
   422  		assert.NoError(t, err)
   423  	})
   424  	t.Run("output bigger than MongoDB document limit should not throw error", func(t *testing.T) {
   425  		result := testkube.Execution{
   426  			Id:       executionID,
   427  			Name:     executionID,
   428  			TestName: testName,
   429  			ExecutionResult: &testkube.ExecutionResult{
   430  				Output: randomString(OutputMaxSize),
   431  			},
   432  		}
   433  		err = repository.UpdateResult(context.Background(), testName, result)
   434  		assert.NoError(t, err)
   435  	})
   436  	t.Run("too many steps", func(t *testing.T) {
   437  		result := testkube.Execution{
   438  			Id:       executionID,
   439  			Name:     executionID,
   440  			TestName: testName,
   441  			ExecutionResult: &testkube.ExecutionResult{
   442  				Output: randomString(OutputMaxSize),
   443  				Steps:  []testkube.ExecutionStepResult{},
   444  			},
   445  		}
   446  		for i := 0; i < StepMaxCount; i++ {
   447  			result.ExecutionResult.Steps = append(result.ExecutionResult.Steps, testkube.ExecutionStepResult{
   448  				Name: fmt.Sprintf("step-%d", i),
   449  			})
   450  		}
   451  
   452  		err = repository.UpdateResult(context.Background(), testName, result)
   453  		assert.NoError(t, err)
   454  	})
   455  }