115 lines
2.6 KiB
Go
115 lines
2.6 KiB
Go
package vidhelpser
|
|
|
|
import (
|
|
"go/ast"
|
|
"go/parser"
|
|
"go/token"
|
|
"path/filepath"
|
|
"runtime"
|
|
"testing"
|
|
)
|
|
|
|
func parseHelpserSource(t *testing.T) *ast.File {
|
|
t.Helper()
|
|
_, testFile, _, ok := runtime.Caller(0)
|
|
if !ok {
|
|
t.Fatal("resolve test source path")
|
|
}
|
|
path := filepath.Join(filepath.Dir(testFile), "helpser.go")
|
|
file, err := parser.ParseFile(token.NewFileSet(), path, nil, 0)
|
|
if err != nil {
|
|
t.Fatalf("parse %s: %v", path, err)
|
|
}
|
|
return file
|
|
}
|
|
|
|
func findFunction(t *testing.T, file *ast.File, name string) *ast.FuncDecl {
|
|
t.Helper()
|
|
for _, decl := range file.Decls {
|
|
fn, ok := decl.(*ast.FuncDecl)
|
|
if ok && fn.Name.Name == name {
|
|
return fn
|
|
}
|
|
}
|
|
t.Fatalf("function %s not found", name)
|
|
return nil
|
|
}
|
|
|
|
func TestVideoInfoEncodersAggregatePageViewsOnlyThroughRedis(t *testing.T) {
|
|
file := parseHelpserSource(t)
|
|
encoders := []string{
|
|
"encodeVideoInfo",
|
|
"newEncodeVideoInfoNotStatus",
|
|
"newEncodeVideoInfo",
|
|
"encodeVideoInfoNoUID",
|
|
}
|
|
|
|
for _, name := range encoders {
|
|
t.Run(name, func(t *testing.T) {
|
|
fn := findFunction(t, file, name)
|
|
directMongoCalls := 0
|
|
redisAggregateCalls := 0
|
|
ast.Inspect(fn.Body, func(node ast.Node) bool {
|
|
call, ok := node.(*ast.CallExpr)
|
|
if !ok {
|
|
return true
|
|
}
|
|
switch callee := call.Fun.(type) {
|
|
case *ast.Ident:
|
|
if callee.Name == "incVideoPageView" {
|
|
redisAggregateCalls++
|
|
}
|
|
case *ast.SelectorExpr:
|
|
pkg, ok := callee.X.(*ast.Ident)
|
|
if ok && pkg.Name == "vidmod" && callee.Sel.Name == "IncVideoPageView" {
|
|
directMongoCalls++
|
|
}
|
|
}
|
|
return true
|
|
})
|
|
|
|
if directMongoCalls != 0 {
|
|
t.Fatalf("direct Mongo page-view increments = %d, want 0", directMongoCalls)
|
|
}
|
|
if redisAggregateCalls != 1 {
|
|
t.Fatalf("Redis page-view aggregate calls = %d, want 1", redisAggregateCalls)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAsyncClosuresDoNotAssignCapturedErr(t *testing.T) {
|
|
file := parseHelpserSource(t)
|
|
functions := []string{
|
|
"encodeVideoInfo",
|
|
"GetVideosByIDs",
|
|
"NewGetVideosByIDs",
|
|
}
|
|
|
|
for _, name := range functions {
|
|
t.Run(name, func(t *testing.T) {
|
|
fn := findFunction(t, file, name)
|
|
ast.Inspect(fn.Body, func(node ast.Node) bool {
|
|
closure, ok := node.(*ast.FuncLit)
|
|
if !ok {
|
|
return true
|
|
}
|
|
ast.Inspect(closure.Body, func(node ast.Node) bool {
|
|
assign, ok := node.(*ast.AssignStmt)
|
|
if !ok || assign.Tok != token.ASSIGN {
|
|
return true
|
|
}
|
|
for _, lhs := range assign.Lhs {
|
|
ident, ok := lhs.(*ast.Ident)
|
|
if ok && ident.Name == "err" {
|
|
t.Errorf("async closure assigns captured err at %s", name)
|
|
}
|
|
}
|
|
return true
|
|
})
|
|
return false
|
|
})
|
|
})
|
|
}
|
|
}
|