...

Source file src/go.opencensus.io/tag/map_test.go

Documentation: go.opencensus.io/tag

     1  // Copyright 2017, OpenCensus Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  //
    15  
    16  package tag
    17  
    18  import (
    19  	"context"
    20  	"fmt"
    21  	"reflect"
    22  	"strings"
    23  	"testing"
    24  )
    25  
    26  var (
    27  	ttlUnlimitedPropMd = createMetadatas(WithTTL(TTLUnlimitedPropagation))
    28  	ttlNoPropMd        = createMetadatas(WithTTL(TTLNoPropagation))
    29  )
    30  
    31  func TestContext(t *testing.T) {
    32  	k1, _ := NewKey("k1")
    33  	k2, _ := NewKey("k2")
    34  
    35  	ctx := context.Background()
    36  	ctx, _ = New(ctx,
    37  		Insert(k1, "v1"),
    38  		Insert(k2, "v2"),
    39  	)
    40  	got := FromContext(ctx)
    41  	want := newMap()
    42  	want.insert(k1, "v1", ttlUnlimitedPropMd)
    43  	want.insert(k2, "v2", ttlUnlimitedPropMd)
    44  
    45  	if !reflect.DeepEqual(got, want) {
    46  		t.Errorf("Map = %#v; want %#v", got, want)
    47  	}
    48  }
    49  
    50  func TestDo(t *testing.T) {
    51  	k1, _ := NewKey("k1")
    52  	k2, _ := NewKey("k2")
    53  	ctx := context.Background()
    54  	ctx, _ = New(ctx,
    55  		Insert(k1, "v1"),
    56  		Insert(k2, "v2"),
    57  	)
    58  	got := FromContext(ctx)
    59  	want := newMap()
    60  	want.insert(k1, "v1", ttlUnlimitedPropMd)
    61  	want.insert(k2, "v2", ttlUnlimitedPropMd)
    62  	Do(ctx, func(ctx context.Context) {
    63  		got = FromContext(ctx)
    64  	})
    65  	if !reflect.DeepEqual(got, want) {
    66  		t.Errorf("Map = %#v; want %#v", got, want)
    67  	}
    68  }
    69  
    70  func TestNewMap(t *testing.T) {
    71  	k1, _ := NewKey("k1")
    72  	k2, _ := NewKey("k2")
    73  	k3, _ := NewKey("k3")
    74  	k4, _ := NewKey("k4")
    75  	k5, _ := NewKey("k5")
    76  
    77  	initial := makeTestTagMap(5)
    78  
    79  	tests := []struct {
    80  		name    string
    81  		initial *Map
    82  		mods    []Mutator
    83  		want    *Map
    84  	}{
    85  		{
    86  			name:    "from empty; insert",
    87  			initial: nil,
    88  			mods: []Mutator{
    89  				Insert(k5, "v5"),
    90  			},
    91  			want: makeTestTagMap(2, 4, 5),
    92  		},
    93  		{
    94  			name:    "from empty; insert existing",
    95  			initial: nil,
    96  			mods: []Mutator{
    97  				Insert(k1, "v1"),
    98  			},
    99  			want: makeTestTagMap(1, 2, 4),
   100  		},
   101  		{
   102  			name:    "from empty; update",
   103  			initial: nil,
   104  			mods: []Mutator{
   105  				Update(k1, "v1"),
   106  			},
   107  			want: makeTestTagMap(2, 4),
   108  		},
   109  		{
   110  			name:    "from empty; update unexisting",
   111  			initial: nil,
   112  			mods: []Mutator{
   113  				Update(k5, "v5"),
   114  			},
   115  			want: makeTestTagMap(2, 4),
   116  		},
   117  		{
   118  			name:    "from existing; upsert",
   119  			initial: initial,
   120  			mods: []Mutator{
   121  				Upsert(k5, "v5"),
   122  			},
   123  			want: makeTestTagMap(2, 4, 5),
   124  		},
   125  		{
   126  			name:    "from existing; delete",
   127  			initial: initial,
   128  			mods: []Mutator{
   129  				Delete(k2),
   130  			},
   131  			want: makeTestTagMap(4, 5),
   132  		},
   133  		{
   134  			name:    "from empty; invalid",
   135  			initial: nil,
   136  			mods: []Mutator{
   137  				Insert(k5, "v\x19"),
   138  				Upsert(k5, "v\x19"),
   139  				Update(k5, "v\x19"),
   140  			},
   141  			want: nil,
   142  		},
   143  		{
   144  			name:    "from empty; no partial",
   145  			initial: nil,
   146  			mods: []Mutator{
   147  				Insert(k5, "v1"),
   148  				Update(k5, "v\x19"),
   149  			},
   150  			want: nil,
   151  		},
   152  	}
   153  
   154  	for _, tt := range tests {
   155  		mods := []Mutator{
   156  			Insert(k1, "v1"),
   157  			Insert(k2, "v2"),
   158  			Update(k3, "v3"),
   159  			Upsert(k4, "v4"),
   160  			Insert(k2, "v2"),
   161  			Delete(k1),
   162  		}
   163  		mods = append(mods, tt.mods...)
   164  		ctx := NewContext(context.Background(), tt.initial)
   165  		ctx, err := New(ctx, mods...)
   166  		if tt.want != nil && err != nil {
   167  			t.Errorf("%v: New = %v", tt.name, err)
   168  		}
   169  
   170  		if got, want := FromContext(ctx), tt.want; !reflect.DeepEqual(got, want) {
   171  			t.Errorf("%v: got %v; want %v", tt.name, got, want)
   172  		}
   173  	}
   174  }
   175  
   176  func TestNewMapWithMetadata(t *testing.T) {
   177  	k3, _ := NewKey("k3")
   178  	k4, _ := NewKey("k4")
   179  	k5, _ := NewKey("k5")
   180  
   181  	tests := []struct {
   182  		name    string
   183  		initial *Map
   184  		mods    []Mutator
   185  		want    *Map
   186  	}{
   187  		{
   188  			name:    "from empty; insert",
   189  			initial: nil,
   190  			mods: []Mutator{
   191  				Insert(k5, "5", WithTTL(TTLNoPropagation)),
   192  				Insert(k4, "4"),
   193  			},
   194  			want: makeTestTagMapWithMetadata(
   195  				tagContent{"5", ttlNoPropMd},
   196  				tagContent{"4", ttlUnlimitedPropMd}),
   197  		},
   198  		{
   199  			name:    "from existing; insert existing",
   200  			initial: makeTestTagMapWithMetadata(tagContent{"5", ttlNoPropMd}),
   201  			mods: []Mutator{
   202  				Insert(k5, "5", WithTTL(TTLUnlimitedPropagation)),
   203  			},
   204  			want: makeTestTagMapWithMetadata(tagContent{"5", ttlNoPropMd}),
   205  		},
   206  		{
   207  			name:    "from existing; update non-existing",
   208  			initial: makeTestTagMapWithMetadata(tagContent{"5", ttlNoPropMd}),
   209  			mods: []Mutator{
   210  				Update(k4, "4", WithTTL(TTLUnlimitedPropagation)),
   211  			},
   212  			want: makeTestTagMapWithMetadata(tagContent{"5", ttlNoPropMd}),
   213  		},
   214  		{
   215  			name: "from existing; update existing",
   216  			initial: makeTestTagMapWithMetadata(
   217  				tagContent{"5", ttlUnlimitedPropMd},
   218  				tagContent{"4", ttlNoPropMd}),
   219  			mods: []Mutator{
   220  				Update(k5, "5"),
   221  				Update(k4, "4", WithTTL(TTLUnlimitedPropagation)),
   222  			},
   223  			want: makeTestTagMapWithMetadata(
   224  				tagContent{"5", ttlUnlimitedPropMd},
   225  				tagContent{"4", ttlUnlimitedPropMd}),
   226  		},
   227  		{
   228  			name: "from existing; upsert existing",
   229  			initial: makeTestTagMapWithMetadata(
   230  				tagContent{"5", ttlNoPropMd},
   231  				tagContent{"4", ttlNoPropMd}),
   232  			mods: []Mutator{
   233  				Upsert(k4, "4", WithTTL(TTLUnlimitedPropagation)),
   234  			},
   235  			want: makeTestTagMapWithMetadata(
   236  				tagContent{"5", ttlNoPropMd},
   237  				tagContent{"4", ttlUnlimitedPropMd}),
   238  		},
   239  		{
   240  			name: "from existing; upsert non-existing",
   241  			initial: makeTestTagMapWithMetadata(
   242  				tagContent{"5", ttlNoPropMd}),
   243  			mods: []Mutator{
   244  				Upsert(k4, "4", WithTTL(TTLUnlimitedPropagation)),
   245  				Upsert(k3, "3"),
   246  			},
   247  			want: makeTestTagMapWithMetadata(
   248  				tagContent{"5", ttlNoPropMd},
   249  				tagContent{"4", ttlUnlimitedPropMd},
   250  				tagContent{"3", ttlUnlimitedPropMd}),
   251  		},
   252  		{
   253  			name: "from existing; delete",
   254  			initial: makeTestTagMapWithMetadata(
   255  				tagContent{"5", ttlNoPropMd},
   256  				tagContent{"4", ttlNoPropMd}),
   257  			mods: []Mutator{
   258  				Delete(k5),
   259  			},
   260  			want: makeTestTagMapWithMetadata(
   261  				tagContent{"4", ttlNoPropMd}),
   262  		},
   263  		{
   264  			name:    "from non-existing; upsert with multiple-metadata",
   265  			initial: nil,
   266  			mods: []Mutator{
   267  				Upsert(k4, "4", WithTTL(TTLUnlimitedPropagation), WithTTL(TTLNoPropagation)),
   268  				Upsert(k5, "5", WithTTL(TTLNoPropagation), WithTTL(TTLUnlimitedPropagation)),
   269  			},
   270  			want: makeTestTagMapWithMetadata(
   271  				tagContent{"4", ttlNoPropMd},
   272  				tagContent{"5", ttlUnlimitedPropMd}),
   273  		},
   274  		{
   275  			name:    "from non-existing; insert with multiple-metadata",
   276  			initial: nil,
   277  			mods: []Mutator{
   278  				Insert(k5, "5", WithTTL(TTLNoPropagation), WithTTL(TTLUnlimitedPropagation)),
   279  			},
   280  			want: makeTestTagMapWithMetadata(
   281  				tagContent{"5", ttlUnlimitedPropMd}),
   282  		},
   283  		{
   284  			name: "from existing; update with multiple-metadata",
   285  			initial: makeTestTagMapWithMetadata(
   286  				tagContent{"5", ttlNoPropMd}),
   287  			mods: []Mutator{
   288  				Update(k5, "5", WithTTL(TTLNoPropagation), WithTTL(TTLUnlimitedPropagation)),
   289  			},
   290  			want: makeTestTagMapWithMetadata(
   291  				tagContent{"5", ttlUnlimitedPropMd}),
   292  		},
   293  		{
   294  			name:    "from empty; update invalid",
   295  			initial: nil,
   296  			mods: []Mutator{
   297  				Insert(k4, "4\x19", WithTTL(TTLUnlimitedPropagation)),
   298  				Upsert(k4, "4\x19", WithTTL(TTLUnlimitedPropagation)),
   299  				Update(k4, "4\x19", WithTTL(TTLUnlimitedPropagation)),
   300  			},
   301  			want: nil,
   302  		},
   303  		{
   304  			name:    "from empty; insert partial",
   305  			initial: nil,
   306  			mods: []Mutator{
   307  				Upsert(k3, "3", WithTTL(TTLUnlimitedPropagation)),
   308  				Upsert(k4, "4\x19", WithTTL(TTLUnlimitedPropagation)),
   309  			},
   310  			want: nil,
   311  		},
   312  	}
   313  
   314  	// Test api for insert, update, and upsert using metadata.
   315  	for _, tt := range tests {
   316  		ctx := NewContext(context.Background(), tt.initial)
   317  		ctx, err := New(ctx, tt.mods...)
   318  		if tt.want != nil && err != nil {
   319  			t.Errorf("%v: New = %v", tt.name, err)
   320  		}
   321  
   322  		if got, want := FromContext(ctx), tt.want; !reflect.DeepEqual(got, want) {
   323  			t.Errorf("%v: got %v; want %v", tt.name, got, want)
   324  		}
   325  	}
   326  }
   327  
   328  func TestNewValidation(t *testing.T) {
   329  	tests := []struct {
   330  		err  string
   331  		seed *Map
   332  	}{
   333  		// Key name validation in seed
   334  		{err: "invalid key", seed: &Map{m: map[Key]tagContent{{name: ""}: {"foo", ttlNoPropMd}}}},
   335  		{err: "", seed: &Map{m: map[Key]tagContent{{name: "key"}: {"foo", ttlNoPropMd}}}},
   336  		{err: "", seed: &Map{m: map[Key]tagContent{{name: strings.Repeat("a", 255)}: {"census", ttlNoPropMd}}}},
   337  		{err: "invalid key", seed: &Map{m: map[Key]tagContent{{name: strings.Repeat("a", 256)}: {"census", ttlNoPropMd}}}},
   338  		{err: "invalid key", seed: &Map{m: map[Key]tagContent{{name: "Приве́т"}: {"census", ttlNoPropMd}}}},
   339  
   340  		// Value validation
   341  		{err: "", seed: &Map{m: map[Key]tagContent{{name: "key"}: {"", ttlNoPropMd}}}},
   342  		{err: "", seed: &Map{m: map[Key]tagContent{{name: "key"}: {strings.Repeat("a", 255), ttlNoPropMd}}}},
   343  		{err: "invalid value", seed: &Map{m: map[Key]tagContent{{name: "key"}: {"Приве́т", ttlNoPropMd}}}},
   344  		{err: "invalid value", seed: &Map{m: map[Key]tagContent{{name: "key"}: {strings.Repeat("a", 256), ttlNoPropMd}}}},
   345  	}
   346  
   347  	for i, tt := range tests {
   348  		ctx := NewContext(context.Background(), tt.seed)
   349  		ctx, err := New(ctx)
   350  
   351  		if tt.err != "" {
   352  			if err == nil {
   353  				t.Errorf("#%d: got nil error; want %q", i, tt.err)
   354  				continue
   355  			} else if s, substr := err.Error(), tt.err; !strings.Contains(s, substr) {
   356  				t.Errorf("#%d:\ngot %q\nwant %q", i, s, substr)
   357  			}
   358  			continue
   359  		}
   360  		if err != nil {
   361  			t.Errorf("#%d: got %q want nil", i, err)
   362  			continue
   363  		}
   364  		m := FromContext(ctx)
   365  		if m == nil {
   366  			t.Errorf("#%d: got nil map", i)
   367  			continue
   368  		}
   369  	}
   370  }
   371  
   372  func makeTestTagMap(ids ...int) *Map {
   373  	m := newMap()
   374  	for _, v := range ids {
   375  		k, _ := NewKey(fmt.Sprintf("k%d", v))
   376  		m.m[k] = tagContent{fmt.Sprintf("v%d", v), ttlUnlimitedPropMd}
   377  	}
   378  	return m
   379  }
   380  
   381  func makeTestTagMapWithMetadata(tcs ...tagContent) *Map {
   382  	m := newMap()
   383  	for _, tc := range tcs {
   384  		k, _ := NewKey(fmt.Sprintf("k%s", tc.value))
   385  		m.m[k] = tc
   386  	}
   387  	return m
   388  }
   389  

View as plain text