mask_test.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. // Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. Use of
  2. // this source code is governed by a BSD-style license that can be found in the
  3. // LICENSE file.
  4. // !appengine
  5. package websocket
  6. import (
  7. "fmt"
  8. "testing"
  9. )
  10. func maskBytesByByte(key [4]byte, pos int, b []byte) int {
  11. for i := range b {
  12. b[i] ^= key[pos&3]
  13. pos++
  14. }
  15. return pos & 3
  16. }
  17. func notzero(b []byte) int {
  18. for i := range b {
  19. if b[i] != 0 {
  20. return i
  21. }
  22. }
  23. return -1
  24. }
  25. func TestMaskBytes(t *testing.T) {
  26. key := [4]byte{1, 2, 3, 4}
  27. for size := 1; size <= 1024; size++ {
  28. for align := 0; align < wordSize; align++ {
  29. for pos := 0; pos < 4; pos++ {
  30. b := make([]byte, size+align)[align:]
  31. maskBytes(key, pos, b)
  32. maskBytesByByte(key, pos, b)
  33. if i := notzero(b); i >= 0 {
  34. t.Errorf("size:%d, align:%d, pos:%d, offset:%d", size, align, pos, i)
  35. }
  36. }
  37. }
  38. }
  39. }
  40. func BenchmarkMaskBytes(b *testing.B) {
  41. for _, size := range []int{2, 4, 8, 16, 32, 512, 1024} {
  42. b.Run(fmt.Sprintf("size-%d", size), func(b *testing.B) {
  43. for _, align := range []int{wordSize / 2} {
  44. b.Run(fmt.Sprintf("align-%d", align), func(b *testing.B) {
  45. for _, fn := range []struct {
  46. name string
  47. fn func(key [4]byte, pos int, b []byte) int
  48. }{
  49. {"byte", maskBytesByByte},
  50. {"word", maskBytes},
  51. } {
  52. b.Run(fn.name, func(b *testing.B) {
  53. key := newMaskKey()
  54. data := make([]byte, size+align)[align:]
  55. for i := 0; i < b.N; i++ {
  56. fn.fn(key, 0, data)
  57. }
  58. b.SetBytes(int64(len(data)))
  59. })
  60. }
  61. })
  62. }
  63. })
  64. }
  65. }