github.com/fastly/cli@v1.7.2-0.20240304164155-9d0f1d77c3bf/pkg/commands/logging/kinesis/kinesis_integration_test.go (about) 1 package kinesis_test 2 3 import ( 4 "bytes" 5 "errors" 6 "io" 7 "strings" 8 "testing" 9 10 "github.com/fastly/go-fastly/v9/fastly" 11 12 "github.com/fastly/cli/pkg/app" 13 "github.com/fastly/cli/pkg/global" 14 "github.com/fastly/cli/pkg/mock" 15 "github.com/fastly/cli/pkg/testutil" 16 ) 17 18 func TestKinesisCreate(t *testing.T) { 19 args := testutil.Args 20 scenarios := []struct { 21 args []string 22 api mock.API 23 wantError string 24 wantOutput string 25 }{ 26 { 27 args: args("logging kinesis create --service-id 123 --version 1 --name log --stream-name log --region us-east-1 --secret-key bar --iam-role arn:aws:iam::123456789012:role/KinesisAccess --autoclone"), 28 api: mock.API{ 29 ListVersionsFn: testutil.ListVersions, 30 CloneVersionFn: testutil.CloneVersionResult(4), 31 }, 32 wantError: "error parsing arguments: the --access-key and --secret-key flags are mutually exclusive with the --iam-role flag", 33 }, 34 { 35 args: args("logging kinesis create --service-id 123 --version 1 --name log --stream-name log --region us-east-1 --access-key foo --iam-role arn:aws:iam::123456789012:role/KinesisAccess --autoclone"), 36 api: mock.API{ 37 ListVersionsFn: testutil.ListVersions, 38 CloneVersionFn: testutil.CloneVersionResult(4), 39 }, 40 wantError: "error parsing arguments: the --access-key and --secret-key flags are mutually exclusive with the --iam-role flag", 41 }, 42 { 43 args: args("logging kinesis create --service-id 123 --version 1 --name log --stream-name log --region us-east-1 --access-key foo --secret-key bar --iam-role arn:aws:iam::123456789012:role/KinesisAccess --autoclone"), 44 api: mock.API{ 45 ListVersionsFn: testutil.ListVersions, 46 CloneVersionFn: testutil.CloneVersionResult(4), 47 }, 48 wantError: "error parsing arguments: the --access-key and --secret-key flags are mutually exclusive with the --iam-role flag", 49 }, 50 { 51 args: args("logging kinesis create --service-id 123 --version 1 --name log --stream-name log --access-key foo --secret-key bar --region us-east-1 --autoclone"), 52 api: mock.API{ 53 ListVersionsFn: testutil.ListVersions, 54 CloneVersionFn: testutil.CloneVersionResult(4), 55 CreateKinesisFn: createKinesisOK, 56 }, 57 wantOutput: "Created Kinesis logging endpoint log (service 123 version 4)", 58 }, 59 { 60 args: args("logging kinesis create --service-id 123 --version 1 --name log --stream-name log --access-key foo --secret-key bar --region us-east-1 --autoclone"), 61 api: mock.API{ 62 ListVersionsFn: testutil.ListVersions, 63 CloneVersionFn: testutil.CloneVersionResult(4), 64 CreateKinesisFn: createKinesisError, 65 }, 66 wantError: errTest.Error(), 67 }, 68 { 69 args: args("logging kinesis create --service-id 123 --version 1 --name log2 --stream-name log --region us-east-1 --iam-role arn:aws:iam::123456789012:role/KinesisAccess --autoclone"), 70 api: mock.API{ 71 ListVersionsFn: testutil.ListVersions, 72 CloneVersionFn: testutil.CloneVersionResult(4), 73 CreateKinesisFn: createKinesisOK, 74 }, 75 wantOutput: "Created Kinesis logging endpoint log2 (service 123 version 4)", 76 }, 77 { 78 args: args("logging kinesis create --service-id 123 --version 1 --name log2 --stream-name log --region us-east-1 --iam-role arn:aws:iam::123456789012:role/KinesisAccess --autoclone"), 79 api: mock.API{ 80 ListVersionsFn: testutil.ListVersions, 81 CloneVersionFn: testutil.CloneVersionResult(4), 82 CreateKinesisFn: createKinesisError, 83 }, 84 wantError: errTest.Error(), 85 }, 86 } 87 for testcaseIdx := range scenarios { 88 testcase := &scenarios[testcaseIdx] 89 t.Run(strings.Join(testcase.args, " "), func(t *testing.T) { 90 var stdout bytes.Buffer 91 app.Init = func(_ []string, _ io.Reader) (*global.Data, error) { 92 opts := testutil.MockGlobalData(testcase.args, &stdout) 93 opts.APIClientFactory = mock.APIClient(testcase.api) 94 return opts, nil 95 } 96 err := app.Run(testcase.args, nil) 97 testutil.AssertErrorContains(t, err, testcase.wantError) 98 testutil.AssertStringContains(t, stdout.String(), testcase.wantOutput) 99 }) 100 } 101 } 102 103 func TestKinesisList(t *testing.T) { 104 args := testutil.Args 105 scenarios := []struct { 106 args []string 107 api mock.API 108 wantError string 109 wantOutput string 110 }{ 111 { 112 args: args("logging kinesis list --service-id 123 --version 1"), 113 api: mock.API{ 114 ListVersionsFn: testutil.ListVersions, 115 ListKinesisFn: listKinesesOK, 116 }, 117 wantOutput: listKinesesShortOutput, 118 }, 119 { 120 args: args("logging kinesis list --service-id 123 --version 1 --verbose"), 121 api: mock.API{ 122 ListVersionsFn: testutil.ListVersions, 123 ListKinesisFn: listKinesesOK, 124 }, 125 wantOutput: listKinesesVerboseOutput, 126 }, 127 { 128 args: args("logging kinesis list --service-id 123 --version 1 -v"), 129 api: mock.API{ 130 ListVersionsFn: testutil.ListVersions, 131 ListKinesisFn: listKinesesOK, 132 }, 133 wantOutput: listKinesesVerboseOutput, 134 }, 135 { 136 args: args("logging kinesis --verbose list --service-id 123 --version 1"), 137 api: mock.API{ 138 ListVersionsFn: testutil.ListVersions, 139 ListKinesisFn: listKinesesOK, 140 }, 141 wantOutput: listKinesesVerboseOutput, 142 }, 143 { 144 args: args("logging -v kinesis list --service-id 123 --version 1"), 145 api: mock.API{ 146 ListVersionsFn: testutil.ListVersions, 147 ListKinesisFn: listKinesesOK, 148 }, 149 wantOutput: listKinesesVerboseOutput, 150 }, 151 { 152 args: args("logging kinesis list --service-id 123 --version 1"), 153 api: mock.API{ 154 ListVersionsFn: testutil.ListVersions, 155 ListKinesisFn: listKinesesError, 156 }, 157 wantError: errTest.Error(), 158 }, 159 } 160 for testcaseIdx := range scenarios { 161 testcase := &scenarios[testcaseIdx] 162 t.Run(strings.Join(testcase.args, " "), func(t *testing.T) { 163 var stdout bytes.Buffer 164 app.Init = func(_ []string, _ io.Reader) (*global.Data, error) { 165 opts := testutil.MockGlobalData(testcase.args, &stdout) 166 opts.APIClientFactory = mock.APIClient(testcase.api) 167 return opts, nil 168 } 169 err := app.Run(testcase.args, nil) 170 testutil.AssertErrorContains(t, err, testcase.wantError) 171 testutil.AssertString(t, testcase.wantOutput, stdout.String()) 172 }) 173 } 174 } 175 176 func TestKinesisDescribe(t *testing.T) { 177 args := testutil.Args 178 scenarios := []struct { 179 args []string 180 api mock.API 181 wantError string 182 wantOutput string 183 }{ 184 { 185 args: args("logging kinesis describe --service-id 123 --version 1"), 186 wantError: "error parsing arguments: required flag --name not provided", 187 }, 188 { 189 args: args("logging kinesis describe --service-id 123 --version 1 --name logs"), 190 api: mock.API{ 191 ListVersionsFn: testutil.ListVersions, 192 GetKinesisFn: getKinesisError, 193 }, 194 wantError: errTest.Error(), 195 }, 196 { 197 args: args("logging kinesis describe --service-id 123 --version 1 --name logs"), 198 api: mock.API{ 199 ListVersionsFn: testutil.ListVersions, 200 GetKinesisFn: getKinesisOK, 201 }, 202 wantOutput: describeKinesisOutput, 203 }, 204 } 205 for testcaseIdx := range scenarios { 206 testcase := &scenarios[testcaseIdx] 207 t.Run(strings.Join(testcase.args, " "), func(t *testing.T) { 208 var stdout bytes.Buffer 209 app.Init = func(_ []string, _ io.Reader) (*global.Data, error) { 210 opts := testutil.MockGlobalData(testcase.args, &stdout) 211 opts.APIClientFactory = mock.APIClient(testcase.api) 212 return opts, nil 213 } 214 err := app.Run(testcase.args, nil) 215 testutil.AssertErrorContains(t, err, testcase.wantError) 216 testutil.AssertString(t, testcase.wantOutput, stdout.String()) 217 }) 218 } 219 } 220 221 func TestKinesisUpdate(t *testing.T) { 222 args := testutil.Args 223 scenarios := []struct { 224 args []string 225 api mock.API 226 wantError string 227 wantOutput string 228 }{ 229 { 230 args: args("logging kinesis update --service-id 123 --version 1 --new-name log"), 231 wantError: "error parsing arguments: required flag --name not provided", 232 }, 233 { 234 args: args("logging kinesis update --service-id 123 --version 1 --name logs --new-name log --autoclone"), 235 api: mock.API{ 236 ListVersionsFn: testutil.ListVersions, 237 CloneVersionFn: testutil.CloneVersionResult(4), 238 UpdateKinesisFn: updateKinesisError, 239 }, 240 wantError: errTest.Error(), 241 }, 242 { 243 args: args("logging kinesis update --service-id 123 --version 1 --name logs --new-name log --region us-west-1 --autoclone"), 244 api: mock.API{ 245 ListVersionsFn: testutil.ListVersions, 246 CloneVersionFn: testutil.CloneVersionResult(4), 247 UpdateKinesisFn: updateKinesisOK, 248 }, 249 wantOutput: "Updated Kinesis logging endpoint log (service 123 version 4)", 250 }, 251 } 252 for testcaseIdx := range scenarios { 253 testcase := &scenarios[testcaseIdx] 254 t.Run(strings.Join(testcase.args, " "), func(t *testing.T) { 255 var stdout bytes.Buffer 256 app.Init = func(_ []string, _ io.Reader) (*global.Data, error) { 257 opts := testutil.MockGlobalData(testcase.args, &stdout) 258 opts.APIClientFactory = mock.APIClient(testcase.api) 259 return opts, nil 260 } 261 err := app.Run(testcase.args, nil) 262 testutil.AssertErrorContains(t, err, testcase.wantError) 263 testutil.AssertStringContains(t, stdout.String(), testcase.wantOutput) 264 }) 265 } 266 } 267 268 func TestKinesisDelete(t *testing.T) { 269 args := testutil.Args 270 scenarios := []struct { 271 args []string 272 api mock.API 273 wantError string 274 wantOutput string 275 }{ 276 { 277 args: args("logging kinesis delete --service-id 123 --version 1"), 278 wantError: "error parsing arguments: required flag --name not provided", 279 }, 280 { 281 args: args("logging kinesis delete --service-id 123 --version 1 --name logs --autoclone"), 282 api: mock.API{ 283 ListVersionsFn: testutil.ListVersions, 284 CloneVersionFn: testutil.CloneVersionResult(4), 285 DeleteKinesisFn: deleteKinesisError, 286 }, 287 wantError: errTest.Error(), 288 }, 289 { 290 args: args("logging kinesis delete --service-id 123 --version 1 --name logs --autoclone"), 291 api: mock.API{ 292 ListVersionsFn: testutil.ListVersions, 293 CloneVersionFn: testutil.CloneVersionResult(4), 294 DeleteKinesisFn: deleteKinesisOK, 295 }, 296 wantOutput: "Deleted Kinesis logging endpoint logs (service 123 version 4)", 297 }, 298 } 299 for testcaseIdx := range scenarios { 300 testcase := &scenarios[testcaseIdx] 301 t.Run(strings.Join(testcase.args, " "), func(t *testing.T) { 302 var stdout bytes.Buffer 303 app.Init = func(_ []string, _ io.Reader) (*global.Data, error) { 304 opts := testutil.MockGlobalData(testcase.args, &stdout) 305 opts.APIClientFactory = mock.APIClient(testcase.api) 306 return opts, nil 307 } 308 err := app.Run(testcase.args, nil) 309 testutil.AssertErrorContains(t, err, testcase.wantError) 310 testutil.AssertStringContains(t, stdout.String(), testcase.wantOutput) 311 }) 312 } 313 } 314 315 var errTest = errors.New("fixture error") 316 317 func createKinesisOK(i *fastly.CreateKinesisInput) (*fastly.Kinesis, error) { 318 return &fastly.Kinesis{ 319 ServiceID: fastly.ToPointer(i.ServiceID), 320 ServiceVersion: fastly.ToPointer(i.ServiceVersion), 321 Name: i.Name, 322 }, nil 323 } 324 325 func createKinesisError(_ *fastly.CreateKinesisInput) (*fastly.Kinesis, error) { 326 return nil, errTest 327 } 328 329 func listKinesesOK(i *fastly.ListKinesisInput) ([]*fastly.Kinesis, error) { 330 return []*fastly.Kinesis{ 331 { 332 ServiceID: fastly.ToPointer(i.ServiceID), 333 ServiceVersion: fastly.ToPointer(i.ServiceVersion), 334 Name: fastly.ToPointer("logs"), 335 StreamName: fastly.ToPointer("my-logs"), 336 AccessKey: fastly.ToPointer("1234"), 337 SecretKey: fastly.ToPointer("-----BEGIN RSA PRIVATE KEY-----MIIEogIBAAKCA"), 338 Region: fastly.ToPointer("us-east-1"), 339 Format: fastly.ToPointer(`%h %l %u %t "%r" %>s %b`), 340 FormatVersion: fastly.ToPointer(2), 341 ResponseCondition: fastly.ToPointer("Prevent default logging"), 342 Placement: fastly.ToPointer("none"), 343 }, 344 { 345 ServiceID: fastly.ToPointer(i.ServiceID), 346 ServiceVersion: fastly.ToPointer(i.ServiceVersion), 347 Name: fastly.ToPointer("analytics"), 348 StreamName: fastly.ToPointer("analytics"), 349 AccessKey: fastly.ToPointer("1234"), 350 SecretKey: fastly.ToPointer("-----BEGIN RSA PRIVATE KEY-----MIIEogIBAAKCA"), 351 Region: fastly.ToPointer("us-east-1"), 352 Format: fastly.ToPointer(`%h %l %u %t "%r" %>s %b`), 353 FormatVersion: fastly.ToPointer(2), 354 ResponseCondition: fastly.ToPointer("Prevent default logging"), 355 Placement: fastly.ToPointer("none"), 356 }, 357 }, nil 358 } 359 360 func listKinesesError(_ *fastly.ListKinesisInput) ([]*fastly.Kinesis, error) { 361 return nil, errTest 362 } 363 364 var listKinesesShortOutput = strings.TrimSpace(` 365 SERVICE VERSION NAME 366 123 1 logs 367 123 1 analytics 368 `) + "\n" 369 370 var listKinesesVerboseOutput = strings.TrimSpace(` 371 Fastly API endpoint: https://api.fastly.com 372 Fastly API token provided via config file (profile: user) 373 374 Service ID (via --service-id): 123 375 376 Version: 1 377 Kinesis 1/2 378 Service ID: 123 379 Version: 1 380 Name: logs 381 Stream name: my-logs 382 Region: us-east-1 383 Access key: 1234 384 Secret key: -----BEGIN RSA PRIVATE KEY-----MIIEogIBAAKCA 385 Format: %h %l %u %t "%r" %>s %b 386 Format version: 2 387 Response condition: Prevent default logging 388 Placement: none 389 Kinesis 2/2 390 Service ID: 123 391 Version: 1 392 Name: analytics 393 Stream name: analytics 394 Region: us-east-1 395 Access key: 1234 396 Secret key: -----BEGIN RSA PRIVATE KEY-----MIIEogIBAAKCA 397 Format: %h %l %u %t "%r" %>s %b 398 Format version: 2 399 Response condition: Prevent default logging 400 Placement: none 401 `) + "\n\n" 402 403 func getKinesisOK(i *fastly.GetKinesisInput) (*fastly.Kinesis, error) { 404 return &fastly.Kinesis{ 405 ServiceID: fastly.ToPointer(i.ServiceID), 406 ServiceVersion: fastly.ToPointer(i.ServiceVersion), 407 Name: fastly.ToPointer("logs"), 408 StreamName: fastly.ToPointer("my-logs"), 409 AccessKey: fastly.ToPointer("1234"), 410 SecretKey: fastly.ToPointer("-----BEGIN RSA PRIVATE KEY-----MIIEogIBAAKCA"), 411 Region: fastly.ToPointer("us-east-1"), 412 Format: fastly.ToPointer(`%h %l %u %t "%r" %>s %b`), 413 FormatVersion: fastly.ToPointer(2), 414 ResponseCondition: fastly.ToPointer("Prevent default logging"), 415 Placement: fastly.ToPointer("none"), 416 }, nil 417 } 418 419 func getKinesisError(_ *fastly.GetKinesisInput) (*fastly.Kinesis, error) { 420 return nil, errTest 421 } 422 423 var describeKinesisOutput = "\n" + strings.TrimSpace(` 424 Access key: 1234 425 Format: %h %l %u %t "%r" %>s %b 426 Format version: 2 427 Name: logs 428 Placement: none 429 Region: us-east-1 430 Response condition: Prevent default logging 431 Secret key: -----BEGIN RSA PRIVATE KEY-----MIIEogIBAAKCA 432 Service ID: 123 433 Stream name: my-logs 434 Version: 1 435 `) + "\n" 436 437 func updateKinesisOK(i *fastly.UpdateKinesisInput) (*fastly.Kinesis, error) { 438 return &fastly.Kinesis{ 439 ServiceID: fastly.ToPointer(i.ServiceID), 440 ServiceVersion: fastly.ToPointer(i.ServiceVersion), 441 Name: fastly.ToPointer("log"), 442 StreamName: fastly.ToPointer("my-logs"), 443 AccessKey: fastly.ToPointer("1234"), 444 SecretKey: fastly.ToPointer("-----BEGIN RSA PRIVATE KEY-----MIIEogIBAAKCA"), 445 Region: fastly.ToPointer("us-west-1"), 446 Format: fastly.ToPointer(`%h %l %u %t "%r" %>s %b`), 447 FormatVersion: fastly.ToPointer(2), 448 ResponseCondition: fastly.ToPointer("Prevent default logging"), 449 Placement: fastly.ToPointer("none"), 450 }, nil 451 } 452 453 func updateKinesisError(_ *fastly.UpdateKinesisInput) (*fastly.Kinesis, error) { 454 return nil, errTest 455 } 456 457 func deleteKinesisOK(_ *fastly.DeleteKinesisInput) error { 458 return nil 459 } 460 461 func deleteKinesisError(_ *fastly.DeleteKinesisInput) error { 462 return errTest 463 }