get.porter.sh/porter@v1.3.0/pkg/portercontext/context_test.go (about)

     1  package portercontext
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"runtime"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  	"go.uber.org/zap/zapcore"
    13  )
    14  
    15  func TestContext_EnvironMap(t *testing.T) {
    16  	c := NewTestContext(t)
    17  	c.Clearenv()
    18  
    19  	c.Setenv("a", "1")
    20  	c.Setenv("b", "2")
    21  
    22  	got := c.EnvironMap()
    23  
    24  	want := map[string]string{
    25  		"a": "1",
    26  		"b": "2",
    27  	}
    28  	assert.Equal(t, want, got)
    29  
    30  	// Make sure we have a copy
    31  	got["c"] = "3"
    32  	assert.Empty(t, c.Getenv("c"), "Expected to get a copy of the context's environment variables")
    33  }
    34  
    35  func TestContext_LogToFile(t *testing.T) {
    36  	c := NewTestContext(t)
    37  	c.ConfigureLogging(context.Background(), LogConfiguration{
    38  		Verbosity:    zapcore.DebugLevel,
    39  		LogLevel:     zapcore.DebugLevel,
    40  		LogToFile:    true,
    41  		LogDirectory: "/.porter/logs",
    42  	})
    43  	c.timestampLogs = false // turn off timestamps so we can compare more easily
    44  	logfile := c.logFile.Name()
    45  	_, log := c.StartRootSpan(context.Background(), t.Name())
    46  	log.Info("a thing happened")
    47  	log.Warn("a weird thing happened")
    48  	//throwing away error here because it is a test
    49  	// we do not return it
    50  	_ = log.Error(errors.New("a bad thing happened"))
    51  
    52  	log.EndSpan()
    53  	c.Close()
    54  
    55  	// Check that the logs are in json
    56  	logContents, err := c.FileSystem.ReadFile(logfile)
    57  	require.NoError(t, err)
    58  	c.CompareGoldenFile("testdata/expected-logs.txt", string(logContents))
    59  
    60  	// Compare the human readable logs sent to stderr
    61  	if runtime.GOOS == "windows" {
    62  		c.CompareGoldenFile("testdata/expected-output-windows.txt", c.GetAllLogs())
    63  	} else {
    64  		c.CompareGoldenFile("testdata/expected-output.txt", c.GetAllLogs())
    65  	}
    66  }
    67  
    68  func TestContext_PluginVerbosityLevel(t *testing.T) {
    69  	testcases := []struct {
    70  		name                 string
    71  		verbosityLevel       zapcore.Level
    72  		wantNumberOfLogLines int
    73  	}{
    74  		{"debug level", zapcore.DebugLevel, 4},
    75  		{"info level", zapcore.InfoLevel, 3},
    76  		{"warn level", zapcore.WarnLevel, 2},
    77  		{"error level", zapcore.ErrorLevel, 1},
    78  	}
    79  
    80  	for _, tc := range testcases {
    81  		t.Run(tc.name, func(t *testing.T) {
    82  			c := NewTestContext(t)
    83  			c.IsInternalPlugin = true
    84  			c.ConfigureLogging(context.Background(), LogConfiguration{
    85  				Verbosity: tc.verbosityLevel,
    86  			})
    87  
    88  			_, log := c.StartRootSpan(context.Background(), t.Name())
    89  			log.Debug("debug log")
    90  			log.Info("info log")
    91  			log.Warn("warning log")
    92  			//throwing away error here because it is a test
    93  			// we do not return it
    94  			_ = log.Error(errors.New("error log"))
    95  
    96  			log.EndSpan()
    97  			c.Close()
    98  
    99  			lines := strings.Split(c.captureLogs.String(), "\n")
   100  			lines = lines[:len(lines)-1] // Remove last line as it will be empty
   101  			require.Len(t, lines, tc.wantNumberOfLogLines)
   102  		})
   103  	}
   104  }
   105  
   106  func TestContext_PluginLogCollectorLevel(t *testing.T) {
   107  	c := NewTestContext(t)
   108  	c.IsInternalPlugin = true
   109  	c.ConfigureLogging(context.Background(), LogConfiguration{
   110  		Verbosity: zapcore.DebugLevel,
   111  	})
   112  
   113  	_, log := c.StartRootSpan(context.Background(), t.Name())
   114  	log.Debug("debug log")
   115  	log.Info("info log")
   116  	log.Warn("warning log")
   117  	//throwing away error here because it is a test
   118  	// we do not return it
   119  	_ = log.Error(errors.New("error log"))
   120  
   121  	log.EndSpan()
   122  	c.Close()
   123  
   124  	lines := strings.Split(c.captureLogs.String(), "\n")
   125  	require.Contains(t, lines[0], "\"@level\":\"debug\"")
   126  	require.Contains(t, lines[0], "\"@message\":\"debug log\"")
   127  	require.Contains(t, lines[1], "\"@level\":\"info\"")
   128  	require.Contains(t, lines[1], "\"@message\":\"info log\"")
   129  	require.Contains(t, lines[2], "\"@level\":\"warn\"")
   130  	require.Contains(t, lines[2], "\"@message\":\"warning log\"")
   131  	require.Contains(t, lines[3], "\"@level\":\"error\"")
   132  	require.Contains(t, lines[3], "\"@message\":\"error log\"")
   133  }
   134  
   135  func TestContext_SensitiveLogsAreCensored(t *testing.T) {
   136  	c := NewTestContext(t)
   137  	defer c.Close()
   138  	c.ConfigureLogging(context.Background(), LogConfiguration{
   139  		Verbosity: zapcore.DebugLevel,
   140  	})
   141  	c.SetSensitiveValues([]string{"topsecret"})
   142  
   143  	c.logger.Info("this is a test with sensitive data: topsecret")
   144  
   145  	logs := c.captureLogs.String()
   146  	require.Contains(t, logs, "this is a test with sensitive data: *******")
   147  	require.NotContains(t, logs, "topsecret")
   148  }
   149  
   150  func TestContext_TracesWithSensitiveLogsAreCensored(t *testing.T) {
   151  	c := NewTestContext(t)
   152  	c.ConfigureLogging(context.Background(), LogConfiguration{
   153  		Verbosity: zapcore.DebugLevel,
   154  	})
   155  	c.SetSensitiveValues([]string{"topsecret"})
   156  
   157  	_, log := c.StartRootSpan(context.Background(), t.Name())
   158  	log.Debug("this is a test with sensitive data: topsecret")
   159  	log.EndSpan()
   160  	c.Close()
   161  
   162  	logs := c.captureLogs.String()
   163  	require.Contains(t, logs, "this is a test with sensitive data: *******")
   164  	require.NotContains(t, logs, "topsecret")
   165  }
   166  
   167  func TestContext_PluginLogsAreCensored(t *testing.T) {
   168  	c := NewTestContext(t)
   169  	c.IsInternalPlugin = true
   170  	c.ConfigureLogging(context.Background(), LogConfiguration{
   171  		Verbosity: zapcore.DebugLevel,
   172  	})
   173  	c.SetSensitiveValues([]string{"topsecret"})
   174  
   175  	_, log := c.StartRootSpan(context.Background(), t.Name())
   176  	log.Debug("this is a test with sensitive data: topsecret")
   177  	log.EndSpan()
   178  	c.Close()
   179  
   180  	logs := c.captureLogs.String()
   181  	require.Contains(t, logs, "this is a test with sensitive data: *******")
   182  	require.NotContains(t, logs, "topsecret")
   183  }
   184  
   185  func TestContext_LogToFileWithCensoredValues(t *testing.T) {
   186  	c := NewTestContext(t)
   187  	c.ConfigureLogging(context.Background(), LogConfiguration{
   188  		Verbosity:    zapcore.DebugLevel,
   189  		LogLevel:     zapcore.DebugLevel,
   190  		LogToFile:    true,
   191  		LogDirectory: "/.porter/logs",
   192  	})
   193  	c.SetSensitiveValues([]string{"topsecret"})
   194  	c.timestampLogs = false // turn off timestamps so we can compare more easily
   195  	logfile := c.logFile.Name()
   196  	_, log := c.StartRootSpan(context.Background(), t.Name())
   197  	log.Info("this is a test with sensitive data: topsecret")
   198  
   199  	log.EndSpan()
   200  	c.Close()
   201  
   202  	logContents, err := c.FileSystem.ReadFile(logfile)
   203  	require.NoError(t, err)
   204  	require.Contains(t, string(logContents), "this is a test with sensitive data: *******")
   205  	require.NotContains(t, string(logContents), "topsecret")
   206  }