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

     1  package file
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/nextlinux/gosbom/gosbom/artifact"
     7  	"github.com/stretchr/testify/assert"
     8  	"github.com/stretchr/testify/require"
     9  )
    10  
    11  func TestLocationSet(t *testing.T) {
    12  
    13  	etcHostsLinkVar := Location{
    14  		LocationData: LocationData{
    15  			Coordinates: Coordinates{
    16  				RealPath:     "/etc/hosts",
    17  				FileSystemID: "a",
    18  			},
    19  			VirtualPath: "/var/etc/hosts",
    20  		},
    21  	}
    22  
    23  	etcHostsLinkHome := Location{
    24  		LocationData: LocationData{
    25  			Coordinates: Coordinates{
    26  				RealPath:     "/etc/hosts",
    27  				FileSystemID: "a",
    28  			},
    29  			VirtualPath: "/home/wagoodman/hosts",
    30  		},
    31  	}
    32  
    33  	binA := Location{
    34  		LocationData: LocationData{
    35  			Coordinates: Coordinates{
    36  				RealPath:     "/bin",
    37  				FileSystemID: "a",
    38  			},
    39  			VirtualPath: "/usr/bin",
    40  		},
    41  	}
    42  
    43  	binB := Location{
    44  		LocationData: LocationData{
    45  			Coordinates: Coordinates{
    46  				RealPath:     "/bin",
    47  				FileSystemID: "b",
    48  			},
    49  			VirtualPath: "/usr/bin",
    50  		},
    51  	}
    52  
    53  	tests := []struct {
    54  		name     string
    55  		input    []Location
    56  		expected []Location
    57  	}{
    58  		{
    59  			name: "de-dup same location",
    60  			input: []Location{
    61  				binA, binA, binA,
    62  			},
    63  			expected: []Location{
    64  				binA,
    65  			},
    66  		},
    67  		{
    68  			name: "dont de-dup different filesystem",
    69  			input: []Location{
    70  				binB, binA,
    71  			},
    72  			expected: []Location{
    73  				binA, binB,
    74  			},
    75  		},
    76  		{
    77  			name: "dont de-dup different virtual paths",
    78  			input: []Location{
    79  				etcHostsLinkVar, etcHostsLinkHome,
    80  			},
    81  			expected: []Location{
    82  				etcHostsLinkHome, etcHostsLinkVar,
    83  			},
    84  		},
    85  	}
    86  
    87  	for _, test := range tests {
    88  		t.Run(test.name, func(t *testing.T) {
    89  			set := NewLocationSet(test.input...)
    90  			assert.Equal(t, test.expected, set.ToSlice())
    91  		})
    92  	}
    93  }
    94  
    95  func TestLocationSet_Hash(t *testing.T) {
    96  	etcAlink := Location{
    97  		LocationData: LocationData{
    98  			Coordinates: Coordinates{
    99  				RealPath:     "/etc/hosts",
   100  				FileSystemID: "a",
   101  			},
   102  			VirtualPath: "/var/etc/hosts",
   103  		},
   104  	}
   105  
   106  	etcA := Location{
   107  		LocationData: LocationData{
   108  			Coordinates: Coordinates{
   109  				RealPath:     "/etc/hosts",
   110  				FileSystemID: "a",
   111  			},
   112  		},
   113  	}
   114  
   115  	etcB := Location{
   116  		LocationData: LocationData{
   117  			Coordinates: Coordinates{
   118  				RealPath:     "/etc/hosts",
   119  				FileSystemID: "b",
   120  			},
   121  		},
   122  	}
   123  
   124  	binA := Location{
   125  		LocationData: LocationData{
   126  			Coordinates: Coordinates{
   127  				RealPath:     "/bin",
   128  				FileSystemID: "a",
   129  			},
   130  			VirtualPath: "/usr/bin",
   131  		},
   132  	}
   133  
   134  	binB := Location{
   135  		LocationData: LocationData{
   136  			Coordinates: Coordinates{
   137  				RealPath:     "/bin",
   138  				FileSystemID: "b",
   139  			},
   140  			VirtualPath: "/usr/bin",
   141  		},
   142  	}
   143  
   144  	tests := []struct {
   145  		name string
   146  		setA LocationSet
   147  		setB LocationSet
   148  		want assert.ComparisonAssertionFunc
   149  	}{
   150  		{
   151  			name: "empty sets have the same hash",
   152  			setA: NewLocationSet(),
   153  			setB: NewLocationSet(),
   154  			want: assert.Equal,
   155  		},
   156  		{
   157  			name: "sets with same elements accessed through different paths have the same hash",
   158  			setA: NewLocationSet(binA, etcA),
   159  			setB: NewLocationSet(etcAlink, binA),
   160  			want: assert.Equal,
   161  		},
   162  		{
   163  			name: "sets with same elements have the same hash",
   164  			setA: NewLocationSet(binA, etcA),
   165  			setB: NewLocationSet(etcA, binA),
   166  			want: assert.Equal,
   167  		},
   168  		{
   169  			name: "sets with different element counts have different hashes",
   170  			setA: NewLocationSet(binA, etcA),
   171  			setB: NewLocationSet(binA),
   172  			want: assert.NotEqual,
   173  		},
   174  		{
   175  			name: "sets with same path but different FS IDs have the same hash",
   176  			setA: NewLocationSet(binA),
   177  			setB: NewLocationSet(binB),
   178  			want: assert.Equal,
   179  		},
   180  		{
   181  			name: "sets with same paths but different FS IDs have the same hash",
   182  			setA: NewLocationSet(etcA, binA),
   183  			setB: NewLocationSet(binB, etcB),
   184  			want: assert.Equal,
   185  		},
   186  	}
   187  	for _, tt := range tests {
   188  		t.Run(tt.name, func(t *testing.T) {
   189  			gotA, err := artifact.IDByHash(tt.setA)
   190  			require.NoError(t, err)
   191  			gotB, err := artifact.IDByHash(tt.setB)
   192  			require.NoError(t, err)
   193  			tt.want(t, gotA, gotB)
   194  		})
   195  	}
   196  }