github.com/abemedia/appcast@v0.4.0/integrations/apk/build_test.go (about)

     1  package apk_test
     2  
     3  import (
     4  	"context"
     5  	"io"
     6  	"io/fs"
     7  	"os"
     8  	"path/filepath"
     9  	"testing"
    10  
    11  	"github.com/abemedia/appcast/integrations/apk"
    12  	"github.com/abemedia/appcast/internal/test"
    13  	"github.com/abemedia/appcast/pkg/crypto/rsa"
    14  	source "github.com/abemedia/appcast/source/file"
    15  	target "github.com/abemedia/appcast/target/file"
    16  	"github.com/google/go-cmp/cmp"
    17  	"gitlab.alpinelinux.org/alpine/go/repository"
    18  )
    19  
    20  func TestBuild(t *testing.T) {
    21  	want := readTestData(t)
    22  
    23  	dir := t.TempDir() + "/rpm"
    24  	src, _ := source.New(source.Config{Path: "../../testdata"})
    25  	tgt, _ := target.New(target.Config{Path: dir})
    26  
    27  	test.Golden(t, "testdata", dir)
    28  
    29  	c := &apk.Config{
    30  		Source: src,
    31  		Target: tgt,
    32  	}
    33  
    34  	t.Run("New", func(t *testing.T) {
    35  		testBuild(t, c, want)
    36  	})
    37  
    38  	t.Run("NoChange", func(t *testing.T) {
    39  		testBuild(t, c, want)
    40  	})
    41  
    42  	t.Run("RSA", func(t *testing.T) {
    43  		rsaKey, _ := rsa.NewPrivateKey()
    44  		dir := t.TempDir()
    45  		tgt, _ := target.New(target.Config{Path: dir})
    46  
    47  		c := &apk.Config{
    48  			Source:  src,
    49  			Target:  tgt,
    50  			RSAKey:  rsaKey,
    51  			KeyName: "test.rsa.pub",
    52  		}
    53  
    54  		err := apk.Build(context.Background(), c)
    55  		if err != nil {
    56  			t.Fatal(err)
    57  		}
    58  
    59  		pubBytes, _ := os.ReadFile(filepath.Join(dir, "test.rsa.pub"))
    60  		pub, _ := rsa.UnmarshalPublicKey(pubBytes)
    61  		if !rsaKey.PublicKey.Equal(pub) {
    62  			t.Fatal("should have public key")
    63  		}
    64  
    65  		indexFile, _ := os.Open(filepath.Join(dir, "x86_64", "APKINDEX.tar.gz"))
    66  		apkindex, _ := repository.IndexFromArchive(indexFile)
    67  		unsigedIndex, _ := repository.ArchiveFromIndex(apkindex)
    68  		indexBytes, _ := io.ReadAll(unsigedIndex)
    69  		if !rsa.Verify(pub, indexBytes, apkindex.Signature) {
    70  			t.Fatal("should pass RSA verification")
    71  		}
    72  	})
    73  }
    74  
    75  func readTestData(t *testing.T) map[string][]byte {
    76  	t.Helper()
    77  
    78  	want := make(map[string][]byte)
    79  
    80  	err := fs.WalkDir(os.DirFS("testdata"), ".", func(path string, d fs.DirEntry, err error) error {
    81  		if err != nil || d.IsDir() {
    82  			return err
    83  		}
    84  		b, err := fs.ReadFile(os.DirFS("testdata"), path)
    85  		if err != nil {
    86  			return err
    87  		}
    88  		want[path] = b
    89  		return nil
    90  	})
    91  	if err != nil {
    92  		t.Fatal(err)
    93  	}
    94  
    95  	return want
    96  }
    97  
    98  func testBuild(t *testing.T, c *apk.Config, want map[string][]byte) {
    99  	t.Helper()
   100  
   101  	err := apk.Build(context.Background(), c)
   102  	if err != nil {
   103  		t.Fatal(err)
   104  	}
   105  
   106  	for name, data := range want {
   107  		r, err := c.Target.NewReader(context.Background(), name)
   108  		if err != nil {
   109  			t.Fatal(name, err)
   110  		}
   111  		defer r.Close()
   112  
   113  		got, err := io.ReadAll(r)
   114  		if err != nil {
   115  			t.Fatal(name, err)
   116  		}
   117  
   118  		if diff := cmp.Diff(data, got); diff != "" {
   119  			t.Error(name, diff)
   120  		}
   121  	}
   122  }