From 7b289c9623d74cfa909f83f9b843964bd3b97e45 Mon Sep 17 00:00:00 2001 From: Jamie Magee Date: Fri, 15 Nov 2024 12:48:00 -0800 Subject: [PATCH] add tests Signed-off-by: Jamie Magee --- clients/azuredevopsrepo/testdata/basic.zip | Bin 0 -> 699 bytes clients/azuredevopsrepo/zip_test.go | 183 +++++++++++++++++++++ 2 files changed, 183 insertions(+) create mode 100644 clients/azuredevopsrepo/testdata/basic.zip create mode 100644 clients/azuredevopsrepo/zip_test.go diff --git a/clients/azuredevopsrepo/testdata/basic.zip b/clients/azuredevopsrepo/testdata/basic.zip new file mode 100644 index 0000000000000000000000000000000000000000..280d8545a4d49d98bdd2cab13080525b97a2464f GIT binary patch literal 699 zcmWIWW@Zs#0D%*!_kzF-D8UM(Q!Wjgs^8N>cMmjJQCiLv$Sh>Y8QhYX{Q>HyxzG5URltNy9auhTAM* z>M#u;7lYIqK-C%m)iN^KGvM-{3Q#==2tX)^6S)`^z+6TK2?mBa9X~$gUT1{L!zpBA zF~bDeSY@CdgwK)9Zpf`<{D{+RT;T{ay8&pfH;UQdP$ks@%pga$pb=&PI0BH(W_WS< sGwy(aI36>0kj>r%G#eaO$i_BQFW|r)Cai2g^$e^)cpMlT_dpy50Lv_FNdN!< literal 0 HcmV?d00001 diff --git a/clients/azuredevopsrepo/zip_test.go b/clients/azuredevopsrepo/zip_test.go new file mode 100644 index 00000000000..9e65bddd5c2 --- /dev/null +++ b/clients/azuredevopsrepo/zip_test.go @@ -0,0 +1,183 @@ +// Copyright 2024 OpenSSF Scorecard Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package azuredevopsrepo + +import ( + "errors" + "fmt" + "io" + "os" + "strings" + "sync" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" +) + +type listfileTest struct { + predicate func(string) (bool, error) + err error + outcome []string +} + +type getcontentTest struct { + err error + filename string + output []byte +} + +func isSortedString(x, y string) bool { + return x < y +} + +func setup(inputFile string) (zipHandler, error) { + tempDir, err := os.MkdirTemp("", repoDir) + if err != nil { + return zipHandler{}, fmt.Errorf("test failed to create TempDir: %w", err) + } + tempFile, err := os.CreateTemp(tempDir, repoFilename) + if err != nil { + return zipHandler{}, fmt.Errorf("test failed to create TempFile: %w", err) + } + testFile, err := os.OpenFile(inputFile, os.O_RDONLY, 0o644) + if err != nil { + return zipHandler{}, fmt.Errorf("unable to open testfile: %w", err) + } + if _, err := io.Copy(tempFile, testFile); err != nil { + return zipHandler{}, fmt.Errorf("unable to do io.Copy: %w", err) + } + zipHandler := zipHandler{ + tempDir: tempDir, + tempZipFile: tempFile.Name(), + once: new(sync.Once), + } + zipHandler.once.Do(func() { + // We don't want to run the code in zipHandler.setup(), so if we execute zipHandler.once.Do() right + // here, it won't get executed later when setup() is called. + }) + return zipHandler, nil +} + +//nolint:gocognit +func TestExtractZip(t *testing.T) { + t.Parallel() + testcases := []struct { + name string + inputFile string + listfileTests []listfileTest + getcontentTests []getcontentTest + }{ + { + name: "Basic", + inputFile: "testdata/basic.zip", + listfileTests: []listfileTest{ + { + // Returns all files in the zip. + predicate: func(string) (bool, error) { return true, nil }, + outcome: []string{"file0", "dir1/file1", "dir1/dir2/file2"}, + }, + { + // Skips all files inside `dir1/dir2` directory. + predicate: func(fn string) (bool, error) { return !strings.HasPrefix(fn, "dir1/dir2"), nil }, + outcome: []string{"file0", "dir1/file1"}, + }, + { + // Skips all files. + predicate: func(fn string) (bool, error) { return false, nil }, + outcome: []string{}, + }, + }, + getcontentTests: []getcontentTest{ + { + filename: "file0", + output: []byte("content0\n"), + }, + { + filename: "dir1/file1", + output: []byte("content1\n"), + }, + { + filename: "dir1/dir2/file2", + output: []byte("content2\n"), + }, + { + filename: "does/not/exist", + err: os.ErrNotExist, + }, + }, + }, + } + + for _, testcase := range testcases { + testcase := testcase + t.Run(testcase.name, func(t *testing.T) { + t.Parallel() + + // Setup + handler, err := setup(testcase.inputFile) + if err != nil { + t.Fatalf("test setup failed: %v", err) + } + + // Extract zip. + if err := handler.extractZip(); err != nil { + t.Fatalf("test failed: %v", err) + } + + // Test ListFiles API. + for _, listfiletest := range testcase.listfileTests { + matchedFiles, err := handler.listFiles(listfiletest.predicate) + if !errors.Is(err, listfiletest.err) { + t.Errorf("test failed: expected - %v, got - %v", listfiletest.err, err) + continue + } + if !cmp.Equal(listfiletest.outcome, + matchedFiles, + cmpopts.SortSlices(isSortedString)) { + t.Errorf("test failed: expected - %q, got - %q", listfiletest.outcome, matchedFiles) + } + } + + // Test GetFileContent API. + for _, getcontenttest := range testcase.getcontentTests { + f, err := handler.getFile(getcontenttest.filename) + if getcontenttest.err != nil && !errors.Is(err, getcontenttest.err) { + t.Errorf("test failed: expected - %v, got - %v", getcontenttest.err, err) + } + if getcontenttest.err == nil { + content, err := io.ReadAll(f) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if !cmp.Equal(getcontenttest.output, content) { + t.Errorf("test failed: expected - %s, got - %s", string(getcontenttest.output), string(content)) + } + } + } + + // Test that files get deleted. + if err := handler.cleanup(); err != nil { + t.Errorf("test failed: %v", err) + } + if _, err := os.Stat(handler.tempDir); !os.IsNotExist(err) { + t.Errorf("%v", err) + } + if len(handler.files) != 0 { + t.Error("client.files not cleaned up!") + } + }) + } +}