github.com/aws/aws-lambda-go@v1.47.0/cmd/build-lambda-zip/main_test.go (about) 1 // Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved 2 3 package main 4 5 import ( 6 "archive/zip" 7 "fmt" 8 "io/ioutil" //nolint: staticcheck 9 "os" 10 "os/exec" 11 "path" 12 "path/filepath" 13 "testing" 14 15 "github.com/stretchr/testify/assert" 16 "github.com/stretchr/testify/require" 17 ) 18 19 func TestSizes(t *testing.T) { 20 if testing.Short() { 21 t.Skip() 22 return 23 } 24 t.Log("test how different arguments affect binary and archive sizes") 25 cases := []struct { 26 file string 27 args []string 28 }{ 29 {"testdata/apigw.go", nil}, 30 {"testdata/noop.go", nil}, 31 {"testdata/noop.go", []string{"-tags", "lambda.norpc"}}, 32 {"testdata/noop.go", []string{"-ldflags=-s -w"}}, 33 {"testdata/noop.go", []string{"-tags", "lambda.norpc", "-ldflags=-s -w"}}, 34 } 35 testDir, err := os.Getwd() 36 require.NoError(t, err) 37 tempDir, err := ioutil.TempDir("/tmp", "build-lambda-zip") 38 require.NoError(t, err) 39 for _, test := range cases { 40 require.NoError(t, os.Chdir(testDir)) 41 testName := fmt.Sprintf("%s, %v", test.file, test.args) 42 t.Run(testName, func(t *testing.T) { 43 binPath := path.Join(tempDir, test.file+".bin") 44 zipPath := path.Join(tempDir, test.file+".zip") 45 46 buildArgs := []string{"build", "-o", binPath} 47 buildArgs = append(buildArgs, test.args...) 48 buildArgs = append(buildArgs, test.file) 49 50 gocmd := exec.Command("go", buildArgs...) 51 gocmd.Env = append(os.Environ(), "GOOS=linux") 52 gocmd.Stderr = os.Stderr 53 require.NoError(t, gocmd.Run()) 54 require.NoError(t, os.Chdir(filepath.Dir(binPath))) 55 require.NoError(t, compressExeAndArgs(zipPath, binPath, []string{})) 56 57 binInfo, err := os.Stat(binPath) 58 require.NoError(t, err) 59 zipInfo, err := os.Stat(zipPath) 60 require.NoError(t, err) 61 62 t.Logf("zip size = %d Kb, bin size = %d Kb", zipInfo.Size()/1024, binInfo.Size()/1024) 63 }) 64 } 65 66 } 67 68 func TestCompressExeAndArgs(t *testing.T) { 69 tempDir, err := ioutil.TempDir("/tmp", "build-lambda-zip") 70 require.NoError(t, err) 71 defer os.RemoveAll(tempDir) 72 73 fileNames := []string{"the-exe", "the-config", "other-config"} 74 filePaths := make([]string, len(fileNames)) 75 for i, fileName := range fileNames { 76 filePaths[i] = filepath.Join(tempDir, fileName) 77 f, err := os.Create(filePaths[i]) 78 require.NoError(t, err) 79 _, _ = fmt.Fprintf(f, "Hello file %d!", i) 80 err = f.Close() 81 require.NoError(t, err) 82 } 83 outZipPath := filepath.Join(tempDir, "lambda.zip") 84 85 err = compressExeAndArgs(outZipPath, filePaths[0], filePaths[1:]) 86 require.NoError(t, err) 87 88 t.Run("handler exe configured in zip root", func(t *testing.T) { 89 require.NotEqual(t, filePaths[0], filepath.Base(filePaths[0]), "test precondition") 90 zipReader, err := zip.OpenReader(outZipPath) 91 require.NoError(t, err) 92 defer zipReader.Close() 93 for _, zf := range zipReader.File { 94 if zf.Name == filepath.Base(filePaths[0]) { 95 assert.True(t, zf.FileInfo().Mode().IsRegular()) 96 permissions := int(zf.FileInfo().Mode() & 0777) 97 assert.Equal(t, 0111, permissions&0111, "file permissions: %#o, aren't executable", permissions) 98 assert.Equal(t, 0444, permissions&0444, "file permissions: %#o, aren't readable", permissions) 99 return 100 } 101 } 102 t.Fatalf("failed to find handler exe in zip") 103 }) 104 105 t.Run("boostrap is a symlink to handler exe", func(t *testing.T) { 106 zipReader, err := zip.OpenReader(outZipPath) 107 require.NoError(t, err) 108 defer zipReader.Close() 109 var bootstrap *zip.File 110 for _, f := range zipReader.File { 111 if f.Name == "bootstrap" { 112 bootstrap = f 113 } 114 } 115 require.NotNil(t, bootstrap) 116 assert.Equal(t, 0755|os.ModeSymlink, bootstrap.FileInfo().Mode()) 117 link, err := bootstrap.Open() 118 require.NoError(t, err) 119 defer link.Close() 120 linkTarget, err := ioutil.ReadAll(link) 121 require.NoError(t, err) 122 assert.Equal(t, filepath.Base(filePaths[0]), string(linkTarget)) 123 }) 124 125 t.Run("resource file paths", func(t *testing.T) { 126 zipReader, err := zip.OpenReader(outZipPath) 127 require.NoError(t, err) 128 defer zipReader.Close() 129 eachFile: 130 for _, path := range filePaths[1:] { 131 for _, zipFileEntry := range zipReader.File { 132 if zipFileEntry.Name == path { 133 continue eachFile 134 } 135 } 136 t.Logf("failed to find resource file %s in zip", path) 137 t.Fail() 138 } 139 }) 140 141 t.Run("file contents match", func(t *testing.T) { 142 zipReader, err := zip.OpenReader(outZipPath) 143 require.NoError(t, err) 144 defer zipReader.Close() 145 expectedIndex := 0 146 for _, zf := range zipReader.File { 147 if zf.FileInfo().Mode().IsRegular() { 148 f, err := zf.Open() 149 require.NoError(t, err) 150 defer f.Close() 151 content, err := ioutil.ReadAll(f) 152 require.NoError(t, err) 153 assert.Equal(t, fmt.Sprintf("Hello file %d!", expectedIndex), string(content), "in file: %s", zf.Name) 154 expectedIndex++ 155 } 156 } 157 }) 158 159 }