Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure errors.json with structured data is parsed #995

Merged
merged 1 commit into from
Nov 13, 2019
Merged
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
5 changes: 3 additions & 2 deletions pkg/client/results/processing.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package results

import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path"
Expand Down Expand Up @@ -270,14 +271,14 @@ func errProcessor(pluginDir string, currentFile string) (Item, error) {
defer infile.Close()

dec := json.NewDecoder(infile)
result := map[string]string{}
result := map[string]interface{}{}
if err := dec.Decode(&result); err != nil {
return resultObj, errors.Wrapf(err, "decoding file %v", currentFile)
}

// Just copy the data from the saved error file.
for k, v := range result {
resultObj.Details[k] = v
resultObj.Details[k] = fmt.Sprint(v)
}

// Surface the error to be the name of the "test" to make the error mode more visible to end users.
Expand Down
4 changes: 4 additions & 0 deletions pkg/client/results/processing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ func TestPostProcessPlugin(t *testing.T) {
desc: "Timeout errors cause timeout status",
key: "job-timeout",
plugin: getPlugin("job-timeout", "job", "junit", []string{}),
}, {
desc: "Errors can contain complex structured data",
key: "job-complex-err",
plugin: getPlugin("job-complex-err", "job", "junit", []string{}),
},
}
for _, tc := range testCases {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"error":"Container e2e is terminated state (exit code 0) due to reason: Completed: ","pod":{"metadata":{"name":"sonobuoy-e2e-job-2a1ccb8f20764fa6","namespace":"sonobuoy","selfLink":"/api/v1/namespaces/sonobuoy/pods/sonobuoy-e2e-job-2a1ccb8f20764fa6","uid":"a61eafb3-a789-4eed-9a6e-b59e7ed40f8e","resourceVersion":"783915","creationTimestamp":"2019-11-13T09:12:57Z","labels":{"component":"sonobuoy","sonobuoy-plugin":"e2e","sonobuoy-run":"2a1ccb8f20764fa6","tier":"analysis"},"annotations":{"sonobuoy-driver":"Job","sonobuoy-plugin":"e2e"},"ownerReferences":[{"apiVersion":"v1","kind":"Pod","name":"sonobuoy","uid":"ec2ac9a2-3bfb-453c-99ee-dfda0d1f75c2"}]},"spec":{"volumes":[{"name":"results","emptyDir":{}},{"name":"sonobuoy-serviceaccount-token-k245m","secret":{"secretName":"sonobuoy-serviceaccount-token-k245m","defaultMode":420}}],"containers":[{"name":"e2e","image":"gcr.io/google-containers/conformance:v1.15.3","command":["/run_e2e.sh"],"env":[{"name":"E2E_FOCUS","value":"Pods should be submitted and removed"},{"name":"E2E_SKIP"},{"name":"E2E_PARALLEL","value":"1"},{"name":"E2E_USE_GO_RUNNER","value":"true"}],"resources":{},"volumeMounts":[{"name":"results","mountPath":"/tmp/results"},{"name":"sonobuoy-serviceaccount-token-k245m","readOnly":true,"mountPath":"/var/run/secrets/kubernetes.io/serviceaccount"}],"terminationMessagePath":"/dev/termination-log","terminationMessagePolicy":"File","imagePullPolicy":"Always"},{"name":"sonobuoy-worker","image":"sonobuoy/sonobuoy:v0.16.3","command":["/sonobuoy"],"args":["worker","global","-v","5","--logtostderr"],"env":[{"name":"NODE_NAME","valueFrom":{"fieldRef":{"apiVersion":"v1","fieldPath":"spec.nodeName"}}},{"name":"RESULTS_DIR","value":"/tmp/results"},{"name":"RESULT_TYPE","value":"e2e"},{"name":"MASTER_URL","value":"https://[10.88.0.16]:8080"},{"name":"CA_CERT","value":"-----BEGIN CERTIFICATE-----\nMIIB0jCCAXigAwIBAgIBATAKBggqhkjOPQQDAjBgMQwwCgYDVQQGEwNVU0ExFjAU\nBgNVBAcTDVBhbG8gQWx0bywgQ0ExDzANBgNVBAoTBlZNd2FyZTERMA8GA1UECxMI\nU29ub2J1b3kxFDASBgNVBAMTC3Nvbm9idW95LWNhMB4XDTE5MTExMzA5MTI1N1oX\nDTE5MTExNTA5MTI1N1owYDEMMAoGA1UEBhMDVVNBMRYwFAYDVQQHEw1QYWxvIEFs\ndG8sIENBMQ8wDQYDVQQKEwZWTXdhcmUxETAPBgNVBAsTCFNvbm9idW95MRQwEgYD\nVQQDEwtzb25vYnVveS1jYTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABN0+QzRo\nYef72BU07GIczIIaHqWYgHUHr8ZqkGVeomIsOoKqiY6M6kSQUcpDHEW/5f6m8OE/\n/GoJx70div2hxnOjIzAhMA4GA1UdDwEB/wQEAwICBDAPBgNVHRMBAf8EBTADAQH/\nMAoGCCqGSM49BAMCA0gAMEUCIQDWlamkfJjZXOWp0EJZjDEdGzV+Xj44yKXKfBOO\neVp9EgIgbmREQ4WUYtg7pqv5HMMu4gd3AtIxQvOpx9Xgtevnx48=\n-----END CERTIFICATE-----\n"},{"name":"CLIENT_CERT","valueFrom":{"secretKeyRef":{"name":"sonobuoy-plugin-e2e-2a1ccb8f20764fa6","key":"tls.crt"}}},{"name":"CLIENT_KEY","valueFrom":{"secretKeyRef":{"name":"sonobuoy-plugin-e2e-2a1ccb8f20764fa6","key":"tls.key"}}},{"name":"SONOBUOY_PROGRESS_PORT","value":"8099"}],"resources":{},"volumeMounts":[{"name":"results","mountPath":"/tmp/results"},{"name":"sonobuoy-serviceaccount-token-k245m","readOnly":true,"mountPath":"/var/run/secrets/kubernetes.io/serviceaccount"}],"terminationMessagePath":"/dev/termination-log","terminationMessagePolicy":"File","imagePullPolicy":"IfNotPresent"}],"restartPolicy":"Never","terminationGracePeriodSeconds":30,"dnsPolicy":"ClusterFirst","serviceAccountName":"sonobuoy-serviceaccount","serviceAccount":"sonobuoy-serviceaccount","nodeName":"worker-1","securityContext":{},"schedulerName":"default-scheduler","tolerations":[{"key":"node-role.kubernetes.io/master","operator":"Exists","effect":"NoSchedule"},{"key":"CriticalAddonsOnly","operator":"Exists"},{"key":"kubernetes.io/e2e-evict-taint-key","operator":"Exists"},{"key":"node.kubernetes.io/not-ready","operator":"Exists","effect":"NoExecute","tolerationSeconds":300},{"key":"node.kubernetes.io/unreachable","operator":"Exists","effect":"NoExecute","tolerationSeconds":300}],"priority":0,"enableServiceLinks":true},"status":{"phase":"Running","conditions":[{"type":"Initialized","status":"True","lastProbeTime":null,"lastTransitionTime":"2019-11-13T09:12:57Z"},{"type":"Ready","status":"False","lastProbeTime":null,"lastTransitionTime":"2019-11-13T09:13:16Z","reason":"ContainersNotReady","message":"containers with unready status: [e2e]"},{"type":"ContainersReady","status":"False","lastProbeTime":null,"lastTransitionTime":"2019-11-13T09:13:16Z","reason":"ContainersNotReady","message":"containers with unready status: [e2e]"},{"type":"PodScheduled","status":"True","lastProbeTime":null,"lastTransitionTime":"2019-11-13T09:12:57Z"}],"hostIP":"192.168.0.21","podIP":"10.88.0.17","startTime":"2019-11-13T09:12:57Z","containerStatuses":[{"name":"e2e","state":{"terminated":{"exitCode":0,"reason":"Completed","startedAt":"2019-11-13T09:12:59Z","finishedAt":"2019-11-13T09:13:16Z","containerID":"cri-o://67cc3e7b86946202181601b3015b6bba7eaa6abbfcbf3163b296e09aa4ffa33d"}},"lastState":{},"ready":false,"restartCount":0,"image":"gcr.io/google-containers/conformance:v1.15.3","imageID":"gcr.io/google-containers/conformance@sha256:fd457d177f69c64cc06bacb824b44d099e73c432ac84b8130af6eab2bf702345","containerID":"cri-o://67cc3e7b86946202181601b3015b6bba7eaa6abbfcbf3163b296e09aa4ffa33d"},{"name":"sonobuoy-worker","state":{"running":{"startedAt":"2019-11-13T09:12:59Z"}},"lastState":{},"ready":true,"restartCount":0,"image":"docker.io/sonobuoy/sonobuoy:v0.16.3","imageID":"docker.io/sonobuoy/sonobuoy@sha256:d1c511532ac706b57af9d000866953ebc43729fa87bd088056e7f77b2a6d0633","containerID":"cri-o://f02638d227a08e11f9d97e0b3f29f5a7a6157a7313bbd9608d3779be2ac92738"}],"qosClass":"BestEffort"}}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "job-complex-err",
"status": "failed",
"items": [
{
"name": "Container e2e is terminated state (exit code 0) due to reason: Completed: ",
"status": "failed",
"meta": {
"file": "errors/error.json"
},
"details": {
"error": "Container e2e is terminated state (exit code 0) due to reason: Completed: ",
"pod": "map[metadata:map[annotations:map[sonobuoy-driver:Job sonobuoy-plugin:e2e] creationTimestamp:2019-11-13T09:12:57Z labels:map[component:sonobuoy sonobuoy-plugin:e2e sonobuoy-run:2a1ccb8f20764fa6 tier:analysis] name:sonobuoy-e2e-job-2a1ccb8f20764fa6 namespace:sonobuoy ownerReferences:[map[apiVersion:v1 kind:Pod name:sonobuoy uid:ec2ac9a2-3bfb-453c-99ee-dfda0d1f75c2]] resourceVersion:783915 selfLink:/api/v1/namespaces/sonobuoy/pods/sonobuoy-e2e-job-2a1ccb8f20764fa6 uid:a61eafb3-a789-4eed-9a6e-b59e7ed40f8e] spec:map[containers:[map[command:[/run_e2e.sh] env:[map[name:E2E_FOCUS value:Pods should be submitted and removed] map[name:E2E_SKIP] map[name:E2E_PARALLEL value:1] map[name:E2E_USE_GO_RUNNER value:true]] image:gcr.io/google-containers/conformance:v1.15.3 imagePullPolicy:Always name:e2e resources:map[] terminationMessagePath:/dev/termination-log terminationMessagePolicy:File volumeMounts:[map[mountPath:/tmp/results name:results] map[mountPath:/var/run/secrets/kubernetes.io/serviceaccount name:sonobuoy-serviceaccount-token-k245m readOnly:true]]] map[args:[worker global -v 5 --logtostderr] command:[/sonobuoy] env:[map[name:NODE_NAME valueFrom:map[fieldRef:map[apiVersion:v1 fieldPath:spec.nodeName]]] map[name:RESULTS_DIR value:/tmp/results] map[name:RESULT_TYPE value:e2e] map[name:MASTER_URL value:https://[10.88.0.16]:8080] map[name:CA_CERT value:-----BEGIN CERTIFICATE-----\nMIIB0jCCAXigAwIBAgIBATAKBggqhkjOPQQDAjBgMQwwCgYDVQQGEwNVU0ExFjAU\nBgNVBAcTDVBhbG8gQWx0bywgQ0ExDzANBgNVBAoTBlZNd2FyZTERMA8GA1UECxMI\nU29ub2J1b3kxFDASBgNVBAMTC3Nvbm9idW95LWNhMB4XDTE5MTExMzA5MTI1N1oX\nDTE5MTExNTA5MTI1N1owYDEMMAoGA1UEBhMDVVNBMRYwFAYDVQQHEw1QYWxvIEFs\ndG8sIENBMQ8wDQYDVQQKEwZWTXdhcmUxETAPBgNVBAsTCFNvbm9idW95MRQwEgYD\nVQQDEwtzb25vYnVveS1jYTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABN0+QzRo\nYef72BU07GIczIIaHqWYgHUHr8ZqkGVeomIsOoKqiY6M6kSQUcpDHEW/5f6m8OE/\n/GoJx70div2hxnOjIzAhMA4GA1UdDwEB/wQEAwICBDAPBgNVHRMBAf8EBTADAQH/\nMAoGCCqGSM49BAMCA0gAMEUCIQDWlamkfJjZXOWp0EJZjDEdGzV+Xj44yKXKfBOO\neVp9EgIgbmREQ4WUYtg7pqv5HMMu4gd3AtIxQvOpx9Xgtevnx48=\n-----END CERTIFICATE-----\n] map[name:CLIENT_CERT valueFrom:map[secretKeyRef:map[key:tls.crt name:sonobuoy-plugin-e2e-2a1ccb8f20764fa6]]] map[name:CLIENT_KEY valueFrom:map[secretKeyRef:map[key:tls.key name:sonobuoy-plugin-e2e-2a1ccb8f20764fa6]]] map[name:SONOBUOY_PROGRESS_PORT value:8099]] image:sonobuoy/sonobuoy:v0.16.3 imagePullPolicy:IfNotPresent name:sonobuoy-worker resources:map[] terminationMessagePath:/dev/termination-log terminationMessagePolicy:File volumeMounts:[map[mountPath:/tmp/results name:results] map[mountPath:/var/run/secrets/kubernetes.io/serviceaccount name:sonobuoy-serviceaccount-token-k245m readOnly:true]]]] dnsPolicy:ClusterFirst enableServiceLinks:true nodeName:worker-1 priority:0 restartPolicy:Never schedulerName:default-scheduler securityContext:map[] serviceAccount:sonobuoy-serviceaccount serviceAccountName:sonobuoy-serviceaccount terminationGracePeriodSeconds:30 tolerations:[map[effect:NoSchedule key:node-role.kubernetes.io/master operator:Exists] map[key:CriticalAddonsOnly operator:Exists] map[key:kubernetes.io/e2e-evict-taint-key operator:Exists] map[effect:NoExecute key:node.kubernetes.io/not-ready operator:Exists tolerationSeconds:300] map[effect:NoExecute key:node.kubernetes.io/unreachable operator:Exists tolerationSeconds:300]] volumes:[map[emptyDir:map[] name:results] map[name:sonobuoy-serviceaccount-token-k245m secret:map[defaultMode:420 secretName:sonobuoy-serviceaccount-token-k245m]]]] status:map[conditions:[map[lastProbeTime:\u003cnil\u003e lastTransitionTime:2019-11-13T09:12:57Z status:True type:Initialized] map[lastProbeTime:\u003cnil\u003e lastTransitionTime:2019-11-13T09:13:16Z message:containers with unready status: [e2e] reason:ContainersNotReady status:False type:Ready] map[lastProbeTime:\u003cnil\u003e lastTransitionTime:2019-11-13T09:13:16Z message:containers with unready status: [e2e] reason:ContainersNotReady status:False type:ContainersReady] map[lastProbeTime:\u003cnil\u003e lastTransitionTime:2019-11-13T09:12:57Z status:True type:PodScheduled]] containerStatuses:[map[containerID:cri-o://67cc3e7b86946202181601b3015b6bba7eaa6abbfcbf3163b296e09aa4ffa33d image:gcr.io/google-containers/conformance:v1.15.3 imageID:gcr.io/google-containers/conformance@sha256:fd457d177f69c64cc06bacb824b44d099e73c432ac84b8130af6eab2bf702345 lastState:map[] name:e2e ready:false restartCount:0 state:map[terminated:map[containerID:cri-o://67cc3e7b86946202181601b3015b6bba7eaa6abbfcbf3163b296e09aa4ffa33d exitCode:0 finishedAt:2019-11-13T09:13:16Z reason:Completed startedAt:2019-11-13T09:12:59Z]]] map[containerID:cri-o://f02638d227a08e11f9d97e0b3f29f5a7a6157a7313bbd9608d3779be2ac92738 image:docker.io/sonobuoy/sonobuoy:v0.16.3 imageID:docker.io/sonobuoy/sonobuoy@sha256:d1c511532ac706b57af9d000866953ebc43729fa87bd088056e7f77b2a6d0633 lastState:map[] name:sonobuoy-worker ready:true restartCount:0 state:map[running:map[startedAt:2019-11-13T09:12:59Z]]]] hostIP:192.168.0.21 phase:Running podIP:10.88.0.17 qosClass:BestEffort startTime:2019-11-13T09:12:57Z]]"
}
}
]
}
4 changes: 2 additions & 2 deletions pkg/plugin/driver/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ import (
"time"

"github.com/vmware-tanzu/sonobuoy/pkg/plugin"
gouuid "github.com/satori/go.uuid"

gouuid "github.com/satori/go.uuid"
v1 "k8s.io/api/core/v1"
)

Expand Down Expand Up @@ -74,7 +74,7 @@ func IsPodFailing(pod *v1.Pod) (bool, string) {
if cstatus.State.Terminated != nil {
// Ensure we give some time to process the results.
if time.Now().Sub(cstatus.State.Terminated.FinishedAt.Time) > terminatedContainerWindow {
errstr := fmt.Sprintf("Container %v is terminated state (exit code %v) due to reason: %v: %v",
errstr := fmt.Sprintf("Container %v is in a terminated state (exit code %v) due to reason: %v: %v",
cstatus.Name,
cstatus.State.Terminated.ExitCode,
cstatus.State.Terminated.Reason,
Expand Down
2 changes: 1 addition & 1 deletion pkg/plugin/driver/utils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func TestPodFailing(t *testing.T) {
}, {
desc: "Terminated container reported failing if old enough",
expectFailing: true,
expectMsg: "Container container1 is terminated state (exit code 1) due to reason: myReason: myMsg",
expectMsg: "Container container1 is in a terminated state (exit code 1) due to reason: myReason: myMsg",
pod: fromGoodPod(func(p *corev1.Pod) *corev1.Pod {
p.Status.ContainerStatuses = []corev1.ContainerStatus{
{
Expand Down