~dave-cheney/juju-core/160-hack-default-logger

« back to all changes in this revision

Viewing changes to state/state_test.go

[r=dimitern] state: Add SetEnvironAgentVersion

Implemented a SetEnvironAgentVersion state call, which:
1. Ensures the current environment has a valid agent-version;
2. Finds all machines and units in state that have an empty
or different tools version;
3. Changes the agent-version in the environment, asserting it
haven't changed in the mean time.

This is a prerequisite step to changing upgrage-juju command
to default to major.minor+2 steps, unless forced with --version.

https://codereview.appspot.com/14486043/

R=fwereade, rogpeppe

Show diffs side-by-side

added added

removed removed

Lines of Context:
1846
1846
        c.Assert(state.ContainerTypeFromId("0/lxc/1/kvm/0"), gc.Equals, instance.KVM)
1847
1847
}
1848
1848
 
 
1849
func (s *StateSuite) TestSetEnvironAgentVersionErrors(c *gc.C) {
 
1850
        // Get the agent-version set in the environment.
 
1851
        envConfig, err := s.State.EnvironConfig()
 
1852
        c.Assert(err, gc.IsNil)
 
1853
        agentVersion, ok := envConfig.AgentVersion()
 
1854
        c.Assert(ok, jc.IsTrue)
 
1855
        stringVersion := agentVersion.String()
 
1856
 
 
1857
        // Add 4 machines: one with a different version, one with an
 
1858
        // empty version, one with the current version, and one with
 
1859
        // the new version.
 
1860
        machine0, err := s.State.AddMachine("series", state.JobHostUnits)
 
1861
        c.Assert(err, gc.IsNil)
 
1862
        err = machine0.SetAgentVersion(version.MustParseBinary("9.9.9-series-arch"))
 
1863
        c.Assert(err, gc.IsNil)
 
1864
        machine1, err := s.State.AddMachine("series", state.JobHostUnits)
 
1865
        c.Assert(err, gc.IsNil)
 
1866
        machine2, err := s.State.AddMachine("series", state.JobHostUnits)
 
1867
        c.Assert(err, gc.IsNil)
 
1868
        err = machine2.SetAgentVersion(version.MustParseBinary(stringVersion + "-series-arch"))
 
1869
        c.Assert(err, gc.IsNil)
 
1870
        machine3, err := s.State.AddMachine("series", state.JobHostUnits)
 
1871
        c.Assert(err, gc.IsNil)
 
1872
        err = machine3.SetAgentVersion(version.MustParseBinary("4.5.6-series-arch"))
 
1873
        c.Assert(err, gc.IsNil)
 
1874
 
 
1875
        // Verify machine0 and machine1 are reported as error.
 
1876
        err = s.State.SetEnvironAgentVersion(version.MustParse("4.5.6"))
 
1877
        expectErr := fmt.Sprintf("some agents have not upgraded to the current environment version %s: machine-0, machine-1", stringVersion)
 
1878
        c.Assert(err, gc.ErrorMatches, expectErr)
 
1879
        c.Assert(err, jc.Satisfies, state.IsVersionInconsistentError)
 
1880
 
 
1881
        // Add a service and 4 units: one with a different version, one
 
1882
        // with an empty version, one with the current version, and one
 
1883
        // with the new version.
 
1884
        service, err := s.State.AddService("wordpress", s.AddTestingCharm(c, "wordpress"))
 
1885
        c.Assert(err, gc.IsNil)
 
1886
        unit0, err := service.AddUnit()
 
1887
        c.Assert(err, gc.IsNil)
 
1888
        err = unit0.SetAgentVersion(version.MustParseBinary("6.6.6-series-arch"))
 
1889
        c.Assert(err, gc.IsNil)
 
1890
        _, err = service.AddUnit()
 
1891
        c.Assert(err, gc.IsNil)
 
1892
        unit2, err := service.AddUnit()
 
1893
        c.Assert(err, gc.IsNil)
 
1894
        err = unit2.SetAgentVersion(version.MustParseBinary(stringVersion + "-series-arch"))
 
1895
        c.Assert(err, gc.IsNil)
 
1896
        unit3, err := service.AddUnit()
 
1897
        c.Assert(err, gc.IsNil)
 
1898
        err = unit3.SetAgentVersion(version.MustParseBinary("4.5.6-series-arch"))
 
1899
        c.Assert(err, gc.IsNil)
 
1900
 
 
1901
        // Verify unit0 and unit1 are reported as error, along with the
 
1902
        // machines from before.
 
1903
        err = s.State.SetEnvironAgentVersion(version.MustParse("4.5.6"))
 
1904
        expectErr = fmt.Sprintf("some agents have not upgraded to the current environment version %s: machine-0, machine-1, unit-wordpress-0, unit-wordpress-1", stringVersion)
 
1905
        c.Assert(err, gc.ErrorMatches, expectErr)
 
1906
        c.Assert(err, jc.Satisfies, state.IsVersionInconsistentError)
 
1907
 
 
1908
        // Now remove the machines.
 
1909
        for _, machine := range []*state.Machine{machine0, machine1, machine2} {
 
1910
                err = machine.EnsureDead()
 
1911
                c.Assert(err, gc.IsNil)
 
1912
                err = machine.Remove()
 
1913
                c.Assert(err, gc.IsNil)
 
1914
        }
 
1915
 
 
1916
        // Verify only the units are reported as error.
 
1917
        err = s.State.SetEnvironAgentVersion(version.MustParse("4.5.6"))
 
1918
        expectErr = fmt.Sprintf("some agents have not upgraded to the current environment version %s: unit-wordpress-0, unit-wordpress-1", stringVersion)
 
1919
        c.Assert(err, gc.ErrorMatches, expectErr)
 
1920
        c.Assert(err, jc.Satisfies, state.IsVersionInconsistentError)
 
1921
}
 
1922
 
 
1923
func (s *StateSuite) prepareAgentVersionTests(c *gc.C) (*config.Config, string) {
 
1924
        // Get the agent-version set in the environment.
 
1925
        envConfig, err := s.State.EnvironConfig()
 
1926
        c.Assert(err, gc.IsNil)
 
1927
        agentVersion, ok := envConfig.AgentVersion()
 
1928
        c.Assert(ok, jc.IsTrue)
 
1929
        currentVersion := agentVersion.String()
 
1930
 
 
1931
        // Add a machine and a unit with the current version.
 
1932
        machine, err := s.State.AddMachine("series", state.JobHostUnits)
 
1933
        c.Assert(err, gc.IsNil)
 
1934
        service, err := s.State.AddService("wordpress", s.AddTestingCharm(c, "wordpress"))
 
1935
        c.Assert(err, gc.IsNil)
 
1936
        unit, err := service.AddUnit()
 
1937
        c.Assert(err, gc.IsNil)
 
1938
 
 
1939
        err = machine.SetAgentVersion(version.MustParseBinary(currentVersion + "-series-arch"))
 
1940
        c.Assert(err, gc.IsNil)
 
1941
        err = unit.SetAgentVersion(version.MustParseBinary(currentVersion + "-series-arch"))
 
1942
        c.Assert(err, gc.IsNil)
 
1943
 
 
1944
        return envConfig, currentVersion
 
1945
}
 
1946
 
 
1947
func (s *StateSuite) changeEnviron(c *gc.C, envConfig *config.Config, name string, value interface{}) {
 
1948
        attrs := envConfig.AllAttrs()
 
1949
        attrs[name] = value
 
1950
        newConfig, err := config.New(config.NoDefaults, attrs)
 
1951
        c.Assert(err, gc.IsNil)
 
1952
        c.Assert(s.State.SetEnvironConfig(newConfig), gc.IsNil)
 
1953
}
 
1954
 
 
1955
func (s *StateSuite) assertAgentVersion(c *gc.C, envConfig *config.Config, vers string) {
 
1956
        envConfig, err := s.State.EnvironConfig()
 
1957
        c.Assert(err, gc.IsNil)
 
1958
        agentVersion, ok := envConfig.AgentVersion()
 
1959
        c.Assert(ok, jc.IsTrue)
 
1960
        c.Assert(agentVersion.String(), gc.Equals, vers)
 
1961
}
 
1962
 
 
1963
func (s *StateSuite) TestSetEnvironAgentVersionRetriesOnConfigChange(c *gc.C) {
 
1964
        envConfig, _ := s.prepareAgentVersionTests(c)
 
1965
 
 
1966
        // Set up a transaction hook to change something
 
1967
        // other than the version, and make sure it retries
 
1968
        // and passes.
 
1969
        defer state.SetBeforeHooks(c, s.State, func() {
 
1970
                s.changeEnviron(c, envConfig, "default-series", "foo")
 
1971
        }).Check()
 
1972
 
 
1973
        // Change the agent-version and ensure it has changed.
 
1974
        err := s.State.SetEnvironAgentVersion(version.MustParse("4.5.6"))
 
1975
        c.Assert(err, gc.IsNil)
 
1976
        s.assertAgentVersion(c, envConfig, "4.5.6")
 
1977
}
 
1978
 
 
1979
func (s *StateSuite) TestSetEnvironAgentVersionSucceedsWithSameVersion(c *gc.C) {
 
1980
        envConfig, _ := s.prepareAgentVersionTests(c)
 
1981
 
 
1982
        // Set up a transaction hook to change the version
 
1983
        // to the new one, and make sure it retries
 
1984
        // and passes.
 
1985
        defer state.SetBeforeHooks(c, s.State, func() {
 
1986
                s.changeEnviron(c, envConfig, "agent-version", "4.5.6")
 
1987
        }).Check()
 
1988
 
 
1989
        // Change the agent-version and verify.
 
1990
        err := s.State.SetEnvironAgentVersion(version.MustParse("4.5.6"))
 
1991
        c.Assert(err, gc.IsNil)
 
1992
        s.assertAgentVersion(c, envConfig, "4.5.6")
 
1993
}
 
1994
 
 
1995
func (s *StateSuite) TestSetEnvironAgentVersionExcessiveContention(c *gc.C) {
 
1996
        envConfig, currentVersion := s.prepareAgentVersionTests(c)
 
1997
 
 
1998
        // Set a hook to change the config 5 times
 
1999
        // to test we return ErrExcessiveContention.
 
2000
        changeFuncs := []func(){
 
2001
                func() { s.changeEnviron(c, envConfig, "default-series", "1") },
 
2002
                func() { s.changeEnviron(c, envConfig, "default-series", "2") },
 
2003
                func() { s.changeEnviron(c, envConfig, "default-series", "3") },
 
2004
                func() { s.changeEnviron(c, envConfig, "default-series", "4") },
 
2005
                func() { s.changeEnviron(c, envConfig, "default-series", "5") },
 
2006
        }
 
2007
        defer state.SetBeforeHooks(c, s.State, changeFuncs...).Check()
 
2008
        err := s.State.SetEnvironAgentVersion(version.MustParse("4.5.6"))
 
2009
        c.Assert(err, gc.Equals, state.ErrExcessiveContention)
 
2010
        // Make sure the version remained the same.
 
2011
        s.assertAgentVersion(c, envConfig, currentVersion)
 
2012
}
 
2013
 
1849
2014
type waiter interface {
1850
2015
        Wait() error
1851
2016
}