Skip to content

Commit

Permalink
Test: Checks for deadlocks panics in logs per each test.
Browse files Browse the repository at this point in the history
This commit make sure that there is no panic or deadlocks in cilium logs
after executed the test.

The test uses `CurrentGinkgoTestDescription().Duration` to know the
current duration of the test, so the helper only search in the logs
files since test starts. (In case of any panic in log, it'll not mark
all test as failed)

The panic string example is:

```
Mar 15 16:35:50 runtime cilium-agent[8220]: panic: runtime error: invalid memory address or nil pointer dereference
Mar 15 16:35:50 runtime cilium-agent[8220]: [signal SIGSEGV: segmentation violation code=0x1 addr=0x2 pc=0x17e3b2c]
Mar 15 16:35:50 runtime cilium-agent[8220]: goroutine 58384 [running]:
```

The deadlock string example is:
```
Jan 03 00:40:09 cilium-master cilium-agent[32439]: POTENTIAL DEADLOCK:
Jan 03 00:40:09 cilium-master cilium-agent[32439]: Previous place where the lock was grabbed
Jan 03 00:40:09 cilium-master cilium-agent[32439]: goroutine 8974 lock 0xc4201b875c
```

Signed-off-by: Eloy Coto <eloy.coto@gmail.com>
  • Loading branch information
eloycoto authored and raybejjani committed Mar 21, 2018
1 parent b5c17fd commit 5185789
Show file tree
Hide file tree
Showing 45 changed files with 399 additions and 234 deletions.
16 changes: 16 additions & 0 deletions test/helpers/cilium.go
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/cilium/cilium/pkg/logging/logfields"

"github.com/onsi/ginkgo"
"github.com/onsi/gomega"
"github.com/sirupsen/logrus"
)

Expand Down Expand Up @@ -527,6 +528,21 @@ func (s *SSHMeta) ReportFailed(commands ...string) {
fmt.Fprint(wr, "===================== EXITING REPORT GENERATION =====================\n")
}

// ValidateNoErrorsOnLogs checks in cilium logs since the given duration (By
// default `CurrentGinkgoTestDescription().Duration`) that no `panic` messages
// or `deadlocks`. In case of any of these messages, it'll mark the test as
// failed.
func (s *SSHMeta) ValidateNoErrorsOnLogs(duration time.Duration) {
logsCmd := fmt.Sprintf(`sudo journalctl -au %s --since '%v seconds ago'`,
DaemonName, duration.Seconds())
logs := s.Exec(logsCmd).Output().String()

gomega.ExpectWithOffset(1, logs).ToNot(gomega.ContainSubstring("panic: "),
"Found a panic in Cilium logs")
gomega.ExpectWithOffset(1, logs).ToNot(gomega.ContainSubstring(deadLockHeader),
"Found a deadlock in Cilium logs")
}

// CheckLogsForDeadlock checks if the logs for Cilium log messages that signify
// that a deadlock has occurred.
func (s *SSHMeta) CheckLogsForDeadlock() {
Expand Down
2 changes: 2 additions & 0 deletions test/helpers/cons.go
Expand Up @@ -154,6 +154,8 @@ const (

StableImage = "cilium/cilium:stable"
configMap = "ConfigMap"

deadLockHeader = "POTENTIAL DEADLOCK:" // from github.com/sasha-s/go-deadlock/deadlock.go:header
)

var ciliumCLICommands = map[string]string{
Expand Down
19 changes: 19 additions & 0 deletions test/helpers/kubectl.go
Expand Up @@ -33,6 +33,7 @@ import (

"github.com/asaskevich/govalidator"
"github.com/onsi/ginkgo"
"github.com/onsi/gomega"
"github.com/sirupsen/logrus"
"golang.org/x/crypto/ssh"
"k8s.io/api/core/v1"
Expand Down Expand Up @@ -777,6 +778,24 @@ func (kub *Kubectl) CiliumReport(namespace string, pod string, commands ...[]str

}

// ValidateNoErrorsOnLogs checks in cilium logs since the given duration (By
// default `CurrentGinkgoTestDescription().Duration`) that no `panic` messages
// or `deadlocks`. In case of any of these messages, it'll mark the test as
// failed.
func (kub *Kubectl) ValidateNoErrorsOnLogs(duration time.Duration) {
cmd := fmt.Sprintf("%s -n %s logs --timestamps=true -l k8s-app=cilium --since=%vs",
KubectlCmd, KubeSystemNamespace, duration.Seconds())
res := kub.Exec(fmt.Sprintf("%s --previous", cmd))
if !res.WasSuccessful() {
res = kub.Exec(cmd)
}
logs := res.Output().String()
gomega.ExpectWithOffset(1, logs).ToNot(gomega.ContainSubstring("panic: "),
"Found a panic in Cilium logs")
gomega.ExpectWithOffset(1, logs).ToNot(gomega.ContainSubstring(deadLockHeader),
"Found a deadlock in Cilium logs")
}

// CheckLogsForDeadlock checks if the logs for Cilium log messages that signify
// that a deadlock has occurred.
func (kub *Kubectl) CheckLogsForDeadlock() {
Expand Down
1 change: 1 addition & 0 deletions test/k8sT/Chaos.go
Expand Up @@ -61,6 +61,7 @@ var _ = Describe("K8sValidatedChaosTest", func() {
})

AfterEach(func() {
kubectl.ValidateNoErrorsOnLogs(CurrentGinkgoTestDescription().Duration)
if CurrentGinkgoTestDescription().Failed {
ciliumPod, _ := kubectl.GetCiliumPodOnNode(
helpers.KubeSystemNamespace, helpers.K8s1VMName())
Expand Down
1 change: 1 addition & 0 deletions test/k8sT/Health.go
Expand Up @@ -48,6 +48,7 @@ var _ = Describe(testName, func() {
})

AfterEach(func() {
kubectl.ValidateNoErrorsOnLogs(CurrentGinkgoTestDescription().Duration)
if CurrentGinkgoTestDescription().Failed {
ciliumPod, _ := kubectl.GetCiliumPodOnNode("kube-system", "k8s1")
kubectl.CiliumReport("kube-system", ciliumPod, []string{
Expand Down
1 change: 1 addition & 0 deletions test/k8sT/KafkaPolicies.go
Expand Up @@ -95,6 +95,7 @@ var _ = Describe("K8sValidatedKafkaPolicyTest", func() {
})

AfterEach(func() {
kubectl.ValidateNoErrorsOnLogs(CurrentGinkgoTestDescription().Duration)
if CurrentGinkgoTestDescription().Failed {
ciliumPod, _ := kubectl.GetCiliumPodOnNode(helpers.KubeSystemNamespace, helpers.K8s1)
kubectl.CiliumReport(helpers.KubeSystemNamespace, ciliumPod, []string{
Expand Down
3 changes: 3 additions & 0 deletions test/k8sT/Nightly.go
Expand Up @@ -80,6 +80,7 @@ var _ = Describe("NightlyEpsMeasurement", func() {
})

AfterEach(func() {
kubectl.ValidateNoErrorsOnLogs(CurrentGinkgoTestDescription().Duration)
if CurrentGinkgoTestDescription().Failed {
ciliumPod, _ := kubectl.GetCiliumPodOnNode(helpers.KubeSystemNamespace, helpers.K8s1)
kubectl.CiliumReport(helpers.KubeSystemNamespace, ciliumPod, []string{
Expand Down Expand Up @@ -291,6 +292,7 @@ var _ = Describe("NightlyEpsMeasurement", func() {
}

It("Test TCP Keepalive with L7 Policy", func() {
kubectl.ValidateNoErrorsOnLogs(CurrentGinkgoTestDescription().Duration)
manifest := kubectl.ManifestGet(netcatDsManifest)
kubectl.Apply(manifest).ExpectSuccess("Cannot apply netcat ds")
defer kubectl.Delete(manifest)
Expand Down Expand Up @@ -348,6 +350,7 @@ var _ = Describe("NightlyExamples", func() {
})

AfterEach(func() {
kubectl.ValidateNoErrorsOnLogs(CurrentGinkgoTestDescription().Duration)
if CurrentGinkgoTestDescription().Failed {
ciliumPod, _ := kubectl.GetCiliumPodOnNode(helpers.KubeSystemNamespace, helpers.K8s1)
kubectl.CiliumReport(helpers.KubeSystemNamespace, ciliumPod, []string{
Expand Down
2 changes: 2 additions & 0 deletions test/k8sT/Policies.go
Expand Up @@ -81,6 +81,7 @@ var _ = Describe("K8sValidatedPolicyTest", func() {
})

AfterEach(func() {
kubectl.ValidateNoErrorsOnLogs(CurrentGinkgoTestDescription().Duration)
if CurrentGinkgoTestDescription().Failed {
ciliumPod, _ := kubectl.GetCiliumPodOnNode(helpers.KubeSystemNamespace, helpers.K8s1)
kubectl.CiliumReport(helpers.KubeSystemNamespace, ciliumPod, []string{
Expand Down Expand Up @@ -719,6 +720,7 @@ var _ = Describe("K8sValidatedPolicyTestAcrossNamespaces", func() {
})

AfterEach(func() {
kubectl.ValidateNoErrorsOnLogs(CurrentGinkgoTestDescription().Duration)
if CurrentGinkgoTestDescription().Failed {
ciliumPod, _ := kubectl.GetCiliumPodOnNode(helpers.KubeSystemNamespace, helpers.K8s1)
kubectl.CiliumReport(helpers.KubeSystemNamespace, ciliumPod, []string{
Expand Down
1 change: 1 addition & 0 deletions test/k8sT/PoliciesNightly.go
Expand Up @@ -51,6 +51,7 @@ var _ = Describe("NightlyPolicies", func() {
})

AfterEach(func() {
kubectl.ValidateNoErrorsOnLogs(CurrentGinkgoTestDescription().Duration)
if CurrentGinkgoTestDescription().Failed {
ciliumPod, _ := kubectl.GetCiliumPodOnNode(helpers.KubeSystemNamespace, "k8s1")
kubectl.CiliumReport("kube-system", ciliumPod, []string{
Expand Down
1 change: 1 addition & 0 deletions test/k8sT/Services.go
Expand Up @@ -61,6 +61,7 @@ var _ = Describe("K8sValidatedServicesTest", func() {
})

AfterEach(func() {
kubectl.ValidateNoErrorsOnLogs(CurrentGinkgoTestDescription().Duration)
if CurrentGinkgoTestDescription().Failed {
ciliumPod, _ := kubectl.GetCiliumPodOnNode("kube-system", "k8s1")
kubectl.CiliumReport("kube-system", ciliumPod, []string{
Expand Down
1 change: 1 addition & 0 deletions test/k8sT/Tunnels.go
Expand Up @@ -52,6 +52,7 @@ var _ = Describe("K8sValidatedTunnelTest", func() {
}, 600)

AfterEach(func() {
kubectl.ValidateNoErrorsOnLogs(CurrentGinkgoTestDescription().Duration)
if CurrentGinkgoTestDescription().Failed {
ciliumPod, _ := kubectl.GetCiliumPodOnNode(helpers.KubeSystemNamespace, helpers.K8s1)
kubectl.CiliumReport(helpers.KubeSystemNamespace, ciliumPod, []string{
Expand Down
9 changes: 8 additions & 1 deletion test/k8sT/Updates.go
Expand Up @@ -48,7 +48,14 @@ var _ = Describe("DisabledK8sValidatedUpdates", func() {
}

AfterEach(func() {

kubectl.ValidateNoErrorsOnLogs(CurrentGinkgoTestDescription().Duration)
if CurrentGinkgoTestDescription().Failed {
ciliumPod, _ := kubectl.GetCiliumPodOnNode(
helpers.KubeSystemNamespace, helpers.K8s1VMName())
kubectl.CiliumReport("kube-system", ciliumPod, []string{
"cilium service list",
"cilium endpoint list"})
}
//This policies maybe are not loaded, (Test failed before) so no assert here.
kubectl.Delete(l7Policy)
kubectl.Delete(l3Policy)
Expand Down
2 changes: 1 addition & 1 deletion test/k8sT/demos.go
Expand Up @@ -77,8 +77,8 @@ var _ = Describe(demoTestName, func() {
})

AfterEach(func() {
kubectl.ValidateNoErrorsOnLogs(CurrentGinkgoTestDescription().Duration)
if CurrentGinkgoTestDescription().Failed {
log.Debugf("======================== TEST FAILED ======================== ")
ciliumPod, _ := kubectl.GetCiliumPodOnNode(helpers.KubeSystemNamespace, helpers.K8s1)
kubectl.CiliumReport(helpers.KubeSystemNamespace, ciliumPod)
}
Expand Down
5 changes: 5 additions & 0 deletions test/runtime/Policies.go
Expand Up @@ -75,6 +75,8 @@ var _ = Describe("RuntimeValidatedPolicyEnforcement", func() {
})

AfterEach(func() {
vm.ValidateNoErrorsOnLogs(CurrentGinkgoTestDescription().Duration)

if CurrentGinkgoTestDescription().Failed {
vm.ReportFailed()
}
Expand Down Expand Up @@ -430,6 +432,8 @@ var _ = Describe("RuntimeValidatedPolicies", func() {
})

AfterEach(func() {
vm.ValidateNoErrorsOnLogs(CurrentGinkgoTestDescription().Duration)

if CurrentGinkgoTestDescription().Failed {
vm.ReportFailed()
}
Expand Down Expand Up @@ -1006,6 +1010,7 @@ var _ = Describe("RuntimeValidatedPolicyImportTests", func() {
})

AfterEach(func() {
vm.ValidateNoErrorsOnLogs(CurrentGinkgoTestDescription().Duration)
if CurrentGinkgoTestDescription().Failed {
vm.ReportFailed()
}
Expand Down
1 change: 1 addition & 0 deletions test/runtime/chaos.go
Expand Up @@ -47,6 +47,7 @@ var _ = Describe("RuntimeValidatedChaos", func() {
})

AfterEach(func() {
vm.ValidateNoErrorsOnLogs(CurrentGinkgoTestDescription().Duration)
if CurrentGinkgoTestDescription().Failed {
vm.ReportFailed()
}
Expand Down
1 change: 1 addition & 0 deletions test/runtime/cli.go
Expand Up @@ -47,6 +47,7 @@ var _ = Describe("RuntimeValidatedCLI", func() {
})

AfterEach(func() {
vm.ValidateNoErrorsOnLogs(CurrentGinkgoTestDescription().Duration)
if CurrentGinkgoTestDescription().Failed {
vm.ReportFailed("cilium endpoint list")
}
Expand Down
2 changes: 2 additions & 0 deletions test/runtime/connectivity.go
Expand Up @@ -38,6 +38,7 @@ var _ = Describe("RuntimeValidatedConnectivityTest", func() {
}

AfterEach(func() {
vm.ValidateNoErrorsOnLogs(CurrentGinkgoTestDescription().Duration)
if CurrentGinkgoTestDescription().Failed {
vm.ReportFailed()
}
Expand Down Expand Up @@ -485,6 +486,7 @@ var _ = Describe("RuntimeValidatedConntrackTest", func() {
})

AfterEach(func() {
vm.ValidateNoErrorsOnLogs(CurrentGinkgoTestDescription().Duration)
if CurrentGinkgoTestDescription().Failed {
vm.ReportFailed()
}
Expand Down
2 changes: 2 additions & 0 deletions test/runtime/ct.go
Expand Up @@ -126,6 +126,8 @@ var _ = Describe("RuntimeDisabledValidatedConntrackTable", func() {
})

AfterEach(func() {

vm.ValidateNoErrorsOnLogs(CurrentGinkgoTestDescription().Duration)
if CurrentGinkgoTestDescription().Failed {
vm.ReportFailed(
"sudo cilium bpf ct list global",
Expand Down
2 changes: 2 additions & 0 deletions test/runtime/examples.go
Expand Up @@ -44,6 +44,8 @@ var _ = Describe("RuntimeValidatedPolicyValidationTests", func() {
})

AfterEach(func() {

vm.ValidateNoErrorsOnLogs(CurrentGinkgoTestDescription().Duration)
if CurrentGinkgoTestDescription().Failed {
vm.ReportFailed()
}
Expand Down
1 change: 1 addition & 0 deletions test/runtime/kafka.go
Expand Up @@ -112,6 +112,7 @@ var _ = Describe("RuntimeValidatedKafka", func() {
})

AfterEach(func() {
vm.ValidateNoErrorsOnLogs(CurrentGinkgoTestDescription().Duration)
if CurrentGinkgoTestDescription().Failed {
vm.ReportFailed()
}
Expand Down
1 change: 1 addition & 0 deletions test/runtime/kvstore.go
Expand Up @@ -54,6 +54,7 @@ var _ = Describe("RuntimeValidatedKVStoreTest", func() {
}, 150)

AfterEach(func() {
vm.ValidateNoErrorsOnLogs(CurrentGinkgoTestDescription().Duration)
if CurrentGinkgoTestDescription().Failed {
vm.ReportFailed(
"sudo docker ps -a",
Expand Down

0 comments on commit 5185789

Please sign in to comment.