Skip to content
This repository was archived by the owner on Apr 2, 2024. It is now read-only.

Commit 988bf3c

Browse files
committed
Add main package unit tests
These tests cover most of the basic declaritive logic of the main package. Some of the functions require a DB to be fully tested, to test them would require major refactorings of the project so they are out-of-scope for this commit.
1 parent 88f19a0 commit 988bf3c

File tree

2 files changed

+610
-26
lines changed

2 files changed

+610
-26
lines changed

cmd/timescale-prometheus/main.go

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,16 @@ func main() {
137137

138138
http.Handle(cfg.telemetryPath, promhttp.Handler())
139139

140-
elector = initElector(cfg)
140+
elector, err = initElector(cfg)
141+
142+
if err != nil {
143+
log.Error("msg", err.Error())
144+
os.Exit(1)
145+
}
146+
147+
if elector == nil {
148+
log.Warn("msg", "No adapter leader election. Group lock id is not set. Possible duplicate write load if running adapter in high-availability mode")
149+
}
141150

142151
// migrate has to happen after elector started
143152
if cfg.migrate {
@@ -153,8 +162,8 @@ func main() {
153162
}
154163
defer client.Close()
155164

156-
http.Handle("/write", timeHandler("write", write(client)))
157-
http.Handle("/read", timeHandler("read", read(client)))
165+
http.Handle("/write", timeHandler(httpRequestDuration, "write", write(client)))
166+
http.Handle("/read", timeHandler(httpRequestDuration, "read", read(client)))
158167
http.Handle("/healthz", health(client))
159168

160169
log.Info("msg", "Starting up...")
@@ -189,26 +198,22 @@ func parseFlags() *config {
189198
return cfg
190199
}
191200

192-
func initElector(cfg *config) *util.Elector {
201+
func initElector(cfg *config) (*util.Elector, error) {
193202
if cfg.restElection && cfg.haGroupLockID != 0 {
194-
log.Error("msg", "Use either REST or PgAdvisoryLock for the leader election")
195-
os.Exit(1)
203+
return nil, fmt.Errorf("Use either REST or PgAdvisoryLock for the leader election")
196204
}
197205
if cfg.restElection {
198-
return util.NewElector(util.NewRestElection())
206+
return util.NewElector(util.NewRestElection()), nil
199207
}
200208
if cfg.haGroupLockID == 0 {
201-
log.Warn("msg", "No adapter leader election. Group lock id is not set. Possible duplicate write load if running adapter in high-availability mode")
202-
return nil
209+
return nil, nil
203210
}
204211
if cfg.prometheusTimeout == -1 {
205-
log.Error("msg", "Prometheus timeout configuration must be set when using PG advisory lock")
206-
os.Exit(1)
212+
return nil, fmt.Errorf("Prometheus timeout configuration must be set when using PG advisory lock")
207213
}
208214
lock, err := util.NewPgAdvisoryLock(cfg.haGroupLockID, cfg.pgmodelCfg.GetConnectionStr())
209215
if err != nil {
210-
log.Error("msg", "Error creating advisory lock", "haGroupLockId", cfg.haGroupLockID, "err", err)
211-
os.Exit(1)
216+
return nil, fmt.Errorf("Error creating advisory lock\nhaGroupLockId: %d\nerr: %s\n", cfg.haGroupLockID, err)
212217
}
213218
scheduledElector := util.NewScheduledElector(lock, cfg.electionInterval)
214219
log.Info("msg", "Initialized leader election based on PostgreSQL advisory lock")
@@ -221,7 +226,7 @@ func initElector(cfg *config) *util.Elector {
221226
}
222227
}()
223228
}
224-
return &scheduledElector.Elector
229+
return &scheduledElector.Elector, nil
225230
}
226231

227232
func migrate(cfg *pgclient.Config) {
@@ -261,15 +266,6 @@ func migrate(cfg *pgclient.Config) {
261266

262267
func write(writer pgmodel.DBInserter) http.Handler {
263268
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
264-
compressed, err := ioutil.ReadAll(r.Body)
265-
if err != nil {
266-
log.Error("msg", "Read error", "err", err.Error())
267-
http.Error(w, err.Error(), http.StatusInternalServerError)
268-
return
269-
}
270-
271-
atomic.StoreInt64(&lastRequestUnixNano, time.Now().UnixNano())
272-
273269
shouldWrite, err := isWriter()
274270
if err != nil {
275271
leaderGauge.Set(0)
@@ -283,6 +279,16 @@ func write(writer pgmodel.DBInserter) http.Handler {
283279
}
284280

285281
leaderGauge.Set(1)
282+
283+
compressed, err := ioutil.ReadAll(r.Body)
284+
if err != nil {
285+
log.Error("msg", "Read error", "err", err.Error())
286+
http.Error(w, err.Error(), http.StatusInternalServerError)
287+
return
288+
}
289+
290+
atomic.StoreInt64(&lastRequestUnixNano, time.Now().UnixNano())
291+
286292
reqBuf, err := snappy.Decode(nil, compressed)
287293
if err != nil {
288294
log.Error("msg", "Decode error", "err", err.Error())
@@ -310,6 +316,7 @@ func write(writer pgmodel.DBInserter) http.Handler {
310316
numSamples, err := writer.Ingest(req.GetTimeseries())
311317
if err != nil {
312318
log.Warn("msg", "Error sending samples to remote storage", "err", err, "num_samples", numSamples)
319+
http.Error(w, err.Error(), http.StatusInternalServerError)
313320
failedSamples.Add(float64(receivedBatchCount))
314321
return
315322
}
@@ -415,12 +422,12 @@ func health(hc pgmodel.HealthChecker) http.Handler {
415422
}
416423

417424
// timeHandler uses Prometheus histogram to track request time
418-
func timeHandler(path string, handler http.Handler) http.Handler {
425+
func timeHandler(histogramVec prometheus.ObserverVec, path string, handler http.Handler) http.Handler {
419426
f := func(w http.ResponseWriter, r *http.Request) {
420427
start := time.Now()
421428
handler.ServeHTTP(w, r)
422-
elapsedMs := time.Since(start).Nanoseconds() / int64(time.Millisecond)
423-
httpRequestDuration.WithLabelValues(path).Observe(float64(elapsedMs))
429+
elapsedMs := time.Since(start).Milliseconds()
430+
histogramVec.WithLabelValues(path).Observe(float64(elapsedMs))
424431
}
425432
return http.HandlerFunc(f)
426433
}

0 commit comments

Comments
 (0)