...

Source file src/go.mongodb.org/mongo-driver/x/mongo/driver/operation/hello_test.go

Documentation: go.mongodb.org/mongo-driver/x/mongo/driver/operation

     1  // Copyright (C) MongoDB, Inc. 2023-present.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License"); you may
     4  // not use this file except in compliance with the License. You may obtain
     5  // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
     6  
     7  package operation
     8  
     9  import (
    10  	"fmt"
    11  	"os"
    12  	"runtime"
    13  	"testing"
    14  
    15  	"go.mongodb.org/mongo-driver/bson"
    16  	"go.mongodb.org/mongo-driver/internal/assert"
    17  	"go.mongodb.org/mongo-driver/internal/driverutil"
    18  	"go.mongodb.org/mongo-driver/internal/require"
    19  	"go.mongodb.org/mongo-driver/version"
    20  	"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
    21  )
    22  
    23  func assertDocsEqual(t *testing.T, got bsoncore.Document, want []byte) {
    24  	t.Helper()
    25  
    26  	var gotD bson.D
    27  	err := bson.Unmarshal(got, &gotD)
    28  	require.NoError(t, err, "error unmarshaling got document: %v", err)
    29  
    30  	var wantD bson.D
    31  	err = bson.UnmarshalExtJSON(want, true, &wantD)
    32  	require.NoError(t, err, "error unmarshaling want byte slice: %v", err)
    33  
    34  	assert.Equal(t, wantD, gotD, "got %v, want %v", gotD, wantD)
    35  }
    36  
    37  func encodeWithCallback(t *testing.T, cb func(int, []byte) ([]byte, error)) bsoncore.Document {
    38  	t.Helper()
    39  
    40  	var err error
    41  	idx, dst := bsoncore.AppendDocumentStart(nil)
    42  
    43  	dst, err = cb(len(dst), dst)
    44  	require.NoError(t, err, "error appending client metadata: %v", err)
    45  
    46  	dst, err = bsoncore.AppendDocumentEnd(dst, idx)
    47  	require.NoError(t, err, "error appending document end: %v", err)
    48  
    49  	got, _, ok := bsoncore.ReadDocument(dst)
    50  	require.True(t, ok, "error reading document: %v", got)
    51  
    52  	return got
    53  }
    54  
    55  // clearTestEnv will clear the test environment created by tests. This will
    56  // ensure that the local environment does not effect the outcome of a unit
    57  // test.
    58  func clearTestEnv(t *testing.T) {
    59  	t.Setenv("AWS_EXECUTION_ENV", "")
    60  	t.Setenv("AWS_LAMBDA_RUNTIME_API", "")
    61  	t.Setenv("FUNCTIONS_WORKER_RUNTIME", "")
    62  	t.Setenv("K_SERVICE", "")
    63  	t.Setenv("FUNCTION_NAME", "")
    64  	t.Setenv("VERCEL", "")
    65  	t.Setenv("AWS_REGION", "")
    66  	t.Setenv("AWS_LAMBDA_FUNCTION_MEMORY_SIZE", "")
    67  	t.Setenv("FUNCTION_MEMORY_MB", "")
    68  	t.Setenv("FUNCTION_TIMEOUT_SEC", "")
    69  	t.Setenv("FUNCTION_REGION", "")
    70  	t.Setenv("VERCEL_REGION", "")
    71  }
    72  
    73  func TestAppendClientName(t *testing.T) {
    74  	t.Parallel()
    75  
    76  	tests := []struct {
    77  		name    string
    78  		appname string
    79  		want    []byte // Extend JSON
    80  	}{
    81  		{
    82  			name: "empty",
    83  			want: []byte(`{}`),
    84  		},
    85  		{
    86  			name:    "non-empty",
    87  			appname: "foo",
    88  			want:    []byte(`{"application":{"name":"foo"}}`),
    89  		},
    90  	}
    91  
    92  	for _, test := range tests {
    93  		test := test
    94  
    95  		t.Run(test.name, func(t *testing.T) {
    96  			t.Parallel()
    97  
    98  			cb := func(_ int, dst []byte) ([]byte, error) {
    99  				var err error
   100  				dst, err = appendClientAppName(dst, test.appname)
   101  
   102  				return dst, err
   103  			}
   104  
   105  			got := encodeWithCallback(t, cb)
   106  			assertDocsEqual(t, got, test.want)
   107  		})
   108  	}
   109  }
   110  
   111  func TestAppendClientDriver(t *testing.T) {
   112  	t.Parallel()
   113  
   114  	tests := []struct {
   115  		name string
   116  		want []byte // Extend JSON
   117  	}{
   118  		{
   119  			name: "full",
   120  			want: []byte(fmt.Sprintf(`{"driver":{"name": %q, "version": %q}}`, driverName, version.Driver)),
   121  		},
   122  	}
   123  
   124  	for _, test := range tests {
   125  		test := test
   126  
   127  		t.Run(test.name, func(t *testing.T) {
   128  			t.Parallel()
   129  
   130  			cb := func(_ int, dst []byte) ([]byte, error) {
   131  				var err error
   132  				dst, err = appendClientDriver(dst)
   133  
   134  				return dst, err
   135  			}
   136  
   137  			got := encodeWithCallback(t, cb)
   138  			assertDocsEqual(t, got, test.want)
   139  		})
   140  	}
   141  }
   142  
   143  func TestAppendClientEnv(t *testing.T) {
   144  	clearTestEnv(t)
   145  
   146  	if os.Getenv("DOCKER_RUNNING") != "" {
   147  		t.Skip("These tests gives different results when run in Docker due to extra environment data.")
   148  	}
   149  
   150  	tests := []struct {
   151  		name          string
   152  		omitEnvFields bool
   153  		env           map[string]string
   154  		want          []byte // Extended JSON
   155  	}{
   156  		{
   157  			name: "empty",
   158  			want: []byte(`{}`),
   159  		},
   160  		{
   161  			name:          "empty with omit",
   162  			omitEnvFields: true,
   163  			want:          []byte(`{}`),
   164  		},
   165  		{
   166  			name: "aws only",
   167  			env: map[string]string{
   168  				"AWS_EXECUTION_ENV": "AWS_Lambda_foo",
   169  			},
   170  			want: []byte(`{"env":{"name":"aws.lambda"}}`),
   171  		},
   172  		{
   173  			name: "aws mem only",
   174  			env: map[string]string{
   175  				"AWS_EXECUTION_ENV":               "AWS_Lambda_foo",
   176  				"AWS_LAMBDA_FUNCTION_MEMORY_SIZE": "1024",
   177  			},
   178  			want: []byte(`{"env":{"name":"aws.lambda","memory_mb":1024}}`),
   179  		},
   180  		{
   181  			name: "aws region only",
   182  			env: map[string]string{
   183  				"AWS_EXECUTION_ENV": "AWS_Lambda_foo",
   184  				"AWS_REGION":        "us-east-2",
   185  			},
   186  			want: []byte(`{"env":{"name":"aws.lambda","region":"us-east-2"}}`),
   187  		},
   188  		{
   189  			name: "aws mem and region",
   190  			env: map[string]string{
   191  				"AWS_EXECUTION_ENV":               "AWS_Lambda_foo",
   192  				"AWS_LAMBDA_FUNCTION_MEMORY_SIZE": "1024",
   193  				"AWS_REGION":                      "us-east-2",
   194  			},
   195  			want: []byte(`{"env":{"name":"aws.lambda","memory_mb":1024,"region":"us-east-2"}}`),
   196  		},
   197  		{
   198  			name:          "aws mem and region with omit fields",
   199  			omitEnvFields: true,
   200  			env: map[string]string{
   201  				"AWS_EXECUTION_ENV":               "AWS_Lambda_foo",
   202  				"AWS_LAMBDA_FUNCTION_MEMORY_SIZE": "1024",
   203  				"AWS_REGION":                      "us-east-2",
   204  			},
   205  			want: []byte(`{"env":{"name":"aws.lambda"}}`),
   206  		},
   207  		{
   208  			name: "gcp only",
   209  			env: map[string]string{
   210  				"K_SERVICE": "servicename",
   211  			},
   212  			want: []byte(`{"env":{"name":"gcp.func"}}`),
   213  		},
   214  		{
   215  			name: "gcp mem",
   216  			env: map[string]string{
   217  				"K_SERVICE":          "servicename",
   218  				"FUNCTION_MEMORY_MB": "1024",
   219  			},
   220  			want: []byte(`{"env":{"name":"gcp.func","memory_mb":1024}}`),
   221  		},
   222  		{
   223  			name: "gcp region",
   224  			env: map[string]string{
   225  				"K_SERVICE":       "servicename",
   226  				"FUNCTION_REGION": "us-east-2",
   227  			},
   228  			want: []byte(`{"env":{"name":"gcp.func","region":"us-east-2"}}`),
   229  		},
   230  		{
   231  			name: "gcp timeout",
   232  			env: map[string]string{
   233  				"K_SERVICE":            "servicename",
   234  				"FUNCTION_TIMEOUT_SEC": "1",
   235  			},
   236  			want: []byte(`{"env":{"name":"gcp.func","timeout_sec":1}}`),
   237  		},
   238  		{
   239  			name: "gcp mem, region, and timeout",
   240  			env: map[string]string{
   241  				"K_SERVICE":            "servicename",
   242  				"FUNCTION_TIMEOUT_SEC": "1",
   243  				"FUNCTION_REGION":      "us-east-2",
   244  				"FUNCTION_MEMORY_MB":   "1024",
   245  			},
   246  			want: []byte(`{"env":{"name":"gcp.func","memory_mb":1024,"region":"us-east-2","timeout_sec":1}}`),
   247  		},
   248  		{
   249  			name:          "gcp mem, region, and timeout with omit fields",
   250  			omitEnvFields: true,
   251  			env: map[string]string{
   252  				"K_SERVICE":            "servicename",
   253  				"FUNCTION_TIMEOUT_SEC": "1",
   254  				"FUNCTION_REGION":      "us-east-2",
   255  				"FUNCTION_MEMORY_MB":   "1024",
   256  			},
   257  			want: []byte(`{"env":{"name":"gcp.func"}}`),
   258  		},
   259  		{
   260  			name: "vercel only",
   261  			env: map[string]string{
   262  				"VERCEL": "1",
   263  			},
   264  			want: []byte(`{"env":{"name":"vercel"}}`),
   265  		},
   266  		{
   267  			name: "vercel region",
   268  			env: map[string]string{
   269  				"VERCEL":        "1",
   270  				"VERCEL_REGION": "us-east-2",
   271  			},
   272  			want: []byte(`{"env":{"name":"vercel","region":"us-east-2"}}`),
   273  		},
   274  		{
   275  			name: "azure only",
   276  			env: map[string]string{
   277  				"FUNCTIONS_WORKER_RUNTIME": "go1.x",
   278  			},
   279  			want: []byte(`{"env":{"name":"azure.func"}}`),
   280  		},
   281  		{
   282  			name: "k8s",
   283  			env: map[string]string{
   284  				"KUBERNETES_SERVICE_HOST": "0.0.0.0",
   285  			},
   286  			want: []byte(`{"env":{"container":{"orchestrator":"kubernetes"}}}`),
   287  		},
   288  		// client.env.container.runtime is untested.
   289  	}
   290  
   291  	for _, test := range tests {
   292  		test := test
   293  
   294  		t.Run(test.name, func(t *testing.T) {
   295  			for key, val := range test.env {
   296  				t.Setenv(key, val)
   297  			}
   298  
   299  			cb := func(_ int, dst []byte) ([]byte, error) {
   300  				var err error
   301  				dst, err = appendClientEnv(dst, test.omitEnvFields, false)
   302  
   303  				return dst, err
   304  			}
   305  
   306  			got := encodeWithCallback(t, cb)
   307  			assertDocsEqual(t, got, test.want)
   308  		})
   309  	}
   310  }
   311  
   312  func TestAppendClientOS(t *testing.T) {
   313  	t.Parallel()
   314  
   315  	tests := []struct {
   316  		name        string
   317  		omitNonType bool
   318  		want        []byte // Extended JSON
   319  	}{
   320  		{
   321  			name: "full",
   322  			want: []byte(fmt.Sprintf(`{"os":{"type":%q,"architecture":%q}}`, runtime.GOOS, runtime.GOARCH)),
   323  		},
   324  		{
   325  			name:        "partial",
   326  			omitNonType: true,
   327  			want:        []byte(fmt.Sprintf(`{"os":{"type":%q}}`, runtime.GOOS)),
   328  		},
   329  	}
   330  
   331  	for _, test := range tests {
   332  		test := test
   333  
   334  		t.Run(test.name, func(t *testing.T) {
   335  			t.Parallel()
   336  
   337  			cb := func(_ int, dst []byte) ([]byte, error) {
   338  				var err error
   339  				dst, err = appendClientOS(dst, test.omitNonType)
   340  
   341  				return dst, err
   342  			}
   343  
   344  			got := encodeWithCallback(t, cb)
   345  			assertDocsEqual(t, got, test.want)
   346  		})
   347  	}
   348  }
   349  
   350  func TestAppendClientPlatform(t *testing.T) {
   351  	t.Parallel()
   352  
   353  	tests := []struct {
   354  		name string
   355  		want []byte // Extended JSON
   356  	}{
   357  		{
   358  			name: "full",
   359  			want: []byte(fmt.Sprintf(`{"platform":%q}`, runtime.Version())),
   360  		},
   361  	}
   362  
   363  	for _, test := range tests {
   364  		test := test
   365  
   366  		t.Run(test.name, func(t *testing.T) {
   367  			t.Parallel()
   368  
   369  			cb := func(_ int, dst []byte) ([]byte, error) {
   370  				var err error
   371  				dst = appendClientPlatform(dst)
   372  
   373  				return dst, err
   374  			}
   375  
   376  			got := encodeWithCallback(t, cb)
   377  			assertDocsEqual(t, got, test.want)
   378  		})
   379  	}
   380  }
   381  
   382  func TestEncodeClientMetadata(t *testing.T) {
   383  	clearTestEnv(t)
   384  
   385  	if os.Getenv("DOCKER_RUNNING") != "" {
   386  		t.Skip("These tests gives different results when run in Docker due to extra environment data.")
   387  	}
   388  
   389  	type application struct {
   390  		Name string `bson:"name"`
   391  	}
   392  
   393  	type driver struct {
   394  		Name    string `bson:"name"`
   395  		Version string `bson:"version"`
   396  	}
   397  
   398  	type dist struct {
   399  		Type         string `bson:"type,omitempty"`
   400  		Architecture string `bson:"architecture,omitempty"`
   401  	}
   402  
   403  	type container struct {
   404  		Runtime      string `bson:"runtime,omitempty"`
   405  		Orchestrator string `bson:"orchestrator,omitempty"`
   406  	}
   407  
   408  	type env struct {
   409  		Name       string     `bson:"name,omitempty"`
   410  		TimeoutSec int64      `bson:"timeout_sec,omitempty"`
   411  		MemoryMB   int32      `bson:"memory_mb,omitempty"`
   412  		Region     string     `bson:"region,omitempty"`
   413  		Container  *container `bson:"container,omitempty"`
   414  	}
   415  
   416  	type clientMetadata struct {
   417  		Application *application `bson:"application"`
   418  		Driver      *driver      `bson:"driver"`
   419  		OS          *dist        `bson:"os"`
   420  		Platform    string       `bson:"platform,omitempty"`
   421  		Env         *env         `bson:"env,omitempty"`
   422  	}
   423  
   424  	formatJSON := func(client *clientMetadata) []byte {
   425  		bytes, err := bson.MarshalExtJSON(client, true, false)
   426  		require.NoError(t, err, "error encoding client metadata for test: %v", err)
   427  
   428  		return bytes
   429  	}
   430  
   431  	// Set environment variables to add `env` field to handshake.
   432  	t.Setenv("AWS_LAMBDA_RUNTIME_API", "lambda")
   433  	t.Setenv("AWS_LAMBDA_FUNCTION_MEMORY_SIZE", "123")
   434  	t.Setenv("AWS_REGION", "us-east-2")
   435  	t.Setenv("KUBERNETES_SERVICE_HOST", "0.0.0.0")
   436  
   437  	t.Run("nothing is omitted", func(t *testing.T) {
   438  		got, err := encodeClientMetadata("foo", maxClientMetadataSize)
   439  		assert.Nil(t, err, "error in encodeClientMetadata: %v", err)
   440  
   441  		want := formatJSON(&clientMetadata{
   442  			Application: &application{Name: "foo"},
   443  			Driver:      &driver{Name: driverName, Version: version.Driver},
   444  			OS:          &dist{Type: runtime.GOOS, Architecture: runtime.GOARCH},
   445  			Platform:    runtime.Version(),
   446  			Env: &env{
   447  				Name:     "aws.lambda",
   448  				MemoryMB: 123,
   449  				Region:   "us-east-2",
   450  				Container: &container{
   451  					Orchestrator: "kubernetes",
   452  				},
   453  			},
   454  		})
   455  
   456  		assertDocsEqual(t, got, want)
   457  	})
   458  
   459  	t.Run("env is omitted sub env.name", func(t *testing.T) {
   460  		// Calculate the full length of a bsoncore.Document.
   461  		temp, err := encodeClientMetadata("foo", maxClientMetadataSize)
   462  		require.NoError(t, err, "error constructing template: %v", err)
   463  
   464  		got, err := encodeClientMetadata("foo", len(temp)-1)
   465  		assert.Nil(t, err, "error in encodeClientMetadata: %v", err)
   466  
   467  		want := formatJSON(&clientMetadata{
   468  			Application: &application{Name: "foo"},
   469  			Driver:      &driver{Name: driverName, Version: version.Driver},
   470  			OS:          &dist{Type: runtime.GOOS, Architecture: runtime.GOARCH},
   471  			Platform:    runtime.Version(),
   472  			Env: &env{
   473  				Name: "aws.lambda",
   474  				Container: &container{
   475  					Orchestrator: "kubernetes",
   476  				},
   477  			},
   478  		})
   479  
   480  		assertDocsEqual(t, got, want)
   481  	})
   482  
   483  	t.Run("os is omitted sub os.type", func(t *testing.T) {
   484  		// Calculate the full length of a bsoncore.Document.
   485  		temp, err := encodeClientMetadata("foo", maxClientMetadataSize)
   486  		require.NoError(t, err, "error constructing template: %v", err)
   487  
   488  		// Calculate what the environment costs.
   489  		edst, err := appendClientEnv(nil, false, false)
   490  		require.NoError(t, err, "error constructing env template: %v", err)
   491  
   492  		// Calculate what the env.name costs.
   493  		ndst := bsoncore.AppendStringElement(nil, "name", "aws.lambda")
   494  		idx, ndst := bsoncore.AppendDocumentElementStart(ndst, "container")
   495  		ndst = bsoncore.AppendStringElement(ndst, "orchestrator", "kubernetes")
   496  		ndst, err = bsoncore.AppendDocumentEnd(ndst, idx)
   497  		require.NoError(t, err)
   498  
   499  		// Environment sub name.
   500  		envSubName := len(edst) - len(ndst)
   501  
   502  		got, err := encodeClientMetadata("foo", len(temp)-envSubName-1)
   503  		assert.Nil(t, err, "error in encodeClientMetadata: %v", err)
   504  
   505  		want := formatJSON(&clientMetadata{
   506  			Application: &application{Name: "foo"},
   507  			Driver:      &driver{Name: driverName, Version: version.Driver},
   508  			OS:          &dist{Type: runtime.GOOS},
   509  			Platform:    runtime.Version(),
   510  			Env: &env{
   511  				Name: "aws.lambda",
   512  				Container: &container{
   513  					Orchestrator: "kubernetes",
   514  				},
   515  			},
   516  		})
   517  
   518  		assertDocsEqual(t, got, want)
   519  	})
   520  
   521  	t.Run("omit the env doc entirely", func(t *testing.T) {
   522  		// Calculate the full length of a bsoncore.Document.
   523  		temp, err := encodeClientMetadata("foo", maxClientMetadataSize)
   524  		require.NoError(t, err, "error constructing template: %v", err)
   525  
   526  		// Calculate what the environment costs.
   527  		edst, err := appendClientEnv(nil, false, false)
   528  		require.NoError(t, err, "error constructing env template: %v", err)
   529  
   530  		// Calculate what the os.type costs.
   531  		odst := bsoncore.AppendStringElement(nil, "type", runtime.GOOS)
   532  
   533  		// Calculate what the environment plus the os.type costs.
   534  		envAndOSType := len(edst) + len(odst)
   535  
   536  		got, err := encodeClientMetadata("foo", len(temp)-envAndOSType-1)
   537  		assert.Nil(t, err, "error in encodeClientMetadata: %v", err)
   538  
   539  		want := formatJSON(&clientMetadata{
   540  			Application: &application{Name: "foo"},
   541  			Driver:      &driver{Name: driverName, Version: version.Driver},
   542  			OS:          &dist{Type: runtime.GOOS},
   543  			Platform:    runtime.Version(),
   544  		})
   545  
   546  		assertDocsEqual(t, got, want)
   547  	})
   548  
   549  	t.Run("omit the platform", func(t *testing.T) {
   550  		// Calculate the full length of a bsoncore.Document.
   551  		temp, err := encodeClientMetadata("foo", maxClientMetadataSize)
   552  		require.NoError(t, err, "error constructing template: %v", err)
   553  
   554  		// Calculate what the environment costs.
   555  		edst, err := appendClientEnv(nil, false, false)
   556  		require.NoError(t, err, "error constructing env template: %v", err)
   557  
   558  		// Calculate what the os.type costs.
   559  		odst := bsoncore.AppendStringElement(nil, "type", runtime.GOOS)
   560  
   561  		// Calculate what the platform costs
   562  		pdst := appendClientPlatform(nil)
   563  
   564  		// Calculate what the environment plus the os.type costs.
   565  		envAndOSTypeAndPlatform := len(edst) + len(odst) + len(pdst)
   566  
   567  		got, err := encodeClientMetadata("foo", len(temp)-envAndOSTypeAndPlatform)
   568  		assert.Nil(t, err, "error in encodeClientMetadata: %v", err)
   569  
   570  		want := formatJSON(&clientMetadata{
   571  			Application: &application{Name: "foo"},
   572  			Driver:      &driver{Name: driverName, Version: version.Driver},
   573  			OS:          &dist{Type: runtime.GOOS},
   574  		})
   575  
   576  		assertDocsEqual(t, got, want)
   577  	})
   578  
   579  	t.Run("0 max len", func(t *testing.T) {
   580  		got, err := encodeClientMetadata("foo", 0)
   581  		assert.Nil(t, err, "error in encodeClientMetadata: %v", err)
   582  		assert.Len(t, got, 0)
   583  	})
   584  }
   585  
   586  func TestParseFaasEnvName(t *testing.T) {
   587  	clearTestEnv(t)
   588  
   589  	tests := []struct {
   590  		name string
   591  		env  map[string]string
   592  		want string
   593  	}{
   594  		{
   595  			name: "no env",
   596  			want: "",
   597  		},
   598  		{
   599  			name: "one aws",
   600  			env: map[string]string{
   601  				"AWS_EXECUTION_ENV": "AWS_Lambda_foo",
   602  			},
   603  			want: "aws.lambda",
   604  		},
   605  		{
   606  			name: "both aws options",
   607  			env: map[string]string{
   608  				"AWS_EXECUTION_ENV":      "AWS_Lambda_foo",
   609  				"AWS_LAMBDA_RUNTIME_API": "hello",
   610  			},
   611  			want: "aws.lambda",
   612  		},
   613  		{
   614  			name: "multiple variables",
   615  			env: map[string]string{
   616  				"AWS_EXECUTION_ENV":        "AWS_Lambda_foo",
   617  				"FUNCTIONS_WORKER_RUNTIME": "hello",
   618  			},
   619  			want: "",
   620  		},
   621  		{
   622  			name: "vercel and aws lambda",
   623  			env: map[string]string{
   624  				"AWS_EXECUTION_ENV": "AWS_Lambda_foo",
   625  				"VERCEL":            "hello",
   626  			},
   627  			want: "vercel",
   628  		},
   629  		{
   630  			name: "invalid aws prefix",
   631  			env: map[string]string{
   632  				"AWS_EXECUTION_ENV": "foo",
   633  			},
   634  			want: "",
   635  		},
   636  	}
   637  
   638  	for _, test := range tests {
   639  		test := test
   640  
   641  		t.Run(test.name, func(t *testing.T) {
   642  			for key, value := range test.env {
   643  				t.Setenv(key, value)
   644  			}
   645  
   646  			got := driverutil.GetFaasEnvName()
   647  			if got != test.want {
   648  				t.Errorf("parseFaasEnvName(%s) = %s, want %s", test.name, got, test.want)
   649  			}
   650  		})
   651  	}
   652  }
   653  
   654  func BenchmarkClientMetadata(b *testing.B) {
   655  	b.ReportAllocs()
   656  	b.ResetTimer()
   657  
   658  	b.RunParallel(func(pb *testing.PB) {
   659  		for pb.Next() {
   660  			_, err := encodeClientMetadata("foo", maxClientMetadataSize)
   661  			if err != nil {
   662  				b.Fatal(err)
   663  			}
   664  		}
   665  	})
   666  }
   667  
   668  func BenchmarkClientMetadtaLargeEnv(b *testing.B) {
   669  	b.ReportAllocs()
   670  	b.ResetTimer()
   671  
   672  	b.Setenv("aws.lambda", "foo")
   673  
   674  	str := ""
   675  	for i := 0; i < 512; i++ {
   676  		str += "a"
   677  	}
   678  
   679  	b.Setenv("AWS_LAMBDA_RUNTIME_API", str)
   680  
   681  	b.RunParallel(func(pb *testing.PB) {
   682  		for pb.Next() {
   683  			_, err := encodeClientMetadata("foo", maxClientMetadataSize)
   684  			if err != nil {
   685  				b.Fatal(err)
   686  			}
   687  		}
   688  	})
   689  }
   690  
   691  func FuzzEncodeClientMetadata(f *testing.F) {
   692  	f.Fuzz(func(t *testing.T, b []byte, appname string) {
   693  		if len(b) > maxClientMetadataSize {
   694  			return
   695  		}
   696  
   697  		_, err := encodeClientMetadata(appname, maxClientMetadataSize)
   698  		if err != nil {
   699  			t.Fatalf("error appending client: %v", err)
   700  		}
   701  
   702  		_, err = appendClientAppName(b, appname)
   703  		if err != nil {
   704  			t.Fatalf("error appending client app name: %v", err)
   705  		}
   706  
   707  		_, err = appendClientDriver(b)
   708  		if err != nil {
   709  			t.Fatalf("error appending client driver: %v", err)
   710  		}
   711  
   712  		_, err = appendClientEnv(b, false, false)
   713  		if err != nil {
   714  			t.Fatalf("error appending client env ff: %v", err)
   715  		}
   716  
   717  		_, err = appendClientEnv(b, false, true)
   718  		if err != nil {
   719  			t.Fatalf("error appending client env ft: %v", err)
   720  		}
   721  
   722  		_, err = appendClientEnv(b, true, false)
   723  		if err != nil {
   724  			t.Fatalf("error appending client env tf: %v", err)
   725  		}
   726  
   727  		_, err = appendClientEnv(b, true, true)
   728  		if err != nil {
   729  			t.Fatalf("error appending client env tt: %v", err)
   730  		}
   731  
   732  		_, err = appendClientOS(b, false)
   733  		if err != nil {
   734  			t.Fatalf("error appending client os f: %v", err)
   735  		}
   736  
   737  		_, err = appendClientOS(b, true)
   738  		if err != nil {
   739  			t.Fatalf("error appending client os t: %v", err)
   740  		}
   741  
   742  		appendClientPlatform(b)
   743  	})
   744  }
   745  

View as plain text