blob: 7796a4783a093d604c701d323fe4f73d9ac11392 [file] [log] [blame]
// Copyright 2016 Google Inc. All Rights Reserved.
//
// 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.
// Tests that require access to unexported names of the logging package.
package logging
import (
"net/http"
"net/url"
"reflect"
"testing"
"time"
"cloud.google.com/go/internal/bundler"
"github.com/golang/protobuf/proto"
structpb "github.com/golang/protobuf/ptypes/struct"
mrpb "google.golang.org/genproto/googleapis/api/monitoredres"
logtypepb "google.golang.org/genproto/googleapis/logging/type"
)
func TestLoggerCreation(t *testing.T) {
const logID = "testing"
c := &Client{projectID: "PROJECT_ID"}
defaultResource := &mrpb.MonitoredResource{Type: "global"}
defaultBundler := &bundler.Bundler{
DelayThreshold: DefaultDelayThreshold,
BundleCountThreshold: DefaultEntryCountThreshold,
BundleByteThreshold: DefaultEntryByteThreshold,
BundleByteLimit: 0,
BufferedByteLimit: DefaultBufferedByteLimit,
}
for _, test := range []struct {
options []LoggerOption
wantLogger *Logger
wantBundler *bundler.Bundler
}{
{nil, &Logger{commonResource: defaultResource}, defaultBundler},
{
[]LoggerOption{CommonResource(nil), CommonLabels(map[string]string{"a": "1"})},
&Logger{commonResource: nil, commonLabels: map[string]string{"a": "1"}},
defaultBundler,
},
{
[]LoggerOption{DelayThreshold(time.Minute), EntryCountThreshold(99),
EntryByteThreshold(17), EntryByteLimit(18), BufferedByteLimit(19)},
&Logger{commonResource: defaultResource},
&bundler.Bundler{
DelayThreshold: time.Minute,
BundleCountThreshold: 99,
BundleByteThreshold: 17,
BundleByteLimit: 18,
BufferedByteLimit: 19,
},
},
} {
gotLogger := c.Logger(logID, test.options...)
if got, want := gotLogger.commonResource, test.wantLogger.commonResource; !reflect.DeepEqual(got, want) {
t.Errorf("%v: resource: got %v, want %v", test.options, got, want)
}
if got, want := gotLogger.commonLabels, test.wantLogger.commonLabels; !reflect.DeepEqual(got, want) {
t.Errorf("%v: commonLabels: got %v, want %v", test.options, got, want)
}
if got, want := gotLogger.bundler.DelayThreshold, test.wantBundler.DelayThreshold; got != want {
t.Errorf("%v: DelayThreshold: got %v, want %v", test.options, got, want)
}
if got, want := gotLogger.bundler.BundleCountThreshold, test.wantBundler.BundleCountThreshold; got != want {
t.Errorf("%v: BundleCountThreshold: got %v, want %v", test.options, got, want)
}
if got, want := gotLogger.bundler.BundleByteThreshold, test.wantBundler.BundleByteThreshold; got != want {
t.Errorf("%v: BundleByteThreshold: got %v, want %v", test.options, got, want)
}
if got, want := gotLogger.bundler.BundleByteLimit, test.wantBundler.BundleByteLimit; got != want {
t.Errorf("%v: BundleByteLimit: got %v, want %v", test.options, got, want)
}
if got, want := gotLogger.bundler.BufferedByteLimit, test.wantBundler.BufferedByteLimit; got != want {
t.Errorf("%v: BufferedByteLimit: got %v, want %v", test.options, got, want)
}
}
}
func TestToProtoStruct(t *testing.T) {
v := struct {
Foo string `json:"foo"`
Bar int `json:"bar,omitempty"`
Baz []float64 `json:"baz"`
Moo map[string]interface{} `json:"moo"`
}{
Foo: "foovalue",
Baz: []float64{1.1},
Moo: map[string]interface{}{
"a": 1,
"b": "two",
"c": true,
},
}
got, err := toProtoStruct(v)
if err != nil {
t.Fatal(err)
}
want := &structpb.Struct{
Fields: map[string]*structpb.Value{
"foo": {Kind: &structpb.Value_StringValue{v.Foo}},
"baz": {Kind: &structpb.Value_ListValue{&structpb.ListValue{
[]*structpb.Value{{Kind: &structpb.Value_NumberValue{1.1}}}}}},
"moo": {Kind: &structpb.Value_StructValue{
&structpb.Struct{
Fields: map[string]*structpb.Value{
"a": {Kind: &structpb.Value_NumberValue{1}},
"b": {Kind: &structpb.Value_StringValue{"two"}},
"c": {Kind: &structpb.Value_BoolValue{true}},
},
},
}},
},
}
if !proto.Equal(got, want) {
t.Errorf("got %+v\nwant %+v", got, want)
}
// Non-structs should fail to convert.
for v := range []interface{}{3, "foo", []int{1, 2, 3}} {
_, err := toProtoStruct(v)
if err == nil {
t.Errorf("%v: got nil, want error", v)
}
}
}
func TestFromHTTPRequest(t *testing.T) {
const testURL = "http:://example.com/path?q=1"
u, err := url.Parse(testURL)
if err != nil {
t.Fatal(err)
}
req := &HTTPRequest{
Request: &http.Request{
Method: "GET",
URL: u,
Header: map[string][]string{
"User-Agent": []string{"user-agent"},
"Referer": []string{"referer"},
},
},
RequestSize: 100,
Status: 200,
ResponseSize: 25,
RemoteIP: "127.0.0.1",
CacheHit: true,
CacheValidatedWithOriginServer: true,
}
got := fromHTTPRequest(req)
want := &logtypepb.HttpRequest{
RequestMethod: "GET",
RequestUrl: testURL,
RequestSize: 100,
Status: 200,
ResponseSize: 25,
UserAgent: "user-agent",
RemoteIp: "127.0.0.1",
Referer: "referer",
CacheHit: true,
CacheValidatedWithOriginServer: true,
}
if !reflect.DeepEqual(got, want) {
t.Errorf("got %+v\nwant %+v", got, want)
}
}
// Used by the tests in logging_test.
func SetNow(f func() time.Time) {
now = f
}