Source file src/cmd/go/internal/modfetch/fetch_test.go

     1  // Copyright 2026 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build !js && !wasip1
     6  
     7  package modfetch
     8  
     9  import (
    10  	"errors"
    11  	"io/fs"
    12  	"os"
    13  	"path/filepath"
    14  	"testing"
    15  
    16  	"golang.org/x/mod/module"
    17  	"golang.org/x/mod/sumdb/dirhash"
    18  	modzip "golang.org/x/mod/zip"
    19  )
    20  
    21  func TestUnzipVerify(t *testing.T) {
    22  	var (
    23  		ctx = t.Context()
    24  		src = t.TempDir()
    25  		mod = module.Version{Path: "example.com/unzip", Version: "v1.0.0"}
    26  	)
    27  	if err := os.WriteFile(filepath.Join(src, "go.mod"), []byte("module example.com/unzip\n"), 0o666); err != nil {
    28  		t.Fatal(err)
    29  	}
    30  
    31  	zipfile := filepath.Join(t.TempDir(), "v1.0.0.zip")
    32  	zf, err := os.Create(zipfile)
    33  	if err != nil {
    34  		t.Fatal(err)
    35  	}
    36  	if err := modzip.CreateFromDir(zf, mod, src); err != nil {
    37  		t.Fatal(err)
    38  	}
    39  	if err := zf.Close(); err != nil {
    40  		t.Fatal(err)
    41  	}
    42  	ziphash, err := dirhash.HashZip(zipfile, dirhash.DefaultHash)
    43  	if err != nil {
    44  		t.Fatal(err)
    45  	}
    46  
    47  	unzip := func(verify func() error) (string, error) {
    48  		dir, err := NewFetcher().Unzip(ctx, mod, zipfile, ziphash, verify)
    49  		if dir != "" {
    50  			t.Cleanup(func() { RemoveAll(dir) })
    51  		}
    52  		return dir, err
    53  	}
    54  
    55  	var (
    56  		errVerify      = errors.New("verify failed")
    57  		verifyFnFails  = func() error { return errVerify }
    58  		verifyFnPasses = func() error { return nil }
    59  	)
    60  	if _, err := unzip(verifyFnFails); !errors.Is(err, errVerify) {
    61  		t.Fatalf("unzip with empty cache: got %v, want %v", err, errVerify)
    62  	}
    63  	if _, err := DownloadDir(ctx, mod); !errors.Is(err, fs.ErrNotExist) {
    64  		t.Fatalf("DownloadDir after failed verify: got %v, want %v", err, fs.ErrNotExist)
    65  	}
    66  
    67  	if _, err := unzip(verifyFnPasses); err != nil {
    68  		t.Fatal(err)
    69  	}
    70  	if _, err := DownloadDir(ctx, mod); err != nil {
    71  		t.Fatal(err)
    72  	}
    73  	if ok, err := haveZipHash(ctx, mod, ziphash); err != nil || !ok {
    74  		t.Fatalf("haveZipHash = (%v, %v), want (true, nil)", ok, err)
    75  	}
    76  
    77  	if _, err := unzip(verifyFnFails); err != nil {
    78  		t.Fatalf("unzip with cached copy: got %v, want nil", err)
    79  	}
    80  
    81  	if err := writeZipHash(ctx, mod, "h1:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="); err != nil {
    82  		t.Fatal(err)
    83  	}
    84  	if _, err := unzip(verifyFnFails); !errors.Is(err, errVerify) {
    85  		t.Fatalf("unzip with mismatched ziphash: got %v, want %v", err, errVerify)
    86  	}
    87  	if _, err := DownloadDir(ctx, mod); err != nil {
    88  		t.Fatal(err)
    89  	}
    90  
    91  	if _, err := unzip(verifyFnPasses); err != nil {
    92  		t.Fatal(err)
    93  	}
    94  	if _, err := DownloadDir(ctx, mod); err != nil {
    95  		t.Fatal(err)
    96  	}
    97  
    98  	if ok, err := haveZipHash(ctx, mod, ziphash); err != nil || !ok {
    99  		t.Errorf("haveZipHash after re-unpack: got (%v, %v), want (true, nil)", ok, err)
   100  	}
   101  }
   102  

View as plain text