func TestDirector(t *testing.T) { g := goblin.Goblin(t) g.Describe("Director", func() { g.It("Should mark work as pending", func() { d := New() d.markPending(&worker.Work{}) d.markPending(&worker.Work{}) g.Assert(len(d.GetPending())).Equal(2) }) g.It("Should mark work as started", func() { d := New() w1 := worker.Work{} w2 := worker.Work{} d.markPending(&w1) d.markPending(&w2) g.Assert(len(d.GetPending())).Equal(2) d.markStarted(&w1, &mockWorker{}) g.Assert(len(d.GetStarted())).Equal(1) g.Assert(len(d.GetPending())).Equal(1) d.markStarted(&w2, &mockWorker{}) g.Assert(len(d.GetStarted())).Equal(2) g.Assert(len(d.GetPending())).Equal(0) }) g.It("Should mark work as complete", func() { d := New() w1 := worker.Work{} w2 := worker.Work{} d.markStarted(&w1, &mockWorker{}) d.markStarted(&w2, &mockWorker{}) g.Assert(len(d.GetStarted())).Equal(2) d.markComplete(&w1) g.Assert(len(d.GetStarted())).Equal(1) d.markComplete(&w2) g.Assert(len(d.GetStarted())).Equal(0) }) g.It("Should get work assignments", func() { d := New() w1 := worker.Work{} w2 := worker.Work{} d.markStarted(&w1, &mockWorker{}) d.markStarted(&w2, &mockWorker{}) g.Assert(len(d.GetAssignemnts())).Equal(2) }) g.It("Should recover from a panic", func() { d := New() d.Do(nil, nil) g.Assert(true).Equal(true) }) g.It("Should distribute work to worker", func() { work := &worker.Work{} workr := &mockWorker{} c := context.Background() p := pool.New() p.Allocate(workr) c = pool.NewContext(c, p) d := New() d.do(c, work) g.Assert(workr.work).Equal(work) // verify mock worker gets work }) g.It("Should add director to context", func() { d := New() c := context.Background() c = NewContext(c, d) g.Assert(worker.FromContext(c)).Equal(d) }) }) }
func main() { log.SetPriority(log.LOG_NOTICE) // Parses flags. The only flag that can be passed into the // application is the location of the configuration (.toml) file. var conf string flag.StringVar(&conf, "config", "", "") flag.Parse() config.Var(&nodes, "worker-nodes") // Parses config data. The config data can be stored in a config // file (.toml format) or environment variables, or a combo. config.SetPrefix("DRONE_") err := config.Parse(conf) if err != nil { log.Errf("Unable to parse config: %v", err) os.Exit(1) } // Setup the remote services. We need to execute these to register // the remote plugins with the system. // // NOTE: this cannot be done via init() because they need to be // executed after config.Parse bitbucket.Register() github.Register() gitlab.Register() gogs.Register() // setup the database and cancel all pending // commits in the system. db = database.MustConnect(*driver, *datasource) go database.NewCommitstore(db).KillCommits() // Create the worker, director and builders workers = pool.New() worker = director.New() if nodes == nil || len(nodes) == 0 { workers.Allocate(docker.New()) workers.Allocate(docker.New()) } else { for _, node := range nodes { if strings.HasPrefix(node, "unix://") { workers.Allocate(docker.NewHost(node)) } else if *dockercert != "" && *dockerkey != "" { workers.Allocate(docker.NewHostCertFile(node, *dockercert, *dockerkey)) } else { fmt.Println(DockerTLSWarning) workers.Allocate(docker.NewHost(node)) } } } pub = pubsub.NewPubSub() // create handler for static resources // if we have a configured assets folder it takes precedence over the assets // bundled to the binary var assetserve http.Handler if *assets_folder != "" { assetserve = http.FileServer(http.Dir(*assets_folder)) } else { assetserve = http.FileServer(rice.MustFindBox("app").HTTPBox()) } http.Handle("/robots.txt", assetserve) http.Handle("/static/", http.StripPrefix("/static", assetserve)) http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { r.URL.Path = "/" assetserve.ServeHTTP(w, r) }) // create the router and add middleware mux := router.New() mux.Use(middleware.Options) mux.Use(ContextMiddleware) mux.Use(middleware.SetHeaders) mux.Use(middleware.SetUser) http.Handle("/api/", mux) // start the http server in either http or https mode, // depending on whether a certificate was provided. if len(*sslcrt) == 0 { panic(http.ListenAndServe(*port, nil)) } else { panic(http.ListenAndServeTLS(*port, *sslcrt, *sslkey, nil)) } }