func (s *S) TestExportEnvironmentsBackward(c *gocheck.C) { envNames := []string{ "TSURU_S3_ACCESS_KEY_ID", "TSURU_S3_SECRET_KEY", "TSURU_APPNAME", "TSURU_HOST", "TSURU_S3_ENDPOINT", "TSURU_S3_LOCATIONCONSTRAINT", "TSURU_S3_BUCKET", "TSURU_APP_TOKEN", } app := App{Name: "moon", Platform: "opeth", Env: make(map[string]bind.EnvVar)} for _, name := range envNames { envVar := bind.EnvVar{Name: name, Value: name, Public: false} if strings.HasPrefix(name, "TSURU_S3_") { envVar.InstanceName = s3InstanceName } app.Env[name] = envVar } token, err := auth.CreateApplicationToken(app.Name) c.Assert(err, gocheck.IsNil) app.Env["TSURU_APP_TOKEN"] = bind.EnvVar{Name: "TSURU_APP_NAME", Value: token.Token} err = s.conn.Apps().Insert(app) c.Assert(err, gocheck.IsNil) defer s.conn.Apps().Remove(bson.M{"name": app.Name}) ctx := action.BWContext{Params: []interface{}{&app}} exportEnvironmentsAction.Backward(ctx) copy, err := GetByName(app.Name) c.Assert(err, gocheck.IsNil) for _, name := range envNames { if _, ok := copy.Env[name]; ok { c.Errorf("Variable %q should be unexported, but it's still exported.", name) } } _, err = auth.GetToken("bearer " + token.Token) c.Assert(err, gocheck.Equals, auth.ErrInvalidToken) }
func (t *LiveTests) TestStopInstances(c *gc.C) { // It would be nice if this test was in jujutest, but // there's no way for jujutest to fabricate a valid-looking // instance id. inst0, _ := testing.AssertStartInstance(c, t.Env, "40") inst1 := ec2.FabricateInstance(inst0, "i-aaaaaaaa") inst2, _ := testing.AssertStartInstance(c, t.Env, "41") err := t.Env.StopInstances(inst0.Id(), inst1.Id(), inst2.Id()) c.Check(err, gc.IsNil) var insts []instance.Instance // We need the retry logic here because we are waiting // for Instances to return an error, and it will not retry // if it succeeds. gone := false for a := ec2.ShortAttempt.Start(); a.Next(); { insts, err = t.Env.Instances([]instance.Id{inst0.Id(), inst2.Id()}) if err == environs.ErrPartialInstances { // instances not gone yet. continue } if err == environs.ErrNoInstances { gone = true break } c.Fatalf("error getting instances: %v", err) } if !gone { c.Errorf("after termination, instances remaining: %v", insts) } }
func (tw *TestWatcher) TriggerChange(c *gc.C) { select { case tw.changes <- struct{}{}: case <-time.After(coretesting.LongWait): c.Errorf("Timeout changes triggering change after %s", coretesting.LongWait) } }
func (s *singularSuite) TestPingCalledOnceOnlyForSeveralWorkers(c *gc.C) { // Patch the ping interval to a large value, start several workers // and check that Ping is only called once. s.PatchValue(&singular.PingInterval, testing.LongWait) underlyingRunner := newRunner() conn := &fakeConn{ isMaster: false, pinged: make(chan struct{}, 2), } r, err := singular.New(underlyingRunner, conn) c.Assert(err, gc.IsNil) for i := 0; i < 5; i++ { name := fmt.Sprint("worker", i) err := r.StartWorker(name, func() (worker.Worker, error) { c.Errorf("worker unexpectedly started") return nil, fmt.Errorf("no worker") }) c.Assert(err, gc.IsNil) } time.Sleep(testing.ShortWait) n := 0 loop: for { select { case <-conn.pinged: n++ default: break loop } } c.Assert(n, gc.Equals, 1) }
// Communicate with all EC2 endpoints to see if they are alive. func (s *ClientTests) TestRegions(c *gocheck.C) { name := sessionName("goamz-region-test") perms := []ec2.IPPerm{{ Protocol: "tcp", FromPort: 80, ToPort: 80, SourceIPs: []string{"127.0.0.1/32"}, }} errs := make(chan error, len(allRegions)) for _, region := range allRegions { go func(r aws.Region) { e := ec2.New(s.ec2.Auth, r) _, err := e.AuthorizeSecurityGroup(ec2.SecurityGroup{Name: name}, perms) errs <- err }(region) } for _ = range allRegions { err := <-errs if err != nil { ec2_err, ok := err.(*ec2.Error) if ok { c.Check(ec2_err.Code, gocheck.Matches, "InvalidGroup.NotFound") } else { c.Errorf("Non-EC2 error: %s", err) } } else { c.Errorf("Test should have errored but it seems to have succeeded") } } }
func (s *watcherSuite) TestWatchInitialEventConsumed(c *gc.C) { // Machiner.Watch should send the initial event as part of the Watch // call (for NotifyWatchers there is no state to be transmitted). So a // call to Next() should not have anything to return. var results params.NotifyWatchResults args := params.Entities{Entities: []params.Entity{{Tag: s.rawMachine.Tag().String()}}} err := s.stateAPI.Call("Machiner", "", "Watch", args, &results) c.Assert(err, gc.IsNil) c.Assert(results.Results, gc.HasLen, 1) result := results.Results[0] c.Assert(result.Error, gc.IsNil) // We expect the Call() to "Next" to block, so run it in a goroutine. done := make(chan error) go func() { ignored := struct{}{} done <- s.stateAPI.Call("NotifyWatcher", result.NotifyWatcherId, "Next", nil, &ignored) }() select { case err := <-done: c.Errorf("Call(Next) did not block immediately after Watch(): err %v", err) case <-time.After(coretesting.ShortWait): } }
func (s *S) TestUnitListState(c *gocheck.C) { var tests = []struct { input []Unit expected string }{ { []Unit{{State: "started"}, {State: "started"}}, "started", }, {nil, ""}, { []Unit{{State: "started"}, {State: "pending"}}, "", }, { []Unit{{State: "error"}}, "error", }, { []Unit{{State: "pending"}}, "pending", }, } for _, t := range tests { l := unitList(t.input) if got := l.State(); got != t.expected { c.Errorf("l.State(): want %q. Got %q.", t.expected, got) } } }
func (s *storageSuite) TestWriteFailure(c *gc.C) { // Invocations: // 1: first "install" // 2: touch, Put // 3: second "install" // 4: touch var invocations int badSshCommand := func(host string, command ...string) *ssh.Cmd { invocations++ switch invocations { case 1, 3: return s.sshCommand(c, host, "true") case 2: // Note: must close stdin before responding the first time, or // the second command will race with closing stdin, and may // flush first. return s.sshCommand(c, host, "head -n 1 > /dev/null; exec 0<&-; echo JUJU-RC: 0; echo blah blah; echo more") case 4: return s.sshCommand(c, host, `head -n 1 > /dev/null; echo "Hey it's JUJU-RC: , but not at the beginning of the line"; echo more`) default: c.Errorf("unexpected invocation: #%d, %s", invocations, command) return nil } } s.PatchValue(&sshCommand, badSshCommand) stor, err := newSSHStorage("example.com", c.MkDir(), c.MkDir()) c.Assert(err, gc.IsNil) defer stor.Close() err = stor.Put("whatever", bytes.NewBuffer(nil), 0) c.Assert(err, gc.ErrorMatches, `failed to write input: write \|1: broken pipe \(output: "blah blah\\nmore"\)`) _, err = newSSHStorage("example.com", c.MkDir(), c.MkDir()) c.Assert(err, gc.ErrorMatches, `failed to locate "JUJU-RC: " \(output: "Hey it's JUJU-RC: , but not at the beginning of the line\\nmore"\)`) }
func checkInteger(elem interface{}, expected int64, c *gc.C) { if num, is_num := elem.(Integer); is_num { c.Check(num.ToInteger(), gc.Equals, expected) } else { c.Errorf("actual value is not an Integer: %T", elem) } }
// Communicate with all endpoints to see if they are alive. func (s *ClientTests) TestRegions(c *gocheck.C) { errs := make(chan error, len(aws.Regions)) for _, region := range aws.Regions { go func(r aws.Region) { s := s3.New(s.s3.Auth, r) b := s.Bucket("goamz-" + s.Auth.AccessKey) _, err := b.Get("non-existent") errs <- err }(region) } for _ = range aws.Regions { err := <-errs if err != nil { s3_err, ok := err.(*s3.Error) if ok { c.Check(s3_err.Code, gocheck.Matches, "NoSuchBucket") } else if _, ok = err.(*net.DNSError); ok { // Okay as well. } else { c.Errorf("Non-S3 error: %s", err) } } else { c.Errorf("Test should have errored but it seems to have succeeded") } } }
func (s *S) TestUnitListStarted(c *gocheck.C) { var tests = []struct { input []Unit expected bool }{ { []Unit{ {State: "started"}, {State: "started"}, {State: "started"}, }, true, }, {nil, true}, { []Unit{ {State: "started"}, {State: "blabla"}, }, false, }, } for _, t := range tests { l := unitList(t.input) if got := l.Started(); got != t.expected { c.Errorf("l.Started(): want %v. Got %v.", t.expected, got) } } }
func (s *IntegrationTestSuite) TestLongContainerName(c *chk.C) { id, err := containers.NewIdentifier("IntTest006xxxxxxxxxxxxxx") c.Assert(err, chk.IsNil) s.containerIds = append(s.containerIds, id) hostContainerId := fmt.Sprintf("%v/%v", s.daemonURI, id) cmd := exec.Command("/usr/bin/gear", "install", TestImage, hostContainerId, "--start", "--ports=8080:0", "--isolate") data, err := cmd.CombinedOutput() c.Log(string(data)) c.Assert(err, chk.IsNil) s.assertContainerStarts(c, id) s.assertFilePresent(c, id.UnitPathFor(), 0664, true) s.assertFilePresent(c, filepath.Join(id.RunPathFor(), "container-init.sh"), 0700, false) ports, err := containers.GetExistingPorts(id) c.Assert(err, chk.IsNil) c.Assert(len(ports), chk.Equals, 1) httpAlive := func() bool { resp, err := http.Get(fmt.Sprintf("http://0.0.0.0:%v", ports[0].External)) if err == nil { c.Assert(resp.StatusCode, chk.Equals, 200) return true } return false } if !until(TimeoutContainerStateChange, IntervalHttpCheck, httpAlive) { c.Errorf("Unable to retrieve a 200 status code from port %d", ports[0].External) c.FailNow() } }
func (s *IntegrationTestSuite) assertContainerStartsAndExits(c *chk.C, start time.Time, id containers.Identifier) { hasStarted := func() bool { _, inactiveEnd, activeStart, _ := s.unitTimes(id) if inactiveEnd.IsZero() || activeStart.IsZero() { c.Logf("Variables empty before") } if inactiveEnd.Before(start) || activeStart.Before(start) { return false } return true } if !until(TimeoutContainerStateChange, IntervalContainerCheck, hasStarted) { c.Errorf("The service did not start in the allotted time") c.FailNow() } hasCompleted := func() bool { switch active, _ := s.unitState(id); active { case "active", "activating", "deactivating": return false } return true } if !until(TimeoutContainerStateChange, IntervalContainerCheck, hasCompleted) { c.Errorf("The service did not finish in the allotted time") c.FailNow() } }
func (s *S) TestIsValid(c *gocheck.C) { var data = []struct { name string expected bool }{ {"myappmyappmyappmyappmyappmyappmyappmyappmyappmyappmyappmyappmyapp", false}, {"myappmyappmyappmyappmyappmyappmyappmyappmyappmyappmyappmyappmyap", false}, {"myappmyappmyappmyappmyappmyappmyappmyappmyappmyappmyappmyappmya", true}, {"myApp", false}, {"my app", false}, {"123myapp", false}, {"myapp", true}, {"_theirapp", false}, {"my-app", true}, {"-myapp", false}, {"my_app", false}, {"b", true}, } for _, d := range data { a := App{Name: d.name} if valid := a.isValid(); valid != d.expected { c.Errorf("Is %q a valid app name? Expected: %v. Got: %v.", d.name, d.expected, valid) } } }
func (s *ManagerTestSuite) TestAddWatcher(t *gocheck.C) { now = int64(1380330697385120263) // Fri Sep 27 18:11:37.385120 -0700 PDT 2013 s.tickerFactory.Set([]ticker.Ticker{s.mockTicker}) m := ticker.NewClock(s.tickerFactory, nowFunc) c := make(chan time.Time) m.Add(c, 79, true) if !test.WaitState(s.mockTicker.RunningChan) { t.Error("Starts ticker") } if ok, diff := test.IsDeeply(s.tickerFactory.Made, []uint{79}); !ok { t.Errorf("Make 79s ticker, got %#v", diff) } if len(s.mockTicker.Added) == 0 { t.Error("Ticker added watcher") } // Manager should call ticker's ETA() to return time to next tick. d := m.ETA(c) if d != 0.1 { t.Error("clock.Manager.ETA()") } m.Remove(c) }
func waitForHandledNotify(c *gc.C, handled chan struct{}) { select { case <-handled: case <-time.After(coretesting.LongWait): c.Errorf("handled failed to signal after %s", coretesting.LongWait) } }
func (s *S) TestExportEnvironmentsBackward(c *gocheck.C) { envNames := []string{ "TSURU_APP_TOKEN", } app := App{Name: "moon", Platform: "opeth", Env: make(map[string]bind.EnvVar)} for _, name := range envNames { envVar := bind.EnvVar{Name: name, Value: name, Public: false} app.Env[name] = envVar } token, err := nativeScheme.AppLogin(app.Name) c.Assert(err, gocheck.IsNil) app.Env["TSURU_APP_TOKEN"] = bind.EnvVar{Name: "TSURU_APP_NAME", Value: token.GetValue()} err = s.conn.Apps().Insert(app) c.Assert(err, gocheck.IsNil) defer s.conn.Apps().Remove(bson.M{"name": app.Name}) ctx := action.BWContext{Params: []interface{}{&app}} exportEnvironmentsAction.Backward(ctx) copy, err := GetByName(app.Name) c.Assert(err, gocheck.IsNil) for _, name := range envNames { if _, ok := copy.Env[name]; ok { c.Errorf("Variable %q should be unexported, but it's still exported.", name) } } _, err = nativeScheme.Auth(token.GetValue()) c.Assert(err, gocheck.Equals, auth.ErrInvalidToken) }
func (s *S) TestCreateTeamValidation(c *gocheck.C) { var tests = []struct { input string err error }{ {"", ErrInvalidTeamName}, {" ", ErrInvalidTeamName}, {"1abc", ErrInvalidTeamName}, {"a", ErrInvalidTeamName}, {"@abc", ErrInvalidTeamName}, {"my team", nil}, {"team-1", nil}, {"team_1", nil}, {"ab", nil}, {"Abacaxi", nil}, {"*****@*****.**", nil}, } for _, t := range tests { err := CreateTeam(t.input) if err != t.err { c.Errorf("Is %q valid? Want %v. Got %v.", t.input, t.err, err) } defer s.conn.Teams().Remove(bson.M{"_id": t.input}) } }
func (s *BootstrapSuite) TestKeepBrokenDoesNoStop(c *gc.C) { innerStorage := newStorage(s, c) stor := &mockStorage{Storage: innerStorage} checkHardware := instance.MustParseHardware("arch=ppc64el mem=2T") startInstance := func( _ string, _ constraints.Value, _ []string, _ tools.List, mcfg *cloudinit.MachineConfig, ) ( instance.Instance, *instance.HardwareCharacteristics, []network.Info, error, ) { stor.putErr = fmt.Errorf("suddenly a wild blah") return &mockInstance{id: "i-blah"}, &checkHardware, nil, nil } stopInstances := func(instances []instance.Id) error { c.Errorf("unexpected call to StopInstances") return nil } env := &mockEnviron{ storage: stor, startInstance: startInstance, stopInstances: stopInstances, config: configGetter(c), } ctx := coretesting.Context(c) _, _, _, err := common.Bootstrap(ctx, env, environs.BootstrapParams{ KeepBroken: true, AvailableTools: tools.List{&tools.Tools{Version: version.Current}}, }) c.Assert(err, gc.ErrorMatches, "cannot save state: suddenly a wild blah") }
func (s *DynamoDBTest) WaitUntilStatus(c *gocheck.C, status string) { // We should wait until the table is in specified status because a real DynamoDB has some delay for ready done := make(chan bool) timeout := time.After(TIMEOUT) go func() { for { select { case <-done: return default: desc, err := s.table.DescribeTable() if err != nil { c.Fatal(err) } if desc.TableStatus == status { done <- true return } time.Sleep(5 * time.Second) } } }() select { case <-done: break case <-timeout: c.Errorf("Expect a status to be %s, but timed out", status) close(done) } }
// installFakeSSH creates a fake "ssh" command in a new $PATH, // updates $PATH, and returns a function to reset $PATH to its // original value when called. // // input may be: // - nil (ignore input) // - a string (match input exactly) // output may be: // - nil (no output) // - a string (stdout) // - a slice of strings, of length two (stdout, stderr) func installFakeSSH(c *gc.C, input, output interface{}, rc int) testing.Restorer { fakebin := c.MkDir() ssh := filepath.Join(fakebin, "ssh") switch input := input.(type) { case nil: case string: sshexpectedinput := ssh + ".expected-input" err := ioutil.WriteFile(sshexpectedinput, []byte(input), 0644) c.Assert(err, gc.IsNil) default: c.Errorf("input has invalid type: %T", input) } var stdout, stderr string switch output := output.(type) { case nil: case string: stdout = fmt.Sprintf("cat<<EOF\n%s\nEOF", output) case []string: c.Assert(output, gc.HasLen, 2) stdout = fmt.Sprintf("cat<<EOF\n%s\nEOF", output[0]) stderr = fmt.Sprintf("cat>&2<<EOF\n%s\nEOF", output[1]) } script := fmt.Sprintf(sshscript, stdout, stderr, rc) err := ioutil.WriteFile(ssh, []byte(script), 0777) c.Assert(err, gc.IsNil) return testing.PatchEnvPathPrepend(fakebin) }
func (s *S) TestUnitStatus(c *gocheck.C) { var tests = []struct { instance string agent string machineAgent string expected provision.Status }{ {"something", "nothing", "wut", provision.StatusPending}, {"", "", "", provision.StatusCreating}, {"", "", "pending", provision.StatusCreating}, {"", "", "not-started", provision.StatusCreating}, {"pending", "", "", provision.StatusCreating}, {"", "not-started", "running", provision.StatusCreating}, {"error", "install-error", "start-error", provision.StatusError}, {"started", "start-error", "running", provision.StatusError}, {"started", "charm-upgrade-error", "running", provision.StatusError}, {"running", "pending", "running", provision.StatusInstalling}, {"running", "started", "running", provision.StatusStarted}, {"running", "down", "running", provision.StatusDown}, } for _, t := range tests { got := unitStatus(t.instance, t.agent, t.machineAgent) if got != t.expected { c.Errorf("unitStatus(%q, %q, %q): Want %q. Got %q.", t.instance, t.agent, t.machineAgent, t.expected, got) } } }
func (s *S) TestRemoveUnit(c *gocheck.C) { fexec := &etesting.FakeExecutor{} setExecut(fexec) defer setExecut(nil) app := testing.NewFakeApp("two", "rush", 3) p := JujuProvisioner{} collection := p.unitsCollection() defer collection.Close() err := collection.Insert(instance{UnitName: "two/2", InstanceID: "i-00000439"}) c.Assert(err, gocheck.IsNil) err = p.RemoveUnit(app, "two/2") c.Assert(err, gocheck.IsNil) ran := make(chan bool, 1) go func() { for { args1 := []string{"remove-unit", "two/2"} args2 := []string{"terminate-machine", "3"} if fexec.ExecutedCmd("juju", args1) && fexec.ExecutedCmd("juju", args2) { ran <- true } runtime.Gosched() } }() select { case <-ran: case <-time.After(2e9): c.Errorf("Did not run terminate-machine command after 2 seconds.") } n, err := collection.Find(bson.M{"_id": "two/2"}).Count() c.Assert(err, gocheck.IsNil) c.Assert(n, gocheck.Equals, 0) }
func (tsw *testStringsWatcher) TriggerChange(c *gc.C, changes []string) { select { case tsw.changes <- changes: case <-time.After(coretesting.LongWait): c.Errorf("timed out trying to trigger a change") } }
func (s *S) TestRetire(c *gocheck.C) { defer func() { if r := recover(); !c.Failed() && r == nil { c.Errorf("Should panic in ping, but did not!") } }() Open("127.0.0.1:27017", "tsuru_storage_test") sess := conn["127.0.0.1:27017"] sess.used = sess.used.Add(-1 * 2 * period) conn["127.0.0.1:27017"] = sess var ticker time.Ticker ch := make(chan time.Time, 1) ticker.C = ch ch <- time.Now() var wg sync.WaitGroup wg.Add(1) go func() { retire(&ticker) wg.Done() }() close(ch) wg.Wait() _, ok := conn["127.0.0.1:27017"] c.Check(ok, gocheck.Equals, false) sess.s.Ping() }
func (s *InstanceSuite) TestCreateServiceInstanceValidatesTheName(c *gocheck.C) { var tests = []struct { input string err error }{ {"my-service", nil}, {"my_service", nil}, {"my_service_123", nil}, {"My_service_123", nil}, {"a1", nil}, {"--app", ErrInvalidInstanceName}, {"123servico", ErrInvalidInstanceName}, {"a", ErrInvalidInstanceName}, {"a@123", ErrInvalidInstanceName}, } ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNoContent) })) defer ts.Close() srv := Service{Name: "mongodb", Endpoint: map[string]string{"production": ts.URL}} err := s.conn.Services().Insert(&srv) c.Assert(err, gocheck.IsNil) defer s.conn.Services().RemoveId(srv.Name) for _, t := range tests { err := CreateServiceInstance(t.input, &srv, nil, s.user) if err != t.err { c.Errorf("Is %q valid? Want %#v. Got %#v", t.input, t.err, err) } defer s.conn.ServiceInstances().Remove(bson.M{"name": t.input}) } }
func assertSecurityGroups(c *gc.C, env environs.Environ, expected []string) { novaClient := openstack.GetNovaClient(env) groups, err := novaClient.ListSecurityGroups() c.Assert(err, gc.IsNil) for _, name := range expected { found := false for _, group := range groups { if group.Name == name { found = true break } } if !found { c.Errorf("expected security group %q not found", name) } } for _, group := range groups { found := false for _, name := range expected { if group.Name == name { found = true break } } if !found { c.Errorf("existing security group %q is not expected", group.Name) } } }
func (s *workerSuite) TestWorkerPublishesInstanceIds(c *gc.C) { s.PatchValue(&pollInterval, coretesting.LongWait+time.Second) s.PatchValue(&initialRetryInterval, 5*time.Millisecond) s.PatchValue(&maxRetryInterval, initialRetryInterval) publishCh := make(chan []instance.Id, 100) publish := func(apiServers [][]instance.HostPort, instanceIds []instance.Id) error { publishCh <- instanceIds return nil } st := newFakeState() initState(c, st, 3) w := newWorker(st, publisherFunc(publish)) defer func() { c.Check(worker.Stop(w), gc.IsNil) }() select { case instanceIds := <-publishCh: c.Assert(instanceIds, jc.SameContents, []instance.Id{"id-10", "id-11", "id-12"}) case <-time.After(coretesting.LongWait): c.Errorf("timed out waiting for publish") } }
func (tnw *testNotifyWatcher) TriggerChange(c *gc.C) { select { case tnw.changes <- struct{}{}: case <-time.After(coretesting.LongWait): c.Errorf("timed out trying to trigger a change") } }
func checkSecurityGroupAllowed(c *gc.C, perms []amzec2.IPPerm, g amzec2.SecurityGroup) { protos := map[string]struct { fromPort int toPort int }{ "tcp": {0, 65535}, "udp": {0, 65535}, "icmp": {-1, -1}, } for _, perm := range perms { if len(perm.SourceGroups) > 0 { c.Check(perm.SourceGroups, gc.HasLen, 1) c.Check(perm.SourceGroups[0].Id, gc.Equals, g.Id) ports, ok := protos[perm.Protocol] if !ok { c.Errorf("unexpected protocol in security group: %q", perm.Protocol) continue } delete(protos, perm.Protocol) c.Check(perm.FromPort, gc.Equals, ports.fromPort) c.Check(perm.ToPort, gc.Equals, ports.toPort) } } if len(protos) > 0 { c.Errorf("%d security group permission not found for %#v in %#v", len(protos), g, perms) } }