mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
refactor runner
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
package runner
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
@@ -24,24 +24,15 @@ type Config struct {
|
||||
Timeout time.Duration
|
||||
RequestURL string
|
||||
AppName string
|
||||
Stdout io.Writer
|
||||
Stderr io.Writer
|
||||
}
|
||||
|
||||
type Runner struct {
|
||||
cfg *Config
|
||||
status string
|
||||
out bytes.Buffer
|
||||
err bytes.Buffer
|
||||
driver drivers.Driver
|
||||
}
|
||||
|
||||
func New(cfg *Config) *Runner {
|
||||
return &Runner{
|
||||
cfg: cfg,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Runner) Run() error {
|
||||
var err error
|
||||
|
||||
func New() (*Runner, error) {
|
||||
// TODO: Is this really required for Titan's driver?
|
||||
// Can we remove it?
|
||||
env := common.NewEnvironment(func(e *common.Environment) {})
|
||||
@@ -49,36 +40,28 @@ func (r *Runner) Run() error {
|
||||
// TODO: Create a drivers.New(runnerConfig) in Titan
|
||||
driver, err := selectDriver("docker", env, &driverscommon.Config{})
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Runner{
|
||||
driver: driver,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r *Runner) Run(ctx context.Context, cfg *Config) (drivers.RunResult, error) {
|
||||
var err error
|
||||
|
||||
ctask := &containerTask{
|
||||
cfg: r.cfg,
|
||||
auth: &agent.ConfigAuth{},
|
||||
stdout: &r.out,
|
||||
stderr: &r.err,
|
||||
cfg: cfg,
|
||||
auth: &agent.ConfigAuth{},
|
||||
}
|
||||
|
||||
result, err := driver.Run(r.cfg.Ctx, ctask)
|
||||
result, err := r.driver.Run(ctx, ctask)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r.status = result.Status()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Runner) ReadOut() []byte {
|
||||
return r.out.Bytes()
|
||||
}
|
||||
|
||||
func (r Runner) ReadErr() []byte {
|
||||
return r.err.Bytes()
|
||||
}
|
||||
|
||||
func (r Runner) Status() string {
|
||||
return r.status
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func selectDriver(driver string, env *common.Environment, conf *driverscommon.Config) (drivers.Driver, error) {
|
||||
|
||||
@@ -11,6 +11,13 @@ import (
|
||||
)
|
||||
|
||||
func TestRunnerHello(t *testing.T) {
|
||||
runner, err := New()
|
||||
if err != nil {
|
||||
t.Fatalf("Test error during New() - %s", err)
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
for i, test := range []struct {
|
||||
route *models.Route
|
||||
payload string
|
||||
@@ -21,33 +28,43 @@ func TestRunnerHello(t *testing.T) {
|
||||
{&models.Route{Image: "iron/hello"}, ``, "success", "Hello World!", ""},
|
||||
{&models.Route{Image: "iron/hello"}, `{"name": "test"}`, "success", "Hello test!", ""},
|
||||
} {
|
||||
runner := New(&Config{
|
||||
var stdout, stderr bytes.Buffer
|
||||
cfg := &Config{
|
||||
ID: fmt.Sprintf("task-hello-%d-%d", i, time.Now().Unix()),
|
||||
Ctx: context.Background(),
|
||||
Route: test.route,
|
||||
Timeout: 5 * time.Second,
|
||||
Payload: test.payload,
|
||||
})
|
||||
Stdout: &stdout,
|
||||
Stderr: &stderr,
|
||||
}
|
||||
|
||||
if err := runner.Run(); err != nil {
|
||||
result, err := runner.Run(ctx, cfg)
|
||||
if err != nil {
|
||||
t.Fatalf("Test %d: error during Run() - %s", i, err)
|
||||
}
|
||||
|
||||
if test.expectedStatus != runner.Status() {
|
||||
t.Fatalf("Test %d: expected result status to be `%s` but it was `%s`", i, test.expectedStatus, runner.Status())
|
||||
if test.expectedStatus != result.Status() {
|
||||
t.Fatalf("Test %d: expected result status to be `%s` but it was `%s`", i, test.expectedStatus, result.Status())
|
||||
}
|
||||
|
||||
if !bytes.Contains(runner.ReadOut(), []byte(test.expectedOut)) {
|
||||
t.Fatalf("Test %d: expected output log to contain `%s` in `%s`", i, test.expectedOut, runner.ReadOut())
|
||||
if !bytes.Contains(stdout.Bytes(), []byte(test.expectedOut)) {
|
||||
t.Fatalf("Test %d: expected output log to contain `%s` in `%s`", i, test.expectedOut, stdout.String())
|
||||
}
|
||||
|
||||
if !bytes.Contains(runner.ReadErr(), []byte(test.expectedErr)) {
|
||||
t.Fatalf("Test %d: expected error log to contain `%s` in `%s`", i, test.expectedErr, runner.ReadErr())
|
||||
if !bytes.Contains(stderr.Bytes(), []byte(test.expectedErr)) {
|
||||
t.Fatalf("Test %d: expected error log to contain `%s` in `%s`", i, test.expectedErr, stderr.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunnerError(t *testing.T) {
|
||||
runner, err := New()
|
||||
if err != nil {
|
||||
t.Fatalf("Test error during New() - %s", err)
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
for i, test := range []struct {
|
||||
route *models.Route
|
||||
payload string
|
||||
@@ -58,28 +75,31 @@ func TestRunnerError(t *testing.T) {
|
||||
{&models.Route{Image: "iron/error"}, ``, "error", "", "RuntimeError"},
|
||||
{&models.Route{Image: "iron/error"}, `{"name": "test"}`, "error", "", "RuntimeError"},
|
||||
} {
|
||||
runner := New(&Config{
|
||||
ID: fmt.Sprintf("task-error-%d-%d", i, time.Now().Unix()),
|
||||
Ctx: context.Background(),
|
||||
var stdout, stderr bytes.Buffer
|
||||
cfg := &Config{
|
||||
ID: fmt.Sprintf("task-err-%d-%d", i, time.Now().Unix()),
|
||||
Route: test.route,
|
||||
Timeout: 5 * time.Second,
|
||||
Payload: test.payload,
|
||||
})
|
||||
Stdout: &stdout,
|
||||
Stderr: &stderr,
|
||||
}
|
||||
|
||||
if err := runner.Run(); err != nil {
|
||||
result, err := runner.Run(ctx, cfg)
|
||||
if err != nil {
|
||||
t.Fatalf("Test %d: error during Run() - %s", i, err)
|
||||
}
|
||||
|
||||
if test.expectedStatus != runner.Status() {
|
||||
t.Fatalf("Test %d: expected result status to be `%s` but it was `%s`", i, test.expectedStatus, runner.Status())
|
||||
if test.expectedStatus != result.Status() {
|
||||
t.Fatalf("Test %d: expected result status to be `%s` but it was `%s`", i, test.expectedStatus, result.Status())
|
||||
}
|
||||
|
||||
if !bytes.Contains(runner.ReadOut(), []byte(test.expectedOut)) {
|
||||
t.Fatalf("Test %d: expected output log to contain `%s` in `%s`", i, test.expectedOut, runner.ReadOut())
|
||||
if !bytes.Contains(stdout.Bytes(), []byte(test.expectedOut)) {
|
||||
t.Fatalf("Test %d: expected output log to contain `%s` in `%s`", i, test.expectedOut, stdout.String())
|
||||
}
|
||||
|
||||
if !bytes.Contains(runner.ReadErr(), []byte(test.expectedErr)) {
|
||||
t.Fatalf("Test %d: expected error log to contain `%s` in `%s`", i, test.expectedErr, runner.ReadErr())
|
||||
if !bytes.Contains(stderr.Bytes(), []byte(test.expectedErr)) {
|
||||
t.Fatalf("Test %d: expected error log to contain `%s` in `%s`", i, test.expectedErr, stderr.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,10 +8,8 @@ import (
|
||||
)
|
||||
|
||||
type containerTask struct {
|
||||
auth tasker.Auther
|
||||
stdout io.Writer
|
||||
stderr io.Writer
|
||||
cfg *Config
|
||||
auth tasker.Auther
|
||||
cfg *Config
|
||||
}
|
||||
|
||||
func (t *containerTask) Command() string { return "" }
|
||||
@@ -34,7 +32,7 @@ func (t *containerTask) Id() string { return t.cfg.ID }
|
||||
func (t *containerTask) Group() string { return "" }
|
||||
func (t *containerTask) Image() string { return t.cfg.Route.Image }
|
||||
func (t *containerTask) Timeout() uint { return uint(t.cfg.Timeout.Seconds()) }
|
||||
func (t *containerTask) Logger() (stdout, stderr io.Writer) { return t.stdout, t.stderr }
|
||||
func (t *containerTask) Logger() (stdout, stderr io.Writer) { return t.cfg.Stdout, t.cfg.Stderr }
|
||||
func (t *containerTask) Volumes() [][2]string { return [][2]string{} }
|
||||
func (t *containerTask) WorkDir() string { return "" }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user