gitee.com/KyleChenSource/lib-robot@v1.0.2/robottest/common/brutetest/brutetest.go (about) 1 package brutetest 2 3 /* 4 暴力测试 5 // 如果相互嵌套,只能单层嵌套 6 7 配置 [ 8 // 根据循序进行测试 9 { 10 'msgname': // 协议名 11 'msgid': // 协议id, 可以为0, 则不进行测试 12 'notest': // 不进行测试标记 13 'caseid': // = 0, 没有要求。非0则会相同id,根据flowid排序 14 'flowid': // 顺序 15 'data': { //发送的协议 16 %B_I8 min:max:...valid value% 16,32,64 17 %B_U8 min:max:...valid value% 16,32,64 18 %B_F32 min:max:...valid value% 64 19 %B_BL% 20 %B_STR min:max:...valid value% 21 %B_BS minLen:maxLen:...valid% base64 22 %B_MSG msgName% 23 %B_ARR minLen:maxLen type params% 24 %B_MAP minLen:maxLen key_type params value_type params% 25 } 26 ] 27 */ 28 29 import ( 30 "bytes" 31 "encoding/base64" 32 "encoding/json" 33 "fmt" 34 "io/ioutil" 35 "math" 36 "math/rand" 37 "os" 38 "regexp" 39 "sort" 40 "strconv" 41 "strings" 42 43 "gitee.com/KyleChenSource/lib-robot/robottest/log" 44 "github.com/valyala/fastjson" 45 ) 46 47 const ( 48 testcnt_warn = 5000 49 generator_cnt_max = 300000 // 限制一个消息的实际测试次数, 如果超过该次数,会启动Step = [Count / generator_cnt_max + 1, +2] 50 caseCnfPattern = ": *\"%B_(I8|I16|I32|I64|U8|U16|U32|U64|F32|F64|BL|STR|BS|MSG|ARR|MAP)([=_\\-\\.0-9:a-zA-Z ]*)%\"" 51 caseCnfSplitPattern = " *: *" 52 caseCnfArrayPattern = " *([0-9]*) *: *([0-9]*) *B_(I8|I16|I32|I64|U8|U16|U32|U64|F32|F64|BL|STR|BS|MSG|ARR) *(.*)" 53 caseCnfMapPattern = " *([0-9]*) *: *([0-9]*) *B_(I8|I16|I32|I64|U8|U16|U32|U64|F32|F64|BL|STR|BS)(.*) *B_(I8|I16|I32|I64|U8|U16|U32|U64|F32|F64|BL|STR|BS|MSG|ARR|MAP)(.*)" 54 randCntInt = 3 55 randCntString = 3 56 randCntBytes = 4 57 randCntArrayLenMin = 0 58 randCntArrayLenMax = 10 59 randCntArray = 3 60 randCntMapLenMin = 0 61 randCntMapLenMax = 10 62 randCntMap = 3 63 ) 64 65 var a float32 66 var ( 67 BrutetestMsgMap = make(map[string]*BruteMsgCnf) 68 BrutetestCaselistMap = make(map[int][]*BruteMsgCnf) 69 ) 70 71 type BruteCaseType int 72 73 const ( 74 BruteCaseType_Int8 BruteCaseType = iota 75 BruteCaseType_Int16 76 BruteCaseType_Int32 77 BruteCaseType_Int64 78 BruteCaseType_Uint8 79 BruteCaseType_Uint16 80 BruteCaseType_Uint32 81 BruteCaseType_Uint64 82 BruteCaseType_Float32 83 BruteCaseType_Float64 84 BruteCaseType_BOOL 85 BruteCaseType_STR 86 BruteCaseType_BS 87 BruteCaseType_MSG 88 BruteCaseType_ARR 89 BruteCaseType_MAP 90 BruteCaseType_Cnt 91 ) 92 93 var ( 94 prePath = "./brutetest" 95 caseCnfRe = regexp.MustCompile(caseCnfPattern) 96 caseCnfInt8SpliteRe = regexp.MustCompile(caseCnfSplitPattern) 97 caseCnfArrayRe = regexp.MustCompile(caseCnfArrayPattern) 98 caseCnfMapRe = regexp.MustCompile(caseCnfMapPattern) 99 ) 100 101 func SpaceCnt(data string) int { 102 cnt := 0 103 for ; cnt < len(data); cnt++ { 104 if data[cnt] != ' ' { 105 break 106 } 107 } 108 return cnt 109 } 110 111 func Int64(data string) (out int64, parseLen int, err error) { 112 data = strings.Trim(data, " ") 113 parseLen = len(data) 114 if parseLen == 0 { 115 return 116 } 117 118 out, err = strconv.ParseInt(data, 10, 64) 119 if err != nil { 120 return 121 } 122 123 return 124 } 125 126 func Uint64(data string) (out uint64, parseLen int, err error) { 127 data = strings.Trim(data, " ") 128 parseLen = len(data) 129 if parseLen == 0 { 130 return 131 } 132 133 out, err = strconv.ParseUint(data, 10, 64) 134 if err != nil { 135 return 136 } 137 138 return 139 } 140 141 func Float64(data string) (out float64, parseLen int, err error) { 142 data = strings.Trim(data, " ") 143 parseLen = len(data) 144 if parseLen == 0 { 145 return 146 } 147 148 out, err = strconv.ParseFloat(data, 64) 149 if err != nil { 150 return 151 } 152 153 return 154 } 155 156 func String(data string) (out string, parseLen int, err error) { 157 out = strings.Trim(data, " \n\r") 158 parseLen = len(out) 159 return 160 } 161 162 type BruteCase interface { 163 // ok : 是否循环结束 164 // v : 如果Ok,就是可以放入json的文本 165 Next() (ok bool, v string) 166 // 必定返回成功, 跳过step个的下一个例子 167 Step(step uint64) string 168 // 获取随机值总数 169 Count() uint64 170 } 171 172 type BruteCaseCnf interface { 173 Type() BruteCaseType 174 Case() BruteCase 175 RandCnt() int 176 } 177 178 type BruteCaseCnfInt struct { 179 BType BruteCaseType 180 Min int64 181 Max int64 182 Datas []string 183 } 184 185 func (this *BruteCaseCnfInt) Type() BruteCaseType { 186 return this.BType 187 } 188 189 func (this *BruteCaseCnfInt) RandCnt() int { 190 if this.Max == this.Min { 191 return 0 192 } 193 return randCntInt 194 } 195 196 func (this *BruteCaseCnfInt) Case() BruteCase { 197 return &BruteCaseInt{ 198 cnf: this, 199 cnt: uint64(len(this.Datas) + this.RandCnt()), 200 } 201 } 202 203 type BruteCaseInt struct { 204 cnf *BruteCaseCnfInt 205 cnt uint64 206 index uint64 207 } 208 209 func (this *BruteCaseInt) Next() (ok bool, v string) { 210 ok = false 211 if this.index >= this.cnt { 212 this.index = 0 213 return 214 } 215 216 if this.index < uint64(len(this.cnf.Datas)) { 217 ok = true 218 v = this.cnf.Datas[this.index] 219 this.index++ 220 return 221 } 222 223 this.index++ 224 r := rand.Int63n(this.cnf.Max/2 - this.cnf.Min/2) 225 return true, fmt.Sprintf("%d", this.cnf.Min+r+r) 226 } 227 228 func (this *BruteCaseInt) Step(step uint64) (v string) { 229 this.index = (this.index + step) % this.cnt 230 231 if this.index < uint64(len(this.cnf.Datas)) { 232 v = this.cnf.Datas[this.index] 233 this.index++ 234 return 235 } 236 237 this.index++ 238 r := rand.Int63n(this.cnf.Max/2 - this.cnf.Min/2) 239 return fmt.Sprintf("%d", this.cnf.Min+r+r) 240 } 241 242 func (this *BruteCaseInt) Count() uint64 { 243 return this.cnt 244 } 245 246 func ParseParamInt(data string, t BruteCaseType) (cnf BruteCaseCnf, err error) { 247 var min int64 248 var max int64 249 switch t { 250 case BruteCaseType_Int8: 251 min = math.MinInt8 252 max = math.MaxInt8 253 case BruteCaseType_Int16: 254 min = math.MinInt16 255 max = math.MaxInt16 256 case BruteCaseType_Int32: 257 min = math.MinInt32 258 max = math.MaxInt32 259 case BruteCaseType_Int64: 260 min = math.MinInt64 261 max = math.MaxInt64 262 default: 263 err = fmt.Errorf("type:%d not Int", t) 264 return 265 } 266 267 s := caseCnfInt8SpliteRe.Split(data, -1) 268 slen := len(s) 269 if slen == 0 { 270 // 默认的Int8 271 datas := make([]string, 2, 2) 272 datas[0] = fmt.Sprintf("%d", min) 273 datas[1] = fmt.Sprintf("%d", max) 274 cnf = &BruteCaseCnfInt{ 275 BType: t, 276 Min: min, 277 Max: max, 278 Datas: datas, 279 } 280 return 281 } 282 283 p, l, e := Int64(s[0]) 284 if e != nil { 285 err = e 286 return 287 } 288 289 if l != 0 && p > min { 290 min = p 291 } 292 293 if slen <= 1 { 294 datas := make([]string, 2, 2) 295 datas[0] = fmt.Sprintf("%d", min) 296 datas[1] = fmt.Sprintf("%d", max) 297 cnf = &BruteCaseCnfInt{ 298 BType: t, 299 Min: min, 300 Max: max, 301 Datas: datas, 302 } 303 return 304 } 305 306 p, l, e = Int64(s[1]) 307 if e != nil { 308 err = e 309 return 310 } 311 312 if l != 0 && p < max { 313 max = p 314 } 315 316 if slen <= 2 { 317 datas := make([]string, 2, 2) 318 datas[0] = fmt.Sprintf("%d", min) 319 datas[1] = fmt.Sprintf("%d", max) 320 cnf = &BruteCaseCnfInt{ 321 BType: t, 322 Min: min, 323 Max: max, 324 Datas: datas, 325 } 326 return 327 } 328 329 ps := make([]string, 2, slen) 330 for i := 2; i < slen; i++ { 331 p, l, e = Int64(s[i]) 332 if e != nil { 333 err = e 334 return 335 } 336 337 if l == 0 { 338 continue 339 } 340 341 ps = append(ps, fmt.Sprintf("%d", p)) 342 } 343 344 ps[0] = fmt.Sprintf("%d", min) 345 ps[1] = fmt.Sprintf("%d", max) 346 cnf = &BruteCaseCnfInt{ 347 BType: t, 348 Min: min, 349 Max: max, 350 Datas: ps, 351 } 352 return 353 } 354 355 type BruteCaseCnfUint struct { 356 BType BruteCaseType 357 Min uint64 358 Max uint64 359 Datas []string 360 } 361 362 func (this *BruteCaseCnfUint) Type() BruteCaseType { 363 return this.BType 364 } 365 366 func (this *BruteCaseCnfUint) RandCnt() int { 367 if this.Max == this.Min { 368 return 0 369 } 370 371 return randCntInt 372 } 373 374 func (this *BruteCaseCnfUint) Case() BruteCase { 375 return &BruteCaseUint{ 376 cnf: this, 377 cnt: uint64(len(this.Datas) + this.RandCnt()), 378 } 379 } 380 381 type BruteCaseUint struct { 382 cnf *BruteCaseCnfUint 383 cnt uint64 384 index uint64 385 } 386 387 func (this *BruteCaseUint) Next() (ok bool, v string) { 388 ok = false 389 if this.index >= this.cnt { 390 this.index = 0 391 return 392 } 393 394 if this.index < uint64(len(this.cnf.Datas)) { 395 ok = true 396 v = this.cnf.Datas[this.index] 397 this.index++ 398 return 399 } 400 401 this.index++ 402 r := rand.Int63n(int64((this.cnf.Max - this.cnf.Min) / 2)) 403 return true, fmt.Sprintf("%d", this.cnf.Min+uint64(r)*2) 404 } 405 406 func (this *BruteCaseUint) Step(step uint64) (v string) { 407 this.index = (this.index + step) % this.cnt 408 409 if this.index < uint64(len(this.cnf.Datas)) { 410 v = this.cnf.Datas[this.index] 411 this.index++ 412 return 413 } 414 415 this.index++ 416 r := rand.Int63n(int64((this.cnf.Max - this.cnf.Min) / 2)) 417 return fmt.Sprintf("%d", this.cnf.Min+uint64(r)*2) 418 } 419 420 func (this *BruteCaseUint) Count() uint64 { 421 return this.cnt 422 } 423 424 func ParseParamUint(data string, t BruteCaseType) (cnf BruteCaseCnf, err error) { 425 min := uint64(0) 426 var max uint64 427 switch t { 428 case BruteCaseType_Uint8: 429 max = math.MaxUint8 430 case BruteCaseType_Uint16: 431 max = math.MaxUint16 432 case BruteCaseType_Uint32: 433 max = math.MaxUint32 434 case BruteCaseType_Uint64: 435 max = math.MaxUint64 436 default: 437 err = fmt.Errorf("type:%d not UInt", t) 438 return 439 } 440 441 s := caseCnfInt8SpliteRe.Split(data, -1) 442 slen := len(s) 443 if slen == 0 { 444 // 默认的Int8 445 datas := make([]string, 2, 2) 446 datas[0] = fmt.Sprintf("%d", min) 447 datas[1] = fmt.Sprintf("%d", max) 448 cnf = &BruteCaseCnfUint{ 449 BType: t, 450 Min: min, 451 Max: max, 452 Datas: datas, 453 } 454 return 455 } 456 457 p, l, e := Uint64(s[0]) 458 if e != nil { 459 err = e 460 return 461 } 462 463 if l != 0 && p > min { 464 min = p 465 } 466 467 if slen <= 1 { 468 datas := make([]string, 2, 2) 469 datas[0] = fmt.Sprintf("%d", min) 470 datas[1] = fmt.Sprintf("%d", max) 471 cnf = &BruteCaseCnfUint{ 472 BType: t, 473 Min: min, 474 Max: max, 475 Datas: datas, 476 } 477 return 478 } 479 480 p, l, e = Uint64(s[1]) 481 if e != nil { 482 err = e 483 return 484 } 485 486 if l != 0 && p < max { 487 max = p 488 } 489 490 if slen <= 2 { 491 datas := make([]string, 2, 2) 492 datas[0] = fmt.Sprintf("%d", min) 493 datas[1] = fmt.Sprintf("%d", max) 494 cnf = &BruteCaseCnfUint{ 495 BType: t, 496 Min: min, 497 Max: max, 498 Datas: datas, 499 } 500 return 501 } 502 503 ps := make([]string, 2, slen) 504 for i := 2; i < slen; i++ { 505 p, l, e = Uint64(s[i]) 506 if e != nil { 507 err = e 508 return 509 } 510 511 if l == 0 { 512 continue 513 } 514 515 ps = append(ps, fmt.Sprintf("%d", p)) 516 } 517 518 ps[0] = fmt.Sprintf("%d", min) 519 ps[1] = fmt.Sprintf("%d", max) 520 cnf = &BruteCaseCnfUint{ 521 BType: t, 522 Min: min, 523 Max: max, 524 Datas: ps, 525 } 526 return 527 } 528 529 type BruteCaseCnfFloat struct { 530 BType BruteCaseType 531 Min float64 532 Max float64 533 Datas []string 534 } 535 536 func (this *BruteCaseCnfFloat) Type() BruteCaseType { 537 return this.BType 538 } 539 540 func (this *BruteCaseCnfFloat) RandCnt() int { 541 if this.Min == this.Max { 542 return 0 543 } 544 545 return randCntInt 546 } 547 548 func (this *BruteCaseCnfFloat) Case() BruteCase { 549 return &BruteCaseFloat{ 550 cnf: this, 551 cnt: uint64(len(this.Datas) + this.RandCnt()), 552 } 553 } 554 555 type BruteCaseFloat struct { 556 cnf *BruteCaseCnfFloat 557 cnt uint64 558 index uint64 559 } 560 561 func (this *BruteCaseFloat) Next() (ok bool, v string) { 562 ok = false 563 if this.index >= this.cnt { 564 this.index = 0 565 return 566 } 567 568 if this.index < uint64(len(this.cnf.Datas)) { 569 ok = true 570 v = this.cnf.Datas[this.index] 571 this.index++ 572 return 573 } 574 575 this.index++ 576 return true, fmt.Sprintf("%.5f", rand.Float64()*(this.cnf.Max-this.cnf.Min)+this.cnf.Min) 577 } 578 579 func (this *BruteCaseFloat) Step(step uint64) (v string) { 580 this.index = (this.index + step) % this.cnt 581 582 if this.index < uint64(len(this.cnf.Datas)) { 583 v = this.cnf.Datas[this.index] 584 this.index++ 585 return 586 } 587 588 this.index++ 589 return fmt.Sprintf("%.5f", rand.Float64()*(this.cnf.Max-this.cnf.Min)+this.cnf.Min) 590 } 591 592 func (this *BruteCaseFloat) Count() uint64 { 593 return this.cnt 594 } 595 596 func ParseParamFloat(data string, t BruteCaseType) (cnf BruteCaseCnf, err error) { 597 var min float64 598 var max float64 599 switch t { 600 case BruteCaseType_Float32: 601 min = -math.MaxFloat32 602 max = math.MaxFloat32 603 case BruteCaseType_Float64: 604 min = -math.MaxFloat64 605 max = math.MaxFloat64 606 default: 607 err = fmt.Errorf("type:%d not Float", t) 608 return 609 } 610 611 s := caseCnfInt8SpliteRe.Split(data, -1) 612 slen := len(s) 613 if slen == 0 { 614 // 默认的Int8 615 datas := make([]string, 2, 2) 616 datas[0] = fmt.Sprintf("%.5f", min) 617 datas[1] = fmt.Sprintf("%.5f", max) 618 cnf = &BruteCaseCnfFloat{ 619 BType: t, 620 Min: min, 621 Max: max, 622 Datas: datas, 623 } 624 return 625 } 626 627 p, l, e := Float64(s[0]) 628 if e != nil { 629 err = e 630 return 631 } 632 633 if l != 0 && p > min { 634 min = p 635 } 636 637 if slen <= 1 { 638 datas := make([]string, 2, 2) 639 datas[0] = fmt.Sprintf("%.5f", min) 640 datas[1] = fmt.Sprintf("%.5f", max) 641 cnf = &BruteCaseCnfFloat{ 642 BType: t, 643 Min: min, 644 Max: max, 645 Datas: datas, 646 } 647 return 648 } 649 650 p, l, e = Float64(s[1]) 651 if e != nil { 652 err = e 653 return 654 } 655 656 if l != 0 && p < max { 657 max = p 658 } 659 660 if slen <= 2 { 661 datas := make([]string, 2, 2) 662 datas[0] = fmt.Sprintf("%.5f", min) 663 datas[1] = fmt.Sprintf("%.5f", max) 664 cnf = &BruteCaseCnfFloat{ 665 BType: t, 666 Min: min, 667 Max: max, 668 Datas: datas, 669 } 670 return 671 } 672 673 ps := make([]string, 2, slen) 674 for i := 2; i < slen; i++ { 675 p, l, e = Float64(s[i]) 676 if e != nil { 677 err = e 678 return 679 } 680 681 if l == 0 { 682 continue 683 } 684 685 ps = append(ps, fmt.Sprintf("%.5f", p)) 686 } 687 688 ps[0] = fmt.Sprintf("%.5f", min) 689 ps[1] = fmt.Sprintf("%.5f", max) 690 cnf = &BruteCaseCnfFloat{ 691 BType: t, 692 Min: min, 693 Max: max, 694 Datas: ps, 695 } 696 return 697 } 698 699 type BruteCaseCnfBool struct { 700 } 701 702 func (this *BruteCaseCnfBool) Type() BruteCaseType { 703 return BruteCaseType_BOOL 704 } 705 706 func (this *BruteCaseCnfBool) RandCnt() int { 707 return 0 708 } 709 710 func (this *BruteCaseCnfBool) Case() BruteCase { 711 return &BruteCaseBool{} 712 } 713 714 var ( 715 bruteCaseBool = []string{"true", "false"} 716 ) 717 718 type BruteCaseBool struct { 719 index uint64 720 } 721 722 func (this *BruteCaseBool) Next() (ok bool, v string) { 723 ok = false 724 if this.index >= 2 { 725 this.index = 0 726 return 727 } 728 729 ok = true 730 v = bruteCaseBool[this.index] 731 this.index++ 732 return 733 } 734 735 func (this *BruteCaseBool) Step(step uint64) (v string) { 736 this.index = (this.index + step) % 2 737 v = bruteCaseBool[this.index] 738 this.index++ 739 return 740 } 741 742 func (this *BruteCaseBool) Count() uint64 { 743 return 2 744 } 745 746 type BruteCaseCnfString struct { 747 Min int 748 Max int 749 Datas []string 750 } 751 752 func (this *BruteCaseCnfString) Type() BruteCaseType { 753 return BruteCaseType_STR 754 } 755 756 func (this *BruteCaseCnfString) RandCnt() int { 757 return randCntString 758 } 759 760 func (this *BruteCaseCnfString) Case() BruteCase { 761 return &BruteCaseString{ 762 cnf: this, 763 cnt: uint64(len(this.Datas) + this.RandCnt()), 764 } 765 } 766 767 type BruteCaseString struct { 768 cnf *BruteCaseCnfString 769 cnt uint64 770 index uint64 771 } 772 773 const stringList = " .ABCDEFGHIJKLMNOPQRSTUVWXWZabcdefghijklmnoqprstuvwxyz0123456789" 774 775 func (this *BruteCaseString) Next() (ok bool, v string) { 776 ok = false 777 if this.index >= this.cnt { 778 this.index = 0 779 return 780 } 781 782 if this.index < uint64(len(this.cnf.Datas)) { 783 ok = true 784 v = this.cnf.Datas[this.index] 785 this.index++ 786 return 787 } 788 789 this.index++ 790 slen := rand.Int31n(int32(this.cnf.Max-this.cnf.Min)) + int32(this.cnf.Min+2) 791 b := make([]byte, slen) 792 b[0] = '"' 793 for i := 1; i < int(slen-1); i++ { 794 b[i] = stringList[rand.Int31n(int32(len(stringList)))] 795 } 796 b[slen-1] = '"' 797 return true, string(b) 798 } 799 800 func (this *BruteCaseString) Step(step uint64) (v string) { 801 this.index = (this.index + step) % this.cnt 802 803 if this.index < uint64(len(this.cnf.Datas)) { 804 v = this.cnf.Datas[this.index] 805 this.index++ 806 return 807 } 808 809 this.index++ 810 slen := rand.Int31n(int32(this.cnf.Max-this.cnf.Min)) + int32(this.cnf.Min+2) 811 b := make([]byte, slen) 812 b[0] = '"' 813 for i := 1; i < int(slen-1); i++ { 814 b[i] = stringList[rand.Int31n(int32(len(stringList)))] 815 } 816 b[slen-1] = '"' 817 return string(b) 818 } 819 820 func (this *BruteCaseString) Count() uint64 { 821 return this.cnt 822 } 823 824 func ParseParamString(data string) (cnf BruteCaseCnf, err error) { 825 minLen := 0 826 maxLen := 10 827 828 s := caseCnfInt8SpliteRe.Split(data, -1) 829 slen := len(s) 830 if slen == 0 { 831 cnf = &BruteCaseCnfString{ 832 Min: minLen, 833 Max: maxLen, 834 } 835 return 836 } 837 838 p, l, e := Int64(s[0]) 839 if e != nil { 840 err = e 841 return 842 } 843 844 if l != 0 && int(p) > minLen { 845 minLen = int(p) 846 } 847 848 if slen <= 1 { 849 cnf = &BruteCaseCnfString{ 850 Min: minLen, 851 Max: maxLen, 852 } 853 return 854 } 855 856 p, l, e = Int64(s[1]) 857 if e != nil { 858 err = e 859 return 860 } 861 862 if l != 0 && int(p) < maxLen { 863 maxLen = int(p) 864 } 865 866 if slen <= 2 { 867 cnf = &BruteCaseCnfString{ 868 Min: minLen, 869 Max: maxLen, 870 } 871 return 872 } 873 874 ps := make([]string, 0, slen-2) 875 for i := 2; i < slen; i++ { 876 var tempS string 877 tempS, l, e = String(s[i]) 878 if e != nil { 879 err = e 880 return 881 } 882 883 if l == 0 { 884 continue 885 } 886 887 ps = append(ps, fmt.Sprintf("\"%s\"", tempS)) 888 } 889 890 cnf = &BruteCaseCnfString{ 891 Min: minLen, 892 Max: maxLen, 893 Datas: ps, 894 } 895 return 896 } 897 898 type BruteCaseCnfByteString struct { 899 Min int 900 Max int 901 Datas []string 902 } 903 904 func (this *BruteCaseCnfByteString) Type() BruteCaseType { 905 return BruteCaseType_BS 906 } 907 908 func (this *BruteCaseCnfByteString) RandCnt() int { 909 return randCntBytes 910 } 911 912 func (this *BruteCaseCnfByteString) Case() BruteCase { 913 return &BruteCaseByteString{ 914 cnf: this, 915 cnt: uint64(len(this.Datas) + this.RandCnt()), 916 } 917 } 918 919 type BruteCaseByteString struct { 920 cnf *BruteCaseCnfByteString 921 cnt uint64 922 index uint64 923 } 924 925 func (this *BruteCaseByteString) Next() (ok bool, v string) { 926 ok = false 927 if this.index >= this.cnt { 928 this.index = 0 929 return 930 } 931 932 if this.index < uint64(len(this.cnf.Datas)) { 933 ok = true 934 v = this.cnf.Datas[this.index] 935 this.index++ 936 return 937 } 938 939 this.index++ 940 slen := rand.Int31n(int32(this.cnf.Max - this.cnf.Min)) 941 b := make([]byte, slen) 942 for i := 0; i < int(slen); i++ { 943 b[i] = byte(rand.Intn(255) - 128) 944 } 945 return true, fmt.Sprintf("\"%s\"", base64.StdEncoding.EncodeToString(b)) 946 } 947 948 func (this *BruteCaseByteString) Step(step uint64) (v string) { 949 this.index = (this.index + step) % this.cnt 950 if this.index < uint64(len(this.cnf.Datas)) { 951 v = this.cnf.Datas[this.index] 952 this.index++ 953 return 954 } 955 956 this.index++ 957 slen := rand.Int31n(int32(this.cnf.Max - this.cnf.Min)) 958 b := make([]byte, slen) 959 for i := 0; i < int(slen); i++ { 960 b[i] = byte(rand.Intn(255) - 128) 961 } 962 return fmt.Sprintf("\"%s\"", base64.StdEncoding.EncodeToString(b)) 963 } 964 965 func (this *BruteCaseByteString) Count() uint64 { 966 return this.cnt 967 } 968 969 func ParseParamByteString(data string) (cnf BruteCaseCnf, err error) { 970 minLen := 0 971 maxLen := 10 972 973 s := caseCnfInt8SpliteRe.Split(data, -1) 974 slen := len(s) 975 if slen == 0 { 976 cnf = &BruteCaseCnfByteString{ 977 Min: minLen, 978 Max: maxLen, 979 } 980 return 981 } 982 983 p, l, e := Int64(s[0]) 984 if e != nil { 985 err = e 986 return 987 } 988 989 if l != 0 && int(p) > minLen { 990 minLen = int(p) 991 } 992 993 if slen <= 1 { 994 cnf = &BruteCaseCnfByteString{ 995 Min: minLen, 996 Max: maxLen, 997 } 998 return 999 } 1000 1001 p, l, e = Int64(s[1]) 1002 if e != nil { 1003 err = e 1004 return 1005 } 1006 1007 if l != 0 && int(p) < maxLen { 1008 maxLen = int(p) 1009 } 1010 1011 if slen <= 2 { 1012 cnf = &BruteCaseCnfByteString{ 1013 Min: minLen, 1014 Max: maxLen, 1015 } 1016 return 1017 } 1018 1019 ps := make([]string, 0, slen-2) 1020 for i := 2; i < slen; i++ { 1021 var tempS string 1022 tempS, l, err = String(s[i]) 1023 if err != nil { 1024 return 1025 } 1026 1027 if l == 0 { 1028 continue 1029 } 1030 1031 if _, err = base64.StdEncoding.DecodeString(tempS); err != nil { 1032 return 1033 } 1034 1035 ps = append(ps, fmt.Sprintf("\"%s\"", tempS)) 1036 } 1037 1038 cnf = &BruteCaseCnfByteString{ 1039 Min: minLen, 1040 Max: maxLen, 1041 Datas: ps, 1042 } 1043 return 1044 } 1045 1046 type BruteCaseCnfMsg struct { 1047 msgName string 1048 } 1049 1050 func (this *BruteCaseCnfMsg) Type() BruteCaseType { 1051 return BruteCaseType_MSG 1052 } 1053 1054 func (this *BruteCaseCnfMsg) RandCnt() int { 1055 return 0 1056 } 1057 1058 func (this *BruteCaseCnfMsg) Case() BruteCase { 1059 mc, ok := BrutetestMsgMap[this.msgName] 1060 if !ok { 1061 return nil 1062 } 1063 1064 m := mc.Generator(0, 0) 1065 if m == nil { 1066 return nil 1067 } 1068 1069 return &BruteCaseMsg{ 1070 msg: m, 1071 } 1072 } 1073 1074 type BruteCaseMsg struct { 1075 msg *BruteMsgGenerator 1076 } 1077 1078 func (this *BruteCaseMsg) Next() (ok bool, v string) { 1079 return this.msg.Next() 1080 } 1081 1082 func (this *BruteCaseMsg) Step(step uint64) (v string) { 1083 return this.msg._step(step) 1084 } 1085 1086 func (this *BruteCaseMsg) Count() uint64 { 1087 return this.msg.Count() 1088 } 1089 1090 func ParseParamMsg(data string) (cnf BruteCaseCnf, err error) { 1091 1092 p, l, e := String(data) 1093 if e != nil { 1094 err = e 1095 return 1096 } 1097 1098 if l == 0 { 1099 err = fmt.Errorf("msgname null") 1100 return 1101 } 1102 1103 cnf = &BruteCaseCnfMsg{ 1104 msgName: p, 1105 } 1106 return 1107 } 1108 1109 type BruteCaseCnfArray struct { 1110 Min int 1111 Max int 1112 Cnf BruteCaseCnf 1113 } 1114 1115 func (this *BruteCaseCnfArray) Type() BruteCaseType { 1116 return BruteCaseType_ARR 1117 } 1118 1119 func (this *BruteCaseCnfArray) RandCnt() int { 1120 return randCntArray 1121 } 1122 1123 func (this *BruteCaseCnfArray) Case() BruteCase { 1124 return &BruteCaseArray{ 1125 cnf: this, 1126 bruteCase: this.Cnf.Case(), 1127 } 1128 } 1129 1130 type BruteCaseArray struct { 1131 cnf *BruteCaseCnfArray 1132 index uint64 1133 bruteCase BruteCase 1134 } 1135 1136 func (this *BruteCaseArray) one() string { 1137 ok, s := this.bruteCase.Next() 1138 if !ok { 1139 _, s = this.bruteCase.Next() 1140 } 1141 1142 return s 1143 } 1144 1145 func (this *BruteCaseArray) Next() (ok bool, v string) { 1146 if this.index >= this.Count() { 1147 this.index = 0 1148 return false, "" 1149 } 1150 1151 var outBuilder strings.Builder 1152 outBuilder.WriteString("[") 1153 cnt := rand.Int31n(int32(this.cnf.Max-this.cnf.Min)) + int32(this.cnf.Min) 1154 if cnt > 0 { 1155 outBuilder.WriteString(this.one()) 1156 } 1157 for i := 1; i < int(cnt); i++ { 1158 outBuilder.WriteString(",") 1159 outBuilder.WriteString(this.one()) 1160 } 1161 outBuilder.WriteString("]") 1162 this.index++ 1163 return true, outBuilder.String() 1164 } 1165 1166 func (this *BruteCaseArray) Step(step uint64) (v string) { 1167 var outBuilder strings.Builder 1168 outBuilder.WriteString("[") 1169 cnt := rand.Int31n(int32(this.cnf.Max-this.cnf.Min)) + int32(this.cnf.Min) 1170 if cnt > 0 { 1171 outBuilder.WriteString(this.one()) 1172 } 1173 for i := 1; i < int(cnt); i++ { 1174 outBuilder.WriteString(",") 1175 outBuilder.WriteString(this.one()) 1176 } 1177 outBuilder.WriteString("]") 1178 return outBuilder.String() 1179 } 1180 1181 func (this *BruteCaseArray) Count() uint64 { 1182 return uint64(this.cnf.RandCnt()) 1183 } 1184 1185 func ParseParamArray(data string) (cnf BruteCaseCnf, err error) { 1186 matches := caseCnfArrayRe.FindStringSubmatch(data) 1187 if len(matches) != 5 { 1188 err = fmt.Errorf("caseCnfArrayRe match len:%d not 5", len(matches)) 1189 return 1190 } 1191 1192 cnf, err = ParseCnf(matches[3], matches[4]) 1193 if err != nil { 1194 return 1195 } 1196 1197 min := int64(randCntArrayLenMin) 1198 max := int64(randCntArrayLenMax) 1199 i, l, e := Int64(matches[1]) 1200 if e != nil { 1201 err = e 1202 return 1203 } 1204 1205 if l > 0 { 1206 min = i 1207 } 1208 1209 i, l, e = Int64(matches[2]) 1210 if e != nil { 1211 err = e 1212 return 1213 } 1214 1215 if l > 0 { 1216 max = i 1217 } 1218 1219 cnf = &BruteCaseCnfArray{ 1220 Min: int(min), 1221 Max: int(max), 1222 Cnf: cnf, 1223 } 1224 return 1225 } 1226 1227 type BruteCaseCnfMap struct { 1228 Min int 1229 Max int 1230 Key BruteCaseCnf 1231 Value BruteCaseCnf 1232 } 1233 1234 func (this *BruteCaseCnfMap) Type() BruteCaseType { 1235 return BruteCaseType_MAP 1236 } 1237 1238 func (this *BruteCaseCnfMap) RandCnt() int { 1239 return randCntMap 1240 } 1241 1242 func (this *BruteCaseCnfMap) Case() BruteCase { 1243 return &BruteCaseMap{ 1244 cnf: this, 1245 key: this.Key.Case(), 1246 value: this.Value.Case(), 1247 } 1248 } 1249 1250 type BruteCaseMap struct { 1251 cnf *BruteCaseCnfMap 1252 cnt uint64 1253 index uint64 1254 key BruteCase 1255 value BruteCase 1256 } 1257 1258 func (this *BruteCaseMap) one(keys map[string]bool) string { 1259 var outBuilder strings.Builder 1260 1261 ok := false 1262 s := "" 1263 for !ok { 1264 ok, s = this.key.Next() 1265 if ok { 1266 _, ok = keys[s] 1267 ok = !ok 1268 } 1269 } 1270 keys[s] = true 1271 1272 if s[0] == '"' { 1273 outBuilder.WriteString(s) 1274 outBuilder.WriteString(":") 1275 } else { 1276 outBuilder.WriteString("\"") 1277 outBuilder.WriteString(s) 1278 outBuilder.WriteString("\":") 1279 } 1280 1281 ok, s = this.value.Next() 1282 if !ok { 1283 _, s = this.value.Next() 1284 } 1285 outBuilder.WriteString(s) 1286 1287 return outBuilder.String() 1288 } 1289 1290 func (this *BruteCaseMap) Next() (ok bool, v string) { 1291 if this.index >= this.Count() { 1292 this.index = 0 1293 return false, "" 1294 } 1295 1296 var outBuilder strings.Builder 1297 outBuilder.WriteString("{") 1298 cnt := rand.Int31n(int32(this.cnf.Max-this.cnf.Min)) + int32(this.cnf.Min) 1299 keys := make(map[string]bool, cnt) 1300 for i := 0; i < int(cnt); i++ { 1301 if i > 0 { 1302 outBuilder.WriteString(",") 1303 } 1304 outBuilder.WriteString(this.one(keys)) 1305 } 1306 outBuilder.WriteString("}") 1307 this.index++ 1308 return true, outBuilder.String() 1309 } 1310 1311 func (this *BruteCaseMap) Step(step uint64) (v string) { 1312 var outBuilder strings.Builder 1313 outBuilder.WriteString("{") 1314 cnt := rand.Int31n(int32(this.cnf.Max-this.cnf.Min)) + int32(this.cnf.Min) 1315 keys := make(map[string]bool, cnt) 1316 1317 for i := 0; i < int(cnt); i++ { 1318 if i > 0 { 1319 outBuilder.WriteString(",") 1320 } 1321 outBuilder.WriteString(this.one(keys)) 1322 } 1323 outBuilder.WriteString("}") 1324 return outBuilder.String() 1325 } 1326 1327 func (this *BruteCaseMap) Count() uint64 { 1328 return this.key.Count() 1329 } 1330 1331 func ParseParamMap(data string) (cnf BruteCaseCnf, err error) { 1332 matches := caseCnfMapRe.FindStringSubmatch(data) 1333 if len(matches) != 7 { 1334 err = fmt.Errorf("caseCnfMapRe match len:%d not 5", len(matches)) 1335 return 1336 } 1337 1338 key, err := ParseCnf(matches[3], matches[4]) 1339 if err != nil { 1340 return 1341 } 1342 1343 value, err := ParseCnf(matches[5], matches[6]) 1344 if err != nil { 1345 return 1346 } 1347 1348 min := int64(randCntMapLenMin) 1349 max := int64(randCntMapLenMax) 1350 i, l, e := Int64(matches[1]) 1351 if e != nil { 1352 err = e 1353 return 1354 } 1355 1356 if l > 0 { 1357 min = i 1358 } 1359 1360 i, l, e = Int64(matches[2]) 1361 if e != nil { 1362 err = e 1363 return 1364 } 1365 1366 if l > 0 { 1367 max = i 1368 } 1369 1370 cnf = &BruteCaseCnfMap{ 1371 Min: int(min), 1372 Max: int(max), 1373 Key: key, 1374 Value: value, 1375 } 1376 return 1377 } 1378 1379 type BruteMsgCnf struct { 1380 Test bool 1381 Pre string 1382 1383 MsgName string 1384 MsgId int 1385 ResponeId int 1386 Timeout int64 1387 1388 Data string 1389 Ctxs []string 1390 Cnfs []BruteCaseCnf 1391 } 1392 1393 func (this *BruteMsgCnf) Generator(skip uint64, cnt uint64) *BruteMsgGenerator { 1394 cnfCnt := len(this.Cnfs) 1395 cases := make([]BruteCase, cnfCnt) 1396 caseCnts := make([]uint64, cnfCnt) 1397 testCnt := uint64(1) 1398 for i := cnfCnt - 1; i >= 0; i-- { 1399 c := this.Cnfs[i] 1400 1401 cases[i] = c.Case() 1402 if cases[i] == nil { 1403 return nil 1404 } 1405 1406 testCnt = testCnt * cases[i].Count() 1407 if i > 0 { 1408 caseCnts[i-1] = testCnt 1409 } 1410 } 1411 1412 var caseNows []string 1413 if cnfCnt > 0 { 1414 caseNows = make([]string, cnfCnt) 1415 caseCnts[cnfCnt-1] = 1 1416 } 1417 1418 step := uint64(1) 1419 if testCnt > generator_cnt_max { 1420 step = testCnt / generator_cnt_max 1421 } 1422 1423 gen := BruteMsgGenerator{ 1424 iteratoring: false, 1425 cnf: this, 1426 cases: cases, 1427 casesNows: caseNows, 1428 1429 caseCnts: caseCnts, 1430 cnt: testCnt, 1431 skip: skip, 1432 limit: cnt, 1433 1434 step: step, 1435 } 1436 1437 return &gen 1438 } 1439 1440 // 设置offset、Count,实现一个generator拆分不同task并发测试 1441 // 使用Step来进行实际测试数量调整。因为一个robot 10ms一次测试,限制一个测试单元的测试次数在30万次以内。如果超过了,就会使用Step进行随机跳跃 1442 type BruteMsgGenerator struct { 1443 iteratoring bool // 是否遍历过程中 1444 cnf *BruteMsgCnf 1445 cases []BruteCase 1446 casesNows []string 1447 format string 1448 1449 cnt uint64 // 用例总次数 1450 caseCnts []uint64 // 每个用例的次数 1451 skip uint64 // 跳过的用例数 1452 1453 index uint64 // 当前返回次数 1454 limit uint64 // 限制的用例数 1455 1456 step uint64 // 获取用例的步长 1457 } 1458 1459 func (this *BruteMsgGenerator) reset() { 1460 this.iteratoring = false 1461 } 1462 1463 func (this *BruteMsgGenerator) _next() (bool, string) { 1464 index := 0 1465 if !this.iteratoring { 1466 this.iteratoring = true 1467 // 还未初始化 1468 caseLen := len(this.cases) 1469 if caseLen == 0 { 1470 // 没有随机 1471 return true, this.cnf.Ctxs[0] 1472 } 1473 1474 var formatBuild strings.Builder 1475 formatBuild.WriteString(this.cnf.Ctxs[index]) 1476 1477 for ; index < caseLen-1; index++ { 1478 _, this.casesNows[index] = this.cases[index].Next() 1479 formatBuild.WriteString(this.casesNows[index]) 1480 formatBuild.WriteString(this.cnf.Ctxs[index+1]) 1481 } 1482 1483 formatBuild.WriteString("%s") 1484 formatBuild.WriteString(this.cnf.Ctxs[index+1]) 1485 1486 this.format = formatBuild.String() 1487 } 1488 1489 if len(this.cases) == 0 { 1490 // 无随机 1491 return false, "" 1492 } 1493 index = len(this.cases) - 1 1494 ok, cs := this.cases[index].Next() 1495 if !ok { 1496 // 需要进行format重新生成 1497 index-- 1498 1499 for ; index >= 0; index-- { 1500 ok, cs = this.cases[index].Next() 1501 if ok { 1502 break 1503 } 1504 } 1505 1506 if !ok { 1507 // 遍历结束 1508 return false, "" 1509 } 1510 1511 this.casesNows[index] = cs 1512 1513 var formatBuild strings.Builder 1514 for i := 0; i <= index; i++ { 1515 formatBuild.WriteString(this.cnf.Ctxs[i]) 1516 formatBuild.WriteString(this.casesNows[i]) 1517 } 1518 1519 for index++; index < len(this.cases)-1; index++ { 1520 formatBuild.WriteString(this.cnf.Ctxs[index]) 1521 _, this.casesNows[index] = this.cases[index].Next() 1522 formatBuild.WriteString(this.casesNows[index]) 1523 } 1524 1525 formatBuild.WriteString(this.cnf.Ctxs[index]) 1526 formatBuild.WriteString("%s") 1527 formatBuild.WriteString(this.cnf.Ctxs[index+1]) 1528 1529 this.format = formatBuild.String() 1530 1531 ok, cs = this.cases[index].Next() 1532 } 1533 1534 return true, fmt.Sprintf(this.format, cs) 1535 } 1536 1537 func (this *BruteMsgGenerator) _step(step uint64) string { 1538 var b strings.Builder 1539 if !this.iteratoring { 1540 step = this.skip 1541 for i := 0; i < len(this.cases); i++ { 1542 b.WriteString(this.cnf.Ctxs[i]) 1543 cStep := (step / this.caseCnts[i]) % this.cases[i].Count() 1544 if cStep > 0 { 1545 this.casesNows[i] = this.cases[i].Step(cStep) 1546 } else { 1547 this.casesNows[i] = this.cases[i].Step(1) 1548 } 1549 b.WriteString(this.casesNows[i]) 1550 } 1551 this.iteratoring = true 1552 } else { 1553 for i := 0; i < len(this.cases); i++ { 1554 b.WriteString(this.cnf.Ctxs[i]) 1555 cStep := (step / this.caseCnts[i]) % this.cases[i].Count() 1556 if cStep > 0 { 1557 this.casesNows[i] = this.cases[i].Step(cStep) 1558 } 1559 b.WriteString(this.casesNows[i]) 1560 } 1561 } 1562 b.WriteString(this.cnf.Ctxs[len(this.cases)]) 1563 1564 return b.String() 1565 } 1566 1567 func (this *BruteMsgGenerator) Next() (bool, string) { 1568 if this.limit > 0 && this.index > this.limit { 1569 this.reset() 1570 return false, "" 1571 } 1572 1573 if this.step == 1 { 1574 ok, s := this._next() 1575 if !ok { 1576 this.reset() 1577 } else { 1578 this.index++ 1579 } 1580 return ok, s 1581 } 1582 1583 this.index++ 1584 return true, this._step(this.step) 1585 } 1586 1587 func (this *BruteMsgGenerator) RealCount() uint64 { 1588 return this.cnt 1589 } 1590 1591 func (this *BruteMsgGenerator) Count() uint64 { 1592 return this.cnt / this.step 1593 } 1594 1595 func (this *BruteMsgGenerator) Step() uint64 { 1596 return this.step 1597 } 1598 1599 func (this *BruteMsgGenerator) BruteCnf() *BruteMsgCnf { 1600 return this.cnf 1601 } 1602 1603 func ParseCnf(t string, param string) (cnf BruteCaseCnf, err error) { 1604 switch t { 1605 case "I8": 1606 cnf, err = ParseParamInt(param, BruteCaseType_Int8) 1607 if err != nil { 1608 return 1609 } 1610 case "I16": 1611 cnf, err = ParseParamInt(param, BruteCaseType_Int16) 1612 if err != nil { 1613 return 1614 } 1615 case "I32": 1616 cnf, err = ParseParamInt(param, BruteCaseType_Int32) 1617 if err != nil { 1618 return 1619 } 1620 case "I64": 1621 cnf, err = ParseParamInt(param, BruteCaseType_Int64) 1622 if err != nil { 1623 return 1624 } 1625 case "U8": 1626 cnf, err = ParseParamUint(param, BruteCaseType_Uint8) 1627 if err != nil { 1628 return 1629 } 1630 case "U16": 1631 cnf, err = ParseParamUint(param, BruteCaseType_Uint16) 1632 if err != nil { 1633 return 1634 } 1635 case "U32": 1636 cnf, err = ParseParamUint(param, BruteCaseType_Uint32) 1637 if err != nil { 1638 return 1639 } 1640 case "U64": 1641 cnf, err = ParseParamUint(param, BruteCaseType_Uint64) 1642 if err != nil { 1643 return 1644 } 1645 case "F32": 1646 cnf, err = ParseParamFloat(param, BruteCaseType_Float32) 1647 if err != nil { 1648 return 1649 } 1650 case "F64": 1651 cnf, err = ParseParamFloat(param, BruteCaseType_Float64) 1652 if err != nil { 1653 return 1654 } 1655 case "BL": 1656 cnf = &BruteCaseCnfBool{} 1657 case "STR": 1658 cnf, err = ParseParamString(param) 1659 if err != nil { 1660 return 1661 } 1662 case "BS": 1663 cnf, err = ParseParamByteString(param) 1664 if err != nil { 1665 return 1666 } 1667 case "MSG": 1668 cnf, err = ParseParamMsg(param) 1669 if err != nil { 1670 return 1671 } 1672 case "ARR": 1673 cnf, err = ParseParamArray(param) 1674 if err != nil { 1675 return 1676 } 1677 case "MAP": 1678 cnf, err = ParseParamMap(param) 1679 if err != nil { 1680 return 1681 } 1682 default: 1683 err = fmt.Errorf("type:%s err %s", t, param) 1684 } 1685 1686 return 1687 } 1688 1689 func Json2Brute(data string) (ctxs []string, cnfs []BruteCaseCnf, err error) { 1690 // 查找随机,记录 1691 ctxs = make([]string, 0, 10) 1692 cnfs = make([]BruteCaseCnf, 0, 9) 1693 1694 lastIndex := 0 1695 caseIndexes := caseCnfRe.FindAllStringSubmatchIndex(data, -1) 1696 for _, v := range caseIndexes { 1697 var c BruteCaseCnf 1698 c, err = ParseCnf(data[v[2]:v[3]], data[v[4]:v[5]]) 1699 ctxs = append(ctxs, data[lastIndex:v[0]+1]) 1700 lastIndex = v[1] 1701 cnfs = append(cnfs, c) 1702 } 1703 1704 if lastIndex < len(data) { 1705 ctxs = append(ctxs, data[lastIndex:]) 1706 } 1707 1708 return 1709 } 1710 1711 func BruteTestFileExsit(file string) bool { 1712 f, err := os.Stat(fmt.Sprintf("%s/%s", prePath, file)) 1713 if err != nil { 1714 log.LogError("os.State %s/%s err:%s", prePath, file, err.Error()) 1715 return false 1716 } 1717 1718 return f != nil 1719 } 1720 func BruteTestCreate(file string) (err error) { 1721 // 进行配置加载 1722 readFile, err := ioutil.ReadFile(fmt.Sprintf("%s/%s", prePath, file)) 1723 if err != nil { 1724 log.LogError("File open:%s/%s err:%s", prePath, file, err.Error()) 1725 return 1726 } 1727 1728 v, err := fastjson.ParseBytes(readFile) 1729 if err != nil { 1730 log.LogError("File:%s fastjson Parse err:%s", file, err.Error()) 1731 return 1732 } 1733 1734 a, err := v.Array() 1735 if err != nil { 1736 log.LogError("File:%s Object Get err:%s", file, err.Error()) 1737 return 1738 } 1739 1740 caseId := 1 1741 for i := 0; i < len(a); i++ { 1742 c := BruteMsgCnf{} 1743 m := a[i] 1744 1745 c.Test = !m.GetBool("notest") 1746 c.Pre = string(m.GetStringBytes("premsg")) 1747 1748 c.MsgName = string(m.GetStringBytes("msgname")) 1749 c.MsgId = m.GetInt("msgid") 1750 c.ResponeId = m.GetInt("responseid") 1751 c.Timeout = m.GetInt64("timeout") 1752 1753 c.Data = m.GetObject("data").String() 1754 1755 // 进行data文本解析 1756 c.Ctxs, c.Cnfs, err = Json2Brute(c.Data) 1757 if err != nil { 1758 log.LogError("msg:%s Json2Brute err:%s", c.MsgName, err.Error()) 1759 return 1760 } 1761 1762 if !c.Test { 1763 BrutetestMsgMap[c.MsgName] = &c 1764 } else { 1765 BrutetestMsgMap[c.MsgName] = &c 1766 msgSlice := make([]*BruteMsgCnf, 0, 1) 1767 msgSlice = append(msgSlice, &c) 1768 BrutetestCaselistMap[caseId] = msgSlice 1769 caseId++ 1770 } 1771 } 1772 1773 for _, mslice := range BrutetestCaselistMap { 1774 for pre := mslice[0].Pre; len(pre) > 0; { 1775 m, ok := BrutetestMsgMap[pre] 1776 if !ok { 1777 err = fmt.Errorf("msg:%s pre:%s nil", mslice[len(mslice)-1].MsgName, pre) 1778 return 1779 } 1780 1781 mslice = append(mslice, m) 1782 pre = m.Pre 1783 } 1784 } 1785 1786 return 1787 } 1788 1789 func BruteTestSave(file string) { 1790 brutes := make([]*BruteMsgCnf, 0, len(BrutetestMsgMap)) 1791 for _, b := range BrutetestMsgMap { 1792 brutes = append(brutes, b) 1793 } 1794 1795 sort.Slice(brutes, func(i, j int) bool { 1796 if brutes[i].MsgId > 0 && brutes[j].MsgId > 0 { 1797 return brutes[i].MsgId < brutes[j].MsgId 1798 } 1799 1800 if brutes[i].MsgId > 0 { 1801 return true 1802 } 1803 1804 if brutes[j].MsgId > 0 { 1805 return false 1806 } 1807 1808 return brutes[i].MsgName < brutes[j].MsgName 1809 }) 1810 1811 writeFile, err := os.OpenFile(fmt.Sprintf("%s/%s", prePath, file), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666) 1812 if err != nil { 1813 log.LogError("No File:%s/%s", prePath, file) 1814 return 1815 } 1816 1817 if len(brutes) == 0 { 1818 log.LogInfo("brute msg 0") 1819 return 1820 } 1821 1822 log.LogInfo("%s/%s brutes cnt:%d", prePath, file, len(brutes)) 1823 writeFile.WriteString("[") 1824 1825 for i := 0; i < len(brutes); i++ { 1826 b := brutes[i] 1827 1828 if b.Test { 1829 tCnt := b.Generator(0, 0).Count() 1830 if tCnt > testcnt_warn { 1831 log.LogError("%s Test Count:%d try mannual config", b.MsgName, tCnt) 1832 } 1833 } 1834 1835 if i == 0 { 1836 writeFile.WriteString("\n\t{\n") 1837 } else { 1838 writeFile.WriteString(",\n\t{\n") 1839 } 1840 1841 writeFile.WriteString(fmt.Sprintf("\t\t\"msgname\":\"%s\",\n", b.MsgName)) 1842 if !b.Test { 1843 writeFile.WriteString("\t\t\"notest\":true,\n") 1844 } else { 1845 writeFile.WriteString(fmt.Sprintf("\t\t\"msgid\":%d,\n", b.MsgId)) 1846 writeFile.WriteString(fmt.Sprintf("\t\t\"responseid\":%d,\n", b.ResponeId)) 1847 if b.Timeout != 0 { 1848 writeFile.WriteString(fmt.Sprintf("\t\t\"timeout\":%d,\n", b.Timeout)) 1849 } 1850 } 1851 1852 if len(b.Pre) > 0 { 1853 writeFile.WriteString(fmt.Sprintf("\t\t\"premsg\":\"%s\",\n", b.Pre)) 1854 } 1855 1856 var buf bytes.Buffer 1857 err := json.Indent(&buf, []byte(b.Data), "", "\t\t\t") 1858 if err != nil { 1859 log.LogError("%d Indent err:%s", b.Data, err.Error()) 1860 } 1861 if buf.Len() > 2 { 1862 buf.Truncate(buf.Len() - 1) 1863 buf.WriteString("\t\t}") 1864 } 1865 writeFile.WriteString(fmt.Sprintf("\t\t\"data\":%s", buf.String())) 1866 1867 writeFile.WriteString("\n\t}") 1868 } 1869 writeFile.WriteString("\n]") 1870 1871 writeFile.Sync() 1872 writeFile.Close() 1873 }