2020-03-29 16:03:07 +00:00
|
|
|
package api_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/golang/mock/gomock"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"go.uber.org/zap/zaptest"
|
|
|
|
|
2024-06-05 17:36:34 +00:00
|
|
|
"gitlab.com/slon/shad-go/distbuild/pkg/api"
|
|
|
|
mock "gitlab.com/slon/shad-go/distbuild/pkg/api/mock"
|
|
|
|
"gitlab.com/slon/shad-go/distbuild/pkg/build"
|
2020-03-29 16:03:07 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
//go:generate mockgen -package mock -destination mock/mock.go . Service
|
|
|
|
|
|
|
|
type env struct {
|
|
|
|
ctrl *gomock.Controller
|
|
|
|
mock *mock.MockService
|
|
|
|
server *httptest.Server
|
2020-04-04 21:13:45 +00:00
|
|
|
client *api.BuildClient
|
2020-03-29 16:03:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (e *env) stop() {
|
|
|
|
e.server.Close()
|
|
|
|
}
|
|
|
|
|
|
|
|
func newEnv(t *testing.T) (*env, func()) {
|
|
|
|
env := &env{}
|
|
|
|
env.ctrl = gomock.NewController(t)
|
|
|
|
env.mock = mock.NewMockService(env.ctrl)
|
|
|
|
|
|
|
|
log := zaptest.NewLogger(t)
|
|
|
|
|
|
|
|
mux := http.NewServeMux()
|
|
|
|
|
2020-04-04 21:13:45 +00:00
|
|
|
handler := api.NewBuildService(log, env.mock)
|
2020-03-29 16:03:07 +00:00
|
|
|
handler.Register(mux)
|
|
|
|
|
|
|
|
env.server = httptest.NewServer(mux)
|
|
|
|
|
2020-04-04 21:13:45 +00:00
|
|
|
env.client = api.NewBuildClient(log, env.server.URL)
|
2020-03-29 16:03:07 +00:00
|
|
|
|
|
|
|
return env, env.stop
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestBuildSignal(t *testing.T) {
|
|
|
|
env, stop := newEnv(t)
|
|
|
|
defer stop()
|
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
|
2024-06-05 17:36:34 +00:00
|
|
|
buildIDa := build.ID{01}
|
|
|
|
buildIDb := build.ID{02}
|
2020-03-29 16:03:07 +00:00
|
|
|
req := &api.SignalRequest{}
|
|
|
|
rsp := &api.SignalResponse{}
|
|
|
|
|
|
|
|
env.mock.EXPECT().SignalBuild(gomock.Any(), buildIDa, req).Return(rsp, nil)
|
|
|
|
env.mock.EXPECT().SignalBuild(gomock.Any(), buildIDb, req).Return(nil, fmt.Errorf("foo bar error"))
|
|
|
|
|
|
|
|
_, err := env.client.SignalBuild(ctx, buildIDa, req)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
_, err = env.client.SignalBuild(ctx, buildIDb, req)
|
|
|
|
require.Error(t, err)
|
|
|
|
require.Contains(t, err.Error(), "foo bar error")
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestBuildStartError(t *testing.T) {
|
|
|
|
env, stop := newEnv(t)
|
|
|
|
defer stop()
|
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
env.mock.EXPECT().StartBuild(gomock.Any(), gomock.Any(), gomock.Any()).Return(fmt.Errorf("foo bar error"))
|
|
|
|
|
|
|
|
_, _, err := env.client.StartBuild(ctx, &api.BuildRequest{})
|
2020-04-20 21:07:18 +00:00
|
|
|
require.Error(t, err)
|
2020-03-29 16:03:07 +00:00
|
|
|
require.Contains(t, err.Error(), "foo bar error")
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestBuildRunning(t *testing.T) {
|
|
|
|
env, stop := newEnv(t)
|
|
|
|
defer stop()
|
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
|
2024-06-05 17:36:34 +00:00
|
|
|
buildID := build.ID{02}
|
2020-03-29 16:03:07 +00:00
|
|
|
|
|
|
|
req := &api.BuildRequest{
|
2024-06-05 17:36:34 +00:00
|
|
|
Graph: build.Graph{SourceFiles: map[build.ID]string{{01}: "a.txt"}},
|
2020-03-29 16:03:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
started := &api.BuildStarted{ID: buildID}
|
|
|
|
finished := &api.StatusUpdate{BuildFinished: &api.BuildFinished{}}
|
|
|
|
|
|
|
|
env.mock.EXPECT().StartBuild(gomock.Any(), gomock.Any(), gomock.Any()).
|
|
|
|
DoAndReturn(func(_ context.Context, req *api.BuildRequest, w api.StatusWriter) error {
|
|
|
|
if err := w.Started(started); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := w.Updated(finished); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return fmt.Errorf("foo bar error")
|
|
|
|
})
|
|
|
|
|
|
|
|
rsp, r, err := env.client.StartBuild(ctx, req)
|
|
|
|
require.NoError(t, err)
|
2020-04-17 16:41:14 +00:00
|
|
|
defer r.Close()
|
2020-03-29 16:03:07 +00:00
|
|
|
|
|
|
|
require.Equal(t, started, rsp)
|
|
|
|
|
|
|
|
u, err := r.Next()
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, finished, u)
|
|
|
|
|
|
|
|
u, err = r.Next()
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Contains(t, u.BuildFailed.Error, "foo bar error")
|
|
|
|
|
|
|
|
_, err = r.Next()
|
2021-05-05 10:53:18 +00:00
|
|
|
require.Equal(t, io.EOF, err)
|
2020-03-29 16:03:07 +00:00
|
|
|
}
|
2020-04-04 21:13:45 +00:00
|
|
|
|
|
|
|
func TestBuildResultsStreaming(t *testing.T) {
|
|
|
|
// Test is hanging?
|
|
|
|
// See https://golang.org/pkg/net/http/#Flusher
|
|
|
|
|
|
|
|
env, stop := newEnv(t)
|
|
|
|
defer stop()
|
|
|
|
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
defer cancel()
|
|
|
|
|
2024-06-05 17:36:34 +00:00
|
|
|
buildID := build.ID{02}
|
2020-04-04 21:13:45 +00:00
|
|
|
req := &api.BuildRequest{}
|
|
|
|
started := &api.BuildStarted{ID: buildID}
|
|
|
|
|
|
|
|
env.mock.EXPECT().StartBuild(gomock.Any(), gomock.Any(), gomock.Any()).
|
|
|
|
DoAndReturn(func(ctx context.Context, req *api.BuildRequest, w api.StatusWriter) error {
|
|
|
|
if err := w.Started(started); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
<-ctx.Done()
|
|
|
|
return ctx.Err()
|
|
|
|
})
|
|
|
|
|
2020-04-17 16:41:14 +00:00
|
|
|
rsp, r, err := env.client.StartBuild(ctx, req)
|
2020-04-04 21:13:45 +00:00
|
|
|
require.NoError(t, err)
|
2020-04-17 16:41:14 +00:00
|
|
|
defer r.Close()
|
2020-04-04 21:13:45 +00:00
|
|
|
require.Equal(t, started, rsp)
|
|
|
|
}
|