github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/environs/simplestreams/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  // Provides a TestDataSuite which creates and provides http access to sample simplestreams metadata.
     7  
     8  import (
     9  	"fmt"
    10  	"io/ioutil"
    11  	"net/http"
    12  	"strings"
    13  
    14  	jc "github.com/juju/testing/checkers"
    15  	"github.com/juju/utils/series"
    16  	gc "gopkg.in/check.v1"
    17  
    18  	"github.com/juju/juju/environs/simplestreams"
    19  	"github.com/juju/juju/testing"
    20  )
    21  
    22  var PrivateKeyPassphrase = "12345"
    23  
    24  var SignedMetadataPrivateKey = `
    25  -----BEGIN PGP PRIVATE KEY BLOCK-----
    26  Version: GnuPG v1.4.12 (GNU/Linux)
    27  
    28  lQH+BFJCk2EBBAC4wo3+aJ0PSeE54sv+GYNYckqysjazcZfJSdPK1GCN+Teat7ey
    29  9dwlLhUIS34H29V+0/RcXmmRV+dObSkXzCx5ltKPSnuDsxvqiDEP0CgWdyFxhDf0
    30  TbQuKK5OXcZ9rOTSFmnMxGaAzaV7T1IyuqA9HqntTIfC2tL4Y+QN41gS+QARAQAB
    31  /gMDAjYGIOoxe8CYYGwpat1V7NGuphvvZRpqeP0RrJ6h4vHV3hXu5NK3tn6LZF0n
    32  Qp31LfTH4BHF091UTiebexuuF1/ixLVihtv45mEVejFG1U3G298+WkWUP6AYA/5c
    33  QRzXGiuTXlsBUuFVTGn1mvxRmG3yVoLkDj0l5rN9Tq3Ir4BACIWyxjBv1n8fqw+x
    34  ti4b7YoE35FpIXQqLOdfdcKTOqUJt+5c+bed4Yx82BsLiY2/huqG2dLnbwln80Dz
    35  iYudtG8xLJ1AeHBBFB0nVdyO+mPzXgLNEbP3zle2W+rUfz+s6te7y+rlV0gad2VG
    36  tBAvUy08T9rDk0DNQl7jMq/3cGfDI1Zi/nzf2BuuBu2ddgIRmsXgKYly+Fq6eIpa
    37  nM+P1hd1Fa3rQwUSJc/zrl48tukf8sdPLDk/+nMhLHy86jp+NeXyXPLvsMAlF5kR
    38  eFjxEjHOnJlo4uIUxvlUuePyEOEl0XkQfZs+VWAPo+l2tB5UZXN0IFVzZXIgPHRl
    39  c3RAc29tZXdoZXJlLmNvbT6IuAQTAQIAIgUCUkKTYQIbAwYLCQgHAwIGFQgCCQoL
    40  BBYCAwECHgECF4AACgkQuK3uqWB66vCVugP/eJFir6Qdcvl+y9/HuP4q2iECi8ny
    41  z9tC3YC9DcJePyoBnt1LJO3HvaquZh1AIr6hgMFaujjx6cCb7YEgE0pJ4m74dvtS
    42  Y03MUPQ+Ok4cYV66zaDZLk6zpYJXZhxP7ZhlBvwQRES/rudBEQMfBcU9PrduFU39
    43  iI+2ojHI4lsnMQE=
    44  =UUIf
    45  -----END PGP PRIVATE KEY BLOCK-----
    46  `
    47  
    48  var SignedMetadataPublicKey = `
    49  -----BEGIN PGP PUBLIC KEY BLOCK-----
    50  Version: GnuPG v1.4.12 (GNU/Linux)
    51  
    52  mI0EUkKTYQEEALjCjf5onQ9J4Tniy/4Zg1hySrKyNrNxl8lJ08rUYI35N5q3t7L1
    53  3CUuFQhLfgfb1X7T9FxeaZFX505tKRfMLHmW0o9Ke4OzG+qIMQ/QKBZ3IXGEN/RN
    54  tC4ork5dxn2s5NIWaczEZoDNpXtPUjK6oD0eqe1Mh8La0vhj5A3jWBL5ABEBAAG0
    55  HlRlc3QgVXNlciA8dGVzdEBzb21ld2hlcmUuY29tPoi4BBMBAgAiBQJSQpNhAhsD
    56  BgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRC4re6pYHrq8JW6A/94kWKvpB1y
    57  +X7L38e4/iraIQKLyfLP20LdgL0Nwl4/KgGe3Usk7ce9qq5mHUAivqGAwVq6OPHp
    58  wJvtgSATSknibvh2+1JjTcxQ9D46ThxhXrrNoNkuTrOlgldmHE/tmGUG/BBERL+u
    59  50ERAx8FxT0+t24VTf2Ij7aiMcjiWycxAQ==
    60  =zBYH
    61  -----END PGP PUBLIC KEY BLOCK-----`
    62  
    63  var imageData = map[string]string{
    64  	"/daily/streams/v1/index.json": `
    65          {
    66           "index": {
    67            "com.ubuntu.cloud:released:raring": {
    68             "updated": "Wed, 01 May 2013 13:31:26 +0000",
    69             "clouds": [
    70              {
    71               "region": "us-east-1",
    72               "endpoint": "https://ec2.us-east-1.amazonaws.com"
    73              }
    74             ],
    75             "cloudname": "aws",
    76             "datatype": "image-ids",
    77             "format": "products:1.0",
    78             "products": [
    79              "com.ubuntu.cloud:server:13.04:amd64"
    80             ],
    81             "path": "streams/v1/raring_metadata.json"
    82            }
    83           },
    84           "updated": "Wed, 01 May 2013 13:31:26 +0000",
    85           "format": "index:1.0"
    86          }
    87      `,
    88  	"/streams/v1/index.json": `
    89  		{
    90  		 "index": {
    91  		  "com.ubuntu.cloud:released:precise": {
    92  		   "updated": "Wed, 01 May 2013 13:31:26 +0000",
    93  		   "clouds": [
    94  			{
    95  			 "region": "us-east-1",
    96  			 "endpoint": "https://ec2.us-east-1.amazonaws.com"
    97  			}
    98  		   ],
    99  		   "cloudname": "aws",
   100  		   "datatype": "image-ids",
   101  		   "format": "products:1.0",
   102  		   "products": [
   103  			"com.ubuntu.cloud:server:12.04:amd64",
   104  			"com.ubuntu.cloud:server:12.04:arm"
   105  		   ],
   106  		   "path": "streams/v1/image_metadata.json"
   107  		  },
   108  		  "com.ubuntu.cloud:released:raring": {
   109  		   "updated": "Wed, 01 May 2013 13:31:26 +0000",
   110  		   "clouds": [
   111  			{
   112  			 "region": "us-east-1",
   113  			 "endpoint": "https://ec2.us-east-1.amazonaws.com"
   114  			}
   115  		   ],
   116  		   "cloudname": "aws",
   117  		   "datatype": "image-ids",
   118  		   "format": "products:1.0",
   119  		   "products": [
   120  			"com.ubuntu.cloud:server:13.04:amd64"
   121  		   ],
   122  		   "path": "streams/v1/raring_metadata.json"
   123  		  },
   124  		  "com.ubuntu.cloud:released:download": {
   125  		   "datatype": "content-download",
   126  		   "path": "streams/v1/com.ubuntu.cloud:released:download.json",
   127  		   "updated": "Wed, 01 May 2013 13:30:37 +0000",
   128  		   "products": [
   129  			"com.ubuntu.cloud:server:12.10:amd64",
   130  			"com.ubuntu.cloud:server:13.04:amd64"
   131  		   ],
   132  		   "format": "products:1.0"
   133  		  },
   134  		  "com.ubuntu.juju:released:tools": {
   135  		   "updated": "Mon, 05 Aug 2013 11:07:04 +0000",
   136  		   "datatype": "content-download",
   137  		   "format": "products:1.0",
   138  		   "products": [
   139  		     "com.ubuntu.juju:12.04:amd64",
   140  		     "com.ubuntu.juju:12.04:arm",
   141  		     "com.ubuntu.juju:13.04:amd64",
   142  		     "com.ubuntu.juju:13.04:arm"
   143  		   ],
   144  		   "path": "streams/v1/tools_metadata.json"
   145  		  },
   146  		  "com.ubuntu.juju:testing:tools": {
   147  		   "updated": "Mon, 05 Aug 2013 11:07:04 +0000",
   148  		   "datatype": "content-download",
   149  		   "format": "products:1.0",
   150  		   "products": [
   151  		     "com.ubuntu.juju:14.04:amd64"
   152  		   ],
   153  		   "path": "streams/v1/testing_tools_metadata.json"
   154  		  }
   155  		 },
   156  		 "updated": "Wed, 01 May 2013 13:31:26 +0000",
   157  		 "format": "index:1.0"
   158  		}
   159  `,
   160  	"/streams/v1/mirrors.json": `
   161          {
   162           "mirrors": {
   163            "com.ubuntu.juju:released:tools": [
   164               {
   165                "datatype": "content-download",
   166                "path": "streams/v1/tools_metadata:public-mirrors.json",
   167                "clouds": [
   168                 {
   169                  "region": "us-east-2",
   170                  "endpoint": "https://ec2.us-east-2.amazonaws.com"
   171                 },
   172                 {
   173                  "region": "us-west-2",
   174                  "endpoint": "https://ec2.us-west-2.amazonaws.com"
   175                 }
   176                ],
   177                "updated": "Wed, 14 Aug 2013 13:46:17 +0000",
   178                "format": "mirrors:1.0"
   179               },
   180               {
   181                "datatype": "content-download",
   182                "path": "streams/v1/tools_metadata:more-mirrors.json",
   183                "updated": "Wed, 14 Aug 2013 13:46:17 +0000",
   184                "format": "mirrors:1.0"
   185               }
   186            ]
   187           },
   188           "updated": "Wed, 01 May 2013 13:31:26 +0000",
   189           "format": "index:1.0"
   190          }
   191  `,
   192  	"/streams/v1/tools_metadata.json": `
   193  {
   194   "content_id": "com.ubuntu.juju:tools",
   195   "datatype": "content-download",
   196   "updated": "Tue, 04 Jun 2013 13:50:31 +0000",
   197   "format": "products:1.0",
   198   "products": {
   199    "com.ubuntu.juju:12.04:amd64": {
   200     "arch": "amd64",
   201     "release": "precise",
   202     "versions": {
   203      "20130806": {
   204       "items": {
   205        "1130preciseamd64": {
   206         "version": "1.13.0",
   207         "size": 2973595,
   208         "path": "tools/released/20130806/juju-1.13.0-precise-amd64.tgz",
   209         "ftype": "tar.gz",
   210         "sha256": "447aeb6a934a5eaec4f703eda4ef2dde"
   211        }
   212       }
   213      }
   214     }
   215    },
   216    "com.ubuntu.juju:13.04:amd64": {
   217     "arch": "amd64",
   218     "release": "raring",
   219     "versions": {
   220      "20130806": {
   221       "items": {
   222        "1130raringamd64": {
   223         "version": "1.13.0",
   224         "size": 2973173,
   225         "path": "tools/released/20130806/juju-1.13.0-raring-amd64.tgz",
   226         "ftype": "tar.gz",
   227         "sha256": "df07ac5e1fb4232d4e9aa2effa57918a"
   228        },
   229        "1140raringamd64": {
   230         "version": "1.14.0",
   231         "size": 2973173,
   232         "path": "tools/released/20130806/juju-1.14.0-raring-amd64.tgz",
   233         "ftype": "tar.gz",
   234         "sha256": "df07ac5e1fb4232d4e9aa2effa57918a"
   235        }
   236       }
   237      }
   238     }
   239    },
   240    "com.ubuntu.juju:12.04:arm": {
   241     "arch": "arm",
   242     "release": "precise",
   243     "versions": {
   244      "20130806": {
   245       "items": {
   246        "201precisearm": {
   247         "version": "2.0.1",
   248         "size": 1951096,
   249         "path": "tools/released/20130806/juju-2.0.1-precise-arm.tgz",
   250         "ftype": "tar.gz",
   251         "sha256": "f65a92b3b41311bdf398663ee1c5cd0c"
   252        },
   253        "1114precisearm": {
   254         "version": "1.11.4",
   255         "size": 1951096,
   256         "path": "tools/released/20130806/juju-1.11.4-precise-arm.tgz",
   257         "ftype": "tar.gz",
   258         "sha256": "f65a92b3b41311bdf398663ee1c5cd0c"
   259        }
   260       }
   261      },
   262      "20130803": {
   263       "items": {
   264        "1114precisearm": {
   265         "version": "1.11.4",
   266         "size": 2851541,
   267         "path": "tools/released/20130803/juju-1.11.4-precise-arm.tgz",
   268         "ftype": "tar.gz",
   269         "sha256": "df07ac5e1fb4232d4e9aa2effa57918a"
   270        },
   271        "1115precisearm": {
   272         "version": "1.11.5",
   273         "size": 2031281,
   274         "path": "tools/released/20130803/juju-1.11.5-precise-arm.tgz",
   275         "ftype": "tar.gz",
   276         "sha256": "df07ac5e1fb4232d4e9aa2effa57918a"
   277        }
   278       }
   279      }
   280     }
   281    },
   282    "com.ubuntu.juju:13.04:arm": {
   283     "arch": "arm",
   284     "release": "raring",
   285     "versions": {
   286      "20130806": {
   287       "items": {
   288        "1114raringarm": {
   289         "version": "1.11.4",
   290         "size": 1950327,
   291         "path": "tools/released/20130806/juju-1.11.4-raring-arm.tgz",
   292         "ftype": "tar.gz",
   293         "sha256": "6472014e3255e3fe7fbd3550ef3f0a11"
   294        },
   295        "201raringarm": {
   296         "version": "2.0.1",
   297         "size": 1950327,
   298         "path": "tools/released/20130806/juju-2.0.1-raring-arm.tgz",
   299         "ftype": "tar.gz",
   300         "sha256": "6472014e3255e3fe7fbd3550ef3f0a11"
   301        }
   302       }
   303      }
   304     }
   305    }
   306   }
   307  }
   308  `,
   309  	"/streams/v1/testing_tools_metadata.json": `
   310  {
   311   "content_id": "com.ubuntu.juju:tools",
   312   "datatype": "content-download",
   313   "updated": "Tue, 04 Jun 2013 13:50:31 +0000",
   314   "format": "products:1.0",
   315   "products": {
   316    "com.ubuntu.juju:14.04:amd64": {
   317     "arch": "amd64",
   318     "release": "trusty",
   319     "versions": {
   320      "20130806": {
   321       "items": {
   322        "1130preciseamd64": {
   323         "version": "1.16.0",
   324         "size": 2973512,
   325         "path": "tools/testing/20130806/juju-1.16.0-trusty-amd64.tgz",
   326         "ftype": "tar.gz",
   327         "sha256": "447aeb6a934a5eaec4f703eda4ef2dac"
   328        }
   329       }
   330      }
   331     }
   332    }
   333   }
   334  }
   335  `,
   336  	"/streams/v1/mirrored-tools-metadata.json": `
   337  {
   338   "content_id": "com.ubuntu.juju:tools",
   339   "datatype": "content-download",
   340   "updated": "Tue, 04 Jun 2013 13:50:31 +0000",
   341   "format": "products:1.0",
   342   "products": {
   343    "com.ubuntu.juju:12.04:amd64": {
   344     "arch": "amd64",
   345     "release": "precise",
   346     "versions": {
   347      "20130806": {
   348       "items": {
   349        "1130preciseamd64": {
   350         "version": "1.13.0",
   351         "size": 2973595,
   352         "path": "mirrored-path/juju-1.13.0-precise-amd64.tgz",
   353         "ftype": "tar.gz",
   354         "sha256": "447aeb6a934a5eaec4f703eda4ef2dde"
   355        }
   356       }
   357      }
   358     }
   359    }
   360   }
   361  }
   362  `,
   363  	"/streams/v1/tools_metadata:public-mirrors.json": `
   364  {
   365    "mirrors": {
   366      "com.ubuntu.juju:released:tools": [
   367        {
   368          "mirror": "http://some-mirror/",
   369          "path": "com.ubuntu.juju:download.json",
   370          "format": "products:1.0",
   371          "clouds": [
   372            {
   373              "endpoint": "https://ec2.us-east-2.amazonaws.com",
   374              "region": "us-east-2"
   375            }
   376          ]
   377        },
   378        {
   379          "mirror": "test:/",
   380          "path": "streams/v1/mirrored-tools-metadata.json",
   381          "format": "products:1.0",
   382          "clouds": [
   383            {
   384              "endpoint": "https://ec2.us-west-2.amazonaws.com",
   385              "region": "us-west-2"
   386            }
   387          ]
   388        },
   389        {
   390          "mirror": "http://another-mirror/",
   391          "path": "com.ubuntu.juju:download.json",
   392          "format": "products:1.0",
   393          "clouds": [
   394            {
   395              "endpoint": "https://ec2.us-west-1.amazonaws.com",
   396              "region": "us-west-1"
   397            }
   398          ]
   399        }
   400      ]
   401    },
   402    "format": "mirrors:1.0",
   403    "updated": "Mon, 05 Aug 2013 11:07:04 +0000"
   404  }
   405  `,
   406  	"/streams/v1/tools_metadata:more-mirrors.json": `
   407  {
   408    "mirrors": {
   409      "com.ubuntu.juju:released:tools": [
   410        {
   411          "mirror": "http://big-mirror/",
   412          "path": "big:download.json",
   413          "clouds": [
   414            {
   415              "endpoint": "https://some-endpoint.com",
   416              "region": "some-region"
   417            }
   418          ]
   419        }
   420      ]
   421    },
   422    "format": "mirrors:1.0",
   423    "updated": "Mon, 05 Aug 2013 11:07:04 +0000"
   424  }
   425  `,
   426  	"/streams/v1/image_metadata.json": `
   427  {
   428   "updated": "Wed, 01 May 2013 13:31:26 +0000",
   429   "content_id": "com.ubuntu.cloud:released:aws",
   430   "region": "nz-east-1",
   431   "endpoint": "https://anywhere",
   432   "products": {
   433    "com.ubuntu.cloud:server:14.04:amd64": {
   434     "release": "trusty",
   435     "version": "14.04",
   436     "arch": "amd64",
   437     "versions": {
   438      "20140118": {
   439       "items": {
   440        "nzww1pe": {
   441         "root_store": "ebs",
   442         "virt": "pv",
   443         "id": "ami-36745463"
   444        }
   445       },
   446       "pubname": "ubuntu-trusty-14.04-amd64-server-20140118",
   447       "label": "release"
   448      }
   449     }
   450    },
   451    "com.ubuntu.cloud:server:12.04:amd64": {
   452     "release": "precise",
   453     "version": "12.04",
   454     "arch": "amd64",
   455     "region": "au-east-1",
   456     "endpoint": "https://somewhere",
   457     "versions": {
   458      "20121218": {
   459       "region": "au-east-2",
   460       "endpoint": "https://somewhere-else",
   461       "items": {
   462        "usww1pe": {
   463         "root_store": "ebs",
   464         "virt": "pv",
   465         "id": "ami-26745463"
   466        },
   467        "usww2he": {
   468         "root_store": "ebs",
   469         "virt": "hvm",
   470         "id": "ami-442ea674",
   471         "region": "us-east-1",
   472         "endpoint": "https://ec2.us-east-1.amazonaws.com"
   473        },
   474        "usww3he": {
   475         "root_store": "ebs",
   476         "virt": "hvm",
   477         "crsn": "uswest3",
   478         "id": "ami-442ea675"
   479        }
   480       },
   481       "pubname": "ubuntu-precise-12.04-amd64-server-20121218",
   482       "label": "release"
   483      },
   484      "20111111": {
   485       "items": {
   486        "usww3pe": {
   487         "root_store": "ebs",
   488         "virt": "pv",
   489         "id": "ami-26745464"
   490        },
   491        "usww2pe": {
   492         "root_store": "instance",
   493         "virt": "pv",
   494         "id": "ami-442ea684",
   495         "region": "us-east-1",
   496         "endpoint": "https://ec2.us-east-1.amazonaws.com"
   497        }
   498       },
   499       "pubname": "ubuntu-precise-12.04-amd64-server-20111111",
   500       "label": "release"
   501      }
   502     }
   503    },
   504    "com.ubuntu.cloud:server:12.04:arm": {
   505     "release": "precise",
   506     "version": "12.04",
   507     "arch": "arm",
   508     "region": "us-east-1",
   509     "endpoint": "https://ec2.us-east-1.amazonaws.com",
   510     "versions": {
   511      "20121219": {
   512       "items": {
   513        "usww2he": {
   514         "root_store": "ebs",
   515         "virt": "pv",
   516         "id": "ami-442ea699"
   517        }
   518       },
   519       "pubname": "ubuntu-precise-12.04-arm-server-20121219",
   520       "label": "release"
   521      }
   522     }
   523    }
   524   },
   525   "_aliases": {
   526    "crsn": {
   527     "uswest3": {
   528      "region": "us-west-3",
   529      "endpoint": "https://ec2.us-west-3.amazonaws.com"
   530     }
   531    }
   532   },
   533   "format": "products:1.0"
   534  }
   535  `,
   536  }
   537  
   538  var TestRoundTripper = &testing.ProxyRoundTripper{}
   539  
   540  func init() {
   541  	TestRoundTripper.RegisterForScheme("test")
   542  	TestRoundTripper.RegisterForScheme("signedtest")
   543  }
   544  
   545  type TestDataSuite struct{}
   546  
   547  func (s *TestDataSuite) SetUpSuite(c *gc.C) {
   548  	TestRoundTripper.Sub = testing.NewCannedRoundTripper(imageData, map[string]int{"test://unauth": http.StatusUnauthorized})
   549  }
   550  
   551  func (s *TestDataSuite) TearDownSuite(c *gc.C) {
   552  	TestRoundTripper.Sub = nil
   553  }
   554  
   555  const (
   556  	UnsignedJsonSuffix = ".json"
   557  	SignedJsonSuffix   = ".sjson"
   558  )
   559  
   560  func SetRoundTripperFiles(files map[string]string, errorFiles map[string]int) {
   561  	TestRoundTripper.Sub = testing.NewCannedRoundTripper(files, errorFiles)
   562  }
   563  
   564  func AddSignedFiles(c *gc.C, files map[string]string) map[string]string {
   565  	all := make(map[string]string)
   566  	for name, content := range files {
   567  		all[name] = content
   568  		// Sign file content
   569  		r := strings.NewReader(content)
   570  		bytes, err := ioutil.ReadAll(r)
   571  		c.Assert(err, jc.ErrorIsNil)
   572  		signedName, signedContent, err := SignMetadata(name, bytes)
   573  		c.Assert(err, jc.ErrorIsNil)
   574  		all[signedName] = string(signedContent)
   575  	}
   576  	return all
   577  }
   578  
   579  func SignMetadata(fileName string, fileData []byte) (string, []byte, error) {
   580  	signString := func(unsigned string) string {
   581  		return strings.Replace(unsigned, UnsignedJsonSuffix, SignedJsonSuffix, -1)
   582  	}
   583  
   584  	// Make sure that contents point to signed files too.
   585  	signedFileData := signString(string(fileData))
   586  	signedBytes, err := simplestreams.Encode(strings.NewReader(signedFileData), SignedMetadataPrivateKey, PrivateKeyPassphrase)
   587  	if err != nil {
   588  		return "", nil, err
   589  	}
   590  
   591  	return signString(fileName), signedBytes, nil
   592  }
   593  
   594  // SourceDetails stored some details that need to be checked about data source.
   595  type SourceDetails struct {
   596  	URL string
   597  	Key string
   598  }
   599  
   600  func AssertExpectedSources(c *gc.C, obtained []simplestreams.DataSource, dsDetails []SourceDetails) {
   601  	// Some data sources do not require to contain signed data.
   602  	// However, they may still contain it.
   603  	// Since we will always try to read signed data first,
   604  	// we want to be able to try to read this signed data
   605  	// with a public key. Check keys are provided where needed.
   606  	// Bugs #1542127, #1542131
   607  	for i, source := range obtained {
   608  		url, err := source.URL("")
   609  		c.Assert(err, jc.ErrorIsNil)
   610  		expected := dsDetails[i]
   611  		c.Assert(url, gc.DeepEquals, expected.URL)
   612  		c.Assert(source.PublicSigningKey(), gc.DeepEquals, expected.Key)
   613  	}
   614  	c.Assert(obtained, gc.HasLen, len(dsDetails))
   615  }
   616  
   617  type LocalLiveSimplestreamsSuite struct {
   618  	testing.BaseSuite
   619  	Source          simplestreams.DataSource
   620  	RequireSigned   bool
   621  	StreamsVersion  string
   622  	DataType        string
   623  	ValidConstraint simplestreams.LookupConstraint
   624  }
   625  
   626  func (s *LocalLiveSimplestreamsSuite) SetUpSuite(c *gc.C) {
   627  	s.BaseSuite.SetUpSuite(c)
   628  }
   629  
   630  func (s *LocalLiveSimplestreamsSuite) TearDownSuite(c *gc.C) {
   631  	s.BaseSuite.TearDownSuite(c)
   632  }
   633  
   634  const (
   635  	Index_v1   = "index:1.0"
   636  	Product_v1 = "products:1.0"
   637  	Mirror_v1  = "mirrors:1.0"
   638  )
   639  
   640  type testConstraint struct {
   641  	simplestreams.LookupParams
   642  }
   643  
   644  func NewTestConstraint(params simplestreams.LookupParams) *testConstraint {
   645  	return &testConstraint{LookupParams: params}
   646  }
   647  
   648  func (tc *testConstraint) IndexIds() []string {
   649  	return nil
   650  }
   651  
   652  func (tc *testConstraint) ProductIds() ([]string, error) {
   653  	version, err := series.SeriesVersion(tc.Series[0])
   654  	if err != nil {
   655  		return nil, err
   656  	}
   657  	ids := make([]string, len(tc.Arches))
   658  	for i, arch := range tc.Arches {
   659  		ids[i] = fmt.Sprintf("com.ubuntu.cloud:server:%s:%s", version, arch)
   660  	}
   661  	return ids, nil
   662  }
   663  
   664  func init() {
   665  	// Ensure out test struct can have its tags extracted.
   666  	simplestreams.RegisterStructTags(TestItem{})
   667  }
   668  
   669  type TestItem struct {
   670  	Id          string `json:"id"`
   671  	Storage     string `json:"root_store"`
   672  	VirtType    string `json:"virt"`
   673  	Arch        string `json:"arch"`
   674  	RegionAlias string `json:"crsn"`
   675  	RegionName  string `json:"region"`
   676  	Endpoint    string `json:"endpoint"`
   677  }
   678  
   679  func (s *LocalLiveSimplestreamsSuite) IndexPath() string {
   680  	if s.RequireSigned {
   681  		return fmt.Sprintf("streams/%s/index.sjson", s.StreamsVersion)
   682  	}
   683  	return fmt.Sprintf("streams/%s/index.json", s.StreamsVersion)
   684  }
   685  
   686  func (s *LocalLiveSimplestreamsSuite) TestGetIndex(c *gc.C) {
   687  	indexRef, err := s.GetIndexRef(Index_v1)
   688  	c.Assert(err, jc.ErrorIsNil)
   689  	c.Assert(indexRef.Format, gc.Equals, Index_v1)
   690  	c.Assert(indexRef.Source, gc.Equals, s.Source)
   691  	c.Assert(len(indexRef.Indexes) > 0, jc.IsTrue)
   692  }
   693  
   694  func (s *LocalLiveSimplestreamsSuite) GetIndexRef(format string) (*simplestreams.IndexReference, error) {
   695  	params := simplestreams.ValueParams{
   696  		DataType:      s.DataType,
   697  		ValueTemplate: TestItem{},
   698  	}
   699  	return simplestreams.GetIndexWithFormat(
   700  		s.Source, s.IndexPath(), format, simplestreams.MirrorsPath(s.StreamsVersion), s.RequireSigned,
   701  		s.ValidConstraint.Params().CloudSpec, params)
   702  }
   703  
   704  func (s *LocalLiveSimplestreamsSuite) TestGetIndexWrongFormat(c *gc.C) {
   705  	_, err := s.GetIndexRef("bad")
   706  	c.Assert(err, gc.NotNil)
   707  }
   708  
   709  func (s *LocalLiveSimplestreamsSuite) TestGetProductsPathExists(c *gc.C) {
   710  	indexRef, err := s.GetIndexRef(Index_v1)
   711  	c.Assert(err, jc.ErrorIsNil)
   712  	path, err := indexRef.GetProductsPath(s.ValidConstraint)
   713  	c.Assert(err, jc.ErrorIsNil)
   714  	c.Assert(path, gc.Not(gc.Equals), "")
   715  }
   716  
   717  func (s *LocalLiveSimplestreamsSuite) TestGetProductsPathInvalidCloudSpec(c *gc.C) {
   718  	indexRef, err := s.GetIndexRef(Index_v1)
   719  	c.Assert(err, jc.ErrorIsNil)
   720  	ic := NewTestConstraint(simplestreams.LookupParams{
   721  		CloudSpec: simplestreams.CloudSpec{"bad", "spec"},
   722  		Series:    []string{"precise"},
   723  	})
   724  	_, err = indexRef.GetProductsPath(ic)
   725  	c.Assert(err, gc.NotNil)
   726  }
   727  
   728  func (s *LocalLiveSimplestreamsSuite) TestGetProductsPathInvalidProductSpec(c *gc.C) {
   729  	indexRef, err := s.GetIndexRef(Index_v1)
   730  	c.Assert(err, jc.ErrorIsNil)
   731  	ic := NewTestConstraint(simplestreams.LookupParams{
   732  		CloudSpec: s.ValidConstraint.Params().CloudSpec,
   733  		Series:    []string{"precise"},
   734  		Arches:    []string{"bad"},
   735  		Stream:    "spec",
   736  	})
   737  	_, err = indexRef.GetProductsPath(ic)
   738  	c.Assert(err, gc.NotNil)
   739  }
   740  
   741  func (s *LocalLiveSimplestreamsSuite) AssertGetMetadata(c *gc.C) *simplestreams.CloudMetadata {
   742  	indexRef, err := s.GetIndexRef(Index_v1)
   743  	c.Assert(err, jc.ErrorIsNil)
   744  	metadata, err := indexRef.GetCloudMetadataWithFormat(s.ValidConstraint, Product_v1, s.RequireSigned)
   745  	c.Assert(err, jc.ErrorIsNil)
   746  	c.Assert(metadata.Format, gc.Equals, Product_v1)
   747  	c.Assert(len(metadata.Products) > 0, jc.IsTrue)
   748  	return metadata
   749  }
   750  
   751  func (s *LocalLiveSimplestreamsSuite) TestGetCloudMetadataWithFormat(c *gc.C) {
   752  	s.AssertGetMetadata(c)
   753  }
   754  
   755  func (s *LocalLiveSimplestreamsSuite) AssertGetItemCollections(c *gc.C, version string) *simplestreams.ItemCollection {
   756  	metadata := s.AssertGetMetadata(c)
   757  	metadataCatalog := metadata.Products["com.ubuntu.cloud:server:12.04:amd64"]
   758  	ic := metadataCatalog.Items[version]
   759  	return ic
   760  }