github.com/verrazzano/verrazzano@v1.7.0/tools/vz/cmd/bugreport/bugreport_test.go (about)

     1  // Copyright (c) 2022, 2023, Oracle and/or its affiliates.
     2  // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
     3  
     4  package bugreport
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  	"os"
    10  	"testing"
    11  
    12  	"github.com/spf13/cobra"
    13  	"github.com/stretchr/testify/assert"
    14  	vzconstants "github.com/verrazzano/verrazzano/pkg/constants"
    15  	"github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/v1beta1"
    16  	"github.com/verrazzano/verrazzano/tools/vz/pkg/constants"
    17  	pkghelper "github.com/verrazzano/verrazzano/tools/vz/pkg/helpers"
    18  	"github.com/verrazzano/verrazzano/tools/vz/test/helpers"
    19  	appsv1 "k8s.io/api/apps/v1"
    20  	corev1 "k8s.io/api/core/v1"
    21  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    22  	"k8s.io/apimachinery/pkg/types"
    23  	"k8s.io/cli-runtime/pkg/genericclioptions"
    24  	dynfake "k8s.io/client-go/dynamic/fake"
    25  	"sigs.k8s.io/controller-runtime/pkg/client"
    26  	"sigs.k8s.io/controller-runtime/pkg/client/fake"
    27  )
    28  
    29  const (
    30  	testKubeConfig = "kubeconfig"
    31  	testK8sContext = "testcontext"
    32  
    33  	// captureResourceErrMsg   = "Capturing resources from the cluster"
    34  	// sensitiveDataErrMsg     = "WARNING: Please examine the contents of the bug report for any sensitive data"
    35  	// captureLogErrMsg        = "Capturing log from pod verrazzano-platform-operator in verrazzano-install namespace"
    36  	// dummyNamespaceErrMsg    = "Namespace dummy not found in the cluster"
    37  )
    38  
    39  // TestBugReportHelp
    40  // GIVEN a CLI bug-report command
    41  // WHEN I call cmd.Help for bug-report
    42  // THEN expect the help for the command in the standard output
    43  func TestBugReportHelp(t *testing.T) {
    44  	stdoutFile, stderrFile := createStdTempFiles(t)
    45  	defer os.Remove(stdoutFile.Name())
    46  	defer os.Remove(stderrFile.Name())
    47  
    48  	rc := helpers.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: stdoutFile, ErrOut: stderrFile})
    49  	cmd := NewCmdBugReport(rc)
    50  	assert.NotNil(t, cmd)
    51  	err := cmd.Help()
    52  	if err != nil {
    53  		assert.Error(t, err)
    54  	}
    55  
    56  	buf, err := os.ReadFile(stdoutFile.Name())
    57  	assert.NoError(t, err)
    58  	assert.Contains(t, string(buf), "Verrazzano command line utility to collect data from the cluster, to report an issue")
    59  }
    60  
    61  // TestBugReportExistingReportFile
    62  // GIVEN a CLI bug-report command using an existing file for flag --report-file
    63  // WHEN I call cmd.Execute for bug-report
    64  // THEN expect an error
    65  func TestBugReportExistingReportFile(t *testing.T) {
    66  	cmd := setUpAndVerifyResources(t)
    67  
    68  	tmpDir, _ := os.MkdirTemp("", "bug-report")
    69  	defer cleanupTempDir(t, tmpDir)
    70  
    71  	// Define and create the bug report file
    72  	reportFile := "bug-report.tgz"
    73  	bugRepFile, err := os.Create(tmpDir + string(os.PathSeparator) + reportFile)
    74  	if err != nil {
    75  		assert.Error(t, err)
    76  	}
    77  	defer cleanupFile(t, bugRepFile)
    78  
    79  	setUpGlobalFlags(cmd)
    80  	err = cmd.PersistentFlags().Set(constants.BugReportFileFlagName, bugRepFile.Name())
    81  	assert.NoError(t, err)
    82  	err = cmd.Execute()
    83  	assert.NotNil(t, err)
    84  	assert.Contains(t, err.Error(), "file exists")
    85  }
    86  
    87  // TestBugReportExistingDir
    88  // GIVEN a CLI bug-report command with flag --report-file pointing to an existing directory
    89  // WHEN I call cmd.Execute for bug-report
    90  // THEN expect an error
    91  func TestBugReportExistingDir(t *testing.T) {
    92  	cmd := setUpAndVerifyResources(t)
    93  
    94  	tmpDir, _ := os.MkdirTemp("", "bug-report")
    95  	defer cleanupTempDir(t, tmpDir)
    96  
    97  	reportDir := tmpDir + string(os.PathSeparator) + "test-report"
    98  	if err := os.Mkdir(reportDir, os.ModePerm); err != nil {
    99  		assert.Error(t, err)
   100  	}
   101  
   102  	setUpGlobalFlags(cmd)
   103  	err := cmd.PersistentFlags().Set(constants.BugReportFileFlagName, reportDir)
   104  	assert.NoError(t, err)
   105  	err = cmd.Execute()
   106  	assert.NotNil(t, err)
   107  	assert.Contains(t, err.Error(), "file exists")
   108  }
   109  
   110  // TestBugReportNonExistingFileDir
   111  // GIVEN a CLI bug-report command with flag --report-file pointing to a file, where the directory doesn't exist
   112  // WHEN I call cmd.Execute for bug-report
   113  // THEN expect an error
   114  func TestBugReportNonExistingFileDir(t *testing.T) {
   115  	cmd := setUpAndVerifyResources(t)
   116  
   117  	tmpDir, _ := os.MkdirTemp("", "bug-report")
   118  	defer cleanupTempDir(t, tmpDir)
   119  
   120  	reportDir := tmpDir + string(os.PathSeparator) + "test-report"
   121  	reportFile := reportDir + string(os.PathSeparator) + string(os.PathSeparator) + "bug-report.tgz"
   122  
   123  	setUpGlobalFlags(cmd)
   124  	err := cmd.PersistentFlags().Set(constants.BugReportFileFlagName, reportFile)
   125  	assert.NoError(t, err)
   126  	err = cmd.Execute()
   127  	assert.NotNil(t, err)
   128  	assert.Contains(t, err.Error(), "no such file or directory")
   129  }
   130  
   131  // TestBugReportFileNoPermission
   132  // GIVEN a CLI bug-report command with flag --report-file pointing to a file, where there is no write permission
   133  // WHEN I call cmd.Execute for bug-report
   134  // THEN expect an error
   135  func TestBugReportFileNoPermission(t *testing.T) {
   136  	cmd := setUpAndVerifyResources(t)
   137  
   138  	tmpDir, _ := os.MkdirTemp("", "bug-report")
   139  	defer cleanupTempDir(t, tmpDir)
   140  
   141  	reportDir := tmpDir + string(os.PathSeparator) + "test-report"
   142  	// Create a directory with only read permission
   143  	if err := os.Mkdir(reportDir, 0400); err != nil {
   144  		assert.Error(t, err)
   145  	}
   146  	reportFile := reportDir + string(os.PathSeparator) + "bug-report.tgz"
   147  	setUpGlobalFlags(cmd)
   148  	err := cmd.PersistentFlags().Set(constants.BugReportFileFlagName, reportFile)
   149  	assert.NoError(t, err)
   150  	err = cmd.Execute()
   151  	assert.NotNil(t, err)
   152  	assert.Contains(t, err.Error(), "permission denied")
   153  }
   154  
   155  // TestBugReportSuccess
   156  // GIVEN a CLI bug-report command with multiple flags
   157  // WHEN I call cmd.Execute
   158  // THEN expect the command to show the resources captured in the standard output and create the bug report file
   159  func TestBugReportSuccess(t *testing.T) {
   160  	cmd := setUpAndVerifyResources(t)
   161  
   162  	tmpDir, _ := os.MkdirTemp("", "bug-report")
   163  	defer cleanupTempDir(t, tmpDir)
   164  
   165  	bugRepFile := tmpDir + string(os.PathSeparator) + "bug-report.tgz"
   166  	setUpGlobalFlags(cmd)
   167  	err := cmd.PersistentFlags().Set(constants.BugReportFileFlagName, bugRepFile)
   168  	assert.NoError(t, err)
   169  	err = cmd.PersistentFlags().Set(constants.BugReportIncludeNSFlagName, "dummy,verrazzano-install,default")
   170  	assert.NoError(t, err)
   171  	err = cmd.PersistentFlags().Set(constants.VerboseFlag, "true")
   172  	assert.NoError(t, err)
   173  	err = cmd.Execute()
   174  	if err != nil {
   175  		assert.Error(t, err)
   176  	}
   177  	assert.NoError(t, err)
   178  }
   179  
   180  // TestDefaultBugReportSuccess
   181  // GIVEN a CLI bug-report command with no flags (default)
   182  // WHEN I call cmd.Execute from user permissive directory
   183  // THEN expect the command to show the resources captured in the standard output and create the bug report file in current dir
   184  func TestDefaultBugReportSuccess(t *testing.T) {
   185  	c := getClientWithVZWatch()
   186  
   187  	// Verify the vz resource is as expected
   188  	vz := v1beta1.Verrazzano{}
   189  	err := c.Get(context.TODO(), types.NamespacedName{Namespace: "default", Name: "verrazzano"}, &vz)
   190  	assert.NoError(t, err)
   191  
   192  	stdoutFile, stderrFile := createStdTempFiles(t)
   193  	defer os.Remove(stdoutFile.Name())
   194  	defer os.Remove(stderrFile.Name())
   195  
   196  	rc := setupFakeDynamicClient(c, genericclioptions.IOStreams{In: os.Stdin, Out: stdoutFile, ErrOut: stderrFile})
   197  	rc.SetClient(c)
   198  	cmd := NewCmdBugReport(rc)
   199  	assert.NotNil(t, cmd)
   200  	setUpGlobalFlags(cmd)
   201  	err = cmd.Execute()
   202  	assert.Nil(t, err)
   203  
   204  	if !pkghelper.CheckAndRemoveBugReportExistsInDir("") {
   205  		t.Fatal("cannot find bug report file in current directory")
   206  	}
   207  }
   208  
   209  // TestDefaultBugReportSuccess
   210  // GIVEN a CLI bug-report command with no flags (default)
   211  // WHEN I call cmd.Execute from read only directory
   212  // THEN expect the command to show the resources captured in the standard output and create the bug report file in tmp dir
   213  func TestDefaultBugReportReadOnlySuccess(t *testing.T) {
   214  	c := getClientWithVZWatch()
   215  
   216  	// Verify the vz resource is as expected
   217  	vz := v1beta1.Verrazzano{}
   218  	err := c.Get(context.TODO(), types.NamespacedName{Namespace: "default", Name: "verrazzano"}, &vz)
   219  	assert.NoError(t, err)
   220  
   221  	stdoutFile, stderrFile := createStdTempFiles(t)
   222  	defer os.Remove(stdoutFile.Name())
   223  	defer os.Remove(stderrFile.Name())
   224  
   225  	rc := setupFakeDynamicClient(c, genericclioptions.IOStreams{In: os.Stdin, Out: stdoutFile, ErrOut: stderrFile})
   226  	rc.SetClient(c)
   227  	cmd := NewCmdBugReport(rc)
   228  	assert.NotNil(t, cmd)
   229  	setUpGlobalFlags(cmd)
   230  	pwd, err := os.Getwd()
   231  	assert.Nil(t, err)
   232  	assert.Nil(t, os.Chdir("/"))
   233  	defer os.Chdir(pwd)
   234  
   235  	err = cmd.Execute()
   236  	assert.Nil(t, err)
   237  
   238  	if !pkghelper.CheckAndRemoveBugReportExistsInDir(os.TempDir() + "/") {
   239  		t.Fatal("cannot find bug report file in temp directory")
   240  	}
   241  }
   242  
   243  // TestBugReportDefaultReportFile
   244  // GIVEN a CLI bug-report command
   245  // WHEN I call cmd.Execute, without specifying --report-file
   246  // THEN expect the command to create the report vz-bug-report-*.tar.gz under the current directory
   247  func TestBugReportDefaultReportFile(t *testing.T) {
   248  	// clean up the bugreport file that is generated
   249  	defer func(t *testing.T) {
   250  		if !pkghelper.CheckAndRemoveBugReportExistsInDir("") {
   251  			t.Fatal("cannot find and delete bug report file in current directory")
   252  		}
   253  	}(t)
   254  
   255  	c := getClientWithVZWatch()
   256  
   257  	// Verify the vz resource is as expected
   258  	vz := v1beta1.Verrazzano{}
   259  	err := c.Get(context.TODO(), types.NamespacedName{Namespace: "default", Name: "verrazzano"}, &vz)
   260  	assert.NoError(t, err)
   261  
   262  	stdoutFile, err := os.CreateTemp("", "tmpstdout")
   263  	assert.NoError(t, err)
   264  	defer os.Remove(stdoutFile.Name())
   265  
   266  	stderrFile, err := os.CreateTemp("", "tmpstderr")
   267  	assert.NoError(t, err)
   268  	defer os.Remove(stderrFile.Name())
   269  
   270  	rc := setupFakeDynamicClient(c, genericclioptions.IOStreams{In: os.Stdin, Out: stdoutFile, ErrOut: stderrFile})
   271  	rc.SetClient(c)
   272  	cmd := NewCmdBugReport(rc)
   273  	err = cmd.PersistentFlags().Set(constants.VerboseFlag, "true")
   274  	setUpGlobalFlags(cmd)
   275  	assert.NoError(t, err)
   276  	assert.NotNil(t, cmd)
   277  	err = cmd.Execute()
   278  	assert.NoError(t, err)
   279  
   280  	_, err = os.ReadFile(stdoutFile.Name())
   281  	assert.NoError(t, err)
   282  }
   283  
   284  // TestBugReportNoVerrazzano
   285  // GIVEN a CLI bug-report command
   286  // WHEN I call cmd.Execute without Verrazzano installed
   287  // THEN expect the command to generate bug report
   288  func TestBugReportNoVerrazzano(t *testing.T) {
   289  	c := getClientWithWatch()
   290  	stdoutFile, stderrFile := createStdTempFiles(t)
   291  	defer os.Remove(stdoutFile.Name())
   292  	defer os.Remove(stderrFile.Name())
   293  
   294  	rc := setupFakeDynamicClient(c, genericclioptions.IOStreams{In: os.Stdin, Out: stdoutFile, ErrOut: stderrFile})
   295  	rc.SetClient(c)
   296  	cmd := NewCmdBugReport(rc)
   297  	assert.NotNil(t, cmd)
   298  
   299  	tmpDir, _ := os.MkdirTemp("", "bug-report")
   300  	defer cleanupTempDir(t, tmpDir)
   301  
   302  	bugRepFile := tmpDir + string(os.PathSeparator) + "bug-report.tgz"
   303  	setUpGlobalFlags(cmd)
   304  	err := cmd.PersistentFlags().Set(constants.BugReportFileFlagName, bugRepFile)
   305  	assert.NoError(t, err)
   306  	err = cmd.PersistentFlags().Set(constants.BugReportIncludeNSFlagName, "dummy,verrazzano-install")
   307  	assert.NoError(t, err)
   308  	err = cmd.Execute()
   309  	if err != nil {
   310  		assert.Error(t, err)
   311  	}
   312  
   313  	errBuf, err := os.ReadFile(stderrFile.Name())
   314  	assert.NoError(t, err)
   315  	assert.NotContains(t, string(errBuf), "Verrazzano is not installed")
   316  	assert.FileExists(t, bugRepFile)
   317  }
   318  
   319  // TestBugReportFailureUsingInvalidClient
   320  // GIVEN a CLI bug-report command
   321  // WHEN I call cmd.Execute without Verrazzano installed and using an invalid client
   322  // THEN expect the command to fail with a message indicating Verrazzano is not installed and no resource captured
   323  func TestBugReportFailureUsingInvalidClient(t *testing.T) {
   324  	c := getInvalidClient()
   325  	stdoutFile, stderrFile := createStdTempFiles(t)
   326  	defer os.Remove(stdoutFile.Name())
   327  	defer os.Remove(stderrFile.Name())
   328  
   329  	rc := setupFakeDynamicClient(c, genericclioptions.IOStreams{In: os.Stdin, Out: stdoutFile, ErrOut: stderrFile})
   330  	rc.SetClient(c)
   331  	cmd := NewCmdBugReport(rc)
   332  	assert.NotNil(t, cmd)
   333  
   334  	tmpDir, _ := os.MkdirTemp("", "bug-report")
   335  	defer cleanupTempDir(t, tmpDir)
   336  
   337  	bugRepFile := tmpDir + string(os.PathSeparator) + "bug-report.tgz"
   338  	setUpGlobalFlags(cmd)
   339  	err := cmd.PersistentFlags().Set(constants.BugReportFileFlagName, bugRepFile)
   340  	assert.NoError(t, err)
   341  	err = cmd.PersistentFlags().Set(constants.BugReportIncludeNSFlagName, "dummy,verrazzano-install")
   342  	assert.NoError(t, err)
   343  	err = cmd.Execute()
   344  	if err != nil {
   345  		assert.Error(t, err)
   346  	}
   347  
   348  	errBuf, err := os.ReadFile(stderrFile.Name())
   349  	assert.NoError(t, err)
   350  	assert.NotContains(t, string(errBuf), "Verrazzano is not installed")
   351  	assert.FileExists(t, bugRepFile)
   352  }
   353  
   354  // getClientWithWatch returns a client containing all VPO objects
   355  func getClientWithWatch() client.WithWatch {
   356  	return fake.NewClientBuilder().WithScheme(pkghelper.NewScheme()).WithObjects(getVpoObjects()[1:]...).Build()
   357  }
   358  
   359  // getClientWithVZWatch returns a client containing all VPO objects and the Verrazzano CR
   360  func getClientWithVZWatch() client.WithWatch {
   361  	return fake.NewClientBuilder().WithScheme(pkghelper.NewScheme()).WithObjects(getVpoObjects()...).Build()
   362  }
   363  
   364  func getVpoObjects() []client.Object {
   365  	return []client.Object{
   366  		&v1beta1.Verrazzano{
   367  			ObjectMeta: metav1.ObjectMeta{
   368  				Namespace: "default",
   369  				Name:      "verrazzano",
   370  			},
   371  			Spec: v1beta1.VerrazzanoSpec{
   372  				Profile: v1beta1.Dev,
   373  			},
   374  		},
   375  		&corev1.Pod{
   376  			ObjectMeta: metav1.ObjectMeta{
   377  				Namespace: vzconstants.VerrazzanoInstallNamespace,
   378  				Name:      constants.VerrazzanoPlatformOperator,
   379  				Labels: map[string]string{
   380  					"app":               constants.VerrazzanoPlatformOperator,
   381  					"pod-template-hash": "45f78ffddd",
   382  				},
   383  			},
   384  		},
   385  		&appsv1.Deployment{
   386  			ObjectMeta: metav1.ObjectMeta{
   387  				Namespace: vzconstants.VerrazzanoInstallNamespace,
   388  				Name:      constants.VerrazzanoPlatformOperator,
   389  			},
   390  			Spec: appsv1.DeploymentSpec{
   391  				Selector: &metav1.LabelSelector{
   392  					MatchLabels: map[string]string{"app": constants.VerrazzanoPlatformOperator},
   393  				},
   394  			},
   395  			Status: appsv1.DeploymentStatus{
   396  				AvailableReplicas: 1,
   397  				UpdatedReplicas:   1,
   398  			},
   399  		},
   400  		&appsv1.ReplicaSet{
   401  			ObjectMeta: metav1.ObjectMeta{
   402  				Namespace: vzconstants.VerrazzanoInstallNamespace,
   403  				Name:      fmt.Sprintf("%s-45f78ffddd", constants.VerrazzanoPlatformOperator),
   404  				Annotations: map[string]string{
   405  					"deployment.kubernetes.io/revision": "1",
   406  				},
   407  			},
   408  		},
   409  	}
   410  }
   411  
   412  // getInvalidClient returns an invalid client
   413  func getInvalidClient() client.WithWatch {
   414  	testObj := &corev1.Pod{
   415  		ObjectMeta: metav1.ObjectMeta{
   416  			Namespace: "testnamespace",
   417  			Name:      "testpod",
   418  			Labels: map[string]string{
   419  				"app":               "test-app",
   420  				"pod-template-hash": "56f78ddcfd",
   421  			},
   422  		},
   423  	}
   424  	deployment := &appsv1.Deployment{
   425  		ObjectMeta: metav1.ObjectMeta{
   426  			Namespace: "testnamespace",
   427  			Name:      "testpod",
   428  		},
   429  		Spec: appsv1.DeploymentSpec{
   430  			Selector: &metav1.LabelSelector{
   431  				MatchLabels: map[string]string{"app": "test-app"},
   432  			},
   433  		},
   434  	}
   435  	return fake.NewClientBuilder().WithScheme(pkghelper.NewScheme()).WithObjects(testObj, deployment).Build()
   436  }
   437  
   438  // cleanupTempDir cleans up the given temp directory after the test run
   439  func cleanupTempDir(t *testing.T, dirName string) {
   440  	if err := os.RemoveAll(dirName); err != nil {
   441  		t.Fatalf("Remove directory failed: %v", err)
   442  	}
   443  }
   444  
   445  // cleanupTempDir cleans up the given temp file after the test run
   446  func cleanupFile(t *testing.T, file *os.File) {
   447  	if err := file.Close(); err != nil {
   448  		t.Fatalf("Close file failed: %v", err)
   449  	}
   450  	if err := os.Remove(file.Name()); err != nil {
   451  		t.Fatalf("Close file failed: %v", err)
   452  	}
   453  }
   454  
   455  // createStdTempFiles creates temporary files for stdout and stderr.
   456  func createStdTempFiles(t *testing.T) (*os.File, *os.File) {
   457  	stdoutFile, err := os.CreateTemp("", "tmpstdout")
   458  	assert.NoError(t, err)
   459  
   460  	stderrFile, err := os.CreateTemp("", "tmpstderr")
   461  	assert.NoError(t, err)
   462  
   463  	return stdoutFile, stderrFile
   464  }
   465  
   466  // TestBugReportSuccess
   467  // GIVEN a CLI bug-report command
   468  // WHEN I call cmd.Execute with include logs of  additional namespace and duration
   469  // THEN expect the command to show the resources captured in the standard output and create the bug report file
   470  func TestBugReportSuccessWithDuration(t *testing.T) {
   471  	cmd := setUpAndVerifyResources(t)
   472  
   473  	tmpDir, _ := os.MkdirTemp("", "bug-report")
   474  	defer cleanupTempDir(t, tmpDir)
   475  
   476  	bugRepFile := tmpDir + string(os.PathSeparator) + "bug-report.tgz"
   477  	setUpGlobalFlags(cmd)
   478  	err := cmd.PersistentFlags().Set(constants.BugReportFileFlagName, bugRepFile)
   479  	assert.NoError(t, err)
   480  	err = cmd.PersistentFlags().Set(constants.BugReportIncludeNSFlagName, "dummy,verrazzano-install,default,test")
   481  	assert.NoError(t, err)
   482  	err = cmd.PersistentFlags().Set(constants.VerboseFlag, "true")
   483  	assert.NoError(t, err)
   484  	err = cmd.PersistentFlags().Set(constants.BugReportLogFlagName, "true")
   485  	assert.NoError(t, err)
   486  	// If invalid time value is given then error is expected
   487  	err = cmd.PersistentFlags().Set(constants.BugReportTimeFlagName, "3t")
   488  	assert.Error(t, err)
   489  	// Valid time value
   490  	err = cmd.PersistentFlags().Set(constants.BugReportTimeFlagName, "3h")
   491  	assert.NoError(t, err)
   492  	err = cmd.Execute()
   493  	if err != nil {
   494  		assert.Error(t, err)
   495  	}
   496  	assert.NoError(t, err)
   497  }
   498  
   499  func setUpGlobalFlags(cmd *cobra.Command) {
   500  	tempKubeConfigPath, _ := os.CreateTemp(os.TempDir(), testKubeConfig)
   501  	cmd.Flags().String(constants.GlobalFlagKubeConfig, tempKubeConfigPath.Name(), "")
   502  	cmd.Flags().String(constants.GlobalFlagContext, testK8sContext, "")
   503  }
   504  
   505  func setUpAndVerifyResources(t *testing.T) *cobra.Command {
   506  	c := getClientWithVZWatch()
   507  
   508  	// Verify the vz resource is as expected
   509  	vz := v1beta1.Verrazzano{}
   510  	err := c.Get(context.TODO(), types.NamespacedName{Namespace: "default", Name: "verrazzano"}, &vz)
   511  	assert.NoError(t, err)
   512  
   513  	stdoutFile, stderrFile := createStdTempFiles(t)
   514  	defer os.Remove(stdoutFile.Name())
   515  	defer os.Remove(stderrFile.Name())
   516  	rc := setupFakeDynamicClient(c, genericclioptions.IOStreams{In: os.Stdin, Out: stdoutFile, ErrOut: stderrFile})
   517  
   518  	cmd := NewCmdBugReport(rc)
   519  	assert.NotNil(t, cmd)
   520  
   521  	return cmd
   522  }
   523  
   524  func setupFakeDynamicClient(c client.WithWatch, ioStreams genericclioptions.IOStreams) *helpers.FakeRootCmdContext {
   525  	rc := helpers.NewFakeRootCmdContext(ioStreams)
   526  	rc.SetClient(c)
   527  	rc.SetDynamicClient(dynfake.NewSimpleDynamicClient(pkghelper.GetScheme()))
   528  	return rc
   529  }