github.com/argoproj/argo-cd@v1.8.7/resource_customizations/custom_actions_test.go (about)

     1  package resource_customizations
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"path/filepath"
     8  	"strings"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/undefinedlabs/go-mpatch"
    13  
    14  	"github.com/argoproj/gitops-engine/pkg/diff"
    15  	"github.com/ghodss/yaml"
    16  	"github.com/stretchr/testify/assert"
    17  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    18  
    19  	appsv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
    20  	"github.com/argoproj/argo-cd/util/cli"
    21  	"github.com/argoproj/argo-cd/util/lua"
    22  )
    23  
    24  type testNormalizer struct{}
    25  
    26  func (t testNormalizer) Normalize(un *unstructured.Unstructured) error {
    27  	return nil
    28  }
    29  
    30  type ActionTestStructure struct {
    31  	DiscoveryTests []IndividualDiscoveryTest `yaml:"discoveryTests"`
    32  	ActionTests    []IndividualActionTest    `yaml:"actionTests"`
    33  }
    34  
    35  type IndividualDiscoveryTest struct {
    36  	InputPath string                  `yaml:"inputPath"`
    37  	Result    []appsv1.ResourceAction `yaml:"result"`
    38  }
    39  
    40  type IndividualActionTest struct {
    41  	Action             string `yaml:"action"`
    42  	InputPath          string `yaml:"inputPath"`
    43  	ExpectedOutputPath string `yaml:"expectedOutputPath"`
    44  	InputStr           string `yaml:"input"`
    45  }
    46  
    47  func TestLuaResourceActionsScript(t *testing.T) {
    48  	err := filepath.Walk(".", func(path string, f os.FileInfo, err error) error {
    49  		if !strings.Contains(path, "action_test.yaml") {
    50  			return nil
    51  		}
    52  		assert.NoError(t, err)
    53  		dir := filepath.Dir(path)
    54  		//TODO: Change to path
    55  		yamlBytes, err := ioutil.ReadFile(dir + "/action_test.yaml")
    56  		assert.NoError(t, err)
    57  		var resourceTest ActionTestStructure
    58  		err = yaml.Unmarshal(yamlBytes, &resourceTest)
    59  		assert.NoError(t, err)
    60  		for i := range resourceTest.DiscoveryTests {
    61  			test := resourceTest.DiscoveryTests[i]
    62  			testName := fmt.Sprintf("discovery/%s", test.InputPath)
    63  			t.Run(testName, func(t *testing.T) {
    64  				vm := lua.VM{
    65  					UseOpenLibs: true,
    66  				}
    67  				obj := getObj(filepath.Join(dir, test.InputPath))
    68  				discoveryLua, err := vm.GetResourceActionDiscovery(obj)
    69  				assert.NoError(t, err)
    70  				result, err := vm.ExecuteResourceActionDiscovery(obj, discoveryLua)
    71  				assert.NoError(t, err)
    72  				for i := range result {
    73  					assert.Contains(t, test.Result, result[i])
    74  				}
    75  			})
    76  		}
    77  		for i := range resourceTest.ActionTests {
    78  			test := resourceTest.ActionTests[i]
    79  			testName := fmt.Sprintf("actions/%s/%s", test.Action, test.InputPath)
    80  			t.Run(testName, func(t *testing.T) {
    81  				vm := lua.VM{
    82  					// Uncomment the following line if you need to use lua libraries debugging
    83  					// purposes. Otherwise, leave this false to ensure tests reflect the same
    84  					// privileges that API server has.
    85  					//UseOpenLibs: true,
    86  				}
    87  				obj := getObj(filepath.Join(dir, test.InputPath))
    88  				action, err := vm.GetResourceAction(obj, test.Action)
    89  				assert.NoError(t, err)
    90  
    91  				// freeze time so that lua test has predictable time output (will return 0001-01-01T00:00:00Z)
    92  				patch, err := mpatch.PatchMethod(time.Now, func() time.Time { return time.Time{} })
    93  				assert.NoError(t, err)
    94  				result, err := vm.ExecuteResourceAction(obj, action.ActionLua)
    95  				assert.NoError(t, err)
    96  				err = patch.Unpatch()
    97  				assert.NoError(t, err)
    98  
    99  				expectedObj := getObj(filepath.Join(dir, test.ExpectedOutputPath))
   100  				// Ideally, we would use a assert.Equal to detect the difference, but the Lua VM returns a object with float64 instead of the original int32.  As a result, the assert.Equal is never true despite that the change has been applied.
   101  				diffResult, err := diff.Diff(expectedObj, result, diff.WithNormalizer(testNormalizer{}))
   102  				assert.NoError(t, err)
   103  				if diffResult.Modified {
   104  					t.Error("Output does not match input:")
   105  					err = cli.PrintDiff(test.Action, expectedObj, result)
   106  					assert.NoError(t, err)
   107  				}
   108  			})
   109  		}
   110  
   111  		return nil
   112  	})
   113  	assert.Nil(t, err)
   114  }