github.com/nextlinux/gosbom@v0.81.1-0.20230627115839-1ff50c281391/gosbom/source/scheme_test.go (about)

     1  package source
     2  
     3  import (
     4  	"os"
     5  	"testing"
     6  
     7  	"github.com/mitchellh/go-homedir"
     8  	"github.com/spf13/afero"
     9  	"github.com/stretchr/testify/assert"
    10  
    11  	"github.com/anchore/stereoscope/pkg/image"
    12  )
    13  
    14  func TestDetectScheme(t *testing.T) {
    15  	type detectorResult struct {
    16  		src image.Source
    17  		ref string
    18  		err error
    19  	}
    20  
    21  	testCases := []struct {
    22  		name             string
    23  		userInput        string
    24  		dirs             []string
    25  		files            []string
    26  		detection        detectorResult
    27  		expectedScheme   Scheme
    28  		expectedLocation string
    29  	}{
    30  		{
    31  			name:      "docker-image-ref",
    32  			userInput: "wagoodman/dive:latest",
    33  			detection: detectorResult{
    34  				src: image.DockerDaemonSource,
    35  				ref: "wagoodman/dive:latest",
    36  			},
    37  			expectedScheme:   ImageScheme,
    38  			expectedLocation: "wagoodman/dive:latest",
    39  		},
    40  		{
    41  			name:      "docker-image-ref-no-tag",
    42  			userInput: "wagoodman/dive",
    43  			detection: detectorResult{
    44  				src: image.DockerDaemonSource,
    45  				ref: "wagoodman/dive",
    46  			},
    47  			expectedScheme:   ImageScheme,
    48  			expectedLocation: "wagoodman/dive",
    49  		},
    50  		{
    51  			name:      "registry-image-explicit-scheme",
    52  			userInput: "registry:wagoodman/dive:latest",
    53  			detection: detectorResult{
    54  				src: image.OciRegistrySource,
    55  				ref: "wagoodman/dive:latest",
    56  			},
    57  			expectedScheme:   ImageScheme,
    58  			expectedLocation: "wagoodman/dive:latest",
    59  		},
    60  		{
    61  			name:      "docker-image-explicit-scheme",
    62  			userInput: "docker:wagoodman/dive:latest",
    63  			detection: detectorResult{
    64  				src: image.DockerDaemonSource,
    65  				ref: "wagoodman/dive:latest",
    66  			},
    67  			expectedScheme:   ImageScheme,
    68  			expectedLocation: "wagoodman/dive:latest",
    69  		},
    70  		{
    71  			name:      "docker-image-explicit-scheme-no-tag",
    72  			userInput: "docker:wagoodman/dive",
    73  			detection: detectorResult{
    74  				src: image.DockerDaemonSource,
    75  				ref: "wagoodman/dive",
    76  			},
    77  			expectedScheme:   ImageScheme,
    78  			expectedLocation: "wagoodman/dive",
    79  		},
    80  		{
    81  			name:      "docker-image-edge-case",
    82  			userInput: "docker:latest",
    83  			detection: detectorResult{
    84  				src: image.DockerDaemonSource,
    85  				ref: "latest",
    86  			},
    87  			expectedScheme: ImageScheme,
    88  			// we expected to be able to handle this case better, however, I don't see a way to do this
    89  			// the user will need to provide more explicit input (docker:docker:latest)
    90  			expectedLocation: "latest",
    91  		},
    92  		{
    93  			name:      "docker-image-edge-case-explicit",
    94  			userInput: "docker:docker:latest",
    95  			detection: detectorResult{
    96  				src: image.DockerDaemonSource,
    97  				ref: "docker:latest",
    98  			},
    99  			expectedScheme: ImageScheme,
   100  			// we expected to be able to handle this case better, however, I don't see a way to do this
   101  			// the user will need to provide more explicit input (docker:docker:latest)
   102  			expectedLocation: "docker:latest",
   103  		},
   104  		{
   105  			name:      "oci-tar",
   106  			userInput: "some/path-to-file",
   107  			detection: detectorResult{
   108  				src: image.OciTarballSource,
   109  				ref: "some/path-to-file",
   110  			},
   111  			expectedScheme:   ImageScheme,
   112  			expectedLocation: "some/path-to-file",
   113  		},
   114  		{
   115  			name:      "oci-dir",
   116  			userInput: "some/path-to-dir",
   117  			detection: detectorResult{
   118  				src: image.OciDirectorySource,
   119  				ref: "some/path-to-dir",
   120  			},
   121  			dirs:             []string{"some/path-to-dir"},
   122  			expectedScheme:   ImageScheme,
   123  			expectedLocation: "some/path-to-dir",
   124  		},
   125  		{
   126  			name:      "guess-dir",
   127  			userInput: "some/path-to-dir",
   128  			detection: detectorResult{
   129  				src: image.UnknownSource,
   130  				ref: "",
   131  			},
   132  			dirs:             []string{"some/path-to-dir"},
   133  			expectedScheme:   DirectoryScheme,
   134  			expectedLocation: "some/path-to-dir",
   135  		},
   136  		{
   137  			name:      "generic-dir-does-not-exist",
   138  			userInput: "some/path-to-dir",
   139  			detection: detectorResult{
   140  				src: image.DockerDaemonSource,
   141  				ref: "some/path-to-dir",
   142  			},
   143  			expectedScheme:   ImageScheme,
   144  			expectedLocation: "some/path-to-dir",
   145  		},
   146  		{
   147  			name:      "found-podman-image-scheme",
   148  			userInput: "podman:something:latest",
   149  			detection: detectorResult{
   150  				src: image.PodmanDaemonSource,
   151  				ref: "something:latest",
   152  			},
   153  			expectedScheme:   ImageScheme,
   154  			expectedLocation: "something:latest",
   155  		},
   156  		{
   157  			name:      "explicit-dir",
   158  			userInput: "dir:some/path-to-dir",
   159  			detection: detectorResult{
   160  				src: image.UnknownSource,
   161  				ref: "",
   162  			},
   163  			dirs:             []string{"some/path-to-dir"},
   164  			expectedScheme:   DirectoryScheme,
   165  			expectedLocation: "some/path-to-dir",
   166  		},
   167  		{
   168  			name:      "explicit-file",
   169  			userInput: "file:some/path-to-file",
   170  			detection: detectorResult{
   171  				src: image.UnknownSource,
   172  				ref: "",
   173  			},
   174  			files:            []string{"some/path-to-file"},
   175  			expectedScheme:   FileScheme,
   176  			expectedLocation: "some/path-to-file",
   177  		},
   178  		{
   179  			name:      "implicit-file",
   180  			userInput: "some/path-to-file",
   181  			detection: detectorResult{
   182  				src: image.UnknownSource,
   183  				ref: "",
   184  			},
   185  			files:            []string{"some/path-to-file"},
   186  			expectedScheme:   FileScheme,
   187  			expectedLocation: "some/path-to-file",
   188  		},
   189  		{
   190  			name:      "explicit-current-dir",
   191  			userInput: "dir:.",
   192  			detection: detectorResult{
   193  				src: image.UnknownSource,
   194  				ref: "",
   195  			},
   196  			expectedScheme:   DirectoryScheme,
   197  			expectedLocation: ".",
   198  		},
   199  		{
   200  			name:      "current-dir",
   201  			userInput: ".",
   202  			detection: detectorResult{
   203  				src: image.UnknownSource,
   204  				ref: "",
   205  			},
   206  			expectedScheme:   DirectoryScheme,
   207  			expectedLocation: ".",
   208  		},
   209  		// we should support tilde expansion
   210  		{
   211  			name:      "tilde-expansion-image-implicit",
   212  			userInput: "~/some-path",
   213  			detection: detectorResult{
   214  				src: image.OciDirectorySource,
   215  				ref: "~/some-path",
   216  			},
   217  			expectedScheme:   ImageScheme,
   218  			expectedLocation: "~/some-path",
   219  		},
   220  		{
   221  			name:      "tilde-expansion-dir-implicit",
   222  			userInput: "~/some-path",
   223  			detection: detectorResult{
   224  				src: image.UnknownSource,
   225  				ref: "",
   226  			},
   227  			dirs:             []string{"~/some-path"},
   228  			expectedScheme:   DirectoryScheme,
   229  			expectedLocation: "~/some-path",
   230  		},
   231  		{
   232  			name:             "tilde-expansion-dir-explicit-exists",
   233  			userInput:        "dir:~/some-path",
   234  			dirs:             []string{"~/some-path"},
   235  			expectedScheme:   DirectoryScheme,
   236  			expectedLocation: "~/some-path",
   237  		},
   238  		{
   239  			name:             "tilde-expansion-dir-explicit-dne",
   240  			userInput:        "dir:~/some-path",
   241  			expectedScheme:   DirectoryScheme,
   242  			expectedLocation: "~/some-path",
   243  		},
   244  		{
   245  			name:             "tilde-expansion-dir-implicit-dne",
   246  			userInput:        "~/some-path",
   247  			expectedScheme:   UnknownScheme,
   248  			expectedLocation: "",
   249  		},
   250  	}
   251  	for _, test := range testCases {
   252  		t.Run(test.name, func(t *testing.T) {
   253  			fs := afero.NewMemMapFs()
   254  
   255  			for _, p := range test.dirs {
   256  				expandedExpectedLocation, err := homedir.Expand(p)
   257  				if err != nil {
   258  					t.Fatalf("unable to expand path=%q: %+v", p, err)
   259  				}
   260  				err = fs.Mkdir(expandedExpectedLocation, os.ModePerm)
   261  				if err != nil {
   262  					t.Fatalf("failed to create dummy dir: %+v", err)
   263  				}
   264  			}
   265  
   266  			for _, p := range test.files {
   267  				expandedExpectedLocation, err := homedir.Expand(p)
   268  				if err != nil {
   269  					t.Fatalf("unable to expand path=%q: %+v", p, err)
   270  				}
   271  				_, err = fs.Create(expandedExpectedLocation)
   272  				if err != nil {
   273  					t.Fatalf("failed to create dummy file: %+v", err)
   274  				}
   275  			}
   276  
   277  			imageDetector := func(string) (image.Source, string, error) {
   278  				// lean on the users real home directory value
   279  				switch test.detection.src {
   280  				case image.OciDirectorySource, image.DockerTarballSource, image.OciTarballSource:
   281  					expandedExpectedLocation, err := homedir.Expand(test.expectedLocation)
   282  					if err != nil {
   283  						t.Fatalf("unable to expand path=%q: %+v", test.expectedLocation, err)
   284  					}
   285  					return test.detection.src, expandedExpectedLocation, test.detection.err
   286  				default:
   287  					return test.detection.src, test.detection.ref, test.detection.err
   288  				}
   289  			}
   290  
   291  			actualScheme, actualSource, actualLocation, err := DetectScheme(fs, imageDetector, test.userInput)
   292  			if err != nil {
   293  				t.Fatalf("unexpected err : %+v", err)
   294  			}
   295  
   296  			assert.Equal(t, test.detection.src, actualSource, "mismatched source")
   297  			assert.Equal(t, test.expectedScheme, actualScheme, "mismatched scheme")
   298  
   299  			// lean on the users real home directory value
   300  			expandedExpectedLocation, err := homedir.Expand(test.expectedLocation)
   301  			if err != nil {
   302  				t.Fatalf("unable to expand path=%q: %+v", test.expectedLocation, err)
   303  			}
   304  
   305  			assert.Equal(t, expandedExpectedLocation, actualLocation, "mismatched location")
   306  		})
   307  	}
   308  }