Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 

285 lignes
7.5 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): document in CONTRIBUTING.md that service account must be given "Logs Configuration Writer" IAM role for sink tests to pass.
  15. // TODO(jba): [cont] (1) From top left menu, go to IAM & Admin. (2) In Roles dropdown for acct, select Logging > Logs Configuration Writer. (3) Save.
  16. // TODO(jba): Also, cloud-logs@google.com must have Owner permission on the GCS bucket named for the test project.
  17. package logadmin
  18. import (
  19. "context"
  20. "log"
  21. "testing"
  22. "time"
  23. "cloud.google.com/go/internal/testutil"
  24. "cloud.google.com/go/internal/uid"
  25. ltest "cloud.google.com/go/logging/internal/testing"
  26. "cloud.google.com/go/storage"
  27. "google.golang.org/api/iterator"
  28. "google.golang.org/api/option"
  29. )
  30. var sinkIDs = uid.NewSpace("GO-CLIENT-TEST-SINK", nil)
  31. const testFilter = ""
  32. var testSinkDestination string
  33. // Called just before TestMain calls m.Run.
  34. // Returns a cleanup function to be called after the tests finish.
  35. func initSinks(ctx context.Context) func() {
  36. // Create a unique GCS bucket so concurrent tests don't interfere with each other.
  37. bucketIDs := uid.NewSpace(testProjectID+"-log-sink", nil)
  38. testBucket := bucketIDs.New()
  39. testSinkDestination = "storage.googleapis.com/" + testBucket
  40. var storageClient *storage.Client
  41. if integrationTest {
  42. // Create a unique bucket as a sink destination, and give the cloud logging account
  43. // owner right.
  44. ts := testutil.TokenSource(ctx, storage.ScopeFullControl)
  45. var err error
  46. storageClient, err = storage.NewClient(ctx, option.WithTokenSource(ts))
  47. if err != nil {
  48. log.Fatalf("new storage client: %v", err)
  49. }
  50. bucket := storageClient.Bucket(testBucket)
  51. if err := bucket.Create(ctx, testProjectID, nil); err != nil {
  52. log.Fatalf("creating storage bucket %q: %v", testBucket, err)
  53. }
  54. log.Printf("successfully created bucket %s", testBucket)
  55. if err := bucket.ACL().Set(ctx, "group-cloud-logs@google.com", storage.RoleOwner); err != nil {
  56. log.Fatalf("setting owner role: %v", err)
  57. }
  58. }
  59. // Clean up from aborted tests.
  60. it := client.Sinks(ctx)
  61. for {
  62. s, err := it.Next()
  63. if err == iterator.Done {
  64. break
  65. }
  66. if err != nil {
  67. log.Printf("listing sinks: %v", err)
  68. break
  69. }
  70. if sinkIDs.Older(s.ID, time.Hour) {
  71. client.DeleteSink(ctx, s.ID) // ignore error
  72. }
  73. }
  74. if integrationTest {
  75. for _, bn := range bucketNames(ctx, storageClient) {
  76. if bucketIDs.Older(bn, 24*time.Hour) {
  77. storageClient.Bucket(bn).Delete(ctx) // ignore error
  78. }
  79. }
  80. return func() {
  81. storageClient.Close()
  82. }
  83. }
  84. return func() {}
  85. }
  86. // Collect the name of all buckets for the test project.
  87. func bucketNames(ctx context.Context, client *storage.Client) []string {
  88. var names []string
  89. it := client.Buckets(ctx, testProjectID)
  90. loop:
  91. for {
  92. b, err := it.Next()
  93. switch err {
  94. case nil:
  95. names = append(names, b.Name)
  96. case iterator.Done:
  97. break loop
  98. default:
  99. log.Printf("listing buckets: %v", err)
  100. break loop
  101. }
  102. }
  103. return names
  104. }
  105. func TestCreateSink(t *testing.T) {
  106. ctx := context.Background()
  107. sink := &Sink{
  108. ID: sinkIDs.New(),
  109. Destination: testSinkDestination,
  110. Filter: testFilter,
  111. IncludeChildren: true,
  112. }
  113. got, err := client.CreateSink(ctx, sink)
  114. if err != nil {
  115. t.Fatal(err)
  116. }
  117. sink.WriterIdentity = ltest.SharedServiceAccount
  118. if want := sink; !testutil.Equal(got, want) {
  119. t.Errorf("got %+v, want %+v", got, want)
  120. }
  121. got, err = client.Sink(ctx, sink.ID)
  122. if err != nil {
  123. t.Fatal(err)
  124. }
  125. if want := sink; !testutil.Equal(got, want) {
  126. t.Errorf("got %+v, want %+v", got, want)
  127. }
  128. // UniqueWriterIdentity
  129. sink.ID = sinkIDs.New()
  130. got, err = client.CreateSinkOpt(ctx, sink, SinkOptions{UniqueWriterIdentity: true})
  131. if err != nil {
  132. t.Fatal(err)
  133. }
  134. // The WriterIdentity should be different.
  135. if got.WriterIdentity == sink.WriterIdentity {
  136. t.Errorf("got %s, want something different", got.WriterIdentity)
  137. }
  138. }
  139. func TestUpdateSink(t *testing.T) {
  140. ctx := context.Background()
  141. sink := &Sink{
  142. ID: sinkIDs.New(),
  143. Destination: testSinkDestination,
  144. Filter: testFilter,
  145. IncludeChildren: true,
  146. WriterIdentity: ltest.SharedServiceAccount,
  147. }
  148. if _, err := client.CreateSink(ctx, sink); err != nil {
  149. t.Fatal(err)
  150. }
  151. got, err := client.UpdateSink(ctx, sink)
  152. if err != nil {
  153. t.Fatal(err)
  154. }
  155. if want := sink; !testutil.Equal(got, want) {
  156. t.Errorf("got\n%+v\nwant\n%+v", got, want)
  157. }
  158. got, err = client.Sink(ctx, sink.ID)
  159. if err != nil {
  160. t.Fatal(err)
  161. }
  162. if want := sink; !testutil.Equal(got, want) {
  163. t.Errorf("got\n%+v\nwant\n%+v", got, want)
  164. }
  165. // Updating an existing sink changes it.
  166. sink.Filter = ""
  167. sink.IncludeChildren = false
  168. if _, err := client.UpdateSink(ctx, sink); err != nil {
  169. t.Fatal(err)
  170. }
  171. got, err = client.Sink(ctx, sink.ID)
  172. if err != nil {
  173. t.Fatal(err)
  174. }
  175. if want := sink; !testutil.Equal(got, want) {
  176. t.Errorf("got\n%+v\nwant\n%+v", got, want)
  177. }
  178. }
  179. func TestUpdateSinkOpt(t *testing.T) {
  180. ctx := context.Background()
  181. id := sinkIDs.New()
  182. origSink := &Sink{
  183. ID: id,
  184. Destination: testSinkDestination,
  185. Filter: testFilter,
  186. IncludeChildren: true,
  187. WriterIdentity: ltest.SharedServiceAccount,
  188. }
  189. if _, err := client.CreateSink(ctx, origSink); err != nil {
  190. t.Fatal(err)
  191. }
  192. // Updating with empty options is an error.
  193. _, err := client.UpdateSinkOpt(ctx, &Sink{ID: id, Destination: testSinkDestination}, SinkOptions{})
  194. if err == nil {
  195. t.Errorf("got %v, want nil", err)
  196. }
  197. // Update selected fields.
  198. got, err := client.UpdateSinkOpt(ctx, &Sink{ID: id}, SinkOptions{
  199. UpdateFilter: true,
  200. UpdateIncludeChildren: true,
  201. })
  202. if err != nil {
  203. t.Fatal(err)
  204. }
  205. want := *origSink
  206. want.Filter = ""
  207. want.IncludeChildren = false
  208. if !testutil.Equal(got, &want) {
  209. t.Errorf("got\n%+v\nwant\n%+v", got, want)
  210. }
  211. // Update writer identity.
  212. got, err = client.UpdateSinkOpt(ctx, &Sink{ID: id, Filter: "foo"},
  213. SinkOptions{UniqueWriterIdentity: true})
  214. if err != nil {
  215. t.Fatal(err)
  216. }
  217. if got.WriterIdentity == want.WriterIdentity {
  218. t.Errorf("got %s, want something different", got.WriterIdentity)
  219. }
  220. want.WriterIdentity = got.WriterIdentity
  221. if !testutil.Equal(got, &want) {
  222. t.Errorf("got\n%+v\nwant\n%+v", got, want)
  223. }
  224. }
  225. func TestListSinks(t *testing.T) {
  226. ctx := context.Background()
  227. var sinks []*Sink
  228. want := map[string]*Sink{}
  229. for i := 0; i < 4; i++ {
  230. s := &Sink{
  231. ID: sinkIDs.New(),
  232. Destination: testSinkDestination,
  233. Filter: testFilter,
  234. WriterIdentity: "serviceAccount:cloud-logs@system.gserviceaccount.com",
  235. }
  236. sinks = append(sinks, s)
  237. want[s.ID] = s
  238. }
  239. for _, s := range sinks {
  240. if _, err := client.CreateSink(ctx, s); err != nil {
  241. t.Fatalf("Create(%q): %v", s.ID, err)
  242. }
  243. }
  244. got := map[string]*Sink{}
  245. it := client.Sinks(ctx)
  246. for {
  247. s, err := it.Next()
  248. if err == iterator.Done {
  249. break
  250. }
  251. if err != nil {
  252. t.Fatal(err)
  253. }
  254. // If tests run simultaneously, we may have more sinks than we
  255. // created. So only check for our own.
  256. if _, ok := want[s.ID]; ok {
  257. got[s.ID] = s
  258. }
  259. }
  260. if !testutil.Equal(got, want) {
  261. t.Errorf("got %+v, want %+v", got, want)
  262. }
  263. }