mirror of
https://github.com/hanzo-fi/stack.git
synced 2026-10-30 20:34:43 +00:00
* feat: first commit * feat: import wallet, fctl sdk and some stuff * fix: make hooks enabled only if changes in the code * feat: refine scripts * chore: disable pre commit hooks * chore: update payments * feat: make all hooks pass this has required modifications on almost each project * git subrepo push services/webhooks subrepo: subdir: "services/webhooks" merged: "ca5d19c5" upstream: origin: "webhooks" branch: "main" commit: "ca5d19c5" git-subrepo: version: "0.4.5" origin: "ssh://[email protected]/ingydotnet/git-subrepo" commit: "dbb99be" * chore: push backport * chore: backports * chore: backports * chore: backports * chore: backports * chore: backports * chore: remove test code * chore: backports * fix: branch * git subrepo push --branch=chore/backports --force services/fctl subrepo: subdir: "services/fctl" merged: "0d98fdaa" upstream: origin: "fctl" branch: "chore/backports" commit: "0d98fdaa" git-subrepo: version: "0.4.5" origin: "ssh://[email protected]/ingydotnet/git-subrepo" commit: "dbb99be" * feat(fctl): fix argument * git subrepo push --branch=chore/backports --force services/fctl subrepo: subdir: "services/fctl" merged: "5a7a41f9" upstream: origin: "fctl" branch: "chore/backports" commit: "5a7a41f9" git-subrepo: version: "0.4.5" origin: "ssh://[email protected]/ingydotnet/git-subrepo" commit: "dbb99be" * feat: remove ledger * git subrepo clone ledger services/ledger subrepo: subdir: "services/ledger" merged: "ad57138a" upstream: origin: "ledger" branch: "main" commit: "ad57138a" git-subrepo: version: "0.4.5" origin: "ssh://[email protected]/ingydotnet/git-subrepo" commit: "dbb99be" * feat(auth): fix dependencies * chore: backports * feat: remove ledger * feat: add ledger * feat: remove auth * feat: fetch auth main * feat: remove search * feat: add search * feat: remove submodules * feat: reomve payments * feat: add payments from main * feat: add 'yarn install' before generate sdk * feat: Update CI * feat: remove fctl * feat: add fctl * chore: go mod tidy * git subrepo push services/fctl subrepo: subdir: "services/fctl" merged: "5d4c919" upstream: origin: "fctl" branch: "main" commit: "5d4c919" git-subrepo: version: "0.4.5" origin: "ssh://[email protected]/ingydotnet/git-subrepo" commit: "dbb99be" * feat: add go-project-template * feat: update go-project-template under new go libs * git subrepo push libs/go-project-template subrepo: subdir: "libs/go-project-template" merged: "40e49f0" upstream: origin: "go-project-template" branch: "main" commit: "40e49f0" git-subrepo: version: "0.4.5" origin: "ssh://[email protected]/ingydotnet/git-subrepo" commit: "dbb99be" * fix: sdk hook * feat: Update CI * feat: Update CI * feat: Update CI * feat: Update CI * feat: Update * feat: CI Update * feat: Clear CI * feat: CI clear * fee * feat: CI * feat: Update CI * feat: Update CI * feat: Desactivate release mode * feat: Update CI * feat: Update CI * ci: upgrade * feat: update go-libs * feat(orchetration): init project * git subrepo push libs/go-project-template subrepo: subdir: "libs/go-project-template" merged: "cbead19" upstream: origin: "go-project-template" branch: "main" commit: "cbead19" git-subrepo: version: "0.4.5" origin: "ssh://[email protected]/ingydotnet/git-subrepo" commit: "dbb99be" * fix: commitlint * feat: little clean & fix pre-commit * fix: for pre-commit * ci: Improvement * ci: Improvement * ci: Improvement * ci: Improvement * ci: Improvement * chore: add machine * ci: Improvement * ci: Improvement * ci: Improvement * ci: Improvement * feat: Add all SDK * ci: Improvement * feat: Update taskfile & CI * feat: Update taskfile & CI * feat: List foliders in find * feat: List foliders in find * feat: List foliders in find * feat: List foliders in find * feat: List foliders in find * feat: List foliders in find * feat: Add GoBuild * feat: Add GoBuild * feat: Add GoBuild * feat: Add GoBuild * feat: Add GoBuild * feat: Add GoBuild * feat: Add GoBuild * feat: Add GoBuild * feat: Add GoBuild * feat: Add GoBuild * chore: Empty-Commit * feat: Add GoBuild * feat: Add GoBuild * feat: Add GoBuild * feat: Add GoBuild * feat: Add GoBuild * feat: Add GoBuild * feat: Add GoBuild * feat: Add GoBuild * feat: Add GoBuild * feat: Add GoBuild * feat: Add GoBuild * feat: Add GoBuild * feat: Add GoBuild * feat: Add GoBuild * feat: big bang * feat: big bang * feat: big bang * ci: Update * ci: Add release * ci: Update .goreleaser.yml * feat(orchestration): first working version * feat(operator): simplify * feat(operator): factorize ingress, services, auth clients... * feat(operator): remove resources * fix: auth configuration causing pods reboot * feat: Update gitpod configuration * feat(gitpod): Add Garden * feat(gitpod): Add rsync * feat(gitpod): Add packages * feat(gitpod): Add packages * feat(gitpod): Optimize configuration * feat(gitpod): restore default config * feat(gitpod): Add port 80 & 443 on qemu * feat(gitpod): Ignore .garden fodler * feat(gitpod): Upgrade qemu * feat: add 'stack' label on created objects * feat: add taskfile operator to root taskfile * feat(operator): add lint to taskfile * feat(operator): add build.Dockerfile * fix(operator): fix build.Dockerfile * fix(operator): restore service names * fix(operator): ingresses * fix(operator): fix middlewares * fix(operator): duplicate middlewares entries * fix(operator): control ingress path prefix * feat(operator): disable ingress on service if not specified in configuration * fix(fctl): membership uri * fix(orchestration): application/json content-type * feat: wip * fix: orchestration run ids * fix: catch panic on workflow executions Co-authored-by: Ragot Geoffrey <[email protected]> Co-authored-by: Antoine Gelloz <[email protected]>
167 lines
3.5 KiB
Go
167 lines
3.5 KiB
Go
package analytics
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"io"
|
|
"net/http"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/segmentio/analytics-go"
|
|
"github.com/stretchr/testify/require"
|
|
"go.uber.org/fx"
|
|
)
|
|
|
|
type transport func(*http.Request) (*http.Response, error)
|
|
|
|
func (fn transport) RoundTrip(req *http.Request) (*http.Response, error) {
|
|
return fn(req)
|
|
}
|
|
|
|
type Queue[ITEM any] struct {
|
|
mu sync.Mutex
|
|
items []ITEM
|
|
}
|
|
|
|
func (s *Queue[ITEM]) Get() (ret ITEM, ok bool) {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
|
|
if len(s.items) == 0 {
|
|
return
|
|
}
|
|
ret = s.items[0]
|
|
ok = true
|
|
if len(s.items) == 1 {
|
|
s.items = make([]ITEM, 0)
|
|
return
|
|
}
|
|
s.items = s.items[1:]
|
|
return
|
|
}
|
|
|
|
func (s *Queue[ITEM]) Put(i ITEM) *Queue[ITEM] {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
|
|
s.items = append(s.items, i)
|
|
return s
|
|
}
|
|
|
|
func (s *Queue[ITEM]) Empty() bool {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
return len(s.items) == 0
|
|
}
|
|
|
|
func NewQueue[ITEM any]() *Queue[ITEM] {
|
|
return &Queue[ITEM]{}
|
|
}
|
|
|
|
type segmentBatch struct {
|
|
Batch []analytics.Track `json:"batch"`
|
|
}
|
|
|
|
const (
|
|
interval = 10 * time.Millisecond
|
|
version = "100.0.0"
|
|
applicationId = "foo"
|
|
writeKey = "key"
|
|
)
|
|
|
|
var (
|
|
module = fx.Options(
|
|
fx.NopLogger,
|
|
NewHeartbeatModule(version, writeKey, interval),
|
|
fx.Replace(func() AppIdProvider {
|
|
return AppIdProviderFn(func(ctx context.Context) (string, error) {
|
|
return applicationId, nil
|
|
})
|
|
}),
|
|
fx.Supply(fx.Annotate(PropertiesEnricherFn(func(ctx context.Context, p analytics.Properties) error {
|
|
p.Set("foo", "bar")
|
|
return nil
|
|
}), fx.ResultTags(FXTagPropertiesEnrichers), fx.As(new(PropertiesEnricher)))),
|
|
)
|
|
)
|
|
|
|
func EventuallyQueueNotEmpty[ITEM any](t *testing.T, queue *Queue[ITEM]) {
|
|
require.Eventually(t, func() bool {
|
|
return !queue.Empty()
|
|
}, 10*interval, interval)
|
|
}
|
|
|
|
var emptyHttpResponse = &http.Response{
|
|
Body: io.NopCloser(bytes.NewReader([]byte{})),
|
|
StatusCode: http.StatusOK,
|
|
}
|
|
|
|
func newApp(module fx.Option, t transport) *fx.App {
|
|
return fx.New(module, fx.Replace(analytics.Config{
|
|
BatchSize: 1,
|
|
Transport: t,
|
|
}))
|
|
}
|
|
|
|
func withApp(t *testing.T, app *fx.App, fn func(t *testing.T)) {
|
|
require.NoError(t, app.Start(context.Background()))
|
|
defer func() {
|
|
require.NoError(t, app.Stop(context.Background()))
|
|
}()
|
|
fn(t)
|
|
}
|
|
|
|
func TestSegment(t *testing.T) {
|
|
|
|
t.Run("Nominal case", func(t *testing.T) {
|
|
queue := NewQueue[*http.Request]()
|
|
app := newApp(module, func(request *http.Request) (*http.Response, error) {
|
|
queue.Put(request)
|
|
return emptyHttpResponse, nil
|
|
})
|
|
withApp(t, app, func(t *testing.T) {
|
|
for i := 0; i < 10; i++ {
|
|
EventuallyQueueNotEmpty(t, queue)
|
|
request, ok := queue.Get()
|
|
require.True(t, ok)
|
|
|
|
username, password, ok := request.BasicAuth()
|
|
require.True(t, ok)
|
|
require.Equal(t, writeKey, username)
|
|
require.Empty(t, password)
|
|
|
|
batch := &segmentBatch{}
|
|
require.NoError(t, json.NewDecoder(request.Body).Decode(batch))
|
|
require.Len(t, batch.Batch, 1)
|
|
|
|
track := batch.Batch[0]
|
|
require.Equal(t, ApplicationStats, track.Event)
|
|
require.Equal(t, "bar", track.Properties["foo"])
|
|
}
|
|
})
|
|
})
|
|
t.Run("With error on the backend", func(t *testing.T) {
|
|
firstCall := true
|
|
|
|
queue := NewQueue[*http.Request]()
|
|
app := newApp(module, func(request *http.Request) (*http.Response, error) {
|
|
if firstCall {
|
|
firstCall = false
|
|
return nil, errors.New("error on the first try")
|
|
}
|
|
queue.Put(request)
|
|
return emptyHttpResponse, nil
|
|
})
|
|
withApp(t, app, func(t *testing.T) {
|
|
EventuallyQueueNotEmpty(t, queue)
|
|
|
|
_, ok := queue.Get()
|
|
require.True(t, ok)
|
|
})
|
|
})
|
|
}
|