github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/clients/pkg/promtail/targets/gcplog/pull_target_test.go (about) 1 package gcplog 2 3 import ( 4 "context" 5 "sync" 6 "testing" 7 "time" 8 9 "cloud.google.com/go/pubsub" 10 "cloud.google.com/go/pubsub/pstest" 11 "github.com/go-kit/log" 12 "github.com/prometheus/client_golang/prometheus" 13 "github.com/prometheus/common/model" 14 "github.com/stretchr/testify/assert" 15 "github.com/stretchr/testify/require" 16 "google.golang.org/api/option" 17 "google.golang.org/grpc" 18 "google.golang.org/grpc/credentials/insecure" 19 20 "github.com/grafana/loki/clients/pkg/promtail/api" 21 "github.com/grafana/loki/clients/pkg/promtail/client/fake" 22 "github.com/grafana/loki/clients/pkg/promtail/scrapeconfig" 23 "github.com/grafana/loki/clients/pkg/promtail/targets/target" 24 ) 25 26 func TestPullTarget_Run(t *testing.T) { 27 // Goal: Check message written to pubsub topic is received by the target. 28 tt, apiclient, pubsubClient, teardown := testPullTarget(t) 29 defer teardown() 30 31 // seed pubsub 32 ctx := context.Background() 33 tp, err := pubsubClient.CreateTopic(ctx, topic) 34 require.NoError(t, err) 35 _, err = pubsubClient.CreateSubscription(ctx, subscription, pubsub.SubscriptionConfig{ 36 Topic: tp, 37 }) 38 require.NoError(t, err) 39 40 var wg sync.WaitGroup 41 42 wg.Add(1) 43 go func() { 44 defer wg.Done() 45 _ = tt.run() 46 }() 47 48 publishMessage(t, tp) 49 50 // Wait till message is received by the run loop. 51 // NOTE(kavi): sleep is not ideal. but not other way to confirm if api.Handler received messages 52 time.Sleep(1 * time.Second) 53 54 err = tt.Stop() 55 require.NoError(t, err) 56 57 // wait till `run` stops. 58 wg.Wait() 59 60 assert.Equal(t, 1, len(apiclient.Received())) 61 } 62 63 func TestPullTarget_Stop(t *testing.T) { 64 // Goal: To test that `run()` stops when you invoke `target.Stop()` 65 66 errs := make(chan error, 1) 67 68 tt, _, _, teardown := testPullTarget(t) 69 defer teardown() 70 71 var wg sync.WaitGroup 72 73 wg.Add(1) 74 go func() { 75 defer wg.Done() 76 errs <- tt.run() 77 }() 78 79 // invoke stop 80 _ = tt.Stop() 81 82 // wait till run returns 83 wg.Wait() 84 85 // wouldn't block as 1 error is buffered into the channel. 86 err := <-errs 87 88 // returned error should be cancelled context error 89 assert.Equal(t, tt.ctx.Err(), err) 90 } 91 92 func TestPullTarget_Type(t *testing.T) { 93 tt, _, _, teardown := testPullTarget(t) 94 defer teardown() 95 96 assert.Equal(t, target.TargetType("Gcplog"), tt.Type()) 97 } 98 99 func TestPullTarget_Ready(t *testing.T) { 100 tt, _, _, teardown := testPullTarget(t) 101 defer teardown() 102 103 assert.Equal(t, true, tt.Ready()) 104 } 105 106 func TestPullTarget_Labels(t *testing.T) { 107 tt, _, _, teardown := testPullTarget(t) 108 defer teardown() 109 110 assert.Equal(t, model.LabelSet{"job": "test-gcplogtarget"}, tt.Labels()) 111 } 112 113 func testPullTarget(t *testing.T) (*pullTarget, *fake.Client, *pubsub.Client, func()) { 114 t.Helper() 115 116 ctx, cancel := context.WithCancel(context.Background()) 117 118 mockSvr := pstest.NewServer() 119 conn, err := grpc.Dial(mockSvr.Addr, grpc.WithTransportCredentials(insecure.NewCredentials())) 120 require.NoError(t, err) 121 122 mockpubsubClient, err := pubsub.NewClient(ctx, testConfig.ProjectID, option.WithGRPCConn(conn)) 123 require.NoError(t, err) 124 125 fakeClient := fake.New(func() {}) 126 127 var handler api.EntryHandler = fakeClient 128 target := &pullTarget{ 129 metrics: NewMetrics(prometheus.NewRegistry()), 130 logger: log.NewNopLogger(), 131 handler: handler, 132 relabelConfig: nil, 133 config: testConfig, 134 jobName: "job-test-gcplogtarget", 135 ctx: ctx, 136 cancel: cancel, 137 ps: mockpubsubClient, 138 msgs: make(chan *pubsub.Message), 139 } 140 141 // cleanup 142 return target, fakeClient, mockpubsubClient, func() { 143 cancel() 144 conn.Close() 145 mockSvr.Close() 146 } 147 } 148 149 func publishMessage(t *testing.T, topic *pubsub.Topic) { 150 t.Helper() 151 152 ctx := context.Background() 153 res := topic.Publish(ctx, &pubsub.Message{Data: []byte(gcpLogEntry)}) 154 _, err := res.Get(ctx) // wait till message is actully published 155 require.NoError(t, err) 156 } 157 158 const ( 159 project = "test-project" 160 topic = "test-topic" 161 subscription = "test-subscription" 162 163 gcpLogEntry = ` 164 { 165 "insertId": "ajv4d1f1ch8dr", 166 "logName": "projects/grafanalabs-dev/logs/cloudaudit.googleapis.com%2Fdata_access", 167 "protoPayload": { 168 "@type": "type.googleapis.com/google.cloud.audit.AuditLog", 169 "authenticationInfo": { 170 "principalEmail": "1040409107725-compute@developer.gserviceaccount.com", 171 "serviceAccountDelegationInfo": [ 172 { 173 "firstPartyPrincipal": { 174 "principalEmail": "service-1040409107725@compute-system.iam.gserviceaccount.com" 175 } 176 } 177 ] 178 }, 179 "authorizationInfo": [ 180 { 181 "granted": true, 182 "permission": "storage.objects.list", 183 "resource": "projects/_/buckets/dev-us-central1-cortex-tsdb-dev", 184 "resourceAttributes": { 185 } 186 }, 187 { 188 "permission": "storage.objects.get", 189 "resource": "projects/_/buckets/dev-us-central1-cortex-tsdb-dev/objects/load-generator-20/01EM34PFBC2SCV3ETBGRAQZ090/deletion-mark.json", 190 "resourceAttributes": { 191 } 192 } 193 ], 194 "methodName": "storage.objects.get", 195 "requestMetadata": { 196 "callerIp": "34.66.19.193", 197 "callerNetwork": "//compute.googleapis.com/projects/grafanalabs-dev/global/networks/__unknown__", 198 "callerSuppliedUserAgent": "thanos-store-gateway/1.5.0 (go1.14.9),gzip(gfe)", 199 "destinationAttributes": { 200 }, 201 "requestAttributes": { 202 "auth": { 203 }, 204 "time": "2021-01-01T02:17:10.661405637Z" 205 } 206 }, 207 "resourceLocation": { 208 "currentLocations": [ 209 "us-central1" 210 ] 211 }, 212 "resourceName": "projects/_/buckets/dev-us-central1-cortex-tsdb-dev/objects/load-generator-20/01EM34PFBC2SCV3ETBGRAQZ090/deletion-mark.json", 213 "serviceName": "storage.googleapis.com", 214 "status": { 215 } 216 }, 217 "receiveTimestamp": "2021-01-01T02:17:10.82013623Z", 218 "resource": { 219 "labels": { 220 "bucket_name": "dev-us-central1-cortex-tsdb-dev", 221 "location": "us-central1", 222 "project_id": "grafanalabs-dev" 223 }, 224 "type": "gcs_bucket" 225 }, 226 "severity": "INFO", 227 "timestamp": "2021-01-01T02:17:10.655982344Z" 228 } 229 ` 230 ) 231 232 var testConfig = &scrapeconfig.GcplogTargetConfig{ 233 ProjectID: project, 234 Subscription: subscription, 235 Labels: model.LabelSet{ 236 "job": "test-gcplogtarget", 237 }, 238 SubscriptionType: "pull", 239 }