github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/state/backups/legacy_test.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package backups_test
     5  
     6  import (
     7  	"archive/tar"
     8  	"bytes"
     9  	"compress/gzip"
    10  	"fmt"
    11  	"io"
    12  	"os"
    13  	"path"
    14  	"path/filepath"
    15  	"strings"
    16  
    17  	jc "github.com/juju/testing/checkers"
    18  	gc "gopkg.in/check.v1"
    19  
    20  	backupsTesting "github.com/juju/juju/state/backups/testing"
    21  	"github.com/juju/juju/testing"
    22  )
    23  
    24  type LegacySuite struct {
    25  	testing.BaseSuite
    26  }
    27  
    28  type tarContent struct {
    29  	Name   string
    30  	Body   string
    31  	Nested []tarContent
    32  }
    33  
    34  var expectedContents = map[string]string{
    35  	"TarDirectoryEmpty":                     "",
    36  	"TarDirectoryPopulated":                 "",
    37  	"TarDirectoryPopulated/TarSubFile1":     "TarSubFile1",
    38  	"TarDirectoryPopulated/TarSubDirectory": "",
    39  	"TarFile1":                              "TarFile1",
    40  	"TarFile2":                              "TarFile2",
    41  }
    42  
    43  func (s *LegacySuite) createTestFiles(c *gc.C) (string, []string, []tarContent) {
    44  	var expected []tarContent
    45  	var tempFiles []string
    46  
    47  	rootDir := c.MkDir()
    48  
    49  	for name, body := range expectedContents {
    50  		filename := filepath.Join(rootDir, filepath.FromSlash(name))
    51  
    52  		top := (path.Dir(name) == ".")
    53  
    54  		if body == "" {
    55  			err := os.MkdirAll(filename, os.FileMode(0755))
    56  			c.Check(err, jc.ErrorIsNil)
    57  		} else {
    58  			if !top {
    59  				err := os.MkdirAll(filepath.Dir(filename), os.FileMode(0755))
    60  				c.Check(err, jc.ErrorIsNil)
    61  			}
    62  			file, err := os.Create(filename)
    63  			c.Assert(err, jc.ErrorIsNil)
    64  			file.WriteString(body)
    65  			file.Close()
    66  		}
    67  
    68  		if top {
    69  			tempFiles = append(tempFiles, filename)
    70  		}
    71  		content := tarContent{filepath.ToSlash(filename), body, nil}
    72  		expected = append(expected, content)
    73  	}
    74  
    75  	return rootDir, tempFiles, expected
    76  }
    77  
    78  func readTarFile(c *gc.C, tarFile io.Reader) map[string]string {
    79  	tr := tar.NewReader(tarFile)
    80  	contents := make(map[string]string)
    81  
    82  	// Iterate through the files in the archive.
    83  	for {
    84  		hdr, err := tr.Next()
    85  		if err == io.EOF {
    86  			// end of tar archive
    87  			break
    88  		}
    89  		c.Assert(err, jc.ErrorIsNil)
    90  		buf, err := io.ReadAll(tr)
    91  		c.Assert(err, jc.ErrorIsNil)
    92  		contents[hdr.Name] = string(buf)
    93  	}
    94  
    95  	return contents
    96  }
    97  
    98  func (s *LegacySuite) checkTarContents(
    99  	c *gc.C, tarFile io.Reader, allExpected []tarContent,
   100  ) {
   101  	contents := readTarFile(c, tarFile)
   102  
   103  	// Check that the expected entries are there.
   104  	// XXX Check for unexpected entries.
   105  	for _, expected := range allExpected {
   106  		relPath := strings.TrimPrefix(expected.Name, string(os.PathSeparator))
   107  
   108  		c.Log(fmt.Sprintf("checking for presence of %q on tar file", relPath))
   109  		body, found := contents[relPath]
   110  		if !found {
   111  			c.Errorf("%q not found", expected.Name)
   112  			continue
   113  		}
   114  
   115  		if expected.Body != "" {
   116  			c.Log("Also checking the file contents")
   117  			c.Check(body, gc.Equals, expected.Body)
   118  		}
   119  
   120  		if expected.Nested != nil {
   121  			c.Log("Also checking the nested tar file")
   122  			nestedFile := bytes.NewBufferString(body)
   123  			s.checkTarContents(c, nestedFile, expected.Nested)
   124  		}
   125  	}
   126  
   127  	if c.Failed() {
   128  		c.Log("-----------------------")
   129  		c.Log("expected:")
   130  		for _, expected := range allExpected {
   131  			c.Log(fmt.Sprintf("%s -> %q", expected.Name, expected.Body))
   132  		}
   133  		c.Log("got:")
   134  		for name, body := range contents {
   135  			if len(body) > 200 {
   136  				body = body[:200] + "...(truncated)"
   137  			}
   138  			c.Log(fmt.Sprintf("%s -> %q", name, body))
   139  		}
   140  	}
   141  }
   142  
   143  func (s *LegacySuite) checkChecksum(c *gc.C, file *os.File, checksum string) {
   144  	fileShaSum := backupsTesting.SHA1SumFile(c, file)
   145  	c.Check(fileShaSum, gc.Equals, checksum)
   146  	resetFile(c, file)
   147  }
   148  
   149  func (s *LegacySuite) checkSize(c *gc.C, file *os.File, size int64) {
   150  	stat, err := file.Stat()
   151  	c.Assert(err, jc.ErrorIsNil)
   152  	c.Check(stat.Size(), gc.Equals, size)
   153  }
   154  
   155  func (s *LegacySuite) checkArchive(c *gc.C, file *os.File, bundle []tarContent) {
   156  	expected := []tarContent{
   157  		{"juju-backup", "", nil},
   158  		{"juju-backup/dump", "", nil},
   159  		{"juju-backup/root.tar", "", bundle},
   160  		{"juju-backup/metadata.json", "", nil},
   161  	}
   162  
   163  	tarFile, err := gzip.NewReader(file)
   164  	c.Assert(err, jc.ErrorIsNil)
   165  
   166  	s.checkTarContents(c, tarFile, expected)
   167  	resetFile(c, file)
   168  }
   169  
   170  func resetFile(c *gc.C, reader io.Reader) {
   171  	file, ok := reader.(*os.File)
   172  	c.Assert(ok, jc.IsTrue)
   173  	_, err := file.Seek(0, os.SEEK_SET)
   174  	c.Assert(err, jc.ErrorIsNil)
   175  }