mirror of https://github.com/knative/serving.git
217 lines
6.4 KiB
Go
217 lines
6.4 KiB
Go
/*
|
|
Copyright 2019 The Knative 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 main
|
|
|
|
import (
|
|
"bytes"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
corev1 "k8s.io/api/core/v1"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/types"
|
|
"k8s.io/apimachinery/pkg/util/uuid"
|
|
|
|
ltesting "knative.dev/pkg/logging/testing"
|
|
|
|
"knative.dev/serving/pkg/activator"
|
|
activatorhandler "knative.dev/serving/pkg/activator/handler"
|
|
"knative.dev/serving/pkg/apis/serving"
|
|
v1 "knative.dev/serving/pkg/apis/serving/v1"
|
|
pkghttp "knative.dev/serving/pkg/http"
|
|
"knative.dev/serving/pkg/observability"
|
|
)
|
|
|
|
const (
|
|
testRevisionName = "testRevision"
|
|
testNamespaceName = "testNs"
|
|
testServiceName = "testSvc"
|
|
testConfigName = "testConfig"
|
|
)
|
|
|
|
func TestUpdateRequestLogFromConfigMap(t *testing.T) {
|
|
baseHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.WriteHeader(http.StatusOK)
|
|
})
|
|
buf := bytes.NewBufferString("")
|
|
handler, err := pkghttp.NewRequestLogHandler(baseHandler, buf, "",
|
|
requestLogTemplateInputGetter, false /*enableProbeRequestLog*/)
|
|
if err != nil {
|
|
t.Fatal("want: no error, got:", err)
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
url string
|
|
data map[string]string
|
|
want string
|
|
}{{
|
|
name: "empty template",
|
|
url: "http://example.com/testpage",
|
|
data: map[string]string{
|
|
observability.RequestLogTemplateKey: "",
|
|
},
|
|
}, {
|
|
name: "template with new line",
|
|
url: "http://example.com/testpage",
|
|
data: map[string]string{
|
|
observability.RequestLogTemplateKey: "{{.Request.URL}}\n",
|
|
observability.EnableRequestLogKey: "true",
|
|
},
|
|
want: "http://example.com/testpage\n",
|
|
}, {
|
|
name: "invalid template",
|
|
url: "http://example.com",
|
|
data: map[string]string{
|
|
observability.RequestLogTemplateKey: "{{}}",
|
|
},
|
|
want: "http://example.com\n",
|
|
}, {
|
|
name: "revision info",
|
|
url: "http://example.com",
|
|
data: map[string]string{
|
|
observability.RequestLogTemplateKey: "{{.Revision.Name}}, {{.Revision.Namespace}}, {{.Revision.Service}}, {{.Revision.Configuration}}, {{.Revision.PodName}}, {{.Revision.PodIP}}",
|
|
observability.EnableRequestLogKey: "true",
|
|
},
|
|
want: "testRevision, testNs, testSvc, testConfig, , \n",
|
|
}, {
|
|
name: "empty template 2",
|
|
url: "http://example.com/testpage",
|
|
data: map[string]string{
|
|
observability.RequestLogTemplateKey: "",
|
|
},
|
|
}, {
|
|
name: "explicitly enable request logging",
|
|
url: "http://example.com/testpage",
|
|
data: map[string]string{
|
|
observability.RequestLogTemplateKey: "{{.Request.URL}}\n",
|
|
observability.EnableRequestLogKey: "true",
|
|
},
|
|
want: "http://example.com/testpage\n",
|
|
}, {
|
|
name: "explicitly disable request logging",
|
|
url: "http://example.com/testpage",
|
|
data: map[string]string{
|
|
observability.RequestLogTemplateKey: "{{.Request.URL}}\n",
|
|
observability.EnableRequestLogKey: "false",
|
|
},
|
|
}, {
|
|
name: "explicitly enable request logging with empty template",
|
|
url: "http://example.com/testpage",
|
|
data: map[string]string{
|
|
observability.RequestLogTemplateKey: "",
|
|
observability.EnableRequestLogKey: "true",
|
|
},
|
|
}}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
buf.Reset()
|
|
cm := &corev1.ConfigMap{}
|
|
cm.Data = test.data
|
|
(updateRequestLogFromConfigMap(ltesting.TestLogger(t), handler))(cm)
|
|
resp := httptest.NewRecorder()
|
|
rs := string(uuid.NewUUID())
|
|
req := httptest.NewRequest(http.MethodPost, test.url, bytes.NewBufferString(rs))
|
|
|
|
rev := revision(true)
|
|
revID := types.NamespacedName{Namespace: rev.Namespace, Name: rev.Name}
|
|
ctx := activatorhandler.WithRevisionAndID(req.Context(), rev, revID)
|
|
handler.ServeHTTP(resp, req.WithContext(ctx))
|
|
|
|
if got := buf.String(); got != test.want {
|
|
t.Errorf("got '%v', want '%v'", got, test.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRequestLogTemplateInputGetter(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
revision *v1.Revision
|
|
request *http.Request
|
|
response *pkghttp.RequestLogResponse
|
|
want pkghttp.RequestLogRevision
|
|
}{{
|
|
name: "success",
|
|
revision: revision(true),
|
|
request: &http.Request{Header: map[string][]string{
|
|
activator.RevisionHeaderName: {testRevisionName},
|
|
activator.RevisionHeaderNamespace: {testNamespaceName},
|
|
}},
|
|
response: &pkghttp.RequestLogResponse{Code: http.StatusAlreadyReported},
|
|
want: pkghttp.RequestLogRevision{
|
|
Namespace: testNamespaceName,
|
|
Name: testRevisionName,
|
|
Configuration: testConfigName,
|
|
Service: testServiceName,
|
|
},
|
|
}, {
|
|
name: "labels not found",
|
|
revision: revision(false),
|
|
request: &http.Request{Header: map[string][]string{
|
|
activator.RevisionHeaderName: {testRevisionName},
|
|
activator.RevisionHeaderNamespace: {testNamespaceName},
|
|
}},
|
|
response: &pkghttp.RequestLogResponse{Code: http.StatusAlreadyReported},
|
|
want: pkghttp.RequestLogRevision{
|
|
Namespace: testNamespaceName,
|
|
Name: testRevisionName,
|
|
},
|
|
}}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
revID := types.NamespacedName{Namespace: test.revision.Namespace, Name: test.revision.Name}
|
|
ctx := activatorhandler.WithRevisionAndID(test.request.Context(), test.revision, revID)
|
|
request := test.request.WithContext(ctx)
|
|
|
|
got := requestLogTemplateInputGetter(request, test.response)
|
|
if !cmp.Equal(*got.Revision, test.want) {
|
|
t.Errorf("Got = %v, want: %v, diff:\n%s", got.Revision, test.want, cmp.Diff(got.Revision, test.want))
|
|
}
|
|
if got.Request != request {
|
|
t.Errorf("Got = %v, want: %v", got.Request, request)
|
|
}
|
|
if got.Response != test.response {
|
|
t.Errorf("Got = %v, want: %v", got.Response, test.response)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func revision(addLabels bool) *v1.Revision {
|
|
rev := &v1.Revision{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: testRevisionName,
|
|
Namespace: testNamespaceName,
|
|
},
|
|
}
|
|
|
|
if addLabels {
|
|
rev.Labels = map[string]string{
|
|
serving.ConfigurationLabelKey: testConfigName,
|
|
serving.ServiceLabelKey: testServiceName,
|
|
}
|
|
}
|
|
|
|
return rev
|
|
}
|