Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✅ Add End-To-End test suite #81

Merged
merged 30 commits into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
f05ba30
:pencil2: fix case of field in `list_users` API response
linkdd Sep 12, 2024
afeebaa
:sparkles: add `whoami` API operation
linkdd Sep 12, 2024
27fc57c
:recycle: :white_check_mark: use docker image to run benchmark
linkdd Sep 12, 2024
3ea795d
:white_check_mark: add beginning of End-To-End test suite
linkdd Sep 12, 2024
4c83cdf
:hammer: add tasks to run End-To-End test suite in task runner
linkdd Sep 12, 2024
880cb02
:construction_worker: add End-To-End test suite to `build` workflow
linkdd Sep 12, 2024
3a4960e
:whale: :arrow_up: upgrade templ in docker image
linkdd Sep 12, 2024
accf294
:hammer: use `docker run -d` instead of `docker run &` in test suites
linkdd Sep 12, 2024
97d0f66
:memo: remove disclaimer from README
linkdd Sep 12, 2024
b2b7865
:white_check_mark: add stream management e2e test suite
linkdd Sep 12, 2024
0c7edf0
:bug: `StreamConfig.IndexedFields` should never be `nil`
linkdd Sep 12, 2024
f0038f0
:recycle: add guest user in test database
linkdd Sep 12, 2024
8ed3da5
:white_check_mark: add permissions test suite
linkdd Sep 12, 2024
4a458ca
:white_check_mark: add stress test and html/junit report of integrati…
linkdd Sep 13, 2024
9eee7a5
:bug: retry transaction on conflict when ingesting logs
linkdd Sep 13, 2024
a1e4d84
:construction_worker: add junit report to PR
linkdd Sep 13, 2024
ac3cd26
:construction_worker: include passed JUnit annotations
linkdd Sep 13, 2024
6e8087f
:construction_worker: add report to PR as comment
linkdd Sep 13, 2024
f5456fc
:green_heart: use correct version for `report@test` workflow step
linkdd Sep 13, 2024
26f5fc9
:green_heart: don't keep data folder after tests
linkdd Sep 13, 2024
d017e6c
:construction_worker: rename check generated by junit report
linkdd Sep 13, 2024
26e5c08
:construction_worker: adjust junit report configuration
linkdd Sep 13, 2024
36235b8
:white_check_mark: add retention test suite
linkdd Sep 13, 2024
9a6d9ec
:white_check_mark: add transformers test suite
linkdd Sep 13, 2024
ca2cf41
:white_check_mark: add alerts test suite
linkdd Sep 13, 2024
83e00f0
:white_check_mark: add test suite for ACL API
linkdd Sep 13, 2024
fc124c6
:white_check_mark: add timeout in log notifier test suite
linkdd Sep 13, 2024
4466e13
:bug: fix out of bound error in `save_role` API operation
linkdd Sep 13, 2024
817535e
:sparkles: return token UUID as part of API response
linkdd Sep 13, 2024
a8a3441
:white_check_mark: add piplines API test suite
linkdd Sep 13, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,22 @@ jobs:
load: true
cache-from: type=gha
cache-to: type=gha,mode=max

- name: setup@test
uses: gacts/install-hurl@v1

- name: e2e@test
working-directory: ./tests/e2e
run: sh ./run.sh

- name: report@test
uses: mikepenz/[email protected]
if: ${{ github.event_name == 'pull_request' && (success() || failure()) }}
with:
report_paths: "./tests/e2e/reports/junit.xml"
include_passed: true
check_name: "End-To-End Test Report"
job_summary: true
comment: true
updateComment: true
fail_on_failure: true
9 changes: 0 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,6 @@ Result:
- **Total time:** 481.65s
- **Average:** 2076.18 request/s

## :warning: Disclaimer

This project is in a very early stage of development, as such:

- it has not been tested in production
- not even an automated test suite

Those points will be improved on given enough time.

## :construction: Build

**Requirements:**
Expand Down
15 changes: 13 additions & 2 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,23 @@ tasks:
- task: "gen:js"
- go build -o bin/ ./...

test:
desc: "Run tests"
run:
desc: "Run the project"
cmds:
- ./bin/flowg serve {{.CLI_ARGS}}

"test:unit":
desc: "Run unit tests"
cmds:
- task: "test:go"
- task: "test:rust"

"test:e2e":
desc: "Run end-to-end tests"
dir: ./tests/e2e
cmds:
- sh run.sh

doc:
desc: "Generate documentation"
cmds:
Expand Down
8 changes: 5 additions & 3 deletions api/create_token.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ import (
type CreateTokenRequest struct{}

type CreateTokenResponse struct {
Success bool `json:"success"`
Token string `json:"token"`
Success bool `json:"success"`
Token string `json:"token"`
TokenUUID string `json:"token-uuid"`
}

func CreateTokenUsecase(authDb *auth.Database) usecase.Interactor {
Expand All @@ -28,7 +29,7 @@ func CreateTokenUsecase(authDb *auth.Database) usecase.Interactor {
) error {
user := auth.GetContextUser(ctx)

token, err := tokenSys.CreateToken(user.Name)
token, tokenUuid, err := tokenSys.CreateToken(user.Name)
if err != nil {
slog.ErrorContext(
ctx,
Expand All @@ -44,6 +45,7 @@ func CreateTokenUsecase(authDb *auth.Database) usecase.Interactor {

resp.Success = true
resp.Token = token
resp.TokenUUID = tokenUuid

return nil
},
Expand Down
2 changes: 1 addition & 1 deletion api/list_users.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
type ListUsersRequest struct{}
type ListUsersResponse struct {
Success bool `json:"success"`
Users []auth.User `json:"Users"`
Users []auth.User `json:"users"`
}

func ListUsersUsecase(authDb *auth.Database) usecase.Interactor {
Expand Down
2 changes: 2 additions & 0 deletions api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ func NewHandler(
r.Put("/api/v1/users/{user}", SaveUserUsecase(authDb))
r.Delete("/api/v1/users/{user}", DeleteUserUsecase(authDb))

r.Get("/api/v1/whoami", WhoamiUsecase(authDb))

r.Get("/api/v1/tokens", ListTokensUsecase(authDb))
r.Post("/api/v1/token", CreateTokenUsecase(authDb))
r.Delete("/api/v1/tokens/{token-uuid}", DeleteTokenUsecase(authDb))
Expand Down
2 changes: 1 addition & 1 deletion api/save_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func SaveRoleUsecase(authDb *auth.Database) usecase.Interactor {
req SaveRoleRequest,
resp *SaveRoleResponse,
) error {
scopes := make([]auth.Scope, 0, len(req.Scopes))
scopes := make([]auth.Scope, len(req.Scopes))

for i, scopeName := range req.Scopes {
scope, err := auth.ParseScope(scopeName)
Expand Down
39 changes: 39 additions & 0 deletions api/whoami.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package api

import (
"context"

"github.com/swaggest/usecase"
"github.com/swaggest/usecase/status"

"link-society.com/flowg/internal/data/auth"
)

type WhoamiRequest struct{}
type WhoamiResponse struct {
Success bool `json:"success"`
User *auth.User `json:"user"`
}

func WhoamiUsecase(authDb *auth.Database) usecase.Interactor {
u := usecase.NewInteractor(
func(
ctx context.Context,
req WhoamiRequest,
resp *WhoamiResponse,
) error {
resp.Success = true
resp.User = auth.GetContextUser(ctx)
return nil
},
)

u.SetName("whoami")
u.SetTitle("Fetch current profile")
u.SetDescription("Fetch the profile of the currently authenticated user")
u.SetTags("acls")

u.SetExpectedErrors(status.PermissionDenied)

return u
}
2 changes: 1 addition & 1 deletion cmd/flowg/admin_token_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func NewAdminTokenCreateCommand() *cobra.Command {
return
}

token, err := tokenSys.CreateToken(user.Name)
token, _, err := tokenSys.CreateToken(user.Name)
if err != nil {
fmt.Fprintln(os.Stderr, "ERROR: Failed to generate token:", err)
exitCode = 1
Expand Down
2 changes: 1 addition & 1 deletion docker/flowg.dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ RUN npm run build
FROM golang:1.23-alpine3.20 AS builder-go

RUN apk add --no-cache gcc musl-dev
RUN go install github.com/a-h/templ/cmd/[email protected].771
RUN go install github.com/a-h/templ/cmd/[email protected].778

COPY --from=sources-go /src /workspace
COPY --from=builder-rust-filterdsl /workspace/internal/ffi/filterdsl/rust-crate/target/release/libflowg_filterdsl.a /workspace/internal/ffi/filterdsl/rust-crate/target/release/libflowg_filterdsl.a
Expand Down
14 changes: 8 additions & 6 deletions internal/data/auth/system_token.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,19 @@ func NewTokenSystem(backend *Database) *TokenSystem {
return &TokenSystem{backend: backend}
}

func (sys *TokenSystem) CreateToken(username string) (string, error) {
func (sys *TokenSystem) CreateToken(username string) (string, string, error) {
token, err := newToken(32)
if err != nil {
return "", err
return "", "", err
}

tokenHash, err := hash.HashPassword(token)
if err != nil {
return "", fmt.Errorf("failed to hash token: %w", err)
return "", "", fmt.Errorf("failed to hash token: %w", err)
}

tokenUuid := uuid.New().String()

err = sys.backend.db.Update(func(txn *badger.Txn) error {
userKey := []byte(fmt.Sprintf("index:user:%s", username))
_, err := txn.Get(userKey)
Expand All @@ -43,7 +45,7 @@ func (sys *TokenSystem) CreateToken(username string) (string, error) {
return fmt.Errorf("failed to check if user '%s' exists: %w", username, err)
}

tokenKey := []byte(fmt.Sprintf("pat:%s:%s", username, uuid.New().String()))
tokenKey := []byte(fmt.Sprintf("pat:%s:%s", username, tokenUuid))
err = txn.Set(tokenKey, []byte(tokenHash))
if err != nil {
return fmt.Errorf("failed to add token to user '%s': %w", username, err)
Expand All @@ -53,10 +55,10 @@ func (sys *TokenSystem) CreateToken(username string) (string, error) {
})

if err != nil {
return "", err
return "", "", err
}

return token, nil
return token, tokenUuid, nil
}

func (sys *TokenSystem) VerifyToken(token string) (*User, error) {
Expand Down
25 changes: 19 additions & 6 deletions internal/data/lognotify/notify_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package lognotify_test

import (
"reflect"
"sync"
"testing"

"sync"
"time"

"link-society.com/flowg/internal/data/logstorage"

"link-society.com/flowg/internal/data/lognotify"
Expand All @@ -15,11 +17,12 @@ func TestLogNotifier(t *testing.T) {
notifier.Start()
defer notifier.Stop()

doneC := make(chan struct{})
logC := notifier.Subscribe("test", doneC)
logDoneC := make(chan struct{})
logC := notifier.Subscribe("test", logDoneC)

logEntry := logstorage.NewLogEntry(map[string]string{})

wgDoneC := make(chan struct{})
wg := sync.WaitGroup{}
wg.Add(2)

Expand All @@ -34,7 +37,17 @@ func TestLogNotifier(t *testing.T) {
result = <-logC
}()

wg.Wait()
go func() {
wg.Wait()
wgDoneC <- struct{}{}
close(wgDoneC)
}()

select {
case <-wgDoneC:
case <-time.After(5 * time.Second):
t.Fatalf("timed out waiting for log")
}

if result.Stream != "test" {
t.Fatalf("unexpected stream: %s", result.Stream)
Expand All @@ -48,6 +61,6 @@ func TestLogNotifier(t *testing.T) {
t.Fatalf("unexpected log entry: %v", result.LogEntry)
}

doneC <- struct{}{}
close(doneC)
logDoneC <- struct{}{}
close(logDoneC)
}
Loading