package main import ( "bytes" "context" "fmt" "isle/bootstrap" "isle/daemon" "isle/daemon/jsonrpc2" "isle/toolkit" "net/http/httptest" "reflect" "testing" "dev.mediocregopher.com/mediocre-go-lib.git/mlog" "github.com/stretchr/testify/assert" "gopkg.in/yaml.v3" ) func bootstrapNewCreationParams(name, domain string) bootstrap.CreationParams { return bootstrap.CreationParams{ ID: fmt.Sprintf("%s-%s", name, domain), Name: name, Domain: domain, } } type runHarness struct { ctx context.Context logger *mlog.Logger daemonRPC *daemon.MockRPC daemonRPCServer *httptest.Server stdout *bytes.Buffer changeStager *changeStager } func newRunHarness(t *testing.T) *runHarness { t.Parallel() var ( ctx = context.Background() logger = toolkit.NewTestLogger(t) daemonRPC = daemon.NewMockRPC(t) daemonRPCHandler = jsonrpc2.NewHTTPHandler(daemon.NewRPCHandler( logger.WithNamespace("rpc"), daemonRPC, )) daemonRPCServer = httptest.NewServer(daemonRPCHandler) stdout = new(bytes.Buffer) changeStager = &changeStager{toolkit.TempDir(t)} ) t.Cleanup(daemonRPCServer.Close) return &runHarness{ ctx, logger, daemonRPC, daemonRPCServer, stdout, changeStager, } } func (h *runHarness) run(t *testing.T, args ...string) error { httpClient := toolkit.NewHTTPClient(h.logger.WithNamespace("http")) t.Cleanup(func() { assert.NoError(t, httpClient.Close()) }) daemonRPCClient := daemon.RPCFromClient( jsonrpc2.NewHTTPClient(httpClient, h.daemonRPCServer.URL), ) return doRootCmd(h.ctx, h.logger, &subCmdCtxOpts{ args: args, stdout: h.stdout, changeStager: h.changeStager, daemonRPC: daemonRPCClient, bootstrapNewCreationParams: bootstrapNewCreationParams, }) } func (h *runHarness) runAssertStdout( t *testing.T, want any, args ...string, ) { var ( gotType = reflect.ValueOf(want) got = reflect.New(gotType.Type()) ) h.stdout.Reset() assert.NoError(t, h.run(t, args...)) assert.NoError(t, yaml.Unmarshal(h.stdout.Bytes(), got.Interface())) assert.Equal(t, want, got.Elem().Interface()) } func (h *runHarness) runAssertErrorContains( t *testing.T, want string, args ...string, ) { err := h.run(t, args...) if assert.Error(t, err) { assert.Contains(t, err.Error(), want) } } func (h *runHarness) assertChangeStaged( t *testing.T, want any, name string, ) { t.Helper() var ( gotV = reflect.New(reflect.TypeOf(want)) gotPtr = gotV.Interface() ) ok, err := h.changeStager.get(gotPtr, name) assert.NoError(t, err) assert.True(t, ok) assert.Equal(t, want, gotV.Elem().Interface()) }