github.com/grafana/tanka@v0.26.1-0.20240506093700-c22cfc35c21a/pkg/jsonnet/eval_test.go (about)

     1  package jsonnet
     2  
     3  import (
     4  	"os"
     5  	"os/exec"
     6  	"path/filepath"
     7  	"testing"
     8  
     9  	"github.com/grafana/tanka/pkg/jsonnet/implementations/binary"
    10  	"github.com/grafana/tanka/pkg/jsonnet/implementations/goimpl"
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  )
    14  
    15  var jsonnetImpl = &goimpl.JsonnetGoImplementation{}
    16  
    17  const importTreeResult = `[
    18     {
    19        "breed": "apple",
    20        "color": "red",
    21        "creates": "o2",
    22        "eats": "co2",
    23        "keeps": "the world healthy",
    24        "kind": "tree",
    25        "needs": "water",
    26        "size": "m"
    27     },
    28     {
    29        "breed": "cherry",
    30        "color": "red",
    31        "creates": "o2",
    32        "eats": "co2",
    33        "keeps": "the world healthy",
    34        "kind": "tree",
    35        "needs": "water",
    36        "size": "xs"
    37     },
    38     {
    39        "breed": "peach",
    40        "color": "orange",
    41        "creates": "o2",
    42        "eats": "co2",
    43        "keeps": "the world healthy",
    44        "kind": "tree",
    45        "needs": "water",
    46        "size": "s"
    47     }
    48  ]
    49  `
    50  
    51  const thisFileResult = `{
    52     "test": "testdata/thisFile/main.jsonnet"
    53  }
    54  `
    55  
    56  // To be consistent with the jsonnet executable,
    57  // when evaluating a file, `std.thisFile` should point to the given path
    58  func TestEvaluateFile(t *testing.T) {
    59  	result, err := EvaluateFile(jsonnetImpl, "testdata/thisFile/main.jsonnet", Opts{})
    60  	assert.NoError(t, err)
    61  	assert.Equal(t, thisFileResult, result)
    62  }
    63  
    64  func TestEvaluateFileWithInvalidBinary(t *testing.T) {
    65  	binaryImpl := &binary.JsonnetBinaryImplementation{BinPath: "this-file-doesnt-exist"}
    66  	result, err := EvaluateFile(binaryImpl, "testdata/thisFile/main.jsonnet", Opts{})
    67  	assert.Equal(t, result, "")
    68  	assert.ErrorIs(t, err, exec.ErrNotFound)
    69  }
    70  
    71  // This test requires jsonnet to be installed and available in the PATH
    72  func TestEvaluateFileWithJsonnetBinary(t *testing.T) {
    73  	binaryImpl := &binary.JsonnetBinaryImplementation{BinPath: "jsonnet"}
    74  	result, err := EvaluateFile(binaryImpl, "testdata/thisFile/main.jsonnet", Opts{})
    75  	assert.NoError(t, err)
    76  	assert.Equal(t, thisFileResult, result)
    77  }
    78  
    79  func TestEvaluateFileDoesntExist(t *testing.T) {
    80  	result, err := EvaluateFile(jsonnetImpl, "testdata/doesnt-exist/main.jsonnet", Opts{})
    81  	assert.EqualError(t, err, "open testdata/doesnt-exist/main.jsonnet: no such file or directory")
    82  	assert.Equal(t, "", result)
    83  }
    84  
    85  func TestEvaluateFileWithCaching(t *testing.T) {
    86  	tmp, err := os.MkdirTemp("", "test-tanka-caching")
    87  	require.NoError(t, err)
    88  	defer os.RemoveAll(tmp)
    89  	cachePath := filepath.Join(tmp, "cache") // Should be created during caching
    90  
    91  	// Evaluate two files
    92  	result, err := EvaluateFile(jsonnetImpl, "testdata/thisFile/main.jsonnet", Opts{CachePath: cachePath})
    93  	assert.NoError(t, err)
    94  	assert.Equal(t, thisFileResult, result)
    95  	result, err = EvaluateFile(jsonnetImpl, "testdata/importTree/main.jsonnet", Opts{CachePath: cachePath})
    96  	assert.NoError(t, err)
    97  	assert.Equal(t, importTreeResult, result)
    98  
    99  	// Check that we have two entries in the cache
   100  	readCache, err := os.ReadDir(cachePath)
   101  	require.NoError(t, err)
   102  	assert.Len(t, readCache, 2)
   103  
   104  	// Evaluate two files again, same result
   105  	result, err = EvaluateFile(jsonnetImpl, "testdata/thisFile/main.jsonnet", Opts{CachePath: cachePath})
   106  	assert.NoError(t, err)
   107  	assert.Equal(t, thisFileResult, result)
   108  	result, err = EvaluateFile(jsonnetImpl, "testdata/importTree/main.jsonnet", Opts{CachePath: cachePath})
   109  	assert.NoError(t, err)
   110  	assert.Equal(t, importTreeResult, result)
   111  
   112  	// Modify the cache items
   113  	for _, entry := range readCache {
   114  		require.NoError(t, os.WriteFile(filepath.Join(cachePath, entry.Name()), []byte(entry.Name()), 0666))
   115  	}
   116  
   117  	// Evaluate two files again, modified cache is returned instead of the actual result
   118  	result, err = EvaluateFile(jsonnetImpl, "testdata/thisFile/main.jsonnet", Opts{CachePath: cachePath})
   119  	assert.NoError(t, err)
   120  	assert.Equal(t, "BYfdlr1ZOVwiOfbd89JYTcK-eRQh05bi8ky3k1vVW5o=.json", result)
   121  	result, err = EvaluateFile(jsonnetImpl, "testdata/importTree/main.jsonnet", Opts{CachePath: cachePath})
   122  	assert.NoError(t, err)
   123  	assert.Equal(t, "R_3hy-dRfOwXN-fezQ50ZF4dnrFcBcbQ9LztR_XWzJA=.json", result)
   124  }