about summary refs log tree commit diff
path: root/main/civisibility/integrations/manual_api_ddtestsession.go
diff options
context:
space:
mode:
authorManuel Palenzuela Merino <manuel.palenzuela@datadoghq.com>2024-12-05 11:07:35 +0100
committerManuel Palenzuela Merino <manuel.palenzuela@datadoghq.com>2024-12-05 11:08:17 +0100
commitee3c0aa3d71a857ae7fb60f1b98cf129ee6ad71d (patch)
tree8aeaa3b76be6cdcf326acf3627b3d283a8b2c372 /main/civisibility/integrations/manual_api_ddtestsession.go
parentUpdate README.md (diff)
downloadtest-repo-ee3c0aa3d71a857ae7fb60f1b98cf129ee6ad71d.tar.gz
test-repo-ee3c0aa3d71a857ae7fb60f1b98cf129ee6ad71d.tar.bz2
test-repo-ee3c0aa3d71a857ae7fb60f1b98cf129ee6ad71d.zip
Add tests
Diffstat (limited to 'main/civisibility/integrations/manual_api_ddtestsession.go')
-rw-r--r--main/civisibility/integrations/manual_api_ddtestsession.go171
1 files changed, 171 insertions, 0 deletions
diff --git a/main/civisibility/integrations/manual_api_ddtestsession.go b/main/civisibility/integrations/manual_api_ddtestsession.go
new file mode 100644
index 0000000..93cf8a8
--- /dev/null
+++ b/main/civisibility/integrations/manual_api_ddtestsession.go
@@ -0,0 +1,171 @@
+// Unless explicitly stated otherwise all files in this repository are licensed
+// under the Apache License Version 2.0.
+// This product includes software developed at Datadog (https://www.datadoghq.com/).
+// Copyright 2024 Datadog, Inc.
+
+package integrations
+
+import (
+	"context"
+	"fmt"
+	"os"
+	"path/filepath"
+	"regexp"
+	"strings"
+	"time"
+
+	"ci-visibility-test-github/main/civisibility/constants"
+	"ci-visibility-test-github/main/civisibility/utils"
+
+	"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
+)
+
+// Test Session
+
+// Ensures that tslvTestSession implements the DdTestSession interface.
+var _ DdTestSession = (*tslvTestSession)(nil)
+
+// tslvTestSession implements the DdTestSession interface and represents a session for a set of tests.
+type tslvTestSession struct {
+	ciVisibilityCommon
+	sessionID        uint64
+	command          string
+	workingDirectory string
+	framework        string
+
+	modules map[string]DdTestModule
+}
+
+// CreateTestSession initializes a new test session. It automatically determines the command and working directory.
+func CreateTestSession() DdTestSession {
+	var cmd string
+	if len(os.Args) == 1 {
+		cmd = filepath.Base(os.Args[0])
+	} else {
+		cmd = fmt.Sprintf("%s %s ", filepath.Base(os.Args[0]), strings.Join(os.Args[1:], " "))
+	}
+
+	// Filter out some parameters to make the command more stable.
+	cmd = regexp.MustCompile(`(?si)-test.gocoverdir=(.*)\s`).ReplaceAllString(cmd, "")
+	cmd = regexp.MustCompile(`(?si)-test.v=(.*)\s`).ReplaceAllString(cmd, "")
+	cmd = regexp.MustCompile(`(?si)-test.testlogfile=(.*)\s`).ReplaceAllString(cmd, "")
+	cmd = strings.TrimSpace(cmd)
+	wd, err := os.Getwd()
+	if err == nil {
+		wd = utils.GetRelativePathFromCITagsSourceRoot(wd)
+	}
+	return CreateTestSessionWith(cmd, wd, "", time.Now())
+}
+
+// CreateTestSessionWith initializes a new test session with specified command, working directory, framework, and start time.
+func CreateTestSessionWith(command string, workingDirectory string, framework string, startTime time.Time) DdTestSession {
+	// Ensure CI visibility is properly configured.
+	EnsureCiVisibilityInitialization()
+
+	operationName := "test_session"
+	if framework != "" {
+		operationName = fmt.Sprintf("%s.%s", strings.ToLower(framework), operationName)
+	}
+
+	resourceName := fmt.Sprintf("%s.%s", operationName, command)
+
+	sessionTags := []tracer.StartSpanOption{
+		tracer.Tag(constants.TestType, constants.TestTypeTest),
+		tracer.Tag(constants.TestCommand, command),
+		tracer.Tag(constants.TestCommandWorkingDirectory, workingDirectory),
+	}
+
+	testOpts := append(fillCommonTags([]tracer.StartSpanOption{
+		tracer.ResourceName(resourceName),
+		tracer.SpanType(constants.SpanTypeTestSession),
+		tracer.StartTime(startTime),
+	}), sessionTags...)
+
+	span, ctx := tracer.StartSpanFromContext(context.Background(), operationName, testOpts...)
+	sessionID := span.Context().SpanID()
+	span.SetTag(constants.TestSessionIDTag, fmt.Sprint(sessionID))
+
+	s := &tslvTestSession{
+		sessionID:        sessionID,
+		command:          command,
+		workingDirectory: workingDirectory,
+		framework:        framework,
+		modules:          map[string]DdTestModule{},
+		ciVisibilityCommon: ciVisibilityCommon{
+			startTime: startTime,
+			tags:      sessionTags,
+			span:      span,
+			ctx:       ctx,
+		},
+	}
+
+	// Ensure to close everything before CI visibility exits. In CI visibility mode, we try to never lose data.
+	PushCiVisibilityCloseAction(func() { s.Close(1) })
+
+	return s
+}
+
+// Command returns the command used to run the test session.
+func (t *tslvTestSession) Command() string { return t.command }
+
+// Framework returns the testing framework used in the test session.
+func (t *tslvTestSession) Framework() string { return t.framework }
+
+// WorkingDirectory returns the working directory of the test session.
+func (t *tslvTestSession) WorkingDirectory() string { return t.workingDirectory }
+
+// Close closes the test session with the given exit code and sets the finish time to the current time.
+func (t *tslvTestSession) Close(exitCode int) { t.CloseWithFinishTime(exitCode, time.Now()) }
+
+// CloseWithFinishTime closes the test session with the given exit code and finish time.
+func (t *tslvTestSession) CloseWithFinishTime(exitCode int, finishTime time.Time) {
+	t.mutex.Lock()
+	defer t.mutex.Unlock()
+	if t.closed {
+		return
+	}
+
+	for _, m := range t.modules {
+		m.Close()
+	}
+	t.modules = map[string]DdTestModule{}
+
+	t.span.SetTag(constants.TestCommandExitCode, exitCode)
+	if exitCode == 0 {
+		t.span.SetTag(constants.TestStatus, constants.TestStatusPass)
+	} else {
+		t.SetErrorInfo("ExitCode", "exit code is not zero.", "")
+		t.span.SetTag(constants.TestStatus, constants.TestStatusFail)
+	}
+
+	t.span.Finish(tracer.FinishTime(finishTime))
+	t.closed = true
+
+	tracer.Flush()
+}
+
+// GetOrCreateModule returns an existing module or creates a new one with the given name.
+func (t *tslvTestSession) GetOrCreateModule(name string) DdTestModule {
+	return t.GetOrCreateModuleWithFramework(name, "", "")
+}
+
+// GetOrCreateModuleWithFramework returns an existing module or creates a new one with the given name, framework, and framework version.
+func (t *tslvTestSession) GetOrCreateModuleWithFramework(name string, framework string, frameworkVersion string) DdTestModule {
+	return t.GetOrCreateModuleWithFrameworkAndStartTime(name, framework, frameworkVersion, time.Now())
+}
+
+// GetOrCreateModuleWithFrameworkAndStartTime returns an existing module or creates a new one with the given name, framework, framework version, and start time.
+func (t *tslvTestSession) GetOrCreateModuleWithFrameworkAndStartTime(name string, framework string, frameworkVersion string, startTime time.Time) DdTestModule {
+	t.mutex.Lock()
+	defer t.mutex.Unlock()
+
+	var mod DdTestModule
+	if v, ok := t.modules[name]; ok {
+		mod = v
+	} else {
+		mod = createTestModule(t, name, framework, frameworkVersion, startTime)
+		t.modules[name] = mod
+	}
+
+	return mod
+}