storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/pkg/event/config_test.go (about) 1 /* 2 * MinIO Cloud Storage, (C) 2018 MinIO, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package event 18 19 import ( 20 "encoding/xml" 21 "reflect" 22 "strings" 23 "testing" 24 ) 25 26 func TestValidateFilterRuleValue(t *testing.T) { 27 testCases := []struct { 28 value string 29 expectErr bool 30 }{ 31 {"foo/.", true}, 32 {"../foo", true}, 33 {`foo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/bazfoo/bar/baz`, true}, 34 {string([]byte{0xff, 0xfe, 0xfd}), true}, 35 {`foo\bar`, true}, 36 {"Hello/世界", false}, 37 } 38 39 for i, testCase := range testCases { 40 err := ValidateFilterRuleValue(testCase.value) 41 expectErr := (err != nil) 42 43 if expectErr != testCase.expectErr { 44 t.Fatalf("test %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr) 45 } 46 } 47 } 48 49 func TestFilterRuleUnmarshalXML(t *testing.T) { 50 testCases := []struct { 51 data []byte 52 expectedResult *FilterRule 53 expectErr bool 54 }{ 55 {[]byte(`<FilterRule></FilterRule>`), nil, true}, 56 {[]byte(`<FilterRule><Name></Name></FilterRule>`), nil, true}, 57 {[]byte(`<FilterRule><Value></Value></FilterRule>`), nil, true}, 58 {[]byte(`<FilterRule><Name></Name><Value></Value></FilterRule>`), nil, true}, 59 {[]byte(`<FilterRule><Name>Prefix</Name><Value>Hello/世界</Value></FilterRule>`), nil, true}, 60 {[]byte(`<FilterRule><Name>ends</Name><Value>foo/bar</Value></FilterRule>`), nil, true}, 61 {[]byte(`<FilterRule><Name>prefix</Name><Value>Hello/世界</Value></FilterRule>`), &FilterRule{"prefix", "Hello/世界"}, false}, 62 {[]byte(`<FilterRule><Name>suffix</Name><Value>foo/bar</Value></FilterRule>`), &FilterRule{"suffix", "foo/bar"}, false}, 63 } 64 65 for i, testCase := range testCases { 66 result := &FilterRule{} 67 err := xml.Unmarshal(testCase.data, result) 68 expectErr := (err != nil) 69 70 if expectErr != testCase.expectErr { 71 t.Fatalf("test %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr) 72 } 73 74 if !testCase.expectErr { 75 if !reflect.DeepEqual(result, testCase.expectedResult) { 76 t.Fatalf("test %v: data: expected: %v, got: %v", i+1, testCase.expectedResult, result) 77 } 78 } 79 } 80 } 81 82 func TestFilterRuleListUnmarshalXML(t *testing.T) { 83 testCases := []struct { 84 data []byte 85 expectedResult *FilterRuleList 86 expectErr bool 87 }{ 88 {[]byte(`<S3Key><FilterRule><Name>suffix</Name><Value>Hello/世界</Value></FilterRule><FilterRule><Name>suffix</Name><Value>foo/bar</Value></FilterRule></S3Key>`), nil, true}, 89 {[]byte(`<S3Key><FilterRule><Name>prefix</Name><Value>Hello/世界</Value></FilterRule><FilterRule><Name>prefix</Name><Value>foo/bar</Value></FilterRule></S3Key>`), nil, true}, 90 {[]byte(`<S3Key><FilterRule><Name>prefix</Name><Value>Hello/世界</Value></FilterRule></S3Key>`), &FilterRuleList{[]FilterRule{{"prefix", "Hello/世界"}}}, false}, 91 {[]byte(`<S3Key><FilterRule><Name>suffix</Name><Value>foo/bar</Value></FilterRule></S3Key>`), &FilterRuleList{[]FilterRule{{"suffix", "foo/bar"}}}, false}, 92 {[]byte(`<S3Key><FilterRule><Name>prefix</Name><Value>Hello/世界</Value></FilterRule><FilterRule><Name>suffix</Name><Value>foo/bar</Value></FilterRule></S3Key>`), &FilterRuleList{[]FilterRule{{"prefix", "Hello/世界"}, {"suffix", "foo/bar"}}}, false}, 93 } 94 95 for i, testCase := range testCases { 96 result := &FilterRuleList{} 97 err := xml.Unmarshal(testCase.data, result) 98 expectErr := (err != nil) 99 100 if expectErr != testCase.expectErr { 101 t.Fatalf("test %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr) 102 } 103 104 if !testCase.expectErr { 105 if !reflect.DeepEqual(result, testCase.expectedResult) { 106 t.Fatalf("test %v: data: expected: %v, got: %v", i+1, testCase.expectedResult, result) 107 } 108 } 109 } 110 } 111 112 func TestFilterRuleListPattern(t *testing.T) { 113 testCases := []struct { 114 filterRuleList FilterRuleList 115 expectedResult string 116 }{ 117 {FilterRuleList{}, ""}, 118 {FilterRuleList{[]FilterRule{{"prefix", "Hello/世界"}}}, "Hello/世界*"}, 119 {FilterRuleList{[]FilterRule{{"suffix", "foo/bar"}}}, "*foo/bar"}, 120 {FilterRuleList{[]FilterRule{{"prefix", "Hello/世界"}, {"suffix", "foo/bar"}}}, "Hello/世界*foo/bar"}, 121 } 122 123 for i, testCase := range testCases { 124 result := testCase.filterRuleList.Pattern() 125 126 if result != testCase.expectedResult { 127 t.Fatalf("test %v: data: expected: %v, got: %v", i+1, testCase.expectedResult, result) 128 } 129 } 130 } 131 132 func TestQueueUnmarshalXML(t *testing.T) { 133 dataCase1 := []byte(` 134 <QueueConfiguration> 135 <Id>1</Id> 136 <Filter></Filter> 137 <Queue>arn:minio:sqs:us-east-1:1:webhook</Queue> 138 <Event>s3:ObjectAccessed:*</Event> 139 <Event>s3:ObjectCreated:*</Event> 140 <Event>s3:ObjectRemoved:*</Event> 141 </QueueConfiguration>`) 142 143 dataCase2 := []byte(` 144 <QueueConfiguration> 145 <Id>1</Id> 146 <Filter> 147 <S3Key> 148 <FilterRule> 149 <Name>prefix</Name> 150 <Value>images/</Value> 151 </FilterRule> 152 <FilterRule> 153 <Name>suffix</Name> 154 <Value>jpg</Value> 155 </FilterRule> 156 </S3Key> 157 </Filter> 158 <Queue>arn:minio:sqs:us-east-1:1:webhook</Queue> 159 <Event>s3:ObjectCreated:Put</Event> 160 </QueueConfiguration>`) 161 162 dataCase3 := []byte(` 163 <QueueConfiguration> 164 <Id>1</Id> 165 <Filter> 166 <S3Key> 167 <FilterRule> 168 <Name>prefix</Name> 169 <Value>images/</Value> 170 </FilterRule> 171 <FilterRule> 172 <Name>suffix</Name> 173 <Value>jpg</Value> 174 </FilterRule> 175 </S3Key> 176 </Filter> 177 <Queue>arn:minio:sqs:us-east-1:1:webhook</Queue> 178 <Event>s3:ObjectCreated:Put</Event> 179 <Event>s3:ObjectCreated:Put</Event> 180 </QueueConfiguration>`) 181 182 testCases := []struct { 183 data []byte 184 expectErr bool 185 }{ 186 {dataCase1, false}, 187 {dataCase2, false}, 188 {dataCase3, true}, 189 } 190 191 for i, testCase := range testCases { 192 err := xml.Unmarshal(testCase.data, &Queue{}) 193 expectErr := (err != nil) 194 195 if expectErr != testCase.expectErr { 196 t.Fatalf("test %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr) 197 } 198 } 199 } 200 201 func TestQueueValidate(t *testing.T) { 202 data := []byte(` 203 <QueueConfiguration> 204 <Id>1</Id> 205 <Filter></Filter> 206 <Queue>arn:minio:sqs:us-east-1:1:webhook</Queue> 207 <Event>s3:ObjectAccessed:*</Event> 208 <Event>s3:ObjectCreated:*</Event> 209 <Event>s3:ObjectRemoved:*</Event> 210 </QueueConfiguration>`) 211 queue1 := &Queue{} 212 if err := xml.Unmarshal(data, queue1); err != nil { 213 panic(err) 214 } 215 216 data = []byte(` 217 <QueueConfiguration> 218 <Id>1</Id> 219 <Filter> 220 <S3Key> 221 <FilterRule> 222 <Name>prefix</Name> 223 <Value>images/</Value> 224 </FilterRule> 225 <FilterRule> 226 <Name>suffix</Name> 227 <Value>jpg</Value> 228 </FilterRule> 229 </S3Key> 230 </Filter> 231 <Queue>arn:minio:sqs:us-east-1:1:webhook</Queue> 232 <Event>s3:ObjectCreated:Put</Event> 233 </QueueConfiguration>`) 234 queue2 := &Queue{} 235 if err := xml.Unmarshal(data, queue2); err != nil { 236 panic(err) 237 } 238 239 data = []byte(` 240 <QueueConfiguration> 241 <Id>1</Id> 242 <Filter></Filter> 243 <Queue>arn:minio:sqs:eu-west-2:1:webhook</Queue> 244 <Event>s3:ObjectAccessed:*</Event> 245 <Event>s3:ObjectCreated:*</Event> 246 <Event>s3:ObjectRemoved:*</Event> 247 </QueueConfiguration>`) 248 queue3 := &Queue{} 249 if err := xml.Unmarshal(data, queue3); err != nil { 250 panic(err) 251 } 252 253 targetList1 := NewTargetList() 254 255 targetList2 := NewTargetList() 256 if err := targetList2.Add(&ExampleTarget{TargetID{"1", "webhook"}, false, false}); err != nil { 257 panic(err) 258 } 259 260 testCases := []struct { 261 queue *Queue 262 region string 263 targetList *TargetList 264 expectErr bool 265 }{ 266 {queue1, "eu-west-1", nil, true}, 267 {queue2, "us-east-1", targetList1, true}, 268 {queue3, "", targetList2, false}, 269 {queue2, "us-east-1", targetList2, false}, 270 } 271 272 for i, testCase := range testCases { 273 err := testCase.queue.Validate(testCase.region, testCase.targetList) 274 expectErr := (err != nil) 275 276 if expectErr != testCase.expectErr { 277 t.Fatalf("test %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr) 278 } 279 } 280 } 281 282 func TestQueueSetRegion(t *testing.T) { 283 data := []byte(` 284 <QueueConfiguration> 285 <Id>1</Id> 286 <Filter></Filter> 287 <Queue>arn:minio:sqs:us-east-1:1:webhook</Queue> 288 <Event>s3:ObjectAccessed:*</Event> 289 <Event>s3:ObjectCreated:*</Event> 290 <Event>s3:ObjectRemoved:*</Event> 291 </QueueConfiguration>`) 292 queue1 := &Queue{} 293 if err := xml.Unmarshal(data, queue1); err != nil { 294 panic(err) 295 } 296 297 data = []byte(` 298 <QueueConfiguration> 299 <Id>1</Id> 300 <Filter> 301 <S3Key> 302 <FilterRule> 303 <Name>prefix</Name> 304 <Value>images/</Value> 305 </FilterRule> 306 <FilterRule> 307 <Name>suffix</Name> 308 <Value>jpg</Value> 309 </FilterRule> 310 </S3Key> 311 </Filter> 312 <Queue>arn:minio:sqs::1:webhook</Queue> 313 <Event>s3:ObjectCreated:Put</Event> 314 </QueueConfiguration>`) 315 queue2 := &Queue{} 316 if err := xml.Unmarshal(data, queue2); err != nil { 317 panic(err) 318 } 319 320 testCases := []struct { 321 queue *Queue 322 region string 323 expectedResult ARN 324 }{ 325 {queue1, "eu-west-1", ARN{TargetID{"1", "webhook"}, "eu-west-1"}}, 326 {queue1, "", ARN{TargetID{"1", "webhook"}, ""}}, 327 {queue2, "us-east-1", ARN{TargetID{"1", "webhook"}, "us-east-1"}}, 328 {queue2, "", ARN{TargetID{"1", "webhook"}, ""}}, 329 } 330 331 for i, testCase := range testCases { 332 testCase.queue.SetRegion(testCase.region) 333 result := testCase.queue.ARN 334 335 if !reflect.DeepEqual(result, testCase.expectedResult) { 336 t.Fatalf("test %v: data: expected: %v, got: %v", i+1, testCase.expectedResult, result) 337 } 338 } 339 } 340 341 func TestQueueToRulesMap(t *testing.T) { 342 data := []byte(` 343 <QueueConfiguration> 344 <Id>1</Id> 345 <Filter></Filter> 346 <Queue>arn:minio:sqs:us-east-1:1:webhook</Queue> 347 <Event>s3:ObjectAccessed:*</Event> 348 <Event>s3:ObjectCreated:*</Event> 349 <Event>s3:ObjectRemoved:*</Event> 350 </QueueConfiguration>`) 351 queueCase1 := &Queue{} 352 if err := xml.Unmarshal(data, queueCase1); err != nil { 353 panic(err) 354 } 355 356 data = []byte(` 357 <QueueConfiguration> 358 <Id>1</Id> 359 <Filter> 360 <S3Key> 361 <FilterRule> 362 <Name>prefix</Name> 363 <Value>images/</Value> 364 </FilterRule> 365 <FilterRule> 366 <Name>suffix</Name> 367 <Value>jpg</Value> 368 </FilterRule> 369 </S3Key> 370 </Filter> 371 <Queue>arn:minio:sqs:us-east-1:1:webhook</Queue> 372 <Event>s3:ObjectCreated:Put</Event> 373 </QueueConfiguration>`) 374 queueCase2 := &Queue{} 375 if err := xml.Unmarshal(data, queueCase2); err != nil { 376 panic(err) 377 } 378 379 rulesMapCase1 := NewRulesMap([]Name{ObjectAccessedAll, ObjectCreatedAll, ObjectRemovedAll}, "*", TargetID{"1", "webhook"}) 380 rulesMapCase2 := NewRulesMap([]Name{ObjectCreatedPut}, "images/*jpg", TargetID{"1", "webhook"}) 381 382 testCases := []struct { 383 queue *Queue 384 expectedResult RulesMap 385 }{ 386 {queueCase1, rulesMapCase1}, 387 {queueCase2, rulesMapCase2}, 388 } 389 390 for i, testCase := range testCases { 391 result := testCase.queue.ToRulesMap() 392 393 if !reflect.DeepEqual(result, testCase.expectedResult) { 394 t.Fatalf("test %v: data: expected: %v, got: %v", i+1, testCase.expectedResult, result) 395 } 396 } 397 } 398 399 func TestConfigUnmarshalXML(t *testing.T) { 400 dataCase1 := []byte(` 401 <NotificationConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> 402 <QueueConfiguration> 403 <Id>1</Id> 404 <Filter></Filter> 405 <Queue>arn:minio:sqs:us-east-1:1:webhook</Queue> 406 <Event>s3:ObjectAccessed:*</Event> 407 <Event>s3:ObjectCreated:*</Event> 408 <Event>s3:ObjectRemoved:*</Event> 409 </QueueConfiguration> 410 </NotificationConfiguration> 411 `) 412 413 dataCase2 := []byte(` 414 <NotificationConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> 415 <QueueConfiguration> 416 <Id>1</Id> 417 <Filter> 418 <S3Key> 419 <FilterRule> 420 <Name>prefix</Name> 421 <Value>images/</Value> 422 </FilterRule> 423 <FilterRule> 424 <Name>suffix</Name> 425 <Value>jpg</Value> 426 </FilterRule> 427 </S3Key> 428 </Filter> 429 <Queue>arn:minio:sqs:us-east-1:1:webhook</Queue> 430 <Event>s3:ObjectCreated:Put</Event> 431 </QueueConfiguration> 432 </NotificationConfiguration> 433 `) 434 435 dataCase3 := []byte(` 436 <NotificationConfiguration> 437 <QueueConfiguration> 438 <Id>1</Id> 439 <Filter></Filter> 440 <Queue>arn:minio:sqs:us-east-1:1:webhook</Queue> 441 <Event>s3:ObjectAccessed:*</Event> 442 <Event>s3:ObjectCreated:*</Event> 443 <Event>s3:ObjectRemoved:*</Event> 444 </QueueConfiguration> 445 <QueueConfiguration> 446 <Id>2</Id> 447 <Filter> 448 <S3Key> 449 <FilterRule> 450 <Name>prefix</Name> 451 <Value>images/</Value> 452 </FilterRule> 453 <FilterRule> 454 <Name>suffix</Name> 455 <Value>jpg</Value> 456 </FilterRule> 457 </S3Key> 458 </Filter> 459 <Queue>arn:minio:sqs:us-east-1:1:webhook</Queue> 460 <Event>s3:ObjectCreated:Put</Event> 461 </QueueConfiguration> 462 </NotificationConfiguration> 463 `) 464 465 dataCase4 := []byte(` 466 <NotificationConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> 467 <QueueConfiguration> 468 <Id>1</Id> 469 <Filter></Filter> 470 <Queue>arn:minio:sqs:us-east-1:1:webhook</Queue> 471 <Event>s3:ObjectAccessed:*</Event> 472 <Event>s3:ObjectCreated:*</Event> 473 <Event>s3:ObjectRemoved:*</Event> 474 </QueueConfiguration> 475 <CloudFunctionConfiguration> 476 <Id>1</Id> 477 <Filter> 478 <S3Key> 479 <FilterRule> 480 <Name>suffix</Name> 481 <Value>.jpg</Value> 482 </FilterRule> 483 </S3Key> 484 </Filter> 485 <Cloudcode>arn:aws:lambda:us-west-2:444455556666:cloud-function-A</Cloudcode> 486 <Event>s3:ObjectCreated:Put</Event> 487 </CloudFunctionConfiguration> 488 <TopicConfiguration> 489 <Topic>arn:aws:sns:us-west-2:444455556666:sns-notification-one</Topic> 490 <Event>s3:ObjectCreated:*</Event> 491 </TopicConfiguration> 492 </NotificationConfiguration> 493 `) 494 495 dataCase5 := []byte(`<NotificationConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/" ></NotificationConfiguration>`) 496 497 testCases := []struct { 498 data []byte 499 expectErr bool 500 }{ 501 {dataCase1, false}, 502 {dataCase2, false}, 503 {dataCase3, false}, 504 {dataCase4, true}, 505 // make sure we don't fail when queue is empty. 506 {dataCase5, false}, 507 } 508 509 for i, testCase := range testCases { 510 err := xml.Unmarshal(testCase.data, &Config{}) 511 expectErr := (err != nil) 512 513 if expectErr != testCase.expectErr { 514 t.Fatalf("test %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr) 515 } 516 } 517 } 518 519 func TestConfigValidate(t *testing.T) { 520 data := []byte(` 521 <NotificationConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> 522 <QueueConfiguration> 523 <Id>1</Id> 524 <Filter></Filter> 525 <Queue>arn:minio:sqs:us-east-1:1:webhook</Queue> 526 <Event>s3:ObjectAccessed:*</Event> 527 <Event>s3:ObjectCreated:*</Event> 528 <Event>s3:ObjectRemoved:*</Event> 529 </QueueConfiguration> 530 </NotificationConfiguration> 531 `) 532 config1 := &Config{} 533 if err := xml.Unmarshal(data, config1); err != nil { 534 panic(err) 535 } 536 537 data = []byte(` 538 <NotificationConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> 539 <QueueConfiguration> 540 <Id>1</Id> 541 <Filter> 542 <S3Key> 543 <FilterRule> 544 <Name>prefix</Name> 545 <Value>images/</Value> 546 </FilterRule> 547 <FilterRule> 548 <Name>suffix</Name> 549 <Value>jpg</Value> 550 </FilterRule> 551 </S3Key> 552 </Filter> 553 <Queue>arn:minio:sqs:us-east-1:1:webhook</Queue> 554 <Event>s3:ObjectCreated:Put</Event> 555 </QueueConfiguration> 556 </NotificationConfiguration> 557 `) 558 config2 := &Config{} 559 if err := xml.Unmarshal(data, config2); err != nil { 560 panic(err) 561 } 562 563 data = []byte(` 564 <NotificationConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> 565 <QueueConfiguration> 566 <Id>1</Id> 567 <Filter></Filter> 568 <Queue>arn:minio:sqs:us-east-1:1:webhook</Queue> 569 <Event>s3:ObjectAccessed:*</Event> 570 <Event>s3:ObjectCreated:*</Event> 571 <Event>s3:ObjectRemoved:*</Event> 572 </QueueConfiguration> 573 <QueueConfiguration> 574 <Id>2</Id> 575 <Filter> 576 <S3Key> 577 <FilterRule> 578 <Name>prefix</Name> 579 <Value>images/</Value> 580 </FilterRule> 581 <FilterRule> 582 <Name>suffix</Name> 583 <Value>jpg</Value> 584 </FilterRule> 585 </S3Key> 586 </Filter> 587 <Queue>arn:minio:sqs:us-east-1:1:webhook</Queue> 588 <Event>s3:ObjectCreated:Put</Event> 589 </QueueConfiguration> 590 </NotificationConfiguration> 591 `) 592 config3 := &Config{} 593 if err := xml.Unmarshal(data, config3); err != nil { 594 panic(err) 595 } 596 597 targetList1 := NewTargetList() 598 599 targetList2 := NewTargetList() 600 if err := targetList2.Add(&ExampleTarget{TargetID{"1", "webhook"}, false, false}); err != nil { 601 panic(err) 602 } 603 604 testCases := []struct { 605 config *Config 606 region string 607 targetList *TargetList 608 expectErr bool 609 }{ 610 {config1, "eu-west-1", nil, true}, 611 {config2, "us-east-1", targetList1, true}, 612 {config3, "", targetList2, false}, 613 {config2, "us-east-1", targetList2, false}, 614 } 615 616 for i, testCase := range testCases { 617 err := testCase.config.Validate(testCase.region, testCase.targetList) 618 expectErr := (err != nil) 619 620 if expectErr != testCase.expectErr { 621 t.Fatalf("test %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr) 622 } 623 } 624 } 625 626 func TestConfigSetRegion(t *testing.T) { 627 data := []byte(` 628 <NotificationConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> 629 <QueueConfiguration> 630 <Id>1</Id> 631 <Filter></Filter> 632 <Queue>arn:minio:sqs:us-east-1:1:webhook</Queue> 633 <Event>s3:ObjectAccessed:*</Event> 634 <Event>s3:ObjectCreated:*</Event> 635 <Event>s3:ObjectRemoved:*</Event> 636 </QueueConfiguration> 637 </NotificationConfiguration> 638 `) 639 config1 := &Config{} 640 if err := xml.Unmarshal(data, config1); err != nil { 641 panic(err) 642 } 643 644 data = []byte(` 645 <NotificationConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> 646 <QueueConfiguration> 647 <Id>1</Id> 648 <Filter> 649 <S3Key> 650 <FilterRule> 651 <Name>prefix</Name> 652 <Value>images/</Value> 653 </FilterRule> 654 <FilterRule> 655 <Name>suffix</Name> 656 <Value>jpg</Value> 657 </FilterRule> 658 </S3Key> 659 </Filter> 660 <Queue>arn:minio:sqs::1:webhook</Queue> 661 <Event>s3:ObjectCreated:Put</Event> 662 </QueueConfiguration> 663 </NotificationConfiguration> 664 `) 665 config2 := &Config{} 666 if err := xml.Unmarshal(data, config2); err != nil { 667 panic(err) 668 } 669 670 data = []byte(` 671 <NotificationConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> 672 <QueueConfiguration> 673 <Id>1</Id> 674 <Filter></Filter> 675 <Queue>arn:minio:sqs:us-east-1:1:webhook</Queue> 676 <Event>s3:ObjectAccessed:*</Event> 677 <Event>s3:ObjectCreated:*</Event> 678 <Event>s3:ObjectRemoved:*</Event> 679 </QueueConfiguration> 680 <QueueConfiguration> 681 <Id>2</Id> 682 <Filter> 683 <S3Key> 684 <FilterRule> 685 <Name>prefix</Name> 686 <Value>images/</Value> 687 </FilterRule> 688 <FilterRule> 689 <Name>suffix</Name> 690 <Value>jpg</Value> 691 </FilterRule> 692 </S3Key> 693 </Filter> 694 <Queue>arn:minio:sqs:us-east-1:2:amqp</Queue> 695 <Event>s3:ObjectCreated:Put</Event> 696 </QueueConfiguration> 697 </NotificationConfiguration> 698 `) 699 config3 := &Config{} 700 if err := xml.Unmarshal(data, config3); err != nil { 701 panic(err) 702 } 703 704 testCases := []struct { 705 config *Config 706 region string 707 expectedResult []ARN 708 }{ 709 {config1, "eu-west-1", []ARN{{TargetID{"1", "webhook"}, "eu-west-1"}}}, 710 {config1, "", []ARN{{TargetID{"1", "webhook"}, ""}}}, 711 {config2, "us-east-1", []ARN{{TargetID{"1", "webhook"}, "us-east-1"}}}, 712 {config2, "", []ARN{{TargetID{"1", "webhook"}, ""}}}, 713 {config3, "us-east-1", []ARN{{TargetID{"1", "webhook"}, "us-east-1"}, {TargetID{"2", "amqp"}, "us-east-1"}}}, 714 {config3, "", []ARN{{TargetID{"1", "webhook"}, ""}, {TargetID{"2", "amqp"}, ""}}}, 715 } 716 717 for i, testCase := range testCases { 718 testCase.config.SetRegion(testCase.region) 719 result := []ARN{} 720 for _, queue := range testCase.config.QueueList { 721 result = append(result, queue.ARN) 722 } 723 724 if !reflect.DeepEqual(result, testCase.expectedResult) { 725 t.Fatalf("test %v: data: expected: %v, got: %v", i+1, testCase.expectedResult, result) 726 } 727 } 728 } 729 730 func TestConfigToRulesMap(t *testing.T) { 731 data := []byte(` 732 <NotificationConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> 733 <QueueConfiguration> 734 <Id>1</Id> 735 <Filter></Filter> 736 <Queue>arn:minio:sqs:us-east-1:1:webhook</Queue> 737 <Event>s3:ObjectAccessed:*</Event> 738 <Event>s3:ObjectCreated:*</Event> 739 <Event>s3:ObjectRemoved:*</Event> 740 </QueueConfiguration> 741 </NotificationConfiguration> 742 `) 743 config1 := &Config{} 744 if err := xml.Unmarshal(data, config1); err != nil { 745 panic(err) 746 } 747 748 data = []byte(` 749 <NotificationConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> 750 <QueueConfiguration> 751 <Id>1</Id> 752 <Filter> 753 <S3Key> 754 <FilterRule> 755 <Name>prefix</Name> 756 <Value>images/</Value> 757 </FilterRule> 758 <FilterRule> 759 <Name>suffix</Name> 760 <Value>jpg</Value> 761 </FilterRule> 762 </S3Key> 763 </Filter> 764 <Queue>arn:minio:sqs::1:webhook</Queue> 765 <Event>s3:ObjectCreated:Put</Event> 766 </QueueConfiguration> 767 </NotificationConfiguration> 768 `) 769 config2 := &Config{} 770 if err := xml.Unmarshal(data, config2); err != nil { 771 panic(err) 772 } 773 774 data = []byte(` 775 <NotificationConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> 776 <QueueConfiguration> 777 <Id>1</Id> 778 <Filter></Filter> 779 <Queue>arn:minio:sqs:us-east-1:1:webhook</Queue> 780 <Event>s3:ObjectAccessed:*</Event> 781 <Event>s3:ObjectCreated:*</Event> 782 <Event>s3:ObjectRemoved:*</Event> 783 </QueueConfiguration> 784 <QueueConfiguration> 785 <Id>2</Id> 786 <Filter> 787 <S3Key> 788 <FilterRule> 789 <Name>prefix</Name> 790 <Value>images/</Value> 791 </FilterRule> 792 <FilterRule> 793 <Name>suffix</Name> 794 <Value>jpg</Value> 795 </FilterRule> 796 </S3Key> 797 </Filter> 798 <Queue>arn:minio:sqs:us-east-1:2:amqp</Queue> 799 <Event>s3:ObjectCreated:Put</Event> 800 </QueueConfiguration> 801 </NotificationConfiguration> 802 `) 803 config3 := &Config{} 804 if err := xml.Unmarshal(data, config3); err != nil { 805 panic(err) 806 } 807 808 rulesMapCase1 := NewRulesMap([]Name{ObjectAccessedAll, ObjectCreatedAll, ObjectRemovedAll}, "*", TargetID{"1", "webhook"}) 809 810 rulesMapCase2 := NewRulesMap([]Name{ObjectCreatedPut}, "images/*jpg", TargetID{"1", "webhook"}) 811 812 rulesMapCase3 := NewRulesMap([]Name{ObjectAccessedAll, ObjectCreatedAll, ObjectRemovedAll}, "*", TargetID{"1", "webhook"}) 813 rulesMapCase3.add([]Name{ObjectCreatedPut}, "images/*jpg", TargetID{"2", "amqp"}) 814 815 testCases := []struct { 816 config *Config 817 expectedResult RulesMap 818 }{ 819 {config1, rulesMapCase1}, 820 {config2, rulesMapCase2}, 821 {config3, rulesMapCase3}, 822 } 823 824 for i, testCase := range testCases { 825 result := testCase.config.ToRulesMap() 826 827 if !reflect.DeepEqual(result, testCase.expectedResult) { 828 t.Fatalf("test %v: data: expected: %v, got: %v", i+1, testCase.expectedResult, result) 829 } 830 } 831 } 832 833 func TestParseConfig(t *testing.T) { 834 reader1 := strings.NewReader(` 835 <NotificationConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> 836 <QueueConfiguration> 837 <Id>1</Id> 838 <Filter></Filter> 839 <Queue>arn:minio:sqs:us-east-1:1:webhook</Queue> 840 <Event>s3:ObjectAccessed:*</Event> 841 <Event>s3:ObjectCreated:*</Event> 842 <Event>s3:ObjectRemoved:*</Event> 843 </QueueConfiguration> 844 </NotificationConfiguration> 845 `) 846 847 reader2 := strings.NewReader(` 848 <NotificationConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> 849 <QueueConfiguration> 850 <Id>1</Id> 851 <Filter> 852 <S3Key> 853 <FilterRule> 854 <Name>prefix</Name> 855 <Value>images/</Value> 856 </FilterRule> 857 <FilterRule> 858 <Name>suffix</Name> 859 <Value>jpg</Value> 860 </FilterRule> 861 </S3Key> 862 </Filter> 863 <Queue>arn:minio:sqs:us-east-1:1:webhook</Queue> 864 <Event>s3:ObjectCreated:Put</Event> 865 </QueueConfiguration> 866 </NotificationConfiguration> 867 `) 868 869 reader3 := strings.NewReader(` 870 <NotificationConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> 871 <QueueConfiguration> 872 <Id>1</Id> 873 <Filter></Filter> 874 <Queue>arn:minio:sqs:us-east-1:1:webhook</Queue> 875 <Event>s3:ObjectAccessed:*</Event> 876 <Event>s3:ObjectCreated:*</Event> 877 <Event>s3:ObjectRemoved:*</Event> 878 </QueueConfiguration> 879 <QueueConfiguration> 880 <Id>2</Id> 881 <Filter> 882 <S3Key> 883 <FilterRule> 884 <Name>prefix</Name> 885 <Value>images/</Value> 886 </FilterRule> 887 <FilterRule> 888 <Name>suffix</Name> 889 <Value>jpg</Value> 890 </FilterRule> 891 </S3Key> 892 </Filter> 893 <Queue>arn:minio:sqs:us-east-1:1:webhook</Queue> 894 <Event>s3:ObjectCreated:Put</Event> 895 </QueueConfiguration> 896 </NotificationConfiguration> 897 `) 898 899 reader4 := strings.NewReader(` 900 <NotificationConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> 901 <QueueConfiguration> 902 <Id>1</Id> 903 <Filter></Filter> 904 <Queue>arn:minio:sqs:us-east-1:1:webhook</Queue> 905 <Event>s3:ObjectAccessed:*</Event> 906 <Event>s3:ObjectCreated:*</Event> 907 <Event>s3:ObjectRemoved:*</Event> 908 </QueueConfiguration> 909 <CloudFunctionConfiguration> 910 <Id>1</Id> 911 <Filter> 912 <S3Key> 913 <FilterRule> 914 <Name>suffix</Name> 915 <Value>.jpg</Value> 916 </FilterRule> 917 </S3Key> 918 </Filter> 919 <Cloudcode>arn:aws:lambda:us-west-2:444455556666:cloud-function-A</Cloudcode> 920 <Event>s3:ObjectCreated:Put</Event> 921 </CloudFunctionConfiguration> 922 <TopicConfiguration> 923 <Topic>arn:aws:sns:us-west-2:444455556666:sns-notification-one</Topic> 924 <Event>s3:ObjectCreated:*</Event> 925 </TopicConfiguration> 926 </NotificationConfiguration> 927 `) 928 929 targetList1 := NewTargetList() 930 931 targetList2 := NewTargetList() 932 if err := targetList2.Add(&ExampleTarget{TargetID{"1", "webhook"}, false, false}); err != nil { 933 panic(err) 934 } 935 936 testCases := []struct { 937 reader *strings.Reader 938 region string 939 targetList *TargetList 940 expectErr bool 941 }{ 942 {reader1, "eu-west-1", nil, true}, 943 {reader2, "us-east-1", targetList1, true}, 944 {reader4, "us-east-1", targetList1, true}, 945 {reader3, "", targetList2, false}, 946 {reader2, "us-east-1", targetList2, false}, 947 } 948 949 for i, testCase := range testCases { 950 if _, err := testCase.reader.Seek(0, 0); err != nil { 951 panic(err) 952 } 953 _, err := ParseConfig(testCase.reader, testCase.region, testCase.targetList) 954 expectErr := (err != nil) 955 956 if expectErr != testCase.expectErr { 957 t.Fatalf("test %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr) 958 } 959 } 960 }