Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 19 additions & 14 deletions check_in_external_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package sentry_test

import (
"context"
"errors"
"testing"
"time"
Expand All @@ -23,7 +24,7 @@ func checkInEvents(t *testing.T, f *sentrytest.Fixture) []*sentry.Event {
return events
}

func TestHubWithMonitor(t *testing.T) {
func TestWithMonitor(t *testing.T) {
t.Parallel()

errJob := errors.New("job failed")
Expand Down Expand Up @@ -62,7 +63,7 @@ func TestHubWithMonitor(t *testing.T) {
t.Parallel()
sentrytest.Run(t, func(t *testing.T, f *sentrytest.Fixture) {
calls := 0
err := f.Hub.WithMonitor("my-job", tt.monitorConfig, func() error {
err := sentry.WithMonitor(f.Context, "my-job", tt.monitorConfig, func() error {
calls++
time.Sleep(3 * time.Second)
return tt.fnErr
Expand All @@ -89,11 +90,11 @@ func TestHubWithMonitor(t *testing.T) {
}
}

func TestHubWithMonitorPanic(t *testing.T) {
func TestWithMonitorPanic(t *testing.T) {
t.Parallel()
sentrytest.Run(t, func(t *testing.T, f *sentrytest.Fixture) {
assert.PanicsWithValue(t, "boom", func() {
_ = f.Hub.WithMonitor("my-job", nil, func() error {
_ = sentry.WithMonitor(f.Context, "my-job", nil, func() error {
time.Sleep(time.Second)
panic("boom")
})
Expand All @@ -108,15 +109,19 @@ func TestHubWithMonitorPanic(t *testing.T) {
})
}

func TestWithMonitor(t *testing.T) {
f := sentrytest.NewFixture(t, sentrytest.WithGlobal())

monitorConfig := &sentry.MonitorConfig{Schedule: sentry.IntervalSchedule(1, sentry.MonitorScheduleUnitHour)}
err := sentry.WithMonitor("my-job", monitorConfig, func() error { return nil })
require.NoError(t, err)
func TestWithMonitorTrace(t *testing.T) {
t.Parallel()
sentrytest.Run(t, func(t *testing.T, f *sentrytest.Fixture) {
ctx := sentry.ContextWithClient(context.Background(), f.Client)
for range 2 {
_ = sentry.WithMonitor(ctx, "my-job", nil, func() error { return nil })
}

events := checkInEvents(t, f)
require.Len(t, events, 2)
assert.Equal(t, monitorConfig, events[0].MonitorConfig)
assert.Equal(t, sentry.CheckInStatusOK, events[1].CheckIn.Status)
events := checkInEvents(t, f)
require.Len(t, events, 4)
trace := func(i int) string { return events[i].GetDynamicSamplingContext()["trace_id"] }
assert.Equal(t, trace(0), trace(1))
assert.Equal(t, trace(2), trace(3))
assert.NotEqual(t, trace(0), trace(2))
})
}
13 changes: 6 additions & 7 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,8 +288,8 @@ type ClientOptions struct {
DisableTelemetryBuffer bool
}

// Client is the underlying processor that is used by the main API and Hub
// instances. It must be created with NewClient.
// Client processes telemetry captured through the SDK.
// It must be created with NewClient.
type Client struct {
mu sync.RWMutex
disabled bool
Expand All @@ -314,9 +314,8 @@ type Client struct {
// ClientOptions.
//
// Most users will not create clients directly. Instead, initialize the SDK with
// Init and use the package-level functions (for simple programs that run on a
// single goroutine) or hub methods (for concurrent programs, for example web
// servers).
// Init and use the package-level capture functions. Server applications should
// pass an isolated request context to those functions.
func NewClient(options ClientOptions) (*Client, error) {
// The default error event sample rate for all SDKs is 1.0 (send all).
//
Expand Down Expand Up @@ -589,8 +588,8 @@ func (client *Client) setupIntegrations() {
// ClientOptions.BeforeSend or Scope.AddEventProcessor instead.
//
// Note that typical programs have only a single client created by Init and the
// client is shared among multiple hubs, one per goroutine, such that adding an
// event processor to the client affects all hubs that share the client.
// client can be shared by multiple contexts, such that adding an event
// processor affects all contexts that share the client.
func (client *Client) AddEventProcessor(processor EventProcessor) {
if !client.IsEnabled() {
return
Expand Down
21 changes: 9 additions & 12 deletions client_reports_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package sentry

import (
"bytes"
"context"
"encoding/json"
"io"
"net/http"
Expand Down Expand Up @@ -35,7 +36,6 @@ func TestClientReports_Integration(t *testing.T) {
defer srv.Close()

dsn := strings.Replace(srv.URL, "//", "//test@", 1) + "/1"
hub := CurrentHub().Clone()
c, err := NewClient(ClientOptions{
Dsn: dsn,
DisableClientReports: false,
Expand All @@ -50,8 +50,8 @@ func TestClientReports_Integration(t *testing.T) {
if err != nil {
t.Fatalf("Init failed: %v", err)
}
hub.BindClient(c)
defer hub.Flush(testutils.FlushTimeout())
ctx, _ := WithScope(context.Background())
defer c.Flush(testutils.FlushTimeout())

// second client with disabled reports shouldn't affect the first
_, _ = NewClient(ClientOptions{
Expand All @@ -60,21 +60,18 @@ func TestClientReports_Integration(t *testing.T) {
})

// simulate dropped events for report outcomes
hub.CaptureMessage("drop-me")
scope := NewScope()
scope.AddEventProcessor(func(event *Event, _ *EventHint) *Event {
c.CaptureMessage(ctx, "drop-me")
processorCtx, processorScope := WithScope(ctx)
processorScope.AddEventProcessor(func(event *Event, _ *EventHint) *Event {
if event.Message == "processor-drop" {
return nil
}
return event
})
hub.WithScope(func(s *Scope) {
s.eventProcessors = scope.eventProcessors
hub.CaptureMessage("processor-drop")
})
c.CaptureMessage(processorCtx, "processor-drop")

hub.CaptureMessage("hi") // send an event to capture the report along with it
if !hub.Flush(testutils.FlushTimeout()) {
c.CaptureMessage(ctx, "hi") // send an event to capture the report along with it
if !c.Flush(testutils.FlushTimeout()) {
t.Fatal("Flush timed out")
}

Expand Down
20 changes: 5 additions & 15 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import (
"github.com/stretchr/testify/require"
)

const testDsn = "https://whatever@sentry.io/1337"

func TestNewClientAllowsEmptyDSN(t *testing.T) {
transport := &MockTransport{}
client, err := NewClient(ClientOptions{
Expand Down Expand Up @@ -71,6 +73,7 @@ func TestNoopClient(t *testing.T) {
{"message", func() *EventID { return first.CaptureMessage(context.Background(), "message") }},
{"exception", func() *EventID { return first.CaptureException(context.Background(), errors.New("exception")) }},
{"event", func() *EventID { return first.CaptureEvent(context.Background(), &Event{Message: "event"}) }},
{"nil event", func() *EventID { return CaptureEvent(ContextWithClient(context.Background(), first), nil) }},
{"check-in", func() *EventID {
return first.CaptureCheckIn(context.Background(), &CheckIn{MonitorSlug: "cron", Status: CheckInStatusOK}, nil)
}},
Expand Down Expand Up @@ -281,17 +284,6 @@ func TestWithScopeClonesParentTrace(t *testing.T) {
assert.Equal(t, parent.propagationContextSnapshot().TraceID, transport.Events()[0].Contexts["trace"][traceIDContextKey])
}

func TestWithScopeInheritsActiveTransaction(t *testing.T) {
client, transport := newCaptureTestClient(t, ClientOptions{EnableTracing: true})
transaction := StartTransaction(ContextWithClient(context.Background(), client), "transaction")
t.Cleanup(transaction.Finish)

ctx, _ := WithScope(transaction.Context())
require.NotNil(t, CaptureMessage(ctx, "child"))
require.Len(t, transport.Events(), 1)
assert.Equal(t, transaction.TraceID, transport.Events()[0].Contexts["trace"][traceIDContextKey])
}

func TestCaptureMessageCopiesHintAndUsesContext(t *testing.T) {
type key struct{}
providedCtx := context.WithValue(context.Background(), key{}, "provided")
Expand Down Expand Up @@ -1304,8 +1296,7 @@ func TestSampleRate(t *testing.T) {
total uint64
sampled uint64
)
// Call sample from multiple goroutines just like multiple hubs
// sharing a client would. This should help uncover data races.
// Call sample from multiple goroutines sharing a client to uncover data races.
var wg sync.WaitGroup
for i := 0; i < 4; i++ {
wg.Add(1)
Expand Down Expand Up @@ -1804,10 +1795,9 @@ func TestClient_MultiClientSetup(t *testing.T) {
require.Equal(t, want, creatorTransport.Events()[0].sdkMetaData.dsc)
})
t.Run("unbound transaction follows later Init with frozen DSC", func(t *testing.T) {
previousClient, previousHubClient := globalClientSnapshot(), CurrentHub().Client()
previousClient := globalClientSnapshot()
t.Cleanup(func() {
setGlobalClient(previousClient)
CurrentHub().BindClient(previousHubClient)
})
initClient := func(release string, transport *MockTransport) {
require.NoError(t, Init(ClientOptions{
Expand Down
1 change: 1 addition & 0 deletions cron/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ require (

require (
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
golang.org/x/sys v0.48.0 // indirect
Expand Down
3 changes: 2 additions & 1 deletion cron/sentrycron.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package sentrycron

import (
"context"
"os"
"path/filepath"
"runtime"
Expand All @@ -25,7 +26,7 @@ import (
func AddFunc(c *cron.Cron, spec, slug string, fn func() error, config *sentry.MonitorConfig) (cron.EntryID, error) {
monitorConfig := newMonitorConfig(spec, c.Location(), config)
return c.AddFunc(spec, func() {
_ = sentry.WithMonitor(slug, monitorConfig, fn)
_ = sentry.WithMonitor(context.Background(), slug, monitorConfig, fn)
Comment thread
giortzisg marked this conversation as resolved.
})
}

Expand Down
12 changes: 4 additions & 8 deletions cron/sentrycron_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"time"

"github.com/getsentry/sentry-go"
"github.com/getsentry/sentry-go/internal/sentrytest"
"github.com/robfig/cron/v3"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -66,20 +67,15 @@ func TestNewMonitorConfig(t *testing.T) {
}

func TestAddFunc(t *testing.T) {
transport := &sentry.MockTransport{}
client, err := sentry.NewClient(sentry.ClientOptions{Transport: transport})
require.NoError(t, err)
hub := sentry.CurrentHub()
previous := hub.Client()
t.Cleanup(func() { hub.BindClient(previous) })
hub.BindClient(client)
f := sentrytest.NewFixture(t, sentrytest.WithGlobal())

c := cron.New(cron.WithLocation(time.UTC))
id, err := AddFunc(c, "0 3 * * *", "nightly", func() error { return errors.New("failed") }, nil)
require.NoError(t, err)
c.Entry(id).Job.Run()

events := transport.Events()
f.Flush()
events := f.Events()
require.Len(t, events, 2)
assert.Equal(t, sentry.CheckInStatusInProgress, events[0].CheckIn.Status)
assert.Equal(t, sentry.CrontabSchedule("0 3 * * *"), events[0].MonitorConfig.Schedule)
Expand Down
1 change: 0 additions & 1 deletion fasthttp/sentryfasthttp.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ func (h *Handler) Handle(handler fasthttp.RequestHandler) fasthttp.RequestHandle
}()
}
storedCtx.ctx = requestCtx
r = r.WithContext(requestCtx)

scope.SetRequest(r)
scope.SetRequestBody(bytes.Clone(ctx.Request.Body()))
Expand Down
1 change: 0 additions & 1 deletion fiber/sentryfiber.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ func (h *handler) handle(ctx *fiber.Ctx) error {
}
storedCtx.ctx = requestCtx
ctx.SetUserContext(requestCtx)
r = r.WithContext(requestCtx)

scope.SetRequest(r)
scope.SetRequestBody(bytes.Clone(ctx.Request().Body()))
Expand Down
1 change: 0 additions & 1 deletion fiberv3/sentryfiber.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ func (h *handler) handle(ctx fiber.Ctx) error {
}
storedCtx.ctx = requestCtx
ctx.SetContext(requestCtx)
r = r.WithContext(requestCtx)

scope.SetRequest(r)
scope.SetRequestBody(bytes.Clone(ctx.Body()))
Expand Down
Loading
Loading