| package actions |
| import ( |
| "context" |
| "fmt" |
| "os" |
| "path" |
| "testing" |
| |
| "cos.googlesource.com/cos/tools.git/src/pkg/dkms" |
| "cos.googlesource.com/cos/tools.git/src/pkg/fakes" |
| "cos.googlesource.com/cos/tools.git/src/pkg/fs" |
| "cos.googlesource.com/cos/tools.git/src/pkg/gcs" |
| "github.com/google/go-cmp/cmp" |
| ) |
| |
| func TestFetchKernelVersion(t *testing.T) { |
| kernelVersion, err := FetchKernelVersion() |
| if err != nil { |
| t.Fatalf("error fetching kernel version: %v", err) |
| } |
| if kernelVersion == "" { |
| t.Fatal("expected to find kernel version, found none") |
| } |
| |
| t.Setenv("KERNEL_VERSION", "abc") |
| kernelVersion, err = FetchKernelVersion() |
| if err != nil { |
| t.Fatalf("error fetching kernel version: %v", err) |
| } |
| if kernelVersion != "abc" { |
| t.Fatalf("expected kernel version to be abc, found %s", kernelVersion) |
| } |
| } |
| |
| func TestFetchKernelVersionFromHeaders(t *testing.T) { |
| kernelVersion, err := FetchKernelVersionFromHeaders("19126.0.0", "lakitu") |
| if err != nil { |
| t.Fatalf("error fetching kernel version: %v", err) |
| } |
| if kernelVersion != "6.6.94+" { |
| t.Fatalf("expected to find kernel version 6.6.94+, found %s", kernelVersion) |
| } |
| } |
| |
| func TestFetchArch(t *testing.T) { |
| arch, err := FetchArch() |
| if err != nil { |
| t.Fatalf("error fetching arch: %v", err) |
| } |
| if arch == "" { |
| t.Fatal("expected to find arch, found none") |
| } |
| |
| t.Setenv("ARCH", "abc") |
| arch, err = FetchArch() |
| if err != nil { |
| t.Fatalf("error fetching arch: %v", err) |
| } |
| if arch != "abc" { |
| t.Fatalf("expected arch to be abc, found %s", arch) |
| } |
| } |
| |
| func TestParsePackageNameAndVersion(t *testing.T) { |
| testCases := []struct { |
| name string |
| version string |
| expectedName string |
| expectedVersion string |
| okay bool |
| }{ |
| {"mymodule", "123", "mymodule", "123", true}, |
| {"mymodule/123", "", "mymodule", "123", true}, |
| {"", "", "", "", false}, |
| {"mymodule", "", "", "", false}, |
| {"", "123", "", "", false}, |
| {"mymodule/1", "3", "", "", false}, |
| {"mymodule/1/2", "", "", "", false}, |
| {"mymodule/1/2", "3", "", "", false}, |
| } |
| |
| for _, testCase := range testCases { |
| name, version, err := ParsePackageNameAndVersion(testCase.name, testCase.version) |
| if testCase.okay { |
| if err != nil { |
| t.Fatalf("unexpected error for test case %v: %v", testCase, err) |
| } |
| |
| if name != testCase.expectedName || version != testCase.expectedVersion { |
| t.Fatalf("expected name to be %s and version to be %s, found %s and %s", |
| testCase.expectedName, testCase.expectedVersion, name, version) |
| } |
| } |
| |
| if !testCase.okay && err == nil { |
| t.Fatalf("expected error for test case %v, but error was nil", testCase) |
| } |
| } |
| } |
| |
| func TestFetchLatestCompatiblePackageVersion(t *testing.T) { |
| ctx := context.Background() |
| fakeGCS := fakes.GCSForTest(t) |
| fakeGCS.LogMissing = false |
| cache := gcs.NewGCSBucket(fakeGCS.Client, "test", "dkms") |
| |
| pkg := &dkms.Package{ |
| Name: "mymodule", |
| Trees: &dkms.Trees{ |
| Source: t.TempDir(), |
| Dkms: t.TempDir(), |
| }, |
| } |
| |
| // Make sure we get errors when there are no compatible versions yet |
| version, err := FetchLatestCompatiblePackageVersion(pkg, nil) |
| if err == nil { |
| t.Fatal("expected an error when no compatible versoins are present locally") |
| } |
| |
| version, err = FetchLatestCompatiblePackageVersion(pkg, cache) |
| if err == nil { |
| t.Fatal("expected an error when no compatible versions are present locally or in cache") |
| } |
| |
| // We need to add some package before we can use --latest |
| for _, version := range []string{"0.3", "1.0", "1.5"} { |
| fs.CopyDir( |
| "testdata/source-tree/mymodule-1.0", |
| path.Join(pkg.Trees.Source, fmt.Sprintf("mymodule-%s", version)), |
| 0777, |
| ) |
| versionPackage := pkg |
| versionPackage.Version = version |
| InitPackage(versionPackage, nil, false) |
| options := &dkms.Options{Upload: true} |
| |
| if err := dkms.CachedAdd(ctx, pkg, cache, options); err != nil { |
| t.Fatal(err) |
| } |
| } |
| |
| // Check only the local versions first |
| version, err = FetchLatestCompatiblePackageVersion(pkg, nil) |
| if err != nil { |
| t.Fatal(err) |
| } |
| if version != "1.5" { |
| t.Fatalf("expected latest version to be 1.5, found %s", version) |
| } |
| |
| // Remove the local sources so we're forced to check the cache |
| for _, version := range []string{"0.3", "1.0", "1.5"} { |
| os.RemoveAll(path.Join(pkg.Trees.Source, fmt.Sprintf("mymodule-%s", version))) |
| } |
| |
| version, err = FetchLatestCompatiblePackageVersion(pkg, nil) |
| if err == nil { |
| t.Fatal("did not expect to find sources locally; check that remove is working") |
| } |
| |
| // Check the cached versions |
| version, err = FetchLatestCompatiblePackageVersion(pkg, cache) |
| if err != nil { |
| t.Fatal(err) |
| } |
| if version != "1.5" { |
| t.Fatalf("expected latest version to be 1.5, found %s", version) |
| } |
| } |
| |
| func TestInitPackage(t *testing.T) { |
| // Make sure unset keys get loaded from environment |
| t.Setenv("BUILD_ID", "test-build-id") |
| t.Setenv("BOARD", "test-board") |
| t.Setenv("KERNEL_VERSION", "test-kernel-version") |
| t.Setenv("ARCH", "test-arch") |
| pkg := &dkms.Package{Name: "mymodule/1.0", Trees: &dkms.Trees{}} |
| expectedTrees := &dkms.Trees{ |
| Source: "/usr/src", |
| Dkms: "", |
| Install: "/lib/modules/test-kernel-version", |
| Kernel: "/lib/modules/test-kernel-version/build", |
| KernelModules: "/lib/modules/test-kernel-version", |
| } |
| expectedPackage := &dkms.Package{ |
| Name: "mymodule", |
| Version: "1.0", |
| BuildId: "test-build-id", |
| Board: "test-board", |
| KernelVersion: "test-kernel-version", |
| Arch: "test-arch", |
| Trees: expectedTrees, |
| } |
| InitCOSValues(pkg, "testdata/lsb-release") |
| if err := InitPackage(pkg, nil, false); err != nil { |
| t.Fatal(err) |
| } |
| if diff := cmp.Diff(expectedPackage, pkg); diff != "" { |
| t.Fatalf("package differed from expected: %s", diff) |
| } |
| |
| // Make sure that initPackage is a no-op for a package which is already |
| // initialized |
| expectedPackageCopy := expectedPackage |
| expectedTreesCopy := expectedTrees |
| expectedPackageCopy.Trees = expectedTreesCopy |
| if err := InitPackage(expectedPackageCopy, nil, false); err != nil { |
| t.Fatal(err) |
| } |
| if diff := cmp.Diff(expectedPackage, expectedPackageCopy); diff != "" { |
| t.Fatalf("package differed from expected: %s", diff) |
| } |
| } |
| |
| func TestInitCOSValues(t *testing.T) { |
| // Make sure BuildId and Board get loaded from lsb-release |
| pkg := &dkms.Package{} |
| expectedPackage := &dkms.Package{ |
| BuildId: "18808.0.0", |
| Board: "lakitu", |
| } |
| InitCOSValues(pkg, "testdata/lsb-release") |
| |
| if diff := cmp.Diff(expectedPackage, pkg); diff != "" { |
| t.Fatalf("package differed from expected: %s", diff) |
| } |
| |
| // Make sure that env variables can override the lsb-release values |
| t.Setenv("BUILD_ID", "test-env-build-id") |
| t.Setenv("BOARD", "test-env-board") |
| pkg = &dkms.Package{} |
| expectedPackage = &dkms.Package{ |
| BuildId: "test-env-build-id", |
| Board: "test-env-board", |
| } |
| InitCOSValues(pkg, "") |
| |
| if diff := cmp.Diff(expectedPackage, pkg); diff != "" { |
| t.Fatalf("package differed from expected: %s", diff) |
| } |
| } |
| |
| func TestInitPackageLatest(t *testing.T) { |
| pkg := &dkms.Package{ |
| Name: "mymodule", |
| Version: "1.0", |
| Trees: &dkms.Trees{ |
| Source: "testdata/source-tree", |
| Dkms: t.TempDir(), |
| }, |
| } |
| |
| // We need to add a package before we can use --latest |
| InitPackage(pkg, nil, false) |
| if err := dkms.Add(pkg, &dkms.Options{}); err != nil { |
| t.Fatal(err) |
| } |
| |
| latestPackage := pkg |
| latestPackage.Version = "" |
| if err := InitPackage(latestPackage, nil, true); err != nil { |
| t.Fatal(err) |
| } |
| if diff := cmp.Diff(pkg, latestPackage); diff != "" { |
| t.Fatalf("package differed from expected: %s", diff) |
| } |
| |
| // Make sure that latest and an explicit version are mutually exclusive |
| if err := InitPackage(pkg, nil, true); err == nil { |
| t.Fatal("expected error when using --latest and explicit version") |
| } |
| |
| pkg.Version = "123" |
| if err := InitPackage(pkg, nil, true); err == nil { |
| t.Fatal("expected error when using --latest and explicit version") |
| } |
| |
| pkg.Version = "" |
| pkg.Name = "mymodule/1.0" |
| if err := InitPackage(pkg, nil, true); err == nil { |
| t.Fatal("expected error when using --latest and explicit version") |
| } |
| } |
| |
| func TestInitPackageLatestCache(t *testing.T) { |
| ctx := context.Background() |
| fakeGCS := fakes.GCSForTest(t) |
| fakeGCS.LogMissing = false |
| cache := gcs.NewGCSBucket(fakeGCS.Client, "test", "dkms") |
| |
| pkg := &dkms.Package{ |
| Name: "mymodule", |
| Version: "1.0", |
| Trees: &dkms.Trees{ |
| Source: "testdata/source-tree", |
| Dkms: t.TempDir(), |
| }, |
| } |
| |
| // We need to add a package before we can use --latest |
| InitPackage(pkg, nil, false) |
| options := &dkms.Options{Upload: true} |
| |
| if err := dkms.CachedAdd(ctx, pkg, cache, options); err != nil { |
| t.Fatal(err) |
| } |
| |
| // Remove the local sources so we're forced to check the cache |
| if err := dkms.Remove(pkg); err != nil { |
| t.Fatal(err) |
| } |
| |
| latestPackage := pkg |
| latestPackage.Version = "" |
| if err := InitPackage(latestPackage, cache, true); err != nil { |
| t.Fatal(err) |
| } |
| if diff := cmp.Diff(pkg, latestPackage); diff != "" { |
| t.Fatalf("package differed from expected: %s", diff) |
| } |
| } |
| |
| func TestInitCache(t *testing.T) { |
| testCases := []struct { |
| gcsPath string |
| buildId string |
| board string |
| expectedUri string |
| }{ |
| {"gs://mybucket", "", "", "gs://mybucket/obj"}, |
| {"gs://mybucket/abc", "", "", "gs://mybucket/abc/obj"}, |
| {"gs://mybucket/abc/def", "", "", "gs://mybucket/abc/def/obj"}, |
| {"cos-default", "18808.0.0", "lakitu", "gs://cos-tools/18808.0.0/lakitu/obj"}, |
| } |
| |
| for _, testCase := range testCases { |
| cache, err := InitCache(testCase.gcsPath, testCase.buildId, testCase.board) |
| if err != nil { |
| t.Fatalf("unexpected error for test case %v: %v", testCase, err) |
| } |
| |
| if cache.URI("obj") != testCase.expectedUri { |
| t.Fatalf("expected obj URI to be %s, found %s", testCase.expectedUri, cache.URI("obj")) |
| } |
| } |
| } |
| |
| func TestParsePositionalArgs(t *testing.T) { |
| testCases := []struct { |
| args []string |
| pkg *dkms.Package |
| expectedPackage *dkms.Package |
| okay bool |
| }{ |
| { |
| []string{"mymodule"}, |
| &dkms.Package{Trees: &dkms.Trees{}}, |
| &dkms.Package{Name: "mymodule", Trees: &dkms.Trees{}}, |
| true, |
| }, |
| { |
| []string{"mymodule"}, |
| &dkms.Package{Trees: &dkms.Trees{}}, |
| &dkms.Package{Name: "mymodule", Trees: &dkms.Trees{}}, |
| true, |
| }, |
| { |
| []string{"mymodule/1.0"}, |
| &dkms.Package{Trees: &dkms.Trees{}}, |
| &dkms.Package{Name: "mymodule/1.0", Trees: &dkms.Trees{}}, |
| true, |
| }, |
| { |
| []string{"mymodule/1.0", "source-tree"}, |
| &dkms.Package{Trees: &dkms.Trees{}}, |
| &dkms.Package{Name: "mymodule/1.0", Trees: &dkms.Trees{Source: "source-tree"}}, |
| true, |
| }, |
| { |
| []string{"mymodule"}, |
| &dkms.Package{Name: "mymodule", Trees: &dkms.Trees{}}, |
| nil, |
| false, |
| }, |
| { |
| []string{"mymodule", "1.0.1"}, |
| &dkms.Package{Name: "mymodule", Trees: &dkms.Trees{}}, |
| nil, |
| false, |
| }, |
| { |
| []string{"mymodule/1.0", "source-tree"}, |
| &dkms.Package{Trees: &dkms.Trees{Source: "source-tree"}}, |
| nil, |
| false, |
| }, |
| { |
| []string{"mymodule/1.0", "source-tree", "arg3"}, |
| &dkms.Package{Trees: &dkms.Trees{}}, |
| nil, |
| false, |
| }, |
| } |
| |
| for i, testCase := range testCases { |
| err := parsePositionalArgs(testCase.args, testCase.pkg) |
| t.Log(err) |
| if testCase.okay { |
| if err != nil { |
| t.Fatalf("unexpected error for test case %v: %v", testCase, err) |
| } |
| |
| if diff := cmp.Diff(testCase.expectedPackage, testCase.pkg); diff != "" { |
| t.Fatalf("test case %d package differed from expected: %v", i, diff) |
| } |
| } |
| |
| if !testCase.okay && err == nil { |
| t.Fatalf("expected error for test case %v, but error was nil", testCase) |
| } |
| } |
| } |