get.porter.sh/porter@v1.3.0/pkg/exec/builder/output_jsonpath_test.go (about) 1 package builder 2 3 import ( 4 "context" 5 "os" 6 "path/filepath" 7 "testing" 8 9 "get.porter.sh/porter/pkg/portercontext" 10 "get.porter.sh/porter/pkg/runtime" 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/require" 13 ) 14 15 type TestStep struct { 16 Command string 17 Arguments []string 18 Flags Flags 19 Outputs []Output 20 WorkingDirectory string 21 EnvironmentVars map[string]string 22 } 23 24 func (s TestStep) GetCommand() string { 25 return s.Command 26 } 27 28 func (s TestStep) GetArguments() []string { 29 return s.Arguments 30 } 31 32 func (s TestStep) GetWorkingDir() string { 33 return s.WorkingDirectory 34 } 35 36 func (s TestStep) GetFlags() Flags { 37 return s.Flags 38 } 39 40 func (s TestStep) GetDashes() Dashes { 41 return DefaultFlagDashes 42 } 43 44 func (s TestStep) GetOutputs() []Output { 45 return s.Outputs 46 } 47 48 type TestJsonPathOutput struct { 49 Name string 50 JsonPath string 51 } 52 53 func (o TestJsonPathOutput) GetName() string { 54 return o.Name 55 } 56 57 func (o TestJsonPathOutput) GetJsonPath() string { 58 return o.JsonPath 59 } 60 61 func TestJsonPathOutputs(t *testing.T) { 62 testcases := []struct { 63 name string 64 jsonPath string 65 wantOutput string 66 }{ 67 {"array", "$[*].id", `["1085517466897181794"]`}, 68 {"object", "$[0].tags", `{"fingerprint":"42WmSpB8rSM="}`}, 69 {"integer", "$[0].index", `0`}, 70 {"big integer", "$[0]._id", `123123123`}, 71 {"exponential notation", "$[0]._bigId", `1.23123123e+08`}, 72 {"boolean", "$[0].deletionProtection", `false`}, 73 {"string", "$[0].cpuPlatform", `Intel Haswell`}, 74 } 75 76 stdout, err := os.ReadFile("testdata/install-output.json") 77 require.NoError(t, err, "could not read testdata") 78 79 for _, tc := range testcases { 80 t.Run(tc.name, func(t *testing.T) { 81 ctx := context.Background() 82 cfg := runtime.NewTestRuntimeConfig(t) 83 84 step := TestStep{ 85 Outputs: []Output{ 86 TestJsonPathOutput{Name: tc.name, JsonPath: tc.jsonPath}, 87 }, 88 } 89 90 err = ProcessJsonPathOutputs(ctx, cfg.RuntimeConfig, step, string(stdout)) 91 require.NoError(t, err, "ProcessJsonPathOutputs should not return an error") 92 93 f := filepath.Join(portercontext.MixinOutputsDir, tc.name) 94 gotOutput, err := cfg.FileSystem.ReadFile(f) 95 require.NoError(t, err, "could not read output file %s", f) 96 97 wantOutput := tc.wantOutput 98 assert.Equal(t, wantOutput, string(gotOutput)) 99 }) 100 } 101 } 102 103 func TestJsonPathOutputs_DebugPrintsDocument(t *testing.T) { 104 cfg := runtime.NewTestRuntimeConfig(t) 105 ctx := context.Background() 106 107 step := TestStep{ 108 Outputs: []Output{ 109 TestJsonPathOutput{Name: "ids", JsonPath: "$[*].id"}, 110 }, 111 } 112 113 document := `[{"id": "abc123"}]` 114 err := ProcessJsonPathOutputs(ctx, cfg.RuntimeConfig, step, document) 115 require.NoError(t, err) 116 wantDebugLine := `Processing jsonpath output ids using query $[*].id against document 117 [{"id": "abc123"}] 118 ` 119 stderr := cfg.TestContext.GetError() 120 assert.Contains(t, stderr, wantDebugLine, "Debug mode should print the full document and query being captured") 121 } 122 123 func TestJsonPathOutputs_NoOutput(t *testing.T) { 124 ctx := context.Background() 125 cfg := runtime.NewTestRuntimeConfig(t) 126 127 step := TestStep{ 128 Outputs: []Output{ 129 TestJsonPathOutput{Name: "ids", JsonPath: "$[*].id"}, 130 }, 131 } 132 133 err := ProcessJsonPathOutputs(ctx, cfg.RuntimeConfig, step, "") 134 require.NoError(t, err, "ProcessJsonPathOutputs should not return an error when the output buffer is empty") 135 }