...

Source file src/k8s.io/kubernetes/test/conformance/image/go-runner/tar_test.go

Documentation: k8s.io/kubernetes/test/conformance/image/go-runner

     1  /*
     2  Copyright 2019 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 main
    18  
    19  import (
    20  	"archive/tar"
    21  	"compress/gzip"
    22  	"fmt"
    23  	"io"
    24  	"os"
    25  	"path/filepath"
    26  	"reflect"
    27  	"strings"
    28  	"testing"
    29  )
    30  
    31  func TestTar(t *testing.T) {
    32  	tmp, err := os.MkdirTemp("", "testtar")
    33  	if err != nil {
    34  		t.Fatal(err)
    35  	}
    36  	defer os.RemoveAll(tmp)
    37  
    38  	if err := os.Mkdir(filepath.Join(tmp, "subdir"), os.FileMode(0755)); err != nil {
    39  		t.Fatal(err)
    40  	}
    41  	if err := os.WriteFile(filepath.Join(tmp, "file1"), []byte(`file1 data`), os.FileMode(0644)); err != nil {
    42  		t.Fatal(err)
    43  	}
    44  	if err := os.WriteFile(filepath.Join(tmp, "file2"), []byte(`file2 data`), os.FileMode(0644)); err != nil {
    45  		t.Fatal(err)
    46  	}
    47  	if err := os.WriteFile(filepath.Join(tmp, "subdir", "file4"), []byte(`file4 data`), os.FileMode(0644)); err != nil {
    48  		t.Fatal(err)
    49  	}
    50  
    51  	testCases := []struct {
    52  		desc      string
    53  		dir       string
    54  		outpath   string
    55  		expectErr string
    56  		expect    map[string]string
    57  	}{
    58  		{
    59  			desc:    "Contents preserved and no self-reference",
    60  			dir:     tmp,
    61  			outpath: filepath.Join(tmp, "out.tar.gz"),
    62  			expect: map[string]string{
    63  				"file1":        "file1 data",
    64  				"file2":        "file2 data",
    65  				"subdir/file4": "file4 data",
    66  			},
    67  		}, {
    68  			desc:      "Errors if directory does not exist",
    69  			dir:       filepath.Join(tmp, "does-not-exist"),
    70  			outpath:   filepath.Join(tmp, "out.tar.gz"),
    71  			expectErr: "tar unable to stat directory",
    72  		},
    73  	}
    74  	for _, tc := range testCases {
    75  		t.Run(tc.desc, func(t *testing.T) {
    76  			err := tarDir(tc.dir, tc.outpath)
    77  			if err == nil {
    78  				defer os.Remove(tc.outpath)
    79  			}
    80  
    81  			switch {
    82  			case err != nil && len(tc.expectErr) == 0:
    83  				t.Fatalf("Expected nil error but got %q", err)
    84  			case err != nil && len(tc.expectErr) > 0:
    85  				if !strings.Contains(fmt.Sprint(err), tc.expectErr) {
    86  					t.Errorf("Expected error \n\t%q\nbut got\n\t%q", tc.expectErr, err)
    87  				}
    88  				return
    89  			case err == nil && len(tc.expectErr) > 0:
    90  				t.Fatalf("Expected error %q but got nil", tc.expectErr)
    91  			default:
    92  				// No error
    93  			}
    94  
    95  			data, err := readAllTar(tc.outpath)
    96  			if err != nil {
    97  				t.Fatalf("Failed to read tarball: %v", err)
    98  			}
    99  
   100  			if !reflect.DeepEqual(data, tc.expect) {
   101  				t.Errorf("Expected data %v but got %v", tc.expect, data)
   102  			}
   103  		})
   104  	}
   105  }
   106  
   107  // readAllTar walks all of the files in the archive. It returns a map
   108  // of filenames and their contents and any error encountered.
   109  func readAllTar(tarPath string) (map[string]string, error) {
   110  	tarPath, err := filepath.Abs(tarPath)
   111  	if err != nil {
   112  		return nil, err
   113  	}
   114  
   115  	fileReader, err := os.Open(tarPath)
   116  	if err != nil {
   117  		return nil, err
   118  	}
   119  	defer fileReader.Close()
   120  
   121  	gzStream, err := gzip.NewReader(fileReader)
   122  	if err != nil {
   123  		return nil, fmt.Errorf("couldn't uncompress reader: %w", err)
   124  	}
   125  	defer gzStream.Close()
   126  
   127  	// Open and iterate through the files in the archive.
   128  	tr := tar.NewReader(gzStream)
   129  	fileData := map[string]string{}
   130  	for {
   131  		hdr, err := tr.Next()
   132  		if err == io.EOF {
   133  			break // End of archive
   134  		}
   135  		if err != nil {
   136  
   137  			return nil, err
   138  		}
   139  
   140  		b, err := io.ReadAll(tr)
   141  		if err != nil {
   142  			return nil, err
   143  		}
   144  		fileData[filepath.ToSlash(hdr.Name)] = string(b)
   145  	}
   146  	return fileData, nil
   147  }
   148  

View as plain text