mirror of
https://github.com/Luzifer/nginx-sso.git
synced 2024-12-21 13:21:17 +00:00
318 lines
9.8 KiB
Go
318 lines
9.8 KiB
Go
|
// Copyright 2018, OpenCensus Authors
|
||
|
//
|
||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
// you may not use this file except in compliance with the License.
|
||
|
// You may obtain a copy of the License at
|
||
|
//
|
||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||
|
//
|
||
|
// Unless required by applicable law or agreed to in writing, software
|
||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
// See the License for the specific language governing permissions and
|
||
|
// limitations under the License.
|
||
|
|
||
|
package tracestate
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"testing"
|
||
|
)
|
||
|
|
||
|
func checkFront(t *testing.T, tracestate *Tracestate, wantKey, testname string) {
|
||
|
gotKey := tracestate.entries[0].Key
|
||
|
if gotKey != wantKey {
|
||
|
t.Errorf("test:%s: first entry in the list: got %q want %q", testname, gotKey, wantKey)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func checkBack(t *testing.T, tracestate *Tracestate, wantKey, testname string) {
|
||
|
gotKey := tracestate.entries[len(tracestate.entries)-1].Key
|
||
|
if gotKey != wantKey {
|
||
|
t.Errorf("test:%s: last entry in the list: got %q want %q", testname, gotKey, wantKey)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func checkSize(t *testing.T, tracestate *Tracestate, wantSize int, testname string) {
|
||
|
if gotSize := len(tracestate.entries); gotSize != wantSize {
|
||
|
t.Errorf("test:%s: size of the list: got %q want %q", testname, gotSize, wantSize)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (ts *Tracestate) get(key string) (string, bool) {
|
||
|
if ts == nil {
|
||
|
return "", false
|
||
|
}
|
||
|
for _, entry := range ts.entries {
|
||
|
if entry.Key == key {
|
||
|
return entry.Value, true
|
||
|
}
|
||
|
}
|
||
|
return "", false
|
||
|
}
|
||
|
|
||
|
func checkKeyValue(t *testing.T, tracestate *Tracestate, key, wantValue, testname string) {
|
||
|
wantOk := true
|
||
|
if wantValue == "" {
|
||
|
wantOk = false
|
||
|
}
|
||
|
gotValue, gotOk := tracestate.get(key)
|
||
|
if wantOk != gotOk || gotValue != wantValue {
|
||
|
t.Errorf("test:%s: get value for key=%s failed: got %q want %q", testname, key, gotValue, wantValue)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func checkError(t *testing.T, tracestate *Tracestate, err error, testname, msg string) {
|
||
|
if err != nil {
|
||
|
t.Errorf("test:%s: %s: tracestate=%v, error= %v", testname, msg, tracestate, err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func wantError(t *testing.T, tracestate *Tracestate, err error, testname, msg string) {
|
||
|
if err == nil {
|
||
|
t.Errorf("test:%s: %s: tracestate=%v, error=%v", testname, msg, tracestate, err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestCreateWithNullParent(t *testing.T) {
|
||
|
key1, value1 := "hello", "world"
|
||
|
testname := "TestCreateWithNullParent"
|
||
|
|
||
|
entry := Entry{key1, value1}
|
||
|
tracestate, err := New(nil, entry)
|
||
|
checkError(t, tracestate, err, testname, "create failed from null parent")
|
||
|
checkKeyValue(t, tracestate, key1, value1, testname)
|
||
|
}
|
||
|
|
||
|
func TestCreateFromParentWithSingleKey(t *testing.T) {
|
||
|
key1, value1, key2, value2 := "hello", "world", "foo", "bar"
|
||
|
testname := "TestCreateFromParentWithSingleKey"
|
||
|
|
||
|
entry1 := Entry{key1, value1}
|
||
|
entry2 := Entry{key2, value2}
|
||
|
parent, _ := New(nil, entry1)
|
||
|
tracestate, err := New(parent, entry2)
|
||
|
|
||
|
checkError(t, tracestate, err, testname, "create failed from parent with single key")
|
||
|
checkKeyValue(t, tracestate, key2, value2, testname)
|
||
|
checkFront(t, tracestate, key2, testname)
|
||
|
checkBack(t, tracestate, key1, testname)
|
||
|
}
|
||
|
|
||
|
func TestCreateFromParentWithDoubleKeys(t *testing.T) {
|
||
|
key1, value1, key2, value2, key3, value3 := "hello", "world", "foo", "bar", "bar", "baz"
|
||
|
testname := "TestCreateFromParentWithDoubleKeys"
|
||
|
|
||
|
entry1 := Entry{key1, value1}
|
||
|
entry2 := Entry{key2, value2}
|
||
|
entry3 := Entry{key3, value3}
|
||
|
parent, _ := New(nil, entry2, entry1)
|
||
|
tracestate, err := New(parent, entry3)
|
||
|
|
||
|
checkError(t, tracestate, err, testname, "create failed from parent with double keys")
|
||
|
checkKeyValue(t, tracestate, key3, value3, testname)
|
||
|
checkFront(t, tracestate, key3, testname)
|
||
|
checkBack(t, tracestate, key1, testname)
|
||
|
}
|
||
|
|
||
|
func TestCreateFromParentWithExistingKey(t *testing.T) {
|
||
|
key1, value1, key2, value2, key3, value3 := "hello", "world", "foo", "bar", "hello", "baz"
|
||
|
testname := "TestCreateFromParentWithExistingKey"
|
||
|
|
||
|
entry1 := Entry{key1, value1}
|
||
|
entry2 := Entry{key2, value2}
|
||
|
entry3 := Entry{key3, value3}
|
||
|
parent, _ := New(nil, entry2, entry1)
|
||
|
tracestate, err := New(parent, entry3)
|
||
|
|
||
|
checkError(t, tracestate, err, testname, "create failed with an existing key")
|
||
|
checkKeyValue(t, tracestate, key3, value3, testname)
|
||
|
checkFront(t, tracestate, key3, testname)
|
||
|
checkBack(t, tracestate, key2, testname)
|
||
|
checkSize(t, tracestate, 2, testname)
|
||
|
}
|
||
|
|
||
|
func TestImplicitImmutableTracestate(t *testing.T) {
|
||
|
key1, value1, key2, value2, key3, value3 := "hello", "world", "hello", "bar", "foo", "baz"
|
||
|
testname := "TestImplicitImmutableTracestate"
|
||
|
|
||
|
entry1 := Entry{key1, value1}
|
||
|
entry2 := Entry{key2, value2}
|
||
|
parent, _ := New(nil, entry1)
|
||
|
tracestate, err := New(parent, entry2)
|
||
|
|
||
|
checkError(t, tracestate, err, testname, "create failed")
|
||
|
checkKeyValue(t, tracestate, key2, value2, testname)
|
||
|
checkKeyValue(t, parent, key2, value1, testname)
|
||
|
|
||
|
// Get and update entries.
|
||
|
entries := tracestate.Entries()
|
||
|
entry := Entry{key3, value3}
|
||
|
entries = append(entries, entry)
|
||
|
|
||
|
// Check Tracestate does not have key3.
|
||
|
checkKeyValue(t, tracestate, key3, "", testname)
|
||
|
// Check that we added the key3 in the entries
|
||
|
tracestate, err = New(nil, entries...)
|
||
|
checkError(t, tracestate, err, testname, "create failed")
|
||
|
checkKeyValue(t, tracestate, key3, value3, testname)
|
||
|
}
|
||
|
|
||
|
func TestKeyWithValidChar(t *testing.T) {
|
||
|
testname := "TestKeyWithValidChar"
|
||
|
|
||
|
arrayRune := []rune("")
|
||
|
for c := 'a'; c <= 'z'; c++ {
|
||
|
arrayRune = append(arrayRune, c)
|
||
|
}
|
||
|
for c := '0'; c <= '9'; c++ {
|
||
|
arrayRune = append(arrayRune, c)
|
||
|
}
|
||
|
arrayRune = append(arrayRune, '_')
|
||
|
arrayRune = append(arrayRune, '-')
|
||
|
arrayRune = append(arrayRune, '*')
|
||
|
arrayRune = append(arrayRune, '/')
|
||
|
key := string(arrayRune)
|
||
|
entry := Entry{key, "world"}
|
||
|
tracestate, err := New(nil, entry)
|
||
|
|
||
|
checkError(t, tracestate, err, testname, "create failed when the key contains all valid characters")
|
||
|
}
|
||
|
|
||
|
func TestKeyWithInvalidChar(t *testing.T) {
|
||
|
testname := "TestKeyWithInvalidChar"
|
||
|
|
||
|
keys := []string{"1ab", "1ab2", "Abc", " abc", "a=b"}
|
||
|
|
||
|
for _, key := range keys {
|
||
|
entry := Entry{key, "world"}
|
||
|
tracestate, err := New(nil, entry)
|
||
|
wantError(t, tracestate, err, testname, fmt.Sprintf(
|
||
|
"create did not err with invalid key=%q", key))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestNilKey(t *testing.T) {
|
||
|
testname := "TestNilKey"
|
||
|
|
||
|
entry := Entry{"", "world"}
|
||
|
tracestate, err := New(nil, entry)
|
||
|
wantError(t, tracestate, err, testname, "create did not err when the key is nil (\"\")")
|
||
|
}
|
||
|
|
||
|
func TestValueWithInvalidChar(t *testing.T) {
|
||
|
testname := "TestValueWithInvalidChar"
|
||
|
|
||
|
keys := []string{"A=B", "A,B", "AB "}
|
||
|
|
||
|
for _, value := range keys {
|
||
|
entry := Entry{"hello", value}
|
||
|
tracestate, err := New(nil, entry)
|
||
|
wantError(t, tracestate, err, testname,
|
||
|
fmt.Sprintf("create did not err when the value is invalid (%q)", value))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestNilValue(t *testing.T) {
|
||
|
testname := "TestNilValue"
|
||
|
|
||
|
tracestate, err := New(nil, Entry{"hello", ""})
|
||
|
wantError(t, tracestate, err, testname, "create did not err when the value is nil (\"\")")
|
||
|
}
|
||
|
|
||
|
func TestInvalidKeyLen(t *testing.T) {
|
||
|
testname := "TestInvalidKeyLen"
|
||
|
|
||
|
arrayRune := []rune("")
|
||
|
for i := 0; i <= keyMaxSize+1; i++ {
|
||
|
arrayRune = append(arrayRune, 'a')
|
||
|
}
|
||
|
key := string(arrayRune)
|
||
|
tracestate, err := New(nil, Entry{key, "world"})
|
||
|
|
||
|
wantError(t, tracestate, err, testname,
|
||
|
fmt.Sprintf("create did not err when the length (%d) of the key is larger than max (%d)",
|
||
|
len(key), keyMaxSize))
|
||
|
}
|
||
|
|
||
|
func TestInvalidValueLen(t *testing.T) {
|
||
|
testname := "TestInvalidValueLen"
|
||
|
|
||
|
arrayRune := []rune("")
|
||
|
for i := 0; i <= valueMaxSize+1; i++ {
|
||
|
arrayRune = append(arrayRune, 'a')
|
||
|
}
|
||
|
value := string(arrayRune)
|
||
|
tracestate, err := New(nil, Entry{"hello", value})
|
||
|
|
||
|
wantError(t, tracestate, err, testname,
|
||
|
fmt.Sprintf("create did not err when the length (%d) of the value is larger than max (%d)",
|
||
|
len(value), valueMaxSize))
|
||
|
}
|
||
|
|
||
|
func TestCreateFromArrayWithOverLimitKVPairs(t *testing.T) {
|
||
|
testname := "TestCreateFromArrayWithOverLimitKVPairs"
|
||
|
|
||
|
entries := []Entry{}
|
||
|
for i := 0; i <= maxKeyValuePairs; i++ {
|
||
|
key := fmt.Sprintf("a%db", i)
|
||
|
entry := Entry{key, "world"}
|
||
|
entries = append(entries, entry)
|
||
|
}
|
||
|
tracestate, err := New(nil, entries...)
|
||
|
wantError(t, tracestate, err, testname,
|
||
|
fmt.Sprintf("create did not err when the number (%d) of key-value pairs is larger than max (%d)",
|
||
|
len(entries), maxKeyValuePairs))
|
||
|
}
|
||
|
|
||
|
func TestCreateFromEmptyArray(t *testing.T) {
|
||
|
testname := "TestCreateFromEmptyArray"
|
||
|
|
||
|
tracestate, err := New(nil, nil...)
|
||
|
checkError(t, tracestate, err, testname,
|
||
|
"failed to create nil tracestate")
|
||
|
}
|
||
|
|
||
|
func TestCreateFromParentWithOverLimitKVPairs(t *testing.T) {
|
||
|
testname := "TestCreateFromParentWithOverLimitKVPairs"
|
||
|
|
||
|
entries := []Entry{}
|
||
|
for i := 0; i < maxKeyValuePairs; i++ {
|
||
|
key := fmt.Sprintf("a%db", i)
|
||
|
entry := Entry{key, "world"}
|
||
|
entries = append(entries, entry)
|
||
|
}
|
||
|
parent, err := New(nil, entries...)
|
||
|
|
||
|
checkError(t, parent, err, testname, fmt.Sprintf("create failed to add %d key-value pair", maxKeyValuePairs))
|
||
|
|
||
|
// Add one more to go over the limit
|
||
|
key := fmt.Sprintf("a%d", maxKeyValuePairs)
|
||
|
tracestate, err := New(parent, Entry{key, "world"})
|
||
|
wantError(t, tracestate, err, testname,
|
||
|
fmt.Sprintf("create did not err when attempted to exceed the key-value pair limit of %d", maxKeyValuePairs))
|
||
|
}
|
||
|
|
||
|
func TestCreateFromArrayWithDuplicateKeys(t *testing.T) {
|
||
|
key1, value1, key2, value2, key3, value3 := "hello", "world", "foo", "bar", "hello", "baz"
|
||
|
testname := "TestCreateFromArrayWithDuplicateKeys"
|
||
|
|
||
|
entry1 := Entry{key1, value1}
|
||
|
entry2 := Entry{key2, value2}
|
||
|
entry3 := Entry{key3, value3}
|
||
|
tracestate, err := New(nil, entry1, entry2, entry3)
|
||
|
|
||
|
wantError(t, tracestate, err, testname,
|
||
|
"create did not err when entries contained duplicate keys")
|
||
|
}
|
||
|
|
||
|
func TestEntriesWithNil(t *testing.T) {
|
||
|
ts, err := New(nil)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if got, want := len(ts.Entries()), 0; got != want {
|
||
|
t.Errorf("zero value should have no entries, got %v; want %v", got, want)
|
||
|
}
|
||
|
}
|