No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 

268 líneas
7.8 KiB

  1. // Copyright 2016 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // TODO(jba): test that OnError is getting called appropriately.
  15. package logadmin
  16. import (
  17. "flag"
  18. "log"
  19. "net/http"
  20. "net/url"
  21. "os"
  22. "testing"
  23. "time"
  24. "cloud.google.com/go/internal/testutil"
  25. "cloud.google.com/go/logging"
  26. ltesting "cloud.google.com/go/logging/internal/testing"
  27. "github.com/golang/protobuf/proto"
  28. "github.com/golang/protobuf/ptypes"
  29. durpb "github.com/golang/protobuf/ptypes/duration"
  30. structpb "github.com/golang/protobuf/ptypes/struct"
  31. "github.com/google/go-cmp/cmp/cmpopts"
  32. "golang.org/x/net/context"
  33. "google.golang.org/api/option"
  34. mrpb "google.golang.org/genproto/googleapis/api/monitoredres"
  35. audit "google.golang.org/genproto/googleapis/cloud/audit"
  36. logtypepb "google.golang.org/genproto/googleapis/logging/type"
  37. logpb "google.golang.org/genproto/googleapis/logging/v2"
  38. "google.golang.org/grpc"
  39. )
  40. var (
  41. client *Client
  42. testProjectID string
  43. )
  44. var (
  45. // If true, this test is using the production service, not a fake.
  46. integrationTest bool
  47. newClient func(ctx context.Context, projectID string) *Client
  48. )
  49. func TestMain(m *testing.M) {
  50. flag.Parse() // needed for testing.Short()
  51. ctx := context.Background()
  52. testProjectID = testutil.ProjID()
  53. if testProjectID == "" || testing.Short() {
  54. integrationTest = false
  55. if testProjectID != "" {
  56. log.Print("Integration tests skipped in short mode (using fake instead)")
  57. }
  58. testProjectID = "PROJECT_ID"
  59. addr, err := ltesting.NewServer()
  60. if err != nil {
  61. log.Fatalf("creating fake server: %v", err)
  62. }
  63. newClient = func(ctx context.Context, projectID string) *Client {
  64. conn, err := grpc.Dial(addr, grpc.WithInsecure(), grpc.WithBlock())
  65. if err != nil {
  66. log.Fatalf("dialing %q: %v", addr, err)
  67. }
  68. c, err := NewClient(ctx, projectID, option.WithGRPCConn(conn))
  69. if err != nil {
  70. log.Fatalf("creating client for fake at %q: %v", addr, err)
  71. }
  72. return c
  73. }
  74. } else {
  75. integrationTest = true
  76. ts := testutil.TokenSource(ctx, logging.AdminScope)
  77. if ts == nil {
  78. log.Fatal("The project key must be set. See CONTRIBUTING.md for details")
  79. }
  80. log.Printf("running integration tests with project %s", testProjectID)
  81. newClient = func(ctx context.Context, projectID string) *Client {
  82. c, err := NewClient(ctx, projectID, option.WithTokenSource(ts),
  83. option.WithGRPCDialOption(grpc.WithBlock()))
  84. if err != nil {
  85. log.Fatalf("creating prod client: %v", err)
  86. }
  87. return c
  88. }
  89. }
  90. client = newClient(ctx, testProjectID)
  91. initMetrics(ctx)
  92. cleanup := initSinks(ctx)
  93. exit := m.Run()
  94. cleanup()
  95. client.Close()
  96. os.Exit(exit)
  97. }
  98. // EntryIterator and DeleteLog are tested in the logging package.
  99. func TestClientClose(t *testing.T) {
  100. c := newClient(context.Background(), testProjectID)
  101. if err := c.Close(); err != nil {
  102. t.Errorf("want got %v, want nil", err)
  103. }
  104. }
  105. func TestFromLogEntry(t *testing.T) {
  106. now := time.Now()
  107. res := &mrpb.MonitoredResource{Type: "global"}
  108. ts, err := ptypes.TimestampProto(now)
  109. if err != nil {
  110. t.Fatal(err)
  111. }
  112. logEntry := logpb.LogEntry{
  113. LogName: "projects/PROJECT_ID/logs/LOG_ID",
  114. Resource: res,
  115. Payload: &logpb.LogEntry_TextPayload{TextPayload: "hello"},
  116. Timestamp: ts,
  117. Severity: logtypepb.LogSeverity_INFO,
  118. InsertId: "123",
  119. HttpRequest: &logtypepb.HttpRequest{
  120. RequestMethod: "GET",
  121. RequestUrl: "http:://example.com/path?q=1",
  122. RequestSize: 100,
  123. Status: 200,
  124. ResponseSize: 25,
  125. Latency: &durpb.Duration{Seconds: 100},
  126. UserAgent: "user-agent",
  127. RemoteIp: "127.0.0.1",
  128. Referer: "referer",
  129. CacheHit: true,
  130. CacheValidatedWithOriginServer: true,
  131. },
  132. Labels: map[string]string{
  133. "a": "1",
  134. "b": "two",
  135. "c": "true",
  136. },
  137. }
  138. u, err := url.Parse("http:://example.com/path?q=1")
  139. if err != nil {
  140. t.Fatal(err)
  141. }
  142. want := &logging.Entry{
  143. LogName: "projects/PROJECT_ID/logs/LOG_ID",
  144. Resource: res,
  145. Timestamp: now.In(time.UTC),
  146. Severity: logging.Info,
  147. Payload: "hello",
  148. Labels: map[string]string{
  149. "a": "1",
  150. "b": "two",
  151. "c": "true",
  152. },
  153. InsertID: "123",
  154. HTTPRequest: &logging.HTTPRequest{
  155. Request: &http.Request{
  156. Method: "GET",
  157. URL: u,
  158. Header: map[string][]string{
  159. "User-Agent": {"user-agent"},
  160. "Referer": {"referer"},
  161. },
  162. },
  163. RequestSize: 100,
  164. Status: 200,
  165. ResponseSize: 25,
  166. Latency: 100 * time.Second,
  167. RemoteIP: "127.0.0.1",
  168. CacheHit: true,
  169. CacheValidatedWithOriginServer: true,
  170. },
  171. }
  172. got, err := fromLogEntry(&logEntry)
  173. if err != nil {
  174. t.Fatal(err)
  175. }
  176. if diff := testutil.Diff(got, want, cmpopts.IgnoreUnexported(http.Request{})); diff != "" {
  177. t.Errorf("FullEntry:\n%s", diff)
  178. }
  179. // Proto payload.
  180. alog := &audit.AuditLog{
  181. ServiceName: "svc",
  182. MethodName: "method",
  183. ResourceName: "shelves/S/books/B",
  184. }
  185. any, err := ptypes.MarshalAny(alog)
  186. if err != nil {
  187. t.Fatal(err)
  188. }
  189. logEntry = logpb.LogEntry{
  190. LogName: "projects/PROJECT_ID/logs/LOG_ID",
  191. Resource: res,
  192. Timestamp: ts,
  193. Payload: &logpb.LogEntry_ProtoPayload{ProtoPayload: any},
  194. }
  195. got, err = fromLogEntry(&logEntry)
  196. if err != nil {
  197. t.Fatal(err)
  198. }
  199. if !ltesting.PayloadEqual(got.Payload, alog) {
  200. t.Errorf("got %+v, want %+v", got.Payload, alog)
  201. }
  202. // JSON payload.
  203. jstruct := &structpb.Struct{Fields: map[string]*structpb.Value{
  204. "f": {Kind: &structpb.Value_NumberValue{NumberValue: 3.1}},
  205. }}
  206. logEntry = logpb.LogEntry{
  207. LogName: "projects/PROJECT_ID/logs/LOG_ID",
  208. Resource: res,
  209. Timestamp: ts,
  210. Payload: &logpb.LogEntry_JsonPayload{JsonPayload: jstruct},
  211. }
  212. got, err = fromLogEntry(&logEntry)
  213. if err != nil {
  214. t.Fatal(err)
  215. }
  216. if !ltesting.PayloadEqual(got.Payload, jstruct) {
  217. t.Errorf("got %+v, want %+v", got.Payload, jstruct)
  218. }
  219. }
  220. func TestListLogEntriesRequest(t *testing.T) {
  221. for _, test := range []struct {
  222. opts []EntriesOption
  223. resourceNames []string
  224. filter string
  225. orderBy string
  226. }{
  227. // Default is client's project ID, empty filter and orderBy.
  228. {nil, []string{"projects/PROJECT_ID"}, "", ""},
  229. {[]EntriesOption{NewestFirst(), Filter("f")},
  230. []string{"projects/PROJECT_ID"}, "f", "timestamp desc"},
  231. {[]EntriesOption{ProjectIDs([]string{"foo"})},
  232. []string{"projects/foo"}, "", ""},
  233. {[]EntriesOption{ResourceNames([]string{"folders/F", "organizations/O"})},
  234. []string{"folders/F", "organizations/O"}, "", ""},
  235. {[]EntriesOption{NewestFirst(), Filter("f"), ProjectIDs([]string{"foo"})},
  236. []string{"projects/foo"}, "f", "timestamp desc"},
  237. {[]EntriesOption{NewestFirst(), Filter("f"), ProjectIDs([]string{"foo"})},
  238. []string{"projects/foo"}, "f", "timestamp desc"},
  239. // If there are repeats, last one wins.
  240. {[]EntriesOption{NewestFirst(), Filter("no"), ProjectIDs([]string{"foo"}), Filter("f")},
  241. []string{"projects/foo"}, "f", "timestamp desc"},
  242. } {
  243. got := listLogEntriesRequest("projects/PROJECT_ID", test.opts)
  244. want := &logpb.ListLogEntriesRequest{
  245. ResourceNames: test.resourceNames,
  246. Filter: test.filter,
  247. OrderBy: test.orderBy,
  248. }
  249. if !proto.Equal(got, want) {
  250. t.Errorf("%v:\ngot %v\nwant %v", test.opts, got, want)
  251. }
  252. }
  253. }