diff --git a/tavern/internal/www/README.md b/tavern/internal/www/README.md index d411e17f9..c6617f437 100644 --- a/tavern/internal/www/README.md +++ b/tavern/internal/www/README.md @@ -1,7 +1,9 @@ # Tavern UI -This package contains the relevant code for the Tavern UI. It primarily uses [React](https://reactjs.org/docs/getting-started.html) + [Relay](https://relay.dev/docs/guided-tour/) in combination with [TypeScript](https://www.typescriptlang.org/), but depends on code generation to function properly. Read on for more development information. + +This package contains the relevant code for the Tavern UI. It primarily uses [React](https://reactjs.org/docs/getting-started.html) + [Apollo](https://www.apollographql.com/docs/react) in combination with [TypeScript](https://www.typescriptlang.org/), but depends on code generation to function properly. Read on for more development information. ## Code Generation + Any relevant code generation can be executed by running `go generate ./cmd/tavern/internal/www/generate.go` or will automatically be executed when running `go generate ./...`. Code generation is responsible for: * Constructing the GraphQL schema by concatenating all schema files under the [/graphql/schema directory](https://github.com/KCarretto/realm/tree/main/graphql/schema). @@ -12,4 +14,5 @@ _If this is your first time contributing WWW changes in this dev environment, re 1. Run `go generate ./...` to ensure all code generation is up to date 2. Run `go run ./tavern` to start the teamserver (for the GraphQL API) run in the project root -3. In a separate terminal, navigate to the [UI Root /cmd/tavern/internal/www](https://github.com/KCarretto/realm/tree/main/cmd/tavern/internal/www) and run `npm start` (Note this will also run the [Relay compiler](https://relay.dev/docs/guides/compiler/)) + * Note: to run the teamserver with test data (useful for UI development), run `ENABLE_TEST_DATA=1 go run ./tavern` instead +3. In a separate terminal, navigate to the [UI Root /cmd/tavern/internal/www](https://github.com/KCarretto/realm/tree/main/cmd/tavern/internal/www) and run `npm start` diff --git a/tavern/memory b/tavern/memory new file mode 100644 index 000000000..a3c81bc29 Binary files /dev/null and b/tavern/memory differ diff --git a/tavern/test_data.go b/tavern/test_data.go index af292bd57..9ed2ad15f 100644 --- a/tavern/test_data.go +++ b/tavern/test_data.go @@ -27,6 +27,8 @@ func createTestData(ctx context.Context, client *ent.Client) { ) } + // Create test sessions (with tags) + var testSessions []*ent.Session for groupNum := 1; groupNum <= 15; groupNum++ { gTag := client.Tag.Create(). SetKind(tag.KindGroup). @@ -37,34 +39,110 @@ func createTestData(ctx context.Context, client *ent.Client) { hostName := fmt.Sprintf("Group %d - %s", groupNum, svcTag.Name) hostID := newRandomIdentifier() - client.Session.Create(). - SetLastSeenAt(time.Now().Add(-1*time.Minute)). - SetHostname(hostName). - SetIdentifier(newRandomIdentifier()). - SetHostIdentifier(hostID). - SetAgentIdentifier("test-data"). - AddTags(svcTag, gTag). - SaveX(ctx) - - client.Session.Create(). - SetLastSeenAt(time.Now().Add(-10*time.Minute)). - SetHostname(hostName). - SetIdentifier(newRandomIdentifier()). - SetHostIdentifier(hostID). - SetAgentIdentifier("test-data"). - AddTags(svcTag, gTag). - SaveX(ctx) - - client.Session.Create(). - SetLastSeenAt(time.Now().Add(-1*time.Hour)). - SetHostname(hostName). - SetIdentifier(newRandomIdentifier()). - SetHostIdentifier(hostID). - SetAgentIdentifier("test-data"). - AddTags(svcTag, gTag). - SaveX(ctx) + testSessions = append(testSessions, + client.Session.Create(). + SetLastSeenAt(time.Now().Add(-1*time.Minute)). + SetHostname(hostName). + SetIdentifier(newRandomIdentifier()). + SetHostIdentifier(hostID). + SetAgentIdentifier("test-data"). + AddTags(svcTag, gTag). + SaveX(ctx), + ) + + testSessions = append(testSessions, + client.Session.Create(). + SetLastSeenAt(time.Now().Add(-10*time.Minute)). + SetHostname(hostName). + SetIdentifier(newRandomIdentifier()). + SetHostIdentifier(hostID). + SetAgentIdentifier("test-data"). + AddTags(svcTag, gTag). + SaveX(ctx), + ) + + testSessions = append(testSessions, + client.Session.Create(). + SetLastSeenAt(time.Now().Add(-1*time.Hour)). + SetHostname(hostName). + SetIdentifier(newRandomIdentifier()). + SetHostIdentifier(hostID). + SetAgentIdentifier("test-data"). + AddTags(svcTag, gTag). + SaveX(ctx), + ) } } + + /* + * Example Job: Hello World + */ + printMsgTome := client.Tome.Create(). + SetName("PrintMessage"). + SetDescription("Print a message for fun!"). + SetEldritch(`print(input_params['msg'])`). + SetParamDefs(`{"msg":"string"}`). + SaveX(ctx) + + printJob := client.Job.Create(). + SetName("HelloWorld"). + SetParameters(`{"msg":"Hello World!"}`). + SetTome(printMsgTome). + SaveX(ctx) + + // Queued + client.Task.Create(). + SetSession(testSessions[0]). + SetCreatedAt(timeAgo(5 * time.Minute)). + SetJob(printJob). + SaveX(ctx) + + // Claimed + client.Task.Create(). + SetSession(testSessions[1]). + SetCreatedAt(timeAgo(5 * time.Minute)). + SetClaimedAt(timeAgo(1 * time.Minute)). + SetJob(printJob). + SaveX(ctx) + + // Completed + client.Task.Create(). + SetSession(testSessions[2]). + SetCreatedAt(timeAgo(5 * time.Minute)). + SetClaimedAt(timeAgo(1 * time.Minute)). + SetExecStartedAt(timeAgo(5 * time.Second)). + SetExecFinishedAt(timeAgo(5 * time.Second)). + SetOutput("Hello World!"). + SetJob(printJob). + SaveX(ctx) + + // Mid-Execution + client.Task.Create(). + SetSession(testSessions[3]). + SetCreatedAt(timeAgo(5 * time.Minute)). + SetClaimedAt(timeAgo(1 * time.Minute)). + SetExecStartedAt(timeAgo(5 * time.Second)). + SetOutput("Hello"). + SetJob(printJob). + SaveX(ctx) + + // Failed + client.Task.Create(). + SetSession(testSessions[4]). + SetCreatedAt(timeAgo(5 * time.Minute)). + SetClaimedAt(timeAgo(1 * time.Minute)). + SetExecStartedAt(timeAgo(5 * time.Second)). + SetExecFinishedAt(timeAgo(5 * time.Second)). + SetError("oops! Agent is OOM, can't print anything!"). + SetJob(printJob). + SaveX(ctx) + + // Stale + client.Task.Create(). + SetSession(testSessions[5]). + SetCreatedAt(timeAgo(1 * time.Hour)). + SetJob(printJob). + SaveX(ctx) } func newRandomIdentifier() string { @@ -75,3 +153,8 @@ func newRandomIdentifier() string { } return base64.StdEncoding.EncodeToString(buf) } + +// timeAgo returns the current time minus the provided duration (e.g. 5 seconds ago) +func timeAgo(duration time.Duration) time.Time { + return time.Now().Add(-1 * duration) +} diff --git a/tavern/test_data_test.go b/tavern/test_data_test.go new file mode 100644 index 000000000..b29596af1 --- /dev/null +++ b/tavern/test_data_test.go @@ -0,0 +1,23 @@ +package main + +import ( + "context" + "testing" + + "github.com/kcarretto/realm/tavern/ent/enttest" + "github.com/stretchr/testify/assert" +) + +// TestCreateTestData ensures createTestData runs without error and creates at least one session. +func TestCreateTestData(t *testing.T) { + var ( + ctx = context.Background() + driverName = "sqlite3" + dataSourceName = "file:test-create-test-data?mode=memory&cache=shared&_fk=1" + ) + graph := enttest.Open(t, driverName, dataSourceName, enttest.WithOptions()) + defer graph.Close() + + createTestData(ctx, graph) + assert.True(t, graph.Session.Query().ExistX(ctx)) +}