github.com/newrelic/newrelic-client-go@v1.1.0/pkg/alerts/nrql_conditions_integration_test.go (about) 1 //go:build integration 2 // +build integration 3 4 package alerts 5 6 import ( 7 "fmt" 8 "testing" 9 10 "github.com/stretchr/testify/require" 11 12 "github.com/newrelic/newrelic-client-go/pkg/errors" 13 14 mock "github.com/newrelic/newrelic-client-go/pkg/testhelpers" 15 ) 16 17 var ( 18 testNrqlConditionRandomString = mock.RandSeq(5) 19 nrqlConditionBaseThreshold = 1.0 // needed for setting pointer 20 nrqlConditionBaseThresholdZeroValue = float64(0) // needed for setting pointer 21 nrqlConditionBaseSignalFillValue = float64(0.1) // needed for setting pointer 22 nrqlConditionBaseExpirationDuration = 1200 // needed for setting pointer 23 nrqlConditionBaseEvalOffset = 3 // needed for setting pointer 24 nrqlConditionBaseAggWindow = 60 // needed for setting pointer 25 nrqlConditionBaseAggMethod = NrqlConditionAggregationMethodTypes.Cadence // needed for setting pointer 26 nrqlConditionBaseAggDelay = 2 // needed for setting pointer 27 nrqlConditionBaseAggTimer = 5 // needed for setting pointer 28 nrqlConditionBaseSlideBy = 30 // needed for setting pointer 29 nrqlConditionBaseValueFunction = NrqlConditionValueFunctions.SingleValue // needed for setting pointer 30 31 nrqlConditionCreateBase = NrqlConditionCreateBase{ 32 Description: "test description", 33 Enabled: true, 34 Name: fmt.Sprintf("test-nrql-condition-%s", testNrqlConditionRandomString), 35 Nrql: NrqlConditionCreateQuery{ 36 Query: "SELECT rate(sum(apm.service.cpu.usertime.utilization), 1 second) * 100 as cpuUsage FROM Metric WHERE appName like 'Dummy App'", 37 EvaluationOffset: &nrqlConditionBaseEvalOffset, 38 }, 39 RunbookURL: "test.com", 40 Terms: []NrqlConditionTerm{ 41 { 42 Threshold: &nrqlConditionBaseThreshold, 43 ThresholdOccurrences: ThresholdOccurrences.AtLeastOnce, 44 ThresholdDuration: 600, 45 Operator: AlertsNRQLConditionTermsOperatorTypes.ABOVE, 46 Priority: NrqlConditionPriorities.Critical, 47 }, 48 }, 49 ViolationTimeLimitSeconds: 3600, 50 Expiration: &AlertsNrqlConditionExpiration{ 51 CloseViolationsOnExpiration: true, 52 ExpirationDuration: &nrqlConditionBaseExpirationDuration, 53 OpenViolationOnExpiration: false, 54 }, 55 Signal: &AlertsNrqlConditionCreateSignal{ 56 AggregationWindow: &nrqlConditionBaseAggWindow, 57 EvaluationOffset: &nrqlConditionBaseEvalOffset, 58 FillOption: &AlertsFillOptionTypes.STATIC, 59 FillValue: &nrqlConditionBaseSignalFillValue, 60 }, 61 } 62 63 nrqlConditionUpdateBase = NrqlConditionUpdateBase{ 64 Description: "test description", 65 Enabled: true, 66 Name: fmt.Sprintf("test-nrql-condition-%s", testNrqlConditionRandomString), 67 Nrql: NrqlConditionUpdateQuery{ 68 Query: "SELECT rate(sum(apm.service.cpu.usertime.utilization), 1 second) * 100 as cpuUsage FROM Metric WHERE appName like 'Dummy App'", 69 EvaluationOffset: &nrqlConditionBaseEvalOffset, 70 }, 71 RunbookURL: "test.com", 72 Terms: []NrqlConditionTerm{ 73 { 74 Threshold: &nrqlConditionBaseThreshold, 75 ThresholdOccurrences: ThresholdOccurrences.AtLeastOnce, 76 ThresholdDuration: 600, 77 Operator: AlertsNRQLConditionTermsOperatorTypes.ABOVE, 78 Priority: NrqlConditionPriorities.Critical, 79 }, 80 }, 81 ViolationTimeLimitSeconds: 3600, 82 Expiration: &AlertsNrqlConditionExpiration{ 83 CloseViolationsOnExpiration: true, 84 ExpirationDuration: &nrqlConditionBaseExpirationDuration, 85 OpenViolationOnExpiration: false, 86 }, 87 Signal: &AlertsNrqlConditionUpdateSignal{ 88 AggregationWindow: &nrqlConditionBaseAggWindow, 89 EvaluationOffset: &nrqlConditionBaseEvalOffset, 90 FillOption: &AlertsFillOptionTypes.STATIC, 91 FillValue: &nrqlConditionBaseSignalFillValue, 92 }, 93 } 94 95 nrqlConditionCreateWithStreamingMethods = NrqlConditionCreateBase{ 96 Description: "test description", 97 Enabled: true, 98 Name: fmt.Sprintf("test-nrql-condition-%s", testNrqlConditionRandomString), 99 Nrql: NrqlConditionCreateQuery{ 100 Query: "SELECT rate(sum(apm.service.cpu.usertime.utilization), 1 second) * 100 as cpuUsage FROM Metric WHERE appName like 'Dummy App'", 101 }, 102 RunbookURL: "test.com", 103 Terms: []NrqlConditionTerm{ 104 { 105 Threshold: &nrqlConditionBaseThreshold, 106 ThresholdOccurrences: ThresholdOccurrences.AtLeastOnce, 107 ThresholdDuration: 600, 108 Operator: AlertsNRQLConditionTermsOperatorTypes.ABOVE, 109 Priority: NrqlConditionPriorities.Critical, 110 }, 111 }, 112 ViolationTimeLimitSeconds: 3600, 113 Expiration: &AlertsNrqlConditionExpiration{ 114 CloseViolationsOnExpiration: true, 115 ExpirationDuration: &nrqlConditionBaseExpirationDuration, 116 OpenViolationOnExpiration: false, 117 }, 118 Signal: &AlertsNrqlConditionCreateSignal{ 119 AggregationWindow: &nrqlConditionBaseAggWindow, 120 FillOption: &AlertsFillOptionTypes.STATIC, 121 FillValue: &nrqlConditionBaseSignalFillValue, 122 AggregationMethod: &nrqlConditionBaseAggMethod, 123 AggregationDelay: &nrqlConditionBaseAggDelay, 124 }, 125 } 126 127 nrqlConditionUpdateWithStreamingMethods = NrqlConditionUpdateBase{ 128 Description: "test description", 129 Enabled: true, 130 Name: fmt.Sprintf("test-nrql-condition-%s", testNrqlConditionRandomString), 131 Nrql: NrqlConditionUpdateQuery{ 132 Query: "SELECT rate(sum(apm.service.cpu.usertime.utilization), 1 second) * 100 as cpuUsage FROM Metric WHERE appName like 'Dummy App'", 133 }, 134 RunbookURL: "test.com", 135 Terms: []NrqlConditionTerm{ 136 { 137 Threshold: &nrqlConditionBaseThreshold, 138 ThresholdOccurrences: ThresholdOccurrences.AtLeastOnce, 139 ThresholdDuration: 600, 140 Operator: AlertsNRQLConditionTermsOperatorTypes.ABOVE, 141 Priority: NrqlConditionPriorities.Critical, 142 }, 143 }, 144 ViolationTimeLimitSeconds: 3600, 145 Expiration: &AlertsNrqlConditionExpiration{ 146 CloseViolationsOnExpiration: true, 147 ExpirationDuration: &nrqlConditionBaseExpirationDuration, 148 OpenViolationOnExpiration: false, 149 }, 150 Signal: &AlertsNrqlConditionUpdateSignal{ 151 AggregationWindow: &nrqlConditionBaseAggWindow, 152 FillOption: &AlertsFillOptionTypes.STATIC, 153 FillValue: &nrqlConditionBaseSignalFillValue, 154 AggregationMethod: &nrqlConditionBaseAggMethod, 155 AggregationDelay: &nrqlConditionBaseAggDelay, 156 }, 157 } 158 159 nrqlConditionCreateWithSlideBy = NrqlConditionCreateBase{ 160 Description: "test description", 161 Enabled: true, 162 Name: fmt.Sprintf("test-nrql-condition-%s", testNrqlConditionRandomString), 163 Nrql: NrqlConditionCreateQuery{ 164 Query: "SELECT rate(sum(apm.service.cpu.usertime.utilization), 1 second) * 100 as cpuUsage FROM Metric WHERE appName like 'Dummy App' FACET OtherStuff", 165 }, 166 RunbookURL: "test.com", 167 Terms: []NrqlConditionTerm{ 168 { 169 Threshold: &nrqlConditionBaseThreshold, 170 ThresholdOccurrences: ThresholdOccurrences.AtLeastOnce, 171 ThresholdDuration: 600, 172 Operator: AlertsNRQLConditionTermsOperatorTypes.ABOVE, 173 Priority: NrqlConditionPriorities.Critical, 174 }, 175 }, 176 ViolationTimeLimitSeconds: 3600, 177 Expiration: &AlertsNrqlConditionExpiration{ 178 CloseViolationsOnExpiration: true, 179 ExpirationDuration: &nrqlConditionBaseExpirationDuration, 180 OpenViolationOnExpiration: false, 181 }, 182 Signal: &AlertsNrqlConditionCreateSignal{ 183 AggregationWindow: &nrqlConditionBaseAggWindow, 184 FillOption: &AlertsFillOptionTypes.STATIC, 185 FillValue: &nrqlConditionBaseSignalFillValue, 186 AggregationMethod: &nrqlConditionBaseAggMethod, 187 AggregationDelay: &nrqlConditionBaseAggDelay, 188 SlideBy: &nrqlConditionBaseSlideBy, 189 }, 190 } 191 192 nrqlConditionUpdateWithSlideBy = NrqlConditionUpdateBase{ 193 Description: "test description", 194 Enabled: true, 195 Name: fmt.Sprintf("test-nrql-condition-%s", testNrqlConditionRandomString), 196 Nrql: NrqlConditionUpdateQuery{ 197 Query: "SELECT rate(sum(apm.service.cpu.usertime.utilization), 1 second) * 100 as cpuUsage FROM Metric WHERE appName like 'Dummy App'", 198 }, 199 RunbookURL: "test.com", 200 Terms: []NrqlConditionTerm{ 201 { 202 Threshold: &nrqlConditionBaseThreshold, 203 ThresholdOccurrences: ThresholdOccurrences.AtLeastOnce, 204 ThresholdDuration: 600, 205 Operator: AlertsNRQLConditionTermsOperatorTypes.ABOVE, 206 Priority: NrqlConditionPriorities.Critical, 207 }, 208 }, 209 ViolationTimeLimitSeconds: 3600, 210 Expiration: &AlertsNrqlConditionExpiration{ 211 CloseViolationsOnExpiration: true, 212 ExpirationDuration: &nrqlConditionBaseExpirationDuration, 213 OpenViolationOnExpiration: false, 214 }, 215 Signal: &AlertsNrqlConditionUpdateSignal{ 216 AggregationWindow: &nrqlConditionBaseAggWindow, 217 FillOption: &AlertsFillOptionTypes.STATIC, 218 FillValue: &nrqlConditionBaseSignalFillValue, 219 AggregationMethod: &nrqlConditionBaseAggMethod, 220 AggregationDelay: &nrqlConditionBaseAggDelay, 221 SlideBy: &nrqlConditionBaseSlideBy, 222 }, 223 } 224 ) 225 226 //REST API integration test (deprecated) 227 func TestIntegrationNrqlConditions(t *testing.T) { 228 t.Parallel() 229 230 var ( 231 randomString = mock.RandSeq(5) 232 alertPolicy = Policy{ 233 Name: fmt.Sprintf("test-integration-nrql-policy-%s", randomString), 234 IncidentPreference: "PER_POLICY", 235 } 236 nrqlConditionName = fmt.Sprintf("test-integration-nrql-condition-%s", randomString) 237 nrqlConditionNameUpdated = fmt.Sprintf("test-integration-nrql-condition-updated-%s", randomString) 238 nrqlCondition = NrqlCondition{ 239 Nrql: NrqlQuery{ 240 Query: "SELECT count(*) FROM Transactions", 241 SinceValue: "3", 242 }, 243 Terms: []ConditionTerm{ 244 { 245 Duration: 5, 246 Operator: "above", 247 Priority: "critical", 248 Threshold: nrqlConditionBaseThreshold, 249 TimeFunction: "all", 250 }, 251 }, 252 Type: "static", 253 Name: nrqlConditionName, 254 RunbookURL: "https://www.example.com", 255 ValueFunction: "single_value", 256 ViolationCloseTimer: 3600, 257 Enabled: true, 258 } 259 ) 260 261 client := newIntegrationTestClient(t) 262 263 // Setup 264 policy, err := client.CreatePolicy(alertPolicy) 265 266 require.NoError(t, err) 267 268 // Deferred teardown 269 defer func() { 270 _, err := client.DeletePolicy(policy.ID) 271 272 if err != nil { 273 t.Logf("error cleaning up alert policy %d (%s): %s", policy.ID, policy.Name, err) 274 } 275 }() 276 277 // Test: Create 278 createResult, err := client.CreateNrqlCondition(policy.ID, nrqlCondition) 279 280 require.NoError(t, err) 281 require.NotNil(t, createResult) 282 283 // Test: List 284 listResult, err := client.ListNrqlConditions(policy.ID) 285 286 require.NoError(t, err) 287 require.Greater(t, len(listResult), 0) 288 289 // Test: Get 290 readResult, err := client.GetNrqlCondition(policy.ID, createResult.ID) 291 292 require.NoError(t, err) 293 require.NotNil(t, readResult) 294 295 // Test: Update 296 createResult.Name = nrqlConditionNameUpdated 297 updateResult, err := client.UpdateNrqlCondition(*createResult) 298 299 require.NoError(t, err) 300 require.NotNil(t, updateResult) 301 require.Equal(t, nrqlConditionNameUpdated, updateResult.Name) 302 303 // Test: Delete 304 result, err := client.DeleteNrqlCondition(updateResult.ID) 305 306 require.NoError(t, err) 307 require.NotNil(t, result) 308 } 309 310 func TestIntegrationNrqlConditions_Baseline(t *testing.T) { 311 t.Parallel() 312 313 testAccountID, err := mock.GetTestAccountID() 314 if err != nil { 315 t.Skipf("%s", err) 316 } 317 318 var ( 319 randStr = mock.RandSeq(5) 320 createBaselineInput = NrqlConditionCreateInput{ 321 NrqlConditionCreateBase: nrqlConditionCreateWithSlideBy, 322 BaselineDirection: &NrqlBaselineDirections.LowerOnly, 323 } 324 updateBaselineInput = NrqlConditionUpdateInput{ 325 NrqlConditionUpdateBase: nrqlConditionUpdateWithSlideBy, 326 BaselineDirection: &NrqlBaselineDirections.LowerOnly, 327 } 328 ) 329 330 // Setup 331 client := newIntegrationTestClient(t) 332 testPolicy := AlertsPolicyInput{ 333 IncidentPreference: AlertsIncidentPreferenceTypes.PER_POLICY, 334 Name: fmt.Sprintf("test-alert-policy-%s", randStr), 335 } 336 policy, err := client.CreatePolicyMutation(testAccountID, testPolicy) 337 require.NoError(t, err) 338 339 // Test: Create (baseline condition) 340 created, err := client.CreateNrqlConditionBaselineMutation(testAccountID, policy.ID, createBaselineInput) 341 require.NoError(t, err) 342 require.NotNil(t, created) 343 require.NotNil(t, created.ID) 344 require.NotNil(t, created.PolicyID) 345 require.NotNil(t, created.Signal) 346 require.NotNil(t, created.Expiration) 347 require.Equal(t, NrqlConditionType("BASELINE"), created.Type) 348 349 // Test: Get (baseline condition) 350 require.NoError(t, err) 351 readResult, err := client.GetNrqlConditionQuery(testAccountID, created.ID) 352 require.NoError(t, err) 353 require.NotNil(t, readResult) 354 require.Equal(t, NrqlConditionType("BASELINE"), readResult.Type) 355 require.Equal(t, "test description", readResult.Description) 356 357 // Test: Update (baseline condition) 358 // There is currently a timing issue with this test. 359 // TODO: Once the upstream is fixed, test the updated fields to ensure the this worked 360 updateBaselineInput.Description = "test description updated" 361 _, err = client.UpdateNrqlConditionBaselineMutation(testAccountID, created.ID, updateBaselineInput) 362 require.NoError(t, err) 363 364 // Deferred teardown 365 defer func() { 366 _, err := client.DeletePolicyMutation(testAccountID, policy.ID) 367 if err != nil { 368 t.Logf("error cleaning up alert policy %s (%s): %s", policy.ID, policy.Name, err) 369 } 370 }() 371 } 372 373 func TestIntegrationNrqlConditions_Static(t *testing.T) { 374 t.Parallel() 375 376 testAccountID, err := mock.GetTestAccountID() 377 if err != nil { 378 t.Skipf("%s", err) 379 } 380 381 var ( 382 randStr = mock.RandSeq(5) 383 createStaticInput = NrqlConditionCreateInput{ 384 NrqlConditionCreateBase: nrqlConditionCreateBase, 385 ValueFunction: &NrqlConditionValueFunctions.SingleValue, 386 } 387 updateStaticInput = NrqlConditionUpdateInput{ 388 NrqlConditionUpdateBase: nrqlConditionUpdateBase, 389 ValueFunction: &NrqlConditionValueFunctions.SingleValue, 390 } 391 ) 392 393 // Setup 394 client := newIntegrationTestClient(t) 395 testPolicy := AlertsPolicyInput{ 396 IncidentPreference: AlertsIncidentPreferenceTypes.PER_POLICY, 397 Name: fmt.Sprintf("test-alert-policy-%s", randStr), 398 } 399 policy, err := client.CreatePolicyMutation(testAccountID, testPolicy) 400 require.NoError(t, err) 401 402 // Test: Create (static condition) 403 createdStatic, err := client.CreateNrqlConditionStaticMutation(testAccountID, policy.ID, createStaticInput) 404 require.NoError(t, err) 405 require.NotNil(t, createdStatic) 406 require.NotNil(t, createdStatic.ID) 407 require.NotNil(t, createdStatic.PolicyID) 408 require.NotNil(t, createdStatic.Signal) 409 require.NotNil(t, createdStatic.Expiration) 410 require.Equal(t, NrqlConditionType("STATIC"), createdStatic.Type) 411 412 // Test: Get (static condition) 413 readResult, err := client.GetNrqlConditionQuery(testAccountID, createdStatic.ID) 414 require.NoError(t, err) 415 require.NotNil(t, readResult) 416 require.Equal(t, NrqlConditionType("STATIC"), readResult.Type) 417 require.Equal(t, "test description", readResult.Description) 418 419 // Test: Update (static condition) 420 // There is currently a timing issue with this test. 421 // TODO: Once the upstream is fixed, test the updated fields to ensure the this worked 422 updateStaticInput.Description = "test description updated" 423 _, err = client.UpdateNrqlConditionStaticMutation(testAccountID, readResult.ID, updateStaticInput) 424 require.NoError(t, err) 425 426 // Deferred teardown 427 defer func() { 428 _, err := client.DeletePolicyMutation(testAccountID, policy.ID) 429 if err != nil { 430 t.Logf("error cleaning up alert policy %s (%s): %s", policy.ID, policy.Name, err) 431 } 432 }() 433 } 434 435 func TestIntegrationNrqlConditions_ErrorScenarios(t *testing.T) { 436 t.Parallel() 437 438 testAccountID, err := mock.GetTestAccountID() 439 if err != nil { 440 t.Skipf("%s", err) 441 } 442 443 var ( 444 randStr = mock.RandSeq(5) 445 446 // Invalid NrqlConditionCreateInput (Baseline and ValueFunction cannot exist together) 447 testInvalidMutationCreateInput = NrqlConditionCreateInput{ 448 NrqlConditionCreateBase: nrqlConditionCreateBase, 449 450 // Having both of the following fields should result in an error returned from the API 451 BaselineDirection: &NrqlBaselineDirections.LowerOnly, 452 ValueFunction: &NrqlConditionValueFunctions.SingleValue, 453 } 454 455 // Invalid NrqlConditionUpdateInput (Baseline and ValueFunction cannot exist together) 456 testInvalidMutationUpdateInput = NrqlConditionUpdateInput{ 457 NrqlConditionUpdateBase: nrqlConditionUpdateBase, 458 459 // Having both of the following fields should result in an error returned from the API 460 BaselineDirection: &NrqlBaselineDirections.LowerOnly, 461 ValueFunction: &NrqlConditionValueFunctions.SingleValue, 462 } 463 ) 464 465 // Setup 466 client := newIntegrationTestClient(t) 467 testPolicy := AlertsPolicyInput{ 468 IncidentPreference: AlertsIncidentPreferenceTypes.PER_POLICY, 469 Name: fmt.Sprintf("test-alert-policy-%s", randStr), 470 } 471 policy, err := client.CreatePolicyMutation(testAccountID, testPolicy) 472 require.NoError(t, err) 473 474 // Test: Create Invalid (should result in an error) 475 createdBaseline, err := client.CreateNrqlConditionBaselineMutation(testAccountID, policy.ID, testInvalidMutationCreateInput) 476 require.Error(t, err) 477 require.Nil(t, createdBaseline) 478 479 // Test: Update Invalid (should result in an error) 480 updatedBaseline, err := client.UpdateNrqlConditionBaselineMutation(testAccountID, "8675309", testInvalidMutationUpdateInput) 481 require.Error(t, err) 482 require.Nil(t, updatedBaseline) 483 484 // Test: Create Invalid (should result in an error) 485 createdStatic, err := client.CreateNrqlConditionStaticMutation(testAccountID, policy.ID, testInvalidMutationCreateInput) 486 require.Error(t, err) 487 require.Nil(t, createdStatic) 488 489 // Test: Update Invalid (should result in an error) 490 updatedStatic, err := client.UpdateNrqlConditionStaticMutation(testAccountID, "8675309", testInvalidMutationUpdateInput) 491 require.Error(t, err) 492 require.Nil(t, updatedStatic) 493 494 // Test: 'Not Found' error for non-existent condition 495 _, err = client.GetNrqlConditionQuery(testAccountID, "999999999999999") 496 require.Error(t, err) 497 _, ok := err.(*errors.NotFound) 498 require.True(t, ok) 499 500 // Deferred teardown 501 defer func() { 502 _, err := client.DeletePolicyMutation(testAccountID, policy.ID) 503 if err != nil { 504 t.Logf("error cleaning up alert policy %s (%s): %s", policy.ID, policy.Name, err) 505 } 506 }() 507 } 508 509 func TestIntegrationNrqlConditions_Search(t *testing.T) { 510 t.Parallel() 511 512 testAccountID, err := mock.GetTestAccountID() 513 if err != nil { 514 t.Skipf("%s", err) 515 } 516 517 var ( 518 randStr = mock.RandSeq(5) 519 conditionName = fmt.Sprintf("test-nrql-condition-%s", randStr) 520 thresholdCritical = 1.0 521 testConditionInput = NrqlConditionCreateInput{ 522 NrqlConditionCreateBase: NrqlConditionCreateBase{ 523 Description: "test description", 524 Enabled: true, 525 Name: conditionName, 526 Nrql: NrqlConditionCreateQuery{ 527 Query: "SELECT rate(sum(apm.service.cpu.usertime.utilization), 1 second) * 100 as cpuUsage FROM Metric WHERE appName like 'Dummy App'", 528 EvaluationOffset: &nrqlConditionBaseEvalOffset, 529 }, 530 RunbookURL: "test.com", 531 Terms: []NrqlConditionTerm{ 532 { 533 Threshold: &thresholdCritical, 534 ThresholdOccurrences: ThresholdOccurrences.AtLeastOnce, 535 ThresholdDuration: 600, 536 Operator: AlertsNRQLConditionTermsOperatorTypes.ABOVE, 537 Priority: NrqlConditionPriorities.Critical, 538 }, 539 }, 540 ViolationTimeLimitSeconds: 3600, 541 }, 542 BaselineDirection: &NrqlBaselineDirections.LowerOnly, 543 } 544 searchCriteria = NrqlConditionsSearchCriteria{ 545 NameLike: conditionName, 546 } 547 ) 548 549 client := newIntegrationTestClient(t) 550 551 // Setup 552 setupPolicy := AlertsPolicyInput{ 553 IncidentPreference: AlertsIncidentPreferenceTypes.PER_POLICY, 554 Name: fmt.Sprintf("test-alert-policy-%s", randStr), 555 } 556 policy, err := client.CreatePolicyMutation(testAccountID, setupPolicy) 557 require.NoError(t, err) 558 559 condition, err := client.CreateNrqlConditionBaselineMutation(testAccountID, policy.ID, testConditionInput) 560 require.NoError(t, err) 561 require.NotNil(t, condition) 562 563 // Test: Search 564 searchResults, err := client.SearchNrqlConditionsQuery(testAccountID, searchCriteria) 565 require.NoError(t, err) 566 require.Greater(t, len(searchResults), 0) 567 568 // Deferred teardown 569 defer func() { 570 _, err := client.DeletePolicyMutation(testAccountID, policy.ID) 571 if err != nil { 572 t.Logf("error cleaning up alert policy %s (%s): %s", policy.ID, policy.Name, err) 573 } 574 }() 575 } 576 577 func TestIntegrationNrqlConditions_CreateStatic(t *testing.T) { 578 t.Parallel() 579 580 testAccountID, err := mock.GetTestAccountID() 581 if err != nil { 582 t.Skipf("%s", err) 583 } 584 585 var ( 586 randStr = mock.RandSeq(5) 587 conditionName = fmt.Sprintf("test-nrql-condition-%s", randStr) 588 testConditionInput = NrqlConditionCreateInput{ 589 NrqlConditionCreateBase: NrqlConditionCreateBase{ 590 Description: "test description", 591 Enabled: true, 592 Name: conditionName, 593 Nrql: NrqlConditionCreateQuery{ 594 Query: "SELECT rate(sum(apm.service.cpu.usertime.utilization), 1 second) * 100 as cpuUsage FROM Metric WHERE appName like 'Dummy App'", 595 EvaluationOffset: &nrqlConditionBaseEvalOffset, 596 }, 597 RunbookURL: "test.com", 598 Terms: []NrqlConditionTerm{ 599 { 600 Threshold: &nrqlConditionBaseThreshold, 601 ThresholdOccurrences: ThresholdOccurrences.AtLeastOnce, 602 ThresholdDuration: 600, 603 Operator: AlertsNRQLConditionTermsOperatorTypes.ABOVE, 604 Priority: NrqlConditionPriorities.Critical, 605 }, 606 { 607 Threshold: &nrqlConditionBaseThresholdZeroValue, 608 ThresholdOccurrences: ThresholdOccurrences.AtLeastOnce, 609 ThresholdDuration: 600, 610 Operator: AlertsNRQLConditionTermsOperatorTypes.EQUALS, 611 Priority: NrqlConditionPriorities.Warning, 612 }, 613 }, 614 ViolationTimeLimitSeconds: 3600, 615 }, 616 ValueFunction: &NrqlConditionValueFunctions.SingleValue, 617 } 618 ) 619 620 client := newIntegrationTestClient(t) 621 622 // Setup 623 setupPolicy := AlertsPolicyInput{ 624 IncidentPreference: AlertsIncidentPreferenceTypes.PER_POLICY, 625 Name: fmt.Sprintf("test-alert-policy-%s", randStr), 626 } 627 policy, err := client.CreatePolicyMutation(testAccountID, setupPolicy) 628 require.NoError(t, err) 629 630 condition, err := client.CreateNrqlConditionStaticMutation(testAccountID, policy.ID, testConditionInput) 631 require.NoError(t, err) 632 require.NotNil(t, condition) 633 634 // Deferred teardown 635 defer func() { 636 _, err := client.DeletePolicyMutation(testAccountID, policy.ID) 637 if err != nil { 638 t.Logf("error cleaning up alert policy %s (%s): %s", policy.ID, policy.Name, err) 639 } 640 }() 641 } 642 643 func TestIntegrationNrqlConditions_ZeroValueThreshold(t *testing.T) { 644 t.Parallel() 645 646 testAccountID, err := mock.GetTestAccountID() 647 if err != nil { 648 t.Skipf("%s", err) 649 } 650 651 var ( 652 randStr = mock.RandSeq(5) 653 conditionName = fmt.Sprintf("test-nrql-condition-%s", randStr) 654 testConditionInput = NrqlConditionCreateInput{ 655 NrqlConditionCreateBase: NrqlConditionCreateBase{ 656 Description: "test description", 657 Enabled: true, 658 Name: conditionName, 659 Nrql: NrqlConditionCreateQuery{ 660 Query: "SELECT rate(sum(apm.service.cpu.usertime.utilization), 1 second) * 100 as cpuUsage FROM Metric WHERE appName like 'Dummy App'", 661 EvaluationOffset: &nrqlConditionBaseEvalOffset, 662 }, 663 RunbookURL: "test.com", 664 Terms: []NrqlConditionTerm{ 665 { 666 Threshold: &nrqlConditionBaseThresholdZeroValue, 667 ThresholdOccurrences: ThresholdOccurrences.AtLeastOnce, 668 ThresholdDuration: 600, 669 Operator: AlertsNRQLConditionTermsOperatorTypes.ABOVE, 670 Priority: NrqlConditionPriorities.Critical, 671 }, 672 }, 673 ViolationTimeLimitSeconds: 3600, 674 }, 675 ValueFunction: &NrqlConditionValueFunctions.SingleValue, 676 } 677 ) 678 679 client := newIntegrationTestClient(t) 680 681 // Setup 682 setupPolicy := AlertsPolicyInput{ 683 IncidentPreference: AlertsIncidentPreferenceTypes.PER_POLICY, 684 Name: fmt.Sprintf("test-alert-policy-%s", randStr), 685 } 686 policy, err := client.CreatePolicyMutation(testAccountID, setupPolicy) 687 require.NoError(t, err) 688 689 condition, err := client.CreateNrqlConditionStaticMutation(testAccountID, policy.ID, testConditionInput) 690 require.NoError(t, err) 691 require.NotNil(t, condition) 692 693 // Deferred teardown 694 defer func() { 695 _, err := client.DeletePolicyMutation(testAccountID, policy.ID) 696 if err != nil { 697 t.Logf("error cleaning up alert policy %s (%s): %s", policy.ID, policy.Name, err) 698 } 699 }() 700 } 701 702 func TestIntegrationNrqlConditions_StreamingMethods(t *testing.T) { 703 t.Parallel() 704 705 testAccountID, err := mock.GetTestAccountID() 706 if err != nil { 707 t.Skipf("%s", err) 708 } 709 710 var ( 711 randStr = mock.RandSeq(5) 712 createStreamingMethodsInput = NrqlConditionCreateInput{ 713 NrqlConditionCreateBase: nrqlConditionCreateWithStreamingMethods, 714 ValueFunction: &NrqlConditionValueFunctions.SingleValue, 715 } 716 updateStreamingMethodsInput = NrqlConditionUpdateInput{ 717 NrqlConditionUpdateBase: nrqlConditionUpdateWithStreamingMethods, 718 ValueFunction: &NrqlConditionValueFunctions.SingleValue, 719 } 720 ) 721 722 // Setup 723 client := newIntegrationTestClient(t) 724 testPolicy := AlertsPolicyInput{ 725 IncidentPreference: AlertsIncidentPreferenceTypes.PER_POLICY, 726 Name: fmt.Sprintf("test-alert-policy-%s", randStr), 727 } 728 policy, err := client.CreatePolicyMutation(testAccountID, testPolicy) 729 require.NoError(t, err) 730 731 // Test: Create (static condition with streaming methods fields) 732 createdStaticWithStreamingMethods, err := client.CreateNrqlConditionStaticMutation(testAccountID, policy.ID, createStreamingMethodsInput) 733 require.NoError(t, err) 734 require.NotNil(t, createdStaticWithStreamingMethods) 735 require.NotNil(t, createdStaticWithStreamingMethods.ID) 736 require.NotNil(t, createdStaticWithStreamingMethods.PolicyID) 737 require.NotNil(t, createdStaticWithStreamingMethods.Signal) 738 require.NotNil(t, createdStaticWithStreamingMethods.Expiration) 739 require.Equal(t, &nrqlConditionBaseAggMethod, createdStaticWithStreamingMethods.Signal.AggregationMethod) 740 741 // Test: Get (static condition with streaming methods fields) 742 readResult, err := client.GetNrqlConditionQuery(testAccountID, createdStaticWithStreamingMethods.ID) 743 require.NoError(t, err) 744 require.NotNil(t, readResult) 745 require.Equal(t, &nrqlConditionBaseAggMethod, readResult.Signal.AggregationMethod) 746 require.Equal(t, &nrqlConditionBaseAggDelay, readResult.Signal.AggregationDelay) 747 require.Nil(t, createdStaticWithStreamingMethods.Signal.AggregationTimer) 748 749 // Test: Not found 750 notFoundResult, err := client.GetNrqlConditionQuery(testAccountID, "1") 751 require.Error(t, err) 752 require.Nil(t, notFoundResult) 753 _, ok := err.(*errors.NotFound) 754 require.True(t, ok) 755 756 // Test: Update (static condition with streaming methods fields modified) 757 nrqlConditionBaseAggMethodUpdated := NrqlConditionAggregationMethodTypes.EventTimer // needed for setting pointer 758 759 updateStreamingMethodsInput.Signal.AggregationMethod = &nrqlConditionBaseAggMethodUpdated 760 updateStreamingMethodsInput.Signal.AggregationDelay = nil 761 updateStreamingMethodsInput.Signal.AggregationTimer = &nrqlConditionBaseAggTimer 762 763 updatedStaticWithStreamingMethods, err := client.UpdateNrqlConditionStaticMutation(testAccountID, readResult.ID, updateStreamingMethodsInput) 764 require.NoError(t, err) 765 require.Equal(t, &nrqlConditionBaseAggMethodUpdated, updatedStaticWithStreamingMethods.Signal.AggregationMethod) 766 require.Equal(t, &nrqlConditionBaseAggTimer, updatedStaticWithStreamingMethods.Signal.AggregationTimer) 767 require.Nil(t, updatedStaticWithStreamingMethods.Signal.AggregationDelay) 768 769 // Test: Update (static condition without streaming methods fields) 770 updateStreamingMethodsInput.Signal.AggregationMethod = nil 771 updateStreamingMethodsInput.Signal.AggregationDelay = nil 772 updateStreamingMethodsInput.Signal.AggregationTimer = nil 773 updateStreamingMethodsInput.Signal.EvaluationOffset = &nrqlConditionBaseEvalOffset 774 775 updatedStaticWithoutStreamingMethods, err := client.UpdateNrqlConditionStaticMutation(testAccountID, readResult.ID, updateStreamingMethodsInput) 776 require.NoError(t, err) 777 require.Nil(t, updatedStaticWithoutStreamingMethods.Signal.AggregationMethod) 778 require.Nil(t, updatedStaticWithoutStreamingMethods.Signal.AggregationDelay) 779 require.Nil(t, updatedStaticWithoutStreamingMethods.Signal.AggregationTimer) 780 require.Equal(t, &nrqlConditionBaseEvalOffset, updatedStaticWithoutStreamingMethods.Signal.EvaluationOffset) 781 782 // Deferred teardown 783 defer func() { 784 _, err := client.DeletePolicyMutation(testAccountID, policy.ID) 785 if err != nil { 786 t.Logf("error cleaning up alert policy %s (%s): %s", policy.ID, policy.Name, err) 787 } 788 }() 789 } 790 791 func TestIntegrationNrqlConditions_ValueFunctionOptional(t *testing.T) { 792 t.Parallel() 793 794 testAccountID, err := mock.GetTestAccountID() 795 if err != nil { 796 t.Skipf("%s", err) 797 } 798 799 var ( 800 randStr = mock.RandSeq(5) 801 createNoValueFunctionInput = NrqlConditionCreateInput{ 802 NrqlConditionCreateBase: nrqlConditionCreateBase, 803 } 804 updateToAddValueFunctionInput = NrqlConditionUpdateInput{ 805 NrqlConditionUpdateBase: nrqlConditionUpdateBase, 806 ValueFunction: &NrqlConditionValueFunctions.SingleValue, 807 } 808 ) 809 810 // Setup 811 client := newIntegrationTestClient(t) 812 testPolicy := AlertsPolicyInput{ 813 IncidentPreference: AlertsIncidentPreferenceTypes.PER_POLICY, 814 Name: fmt.Sprintf("test-alert-policy-%s", randStr), 815 } 816 policy, err := client.CreatePolicyMutation(testAccountID, testPolicy) 817 require.NoError(t, err) 818 819 // Test: Create (static condition without value function) 820 createdStaticWithoutValueFunction, err := client.CreateNrqlConditionStaticMutation(testAccountID, policy.ID, createNoValueFunctionInput) 821 require.NoError(t, err) 822 require.NotNil(t, createdStaticWithoutValueFunction) 823 require.NotNil(t, createdStaticWithoutValueFunction.ID) 824 require.NotNil(t, createdStaticWithoutValueFunction.PolicyID) 825 // When static condition is created without value function, API returns single value as value function 826 require.Equal(t, &nrqlConditionBaseValueFunction, createdStaticWithoutValueFunction.ValueFunction) 827 828 // Test: Get (static condition without value function) 829 readResult, err := client.GetNrqlConditionQuery(testAccountID, createdStaticWithoutValueFunction.ID) 830 require.NoError(t, err) 831 require.NotNil(t, readResult) 832 // When static condition is created without value function, API returns single value as value function 833 require.Equal(t, &nrqlConditionBaseValueFunction, readResult.ValueFunction) 834 835 // Test: Update (static condition with value function) 836 nrqlConditionSumValueFunction := NrqlConditionValueFunctions.SingleValue // needed for setting pointer 837 838 updatedStaticWithValueFunction, err := client.UpdateNrqlConditionStaticMutation(testAccountID, readResult.ID, updateToAddValueFunctionInput) 839 require.NoError(t, err) 840 require.Equal(t, &nrqlConditionSumValueFunction, updatedStaticWithValueFunction.ValueFunction) 841 842 // Deferred teardown 843 defer func() { 844 _, err := client.DeletePolicyMutation(testAccountID, policy.ID) 845 if err != nil { 846 t.Logf("error cleaning up alert policy %s (%s): %s", policy.ID, policy.Name, err) 847 } 848 }() 849 }