...

Source file src/sigs.k8s.io/release-utils/tar/tar_test.go

Documentation: sigs.k8s.io/release-utils/tar

     1  /*
     2  Copyright 2020 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package tar
    18  
    19  import (
    20  	"archive/tar"
    21  	"io"
    22  	"os"
    23  	"path/filepath"
    24  	"regexp"
    25  	"testing"
    26  
    27  	"github.com/sirupsen/logrus"
    28  	"github.com/stretchr/testify/require"
    29  )
    30  
    31  func TestCompress(t *testing.T) {
    32  	baseTmpDir, err := os.MkdirTemp("", "compress-")
    33  	require.Nil(t, err)
    34  	defer os.RemoveAll(baseTmpDir)
    35  
    36  	for _, fileName := range []string{
    37  		"1.txt", "2.bin", "3.md",
    38  	} {
    39  		require.Nil(t, os.WriteFile(
    40  			filepath.Join(baseTmpDir, fileName),
    41  			[]byte{1, 2, 3},
    42  			os.FileMode(0o644),
    43  		))
    44  	}
    45  
    46  	subTmpDir := filepath.Join(baseTmpDir, "sub")
    47  	require.Nil(t, os.MkdirAll(subTmpDir, os.FileMode(0o755)))
    48  
    49  	for _, fileName := range []string{
    50  		"4.txt", "5.bin", "6.md",
    51  	} {
    52  		require.Nil(t, os.WriteFile(
    53  			filepath.Join(subTmpDir, fileName),
    54  			[]byte{4, 5, 6},
    55  			os.FileMode(0o644),
    56  		))
    57  	}
    58  
    59  	logrus.SetLevel(logrus.DebugLevel)
    60  
    61  	require.Nil(t, os.Symlink(
    62  		filepath.Join(baseTmpDir, "1.txt"),
    63  		filepath.Join(subTmpDir, "link"),
    64  	))
    65  
    66  	excludes := []*regexp.Regexp{
    67  		regexp.MustCompile(".md"),
    68  		regexp.MustCompile("5"),
    69  	}
    70  
    71  	tarFilePath := filepath.Join(baseTmpDir, "res.tar.gz")
    72  	require.Nil(t, Compress(tarFilePath, baseTmpDir, excludes...))
    73  	require.FileExists(t, tarFilePath)
    74  
    75  	res := []string{"1.txt", "2.bin", "sub/4.txt", "sub/link"}
    76  	require.Nil(t, iterateTarball(
    77  		tarFilePath, func(_ *tar.Reader, header *tar.Header) (bool, error) {
    78  			require.Equal(t, res[0], header.Name)
    79  			res = res[1:]
    80  			return false, nil
    81  		}),
    82  	)
    83  }
    84  
    85  func TestCompressWithoutPreservingPath(t *testing.T) {
    86  	baseTmpDir, err := os.MkdirTemp("", "compress-")
    87  	require.Nil(t, err)
    88  	defer os.RemoveAll(baseTmpDir)
    89  
    90  	compressDir := filepath.Join(baseTmpDir, "to_compress")
    91  	require.Nil(t, os.MkdirAll(compressDir, os.FileMode(0o755)))
    92  
    93  	for _, fileName := range []string{
    94  		"1.txt", "2.bin", "3.md",
    95  	} {
    96  		require.Nil(t, os.WriteFile(
    97  			filepath.Join(compressDir, fileName),
    98  			[]byte{1, 2, 3},
    99  			os.FileMode(0o644),
   100  		))
   101  	}
   102  
   103  	logrus.SetLevel(logrus.DebugLevel)
   104  
   105  	tarFilePath := filepath.Join(baseTmpDir, "res.tar.gz")
   106  	require.Nil(t, CompressWithoutPreservingPath(tarFilePath, compressDir))
   107  	require.FileExists(t, tarFilePath)
   108  
   109  	res := []string{"1.txt", "2.bin", "3.md"}
   110  	require.Nil(t, iterateTarball(
   111  		tarFilePath, func(_ *tar.Reader, header *tar.Header) (bool, error) {
   112  			require.Equal(t, res[0], header.Name)
   113  			res = res[1:]
   114  			return false, nil
   115  		}),
   116  	)
   117  }
   118  
   119  func TestExtract(t *testing.T) {
   120  	tarball := []byte{
   121  		0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xec, 0xd7,
   122  		0xdf, 0xea, 0x82, 0x30, 0x14, 0xc0, 0xf1, 0xfd, 0xfe, 0xd4, 0x73, 0xf4,
   123  		0x02, 0xb9, 0xb3, 0x9d, 0xb9, 0xd9, 0xe3, 0xa8, 0x08, 0x49, 0x69, 0xe2,
   124  		0x26, 0xf4, 0xf8, 0x31, 0x93, 0x2e, 0xba, 0x10, 0x8a, 0xe6, 0x08, 0xcf,
   125  		0xe7, 0x66, 0x0c, 0xc4, 0x1d, 0x2f, 0xbe, 0x30, 0x45, 0xe2, 0xae, 0x8e,
   126  		0x85, 0x05, 0x00, 0xa0, 0x95, 0xf2, 0xab, 0x30, 0x29, 0x8c, 0x7b, 0x71,
   127  		0xdf, 0x4f, 0x90, 0x09, 0x34, 0x29, 0x00, 0x48, 0xd4, 0x9a, 0x81, 0x90,
   128  		0x0a, 0x91, 0xed, 0x20, 0xf0, 0x5c, 0xa3, 0xc1, 0xba, 0xbc, 0x67, 0x00,
   129  		0x36, 0xb7, 0xe5, 0x31, 0x9f, 0x7b, 0xae, 0xea, 0xed, 0xcc, 0x7b, 0xa6,
   130  		0x2f, 0x79, 0xac, 0x5f, 0xe2, 0xe7, 0xf7, 0x2f, 0xf6, 0x08, 0x24, 0x22,
   131  		0x99, 0x14, 0x75, 0x1b, 0xf8, 0x8c, 0x37, 0xfa, 0x47, 0x9d, 0x52, 0xff,
   132  		0x4b, 0xa0, 0xfe, 0xd7, 0xcd, 0x0e, 0x05, 0x57, 0x81, 0xef, 0x00, 0xaf,
   133  		0xf7, 0x8f, 0x52, 0x1a, 0xea, 0x7f, 0x09, 0xff, 0x9b, 0x6d, 0xec, 0x11,
   134  		0x48, 0x44, 0xbe, 0xff, 0x73, 0xdd, 0x9e, 0x42, 0x9e, 0xe1, 0x7b, 0x30,
   135  		0xc6, 0xcc, 0xf4, 0x0f, 0x4f, 0xfd, 0x1b, 0xed, 0xef, 0xff, 0x92, 0xbb,
   136  		0xa6, 0xe3, 0xe5, 0xa5, 0xe9, 0xfa, 0xca, 0xda, 0xfd, 0x01, 0x33, 0x25,
   137  		0x54, 0x86, 0x8a, 0x7f, 0xf2, 0xa7, 0x65, 0xe5, 0xfd, 0x13, 0x42, 0xd6,
   138  		0xeb, 0x16, 0x00, 0x00, 0xff, 0xff, 0xe9, 0xde, 0xbe, 0xdf, 0x00, 0x12,
   139  		0x00, 0x00,
   140  	}
   141  	file, err := os.CreateTemp("", "tarball")
   142  	require.Nil(t, err)
   143  	defer os.Remove(file.Name())
   144  	_, err = file.Write(tarball)
   145  	require.Nil(t, err)
   146  
   147  	baseTmpDir, err := os.MkdirTemp("", "extract-")
   148  	require.Nil(t, err)
   149  	require.Nil(t, os.RemoveAll(baseTmpDir))
   150  	defer os.RemoveAll(baseTmpDir)
   151  
   152  	require.Nil(t, Extract(file.Name(), baseTmpDir))
   153  	res := []string{
   154  		filepath.Base(baseTmpDir),
   155  		"1.txt",
   156  		"2.bin",
   157  		"sub",
   158  		"4.txt",
   159  		"link",
   160  	}
   161  	require.Nil(t, filepath.Walk(
   162  		baseTmpDir,
   163  		func(filePath string, fileInfo os.FileInfo, err error) error {
   164  			require.Equal(t, res[0], fileInfo.Name())
   165  			if res[0] == "link" {
   166  				require.True(t, fileInfo.Mode()&os.ModeSymlink == os.ModeSymlink)
   167  			}
   168  			res = res[1:]
   169  			return nil
   170  		},
   171  	))
   172  }
   173  
   174  func TestReadFileFromGzippedTar(t *testing.T) {
   175  	baseTmpDir, err := os.MkdirTemp("", "tar-read-file-")
   176  	require.Nil(t, err)
   177  	defer os.RemoveAll(baseTmpDir)
   178  
   179  	const (
   180  		testFilePath     = "test.txt"
   181  		testFileContents = "test-file-contents"
   182  	)
   183  	testTarPath := filepath.Join(baseTmpDir, "test.tar.gz")
   184  
   185  	require.Nil(t, os.WriteFile(
   186  		filepath.Join(baseTmpDir, testFilePath),
   187  		[]byte(testFileContents),
   188  		os.FileMode(0o644),
   189  	))
   190  	require.Nil(t, Compress(testTarPath, baseTmpDir, nil))
   191  
   192  	type args struct {
   193  		tarPath  string
   194  		filePath string
   195  	}
   196  	type want struct {
   197  		fileContents string
   198  		shouldErr    bool
   199  	}
   200  	cases := map[string]struct {
   201  		args args
   202  		want want
   203  	}{
   204  		"FoundFileInTar": {
   205  			args: args{
   206  				tarPath:  testTarPath,
   207  				filePath: testFilePath,
   208  			},
   209  			want: want{fileContents: testFileContents},
   210  		},
   211  		"FileNotInTar": {
   212  			args: args{
   213  				tarPath:  testTarPath,
   214  				filePath: "badfile.txt",
   215  			},
   216  			want: want{shouldErr: true},
   217  		},
   218  	}
   219  
   220  	for name, tc := range cases {
   221  		t.Run(name, func(t *testing.T) {
   222  			r, err := ReadFileFromGzippedTar(tc.args.tarPath, tc.args.filePath)
   223  			if tc.want.shouldErr {
   224  				require.Nil(t, r)
   225  				require.NotNil(t, err)
   226  			} else {
   227  				file, err := io.ReadAll(r)
   228  				require.Nil(t, err)
   229  				require.Equal(t, tc.want.fileContents, string(file))
   230  			}
   231  		})
   232  	}
   233  }
   234  

View as plain text