about summary refs log blame commit diff
path: root/main/civisibility/integrations/manual_api.go
blob: 168ec86ec49aa02cafa7de0b1c6a69dda7bcc3b5 (plain) (tree)


























































































































































































































                                                                                                                                                                        
// 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"
	"runtime"
	"sync"
	"time"

	"ci-visibility-test-github/main/civisibility/constants"
	"ci-visibility-test-github/main/civisibility/utils"

	"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext"
	"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
)

// TestResultStatus represents the result status of a test.
type TestResultStatus int

const (
	// ResultStatusPass indicates that the test has passed.
	ResultStatusPass TestResultStatus = 0

	// ResultStatusFail indicates that the test has failed.
	ResultStatusFail TestResultStatus = 1

	// ResultStatusSkip indicates that the test has been skipped.
	ResultStatusSkip TestResultStatus = 2
)

// ddTslvEvent is an interface that provides common methods for CI visibility events.
type ddTslvEvent interface {
	// Context returns the context of the event.
	Context() context.Context

	// StartTime returns the start time of the event.
	StartTime() time.Time

	// SetError sets an error on the event.
	SetError(err error)

	// SetErrorInfo sets detailed error information on the event.
	SetErrorInfo(errType string, message string, callstack string)

	// SetTag sets a tag on the event.
	SetTag(key string, value interface{})
}

// DdTestSession represents a session for a set of tests.
type DdTestSession interface {
	ddTslvEvent

	// Command returns the command used to run the session.
	Command() string

	// Framework returns the testing framework used.
	Framework() string

	// WorkingDirectory returns the working directory of the session.
	WorkingDirectory() string

	// Close closes the test session with the given exit code.
	Close(exitCode int)

	// CloseWithFinishTime closes the test session with the given exit code and finish time.
	CloseWithFinishTime(exitCode int, finishTime time.Time)

	// GetOrCreateModule returns an existing module or creates a new one with the given name.
	GetOrCreateModule(name string) DdTestModule

	// GetOrCreateModuleWithFramework returns an existing module or creates a new one with the given name, framework, and framework version.
	GetOrCreateModuleWithFramework(name string, framework string, frameworkVersion string) DdTestModule

	// GetOrCreateModuleWithFrameworkAndStartTime returns an existing module or creates a new one with the given name, framework, framework version, and start time.
	GetOrCreateModuleWithFrameworkAndStartTime(name string, framework string, frameworkVersion string, startTime time.Time) DdTestModule
}

// DdTestModule represents a module within a test session.
type DdTestModule interface {
	ddTslvEvent

	// Session returns the test session to which the module belongs.
	Session() DdTestSession

	// Framework returns the testing framework used by the module.
	Framework() string

	// Name returns the name of the module.
	Name() string

	// Close closes the test module.
	Close()

	// CloseWithFinishTime closes the test module with the given finish time.
	CloseWithFinishTime(finishTime time.Time)

	// GetOrCreateSuite returns an existing suite or creates a new one with the given name.
	GetOrCreateSuite(name string) DdTestSuite

	// GetOrCreateSuiteWithStartTime returns an existing suite or creates a new one with the given name and start time.
	GetOrCreateSuiteWithStartTime(name string, startTime time.Time) DdTestSuite
}

// DdTestSuite represents a suite of tests within a module.
type DdTestSuite interface {
	ddTslvEvent

	// Module returns the module to which the suite belongs.
	Module() DdTestModule

	// Name returns the name of the suite.
	Name() string

	// Close closes the test suite.
	Close()

	// CloseWithFinishTime closes the test suite with the given finish time.
	CloseWithFinishTime(finishTime time.Time)

	// CreateTest creates a new test with the given name.
	CreateTest(name string) DdTest

	// CreateTestWithStartTime creates a new test with the given name and start time.
	CreateTestWithStartTime(name string, startTime time.Time) DdTest
}

// DdTest represents an individual test within a suite.
type DdTest interface {
	ddTslvEvent

	// Name returns the name of the test.
	Name() string

	// Suite returns the suite to which the test belongs.
	Suite() DdTestSuite

	// Close closes the test with the given status.
	Close(status TestResultStatus)

	// CloseWithFinishTime closes the test with the given status and finish time.
	CloseWithFinishTime(status TestResultStatus, finishTime time.Time)

	// CloseWithFinishTimeAndSkipReason closes the test with the given status, finish time, and skip reason.
	CloseWithFinishTimeAndSkipReason(status TestResultStatus, finishTime time.Time, skipReason string)

	// SetTestFunc sets the function to be tested. (Sets the test.source tags and test.codeowners)
	SetTestFunc(fn *runtime.Func)

	// SetBenchmarkData sets benchmark data for the test.
	SetBenchmarkData(measureType string, data map[string]any)
}

// common
var _ ddTslvEvent = (*ciVisibilityCommon)(nil)

// ciVisibilityCommon is a struct that implements the ddTslvEvent interface and provides common functionality for CI visibility.
type ciVisibilityCommon struct {
	startTime time.Time

	tags   []tracer.StartSpanOption
	span   tracer.Span
	ctx    context.Context
	mutex  sync.Mutex
	closed bool
}

// Context returns the context of the event.
func (c *ciVisibilityCommon) Context() context.Context { return c.ctx }

// StartTime returns the start time of the event.
func (c *ciVisibilityCommon) StartTime() time.Time { return c.startTime }

// SetError sets an error on the event.
func (c *ciVisibilityCommon) SetError(err error) {
	c.span.SetTag(ext.Error, err)
}

// SetErrorInfo sets detailed error information on the event.
func (c *ciVisibilityCommon) SetErrorInfo(errType string, message string, callstack string) {
	// set the span with error:1
	c.span.SetTag(ext.Error, true)

	// set the error type
	if errType != "" {
		c.span.SetTag(ext.ErrorType, errType)
	}

	// set the error message
	if message != "" {
		c.span.SetTag(ext.ErrorMsg, message)
	}

	// set the error stacktrace
	if callstack != "" {
		c.span.SetTag(ext.ErrorStack, callstack)
	}
}

// SetTag sets a tag on the event.
func (c *ciVisibilityCommon) SetTag(key string, value interface{}) { c.span.SetTag(key, value) }

// fillCommonTags adds common tags to the span options for CI visibility.
func fillCommonTags(opts []tracer.StartSpanOption) []tracer.StartSpanOption {
	opts = append(opts, []tracer.StartSpanOption{
		tracer.Tag(constants.Origin, constants.CIAppTestOrigin),
		tracer.Tag(ext.ManualKeep, true),
	}...)

	// Apply CI tags
	for k, v := range utils.GetCITags() {
		opts = append(opts, tracer.Tag(k, v))
	}

	return opts
}