github.com/fastly/cli@v1.7.2-0.20240304164155-9d0f1d77c3bf/pkg/commands/logging/scalyr/scalyr_integration_test.go (about) 1 package scalyr_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 fsterrs "github.com/fastly/cli/pkg/errors" 14 "github.com/fastly/cli/pkg/global" 15 "github.com/fastly/cli/pkg/mock" 16 "github.com/fastly/cli/pkg/testutil" 17 ) 18 19 func TestScalyrCreate(t *testing.T) { 20 args := testutil.Args 21 scenarios := []struct { 22 args []string 23 api mock.API 24 wantError string 25 wantOutput string 26 }{ 27 { 28 args: args("logging scalyr create --name log --service-id --version 1 --auth-token abc --autoclone"), 29 api: mock.API{ 30 ListVersionsFn: testutil.ListVersions, 31 CloneVersionFn: testutil.CloneVersionResult(4), 32 }, 33 wantError: fsterrs.ErrNoServiceID.Error(), 34 }, 35 { 36 args: args("logging scalyr create --service-id 123 --version 1 --name log --auth-token abc --autoclone"), 37 api: mock.API{ 38 ListVersionsFn: testutil.ListVersions, 39 CloneVersionFn: testutil.CloneVersionResult(4), 40 CreateScalyrFn: createScalyrOK, 41 }, 42 wantOutput: "Created Scalyr logging endpoint log (service 123 version 4)", 43 }, 44 { 45 args: args("logging scalyr create --service-id 123 --version 1 --name log --auth-token abc --autoclone"), 46 api: mock.API{ 47 ListVersionsFn: testutil.ListVersions, 48 CloneVersionFn: testutil.CloneVersionResult(4), 49 CreateScalyrFn: createScalyrError, 50 }, 51 wantError: errTest.Error(), 52 }, 53 } 54 for testcaseIdx := range scenarios { 55 testcase := &scenarios[testcaseIdx] 56 t.Run(strings.Join(testcase.args, " "), func(t *testing.T) { 57 var stdout bytes.Buffer 58 app.Init = func(_ []string, _ io.Reader) (*global.Data, error) { 59 opts := testutil.MockGlobalData(testcase.args, &stdout) 60 opts.APIClientFactory = mock.APIClient(testcase.api) 61 return opts, nil 62 } 63 err := app.Run(testcase.args, nil) 64 testutil.AssertErrorContains(t, err, testcase.wantError) 65 testutil.AssertStringContains(t, stdout.String(), testcase.wantOutput) 66 }) 67 } 68 } 69 70 func TestScalyrList(t *testing.T) { 71 args := testutil.Args 72 scenarios := []struct { 73 args []string 74 api mock.API 75 wantError string 76 wantOutput string 77 }{ 78 { 79 args: args("logging scalyr list --service-id 123 --version 1"), 80 api: mock.API{ 81 ListVersionsFn: testutil.ListVersions, 82 ListScalyrsFn: listScalyrsOK, 83 }, 84 wantOutput: listScalyrsShortOutput, 85 }, 86 { 87 args: args("logging scalyr list --service-id 123 --version 1 --verbose"), 88 api: mock.API{ 89 ListVersionsFn: testutil.ListVersions, 90 ListScalyrsFn: listScalyrsOK, 91 }, 92 wantOutput: listScalyrsVerboseOutput, 93 }, 94 { 95 args: args("logging scalyr list --service-id 123 --version 1 -v"), 96 api: mock.API{ 97 ListVersionsFn: testutil.ListVersions, 98 ListScalyrsFn: listScalyrsOK, 99 }, 100 wantOutput: listScalyrsVerboseOutput, 101 }, 102 { 103 args: args("logging scalyr --verbose list --service-id 123 --version 1"), 104 api: mock.API{ 105 ListVersionsFn: testutil.ListVersions, 106 ListScalyrsFn: listScalyrsOK, 107 }, 108 wantOutput: listScalyrsVerboseOutput, 109 }, 110 { 111 args: args("logging -v scalyr list --service-id 123 --version 1"), 112 api: mock.API{ 113 ListVersionsFn: testutil.ListVersions, 114 ListScalyrsFn: listScalyrsOK, 115 }, 116 wantOutput: listScalyrsVerboseOutput, 117 }, 118 { 119 args: args("logging scalyr list --service-id 123 --version 1"), 120 api: mock.API{ 121 ListVersionsFn: testutil.ListVersions, 122 ListScalyrsFn: listScalyrsError, 123 }, 124 wantError: errTest.Error(), 125 }, 126 } 127 for testcaseIdx := range scenarios { 128 testcase := &scenarios[testcaseIdx] 129 t.Run(strings.Join(testcase.args, " "), func(t *testing.T) { 130 var stdout bytes.Buffer 131 app.Init = func(_ []string, _ io.Reader) (*global.Data, error) { 132 opts := testutil.MockGlobalData(testcase.args, &stdout) 133 opts.APIClientFactory = mock.APIClient(testcase.api) 134 return opts, nil 135 } 136 err := app.Run(testcase.args, nil) 137 testutil.AssertErrorContains(t, err, testcase.wantError) 138 testutil.AssertString(t, testcase.wantOutput, stdout.String()) 139 }) 140 } 141 } 142 143 func TestScalyrDescribe(t *testing.T) { 144 args := testutil.Args 145 scenarios := []struct { 146 args []string 147 api mock.API 148 wantError string 149 wantOutput string 150 }{ 151 { 152 args: args("logging scalyr describe --service-id 123 --version 1"), 153 wantError: "error parsing arguments: required flag --name not provided", 154 }, 155 { 156 args: args("logging scalyr describe --service-id 123 --version 1 --name logs"), 157 api: mock.API{ 158 ListVersionsFn: testutil.ListVersions, 159 GetScalyrFn: getScalyrError, 160 }, 161 wantError: errTest.Error(), 162 }, 163 { 164 args: args("logging scalyr describe --service-id 123 --version 1 --name logs"), 165 api: mock.API{ 166 ListVersionsFn: testutil.ListVersions, 167 GetScalyrFn: getScalyrOK, 168 }, 169 wantOutput: describeScalyrOutput, 170 }, 171 } 172 for testcaseIdx := range scenarios { 173 testcase := &scenarios[testcaseIdx] 174 t.Run(strings.Join(testcase.args, " "), func(t *testing.T) { 175 var stdout bytes.Buffer 176 app.Init = func(_ []string, _ io.Reader) (*global.Data, error) { 177 opts := testutil.MockGlobalData(testcase.args, &stdout) 178 opts.APIClientFactory = mock.APIClient(testcase.api) 179 return opts, nil 180 } 181 err := app.Run(testcase.args, nil) 182 testutil.AssertErrorContains(t, err, testcase.wantError) 183 testutil.AssertString(t, testcase.wantOutput, stdout.String()) 184 }) 185 } 186 } 187 188 func TestScalyrUpdate(t *testing.T) { 189 args := testutil.Args 190 scenarios := []struct { 191 args []string 192 api mock.API 193 wantError string 194 wantOutput string 195 }{ 196 { 197 args: args("logging scalyr update --service-id 123 --version 1 --new-name log"), 198 wantError: "error parsing arguments: required flag --name not provided", 199 }, 200 { 201 args: args("logging scalyr 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 UpdateScalyrFn: updateScalyrError, 206 }, 207 wantError: errTest.Error(), 208 }, 209 { 210 args: args("logging scalyr update --service-id 123 --version 1 --name logs --new-name log --autoclone"), 211 api: mock.API{ 212 ListVersionsFn: testutil.ListVersions, 213 CloneVersionFn: testutil.CloneVersionResult(4), 214 UpdateScalyrFn: updateScalyrOK, 215 }, 216 wantOutput: "Updated Scalyr logging endpoint log (service 123 version 4)", 217 }, 218 } 219 for testcaseIdx := range scenarios { 220 testcase := &scenarios[testcaseIdx] 221 t.Run(strings.Join(testcase.args, " "), func(t *testing.T) { 222 var stdout bytes.Buffer 223 app.Init = func(_ []string, _ io.Reader) (*global.Data, error) { 224 opts := testutil.MockGlobalData(testcase.args, &stdout) 225 opts.APIClientFactory = mock.APIClient(testcase.api) 226 return opts, nil 227 } 228 err := app.Run(testcase.args, nil) 229 testutil.AssertErrorContains(t, err, testcase.wantError) 230 testutil.AssertStringContains(t, stdout.String(), testcase.wantOutput) 231 }) 232 } 233 } 234 235 func TestScalyrDelete(t *testing.T) { 236 args := testutil.Args 237 scenarios := []struct { 238 args []string 239 api mock.API 240 wantError string 241 wantOutput string 242 }{ 243 { 244 args: args("logging scalyr delete --service-id 123 --version 1"), 245 wantError: "error parsing arguments: required flag --name not provided", 246 }, 247 { 248 args: args("logging scalyr delete --service-id 123 --version 1 --name logs --autoclone"), 249 api: mock.API{ 250 ListVersionsFn: testutil.ListVersions, 251 CloneVersionFn: testutil.CloneVersionResult(4), 252 DeleteScalyrFn: deleteScalyrError, 253 }, 254 wantError: errTest.Error(), 255 }, 256 { 257 args: args("logging scalyr delete --service-id 123 --version 1 --name logs --autoclone"), 258 api: mock.API{ 259 ListVersionsFn: testutil.ListVersions, 260 CloneVersionFn: testutil.CloneVersionResult(4), 261 DeleteScalyrFn: deleteScalyrOK, 262 }, 263 wantOutput: "Deleted Scalyr logging endpoint logs (service 123 version 4)", 264 }, 265 } 266 for testcaseIdx := range scenarios { 267 testcase := &scenarios[testcaseIdx] 268 t.Run(strings.Join(testcase.args, " "), func(t *testing.T) { 269 var stdout bytes.Buffer 270 app.Init = func(_ []string, _ io.Reader) (*global.Data, error) { 271 opts := testutil.MockGlobalData(testcase.args, &stdout) 272 opts.APIClientFactory = mock.APIClient(testcase.api) 273 return opts, nil 274 } 275 err := app.Run(testcase.args, nil) 276 testutil.AssertErrorContains(t, err, testcase.wantError) 277 testutil.AssertStringContains(t, stdout.String(), testcase.wantOutput) 278 }) 279 } 280 } 281 282 var errTest = errors.New("fixture error") 283 284 func createScalyrOK(i *fastly.CreateScalyrInput) (*fastly.Scalyr, error) { 285 s := fastly.Scalyr{ 286 ServiceID: fastly.ToPointer(i.ServiceID), 287 ServiceVersion: fastly.ToPointer(i.ServiceVersion), 288 } 289 290 // Avoids null pointer dereference for test cases with missing required params. 291 // If omitted, tests are guaranteed to panic. 292 if i.Name != nil { 293 s.Name = i.Name 294 } 295 296 if i.Token != nil { 297 s.Token = i.Token 298 } 299 300 if i.Format != nil { 301 s.Format = i.Format 302 } 303 304 if i.FormatVersion != nil { 305 s.FormatVersion = i.FormatVersion 306 } 307 308 if i.ResponseCondition != nil { 309 s.ResponseCondition = i.ResponseCondition 310 } 311 312 if i.Placement != nil { 313 s.Placement = i.Placement 314 } 315 316 return &s, nil 317 } 318 319 func createScalyrError(_ *fastly.CreateScalyrInput) (*fastly.Scalyr, error) { 320 return nil, errTest 321 } 322 323 func listScalyrsOK(i *fastly.ListScalyrsInput) ([]*fastly.Scalyr, error) { 324 return []*fastly.Scalyr{ 325 { 326 ServiceID: fastly.ToPointer(i.ServiceID), 327 ServiceVersion: fastly.ToPointer(i.ServiceVersion), 328 Name: fastly.ToPointer("logs"), 329 Token: fastly.ToPointer("abc"), 330 Region: fastly.ToPointer("US"), 331 Format: fastly.ToPointer(`%h %l %u %t "%r" %>s %b`), 332 FormatVersion: fastly.ToPointer(2), 333 ResponseCondition: fastly.ToPointer("Prevent default logging"), 334 Placement: fastly.ToPointer("none"), 335 }, 336 { 337 ServiceID: fastly.ToPointer(i.ServiceID), 338 ServiceVersion: fastly.ToPointer(i.ServiceVersion), 339 Name: fastly.ToPointer("analytics"), 340 Token: fastly.ToPointer("abc"), 341 Region: fastly.ToPointer("US"), 342 Format: fastly.ToPointer(`%h %l %u %t "%r" %>s %b`), 343 FormatVersion: fastly.ToPointer(2), 344 ResponseCondition: fastly.ToPointer("Prevent default logging"), 345 Placement: fastly.ToPointer("none"), 346 }, 347 }, nil 348 } 349 350 func listScalyrsError(_ *fastly.ListScalyrsInput) ([]*fastly.Scalyr, error) { 351 return nil, errTest 352 } 353 354 var listScalyrsShortOutput = strings.TrimSpace(` 355 SERVICE VERSION NAME 356 123 1 logs 357 123 1 analytics 358 `) + "\n" 359 360 var listScalyrsVerboseOutput = strings.TrimSpace(` 361 Fastly API endpoint: https://api.fastly.com 362 Fastly API token provided via config file (profile: user) 363 364 Service ID (via --service-id): 123 365 366 Version: 1 367 Scalyr 1/2 368 Service ID: 123 369 Version: 1 370 Name: logs 371 Token: abc 372 Region: US 373 Format: %h %l %u %t "%r" %>s %b 374 Format version: 2 375 Response condition: Prevent default logging 376 Placement: none 377 Scalyr 2/2 378 Service ID: 123 379 Version: 1 380 Name: analytics 381 Token: abc 382 Region: US 383 Format: %h %l %u %t "%r" %>s %b 384 Format version: 2 385 Response condition: Prevent default logging 386 Placement: none 387 `) + "\n\n" 388 389 func getScalyrOK(i *fastly.GetScalyrInput) (*fastly.Scalyr, error) { 390 return &fastly.Scalyr{ 391 ServiceID: fastly.ToPointer(i.ServiceID), 392 ServiceVersion: fastly.ToPointer(i.ServiceVersion), 393 Name: fastly.ToPointer("logs"), 394 Token: fastly.ToPointer("abc"), 395 Region: fastly.ToPointer("US"), 396 Format: fastly.ToPointer(`%h %l %u %t "%r" %>s %b`), 397 FormatVersion: fastly.ToPointer(2), 398 ResponseCondition: fastly.ToPointer("Prevent default logging"), 399 Placement: fastly.ToPointer("none"), 400 }, nil 401 } 402 403 func getScalyrError(_ *fastly.GetScalyrInput) (*fastly.Scalyr, error) { 404 return nil, errTest 405 } 406 407 var describeScalyrOutput = "\n" + strings.TrimSpace(` 408 Format: %h %l %u %t "%r" %>s %b 409 Format version: 2 410 Name: logs 411 Placement: none 412 Region: US 413 Response condition: Prevent default logging 414 Service ID: 123 415 Token: abc 416 Version: 1 417 `) + "\n" 418 419 func updateScalyrOK(i *fastly.UpdateScalyrInput) (*fastly.Scalyr, error) { 420 return &fastly.Scalyr{ 421 ServiceID: fastly.ToPointer(i.ServiceID), 422 ServiceVersion: fastly.ToPointer(i.ServiceVersion), 423 Name: fastly.ToPointer("log"), 424 Token: fastly.ToPointer("abc"), 425 Region: fastly.ToPointer("EU"), 426 Format: fastly.ToPointer(`%h %l %u %t "%r" %>s %b`), 427 FormatVersion: fastly.ToPointer(2), 428 ResponseCondition: fastly.ToPointer("Prevent default logging"), 429 Placement: fastly.ToPointer("none"), 430 }, nil 431 } 432 433 func updateScalyrError(_ *fastly.UpdateScalyrInput) (*fastly.Scalyr, error) { 434 return nil, errTest 435 } 436 437 func deleteScalyrOK(_ *fastly.DeleteScalyrInput) error { 438 return nil 439 } 440 441 func deleteScalyrError(_ *fastly.DeleteScalyrInput) error { 442 return errTest 443 }