func setupStepOpenLogWriter() (*stepOpenLogWriter, multistep.StateBag) {
	s := &stepOpenLogWriter{logTimeout: time.Second, maxLogLength: 4}

	bp, _ := backend.NewBackendProvider("fake", config.ProviderConfigFromMap(map[string]string{}))
	ctx := gocontext.TODO()
	instance, _ := bp.Start(ctx, nil)

	job := &fakeJob{
		payload: &JobPayload{
			Type: "job:test",
			Job: JobJobPayload{
				ID:     2,
				Number: "3.1",
			},
			Build: BuildPayload{
				ID:     1,
				Number: "3",
			},
			Repository: RepositoryPayload{
				ID:   4,
				Slug: "green-eggs/ham",
			},
			UUID:     "foo-bar",
			Config:   map[string]interface{}{},
			Timeouts: TimeoutsPayload{},
		},
	}

	state := &multistep.BasicStateBag{}
	state.Put("ctx", ctx)
	state.Put("buildJob", job)
	state.Put("instance", instance)

	return s, state
}
func TestProcessor(t *testing.T) {
	uuid := uuid.NewRandom()
	ctx := workerctx.FromProcessor(context.TODO(), uuid.String())

	provider, err := backend.NewBackendProvider("fake", config.ProviderConfigFromMap(map[string]string{
		"LOG_OUTPUT": "hello, world",
	}))
	if err != nil {
		t.Error(err)
	}

	generator := buildScriptGeneratorFunction(func(ctx context.Context, json *simplejson.Json) ([]byte, error) {
		return []byte("hello, world"), nil
	})

	jobChan := make(chan Job)
	canceller := &fakeCanceller{}

	processor, err := NewProcessor(ctx, "test-hostname", jobChan, provider, generator, canceller, 2*time.Second, time.Second, 3*time.Second, 4*time.Second)
	if err != nil {
		t.Error(err)
	}

	doneChan := make(chan struct{})
	go func() {
		processor.Run()
		doneChan <- struct{}{}
	}()

	job := &fakeJob{
		payload: &JobPayload{
			Type: "job:test",
			Job: JobJobPayload{
				ID:     2,
				Number: "3.1",
			},
			Build: BuildPayload{
				ID:     1,
				Number: "3",
			},
			Repository: RepositoryPayload{
				ID:   4,
				Slug: "green-eggs/ham",
			},
			UUID:     "foo-bar",
			Config:   map[string]interface{}{},
			Timeouts: TimeoutsPayload{},
		},
		startAttributes: &backend.StartAttributes{},
	}
	jobChan <- job

	processor.GracefulShutdown()
	<-doneChan

	if processor.ProcessedCount != 1 {
		t.Errorf("processor.ProcessedCount = %d, expected %d", processor.ProcessedCount, 1)
	}

	expectedEvents := []string{"received", "started", string(FinishStatePassed)}
	if !reflect.DeepEqual(expectedEvents, job.events) {
		t.Errorf("job.events = %#v, expected %#v", job.events, expectedEvents)
	}

	if canceller.subscribedIDs[0] != 2 {
		t.Errorf("canceller.subscribedIDs[0] = %d, expected 2", canceller.subscribedIDs[0])
	}
	if canceller.unsubscribedIDs[0] != 2 {
		t.Errorf("canceller.unsubscribedIDs[0] = %d, expected 2", canceller.unsubscribedIDs[0])
	}
}
Exemple #3
0
// Setup runs one-time preparatory actions and returns a boolean success value
// that is used to determine if it is safe to invoke the Run func
func (i *CLI) Setup() (bool, error) {
	if i.c.String("pprof-port") != "" {
		// Start net/http/pprof server
		go func() {
			http.ListenAndServe(fmt.Sprintf("localhost:%s", i.c.String("pprof-port")), nil)
		}()
	}

	if i.c.Bool("debug") {
		logrus.SetLevel(logrus.DebugLevel)
	}

	ctx, cancel := gocontext.WithCancel(gocontext.Background())
	logger := context.LoggerFromContext(ctx)

	i.ctx = ctx
	i.cancel = cancel
	i.logger = logger

	logrus.SetFormatter(&logrus.TextFormatter{DisableColors: true})

	cfg := config.FromCLIContext(i.c)
	i.Config = cfg

	if i.c.Bool("echo-config") {
		config.WriteEnvConfig(cfg, os.Stdout)
		return false, nil
	}

	if i.c.Bool("list-backend-providers") {
		backend.EachBackend(func(b *backend.Backend) {
			fmt.Println(b.Alias)
		})
		return false, nil
	}

	logger.WithFields(logrus.Fields{
		"cfg": fmt.Sprintf("%#v", cfg),
	}).Debug("read config")

	i.setupSentry()
	i.setupMetrics()

	err := i.setupJobQueueAndCanceller()
	if err != nil {
		logger.WithField("err", err).Error("couldn't create job queue and canceller")
		return false, err
	}

	generator := NewBuildScriptGenerator(cfg)
	logger.WithFields(logrus.Fields{
		"build_script_generator": fmt.Sprintf("%#v", generator),
	}).Debug("built")

	i.BuildScriptGenerator = generator

	provider, err := backend.NewBackendProvider(cfg.ProviderName, cfg.ProviderConfig)
	if err != nil {
		logger.WithField("err", err).Error("couldn't create backend provider")
		return false, err
	}

	err = provider.Setup(ctx)
	if err != nil {
		logger.WithField("err", err).Error("couldn't setup backend provider")
		return false, err
	}

	logger.WithFields(logrus.Fields{
		"provider": fmt.Sprintf("%#v", provider),
	}).Debug("built")

	i.BackendProvider = provider

	ppc := &ProcessorPoolConfig{
		Hostname:            cfg.Hostname,
		Context:             ctx,
		HardTimeout:         cfg.HardTimeout,
		LogTimeout:          cfg.LogTimeout,
		ScriptUploadTimeout: cfg.ScriptUploadTimeout,
		StartupTimeout:      cfg.StartupTimeout,
	}

	pool := NewProcessorPool(ppc, i.BackendProvider, i.BuildScriptGenerator, i.Canceller)

	pool.SkipShutdownOnLogTimeout = cfg.SkipShutdownOnLogTimeout
	logger.WithFields(logrus.Fields{
		"pool": pool,
	}).Debug("built")

	i.ProcessorPool = pool

	return true, nil
}