Skip to content

Commit

Permalink
Remove SeriesSelector
Browse files Browse the repository at this point in the history
Replace it with BaseSelector

This is part of the ongoing task to replace series with base

In most places, BaseSelector and SeriesSelector behave the same. There
are a few notable exceptions. BaseSelector prefers the latest LTS over
the charm's default, which results in some unit test failures.

Also, as a flyby, change NewCharmAtPath to use a base instead of a
series
  • Loading branch information
jack-w-shaw committed Aug 15, 2023
1 parent d6207b5 commit 4266d6c
Show file tree
Hide file tree
Showing 39 changed files with 319 additions and 936 deletions.
128 changes: 45 additions & 83 deletions cmd/juju/application/deploy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"path/filepath"
"regexp"
"runtime"
"runtime/debug"
"sort"
"strings"
"time"
Expand All @@ -19,6 +20,7 @@ import (
"github.com/juju/cmd/v3"
"github.com/juju/cmd/v3/cmdtesting"
"github.com/juju/collections/set"
"github.com/juju/collections/transform"
"github.com/juju/errors"
"github.com/juju/gnuflag"
"github.com/juju/loggo"
Expand Down Expand Up @@ -148,15 +150,9 @@ func (s *DeploySuiteBase) SetUpTest(c *gc.C) {
}
s.RepoSuite.SetUpTest(c)

// TODO: remove this patch once we removed all the old series from tests in current package.
s.PatchValue(&deployer.SupportedJujuSeries,
func(time.Time, string, string) (set.Strings, error) {
return set.NewStrings(
"centos7", "centos9", "genericlinux", "kubernetes",
"jammy", "focal", "jammy", "xenial",
), nil
},
)
s.PatchValue(&deployer.SupportedJujuBases, func(time.Time, corebase.Base, string) ([]corebase.Base, error) {
return transform.SliceOrErr([]string{"ubuntu@22.04", "ubuntu@20.04", "ubuntu@18.04"}, corebase.ParseBaseFromString)
})

s.CmdBlockHelper = coretesting.NewCmdBlockHelper(s.APIState)
c.Assert(s.CmdBlockHelper, gc.NotNil)
Expand Down Expand Up @@ -366,9 +362,9 @@ func (s *DeploySuite) TestDeployFromPathOldCharm(c *gc.C) {
}

func (s *DeploySuite) TestDeployFromPathOldCharmMissingSeries(c *gc.C) {
path := testcharms.RepoWithSeries("bionic").ClonedDirPath(c.MkDir(), "dummy")
path := testcharms.RepoWithSeries("bionic").ClonedDirPath(c.MkDir(), "dummy-no-series")
err := s.runDeploy(c, path)
c.Assert(err, gc.ErrorMatches, "series not specified and charm does not define any")
c.Assert(err, gc.ErrorMatches, "charm does not define any bases, not valid")
}

func (s *DeploySuite) TestDeployFromPathOldCharmMissingSeriesUseDefaultSeries(c *gc.C) {
Expand Down Expand Up @@ -415,31 +411,27 @@ func (s *DeploySuite) TestDeployFromPath(c *gc.C) {
}

func (s *DeploySuite) TestDeployFromPathUnsupportedSeriesHaveOverlap(c *gc.C) {
// Donot remove this because we want to test: series supported by the charm and series supported by Juju have overlap.
s.PatchValue(&deployer.SupportedJujuSeries,
func(time.Time, string, string) (set.Strings, error) {
return set.NewStrings(
"jammy", "focal",
), nil
},
)
// Do not remove this because we want to test: bases supported by the charm and bases supported by Juju have overlap.
s.PatchValue(&deployer.SupportedJujuBases, func(time.Time, corebase.Base, string) ([]corebase.Base, error) {
return transform.SliceOrErr([]string{"ubuntu@22.04", "ubuntu@20.04", "ubuntu@12.10"}, corebase.ParseBaseFromString)
})

path := testcharms.RepoWithSeries("bionic").ClonedDirPath(c.MkDir(), "multi-series")
err := s.runDeploy(c, path, "--base", "ubuntu@12.10")
c.Assert(err, gc.ErrorMatches, `series "quantal" is not supported, supported series are: focal,jammy`)
c.Assert(err, gc.ErrorMatches, `base "ubuntu@12.10/stable" is not supported, supported bases are: .*`)
}

func (s *DeploySuite) TestDeployFromPathUnsupportedSeriesHaveNoOverlap(c *gc.C) {
// Donot remove this because we want to test: series supported by the charm and series supported by Juju have NO overlap.
s.PatchValue(&deployer.SupportedJujuSeries,
func(time.Time, string, string) (set.Strings, error) {
return set.NewStrings("kinetic"), nil
func (s *DeploySuite) TestDeployFromPathUnsupportedBaseHaveNoOverlap(c *gc.C) {
// Do not remove this because we want to test: bases supported by the charm and bases supported by Juju have NO overlap.
s.PatchValue(&deployer.SupportedJujuBases,
func(time.Time, corebase.Base, string) ([]corebase.Base, error) {
return []corebase.Base{corebase.MustParseBaseFromString("ubuntu@22.10")}, nil
},
)

path := testcharms.RepoWithSeries("bionic").ClonedDirPath(c.MkDir(), "multi-series")
err := s.runDeploy(c, path, "--base", "ubuntu@12.10")
c.Assert(err, gc.ErrorMatches, `multi-series is not available on the following series: quantal`)
err := s.runDeploy(c, path)
c.Assert(err, gc.ErrorMatches, `the charm defined bases ".*" not supported`)
}

func (s *DeploySuite) TestDeployFromPathUnsupportedSeriesForce(c *gc.C) {
Expand All @@ -448,14 +440,9 @@ func (s *DeploySuite) TestDeployFromPathUnsupportedSeriesForce(c *gc.C) {
withLocalCharmDeployable(s.fakeAPI, curl, charmDir, false)
withCharmDeployable(s.fakeAPI, curl, corebase.MustParseBaseFromString("ubuntu@20.04"), charmDir.Meta(), charmDir.Metrics(), false, false, 1, nil, nil)

// TODO: remove this patch once we removed all the old series from tests in current package.
s.PatchValue(&deployer.SupportedJujuSeries,
func(time.Time, string, string) (set.Strings, error) {
return set.NewStrings(
"jammy", "focal", "jammy", "xenial", "quantal",
), nil
},
)
s.PatchValue(&deployer.SupportedJujuBases, func(time.Time, corebase.Base, string) ([]corebase.Base, error) {
return transform.SliceOrErr([]string{"ubuntu@22.04", "ubuntu@20.04", "ubuntu@18.04", "ubuntu@12.10"}, corebase.ParseBaseFromString)
})

err := s.runDeployForState(c, charmDir.Path, "--base", "ubuntu@12.10", "--force")
c.Assert(err, jc.ErrorIsNil)
Expand All @@ -468,14 +455,9 @@ func (s *DeploySuite) TestDeployFromPathUnsupportedLXDProfileForce(c *gc.C) {
withLocalCharmDeployable(s.fakeAPI, curl, charmDir, false)
withCharmDeployable(s.fakeAPI, curl, corebase.MustParseBaseFromString("ubuntu@20.04"), charmDir.Meta(), charmDir.Metrics(), false, true, 1, nil, nil)

// TODO: remove this patch once we removed all the old series from tests in current package.
s.PatchValue(&deployer.SupportedJujuSeries,
func(time.Time, string, string) (set.Strings, error) {
return set.NewStrings(
"jammy", "focal", "jammy", "xenial", "quantal",
), nil
},
)
s.PatchValue(&deployer.SupportedJujuBases, func(time.Time, corebase.Base, string) ([]corebase.Base, error) {
return transform.SliceOrErr([]string{"ubuntu@22.04", "ubuntu@20.04", "ubuntu@18.04", "ubuntu@12.10"}, corebase.ParseBaseFromString)
})

err := s.runDeployForState(c, charmDir.Path, "--base", "ubuntu@12.10", "--force")
c.Assert(err, jc.ErrorIsNil)
Expand Down Expand Up @@ -1038,15 +1020,10 @@ func (s *CAASDeploySuiteBase) expectDeployer(c *gc.C, cfg deployer.DeployerConfi

func (s *CAASDeploySuiteBase) SetUpTest(c *gc.C) {

// TODO: remove this patch once we removed all the old series from tests in current package.
s.PatchValue(&deployer.SupportedJujuSeries,
func(time.Time, string, string) (set.Strings, error) {
return set.NewStrings(
"centos7", "centos9", "genericlinux", "kubernetes",
"jammy", "focal", "jammy", "xenial",
), nil
},
)
s.PatchValue(&deployer.SupportedJujuBases, func(time.Time, corebase.Base, string) ([]corebase.Base, error) {
return transform.SliceOrErr([]string{"ubuntu@22.04", "ubuntu@20.04", "ubuntu@18.04"}, corebase.ParseBaseFromString)
})

cookiesFile := filepath.Join(c.MkDir(), ".go-cookies")
s.PatchEnvironment("JUJU_COOKIEFILE", cookiesFile)

Expand Down Expand Up @@ -1217,9 +1194,9 @@ func (s *CAASDeploySuite) TestDevices(c *gc.C) {

func (s *DeploySuite) TestDeployStorageFailContainer(c *gc.C) {
charmDir := testcharms.RepoWithSeries("bionic").ClonedDir(c.MkDir(), "multi-series")
curl := charm.MustParseURL("local:focal/multi-series-1")
curl := charm.MustParseURL("local:jammy/multi-series-1")
withLocalCharmDeployable(s.fakeAPI, curl, charmDir, false)
withCharmDeployable(s.fakeAPI, curl, corebase.MustParseBaseFromString("ubuntu@20.04"), charmDir.Meta(), charmDir.Metrics(), false, false, 1, nil, nil)
withCharmDeployable(s.fakeAPI, curl, corebase.MustParseBaseFromString("ubuntu@22.04"), charmDir.Meta(), charmDir.Metrics(), false, false, 1, nil, nil)

machine, err := s.State.AddMachine(state.UbuntuBase("22.04"), state.JobHostUnits)
c.Assert(err, jc.ErrorIsNil)
Expand Down Expand Up @@ -1446,24 +1423,19 @@ func (s *DeploySuite) TestDeployLocalWithSeriesMismatchReturnsError(c *gc.C) {

_, _, err := s.runDeployWithOutput(c, charmDir.Path, "--base", "ubuntu@12.10")

c.Check(err, gc.ErrorMatches, `terms1 is not available on the following series: quantal not supported`)
c.Check(err, gc.ErrorMatches, `terms1 is not available on the following base: ubuntu@12.10/stable`)
}

func (s *DeploySuite) TestDeployLocalWithSeriesAndForce(c *gc.C) {
s.PatchValue(&deployer.SupportedJujuBases, func(time.Time, corebase.Base, string) ([]corebase.Base, error) {
return transform.SliceOrErr([]string{"ubuntu@22.04", "ubuntu@20.04", "ubuntu@18.04", "ubuntu@12.10"}, corebase.ParseBaseFromString)
})

charmDir := testcharms.RepoWithSeries("quantal").ClonedDir(c.MkDir(), "terms1")
curl := charm.MustParseURL("local:quantal/terms1-1")
withLocalCharmDeployable(s.fakeAPI, curl, charmDir, true)
withCharmDeployable(s.fakeAPI, curl, defaultBase, charmDir.Meta(), charmDir.Metrics(), false, true, 1, nil, nil)

// TODO: remove this patch once we removed all the old series from tests in current package.
s.PatchValue(&deployer.SupportedJujuSeries,
func(time.Time, string, string) (set.Strings, error) {
return set.NewStrings(
"jammy", "focal", "jammy", "xenial", "quantal",
), nil
},
)

err := s.runDeployForState(c, charmDir.Path, "--base", "ubuntu@12.10", "--force")
c.Assert(err, jc.ErrorIsNil)
s.AssertApplication(c, "terms1", curl, 1, 0)
Expand All @@ -1479,15 +1451,9 @@ func (s *DeploySuite) setupNonESMBase(c *gc.C) (corebase.Base, string) {
supportedNotEMS := supported.Difference(set.NewStrings(corebase.ESMSupportedJujuSeries()...))
c.Assert(supportedNotEMS.Size(), jc.GreaterThan, 0)

// TODO: remove this patch once we removed all the old series from tests in current package.
s.PatchValue(&deployer.SupportedJujuSeries,
func(time.Time, string, string) (set.Strings, error) {
return set.NewStrings(
"centos7", "centos9", "genericlinux", "kubernetes",
"jammy", "focal", "jammy", "xenial",
), nil
},
)
s.PatchValue(&deployer.SupportedJujuBases, func(time.Time, corebase.Base, string) ([]corebase.Base, error) {
return transform.SliceOrErr([]string{"centos@7", "centos@9", "ubuntu@22.04", "ubuntu@20.04", "ubuntu@16.04"}, corebase.ParseBaseFromString)
})

nonEMSSeries := supportedNotEMS.SortedValues()[0]

Expand Down Expand Up @@ -1524,6 +1490,7 @@ func (s *DeploySuite) setupNonESMBase(c *gc.C) (corebase.Base, string) {
// TODO (stickupkid): Remove this test once we remove series in 3.2
func (s *DeploySuite) TestDeployLocalWithSupportedNonESMSeries(c *gc.C) {
nonEMSBase, loggingPath := s.setupNonESMBase(c)
fmt.Println(nonEMSBase)
err := s.runDeploy(c, loggingPath, "--base", nonEMSBase.String())
c.Logf("%+v", s.fakeAPI.Calls())
c.Assert(err, jc.ErrorIsNil)
Expand All @@ -1533,7 +1500,7 @@ func (s *DeploySuite) TestDeployLocalWithSupportedNonESMSeries(c *gc.C) {
func (s *DeploySuite) TestDeployLocalWithNotSupportedNonESMSeries(c *gc.C) {
_, loggingPath := s.setupNonESMBase(c)
err := s.runDeploy(c, loggingPath, "--base", "ubuntu@17.10")
c.Assert(err, gc.ErrorMatches, "logging is not available on the following series: artful not supported")
c.Assert(err, gc.ErrorMatches, "logging is not available on the following base: ubuntu@17.10/stable")
}

// setupConfigFile creates a configuration file for testing set
Expand Down Expand Up @@ -1907,15 +1874,9 @@ var _ = gc.Suite(&DeployUnitTestSuite{})
func (s *DeployUnitTestSuite) SetUpTest(c *gc.C) {
s.IsolationSuite.SetUpTest(c)

// TODO: remove this patch once we removed all the old series from tests in current package.
s.PatchValue(&deployer.SupportedJujuSeries,
func(time.Time, string, string) (set.Strings, error) {
return set.NewStrings(
"centos7", "centos9", "genericlinux", "kubernetes",
"jammy", "focal", "jammy", "xenial",
), nil
},
)
s.PatchValue(&deployer.SupportedJujuBases, func(time.Time, corebase.Base, string) ([]corebase.Base, error) {
return transform.SliceOrErr([]string{"ubuntu@22.04", "ubuntu@20.04", "ubuntu@18.04"}, corebase.ParseBaseFromString)
})

cookiesFile := filepath.Join(c.MkDir(), ".go-cookies")
s.PatchEnvironment("JUJU_COOKIEFILE", cookiesFile)
Expand Down Expand Up @@ -2292,6 +2253,7 @@ func (f *fakeDeployAPI) ModelUUID() (string, bool) {
func (f *fakeDeployAPI) AddLocalCharm(url *charm.URL, ch charm.Charm, force bool) (*charm.URL, error) {
results := f.MethodCall(f, "AddLocalCharm", url, ch, force)
if results == nil {
debug.PrintStack()
return nil, errors.NotFoundf("registered API call AddLocalCharm %v", url)
}
return results[0].(*charm.URL), jujutesting.TypeAssertError(results[1])
Expand Down
6 changes: 1 addition & 5 deletions cmd/juju/application/deployer/bundlehandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -711,11 +711,7 @@ func (h *bundleHandler) addLocalCharm(chParams bundlechanges.AddCharmParams, chB
charmPath = filepath.Join(h.bundleDir, charmPath)
}

chSeries, err := corebase.GetSeriesFromBase(chBase)
if err != nil {
return errors.Annotatef(err, "cannot deploy local charm at %q", charmPath)
}
ch, curl, err := corecharm.NewCharmAtPathForceSeries(charmPath, chSeries, h.force)
ch, curl, err := corecharm.NewCharmAtPathForceBase(charmPath, chBase, h.force)
if err != nil {
return errors.Annotatef(err, "cannot deploy local charm at %q", charmPath)
}
Expand Down
Loading

0 comments on commit 4266d6c

Please sign in to comment.