commit
4bbfa8c6f4
|
@ -29,7 +29,7 @@ type Client struct {
|
|||
|
||||
IDGenerator platform.IDGenerator
|
||||
TokenGenerator platform.TokenGenerator
|
||||
time func() time.Time
|
||||
platform.TimeGenerator
|
||||
}
|
||||
|
||||
// NewClient returns an instance of a Client.
|
||||
|
@ -38,7 +38,7 @@ func NewClient() *Client {
|
|||
Logger: zap.NewNop(),
|
||||
IDGenerator: snowflake.NewIDGenerator(),
|
||||
TokenGenerator: rand.NewTokenGenerator(64),
|
||||
time: time.Now,
|
||||
TimeGenerator: platform.RealTimeGenerator{},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,12 +53,6 @@ func (c *Client) WithLogger(l *zap.Logger) {
|
|||
c.Logger = l
|
||||
}
|
||||
|
||||
// WithTime sets the function for computing the current time. Used for updating meta data
|
||||
// about objects stored. Should only be used in tests for mocking.
|
||||
func (c *Client) WithTime(fn func() time.Time) {
|
||||
c.time = fn
|
||||
}
|
||||
|
||||
// Open / create boltDB file.
|
||||
func (c *Client) Open(ctx context.Context) error {
|
||||
// Ensure the required directory structure exists.
|
||||
|
|
|
@ -676,5 +676,5 @@ func (c *Client) appendBucketEventToLog(ctx context.Context, tx *bolt.Tx, id pla
|
|||
return err
|
||||
}
|
||||
|
||||
return c.addLogEntry(ctx, tx, k, v, c.time())
|
||||
return c.addLogEntry(ctx, tx, k, v, c.Now())
|
||||
}
|
||||
|
|
|
@ -286,7 +286,7 @@ func (c *Client) CreateDashboard(ctx context.Context, d *platform.Dashboard) err
|
|||
}
|
||||
|
||||
// TODO(desa): don't populate this here. use the first/last methods of the oplog to get meta fields.
|
||||
d.Meta.CreatedAt = c.time()
|
||||
d.Meta.CreatedAt = c.Now()
|
||||
|
||||
return c.putDashboardWithMeta(ctx, tx, d)
|
||||
})
|
||||
|
@ -698,7 +698,7 @@ func (c *Client) putDashboard(ctx context.Context, tx *bolt.Tx, d *platform.Dash
|
|||
|
||||
func (c *Client) putDashboardWithMeta(ctx context.Context, tx *bolt.Tx, d *platform.Dashboard) error {
|
||||
// TODO(desa): don't populate this here. use the first/last methods of the oplog to get meta fields.
|
||||
d.Meta.UpdatedAt = c.time()
|
||||
d.Meta.UpdatedAt = c.Now()
|
||||
return c.putDashboard(ctx, tx, d)
|
||||
}
|
||||
|
||||
|
@ -907,5 +907,5 @@ func (c *Client) appendDashboardEventToLog(ctx context.Context, tx *bolt.Tx, id
|
|||
return err
|
||||
}
|
||||
|
||||
return c.addLogEntry(ctx, tx, k, v, c.time())
|
||||
return c.addLogEntry(ctx, tx, k, v, c.Now())
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package bolt_test
|
|||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
platform "github.com/influxdata/influxdb"
|
||||
"github.com/influxdata/influxdb/bolt"
|
||||
|
@ -16,12 +15,13 @@ func initDashboardService(f platformtesting.DashboardFields, t *testing.T) (plat
|
|||
t.Fatalf("failed to create new bolt client: %v", err)
|
||||
}
|
||||
|
||||
if f.NowFn == nil {
|
||||
f.NowFn = time.Now
|
||||
if f.TimeGenerator == nil {
|
||||
f.TimeGenerator = platform.RealTimeGenerator{}
|
||||
}
|
||||
|
||||
c.IDGenerator = f.IDGenerator
|
||||
c.WithTime(f.NowFn)
|
||||
c.TimeGenerator = f.TimeGenerator
|
||||
|
||||
ctx := context.TODO()
|
||||
for _, b := range f.Dashboards {
|
||||
if err := c.PutDashboard(ctx, b); err != nil {
|
||||
|
|
|
@ -501,7 +501,7 @@ func (c *Client) appendOrganizationEventToLog(ctx context.Context, tx *bolt.Tx,
|
|||
return err
|
||||
}
|
||||
|
||||
return c.addLogEntry(ctx, tx, k, v, c.time())
|
||||
return c.addLogEntry(ctx, tx, k, v, c.Now())
|
||||
}
|
||||
|
||||
func (c *Client) FindResourceOrganizationID(ctx context.Context, rt influxdb.ResourceType, id influxdb.ID) (influxdb.ID, error) {
|
||||
|
|
|
@ -476,5 +476,5 @@ func (c *Client) appendUserEventToLog(ctx context.Context, tx *bolt.Tx, id platf
|
|||
return err
|
||||
}
|
||||
|
||||
return c.addLogEntry(ctx, tx, k, v, c.time())
|
||||
return c.addLogEntry(ctx, tx, k, v, c.Now())
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ import (
|
|||
_ "github.com/influxdata/influxdb/tsdb/tsm1" // needed for tsm1
|
||||
"github.com/influxdata/influxdb/vault"
|
||||
pzap "github.com/influxdata/influxdb/zap"
|
||||
"github.com/opentracing/opentracing-go"
|
||||
opentracing "github.com/opentracing/opentracing-go"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/spf13/cobra"
|
||||
jaegerconfig "github.com/uber/jaeger-client-go/config"
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
package influxdb
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// CRUDLog is the struct to store crud related ops.
|
||||
type CRUDLog struct {
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
// TimeGenerator represents a generator for now.
|
||||
type TimeGenerator interface {
|
||||
// Now creates the generated time.
|
||||
Now() time.Time
|
||||
}
|
||||
|
||||
// RealTimeGenerator will generate the real time.
|
||||
type RealTimeGenerator struct{}
|
||||
|
||||
// Now returns the current time.
|
||||
func (g RealTimeGenerator) Now() time.Time {
|
||||
return time.Now()
|
||||
}
|
|
@ -28,6 +28,7 @@ type DocumentMeta struct {
|
|||
Type string `json:"type,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Version string `json:"version,omitempty"`
|
||||
CRUDLog
|
||||
}
|
||||
|
||||
// DocumentStore is used to perform CRUD operations on documents. It follows an options
|
||||
|
|
|
@ -1363,7 +1363,7 @@ func initDashboardService(f platformtesting.DashboardFields, t *testing.T) (plat
|
|||
t.Helper()
|
||||
svc := inmem.NewService()
|
||||
svc.IDGenerator = f.IDGenerator
|
||||
svc.WithTime(f.NowFn)
|
||||
svc.TimeGenerator = f.TimeGenerator
|
||||
ctx := context.Background()
|
||||
for _, d := range f.Dashboards {
|
||||
if err := svc.PutDashboard(ctx, d); err != nil {
|
||||
|
|
|
@ -140,6 +140,8 @@ func (h *DocumentHandler) handlePostDocument(w http.ResponseWriter, r *http.Requ
|
|||
return
|
||||
}
|
||||
|
||||
h.Logger.Info("document created")
|
||||
|
||||
if err := encodeResponse(ctx, w, http.StatusCreated, newDocumentResponse(req.Namespace, req.Document)); err != nil {
|
||||
logEncodingError(h.Logger, r, err)
|
||||
return
|
||||
|
@ -459,6 +461,8 @@ func (h *DocumentHandler) handleDeleteDocument(w http.ResponseWriter, r *http.Re
|
|||
return
|
||||
}
|
||||
|
||||
h.Logger.Info("document deleted")
|
||||
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
|
||||
|
@ -526,6 +530,8 @@ func (h *DocumentHandler) handlePutDocument(w http.ResponseWriter, r *http.Reque
|
|||
return
|
||||
}
|
||||
|
||||
h.Logger.Info("document updated")
|
||||
|
||||
ds, err := s.FindDocuments(ctx, influxdb.WhereID(req.Document.ID), influxdb.IncludeContent)
|
||||
if err != nil {
|
||||
EncodeError(ctx, err, w)
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/influxdb"
|
||||
pcontext "github.com/influxdata/influxdb/context"
|
||||
|
@ -43,6 +44,9 @@ var (
|
|||
label3MappingJSON, _ = json.Marshal(influxdb.LabelMapping{
|
||||
LabelID: label3ID,
|
||||
})
|
||||
mockGen = mock.TimeGenerator{
|
||||
FakeValue: time.Date(2006, 5, 24, 1, 2, 3, 4, time.UTC),
|
||||
}
|
||||
doc1 = influxdb.Document{
|
||||
ID: doc1ID,
|
||||
Meta: influxdb.DocumentMeta{
|
||||
|
@ -127,6 +131,8 @@ var (
|
|||
"meta": {
|
||||
"name": "doc1",
|
||||
"type": "typ1",
|
||||
"createdAt": "0001-01-01T00:00:00Z",
|
||||
"updatedAt": "0001-01-01T00:00:00Z",
|
||||
"description": "desc1"
|
||||
}
|
||||
},
|
||||
|
@ -137,7 +143,9 @@ var (
|
|||
},
|
||||
"content": "content2",
|
||||
"meta": {
|
||||
"name": "doc2"
|
||||
"name": "doc2",
|
||||
"createdAt": "0001-01-01T00:00:00Z",
|
||||
"updatedAt": "0001-01-01T00:00:00Z"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -427,6 +435,7 @@ func TestService_handlePostDocumentLabel(t *testing.T) {
|
|||
DocumentService: &mock.DocumentService{
|
||||
FindDocumentStoreFn: func(context.Context, string) (influxdb.DocumentStore, error) {
|
||||
return &mock.DocumentStore{
|
||||
TimeGenerator: mockGen,
|
||||
FindDocumentsFn: func(ctx context.Context, opts ...influxdb.DocumentFindOptions) ([]*influxdb.Document, error) {
|
||||
return []*influxdb.Document{&doc4}, nil
|
||||
},
|
||||
|
@ -801,7 +810,9 @@ func TestService_handlePostDocuments(t *testing.T) {
|
|||
DocumentService: &mock.DocumentService{
|
||||
FindDocumentStoreFn: func(context.Context, string) (influxdb.DocumentStore, error) {
|
||||
return &mock.DocumentStore{
|
||||
TimeGenerator: mockGen,
|
||||
CreateDocumentFn: func(ctx context.Context, d *influxdb.Document, opts ...influxdb.DocumentOptions) error {
|
||||
d.Meta.CreatedAt = mockGen.Now()
|
||||
return nil
|
||||
},
|
||||
}, nil
|
||||
|
@ -826,7 +837,9 @@ func TestService_handlePostDocuments(t *testing.T) {
|
|||
"self": "/api/v2/documents/template/020f755c3c082014"
|
||||
},
|
||||
"meta": {
|
||||
"name": "doc5"
|
||||
"name": "doc5",
|
||||
"createdAt": "2006-05-24T01:02:03.000000004Z",
|
||||
"updatedAt": "0001-01-01T00:00:00Z"
|
||||
}}`,
|
||||
},
|
||||
},
|
||||
|
@ -836,8 +849,10 @@ func TestService_handlePostDocuments(t *testing.T) {
|
|||
DocumentService: &mock.DocumentService{
|
||||
FindDocumentStoreFn: func(context.Context, string) (influxdb.DocumentStore, error) {
|
||||
return &mock.DocumentStore{
|
||||
TimeGenerator: mockGen,
|
||||
CreateDocumentFn: func(ctx context.Context, d *influxdb.Document, opts ...influxdb.DocumentOptions) error {
|
||||
d.Labels = []*influxdb.Label{&label1, &label2}
|
||||
d.Meta.CreatedAt = mockGen.Now()
|
||||
return nil
|
||||
},
|
||||
}, nil
|
||||
|
@ -877,7 +892,9 @@ func TestService_handlePostDocuments(t *testing.T) {
|
|||
"name": "l2"
|
||||
}],
|
||||
"meta": {
|
||||
"name": "doc6"
|
||||
"name": "doc6",
|
||||
"createdAt": "2006-05-24T01:02:03.000000004Z",
|
||||
"updatedAt": "0001-01-01T00:00:00Z"
|
||||
}}`,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -6983,6 +6983,14 @@ components:
|
|||
type: string
|
||||
version:
|
||||
type: string
|
||||
createdAt:
|
||||
type: string
|
||||
format: date-time
|
||||
readOnly: true
|
||||
updatedAt:
|
||||
type: string
|
||||
format: date-time
|
||||
readOnly: true
|
||||
required:
|
||||
- name
|
||||
- version
|
||||
|
|
|
@ -129,7 +129,7 @@ func (s *Service) FindDashboards(ctx context.Context, filter platform.DashboardF
|
|||
// CreateDashboard implements platform.DashboardService interface.
|
||||
func (s *Service) CreateDashboard(ctx context.Context, d *platform.Dashboard) error {
|
||||
d.ID = s.IDGenerator.ID()
|
||||
d.Meta.CreatedAt = s.time()
|
||||
d.Meta.CreatedAt = s.Now()
|
||||
err := s.PutDashboardWithMeta(ctx, d)
|
||||
if err != nil {
|
||||
return &platform.Error{
|
||||
|
@ -160,7 +160,7 @@ func (s *Service) PutCellView(ctx context.Context, cell *platform.Cell) error {
|
|||
|
||||
// PutDashboardWithMeta sets a dashboard while updating the meta field of a dashboard.
|
||||
func (s *Service) PutDashboardWithMeta(ctx context.Context, d *platform.Dashboard) error {
|
||||
d.Meta.UpdatedAt = s.time()
|
||||
d.Meta.UpdatedAt = s.Now()
|
||||
return s.PutDashboard(ctx, d)
|
||||
}
|
||||
|
||||
|
|
|
@ -11,8 +11,8 @@ import (
|
|||
func initDashboardService(f platformtesting.DashboardFields, t *testing.T) (platform.DashboardService, string, func()) {
|
||||
s := NewService()
|
||||
s.IDGenerator = f.IDGenerator
|
||||
s.TimeGenerator = f.TimeGenerator
|
||||
ctx := context.Background()
|
||||
s.WithTime(f.NowFn)
|
||||
for _, b := range f.Dashboards {
|
||||
if err := s.PutDashboard(ctx, b); err != nil {
|
||||
t.Fatalf("failed to populate Dashboards")
|
||||
|
|
|
@ -3,7 +3,6 @@ package inmem
|
|||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
platform "github.com/influxdata/influxdb"
|
||||
"github.com/influxdata/influxdb/rand"
|
||||
|
@ -35,7 +34,7 @@ type Service struct {
|
|||
|
||||
TokenGenerator platform.TokenGenerator
|
||||
IDGenerator platform.IDGenerator
|
||||
time func() time.Time
|
||||
platform.TimeGenerator
|
||||
}
|
||||
|
||||
// NewService creates an instance of a Service.
|
||||
|
@ -43,18 +42,12 @@ func NewService() *Service {
|
|||
s := &Service{
|
||||
TokenGenerator: rand.NewTokenGenerator(64),
|
||||
IDGenerator: snowflake.NewIDGenerator(),
|
||||
time: time.Now,
|
||||
TimeGenerator: platform.RealTimeGenerator{},
|
||||
}
|
||||
s.initializeSources(context.TODO())
|
||||
return s
|
||||
}
|
||||
|
||||
// WithTime sets the function for computing the current time. Used for updating meta data
|
||||
// about objects stored. Should only be used in tests for mocking.
|
||||
func (s *Service) WithTime(fn func() time.Time) {
|
||||
s.time = fn
|
||||
}
|
||||
|
||||
// Flush removes all data from the in-memory store
|
||||
func (s *Service) Flush() {
|
||||
s.flush(&s.authorizationKV)
|
||||
|
|
|
@ -759,7 +759,7 @@ func (s *Service) appendBucketEventToLog(ctx context.Context, tx Tx, id influxdb
|
|||
return err
|
||||
}
|
||||
|
||||
return s.addLogEntry(ctx, tx, k, v, s.time())
|
||||
return s.addLogEntry(ctx, tx, k, v, s.Now())
|
||||
}
|
||||
|
||||
// UnexpectedBucketError is used when the error comes from an internal system.
|
||||
|
|
|
@ -301,7 +301,7 @@ func (s *Service) CreateDashboard(ctx context.Context, d *influxdb.Dashboard) er
|
|||
}
|
||||
|
||||
// TODO(desa): don't populate this here. use the first/last methods of the oplog to get meta fields.
|
||||
d.Meta.CreatedAt = s.time()
|
||||
d.Meta.CreatedAt = s.Now()
|
||||
|
||||
if err := s.putDashboardWithMeta(ctx, tx, d); err != nil {
|
||||
return err
|
||||
|
@ -752,7 +752,7 @@ func (s *Service) putDashboard(ctx context.Context, tx Tx, d *influxdb.Dashboard
|
|||
|
||||
func (s *Service) putDashboardWithMeta(ctx context.Context, tx Tx, d *influxdb.Dashboard) error {
|
||||
// TODO(desa): don't populate this here. use the first/last methods of the oplog to get meta fields.
|
||||
d.Meta.UpdatedAt = s.time()
|
||||
d.Meta.UpdatedAt = s.Now()
|
||||
return s.putDashboard(ctx, tx, d)
|
||||
}
|
||||
|
||||
|
@ -972,5 +972,5 @@ func (s *Service) appendDashboardEventToLog(ctx context.Context, tx Tx, id influ
|
|||
return err
|
||||
}
|
||||
|
||||
return s.addLogEntry(ctx, tx, k, v, s.time())
|
||||
return s.addLogEntry(ctx, tx, k, v, s.Now())
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package kv_test
|
|||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/influxdb"
|
||||
"github.com/influxdata/influxdb/kv"
|
||||
|
@ -46,12 +45,12 @@ func initInmemDashboardService(f influxdbtesting.DashboardFields, t *testing.T)
|
|||
|
||||
func initDashboardService(s kv.Store, f influxdbtesting.DashboardFields, t *testing.T) (influxdb.DashboardService, string, func()) {
|
||||
|
||||
if f.NowFn == nil {
|
||||
f.NowFn = time.Now
|
||||
if f.TimeGenerator == nil {
|
||||
f.TimeGenerator = influxdb.RealTimeGenerator{}
|
||||
}
|
||||
svc := kv.NewService(s)
|
||||
svc.IDGenerator = f.IDGenerator
|
||||
svc.WithTime(f.NowFn)
|
||||
svc.TimeGenerator = f.TimeGenerator
|
||||
|
||||
ctx := context.Background()
|
||||
if err := svc.Initialize(ctx); err != nil {
|
||||
|
|
|
@ -348,7 +348,7 @@ func (i *DocumentIndex) GetAccessorsDocuments(ownerType string, ownerID influxdb
|
|||
|
||||
func (s *Service) createDocument(ctx context.Context, tx Tx, ns string, d *influxdb.Document) error {
|
||||
d.ID = s.IDGenerator.ID()
|
||||
|
||||
d.Meta.CreatedAt = s.Now()
|
||||
if err := s.putDocument(ctx, tx, ns, d); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -357,7 +357,7 @@ func (s *Service) createDocument(ctx context.Context, tx Tx, ns string, d *influ
|
|||
}
|
||||
|
||||
func (s *Service) putDocument(ctx context.Context, tx Tx, ns string, d *influxdb.Document) error {
|
||||
if err := s.putDocumentMeta(ctx, tx, ns, d.ID, &d.Meta); err != nil {
|
||||
if err := s.putDocumentMeta(ctx, tx, ns, d.ID, d.Meta); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -397,7 +397,7 @@ func (s *Service) putDocumentContent(ctx context.Context, tx Tx, ns string, id i
|
|||
return s.putAtID(ctx, tx, path.Join(ns, documentContentBucket), id, data)
|
||||
}
|
||||
|
||||
func (s *Service) putDocumentMeta(ctx context.Context, tx Tx, ns string, id influxdb.ID, m *influxdb.DocumentMeta) error {
|
||||
func (s *Service) putDocumentMeta(ctx context.Context, tx Tx, ns string, id influxdb.ID, m influxdb.DocumentMeta) error {
|
||||
return s.putAtID(ctx, tx, path.Join(ns, documentMetaBucket), id, m)
|
||||
}
|
||||
|
||||
|
@ -735,7 +735,7 @@ func (s *DocumentStore) UpdateDocument(ctx context.Context, d *influxdb.Document
|
|||
|
||||
func (s *Service) updateDocument(ctx context.Context, tx Tx, ns string, d *influxdb.Document) error {
|
||||
// TODO(desa): deindex meta
|
||||
|
||||
d.Meta.UpdatedAt = s.Now()
|
||||
if err := s.putDocument(ctx, tx, ns, d); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -108,7 +108,10 @@ func (s *Service) initializeKVLog(ctx context.Context, tx Tx) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
var errKeyValueLogBoundsNotFound = fmt.Errorf("oplog not found")
|
||||
var errKeyValueLogBoundsNotFound = &platform.Error{
|
||||
Code: platform.ENotFound,
|
||||
Msg: "oplog not found",
|
||||
}
|
||||
|
||||
func (s *Service) getKeyValueLogBounds(ctx context.Context, tx Tx, key []byte) (*keyValueLogBounds, error) {
|
||||
k := encodeKeyValueIndexKey(key)
|
||||
|
@ -381,7 +384,7 @@ func (s *Service) LastLogEntry(ctx context.Context, k []byte) ([]byte, time.Time
|
|||
func (s *Service) firstLogEntry(ctx context.Context, tx Tx, k []byte) ([]byte, time.Time, error) {
|
||||
bounds, err := s.getKeyValueLogBounds(ctx, tx, k)
|
||||
if err != nil {
|
||||
return nil, bounds.StartTime(), err
|
||||
return nil, time.Time{}, err
|
||||
}
|
||||
|
||||
return s.getLogEntry(ctx, tx, k, bounds.StartTime())
|
||||
|
@ -390,7 +393,7 @@ func (s *Service) firstLogEntry(ctx context.Context, tx Tx, k []byte) ([]byte, t
|
|||
func (s *Service) lastLogEntry(ctx context.Context, tx Tx, k []byte) ([]byte, time.Time, error) {
|
||||
bounds, err := s.getKeyValueLogBounds(ctx, tx, k)
|
||||
if err != nil {
|
||||
return nil, bounds.StopTime(), err
|
||||
return nil, time.Time{}, err
|
||||
}
|
||||
|
||||
return s.getLogEntry(ctx, tx, k, bounds.StopTime())
|
||||
|
|
|
@ -570,7 +570,7 @@ func (s *Service) appendOrganizationEventToLog(ctx context.Context, tx Tx, id in
|
|||
return err
|
||||
}
|
||||
|
||||
return s.addLogEntry(ctx, tx, k, v, s.time())
|
||||
return s.addLogEntry(ctx, tx, k, v, s.Now())
|
||||
}
|
||||
|
||||
// FindResourceOrganizationID is used to find the organization that a resource belongs to five the id of a resource and a resource type.
|
||||
|
|
|
@ -2,7 +2,6 @@ package kv
|
|||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
|
@ -26,9 +25,8 @@ type Service struct {
|
|||
|
||||
IDGenerator influxdb.IDGenerator
|
||||
TokenGenerator influxdb.TokenGenerator
|
||||
Hash Crypt
|
||||
|
||||
time func() time.Time
|
||||
influxdb.TimeGenerator
|
||||
Hash Crypt
|
||||
}
|
||||
|
||||
// NewService returns an instance of a Service.
|
||||
|
@ -39,7 +37,7 @@ func NewService(kv Store, configs ...ServiceConfig) *Service {
|
|||
TokenGenerator: rand.NewTokenGenerator(64),
|
||||
Hash: &Bcrypt{},
|
||||
kv: kv,
|
||||
time: time.Now,
|
||||
TimeGenerator: influxdb.RealTimeGenerator{},
|
||||
}
|
||||
|
||||
if len(configs) > 0 {
|
||||
|
@ -131,12 +129,6 @@ func (s *Service) Initialize(ctx context.Context) error {
|
|||
})
|
||||
}
|
||||
|
||||
// WithTime sets the function for computing the current time. Used for updating meta data
|
||||
// about objects stored. Should only be used in tests for mocking.
|
||||
func (s *Service) WithTime(fn func() time.Time) {
|
||||
s.time = fn
|
||||
}
|
||||
|
||||
// WithStore sets kv store for the service.
|
||||
// Should only be used in tests for mocking.
|
||||
func (s *Service) WithStore(store Store) {
|
||||
|
|
|
@ -515,7 +515,7 @@ func (s *Service) appendUserEventToLog(ctx context.Context, tx Tx, id influxdb.I
|
|||
return err
|
||||
}
|
||||
|
||||
return s.addLogEntry(ctx, tx, k, v, s.time())
|
||||
return s.addLogEntry(ctx, tx, k, v, s.Now())
|
||||
}
|
||||
|
||||
var (
|
||||
|
|
|
@ -38,6 +38,7 @@ func NewDocumentService() *DocumentService {
|
|||
|
||||
// DocumentStore is the mocked document store.
|
||||
type DocumentStore struct {
|
||||
TimeGenerator TimeGenerator
|
||||
CreateDocumentFn func(ctx context.Context, d *influxdb.Document, opts ...influxdb.DocumentOptions) error
|
||||
UpdateDocumentFn func(ctx context.Context, d *influxdb.Document, opts ...influxdb.DocumentOptions) error
|
||||
FindDocumentsFn func(ctx context.Context, opts ...influxdb.DocumentFindOptions) ([]*influxdb.Document, error)
|
||||
|
|
|
@ -2,6 +2,7 @@ package mock
|
|||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
platform "github.com/influxdata/influxdb"
|
||||
)
|
||||
|
@ -47,3 +48,13 @@ type TokenGenerator struct {
|
|||
func (g TokenGenerator) Token() (string, error) {
|
||||
return g.TokenFn()
|
||||
}
|
||||
|
||||
// TimeGenerator stores a fake value of time.
|
||||
type TimeGenerator struct {
|
||||
FakeValue time.Time
|
||||
}
|
||||
|
||||
// Now will return the FakeValue stored in the struct.
|
||||
func (g TimeGenerator) Now() time.Time {
|
||||
return g.FakeValue
|
||||
}
|
||||
|
|
|
@ -31,10 +31,10 @@ var dashboardCmpOptions = cmp.Options{
|
|||
|
||||
// DashboardFields will include the IDGenerator, and dashboards
|
||||
type DashboardFields struct {
|
||||
IDGenerator platform.IDGenerator
|
||||
NowFn func() time.Time
|
||||
Dashboards []*platform.Dashboard
|
||||
Views []*platform.View
|
||||
IDGenerator platform.IDGenerator
|
||||
TimeGenerator platform.TimeGenerator
|
||||
Dashboards []*platform.Dashboard
|
||||
Views []*platform.View
|
||||
}
|
||||
|
||||
// DashboardService tests all the service functions.
|
||||
|
@ -125,7 +125,7 @@ func CreateDashboard(
|
|||
return MustIDBase16(dashTwoID)
|
||||
},
|
||||
},
|
||||
NowFn: func() time.Time { return time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC) },
|
||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC)},
|
||||
Dashboards: []*platform.Dashboard{
|
||||
{
|
||||
ID: MustIDBase16(dashOneID),
|
||||
|
@ -168,7 +168,7 @@ func CreateDashboard(
|
|||
return MustIDBase16(dashTwoID)
|
||||
},
|
||||
},
|
||||
NowFn: func() time.Time { return time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC) },
|
||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC)},
|
||||
Dashboards: []*platform.Dashboard{
|
||||
{
|
||||
ID: MustIDBase16(dashOneID),
|
||||
|
@ -253,7 +253,7 @@ func AddDashboardCell(
|
|||
return MustIDBase16(dashTwoID)
|
||||
},
|
||||
},
|
||||
NowFn: func() time.Time { return time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC) },
|
||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC)},
|
||||
Dashboards: []*platform.Dashboard{
|
||||
{
|
||||
ID: MustIDBase16(dashOneID),
|
||||
|
@ -296,7 +296,7 @@ func AddDashboardCell(
|
|||
{
|
||||
name: "add cell with no id",
|
||||
fields: DashboardFields{
|
||||
NowFn: func() time.Time { return time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC) },
|
||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC)},
|
||||
IDGenerator: &mock.IDGenerator{
|
||||
IDFn: func() platform.ID {
|
||||
return MustIDBase16(dashTwoID)
|
||||
|
@ -342,7 +342,7 @@ func AddDashboardCell(
|
|||
{
|
||||
name: "add cell with id not exist",
|
||||
fields: DashboardFields{
|
||||
NowFn: func() time.Time { return time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC) },
|
||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC)},
|
||||
IDGenerator: &mock.IDGenerator{
|
||||
IDFn: func() platform.ID {
|
||||
return MustIDBase16(dashTwoID)
|
||||
|
@ -1059,7 +1059,7 @@ func UpdateDashboard(
|
|||
{
|
||||
name: "update name",
|
||||
fields: DashboardFields{
|
||||
NowFn: func() time.Time { return time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC) },
|
||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC)},
|
||||
Dashboards: []*platform.Dashboard{
|
||||
{
|
||||
ID: MustIDBase16(dashOneID),
|
||||
|
@ -1091,7 +1091,7 @@ func UpdateDashboard(
|
|||
{
|
||||
name: "update description",
|
||||
fields: DashboardFields{
|
||||
NowFn: func() time.Time { return time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC) },
|
||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC)},
|
||||
Dashboards: []*platform.Dashboard{
|
||||
{
|
||||
ID: MustIDBase16(dashOneID),
|
||||
|
@ -1124,7 +1124,7 @@ func UpdateDashboard(
|
|||
{
|
||||
name: "update description and name",
|
||||
fields: DashboardFields{
|
||||
NowFn: func() time.Time { return time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC) },
|
||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC)},
|
||||
Dashboards: []*platform.Dashboard{
|
||||
{
|
||||
ID: MustIDBase16(dashOneID),
|
||||
|
@ -1158,7 +1158,7 @@ func UpdateDashboard(
|
|||
{
|
||||
name: "update with id not exist",
|
||||
fields: DashboardFields{
|
||||
NowFn: func() time.Time { return time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC) },
|
||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC)},
|
||||
Dashboards: []*platform.Dashboard{
|
||||
{
|
||||
ID: MustIDBase16(dashOneID),
|
||||
|
@ -1234,7 +1234,7 @@ func RemoveDashboardCell(
|
|||
{
|
||||
name: "basic remove cell",
|
||||
fields: DashboardFields{
|
||||
NowFn: func() time.Time { return time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC) },
|
||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC)},
|
||||
IDGenerator: &mock.IDGenerator{
|
||||
IDFn: func() platform.ID {
|
||||
return MustIDBase16(dashTwoID)
|
||||
|
@ -1332,7 +1332,7 @@ func UpdateDashboardCell(
|
|||
{
|
||||
name: "basic update cell",
|
||||
fields: DashboardFields{
|
||||
NowFn: func() time.Time { return time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC) },
|
||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC)},
|
||||
IDGenerator: &mock.IDGenerator{
|
||||
IDFn: func() platform.ID {
|
||||
return MustIDBase16(dashTwoID)
|
||||
|
@ -1388,7 +1388,7 @@ func UpdateDashboardCell(
|
|||
{
|
||||
name: "invalid cell update without attribute",
|
||||
fields: DashboardFields{
|
||||
NowFn: func() time.Time { return time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC) },
|
||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC)},
|
||||
IDGenerator: &mock.IDGenerator{
|
||||
IDFn: func() platform.ID {
|
||||
return MustIDBase16(dashTwoID)
|
||||
|
@ -1441,7 +1441,7 @@ func UpdateDashboardCell(
|
|||
{
|
||||
name: "invalid cell update cell id not exist",
|
||||
fields: DashboardFields{
|
||||
NowFn: func() time.Time { return time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC) },
|
||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC)},
|
||||
IDGenerator: &mock.IDGenerator{
|
||||
IDFn: func() platform.ID {
|
||||
return MustIDBase16(dashTwoID)
|
||||
|
@ -1539,7 +1539,7 @@ func ReplaceDashboardCells(
|
|||
{
|
||||
name: "basic replace cells",
|
||||
fields: DashboardFields{
|
||||
NowFn: func() time.Time { return time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC) },
|
||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC)},
|
||||
IDGenerator: &mock.IDGenerator{
|
||||
IDFn: func() platform.ID {
|
||||
return MustIDBase16(dashTwoID)
|
||||
|
@ -1620,7 +1620,7 @@ func ReplaceDashboardCells(
|
|||
{
|
||||
name: "try to add a cell that didn't previously exist",
|
||||
fields: DashboardFields{
|
||||
NowFn: func() time.Time { return time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC) },
|
||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2009, time.November, 10, 24, 0, 0, 0, time.UTC)},
|
||||
IDGenerator: &mock.IDGenerator{
|
||||
IDFn: func() platform.ID {
|
||||
return MustIDBase16(dashTwoID)
|
||||
|
|
|
@ -5,11 +5,13 @@ import (
|
|||
"context"
|
||||
"sort"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
"github.com/influxdata/influxdb"
|
||||
"github.com/influxdata/influxdb/kv"
|
||||
"github.com/influxdata/influxdb/mock"
|
||||
)
|
||||
|
||||
// NewDocumentIntegrationTest will test the documents related funcs.
|
||||
|
@ -17,10 +19,13 @@ func NewDocumentIntegrationTest(store kv.Store) func(t *testing.T) {
|
|||
return func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
svc := kv.NewService(store)
|
||||
mockTimeGen := new(mock.TimeGenerator)
|
||||
if err := svc.Initialize(ctx); err != nil {
|
||||
t.Fatalf("failed to initialize service: %v", err)
|
||||
}
|
||||
|
||||
svc.TimeGenerator = mockTimeGen
|
||||
|
||||
s, err := svc.CreateDocumentStore(ctx, "testing")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create document store: %v", err)
|
||||
|
@ -68,6 +73,7 @@ func NewDocumentIntegrationTest(store kv.Store) func(t *testing.T) {
|
|||
"v1": "v1",
|
||||
},
|
||||
}
|
||||
mockTimeGen.FakeValue = time.Date(2009, 1, 2, 3, 0, 0, 0, time.UTC)
|
||||
if err := s.CreateDocument(ctx, d1, influxdb.AuthorizedWithOrg(s1, o1.Name), influxdb.WithLabel(l1.ID)); err != nil {
|
||||
t.Errorf("failed to create document: %v", err)
|
||||
}
|
||||
|
@ -82,10 +88,12 @@ func NewDocumentIntegrationTest(store kv.Store) func(t *testing.T) {
|
|||
"i2": "i2",
|
||||
},
|
||||
}
|
||||
mockTimeGen.FakeValue = time.Date(2009, 1, 2, 3, 0, 1, 0, time.UTC)
|
||||
if err := s.CreateDocument(ctx, d2, influxdb.AuthorizedWithOrg(s2, o1.Name), influxdb.WithLabel(l2.ID)); err == nil {
|
||||
t.Fatalf("should not have be authorized to create document")
|
||||
}
|
||||
|
||||
mockTimeGen.FakeValue = time.Date(2009, 1, 2, 3, 0, 1, 0, time.UTC)
|
||||
if err := s.CreateDocument(ctx, d2, influxdb.AuthorizedWithOrg(s2, o2.Name)); err != nil {
|
||||
t.Errorf("should have been authorized to create document: %v", err)
|
||||
}
|
||||
|
@ -100,6 +108,7 @@ func NewDocumentIntegrationTest(store kv.Store) func(t *testing.T) {
|
|||
"k2": "v2",
|
||||
},
|
||||
}
|
||||
mockTimeGen.FakeValue = time.Date(2009, 1, 2, 3, 0, 2, 0, time.UTC)
|
||||
if err := s.CreateDocument(ctx, d3, influxdb.AuthorizedWithOrg(s1, o2.Name)); err == nil {
|
||||
t.Errorf("should not have be authorized to create document")
|
||||
}
|
||||
|
@ -107,6 +116,7 @@ func NewDocumentIntegrationTest(store kv.Store) func(t *testing.T) {
|
|||
|
||||
t.Run("can create unowned document", func(t *testing.T) {
|
||||
// TODO(desa): should this be allowed?
|
||||
mockTimeGen.FakeValue = time.Date(2009, 1, 2, 3, 0, 2, 0, time.UTC)
|
||||
if err := s.CreateDocument(ctx, d3); err != nil {
|
||||
t.Fatalf("should have been able to create document: %v", err)
|
||||
}
|
||||
|
@ -128,14 +138,18 @@ func NewDocumentIntegrationTest(store kv.Store) func(t *testing.T) {
|
|||
})
|
||||
})
|
||||
|
||||
d1.Meta.CreatedAt = time.Date(2009, 1, 2, 3, 0, 0, 0, time.UTC)
|
||||
dl1 := new(influxdb.Document)
|
||||
*dl1 = *d1
|
||||
dl1.Labels = append([]*influxdb.Label{}, l1)
|
||||
|
||||
d2.Meta.CreatedAt = time.Date(2009, 1, 2, 3, 0, 1, 0, time.UTC)
|
||||
dl2 := new(influxdb.Document)
|
||||
*dl2 = *d2
|
||||
dl2.Labels = append([]*influxdb.Label{}, d2.Labels...)
|
||||
|
||||
d3.Meta.CreatedAt = time.Date(2009, 1, 2, 3, 0, 2, 0, time.UTC)
|
||||
|
||||
t.Run("bare call to find returns all documents", func(t *testing.T) {
|
||||
ds, err := ss.FindDocuments(ctx)
|
||||
if err != nil {
|
||||
|
@ -153,8 +167,8 @@ func NewDocumentIntegrationTest(store kv.Store) func(t *testing.T) {
|
|||
t.Fatalf("failed to retrieve documents: %v", err)
|
||||
}
|
||||
|
||||
if exp, got := []*influxdb.Document{dl1}, ds; !docsEqual(exp, got) {
|
||||
t.Errorf("documents are different -got/+want\ndiff %s", docsDiff(exp, got))
|
||||
if exp, got := []*influxdb.Document{dl1}, ds; !docsEqual(got, exp) {
|
||||
t.Errorf("documents are different -got/+want\ndiff %s", docsDiff(got, exp))
|
||||
}
|
||||
})
|
||||
|
||||
|
|
Loading…
Reference in New Issue