ingress-nginx-helm/internal/ingress/metric/collectors/process_test.go
Thibault Jamet 27a98f2920
Fix race condition in metric process collector test
There was a goroutine started to log things upon a test that could be
ended at the time `cmd.Wait()` ends.

To solve the problem, when the sub-test ends, ensure we wait until the
command ends when ending the test

The output of `make test` before the fix shows:

```
=== RUN   TestNewUDPLogListener
==================
WARNING: DATA RACE
Read at 0x00c0002a8643 by goroutine 74:
  testing.(*common).logDepth()
      /usr/local/go/src/testing/testing.go:629 +0x132
  testing.(*common).Logf()
      /usr/local/go/src/testing/testing.go:614 +0x90
  k8s.io/ingress-nginx/internal/ingress/metric/collectors.TestProcessCollector.func1.1()
      /go/src/k8s.io/ingress-nginx/internal/ingress/metric/collectors/process_test.go:54 +0x140

Previous write at 0x00c0002a8643 by goroutine 72:
  testing.tRunner.func1()
      /usr/local/go/src/testing/testing.go:856 +0x33e
  testing.tRunner()
      /usr/local/go/src/testing/testing.go:869 +0x17f

Goroutine 74 (running) created at:
  k8s.io/ingress-nginx/internal/ingress/metric/collectors.TestProcessCollector.func1()
      /go/src/k8s.io/ingress-nginx/internal/ingress/metric/collectors/process_test.go:50 +0x218
  testing.tRunner()
      /usr/local/go/src/testing/testing.go:865 +0x163

Goroutine 72 (finished) created at:
  testing.(*T).Run()
      /usr/local/go/src/testing/testing.go:916 +0x699
  testing.runTests.func1()
      /usr/local/go/src/testing/testing.go:1157 +0xa8
  testing.tRunner()
      /usr/local/go/src/testing/testing.go:865 +0x163
  testing.runTests()
      /usr/local/go/src/testing/testing.go:1155 +0x523
  testing.(*M).Run()
      /usr/local/go/src/testing/testing.go:1072 +0x2eb
  main.main()
      _testmain.go:52 +0x222
==================
--- PASS: TestNewUDPLogListener (0.00s)
```

after the patch:

```
=== RUN   TestNewUDPLogListener
--- PASS: TestNewUDPLogListener (0.01s)
```

Change-Id: I8ea246d14f5f80b330be19dd5b8299c6762f6d6b
2019-03-04 21:54:42 +01:00

96 lines
2.1 KiB
Go

/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package collectors
import (
"os/exec"
"syscall"
"testing"
"github.com/prometheus/client_golang/prometheus"
)
func TestProcessCollector(t *testing.T) {
cases := []struct {
name string
metrics []string
}{
{
name: "should return metrics",
metrics: []string{"nginx_ingress_controller_nginx_process_num_procs"},
},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
name = "sleep"
binary = "/bin/sleep"
cmd := exec.Command(binary, "1000000")
err := cmd.Start()
if err != nil {
t.Errorf("unexpected error creating dummy process: %v", err)
}
done := make(chan struct{})
go func() {
cmd.Wait()
status := cmd.ProcessState.Sys().(syscall.WaitStatus)
if status.Signaled() {
t.Logf("Signal: %v", status.Signal())
} else {
t.Logf("Status: %v", status.ExitStatus())
}
done <- struct{}{}
}()
cm, err := NewNGINXProcess("pod", "default", "nginx")
if err != nil {
t.Errorf("unexpected error creating nginx status collector: %v", err)
t.FailNow()
}
go cm.Start()
defer func() {
cm.Stop()
cmd.Process.Kill()
<-done
close(done)
}()
reg := prometheus.NewPedanticRegistry()
if err := reg.Register(cm); err != nil {
t.Errorf("registering collector failed: %s", err)
}
metrics, err := reg.Gather()
if err != nil {
t.Errorf("gathering metrics failed: %s", err)
}
m := filterMetrics(metrics, c.metrics)
if *m[0].GetMetric()[0].Gauge.Value < 0 {
t.Errorf("number of process should be > 0")
}
reg.Unregister(cm)
})
}
}