launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/environs/tools/testing/testing.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package testing
     5  
     6  import (
     7  	"fmt"
     8  	"io/ioutil"
     9  	"os"
    10  	"path"
    11  	"path/filepath"
    12  	"sort"
    13  	"strings"
    14  
    15  	gc "launchpad.net/gocheck"
    16  
    17  	"launchpad.net/juju-core/environs/filestorage"
    18  	"launchpad.net/juju-core/environs/simplestreams"
    19  	"launchpad.net/juju-core/environs/storage"
    20  	"launchpad.net/juju-core/environs/tools"
    21  	jc "launchpad.net/juju-core/testing/checkers"
    22  	coretools "launchpad.net/juju-core/tools"
    23  	"launchpad.net/juju-core/utils"
    24  	"launchpad.net/juju-core/utils/set"
    25  	"launchpad.net/juju-core/version"
    26  )
    27  
    28  // MakeTools creates some fake tools with the given version strings.
    29  func MakeTools(c *gc.C, metadataDir, subdir string, versionStrings []string) {
    30  	makeTools(c, metadataDir, subdir, versionStrings, false)
    31  }
    32  
    33  // MakeTools creates some fake tools (including checksums) with the given version strings.
    34  func MakeToolsWithCheckSum(c *gc.C, metadataDir, subdir string, versionStrings []string) {
    35  	makeTools(c, metadataDir, subdir, versionStrings, true)
    36  }
    37  
    38  func makeTools(c *gc.C, metadataDir, subdir string, versionStrings []string, withCheckSum bool) {
    39  	toolsDir := filepath.Join(metadataDir, storage.BaseToolsPath)
    40  	if subdir != "" {
    41  		toolsDir = filepath.Join(toolsDir, subdir)
    42  	}
    43  	c.Assert(os.MkdirAll(toolsDir, 0755), gc.IsNil)
    44  	var toolsList coretools.List
    45  	for _, versionString := range versionStrings {
    46  		binary := version.MustParseBinary(versionString)
    47  		path := filepath.Join(toolsDir, fmt.Sprintf("juju-%s.tgz", binary))
    48  		data := binary.String()
    49  		err := ioutil.WriteFile(path, []byte(data), 0644)
    50  		c.Assert(err, gc.IsNil)
    51  		tool := &coretools.Tools{
    52  			Version: binary,
    53  			URL:     path,
    54  		}
    55  		if withCheckSum {
    56  			tool.Size, tool.SHA256 = SHA256sum(c, path)
    57  		}
    58  		toolsList = append(toolsList, tool)
    59  	}
    60  	// Write the tools metadata.
    61  	stor, err := filestorage.NewFileStorageWriter(metadataDir, filestorage.UseDefaultTmpDir)
    62  	c.Assert(err, gc.IsNil)
    63  	err = tools.MergeAndWriteMetadata(stor, toolsList, false)
    64  	c.Assert(err, gc.IsNil)
    65  }
    66  
    67  // SHA256sum creates the sha256 checksum for the specified file.
    68  func SHA256sum(c *gc.C, path string) (int64, string) {
    69  	if strings.HasPrefix(path, "file://") {
    70  		path = path[len("file://"):]
    71  	}
    72  	hash, size, err := utils.ReadFileSHA256(path)
    73  	c.Assert(err, gc.IsNil)
    74  	return size, hash
    75  }
    76  
    77  // ParseMetadataFromDir loads ToolsMetadata from the specified directory.
    78  func ParseMetadataFromDir(c *gc.C, metadataDir string, expectMirrors bool) []*tools.ToolsMetadata {
    79  	stor, err := filestorage.NewFileStorageReader(metadataDir)
    80  	c.Assert(err, gc.IsNil)
    81  	return ParseMetadataFromStorage(c, stor, expectMirrors)
    82  }
    83  
    84  // ParseMetadataFromStorage loads ToolsMetadata from the specified storage reader.
    85  func ParseMetadataFromStorage(c *gc.C, stor storage.StorageReader, expectMirrors bool) []*tools.ToolsMetadata {
    86  	source := storage.NewStorageSimpleStreamsDataSource(stor, "tools")
    87  	params := simplestreams.ValueParams{
    88  		DataType:      tools.ContentDownload,
    89  		ValueTemplate: tools.ToolsMetadata{},
    90  	}
    91  
    92  	const requireSigned = false
    93  	indexPath := simplestreams.UnsignedIndex
    94  	indexRef, err := simplestreams.GetIndexWithFormat(
    95  		source, indexPath, "index:1.0", requireSigned, simplestreams.CloudSpec{}, params)
    96  	c.Assert(err, gc.IsNil)
    97  	c.Assert(indexRef.Indexes, gc.HasLen, 1)
    98  
    99  	toolsIndexMetadata := indexRef.Indexes["com.ubuntu.juju:released:tools"]
   100  	c.Assert(toolsIndexMetadata, gc.NotNil)
   101  
   102  	// Read the products file contents.
   103  	r, err := stor.Get(path.Join("tools", toolsIndexMetadata.ProductsFilePath))
   104  	defer r.Close()
   105  	c.Assert(err, gc.IsNil)
   106  	data, err := ioutil.ReadAll(r)
   107  	c.Assert(err, gc.IsNil)
   108  
   109  	url, err := source.URL(toolsIndexMetadata.ProductsFilePath)
   110  	c.Assert(err, gc.IsNil)
   111  	cloudMetadata, err := simplestreams.ParseCloudMetadata(data, "products:1.0", url, tools.ToolsMetadata{})
   112  	c.Assert(err, gc.IsNil)
   113  
   114  	toolsMetadataMap := make(map[string]*tools.ToolsMetadata)
   115  	var expectedProductIds set.Strings
   116  	var toolsVersions set.Strings
   117  	for _, mc := range cloudMetadata.Products {
   118  		for _, items := range mc.Items {
   119  			for key, item := range items.Items {
   120  				toolsMetadata := item.(*tools.ToolsMetadata)
   121  				toolsMetadataMap[key] = toolsMetadata
   122  				toolsVersions.Add(key)
   123  				seriesVersion, err := simplestreams.SeriesVersion(toolsMetadata.Release)
   124  				c.Assert(err, gc.IsNil)
   125  				productId := fmt.Sprintf("com.ubuntu.juju:%s:%s", seriesVersion, toolsMetadata.Arch)
   126  				expectedProductIds.Add(productId)
   127  			}
   128  		}
   129  	}
   130  
   131  	// Make sure index's product IDs are all represented in the products metadata.
   132  	sort.Strings(toolsIndexMetadata.ProductIds)
   133  	c.Assert(toolsIndexMetadata.ProductIds, gc.DeepEquals, expectedProductIds.SortedValues())
   134  
   135  	toolsMetadata := make([]*tools.ToolsMetadata, len(toolsMetadataMap))
   136  	for i, key := range toolsVersions.SortedValues() {
   137  		toolsMetadata[i] = toolsMetadataMap[key]
   138  	}
   139  
   140  	if expectMirrors {
   141  		r, err = stor.Get(path.Join("tools", simplestreams.UnsignedMirror))
   142  		defer r.Close()
   143  		c.Assert(err, gc.IsNil)
   144  		data, err = ioutil.ReadAll(r)
   145  		c.Assert(err, gc.IsNil)
   146  		c.Assert(string(data), jc.Contains, `"mirrors":`)
   147  		c.Assert(err, gc.IsNil)
   148  	}
   149  	return toolsMetadata
   150  }