// Validate makes sure that any labels specifed in Storage or Interfaces // are unique, and that the required specifications are valid. func (a *AllocateMachineArgs) Validate() error { storageLabels := set.NewStrings() for _, spec := range a.Storage { if err := spec.Validate(); err != nil { return errors.Annotate(err, "Storage") } if spec.Label != "" { if storageLabels.Contains(spec.Label) { return errors.NotValidf("reusing storage label %q", spec.Label) } storageLabels.Add(spec.Label) } } interfaceLabels := set.NewStrings() for _, spec := range a.Interfaces { if err := spec.Validate(); err != nil { return errors.Annotate(err, "Interfaces") } if interfaceLabels.Contains(spec.Label) { return errors.NotValidf("reusing interface label %q", spec.Label) } interfaceLabels.Add(spec.Label) } for _, v := range a.NotSpace { if v == "" { return errors.NotValidf("empty NotSpace constraint") } } return nil }
func (s *filesSuite) checkSameStrings(c *gc.C, actual, expected []string) { sActual := set.NewStrings(actual...) sExpected := set.NewStrings(expected...) sActualOnly := sActual.Difference(sExpected) sExpectedOnly := sExpected.Difference(sActual) if !sActualOnly.IsEmpty() || !sExpectedOnly.IsEmpty() { c.Error("strings mismatch") onlyActual := sActualOnly.Values() onlyExpected := sExpectedOnly.Values() sort.Strings(onlyActual) sort.Strings(onlyExpected) if !sActualOnly.IsEmpty() { c.Log("...unexpected values:") for _, str := range onlyActual { c.Log(" " + str) } } if !sExpectedOnly.IsEmpty() { c.Log("...missing values:") for _, str := range onlyExpected { c.Log(" " + str) } } } }
func (s *DeployLocalSuite) assertMachines(c *gc.C, service *state.Application, expectCons constraints.Value, expectIds ...string) { units, err := service.AllUnits() c.Assert(err, jc.ErrorIsNil) c.Assert(units, gc.HasLen, len(expectIds)) // first manually tell state to assign all the units for _, unit := range units { id := unit.Tag().Id() res, err := s.State.AssignStagedUnits([]string{id}) c.Assert(err, jc.ErrorIsNil) c.Assert(res[0].Error, jc.ErrorIsNil) c.Assert(res[0].Unit, gc.Equals, id) } // refresh the list of units from state units, err = service.AllUnits() c.Assert(err, jc.ErrorIsNil) c.Assert(units, gc.HasLen, len(expectIds)) unseenIds := set.NewStrings(expectIds...) for _, unit := range units { id, err := unit.AssignedMachineId() c.Assert(err, jc.ErrorIsNil) unseenIds.Remove(id) machine, err := s.State.Machine(id) c.Assert(err, jc.ErrorIsNil) cons, err := machine.Constraints() c.Assert(err, jc.ErrorIsNil) c.Assert(cons, gc.DeepEquals, expectCons) } c.Assert(unseenIds, gc.DeepEquals, set.NewStrings()) }
func (s *MigrationSuite) TestSSHHostKeyDocFields(c *gc.C) { ignored := set.NewStrings() migrated := set.NewStrings( "Keys", ) s.AssertExportedFields(c, sshHostKeysDoc{}, migrated.Union(ignored)) }
func (s *MigrationSuite) TestBlockDeviceFields(c *gc.C) { ignored := set.NewStrings( "DocID", "ModelUUID", // We manage machine through containment. "Machine", ) migrated := set.NewStrings( "BlockDevices", ) s.AssertExportedFields(c, blockDevicesDoc{}, migrated.Union(ignored)) // The meat is in the type stored in "BlockDevices". migrated = set.NewStrings( "DeviceName", "DeviceLinks", "Label", "UUID", "HardwareId", "BusAddress", "Size", "FilesystemType", "InUse", "MountPoint", ) s.AssertExportedFields(c, BlockDeviceInfo{}, migrated) }
// AllProvisionedStateServersReady returns true if and only if all state servers // that have been started by the provisioner have called EnsureUpgradeInfo with // matching versions. // // When this returns true the master state state server can begin it's // own upgrade. func (info *UpgradeInfo) AllProvisionedStateServersReady() (bool, error) { // Get current state servers. stateServerInfo, err := info.st.StateServerInfo() if err != nil { return false, errors.Annotate(err, "cannot read state servers") } // Extract current and provisioned state servers. sel := bson.D{{ "_id", bson.D{{"$in", stateServerInfo.MachineIds}}, }} instanceData, closer := info.st.getCollection(instanceDataC) defer closer() iter := instanceData.Find(sel).Select(bson.D{{"_id", 1}}).Iter() var doc struct { Id string `bson:"_id"` } provisionedMachineIds := set.NewStrings() for iter.Next(&doc) { provisionedMachineIds.Add(doc.Id) } if err := iter.Close(); err != nil { return false, errors.Annotate(err, "cannot read provisioned machines") } // Find provisioned state machines that haven't indicated // themselves as ready for upgrade. missingMachineIds := provisionedMachineIds.Difference( set.NewStrings(info.doc.StateServersReady...), ) return missingMachineIds.IsEmpty(), nil }
func (s *facadeVersionSuite) TestFacadeVersionsMatchServerVersions(c *gc.C) { // The client side code doesn't want to directly import the server side // code just to list out what versions are available. However, we do // want to make sure that the two sides are kept in sync. clientFacadeNames := set.NewStrings() for name, version := range *api.FacadeVersions { clientFacadeNames.Add(name) // All versions should now be non-zero. c.Check(version, jc.GreaterThan, 0) } // Register the components. all.RegisterForServer() allServerFacades := common.Facades.List() serverFacadeNames := set.NewStrings() serverFacadeBestVersions := make(map[string]int, len(allServerFacades)) for _, facade := range allServerFacades { serverFacadeNames.Add(facade.Name) serverFacadeBestVersions[facade.Name] = facade.Versions[len(facade.Versions)-1] } // First check that both sides know about all the same versions c.Check(serverFacadeNames.Difference(clientFacadeNames).SortedValues(), gc.HasLen, 0) c.Check(clientFacadeNames.Difference(serverFacadeNames).SortedValues(), gc.HasLen, 0) // Next check that the best versions match c.Check(*api.FacadeVersions, jc.DeepEquals, serverFacadeBestVersions) }
func (s *MainSuite) TestHelpCommands(c *gc.C) { // Check that we have correctly registered all the commands // by checking the help output. // First check default commands, and then check commands that are // activated by feature flags. // remove features behind dev_flag for the first test // since they are not enabled. cmdSet := set.NewStrings(commandNames...) // 1. Default Commands. Disable all features. setFeatureFlags("") // Use sorted values here so we can better see what is wrong. registered := getHelpCommandNames(c) unknown := registered.Difference(cmdSet) c.Assert(unknown, jc.DeepEquals, set.NewStrings()) missing := cmdSet.Difference(registered) c.Assert(missing, jc.DeepEquals, set.NewStrings()) // 2. Enable development features, and test again. cmdSet = cmdSet.Union(commandNamesBehindFlags) setFeatureFlags(strings.Join(devFeatures, ",")) registered = getHelpCommandNames(c) unknown = registered.Difference(cmdSet) c.Assert(unknown, jc.DeepEquals, set.NewStrings()) missing = cmdSet.Difference(registered) c.Assert(missing, jc.DeepEquals, set.NewStrings()) }
func (s *networkerSuite) TestPrimaryOrLoopbackInterfacesAreSkipped(c *gc.C) { // Reset what's considered up, so we can test eth0 and lo are not // touched. s.upInterfaces = set.NewStrings() s.interfacesWithAddress = set.NewStrings() nw, _ := s.newCustomNetworker(c, s.apiFacade, s.stateMachine.Id(), true, false) defer worker.Stop(nw) timeout := time.After(coretesting.LongWait) for { select { case <-s.lastCommands: if !s.vlanModuleLoaded { // VLAN module loading commands is one of the first things // the worker does, so if hasn't happened, we wait a bit more. continue } c.Assert(s.upInterfaces.Contains("lo"), jc.IsFalse) c.Assert(s.upInterfaces.Contains("eth0"), jc.IsFalse) if s.upInterfaces.Contains("eth1") { // If we run ifup eth1, we successfully skipped lo and // eth0. s.assertHaveConfig(c, nw, "", "eth0", "eth1", "eth1.42", "eth0.69") return } case <-timeout: c.Fatalf("commands expected but not executed") } } }
func (s *workerSuite) TestConvertSpaceName(c *gc.C) { empty := set.Strings{} nameTests := []struct { name string existing set.Strings expected string }{ {"foo", empty, "foo"}, {"foo1", empty, "foo1"}, {"Foo Thing", empty, "foo-thing"}, {"foo^9*//++!!!!", empty, "foo9"}, {"--Foo", empty, "foo"}, {"---^^&*()!", empty, "empty"}, {" ", empty, "empty"}, {"", empty, "empty"}, {"foo\u2318", empty, "foo"}, {"foo--", empty, "foo"}, {"-foo--foo----bar-", empty, "foo-foo-bar"}, {"foo-", set.NewStrings("foo", "bar", "baz"), "foo-2"}, {"foo", set.NewStrings("foo", "foo-2"), "foo-3"}, {"---", set.NewStrings("empty"), "empty-2"}, } for _, test := range nameTests { result := discoverspaces.ConvertSpaceName(test.name, test.existing) c.Check(result, gc.Equals, test.expected) } }
func (s *MigrationSuite) TestUnitDocFields(c *gc.C) { ignored := set.NewStrings( "ModelUUID", "DocID", "Life", // Application is implicit in the migration structure through containment. "Application", // Resolved is not migrated as we check that all is good before we start. "Resolved", // Series and CharmURL also come from the service. "Series", "CharmURL", "TxnRevno", ) migrated := set.NewStrings( "Name", "Principal", "Subordinates", "StorageAttachmentCount", "MachineId", "Tools", "PasswordHash", ) s.AssertExportedFields(c, unitDoc{}, migrated.Union(ignored)) }
func (s *cloudImageMetadataSuite) TestCloudImageMetadataDocFields(c *gc.C) { ignored := set.NewStrings("Id") migrated := set.NewStrings( "Stream", "Region", "Version", "Series", "Arch", "VirtType", "RootStorageType", "RootStorageSize", "Source", "Priority", "ImageId", "DateCreated", ) fields := migrated.Union(ignored) expected := testing.GetExportedFields(imagesMetadataDoc{}) unknown := expected.Difference(fields) removed := fields.Difference(expected) // If this test fails, it means that extra fields have been added to the // doc without thinking about the migration implications. c.Check(unknown, gc.HasLen, 0) c.Assert(removed, gc.HasLen, 0) }
func (s *configFunctionalSuite) SetUpTest(c *gc.C) { s.configBaseSuite.SetUpTest(c) s.client = newLocalClient(c) origConfigDir := lxd.ConfigDir s.AddCleanup(func(c *gc.C) { lxd.ConfigDir = origConfigDir }) if s.client != nil { origCerts, err := s.client.ListCerts() c.Assert(err, jc.ErrorIsNil) s.AddCleanup(func(c *gc.C) { certs, err := s.client.ListCerts() c.Assert(err, jc.ErrorIsNil) orig := set.NewStrings(origCerts...) added := set.NewStrings(certs...).Difference(orig) for _, fingerprint := range added.Values() { err := s.client.RemoveCertByFingerprint(fingerprint) if err != nil { c.Logf("could not remove cert %q: %v", fingerprint, err) } } }) } }
func (s *ManifoldsSuite) TestFlagDependencies(c *gc.C) { exclusions := set.NewStrings( "agent", "api-caller", "api-config-watcher", "clock", "spaces-imported-gate", "is-responsible-flag", "not-alive-flag", "not-dead-flag", ) manifolds := model.Manifolds(model.ManifoldsConfig{ Agent: &mockAgent{}, }) for name, manifold := range manifolds { c.Logf("checking %s", name) if exclusions.Contains(name) { continue } inputs := set.NewStrings(manifold.Inputs...) if !inputs.Contains("is-responsible-flag") { c.Check(inputs.Contains("migration-fortress"), jc.IsTrue) c.Check(inputs.Contains("migration-inactive-flag"), jc.IsTrue) } } }
func (s *MigrationSuite) TestRelationDocFields(c *gc.C) { fields := set.NewStrings( // DocID itself isn't migrated "DocID", // ModelUUID shouldn't be exported, and is inherited // from the model definition. "ModelUUID", "Key", "Id", "Endpoints", // Life isn't exported, only alive. "Life", // UnitCount isn't explicitly exported, but defined by the stored // unit settings data for the relation endpoint. "UnitCount", ) s.AssertExportedFields(c, relationDoc{}, fields) // We also need to check the Endpoint and nested charm.Relation field. endpointFields := set.NewStrings("ServiceName", "Relation") s.AssertExportedFields(c, Endpoint{}, endpointFields) charmRelationFields := set.NewStrings( "Name", "Role", "Interface", "Optional", "Limit", "Scope", ) s.AssertExportedFields(c, charm.Relation{}, charmRelationFields) }
func (s *MainSuite) TestHelpCommands(c *gc.C) { defer osenv.SetJujuHome(osenv.SetJujuHome(c.MkDir())) // Check that we have correctly registered all the commands // by checking the help output. // First check default commands, and then check commands that are // activated by feature flags. // Here we can add feature flags for any commands we want to hide by default. devFeatures := []string{} // remove features behind dev_flag for the first test // since they are not enabled. cmdSet := set.NewStrings(commandNames...) for _, feature := range devFeatures { cmdSet.Remove(feature) } // 1. Default Commands. Disable all features. setFeatureFlags("") // Use sorted values here so we can better see what is wrong. registered := getHelpCommandNames(c) unknown := registered.Difference(cmdSet) c.Assert(unknown, jc.DeepEquals, set.NewStrings()) missing := cmdSet.Difference(registered) c.Assert(missing, jc.DeepEquals, set.NewStrings()) // 2. Enable development features, and test again. setFeatureFlags(strings.Join(devFeatures, ",")) registered = getHelpCommandNames(c) unknown = registered.Difference(cmdSet) c.Assert(unknown, jc.DeepEquals, set.NewStrings()) missing = cmdSet.Difference(registered) c.Assert(missing, jc.DeepEquals, set.NewStrings()) }
func (s *MigrationSuite) TestUnitDocFields(c *gc.C) { fields := set.NewStrings( // DocID itself isn't migrated "DocID", "Name", // ModelUUID shouldn't be exported, and is inherited // from the model definition. "ModelUUID", // Service is implicit in the migration structure through containment. "Service", // Series, CharmURL, and Channel also come from the service. "Series", "CharmURL", "Principal", "Subordinates", "MachineId", // Resolved is not migrated as we check that all is good before we start. "Resolved", "Tools", // Life isn't migrated as we only migrate live things. "Life", // TxnRevno isn't migrated. "TxnRevno", "PasswordHash", // Obsolete and not migrated. "Ports", "PublicAddress", "PrivateAddress", ) todo := set.NewStrings( "StorageAttachmentCount", ) s.AssertExportedFields(c, unitDoc{}, fields.Union(todo)) }
func (s *MigrationSuite) TestServiceDocFields(c *gc.C) { ignored := set.NewStrings( // DocID is the env + name "DocID", // ModelUUID shouldn't be exported, and is inherited // from the model definition. "ModelUUID", // Always alive, not explicitly exported. "Life", // OwnerTag is deprecated and should be deleted. "OwnerTag", // TxnRevno is mgo internals and should not be migrated. "TxnRevno", // UnitCount is handled by the number of units for the exported service. "UnitCount", // RelationCount is handled by the number of times the service name // appears in relation endpoints. "RelationCount", ) migrated := set.NewStrings( "Name", "Series", "Subordinate", "CharmURL", "Channel", "CharmModifiedVersion", "ForceCharm", "Exposed", "MinUnits", "MetricCredentials", ) s.AssertExportedFields(c, serviceDoc{}, migrated.Union(ignored)) }
// gitManifest returns every file path in the supplied directory, *except* for: // * paths below .git, because we don't need to track every file: we just // want them all gone // * charmURLPath, because we don't ever want to remove that: that's how // the manifestDeployer keeps track of what version it's upgrading from. // All paths are slash-separated, to match the bundle manifest format. func gitManifest(linkPath string) (set.Strings, error) { dirPath, err := os.Readlink(linkPath) if err != nil { return set.NewStrings(), err } manifest := set.NewStrings() err = filepath.Walk(dirPath, func(path string, fileInfo os.FileInfo, err error) error { if err != nil { return err } relPath, err := filepath.Rel(dirPath, path) if err != nil { return err } switch relPath { case ".", charmURLPath: return nil case ".git": err = filepath.SkipDir } manifest.Add(filepath.ToSlash(relPath)) return err }) if err != nil { return set.NewStrings(), err } return manifest, nil }
// Validate implements Model. func (m *model) Validate() error { // A model needs an owner. if m.Owner_ == "" { return errors.NotValidf("missing model owner") } unitsWithOpenPorts := set.NewStrings() for _, machine := range m.Machines_.Machines_ { if err := machine.Validate(); err != nil { return errors.Trace(err) } for _, np := range machine.NetworkPorts() { for _, pr := range np.OpenPorts() { unitsWithOpenPorts.Add(pr.UnitName()) } } } allUnits := set.NewStrings() for _, service := range m.Services_.Services_ { if err := service.Validate(); err != nil { return errors.Trace(err) } allUnits = allUnits.Union(service.unitNames()) } // Make sure that all the unit names specified in machine opened ports // exist as units of services. unknownUnitsWithPorts := unitsWithOpenPorts.Difference(allUnits) if len(unknownUnitsWithPorts) > 0 { return errors.Errorf("unknown unit names in open ports: %s", unknownUnitsWithPorts.SortedValues()) } return m.validateRelations() }
// RegisterConflicts is defined on Validator. func (v *validator) RegisterConflicts(reds, blues []string) { for _, red := range reds { v.conflicts[red] = set.NewStrings(blues...) } for _, blue := range blues { v.conflicts[blue] = set.NewStrings(reds...) } }
func collectMissingMachineIds(expectedIds []string, machines []*Machine) []string { expectedSet := set.NewStrings(expectedIds...) actualSet := set.NewStrings() for _, machine := range machines { actualSet.Add(machine.Id()) } return expectedSet.Difference(actualSet).SortedValues() }
func (stringSetSuite) TestIntersection(c *gc.C) { s1 := set.NewStrings("foo", "bar") s2 := set.NewStrings("foo", "baz", "bang") int1 := s1.Intersection(s2) int2 := s2.Intersection(s1) AssertValues(c, int1, "foo") AssertValues(c, int2, "foo") }
// AllProvisionedControllersReady returns true if and only if all controllers // that have been started by the provisioner have called EnsureUpgradeInfo with // matching versions. // // When this returns true the master state controller can begin it's // own upgrade. func (info *UpgradeInfo) AllProvisionedControllersReady() (bool, error) { provisioned, err := info.getProvisionedControllers() if err != nil { return false, errors.Trace(err) } ready := set.NewStrings(info.doc.ControllersReady...) missing := set.NewStrings(provisioned...).Difference(ready) return missing.IsEmpty(), nil }
func (stringSetSuite) TestUnion(c *gc.C) { s1 := set.NewStrings("foo", "bar") s2 := set.NewStrings("foo", "baz", "bang") union1 := s1.Union(s2) union2 := s2.Union(s1) AssertValues(c, union1, "foo", "bar", "baz", "bang") AssertValues(c, union2, "foo", "bar", "baz", "bang") }
func (stringSetSuite) TestSize(c *gc.C) { // Empty sets are empty. s := set.NewStrings() c.Assert(s.Size(), gc.Equals, 0) // Size returns number of unique values. s = set.NewStrings("foo", "foo", "bar") c.Assert(s.Size(), gc.Equals, 2) }
func (stringSetSuite) TestDifference(c *gc.C) { s1 := set.NewStrings("foo", "bar") s2 := set.NewStrings("foo", "baz", "bang") diff1 := s1.Difference(s2) diff2 := s2.Difference(s1) AssertValues(c, diff1, "bar") AssertValues(c, diff2, "baz", "bang") }
func (m *model) validateStorage(allMachineIDs, allApplications, allUnits set.Strings) error { appsAndUnits := allApplications.Union(allUnits) allStorage := set.NewStrings() for i, storage := range m.Storages_.Storages_ { if err := storage.Validate(); err != nil { return errors.Annotatef(err, "storage[%d]", i) } allStorage.Add(storage.Tag().Id()) owner, err := storage.Owner() if err != nil { return errors.Wrap(err, errors.NotValidf("storage[%d] owner (%s)", i, owner)) } ownerID := owner.Id() if !appsAndUnits.Contains(ownerID) { return errors.NotValidf("storage[%d] owner (%s)", i, ownerID) } for _, unit := range storage.Attachments() { if !allUnits.Contains(unit.Id()) { return errors.NotValidf("storage[%d] attachment referencing unknown unit %q", i, unit) } } } allVolumes := set.NewStrings() for i, volume := range m.Volumes_.Volumes_ { if err := volume.Validate(); err != nil { return errors.Annotatef(err, "volume[%d]", i) } allVolumes.Add(volume.Tag().Id()) if storeID := volume.Storage().Id(); storeID != "" && !allStorage.Contains(storeID) { return errors.NotValidf("volume[%d] referencing unknown storage %q", i, storeID) } for j, attachment := range volume.Attachments() { if machineID := attachment.Machine().Id(); !allMachineIDs.Contains(machineID) { return errors.NotValidf("volume[%d].attachment[%d] referencing unknown machine %q", i, j, machineID) } } } for i, filesystem := range m.Filesystems_.Filesystems_ { if err := filesystem.Validate(); err != nil { return errors.Annotatef(err, "filesystem[%d]", i) } if storeID := filesystem.Storage().Id(); storeID != "" && !allStorage.Contains(storeID) { return errors.NotValidf("filesystem[%d] referencing unknown storage %q", i, storeID) } if volID := filesystem.Volume().Id(); volID != "" && !allVolumes.Contains(volID) { return errors.NotValidf("filesystem[%d] referencing unknown volume %q", i, volID) } for j, attachment := range filesystem.Attachments() { if machineID := attachment.Machine().Id(); !allMachineIDs.Contains(machineID) { return errors.NotValidf("filesystem[%d].attachment[%d] referencing unknown machine %q", i, j, machineID) } } } return nil }
func (s *MigrationSuite) TestStorageConstraintsDocFields(c *gc.C) { ignored := set.NewStrings( "ModelUUID", "DocID", ) migrated := set.NewStrings( "Constraints", ) s.AssertExportedFields(c, storageConstraintsDoc{}, migrated.Union(ignored)) }
// Validate implements Model. func (m *model) Validate() error { // A model needs an owner. if m.Owner_ == "" { return errors.NotValidf("missing model owner") } allMachines := set.NewStrings() unitsWithOpenPorts := set.NewStrings() for _, machine := range m.Machines_.Machines_ { if err := m.validateMachine(machine, allMachines, unitsWithOpenPorts); err != nil { return errors.Trace(err) } } allApplications := set.NewStrings() allUnits := set.NewStrings() for _, application := range m.Applications_.Applications_ { if err := application.Validate(); err != nil { return errors.Trace(err) } allApplications.Add(application.Name()) allUnits = allUnits.Union(application.unitNames()) } // Make sure that all the unit names specified in machine opened ports // exist as units of applications. unknownUnitsWithPorts := unitsWithOpenPorts.Difference(allUnits) if len(unknownUnitsWithPorts) > 0 { return errors.Errorf("unknown unit names in open ports: %s", unknownUnitsWithPorts.SortedValues()) } err := m.validateRelations() if err != nil { return errors.Trace(err) } err = m.validateSubnets() if err != nil { return errors.Trace(err) } err = m.validateLinkLayerDevices() if err != nil { return errors.Trace(err) } err = m.validateAddresses() if err != nil { return errors.Trace(err) } err = m.validateStorage(allMachines, allApplications, allUnits) if err != nil { return errors.Trace(err) } return nil }