func (s *RebootSuite) TestRebootWithMissbehavingContainers(c *gc.C) { testing.PatchExecutable(c, s, "lxc-ls", lxcLsScript) testing.PatchExecutable(c, s, "lxc-info", lxcInfoScriptMissbehave) s.PatchValue(reboot.Timeout, time.Duration(1*time.Second)) w, err := reboot.NewRebootWaiter(s.st, s.acfg) c.Assert(err, jc.ErrorIsNil) err = w.ExecuteReboot(params.ShouldReboot) c.Assert(err, gc.ErrorMatches, "Timeout reached waiting for containers to shutdown") }
func (s *RebootSuite) TestRebootWithContainers(c *gc.C) { testing.PatchExecutable(c, s, "lxc-ls", lxcLsScript) testing.PatchExecutable(c, s, "lxc-info", lxcInfoScript) expectedRebootParams := s.rebootCommandParams(c) s.PatchValue(reboot.Timeout, time.Duration(5*time.Second)) w, err := reboot.NewRebootWaiter(s.st, s.acfg) c.Assert(err, jc.ErrorIsNil) err = w.ExecuteReboot(params.ShouldReboot) c.Assert(err, jc.ErrorIsNil) testing.AssertEchoArgs(c, rebootBin, expectedRebootParams...) ft.File{s.rebootScriptName, expectedRebootScript, 0755}.Check(c, s.tmpDir) }
func (s *ContainerSetupSuite) setupContainerWorker(c *gc.C, tag names.MachineTag) (worker.StringsWatchHandler, worker.Runner) { testing.PatchExecutable(c, s, "ubuntu-cloudimg-query", containertesting.FakeLxcURLScript) runner := worker.NewRunner(allFatal, noImportance) pr := s.st.Provisioner() machine, err := pr.Machine(tag) c.Assert(err, jc.ErrorIsNil) err = machine.SetSupportedContainers(instance.ContainerTypes...) c.Assert(err, jc.ErrorIsNil) cfg := s.AgentConfigForTag(c, tag) watcherName := fmt.Sprintf("%s-container-watcher", machine.Id()) params := provisioner.ContainerSetupParams{ Runner: runner, WorkerName: watcherName, SupportedContainers: instance.ContainerTypes, ImageURLGetter: &containertesting.MockURLGetter{}, Machine: machine, Provisioner: pr, Config: cfg, InitLock: s.initLock, } handler := provisioner.NewContainerSetupHandler(params) runner.StartWorker(watcherName, func() (worker.Worker, error) { return worker.NewStringsWorker(handler), nil }) return handler, runner }
func (s *MongoSuite) SetUpTest(c *gc.C) { s.BaseSuite.SetUpTest(c) s.mongodVersion = mongo.Mongo24 testing.PatchExecutable(c, s, "mongod", "#!/bin/bash\n\nprintf %s 'db version v2.4.9'\n") jujuMongodPath, err := exec.LookPath("mongod") c.Assert(err, jc.ErrorIsNil) s.PatchValue(&mongo.JujuMongod24Path, jujuMongodPath) s.mongodPath = jujuMongodPath // Patch "df" such that it always reports there's 1MB free. s.PatchValue(mongo.AvailSpace, func(dir string) (float64, error) { info, err := os.Stat(dir) if err != nil { return 0, err } if info.IsDir() { return 1, nil } return 0, fmt.Errorf("not a directory") }) s.PatchValue(mongo.MinOplogSizeMB, 1) testPath := c.MkDir() s.mongodConfigPath = filepath.Join(testPath, "mongodConfig") s.PatchValue(mongo.MongoConfigPath, s.mongodConfigPath) s.data = svctesting.NewFakeServiceData() mongo.PatchService(s.PatchValue, s.data) }
func (s *preallocSuite) TestFsAvailSpaceErrors(c *gc.C) { tests := []struct { desc string output string err string }{{ desc: "result is non-numeric", output: `Filesystem 1K-blocks Used Available Use% Mounted on /dev/vda1 8124856 1365292 abc 18% /`, err: `strconv.ParseInt: parsing "abc": invalid syntax`, }, { desc: "not enough lines", output: "abc", err: `could not determine available space on ""`, }, { desc: "not enough fields on second line", output: "abc\ndef", err: `could not determine available space on ""`, }} for i, test := range tests { c.Logf("test %d: %s", i, test.desc) testing.PatchExecutable(c, s, "df", "#!/bin/sh\ncat<<EOF\n"+test.output+"\nEOF") _, err := mongo.FsAvailSpace("") c.Check(err, gc.ErrorMatches, test.err) } }
func (s *ListBlockDevicesSuite) SetUpTest(c *gc.C) { s.BaseSuite.SetUpTest(c) s.PatchValue(diskmanager.BlockDeviceInUse, func(storage.BlockDevice) (bool, error) { return false, nil }) testing.PatchExecutable(c, s, "udevadm", `#!/bin/bash --norc`) }
func (s *MongoSuite) TestInstallMongodFallsBack(c *gc.C) { if runtime.GOOS == "windows" { c.Skip("Skipping TestInstallMongodFallsBack as mongo is not installed on windows") } type installs struct { series string cmd string } tests := []installs{ {"precise", "mongodb-server"}, {"trusty", "juju-mongodb3.2\njuju-mongodb"}, {"wily", "juju-mongodb3.2\njuju-mongodb"}, {"xenial", "juju-mongodb3.2\njuju-mongodb"}, } dataDir := c.MkDir() outputFile := filepath.Join(dataDir, "apt-get-args") testing.PatchExecutable(c, s, "apt-get", fmt.Sprintf(fakeInstallScript, outputFile)) for _, test := range tests { c.Logf("Testing mongo install for series: %s", test.series) s.patchSeries(test.series) err := mongo.EnsureServer(makeEnsureServerParams(dataDir)) c.Assert(err, jc.ErrorIsNil) args, err := ioutil.ReadFile(outputFile) c.Assert(err, jc.ErrorIsNil) c.Check(strings.TrimSpace(string(args)), gc.Equals, test.cmd) err = os.Remove(outputFile) c.Assert(err, jc.ErrorIsNil) } }
func (s *imageSuite) TestDownloadFetchesAndCaches(c *gc.C) { // Set up some image data for a fake server. testing.PatchExecutable(c, s, "ubuntu-cloudimg-query", containertesting.FakeLxcURLScript) useTestImageData(map[string]string{ "/trusty-released-amd64-root.tar.gz": testImageData, "/SHA256SUMS": testImageChecksum + " *trusty-released-amd64-root.tar.gz", }) defer func() { useTestImageData(nil) }() // The image is not in imagestorage, so the download request causes // the API server to search for the image on cloud-images, fetches it, // and then cache it in imagestorage. url := s.imageURL(c, "lxc", "trusty", "amd64") response := s.downloadRequest(c, url) data := s.testDownload(c, response) metadata, cachedData := s.getImageFromStorage(c, s.State, "lxc", "trusty", "amd64") c.Assert(metadata.Size, gc.Equals, int64(len(testImageData))) c.Assert(metadata.SHA256, gc.Equals, testImageChecksum) c.Assert(metadata.SourceURL, gc.Equals, "test://cloud-images/trusty-released-amd64-root.tar.gz") c.Assert(string(data), gc.Equals, string(testImageData)) c.Assert(string(data), gc.Equals, string(cachedData)) }
func (s *lxcBrokerSuite) TestSetupRoutesAndIPTablesIPTablesAddError(c *gc.C) { // Isolate the test from the host machine. Patch iptables with a // script which returns code=1 for the check but fails when adding // the rule. script := `if [[ "$3" == "-C" ]]; then exit 1; else exit 42; fi` gitjujutesting.PatchExecutable(c, s, "iptables", script) gitjujutesting.PatchExecutableThrowError(c, s, "ip", 123) fakeptablesRules := map[string]provisioner.IptablesRule{ "IPTablesSNAT": { "nat", "POSTROUTING", "{{.HostIF}} {{.HostIP}}", }, } s.PatchValue(provisioner.IptablesRules, fakeptablesRules) ifaceInfo := []network.InterfaceInfo{{ Address: network.NewAddress("0.1.2.3"), }} addr := network.NewAddress("0.1.2.1") err := provisioner.SetupRoutesAndIPTables("nic", addr, "bridge", ifaceInfo, false) c.Assert(err, gc.ErrorMatches, `command "iptables -t nat -I .*" failed with exit code 42`) }
func (s *preallocSuite) TestFsAvailSpace(c *gc.C) { output := `Filesystem 1K-blocks Used Available Use% Mounted on /dev/vda1 8124856 1365292 12345 18% /` testing.PatchExecutable(c, s, "df", "#!/bin/sh\ncat<<EOF\n"+output+"\nEOF") mb, err := mongo.FsAvailSpace("") c.Assert(err, gc.IsNil) c.Assert(mb, gc.Equals, float64(12345)/1024) }
func (s *controllerInstancesSuite) TestControllerInstancesInternal(c *gc.C) { // Patch os.Args so it appears that we're running in "jujud". s.PatchValue(&os.Args, []string{"/some/where/containing/jujud", "whatever"}) // Patch the ssh executable so that it would cause an error if we // were to call it. testing.PatchExecutable(c, s, "ssh", "#!/bin/sh\nhead -n1 > /dev/null; echo abc >&2; exit 1") instances, err := s.env.ControllerInstances("not-used") c.Assert(err, jc.ErrorIsNil) c.Assert(instances, gc.DeepEquals, []instance.Id{BootstrapInstanceId}) }
func (s *stateServerInstancesSuite) TestStateServerInstancesInternal(c *gc.C) { // If use-sshstorage=false, then we're on the bootstrap host; // verification is elided. env, err := manualProvider{}.Open(MinimalConfig(c)) c.Assert(err, jc.ErrorIsNil) testing.PatchExecutable(c, s, "ssh", "#!/bin/sh\nhead -n1 > /dev/null; echo abc >&2; exit 1") instances, err := env.StateServerInstances() c.Assert(err, jc.ErrorIsNil) c.Assert(instances, gc.DeepEquals, []instance.Id{BootstrapInstanceId}) }
func (s *ListBlockDevicesSuite) testListBlockDevicesExtended( c *gc.C, udevadmInfo string, expect storage.BlockDevice, ) { testing.PatchExecutable(c, s, "lsblk", `#!/bin/bash --norc cat <<EOF KNAME="sda" SIZE="240057409536" LABEL="" UUID="" TYPE="disk" EOF`) testing.PatchExecutable(c, s, "udevadm", `#!/bin/bash --norc cat <<EOF `+strings.TrimSpace(udevadmInfo)+` EOF`) expect.DeviceName = "sda" expect.Size = 228936 devices, err := diskmanager.ListBlockDevices() c.Assert(err, jc.ErrorIsNil) c.Assert(devices, jc.DeepEquals, []storage.BlockDevice{expect}) }
func (s *ListBlockDevicesSuite) TestListBlockDevicesDeviceNotExist(c *gc.C) { s.PatchValue(diskmanager.BlockDeviceInUse, func(dev storage.BlockDevice) (bool, error) { return false, os.ErrNotExist }) testing.PatchExecutable(c, s, "lsblk", `#!/bin/bash --norc cat <<EOF KNAME="sda" SIZE="240057409536" LABEL="" UUID="" TYPE="disk" KNAME="sdb" SIZE="32017047552" LABEL="" UUID="" TYPE="disk" EOF`) devices, err := diskmanager.ListBlockDevices() c.Assert(err, jc.ErrorIsNil) c.Assert(devices, gc.HasLen, 0) }
func (s *imageSuite) TestDownloadFetchNoSHA256File(c *gc.C) { // Set up some image data for a fake server. testing.PatchExecutable(c, s, "ubuntu-cloudimg-query", containertesting.FakeLxcURLScript) useTestImageData(map[string]string{ "/trusty-released-amd64-root.tar.gz": testImageData, }) defer func() { useTestImageData(nil) }() resp := s.downloadRequest(c, s.imageURL(c, "lxc", "trusty", "amd64")) defer resp.Body.Close() s.assertErrorResponse(c, resp, http.StatusInternalServerError, ".* cannot find sha256 checksum .*") }
func (s *imageSuite) TestDownloadFetchChecksumMismatch(c *gc.C) { // Set up some image data for a fake server. testing.PatchExecutable(c, s, "ubuntu-cloudimg-query", containertesting.FakeLxcURLScript) useTestImageData(map[string]string{ "/trusty-released-amd64-root.tar.gz": s.imageData, "/SHA256SUMS": "different-checksum *trusty-released-amd64-root.tar.gz", }) defer func() { useTestImageData(nil) }() resp, err := s.downloadRequest(c, s.imageURL(c, "lxc", "trusty", "amd64")) defer resp.Body.Close() c.Assert(err, gc.IsNil) s.assertErrorResponse(c, resp, http.StatusInternalServerError, ".* download checksum mismatch .*") }
func (s *imageSuite) TestDownloadFetchesAndCachesConcurrent(c *gc.C) { // Set up some image data for a fake server. testing.PatchExecutable(c, s, "ubuntu-cloudimg-query", containertesting.FakeLxcURLScript) useTestImageData(map[string]string{ "/trusty-released-amd64-root.tar.gz": s.imageData, "/SHA256SUMS": s.imageChecksum + " *trusty-released-amd64-root.tar.gz", }) defer func() { useTestImageData(nil) }() // Fetch the same image multiple times concurrently and ensure that // it is only downloaded from the external URL once. done := make(chan struct{}) go func() { var wg sync.WaitGroup wg.Add(10) for i := 0; i < 10; i++ { go func() { defer wg.Done() url := s.imageURL(c, "lxc", "trusty", "amd64") response, err := s.downloadRequest(c, url) c.Assert(err, jc.ErrorIsNil) data := s.testDownload(c, response) c.Assert(string(data), gc.Equals, string(s.imageData)) }() } wg.Wait() done <- struct{}{} }() select { case <-done: case <-time.After(coretesting.LongWait): c.Fatalf("timed out waiting for images to be fetced") } // Downloading an image is 2 requests - one for image, one for SA256. c.Assert(testRoundTripper.Sub.(*CountingRoundTripper).count, gc.Equals, 2) // Check that the image is correctly cached. metadata, cachedData := s.getImageFromStorage(c, s.State, "lxc", "trusty", "amd64") c.Assert(metadata.Size, gc.Equals, int64(len(s.imageData))) c.Assert(metadata.SHA256, gc.Equals, s.imageChecksum) c.Assert(metadata.SourceURL, gc.Equals, "test://cloud-images/trusty-released-amd64-root.tar.gz") c.Assert(s.imageData, gc.Equals, string(cachedData)) }
func (s *ListBlockDevicesSuite) TestListBlockDevicesBlockDeviceInUseError(c *gc.C) { s.PatchValue(diskmanager.BlockDeviceInUse, func(dev storage.BlockDevice) (bool, error) { return false, errors.New("badness") }) testing.PatchExecutable(c, s, "lsblk", `#!/bin/bash --norc cat <<EOF KNAME="sda" SIZE="240057409536" LABEL="" UUID="" TYPE="disk" EOF`) // If the in-use check errors, the block device will be marked "in use" // to prevent it from being used, but no error will be returned. devices, err := diskmanager.ListBlockDevices() c.Assert(err, jc.ErrorIsNil) c.Assert(devices, jc.SameContents, []storage.BlockDevice{{ DeviceName: "sda", Size: 228936, InUse: true, }}) }
func (s *ListBlockDevicesSuite) TestListBlockDevicesLsblkBadOutput(c *gc.C) { // Extra key/value pairs should be ignored; invalid sizes should // be logged and ignored (Size will be set to zero). testing.PatchExecutable(c, s, "lsblk", `#!/bin/bash --norc cat <<EOF KNAME="sda" SIZE="eleventy" LABEL="" UUID="" TYPE="disk" KNAME="sdb" SIZE="1048576" LABEL="" UUID="" BOB="DOBBS" TYPE="disk" EOF`) devices, err := diskmanager.ListBlockDevices() c.Assert(err, jc.ErrorIsNil) c.Assert(devices, jc.SameContents, []storage.BlockDevice{{ DeviceName: "sda", Size: 0, }, { DeviceName: "sdb", Size: 1, }}) }
func (s *ListBlockDevicesSuite) TestListBlockDevicesDeviceFiltering(c *gc.C) { testing.PatchExecutable(c, s, "lsblk", `#!/bin/bash --norc cat <<EOF KNAME="sda" SIZE="240057409536" LABEL="" UUID="" TYPE="disk" KNAME="sda1" SIZE="254803968" LABEL="" UUID="" TYPE="part" KNAME="loop0" SIZE="254803968" LABEL="" UUID="" TYPE="loop" KNAME="sr0" SIZE="254803968" LABEL="" UUID="" TYPE="rom" KNAME="whatever" SIZE="254803968" LABEL="" UUID="" TYPE="lvm" EOF`) devices, err := diskmanager.ListBlockDevices() c.Assert(err, gc.IsNil) c.Assert(devices, jc.SameContents, []storage.BlockDevice{{ DeviceName: "sda", Size: 228936, }, { DeviceName: "loop0", Size: 243, }}) }
func (s *ListBlockDevicesSuite) TestListBlockDevices(c *gc.C) { s.PatchValue(diskmanager.BlockDeviceInUse, func(dev storage.BlockDevice) (bool, error) { return dev.DeviceName == "sdb", nil }) testing.PatchExecutable(c, s, "lsblk", `#!/bin/bash --norc cat <<EOF KNAME="sda" SIZE="240057409536" LABEL="" UUID="" TYPE="disk" KNAME="sda1" SIZE="254803968" LABEL="" UUID="7a62bd85-a350-4c09-8944-5b99bf2080c6" MOUNTPOINT="/tmp" TYPE="disk" KNAME="sda2" SIZE="1024" LABEL="boot" UUID="" TYPE="disk" KNAME="sdb" SIZE="32017047552" LABEL="" UUID="" TYPE="disk" KNAME="sdb1" SIZE="32015122432" LABEL="media" UUID="2c1c701d-f2ce-43a4-b345-33e2e39f9503" FSTYPE="ext4" TYPE="disk" EOF`) devices, err := diskmanager.ListBlockDevices() c.Assert(err, jc.ErrorIsNil) c.Assert(devices, jc.SameContents, []storage.BlockDevice{{ DeviceName: "sda", Size: 228936, }, { DeviceName: "sda1", Size: 243, UUID: "7a62bd85-a350-4c09-8944-5b99bf2080c6", MountPoint: "/tmp", }, { DeviceName: "sda2", Size: 0, // truncated Label: "boot", }, { DeviceName: "sdb", Size: 30533, InUse: true, }, { DeviceName: "sdb1", Size: 30532, Label: "media", UUID: "2c1c701d-f2ce-43a4-b345-33e2e39f9503", FilesystemType: "ext4", }}) }
func (s *runSuite) mockSSH(c *gc.C, cmd string) { gitjujutesting.PatchExecutable(c, s, "ssh", cmd) gitjujutesting.PatchExecutable(c, s, "scp", cmd) client, _ := ssh.NewOpenSSHClient() s.PatchValue(&ssh.DefaultClient, client) }
func (s *imageURLSuite) SetUpTest(c *gc.C) { testing.PatchExecutable(c, s, "ubuntu-cloudimg-query", containertesting.FakeLxcURLScript) }
func (s *stateServerInstancesSuite) TestStateServerInstancesStderr(c *gc.C) { // Stderr should not affect the behaviour of StateServerInstances. testing.PatchExecutable(c, s, "ssh", "#!/bin/sh\nhead -n1 > /dev/null; echo abc >&2; exit 0") _, err := s.env.StateServerInstances() c.Assert(err, jc.ErrorIsNil) }
func (s *stateServerInstancesSuite) TestStateServerInstancesError(c *gc.C) { // If the ssh execution fails, its stderr will be captured in the error message. testing.PatchExecutable(c, s, "ssh", "#!/bin/sh\nhead -n1 > /dev/null; echo abc >&2; exit 1") _, err := s.env.StateServerInstances() c.Assert(err, gc.ErrorMatches, "abc: .*") }