Skip to content

Commit

Permalink
feat: Improve filters and add integration tests (reloaded). (#521)
Browse files Browse the repository at this point in the history
* feat: Improve filters and add integration tests.

* fix: Use random name for execution id in mongo tests.

* fix: Pass by value for filter dates.
  • Loading branch information
nicufk authored Nov 18, 2021
1 parent b9f3097 commit 008b501
Show file tree
Hide file tree
Showing 4 changed files with 283 additions and 27 deletions.
7 changes: 6 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ jobs:

build:
runs-on: ubuntu-latest

services:
mongo:
image: bitnami/mongodb
ports:
- 27017:27017

steps:
- uses: actions/checkout@v2

Expand Down
2 changes: 1 addition & 1 deletion internal/pkg/api/repository/result/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func (f filter) EndDate() time.Time {
}

func (f filter) StatusDefined() bool {
return f.endDate != nil
return f.status != nil
}

func (f filter) Status() testkube.ExecutionStatus {
Expand Down
72 changes: 47 additions & 25 deletions internal/pkg/api/repository/result/mongo.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ func (r *MongoRepository) GetNewestExecutions(ctx context.Context, limit int) (r
func (r *MongoRepository) GetExecutions(ctx context.Context, filter Filter) (result []testkube.Execution, err error) {
query, opts := composeQueryAndOpts(filter)
cursor, err := r.Coll.Find(ctx, query, opts)

if err != nil {
return
}
Expand All @@ -59,34 +58,57 @@ func (r *MongoRepository) GetExecutions(ctx context.Context, filter Filter) (res
func (r *MongoRepository) GetExecutionTotals(ctx context.Context, filter Filter) (result testkube.ExecutionsTotals, err error) {

query, _ := composeQueryAndOpts(filter)
query["scriptType"] = bson.M{"$exists": true}
total, err := r.Coll.CountDocuments(ctx, query)
if err != nil {
return
return result, err
}
result.Results = int32(total)

query["executionResult"] = bson.M{"status": testkube.QUEUED_ExecutionStatus}
queued, err := r.Coll.CountDocuments(ctx, query)
if err != nil {
return
}
result.Queued = int32(queued)

query["executionResult"] = bson.M{"status": testkube.PENDING_ExecutionStatus}
pending, err := r.Coll.CountDocuments(ctx, query)
if err != nil {
return
if status, ok := query["executionresult.status"]; ok {
count, err := r.Coll.CountDocuments(ctx, query)
if err != nil {
return result, err
}
switch status {
case testkube.QUEUED_ExecutionStatus:
result.Queued = int32(count)
case testkube.PENDING_ExecutionStatus:
result.Pending = int32(count)
case testkube.SUCCESS_ExecutionStatus:
result.Passed = int32(count)
case testkube.ERROR__ExecutionStatus:
result.Failed = int32(count)
}
} else {
query["executionresult.status"] = testkube.ExecutionStatusQueued
queued, err := r.Coll.CountDocuments(ctx, query)
if err != nil {
return result, err
}
result.Queued = int32(queued)

query["executionresult.status"] = testkube.ExecutionStatusPending
pending, err := r.Coll.CountDocuments(ctx, query)
if err != nil {
return result, err
}
result.Pending = int32(pending)

query["executionresult.status"] = testkube.ExecutionStatusSuccess
passed, err := r.Coll.CountDocuments(ctx, query)
if err != nil {
return result, err
}
result.Passed = int32(passed)

query["executionresult.status"] = testkube.ExecutionStatusError
failed, err := r.Coll.CountDocuments(ctx, query)
if err != nil {
return result, err
}
result.Failed = int32(failed)
}
result.Pending = int32(pending)

query["executionResult"] = bson.M{"status": testkube.ERROR__ExecutionStatus}
failed, err := r.Coll.CountDocuments(ctx, query)
if err != nil {
return
}
result.Failed = int32(failed)
return
return result, err
}

func (r *MongoRepository) Insert(ctx context.Context, result testkube.Execution) (err error) {
Expand Down Expand Up @@ -135,11 +157,11 @@ func composeQueryAndOpts(filter Filter) (bson.M, *options.FindOptions) {
}

if len(startTimeQuery) > 0 {
query["startTime"] = startTimeQuery
query["starttime"] = startTimeQuery
}

if filter.StatusDefined() {
query["executionResult"] = bson.M{"status": filter.Status()}
query["executionresult.status"] = filter.Status()
}

opts.SetSkip(int64(filter.Page() * filter.PageSize()))
Expand Down
229 changes: 229 additions & 0 deletions internal/pkg/api/repository/result/mongo_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
package result

import (
"context"
"testing"
"time"

"github.com/kubeshop/testkube/internal/pkg/api/repository/storage"
"github.com/kubeshop/testkube/pkg/api/v1/testkube"
"github.com/kubeshop/testkube/pkg/rand"
"github.com/stretchr/testify/require"
)

const (
mongoDns = "mongodb://localhost:27017"
mongoDbName = "testkube"
)

func TestFilters(t *testing.T) {
assert := require.New(t)

repository, err := getRepository()
assert.NoError(err)

err = repository.Coll.Drop(context.TODO())
assert.NoError(err)

oneDayAgo := time.Now().Add(-24 * time.Hour)
twoDaysAgo := time.Now().Add(-48 * time.Hour)
defaultName := "name"
err = repository.insertExecutionResult(defaultName, testkube.ERROR__ExecutionStatus, time.Now())
assert.NoError(err)
err = repository.insertExecutionResult(defaultName, testkube.ERROR__ExecutionStatus, time.Now())
assert.NoError(err)
err = repository.insertExecutionResult(defaultName, testkube.ERROR__ExecutionStatus, time.Now())
assert.NoError(err)
err = repository.insertExecutionResult(defaultName, testkube.ERROR__ExecutionStatus, time.Now())
assert.NoError(err)
err = repository.insertExecutionResult(defaultName, testkube.SUCCESS_ExecutionStatus, time.Now())
assert.NoError(err)
err = repository.insertExecutionResult(defaultName, testkube.QUEUED_ExecutionStatus, time.Now())
assert.NoError(err)
err = repository.insertExecutionResult(defaultName, testkube.PENDING_ExecutionStatus, time.Now())
assert.NoError(err)
err = repository.insertExecutionResult(defaultName, testkube.ERROR__ExecutionStatus, oneDayAgo)
assert.NoError(err)
err = repository.insertExecutionResult(defaultName, testkube.ERROR__ExecutionStatus, oneDayAgo)
assert.NoError(err)
err = repository.insertExecutionResult(defaultName, testkube.ERROR__ExecutionStatus, oneDayAgo)
assert.NoError(err)
err = repository.insertExecutionResult(defaultName, testkube.ERROR__ExecutionStatus, oneDayAgo)
assert.NoError(err)
err = repository.insertExecutionResult(defaultName, testkube.SUCCESS_ExecutionStatus, oneDayAgo)
assert.NoError(err)
err = repository.insertExecutionResult(defaultName, testkube.QUEUED_ExecutionStatus, oneDayAgo)
assert.NoError(err)
err = repository.insertExecutionResult(defaultName, testkube.PENDING_ExecutionStatus, oneDayAgo)
assert.NoError(err)
err = repository.insertExecutionResult(defaultName, testkube.ERROR__ExecutionStatus, twoDaysAgo)
assert.NoError(err)
err = repository.insertExecutionResult(defaultName, testkube.ERROR__ExecutionStatus, twoDaysAgo)
assert.NoError(err)
err = repository.insertExecutionResult(defaultName, testkube.ERROR__ExecutionStatus, twoDaysAgo)
assert.NoError(err)
err = repository.insertExecutionResult(defaultName, testkube.ERROR__ExecutionStatus, twoDaysAgo)
assert.NoError(err)
err = repository.insertExecutionResult(defaultName, testkube.SUCCESS_ExecutionStatus, twoDaysAgo)
assert.NoError(err)
err = repository.insertExecutionResult(defaultName, testkube.QUEUED_ExecutionStatus, twoDaysAgo)
assert.NoError(err)
err = repository.insertExecutionResult(defaultName, testkube.PENDING_ExecutionStatus, twoDaysAgo)
assert.NoError(err)

t.Run("filter with status should return only executions with that status", func(t *testing.T) {

executions, err := repository.GetExecutions(context.Background(), NewExecutionsFilter().WithStatus(testkube.ERROR__ExecutionStatus))
assert.NoError(err)
assert.Len(executions, 12)
assert.Equal(*executions[0].ExecutionResult.Status, testkube.ERROR__ExecutionStatus)
})

t.Run("filter with status should return only totals with that status", func(t *testing.T) {
filteredTotals, err := repository.GetExecutionTotals(context.Background(), NewExecutionsFilter().WithStatus(testkube.ERROR__ExecutionStatus))

assert.NoError(err)
assert.Equal(int32(12), filteredTotals.Results)
assert.Equal(int32(12), filteredTotals.Failed)
assert.Equal(int32(0), filteredTotals.Passed)
assert.Equal(int32(0), filteredTotals.Queued)
assert.Equal(int32(0), filteredTotals.Pending)
})

t.Run("getting totals without filters should return all the executions", func(t *testing.T) {
totals, err := repository.GetExecutionTotals(context.Background(), NewExecutionsFilter())

assert.NoError(err)
assert.Equal(int32(21), totals.Results)
assert.Equal(int32(12), totals.Failed)
assert.Equal(int32(3), totals.Passed)
assert.Equal(int32(3), totals.Queued)
assert.Equal(int32(3), totals.Pending)
})

t.Run("filter with startDate should return only executions after that day", func(t *testing.T) {

executions, err := repository.GetExecutions(context.Background(), NewExecutionsFilter().WithStartDate(oneDayAgo))
assert.NoError(err)
assert.Len(executions, 14)
assert.True(executions[0].StartTime.After(oneDayAgo) || executions[0].StartTime.Equal(oneDayAgo))
})

t.Run("getting totals with filter by date start date should return only the results after this date", func(t *testing.T) {
totals, err := repository.GetExecutionTotals(context.Background(), NewExecutionsFilter().WithStartDate(oneDayAgo))

assert.NoError(err)
assert.Equal(int32(14), totals.Results)
assert.Equal(int32(8), totals.Failed)
assert.Equal(int32(2), totals.Passed)
assert.Equal(int32(2), totals.Queued)
assert.Equal(int32(2), totals.Pending)
})

t.Run("filter with endDate should return only executions before that day", func(t *testing.T) {

executions, err := repository.GetExecutions(context.Background(), NewExecutionsFilter().WithEndDate(oneDayAgo))
assert.NoError(err)
assert.Len(executions, 14)
assert.True(executions[0].StartTime.Before(oneDayAgo) || executions[0].StartTime.Equal(oneDayAgo))
})

t.Run("getting totals with filter by date start date should return only the results before this date", func(t *testing.T) {
totals, err := repository.GetExecutionTotals(context.Background(), NewExecutionsFilter().WithEndDate(oneDayAgo))

assert.NoError(err)
assert.Equal(int32(14), totals.Results)
assert.Equal(int32(8), totals.Failed)
assert.Equal(int32(2), totals.Passed)
assert.Equal(int32(2), totals.Queued)
assert.Equal(int32(2), totals.Pending)
})

t.Run("filter with script name that doesn't exist should return 0 results", func(t *testing.T) {

executions, err := repository.GetExecutions(context.Background(), NewExecutionsFilter().WithScriptName("noneExisting"))
assert.NoError(err)
assert.Empty(executions)
})

t.Run("getting totals with script name that doesn't exist should return 0 results", func(t *testing.T) {
totals, err := repository.GetExecutionTotals(context.Background(), NewExecutionsFilter().WithScriptName("noneExisting"))

assert.NoError(err)
assert.Equal(int32(0), totals.Results)
assert.Equal(int32(0), totals.Failed)
assert.Equal(int32(0), totals.Passed)
assert.Equal(int32(0), totals.Queued)
assert.Equal(int32(0), totals.Pending)
})

t.Run("filter with ccombined filter should return corresponding results", func(t *testing.T) {
filter := NewExecutionsFilter().
WithStatus(testkube.SUCCESS_ExecutionStatus).
WithStartDate(twoDaysAgo).
WithEndDate(oneDayAgo).
WithScriptName(defaultName)
executions, err := repository.GetExecutions(context.Background(), filter)
assert.NoError(err)
assert.Len(executions, 2)
})

t.Run("getting totals with ccombined filter should return corresponding results", func(t *testing.T) {
filter := NewExecutionsFilter().
WithStatus(testkube.SUCCESS_ExecutionStatus).
WithStartDate(twoDaysAgo).
WithEndDate(oneDayAgo).
WithScriptName(defaultName)
totals, err := repository.GetExecutionTotals(context.Background(), filter)

assert.NoError(err)
assert.Equal(int32(2), totals.Results)
assert.Equal(int32(0), totals.Failed)
assert.Equal(int32(2), totals.Passed)
assert.Equal(int32(0), totals.Queued)
assert.Equal(int32(0), totals.Pending)
})

name := "someDifferentName"
err = repository.insertExecutionResult(name, testkube.PENDING_ExecutionStatus, twoDaysAgo)
assert.NoError(err)

t.Run("filter with script name should return result only for that script name", func(t *testing.T) {

executions, err := repository.GetExecutions(context.Background(), NewExecutionsFilter().WithScriptName(name))
assert.NoError(err)
assert.Len(executions, 1)
assert.Equal(executions[0].ScriptName, name)
})

t.Run("getting totals with script name should return result only for that script name", func(t *testing.T) {
totals, err := repository.GetExecutionTotals(context.Background(), NewExecutionsFilter().WithScriptName(name))

assert.NoError(err)
assert.Equal(int32(1), totals.Results)
assert.Equal(int32(0), totals.Failed)
assert.Equal(int32(0), totals.Passed)
assert.Equal(int32(0), totals.Queued)
assert.Equal(int32(1), totals.Pending)
})

}

func getRepository() (*MongoRepository, error) {
db, err := storage.GetMongoDataBase(mongoDns, mongoDbName)
repository := NewMongoRespository(db)
return repository, err
}

func (repository *MongoRepository) insertExecutionResult(scriptName string, execStatus testkube.ExecutionStatus, startTime time.Time) error {
return repository.Insert(context.Background(),
testkube.Execution{
Id: rand.Name(),
ScriptName: scriptName,
Name: "dummyName",
ScriptType: "test/curl",
StartTime: startTime,
EndTime: time.Now(),
ExecutionResult: &testkube.ExecutionResult{Status: &execStatus},
})
}

0 comments on commit 008b501

Please sign in to comment.