github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/apiserver/provisioner/imagemetadata_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package provisioner_test
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	jc "github.com/juju/testing/checkers"
     9  	gc "gopkg.in/check.v1"
    10  
    11  	"github.com/juju/juju/apiserver/params"
    12  	"github.com/juju/juju/apiserver/provisioner"
    13  	"github.com/juju/juju/environs/imagemetadata"
    14  	imagetesting "github.com/juju/juju/environs/imagemetadata/testing"
    15  	sstesting "github.com/juju/juju/environs/simplestreams/testing"
    16  	"github.com/juju/juju/state/cloudimagemetadata"
    17  )
    18  
    19  // useTestImageData causes the given content to be served when published metadata is requested.
    20  func useTestImageData(c *gc.C, files map[string]string) {
    21  	if files != nil {
    22  		sstesting.SetRoundTripperFiles(sstesting.AddSignedFiles(c, files), nil)
    23  	} else {
    24  		sstesting.SetRoundTripperFiles(nil, nil)
    25  	}
    26  }
    27  
    28  type ImageMetadataSuite struct {
    29  	provisionerSuite
    30  }
    31  
    32  var _ = gc.Suite(&ImageMetadataSuite{})
    33  
    34  func (s *ImageMetadataSuite) SetUpSuite(c *gc.C) {
    35  	s.provisionerSuite.SetUpSuite(c)
    36  
    37  	// Make sure that there is nothing in data sources.
    38  	// Each individual tests will decide if it needs metadata there.
    39  	imagetesting.PatchOfficialDataSources(&s.CleanupSuite, "test:/daily")
    40  	s.PatchValue(&imagemetadata.SimplestreamsImagesPublicKey, sstesting.SignedMetadataPublicKey)
    41  	useTestImageData(c, nil)
    42  }
    43  
    44  func (s *ImageMetadataSuite) TearDownSuite(c *gc.C) {
    45  	useTestImageData(c, nil)
    46  	s.provisionerSuite.TearDownSuite(c)
    47  }
    48  
    49  func (s *ImageMetadataSuite) SetUpTest(c *gc.C) {
    50  	s.provisionerSuite.SetUpTest(c)
    51  }
    52  
    53  func (s *ImageMetadataSuite) TestMetadataNone(c *gc.C) {
    54  	api, err := provisioner.NewProvisionerAPI(s.State, s.resources, s.authorizer)
    55  	c.Assert(err, jc.ErrorIsNil)
    56  
    57  	result, err := api.ProvisioningInfo(s.getTestMachinesTags(c))
    58  	c.Assert(err, jc.ErrorIsNil)
    59  
    60  	expected := make([][]params.CloudImageMetadata, len(s.machines))
    61  	for i, _ := range result.Results {
    62  		expected[i] = nil
    63  	}
    64  	s.assertImageMetadataResults(c, result, expected...)
    65  }
    66  
    67  func (s *ImageMetadataSuite) TestMetadataNotInStateButInDataSources(c *gc.C) {
    68  	// ensure metadata in data sources and not in state
    69  	useTestImageData(c, testImagesData)
    70  
    71  	criteria := cloudimagemetadata.MetadataFilter{Stream: "daily"}
    72  	found, err := s.State.CloudImageMetadataStorage.FindMetadata(criteria)
    73  	c.Assert(errors.IsNotFound(err), jc.IsTrue)
    74  	c.Assert(found, gc.HasLen, 0)
    75  
    76  	api, err := provisioner.NewProvisionerAPI(s.State, s.resources, s.authorizer)
    77  	c.Assert(err, jc.ErrorIsNil)
    78  
    79  	result, err := api.ProvisioningInfo(s.getTestMachinesTags(c))
    80  	c.Assert(err, jc.ErrorIsNil)
    81  
    82  	expected := s.expectedDataSoureImageMetadata()
    83  	s.assertImageMetadataResults(c, result, expected...)
    84  
    85  	// Also make sure that these images metadata has been written to state for re-use
    86  	saved, err := s.State.CloudImageMetadataStorage.FindMetadata(criteria)
    87  	c.Assert(err, jc.ErrorIsNil)
    88  	c.Assert(saved, gc.DeepEquals, map[string][]cloudimagemetadata.Metadata{
    89  		"default cloud images": s.convertCloudImageMetadata(expected[0]),
    90  	})
    91  }
    92  
    93  func (s *ImageMetadataSuite) TestMetadataFromState(c *gc.C) {
    94  	api, err := provisioner.NewProvisionerAPI(s.State, s.resources, s.authorizer)
    95  	c.Assert(err, jc.ErrorIsNil)
    96  
    97  	expected := s.expectedDataSoureImageMetadata()
    98  
    99  	// Write metadata to state.
   100  	metadata := s.convertCloudImageMetadata(expected[0])
   101  	for _, m := range metadata {
   102  		err := s.State.CloudImageMetadataStorage.SaveMetadata(
   103  			[]cloudimagemetadata.Metadata{m},
   104  		)
   105  		c.Assert(err, jc.ErrorIsNil)
   106  	}
   107  
   108  	result, err := api.ProvisioningInfo(s.getTestMachinesTags(c))
   109  	c.Assert(err, jc.ErrorIsNil)
   110  
   111  	s.assertImageMetadataResults(c, result, expected...)
   112  }
   113  
   114  func (s *ImageMetadataSuite) getTestMachinesTags(c *gc.C) params.Entities {
   115  
   116  	testMachines := make([]params.Entity, len(s.machines))
   117  
   118  	for i, m := range s.machines {
   119  		testMachines[i] = params.Entity{Tag: m.Tag().String()}
   120  	}
   121  	return params.Entities{Entities: testMachines}
   122  }
   123  
   124  func (s *ImageMetadataSuite) convertCloudImageMetadata(all []params.CloudImageMetadata) []cloudimagemetadata.Metadata {
   125  	expected := make([]cloudimagemetadata.Metadata, len(all))
   126  	for i, one := range all {
   127  		expected[i] = cloudimagemetadata.Metadata{
   128  			cloudimagemetadata.MetadataAttributes{
   129  				Region:          one.Region,
   130  				Version:         one.Version,
   131  				Series:          one.Series,
   132  				Arch:            one.Arch,
   133  				VirtType:        one.VirtType,
   134  				RootStorageType: one.RootStorageType,
   135  				Source:          one.Source,
   136  				Stream:          one.Stream,
   137  			},
   138  			one.Priority,
   139  			one.ImageId,
   140  		}
   141  	}
   142  	return expected
   143  }
   144  
   145  func (s *ImageMetadataSuite) expectedDataSoureImageMetadata() [][]params.CloudImageMetadata {
   146  	expected := make([][]params.CloudImageMetadata, len(s.machines))
   147  	for i, _ := range s.machines {
   148  		expected[i] = []params.CloudImageMetadata{
   149  			{ImageId: "ami-1126745463",
   150  				Region:          "another_dummy_region",
   151  				Version:         "12.10",
   152  				Series:          "quantal",
   153  				Arch:            "amd64",
   154  				VirtType:        "pv",
   155  				RootStorageType: "ebs",
   156  				Source:          "default cloud images",
   157  				Stream:          "daily",
   158  				Priority:        10,
   159  			},
   160  			{ImageId: "ami-26745463",
   161  				Region:          "dummy_region",
   162  				Version:         "12.10",
   163  				Series:          "quantal",
   164  				Arch:            "amd64",
   165  				VirtType:        "pv",
   166  				RootStorageType: "ebs",
   167  				Stream:          "daily",
   168  				Source:          "default cloud images",
   169  				Priority:        10},
   170  		}
   171  	}
   172  	return expected
   173  }
   174  
   175  func (s *ImageMetadataSuite) assertImageMetadataResults(c *gc.C, obtained params.ProvisioningInfoResults, expected ...[]params.CloudImageMetadata) {
   176  	c.Assert(obtained.Results, gc.HasLen, len(expected))
   177  	for i, one := range obtained.Results {
   178  		// We are only concerned with images here
   179  		c.Assert(one.Result.ImageMetadata, gc.DeepEquals, expected[i])
   180  	}
   181  }
   182  
   183  // TODO (anastasiamac 2015-09-04) This metadata is so verbose.
   184  // Need to generate the text by creating a struct and marshalling it.
   185  var testImagesData = map[string]string{
   186  	"/daily/streams/v1/index.json": `
   187  		{
   188  		 "index": {
   189  		  "com.ubuntu.cloud:daily:aws": {
   190  		   "updated": "Wed, 01 May 2013 13:31:26 +0000",
   191  		   "clouds": [
   192  			{
   193  			 "region": "dummy_region",
   194  			 "endpoint": "https://anywhere"
   195  			},
   196  			{
   197  			 "region": "another_dummy_region",
   198  			 "endpoint": ""
   199  			}
   200  		   ],
   201  		   "cloudname": "aws",
   202  		   "datatype": "image-ids",
   203  		   "format": "products:1.0",
   204  		   "products": [
   205  			"com.ubuntu.cloud.daily:server:12.10:amd64",
   206  			"com.ubuntu.cloud.daily:server:14.04:amd64"
   207  		   ],
   208  		   "path": "streams/v1/image_metadata.json"
   209  		   }
   210  		  },
   211  		 "updated": "Wed, 27 May 2015 13:31:26 +0000",
   212  		 "format": "index:1.0"
   213  		}
   214  `,
   215  	"/daily/streams/v1/image_metadata.json": `
   216  {
   217   "updated": "Wed, 27 May 2015 13:31:26 +0000",
   218   "content_id": "com.ubuntu.cloud:daily:aws",
   219   "products": {
   220    "com.ubuntu.cloud.daily:server:14.04:amd64": {
   221     "release": "trusty",
   222     "version": "14.04",
   223     "arch": "amd64",
   224     "versions": {
   225      "20140118": {
   226       "items": {
   227        "nzww1pe": {
   228         "root_store": "ebs",
   229         "virt": "pv",
   230         "crsn": "da1",
   231         "id": "ami-36745463"
   232        },
   233        "nzww1pe2": {
   234         "root_store": "ebs",
   235         "virt": "pv",
   236         "crsn": "da2",
   237         "id": "ami-1136745463"
   238        }
   239       },
   240       "pubname": "ubuntu-trusty-14.04-amd64-server-20140118",
   241       "label": "release"
   242      }
   243     }
   244    },
   245    "com.ubuntu.cloud.daily:server:12.10:amd64": {
   246     "release": "quantal",
   247     "version": "12.10",
   248     "arch": "amd64",
   249     "versions": {
   250      "20121218": {
   251       "items": {
   252        "usww1pe": {
   253         "root_store": "ebs",
   254         "virt": "pv",
   255         "crsn": "da1",
   256         "id": "ami-26745463"
   257        },
   258        "usww1pe2": {
   259         "root_store": "ebs",
   260         "virt": "pv",
   261         "crsn": "da2",
   262         "id": "ami-1126745463"
   263        }
   264       },
   265       "pubname": "ubuntu-quantal-12.10-amd64-server-20121218",
   266       "label": "release"
   267      }
   268     }
   269    }
   270   },
   271   "_aliases": {
   272    "crsn": {
   273     "da1": {
   274      "region": "dummy_region",
   275      "endpoint": "https://anywhere"
   276     },
   277     "da2": {
   278      "region": "another_dummy_region",
   279      "endpoint": ""
   280     }
   281    }
   282   },
   283   "format": "products:1.0"
   284  }
   285  `,
   286  }