• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pace / bricks / 11250208184

09 Oct 2024 07:25AM UTC coverage: 57.466% (-13.7%) from 71.177%
11250208184

push

github

web-flow
Merge pull request #380 from pace/sentry-tracing-poc

tracing: replace Jaeger with Sentry

140 of 206 new or added lines in 19 files covered. (67.96%)

3 existing lines in 3 files now uncovered.

5515 of 9597 relevant lines covered (57.47%)

21.77 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/tools/testserver/main.go
1
// Copyright © 2018 by PACE Telematics GmbH. All rights reserved.
2

3
package main
4

5
import (
6
        "context"
7
        "encoding/json"
8
        "fmt"
9
        "net/http"
10
        "time"
11

12
        "github.com/getsentry/sentry-go"
13
        "github.com/pace/bricks/grpc"
14
        "github.com/pace/bricks/http/security"
15
        "github.com/pace/bricks/http/transport"
16
        "github.com/pace/bricks/locale"
17

18
        "github.com/pace/bricks/maintenance/failover"
19
        "github.com/pace/bricks/maintenance/health/servicehealthcheck"
20

21
        "github.com/pace/bricks/backend/couchdb"
22
        "github.com/pace/bricks/backend/objstore"
23
        "github.com/pace/bricks/backend/postgres"
24
        "github.com/pace/bricks/backend/redis"
25
        pacehttp "github.com/pace/bricks/http"
26
        "github.com/pace/bricks/http/oauth2"
27
        "github.com/pace/bricks/maintenance/errors"
28
        "github.com/pace/bricks/maintenance/log"
29
        _ "github.com/pace/bricks/maintenance/tracing"
30
        "github.com/pace/bricks/test/livetest"
31
        "github.com/pace/bricks/tools/testserver/math"
32
        simple "github.com/pace/bricks/tools/testserver/simple"
33
)
34

35
// pace lat/lon
36
var (
37
        lat = 49.012553
38
        lon = 8.427087
39
)
40

41
type OauthBackend struct{}
42

43
func (*OauthBackend) IntrospectToken(ctx context.Context, token string) (*oauth2.IntrospectResponse, error) {
×
44
        return &oauth2.IntrospectResponse{
×
45
                Active:   true,
×
46
                ClientID: "some client",
×
47
                Scope:    "email profile",
×
48
                UserID:   "285ec1fc-2843-4ed8-bfa8-4217880c8348",
×
49
        }, nil
×
50
}
×
51

52
type TestService struct{}
53

54
func (*TestService) GetTest(ctx context.Context, w simple.GetTestResponseWriter, r *simple.GetTestRequest) error {
×
55
        log.Debug("Request in flight, this will wait 5 min....")
×
56
        for t := 0; t < 360; t++ {
×
57
                select {
×
58
                case <-ctx.Done():
×
59
                        return ctx.Err()
×
60
                default:
×
61
                        time.Sleep(time.Second)
×
62
                }
63
        }
64
        return nil
×
65
}
66

67
func main() {
×
68
        db := postgres.DefaultConnectionPool()
×
69
        rdb := redis.Client()
×
70
        cdb, err := couchdb.DefaultDatabase()
×
71
        if err != nil {
×
72
                log.Fatal(err)
×
73
        }
×
74
        _, err = objstore.Client()
×
75
        if err != nil {
×
76
                log.Fatal(err)
×
77
        }
×
78

79
        ap, err := failover.NewActivePassive("testserver", time.Second*10, rdb)
×
80
        if err != nil {
×
81
                log.Fatal(err)
×
82
        }
×
83
        go ap.Run(log.WithContext(context.Background())) // nolint: errcheck
×
84

×
85
        h := pacehttp.Router()
×
86
        servicehealthcheck.RegisterHealthCheckFunc("fail-50", func(ctx context.Context) (r servicehealthcheck.HealthCheckResult) {
×
87
                if time.Now().Unix()%2 == 0 {
×
88
                        panic("boom")
×
89
                }
90
                r.Msg = "Foo"
×
91
                r.State = servicehealthcheck.Ok
×
92
                return
×
93
        })
94

95
        h.Handle("/pay/beta/test", simple.Router(new(TestService)))
×
96

×
97
        h.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
×
NEW
98
                ctx := r.Context()
×
NEW
99

×
NEW
100
                span := sentry.StartSpan(ctx, "TestHandler")
×
NEW
101
                defer span.Finish()
×
NEW
102

×
NEW
103
                ctx = span.Context()
×
104

×
105
                // do dummy database query
×
106
                cdb := db.WithContext(ctx)
×
107
                var result struct {
×
108
                        Calc int //nolint
×
109
                }
×
110
                res, err := cdb.QueryOne(&result, `SELECT ? + ? AS Calc`, 10, 10)
×
111
                if err != nil {
×
112
                        log.Ctx(ctx).Debug().Err(err).Msg("Calc failed")
×
113
                        return
×
114
                }
×
115
                log.Ctx(ctx).Debug().Int("rows_affected", res.RowsAffected()).Msg("Calc done")
×
116

×
117
                // do dummy redis query
×
118
                crdb := redis.WithContext(ctx, rdb)
×
119
                if err := crdb.Ping(ctx).Err(); err != nil {
×
120
                        log.Ctx(ctx).Debug().Err(err).Msg("Ping failed")
×
121
                        return
×
122
                }
×
123

124
                // do dummy call to external service
125
                log.Ctx(ctx).Debug().Msg("Test before JSON")
×
126
                w.Header().Set("Content-Type", "application/json")
×
127
                fmt.Fprintf(w, `{"street":"Haid-und-Neu-Straße 18, 76131 Karlsruhe", "sunset": "%s"}`, fetchSunsetandSunrise(ctx))
×
128
        })
129

130
        h.HandleFunc("/grpc", func(rw http.ResponseWriter, r *http.Request) {
×
131
                ctx := r.Context()
×
132

×
NEW
133
                conn, err := grpc.NewClient(":3001")
×
134
                if err != nil {
×
135
                        log.Fatalf("did not connect: %s", err)
×
136
                }
×
137
                defer conn.Close()
×
138

×
139
                ctx = security.ContextWithToken(ctx, security.TokenString("test"))
×
140

×
141
                c := math.NewMathServiceClient(conn)
×
142
                o, err := c.Add(ctx, &math.Input{
×
143
                        A: 1,
×
144
                        B: 23,
×
145
                })
×
146
                if err != nil {
×
147
                        log.Ctx(ctx).Debug().Err(err).Msg("failed to add")
×
148
                        return
×
149
                }
×
150
                log.Ctx(ctx).Info().Msgf("C: %d", o.C)
×
151

×
152
                ctx = locale.WithLocale(ctx, locale.NewLocale("fr-CH", "Europe/Paris"))
×
153

×
154
                _, err = c.Add(ctx, &math.Input{})
×
155
                if err != nil {
×
156
                        log.Ctx(ctx).Debug().Err(err).Msg("failed to substract")
×
157
                        return
×
158
                }
×
159

160
                if r.URL.Query().Get("error") != "" {
×
161
                        _, err = c.Substract(ctx, &math.Input{})
×
162
                        if err != nil {
×
163
                                log.Ctx(ctx).Debug().Err(err).Msg("failed to substract")
×
164
                                return
×
165
                        }
×
166
                }
167
        })
168

169
        h.HandleFunc("/couch", func(w http.ResponseWriter, r *http.Request) {
×
170
                row := cdb.Get(r.Context(), "$health_check")
×
171
                if row.Err != nil {
×
172
                        log.Println(err)
×
173
                        w.WriteHeader(http.StatusInternalServerError)
×
174
                        return
×
175
                }
×
176
                var doc interface{}
×
177
                row.ScanDoc(&doc) // nolint: errcheck
×
178

×
179
                w.Header().Set("Content-Type", "application/json")
×
180
                json.NewEncoder(w).Encode(doc) // nolint: errcheck
×
181
        })
182

183
        h.HandleFunc("/panic", func(w http.ResponseWriter, r *http.Request) {
×
184
                go func() {
×
185
                        defer errors.HandleWithCtx(r.Context(), "Some worker")
×
186

×
187
                        panic(fmt.Errorf("Something went wrong %d - times", 100))
×
188
                }()
189

190
                panic("Test for sentry")
×
191
        })
192
        h.HandleFunc("/err", func(w http.ResponseWriter, r *http.Request) {
×
193
                errors.HandleError(errors.WrapWithExtra(errors.New("Wrap error"), map[string]interface{}{
×
194
                        "Foo": 123,
×
195
                }), "wrapHandler", w, r)
×
196
        })
×
197

198
        // Test OAuth
199
        //
200
        // This middleware is configured against an Oauth application dummy
201
        m := oauth2.NewMiddleware(new(OauthBackend)) // nolint: staticcheck
×
202

×
203
        sr := h.PathPrefix("/test").Subrouter()
×
204
        sr.Use(m.Handler)
×
205

×
206
        // To actually test the Oauth2, one can run the following as an example:
×
207
        //
×
208
        // curl -H "Authorization: Bearer 83142f1b767e910e78ba2d554b6708c371f053d13d6075bcc39766853a932253" localhost:3000/test/auth
×
209
        sr.HandleFunc("/oauth", func(w http.ResponseWriter, r *http.Request) {
×
210
                fmt.Fprintf(w, "Oauth test successful.\n")
×
211
        })
×
212

213
        s := pacehttp.Server(h)
×
214
        log.Logger().Info().Str("addr", s.Addr).Msg("Starting testserver ...")
×
215

×
216
        // nolint:errcheck
×
217
        go livetest.Test(context.Background(), []livetest.TestFunc{
×
218
                func(t *livetest.T) {
×
219
                        t.Log("Test /test query")
×
220

×
221
                        resp, err := http.Get("http://localhost:3000/test")
×
222
                        if err != nil {
×
223
                                t.Error(err)
×
224
                                t.Fail()
×
225
                                return
×
226
                        }
×
227
                        if resp.StatusCode != 200 {
×
228
                                t.Logf("Received status code: %d", resp.StatusCode)
×
229
                                t.Fail()
×
230
                        }
×
231
                },
232
        })
233

234
        log.Fatal(s.ListenAndServe())
×
235
}
236

237
func fetchSunsetandSunrise(ctx context.Context) string {
×
NEW
238
        span := sentry.StartSpan(ctx, "fetchSunsetandSunrise")
×
239
        defer span.Finish()
×
NEW
240

×
NEW
241
        ctx = span.Context()
×
NEW
242

×
NEW
243
        span.SetData("lat", lat)
×
NEW
244
        span.SetData("lon", lon)
×
245

×
246
        url := fmt.Sprintf("https://api.sunrise-sunset.org/json?lat=%f&lng=%f&date=today", lat, lon)
×
247
        req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
×
248
        if err != nil {
×
249
                log.Fatal(err)
×
250
        }
×
251

252
        c := &http.Client{
×
253
                Transport: transport.NewDefaultTransportChain(),
×
254
        }
×
255
        resp, err := c.Do(req)
×
256
        if err != nil {
×
257
                log.Fatal(err)
×
258
        }
×
259
        defer resp.Body.Close()
×
260

×
261
        var r struct {
×
262
                Results struct {
×
263
                        Sunset string `json:"sunset"`
×
264
                } `json:"results"`
×
265
        }
×
266

×
267
        err = json.NewDecoder(resp.Body).Decode(&r)
×
268
        if err != nil {
×
269
                log.Fatal(err)
×
270
        }
×
271

272
        sunset, err := time.Parse("3:04:05 PM", r.Results.Sunset)
×
273
        if err != nil {
×
274
                log.Fatal(err)
×
275
        }
×
276
        sunset = sunset.Local()
×
277

×
278
        log.Ctx(ctx).Debug().Time("sunset", sunset).Str("str", r.Results.Sunset).Msg("Parsed sunset time")
×
279
        return sunset.String()
×
280
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc