func (s *storageSuite) TestListVolumes(c *gc.C) { s.storageClient.ListBlobsFunc = func( container string, params azurestorage.ListBlobsParameters, ) (azurestorage.BlobListResponse, error) { return azurestorage.BlobListResponse{ Blobs: []azurestorage.Blob{{ Name: "volume-1.vhd", Properties: azurestorage.BlobProperties{ ContentLength: 1024 * 1024, // 1MiB }, }, { Name: "volume-0.vhd", Properties: azurestorage.BlobProperties{ ContentLength: 1024 * 1024 * 1024 * 1024, // 1TiB }, }, { Name: "junk.vhd", }, { Name: "volume", }}, }, nil } volumeSource := s.volumeSource(c) volumeIds, err := volumeSource.ListVolumes() c.Assert(err, jc.ErrorIsNil) s.storageClient.CheckCallNames(c, "NewClient", "ListBlobs") s.storageClient.CheckCall( c, 0, "NewClient", fakeStorageAccount, fakeStorageAccountKey, "core.windows.net", azurestorage.DefaultAPIVersion, true, ) s.storageClient.CheckCall(c, 1, "ListBlobs", "datavhds", azurestorage.ListBlobsParameters{}) c.Assert(volumeIds, jc.DeepEquals, []string{"volume-1", "volume-0"}) }
func (s *initSystemSuite) TestRemove(c *gc.C) { s.addService("jujud-machine-0", "inactive") s.addListResponse() err := s.service.Remove() c.Assert(err, jc.ErrorIsNil) s.stub.CheckCalls(c, []testing.StubCall{{ FuncName: "RunCommand", Args: []interface{}{ listCmdArg, }, }, { FuncName: "DisableUnitFiles", Args: []interface{}{ []string{s.name + ".service"}, false, }, }, { FuncName: "Reload", }, { FuncName: "RemoveAll", Args: []interface{}{ fmt.Sprintf("%s/init/%s", s.dataDir, s.name), }, }, { FuncName: "Close", }}) }
func (s *decodeSuite) TestDecodeCheckInvalidSignature(c *gc.C) { r := bytes.NewReader([]byte(invalidClearsignInput + signSuffix)) _, err := simplestreams.DecodeCheckSignature(r, testSigningKey) c.Assert(err, gc.Not(gc.IsNil)) _, ok := err.(*simplestreams.NotPGPSignedError) c.Assert(ok, jc.IsFalse) }
func (s *ListSuite) SetUpTest(c *gc.C) { s.FakeJujuHomeSuite.SetUpTest(c) s.SetFeatureFlags(feature.JES) s.store = configstore.NewMem() var envList = []struct { name string serverUUID string envUUID string }{ { name: "test1", serverUUID: "test1-uuid", envUUID: "test1-uuid", }, { name: "test2", serverUUID: "test1-uuid", envUUID: "test2-uuid", }, { name: "test3", envUUID: "test3-uuid", }, } for _, env := range envList { info := s.store.CreateInfo(env.name) info.SetAPIEndpoint(configstore.APIEndpoint{ Addresses: []string{"localhost"}, CACert: testing.CACert, EnvironUUID: env.envUUID, ServerUUID: env.serverUUID, }) err := info.Write() c.Assert(err, jc.ErrorIsNil) } }
func (s *charmsSuite) TestGetRejectsWrongEnvUUIDPath(c *gc.C) { url := s.charmsURL(c, "url=local:quantal/dummy-1&file=revision") url.Path = "/environment/dead-beef-123456/charms" resp, err := s.authRequest(c, "GET", url.String(), "", nil) c.Assert(err, jc.ErrorIsNil) s.assertErrorResponse(c, resp, http.StatusNotFound, `unknown environment: "dead-beef-123456"`) }
func (s *cinderVolumeSourceSuite) TestAttachVolumes(c *gc.C) { mockAdapter := &mockAdapter{ attachVolume: func(serverId, volId, mountPoint string) (*nova.VolumeAttachment, error) { c.Check(volId, gc.Equals, mockVolId) c.Check(serverId, gc.Equals, mockServerId) return &nova.VolumeAttachment{ Id: volId, VolumeId: volId, ServerId: serverId, Device: "/dev/sda", }, nil }, } volSource := openstack.NewCinderVolumeSource(mockAdapter) results, err := volSource.AttachVolumes([]storage.VolumeAttachmentParams{{ Volume: mockVolumeTag, VolumeId: mockVolId, AttachmentParams: storage.AttachmentParams{ Provider: openstack.CinderProviderType, Machine: mockMachineTag, InstanceId: instance.Id(mockServerId), }}, }) c.Assert(err, jc.ErrorIsNil) c.Check(results, jc.DeepEquals, []storage.AttachVolumesResult{{ VolumeAttachment: &storage.VolumeAttachment{ mockVolumeTag, mockMachineTag, storage.VolumeAttachmentInfo{ DeviceName: "sda", }, }, }}) }
func (s *instanceSuite) TestOpenPorts(c *gc.C) { // Close the default ports. configSetNetwork((*gwacl.Role)(s.role)).InputEndpoints = nil responses := preparePortChangeConversation(c, s.role) record := gwacl.PatchManagementAPIResponses(responses) err := s.instance.OpenPorts("machine-id", []network.PortRange{ {79, 79, "tcp"}, {587, 587, "tcp"}, {9, 9, "udp"}, }) c.Assert(err, jc.ErrorIsNil) assertPortChangeConversation(c, *record, []expectedRequest{ {"GET", ".*/deployments/deployment-one/roles/role-one"}, // GetRole {"PUT", ".*/deployments/deployment-one/roles/role-one"}, // UpdateRole }) // A representative UpdateRole payload includes configuration for the // ports requested. role := &gwacl.PersistentVMRole{} err = role.Deserialize((*record)[1].Payload) c.Assert(err, jc.ErrorIsNil) c.Check( *configSetNetwork((*gwacl.Role)(role)).InputEndpoints, gc.DeepEquals, []gwacl.InputEndpoint{ makeInputEndpoint(79, "tcp"), makeInputEndpoint(587, "tcp"), makeInputEndpoint(9, "udp"), }, ) }
func assertPortChangeConversation(c *gc.C, record []*gwacl.X509Request, expected []expectedRequest) { c.Assert(record, gc.HasLen, len(expected)) for index, request := range record { c.Check(request.Method, gc.Equals, expected[index].method) c.Check(request.URL, gc.Matches, expected[index].urlpattern) } }
func (s *ReportSuite) TestReportError(c *gc.C) { s.fix.run(c, func(engine *dependency.Engine) { mh1 := newManifoldHarness("missing") manifold := mh1.Manifold() err := engine.Install("task", manifold) c.Assert(err, jc.ErrorIsNil) mh1.AssertNoStart(c) workertest.CleanKill(c, engine) report := engine.Report() c.Check(report, jc.DeepEquals, map[string]interface{}{ "state": "stopped", "error": nil, "manifolds": map[string]interface{}{ "task": map[string]interface{}{ "state": "stopped", "error": dependency.ErrMissing, "inputs": []string{"missing"}, "resource-log": []map[string]interface{}{{ "name": "missing", "type": "<nil>", "error": dependency.ErrMissing, }}, "report": (map[string]interface{})(nil), }, }, }) }) }
func (s *Suite) TestWatchError(c *gc.C) { s.backend.watchError = errors.New("boom") api := s.mustMakeAPI(c) _, err := api.Watch() c.Assert(err, gc.ErrorMatches, "boom") c.Assert(s.resources.Count(), gc.Equals, 0) }
func (s *SelfSuite) TestActuallyWorks(c *gc.C) { // Create and install a manifold with an unsatisfied dependency. mh1 := newManifoldHarness("self") err := s.engine.Install("dependent", mh1.Manifold()) c.Assert(err, jc.ErrorIsNil) mh1.AssertNoStart(c) // Install an engine inside itself; once it's "started", dependent will // be restarted. manifold := dependency.SelfManifold(s.engine) err = s.engine.Install("self", manifold) c.Assert(err, jc.ErrorIsNil) mh1.AssertOneStart(c) // Check we can still stop it (with a timeout -- injudicious // implementation changes could induce deadlocks). done := make(chan struct{}) go func() { err := worker.Stop(s.engine) c.Check(err, jc.ErrorIsNil) close(done) }() select { case <-done: case <-time.After(coretesting.LongWait): c.Fatalf("timed out") } }
func (s *ColumnSuite) TestAliasColumnSerializeSqlForColumnListNilExpr(c *gc.C) { col := Alias("foo", nil) buf := &bytes.Buffer{} err := col.SerializeSqlForColumnList(buf) c.Assert(err, gc.NotNil) }
func (s *InitializeSuite) TestEnvironConfigWithoutAgentVersion(c *gc.C) { // admin-secret blocks Initialize. good := testing.EnvironConfig(c) attrs := good.AllAttrs() delete(attrs, "agent-version") bad, err := config.New(config.NoDefaults, attrs) c.Assert(err, jc.ErrorIsNil) owner := names.NewLocalUserTag("initialize-admin") _, err = state.Initialize(owner, statetesting.NewMongoInfo(), bad, statetesting.NewDialOpts(), state.Policy(nil)) c.Assert(err, gc.ErrorMatches, "agent-version must always be set in state") st := statetesting.Initialize(c, owner, good, nil) // yay side effects st.Close() s.openState(c, st.EnvironTag()) err = s.State.UpdateEnvironConfig(map[string]interface{}{}, []string{"agent-version"}, nil) c.Assert(err, gc.ErrorMatches, "agent-version must always be set in state") // EnvironConfig remains inviolate. cfg, err := s.State.EnvironConfig() c.Assert(err, jc.ErrorIsNil) c.Assert(cfg.AllAttrs(), gc.DeepEquals, good.AllAttrs()) }
// countPolls sets up a machine loop with the given // addresses and status to be returned from getInstanceInfo, // waits for coretesting.ShortWait, and returns the // number of times the instance is polled. func countPolls(c *gc.C, addrs []network.Address, instId, instStatus string, machineStatus params.Status) int { count := int32(0) getInstanceInfo := func(id instance.Id) (instanceInfo, error) { c.Check(string(id), gc.Equals, instId) atomic.AddInt32(&count, 1) if addrs == nil { return instanceInfo{}, fmt.Errorf("no instance addresses available") } return instanceInfo{addrs, instStatus}, nil } context := &testMachineContext{ getInstanceInfo: getInstanceInfo, dyingc: make(chan struct{}), } m := &testMachine{ tag: names.NewMachineTag("99"), instanceId: instance.Id(instId), refresh: func() error { return nil }, addresses: addrs, life: params.Alive, status: machineStatus, } died := make(chan machine) go runMachine(context, m, nil, died) time.Sleep(coretesting.ShortWait) killMachineLoop(c, m, context.dyingc, died) c.Assert(context.killAllErr, gc.Equals, nil) return int(count) }
func (s *machineSuite) TestSinglePollWhenInstancInfoUnimplemented(c *gc.C) { s.PatchValue(&ShortPoll, 1*time.Millisecond) s.PatchValue(&LongPoll, 1*time.Millisecond) count := int32(0) getInstanceInfo := func(id instance.Id) (instanceInfo, error) { c.Check(id, gc.Equals, instance.Id("i1234")) atomic.AddInt32(&count, 1) err := ¶ms.Error{ Code: params.CodeNotImplemented, Message: "instance address not implemented", } return instanceInfo{}, err } context := &testMachineContext{ getInstanceInfo: getInstanceInfo, dyingc: make(chan struct{}), } m := &testMachine{ tag: names.NewMachineTag("99"), instanceId: "i1234", refresh: func() error { return nil }, life: params.Alive, } died := make(chan machine) go runMachine(context, m, nil, died) time.Sleep(coretesting.ShortWait) killMachineLoop(c, m, context.dyingc, died) c.Assert(context.killAllErr, gc.Equals, nil) c.Assert(count, gc.Equals, int32(1)) }
func (*lifeSuite) TestLife(c *gc.C) { st := &fakeState{ entities: map[names.Tag]entityWithError{ u("x/0"): &fakeLifer{life: state.Alive}, u("x/1"): &fakeLifer{life: state.Dying}, u("x/2"): &fakeLifer{life: state.Dead}, u("x/3"): &fakeLifer{fetchError: "x3 error"}, }, } getCanRead := func() (common.AuthFunc, error) { x0 := u("x/0") x2 := u("x/2") x3 := u("x/3") return func(tag names.Tag) bool { return tag == x0 || tag == x2 || tag == x3 }, nil } lg := common.NewLifeGetter(st, getCanRead) entities := params.Entities{[]params.Entity{ {"unit-x-0"}, {"unit-x-1"}, {"unit-x-2"}, {"unit-x-3"}, {"unit-x-4"}, }} results, err := lg.Life(entities) c.Assert(err, jc.ErrorIsNil) c.Assert(results, gc.DeepEquals, params.LifeResults{ Results: []params.LifeResult{ {Life: params.Alive}, {Error: apiservertesting.ErrUnauthorized}, {Life: params.Dead}, {Error: ¶ms.Error{Message: "x3 error"}}, {Error: apiservertesting.ErrUnauthorized}, }, }) }
func (s *PathsSuite) TestOther(c *gc.C) { s.PatchValue(&os.HostOS, func() os.OSType { return os.Unknown }) dataDir := c.MkDir() unitTag := names.NewUnitTag("some-service/323") paths := uniter.NewPaths(dataDir, unitTag) relData := relPathFunc(dataDir) relAgent := relPathFunc(relData("agents", "unit-some-service-323")) c.Assert(paths, jc.DeepEquals, uniter.Paths{ ToolsDir: relData("tools/unit-some-service-323"), Runtime: uniter.RuntimePaths{ JujuRunSocket: relAgent("run.socket"), JujucServerSocket: "@" + relAgent("agent.socket"), }, State: uniter.StatePaths{ BaseDir: relAgent(), CharmDir: relAgent("charm"), OperationsFile: relAgent("state", "uniter"), RelationsDir: relAgent("state", "relations"), BundlesDir: relAgent("state", "bundles"), DeployerDir: relAgent("state", "deployer"), StorageDir: relAgent("state", "storage"), MetricsSpoolDir: relAgent("state", "spool", "metrics"), }, }) }
func (s *PathsSuite) TestWorkerPathsWindows(c *gc.C) { s.PatchValue(&os.HostOS, func() os.OSType { return os.Windows }) dataDir := c.MkDir() unitTag := names.NewUnitTag("some-service/323") worker := "some-worker" paths := uniter.NewWorkerPaths(dataDir, unitTag, worker) relData := relPathFunc(dataDir) relAgent := relPathFunc(relData("agents", "unit-some-service-323")) c.Assert(paths, jc.DeepEquals, uniter.Paths{ ToolsDir: relData("tools/unit-some-service-323"), Runtime: uniter.RuntimePaths{ JujuRunSocket: `\\.\pipe\unit-some-service-323-some-worker-run`, JujucServerSocket: `\\.\pipe\unit-some-service-323-some-worker-agent`, }, State: uniter.StatePaths{ BaseDir: relAgent(), CharmDir: relAgent("charm"), OperationsFile: relAgent("state", "uniter"), RelationsDir: relAgent("state", "relations"), BundlesDir: relAgent("state", "bundles"), DeployerDir: relAgent("state", "deployer"), StorageDir: relAgent("state", "storage"), MetricsSpoolDir: relAgent("state", "spool", "metrics"), }, }) }
func (s *credentialsSuite) SetUpTest(c *gc.C) { s.IsolationSuite.SetUpTest(c) var err error s.provider, err = environs.Provider("gce") c.Assert(err, jc.ErrorIsNil) }
func (s *RethinkSuite) TestSelectGetAllCompoundIndex(c *test.C) { // Ensure table + database exist DBCreate("test").Exec(session) DB("test").TableDrop("TableCompound").Exec(session) DB("test").TableCreate("TableCompound").Exec(session) write, err := DB("test").Table("TableCompound").IndexCreateFunc("full_name", func(row Term) interface{} { return []interface{}{row.Field("first_name"), row.Field("last_name")} }).RunWrite(session) DB("test").Table("TableCompound").IndexWait().Exec(session) c.Assert(err, test.IsNil) c.Assert(write.Created, test.Equals, 1) // Insert rows DB("test").Table("TableCompound").Insert(nameList).Exec(session) // Test query var response interface{} query := DB("test").Table("TableCompound").GetAllByIndex("full_name", []interface{}{"John", "Smith"}) res, err := query.Run(session) c.Assert(err, test.IsNil) err = res.One(&response) c.Assert(err, test.IsNil) c.Assert(response, jsonEquals, map[string]interface{}{"id": 1, "first_name": "John", "last_name": "Smith", "gender": "M"}) res.Close() }
func (s *ColumnSuite) TestAliasColumnSetTableName(c *gc.C) { col := Alias("foo", SqlFunc("max", table1Col1)) // should always error err := col.setTableName("test") c.Assert(err, gc.NotNil) }
func (s *managedStorageSuite) TestPutPendingUpload(c *gc.C) { // Manually set up a scenario where there's a resource recorded // but the upload has not occurred. rc := blobstore.GetResourceCatalog(s.managedStorage) hash := "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7" id, path, err := rc.Put(hash, 3) c.Assert(err, gc.IsNil) c.Assert(path, gc.Equals, "") managedResource := blobstore.ManagedResource{ EnvUUID: "env", User: "******", Path: "environs/env/path/to/blob", } c.Assert(err, gc.IsNil) _, err = blobstore.PutManagedResource(s.managedStorage, managedResource, id) _, _, err = s.managedStorage.GetForEnvironment("env", "/path/to/blob") c.Assert(errors.Cause(err), gc.Equals, blobstore.ErrUploadPending) // Despite the upload being pending, a second concurrent upload will succeed. rdr := bytes.NewReader([]byte("abc")) err = s.managedStorage.PutForEnvironment("env", "/path/to/blob", rdr, 3) c.Assert(err, gc.IsNil) s.assertGet(c, "/path/to/blob", []byte("abc")) }
func (s *charmsSuite) TestGetReturnsFileContents(c *gc.C) { // Add the dummy charm. ch := testcharms.Repo.CharmArchive(c.MkDir(), "dummy") _, err := s.uploadRequest( c, s.charmsURI(c, "?series=quantal"), true, ch.Path) c.Assert(err, jc.ErrorIsNil) // Ensure the file contents are properly returned. for i, t := range []struct { summary string file string response string }{{ summary: "relative path", file: "revision", response: "1", }, { summary: "exotic path", file: "./hooks/../revision", response: "1", }, { summary: "sub-directory path", file: "hooks/install", response: "#!/bin/bash\necho \"Done!\"\n", }, } { c.Logf("test %d: %s", i, t.summary) uri := s.charmsURI(c, "?url=local:quantal/dummy-1&file="+t.file) resp, err := s.authRequest(c, "GET", uri, "", nil) c.Assert(err, jc.ErrorIsNil) s.assertGetFileResponse(c, resp, t.response, "text/plain; charset=utf-8") } }
func (s *managedStorageSuite) TestPutForEnvironmentAndCheckHashEmptyHash(c *gc.C) { // Passing "" as the hash to PutForEnvironmentAndCheckHash will elide // the hash check. rdr := strings.NewReader("data") err := s.managedStorage.PutForEnvironmentAndCheckHash("env", "/some/path", rdr, int64(rdr.Len()), "") c.Assert(err, jc.ErrorIsNil) }
func (s *charmsSuite) TestGetUsesCache(c *gc.C) { // Add a fake charm archive in the cache directory. cacheDir := filepath.Join(s.DataDir(), "charm-get-cache") err := os.MkdirAll(cacheDir, 0755) c.Assert(err, jc.ErrorIsNil) // Create and save a bundle in it. charmDir := testcharms.Repo.ClonedDir(c.MkDir(), "dummy") testPath := filepath.Join(charmDir.Path, "utils.js") contents := "// blah blah" err = ioutil.WriteFile(testPath, []byte(contents), 0755) c.Assert(err, jc.ErrorIsNil) var buffer bytes.Buffer err = charmDir.ArchiveTo(&buffer) c.Assert(err, jc.ErrorIsNil) charmArchivePath := filepath.Join( cacheDir, charm.Quote("local:trusty/django-42")+".zip") err = ioutil.WriteFile(charmArchivePath, buffer.Bytes(), 0644) c.Assert(err, jc.ErrorIsNil) // Ensure the cached contents are properly retrieved. uri := s.charmsURI(c, "?url=local:trusty/django-42&file=utils.js") resp, err := s.authRequest(c, "GET", uri, "", nil) c.Assert(err, jc.ErrorIsNil) s.assertGetFileResponse(c, resp, contents, "application/javascript") }
func (s *ActionSuite) TestEnqueueActionRequiresName(c *gc.C) { name := "" // verify can not enqueue an Action without a name _, err := s.State.EnqueueAction(s.unit.Tag(), name, nil) c.Assert(err, gc.ErrorMatches, "action name required") }
func (s *initSystemSuite) SetUpTest(c *gc.C) { s.BaseSuite.SetUpTest(c) dataDir, err := paths.DataDir("vivid") c.Assert(err, jc.ErrorIsNil) s.dataDir = dataDir // Patch things out. s.ch = systemd.PatchNewChan(s) s.stub = &testing.Stub{} s.conn = systemd.PatchNewConn(s, s.stub) s.fops = systemd.PatchFileOps(s, s.stub) s.exec = systemd.PatchExec(s, s.stub) // Set up the service. tagStr := "machine-0" tag, err := names.ParseTag(tagStr) c.Assert(err, jc.ErrorIsNil) s.tag = tag s.name = "jujud-" + tagStr s.conf = common.Conf{ Desc: "juju agent for " + tagStr, ExecStart: jujud + " " + tagStr, } s.service = s.newService(c) // Reset any incidental calls. s.stub.ResetCalls() }
func (s *ActionSuite) TestMergeIds(c *gc.C) { var tests = []struct { changes string adds string removes string expected string }{ {changes: "", adds: "a0,a1", removes: "", expected: "a0,a1"}, {changes: "a0,a1", adds: "", removes: "a0", expected: "a1"}, {changes: "a0,a1", adds: "a2", removes: "a0", expected: "a1,a2"}, {changes: "", adds: "a0,a1,a2", removes: "a0,a2", expected: "a1"}, {changes: "", adds: "a0,a1,a2", removes: "a0,a1,a2", expected: ""}, {changes: "a0", adds: "a0,a1,a2", removes: "a0,a2", expected: "a1"}, {changes: "a1", adds: "a0,a1,a2", removes: "a0,a2", expected: "a1"}, {changes: "a2", adds: "a0,a1,a2", removes: "a0,a2", expected: "a1"}, {changes: "a3,a4", adds: "a1,a4,a5", removes: "a1,a3", expected: "a4,a5"}, {changes: "a0,a1,a2", adds: "a1,a4,a5", removes: "a1,a3", expected: "a0,a2,a4,a5"}, } prefix := state.DocID(s.State, "") for ix, test := range tests { updates := mapify(prefix, test.adds, test.removes) changes := sliceify("", test.changes) expected := sliceify("", test.expected) c.Log(fmt.Sprintf("test number %d %#v", ix, test)) err := state.WatcherMergeIds(s.State, &changes, updates, state.ActionNotificationIdToActionId) c.Assert(err, jc.ErrorIsNil) c.Assert(changes, jc.SameContents, expected) } }
func (s *ActionSuite) TestFindActionTagsByPrefix(c *gc.C) { prefix := "feedbeef" uuidMock := uuidMockHelper{} uuidMock.SetPrefixMask(prefix) s.PatchValue(&state.NewUUID, uuidMock.NewUUID) actions := []struct { Name string Parameters map[string]interface{} }{ {Name: "action-1", Parameters: map[string]interface{}{}}, {Name: "fake", Parameters: map[string]interface{}{"yeah": true, "take": nil}}, {Name: "action-9", Parameters: map[string]interface{}{"district": 9}}, {Name: "blarney", Parameters: map[string]interface{}{"conversation": []string{"what", "now"}}}, } for _, action := range actions { _, err := s.State.EnqueueAction(s.unit.Tag(), action.Name, action.Parameters) c.Assert(err, gc.Equals, nil) } tags := s.State.FindActionTagsByPrefix(prefix) c.Assert(len(tags), gc.Equals, len(actions)) for i, tag := range tags { c.Logf("check %q against %d:%q", prefix, i, tag) c.Check(tag.Id()[:len(prefix)], gc.Equals, prefix) } }
func (s *initSystemSuite) TestInstallCommandsLogfile(c *gc.C) { name := "jujud-machine-0" s.conf.Logfile = "/var/log/juju/machine-0.log" service := s.newService(c) commands, err := service.InstallCommands() c.Assert(err, jc.ErrorIsNil) test := systemdtesting.WriteConfTest{ Service: name, DataDir: s.dataDir, Expected: strings.Replace( s.newConfStr(name), "ExecStart=/var/lib/juju/bin/jujud machine-0", "ExecStart=/var/lib/juju/init/jujud-machine-0/exec-start.sh", -1), Script: ` # Set up logging. touch '/var/log/juju/machine-0.log' chown syslog:syslog '/var/log/juju/machine-0.log' chmod 0600 '/var/log/juju/machine-0.log' exec >> '/var/log/juju/machine-0.log' exec 2>&1 # Run the script. `[1:] + jujud + " machine-0", } test.CheckCommands(c, commands) }