github.com/nextlinux/gosbom@v0.81.1-0.20230627115839-1ff50c281391/cmd/gosbom/cli/options/writer_test.go (about)

     1  package options
     2  
     3  import (
     4  	"io"
     5  	"path/filepath"
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/docker/docker/pkg/homedir"
    10  	"github.com/nextlinux/gosbom/gosbom/sbom"
    11  	"github.com/stretchr/testify/assert"
    12  )
    13  
    14  func Test_MakeSBOMWriter(t *testing.T) {
    15  	tests := []struct {
    16  		outputs []string
    17  		wantErr assert.ErrorAssertionFunc
    18  	}{
    19  		{
    20  			outputs: []string{"json"},
    21  			wantErr: assert.NoError,
    22  		},
    23  		{
    24  			outputs: []string{"table", "json"},
    25  			wantErr: assert.NoError,
    26  		},
    27  		{
    28  			outputs: []string{"unknown"},
    29  			wantErr: func(t assert.TestingT, err error, bla ...interface{}) bool {
    30  				return assert.ErrorContains(t, err, `unsupported output format "unknown", supported formats are: [`)
    31  			},
    32  		},
    33  	}
    34  
    35  	for _, tt := range tests {
    36  		_, err := MakeSBOMWriter(tt.outputs, "", "")
    37  		tt.wantErr(t, err)
    38  	}
    39  }
    40  
    41  func dummyEncoder(io.Writer, sbom.SBOM) error {
    42  	return nil
    43  }
    44  
    45  func dummyFormat(name string) sbom.Format {
    46  	return sbom.NewFormat(sbom.AnyVersion, dummyEncoder, nil, nil, sbom.FormatID(name))
    47  }
    48  
    49  func Test_newSBOMMultiWriter(t *testing.T) {
    50  	type writerConfig struct {
    51  		format string
    52  		file   string
    53  	}
    54  
    55  	tmp := t.TempDir()
    56  
    57  	testName := func(options []sbomWriterDescription, err bool) string {
    58  		var out []string
    59  		for _, opt := range options {
    60  			out = append(out, string(opt.Format.ID())+"="+opt.Path)
    61  		}
    62  		errs := ""
    63  		if err {
    64  			errs = "(err)"
    65  		}
    66  		return strings.Join(out, ", ") + errs
    67  	}
    68  
    69  	tests := []struct {
    70  		outputs  []sbomWriterDescription
    71  		err      bool
    72  		expected []writerConfig
    73  	}{
    74  		{
    75  			outputs: []sbomWriterDescription{},
    76  			err:     true,
    77  		},
    78  		{
    79  			outputs: []sbomWriterDescription{
    80  				{
    81  					Format: dummyFormat("table"),
    82  					Path:   "",
    83  				},
    84  			},
    85  			expected: []writerConfig{
    86  				{
    87  					format: "table",
    88  				},
    89  			},
    90  		},
    91  		{
    92  			outputs: []sbomWriterDescription{
    93  				{
    94  					Format: dummyFormat("json"),
    95  				},
    96  			},
    97  			expected: []writerConfig{
    98  				{
    99  					format: "json",
   100  				},
   101  			},
   102  		},
   103  		{
   104  			outputs: []sbomWriterDescription{
   105  				{
   106  					Format: dummyFormat("json"),
   107  					Path:   "test-2.json",
   108  				},
   109  			},
   110  			expected: []writerConfig{
   111  				{
   112  					format: "json",
   113  					file:   "test-2.json",
   114  				},
   115  			},
   116  		},
   117  		{
   118  			outputs: []sbomWriterDescription{
   119  				{
   120  					Format: dummyFormat("json"),
   121  					Path:   "test-3/1.json",
   122  				},
   123  				{
   124  					Format: dummyFormat("spdx-json"),
   125  					Path:   "test-3/2.json",
   126  				},
   127  			},
   128  			expected: []writerConfig{
   129  				{
   130  					format: "json",
   131  					file:   "test-3/1.json",
   132  				},
   133  				{
   134  					format: "spdx-json",
   135  					file:   "test-3/2.json",
   136  				},
   137  			},
   138  		},
   139  		{
   140  			outputs: []sbomWriterDescription{
   141  				{
   142  					Format: dummyFormat("text"),
   143  				},
   144  				{
   145  					Format: dummyFormat("spdx-json"),
   146  					Path:   "test-4.json",
   147  				},
   148  			},
   149  			expected: []writerConfig{
   150  				{
   151  					format: "text",
   152  				},
   153  				{
   154  					format: "spdx-json",
   155  					file:   "test-4.json",
   156  				},
   157  			},
   158  		},
   159  	}
   160  
   161  	for _, test := range tests {
   162  		t.Run(testName(test.outputs, test.err), func(t *testing.T) {
   163  			outputs := test.outputs
   164  			for i := range outputs {
   165  				if outputs[i].Path != "" {
   166  					outputs[i].Path = tmp + outputs[i].Path
   167  				}
   168  			}
   169  
   170  			mw, err := newSBOMMultiWriter(outputs...)
   171  
   172  			if test.err {
   173  				assert.Error(t, err)
   174  				return
   175  			} else {
   176  				assert.NoError(t, err)
   177  			}
   178  
   179  			assert.Len(t, mw.writers, len(test.expected))
   180  
   181  			for i, e := range test.expected {
   182  				switch w := mw.writers[i].(type) {
   183  				case *sbomStreamWriter:
   184  					assert.Equal(t, string(w.format.ID()), e.format)
   185  					if e.file != "" {
   186  						assert.NotNil(t, w.out)
   187  					} else {
   188  						assert.NotNil(t, w.out)
   189  					}
   190  					if e.file != "" {
   191  						assert.FileExists(t, tmp+e.file)
   192  					}
   193  				default:
   194  					t.Fatalf("unknown writer type: %T", w)
   195  				}
   196  
   197  			}
   198  		})
   199  	}
   200  }
   201  
   202  func Test_newSBOMWriterDescription(t *testing.T) {
   203  	tests := []struct {
   204  		name     string
   205  		path     string
   206  		expected string
   207  	}{
   208  		{
   209  			name:     "expand home dir",
   210  			path:     "~/place.txt",
   211  			expected: filepath.Join(homedir.Get(), "place.txt"),
   212  		},
   213  		{
   214  			name:     "passthrough other paths",
   215  			path:     "/other/place.txt",
   216  			expected: "/other/place.txt",
   217  		},
   218  		{
   219  			name:     "no path",
   220  			path:     "",
   221  			expected: "",
   222  		},
   223  	}
   224  	for _, tt := range tests {
   225  		t.Run(tt.name, func(t *testing.T) {
   226  			o := newSBOMWriterDescription(dummyFormat("table"), tt.path)
   227  			assert.Equal(t, tt.expected, o.Path)
   228  		})
   229  	}
   230  }