github.com/fastly/cli@v1.7.2-0.20240304164155-9d0f1d77c3bf/pkg/commands/logging/elasticsearch/elasticsearch_integration_test.go (about) 1 package elasticsearch_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 TestElasticsearchCreate(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 elasticsearch create --service-id 123 --version 1 --name log --index logs --url example.com --autoclone"), 28 api: mock.API{ 29 ListVersionsFn: testutil.ListVersions, 30 CloneVersionFn: testutil.CloneVersionResult(4), 31 CreateElasticsearchFn: createElasticsearchOK, 32 }, 33 wantOutput: "Created Elasticsearch logging endpoint log (service 123 version 4)", 34 }, 35 { 36 args: args("logging elasticsearch create --service-id 123 --version 1 --name log --index logs --url example.com --autoclone"), 37 api: mock.API{ 38 ListVersionsFn: testutil.ListVersions, 39 CloneVersionFn: testutil.CloneVersionResult(4), 40 CreateElasticsearchFn: createElasticsearchError, 41 }, 42 wantError: errTest.Error(), 43 }, 44 } 45 for testcaseIdx := range scenarios { 46 testcase := &scenarios[testcaseIdx] 47 t.Run(strings.Join(testcase.args, " "), func(t *testing.T) { 48 var stdout bytes.Buffer 49 app.Init = func(_ []string, _ io.Reader) (*global.Data, error) { 50 opts := testutil.MockGlobalData(testcase.args, &stdout) 51 opts.APIClientFactory = mock.APIClient(testcase.api) 52 return opts, nil 53 } 54 err := app.Run(testcase.args, nil) 55 testutil.AssertErrorContains(t, err, testcase.wantError) 56 testutil.AssertStringContains(t, stdout.String(), testcase.wantOutput) 57 }) 58 } 59 } 60 61 func TestElasticsearchList(t *testing.T) { 62 args := testutil.Args 63 scenarios := []struct { 64 args []string 65 api mock.API 66 wantError string 67 wantOutput string 68 }{ 69 { 70 args: args("logging elasticsearch list --service-id 123 --version 1"), 71 api: mock.API{ 72 ListVersionsFn: testutil.ListVersions, 73 ListElasticsearchFn: listElasticsearchsOK, 74 }, 75 wantOutput: listElasticsearchsShortOutput, 76 }, 77 { 78 args: args("logging elasticsearch list --service-id 123 --version 1 --verbose"), 79 api: mock.API{ 80 ListVersionsFn: testutil.ListVersions, 81 ListElasticsearchFn: listElasticsearchsOK, 82 }, 83 wantOutput: listElasticsearchsVerboseOutput, 84 }, 85 { 86 args: args("logging elasticsearch list --service-id 123 --version 1 -v"), 87 api: mock.API{ 88 ListVersionsFn: testutil.ListVersions, 89 ListElasticsearchFn: listElasticsearchsOK, 90 }, 91 wantOutput: listElasticsearchsVerboseOutput, 92 }, 93 { 94 args: args("logging elasticsearch --verbose list --service-id 123 --version 1"), 95 api: mock.API{ 96 ListVersionsFn: testutil.ListVersions, 97 ListElasticsearchFn: listElasticsearchsOK, 98 }, 99 wantOutput: listElasticsearchsVerboseOutput, 100 }, 101 { 102 args: args("logging -v elasticsearch list --service-id 123 --version 1"), 103 api: mock.API{ 104 ListVersionsFn: testutil.ListVersions, 105 ListElasticsearchFn: listElasticsearchsOK, 106 }, 107 wantOutput: listElasticsearchsVerboseOutput, 108 }, 109 { 110 args: args("logging elasticsearch list --service-id 123 --version 1"), 111 api: mock.API{ 112 ListVersionsFn: testutil.ListVersions, 113 ListElasticsearchFn: listElasticsearchsError, 114 }, 115 wantError: errTest.Error(), 116 }, 117 } 118 for testcaseIdx := range scenarios { 119 testcase := &scenarios[testcaseIdx] 120 t.Run(strings.Join(testcase.args, " "), func(t *testing.T) { 121 var stdout bytes.Buffer 122 app.Init = func(_ []string, _ io.Reader) (*global.Data, error) { 123 opts := testutil.MockGlobalData(testcase.args, &stdout) 124 opts.APIClientFactory = mock.APIClient(testcase.api) 125 return opts, nil 126 } 127 err := app.Run(testcase.args, nil) 128 testutil.AssertErrorContains(t, err, testcase.wantError) 129 testutil.AssertString(t, testcase.wantOutput, stdout.String()) 130 }) 131 } 132 } 133 134 func TestElasticsearchDescribe(t *testing.T) { 135 args := testutil.Args 136 scenarios := []struct { 137 args []string 138 api mock.API 139 wantError string 140 wantOutput string 141 }{ 142 { 143 args: args("logging elasticsearch describe --service-id 123 --version 1"), 144 wantError: "error parsing arguments: required flag --name not provided", 145 }, 146 { 147 args: args("logging elasticsearch describe --service-id 123 --version 1 --name logs"), 148 api: mock.API{ 149 ListVersionsFn: testutil.ListVersions, 150 GetElasticsearchFn: getElasticsearchError, 151 }, 152 wantError: errTest.Error(), 153 }, 154 { 155 args: args("logging elasticsearch describe --service-id 123 --version 1 --name logs"), 156 api: mock.API{ 157 ListVersionsFn: testutil.ListVersions, 158 GetElasticsearchFn: getElasticsearchOK, 159 }, 160 wantOutput: describeElasticsearchOutput, 161 }, 162 } 163 for testcaseIdx := range scenarios { 164 testcase := &scenarios[testcaseIdx] 165 t.Run(strings.Join(testcase.args, " "), func(t *testing.T) { 166 var stdout bytes.Buffer 167 app.Init = func(_ []string, _ io.Reader) (*global.Data, error) { 168 opts := testutil.MockGlobalData(testcase.args, &stdout) 169 opts.APIClientFactory = mock.APIClient(testcase.api) 170 return opts, nil 171 } 172 err := app.Run(testcase.args, nil) 173 testutil.AssertErrorContains(t, err, testcase.wantError) 174 testutil.AssertString(t, testcase.wantOutput, stdout.String()) 175 }) 176 } 177 } 178 179 func TestElasticsearchUpdate(t *testing.T) { 180 args := testutil.Args 181 scenarios := []struct { 182 args []string 183 api mock.API 184 wantError string 185 wantOutput string 186 }{ 187 { 188 args: args("logging elasticsearch update --service-id 123 --version 1 --new-name log"), 189 wantError: "error parsing arguments: required flag --name not provided", 190 }, 191 { 192 args: args("logging elasticsearch update --service-id 123 --version 1 --name logs --new-name log --autoclone"), 193 api: mock.API{ 194 ListVersionsFn: testutil.ListVersions, 195 CloneVersionFn: testutil.CloneVersionResult(4), 196 UpdateElasticsearchFn: updateElasticsearchError, 197 }, 198 wantError: errTest.Error(), 199 }, 200 { 201 args: args("logging elasticsearch update --service-id 123 --version 1 --name logs --new-name log --autoclone"), 202 api: mock.API{ 203 ListVersionsFn: testutil.ListVersions, 204 CloneVersionFn: testutil.CloneVersionResult(4), 205 UpdateElasticsearchFn: updateElasticsearchOK, 206 }, 207 wantOutput: "Updated Elasticsearch logging endpoint log (service 123 version 4)", 208 }, 209 } 210 for testcaseIdx := range scenarios { 211 testcase := &scenarios[testcaseIdx] 212 t.Run(strings.Join(testcase.args, " "), func(t *testing.T) { 213 var stdout bytes.Buffer 214 app.Init = func(_ []string, _ io.Reader) (*global.Data, error) { 215 opts := testutil.MockGlobalData(testcase.args, &stdout) 216 opts.APIClientFactory = mock.APIClient(testcase.api) 217 return opts, nil 218 } 219 err := app.Run(testcase.args, nil) 220 testutil.AssertErrorContains(t, err, testcase.wantError) 221 testutil.AssertStringContains(t, stdout.String(), testcase.wantOutput) 222 }) 223 } 224 } 225 226 func TestElasticsearchDelete(t *testing.T) { 227 args := testutil.Args 228 scenarios := []struct { 229 args []string 230 api mock.API 231 wantError string 232 wantOutput string 233 }{ 234 { 235 args: args("logging elasticsearch delete --service-id 123 --version 1"), 236 wantError: "error parsing arguments: required flag --name not provided", 237 }, 238 { 239 args: args("logging elasticsearch delete --service-id 123 --version 1 --name logs --autoclone"), 240 api: mock.API{ 241 ListVersionsFn: testutil.ListVersions, 242 CloneVersionFn: testutil.CloneVersionResult(4), 243 DeleteElasticsearchFn: deleteElasticsearchError, 244 }, 245 wantError: errTest.Error(), 246 }, 247 { 248 args: args("logging elasticsearch delete --service-id 123 --version 1 --name logs --autoclone"), 249 api: mock.API{ 250 ListVersionsFn: testutil.ListVersions, 251 CloneVersionFn: testutil.CloneVersionResult(4), 252 DeleteElasticsearchFn: deleteElasticsearchOK, 253 }, 254 wantOutput: "Deleted Elasticsearch logging endpoint logs (service 123 version 4)", 255 }, 256 } 257 for testcaseIdx := range scenarios { 258 testcase := &scenarios[testcaseIdx] 259 t.Run(strings.Join(testcase.args, " "), func(t *testing.T) { 260 var stdout bytes.Buffer 261 app.Init = func(_ []string, _ io.Reader) (*global.Data, error) { 262 opts := testutil.MockGlobalData(testcase.args, &stdout) 263 opts.APIClientFactory = mock.APIClient(testcase.api) 264 return opts, nil 265 } 266 err := app.Run(testcase.args, nil) 267 testutil.AssertErrorContains(t, err, testcase.wantError) 268 testutil.AssertStringContains(t, stdout.String(), testcase.wantOutput) 269 }) 270 } 271 } 272 273 var errTest = errors.New("fixture error") 274 275 func createElasticsearchOK(i *fastly.CreateElasticsearchInput) (*fastly.Elasticsearch, error) { 276 return &fastly.Elasticsearch{ 277 ServiceID: fastly.ToPointer(i.ServiceID), 278 ServiceVersion: fastly.ToPointer(i.ServiceVersion), 279 Name: fastly.ToPointer("log"), 280 ResponseCondition: fastly.ToPointer("Prevent default logging"), 281 Format: fastly.ToPointer(`%h %l %u %t "%r" %>s %b`), 282 Index: fastly.ToPointer("logs"), 283 URL: fastly.ToPointer("example.com"), 284 Pipeline: fastly.ToPointer("logs"), 285 User: fastly.ToPointer("user"), 286 Password: fastly.ToPointer("password"), 287 RequestMaxEntries: fastly.ToPointer(2), 288 RequestMaxBytes: fastly.ToPointer(2), 289 Placement: fastly.ToPointer("none"), 290 TLSCACert: fastly.ToPointer("-----BEGIN CERTIFICATE-----foo"), 291 TLSHostname: fastly.ToPointer("example.com"), 292 TLSClientCert: fastly.ToPointer("-----BEGIN CERTIFICATE-----bar"), 293 TLSClientKey: fastly.ToPointer("-----BEGIN PRIVATE KEY-----bar"), 294 FormatVersion: fastly.ToPointer(2), 295 }, nil 296 } 297 298 func createElasticsearchError(_ *fastly.CreateElasticsearchInput) (*fastly.Elasticsearch, error) { 299 return nil, errTest 300 } 301 302 func listElasticsearchsOK(i *fastly.ListElasticsearchInput) ([]*fastly.Elasticsearch, error) { 303 return []*fastly.Elasticsearch{ 304 { 305 ServiceID: fastly.ToPointer(i.ServiceID), 306 ServiceVersion: fastly.ToPointer(i.ServiceVersion), 307 Name: fastly.ToPointer("logs"), 308 ResponseCondition: fastly.ToPointer("Prevent default logging"), 309 Format: fastly.ToPointer(`%h %l %u %t "%r" %>s %b`), 310 Index: fastly.ToPointer("logs"), 311 URL: fastly.ToPointer("example.com"), 312 Pipeline: fastly.ToPointer("logs"), 313 User: fastly.ToPointer("user"), 314 Password: fastly.ToPointer("password"), 315 RequestMaxEntries: fastly.ToPointer(2), 316 RequestMaxBytes: fastly.ToPointer(2), 317 Placement: fastly.ToPointer("none"), 318 TLSCACert: fastly.ToPointer("-----BEGIN CERTIFICATE-----foo"), 319 TLSHostname: fastly.ToPointer("example.com"), 320 TLSClientCert: fastly.ToPointer("-----BEGIN CERTIFICATE-----bar"), 321 TLSClientKey: fastly.ToPointer("-----BEGIN PRIVATE KEY-----bar"), 322 FormatVersion: fastly.ToPointer(2), 323 }, 324 { 325 ServiceID: fastly.ToPointer(i.ServiceID), 326 ServiceVersion: fastly.ToPointer(i.ServiceVersion), 327 Name: fastly.ToPointer("analytics"), 328 Index: fastly.ToPointer("analytics"), 329 URL: fastly.ToPointer("example.com"), 330 Pipeline: fastly.ToPointer("analytics"), 331 User: fastly.ToPointer("user"), 332 Password: fastly.ToPointer("password"), 333 RequestMaxEntries: fastly.ToPointer(2), 334 RequestMaxBytes: fastly.ToPointer(2), 335 Placement: fastly.ToPointer("none"), 336 TLSCACert: fastly.ToPointer("-----BEGIN CERTIFICATE-----foo"), 337 TLSHostname: fastly.ToPointer("example.com"), 338 TLSClientCert: fastly.ToPointer("-----BEGIN CERTIFICATE-----bar"), 339 TLSClientKey: fastly.ToPointer("-----BEGIN PRIVATE KEY-----bar"), 340 ResponseCondition: fastly.ToPointer("Prevent default logging"), 341 Format: fastly.ToPointer(`%h %l %u %t "%r" %>s %b`), 342 FormatVersion: fastly.ToPointer(2), 343 }, 344 }, nil 345 } 346 347 func listElasticsearchsError(_ *fastly.ListElasticsearchInput) ([]*fastly.Elasticsearch, error) { 348 return nil, errTest 349 } 350 351 var listElasticsearchsShortOutput = strings.TrimSpace(` 352 SERVICE VERSION NAME 353 123 1 logs 354 123 1 analytics 355 `) + "\n" 356 357 var listElasticsearchsVerboseOutput = strings.TrimSpace(` 358 Fastly API endpoint: https://api.fastly.com 359 Fastly API token provided via config file (profile: user) 360 361 Service ID (via --service-id): 123 362 363 Version: 1 364 Elasticsearch 1/2 365 Service ID: 123 366 Version: 1 367 Name: logs 368 Index: logs 369 URL: example.com 370 Pipeline: logs 371 TLS CA certificate: -----BEGIN CERTIFICATE-----foo 372 TLS client certificate: -----BEGIN CERTIFICATE-----bar 373 TLS client key: -----BEGIN PRIVATE KEY-----bar 374 TLS hostname: example.com 375 User: user 376 Password: password 377 Format: %h %l %u %t "%r" %>s %b 378 Format version: 2 379 Response condition: Prevent default logging 380 Placement: none 381 Elasticsearch 2/2 382 Service ID: 123 383 Version: 1 384 Name: analytics 385 Index: analytics 386 URL: example.com 387 Pipeline: analytics 388 TLS CA certificate: -----BEGIN CERTIFICATE-----foo 389 TLS client certificate: -----BEGIN CERTIFICATE-----bar 390 TLS client key: -----BEGIN PRIVATE KEY-----bar 391 TLS hostname: example.com 392 User: user 393 Password: password 394 Format: %h %l %u %t "%r" %>s %b 395 Format version: 2 396 Response condition: Prevent default logging 397 Placement: none 398 `) + "\n\n" 399 400 func getElasticsearchOK(i *fastly.GetElasticsearchInput) (*fastly.Elasticsearch, error) { 401 return &fastly.Elasticsearch{ 402 ServiceID: fastly.ToPointer(i.ServiceID), 403 ServiceVersion: fastly.ToPointer(i.ServiceVersion), 404 Name: fastly.ToPointer("logs"), 405 ResponseCondition: fastly.ToPointer("Prevent default logging"), 406 Format: fastly.ToPointer(`%h %l %u %t "%r" %>s %b`), 407 Index: fastly.ToPointer("logs"), 408 URL: fastly.ToPointer("example.com"), 409 Pipeline: fastly.ToPointer("logs"), 410 User: fastly.ToPointer("user"), 411 Password: fastly.ToPointer("password"), 412 RequestMaxEntries: fastly.ToPointer(2), 413 RequestMaxBytes: fastly.ToPointer(2), 414 Placement: fastly.ToPointer("none"), 415 TLSCACert: fastly.ToPointer("-----BEGIN CERTIFICATE-----foo"), 416 TLSHostname: fastly.ToPointer("example.com"), 417 TLSClientCert: fastly.ToPointer("-----BEGIN CERTIFICATE-----bar"), 418 TLSClientKey: fastly.ToPointer("-----BEGIN PRIVATE KEY-----bar"), 419 FormatVersion: fastly.ToPointer(2), 420 }, nil 421 } 422 423 func getElasticsearchError(_ *fastly.GetElasticsearchInput) (*fastly.Elasticsearch, error) { 424 return nil, errTest 425 } 426 427 var describeElasticsearchOutput = "\n" + strings.TrimSpace(` 428 Format: %h %l %u %t "%r" %>s %b 429 Format version: 2 430 Index: logs 431 Name: logs 432 Password: password 433 Pipeline: logs 434 Placement: none 435 Response condition: Prevent default logging 436 Service ID: 123 437 TLS CA certificate: -----BEGIN CERTIFICATE-----foo 438 TLS client certificate: -----BEGIN CERTIFICATE-----bar 439 TLS client key: -----BEGIN PRIVATE KEY-----bar 440 TLS hostname: example.com 441 URL: example.com 442 User: user 443 Version: 1 444 `) + "\n" 445 446 func updateElasticsearchOK(i *fastly.UpdateElasticsearchInput) (*fastly.Elasticsearch, error) { 447 return &fastly.Elasticsearch{ 448 ServiceID: fastly.ToPointer(i.ServiceID), 449 ServiceVersion: fastly.ToPointer(i.ServiceVersion), 450 Name: fastly.ToPointer("log"), 451 ResponseCondition: fastly.ToPointer("Prevent default logging"), 452 Format: fastly.ToPointer(`%h %l %u %t "%r" %>s %b`), 453 Index: fastly.ToPointer("logs"), 454 URL: fastly.ToPointer("example.com"), 455 Pipeline: fastly.ToPointer("logs"), 456 User: fastly.ToPointer("user"), 457 Password: fastly.ToPointer("password"), 458 RequestMaxEntries: fastly.ToPointer(2), 459 RequestMaxBytes: fastly.ToPointer(2), 460 Placement: fastly.ToPointer("none"), 461 TLSCACert: fastly.ToPointer("-----BEGIN CERTIFICATE-----foo"), 462 TLSHostname: fastly.ToPointer("example.com"), 463 TLSClientCert: fastly.ToPointer("-----BEGIN CERTIFICATE-----bar"), 464 TLSClientKey: fastly.ToPointer("-----BEGIN PRIVATE KEY-----bar"), 465 FormatVersion: fastly.ToPointer(2), 466 }, nil 467 } 468 469 func updateElasticsearchError(_ *fastly.UpdateElasticsearchInput) (*fastly.Elasticsearch, error) { 470 return nil, errTest 471 } 472 473 func deleteElasticsearchOK(_ *fastly.DeleteElasticsearchInput) error { 474 return nil 475 } 476 477 func deleteElasticsearchError(_ *fastly.DeleteElasticsearchInput) error { 478 return errTest 479 }