Skip to content

Commit

Permalink
fixup unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
rangoo94 committed Jan 17, 2025
1 parent 9dbcc52 commit c0acb70
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 123 deletions.
47 changes: 30 additions & 17 deletions cmd/testworkflow-toolkit/artifacts/cloud_uploader.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,28 @@ import (

"github.com/pkg/errors"

"github.com/kubeshop/testkube/cmd/testworkflow-toolkit/env/config"
"github.com/kubeshop/testkube/pkg/controlplaneclient"
"github.com/kubeshop/testkube/pkg/ui"
)

type CloudUploaderRequestEnhancer = func(req *http.Request, path string, size int64)

func NewCloudUploader(client controlplaneclient.ExecutionSelfClient, opts ...CloudUploaderOpt) Uploader {
func NewCloudUploader(
client controlplaneclient.ExecutionSelfClient,
environmentId string,
executionId string,
workflowName string,
stepRef string,
opts ...CloudUploaderOpt,
) Uploader {
uploader := &cloudUploader{
client: client,
parallelism: 1,
reqEnhancers: make([]CloudUploaderRequestEnhancer, 0),
client: client,
parallelism: 1,
reqEnhancers: make([]CloudUploaderRequestEnhancer, 0),
environmentId: environmentId,
executionId: executionId,
workflowName: workflowName,
stepRef: stepRef,
}
for _, opt := range opts {
opt(uploader)
Expand All @@ -33,13 +43,17 @@ func NewCloudUploader(client controlplaneclient.ExecutionSelfClient, opts ...Clo
}

type cloudUploader struct {
client controlplaneclient.ExecutionSelfClient
wg sync.WaitGroup
sema chan struct{}
parallelism int
error atomic.Bool
reqEnhancers []CloudUploaderRequestEnhancer
waitMu sync.Mutex
client controlplaneclient.ExecutionSelfClient
wg sync.WaitGroup
sema chan struct{}
parallelism int
error atomic.Bool
reqEnhancers []CloudUploaderRequestEnhancer
waitMu sync.Mutex
environmentId string
executionId string
workflowName string
stepRef string
}

func (d *cloudUploader) Start() (err error) {
Expand All @@ -48,13 +62,12 @@ func (d *cloudUploader) Start() (err error) {
}

func (d *cloudUploader) getSignedURL(name, contentType string) (string, error) {
cfg := config.Config()
return d.client.SaveExecutionArtifactGetPresignedURL(
context.Background(),
cfg.Execution.EnvironmentId,
cfg.Execution.Id,
cfg.Workflow.Name,
config.Ref(),
d.environmentId,
d.executionId,
d.workflowName,
d.stepRef,
name,
contentType,
)
Expand Down
76 changes: 25 additions & 51 deletions cmd/testworkflow-toolkit/artifacts/handler_test.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
package artifacts

import (
"encoding/json"
"net/http"
"net/http/httptest"
"os"
"testing"

"github.com/golang/mock/gomock"

"github.com/kubeshop/testkube/pkg/cloud/data/testworkflow"
"github.com/kubeshop/testkube/pkg/controlplaneclient"

"github.com/kubeshop/testkube/cmd/testworkflow-toolkit/common/testdata"
"github.com/kubeshop/testkube/pkg/cloud/data/artifact"
"github.com/kubeshop/testkube/pkg/cloud/data/executor"
"github.com/kubeshop/testkube/pkg/filesystem"
)

Expand Down Expand Up @@ -48,66 +45,43 @@ func TestHandler_CloudUploader(t *testing.T) {
Return(filesystem.NewMockFile("report/junit.xml", []byte(testdata.BasicJUnit)), nil)

}
setDirectPresignedURLExpectations := func(client *executor.MockExecutor) {
req1 := artifact.PutObjectSignedURLRequest{
Object: "test.log",
ContentType: "application/octet-stream",
}
resp1 := artifact.PutObjectSignedURLResponse{
URL: server.URL,
}
resp1Json, _ := json.Marshal(resp1)
client.EXPECT().Execute(gomock.Any(), artifact.CmdScraperPutObjectSignedURL, gomock.Eq(&req1)).Return(resp1Json, nil)
req2 := artifact.PutObjectSignedURLRequest{
Object: "report/junit.xml",
ContentType: "application/octet-stream",
}
resp2 := artifact.PutObjectSignedURLResponse{
URL: server.URL,
}
resp2Json, _ := json.Marshal(resp2)
client.EXPECT().Execute(gomock.Any(), artifact.CmdScraperPutObjectSignedURL, gomock.Eq(&req2)).Return(resp2Json, nil)
setDirectPresignedURLExpectations := func(client *controlplaneclient.MockClient) {
client.EXPECT().
SaveExecutionArtifactGetPresignedURL(gomock.Any(), "env123", "exec123", "workflow123", "step123", "test.log", "application/octet-stream").
Return(server.URL, nil)
client.EXPECT().
SaveExecutionArtifactGetPresignedURL(gomock.Any(), "env123", "exec123", "workflow123", "step123", "report/junit.xml", "application/octet-stream").
Return(server.URL, nil)
}
setTarPresignedURLExpectations := func(client *executor.MockExecutor) {
req1 := artifact.PutObjectSignedURLRequest{
Object: "artifacts.tar.gz",
ContentType: "application/octet-stream",
}
resp1 := artifact.PutObjectSignedURLResponse{
URL: server.URL,
}
resp1Json, _ := json.Marshal(resp1)
client.EXPECT().Execute(gomock.Any(), artifact.CmdScraperPutObjectSignedURL, gomock.Eq(&req1)).Return(resp1Json, nil)
setTarPresignedURLExpectations := func(client *controlplaneclient.MockClient) {
client.EXPECT().
SaveExecutionArtifactGetPresignedURL(gomock.Any(), "env123", "exec123", "workflow123", "step123", "artifacts.tar.gz", "application/octet-stream").
Return(server.URL, nil)
}
setJUnitPostProcessorExpectations := func(client *executor.MockExecutor) {
req := testworkflow.ExecutionsAddReportRequest{
Filepath: "report/junit.xml",
Report: []byte(testdata.BasicJUnit),
}
client.
EXPECT().
Execute(gomock.Any(), testworkflow.CmdTestWorkflowExecutionAddReport, gomock.Eq(&req)).
Return(nil, nil)
setJUnitPostProcessorExpectations := func(client *controlplaneclient.MockClient) {
client.EXPECT().
AppendExecutionReport(gomock.Any(), "env123", "exec123", "workflow123", "step123", "report/junit.xml", []byte(testdata.BasicJUnit)).
Return(nil)
}

tests := []struct {
name string
processor Processor
withJUnitPostProcessor bool
setup func(*filesystem.MockFileSystem, *executor.MockExecutor)
setup func(*filesystem.MockFileSystem, *controlplaneclient.MockClient)
}{
{
name: "direct processor",
processor: NewDirectProcessor(),
setup: func(fs *filesystem.MockFileSystem, client *executor.MockExecutor) {
setup: func(fs *filesystem.MockFileSystem, client *controlplaneclient.MockClient) {
setDirectPresignedURLExpectations(client)
},
},
{
name: "direct processor with junit post processor",
processor: NewDirectProcessor(),
withJUnitPostProcessor: true,
setup: func(fs *filesystem.MockFileSystem, client *executor.MockExecutor) {
setup: func(fs *filesystem.MockFileSystem, client *controlplaneclient.MockClient) {
setFilesystemExpectations(fs)
setDirectPresignedURLExpectations(client)
setJUnitPostProcessorExpectations(client)
Expand All @@ -116,15 +90,15 @@ func TestHandler_CloudUploader(t *testing.T) {
{
name: "tar processor",
processor: NewTarProcessor("artifacts.tar.gz"),
setup: func(fs *filesystem.MockFileSystem, client *executor.MockExecutor) {
setup: func(fs *filesystem.MockFileSystem, client *controlplaneclient.MockClient) {
setTarPresignedURLExpectations(client)
},
},
{
name: "tar processor with junit post processor",
withJUnitPostProcessor: true,
processor: NewTarProcessor("artifacts.tar.gz"),
setup: func(fs *filesystem.MockFileSystem, client *executor.MockExecutor) {
setup: func(fs *filesystem.MockFileSystem, client *controlplaneclient.MockClient) {
setFilesystemExpectations(fs)
setTarPresignedURLExpectations(client)
setJUnitPostProcessorExpectations(client)
Expand All @@ -135,14 +109,14 @@ func TestHandler_CloudUploader(t *testing.T) {
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
mockFilesystem := filesystem.NewMockFileSystem(mockCtrl)
mockExecutor := executor.NewMockExecutor(mockCtrl)
uploader := NewCloudUploader(mockExecutor)
mockClient := controlplaneclient.NewMockClient(mockCtrl)
uploader := NewCloudUploader(mockClient, "env123", "exec123", "workflow123", "step123")
if tc.setup != nil {
tc.setup(mockFilesystem, mockExecutor)
tc.setup(mockFilesystem, mockClient)
}
var handlerOpts []HandlerOpts
if tc.withJUnitPostProcessor {
pp := NewJUnitPostProcessor(mockFilesystem, mockExecutor, "/", "")
pp := NewJUnitPostProcessor(mockFilesystem, mockClient, "env123", "exec123", "workflow123", "step123", "/", "")
handlerOpts = append(handlerOpts, WithPostProcessor(pp))
}
handler := NewHandler(uploader, tc.processor, handlerOpts...)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ type internalArtifactStorage struct {
}

func newArtifactUploader() Uploader {
return NewCloudUploader(env.Cloud(), WithParallelismCloud(30), CloudDetectMimetype)
cfg := config.Config()
return NewCloudUploader(env.Cloud(), cfg.Execution.EnvironmentId, cfg.Execution.Id, cfg.Workflow.Name, config.Ref(), WithParallelismCloud(30), CloudDetectMimetype)
}

func InternalStorage() InternalArtifactStorage {
Expand Down
38 changes: 28 additions & 10 deletions cmd/testworkflow-toolkit/artifacts/junit_post_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (

"github.com/pkg/errors"

"github.com/kubeshop/testkube/cmd/testworkflow-toolkit/env/config"
"github.com/kubeshop/testkube/pkg/controlplaneclient"

"github.com/kubeshop/testkube/pkg/filesystem"
Expand All @@ -19,15 +18,35 @@ import (

// JUnitPostProcessor is a post-processor that checks XML files for JUnit reports and sends them to the cloud.
type JUnitPostProcessor struct {
fs filesystem.FileSystem
client controlplaneclient.ExecutionSelfClient
apiKey string
root string
pathPrefix string
fs filesystem.FileSystem
client controlplaneclient.ExecutionSelfClient
root string
pathPrefix string
environmentId string
executionId string
workflowName string
stepRef string
}

func NewJUnitPostProcessor(fs filesystem.FileSystem, client controlplaneclient.ExecutionSelfClient, apiKey string, root, pathPrefix string) *JUnitPostProcessor {
return &JUnitPostProcessor{fs: fs, client: client, apiKey: apiKey, root: root, pathPrefix: pathPrefix}
func NewJUnitPostProcessor(
fs filesystem.FileSystem,
client controlplaneclient.ExecutionSelfClient,
environmentId string,
executionId string,
workflowName string,
stepRef string,
root, pathPrefix string,
) *JUnitPostProcessor {
return &JUnitPostProcessor{
fs: fs,
client: client,
environmentId: environmentId,
executionId: executionId,
workflowName: workflowName,
stepRef: stepRef,
root: root,
pathPrefix: pathPrefix,
}
}

func (p *JUnitPostProcessor) Start() error {
Expand Down Expand Up @@ -87,9 +106,8 @@ func (p *JUnitPostProcessor) Add(path string) error {

// sendJUnitReport sends the JUnit report to the Agent gRPC API.
func (p *JUnitPostProcessor) sendJUnitReport(path string, report []byte) error {
cfg := config.Config()
// TODO: think if it's valid for the parallel steps that have independent refs
return p.client.AppendExecutionReport(context.Background(), cfg.Execution.EnvironmentId, cfg.Execution.Id, cfg.Workflow.Name, config.Ref(), path, report)
return p.client.AppendExecutionReport(context.Background(), p.environmentId, p.executionId, p.workflowName, p.stepRef, path, report)
}

// isXMLFile checks if the file is an XML file based on the extension.
Expand Down
32 changes: 13 additions & 19 deletions cmd/testworkflow-toolkit/artifacts/junit_post_processor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ import (
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"

"github.com/kubeshop/testkube/pkg/cloud/data/testworkflow"
"github.com/kubeshop/testkube/pkg/controlplaneclient"

"github.com/kubeshop/testkube/cmd/testworkflow-toolkit/common/testdata"
"github.com/kubeshop/testkube/pkg/cloud/data/executor"
"github.com/kubeshop/testkube/pkg/filesystem"
)

Expand All @@ -24,7 +23,7 @@ func TestJUnitPostProcessor_Add(t *testing.T) {

tests := []struct {
name string
setup func(*executor.MockExecutor)
setup func(*controlplaneclient.MockClient)
path string
file fs.File
want error
Expand All @@ -43,12 +42,10 @@ func TestJUnitPostProcessor_Add(t *testing.T) {
},
{
name: "valid junit report",
setup: func(client *executor.MockExecutor) {
expectedPayload := testworkflow.ExecutionsAddReportRequest{
Filepath: "report/junit.xml",
Report: []byte(testdata.BasicJUnit),
}
client.EXPECT().Execute(gomock.Any(), testworkflow.CmdTestWorkflowExecutionAddReport, gomock.Eq(&expectedPayload)).Return(nil, nil)
setup: func(client *controlplaneclient.MockClient) {
client.EXPECT().
AppendExecutionReport(gomock.Any(), "env123", "exec123", "workflow123", "step123", "report/junit.xml", []byte(testdata.BasicJUnit)).
Return(nil)
},
path: "report/junit.xml",
file: filesystem.NewMockFile("basic.xml", []byte(testdata.BasicJUnit)),
Expand All @@ -60,11 +57,11 @@ func TestJUnitPostProcessor_Add(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
mockFS := filesystem.NewMockFileSystem(mockCtrl)
mockFS.EXPECT().OpenFileRO("/"+tc.path).Return(tc.file, nil)
mockClient := executor.NewMockExecutor(mockCtrl)
mockClient := controlplaneclient.NewMockClient(mockCtrl)
if tc.setup != nil {
tc.setup(mockClient)
}
pp := NewJUnitPostProcessor(mockFS, mockClient, "/", "")
pp := NewJUnitPostProcessor(mockFS, mockClient, "env123", "exec123", "workflow123", "step123", "/", "")
err := pp.Add(tc.path)
assert.Equal(t, tc.want, err)
})
Expand All @@ -77,22 +74,19 @@ func TestJUnitPostProcessor_Add_WithPathPrefix(t *testing.T) {
defer mockCtrl.Finish()

mockFS := filesystem.NewMockFileSystem(mockCtrl)
mockClient := executor.NewMockExecutor(mockCtrl)
mockClient := controlplaneclient.NewMockClient(mockCtrl)

pathPrefix := "prefixed/junit/report/"
filePath := "junit.xml"
junitContent := []byte(testdata.BasicJUnit)

mockFS.EXPECT().OpenFileRO(gomock.Any()).Return(filesystem.NewMockFile("junit.xml", junitContent), nil)

pp := NewJUnitPostProcessor(mockFS, mockClient, "/test_root", pathPrefix)
pp := NewJUnitPostProcessor(mockFS, mockClient, "env123", "exec123", "workflow123", "step123", "/test_root", pathPrefix)

expectedPayload := testworkflow.ExecutionsAddReportRequest{
Filepath: filepath.Join(pathPrefix, filePath),
Report: junitContent,
}

mockClient.EXPECT().Execute(gomock.Any(), testworkflow.CmdTestWorkflowExecutionAddReport, gomock.Eq(&expectedPayload)).Return(nil, nil)
mockClient.EXPECT().
AppendExecutionReport(gomock.Any(), "env123", "exec123", "workflow123", "step123", filepath.Join(pathPrefix, filePath), []byte(junitContent)).
Return(nil)

err := pp.Add(filePath)

Expand Down
6 changes: 3 additions & 3 deletions cmd/testworkflow-toolkit/commands/artifacts.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func NewArtifactsCmd() *cobra.Command {
client := env.Cloud()

if env.HasJunitSupport() {
junitProcessor := artifacts.NewJUnitPostProcessor(filesystem.NewOSFileSystem(), client, cfg.Worker.Connection.ApiKey, walker.Root(), cfg.Resource.FsPrefix)
junitProcessor := artifacts.NewJUnitPostProcessor(filesystem.NewOSFileSystem(), client, cfg.Execution.EnvironmentId, cfg.Execution.Id, cfg.Workflow.Name, config.Ref(), walker.Root(), cfg.Resource.FsPrefix)
handlerOpts = append(handlerOpts, artifacts.WithPostProcessor(junitProcessor))
}
if compress != "" {
Expand All @@ -93,10 +93,10 @@ func NewArtifactsCmd() *cobra.Command {
if unpack {
opts = append(opts, cloudUnpack)
}
uploader = artifacts.NewCloudUploader(client, opts...)
uploader = artifacts.NewCloudUploader(client, cfg.Execution.EnvironmentId, cfg.Execution.Id, cfg.Workflow.Name, config.Ref(), opts...)
} else {
processor = artifacts.NewDirectProcessor()
uploader = artifacts.NewCloudUploader(client, artifacts.WithParallelismCloud(30), artifacts.CloudDetectMimetype)
uploader = artifacts.NewCloudUploader(client, cfg.Execution.EnvironmentId, cfg.Execution.Id, cfg.Workflow.Name, config.Ref(), artifacts.WithParallelismCloud(30), artifacts.CloudDetectMimetype)
}

// Isolate the files under specific prefix
Expand Down
Loading

0 comments on commit c0acb70

Please sign in to comment.