github.com/ydb-platform/ydb-go-sdk/v3@v3.89.2/internal/stack/record_test.go (about)

     1  package stack
     2  
     3  import (
     4  	"reflect"
     5  	"runtime"
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/require"
    10  )
    11  
    12  type testStruct struct {
    13  	depth int
    14  	opts  []recordOption
    15  }
    16  
    17  func (s testStruct) TestFunc() string {
    18  	return func() string {
    19  		return Record(s.depth, s.opts...)
    20  	}()
    21  }
    22  
    23  func (s *testStruct) TestPointerFunc() string {
    24  	return func() string {
    25  		return Record(s.depth, s.opts...)
    26  	}()
    27  }
    28  
    29  func TestRecord(t *testing.T) {
    30  	for _, tt := range []struct {
    31  		act string
    32  		exp string
    33  	}{
    34  		{
    35  			act: Record(0),
    36  			exp: "github.com/ydb-platform/ydb-go-sdk/v3/internal/stack.TestRecord(record_test.go:35)",
    37  		},
    38  		{
    39  			act: func() string {
    40  				return Record(1)
    41  			}(),
    42  			exp: "github.com/ydb-platform/ydb-go-sdk/v3/internal/stack.TestRecord(record_test.go:41)",
    43  		},
    44  		{
    45  			act: func() string {
    46  				return func() string {
    47  					return Record(2)
    48  				}()
    49  			}(),
    50  			exp: "github.com/ydb-platform/ydb-go-sdk/v3/internal/stack.TestRecord(record_test.go:49)",
    51  		},
    52  		{
    53  			act: testStruct{depth: 0, opts: []recordOption{
    54  				PackagePath(false),
    55  				PackageName(false),
    56  				StructName(false),
    57  				FunctionName(false),
    58  				Lambda(false),
    59  				FileName(false),
    60  				Line(false),
    61  			}}.TestFunc(),
    62  			exp: "",
    63  		},
    64  		{
    65  			act: testStruct{depth: 0, opts: []recordOption{
    66  				// PackagePath(false),
    67  				PackageName(false),
    68  				StructName(false),
    69  				FunctionName(false),
    70  				Lambda(false),
    71  				FileName(false),
    72  				Line(false),
    73  			}}.TestFunc(),
    74  			exp: "github.com/ydb-platform/ydb-go-sdk/v3/internal",
    75  		},
    76  		{
    77  			act: testStruct{depth: 0, opts: []recordOption{
    78  				PackagePath(false),
    79  				// PackageName(false),
    80  				StructName(false),
    81  				FunctionName(false),
    82  				Lambda(false),
    83  				FileName(false),
    84  				Line(false),
    85  			}}.TestFunc(),
    86  			exp: "stack",
    87  		},
    88  		{
    89  			act: testStruct{depth: 0, opts: []recordOption{
    90  				PackagePath(false),
    91  				PackageName(false),
    92  				// StructName(false),
    93  				FunctionName(false),
    94  				Lambda(false),
    95  				FileName(false),
    96  				Line(false),
    97  			}}.TestFunc(),
    98  			exp: "testStruct",
    99  		},
   100  		{
   101  			act: testStruct{depth: 0, opts: []recordOption{
   102  				PackagePath(false),
   103  				PackageName(false),
   104  				StructName(false),
   105  				// FunctionName(false),
   106  				Lambda(false),
   107  				FileName(false),
   108  				Line(false),
   109  			}}.TestFunc(),
   110  			exp: "TestFunc",
   111  		},
   112  		{
   113  			act: testStruct{depth: 0, opts: []recordOption{
   114  				PackagePath(false),
   115  				PackageName(false),
   116  				StructName(false),
   117  				FunctionName(false),
   118  				// Lambda(false),
   119  				FileName(false),
   120  				Line(false),
   121  			}}.TestFunc(),
   122  			exp: "",
   123  		},
   124  		{
   125  			act: testStruct{depth: 0, opts: []recordOption{
   126  				PackagePath(false),
   127  				PackageName(false),
   128  				StructName(false),
   129  				// FunctionName(false),
   130  				// Lambda(false),
   131  				FileName(false),
   132  				Line(false),
   133  			}}.TestFunc(),
   134  			exp: "TestFunc.func1",
   135  		},
   136  		{
   137  			act: testStruct{depth: 0, opts: []recordOption{
   138  				PackagePath(false),
   139  				PackageName(false),
   140  				StructName(false),
   141  				FunctionName(false),
   142  				Lambda(false),
   143  				// FileName(false),
   144  				Line(false),
   145  			}}.TestFunc(),
   146  			exp: "record_test.go",
   147  		},
   148  		{
   149  			act: testStruct{depth: 0, opts: []recordOption{
   150  				PackagePath(false),
   151  				PackageName(false),
   152  				StructName(false),
   153  				FunctionName(false),
   154  				Lambda(false),
   155  				FileName(false),
   156  				// Line(false),
   157  			}}.TestFunc(),
   158  			exp: "",
   159  		},
   160  		{
   161  			act: testStruct{depth: 0, opts: []recordOption{
   162  				PackagePath(false),
   163  				PackageName(false),
   164  				StructName(false),
   165  				FunctionName(false),
   166  				Lambda(false),
   167  				// FileName(false),
   168  				// Line(false),
   169  			}}.TestFunc(),
   170  			exp: "record_test.go:19",
   171  		},
   172  		{
   173  			act: testStruct{depth: 0, opts: []recordOption{
   174  				// PackagePath(false),
   175  				// PackageName(false),
   176  				StructName(false),
   177  				FunctionName(false),
   178  				Lambda(false),
   179  				FileName(false),
   180  				Line(false),
   181  			}}.TestFunc(),
   182  			exp: "github.com/ydb-platform/ydb-go-sdk/v3/internal/stack",
   183  		},
   184  		{
   185  			act: testStruct{depth: 0, opts: []recordOption{
   186  				// PackagePath(false),
   187  				// PackageName(false),
   188  				// StructName(false),
   189  				FunctionName(false),
   190  				Lambda(false),
   191  				FileName(false),
   192  				Line(false),
   193  			}}.TestFunc(),
   194  			exp: "github.com/ydb-platform/ydb-go-sdk/v3/internal/stack.testStruct",
   195  		},
   196  		{
   197  			act: testStruct{depth: 0, opts: []recordOption{
   198  				// PackagePath(false),
   199  				// PackageName(false),
   200  				// StructName(false),
   201  				// FunctionName(false),
   202  				Lambda(false),
   203  				FileName(false),
   204  				Line(false),
   205  			}}.TestFunc(),
   206  			exp: "github.com/ydb-platform/ydb-go-sdk/v3/internal/stack.testStruct.TestFunc",
   207  		},
   208  		{
   209  			act: testStruct{depth: 0, opts: []recordOption{
   210  				// PackagePath(false),
   211  				// PackageName(false),
   212  				// StructName(false),
   213  				// FunctionName(false),
   214  				// Lambda(false),
   215  				FileName(false),
   216  				Line(false),
   217  			}}.TestFunc(),
   218  			exp: "github.com/ydb-platform/ydb-go-sdk/v3/internal/stack.testStruct.TestFunc.func1",
   219  		},
   220  		{
   221  			act: testStruct{depth: 0, opts: []recordOption{
   222  				// PackagePath(false),
   223  				// PackageName(false),
   224  				// StructName(false),
   225  				// FunctionName(false),
   226  				// Lambda(false),
   227  				// FileName(false),
   228  				Line(false),
   229  			}}.TestFunc(),
   230  			exp: "github.com/ydb-platform/ydb-go-sdk/v3/internal/stack.testStruct.TestFunc.func1(record_test.go)",
   231  		},
   232  		{
   233  			act: testStruct{depth: 0, opts: []recordOption{
   234  				// PackagePath(false),
   235  				// PackageName(false),
   236  				// StructName(false),
   237  				// FunctionName(false),
   238  				// Lambda(false),
   239  				// FileName(false),
   240  				// Line(false),
   241  			}}.TestFunc(),
   242  			exp: "github.com/ydb-platform/ydb-go-sdk/v3/internal/stack.testStruct.TestFunc.func1(record_test.go:19)",
   243  		},
   244  		{
   245  			act: (&testStruct{depth: 0, opts: []recordOption{
   246  				// PackagePath(false),
   247  				// PackageName(false),
   248  				// StructName(false),
   249  				// FunctionName(false),
   250  				// Lambda(false),
   251  				// FileName(false),
   252  				// Line(false),
   253  			}}).TestPointerFunc(),
   254  			exp: "github.com/ydb-platform/ydb-go-sdk/v3/internal/stack.(*testStruct).TestPointerFunc.func1(record_test.go:25)",
   255  		},
   256  	} {
   257  		t.Run("", func(t *testing.T) {
   258  			require.Equal(t, tt.exp, tt.act)
   259  		})
   260  	}
   261  }
   262  
   263  func TestExtractNames(t *testing.T) {
   264  	testFunc := func() {}
   265  	funcPtr := reflect.ValueOf(testFunc).Pointer()
   266  
   267  	funcNameExpected := runtime.FuncForPC(funcPtr).Name()
   268  
   269  	_, file, _, ok := runtime.Caller(0)
   270  	require.True(t, ok, "runtime.Caller should return true indicating success")
   271  
   272  	fileParts := strings.Split(file, "/")
   273  	fileNameExpected := fileParts[len(fileParts)-1]
   274  
   275  	name, fileName := extractName(funcPtr, file)
   276  
   277  	require.Equal(t, funcNameExpected, name, "Function name should match expected value")
   278  	require.Equal(t, fileNameExpected, fileName, "File name should match expected value")
   279  }
   280  
   281  func TestParseFunctionName(t *testing.T) {
   282  	name := "github.com/ydb-platform/ydb-go-sdk/v3/internal/stack.TestParseFunctionName.func1"
   283  	fnDetails := parseFunctionName(name)
   284  
   285  	require.Equal(t, "github.com/ydb-platform/ydb-go-sdk/v3/internal", fnDetails.pkgPath)
   286  	require.Equal(t, "stack", fnDetails.pkgName)
   287  	require.Empty(t, fnDetails.structName, "Struct name should be empty for standalone functions")
   288  	require.Equal(t, "TestParseFunctionName", fnDetails.funcName)
   289  	require.Contains(t, fnDetails.lambdas, "func1", "Lambdas should include 'func1'")
   290  }
   291  
   292  func TestBuildRecordString(t *testing.T) {
   293  	optionsHolder := recordOptions{
   294  		packagePath:  true,
   295  		packageName:  false,
   296  		structName:   true,
   297  		functionName: true,
   298  		fileName:     true,
   299  		line:         true,
   300  		lambdas:      true,
   301  	}
   302  	fnDetails := functionDetails{
   303  		pkgPath:    "github.com/ydb-platform/ydb-go-sdk/v3/internal",
   304  		pkgName:    "",
   305  		structName: "testStruct",
   306  		funcName:   "TestFunc",
   307  
   308  		lambdas: []string{"func1"},
   309  	}
   310  	file := "record_test.go"
   311  	line := 319
   312  
   313  	result := buildRecordString(optionsHolder, &fnDetails, file, line)
   314  	expected := "github.com/ydb-platform/ydb-go-sdk/v3/internal.testStruct.TestFunc.func1(record_test.go:319)"
   315  	require.Equal(t, expected, result)
   316  }
   317  
   318  func BenchmarkCall(b *testing.B) {
   319  	b.ReportAllocs()
   320  	for i := 0; i < b.N; i++ {
   321  		_ = Call(0)
   322  	}
   323  }
   324  
   325  func BenchmarkRecord(b *testing.B) {
   326  	b.ReportAllocs()
   327  	for i := 0; i < b.N; i++ {
   328  		_ = Record(0)
   329  	}
   330  }
   331  
   332  func BenchmarkCallRecord(b *testing.B) {
   333  	b.ReportAllocs()
   334  	for i := 0; i < b.N; i++ {
   335  		_ = Call(0).Record()
   336  	}
   337  }
   338  
   339  func BenchmarkCallFuncionID(b *testing.B) {
   340  	b.ReportAllocs()
   341  	for i := 0; i < b.N; i++ {
   342  		_ = Call(0).FunctionID()
   343  	}
   344  }