github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/provider/oci/images_integration_test.go (about)

     1  // Copyright 2018 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package oci_test
     5  
     6  import (
     7  	"context"
     8  	"time"
     9  
    10  	jc "github.com/juju/testing/checkers"
    11  	ociCore "github.com/oracle/oci-go-sdk/v65/core"
    12  	"go.uber.org/mock/gomock"
    13  	gc "gopkg.in/check.v1"
    14  
    15  	"github.com/juju/juju/core/arch"
    16  	corearch "github.com/juju/juju/core/arch"
    17  	corebase "github.com/juju/juju/core/base"
    18  	"github.com/juju/juju/environs/instances"
    19  	"github.com/juju/juju/provider/oci"
    20  	ocitesting "github.com/juju/juju/provider/oci/testing"
    21  	jujutesting "github.com/juju/juju/testing"
    22  )
    23  
    24  type imagesSuite struct {
    25  	jujutesting.BaseSuite
    26  
    27  	testImageID     string
    28  	testCompartment string
    29  }
    30  
    31  var _ = gc.Suite(&imagesSuite{})
    32  
    33  func (s *imagesSuite) SetUpTest(c *gc.C) {
    34  	s.BaseSuite.SetUpTest(c)
    35  	oci.SetImageCache(&oci.ImageCache{})
    36  
    37  	s.testImageID = "ocid1.image.oc1.phx.aaaaaaaaa5mikpf5fktj4x47bx4p4ak4g5jyuyukkxpdg4nll36qzqwjzd2q"
    38  	s.testCompartment = "ocid1.compartment.oc1..aaaaaaaaakr75vvb5yx4nkm7ag7ekvluap7afa2y4zprswuprcnehqecwqga"
    39  }
    40  
    41  func (s *imagesSuite) TestNewImageVersion(c *gc.C) {
    42  	name := "Canonical-Ubuntu-22.04-2017.08.22-0"
    43  	img := ociCore.Image{
    44  		DisplayName: &name,
    45  	}
    46  	timeStamp, _ := time.Parse("2006.01.02", "2017.08.22")
    47  	version, err := oci.NewImageVersion(img)
    48  	c.Assert(err, gc.IsNil)
    49  	c.Assert(version.TimeStamp, gc.Equals, timeStamp)
    50  	c.Assert(version.Revision, gc.Equals, 0)
    51  }
    52  
    53  func (s *imagesSuite) TestNewImageVersionInvalidDate(c *gc.C) {
    54  	name := "Canonical-Ubuntu-22.04-NotARealDate-0"
    55  	img := ociCore.Image{
    56  		DisplayName: &name,
    57  	}
    58  	_, err := oci.NewImageVersion(img)
    59  	c.Assert(err, gc.ErrorMatches, "parsing time for.*")
    60  }
    61  
    62  func (s *imagesSuite) TestNewImageVersionInvalidRevision(c *gc.C) {
    63  	name := "Canonical-Ubuntu-22.04-2017.08.22-IShouldBeNumeric"
    64  	img := ociCore.Image{
    65  		DisplayName: &name,
    66  	}
    67  	_, err := oci.NewImageVersion(img)
    68  	c.Assert(err, gc.ErrorMatches, "parsing revision for.*")
    69  }
    70  
    71  func (s *imagesSuite) TestNewImageVersionInvalidName(c *gc.C) {
    72  	name := "fakeInvalidName"
    73  	img := ociCore.Image{
    74  		DisplayName: &name,
    75  	}
    76  	_, err := oci.NewImageVersion(img)
    77  	c.Assert(err, gc.ErrorMatches, "invalid image display name.*")
    78  
    79  	img = ociCore.Image{}
    80  	_, err = oci.NewImageVersion(img)
    81  	c.Assert(err, gc.ErrorMatches, "image does not have a display name")
    82  }
    83  
    84  func makeStringPointer(name string) *string {
    85  	return &name
    86  }
    87  
    88  func makeIntPointer(name int) *int {
    89  	return &name
    90  }
    91  
    92  func makeUint64Pointer(name uint64) *uint64 {
    93  	return &name
    94  }
    95  
    96  func makeBoolPointer(name bool) *bool {
    97  	return &name
    98  }
    99  func makeFloat32Pointer(name float32) *float32 {
   100  	return &name
   101  }
   102  
   103  func (s *imagesSuite) TestInstanceTypes(c *gc.C) {
   104  	ctrl := gomock.NewController(c)
   105  	compute := ocitesting.NewMockComputeClient(ctrl)
   106  	defer ctrl.Finish()
   107  
   108  	compute.EXPECT().ListShapes(context.Background(), &s.testCompartment, &s.testImageID).Return(listShapesResponse(), nil)
   109  
   110  	types, err := oci.InstanceTypes(compute, &s.testCompartment, &s.testImageID)
   111  	c.Assert(err, gc.IsNil)
   112  	c.Check(types, gc.HasLen, 5)
   113  	expectedTypes := []instances.InstanceType{
   114  		{
   115  			Name:     "VM.Standard1.1",
   116  			Arch:     arch.AMD64,
   117  			Mem:      7 * 1024,
   118  			CpuCores: 1,
   119  			VirtType: makeStringPointer("vm"),
   120  		}, {
   121  			Name:     "VM.GPU.A10.1",
   122  			Arch:     arch.AMD64,
   123  			Mem:      240 * 1024,
   124  			CpuCores: 15,
   125  			VirtType: makeStringPointer("gpu"),
   126  		}, {
   127  			Name:     "BM.Standard.A1.160",
   128  			Arch:     arch.ARM64,
   129  			Mem:      1024 * 1024,
   130  			CpuCores: 160,
   131  			VirtType: makeStringPointer("metal"),
   132  		}, {
   133  			Name:        "VM.Standard.A1.Flex",
   134  			Arch:        arch.ARM64,
   135  			Mem:         6 * 1024,
   136  			MaxCpuCores: makeUint64Pointer(80),
   137  			MaxMem:      makeUint64Pointer(512 * 1024),
   138  			CpuCores:    1,
   139  			VirtType:    makeStringPointer("vm"),
   140  		}, {
   141  			Name:        "VM.Standard3.Flex",
   142  			Arch:        arch.AMD64,
   143  			Mem:         6 * 1024,
   144  			MaxCpuCores: makeUint64Pointer(32),
   145  			MaxMem:      makeUint64Pointer(512 * 1024),
   146  			CpuCores:    1,
   147  			VirtType:    makeStringPointer("vm"),
   148  		},
   149  	}
   150  	c.Assert(types, gc.DeepEquals, expectedTypes)
   151  }
   152  
   153  func (s *imagesSuite) TestInstanceTypesNilClient(c *gc.C) {
   154  	_, err := oci.InstanceTypes(nil, &s.testCompartment, &s.testImageID)
   155  	c.Assert(err, gc.ErrorMatches, "cannot use nil client")
   156  }
   157  
   158  func (s *imagesSuite) TestNewInstanceImageUbuntu(c *gc.C) {
   159  	image := ociCore.Image{
   160  		CompartmentId:          &s.testCompartment,
   161  		Id:                     &s.testImageID,
   162  		OperatingSystem:        makeStringPointer("Canonical Ubuntu"),
   163  		OperatingSystemVersion: makeStringPointer("22.04"),
   164  		DisplayName:            makeStringPointer("Canonical-Ubuntu-22.04-2018.01.11-0"),
   165  	}
   166  
   167  	imgType, arch, err := oci.NewInstanceImage(image, &s.testCompartment)
   168  	c.Assert(err, gc.IsNil)
   169  	c.Check(imgType.ImageType, gc.Equals, oci.ImageTypeGeneric)
   170  	c.Check(imgType.Base.DisplayString(), gc.Equals, "ubuntu@22.04")
   171  	c.Check(imgType.CompartmentId, gc.NotNil)
   172  	c.Check(*imgType.CompartmentId, gc.Equals, s.testCompartment)
   173  	c.Check(imgType.Id, gc.Equals, s.testImageID)
   174  	c.Check(arch, gc.Equals, corearch.AMD64)
   175  }
   176  
   177  // TestNewInstanceImageUbuntuMinimalNotSupported is testing that if an image
   178  // passed to the parser is of type minimal we result in a not supported error.
   179  func (s *imagesSuite) TestNewInstanceImageUbuntuMinimalNotSupported(c *gc.C) {
   180  	tests := []struct {
   181  		Name  string
   182  		Image ociCore.Image
   183  	}{
   184  		{
   185  			Name: "Test minimal image for amd64 in OperatingSystem",
   186  			Image: ociCore.Image{
   187  				CompartmentId:          &s.testCompartment,
   188  				Id:                     &s.testImageID,
   189  				OperatingSystem:        makeStringPointer("Canonical Ubuntu"),
   190  				OperatingSystemVersion: makeStringPointer("22.04 Minimal"),
   191  				DisplayName:            makeStringPointer("Canonical-Ubuntu-22.04-2018.01.11-0"),
   192  			},
   193  		},
   194  		{
   195  			Name: "Test minimal image for amd64 in DisplayName",
   196  			Image: ociCore.Image{
   197  				CompartmentId:          &s.testCompartment,
   198  				Id:                     &s.testImageID,
   199  				OperatingSystem:        makeStringPointer("Canonical Ubuntu"),
   200  				OperatingSystemVersion: makeStringPointer("22.04"),
   201  				DisplayName:            makeStringPointer("Canonical-Ubuntu-22.04-Minimal-2018.01.11-0"),
   202  			},
   203  		},
   204  		{
   205  			Name: "Test minimal image for amd64 in OperatingSystem",
   206  			Image: ociCore.Image{
   207  				CompartmentId:          &s.testCompartment,
   208  				Id:                     &s.testImageID,
   209  				OperatingSystem:        makeStringPointer("Canonical Ubuntu"),
   210  				OperatingSystemVersion: makeStringPointer("22.04 Minimal aarch64"),
   211  				DisplayName:            makeStringPointer("Canonical-Ubuntu-22.04-aarch64-2018.01.11-0"),
   212  			},
   213  		},
   214  		{
   215  			Name: "Test minimal image for amd64 in DisplayName",
   216  			Image: ociCore.Image{
   217  				CompartmentId:          &s.testCompartment,
   218  				Id:                     &s.testImageID,
   219  				OperatingSystem:        makeStringPointer("Canonical Ubuntu"),
   220  				OperatingSystemVersion: makeStringPointer("22.04 aarch64"),
   221  				DisplayName:            makeStringPointer("Canonical-Ubuntu-22.04-Minimal-aarch64-2018.01.11-0"),
   222  			},
   223  		},
   224  	}
   225  
   226  	for _, test := range tests {
   227  		img, _, err := oci.NewInstanceImage(test.Image, &s.testCompartment)
   228  		c.Assert(err, jc.ErrorIsNil)
   229  		c.Check(img.IsMinimal, jc.IsTrue)
   230  	}
   231  }
   232  
   233  func (s *imagesSuite) TestNewInstanceImageUbuntuAARCH64(c *gc.C) {
   234  	image := ociCore.Image{
   235  		CompartmentId:          &s.testCompartment,
   236  		Id:                     &s.testImageID,
   237  		OperatingSystem:        makeStringPointer("Canonical Ubuntu"),
   238  		OperatingSystemVersion: makeStringPointer("22.04 aarch64"),
   239  		DisplayName:            makeStringPointer("Canonical-Ubuntu-22.04-aarch64-2018.01.11-0"),
   240  	}
   241  
   242  	imgType, arch, err := oci.NewInstanceImage(image, &s.testCompartment)
   243  	c.Assert(err, gc.IsNil)
   244  	c.Check(imgType.ImageType, gc.Equals, oci.ImageTypeGeneric)
   245  	c.Check(imgType.Base.DisplayString(), gc.Equals, "ubuntu@22.04")
   246  	c.Check(imgType.CompartmentId, gc.NotNil)
   247  	c.Check(*imgType.CompartmentId, gc.Equals, s.testCompartment)
   248  	c.Check(imgType.Id, gc.Equals, s.testImageID)
   249  	c.Check(arch, gc.Equals, corearch.ARM64)
   250  }
   251  
   252  func (s *imagesSuite) TestNewInstanceImageUbuntuAARCH64OnDisplayName(c *gc.C) {
   253  	image := ociCore.Image{
   254  		CompartmentId:          &s.testCompartment,
   255  		Id:                     &s.testImageID,
   256  		OperatingSystem:        makeStringPointer("Canonical Ubuntu"),
   257  		OperatingSystemVersion: makeStringPointer("22.04"),
   258  		DisplayName:            makeStringPointer("Canonical-Ubuntu-22.04-aarch64-2018.01.11-0"),
   259  	}
   260  
   261  	imgType, arch, err := oci.NewInstanceImage(image, &s.testCompartment)
   262  	c.Assert(err, gc.IsNil)
   263  	c.Check(imgType.ImageType, gc.Equals, oci.ImageTypeGeneric)
   264  	c.Check(imgType.Base.DisplayString(), gc.Equals, "ubuntu@22.04")
   265  	c.Check(imgType.CompartmentId, gc.NotNil)
   266  	c.Check(*imgType.CompartmentId, gc.Equals, s.testCompartment)
   267  	c.Check(imgType.Id, gc.Equals, s.testImageID)
   268  	c.Check(arch, gc.Equals, corearch.ARM64)
   269  }
   270  
   271  func (s *imagesSuite) TestNewInstanceImageUnknownOS(c *gc.C) {
   272  	image := ociCore.Image{
   273  		CompartmentId:          &s.testCompartment,
   274  		Id:                     &s.testImageID,
   275  		OperatingSystem:        makeStringPointer("NotKnownToJuju"),
   276  		OperatingSystemVersion: makeStringPointer("22.04"),
   277  		DisplayName:            makeStringPointer("Canonical-Ubuntu-22.04-2018.01.11-0"),
   278  	}
   279  
   280  	_, _, err := oci.NewInstanceImage(image, &s.testCompartment)
   281  	c.Assert(err, gc.ErrorMatches, "os NotKnownToJuju not supported")
   282  }
   283  
   284  func (s *imagesSuite) TestRefreshImageCache(c *gc.C) {
   285  	ctrl := gomock.NewController(c)
   286  	compute := ocitesting.NewMockComputeClient(ctrl)
   287  	defer ctrl.Finish()
   288  
   289  	fakeUbuntu1 := "fakeUbuntu1"
   290  	fakeUbuntu2 := "fakeUbuntu2"
   291  	fakeUbuntu3 := "fakeUbuntu3"
   292  	fakeUbuntu4 := "fakeUbuntu4"
   293  	fakeUbuntuMinimal0 := "fakeUbuntuMinimal0"
   294  	fakeUbuntuMinimal1 := "fakeUbuntuMinimal1"
   295  	fakeCentOSID := "fakeCentOS"
   296  
   297  	listImageResponse := []ociCore.Image{
   298  		{
   299  			CompartmentId:          &s.testCompartment,
   300  			Id:                     &fakeUbuntu1,
   301  			OperatingSystem:        makeStringPointer("Canonical Ubuntu"),
   302  			OperatingSystemVersion: makeStringPointer("22.04"),
   303  			DisplayName:            makeStringPointer("Canonical-Ubuntu-22.04-2018.01.11-0"),
   304  		},
   305  		{
   306  			CompartmentId:          &s.testCompartment,
   307  			Id:                     &fakeUbuntu2,
   308  			OperatingSystem:        makeStringPointer("Canonical Ubuntu"),
   309  			OperatingSystemVersion: makeStringPointer("22.04"),
   310  			DisplayName:            makeStringPointer("Canonical-Ubuntu-22.04-2018.01.12-0"),
   311  		},
   312  		{
   313  			CompartmentId:          &s.testCompartment,
   314  			Id:                     &fakeUbuntuMinimal0,
   315  			OperatingSystem:        makeStringPointer("Canonical Ubuntu"),
   316  			OperatingSystemVersion: makeStringPointer("22.04 Minimal"),
   317  			DisplayName:            makeStringPointer("Canonical-Ubuntu-22.04-2018.01.12-0"),
   318  		},
   319  		{
   320  			CompartmentId:          &s.testCompartment,
   321  			Id:                     &fakeUbuntuMinimal1,
   322  			OperatingSystem:        makeStringPointer("Canonical Ubuntu"),
   323  			OperatingSystemVersion: makeStringPointer("22.04"),
   324  			DisplayName:            makeStringPointer("Canonical-Ubuntu-22.04-Minimal-2018.01.12-0"),
   325  		},
   326  		{
   327  			CompartmentId:          &s.testCompartment,
   328  			Id:                     &fakeUbuntu3,
   329  			OperatingSystem:        makeStringPointer("Canonical Ubuntu"),
   330  			OperatingSystemVersion: makeStringPointer("22.04 aarch64"),
   331  			DisplayName:            makeStringPointer("Canonical-Ubuntu-22.04-2018.01.11-0"),
   332  		},
   333  		{
   334  			CompartmentId:          &s.testCompartment,
   335  			Id:                     &fakeUbuntu4,
   336  			OperatingSystem:        makeStringPointer("Canonical Ubuntu"),
   337  			OperatingSystemVersion: makeStringPointer("22.04"),
   338  			DisplayName:            makeStringPointer("Canonical-Ubuntu-22.04-aarch64-2018.01.12-0"),
   339  		},
   340  		{
   341  			CompartmentId:          &s.testCompartment,
   342  			Id:                     makeStringPointer("fakeCentOS"),
   343  			OperatingSystem:        makeStringPointer("CentOS"),
   344  			OperatingSystemVersion: makeStringPointer("7"),
   345  			DisplayName:            makeStringPointer("CentOS-7-2017.10.19-0"),
   346  		},
   347  	}
   348  
   349  	compute.EXPECT().ListImages(context.Background(), &s.testCompartment).Return(listImageResponse, nil)
   350  	compute.EXPECT().ListShapes(context.Background(), &s.testCompartment, &fakeUbuntu1).Return(listShapesResponse(), nil)
   351  	compute.EXPECT().ListShapes(context.Background(), &s.testCompartment, &fakeUbuntu2).Return(listShapesResponse(), nil)
   352  	compute.EXPECT().ListShapes(context.Background(), &s.testCompartment, &fakeUbuntu3).Return(listShapesResponse(), nil)
   353  	compute.EXPECT().ListShapes(context.Background(), &s.testCompartment, &fakeUbuntu4).Return(listShapesResponse(), nil)
   354  	compute.EXPECT().ListShapes(context.Background(), &s.testCompartment, &fakeCentOSID).Return(listShapesResponse()[:2], nil)
   355  
   356  	imgCache, err := oci.RefreshImageCache(compute, &s.testCompartment)
   357  	c.Assert(err, gc.IsNil)
   358  	c.Assert(imgCache, gc.NotNil)
   359  	c.Check(imgCache.ImageMap(), gc.HasLen, 2)
   360  
   361  	imageMap := imgCache.ImageMap()
   362  	jammy := corebase.MakeDefaultBase("ubuntu", "22.04")
   363  	// Both archs AMD64 and ARM64 should be on the base jammy and minimal
   364  	// ubuntu should be ignored.
   365  	c.Check(imageMap[jammy], gc.HasLen, 2)
   366  	// Two images on each arch
   367  	c.Check(imageMap[jammy][corearch.AMD64], gc.HasLen, 2)
   368  	c.Check(imageMap[jammy][corearch.ARM64], gc.HasLen, 2)
   369  	// Only AMD64 on centos base
   370  	c.Check(imageMap[corebase.MakeDefaultBase("centos", "7")], gc.HasLen, 1)
   371  	c.Check(imageMap[corebase.MakeDefaultBase("centos", "7")][corearch.AMD64], gc.HasLen, 1)
   372  
   373  	timeStamp, _ := time.Parse("2006.01.02", "2018.01.12")
   374  
   375  	// Check that the first image in the array is the newest one
   376  	c.Assert(imageMap[jammy][corearch.AMD64][0].Version.TimeStamp, gc.Equals, timeStamp)
   377  	c.Assert(imageMap[jammy][corearch.ARM64][0].Version.TimeStamp, gc.Equals, timeStamp)
   378  
   379  	// Check that InstanceTypes are set
   380  	c.Assert(imageMap[jammy][corearch.AMD64][0].InstanceTypes, gc.HasLen, 5)
   381  	c.Assert(imageMap[jammy][corearch.ARM64][0].InstanceTypes, gc.HasLen, 5)
   382  	c.Assert(imageMap[corebase.MakeDefaultBase("centos", "7")][corearch.AMD64][0].InstanceTypes, gc.HasLen, 2)
   383  }
   384  
   385  func (s *imagesSuite) TestRefreshImageCacheFetchFromCache(c *gc.C) {
   386  	ctrl := gomock.NewController(c)
   387  	compute := ocitesting.NewMockComputeClient(ctrl)
   388  	defer ctrl.Finish()
   389  
   390  	compute.EXPECT().ListImages(gomock.Any(), gomock.Any()).Return([]ociCore.Image{}, nil)
   391  
   392  	imgCache, err := oci.RefreshImageCache(compute, &s.testCompartment)
   393  	c.Assert(err, gc.IsNil)
   394  	c.Assert(imgCache, gc.NotNil)
   395  
   396  	fromCache, err := oci.RefreshImageCache(compute, &s.testCompartment)
   397  	c.Assert(err, gc.IsNil)
   398  	c.Check(imgCache, gc.DeepEquals, fromCache)
   399  }
   400  
   401  func (s *imagesSuite) TestRefreshImageCacheStaleCache(c *gc.C) {
   402  	ctrl := gomock.NewController(c)
   403  	compute := ocitesting.NewMockComputeClient(ctrl)
   404  	defer ctrl.Finish()
   405  
   406  	compute.EXPECT().ListImages(gomock.Any(), gomock.Any()).Return([]ociCore.Image{}, nil).Times(2)
   407  
   408  	imgCache, err := oci.RefreshImageCache(compute, &s.testCompartment)
   409  	c.Assert(err, gc.IsNil)
   410  	c.Assert(imgCache, gc.NotNil)
   411  
   412  	now := time.Now()
   413  
   414  	// No need to check the value. gomock will assert if ListImages
   415  	// is not called twice
   416  	imgCache.SetLastRefresh(now.Add(-31 * time.Minute))
   417  	_, err = oci.RefreshImageCache(compute, &s.testCompartment)
   418  	c.Assert(err, gc.IsNil)
   419  }
   420  
   421  func (s *imagesSuite) TestRefreshImageCacheWithInvalidImage(c *gc.C) {
   422  	ctrl := gomock.NewController(c)
   423  	compute := ocitesting.NewMockComputeClient(ctrl)
   424  	defer ctrl.Finish()
   425  
   426  	listImageResponse := []ociCore.Image{
   427  		{
   428  			CompartmentId:          &s.testCompartment,
   429  			Id:                     makeStringPointer("fakeUbuntu1"),
   430  			OperatingSystem:        makeStringPointer("Canonical Ubuntu"),
   431  			OperatingSystemVersion: makeStringPointer("22.04"),
   432  			DisplayName:            makeStringPointer("Canonical-Ubuntu-22.04-2018.01.11-0"),
   433  		},
   434  		{
   435  			CompartmentId:          &s.testCompartment,
   436  			Id:                     makeStringPointer("fake image id for bad image"),
   437  			OperatingSystem:        makeStringPointer("CentOS"),
   438  			OperatingSystemVersion: makeStringPointer("7"),
   439  			DisplayName:            makeStringPointer("BadlyFormatedDisplayName_IshouldBeIgnored"),
   440  		},
   441  	}
   442  	fakeUbuntuID := "fakeUbuntu1"
   443  
   444  	compute.EXPECT().ListImages(context.Background(), &s.testCompartment).Return(listImageResponse, nil)
   445  	// Only list shapes from "fakeUbuntu1" image, because the other one
   446  	// is invalid.
   447  	compute.EXPECT().ListShapes(context.Background(), &s.testCompartment, &fakeUbuntuID).Return(listShapesResponse(), nil)
   448  
   449  	imgCache, err := oci.RefreshImageCache(compute, &s.testCompartment)
   450  	c.Assert(err, gc.IsNil)
   451  	c.Assert(imgCache, gc.NotNil)
   452  	c.Check(imgCache.ImageMap(), gc.HasLen, 1)
   453  	imageMap := imgCache.ImageMap()
   454  
   455  	jammy := corebase.MakeDefaultBase("ubuntu", "22.04")
   456  	c.Check(imageMap[jammy][corearch.AMD64][0].Id, gc.Equals, "fakeUbuntu1")
   457  }
   458  
   459  func (s *imagesSuite) TestImageMetadataFromCache(c *gc.C) {
   460  	image := ociCore.Image{
   461  		CompartmentId:          &s.testCompartment,
   462  		Id:                     &s.testImageID,
   463  		OperatingSystem:        makeStringPointer("Canonical Ubuntu"),
   464  		OperatingSystemVersion: makeStringPointer("22.04"),
   465  		DisplayName:            makeStringPointer("Canonical-Ubuntu-22.04-2018.01.11-0"),
   466  	}
   467  
   468  	imgType, arch, err := oci.NewInstanceImage(image, &s.testCompartment)
   469  	c.Assert(err, gc.IsNil)
   470  	instanceTypes := []instances.InstanceType{
   471  		{
   472  			Arch: "amd64",
   473  		},
   474  	}
   475  	imgType.SetInstanceTypes(instanceTypes)
   476  
   477  	cache := &oci.ImageCache{}
   478  	jammy := corebase.MakeDefaultBase("ubuntu", "22.04")
   479  	images := map[corebase.Base]map[string][]oci.InstanceImage{
   480  		jammy: {
   481  			corearch.AMD64: {
   482  				imgType,
   483  			},
   484  		},
   485  	}
   486  	cache.SetImages(images)
   487  	metadata := cache.ImageMetadata(jammy, arch, "")
   488  	c.Assert(metadata, gc.HasLen, 1)
   489  	// generic images default to ImageTypeVM
   490  	c.Assert(metadata[0].VirtType, gc.Equals, string(oci.ImageTypeVM))
   491  
   492  	// explicitly set ImageTypeBM on generic images
   493  	metadata = cache.ImageMetadata(jammy, arch, string(oci.ImageTypeBM))
   494  	c.Assert(metadata, gc.HasLen, 1)
   495  	c.Assert(metadata[0].VirtType, gc.Equals, string(oci.ImageTypeBM))
   496  }
   497  
   498  func (s *imagesSuite) TestImageMetadataSpecificImageType(c *gc.C) {
   499  	image := ociCore.Image{
   500  		CompartmentId:          &s.testCompartment,
   501  		Id:                     &s.testImageID,
   502  		OperatingSystem:        makeStringPointer("Canonical Ubuntu"),
   503  		OperatingSystemVersion: makeStringPointer("22.04"),
   504  		DisplayName:            makeStringPointer("Canonical-Ubuntu-22.04-Gen2-GPU-2018.01.11-0"),
   505  	}
   506  
   507  	imgType, arch, err := oci.NewInstanceImage(image, &s.testCompartment)
   508  	c.Assert(err, gc.IsNil)
   509  	instanceTypes := []instances.InstanceType{
   510  		{
   511  			Arch: "amd64",
   512  		},
   513  	}
   514  	imgType.SetInstanceTypes(instanceTypes)
   515  
   516  	cache := &oci.ImageCache{}
   517  	jammy := corebase.MakeDefaultBase("ubuntu", "22.04")
   518  	images := map[corebase.Base]map[string][]oci.InstanceImage{
   519  		jammy: {
   520  			corearch.AMD64: {
   521  				imgType,
   522  			},
   523  		},
   524  	}
   525  	cache.SetImages(images)
   526  	metadata := cache.ImageMetadata(jammy, arch, "")
   527  	c.Assert(metadata, gc.HasLen, 1)
   528  	// generic images default to ImageTypeVM
   529  	c.Assert(metadata[0].VirtType, gc.Equals, string(oci.ImageTypeGPU))
   530  
   531  	// explicitly set ImageTypeBM on generic images
   532  	metadata = cache.ImageMetadata(jammy, arch, string(oci.ImageTypeBM))
   533  	c.Assert(metadata, gc.HasLen, 1)
   534  	c.Assert(metadata[0].VirtType, gc.Equals, string(oci.ImageTypeGPU))
   535  }