Skip to content
This repository has been archived by the owner on Apr 18, 2024. It is now read-only.

feat: modify pool tests #153

Merged
merged 44 commits into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
17bb795
feat: modify pool tests
AmeanAsad Aug 31, 2023
00a4344
fix: surface caboose pool methods for testing
AmeanAsad Sep 1, 2023
0cd98cf
fix: top n node selection from heap
AmeanAsad Sep 1, 2023
b6b03f9
feat: add more comprehensive tests
AmeanAsad Sep 4, 2023
5537699
enhancement: add refresh no to tests
AmeanAsad Sep 4, 2023
778cd45
go fmt
AmeanAsad Sep 4, 2023
35646a8
remove unused metrics
aarshkshah1992 Sep 4, 2023
fa59f39
put back trace
aarshkshah1992 Sep 4, 2023
a23963d
Merge pull request #154 from filecoin-saturn/feat/remove-metrics
aarshkshah1992 Sep 4, 2023
d2c669e
response size does not include header
aarshkshah1992 Sep 4, 2023
ce46ce5
reset retry counter only if progress is made
aarshkshah1992 Sep 4, 2023
ca5522d
update go-car
aarshkshah1992 Sep 4, 2023
27b62be
dont drain response body
aarshkshah1992 Sep 4, 2023
296eaec
send verification errors to Saturn
aarshkshah1992 Sep 4, 2023
eb1e8b8
pool tier promotion
aarshkshah1992 Sep 4, 2023
2713f51
otel and send trace id to Saturn
aarshkshah1992 Sep 4, 2023
7375178
stabilize dynamics tests
willscott Sep 4, 2023
93135a7
mirroring parallel
aarshkshah1992 Sep 5, 2023
bda8d0d
Merge remote-tracking branch 'origin/aa/test-simulator' into feat/por…
aarshkshah1992 Sep 5, 2023
c8be27d
pool-target-size through config to better test dynamics
willscott Sep 5, 2023
d52ef6e
down to flakiness
willscott Sep 6, 2023
61c82da
add substitution (rough)
willscott Sep 10, 2023
550cf5b
Merge remote-tracking branch 'origin/aa/test-simulator' into feat/por…
aarshkshah1992 Sep 18, 2023
c0ea85c
use new orchestrator API
aarshkshah1992 Sep 18, 2023
608a668
Merge pull request #161 from filecoin-saturn/feat/integrate-new-endpoint
aarshkshah1992 Sep 18, 2023
ea1d62b
fix: top N selection
AmeanAsad Sep 18, 2023
05c2b37
Merge branch 'aa/test-simulator' into feat/port-Caboose-main
AmeanAsad Sep 18, 2023
c1ab0e9
enhancement: increase test size
AmeanAsad Sep 19, 2023
1975f49
feat: Add tests for affinity
AmeanAsad Sep 19, 2023
78f3490
test cache affinity
aarshkshah1992 Sep 19, 2023
5e02c7f
test cache affinity
aarshkshah1992 Sep 19, 2023
d8ae01e
remove assert
aarshkshah1992 Sep 19, 2023
b647fab
fix test
aarshkshah1992 Sep 19, 2023
0cf6c94
address review
aarshkshah1992 Sep 19, 2023
552ea1b
Merge pull request #163 from filecoin-saturn/feat/cache-aff-test
aarshkshah1992 Sep 19, 2023
9eb9c18
feat: port compliance cids
AmeanAsad Sep 19, 2023
af17595
fix: remove unused code
AmeanAsad Sep 19, 2023
310c079
modify harness
AmeanAsad Sep 19, 2023
8804f45
feat: add core attr to trace span
AmeanAsad Sep 19, 2023
3f63a01
Merge pull request #164 from filecoin-saturn/feat/port-compliance-cids
aarshkshah1992 Sep 20, 2023
da9ad17
Merge branch 'aa/test-simulator' into feat/port-Caboose-main
aarshkshah1992 Sep 20, 2023
46b5374
fix CI
aarshkshah1992 Sep 20, 2023
ad399fb
Merge pull request #155 from filecoin-saturn/feat/port-Caboose-main
aarshkshah1992 Sep 20, 2023
1015a7f
improve error classification (#165)
AmeanAsad Oct 3, 2023
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
10 changes: 5 additions & 5 deletions caboose.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,14 +195,14 @@ func (c *Caboose) Fetch(ctx context.Context, path string, cb DataCallback) error
ctx, span := spanTrace(ctx, "Fetch", trace.WithAttributes(attribute.String("path", path)))
defer span.End()

return c.pool.fetchResourceWith(ctx, path, cb, c.getAffinity(ctx))
return c.pool.fetchResourceWith(ctx, path, cb, c.GetAffinity(ctx))
}

func (c *Caboose) Has(ctx context.Context, it cid.Cid) (bool, error) {
ctx, span := spanTrace(ctx, "Has", trace.WithAttributes(attribute.Stringer("cid", it)))
defer span.End()

blk, err := c.pool.fetchBlockWith(ctx, it, c.getAffinity(ctx))
blk, err := c.pool.fetchBlockWith(ctx, it, c.GetAffinity(ctx))
if err != nil {
return false, err
}
Expand All @@ -213,7 +213,7 @@ func (c *Caboose) Get(ctx context.Context, it cid.Cid) (blocks.Block, error) {
ctx, span := spanTrace(ctx, "Get", trace.WithAttributes(attribute.Stringer("cid", it)))
defer span.End()

blk, err := c.pool.fetchBlockWith(ctx, it, c.getAffinity(ctx))
blk, err := c.pool.fetchBlockWith(ctx, it, c.GetAffinity(ctx))
if err != nil {
return nil, err
}
Expand All @@ -225,14 +225,14 @@ func (c *Caboose) GetSize(ctx context.Context, it cid.Cid) (int, error) {
ctx, span := spanTrace(ctx, "GetSize", trace.WithAttributes(attribute.Stringer("cid", it)))
defer span.End()

blk, err := c.pool.fetchBlockWith(ctx, it, c.getAffinity(ctx))
blk, err := c.pool.fetchBlockWith(ctx, it, c.GetAffinity(ctx))
if err != nil {
return 0, err
}
return len(blk.RawData()), nil
}

func (c *Caboose) getAffinity(ctx context.Context) string {
func (c *Caboose) GetAffinity(ctx context.Context) string {
// https://github.com/ipfs/bifrost-gateway/issues/53#issuecomment-1442732865
if affG := ctx.Value(gateway.ContentPathKey); affG != nil {
contentPath := affG.(ipath.Path).String()
Expand Down
2 changes: 2 additions & 0 deletions internal/util/harness.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ func BuildCabooseHarness(t *testing.T, n int, maxRetries int, opts ...HarnessOpt
ch.CabooseActiveNodes = conf.Harness.ActiveNodes.(*caboose.NodeRing)
ch.CabooseAllNodes = conf.Harness.AllNodes.(*caboose.NodeHeap)
ch.CaboosePool = conf.Harness.PoolController
ch.Config = conf
return ch
}

Expand All @@ -89,6 +90,7 @@ type CabooseHarness struct {
CabooseActiveNodes *caboose.NodeRing
CabooseAllNodes *caboose.NodeHeap
CaboosePool state.PoolController
Config *caboose.Config

gol sync.Mutex
goodOrch bool
Expand Down
108 changes: 107 additions & 1 deletion pool_dynamics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package caboose_test

import (
"context"
cryptoRand "crypto/rand"
"fmt"
"math/rand"
"net/url"
"testing"
Expand All @@ -15,8 +17,9 @@ import (
)

const (
nodesSize = 200
nodesSize = 6
)
Copy link
Contributor

@aarshkshah1992 aarshkshah1992 Sep 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AmeanAsad @willscott

Why do we need to do this ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is used to change the pool size desired for testing. I reduced the pool size for testing cache affinity to make it easier to debug and get the tests passing. Once we get that passing we can set it to a high / realistic number again.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, yeah that makes sense.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has already been structured so that the lower pool target is only used in the test context. A larger pool size target is used when running normally

const blockPathPattern = "/ipfs/%s?format=car&dag-scope=block"

/*
This function tests if the caboose pool converges to a set of nodes that are expected
Expand Down Expand Up @@ -209,6 +212,94 @@ func TestPoolDynamics(t *testing.T) {

}

func TestPoolAffinity(t *testing.T) {
baseStatSize := 100000
baseStatLatency := 100
// statVarianceFactor := 0.1
poolRefreshNo := 10
simReqCount := 10000
ctx := context.Background()
cidList := generateRandomCIDs(20)

t.Run("selected nodes remain consistent for same cid reqs", func(t *testing.T) {
ch, controlGroup := getHarnessAndControlGroup(t, nodesSize, nodesSize/2)
_, _ = ch.Caboose.Get(ctx, cidList[0])

goodNodes := make([]*caboose.Node, 0)
badNodes := make([]*caboose.Node, 0)

for _, n := range ch.CabooseAllNodes.Nodes {
_, ok := controlGroup[n.URL]
if ok {
goodNodes = append(goodNodes, n)
} else {
badNodes = append(badNodes, n)
}
}

// Send requests to control group nodes to bump their selection into the pool.
for i := 0; i < poolRefreshNo; i++ {
baseStats := util.NodeStats{
Start: time.Now().Add(-time.Second * 2),
Latency: float64(baseStatLatency) / float64(10),
Size: float64(baseStatSize) * float64(10),
}

ch.RecordSuccesses(t, goodNodes, baseStats, 1000)
ch.CaboosePool.DoRefresh()
}

// Make a bunch of requests to similar cids to establish a stable hashring
for i := 0; i < simReqCount; i++ {
rand.New(rand.NewSource(time.Now().Unix()))
idx := rand.Intn(len(cidList))
_, _ = ch.Caboose.Get(ctx, cidList[idx])
}
ch.CaboosePool.DoRefresh()

// Introduce new nodes by sendng same stats to those nodes.
for i := 0; i < poolRefreshNo/2; i++ {
baseStats := util.NodeStats{
Start: time.Now().Add(-time.Second * 2),
Latency: float64(baseStatLatency) / float64(10),
Size: float64(baseStatSize) * float64(10),
}

// variedStats := util.NodeStats{
// Start: time.Now().Add(-time.Second * 2),
// Latency: float64(baseStatLatency) / (float64(10) + (1 + statVarianceFactor)),
// Size: float64(baseStatSize) * float64(10) * (1 + statVarianceFactor),
// }

ch.RecordSuccesses(t, goodNodes, baseStats, 100)
ch.RecordSuccesses(t, badNodes, baseStats, 10)

ch.CaboosePool.DoRefresh()
}

// for _, i := range ch.CabooseAllNodes.Nodes {
// fmt.Println(i.URL, i.Priority(), i.PredictedLatency)
// }

// Get the candidate nodes for a few cids from our formed cid list using
// the affinity of each cid.
for i := 0; i < 10; i++ {
rand.New(rand.NewSource(time.Now().Unix()))
idx := rand.Intn(len(cidList))
c := cidList[idx]
aff := ch.Caboose.GetAffinity(ctx)
if aff == "" {
aff = fmt.Sprintf(blockPathPattern, c)
}
nodes, _ := ch.CabooseActiveNodes.GetNodes(aff, ch.Config.MaxRetrievalAttempts)

// We expect that the candidate nodes are part of the "good nodes" list.
assert.Contains(t, goodNodes, nodes[0])
}

})
}

func getHarnessAndControlGroup(t *testing.T, nodesSize int, poolSize int) (*util.CabooseHarness, map[string]string) {
ch := util.BuildCabooseHarness(t, nodesSize, 3, func(config *caboose.Config) {
config.PoolTargetSize = nodesSize / 2
Expand All @@ -231,3 +322,18 @@ func getHarnessAndControlGroup(t *testing.T, nodesSize int, poolSize int) (*util

return ch, controlGroup
}

func generateRandomCIDs(count int) []cid.Cid {
var cids []cid.Cid
for i := 0; i < count; i++ {
block := make([]byte, 32)
cryptoRand.Read(block)
c, _ := cid.V1Builder{
Codec: uint64(multicodec.Raw),
MhType: uint64(multicodec.Sha2_256),
}.Sum(block)

cids = append(cids, c)
}
return cids
}
Loading