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  }