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 }