github.com/myhau/pulumi/pkg/v3@v3.70.2-0.20221116134521-f2775972e587/backend/display/diff_test.go (about) 1 //nolint:goconst 2 package display 3 4 import ( 5 "bytes" 6 "encoding/json" 7 "fmt" 8 "io" 9 "os" 10 "path/filepath" 11 "testing" 12 13 "github.com/pulumi/pulumi/pkg/v3/engine" 14 "github.com/pulumi/pulumi/sdk/v3/go/common/apitype" 15 "github.com/pulumi/pulumi/sdk/v3/go/common/diag/colors" 16 "github.com/pulumi/pulumi/sdk/v3/go/common/util/cmdutil" 17 "github.com/pulumi/pulumi/sdk/v3/go/common/util/contract" 18 19 "github.com/stretchr/testify/assert" 20 "github.com/stretchr/testify/require" 21 ) 22 23 func loadEvents(path string) (events []engine.Event, err error) { 24 f, err := os.Open(path) 25 if err != nil { 26 return nil, fmt.Errorf("opening '%v': %w", path, err) 27 } 28 defer contract.IgnoreClose(f) 29 30 dec := json.NewDecoder(f) 31 for { 32 var jsonEvent apitype.EngineEvent 33 if err = dec.Decode(&jsonEvent); err != nil { 34 if err == io.EOF { 35 break 36 } 37 38 return nil, fmt.Errorf("decoding event %d: %w", len(events), err) 39 } 40 41 event, err := ConvertJSONEvent(jsonEvent) 42 if err != nil { 43 return nil, fmt.Errorf("converting event %d: %w", len(events), err) 44 } 45 events = append(events, event) 46 } 47 48 // If there are no events or if the event stream does not terminate with a cancel event, 49 // synthesize one here. 50 if len(events) == 0 || events[len(events)-1].Type != engine.CancelEvent { 51 events = append(events, engine.NewEvent(engine.CancelEvent, nil)) 52 } 53 54 return events, nil 55 } 56 57 func testDiffEvents(t *testing.T, path string, accept bool, truncateOutput bool) { 58 events, err := loadEvents(path) 59 require.NoError(t, err) 60 61 var expectedStdout []byte 62 var expectedStderr []byte 63 if !accept { 64 expectedStdout, err = os.ReadFile(path + ".stdout.txt") 65 require.NoError(t, err) 66 67 expectedStderr, err = os.ReadFile(path + ".stderr.txt") 68 require.NoError(t, err) 69 } 70 71 eventChannel, doneChannel := make(chan engine.Event), make(chan bool) 72 73 var stdout bytes.Buffer 74 var stderr bytes.Buffer 75 76 go ShowDiffEvents("test", eventChannel, doneChannel, Options{ 77 Color: colors.Raw, 78 ShowConfig: true, 79 ShowReplacementSteps: true, 80 ShowSameResources: true, 81 ShowReads: true, 82 TruncateOutput: truncateOutput, 83 Stdout: &stdout, 84 Stderr: &stderr, 85 }) 86 87 for _, e := range events { 88 eventChannel <- e 89 } 90 <-doneChannel 91 92 if !accept { 93 assert.Equal(t, string(expectedStdout), string(stdout.Bytes())) 94 assert.Equal(t, string(expectedStderr), string(stderr.Bytes())) 95 } else { 96 err = os.WriteFile(path+".stdout.txt", stdout.Bytes(), 0600) 97 require.NoError(t, err) 98 99 err = os.WriteFile(path+".stderr.txt", stderr.Bytes(), 0600) 100 require.NoError(t, err) 101 } 102 } 103 104 func TestDiffEvents(t *testing.T) { 105 t.Parallel() 106 107 accept := cmdutil.IsTruthy(os.Getenv("PULUMI_ACCEPT")) 108 109 entries, err := os.ReadDir("testdata/not-truncated") 110 require.NoError(t, err) 111 112 //nolint:paralleltest 113 for _, entry := range entries { 114 if entry.IsDir() || filepath.Ext(entry.Name()) != ".json" { 115 continue 116 } 117 118 path := filepath.Join("testdata/not-truncated", entry.Name()) 119 t.Run(entry.Name(), func(t *testing.T) { 120 t.Parallel() 121 testDiffEvents(t, path, accept, false) 122 }) 123 } 124 125 entries, err = os.ReadDir("testdata/truncated") 126 require.NoError(t, err) 127 128 //nolint:paralleltest 129 for _, entry := range entries { 130 if entry.IsDir() || filepath.Ext(entry.Name()) != ".json" { 131 continue 132 } 133 134 path := filepath.Join("testdata/truncated", entry.Name()) 135 t.Run(entry.Name(), func(t *testing.T) { 136 t.Parallel() 137 testDiffEvents(t, path, accept, true) 138 }) 139 } 140 }