mirror of https://github.com/grafana/grafana.git
				
				
				
			
		
			
				
	
	
		
			220 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			220 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Go
		
	
	
	
| package util
 | |
| 
 | |
| import (
 | |
| 	"math"
 | |
| 	"strings"
 | |
| 	"testing"
 | |
| 
 | |
| 	"github.com/stretchr/testify/assert"
 | |
| 	"github.com/stretchr/testify/require"
 | |
| )
 | |
| 
 | |
| func TestGetBasicAuthHeader_Encoding(t *testing.T) {
 | |
| 	t.Run("generating base64 header", func(t *testing.T) {
 | |
| 		result := GetBasicAuthHeader("grafana", "1234")
 | |
| 		assert.Equal(t, "Basic Z3JhZmFuYToxMjM0", result)
 | |
| 	})
 | |
| 
 | |
| 	t.Run("decoding basic auth header", func(t *testing.T) {
 | |
| 		header := GetBasicAuthHeader("grafana", "1234")
 | |
| 		username, password, err := DecodeBasicAuthHeader(header)
 | |
| 		require.NoError(t, err)
 | |
| 
 | |
| 		assert.Equal(t, "grafana", username)
 | |
| 		assert.Equal(t, "1234", password)
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func TestEncodePassword(t *testing.T) {
 | |
| 	encodedPassword, err := EncodePassword("iamgod", "pepper")
 | |
| 	require.NoError(t, err)
 | |
| 	assert.Equal(
 | |
| 		t,
 | |
| 		"e59c568621e57756495a468f47c74e07c911b037084dd464bb2ed72410970dc849cabd71b48c394faf08a5405dae53741ce9",
 | |
| 		encodedPassword,
 | |
| 	)
 | |
| }
 | |
| 
 | |
| func TestDecodeQuotedPrintable(t *testing.T) {
 | |
| 	t.Run("should return not encoded string as is", func(t *testing.T) {
 | |
| 		testStrings := []struct {
 | |
| 			in  string
 | |
| 			out string
 | |
| 		}{
 | |
| 			{"", ""},
 | |
| 			{"munich", "munich"},
 | |
| 			{" munich", " munich"},
 | |
| 			{"munich gothenburg", "munich gothenburg"},
 | |
| 			{"München", "München"},
 | |
| 			{"München Göteborg", "München Göteborg"},
 | |
| 		}
 | |
| 
 | |
| 		for _, str := range testStrings {
 | |
| 			val := DecodeQuotedPrintable(str.in)
 | |
| 			assert.Equal(t, str.out, val)
 | |
| 		}
 | |
| 	})
 | |
| 
 | |
| 	t.Run("should decode encoded string", func(t *testing.T) {
 | |
| 		testStrings := []struct {
 | |
| 			in  string
 | |
| 			out string
 | |
| 		}{
 | |
| 			{"M=C3=BCnchen", "München"},
 | |
| 			{"M=C3=BCnchen G=C3=B6teborg", "München Göteborg"},
 | |
| 			{"=E5=85=AC=E5=8F=B8", "公司"},
 | |
| 		}
 | |
| 
 | |
| 		for _, str := range testStrings {
 | |
| 			val := DecodeQuotedPrintable(str.in)
 | |
| 			assert.Equal(t, str.out, val)
 | |
| 		}
 | |
| 	})
 | |
| 
 | |
| 	t.Run("should preserve meaningful whitespace", func(t *testing.T) {
 | |
| 		testStrings := []struct {
 | |
| 			in  string
 | |
| 			out string
 | |
| 		}{
 | |
| 			{"  ", ""},
 | |
| 			{"  =", "  "},
 | |
| 			{" munich  gothenburg", " munich  gothenburg"},
 | |
| 			{" munich  gothenburg  ", " munich  gothenburg"},
 | |
| 			{" munich  gothenburg  =", " munich  gothenburg  "},
 | |
| 			{" munich\tgothenburg\t \t", " munich\tgothenburg"},
 | |
| 			{" munich\t gothenburg\t \t=", " munich\t gothenburg\t \t"},
 | |
| 		}
 | |
| 
 | |
| 		for _, str := range testStrings {
 | |
| 			val := DecodeQuotedPrintable(str.in)
 | |
| 			assert.Equal(t, str.out, val)
 | |
| 		}
 | |
| 	})
 | |
| 
 | |
| 	t.Run("should gracefully ignore invalid encoding sequences", func(t *testing.T) {
 | |
| 		testStrings := []struct {
 | |
| 			in  string
 | |
| 			out string
 | |
| 		}{
 | |
| 			{"=XY=ZZ", "=XY=ZZ"},
 | |
| 			{"==58", "=X"},
 | |
| 			{"munich = gothenburg", "munich = gothenburg"},
 | |
| 			{"munich == tromso", "munich == tromso"},
 | |
| 		}
 | |
| 
 | |
| 		for _, str := range testStrings {
 | |
| 			val := DecodeQuotedPrintable(str.in)
 | |
| 			assert.Equal(t, str.out, val)
 | |
| 		}
 | |
| 	})
 | |
| 
 | |
| 	t.Run("should return invalid UTF-8 sequences as is", func(t *testing.T) {
 | |
| 		testStrings := []struct {
 | |
| 			in  string
 | |
| 			out string
 | |
| 		}{
 | |
| 			{"=E5 =85=AC =E5=8F =B8", "\xE5 \x85\xAC \xE5\x8F \xB8"},
 | |
| 			{"=00=00munich=FF=FF", "\x00\x00munich\xFF\xFF"},
 | |
| 		}
 | |
| 
 | |
| 		for _, str := range testStrings {
 | |
| 			val := DecodeQuotedPrintable(str.in)
 | |
| 			assert.Equal(t, str.out, val)
 | |
| 		}
 | |
| 	})
 | |
| 
 | |
| 	t.Run("should support long strings", func(t *testing.T) {
 | |
| 		str_in := strings.Repeat(" M=C3=BCnchen", 128)
 | |
| 		str_out := strings.Repeat(" München", 128)
 | |
| 
 | |
| 		val := DecodeQuotedPrintable(str_in)
 | |
| 		assert.Equal(t, str_out, val)
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func TestGetRandomString(t *testing.T) {
 | |
| 	charset := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
 | |
| 	chars := len(charset)
 | |
| 	length := 20
 | |
| 	rounds := 50_000
 | |
| 
 | |
| 	// Generate random strings and count the frequency of each character
 | |
| 	m := make(map[string]int)
 | |
| 	for i := 0; i < rounds; i++ {
 | |
| 		r, err := GetRandomString(length)
 | |
| 		require.NoError(t, err)
 | |
| 
 | |
| 		for _, c := range r {
 | |
| 			m[string(c)]++
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	// Find lowest and highest frequencies
 | |
| 	min := rounds * length
 | |
| 	max := 0
 | |
| 
 | |
| 	// Calculate chi-squared statistic
 | |
| 	expected := float64(rounds) * float64(length) / float64(chars)
 | |
| 	chiSquared := 0.0
 | |
| 
 | |
| 	for _, char := range charset {
 | |
| 		if m[string(char)] < min {
 | |
| 			min = m[string(char)]
 | |
| 		}
 | |
| 		if m[string(char)] > max {
 | |
| 			max = m[string(char)]
 | |
| 		}
 | |
| 		chiSquared += math.Pow(float64(m[string(char)])-expected, 2) / expected
 | |
| 	}
 | |
| 
 | |
| 	// Ensure there is no more than 10% variance between lowest and highest frequency characters
 | |
| 	assert.LessOrEqual(t, float64(max-min)/float64(min), 0.1, "Variance between lowest and highest frequency characters must be no more than 10%")
 | |
| 
 | |
| 	// Ensure chi-squared value is lower than the critical bound
 | |
| 	// 99.99% probability for 61 degrees of freedom
 | |
| 	assert.Less(t, chiSquared, 110.8397, "Chi squared value must be less than the 99.99% critical bound")
 | |
| }
 | |
| 
 | |
| func TestGetRandomDigits(t *testing.T) {
 | |
| 	charset := "0123456789"
 | |
| 	chars := len(charset)
 | |
| 	length := 20
 | |
| 	rounds := 50_000
 | |
| 
 | |
| 	// Generate random strings and count the frequency of each character
 | |
| 	m := make(map[string]int)
 | |
| 	for i := 0; i < rounds; i++ {
 | |
| 		r, err := GetRandomString(length, []byte(charset)...)
 | |
| 		require.NoError(t, err)
 | |
| 
 | |
| 		for _, c := range r {
 | |
| 			m[string(c)]++
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	// Find lowest and highest frequencies
 | |
| 	min := rounds * length
 | |
| 	max := 0
 | |
| 
 | |
| 	// Calculate chi-squared statistic
 | |
| 	expected := float64(rounds) * float64(length) / float64(chars)
 | |
| 	chiSquared := 0.0
 | |
| 
 | |
| 	for _, char := range charset {
 | |
| 		if m[string(char)] < min {
 | |
| 			min = m[string(char)]
 | |
| 		}
 | |
| 		if m[string(char)] > max {
 | |
| 			max = m[string(char)]
 | |
| 		}
 | |
| 		chiSquared += math.Pow(float64(m[string(char)])-expected, 2) / expected
 | |
| 	}
 | |
| 
 | |
| 	// Ensure there is no more than 10% variance between lowest and highest frequency characters
 | |
| 	assert.LessOrEqual(t, float64(max-min)/float64(min), 0.1, "Variance between lowest and highest frequency characters must be no more than 10%")
 | |
| 
 | |
| 	// Ensure chi-squared value is lower than the critical bound
 | |
| 	// 99.99% probability for 9 degrees of freedom
 | |
| 	assert.Less(t, chiSquared, 33.7199, "Chi squared value must be less than the 99.99% critical bound")
 | |
| }
 |