WIP: Morph: Add unit tests #2

Closed
dstepanov-yadro wants to merge 233 commits from TrueCloudLab/frostfs-node:master into object-3608-morph-unit-tests
8 changed files with 236 additions and 6 deletions
Showing only changes of commit 16a142cd0c - Show all commits

View file

@ -36,6 +36,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/fstree"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/engine"
meta "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/metabase"
lsmetrics "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/metrics"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/pilorama"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard"
shardmode "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
@ -752,12 +753,22 @@ func (c *cfg) getSubstorageOpts(shCfg shardCfg) []blobstor.SubStorage {
},
})
case fstree.Type:
fstreeOpts := []fstree.Option{
fstree.WithPath(sRead.path),
fstree.WithPerm(sRead.perm),
fstree.WithDepth(sRead.depth),
fstree.WithNoSync(sRead.noSync),
}
if c.metricsCollector != nil {
fstreeOpts = append(fstreeOpts,
fstree.WithMetrics(
lsmetrics.NewFSTreeMetricsWithoutShardID(sRead.path, c.metricsCollector.FSTree()),
),
)
}
ss = append(ss, blobstor.SubStorage{
Storage: fstree.New(
fstree.WithPath(sRead.path),
fstree.WithPerm(sRead.perm),
fstree.WithDepth(sRead.depth),
fstree.WithNoSync(sRead.noSync)),
Storage: fstree.New(fstreeOpts...),
Policy: func(_ *objectSDK.Object, data []byte) bool {
return true
},

View file

@ -0,0 +1,3 @@
package metrics
const undefined = "undefined"

View file

@ -0,0 +1,61 @@
package metrics
import (
"time"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/fstree"
metrics_impl "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/metrics"
)
func NewFSTreeMetricsWithoutShardID(path string, m metrics_impl.FSTreeMetrics) fstree.Metrics {
return &fstreeMetrics{
shardID: undefined,
path: path,
m: m,
}
}
type fstreeMetrics struct {
shardID string
path string
m metrics_impl.FSTreeMetrics
}
func (m *fstreeMetrics) SetParentID(parentID string) {
m.shardID = parentID
}
func (m *fstreeMetrics) SetMode(readOnly bool) {
m.m.SetMode(m.shardID, m.path, readOnly)
}
func (m *fstreeMetrics) Close() {
m.m.Close(m.shardID, m.path)
}
func (m *fstreeMetrics) Iterate(d time.Duration, success bool) {
m.m.MethodDuration(m.shardID, m.path, "Iterate", d, success)
}
func (m *fstreeMetrics) Delete(d time.Duration, success bool) {
m.m.MethodDuration(m.shardID, m.path, "Delete", d, success)
}
func (m *fstreeMetrics) Exists(d time.Duration, success bool) {
m.m.MethodDuration(m.shardID, m.path, "Exists", d, success)
}
func (m *fstreeMetrics) Put(d time.Duration, size int, success bool) {
m.m.MethodDuration(m.shardID, m.path, "Put", d, success)
if success {
m.m.AddPut(m.shardID, m.path, size)
}
}
func (m *fstreeMetrics) Get(d time.Duration, size int, success bool) {
m.m.MethodDuration(m.shardID, m.path, "Get", d, success)
if success {
m.m.AddGet(m.shardID, m.path, size)
}
}
func (m *fstreeMetrics) GetRange(d time.Duration, size int, success bool) {
m.m.MethodDuration(m.shardID, m.path, "GetRange", d, success)
if success {
m.m.AddGet(m.shardID, m.path, size)
}
}

View file

@ -57,7 +57,9 @@ func (s *Shard) UpdateID() (err error) {
}
s.metaBase.SetParentID(s.info.ID.String())
s.blobStor.SetParentID(s.info.ID.String())
s.pilorama.SetParentID(s.info.ID.String())
if s.pilorama != nil {
s.pilorama.SetParentID(s.info.ID.String())
}
if len(id) != 0 {
return nil

15
pkg/metrics/consts.go Normal file
View file

@ -0,0 +1,15 @@
package metrics
const (
fstreeSubSystem = "fstree"
successLabel = "success"
shardIDLabel = "shardID"
modeLabel = "mode"
pathLabel = "path"
methodLabel = "method"
readWriteMode = "READ_WRITE"
readOnlyMode = "READ_ONLY"
closedMode = "CLOSED"
)

96
pkg/metrics/fstree.go Normal file
View file

@ -0,0 +1,96 @@
package metrics
import (
"strconv"
"time"
"git.frostfs.info/TrueCloudLab/frostfs-observability/metrics"
"github.com/prometheus/client_golang/prometheus"
)
type FSTreeMetrics interface {
SetMode(shardID, path string, readOnly bool)
Close(shardID, path string)
MethodDuration(shardID, path string, method string, d time.Duration, success bool)
AddGet(shardID, path string, size int)
AddPut(shardID, path string, size int)
}
type fstreeMetrics struct {
mode *shardIDPathModeValue
reqDuration *prometheus.HistogramVec
put *prometheus.CounterVec
get *prometheus.CounterVec
}
func newFSTreeMetrics() *fstreeMetrics {
return &fstreeMetrics{
mode: newShardIDPathMode(fstreeSubSystem, "mode", "FSTree mode value"),
reqDuration: metrics.NewHistogramVec(prometheus.HistogramOpts{
Namespace: namespace,
Subsystem: fstreeSubSystem,
Name: "request_duration_seconds",
Help: "Accumulated FSTree request process duration",
}, []string{shardIDLabel, successLabel, pathLabel, methodLabel}),
put: metrics.NewCounterVec(prometheus.CounterOpts{
Namespace: namespace,
Subsystem: fstreeSubSystem,
Name: "put_bytes",
Help: "Accumulated payload size written to FSTree",
}, []string{shardIDLabel, pathLabel}),
get: metrics.NewCounterVec(prometheus.CounterOpts{
Namespace: namespace,
Subsystem: fstreeSubSystem,
Name: "get_bytes",
Help: "Accumulated payload size read from FSTree",
}, []string{shardIDLabel, pathLabel}),
}
}
func (m *fstreeMetrics) SetMode(shardID, path string, readOnly bool) {
modeValue := readWriteMode
if readOnly {
modeValue = readOnlyMode
}
m.mode.SetMode(shardID, path, modeValue)
}
func (m *fstreeMetrics) Close(shardID, path string) {
m.mode.SetMode(shardID, path, closedMode)
m.reqDuration.DeletePartialMatch(prometheus.Labels{
shardIDLabel: shardID,
pathLabel: path,
})
m.get.DeletePartialMatch(prometheus.Labels{
shardIDLabel: shardID,
pathLabel: path,
})
m.put.DeletePartialMatch(prometheus.Labels{
shardIDLabel: shardID,
pathLabel: path,
})
}
func (m *fstreeMetrics) MethodDuration(shardID, path string, method string, d time.Duration, success bool) {
m.reqDuration.With(prometheus.Labels{
shardIDLabel: shardID,
pathLabel: path,
successLabel: strconv.FormatBool(success),
methodLabel: method,
}).Observe(d.Seconds())
}
func (m *fstreeMetrics) AddGet(shardID, path string, size int) {
m.get.With(prometheus.Labels{
shardIDLabel: shardID,
pathLabel: path,
}).Add(float64(size))
}
func (m *fstreeMetrics) AddPut(shardID, path string, size int) {
m.put.With(prometheus.Labels{
shardIDLabel: shardID,
pathLabel: path,
}).Add(float64(size))
}

View file

@ -37,3 +37,39 @@ func (m *shardIDModeValue) Delete(shardID string) {
wcShardID: shardID,
})
}
type shardIDPathModeValue struct {
modeValue *prometheus.GaugeVec
}
func newShardIDPathMode(subsystem, name, help string) *shardIDPathModeValue {
return &shardIDPathModeValue{
modeValue: metrics.NewGaugeVec(
prometheus.GaugeOpts{
Namespace: namespace,
Subsystem: subsystem,
Name: name,
Help: help,
}, []string{shardIDLabel, pathLabel, modeLabel}),
}
}
func (m *shardIDPathModeValue) SetMode(shardID, path string, mode string) {
m.modeValue.DeletePartialMatch(prometheus.Labels{
shardIDLabel: shardID,
pathLabel: path,
})
m.modeValue.With(prometheus.Labels{
shardIDLabel: shardID,
pathLabel: path,
modeLabel: mode,
}).Set(1)
}
func (m *shardIDPathModeValue) Delete(shardID, path string) {
m.modeValue.DeletePartialMatch(prometheus.Labels{
shardIDLabel: shardID,
pathLabel: path,
})
}

View file

@ -14,6 +14,7 @@ type NodeMetrics struct {
objectService *objectServiceMetrics
treeService *treeServiceMetrics
epoch prometheus.Gauge
fstree *fstreeMetrics
}
func NewNodeMetrics() *NodeMetrics {
@ -41,6 +42,7 @@ func NewNodeMetrics() *NodeMetrics {
replicator: replicator,
treeService: treeService,
epoch: epoch,
fstree: newFSTreeMetrics(),
}
}
@ -68,3 +70,7 @@ func (m *NodeMetrics) Engine() EngineMetrics {
func (m *NodeMetrics) State() StateMetrics {
return m.state
}
func (m *NodeMetrics) FSTree() FSTreeMetrics {
return m.fstree
}