github.com/grafana/tanka@v0.26.1-0.20240506093700-c22cfc35c21a/pkg/jsonnet/imports_test.go (about) 1 package jsonnet 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "strings" 8 "sync" 9 "testing" 10 11 "github.com/grafana/tanka/pkg/jsonnet/implementations/goimpl" 12 "github.com/stretchr/testify/assert" 13 "github.com/stretchr/testify/require" 14 ) 15 16 // TestTransitiveImports checks that TransitiveImports is able to report all 17 // recursive imports of a file 18 func TestTransitiveImports(t *testing.T) { 19 imports, err := TransitiveImports("testdata/importTree") 20 fmt.Println(imports) 21 require.NoError(t, err) 22 assert.Equal(t, []string{ 23 "main.jsonnet", 24 "trees.jsonnet", 25 "trees/apple.jsonnet", 26 "trees/cherry.jsonnet", 27 "trees/generic.libsonnet", 28 "trees/peach.jsonnet", 29 }, imports) 30 } 31 32 func BenchmarkGetSnippetHash(b *testing.B) { 33 for _, tc := range []struct { 34 name string 35 importFromMain bool 36 expectedHash string 37 }{ 38 { 39 name: "all-imported-from-main", 40 importFromMain: true, 41 expectedHash: "ktY8NYZOoPacsNYrH7-DslRgLG54EMRdk3MQSM3vcUg=", 42 }, 43 { 44 name: "deeply-nested", 45 importFromMain: false, 46 expectedHash: "W1Q_uS6jTGcsd7nvJfc-i785sqjBmOzfOAzqzhXVc0A=", 47 }, 48 } { 49 b.Run(tc.name, func(b *testing.B) { 50 // Create a very large and complex project 51 tempDir := b.TempDir() 52 generateTestProject(b, tempDir, 1000, tc.importFromMain) 53 54 // Create a VM. It's important to reuse the same VM 55 // While there is a caching mechanism that normally shouldn't be shared in a benchmark iteration, 56 // it's useful to evaluate its impact here, because the caching will also improve the evaluation performance afterwards. 57 vm := goimpl.MakeRawVM([]string{tempDir}, nil, nil, 0) 58 content, err := os.ReadFile(filepath.Join(tempDir, "main.jsonnet")) 59 require.NoError(b, err) 60 61 // Run the benchmark 62 mainPath := filepath.Join(tempDir, "main.jsonnet") 63 c := string(content) 64 b.ResetTimer() 65 for i := 0; i < b.N; i++ { 66 fileHashes = sync.Map{} 67 hash, err := getSnippetHash(vm, mainPath, c) 68 require.NoError(b, err) 69 require.Equal(b, tc.expectedHash, hash) 70 } 71 }) 72 } 73 } 74 75 func generateTestProject(t testing.TB, dir string, depth int, importAllFromMain bool) []string { 76 t.Helper() 77 78 const testFile = ` 79 local localImport = <IMPORT>; 80 local myFunc = function() <IMPORT>; 81 82 { 83 local this = self, 84 85 attribute: { 86 name: 'test', 87 value: self.name, 88 otherValue: 'other ' + self.value, 89 }, 90 nested: { 91 nested: { 92 nested: { 93 nested: { 94 nested1: { 95 nested: { 96 nested1: { 97 nested: { 98 attribute: <IMPORT>, 99 }, 100 }, 101 nested2: { 102 strValue: this.nested.nested.nested, 103 }, 104 }, 105 }, 106 nested2: { 107 intValue: 1, 108 importValue: <IMPORT>, 109 }, 110 }, 111 }, 112 }, 113 }, 114 115 other: myFunc(), 116 useLocal: localImport, 117 }` 118 119 var allFiles []string 120 121 var mainContentSplit []string 122 for i := 0; i < depth; i++ { 123 mainContentSplit = append(mainContentSplit, fmt.Sprintf("(import 'file%d.libsonnet')", i)) 124 filePath := filepath.Join(dir, fmt.Sprintf("file%d.libsonnet", i)) 125 err := os.WriteFile( 126 filePath, 127 []byte(strings.ReplaceAll(testFile, "<IMPORT>", fmt.Sprintf("import 'file%d.libsonnet'", i+1))), 128 0644, 129 ) 130 require.NoError(t, err) 131 allFiles = append(allFiles, filePath) 132 } 133 if !importAllFromMain { 134 mainContentSplit = append(mainContentSplit, "import 'file0.libsonnet'") 135 } 136 require.NoError(t, os.WriteFile(filepath.Join(dir, "main.jsonnet"), []byte(strings.Join(mainContentSplit, " + ")), 0644)) 137 allFiles = append(allFiles, filepath.Join(dir, "main.jsonnet")) 138 require.NoError(t, os.WriteFile(filepath.Join(dir, fmt.Sprintf("file%d.libsonnet", depth)), []byte(`"a string"`), 0644)) 139 allFiles = append(allFiles, filepath.Join(dir, fmt.Sprintf("file%d.libsonnet", depth))) 140 141 return allFiles 142 }