From 73ef5b782431a0c52db448b5d2ef697dfa53f93f Mon Sep 17 00:00:00 2001 From: lostlevels Date: Wed, 3 Jan 2024 11:42:42 -0800 Subject: [PATCH 01/24] [BACK-2416] Add optional TIDEPOOL_AUTH_CLIENT_EXTERNAL_PATH_PREFIX environment variable for path prefixes to auth services calls. --- auth/client/client_test.go | 2 ++ auth/client/external.go | 8 ++++++-- auth/service/service/service_test.go | 2 +- blob/service/service_test.go | 2 +- client/client.go | 6 +++++- env.sh | 1 + prescription/application/application_test.go | 2 +- service/service/DEPRECATED_service_test.go | 2 +- task/service/service/service_test.go | 2 +- 9 files changed, 19 insertions(+), 8 deletions(-) diff --git a/auth/client/client_test.go b/auth/client/client_test.go index 76fdad9723..d43ea60926 100644 --- a/auth/client/client_test.go +++ b/auth/client/client_test.go @@ -54,6 +54,7 @@ var _ = Describe("Client", func() { config.Config.UserAgent = testHttp.NewUserAgent() config.Config.ServiceSecret = authTest.NewServiceSecret() config.ExternalConfig.Address = testHttp.NewAddress() + config.ExternalConfig.PathPrefix = "auth" config.ExternalConfig.UserAgent = testHttp.NewUserAgent() config.ExternalConfig.ServerSessionTokenSecret = serverTokenSecret config.ExternalConfig.ServerSessionTokenTimeout = time.Duration(serverTokenTimeout) * time.Second @@ -115,6 +116,7 @@ var _ = Describe("Client", func() { config.Config.UserAgent = testHttp.NewUserAgent() config.Config.ServiceSecret = authTest.NewServiceSecret() config.ExternalConfig.Address = server.URL() + config.ExternalConfig.PathPrefix = "auth" config.ExternalConfig.UserAgent = testHttp.NewUserAgent() config.ExternalConfig.ServerSessionTokenSecret = serverTokenSecret authorizeAs = platform.AuthorizeAsService diff --git a/auth/client/external.go b/auth/client/external.go index 77e99a43ef..75e333e038 100644 --- a/auth/client/external.go +++ b/auth/client/external.go @@ -68,6 +68,8 @@ type ExternalConfig struct { *platform.Config ServerSessionTokenSecret string `envconfig:"TIDEPOOL_AUTH_CLIENT_EXTERNAL_SERVER_SESSION_TOKEN_SECRET"` ServerSessionTokenTimeout time.Duration `envconfig:"TIDEPOOL_AUTH_CLIENT_EXTERNAL_SERVER_SESSION_TOKEN_TIMEOUT" default:"1h"` + // PathPrefix to prepend to the path of any service calls (if any). + PathPrefix string `envconfig:"TIDEPOOL_AUTH_CLIENT_EXTERNAL_PATH_PREFIX" default:"auth"` } func NewExternalConfig() *ExternalConfig { @@ -107,6 +109,7 @@ type External struct { serverSessionTokenMutex sync.Mutex serverSessionTokenSafe string closingChannel chan chan bool + PathPrefix string // PathPrefix is the prefix to prepend to all external URL path calls to the auth service (if any) } func NewExternal(cfg *ExternalConfig, authorizeAs platform.AuthorizeAs, name string, lgr log.Logger) (*External, error) { @@ -135,6 +138,7 @@ func NewExternal(cfg *ExternalConfig, authorizeAs platform.AuthorizeAs, name str name: name, serverSessionTokenSecret: cfg.ServerSessionTokenSecret, serverSessionTokenTimeout: cfg.ServerSessionTokenTimeout, + PathPrefix: cfg.PathPrefix, }, nil } @@ -200,7 +204,7 @@ func (e *External) ValidateSessionToken(ctx context.Context, token string) (requ IsServer bool UserID string } - if err := e.client.RequestData(ctx, "GET", e.client.ConstructURL("auth", "token", token), nil, nil, &result); err != nil { + if err := e.client.RequestData(ctx, "GET", e.client.ConstructURL(e.PathPrefix, "token", token), nil, nil, &result); err != nil { return nil, err } @@ -329,7 +333,7 @@ func (e *External) refreshServerSessionToken() error { e.logger.Debug("Refreshing server session token") requestMethod := "POST" - requestURL := e.client.ConstructURL("auth", "serverlogin") + requestURL := e.client.ConstructURL(e.PathPrefix, "serverlogin") request, err := http.NewRequest(requestMethod, requestURL, nil) if err != nil { return errors.Wrapf(err, "unable to create new request for %s %s", requestMethod, requestURL) diff --git a/auth/service/service/service_test.go b/auth/service/service/service_test.go index d6f698dd2a..b92ef2cefa 100644 --- a/auth/service/service/service_test.go +++ b/auth/service/service/service_test.go @@ -48,7 +48,7 @@ var _ = Describe("Service", func() { server = NewServer() server.AppendHandlers( CombineHandlers( - VerifyRequest("POST", "/auth/serverlogin"), + VerifyRequest("POST", "/serverlogin"), // by default the path prefix is empty to the auth service unless set in the env var TIDEPOOL_AUTH_CLIENT_EXTERNAL_PATH_PREFIX VerifyHeaderKV("X-Tidepool-Server-Name", *provider.NameOutput), VerifyHeaderKV("X-Tidepool-Server-Secret", serverSecret), VerifyBody(nil), diff --git a/blob/service/service_test.go b/blob/service/service_test.go index 251c376a17..b0246c707c 100644 --- a/blob/service/service_test.go +++ b/blob/service/service_test.go @@ -47,7 +47,7 @@ var _ = Describe("Service", func() { server = NewServer() server.AppendHandlers( CombineHandlers( - VerifyRequest(http.MethodPost, "/auth/serverlogin"), + VerifyRequest(http.MethodPost, "/serverlogin"), VerifyHeaderKV("X-Tidepool-Server-Name", *provider.NameOutput), VerifyHeaderKV("X-Tidepool-Server-Secret", serverSecret), VerifyBody(nil), diff --git a/client/client.go b/client/client.go index 24e8f30b61..55e77b97b1 100644 --- a/client/client.go +++ b/client/client.go @@ -39,7 +39,11 @@ func New(cfg *Config) (*Client, error) { func (c *Client) ConstructURL(paths ...string) string { segments := []string{} for _, path := range paths { - segments = append(segments, url.PathEscape(strings.Trim(path, "/"))) + escapedPath := url.PathEscape(strings.Trim(path, "/")) + if escapedPath == "" { + continue + } + segments = append(segments, escapedPath) } return fmt.Sprintf("%s/%s", strings.TrimRight(c.address, "/"), strings.Join(segments, "/")) } diff --git a/env.sh b/env.sh index 13f8a66e31..22ec573817 100644 --- a/env.sh +++ b/env.sh @@ -32,6 +32,7 @@ export TIDEPOOL_USER_CLIENT_ADDRESS="http://localhost:8009" export TIDEPOOL_AUTH_CLIENT_EXTERNAL_ADDRESS="http://localhost:8009" export TIDEPOOL_AUTH_CLIENT_EXTERNAL_SERVER_SESSION_TOKEN_SECRET="This needs to be the same secret everywhere. YaHut75NsK1f9UKUXuWqxNN0RUwHFBCy" +export TIDEPOOL_AUTH_CLIENT_EXTERNAL_PATH_PREFIX="auth" export TIDEPOOL_AUTH_SERVICE_SERVER_ADDRESS=":9222" export TIDEPOOL_BLOB_SERVICE_SERVER_ADDRESS=":9225" diff --git a/prescription/application/application_test.go b/prescription/application/application_test.go index 9e2d511bd2..6f27e00087 100644 --- a/prescription/application/application_test.go +++ b/prescription/application/application_test.go @@ -53,7 +53,7 @@ var _ = Describe("Application", func() { server = NewServer() server.AppendHandlers( CombineHandlers( - VerifyRequest(http.MethodPost, "/auth/serverlogin"), + VerifyRequest(http.MethodPost, "/serverlogin"), VerifyHeaderKV("X-Tidepool-Server-Name", *prvdr.NameOutput), VerifyHeaderKV("X-Tidepool-Server-Secret", serverSecret), VerifyBody(nil), diff --git a/service/service/DEPRECATED_service_test.go b/service/service/DEPRECATED_service_test.go index 95e148f7be..621256e107 100644 --- a/service/service/DEPRECATED_service_test.go +++ b/service/service/DEPRECATED_service_test.go @@ -39,7 +39,7 @@ var _ = Describe("DEPRECATEDService", func() { Expect(server).ToNot(BeNil()) server.AppendHandlers( CombineHandlers( - VerifyRequest("POST", "/auth/serverlogin"), + VerifyRequest("POST", "/serverlogin"), VerifyHeaderKV("X-Tidepool-Server-Name", *provider.NameOutput), VerifyHeaderKV("X-Tidepool-Server-Secret", serverSecret), VerifyBody(nil), diff --git a/task/service/service/service_test.go b/task/service/service/service_test.go index 8fe529cca5..69f4f2efc2 100644 --- a/task/service/service/service_test.go +++ b/task/service/service/service_test.go @@ -46,7 +46,7 @@ var _ = Describe("Service", func() { server = NewServer() server.AppendHandlers( CombineHandlers( - VerifyRequest("POST", "/auth/serverlogin"), + VerifyRequest("POST", "/serverlogin"), VerifyHeaderKV("X-Tidepool-Server-Name", *provider.NameOutput), VerifyHeaderKV("X-Tidepool-Server-Secret", serverSecret), VerifyBody(nil), From d075b0498cef7597941efacd063875a03aace0ec Mon Sep 17 00:00:00 2001 From: Todd Kazakov Date: Wed, 15 Mar 2023 15:43:41 +0200 Subject: [PATCH 02/24] Add ability to disable index creation on startup with an env variable Allow disabling the user events handler Add error context Fix imports --- auth/service/service/service.go | 19 +++++++++++++------ blob/service/service.go | 19 +++++++++++++------ client/config.go | 3 ++- client/config_test.go | 2 +- data/service/service/standard.go | 20 ++++++++++++++------ events/events.go | 25 +++++++++++++++++++++++++ platform/config_test.go | 2 +- store/structured/mongo/config.go | 19 ++++++++++--------- store/structured/mongo/repository.go | 12 +++++++++++- store/structured/mongo/store.go | 5 ++++- 10 files changed, 94 insertions(+), 32 deletions(-) diff --git a/auth/service/service/service.go b/auth/service/service/service.go index c7202e4e39..4decb54dbb 100644 --- a/auth/service/service/service.go +++ b/auth/service/service/service.go @@ -114,7 +114,7 @@ func (s *Service) Initialize(provider application.Provider) error { if err := s.initializePartnerSecrets(); err != nil { return err } - return s.initializeUserEventsHandler() + return s.initializeUserEventsHandler(provider) } func (s *Service) Terminate() { @@ -417,13 +417,20 @@ func (s *Service) terminateAuthClient() { } } -func (s *Service) initializeUserEventsHandler() error { +func (s *Service) initializeUserEventsHandler(provider application.Provider) error { s.Logger().Debug("Initializing user events handler") - ctx := logInternal.NewContextWithLogger(context.Background(), s.Logger()) - handler := authEvents.NewUserDataDeletionHandler(ctx, s.authClient) - handlers := []eventsCommon.EventHandler{handler} - runner := events.NewRunner(handlers) + var runner events.Runner + + configReporter := provider.ConfigReporter().WithScopes("user", "events", "handler") + if configReporter.GetWithDefault("disable", "") != "true" { + ctx := logInternal.NewContextWithLogger(context.Background(), s.Logger()) + handler := authEvents.NewUserDataDeletionHandler(ctx, s.authClient) + handlers := []eventsCommon.EventHandler{handler} + runner = events.NewRunner(handlers) + } else { + runner = events.NewNoopRunner() + } if err := runner.Initialize(); err != nil { return errors.Wrap(err, "unable to initialize events runner") diff --git a/blob/service/service.go b/blob/service/service.go index a8381e2bd4..ee99021c65 100644 --- a/blob/service/service.go +++ b/blob/service/service.go @@ -69,7 +69,7 @@ func (s *Service) Initialize(provider application.Provider) error { if err := s.initializeBlobClient(); err != nil { return err } - if err := s.initializeUserEventsHandler(); err != nil { + if err := s.initializeUserEventsHandler(provider); err != nil { return err } return s.initializeRouter() @@ -211,13 +211,20 @@ func (s *Service) terminateDeviceLogsUnstructuredStore() { } } -func (s *Service) initializeUserEventsHandler() error { +func (s *Service) initializeUserEventsHandler(provider application.Provider) error { s.Logger().Debug("Initializing user events handler") - ctx := logInternal.NewContextWithLogger(context.Background(), s.Logger()) - handler := blobEvents.NewUserDataDeletionHandler(ctx, s.blobClient) - handlers := []eventsCommon.EventHandler{handler} - runner := events.NewRunner(handlers) + var runner events.Runner + + configReporter := provider.ConfigReporter().WithScopes("user", "events", "handler") + if configReporter.GetWithDefault("disable", "") != "true" { + ctx := logInternal.NewContextWithLogger(context.Background(), s.Logger()) + handler := blobEvents.NewUserDataDeletionHandler(ctx, s.blobClient) + handlers := []eventsCommon.EventHandler{handler} + runner = events.NewRunner(handlers) + } else { + runner = events.NewNoopRunner() + } if err := runner.Initialize(); err != nil { return errors.Wrap(err, "unable to initialize events runner") diff --git a/client/config.go b/client/config.go index 74bdd29dcc..c43574fd85 100644 --- a/client/config.go +++ b/client/config.go @@ -1,6 +1,7 @@ package client import ( + "fmt" "net/url" "github.com/kelseyhightower/envconfig" @@ -36,7 +37,7 @@ func (c *Config) Validate() error { if c.Address == "" { return errors.New("address is missing") } else if _, err := url.Parse(c.Address); err != nil { - return errors.New("address is invalid") + return fmt.Errorf("address is invalid: %w", err) } return nil diff --git a/client/config_test.go b/client/config_test.go index 4c22fbcf29..62090aca71 100644 --- a/client/config_test.go +++ b/client/config_test.go @@ -86,7 +86,7 @@ var _ = Describe("Config", func() { It("returns an error if the address is not a parseable URL", func() { cfg.Address = "Not%Parseable" - Expect(cfg.Validate()).To(MatchError("address is invalid")) + Expect(cfg.Validate()).To(MatchError("address is invalid: parse \"Not%Parseable\": invalid URL escape \"%Pa\"")) }) It("returns success", func() { diff --git a/data/service/service/standard.go b/data/service/service/standard.go index 80911f4b20..cea18b84f5 100644 --- a/data/service/service/standard.go +++ b/data/service/service/standard.go @@ -87,7 +87,7 @@ func (s *Standard) Initialize(provider application.Provider) error { if err := s.initializeDataSourceClient(); err != nil { return err } - if err := s.initializeUserEventsHandler(); err != nil { + if err := s.initializeUserEventsHandler(provider); err != nil { return err } if err := s.initializeAPI(); err != nil { @@ -404,14 +404,22 @@ func (s *Standard) initializeServer() error { return nil } -func (s *Standard) initializeUserEventsHandler() error { +func (s *Standard) initializeUserEventsHandler(provider application.Provider) error { s.Logger().Debug("Initializing user events handler") sarama.Logger = log.New(os.Stdout, "SARAMA ", log.LstdFlags|log.Lshortfile) - ctx := logInternal.NewContextWithLogger(context.Background(), s.Logger()) - handler := dataEvents.NewUserDataDeletionHandler(ctx, s.dataStore, s.dataSourceStructuredStore) - handlers := []eventsCommon.EventHandler{handler} - runner := events.NewRunner(handlers) + var runner events.Runner + + configReporter := provider.ConfigReporter().WithScopes("user", "events", "handler") + if configReporter.GetWithDefault("disable", "") != "true" { + ctx := logInternal.NewContextWithLogger(context.Background(), s.Logger()) + handler := dataEvents.NewUserDataDeletionHandler(ctx, s.dataStore, s.dataSourceStructuredStore) + handlers := []eventsCommon.EventHandler{handler} + runner = events.NewRunner(handlers) + } else { + runner = events.NewNoopRunner() + } + if err := runner.Initialize(); err != nil { return errors.Wrap(err, "unable to initialize user events handler runner") } diff --git a/events/events.go b/events/events.go index e1d3129300..240850c756 100644 --- a/events/events.go +++ b/events/events.go @@ -47,3 +47,28 @@ func (r *runner) Terminate() error { } return nil } + +type noopRunner struct { + terminate chan struct{} +} + +func (n *noopRunner) Initialize() error { + n.terminate = make(chan struct{}, 0) + return nil +} + +func (n *noopRunner) Run() error { + <-n.terminate + return nil +} + +func (n *noopRunner) Terminate() error { + n.terminate <- struct{}{} + return nil +} + +var _ Runner = &noopRunner{} + +func NewNoopRunner() Runner { + return &noopRunner{} +} diff --git a/platform/config_test.go b/platform/config_test.go index edba20a423..841e15294a 100644 --- a/platform/config_test.go +++ b/platform/config_test.go @@ -110,7 +110,7 @@ var _ = Describe("Config", func() { It("returns an error if the address is not a parseable URL", func() { cfg.Address = "Not%Parseable" - Expect(cfg.Validate()).To(MatchError("address is invalid")) + Expect(cfg.Validate()).To(MatchError("address is invalid: parse \"Not%Parseable\": invalid URL escape \"%Pa\"")) }) It("returns success", func() { diff --git a/store/structured/mongo/config.go b/store/structured/mongo/config.go index 72bdf08031..8212f760d1 100644 --- a/store/structured/mongo/config.go +++ b/store/structured/mongo/config.go @@ -28,15 +28,16 @@ func LoadConfig() (*Config, error) { // Config describe parameters need to make a connection to a Mongo database type Config struct { - Scheme string `json:"scheme" envconfig:"TIDEPOOL_STORE_SCHEME"` - Addresses []string `json:"addresses" envconfig:"TIDEPOOL_STORE_ADDRESSES" required:"true"` - TLS bool `json:"tls" envconfig:"TIDEPOOL_STORE_TLS" default:"true"` - Database string `json:"database" envconfig:"TIDEPOOL_STORE_DATABASE" required:"true"` - CollectionPrefix string `json:"collectionPrefix" envconfig:"TIDEPOOL_STORE_COLLECTION_PREFIX"` - Username *string `json:"-" envconfig:"TIDEPOOL_STORE_USERNAME"` - Password *string `json:"-" envconfig:"TIDEPOOL_STORE_PASSWORD"` - Timeout time.Duration `json:"timeout" envconfig:"TIDEPOOL_STORE_TIMEOUT" default:"60s"` - OptParams *string `json:"optParams" envconfig:"TIDEPOOL_STORE_OPT_PARAMS"` + Scheme string `json:"scheme" envconfig:"TIDEPOOL_STORE_SCHEME"` + Addresses []string `json:"addresses" envconfig:"TIDEPOOL_STORE_ADDRESSES" required:"true"` + TLS bool `json:"tls" envconfig:"TIDEPOOL_STORE_TLS" default:"true"` + Database string `json:"database" envconfig:"TIDEPOOL_STORE_DATABASE" required:"true"` + CollectionPrefix string `json:"collectionPrefix" envconfig:"TIDEPOOL_STORE_COLLECTION_PREFIX"` + Username *string `json:"-" envconfig:"TIDEPOOL_STORE_USERNAME"` + Password *string `json:"-" envconfig:"TIDEPOOL_STORE_PASSWORD"` + Timeout time.Duration `json:"timeout" envconfig:"TIDEPOOL_STORE_TIMEOUT" default:"60s"` + OptParams *string `json:"optParams" envconfig:"TIDEPOOL_STORE_OPT_PARAMS"` + DisableIndexCreation bool `json:"disableIndexCreation" envconfig:"TIDEPOOL_DISABLE_INDEX_CREATION"` } // AsConnectionString constructs a MongoDB connection string from a Config diff --git a/store/structured/mongo/repository.go b/store/structured/mongo/repository.go index 274d9217db..16f2ba79f2 100644 --- a/store/structured/mongo/repository.go +++ b/store/structured/mongo/repository.go @@ -15,15 +15,25 @@ import ( type Repository struct { *mongo.Collection + config RepositoryConfig } -func NewRepository(collection *mongo.Collection) *Repository { +type RepositoryConfig struct { + DisableIndexCreation bool +} + +func NewRepository(collection *mongo.Collection, config RepositoryConfig) *Repository { return &Repository{ collection, + config, } } func (r *Repository) CreateAllIndexes(ctx context.Context, indexes []mongo.IndexModel) error { + if r.config.DisableIndexCreation { + return nil + } + if ctx == nil { ctx = context.Background() } diff --git a/store/structured/mongo/store.go b/store/structured/mongo/store.go index 93ef92d1e6..584373bfc9 100644 --- a/store/structured/mongo/store.go +++ b/store/structured/mongo/store.go @@ -62,7 +62,10 @@ func AppendLifecycleHooksToStore(store *Store, lifecycle fx.Lifecycle) { } func (o *Store) GetRepository(collection string) *Repository { - return NewRepository(o.GetCollection(collection)) + config := RepositoryConfig{ + DisableIndexCreation: o.config.DisableIndexCreation, + } + return NewRepository(o.GetCollection(collection), config) } func (o *Store) GetCollection(collection string) *mongoDriver.Collection { From aed9c7069eaab7bdc97150fad345225c13caa896 Mon Sep 17 00:00:00 2001 From: lostlevels Date: Fri, 13 Sep 2024 14:49:14 -0700 Subject: [PATCH 03/24] Create new deviceData indexes, hint, and remove "type" field from indexes that don't need it. --- data/store/mongo/mongo_data.go | 4 -- data/store/mongo/mongo_data_set.go | 24 ++-------- data/store/mongo/mongo_datum.go | 73 ++++++++++++++++++++---------- data/store/mongo/mongo_test.go | 30 +++++++----- 4 files changed, 71 insertions(+), 60 deletions(-) diff --git a/data/store/mongo/mongo_data.go b/data/store/mongo/mongo_data.go index 4076a968af..0818cd70c6 100644 --- a/data/store/mongo/mongo_data.go +++ b/data/store/mongo/mongo_data.go @@ -81,14 +81,12 @@ func (d *DataRepository) DeleteDataSet(ctx context.Context, dataSet *upload.Uplo selector := bson.M{ "_userId": dataSet.UserID, "uploadId": dataSet.UploadID, - "type": bson.M{"$ne": "upload"}, } removeInfo, err = d.DatumRepository.DeleteMany(ctx, selector) if err == nil { selector = bson.M{ "_userId": dataSet.UserID, "uploadId": dataSet.UploadID, - "type": "upload", "deletedTime": bson.M{"$exists": false}, "deletedUserId": bson.M{"$exists": false}, } @@ -136,7 +134,6 @@ func (d *DataRepository) DeleteOtherDataSetData(ctx context.Context, dataSet *up "_userId": dataSet.UserID, "deviceId": *dataSet.DeviceID, "uploadId": bson.M{"$ne": dataSet.UploadID}, - "type": bson.M{"$ne": "upload"}, } removeInfo, err = d.DatumRepository.DeleteMany(ctx, selector) if err == nil { @@ -144,7 +141,6 @@ func (d *DataRepository) DeleteOtherDataSetData(ctx context.Context, dataSet *up "_userId": dataSet.UserID, "deviceId": *dataSet.DeviceID, "uploadId": bson.M{"$ne": dataSet.UploadID}, - "type": "upload", "deletedTime": bson.M{"$exists": false}, "deletedUserId": bson.M{"$exists": false}, } diff --git a/data/store/mongo/mongo_data_set.go b/data/store/mongo/mongo_data_set.go index 82d2e8c963..7688dda67f 100644 --- a/data/store/mongo/mongo_data_set.go +++ b/data/store/mongo/mongo_data_set.go @@ -34,22 +34,11 @@ func (d *DataSetRepository) EnsureIndexes() error { Keys: bson.D{ {Key: "_userId", Value: 1}, {Key: "_active", Value: 1}, - {Key: "type", Value: 1}, {Key: "time", Value: -1}, }, Options: options.Index(). SetName("UserIdTypeWeighted_v2"), }, - { - Keys: bson.D{ - {Key: "origin.id", Value: 1}, - {Key: "type", Value: 1}, - {Key: "deletedTime", Value: -1}, - {Key: "_active", Value: 1}, - }, - Options: options.Index(). - SetName("OriginId"), - }, { Keys: bson.D{ {Key: "uploadId", Value: 1}, @@ -61,7 +50,6 @@ func (d *DataSetRepository) EnsureIndexes() error { { Keys: bson.D{ {Key: "uploadId", Value: 1}, - {Key: "type", Value: 1}, {Key: "deletedTime", Value: -1}, {Key: "_active", Value: 1}, }, @@ -72,7 +60,6 @@ func (d *DataSetRepository) EnsureIndexes() error { Keys: bson.D{ {Key: "_userId", Value: 1}, {Key: "client.name", Value: 1}, - {Key: "type", Value: 1}, {Key: "createdTime", Value: -1}, }, Options: options.Index(). @@ -85,7 +72,6 @@ func (d *DataSetRepository) EnsureIndexes() error { Keys: bson.D{ {Key: "_userId", Value: 1}, {Key: "deviceId", Value: 1}, - {Key: "type", Value: 1}, {Key: "createdTime", Value: -1}, }, Options: options.Index(). @@ -267,7 +253,6 @@ func (d *DataSetRepository) ListUserDataSets(ctx context.Context, userID string, selector := bson.M{ "_active": true, "_userId": userID, - "type": "upload", } if filter.ClientName != nil { selector["client.name"] = *filter.ClientName @@ -321,7 +306,6 @@ func (d *DataSetRepository) GetDataSetsForUserByID(ctx context.Context, userID s selector := bson.M{ "_active": true, "_userId": userID, - "type": "upload", } if !filter.Deleted { selector["deletedTime"] = bson.M{"$exists": false} @@ -330,14 +314,14 @@ func (d *DataSetRepository) GetDataSetsForUserByID(ctx context.Context, userID s SetSort(bson.M{"createdTime": -1}) cursor, err := d.Find(ctx, selector, opts) - loggerFields := log.Fields{"userId": userID, "dataSetsCount": len(dataSets), "duration": time.Since(now) / time.Microsecond} - log.LoggerFromContext(ctx).WithFields(loggerFields).WithError(err).Debug("GetDataSetsForUserByID") - if err != nil { return nil, errors.Wrap(err, "unable to get data sets for user by id") } - if err = cursor.All(ctx, &dataSets); err != nil { + err = cursor.All(ctx, &dataSets) + loggerFields := log.Fields{"userId": userID, "dataSetsCount": len(dataSets), "duration": time.Since(now) / time.Microsecond} + log.LoggerFromContext(ctx).WithFields(loggerFields).WithError(err).Debug("GetDataSetsForUserByID") + if err != nil { return nil, errors.Wrap(err, "unable to decode data sets for user by id") } diff --git a/data/store/mongo/mongo_datum.go b/data/store/mongo/mongo_datum.go index dc78b26175..323f5e29c9 100644 --- a/data/store/mongo/mongo_datum.go +++ b/data/store/mongo/mongo_datum.go @@ -73,13 +73,36 @@ func (d *DatumRepository) EnsureIndexes() error { }, { Keys: bson.D{ - {Key: "origin.id", Value: 1}, + {Key: "_userId", Value: 1}, + {Key: "_active", Value: 1}, {Key: "type", Value: 1}, + {Key: "modifiedTime", Value: 1}, + {Key: "time", Value: 1}, + }, + // temp name because that's what I have it as tested. + Options: options.Index(). + SetName("TestUserIdActiveTypeModifiedTimeTime"). + SetPartialFilterExpression(bson.D{ + { + Key: "time", + Value: bson.D{ + {Key: "$gt", Value: lowerTimeBound}, + }, + }, + }), + }, + { + Keys: bson.D{ + {Key: "_userId", Value: 1}, + {Key: "origin.id", Value: 1}, {Key: "deletedTime", Value: -1}, {Key: "_active", Value: 1}, }, Options: options.Index(). - SetName("OriginId"), + SetPartialFilterExpression(bson.D{ + {Key: "origin.id", Value: bson.D{{Key: "$exists", Value: true}}}, + }). + SetName("UserIdOriginId"), }, { Keys: bson.D{ @@ -95,8 +118,6 @@ func (d *DatumRepository) EnsureIndexes() error { Keys: bson.D{ {Key: "_userId", Value: 1}, {Key: "deviceId", Value: 1}, - {Key: "type", Value: 1}, - {Key: "_active", Value: 1}, {Key: "_deduplicator.hash", Value: 1}, }, Options: options.Index(). @@ -105,7 +126,7 @@ func (d *DatumRepository) EnsureIndexes() error { {Key: "_deduplicator.hash", Value: bson.D{{Key: "$exists", Value: true}}}, {Key: "deviceId", Value: bson.D{{Key: "$exists", Value: true}}}, }). - SetName("DeduplicatorHash"), + SetName("DeduplicatorHashNoType"), }, }) } @@ -135,7 +156,8 @@ func (d *DatumRepository) CreateDataSetData(ctx context.Context, dataSet *upload datum.SetDataSetID(dataSet.UploadID) datum.SetCreatedTime(×tamp) datum.SetModifiedTime(×tamp) - datum.SetModifiedTime(×tamp) + } + for _, datum := range dataSetData { insertData = append(insertData, mongo.NewInsertOneModel().SetDocument(datum)) } @@ -170,7 +192,6 @@ func (d *DatumRepository) ActivateDataSetData(ctx context.Context, dataSet *uplo selector["_userId"] = dataSet.UserID selector["uploadId"] = dataSet.UploadID - selector["type"] = bson.M{"$ne": "upload"} selector["_active"] = false selector["deletedTime"] = bson.M{"$exists": false} set := bson.M{ @@ -210,7 +231,6 @@ func (d *DatumRepository) ArchiveDataSetData(ctx context.Context, dataSet *uploa selector["_userId"] = dataSet.UserID selector["uploadId"] = dataSet.UploadID - selector["type"] = bson.M{"$ne": "upload"} selector["_active"] = true selector["deletedTime"] = bson.M{"$exists": false} set := bson.M{ @@ -224,7 +244,7 @@ func (d *DatumRepository) ArchiveDataSetData(ctx context.Context, dataSet *uploa } opts := options.Update() if hasOriginID { - opts.SetHint("OriginId") + opts.SetHint("UserIdOriginId") } changeInfo, err := d.UpdateMany(ctx, selector, d.ConstructUpdate(set, unset), opts) if err != nil { @@ -254,7 +274,6 @@ func (d *DatumRepository) DeleteDataSetData(ctx context.Context, dataSet *upload selector["_userId"] = dataSet.UserID selector["uploadId"] = dataSet.UploadID - selector["type"] = bson.M{"$ne": "upload"} selector["deletedTime"] = bson.M{"$exists": false} set := bson.M{ "_active": false, @@ -269,7 +288,7 @@ func (d *DatumRepository) DeleteDataSetData(ctx context.Context, dataSet *upload } opts := options.Update() if hasOriginID { - opts.SetHint("OriginId") + opts.SetHint("UserIdOriginId") } changeInfo, err := d.UpdateMany(ctx, selector, d.ConstructUpdate(set, unset), opts) if err != nil { @@ -298,11 +317,11 @@ func (d *DatumRepository) DestroyDeletedDataSetData(ctx context.Context, dataSet selector["_userId"] = dataSet.UserID selector["uploadId"] = dataSet.UploadID - selector["type"] = bson.M{"$ne": "upload"} + // selector["type"] = bson.M{"$ne": "upload"} selector["deletedTime"] = bson.M{"$exists": true} opts := options.Delete() if hasOriginID { - opts.SetHint("OriginId") + opts.SetHint("UserIdOriginId") } changeInfo, err := d.DeleteMany(ctx, selector, opts) if err != nil { @@ -331,7 +350,6 @@ func (d *DatumRepository) DestroyDataSetData(ctx context.Context, dataSet *uploa selector["_userId"] = dataSet.UserID selector["uploadId"] = dataSet.UploadID - selector["type"] = bson.M{"$ne": "upload"} changeInfo, err := d.DeleteMany(ctx, selector) if err != nil { logger.WithError(err).Error("Unable to destroy data set data") @@ -361,7 +379,6 @@ func (d *DatumRepository) ArchiveDeviceDataUsingHashesFromDataSet(ctx context.Co selector := bson.M{ "_userId": dataSet.UserID, "uploadId": dataSet.UploadID, - "type": bson.M{"$ne": "upload"}, } hashes, err := d.Distinct(ctx, "_deduplicator.hash", selector) @@ -369,7 +386,6 @@ func (d *DatumRepository) ArchiveDeviceDataUsingHashesFromDataSet(ctx context.Co selector = bson.M{ "_userId": dataSet.UserID, "deviceId": *dataSet.DeviceID, - "type": bson.M{"$ne": "upload"}, "_active": true, "_deduplicator.hash": bson.M{"$in": hashes}, } @@ -380,7 +396,8 @@ func (d *DatumRepository) ArchiveDeviceDataUsingHashesFromDataSet(ctx context.Co "modifiedTime": timestamp, } unset := bson.M{} - updateInfo, err = d.UpdateMany(ctx, selector, d.ConstructUpdate(set, unset)) + opts := options.Update().SetHint("DeduplicatorHashNoType") + updateInfo, err = d.UpdateMany(ctx, selector, d.ConstructUpdate(set, unset), opts) } loggerFields := log.Fields{"userId": dataSet.UserID, "deviceId": *dataSet.DeviceID, "updateInfo": updateInfo, "duration": time.Since(now) / time.Microsecond} @@ -410,7 +427,6 @@ func (d *DatumRepository) UnarchiveDeviceDataUsingHashesFromDataSet(ctx context. { "$match": bson.M{ "uploadId": dataSet.UploadID, - "type": bson.M{"$ne": "upload"}, }, }, { @@ -700,11 +716,12 @@ func (d *DatumRepository) getTimeRange(ctx context.Context, userId string, typ [ func (d *DatumRepository) populateLastUpload(ctx context.Context, userId string, typ []string, status *data.UserDataStatus) (err error) { // get latest modified record + timeMin := status.FirstData selector := bson.M{ "_userId": userId, "_active": bson.M{"$in": bson.A{true, false}}, "time": bson.M{ - "$gte": status.FirstData, + "$gte": timeMin, "$lte": status.LastData, }, } @@ -715,8 +732,10 @@ func (d *DatumRepository) populateLastUpload(ctx context.Context, userId string, selector["type"] = bson.M{"$in": typ} } - findOptions := options.Find() - findOptions.SetHint("UserIdActiveTypeTimeModifiedTime") + findOptions := options.Find().SetProjection(bson.M{"_id": 0, "modifiedTime": 1, "createdTime": 1}) + if lowerTimeBound, err := time.Parse(time.RFC3339, LowerTimeIndexRaw); err == nil && timeMin.After(lowerTimeBound) { + findOptions.SetHint("TestUserIdActiveTypeModifiedTimeTime") + } findOptions.SetLimit(1) findOptions.SetSort(bson.D{{Key: "modifiedTime", Value: -1}}) @@ -747,11 +766,12 @@ func (d *DatumRepository) populateLastUpload(ctx context.Context, userId string, func (d *DatumRepository) populateEarliestModified(ctx context.Context, userId string, typ []string, status *data.UserDataStatus) (err error) { // get earliest modified record which is newer than LastUpdated + timeMin := status.FirstData selector := bson.M{ "_userId": userId, "_active": bson.M{"$in": bson.A{true, false}}, "time": bson.M{ - "$gte": status.FirstData, + "$gte": timeMin, "$lte": status.LastData, }, } @@ -764,7 +784,8 @@ func (d *DatumRepository) populateEarliestModified(ctx context.Context, userId s findOptions := options.Find() findOptions.SetLimit(1) - findOptions.SetSort(bson.D{{Key: "time", Value: 1}}) + findOptions.SetSort(bson.D{{Key: "time", Value: 1}}). + SetProjection(bson.M{"_id": 0, "time": 1}) // this skips using modifiedTime on fresh calculations as it may cause trouble with initial calculation of summaries // for users with only data old enough to not have a modifiedTime, which would be excluded by this. @@ -773,7 +794,10 @@ func (d *DatumRepository) populateEarliestModified(ctx context.Context, userId s selector["modifiedTime"] = bson.M{ "$gt": status.LastUpdated, } - findOptions.SetHint("UserIdActiveTypeTimeModifiedTime") + if lowerTimeBound, err := time.Parse(time.RFC3339, LowerTimeIndexRaw); err == nil && timeMin.After(lowerTimeBound) { + // has blocking sort, but more selective so usually performs better. + findOptions.SetHint("TestUserIdActiveTypeModifiedTimeTime") + } } var cursor *mongo.Cursor @@ -861,6 +885,7 @@ func (d *DatumRepository) DistinctUserIDs(ctx context.Context, typ []string) ([] pastCutoff := time.Now().AddDate(0, -23, -20).UTC() futureCutoff := time.Now().AddDate(0, 0, 1).UTC() + // TODO: maybe reevaluate, scatters / broadcasts on sharded cluster selector := bson.M{ "_userId": bson.M{"$ne": -1111}, "_active": true, diff --git a/data/store/mongo/mongo_test.go b/data/store/mongo/mongo_test.go index a0a81e89d6..c7c1f94be6 100644 --- a/data/store/mongo/mongo_test.go +++ b/data/store/mongo/mongo_test.go @@ -325,16 +325,26 @@ var _ = Describe("Mongo", func() { }), }), MatchFields(IgnoreExtras, Fields{ - "Key": Equal(storeStructuredMongoTest.MakeKeySlice("origin.id", "type", "-deletedTime", "_active")), - "Name": Equal("OriginId"), + "Key": Equal(storeStructuredMongoTest.MakeKeySlice("_userId", "_active", "type", "modifiedTime", "time")), + "Name": Equal("TestUserIdActiveTypeModifiedTimeTime"), + "PartialFilterExpression": Equal(bson.D{ + {Key: "time", Value: bson.D{{Key: "$gt", Value: primitive.NewDateTimeFromTime(lowerTimeIndex)}}}, + }), + }), + MatchFields(IgnoreExtras, Fields{ + "Key": Equal(storeStructuredMongoTest.MakeKeySlice("_userId", "origin.id", "-deletedTime", "_active")), + "Name": Equal("UserIdOriginId"), + "PartialFilterExpression": Equal(bson.D{ + {Key: "origin.id", Value: bson.D{{Key: "$exists", Value: true}}}, + }), }), MatchFields(IgnoreExtras, Fields{ "Key": Equal(storeStructuredMongoTest.MakeKeySlice("uploadId", "type", "-deletedTime", "_active")), "Name": Equal("UploadId"), }), MatchFields(IgnoreExtras, Fields{ - "Key": Equal(storeStructuredMongoTest.MakeKeySlice("_userId", "deviceId", "type", "_active", "_deduplicator.hash")), - "Name": Equal("DeduplicatorHash"), + "Key": Equal(storeStructuredMongoTest.MakeKeySlice("_userId", "deviceId", "_deduplicator.hash")), + "Name": Equal("DeduplicatorHashNoType"), "PartialFilterExpression": Equal(bson.D{ {Key: "_active", Value: true}, {Key: "_deduplicator.hash", Value: bson.D{{Key: "$exists", Value: true}}}, @@ -357,15 +367,11 @@ var _ = Describe("Mongo", func() { "Key": Equal(storeStructuredMongoTest.MakeKeySlice("_id")), }), MatchFields(IgnoreExtras, Fields{ - "Key": Equal(storeStructuredMongoTest.MakeKeySlice("_userId", "_active", "type", "-time")), + "Key": Equal(storeStructuredMongoTest.MakeKeySlice("_userId", "_active", "-time")), "Name": Equal("UserIdTypeWeighted_v2"), }), MatchFields(IgnoreExtras, Fields{ - "Key": Equal(storeStructuredMongoTest.MakeKeySlice("origin.id", "type", "-deletedTime", "_active")), - "Name": Equal("OriginId"), - }), - MatchFields(IgnoreExtras, Fields{ - "Key": Equal(storeStructuredMongoTest.MakeKeySlice("uploadId", "type", "-deletedTime", "_active")), + "Key": Equal(storeStructuredMongoTest.MakeKeySlice("uploadId", "-deletedTime", "_active")), "Name": Equal("UploadId"), }), MatchFields(IgnoreExtras, Fields{ @@ -374,14 +380,14 @@ var _ = Describe("Mongo", func() { "Name": Equal("UniqueUploadId"), }), MatchFields(IgnoreExtras, Fields{ - "Key": Equal(storeStructuredMongoTest.MakeKeySlice("_userId", "client.name", "type", "-createdTime")), + "Key": Equal(storeStructuredMongoTest.MakeKeySlice("_userId", "client.name", "-createdTime")), "Name": Equal("ListUserDataSets"), "PartialFilterExpression": Equal(bson.D{ {Key: "_active", Value: true}, }), }), MatchFields(IgnoreExtras, Fields{ - "Key": Equal(storeStructuredMongoTest.MakeKeySlice("_userId", "deviceId", "type", "-createdTime")), + "Key": Equal(storeStructuredMongoTest.MakeKeySlice("_userId", "deviceId", "-createdTime")), "Name": Equal("ListUserDataSetsDeviceId"), "PartialFilterExpression": Equal(bson.D{ {Key: "_active", Value: true}, From 0b173d943ef16480606260fb16251d5f64adb73c Mon Sep 17 00:00:00 2001 From: lostlevels Date: Wed, 15 Jan 2025 14:03:18 -0800 Subject: [PATCH 04/24] Match indexes to production in shadowed cluster. --- data/store/mongo/mongo_datum.go | 24 +++++++++++++++++++----- data/store/mongo/mongo_test.go | 10 +++++++--- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/data/store/mongo/mongo_datum.go b/data/store/mongo/mongo_datum.go index 323f5e29c9..8ed421f7db 100644 --- a/data/store/mongo/mongo_datum.go +++ b/data/store/mongo/mongo_datum.go @@ -52,6 +52,17 @@ func (d *DatumRepository) EnsureIndexes() error { Options: options.Index(). SetName("UserIdTypeWeighted_v2"), }, + { + Keys: bson.D{ + {Key: "_userId", Value: 1}, + {Key: "type", Value: 1}, + {Key: "time", Value: 1}, + {Key: "_active", Value: 1}, + {Key: "modifiedTime", Value: 1}, + }, + Options: options.Index(). + SetName("ShardKeyIndex"), + }, { Keys: bson.D{ {Key: "_userId", Value: 1}, @@ -81,7 +92,7 @@ func (d *DatumRepository) EnsureIndexes() error { }, // temp name because that's what I have it as tested. Options: options.Index(). - SetName("TestUserIdActiveTypeModifiedTimeTime"). + SetName("UserIdActiveTypeModifiedTimeTime"). SetPartialFilterExpression(bson.D{ { Key: "time", @@ -118,6 +129,8 @@ func (d *DatumRepository) EnsureIndexes() error { Keys: bson.D{ {Key: "_userId", Value: 1}, {Key: "deviceId", Value: 1}, + {Key: "type", Value: 1}, + {Key: "_active", Value: 1}, {Key: "_deduplicator.hash", Value: 1}, }, Options: options.Index(). @@ -126,7 +139,7 @@ func (d *DatumRepository) EnsureIndexes() error { {Key: "_deduplicator.hash", Value: bson.D{{Key: "$exists", Value: true}}}, {Key: "deviceId", Value: bson.D{{Key: "$exists", Value: true}}}, }). - SetName("DeduplicatorHashNoType"), + SetName("DeduplicatorHash"), }, }) } @@ -396,7 +409,7 @@ func (d *DatumRepository) ArchiveDeviceDataUsingHashesFromDataSet(ctx context.Co "modifiedTime": timestamp, } unset := bson.M{} - opts := options.Update().SetHint("DeduplicatorHashNoType") + opts := options.Update() updateInfo, err = d.UpdateMany(ctx, selector, d.ConstructUpdate(set, unset), opts) } @@ -691,6 +704,7 @@ func (d *DatumRepository) getTimeRange(ctx context.Context, userId string, typ [ } findOptions := options.Find() + findOptions.SetProjection(bson.M{"_id": 0, "time": 1}) findOptions.SetSort(bson.D{{Key: "time", Value: -1}}) findOptions.SetLimit(1) @@ -734,7 +748,7 @@ func (d *DatumRepository) populateLastUpload(ctx context.Context, userId string, findOptions := options.Find().SetProjection(bson.M{"_id": 0, "modifiedTime": 1, "createdTime": 1}) if lowerTimeBound, err := time.Parse(time.RFC3339, LowerTimeIndexRaw); err == nil && timeMin.After(lowerTimeBound) { - findOptions.SetHint("TestUserIdActiveTypeModifiedTimeTime") + findOptions.SetHint("UserIdActiveTypeModifiedTimeTime") } findOptions.SetLimit(1) findOptions.SetSort(bson.D{{Key: "modifiedTime", Value: -1}}) @@ -796,7 +810,7 @@ func (d *DatumRepository) populateEarliestModified(ctx context.Context, userId s } if lowerTimeBound, err := time.Parse(time.RFC3339, LowerTimeIndexRaw); err == nil && timeMin.After(lowerTimeBound) { // has blocking sort, but more selective so usually performs better. - findOptions.SetHint("TestUserIdActiveTypeModifiedTimeTime") + findOptions.SetHint("UserIdActiveTypeModifiedTimeTime") } } diff --git a/data/store/mongo/mongo_test.go b/data/store/mongo/mongo_test.go index c7c1f94be6..e5c891364d 100644 --- a/data/store/mongo/mongo_test.go +++ b/data/store/mongo/mongo_test.go @@ -317,6 +317,10 @@ var _ = Describe("Mongo", func() { "Key": Equal(storeStructuredMongoTest.MakeKeySlice("_userId", "_active", "type", "-time")), "Name": Equal("UserIdTypeWeighted_v2"), }), + MatchFields(IgnoreExtras, Fields{ + "Key": Equal(storeStructuredMongoTest.MakeKeySlice("_userId", "type", "time", "_active", "modifiedTime")), + "Name": Equal("ShardKeyIndex"), + }), MatchFields(IgnoreExtras, Fields{ "Key": Equal(storeStructuredMongoTest.MakeKeySlice("_userId", "_active", "type", "time", "modifiedTime")), "Name": Equal("UserIdActiveTypeTimeModifiedTime"), @@ -326,7 +330,7 @@ var _ = Describe("Mongo", func() { }), MatchFields(IgnoreExtras, Fields{ "Key": Equal(storeStructuredMongoTest.MakeKeySlice("_userId", "_active", "type", "modifiedTime", "time")), - "Name": Equal("TestUserIdActiveTypeModifiedTimeTime"), + "Name": Equal("UserIdActiveTypeModifiedTimeTime"), "PartialFilterExpression": Equal(bson.D{ {Key: "time", Value: bson.D{{Key: "$gt", Value: primitive.NewDateTimeFromTime(lowerTimeIndex)}}}, }), @@ -343,8 +347,8 @@ var _ = Describe("Mongo", func() { "Name": Equal("UploadId"), }), MatchFields(IgnoreExtras, Fields{ - "Key": Equal(storeStructuredMongoTest.MakeKeySlice("_userId", "deviceId", "_deduplicator.hash")), - "Name": Equal("DeduplicatorHashNoType"), + "Key": Equal(storeStructuredMongoTest.MakeKeySlice("_userId", "deviceId", "type", "_active", "_deduplicator.hash")), + "Name": Equal("DeduplicatorHash"), "PartialFilterExpression": Equal(bson.D{ {Key: "_active", Value: true}, {Key: "_deduplicator.hash", Value: bson.D{{Key: "$exists", Value: true}}}, From 0b6b2b564fbff725f2bdb16b2f64163792c18d5e Mon Sep 17 00:00:00 2001 From: lostlevels Date: Wed, 15 Jan 2025 15:18:11 -0800 Subject: [PATCH 05/24] Re-add superfluous "type: {$ne: 'upload'}" query selector to match prod. --- data/store/mongo/mongo_data.go | 2 ++ data/store/mongo/mongo_data_set.go | 6 ++++++ data/store/mongo/mongo_datum.go | 2 ++ data/store/mongo/mongo_test.go | 8 ++++---- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/data/store/mongo/mongo_data.go b/data/store/mongo/mongo_data.go index 0818cd70c6..e8d1484f2e 100644 --- a/data/store/mongo/mongo_data.go +++ b/data/store/mongo/mongo_data.go @@ -81,6 +81,7 @@ func (d *DataRepository) DeleteDataSet(ctx context.Context, dataSet *upload.Uplo selector := bson.M{ "_userId": dataSet.UserID, "uploadId": dataSet.UploadID, + "type": bson.M{"$ne": "upload"}, } removeInfo, err = d.DatumRepository.DeleteMany(ctx, selector) if err == nil { @@ -134,6 +135,7 @@ func (d *DataRepository) DeleteOtherDataSetData(ctx context.Context, dataSet *up "_userId": dataSet.UserID, "deviceId": *dataSet.DeviceID, "uploadId": bson.M{"$ne": dataSet.UploadID}, + "type": bson.M{"$ne": "upload"}, } removeInfo, err = d.DatumRepository.DeleteMany(ctx, selector) if err == nil { diff --git a/data/store/mongo/mongo_data_set.go b/data/store/mongo/mongo_data_set.go index 9495d39783..ee71dbfc56 100644 --- a/data/store/mongo/mongo_data_set.go +++ b/data/store/mongo/mongo_data_set.go @@ -34,6 +34,7 @@ func (d *DataSetRepository) EnsureIndexes() error { Keys: bson.D{ {Key: "_userId", Value: 1}, {Key: "_active", Value: 1}, + {Key: "type", Value: 1}, {Key: "time", Value: -1}, }, Options: options.Index(). @@ -50,6 +51,7 @@ func (d *DataSetRepository) EnsureIndexes() error { { Keys: bson.D{ {Key: "uploadId", Value: 1}, + {Key: "type", Value: 1}, {Key: "deletedTime", Value: -1}, {Key: "_active", Value: 1}, }, @@ -60,6 +62,7 @@ func (d *DataSetRepository) EnsureIndexes() error { Keys: bson.D{ {Key: "_userId", Value: 1}, {Key: "client.name", Value: 1}, + {Key: "type", Value: 1}, {Key: "createdTime", Value: -1}, }, Options: options.Index(). @@ -72,6 +75,7 @@ func (d *DataSetRepository) EnsureIndexes() error { Keys: bson.D{ {Key: "_userId", Value: 1}, {Key: "deviceId", Value: 1}, + {Key: "type", Value: 1}, {Key: "createdTime", Value: -1}, }, Options: options.Index(). @@ -253,6 +257,7 @@ func (d *DataSetRepository) ListUserDataSets(ctx context.Context, userID string, selector := bson.M{ "_active": true, "_userId": userID, + "type": "upload", } if filter.ClientName != nil { selector["client.name"] = *filter.ClientName @@ -306,6 +311,7 @@ func (d *DataSetRepository) GetDataSetsForUserByID(ctx context.Context, userID s selector := bson.M{ "_active": true, "_userId": userID, + "type": "upload", } if !filter.Deleted { selector["deletedTime"] = bson.M{"$exists": false} diff --git a/data/store/mongo/mongo_datum.go b/data/store/mongo/mongo_datum.go index 526196c9b5..59135e03fc 100644 --- a/data/store/mongo/mongo_datum.go +++ b/data/store/mongo/mongo_datum.go @@ -372,6 +372,7 @@ func (d *DatumRepository) DestroyDataSetData(ctx context.Context, dataSet *uploa selector["_userId"] = dataSet.UserID selector["uploadId"] = dataSet.UploadID + selector["type"] = bson.M{"$ne": "upload"} changeInfo, err := d.DeleteMany(ctx, selector) if err != nil { logger.WithError(err).Error("Unable to destroy data set data") @@ -453,6 +454,7 @@ func (d *DatumRepository) UnarchiveDeviceDataUsingHashesFromDataSet(ctx context. { "$match": bson.M{ "uploadId": dataSet.UploadID, + "type": bson.M{"$ne": "upload"}, }, }, { diff --git a/data/store/mongo/mongo_test.go b/data/store/mongo/mongo_test.go index 5ff0194aae..2b50b4a341 100644 --- a/data/store/mongo/mongo_test.go +++ b/data/store/mongo/mongo_test.go @@ -364,11 +364,11 @@ var _ = Describe("Mongo", Label("mongodb", "slow", "integration"), func() { "Key": Equal(storeStructuredMongoTest.MakeKeySlice("_id")), }), MatchFields(IgnoreExtras, Fields{ - "Key": Equal(storeStructuredMongoTest.MakeKeySlice("_userId", "_active", "-time")), + "Key": Equal(storeStructuredMongoTest.MakeKeySlice("_userId", "_active", "type", "-time")), "Name": Equal("UserIdTypeWeighted_v2"), }), MatchFields(IgnoreExtras, Fields{ - "Key": Equal(storeStructuredMongoTest.MakeKeySlice("uploadId", "-deletedTime", "_active")), + "Key": Equal(storeStructuredMongoTest.MakeKeySlice("uploadId", "type", "-deletedTime", "_active")), "Name": Equal("UploadId"), }), MatchFields(IgnoreExtras, Fields{ @@ -377,14 +377,14 @@ var _ = Describe("Mongo", Label("mongodb", "slow", "integration"), func() { "Name": Equal("UniqueUploadId"), }), MatchFields(IgnoreExtras, Fields{ - "Key": Equal(storeStructuredMongoTest.MakeKeySlice("_userId", "client.name", "-createdTime")), + "Key": Equal(storeStructuredMongoTest.MakeKeySlice("_userId", "client.name", "type", "-createdTime")), "Name": Equal("ListUserDataSets"), "PartialFilterExpression": Equal(bson.D{ {Key: "_active", Value: true}, }), }), MatchFields(IgnoreExtras, Fields{ - "Key": Equal(storeStructuredMongoTest.MakeKeySlice("_userId", "deviceId", "-createdTime")), + "Key": Equal(storeStructuredMongoTest.MakeKeySlice("_userId", "deviceId", "type", "-createdTime")), "Name": Equal("ListUserDataSetsDeviceId"), "PartialFilterExpression": Equal(bson.D{ {Key: "_active", Value: true}, From 8a97e2546ad6bd64189604dc3a9672040e9d8945 Mon Sep 17 00:00:00 2001 From: Alexander Diana Date: Wed, 16 Apr 2025 22:57:01 +0000 Subject: [PATCH 06/24] Modify summary indexes to allow for sorted migratiuon queries --- data/store/mongo/mongo_summary.go | 4 ++-- data/store/mongo/mongo_test.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/data/store/mongo/mongo_summary.go b/data/store/mongo/mongo_summary.go index 02f7cf0d18..282fc77258 100644 --- a/data/store/mongo/mongo_summary.go +++ b/data/store/mongo/mongo_summary.go @@ -29,11 +29,11 @@ func (d *SummaryRepository) EnsureIndexes() error { Keys: bson.D{ {Key: "type", Value: 1}, {Key: "dates.outdatedSince", Value: 1}, - {Key: "config.schemaVersion", Value: 1}, {Key: "dates.lastUpdatedDate", Value: 1}, + {Key: "config.schemaVersion", Value: 1}, }, Options: options.Index(). - SetName("OutdatedSinceSchemaLastUpdated"), + SetName("OutdatedAndSchemaMigration"), }, }) } diff --git a/data/store/mongo/mongo_test.go b/data/store/mongo/mongo_test.go index 7b0a0fd2a4..4a2f77b700 100644 --- a/data/store/mongo/mongo_test.go +++ b/data/store/mongo/mongo_test.go @@ -416,9 +416,9 @@ var _ = Describe("Mongo", Label("mongodb", "slow", "integration"), func() { "Name": Equal("UserIDTypeUnique"), }), MatchFields(IgnoreExtras, Fields{ - "Key": Equal(storeStructuredMongoTest.MakeKeySlice("type", "dates.outdatedSince", "config.schemaVersion", "dates.lastUpdatedDate")), + "Key": Equal(storeStructuredMongoTest.MakeKeySlice("type", "dates.outdatedSince", "dates.lastUpdatedDate", "config.schemaVersion")), "Background": Equal(false), - "Name": Equal("OutdatedSinceSchemaLastUpdated"), + "Name": Equal("OutdatedAndSchemaMigration"), }), )) }) From 7a499c7473afa0dcb3832cb875ff108d4d62a481 Mon Sep 17 00:00:00 2001 From: Eric Wollesen Date: Thu, 16 Jan 2025 07:35:30 -0700 Subject: [PATCH 07/24] change egrep to grep -E egrep is deprecated now, at least on my Linux box, so this was spitting out tons of warning messages, which this change stops. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b23b42b460..8712a40cc7 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ VERSION_PACKAGE:=$(REPOSITORY_PACKAGE)/application GO_BUILD_FLAGS:=-buildvcs=false GO_LD_FLAGS:=-ldflags '-X $(VERSION_PACKAGE).VersionBase=$(VERSION_BASE) -X $(VERSION_PACKAGE).VersionShortCommit=$(VERSION_SHORT_COMMIT) -X $(VERSION_PACKAGE).VersionFullCommit=$(VERSION_FULL_COMMIT)' -FIND_MAIN_CMD:=find . -path './$(BUILD)*' -not -path './.gvm_local/*' -not -path './vendor/*' -name '*.go' -not -name '*_test.go' -type f -exec egrep -l '^\s*func\s+main\s*(\s*)' {} \; +FIND_MAIN_CMD:=find . -path './$(BUILD)*' -not -path './.gvm_local/*' -not -path './vendor/*' -name '*.go' -not -name '*_test.go' -type f -exec grep -E -l '^\s*func\s+main\s*(\s*)' {} \; TRANSFORM_GO_BUILD_CMD:=sed 's|\.\(.*\)\(/[^/]*\)/[^/]*|_bin\1\2\2 .\1\2/.|' GO_BUILD_CMD:=go build $(GO_BUILD_FLAGS) $(GO_LD_FLAGS) -o From c6fb178f5f737e7f9129cd5529131c85846d7d56 Mon Sep 17 00:00:00 2001 From: Todd Kazakov Date: Tue, 28 May 2024 18:30:02 +0300 Subject: [PATCH 08/24] Add Twiist provider --- auth/service/service/service.go | 7 ++ oauth/oauth.go | 20 ++++- twiist/provider/provider.go | 132 ++++++++++++++++++++++++++++++++ 3 files changed, 157 insertions(+), 2 deletions(-) create mode 100644 twiist/provider/provider.go diff --git a/auth/service/service/service.go b/auth/service/service/service.go index e7b9e6ca14..234f42cf5a 100644 --- a/auth/service/service/service.go +++ b/auth/service/service/service.go @@ -33,6 +33,7 @@ import ( storeStructuredMongo "github.com/tidepool-org/platform/store/structured/mongo" "github.com/tidepool-org/platform/task" taskClient "github.com/tidepool-org/platform/task/client" + twiistProvider "github.com/tidepool-org/platform/twiist/provider" ) type confirmationClientConfig struct { @@ -365,6 +366,12 @@ func (s *Service) initializeProviderFactory() error { return errors.Wrap(prvdrErr, "unable to add dexcom provider") } + if prvdr, prvdrErr := twiistProvider.New(s.ConfigReporter().WithScopes("provider"), s.DataSourceClient(), s.TaskClient()); prvdrErr != nil { + s.Logger().WithError(prvdrErr).Warn("Unable to create dexcom provider") + } else if prvdrErr = prvdrFctry.Add(prvdr); prvdrErr != nil { + return errors.Wrap(prvdrErr, "unable to add dexcom provider") + } + return nil } diff --git a/oauth/oauth.go b/oauth/oauth.go index 3f49f34f2b..91869b0963 100644 --- a/oauth/oauth.go +++ b/oauth/oauth.go @@ -40,6 +40,7 @@ type TokenSource interface { type Token struct { AccessToken string `json:"accessToken" bson:"accessToken"` + IdToken string `json:"idToken,omitempty" bson:"idToken,omitempty"` TokenType string `json:"tokenType,omitempty" bson:"tokenType,omitempty"` RefreshToken string `json:"refreshToken,omitempty" bson:"refreshToken,omitempty"` ExpirationTime time.Time `json:"expirationTime,omitempty" bson:"expirationTime,omitempty"` @@ -53,9 +54,9 @@ func NewTokenFromRawToken(rawToken *oauth2.Token) (*Token, error) { if rawToken == nil { return nil, errors.New("raw token is missing") } - return &Token{ AccessToken: rawToken.AccessToken, + IdToken: GetIdToken(rawToken), TokenType: rawToken.TokenType, RefreshToken: rawToken.RefreshToken, ExpirationTime: rawToken.Expiry, @@ -66,6 +67,9 @@ func (t *Token) Parse(parser structure.ObjectParser) { if accessToken := parser.String("accessToken"); accessToken != nil { t.AccessToken = *accessToken } + if idToken := parser.String("idToken"); idToken != nil { + t.IdToken = *idToken + } if tokenType := parser.String("tokenType"); tokenType != nil { t.TokenType = *tokenType } @@ -88,17 +92,24 @@ func (t *Token) Expire() { } func (t *Token) RawToken() *oauth2.Token { - return &oauth2.Token{ + token := &oauth2.Token{ AccessToken: t.AccessToken, TokenType: t.TokenType, RefreshToken: t.RefreshToken, Expiry: t.ExpirationTime, } + if t.IdToken != "" { + token.WithExtra(map[string]any{ + "id_token": t.IdToken, + }) + } + return token } func (t *Token) MatchesRawToken(rawToken *oauth2.Token) bool { return rawToken != nil && rawToken.AccessToken == t.AccessToken && + GetIdToken(rawToken) == t.IdToken && rawToken.TokenType == t.TokenType && rawToken.RefreshToken == t.RefreshToken && rawToken.Expiry.Equal(t.ExpirationTime) @@ -120,4 +131,9 @@ func IsRefreshTokenError(err error) bool { } } +func GetIdToken(rawToken *oauth2.Token) string { + idToken, _ := rawToken.Extra("id_token").(string) + return idToken +} + const ErrorAccessDenied = "access_denied" diff --git a/twiist/provider/provider.go b/twiist/provider/provider.go new file mode 100644 index 0000000000..5e598fc058 --- /dev/null +++ b/twiist/provider/provider.go @@ -0,0 +1,132 @@ +package provider + +import ( + "context" + + "github.com/tidepool-org/platform/config" + dataSource "github.com/tidepool-org/platform/data/source" + "github.com/tidepool-org/platform/dexcom/fetch" + "github.com/tidepool-org/platform/errors" + "github.com/tidepool-org/platform/log" + oauthProvider "github.com/tidepool-org/platform/oauth/provider" + "github.com/tidepool-org/platform/pointer" + "github.com/tidepool-org/platform/task" +) + +const ProviderName = "twiist" + +type Provider struct { + *oauthProvider.Provider + dataSourceClient dataSource.Client + taskClient task.Client +} + +func New(configReporter config.Reporter, dataSourceClient dataSource.Client, taskClient task.Client) (*Provider, error) { + if configReporter == nil { + return nil, errors.New("config reporter is missing") + } + if dataSourceClient == nil { + return nil, errors.New("data source client is missing") + } + if taskClient == nil { + return nil, errors.New("task client is missing") + } + + prvdr, err := oauthProvider.NewProvider(ProviderName, configReporter.WithScopes(ProviderName)) + if err != nil { + return nil, err + } + + return &Provider{ + Provider: prvdr, + dataSourceClient: dataSourceClient, + taskClient: taskClient, + }, nil +} + +func (p *Provider) OnCreate(ctx context.Context, userID string, providerSessionID string) error { + if userID == "" { + return errors.New("user id is missing") + } + if providerSessionID == "" { + return errors.New("provider session id is missing") + } + + logger := log.LoggerFromContext(ctx).WithFields(log.Fields{"userId": userID, "type": p.Type(), "name": p.Name()}) + + filter := dataSource.NewFilter() + filter.ProviderType = pointer.FromStringArray([]string{p.Type()}) + filter.ProviderName = pointer.FromStringArray([]string{p.Name()}) + sources, err := p.dataSourceClient.List(ctx, userID, filter, nil) + if err != nil { + return errors.Wrap(err, "unable to fetch data sources") + } + + var source *dataSource.Source + if count := len(sources); count > 0 { + if count > 1 { + logger.WithField("count", count).Warn("unexpected number of data sources found") + } + + source = sources[0] + if *source.State != dataSource.StateDisconnected { + logger.WithFields(log.Fields{"id": source.ID, "state": source.State}).Warn("data source in unexpected state") + } + + update := dataSource.NewUpdate() + update.ProviderSessionID = pointer.FromString(providerSessionID) + update.State = pointer.FromString(dataSource.StateConnected) + + source, err = p.dataSourceClient.Update(ctx, *source.ID, nil, update) + if err != nil { + return errors.Wrap(err, "unable to update data source") + } + } else { + create := dataSource.NewCreate() + create.ProviderType = pointer.FromString(p.Type()) + create.ProviderName = pointer.FromString(p.Name()) + create.ProviderSessionID = pointer.FromString(providerSessionID) + create.State = pointer.FromString(dataSource.StateConnected) + + source, err = p.dataSourceClient.Create(ctx, userID, create) + if err != nil { + return errors.Wrap(err, "unable to create data source") + } + } + + return nil +} + +func (p *Provider) OnDelete(ctx context.Context, userID string, providerSessionID string) error { + if userID == "" { + return errors.New("user id is missing") + } + if providerSessionID == "" { + return errors.New("provider session id is missing") + } + + logger := log.LoggerFromContext(ctx).WithFields(log.Fields{"userId": userID, "providerSessionId": providerSessionID}) + + taskFilter := task.NewTaskFilter() + taskFilter.Name = pointer.FromString(fetch.TaskName(providerSessionID)) + tasks, err := p.taskClient.ListTasks(ctx, taskFilter, nil) + if err != nil { + logger.WithError(err).Error("unable to list tasks after deleting provider session") + return nil + } + + for _, task := range tasks { + if err = p.taskClient.DeleteTask(ctx, task.ID); err != nil { + logger.WithError(err).WithField("taskId", task.ID).Error("unable to delete task after deleting provider session") + } + if dataSourceID, ok := task.Data["dataSourceId"].(string); ok && dataSourceID != "" { + update := dataSource.NewUpdate() + update.State = pointer.FromString(dataSource.StateDisconnected) + _, err = p.dataSourceClient.Update(ctx, dataSourceID, nil, update) + if err != nil { + logger.WithError(err).WithField("dataSourceId", dataSourceID).Error("unable to update data source after deleting provider session") + } + } + } + return nil +} From 73f948749d48ebc2002de6b4f23ce2d673df51b8 Mon Sep 17 00:00:00 2001 From: Todd Kazakov Date: Thu, 6 Jun 2024 18:36:15 +0300 Subject: [PATCH 09/24] Dump request and response for token exchange --- auth/service/api/v1/debug.go | 27 +++++++++++++++++++++++++++ auth/service/api/v1/oauth.go | 7 +++++++ auth/service/service/service.go | 4 ++-- oauth/provider/provider.go | 5 +++++ 4 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 auth/service/api/v1/debug.go diff --git a/auth/service/api/v1/debug.go b/auth/service/api/v1/debug.go new file mode 100644 index 0000000000..d3a9354919 --- /dev/null +++ b/auth/service/api/v1/debug.go @@ -0,0 +1,27 @@ +package v1 + +import ( + "fmt" + "net/http" + "net/http/httputil" + + "github.com/tidepool-org/platform/log" +) + +type DebuggingTransport struct { + Logger log.Logger +} + +func (s *DebuggingTransport) RoundTrip(r *http.Request) (*http.Response, error) { + bytes, _ := httputil.DumpRequestOut(r, true) + + resp, err := http.DefaultTransport.RoundTrip(r) + // err is returned after dumping the response + + respBytes, _ := httputil.DumpResponse(resp, true) + bytes = append(bytes, respBytes...) + + s.Logger.Debug(fmt.Sprintf("%s\n", string(bytes))) + + return resp, err +} diff --git a/auth/service/api/v1/oauth.go b/auth/service/api/v1/oauth.go index 631c9658cd..c96d5c9d85 100644 --- a/auth/service/api/v1/oauth.go +++ b/auth/service/api/v1/oauth.go @@ -1,6 +1,7 @@ package v1 import ( + "context" "fmt" "net/http" "net/url" @@ -8,6 +9,8 @@ import ( "strings" "time" + "golang.org/x/oauth2" + "github.com/ant0ine/go-json-rest/rest" confirmationClient "github.com/tidepool-org/hydrophone/client" @@ -176,6 +179,10 @@ func (r *Router) OAuthProviderRedirectGet(res rest.ResponseWriter, req *rest.Req } } + // TODO: Remove. + transport := DebuggingTransport{Logger: log.LoggerFromContext(ctx)} + ctx = context.WithValue(ctx, oauth2.HTTPClient, http.Client{Transport: &transport}) + oauthToken, err := prvdr.ExchangeAuthorizationCodeForToken(ctx, query.Get("code")) if err != nil { r.htmlOnError(res, req, err) diff --git a/auth/service/service/service.go b/auth/service/service/service.go index 234f42cf5a..e9f13ac5ed 100644 --- a/auth/service/service/service.go +++ b/auth/service/service/service.go @@ -367,9 +367,9 @@ func (s *Service) initializeProviderFactory() error { } if prvdr, prvdrErr := twiistProvider.New(s.ConfigReporter().WithScopes("provider"), s.DataSourceClient(), s.TaskClient()); prvdrErr != nil { - s.Logger().WithError(prvdrErr).Warn("Unable to create dexcom provider") + s.Logger().WithError(prvdrErr).Warn("Unable to create twiist provider") } else if prvdrErr = prvdrFctry.Add(prvdr); prvdrErr != nil { - return errors.Wrap(prvdrErr, "unable to add dexcom provider") + return errors.Wrap(prvdrErr, "unable to add twiist provider") } return nil diff --git a/oauth/provider/provider.go b/oauth/provider/provider.go index 43e6f7eee9..20f02ff18c 100644 --- a/oauth/provider/provider.go +++ b/oauth/provider/provider.go @@ -51,6 +51,11 @@ func NewProvider(name string, configReporter config.Reporter) (*Provider, error) } cfg.Scopes = SplitScopes(configReporter.GetWithDefault("scopes", "")) + authStyleInParams := configReporter.GetWithDefault("auth_style_in_params", "") + if authStyleInParams == "true" { + cfg.Endpoint.AuthStyle = oauth2.AuthStyleInParams + } + stateSalt := configReporter.GetWithDefault("state_salt", "") if stateSalt == "" { return nil, errors.New("state salt is missing") From 49b61a31b56a58ad859101061a18a30161ee3445 Mon Sep 17 00:00:00 2001 From: Todd Kazakov Date: Tue, 11 Jun 2024 10:31:52 +0300 Subject: [PATCH 10/24] Remove debug statements --- auth/service/api/v1/oauth.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/auth/service/api/v1/oauth.go b/auth/service/api/v1/oauth.go index c96d5c9d85..631c9658cd 100644 --- a/auth/service/api/v1/oauth.go +++ b/auth/service/api/v1/oauth.go @@ -1,7 +1,6 @@ package v1 import ( - "context" "fmt" "net/http" "net/url" @@ -9,8 +8,6 @@ import ( "strings" "time" - "golang.org/x/oauth2" - "github.com/ant0ine/go-json-rest/rest" confirmationClient "github.com/tidepool-org/hydrophone/client" @@ -179,10 +176,6 @@ func (r *Router) OAuthProviderRedirectGet(res rest.ResponseWriter, req *rest.Req } } - // TODO: Remove. - transport := DebuggingTransport{Logger: log.LoggerFromContext(ctx)} - ctx = context.WithValue(ctx, oauth2.HTTPClient, http.Client{Transport: &transport}) - oauthToken, err := prvdr.ExchangeAuthorizationCodeForToken(ctx, query.Get("code")) if err != nil { r.htmlOnError(res, req, err) From 1d27a878dc4b570fb6a3ba6f56da730ddaf4f74a Mon Sep 17 00:00:00 2001 From: Darin Krauss Date: Mon, 3 Feb 2025 09:29:28 -0800 Subject: [PATCH 11/24] [BACK-1913] Add sample interval and backfilled to cbg data type - Add sample interval and backfilled to cbg data type - https://tidepool.atlassian.net/browse/BACK-1913 --- .../blood/glucose/continuous/continuous.go | 15 +++- .../glucose/continuous/continuous_test.go | 77 +++++++++++++++++++ 2 files changed, 88 insertions(+), 4 deletions(-) diff --git a/data/types/blood/glucose/continuous/continuous.go b/data/types/blood/glucose/continuous/continuous.go index cc307625ce..a1d976f665 100644 --- a/data/types/blood/glucose/continuous/continuous.go +++ b/data/types/blood/glucose/continuous/continuous.go @@ -17,8 +17,10 @@ const ( RapidFall = "rapidFall" RapidRise = "rapidRise" - TrendRateMaximum = 100 - TrendRateMinimum = -100 + TrendRateMaximum = 100 + TrendRateMinimum = -100 + SampleIntervalMinimum = 0 + SampleIntervalMaximum = 24 * 60 * 60 * 1000 ) func Trends() []string { @@ -26,9 +28,11 @@ func Trends() []string { } type Continuous struct { + glucose.Glucose `bson:",inline"` Trend *string `json:"trend,omitempty" bson:"trend,omitempty"` TrendRate *float64 `json:"trendRate,omitempty" bson:"trendRate,omitempty"` - glucose.Glucose `bson:",inline"` + SampleInterval *int `json:"sampleInterval,omitempty" bson:"sampleInterval,omitempty"` + Backfilled *bool `json:"backfilled,omitempty" bson:"backfilled,omitempty"` } func New() *Continuous { @@ -46,6 +50,8 @@ func (c *Continuous) Parse(parser structure.ObjectParser) { c.Trend = parser.String("trend") c.TrendRate = parser.Float64("trendRate") + c.SampleInterval = parser.Int("sampleInterval") + c.Backfilled = parser.Bool("backfilled") } func (c *Continuous) Validate(validator structure.Validator) { @@ -59,8 +65,9 @@ func (c *Continuous) Validate(validator structure.Validator) { validator.String("type", &c.Type).EqualTo(Type) } - validator.Float64("trendRate", c.TrendRate).InRange(TrendRateMinimum, TrendRateMaximum) validator.String("trend", c.Trend).OneOf(Trends()...) + validator.Float64("trendRate", c.TrendRate).InRange(TrendRateMinimum, TrendRateMaximum) + validator.Int("sampleInterval", c.SampleInterval).InRange(SampleIntervalMinimum, SampleIntervalMaximum) } func (c *Continuous) Normalize(normalizer data.Normalizer) { diff --git a/data/types/blood/glucose/continuous/continuous_test.go b/data/types/blood/glucose/continuous/continuous_test.go index 558534a85f..6b3bea23fd 100644 --- a/data/types/blood/glucose/continuous/continuous_test.go +++ b/data/types/blood/glucose/continuous/continuous_test.go @@ -15,6 +15,7 @@ import ( "github.com/tidepool-org/platform/pointer" "github.com/tidepool-org/platform/structure" structureValidator "github.com/tidepool-org/platform/structure/validator" + "github.com/tidepool-org/platform/test" ) func NewMeta() interface{} { @@ -27,6 +28,10 @@ func NewContinuous(units *string) *continuous.Continuous { datum := continuous.New() datum.Glucose = *dataTypesBloodGlucoseTest.NewGlucose(units) datum.Type = "cbg" + datum.Trend = pointer.FromString(test.RandomStringFromArray(continuous.Trends())) + datum.TrendRate = pointer.FromFloat64(test.RandomFloat64FromRange(continuous.TrendRateMinimum, continuous.TrendRateMaximum)) + datum.SampleInterval = pointer.FromInt(test.RandomIntFromRange(continuous.SampleIntervalMinimum, continuous.SampleIntervalMaximum)) + datum.Backfilled = pointer.FromBool(test.RandomBool()) return datum } @@ -38,6 +43,8 @@ func CloneContinuous(datum *continuous.Continuous) *continuous.Continuous { clone.Glucose = *dataTypesBloodGlucoseTest.CloneGlucose(&datum.Glucose) clone.Trend = pointer.CloneString(datum.Trend) clone.TrendRate = pointer.CloneFloat64(datum.TrendRate) + clone.SampleInterval = pointer.CloneInt(datum.SampleInterval) + clone.Backfilled = pointer.CloneBool(datum.Backfilled) return clone } @@ -53,6 +60,10 @@ var _ = Describe("Continuous", func() { Expect(datum.Type).To(Equal("cbg")) Expect(datum.Units).To(BeNil()) Expect(datum.Value).To(BeNil()) + Expect(datum.Trend).To(BeNil()) + Expect(datum.TrendRate).To(BeNil()) + Expect(datum.SampleInterval).To(BeNil()) + Expect(datum.Backfilled).To(BeNil()) }) }) @@ -225,6 +236,48 @@ var _ = Describe("Continuous", func() { func(datum *continuous.Continuous, units *string) { datum.Value = pointer.FromFloat64(1000.1) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(1000.1, 0.0, 1000.0), "/value", NewMeta()), ), + Entry("trend missing", + pointer.FromString("mg/dl"), + func(datum *continuous.Continuous, units *string) { datum.Trend = nil }, + ), + Entry("trend empty", + pointer.FromString("mg/dl"), + func(datum *continuous.Continuous, units *string) { datum.Trend = pointer.FromString("") }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueStringNotOneOf("", continuous.Trends()), "/trend", NewMeta()), + ), + Entry("trend invalid", + pointer.FromString("mg/dl"), + func(datum *continuous.Continuous, units *string) { datum.Trend = pointer.FromString("invalid") }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueStringNotOneOf("invalid", continuous.Trends()), "/trend", NewMeta()), + ), + Entry("trend constant", + pointer.FromString("mg/dl"), + func(datum *continuous.Continuous, units *string) { datum.Trend = pointer.FromString("constant") }, + ), + Entry("trend slowFall", + pointer.FromString("mg/dl"), + func(datum *continuous.Continuous, units *string) { datum.Trend = pointer.FromString("slowFall") }, + ), + Entry("trend slowRise", + pointer.FromString("mg/dl"), + func(datum *continuous.Continuous, units *string) { datum.Trend = pointer.FromString("slowRise") }, + ), + Entry("trend moderateFall", + pointer.FromString("mg/dl"), + func(datum *continuous.Continuous, units *string) { datum.Trend = pointer.FromString("moderateFall") }, + ), + Entry("trend moderateRise", + pointer.FromString("mg/dl"), + func(datum *continuous.Continuous, units *string) { datum.Trend = pointer.FromString("moderateRise") }, + ), + Entry("trend rapidFall", + pointer.FromString("mg/dl"), + func(datum *continuous.Continuous, units *string) { datum.Trend = pointer.FromString("rapidFall") }, + ), + Entry("trend rapidRise", + pointer.FromString("mg/dl"), + func(datum *continuous.Continuous, units *string) { datum.Trend = pointer.FromString("rapidRise") }, + ), Entry("trend rate missing", pointer.FromString("mg/dl"), func(datum *continuous.Continuous, units *string) { datum.TrendRate = nil }, @@ -247,6 +300,28 @@ var _ = Describe("Continuous", func() { func(datum *continuous.Continuous, units *string) { datum.TrendRate = pointer.FromFloat64(100.1) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, -100.0, 100.0), "/trendRate", NewMeta()), ), + Entry("sample interval missing", + pointer.FromString("mg/dl"), + func(datum *continuous.Continuous, units *string) { datum.SampleInterval = nil }, + ), + Entry("sample interval out of range (lower)", + pointer.FromString("mg/dl"), + func(datum *continuous.Continuous, units *string) { datum.SampleInterval = pointer.FromInt(-1) }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 86400000), "/sampleInterval", NewMeta()), + ), + Entry("sample interval in range (lower)", + pointer.FromString("mg/dl"), + func(datum *continuous.Continuous, units *string) { datum.SampleInterval = pointer.FromInt(0) }, + ), + Entry("sample interval in range (upper)", + pointer.FromString("mg/dl"), + func(datum *continuous.Continuous, units *string) { datum.SampleInterval = pointer.FromInt(86400000) }, + ), + Entry("sample interval out of range (upper)", + pointer.FromString("mg/dl"), + func(datum *continuous.Continuous, units *string) { datum.SampleInterval = pointer.FromInt(86400001) }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, 86400000), "/sampleInterval", NewMeta()), + ), Entry("multiple errors", nil, func(datum *continuous.Continuous, units *string) { @@ -254,11 +329,13 @@ var _ = Describe("Continuous", func() { datum.Value = nil datum.Trend = nil datum.TrendRate = pointer.FromFloat64(-100.1) + datum.SampleInterval = pointer.FromInt(-1) }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueEmpty(), "/type", &types.Meta{}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/units", &types.Meta{}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/value", &types.Meta{}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-100.1, -100.0, 100.0), "/trendRate", &types.Meta{}), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 86400000), "/sampleInterval", &types.Meta{}), ), ) }) From 271837ecbcf090873386439b90c6f68b958d44a2 Mon Sep 17 00:00:00 2001 From: Eric Wollesen Date: Wed, 29 Jan 2025 10:07:27 -0700 Subject: [PATCH 12/24] upgrade golang.org/x/net package to fix CVE-2024-45338 My investigation indicates that neither our code, nor our dependencies use the functions in question, but at the same time, the impact of upgrading them is minimal, so it feels like the less risky path to just upgrade and not have to worry. BACK-3353 --- go.mod | 14 +- go.sum | 28 +- vendor/golang.org/x/crypto/LICENSE | 4 +- vendor/golang.org/x/crypto/md4/md4.go | 2 +- vendor/golang.org/x/crypto/ocsp/ocsp.go | 2 +- vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go | 2 +- vendor/golang.org/x/crypto/scrypt/scrypt.go | 2 +- vendor/golang.org/x/net/LICENSE | 4 +- vendor/golang.org/x/net/html/doc.go | 7 +- vendor/golang.org/x/net/html/doctype.go | 2 +- vendor/golang.org/x/net/html/foreign.go | 3 +- vendor/golang.org/x/net/html/iter.go | 56 ++ vendor/golang.org/x/net/html/node.go | 4 + vendor/golang.org/x/net/html/parse.go | 8 +- .../x/net/http2/client_conn_pool.go | 8 +- vendor/golang.org/x/net/http2/config.go | 122 ++++ vendor/golang.org/x/net/http2/config_go124.go | 61 ++ .../x/net/http2/config_pre_go124.go | 16 + vendor/golang.org/x/net/http2/frame.go | 4 +- vendor/golang.org/x/net/http2/http2.go | 95 +++- vendor/golang.org/x/net/http2/server.go | 244 +++++--- vendor/golang.org/x/net/http2/transport.go | 527 ++++++++++++------ vendor/golang.org/x/net/http2/unencrypted.go | 32 ++ vendor/golang.org/x/net/http2/write.go | 10 + vendor/golang.org/x/sync/LICENSE | 4 +- vendor/golang.org/x/sys/LICENSE | 4 +- vendor/golang.org/x/sys/unix/README.md | 2 +- vendor/golang.org/x/sys/unix/ioctl_linux.go | 96 ++++ vendor/golang.org/x/sys/unix/mkerrors.sh | 18 +- vendor/golang.org/x/sys/unix/mremap.go | 5 + vendor/golang.org/x/sys/unix/syscall_aix.go | 2 +- .../golang.org/x/sys/unix/syscall_darwin.go | 61 ++ .../x/sys/unix/syscall_dragonfly.go | 12 + vendor/golang.org/x/sys/unix/syscall_hurd.go | 1 + vendor/golang.org/x/sys/unix/syscall_linux.go | 65 ++- .../x/sys/unix/syscall_linux_arm64.go | 2 + .../x/sys/unix/syscall_linux_loong64.go | 2 + .../x/sys/unix/syscall_linux_riscv64.go | 2 + .../golang.org/x/sys/unix/syscall_openbsd.go | 1 + vendor/golang.org/x/sys/unix/syscall_unix.go | 9 + .../x/sys/unix/syscall_zos_s390x.go | 104 +++- .../golang.org/x/sys/unix/vgetrandom_linux.go | 13 + .../x/sys/unix/vgetrandom_unsupported.go | 11 + .../x/sys/unix/zerrors_darwin_amd64.go | 12 + .../x/sys/unix/zerrors_darwin_arm64.go | 12 + vendor/golang.org/x/sys/unix/zerrors_linux.go | 82 ++- .../x/sys/unix/zerrors_linux_386.go | 27 + .../x/sys/unix/zerrors_linux_amd64.go | 27 + .../x/sys/unix/zerrors_linux_arm.go | 27 + .../x/sys/unix/zerrors_linux_arm64.go | 28 + .../x/sys/unix/zerrors_linux_loong64.go | 27 + .../x/sys/unix/zerrors_linux_mips.go | 27 + .../x/sys/unix/zerrors_linux_mips64.go | 27 + .../x/sys/unix/zerrors_linux_mips64le.go | 27 + .../x/sys/unix/zerrors_linux_mipsle.go | 27 + .../x/sys/unix/zerrors_linux_ppc.go | 27 + .../x/sys/unix/zerrors_linux_ppc64.go | 27 + .../x/sys/unix/zerrors_linux_ppc64le.go | 27 + .../x/sys/unix/zerrors_linux_riscv64.go | 27 + .../x/sys/unix/zerrors_linux_s390x.go | 27 + .../x/sys/unix/zerrors_linux_sparc64.go | 27 + .../x/sys/unix/zerrors_zos_s390x.go | 2 + .../x/sys/unix/zsyscall_darwin_amd64.go | 101 ++++ .../x/sys/unix/zsyscall_darwin_amd64.s | 25 + .../x/sys/unix/zsyscall_darwin_arm64.go | 101 ++++ .../x/sys/unix/zsyscall_darwin_arm64.s | 25 + .../golang.org/x/sys/unix/zsyscall_linux.go | 43 +- .../x/sys/unix/zsyscall_openbsd_386.go | 24 + .../x/sys/unix/zsyscall_openbsd_386.s | 5 + .../x/sys/unix/zsyscall_openbsd_amd64.go | 24 + .../x/sys/unix/zsyscall_openbsd_amd64.s | 5 + .../x/sys/unix/zsyscall_openbsd_arm.go | 24 + .../x/sys/unix/zsyscall_openbsd_arm.s | 5 + .../x/sys/unix/zsyscall_openbsd_arm64.go | 24 + .../x/sys/unix/zsyscall_openbsd_arm64.s | 5 + .../x/sys/unix/zsyscall_openbsd_mips64.go | 24 + .../x/sys/unix/zsyscall_openbsd_mips64.s | 5 + .../x/sys/unix/zsyscall_openbsd_ppc64.go | 24 + .../x/sys/unix/zsyscall_openbsd_ppc64.s | 6 + .../x/sys/unix/zsyscall_openbsd_riscv64.go | 24 + .../x/sys/unix/zsyscall_openbsd_riscv64.s | 5 + .../x/sys/unix/zsysnum_linux_386.go | 1 + .../x/sys/unix/zsysnum_linux_amd64.go | 2 + .../x/sys/unix/zsysnum_linux_arm.go | 1 + .../x/sys/unix/zsysnum_linux_arm64.go | 3 +- .../x/sys/unix/zsysnum_linux_loong64.go | 3 + .../x/sys/unix/zsysnum_linux_mips.go | 1 + .../x/sys/unix/zsysnum_linux_mips64.go | 1 + .../x/sys/unix/zsysnum_linux_mips64le.go | 1 + .../x/sys/unix/zsysnum_linux_mipsle.go | 1 + .../x/sys/unix/zsysnum_linux_ppc.go | 1 + .../x/sys/unix/zsysnum_linux_ppc64.go | 1 + .../x/sys/unix/zsysnum_linux_ppc64le.go | 1 + .../x/sys/unix/zsysnum_linux_riscv64.go | 3 +- .../x/sys/unix/zsysnum_linux_s390x.go | 1 + .../x/sys/unix/zsysnum_linux_sparc64.go | 1 + .../x/sys/unix/ztypes_darwin_amd64.go | 73 +++ .../x/sys/unix/ztypes_darwin_arm64.go | 73 +++ .../x/sys/unix/ztypes_freebsd_386.go | 1 + .../x/sys/unix/ztypes_freebsd_amd64.go | 1 + .../x/sys/unix/ztypes_freebsd_arm.go | 1 + .../x/sys/unix/ztypes_freebsd_arm64.go | 1 + .../x/sys/unix/ztypes_freebsd_riscv64.go | 1 + vendor/golang.org/x/sys/unix/ztypes_linux.go | 230 ++++++-- .../x/sys/unix/ztypes_linux_riscv64.go | 33 ++ .../golang.org/x/sys/unix/ztypes_zos_s390x.go | 6 + .../golang.org/x/sys/windows/dll_windows.go | 13 +- .../x/sys/windows/security_windows.go | 24 +- .../x/sys/windows/syscall_windows.go | 52 +- .../golang.org/x/sys/windows/types_windows.go | 199 ++++++- .../x/sys/windows/zsyscall_windows.go | 151 +++++ vendor/golang.org/x/term/LICENSE | 4 +- vendor/golang.org/x/term/README.md | 11 +- vendor/golang.org/x/term/term_windows.go | 1 + vendor/golang.org/x/text/LICENSE | 4 +- vendor/modules.txt | 16 +- 116 files changed, 3157 insertions(+), 444 deletions(-) create mode 100644 vendor/golang.org/x/net/html/iter.go create mode 100644 vendor/golang.org/x/net/http2/config.go create mode 100644 vendor/golang.org/x/net/http2/config_go124.go create mode 100644 vendor/golang.org/x/net/http2/config_pre_go124.go create mode 100644 vendor/golang.org/x/net/http2/unencrypted.go create mode 100644 vendor/golang.org/x/sys/unix/vgetrandom_linux.go create mode 100644 vendor/golang.org/x/sys/unix/vgetrandom_unsupported.go diff --git a/go.mod b/go.mod index 1ada6b1ad3..646c4bb7d0 100644 --- a/go.mod +++ b/go.mod @@ -23,16 +23,16 @@ require ( github.com/rinchsan/device-check-go v1.3.0 github.com/tidepool-org/clinic/client v0.0.0-20240926112325-657da308fce2 github.com/tidepool-org/devices/api v0.0.0-20240806072455-2b18f22c9cf5 - github.com/tidepool-org/go-common v0.12.2-0.20240612192926-de6d5c5a742c + github.com/tidepool-org/go-common v0.12.2-0.20250129210214-bd36b59b9733 github.com/tidepool-org/hydrophone/client v0.0.0-20240613043503-6c32828b1ace github.com/urfave/cli v1.22.15 go.mongodb.org/mongo-driver v1.16.0 go.uber.org/fx v1.22.1 - golang.org/x/crypto v0.24.0 + golang.org/x/crypto v0.32.0 golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 golang.org/x/oauth2 v0.21.0 - golang.org/x/sync v0.7.0 + golang.org/x/sync v0.10.0 golang.org/x/tools v0.22.0 gonum.org/v1/gonum v0.15.0 google.golang.org/grpc v1.65.0 @@ -98,10 +98,10 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/mod v0.18.0 // indirect - golang.org/x/net v0.26.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/term v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/net v0.34.0 // indirect + golang.org/x/sys v0.29.0 // indirect + golang.org/x/term v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240624140628-dc46fd24d27d // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d // indirect google.golang.org/protobuf v1.34.2 // indirect diff --git a/go.sum b/go.sum index 389228ddfe..295990bf55 100644 --- a/go.sum +++ b/go.sum @@ -180,8 +180,8 @@ github.com/tidepool-org/clinic/client v0.0.0-20240926112325-657da308fce2 h1:fTIg github.com/tidepool-org/clinic/client v0.0.0-20240926112325-657da308fce2/go.mod h1:7BpAdFdGJNB3aw/xvCz5XnWjSWRoUtWIX4xcMc4Bsko= github.com/tidepool-org/devices/api v0.0.0-20240806072455-2b18f22c9cf5 h1:1kiZtHhs++yXayRD/Mh/3POLwtmxV99YR2bSCle1Q74= github.com/tidepool-org/devices/api v0.0.0-20240806072455-2b18f22c9cf5/go.mod h1:xuQ8k0mLR1ZyEmwe/m0v2BuXctqQuCZeR43urSQpTUM= -github.com/tidepool-org/go-common v0.12.2-0.20240612192926-de6d5c5a742c h1:hJZyiHNGeqyLA/5p60/0H9CZtJi4fAuzOuyQF0TpF7E= -github.com/tidepool-org/go-common v0.12.2-0.20240612192926-de6d5c5a742c/go.mod h1:mIzYteUyPf//fhee4e2KEZhmcm2iE4IQ/2dyQr5pRKA= +github.com/tidepool-org/go-common v0.12.2-0.20250129210214-bd36b59b9733 h1:WCOSrazmNv7KdjIJafWyHkLkHNp2SsoLAm6OXp2rAco= +github.com/tidepool-org/go-common v0.12.2-0.20250129210214-bd36b59b9733/go.mod h1:BeqsQcDwfSsmnmc+/N/EOT8h3m8/YtqrLNykk5kGkv4= github.com/tidepool-org/hydrophone/client v0.0.0-20240613043503-6c32828b1ace h1:L0UiCj2eL/NOpLa19Tf5IgoK6feILmdA+zK3nCTIhqU= github.com/tidepool-org/hydrophone/client v0.0.0-20240613043503-6c32828b1ace/go.mod h1:gon+x+jAh8DZZ2hD23fBWqrYwOizVSwIBbxEsuXCbZ4= github.com/ugorji/go v1.2.4/go.mod h1:EuaSCk8iZMdIspsu6HXH7X2UGKw1ezO4wCfGszGmmo4= @@ -222,8 +222,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= -golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= @@ -241,15 +241,15 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -264,20 +264,20 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= -golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= +golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= +golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/vendor/golang.org/x/crypto/LICENSE b/vendor/golang.org/x/crypto/LICENSE index 6a66aea5ea..2a7cf70da6 100644 --- a/vendor/golang.org/x/crypto/LICENSE +++ b/vendor/golang.org/x/crypto/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. +Copyright 2009 The Go Authors. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer. copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Google Inc. nor the names of its + * Neither the name of Google LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. diff --git a/vendor/golang.org/x/crypto/md4/md4.go b/vendor/golang.org/x/crypto/md4/md4.go index d1911c2e86..7d9281e025 100644 --- a/vendor/golang.org/x/crypto/md4/md4.go +++ b/vendor/golang.org/x/crypto/md4/md4.go @@ -7,7 +7,7 @@ // Deprecated: MD4 is cryptographically broken and should only be used // where compatibility with legacy systems, not security, is the goal. Instead, // use a secure hash like SHA-256 (from crypto/sha256). -package md4 // import "golang.org/x/crypto/md4" +package md4 import ( "crypto" diff --git a/vendor/golang.org/x/crypto/ocsp/ocsp.go b/vendor/golang.org/x/crypto/ocsp/ocsp.go index bf2259537d..e6c645e7ce 100644 --- a/vendor/golang.org/x/crypto/ocsp/ocsp.go +++ b/vendor/golang.org/x/crypto/ocsp/ocsp.go @@ -5,7 +5,7 @@ // Package ocsp parses OCSP responses as specified in RFC 2560. OCSP responses // are signed messages attesting to the validity of a certificate for a small // period of time. This is used to manage revocation for X.509 certificates. -package ocsp // import "golang.org/x/crypto/ocsp" +package ocsp import ( "crypto" diff --git a/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go b/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go index 904b57e01d..28cd99c7f3 100644 --- a/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go +++ b/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go @@ -16,7 +16,7 @@ Hash Functions SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512 for HMAC. To choose, you can pass the `New` functions from the different SHA packages to pbkdf2.Key. */ -package pbkdf2 // import "golang.org/x/crypto/pbkdf2" +package pbkdf2 import ( "crypto/hmac" diff --git a/vendor/golang.org/x/crypto/scrypt/scrypt.go b/vendor/golang.org/x/crypto/scrypt/scrypt.go index c971a99fa6..76fa40fb20 100644 --- a/vendor/golang.org/x/crypto/scrypt/scrypt.go +++ b/vendor/golang.org/x/crypto/scrypt/scrypt.go @@ -5,7 +5,7 @@ // Package scrypt implements the scrypt key derivation function as defined in // Colin Percival's paper "Stronger Key Derivation via Sequential Memory-Hard // Functions" (https://www.tarsnap.com/scrypt/scrypt.pdf). -package scrypt // import "golang.org/x/crypto/scrypt" +package scrypt import ( "crypto/sha256" diff --git a/vendor/golang.org/x/net/LICENSE b/vendor/golang.org/x/net/LICENSE index 6a66aea5ea..2a7cf70da6 100644 --- a/vendor/golang.org/x/net/LICENSE +++ b/vendor/golang.org/x/net/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. +Copyright 2009 The Go Authors. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer. copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Google Inc. nor the names of its + * Neither the name of Google LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. diff --git a/vendor/golang.org/x/net/html/doc.go b/vendor/golang.org/x/net/html/doc.go index 3a7e5ab176..885c4c5936 100644 --- a/vendor/golang.org/x/net/html/doc.go +++ b/vendor/golang.org/x/net/html/doc.go @@ -78,16 +78,11 @@ example, to process each anchor node in depth-first order: if err != nil { // ... } - var f func(*html.Node) - f = func(n *html.Node) { + for n := range doc.Descendants() { if n.Type == html.ElementNode && n.Data == "a" { // Do something with n... } - for c := n.FirstChild; c != nil; c = c.NextSibling { - f(c) - } } - f(doc) The relevant specifications include: https://html.spec.whatwg.org/multipage/syntax.html and diff --git a/vendor/golang.org/x/net/html/doctype.go b/vendor/golang.org/x/net/html/doctype.go index c484e5a94f..bca3ae9a0c 100644 --- a/vendor/golang.org/x/net/html/doctype.go +++ b/vendor/golang.org/x/net/html/doctype.go @@ -87,7 +87,7 @@ func parseDoctype(s string) (n *Node, quirks bool) { } } if lastAttr := n.Attr[len(n.Attr)-1]; lastAttr.Key == "system" && - strings.ToLower(lastAttr.Val) == "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd" { + strings.EqualFold(lastAttr.Val, "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd") { quirks = true } } diff --git a/vendor/golang.org/x/net/html/foreign.go b/vendor/golang.org/x/net/html/foreign.go index 9da9e9dc42..e8515d8e88 100644 --- a/vendor/golang.org/x/net/html/foreign.go +++ b/vendor/golang.org/x/net/html/foreign.go @@ -40,8 +40,7 @@ func htmlIntegrationPoint(n *Node) bool { if n.Data == "annotation-xml" { for _, a := range n.Attr { if a.Key == "encoding" { - val := strings.ToLower(a.Val) - if val == "text/html" || val == "application/xhtml+xml" { + if strings.EqualFold(a.Val, "text/html") || strings.EqualFold(a.Val, "application/xhtml+xml") { return true } } diff --git a/vendor/golang.org/x/net/html/iter.go b/vendor/golang.org/x/net/html/iter.go new file mode 100644 index 0000000000..54be8fd30f --- /dev/null +++ b/vendor/golang.org/x/net/html/iter.go @@ -0,0 +1,56 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.23 + +package html + +import "iter" + +// Ancestors returns an iterator over the ancestors of n, starting with n.Parent. +// +// Mutating a Node or its parents while iterating may have unexpected results. +func (n *Node) Ancestors() iter.Seq[*Node] { + _ = n.Parent // eager nil check + + return func(yield func(*Node) bool) { + for p := n.Parent; p != nil && yield(p); p = p.Parent { + } + } +} + +// ChildNodes returns an iterator over the immediate children of n, +// starting with n.FirstChild. +// +// Mutating a Node or its children while iterating may have unexpected results. +func (n *Node) ChildNodes() iter.Seq[*Node] { + _ = n.FirstChild // eager nil check + + return func(yield func(*Node) bool) { + for c := n.FirstChild; c != nil && yield(c); c = c.NextSibling { + } + } + +} + +// Descendants returns an iterator over all nodes recursively beneath +// n, excluding n itself. Nodes are visited in depth-first preorder. +// +// Mutating a Node or its descendants while iterating may have unexpected results. +func (n *Node) Descendants() iter.Seq[*Node] { + _ = n.FirstChild // eager nil check + + return func(yield func(*Node) bool) { + n.descendants(yield) + } +} + +func (n *Node) descendants(yield func(*Node) bool) bool { + for c := range n.ChildNodes() { + if !yield(c) || !c.descendants(yield) { + return false + } + } + return true +} diff --git a/vendor/golang.org/x/net/html/node.go b/vendor/golang.org/x/net/html/node.go index 1350eef22c..77741a1950 100644 --- a/vendor/golang.org/x/net/html/node.go +++ b/vendor/golang.org/x/net/html/node.go @@ -38,6 +38,10 @@ var scopeMarker = Node{Type: scopeMarkerNode} // that it looks like "a maxFrameSize { + conf.MaxReadFrameSize = maxFrameSize + } + + if h2.t1 != nil { + fillNetHTTPTransportConfig(&conf, h2.t1) + } + setConfigDefaults(&conf, false) + return conf +} + +func setDefault[T ~int | ~int32 | ~uint32 | ~int64](v *T, minval, maxval, defval T) { + if *v < minval || *v > maxval { + *v = defval + } +} + +func setConfigDefaults(conf *http2Config, server bool) { + setDefault(&conf.MaxConcurrentStreams, 1, math.MaxUint32, defaultMaxStreams) + setDefault(&conf.MaxEncoderHeaderTableSize, 1, math.MaxUint32, initialHeaderTableSize) + setDefault(&conf.MaxDecoderHeaderTableSize, 1, math.MaxUint32, initialHeaderTableSize) + if server { + setDefault(&conf.MaxUploadBufferPerConnection, initialWindowSize, math.MaxInt32, 1<<20) + } else { + setDefault(&conf.MaxUploadBufferPerConnection, initialWindowSize, math.MaxInt32, transportDefaultConnFlow) + } + if server { + setDefault(&conf.MaxUploadBufferPerStream, 1, math.MaxInt32, 1<<20) + } else { + setDefault(&conf.MaxUploadBufferPerStream, 1, math.MaxInt32, transportDefaultStreamFlow) + } + setDefault(&conf.MaxReadFrameSize, minMaxFrameSize, maxFrameSize, defaultMaxReadFrameSize) + setDefault(&conf.PingTimeout, 1, math.MaxInt64, 15*time.Second) +} + +// adjustHTTP1MaxHeaderSize converts a limit in bytes on the size of an HTTP/1 header +// to an HTTP/2 MAX_HEADER_LIST_SIZE value. +func adjustHTTP1MaxHeaderSize(n int64) int64 { + // http2's count is in a slightly different unit and includes 32 bytes per pair. + // So, take the net/http.Server value and pad it up a bit, assuming 10 headers. + const perFieldOverhead = 32 // per http2 spec + const typicalHeaders = 10 // conservative + return n + typicalHeaders*perFieldOverhead +} diff --git a/vendor/golang.org/x/net/http2/config_go124.go b/vendor/golang.org/x/net/http2/config_go124.go new file mode 100644 index 0000000000..5b516c55ff --- /dev/null +++ b/vendor/golang.org/x/net/http2/config_go124.go @@ -0,0 +1,61 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.24 + +package http2 + +import "net/http" + +// fillNetHTTPServerConfig sets fields in conf from srv.HTTP2. +func fillNetHTTPServerConfig(conf *http2Config, srv *http.Server) { + fillNetHTTPConfig(conf, srv.HTTP2) +} + +// fillNetHTTPTransportConfig sets fields in conf from tr.HTTP2. +func fillNetHTTPTransportConfig(conf *http2Config, tr *http.Transport) { + fillNetHTTPConfig(conf, tr.HTTP2) +} + +func fillNetHTTPConfig(conf *http2Config, h2 *http.HTTP2Config) { + if h2 == nil { + return + } + if h2.MaxConcurrentStreams != 0 { + conf.MaxConcurrentStreams = uint32(h2.MaxConcurrentStreams) + } + if h2.MaxEncoderHeaderTableSize != 0 { + conf.MaxEncoderHeaderTableSize = uint32(h2.MaxEncoderHeaderTableSize) + } + if h2.MaxDecoderHeaderTableSize != 0 { + conf.MaxDecoderHeaderTableSize = uint32(h2.MaxDecoderHeaderTableSize) + } + if h2.MaxConcurrentStreams != 0 { + conf.MaxConcurrentStreams = uint32(h2.MaxConcurrentStreams) + } + if h2.MaxReadFrameSize != 0 { + conf.MaxReadFrameSize = uint32(h2.MaxReadFrameSize) + } + if h2.MaxReceiveBufferPerConnection != 0 { + conf.MaxUploadBufferPerConnection = int32(h2.MaxReceiveBufferPerConnection) + } + if h2.MaxReceiveBufferPerStream != 0 { + conf.MaxUploadBufferPerStream = int32(h2.MaxReceiveBufferPerStream) + } + if h2.SendPingTimeout != 0 { + conf.SendPingTimeout = h2.SendPingTimeout + } + if h2.PingTimeout != 0 { + conf.PingTimeout = h2.PingTimeout + } + if h2.WriteByteTimeout != 0 { + conf.WriteByteTimeout = h2.WriteByteTimeout + } + if h2.PermitProhibitedCipherSuites { + conf.PermitProhibitedCipherSuites = true + } + if h2.CountError != nil { + conf.CountError = h2.CountError + } +} diff --git a/vendor/golang.org/x/net/http2/config_pre_go124.go b/vendor/golang.org/x/net/http2/config_pre_go124.go new file mode 100644 index 0000000000..060fd6c64c --- /dev/null +++ b/vendor/golang.org/x/net/http2/config_pre_go124.go @@ -0,0 +1,16 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !go1.24 + +package http2 + +import "net/http" + +// Pre-Go 1.24 fallback. +// The Server.HTTP2 and Transport.HTTP2 config fields were added in Go 1.24. + +func fillNetHTTPServerConfig(conf *http2Config, srv *http.Server) {} + +func fillNetHTTPTransportConfig(conf *http2Config, tr *http.Transport) {} diff --git a/vendor/golang.org/x/net/http2/frame.go b/vendor/golang.org/x/net/http2/frame.go index 105c3b279c..81faec7e75 100644 --- a/vendor/golang.org/x/net/http2/frame.go +++ b/vendor/golang.org/x/net/http2/frame.go @@ -1490,7 +1490,7 @@ func (mh *MetaHeadersFrame) checkPseudos() error { pf := mh.PseudoFields() for i, hf := range pf { switch hf.Name { - case ":method", ":path", ":scheme", ":authority": + case ":method", ":path", ":scheme", ":authority", ":protocol": isRequest = true case ":status": isResponse = true @@ -1498,7 +1498,7 @@ func (mh *MetaHeadersFrame) checkPseudos() error { return pseudoHeaderError(hf.Name) } // Check for duplicates. - // This would be a bad algorithm, but N is 4. + // This would be a bad algorithm, but N is 5. // And this doesn't allocate. for _, hf2 := range pf[:i] { if hf.Name == hf2.Name { diff --git a/vendor/golang.org/x/net/http2/http2.go b/vendor/golang.org/x/net/http2/http2.go index 003e649f30..c7601c909f 100644 --- a/vendor/golang.org/x/net/http2/http2.go +++ b/vendor/golang.org/x/net/http2/http2.go @@ -19,8 +19,9 @@ import ( "bufio" "context" "crypto/tls" + "errors" "fmt" - "io" + "net" "net/http" "os" "sort" @@ -33,10 +34,11 @@ import ( ) var ( - VerboseLogs bool - logFrameWrites bool - logFrameReads bool - inTests bool + VerboseLogs bool + logFrameWrites bool + logFrameReads bool + inTests bool + disableExtendedConnectProtocol bool ) func init() { @@ -49,6 +51,9 @@ func init() { logFrameWrites = true logFrameReads = true } + if strings.Contains(e, "http2xconnect=0") { + disableExtendedConnectProtocol = true + } } const ( @@ -140,6 +145,10 @@ func (s Setting) Valid() error { if s.Val < 16384 || s.Val > 1<<24-1 { return ConnectionError(ErrCodeProtocol) } + case SettingEnableConnectProtocol: + if s.Val != 1 && s.Val != 0 { + return ConnectionError(ErrCodeProtocol) + } } return nil } @@ -149,21 +158,23 @@ func (s Setting) Valid() error { type SettingID uint16 const ( - SettingHeaderTableSize SettingID = 0x1 - SettingEnablePush SettingID = 0x2 - SettingMaxConcurrentStreams SettingID = 0x3 - SettingInitialWindowSize SettingID = 0x4 - SettingMaxFrameSize SettingID = 0x5 - SettingMaxHeaderListSize SettingID = 0x6 + SettingHeaderTableSize SettingID = 0x1 + SettingEnablePush SettingID = 0x2 + SettingMaxConcurrentStreams SettingID = 0x3 + SettingInitialWindowSize SettingID = 0x4 + SettingMaxFrameSize SettingID = 0x5 + SettingMaxHeaderListSize SettingID = 0x6 + SettingEnableConnectProtocol SettingID = 0x8 ) var settingName = map[SettingID]string{ - SettingHeaderTableSize: "HEADER_TABLE_SIZE", - SettingEnablePush: "ENABLE_PUSH", - SettingMaxConcurrentStreams: "MAX_CONCURRENT_STREAMS", - SettingInitialWindowSize: "INITIAL_WINDOW_SIZE", - SettingMaxFrameSize: "MAX_FRAME_SIZE", - SettingMaxHeaderListSize: "MAX_HEADER_LIST_SIZE", + SettingHeaderTableSize: "HEADER_TABLE_SIZE", + SettingEnablePush: "ENABLE_PUSH", + SettingMaxConcurrentStreams: "MAX_CONCURRENT_STREAMS", + SettingInitialWindowSize: "INITIAL_WINDOW_SIZE", + SettingMaxFrameSize: "MAX_FRAME_SIZE", + SettingMaxHeaderListSize: "MAX_HEADER_LIST_SIZE", + SettingEnableConnectProtocol: "ENABLE_CONNECT_PROTOCOL", } func (s SettingID) String() string { @@ -237,13 +248,19 @@ func (cw closeWaiter) Wait() { // Its buffered writer is lazily allocated as needed, to minimize // idle memory usage with many connections. type bufferedWriter struct { - _ incomparable - w io.Writer // immutable - bw *bufio.Writer // non-nil when data is buffered + _ incomparable + group synctestGroupInterface // immutable + conn net.Conn // immutable + bw *bufio.Writer // non-nil when data is buffered + byteTimeout time.Duration // immutable, WriteByteTimeout } -func newBufferedWriter(w io.Writer) *bufferedWriter { - return &bufferedWriter{w: w} +func newBufferedWriter(group synctestGroupInterface, conn net.Conn, timeout time.Duration) *bufferedWriter { + return &bufferedWriter{ + group: group, + conn: conn, + byteTimeout: timeout, + } } // bufWriterPoolBufferSize is the size of bufio.Writer's @@ -270,7 +287,7 @@ func (w *bufferedWriter) Available() int { func (w *bufferedWriter) Write(p []byte) (n int, err error) { if w.bw == nil { bw := bufWriterPool.Get().(*bufio.Writer) - bw.Reset(w.w) + bw.Reset((*bufferedWriterTimeoutWriter)(w)) w.bw = bw } return w.bw.Write(p) @@ -288,6 +305,38 @@ func (w *bufferedWriter) Flush() error { return err } +type bufferedWriterTimeoutWriter bufferedWriter + +func (w *bufferedWriterTimeoutWriter) Write(p []byte) (n int, err error) { + return writeWithByteTimeout(w.group, w.conn, w.byteTimeout, p) +} + +// writeWithByteTimeout writes to conn. +// If more than timeout passes without any bytes being written to the connection, +// the write fails. +func writeWithByteTimeout(group synctestGroupInterface, conn net.Conn, timeout time.Duration, p []byte) (n int, err error) { + if timeout <= 0 { + return conn.Write(p) + } + for { + var now time.Time + if group == nil { + now = time.Now() + } else { + now = group.Now() + } + conn.SetWriteDeadline(now.Add(timeout)) + nn, err := conn.Write(p[n:]) + n += nn + if n == len(p) || nn == 0 || !errors.Is(err, os.ErrDeadlineExceeded) { + // Either we finished the write, made no progress, or hit the deadline. + // Whichever it is, we're done now. + conn.SetWriteDeadline(time.Time{}) + return n, err + } + } +} + func mustUint31(v int32) uint32 { if v < 0 || v > 2147483647 { panic("out of range") diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go index 6c349f3ec6..b55547aec6 100644 --- a/vendor/golang.org/x/net/http2/server.go +++ b/vendor/golang.org/x/net/http2/server.go @@ -29,6 +29,7 @@ import ( "bufio" "bytes" "context" + "crypto/rand" "crypto/tls" "errors" "fmt" @@ -52,10 +53,14 @@ import ( ) const ( - prefaceTimeout = 10 * time.Second - firstSettingsTimeout = 2 * time.Second // should be in-flight with preface anyway - handlerChunkWriteSize = 4 << 10 - defaultMaxStreams = 250 // TODO: make this 100 as the GFE seems to? + prefaceTimeout = 10 * time.Second + firstSettingsTimeout = 2 * time.Second // should be in-flight with preface anyway + handlerChunkWriteSize = 4 << 10 + defaultMaxStreams = 250 // TODO: make this 100 as the GFE seems to? + + // maxQueuedControlFrames is the maximum number of control frames like + // SETTINGS, PING and RST_STREAM that will be queued for writing before + // the connection is closed to prevent memory exhaustion attacks. maxQueuedControlFrames = 10000 ) @@ -127,6 +132,22 @@ type Server struct { // If zero or negative, there is no timeout. IdleTimeout time.Duration + // ReadIdleTimeout is the timeout after which a health check using a ping + // frame will be carried out if no frame is received on the connection. + // If zero, no health check is performed. + ReadIdleTimeout time.Duration + + // PingTimeout is the timeout after which the connection will be closed + // if a response to a ping is not received. + // If zero, a default of 15 seconds is used. + PingTimeout time.Duration + + // WriteByteTimeout is the timeout after which a connection will be + // closed if no data can be written to it. The timeout begins when data is + // available to write, and is extended whenever any bytes are written. + // If zero or negative, there is no timeout. + WriteByteTimeout time.Duration + // MaxUploadBufferPerConnection is the size of the initial flow // control window for each connections. The HTTP/2 spec does not // allow this to be smaller than 65535 or larger than 2^32-1. @@ -189,57 +210,6 @@ func (s *Server) afterFunc(d time.Duration, f func()) timer { return timeTimer{time.AfterFunc(d, f)} } -func (s *Server) initialConnRecvWindowSize() int32 { - if s.MaxUploadBufferPerConnection >= initialWindowSize { - return s.MaxUploadBufferPerConnection - } - return 1 << 20 -} - -func (s *Server) initialStreamRecvWindowSize() int32 { - if s.MaxUploadBufferPerStream > 0 { - return s.MaxUploadBufferPerStream - } - return 1 << 20 -} - -func (s *Server) maxReadFrameSize() uint32 { - if v := s.MaxReadFrameSize; v >= minMaxFrameSize && v <= maxFrameSize { - return v - } - return defaultMaxReadFrameSize -} - -func (s *Server) maxConcurrentStreams() uint32 { - if v := s.MaxConcurrentStreams; v > 0 { - return v - } - return defaultMaxStreams -} - -func (s *Server) maxDecoderHeaderTableSize() uint32 { - if v := s.MaxDecoderHeaderTableSize; v > 0 { - return v - } - return initialHeaderTableSize -} - -func (s *Server) maxEncoderHeaderTableSize() uint32 { - if v := s.MaxEncoderHeaderTableSize; v > 0 { - return v - } - return initialHeaderTableSize -} - -// maxQueuedControlFrames is the maximum number of control frames like -// SETTINGS, PING and RST_STREAM that will be queued for writing before -// the connection is closed to prevent memory exhaustion attacks. -func (s *Server) maxQueuedControlFrames() int { - // TODO: if anybody asks, add a Server field, and remember to define the - // behavior of negative values. - return maxQueuedControlFrames -} - type serverInternalState struct { mu sync.Mutex activeConns map[*serverConn]struct{} @@ -336,7 +306,7 @@ func ConfigureServer(s *http.Server, conf *Server) error { if s.TLSNextProto == nil { s.TLSNextProto = map[string]func(*http.Server, *tls.Conn, http.Handler){} } - protoHandler := func(hs *http.Server, c *tls.Conn, h http.Handler) { + protoHandler := func(hs *http.Server, c net.Conn, h http.Handler, sawClientPreface bool) { if testHookOnConn != nil { testHookOnConn() } @@ -353,12 +323,31 @@ func ConfigureServer(s *http.Server, conf *Server) error { ctx = bc.BaseContext() } conf.ServeConn(c, &ServeConnOpts{ - Context: ctx, - Handler: h, - BaseConfig: hs, + Context: ctx, + Handler: h, + BaseConfig: hs, + SawClientPreface: sawClientPreface, }) } - s.TLSNextProto[NextProtoTLS] = protoHandler + s.TLSNextProto[NextProtoTLS] = func(hs *http.Server, c *tls.Conn, h http.Handler) { + protoHandler(hs, c, h, false) + } + // The "unencrypted_http2" TLSNextProto key is used to pass off non-TLS HTTP/2 conns. + // + // A connection passed in this method has already had the HTTP/2 preface read from it. + s.TLSNextProto[nextProtoUnencryptedHTTP2] = func(hs *http.Server, c *tls.Conn, h http.Handler) { + nc, err := unencryptedNetConnFromTLSConn(c) + if err != nil { + if lg := hs.ErrorLog; lg != nil { + lg.Print(err) + } else { + log.Print(err) + } + go c.Close() + return + } + protoHandler(hs, nc, h, true) + } return nil } @@ -440,13 +429,15 @@ func (s *Server) serveConn(c net.Conn, opts *ServeConnOpts, newf func(*serverCon baseCtx, cancel := serverConnBaseContext(c, opts) defer cancel() + http1srv := opts.baseConfig() + conf := configFromServer(http1srv, s) sc := &serverConn{ srv: s, - hs: opts.baseConfig(), + hs: http1srv, conn: c, baseCtx: baseCtx, remoteAddrStr: c.RemoteAddr().String(), - bw: newBufferedWriter(c), + bw: newBufferedWriter(s.group, c, conf.WriteByteTimeout), handler: opts.handler(), streams: make(map[uint32]*stream), readFrameCh: make(chan readFrameResult), @@ -456,9 +447,12 @@ func (s *Server) serveConn(c net.Conn, opts *ServeConnOpts, newf func(*serverCon bodyReadCh: make(chan bodyReadMsg), // buffering doesn't matter either way doneServing: make(chan struct{}), clientMaxStreams: math.MaxUint32, // Section 6.5.2: "Initially, there is no limit to this value" - advMaxStreams: s.maxConcurrentStreams(), + advMaxStreams: conf.MaxConcurrentStreams, initialStreamSendWindowSize: initialWindowSize, + initialStreamRecvWindowSize: conf.MaxUploadBufferPerStream, maxFrameSize: initialMaxFrameSize, + pingTimeout: conf.PingTimeout, + countErrorFunc: conf.CountError, serveG: newGoroutineLock(), pushEnabled: true, sawClientPreface: opts.SawClientPreface, @@ -491,15 +485,15 @@ func (s *Server) serveConn(c net.Conn, opts *ServeConnOpts, newf func(*serverCon sc.flow.add(initialWindowSize) sc.inflow.init(initialWindowSize) sc.hpackEncoder = hpack.NewEncoder(&sc.headerWriteBuf) - sc.hpackEncoder.SetMaxDynamicTableSizeLimit(s.maxEncoderHeaderTableSize()) + sc.hpackEncoder.SetMaxDynamicTableSizeLimit(conf.MaxEncoderHeaderTableSize) fr := NewFramer(sc.bw, c) - if s.CountError != nil { - fr.countError = s.CountError + if conf.CountError != nil { + fr.countError = conf.CountError } - fr.ReadMetaHeaders = hpack.NewDecoder(s.maxDecoderHeaderTableSize(), nil) + fr.ReadMetaHeaders = hpack.NewDecoder(conf.MaxDecoderHeaderTableSize, nil) fr.MaxHeaderListSize = sc.maxHeaderListSize() - fr.SetMaxReadFrameSize(s.maxReadFrameSize()) + fr.SetMaxReadFrameSize(conf.MaxReadFrameSize) sc.framer = fr if tc, ok := c.(connectionStater); ok { @@ -532,7 +526,7 @@ func (s *Server) serveConn(c net.Conn, opts *ServeConnOpts, newf func(*serverCon // So for now, do nothing here again. } - if !s.PermitProhibitedCipherSuites && isBadCipher(sc.tlsState.CipherSuite) { + if !conf.PermitProhibitedCipherSuites && isBadCipher(sc.tlsState.CipherSuite) { // "Endpoints MAY choose to generate a connection error // (Section 5.4.1) of type INADEQUATE_SECURITY if one of // the prohibited cipher suites are negotiated." @@ -569,7 +563,7 @@ func (s *Server) serveConn(c net.Conn, opts *ServeConnOpts, newf func(*serverCon opts.UpgradeRequest = nil } - sc.serve() + sc.serve(conf) } func serverConnBaseContext(c net.Conn, opts *ServeConnOpts) (ctx context.Context, cancel func()) { @@ -609,6 +603,7 @@ type serverConn struct { tlsState *tls.ConnectionState // shared by all handlers, like net/http remoteAddrStr string writeSched WriteScheduler + countErrorFunc func(errType string) // Everything following is owned by the serve loop; use serveG.check(): serveG goroutineLock // used to verify funcs are on serve() @@ -628,6 +623,7 @@ type serverConn struct { streams map[uint32]*stream unstartedHandlers []unstartedHandler initialStreamSendWindowSize int32 + initialStreamRecvWindowSize int32 maxFrameSize int32 peerMaxHeaderListSize uint32 // zero means unknown (default) canonHeader map[string]string // http2-lower-case -> Go-Canonical-Case @@ -638,9 +634,14 @@ type serverConn struct { inGoAway bool // we've started to or sent GOAWAY inFrameScheduleLoop bool // whether we're in the scheduleFrameWrite loop needToSendGoAway bool // we need to schedule a GOAWAY frame write + pingSent bool + sentPingData [8]byte goAwayCode ErrCode shutdownTimer timer // nil until used idleTimer timer // nil if unused + readIdleTimeout time.Duration + pingTimeout time.Duration + readIdleTimer timer // nil if unused // Owned by the writeFrameAsync goroutine: headerWriteBuf bytes.Buffer @@ -655,11 +656,7 @@ func (sc *serverConn) maxHeaderListSize() uint32 { if n <= 0 { n = http.DefaultMaxHeaderBytes } - // http2's count is in a slightly different unit and includes 32 bytes per pair. - // So, take the net/http.Server value and pad it up a bit, assuming 10 headers. - const perFieldOverhead = 32 // per http2 spec - const typicalHeaders = 10 // conservative - return uint32(n + typicalHeaders*perFieldOverhead) + return uint32(adjustHTTP1MaxHeaderSize(int64(n))) } func (sc *serverConn) curOpenStreams() uint32 { @@ -923,7 +920,7 @@ func (sc *serverConn) notePanic() { } } -func (sc *serverConn) serve() { +func (sc *serverConn) serve(conf http2Config) { sc.serveG.check() defer sc.notePanic() defer sc.conn.Close() @@ -935,20 +932,24 @@ func (sc *serverConn) serve() { sc.vlogf("http2: server connection from %v on %p", sc.conn.RemoteAddr(), sc.hs) } + settings := writeSettings{ + {SettingMaxFrameSize, conf.MaxReadFrameSize}, + {SettingMaxConcurrentStreams, sc.advMaxStreams}, + {SettingMaxHeaderListSize, sc.maxHeaderListSize()}, + {SettingHeaderTableSize, conf.MaxDecoderHeaderTableSize}, + {SettingInitialWindowSize, uint32(sc.initialStreamRecvWindowSize)}, + } + if !disableExtendedConnectProtocol { + settings = append(settings, Setting{SettingEnableConnectProtocol, 1}) + } sc.writeFrame(FrameWriteRequest{ - write: writeSettings{ - {SettingMaxFrameSize, sc.srv.maxReadFrameSize()}, - {SettingMaxConcurrentStreams, sc.advMaxStreams}, - {SettingMaxHeaderListSize, sc.maxHeaderListSize()}, - {SettingHeaderTableSize, sc.srv.maxDecoderHeaderTableSize()}, - {SettingInitialWindowSize, uint32(sc.srv.initialStreamRecvWindowSize())}, - }, + write: settings, }) sc.unackedSettings++ // Each connection starts with initialWindowSize inflow tokens. // If a higher value is configured, we add more tokens. - if diff := sc.srv.initialConnRecvWindowSize() - initialWindowSize; diff > 0 { + if diff := conf.MaxUploadBufferPerConnection - initialWindowSize; diff > 0 { sc.sendWindowUpdate(nil, int(diff)) } @@ -968,11 +969,18 @@ func (sc *serverConn) serve() { defer sc.idleTimer.Stop() } + if conf.SendPingTimeout > 0 { + sc.readIdleTimeout = conf.SendPingTimeout + sc.readIdleTimer = sc.srv.afterFunc(conf.SendPingTimeout, sc.onReadIdleTimer) + defer sc.readIdleTimer.Stop() + } + go sc.readFrames() // closed by defer sc.conn.Close above settingsTimer := sc.srv.afterFunc(firstSettingsTimeout, sc.onSettingsTimer) defer settingsTimer.Stop() + lastFrameTime := sc.srv.now() loopNum := 0 for { loopNum++ @@ -986,6 +994,7 @@ func (sc *serverConn) serve() { case res := <-sc.wroteFrameCh: sc.wroteFrame(res) case res := <-sc.readFrameCh: + lastFrameTime = sc.srv.now() // Process any written frames before reading new frames from the client since a // written frame could have triggered a new stream to be started. if sc.writingFrameAsync { @@ -1017,6 +1026,8 @@ func (sc *serverConn) serve() { case idleTimerMsg: sc.vlogf("connection is idle") sc.goAway(ErrCodeNo) + case readIdleTimerMsg: + sc.handlePingTimer(lastFrameTime) case shutdownTimerMsg: sc.vlogf("GOAWAY close timer fired; closing conn from %v", sc.conn.RemoteAddr()) return @@ -1039,7 +1050,7 @@ func (sc *serverConn) serve() { // If the peer is causing us to generate a lot of control frames, // but not reading them from us, assume they are trying to make us // run out of memory. - if sc.queuedControlFrames > sc.srv.maxQueuedControlFrames() { + if sc.queuedControlFrames > maxQueuedControlFrames { sc.vlogf("http2: too many control frames in send queue, closing connection") return } @@ -1055,12 +1066,39 @@ func (sc *serverConn) serve() { } } +func (sc *serverConn) handlePingTimer(lastFrameReadTime time.Time) { + if sc.pingSent { + sc.vlogf("timeout waiting for PING response") + sc.conn.Close() + return + } + + pingAt := lastFrameReadTime.Add(sc.readIdleTimeout) + now := sc.srv.now() + if pingAt.After(now) { + // We received frames since arming the ping timer. + // Reset it for the next possible timeout. + sc.readIdleTimer.Reset(pingAt.Sub(now)) + return + } + + sc.pingSent = true + // Ignore crypto/rand.Read errors: It generally can't fail, and worse case if it does + // is we send a PING frame containing 0s. + _, _ = rand.Read(sc.sentPingData[:]) + sc.writeFrame(FrameWriteRequest{ + write: &writePing{data: sc.sentPingData}, + }) + sc.readIdleTimer.Reset(sc.pingTimeout) +} + type serverMessage int // Message values sent to serveMsgCh. var ( settingsTimerMsg = new(serverMessage) idleTimerMsg = new(serverMessage) + readIdleTimerMsg = new(serverMessage) shutdownTimerMsg = new(serverMessage) gracefulShutdownMsg = new(serverMessage) handlerDoneMsg = new(serverMessage) @@ -1068,6 +1106,7 @@ var ( func (sc *serverConn) onSettingsTimer() { sc.sendServeMsg(settingsTimerMsg) } func (sc *serverConn) onIdleTimer() { sc.sendServeMsg(idleTimerMsg) } +func (sc *serverConn) onReadIdleTimer() { sc.sendServeMsg(readIdleTimerMsg) } func (sc *serverConn) onShutdownTimer() { sc.sendServeMsg(shutdownTimerMsg) } func (sc *serverConn) sendServeMsg(msg interface{}) { @@ -1320,6 +1359,10 @@ func (sc *serverConn) wroteFrame(res frameWriteResult) { sc.writingFrame = false sc.writingFrameAsync = false + if res.err != nil { + sc.conn.Close() + } + wr := res.wr if writeEndsStream(wr.write) { @@ -1594,6 +1637,11 @@ func (sc *serverConn) processFrame(f Frame) error { func (sc *serverConn) processPing(f *PingFrame) error { sc.serveG.check() if f.IsAck() { + if sc.pingSent && sc.sentPingData == f.Data { + // This is a response to a PING we sent. + sc.pingSent = false + sc.readIdleTimer.Reset(sc.readIdleTimeout) + } // 6.7 PING: " An endpoint MUST NOT respond to PING frames // containing this flag." return nil @@ -1757,6 +1805,9 @@ func (sc *serverConn) processSetting(s Setting) error { sc.maxFrameSize = int32(s.Val) // the maximum valid s.Val is < 2^31 case SettingMaxHeaderListSize: sc.peerMaxHeaderListSize = s.Val + case SettingEnableConnectProtocol: + // Receipt of this parameter by a server does not + // have any impact default: // Unknown setting: "An endpoint that receives a SETTINGS // frame with any unknown or unsupported identifier MUST @@ -2160,7 +2211,7 @@ func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream st.cw.Init() st.flow.conn = &sc.flow // link to conn-level counter st.flow.add(sc.initialStreamSendWindowSize) - st.inflow.init(sc.srv.initialStreamRecvWindowSize()) + st.inflow.init(sc.initialStreamRecvWindowSize) if sc.hs.WriteTimeout > 0 { st.writeDeadline = sc.srv.afterFunc(sc.hs.WriteTimeout, st.onWriteTimeout) } @@ -2187,11 +2238,17 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res scheme: f.PseudoValue("scheme"), authority: f.PseudoValue("authority"), path: f.PseudoValue("path"), + protocol: f.PseudoValue("protocol"), + } + + // extended connect is disabled, so we should not see :protocol + if disableExtendedConnectProtocol && rp.protocol != "" { + return nil, nil, sc.countError("bad_connect", streamError(f.StreamID, ErrCodeProtocol)) } isConnect := rp.method == "CONNECT" if isConnect { - if rp.path != "" || rp.scheme != "" || rp.authority == "" { + if rp.protocol == "" && (rp.path != "" || rp.scheme != "" || rp.authority == "") { return nil, nil, sc.countError("bad_connect", streamError(f.StreamID, ErrCodeProtocol)) } } else if rp.method == "" || rp.path == "" || (rp.scheme != "https" && rp.scheme != "http") { @@ -2215,6 +2272,9 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res if rp.authority == "" { rp.authority = rp.header.Get("Host") } + if rp.protocol != "" { + rp.header.Set(":protocol", rp.protocol) + } rw, req, err := sc.newWriterAndRequestNoBody(st, rp) if err != nil { @@ -2241,6 +2301,7 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res type requestParam struct { method string scheme, authority, path string + protocol string header http.Header } @@ -2282,7 +2343,7 @@ func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp requestParam) (*r var url_ *url.URL var requestURI string - if rp.method == "CONNECT" { + if rp.method == "CONNECT" && rp.protocol == "" { url_ = &url.URL{Host: rp.authority} requestURI = rp.authority // mimic HTTP/1 server behavior } else { @@ -2855,6 +2916,11 @@ func (w *responseWriter) SetWriteDeadline(deadline time.Time) error { return nil } +func (w *responseWriter) EnableFullDuplex() error { + // We always support full duplex responses, so this is a no-op. + return nil +} + func (w *responseWriter) Flush() { w.FlushError() } @@ -3301,7 +3367,7 @@ func (sc *serverConn) countError(name string, err error) error { if sc == nil || sc.srv == nil { return err } - f := sc.srv.CountError + f := sc.countErrorFunc if f == nil { return err } diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go index 98a49c6b6e..b2e2ed3373 100644 --- a/vendor/golang.org/x/net/http2/transport.go +++ b/vendor/golang.org/x/net/http2/transport.go @@ -25,7 +25,6 @@ import ( "net/http" "net/http/httptrace" "net/textproto" - "os" "sort" "strconv" "strings" @@ -203,6 +202,20 @@ func (t *Transport) markNewGoroutine() { } } +func (t *Transport) now() time.Time { + if t != nil && t.transportTestHooks != nil { + return t.transportTestHooks.group.Now() + } + return time.Now() +} + +func (t *Transport) timeSince(when time.Time) time.Duration { + if t != nil && t.transportTestHooks != nil { + return t.now().Sub(when) + } + return time.Since(when) +} + // newTimer creates a new time.Timer, or a synthetic timer in tests. func (t *Transport) newTimer(d time.Duration) timer { if t.transportTestHooks != nil { @@ -227,40 +240,26 @@ func (t *Transport) contextWithTimeout(ctx context.Context, d time.Duration) (co } func (t *Transport) maxHeaderListSize() uint32 { - if t.MaxHeaderListSize == 0 { + n := int64(t.MaxHeaderListSize) + if t.t1 != nil && t.t1.MaxResponseHeaderBytes != 0 { + n = t.t1.MaxResponseHeaderBytes + if n > 0 { + n = adjustHTTP1MaxHeaderSize(n) + } + } + if n <= 0 { return 10 << 20 } - if t.MaxHeaderListSize == 0xffffffff { + if n >= 0xffffffff { return 0 } - return t.MaxHeaderListSize -} - -func (t *Transport) maxFrameReadSize() uint32 { - if t.MaxReadFrameSize == 0 { - return 0 // use the default provided by the peer - } - if t.MaxReadFrameSize < minMaxFrameSize { - return minMaxFrameSize - } - if t.MaxReadFrameSize > maxFrameSize { - return maxFrameSize - } - return t.MaxReadFrameSize + return uint32(n) } func (t *Transport) disableCompression() bool { return t.DisableCompression || (t.t1 != nil && t.t1.DisableCompression) } -func (t *Transport) pingTimeout() time.Duration { - if t.PingTimeout == 0 { - return 15 * time.Second - } - return t.PingTimeout - -} - // ConfigureTransport configures a net/http HTTP/1 Transport to use HTTP/2. // It returns an error if t1 has already been HTTP/2-enabled. // @@ -296,8 +295,8 @@ func configureTransports(t1 *http.Transport) (*Transport, error) { if !strSliceContains(t1.TLSClientConfig.NextProtos, "http/1.1") { t1.TLSClientConfig.NextProtos = append(t1.TLSClientConfig.NextProtos, "http/1.1") } - upgradeFn := func(authority string, c *tls.Conn) http.RoundTripper { - addr := authorityAddr("https", authority) + upgradeFn := func(scheme, authority string, c net.Conn) http.RoundTripper { + addr := authorityAddr(scheme, authority) if used, err := connPool.addConnIfNeeded(addr, t2, c); err != nil { go c.Close() return erringRoundTripper{err} @@ -308,18 +307,37 @@ func configureTransports(t1 *http.Transport) (*Transport, error) { // was unknown) go c.Close() } + if scheme == "http" { + return (*unencryptedTransport)(t2) + } return t2 } - if m := t1.TLSNextProto; len(m) == 0 { - t1.TLSNextProto = map[string]func(string, *tls.Conn) http.RoundTripper{ - "h2": upgradeFn, + if t1.TLSNextProto == nil { + t1.TLSNextProto = make(map[string]func(string, *tls.Conn) http.RoundTripper) + } + t1.TLSNextProto[NextProtoTLS] = func(authority string, c *tls.Conn) http.RoundTripper { + return upgradeFn("https", authority, c) + } + // The "unencrypted_http2" TLSNextProto key is used to pass off non-TLS HTTP/2 conns. + t1.TLSNextProto[nextProtoUnencryptedHTTP2] = func(authority string, c *tls.Conn) http.RoundTripper { + nc, err := unencryptedNetConnFromTLSConn(c) + if err != nil { + go c.Close() + return erringRoundTripper{err} } - } else { - m["h2"] = upgradeFn + return upgradeFn("http", authority, nc) } return t2, nil } +// unencryptedTransport is a Transport with a RoundTrip method that +// always permits http:// URLs. +type unencryptedTransport Transport + +func (t *unencryptedTransport) RoundTrip(req *http.Request) (*http.Response, error) { + return (*Transport)(t).RoundTripOpt(req, RoundTripOpt{allowHTTP: true}) +} + func (t *Transport) connPool() ClientConnPool { t.connPoolOnce.Do(t.initConnPool) return t.connPoolOrDef @@ -339,7 +357,7 @@ type ClientConn struct { t *Transport tconn net.Conn // usually *tls.Conn, except specialized impls tlsState *tls.ConnectionState // nil only for specialized impls - reused uint32 // whether conn is being reused; atomic + atomicReused uint32 // whether conn is being reused; atomic singleUse bool // whether being used for a single http.Request getConnCalled bool // used by clientConnPool @@ -350,31 +368,55 @@ type ClientConn struct { idleTimeout time.Duration // or 0 for never idleTimer timer - mu sync.Mutex // guards following - cond *sync.Cond // hold mu; broadcast on flow/closed changes - flow outflow // our conn-level flow control quota (cs.outflow is per stream) - inflow inflow // peer's conn-level flow control - doNotReuse bool // whether conn is marked to not be reused for any future requests - closing bool - closed bool - seenSettings bool // true if we've seen a settings frame, false otherwise - wantSettingsAck bool // we sent a SETTINGS frame and haven't heard back - goAway *GoAwayFrame // if non-nil, the GoAwayFrame we received - goAwayDebug string // goAway frame's debug data, retained as a string - streams map[uint32]*clientStream // client-initiated - streamsReserved int // incr by ReserveNewRequest; decr on RoundTrip - nextStreamID uint32 - pendingRequests int // requests blocked and waiting to be sent because len(streams) == maxConcurrentStreams - pings map[[8]byte]chan struct{} // in flight ping data to notification channel - br *bufio.Reader - lastActive time.Time - lastIdle time.Time // time last idle + mu sync.Mutex // guards following + cond *sync.Cond // hold mu; broadcast on flow/closed changes + flow outflow // our conn-level flow control quota (cs.outflow is per stream) + inflow inflow // peer's conn-level flow control + doNotReuse bool // whether conn is marked to not be reused for any future requests + closing bool + closed bool + closedOnIdle bool // true if conn was closed for idleness + seenSettings bool // true if we've seen a settings frame, false otherwise + seenSettingsChan chan struct{} // closed when seenSettings is true or frame reading fails + wantSettingsAck bool // we sent a SETTINGS frame and haven't heard back + goAway *GoAwayFrame // if non-nil, the GoAwayFrame we received + goAwayDebug string // goAway frame's debug data, retained as a string + streams map[uint32]*clientStream // client-initiated + streamsReserved int // incr by ReserveNewRequest; decr on RoundTrip + nextStreamID uint32 + pendingRequests int // requests blocked and waiting to be sent because len(streams) == maxConcurrentStreams + pings map[[8]byte]chan struct{} // in flight ping data to notification channel + br *bufio.Reader + lastActive time.Time + lastIdle time.Time // time last idle // Settings from peer: (also guarded by wmu) - maxFrameSize uint32 - maxConcurrentStreams uint32 - peerMaxHeaderListSize uint64 - peerMaxHeaderTableSize uint32 - initialWindowSize uint32 + maxFrameSize uint32 + maxConcurrentStreams uint32 + peerMaxHeaderListSize uint64 + peerMaxHeaderTableSize uint32 + initialWindowSize uint32 + initialStreamRecvWindowSize int32 + readIdleTimeout time.Duration + pingTimeout time.Duration + extendedConnectAllowed bool + + // rstStreamPingsBlocked works around an unfortunate gRPC behavior. + // gRPC strictly limits the number of PING frames that it will receive. + // The default is two pings per two hours, but the limit resets every time + // the gRPC endpoint sends a HEADERS or DATA frame. See golang/go#70575. + // + // rstStreamPingsBlocked is set after receiving a response to a PING frame + // bundled with an RST_STREAM (see pendingResets below), and cleared after + // receiving a HEADERS or DATA frame. + rstStreamPingsBlocked bool + + // pendingResets is the number of RST_STREAM frames we have sent to the peer, + // without confirming that the peer has received them. When we send a RST_STREAM, + // we bundle it with a PING frame, unless a PING is already in flight. We count + // the reset stream against the connection's concurrency limit until we get + // a PING response. This limits the number of requests we'll try to send to a + // completely unresponsive connection. + pendingResets int // reqHeaderMu is a 1-element semaphore channel controlling access to sending new requests. // Write to reqHeaderMu to lock it, read from it to unlock. @@ -432,12 +474,12 @@ type clientStream struct { sentHeaders bool // owned by clientConnReadLoop: - firstByte bool // got the first response byte - pastHeaders bool // got first MetaHeadersFrame (actual headers) - pastTrailers bool // got optional second MetaHeadersFrame (trailers) - num1xx uint8 // number of 1xx responses seen - readClosed bool // peer sent an END_STREAM flag - readAborted bool // read loop reset the stream + firstByte bool // got the first response byte + pastHeaders bool // got first MetaHeadersFrame (actual headers) + pastTrailers bool // got optional second MetaHeadersFrame (trailers) + readClosed bool // peer sent an END_STREAM flag + readAborted bool // read loop reset the stream + totalHeaderSize int64 // total size of 1xx headers seen trailer http.Header // accumulated trailers resTrailer *http.Header // client's Response.Trailer @@ -499,6 +541,7 @@ func (cs *clientStream) closeReqBodyLocked() { } type stickyErrWriter struct { + group synctestGroupInterface conn net.Conn timeout time.Duration err *error @@ -508,22 +551,9 @@ func (sew stickyErrWriter) Write(p []byte) (n int, err error) { if *sew.err != nil { return 0, *sew.err } - for { - if sew.timeout != 0 { - sew.conn.SetWriteDeadline(time.Now().Add(sew.timeout)) - } - nn, err := sew.conn.Write(p[n:]) - n += nn - if n < len(p) && nn > 0 && errors.Is(err, os.ErrDeadlineExceeded) { - // Keep extending the deadline so long as we're making progress. - continue - } - if sew.timeout != 0 { - sew.conn.SetWriteDeadline(time.Time{}) - } - *sew.err = err - return n, err - } + n, err = writeWithByteTimeout(sew.group, sew.conn, sew.timeout, p) + *sew.err = err + return n, err } // noCachedConnError is the concrete type of ErrNoCachedConn, which @@ -554,6 +584,8 @@ type RoundTripOpt struct { // no cached connection is available, RoundTripOpt // will return ErrNoCachedConn. OnlyCachedConn bool + + allowHTTP bool // allow http:// URLs } func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) { @@ -586,7 +618,14 @@ func authorityAddr(scheme string, authority string) (addr string) { // RoundTripOpt is like RoundTrip, but takes options. func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) { - if !(req.URL.Scheme == "https" || (req.URL.Scheme == "http" && t.AllowHTTP)) { + switch req.URL.Scheme { + case "https": + // Always okay. + case "http": + if !t.AllowHTTP && !opt.allowHTTP { + return nil, errors.New("http2: unencrypted HTTP/2 not enabled") + } + default: return nil, errors.New("http2: unsupported scheme") } @@ -597,7 +636,7 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res t.vlogf("http2: Transport failed to get client conn for %s: %v", addr, err) return nil, err } - reused := !atomic.CompareAndSwapUint32(&cc.reused, 0, 1) + reused := !atomic.CompareAndSwapUint32(&cc.atomicReused, 0, 1) traceGotConn(req, cc, reused) res, err := cc.RoundTrip(req) if err != nil && retry <= 6 { @@ -622,6 +661,22 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res } } } + if err == errClientConnNotEstablished { + // This ClientConn was created recently, + // this is the first request to use it, + // and the connection is closed and not usable. + // + // In this state, cc.idleTimer will remove the conn from the pool + // when it fires. Stop the timer and remove it here so future requests + // won't try to use this connection. + // + // If the timer has already fired and we're racing it, the redundant + // call to MarkDead is harmless. + if cc.idleTimer != nil { + cc.idleTimer.Stop() + } + t.connPool().MarkDead(cc) + } if err != nil { t.vlogf("RoundTrip failure: %v", err) return nil, err @@ -640,9 +695,10 @@ func (t *Transport) CloseIdleConnections() { } var ( - errClientConnClosed = errors.New("http2: client conn is closed") - errClientConnUnusable = errors.New("http2: client conn not usable") - errClientConnGotGoAway = errors.New("http2: Transport received Server's graceful shutdown GOAWAY") + errClientConnClosed = errors.New("http2: client conn is closed") + errClientConnUnusable = errors.New("http2: client conn not usable") + errClientConnNotEstablished = errors.New("http2: client conn could not be established") + errClientConnGotGoAway = errors.New("http2: Transport received Server's graceful shutdown GOAWAY") ) // shouldRetryRequest is called by RoundTrip when a request fails to get @@ -758,44 +814,38 @@ func (t *Transport) expectContinueTimeout() time.Duration { return t.t1.ExpectContinueTimeout } -func (t *Transport) maxDecoderHeaderTableSize() uint32 { - if v := t.MaxDecoderHeaderTableSize; v > 0 { - return v - } - return initialHeaderTableSize -} - -func (t *Transport) maxEncoderHeaderTableSize() uint32 { - if v := t.MaxEncoderHeaderTableSize; v > 0 { - return v - } - return initialHeaderTableSize -} - func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) { return t.newClientConn(c, t.disableKeepAlives()) } func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, error) { + conf := configFromTransport(t) cc := &ClientConn{ - t: t, - tconn: c, - readerDone: make(chan struct{}), - nextStreamID: 1, - maxFrameSize: 16 << 10, // spec default - initialWindowSize: 65535, // spec default - maxConcurrentStreams: initialMaxConcurrentStreams, // "infinite", per spec. Use a smaller value until we have received server settings. - peerMaxHeaderListSize: 0xffffffffffffffff, // "infinite", per spec. Use 2^64-1 instead. - streams: make(map[uint32]*clientStream), - singleUse: singleUse, - wantSettingsAck: true, - pings: make(map[[8]byte]chan struct{}), - reqHeaderMu: make(chan struct{}, 1), - } + t: t, + tconn: c, + readerDone: make(chan struct{}), + nextStreamID: 1, + maxFrameSize: 16 << 10, // spec default + initialWindowSize: 65535, // spec default + initialStreamRecvWindowSize: conf.MaxUploadBufferPerStream, + maxConcurrentStreams: initialMaxConcurrentStreams, // "infinite", per spec. Use a smaller value until we have received server settings. + peerMaxHeaderListSize: 0xffffffffffffffff, // "infinite", per spec. Use 2^64-1 instead. + streams: make(map[uint32]*clientStream), + singleUse: singleUse, + seenSettingsChan: make(chan struct{}), + wantSettingsAck: true, + readIdleTimeout: conf.SendPingTimeout, + pingTimeout: conf.PingTimeout, + pings: make(map[[8]byte]chan struct{}), + reqHeaderMu: make(chan struct{}, 1), + lastActive: t.now(), + } + var group synctestGroupInterface if t.transportTestHooks != nil { t.markNewGoroutine() t.transportTestHooks.newclientconn(cc) c = cc.tconn + group = t.group } if VerboseLogs { t.vlogf("http2: Transport creating client conn %p to %v", cc, c.RemoteAddr()) @@ -807,30 +857,25 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro // TODO: adjust this writer size to account for frame size + // MTU + crypto/tls record padding. cc.bw = bufio.NewWriter(stickyErrWriter{ + group: group, conn: c, - timeout: t.WriteByteTimeout, + timeout: conf.WriteByteTimeout, err: &cc.werr, }) cc.br = bufio.NewReader(c) cc.fr = NewFramer(cc.bw, cc.br) - if t.maxFrameReadSize() != 0 { - cc.fr.SetMaxReadFrameSize(t.maxFrameReadSize()) - } + cc.fr.SetMaxReadFrameSize(conf.MaxReadFrameSize) if t.CountError != nil { cc.fr.countError = t.CountError } - maxHeaderTableSize := t.maxDecoderHeaderTableSize() + maxHeaderTableSize := conf.MaxDecoderHeaderTableSize cc.fr.ReadMetaHeaders = hpack.NewDecoder(maxHeaderTableSize, nil) cc.fr.MaxHeaderListSize = t.maxHeaderListSize() cc.henc = hpack.NewEncoder(&cc.hbuf) - cc.henc.SetMaxDynamicTableSizeLimit(t.maxEncoderHeaderTableSize()) + cc.henc.SetMaxDynamicTableSizeLimit(conf.MaxEncoderHeaderTableSize) cc.peerMaxHeaderTableSize = initialHeaderTableSize - if t.AllowHTTP { - cc.nextStreamID = 3 - } - if cs, ok := c.(connectionStater); ok { state := cs.ConnectionState() cc.tlsState = &state @@ -838,11 +883,9 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro initialSettings := []Setting{ {ID: SettingEnablePush, Val: 0}, - {ID: SettingInitialWindowSize, Val: transportDefaultStreamFlow}, - } - if max := t.maxFrameReadSize(); max != 0 { - initialSettings = append(initialSettings, Setting{ID: SettingMaxFrameSize, Val: max}) + {ID: SettingInitialWindowSize, Val: uint32(cc.initialStreamRecvWindowSize)}, } + initialSettings = append(initialSettings, Setting{ID: SettingMaxFrameSize, Val: conf.MaxReadFrameSize}) if max := t.maxHeaderListSize(); max != 0 { initialSettings = append(initialSettings, Setting{ID: SettingMaxHeaderListSize, Val: max}) } @@ -852,8 +895,8 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro cc.bw.Write(clientPreface) cc.fr.WriteSettings(initialSettings...) - cc.fr.WriteWindowUpdate(0, transportDefaultConnFlow) - cc.inflow.init(transportDefaultConnFlow + initialWindowSize) + cc.fr.WriteWindowUpdate(0, uint32(conf.MaxUploadBufferPerConnection)) + cc.inflow.init(conf.MaxUploadBufferPerConnection + initialWindowSize) cc.bw.Flush() if cc.werr != nil { cc.Close() @@ -871,7 +914,7 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro } func (cc *ClientConn) healthCheck() { - pingTimeout := cc.t.pingTimeout() + pingTimeout := cc.pingTimeout // We don't need to periodically ping in the health check, because the readLoop of ClientConn will // trigger the healthCheck again if there is no frame received. ctx, cancel := cc.t.contextWithTimeout(context.Background(), pingTimeout) @@ -999,7 +1042,7 @@ func (cc *ClientConn) State() ClientConnState { return ClientConnState{ Closed: cc.closed, Closing: cc.closing || cc.singleUse || cc.doNotReuse || cc.goAway != nil, - StreamsActive: len(cc.streams), + StreamsActive: len(cc.streams) + cc.pendingResets, StreamsReserved: cc.streamsReserved, StreamsPending: cc.pendingRequests, LastIdle: cc.lastIdle, @@ -1031,16 +1074,40 @@ func (cc *ClientConn) idleStateLocked() (st clientConnIdleState) { // writing it. maxConcurrentOkay = true } else { - maxConcurrentOkay = int64(len(cc.streams)+cc.streamsReserved+1) <= int64(cc.maxConcurrentStreams) + // We can take a new request if the total of + // - active streams; + // - reservation slots for new streams; and + // - streams for which we have sent a RST_STREAM and a PING, + // but received no subsequent frame + // is less than the concurrency limit. + maxConcurrentOkay = cc.currentRequestCountLocked() < int(cc.maxConcurrentStreams) } st.canTakeNewRequest = cc.goAway == nil && !cc.closed && !cc.closing && maxConcurrentOkay && !cc.doNotReuse && int64(cc.nextStreamID)+2*int64(cc.pendingRequests) < math.MaxInt32 && !cc.tooIdleLocked() + + // If this connection has never been used for a request and is closed, + // then let it take a request (which will fail). + // If the conn was closed for idleness, we're racing the idle timer; + // don't try to use the conn. (Issue #70515.) + // + // This avoids a situation where an error early in a connection's lifetime + // goes unreported. + if cc.nextStreamID == 1 && cc.streamsReserved == 0 && cc.closed && !cc.closedOnIdle { + st.canTakeNewRequest = true + } + return } +// currentRequestCountLocked reports the number of concurrency slots currently in use, +// including active streams, reserved slots, and reset streams waiting for acknowledgement. +func (cc *ClientConn) currentRequestCountLocked() int { + return len(cc.streams) + cc.streamsReserved + cc.pendingResets +} + func (cc *ClientConn) canTakeNewRequestLocked() bool { st := cc.idleStateLocked() return st.canTakeNewRequest @@ -1053,7 +1120,7 @@ func (cc *ClientConn) tooIdleLocked() bool { // times are compared based on their wall time. We don't want // to reuse a connection that's been sitting idle during // VM/laptop suspend if monotonic time was also frozen. - return cc.idleTimeout != 0 && !cc.lastIdle.IsZero() && time.Since(cc.lastIdle.Round(0)) > cc.idleTimeout + return cc.idleTimeout != 0 && !cc.lastIdle.IsZero() && cc.t.timeSince(cc.lastIdle.Round(0)) > cc.idleTimeout } // onIdleTimeout is called from a time.AfterFunc goroutine. It will @@ -1091,6 +1158,7 @@ func (cc *ClientConn) closeIfIdle() { return } cc.closed = true + cc.closedOnIdle = true nextID := cc.nextStreamID // TODO: do clients send GOAWAY too? maybe? Just Close: cc.mu.Unlock() @@ -1415,6 +1483,8 @@ func (cs *clientStream) doRequest(req *http.Request, streamf func(*clientStream) cs.cleanupWriteRequest(err) } +var errExtendedConnectNotSupported = errors.New("net/http: extended connect not supported by peer") + // writeRequest sends a request. // // It returns nil after the request is written, the response read, @@ -1430,12 +1500,31 @@ func (cs *clientStream) writeRequest(req *http.Request, streamf func(*clientStre return err } + // wait for setting frames to be received, a server can change this value later, + // but we just wait for the first settings frame + var isExtendedConnect bool + if req.Method == "CONNECT" && req.Header.Get(":protocol") != "" { + isExtendedConnect = true + } + // Acquire the new-request lock by writing to reqHeaderMu. // This lock guards the critical section covering allocating a new stream ID // (requires mu) and creating the stream (requires wmu). if cc.reqHeaderMu == nil { panic("RoundTrip on uninitialized ClientConn") // for tests } + if isExtendedConnect { + select { + case <-cs.reqCancel: + return errRequestCanceled + case <-ctx.Done(): + return ctx.Err() + case <-cc.seenSettingsChan: + if !cc.extendedConnectAllowed { + return errExtendedConnectNotSupported + } + } + } select { case cc.reqHeaderMu <- struct{}{}: case <-cs.reqCancel: @@ -1617,6 +1706,7 @@ func (cs *clientStream) cleanupWriteRequest(err error) { cs.reqBodyClosed = make(chan struct{}) } bodyClosed := cs.reqBodyClosed + closeOnIdle := cc.singleUse || cc.doNotReuse || cc.t.disableKeepAlives() || cc.goAway != nil cc.mu.Unlock() if mustCloseBody { cs.reqBody.Close() @@ -1641,16 +1731,44 @@ func (cs *clientStream) cleanupWriteRequest(err error) { if cs.sentHeaders { if se, ok := err.(StreamError); ok { if se.Cause != errFromPeer { - cc.writeStreamReset(cs.ID, se.Code, err) + cc.writeStreamReset(cs.ID, se.Code, false, err) } } else { - cc.writeStreamReset(cs.ID, ErrCodeCancel, err) + // We're cancelling an in-flight request. + // + // This could be due to the server becoming unresponsive. + // To avoid sending too many requests on a dead connection, + // we let the request continue to consume a concurrency slot + // until we can confirm the server is still responding. + // We do this by sending a PING frame along with the RST_STREAM + // (unless a ping is already in flight). + // + // For simplicity, we don't bother tracking the PING payload: + // We reset cc.pendingResets any time we receive a PING ACK. + // + // We skip this if the conn is going to be closed on idle, + // because it's short lived and will probably be closed before + // we get the ping response. + ping := false + if !closeOnIdle { + cc.mu.Lock() + // rstStreamPingsBlocked works around a gRPC behavior: + // see comment on the field for details. + if !cc.rstStreamPingsBlocked { + if cc.pendingResets == 0 { + ping = true + } + cc.pendingResets++ + } + cc.mu.Unlock() + } + cc.writeStreamReset(cs.ID, ErrCodeCancel, ping, err) } } cs.bufPipe.CloseWithError(err) // no-op if already closed } else { if cs.sentHeaders && !cs.sentEndStream { - cc.writeStreamReset(cs.ID, ErrCodeNo, nil) + cc.writeStreamReset(cs.ID, ErrCodeNo, false, nil) } cs.bufPipe.CloseWithError(errRequestCanceled) } @@ -1672,12 +1790,17 @@ func (cs *clientStream) cleanupWriteRequest(err error) { // Must hold cc.mu. func (cc *ClientConn) awaitOpenSlotForStreamLocked(cs *clientStream) error { for { - cc.lastActive = time.Now() + if cc.closed && cc.nextStreamID == 1 && cc.streamsReserved == 0 { + // This is the very first request sent to this connection. + // Return a fatal error which aborts the retry loop. + return errClientConnNotEstablished + } + cc.lastActive = cc.t.now() if cc.closed || !cc.canTakeNewRequestLocked() { return errClientConnUnusable } cc.lastIdle = time.Time{} - if int64(len(cc.streams)) < int64(cc.maxConcurrentStreams) { + if cc.currentRequestCountLocked() < int(cc.maxConcurrentStreams) { return nil } cc.pendingRequests++ @@ -1949,7 +2072,7 @@ func (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error) func validateHeaders(hdrs http.Header) string { for k, vv := range hdrs { - if !httpguts.ValidHeaderFieldName(k) { + if !httpguts.ValidHeaderFieldName(k) && k != ":protocol" { return fmt.Sprintf("name %q", k) } for _, v := range vv { @@ -1965,6 +2088,10 @@ func validateHeaders(hdrs http.Header) string { var errNilRequestURL = errors.New("http2: Request.URI is nil") +func isNormalConnect(req *http.Request) bool { + return req.Method == "CONNECT" && req.Header.Get(":protocol") == "" +} + // requires cc.wmu be held. func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trailers string, contentLength int64) ([]byte, error) { cc.hbuf.Reset() @@ -1985,7 +2112,7 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail } var path string - if req.Method != "CONNECT" { + if !isNormalConnect(req) { path = req.URL.RequestURI() if !validPseudoPath(path) { orig := path @@ -2022,7 +2149,7 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail m = http.MethodGet } f(":method", m) - if req.Method != "CONNECT" { + if !isNormalConnect(req) { f(":path", path) f(":scheme", req.URL.Scheme) } @@ -2203,7 +2330,7 @@ type resAndError struct { func (cc *ClientConn) addStreamLocked(cs *clientStream) { cs.flow.add(int32(cc.initialWindowSize)) cs.flow.setConnFlow(&cc.flow) - cs.inflow.init(transportDefaultStreamFlow) + cs.inflow.init(cc.initialStreamRecvWindowSize) cs.ID = cc.nextStreamID cc.nextStreamID += 2 cc.streams[cs.ID] = cs @@ -2219,10 +2346,10 @@ func (cc *ClientConn) forgetStreamID(id uint32) { if len(cc.streams) != slen-1 { panic("forgetting unknown stream id") } - cc.lastActive = time.Now() + cc.lastActive = cc.t.now() if len(cc.streams) == 0 && cc.idleTimer != nil { cc.idleTimer.Reset(cc.idleTimeout) - cc.lastIdle = time.Now() + cc.lastIdle = cc.t.now() } // Wake up writeRequestBody via clientStream.awaitFlowControl and // wake up RoundTrip if there is a pending request. @@ -2282,7 +2409,6 @@ func isEOFOrNetReadError(err error) bool { func (rl *clientConnReadLoop) cleanup() { cc := rl.cc - cc.t.connPool().MarkDead(cc) defer cc.closeConn() defer close(cc.readerDone) @@ -2306,6 +2432,27 @@ func (rl *clientConnReadLoop) cleanup() { } cc.closed = true + // If the connection has never been used, and has been open for only a short time, + // leave it in the connection pool for a little while. + // + // This avoids a situation where new connections are constantly created, + // added to the pool, fail, and are removed from the pool, without any error + // being surfaced to the user. + unusedWaitTime := 5 * time.Second + if cc.idleTimeout > 0 && unusedWaitTime > cc.idleTimeout { + unusedWaitTime = cc.idleTimeout + } + idleTime := cc.t.now().Sub(cc.lastActive) + if atomic.LoadUint32(&cc.atomicReused) == 0 && idleTime < unusedWaitTime && !cc.closedOnIdle { + cc.idleTimer = cc.t.afterFunc(unusedWaitTime-idleTime, func() { + cc.t.connPool().MarkDead(cc) + }) + } else { + cc.mu.Unlock() // avoid any deadlocks in MarkDead + cc.t.connPool().MarkDead(cc) + cc.mu.Lock() + } + for _, cs := range cc.streams { select { case <-cs.peerClosed: @@ -2349,7 +2496,7 @@ func (cc *ClientConn) countReadFrameError(err error) { func (rl *clientConnReadLoop) run() error { cc := rl.cc gotSettings := false - readIdleTimeout := cc.t.ReadIdleTimeout + readIdleTimeout := cc.readIdleTimeout var t timer if readIdleTimeout != 0 { t = cc.t.afterFunc(readIdleTimeout, cc.healthCheck) @@ -2363,7 +2510,7 @@ func (rl *clientConnReadLoop) run() error { cc.vlogf("http2: Transport readFrame error on conn %p: (%T) %v", cc, err, err) } if se, ok := err.(StreamError); ok { - if cs := rl.streamByID(se.StreamID); cs != nil { + if cs := rl.streamByID(se.StreamID, notHeaderOrDataFrame); cs != nil { if se.Cause == nil { se.Cause = cc.fr.errDetail } @@ -2409,13 +2556,16 @@ func (rl *clientConnReadLoop) run() error { if VerboseLogs { cc.vlogf("http2: Transport conn %p received error from processing frame %v: %v", cc, summarizeFrame(f), err) } + if !cc.seenSettings { + close(cc.seenSettingsChan) + } return err } } } func (rl *clientConnReadLoop) processHeaders(f *MetaHeadersFrame) error { - cs := rl.streamByID(f.StreamID) + cs := rl.streamByID(f.StreamID, headerOrDataFrame) if cs == nil { // We'd get here if we canceled a request while the // server had its response still in flight. So if this @@ -2533,15 +2683,34 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra if f.StreamEnded() { return nil, errors.New("1xx informational response with END_STREAM flag") } - cs.num1xx++ - const max1xxResponses = 5 // arbitrary bound on number of informational responses, same as net/http - if cs.num1xx > max1xxResponses { - return nil, errors.New("http2: too many 1xx informational responses") - } if fn := cs.get1xxTraceFunc(); fn != nil { + // If the 1xx response is being delivered to the user, + // then they're responsible for limiting the number + // of responses. if err := fn(statusCode, textproto.MIMEHeader(header)); err != nil { return nil, err } + } else { + // If the user didn't examine the 1xx response, then we + // limit the size of all 1xx headers. + // + // This differs a bit from the HTTP/1 implementation, which + // limits the size of all 1xx headers plus the final response. + // Use the larger limit of MaxHeaderListSize and + // net/http.Transport.MaxResponseHeaderBytes. + limit := int64(cs.cc.t.maxHeaderListSize()) + if t1 := cs.cc.t.t1; t1 != nil && t1.MaxResponseHeaderBytes > limit { + limit = t1.MaxResponseHeaderBytes + } + for _, h := range f.Fields { + cs.totalHeaderSize += int64(h.Size()) + } + if cs.totalHeaderSize > limit { + if VerboseLogs { + log.Printf("http2: 1xx informational responses too large") + } + return nil, errors.New("header list too large") + } } if statusCode == 100 { traceGot100Continue(cs.trace) @@ -2725,7 +2894,7 @@ func (b transportResponseBody) Close() error { func (rl *clientConnReadLoop) processData(f *DataFrame) error { cc := rl.cc - cs := rl.streamByID(f.StreamID) + cs := rl.streamByID(f.StreamID, headerOrDataFrame) data := f.Data() if cs == nil { cc.mu.Lock() @@ -2860,9 +3029,22 @@ func (rl *clientConnReadLoop) endStreamError(cs *clientStream, err error) { cs.abortStream(err) } -func (rl *clientConnReadLoop) streamByID(id uint32) *clientStream { +// Constants passed to streamByID for documentation purposes. +const ( + headerOrDataFrame = true + notHeaderOrDataFrame = false +) + +// streamByID returns the stream with the given id, or nil if no stream has that id. +// If headerOrData is true, it clears rst.StreamPingsBlocked. +func (rl *clientConnReadLoop) streamByID(id uint32, headerOrData bool) *clientStream { rl.cc.mu.Lock() defer rl.cc.mu.Unlock() + if headerOrData { + // Work around an unfortunate gRPC behavior. + // See comment on ClientConn.rstStreamPingsBlocked for details. + rl.cc.rstStreamPingsBlocked = false + } cs := rl.cc.streams[id] if cs != nil && !cs.readAborted { return cs @@ -2956,6 +3138,21 @@ func (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error { case SettingHeaderTableSize: cc.henc.SetMaxDynamicTableSize(s.Val) cc.peerMaxHeaderTableSize = s.Val + case SettingEnableConnectProtocol: + if err := s.Valid(); err != nil { + return err + } + // If the peer wants to send us SETTINGS_ENABLE_CONNECT_PROTOCOL, + // we require that it do so in the first SETTINGS frame. + // + // When we attempt to use extended CONNECT, we wait for the first + // SETTINGS frame to see if the server supports it. If we let the + // server enable the feature with a later SETTINGS frame, then + // users will see inconsistent results depending on whether we've + // seen that frame or not. + if !cc.seenSettings { + cc.extendedConnectAllowed = s.Val == 1 + } default: cc.vlogf("Unhandled Setting: %v", s) } @@ -2973,6 +3170,7 @@ func (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error { // connection can establish to our default. cc.maxConcurrentStreams = defaultMaxConcurrentStreams } + close(cc.seenSettingsChan) cc.seenSettings = true } @@ -2981,7 +3179,7 @@ func (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error { func (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error { cc := rl.cc - cs := rl.streamByID(f.StreamID) + cs := rl.streamByID(f.StreamID, notHeaderOrDataFrame) if f.StreamID != 0 && cs == nil { return nil } @@ -3010,7 +3208,7 @@ func (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error { } func (rl *clientConnReadLoop) processResetStream(f *RSTStreamFrame) error { - cs := rl.streamByID(f.StreamID) + cs := rl.streamByID(f.StreamID, notHeaderOrDataFrame) if cs == nil { // TODO: return error if server tries to RST_STREAM an idle stream return nil @@ -3085,6 +3283,12 @@ func (rl *clientConnReadLoop) processPing(f *PingFrame) error { close(c) delete(cc.pings, f.Data) } + if cc.pendingResets > 0 { + // See clientStream.cleanupWriteRequest. + cc.pendingResets = 0 + cc.rstStreamPingsBlocked = true + cc.cond.Broadcast() + } return nil } cc := rl.cc @@ -3107,13 +3311,20 @@ func (rl *clientConnReadLoop) processPushPromise(f *PushPromiseFrame) error { return ConnectionError(ErrCodeProtocol) } -func (cc *ClientConn) writeStreamReset(streamID uint32, code ErrCode, err error) { +// writeStreamReset sends a RST_STREAM frame. +// When ping is true, it also sends a PING frame with a random payload. +func (cc *ClientConn) writeStreamReset(streamID uint32, code ErrCode, ping bool, err error) { // TODO: map err to more interesting error codes, once the // HTTP community comes up with some. But currently for // RST_STREAM there's no equivalent to GOAWAY frame's debug // data, and the error codes are all pretty vague ("cancel"). cc.wmu.Lock() cc.fr.WriteRSTStream(streamID, code) + if ping { + var payload [8]byte + rand.Read(payload[:]) + cc.fr.WritePing(false, payload) + } cc.bw.Flush() cc.wmu.Unlock() } @@ -3267,7 +3478,7 @@ func traceGotConn(req *http.Request, cc *ClientConn, reused bool) { cc.mu.Lock() ci.WasIdle = len(cc.streams) == 0 && reused if ci.WasIdle && !cc.lastActive.IsZero() { - ci.IdleTime = time.Since(cc.lastActive) + ci.IdleTime = cc.t.timeSince(cc.lastActive) } cc.mu.Unlock() diff --git a/vendor/golang.org/x/net/http2/unencrypted.go b/vendor/golang.org/x/net/http2/unencrypted.go new file mode 100644 index 0000000000..b2de211613 --- /dev/null +++ b/vendor/golang.org/x/net/http2/unencrypted.go @@ -0,0 +1,32 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package http2 + +import ( + "crypto/tls" + "errors" + "net" +) + +const nextProtoUnencryptedHTTP2 = "unencrypted_http2" + +// unencryptedNetConnFromTLSConn retrieves a net.Conn wrapped in a *tls.Conn. +// +// TLSNextProto functions accept a *tls.Conn. +// +// When passing an unencrypted HTTP/2 connection to a TLSNextProto function, +// we pass a *tls.Conn with an underlying net.Conn containing the unencrypted connection. +// To be extra careful about mistakes (accidentally dropping TLS encryption in a place +// where we want it), the tls.Conn contains a net.Conn with an UnencryptedNetConn method +// that returns the actual connection we want to use. +func unencryptedNetConnFromTLSConn(tc *tls.Conn) (net.Conn, error) { + conner, ok := tc.NetConn().(interface { + UnencryptedNetConn() net.Conn + }) + if !ok { + return nil, errors.New("http2: TLS conn unexpectedly found in unencrypted handoff") + } + return conner.UnencryptedNetConn(), nil +} diff --git a/vendor/golang.org/x/net/http2/write.go b/vendor/golang.org/x/net/http2/write.go index 33f61398a1..6ff6bee7e9 100644 --- a/vendor/golang.org/x/net/http2/write.go +++ b/vendor/golang.org/x/net/http2/write.go @@ -131,6 +131,16 @@ func (se StreamError) writeFrame(ctx writeContext) error { func (se StreamError) staysWithinBuffer(max int) bool { return frameHeaderLen+4 <= max } +type writePing struct { + data [8]byte +} + +func (w writePing) writeFrame(ctx writeContext) error { + return ctx.Framer().WritePing(false, w.data) +} + +func (w writePing) staysWithinBuffer(max int) bool { return frameHeaderLen+len(w.data) <= max } + type writePingAck struct{ pf *PingFrame } func (w writePingAck) writeFrame(ctx writeContext) error { diff --git a/vendor/golang.org/x/sync/LICENSE b/vendor/golang.org/x/sync/LICENSE index 6a66aea5ea..2a7cf70da6 100644 --- a/vendor/golang.org/x/sync/LICENSE +++ b/vendor/golang.org/x/sync/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. +Copyright 2009 The Go Authors. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer. copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Google Inc. nor the names of its + * Neither the name of Google LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. diff --git a/vendor/golang.org/x/sys/LICENSE b/vendor/golang.org/x/sys/LICENSE index 6a66aea5ea..2a7cf70da6 100644 --- a/vendor/golang.org/x/sys/LICENSE +++ b/vendor/golang.org/x/sys/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. +Copyright 2009 The Go Authors. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer. copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Google Inc. nor the names of its + * Neither the name of Google LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. diff --git a/vendor/golang.org/x/sys/unix/README.md b/vendor/golang.org/x/sys/unix/README.md index 7d3c060e12..6e08a76a71 100644 --- a/vendor/golang.org/x/sys/unix/README.md +++ b/vendor/golang.org/x/sys/unix/README.md @@ -156,7 +156,7 @@ from the generated architecture-specific files listed below, and merge these into a common file for each OS. The merge is performed in the following steps: -1. Construct the set of common code that is idential in all architecture-specific files. +1. Construct the set of common code that is identical in all architecture-specific files. 2. Write this common code to the merged file. 3. Remove the common code from all architecture-specific files. diff --git a/vendor/golang.org/x/sys/unix/ioctl_linux.go b/vendor/golang.org/x/sys/unix/ioctl_linux.go index dbe680eab8..7ca4fa12aa 100644 --- a/vendor/golang.org/x/sys/unix/ioctl_linux.go +++ b/vendor/golang.org/x/sys/unix/ioctl_linux.go @@ -58,6 +58,102 @@ func IoctlGetEthtoolDrvinfo(fd int, ifname string) (*EthtoolDrvinfo, error) { return &value, err } +// IoctlGetEthtoolTsInfo fetches ethtool timestamping and PHC +// association for the network device specified by ifname. +func IoctlGetEthtoolTsInfo(fd int, ifname string) (*EthtoolTsInfo, error) { + ifr, err := NewIfreq(ifname) + if err != nil { + return nil, err + } + + value := EthtoolTsInfo{Cmd: ETHTOOL_GET_TS_INFO} + ifrd := ifr.withData(unsafe.Pointer(&value)) + + err = ioctlIfreqData(fd, SIOCETHTOOL, &ifrd) + return &value, err +} + +// IoctlGetHwTstamp retrieves the hardware timestamping configuration +// for the network device specified by ifname. +func IoctlGetHwTstamp(fd int, ifname string) (*HwTstampConfig, error) { + ifr, err := NewIfreq(ifname) + if err != nil { + return nil, err + } + + value := HwTstampConfig{} + ifrd := ifr.withData(unsafe.Pointer(&value)) + + err = ioctlIfreqData(fd, SIOCGHWTSTAMP, &ifrd) + return &value, err +} + +// IoctlSetHwTstamp updates the hardware timestamping configuration for +// the network device specified by ifname. +func IoctlSetHwTstamp(fd int, ifname string, cfg *HwTstampConfig) error { + ifr, err := NewIfreq(ifname) + if err != nil { + return err + } + ifrd := ifr.withData(unsafe.Pointer(cfg)) + return ioctlIfreqData(fd, SIOCSHWTSTAMP, &ifrd) +} + +// FdToClockID derives the clock ID from the file descriptor number +// - see clock_gettime(3), FD_TO_CLOCKID macros. The resulting ID is +// suitable for system calls like ClockGettime. +func FdToClockID(fd int) int32 { return int32((int(^fd) << 3) | 3) } + +// IoctlPtpClockGetcaps returns the description of a given PTP device. +func IoctlPtpClockGetcaps(fd int) (*PtpClockCaps, error) { + var value PtpClockCaps + err := ioctlPtr(fd, PTP_CLOCK_GETCAPS2, unsafe.Pointer(&value)) + return &value, err +} + +// IoctlPtpSysOffsetPrecise returns a description of the clock +// offset compared to the system clock. +func IoctlPtpSysOffsetPrecise(fd int) (*PtpSysOffsetPrecise, error) { + var value PtpSysOffsetPrecise + err := ioctlPtr(fd, PTP_SYS_OFFSET_PRECISE2, unsafe.Pointer(&value)) + return &value, err +} + +// IoctlPtpSysOffsetExtended returns an extended description of the +// clock offset compared to the system clock. The samples parameter +// specifies the desired number of measurements. +func IoctlPtpSysOffsetExtended(fd int, samples uint) (*PtpSysOffsetExtended, error) { + value := PtpSysOffsetExtended{Samples: uint32(samples)} + err := ioctlPtr(fd, PTP_SYS_OFFSET_EXTENDED2, unsafe.Pointer(&value)) + return &value, err +} + +// IoctlPtpPinGetfunc returns the configuration of the specified +// I/O pin on given PTP device. +func IoctlPtpPinGetfunc(fd int, index uint) (*PtpPinDesc, error) { + value := PtpPinDesc{Index: uint32(index)} + err := ioctlPtr(fd, PTP_PIN_GETFUNC2, unsafe.Pointer(&value)) + return &value, err +} + +// IoctlPtpPinSetfunc updates configuration of the specified PTP +// I/O pin. +func IoctlPtpPinSetfunc(fd int, pd *PtpPinDesc) error { + return ioctlPtr(fd, PTP_PIN_SETFUNC2, unsafe.Pointer(pd)) +} + +// IoctlPtpPeroutRequest configures the periodic output mode of the +// PTP I/O pins. +func IoctlPtpPeroutRequest(fd int, r *PtpPeroutRequest) error { + return ioctlPtr(fd, PTP_PEROUT_REQUEST2, unsafe.Pointer(r)) +} + +// IoctlPtpExttsRequest configures the external timestamping mode +// of the PTP I/O pins. +func IoctlPtpExttsRequest(fd int, r *PtpExttsRequest) error { + return ioctlPtr(fd, PTP_EXTTS_REQUEST2, unsafe.Pointer(r)) +} + // IoctlGetWatchdogInfo fetches information about a watchdog device from the // Linux watchdog API. For more information, see: // https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html. diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh index 4ed2e488b6..6ab02b6c31 100644 --- a/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -58,6 +58,7 @@ includes_Darwin=' #define _DARWIN_USE_64_BIT_INODE #define __APPLE_USE_RFC_3542 #include +#include #include #include #include @@ -157,6 +158,16 @@ includes_Linux=' #endif #define _GNU_SOURCE +// See the description in unix/linux/types.go +#if defined(__ARM_EABI__) || \ + (defined(__mips__) && (_MIPS_SIM == _ABIO32)) || \ + (defined(__powerpc__) && (!defined(__powerpc64__))) +# ifdef _TIME_BITS +# undef _TIME_BITS +# endif +# define _TIME_BITS 32 +#endif + // is broken on powerpc64, as it fails to include definitions of // these structures. We just include them copied from . #if defined(__powerpc__) @@ -255,6 +266,7 @@ struct ltchars { #include #include #include +#include #include #include #include @@ -526,6 +538,7 @@ ccflags="$@" $2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MREMAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL|TCPOPT|UDP)_/ || $2 ~ /^NFC_(GENL|PROTO|COMM|RF|SE|DIRECTION|LLCP|SOCKPROTO)_/ || $2 ~ /^NFC_.*_(MAX)?SIZE$/ || + $2 ~ /^PTP_/ || $2 ~ /^RAW_PAYLOAD_/ || $2 ~ /^[US]F_/ || $2 ~ /^TP_STATUS_/ || @@ -551,6 +564,7 @@ ccflags="$@" $2 !~ /^RTC_VL_(ACCURACY|BACKUP|DATA)/ && $2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTC|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P|NETNSA)_/ || $2 ~ /^SOCK_|SK_DIAG_|SKNLGRP_$/ || + $2 ~ /^(CONNECT|SAE)_/ || $2 ~ /^FIORDCHK$/ || $2 ~ /^SIOC/ || $2 ~ /^TIOC/ || @@ -654,7 +668,7 @@ errors=$( signals=$( echo '#include ' | $CC -x c - -E -dM $ccflags | awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' | - grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT\|SIGMAX64' | + grep -E -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' | sort ) @@ -664,7 +678,7 @@ echo '#include ' | $CC -x c - -E -dM $ccflags | sort >_error.grep echo '#include ' | $CC -x c - -E -dM $ccflags | awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' | - grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT\|SIGMAX64' | + grep -E -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' | sort >_signal.grep echo '// mkerrors.sh' "$@" diff --git a/vendor/golang.org/x/sys/unix/mremap.go b/vendor/golang.org/x/sys/unix/mremap.go index fd45fe529d..3a5e776f89 100644 --- a/vendor/golang.org/x/sys/unix/mremap.go +++ b/vendor/golang.org/x/sys/unix/mremap.go @@ -50,3 +50,8 @@ func (m *mremapMmapper) Mremap(oldData []byte, newLength int, flags int) (data [ func Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) { return mapper.Mremap(oldData, newLength, flags) } + +func MremapPtr(oldAddr unsafe.Pointer, oldSize uintptr, newAddr unsafe.Pointer, newSize uintptr, flags int) (ret unsafe.Pointer, err error) { + xaddr, err := mapper.mremap(uintptr(oldAddr), oldSize, newSize, flags, uintptr(newAddr)) + return unsafe.Pointer(xaddr), err +} diff --git a/vendor/golang.org/x/sys/unix/syscall_aix.go b/vendor/golang.org/x/sys/unix/syscall_aix.go index 67ce6cef2d..6f15ba1eaf 100644 --- a/vendor/golang.org/x/sys/unix/syscall_aix.go +++ b/vendor/golang.org/x/sys/unix/syscall_aix.go @@ -360,7 +360,7 @@ func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, var status _C_int var r Pid_t err = ERESTART - // AIX wait4 may return with ERESTART errno, while the processus is still + // AIX wait4 may return with ERESTART errno, while the process is still // active. for err == ERESTART { r, err = wait4(Pid_t(pid), &status, options, rusage) diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin.go b/vendor/golang.org/x/sys/unix/syscall_darwin.go index 59542a897d..099867deed 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin.go @@ -402,6 +402,18 @@ func IoctlSetIfreqMTU(fd int, ifreq *IfreqMTU) error { return ioctlPtr(fd, SIOCSIFMTU, unsafe.Pointer(ifreq)) } +//sys renamexNp(from string, to string, flag uint32) (err error) + +func RenamexNp(from string, to string, flag uint32) (err error) { + return renamexNp(from, to, flag) +} + +//sys renameatxNp(fromfd int, from string, tofd int, to string, flag uint32) (err error) + +func RenameatxNp(fromfd int, from string, tofd int, to string, flag uint32) (err error) { + return renameatxNp(fromfd, from, tofd, to, flag) +} + //sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS_SYSCTL func Uname(uname *Utsname) error { @@ -542,6 +554,55 @@ func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) { } } +//sys pthread_chdir_np(path string) (err error) + +func PthreadChdir(path string) (err error) { + return pthread_chdir_np(path) +} + +//sys pthread_fchdir_np(fd int) (err error) + +func PthreadFchdir(fd int) (err error) { + return pthread_fchdir_np(fd) +} + +// Connectx calls connectx(2) to initiate a connection on a socket. +// +// srcIf, srcAddr, and dstAddr are filled into a [SaEndpoints] struct and passed as the endpoints argument. +// +// - srcIf is the optional source interface index. 0 means unspecified. +// - srcAddr is the optional source address. nil means unspecified. +// - dstAddr is the destination address. +// +// On success, Connectx returns the number of bytes enqueued for transmission. +func Connectx(fd int, srcIf uint32, srcAddr, dstAddr Sockaddr, associd SaeAssocID, flags uint32, iov []Iovec, connid *SaeConnID) (n uintptr, err error) { + endpoints := SaEndpoints{ + Srcif: srcIf, + } + + if srcAddr != nil { + addrp, addrlen, err := srcAddr.sockaddr() + if err != nil { + return 0, err + } + endpoints.Srcaddr = (*RawSockaddr)(addrp) + endpoints.Srcaddrlen = uint32(addrlen) + } + + if dstAddr != nil { + addrp, addrlen, err := dstAddr.sockaddr() + if err != nil { + return 0, err + } + endpoints.Dstaddr = (*RawSockaddr)(addrp) + endpoints.Dstaddrlen = uint32(addrlen) + } + + err = connectx(fd, &endpoints, associd, flags, iov, &n, connid) + return +} + +//sys connectx(fd int, endpoints *SaEndpoints, associd SaeAssocID, flags uint32, iov []Iovec, n *uintptr, connid *SaeConnID) (err error) //sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) //sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_dragonfly.go b/vendor/golang.org/x/sys/unix/syscall_dragonfly.go index 97cb916f2c..be8c002070 100644 --- a/vendor/golang.org/x/sys/unix/syscall_dragonfly.go +++ b/vendor/golang.org/x/sys/unix/syscall_dragonfly.go @@ -246,6 +246,18 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e return sendfile(outfd, infd, offset, count) } +func Dup3(oldfd, newfd, flags int) error { + if oldfd == newfd || flags&^O_CLOEXEC != 0 { + return EINVAL + } + how := F_DUP2FD + if flags&O_CLOEXEC != 0 { + how = F_DUP2FD_CLOEXEC + } + _, err := fcntl(oldfd, how, newfd) + return err +} + /* * Exposed directly */ diff --git a/vendor/golang.org/x/sys/unix/syscall_hurd.go b/vendor/golang.org/x/sys/unix/syscall_hurd.go index ba46651f8e..a6a2d2fc2b 100644 --- a/vendor/golang.org/x/sys/unix/syscall_hurd.go +++ b/vendor/golang.org/x/sys/unix/syscall_hurd.go @@ -11,6 +11,7 @@ package unix int ioctl(int, unsigned long int, uintptr_t); */ import "C" +import "unsafe" func ioctl(fd int, req uint, arg uintptr) (err error) { r0, er := C.ioctl(C.int(fd), C.ulong(req), C.uintptr_t(arg)) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go index 5682e2628a..230a94549a 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -1295,6 +1295,48 @@ func GetsockoptTCPInfo(fd, level, opt int) (*TCPInfo, error) { return &value, err } +// GetsockoptTCPCCVegasInfo returns algorithm specific congestion control information for a socket using the "vegas" +// algorithm. +// +// The socket's congestion control algorighm can be retrieved via [GetsockoptString] with the [TCP_CONGESTION] option: +// +// algo, err := unix.GetsockoptString(fd, unix.IPPROTO_TCP, unix.TCP_CONGESTION) +func GetsockoptTCPCCVegasInfo(fd, level, opt int) (*TCPVegasInfo, error) { + var value [SizeofTCPCCInfo / 4]uint32 // ensure proper alignment + vallen := _Socklen(SizeofTCPCCInfo) + err := getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen) + out := (*TCPVegasInfo)(unsafe.Pointer(&value[0])) + return out, err +} + +// GetsockoptTCPCCDCTCPInfo returns algorithm specific congestion control information for a socket using the "dctp" +// algorithm. +// +// The socket's congestion control algorighm can be retrieved via [GetsockoptString] with the [TCP_CONGESTION] option: +// +// algo, err := unix.GetsockoptString(fd, unix.IPPROTO_TCP, unix.TCP_CONGESTION) +func GetsockoptTCPCCDCTCPInfo(fd, level, opt int) (*TCPDCTCPInfo, error) { + var value [SizeofTCPCCInfo / 4]uint32 // ensure proper alignment + vallen := _Socklen(SizeofTCPCCInfo) + err := getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen) + out := (*TCPDCTCPInfo)(unsafe.Pointer(&value[0])) + return out, err +} + +// GetsockoptTCPCCBBRInfo returns algorithm specific congestion control information for a socket using the "bbr" +// algorithm. +// +// The socket's congestion control algorighm can be retrieved via [GetsockoptString] with the [TCP_CONGESTION] option: +// +// algo, err := unix.GetsockoptString(fd, unix.IPPROTO_TCP, unix.TCP_CONGESTION) +func GetsockoptTCPCCBBRInfo(fd, level, opt int) (*TCPBBRInfo, error) { + var value [SizeofTCPCCInfo / 4]uint32 // ensure proper alignment + vallen := _Socklen(SizeofTCPCCInfo) + err := getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen) + out := (*TCPBBRInfo)(unsafe.Pointer(&value[0])) + return out, err +} + // GetsockoptString returns the string value of the socket option opt for the // socket associated with fd at the given socket level. func GetsockoptString(fd, level, opt int) (string, error) { @@ -1818,6 +1860,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e //sys ClockAdjtime(clockid int32, buf *Timex) (state int, err error) //sys ClockGetres(clockid int32, res *Timespec) (err error) //sys ClockGettime(clockid int32, time *Timespec) (err error) +//sys ClockSettime(clockid int32, time *Timespec) (err error) //sys ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) //sys Close(fd int) (err error) //sys CloseRange(first uint, last uint, flags uint) (err error) @@ -1959,7 +2002,26 @@ func Getpgrp() (pid int) { //sysnb Getpid() (pid int) //sysnb Getppid() (ppid int) //sys Getpriority(which int, who int) (prio int, err error) -//sys Getrandom(buf []byte, flags int) (n int, err error) + +func Getrandom(buf []byte, flags int) (n int, err error) { + vdsoRet, supported := vgetrandom(buf, uint32(flags)) + if supported { + if vdsoRet < 0 { + return 0, errnoErr(syscall.Errno(-vdsoRet)) + } + return vdsoRet, nil + } + var p *byte + if len(buf) > 0 { + p = &buf[0] + } + r, _, e := Syscall(SYS_GETRANDOM, uintptr(unsafe.Pointer(p)), uintptr(len(buf)), uintptr(flags)) + if e != 0 { + return 0, errnoErr(e) + } + return int(r), nil +} + //sysnb Getrusage(who int, rusage *Rusage) (err error) //sysnb Getsid(pid int) (sid int, err error) //sysnb Gettid() (tid int) @@ -2592,3 +2654,4 @@ func SchedGetAttr(pid int, flags uint) (*SchedAttr, error) { } //sys Cachestat(fd uint, crange *CachestatRange, cstat *Cachestat_t, flags uint) (err error) +//sys Mseal(b []byte, flags uint) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go b/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go index cf2ee6c75e..745e5c7e6c 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go @@ -182,3 +182,5 @@ func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error } return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags) } + +const SYS_FSTATAT = SYS_NEWFSTATAT diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_loong64.go b/vendor/golang.org/x/sys/unix/syscall_linux_loong64.go index 3d0e98451f..dd2262a407 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_loong64.go @@ -214,3 +214,5 @@ func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error } return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags) } + +const SYS_FSTATAT = SYS_NEWFSTATAT diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go b/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go index 6f5a288944..8cf3670bda 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go @@ -187,3 +187,5 @@ func RISCVHWProbe(pairs []RISCVHWProbePairs, set *CPUSet, flags uint) (err error } return riscvHWProbe(pairs, setSize, set, flags) } + +const SYS_FSTATAT = SYS_NEWFSTATAT diff --git a/vendor/golang.org/x/sys/unix/syscall_openbsd.go b/vendor/golang.org/x/sys/unix/syscall_openbsd.go index b25343c71a..b86ded549c 100644 --- a/vendor/golang.org/x/sys/unix/syscall_openbsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_openbsd.go @@ -293,6 +293,7 @@ func Uname(uname *Utsname) error { //sys Mkfifoat(dirfd int, path string, mode uint32) (err error) //sys Mknod(path string, mode uint32, dev int) (err error) //sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error) +//sys Mount(fsType string, dir string, flags int, data unsafe.Pointer) (err error) //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) //sys Open(path string, mode int, perm uint32) (fd int, err error) //sys Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_unix.go b/vendor/golang.org/x/sys/unix/syscall_unix.go index 77081de8c7..4e92e5aa40 100644 --- a/vendor/golang.org/x/sys/unix/syscall_unix.go +++ b/vendor/golang.org/x/sys/unix/syscall_unix.go @@ -154,6 +154,15 @@ func Munmap(b []byte) (err error) { return mapper.Munmap(b) } +func MmapPtr(fd int, offset int64, addr unsafe.Pointer, length uintptr, prot int, flags int) (ret unsafe.Pointer, err error) { + xaddr, err := mapper.mmap(uintptr(addr), length, prot, flags, fd, offset) + return unsafe.Pointer(xaddr), err +} + +func MunmapPtr(addr unsafe.Pointer, length uintptr) (err error) { + return mapper.munmap(uintptr(addr), length) +} + func Read(fd int, p []byte) (n int, err error) { n, err = read(fd, p) if raceenabled { diff --git a/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go b/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go index 312ae6ac1d..7bf5c04bb0 100644 --- a/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go +++ b/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go @@ -768,6 +768,15 @@ func Munmap(b []byte) (err error) { return mapper.Munmap(b) } +func MmapPtr(fd int, offset int64, addr unsafe.Pointer, length uintptr, prot int, flags int) (ret unsafe.Pointer, err error) { + xaddr, err := mapper.mmap(uintptr(addr), length, prot, flags, fd, offset) + return unsafe.Pointer(xaddr), err +} + +func MunmapPtr(addr unsafe.Pointer, length uintptr) (err error) { + return mapper.munmap(uintptr(addr), length) +} + //sys Gethostname(buf []byte) (err error) = SYS___GETHOSTNAME_A //sysnb Getgid() (gid int) //sysnb Getpid() (pid int) @@ -816,10 +825,10 @@ func Lstat(path string, stat *Stat_t) (err error) { // for checking symlinks begins with $VERSION/ $SYSNAME/ $SYSSYMR/ $SYSSYMA/ func isSpecialPath(path []byte) (v bool) { var special = [4][8]byte{ - [8]byte{'V', 'E', 'R', 'S', 'I', 'O', 'N', '/'}, - [8]byte{'S', 'Y', 'S', 'N', 'A', 'M', 'E', '/'}, - [8]byte{'S', 'Y', 'S', 'S', 'Y', 'M', 'R', '/'}, - [8]byte{'S', 'Y', 'S', 'S', 'Y', 'M', 'A', '/'}} + {'V', 'E', 'R', 'S', 'I', 'O', 'N', '/'}, + {'S', 'Y', 'S', 'N', 'A', 'M', 'E', '/'}, + {'S', 'Y', 'S', 'S', 'Y', 'M', 'R', '/'}, + {'S', 'Y', 'S', 'S', 'Y', 'M', 'A', '/'}} var i, j int for i = 0; i < len(special); i++ { @@ -3115,3 +3124,90 @@ func legacy_Mkfifoat(dirfd int, path string, mode uint32) (err error) { //sys Posix_openpt(oflag int) (fd int, err error) = SYS_POSIX_OPENPT //sys Grantpt(fildes int) (rc int, err error) = SYS_GRANTPT //sys Unlockpt(fildes int) (rc int, err error) = SYS_UNLOCKPT + +func fcntlAsIs(fd uintptr, cmd int, arg uintptr) (val int, err error) { + runtime.EnterSyscall() + r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FCNTL<<4, uintptr(fd), uintptr(cmd), arg) + runtime.ExitSyscall() + val = int(r0) + if int64(r0) == -1 { + err = errnoErr2(e1, e2) + } + return +} + +func Fcntl(fd uintptr, cmd int, op interface{}) (ret int, err error) { + switch op.(type) { + case *Flock_t: + err = FcntlFlock(fd, cmd, op.(*Flock_t)) + if err != nil { + ret = -1 + } + return + case int: + return FcntlInt(fd, cmd, op.(int)) + case *F_cnvrt: + return fcntlAsIs(fd, cmd, uintptr(unsafe.Pointer(op.(*F_cnvrt)))) + case unsafe.Pointer: + return fcntlAsIs(fd, cmd, uintptr(op.(unsafe.Pointer))) + default: + return -1, EINVAL + } + return +} + +func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { + if raceenabled { + raceReleaseMerge(unsafe.Pointer(&ioSync)) + } + return sendfile(outfd, infd, offset, count) +} + +func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { + // TODO: use LE call instead if the call is implemented + originalOffset, err := Seek(infd, 0, SEEK_CUR) + if err != nil { + return -1, err + } + //start reading data from in_fd + if offset != nil { + _, err := Seek(infd, *offset, SEEK_SET) + if err != nil { + return -1, err + } + } + + buf := make([]byte, count) + readBuf := make([]byte, 0) + var n int = 0 + for i := 0; i < count; i += n { + n, err := Read(infd, buf) + if n == 0 { + if err != nil { + return -1, err + } else { // EOF + break + } + } + readBuf = append(readBuf, buf...) + buf = buf[0:0] + } + + n2, err := Write(outfd, readBuf) + if err != nil { + return -1, err + } + + //When sendfile() returns, this variable will be set to the + // offset of the byte following the last byte that was read. + if offset != nil { + *offset = *offset + int64(n) + // If offset is not NULL, then sendfile() does not modify the file + // offset of in_fd + _, err := Seek(infd, originalOffset, SEEK_SET) + if err != nil { + return -1, err + } + } + return n2, nil +} diff --git a/vendor/golang.org/x/sys/unix/vgetrandom_linux.go b/vendor/golang.org/x/sys/unix/vgetrandom_linux.go new file mode 100644 index 0000000000..07ac8e09d1 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/vgetrandom_linux.go @@ -0,0 +1,13 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build linux && go1.24 + +package unix + +import _ "unsafe" + +//go:linkname vgetrandom runtime.vgetrandom +//go:noescape +func vgetrandom(p []byte, flags uint32) (ret int, supported bool) diff --git a/vendor/golang.org/x/sys/unix/vgetrandom_unsupported.go b/vendor/golang.org/x/sys/unix/vgetrandom_unsupported.go new file mode 100644 index 0000000000..297e97bce9 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/vgetrandom_unsupported.go @@ -0,0 +1,11 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !linux || !go1.24 + +package unix + +func vgetrandom(p []byte, flags uint32) (ret int, supported bool) { + return -1, false +} diff --git a/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go index e40fa85245..d73c4652e6 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go @@ -237,6 +237,9 @@ const ( CLOCK_UPTIME_RAW_APPROX = 0x9 CLONE_NOFOLLOW = 0x1 CLONE_NOOWNERCOPY = 0x2 + CONNECT_DATA_AUTHENTICATED = 0x4 + CONNECT_DATA_IDEMPOTENT = 0x2 + CONNECT_RESUME_ON_READ_WRITE = 0x1 CR0 = 0x0 CR1 = 0x1000 CR2 = 0x2000 @@ -1169,6 +1172,11 @@ const ( PT_WRITE_D = 0x5 PT_WRITE_I = 0x4 PT_WRITE_U = 0x6 + RENAME_EXCL = 0x4 + RENAME_NOFOLLOW_ANY = 0x10 + RENAME_RESERVED1 = 0x8 + RENAME_SECLUDE = 0x1 + RENAME_SWAP = 0x2 RLIMIT_AS = 0x5 RLIMIT_CORE = 0x4 RLIMIT_CPU = 0x0 @@ -1260,6 +1268,10 @@ const ( RTV_SSTHRESH = 0x20 RUSAGE_CHILDREN = -0x1 RUSAGE_SELF = 0x0 + SAE_ASSOCID_ALL = 0xffffffff + SAE_ASSOCID_ANY = 0x0 + SAE_CONNID_ALL = 0xffffffff + SAE_CONNID_ANY = 0x0 SCM_CREDS = 0x3 SCM_RIGHTS = 0x1 SCM_TIMESTAMP = 0x2 diff --git a/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go index bb02aa6c05..4a55a40058 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go @@ -237,6 +237,9 @@ const ( CLOCK_UPTIME_RAW_APPROX = 0x9 CLONE_NOFOLLOW = 0x1 CLONE_NOOWNERCOPY = 0x2 + CONNECT_DATA_AUTHENTICATED = 0x4 + CONNECT_DATA_IDEMPOTENT = 0x2 + CONNECT_RESUME_ON_READ_WRITE = 0x1 CR0 = 0x0 CR1 = 0x1000 CR2 = 0x2000 @@ -1169,6 +1172,11 @@ const ( PT_WRITE_D = 0x5 PT_WRITE_I = 0x4 PT_WRITE_U = 0x6 + RENAME_EXCL = 0x4 + RENAME_NOFOLLOW_ANY = 0x10 + RENAME_RESERVED1 = 0x8 + RENAME_SECLUDE = 0x1 + RENAME_SWAP = 0x2 RLIMIT_AS = 0x5 RLIMIT_CORE = 0x4 RLIMIT_CPU = 0x0 @@ -1260,6 +1268,10 @@ const ( RTV_SSTHRESH = 0x20 RUSAGE_CHILDREN = -0x1 RUSAGE_SELF = 0x0 + SAE_ASSOCID_ALL = 0xffffffff + SAE_ASSOCID_ANY = 0x0 + SAE_CONNID_ALL = 0xffffffff + SAE_CONNID_ANY = 0x0 SCM_CREDS = 0x3 SCM_RIGHTS = 0x1 SCM_TIMESTAMP = 0x2 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go index 877a62b479..6ebc48b3fe 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -321,6 +321,9 @@ const ( AUDIT_INTEGRITY_STATUS = 0x70a AUDIT_IPC = 0x517 AUDIT_IPC_SET_PERM = 0x51f + AUDIT_IPE_ACCESS = 0x58c + AUDIT_IPE_CONFIG_CHANGE = 0x58d + AUDIT_IPE_POLICY_LOAD = 0x58e AUDIT_KERNEL = 0x7d0 AUDIT_KERNEL_OTHER = 0x524 AUDIT_KERN_MODULE = 0x532 @@ -457,6 +460,7 @@ const ( B600 = 0x8 B75 = 0x2 B9600 = 0xd + BCACHEFS_SUPER_MAGIC = 0xca451a4e BDEVFS_MAGIC = 0x62646576 BINDERFS_SUPER_MAGIC = 0x6c6f6f70 BINFMTFS_MAGIC = 0x42494e4d @@ -488,12 +492,14 @@ const ( BPF_F_ID = 0x20 BPF_F_NETFILTER_IP_DEFRAG = 0x1 BPF_F_QUERY_EFFECTIVE = 0x1 + BPF_F_REDIRECT_FLAGS = 0x19 BPF_F_REPLACE = 0x4 BPF_F_SLEEPABLE = 0x10 BPF_F_STRICT_ALIGNMENT = 0x1 BPF_F_TEST_REG_INVARIANTS = 0x80 BPF_F_TEST_RND_HI32 = 0x4 BPF_F_TEST_RUN_ON_CPU = 0x1 + BPF_F_TEST_SKB_CHECKSUM_COMPLETE = 0x4 BPF_F_TEST_STATE_FREQ = 0x8 BPF_F_TEST_XDP_LIVE_FRAMES = 0x2 BPF_F_XDP_DEV_BOUND_ONLY = 0x40 @@ -928,6 +934,7 @@ const ( EPOLL_CTL_ADD = 0x1 EPOLL_CTL_DEL = 0x2 EPOLL_CTL_MOD = 0x3 + EPOLL_IOC_TYPE = 0x8a EROFS_SUPER_MAGIC_V1 = 0xe0f5e1e2 ESP_V4_FLOW = 0xa ESP_V6_FLOW = 0xc @@ -941,9 +948,6 @@ const ( ETHTOOL_FEC_OFF = 0x4 ETHTOOL_FEC_RS = 0x8 ETHTOOL_FLAG_ALL = 0x7 - ETHTOOL_FLAG_COMPACT_BITSETS = 0x1 - ETHTOOL_FLAG_OMIT_REPLY = 0x2 - ETHTOOL_FLAG_STATS = 0x4 ETHTOOL_FLASHDEV = 0x33 ETHTOOL_FLASH_MAX_FILENAME = 0x80 ETHTOOL_FWVERS_LEN = 0x20 @@ -1166,6 +1170,7 @@ const ( EXTA = 0xe EXTB = 0xf F2FS_SUPER_MAGIC = 0xf2f52010 + FALLOC_FL_ALLOCATE_RANGE = 0x0 FALLOC_FL_COLLAPSE_RANGE = 0x8 FALLOC_FL_INSERT_RANGE = 0x20 FALLOC_FL_KEEP_SIZE = 0x1 @@ -1705,6 +1710,7 @@ const ( KEXEC_ARCH_S390 = 0x160000 KEXEC_ARCH_SH = 0x2a0000 KEXEC_ARCH_X86_64 = 0x3e0000 + KEXEC_CRASH_HOTPLUG_SUPPORT = 0x8 KEXEC_FILE_DEBUG = 0x8 KEXEC_FILE_NO_INITRAMFS = 0x4 KEXEC_FILE_ON_CRASH = 0x2 @@ -1780,6 +1786,7 @@ const ( KEY_SPEC_USER_KEYRING = -0x4 KEY_SPEC_USER_SESSION_KEYRING = -0x5 LANDLOCK_ACCESS_FS_EXECUTE = 0x1 + LANDLOCK_ACCESS_FS_IOCTL_DEV = 0x8000 LANDLOCK_ACCESS_FS_MAKE_BLOCK = 0x800 LANDLOCK_ACCESS_FS_MAKE_CHAR = 0x40 LANDLOCK_ACCESS_FS_MAKE_DIR = 0x80 @@ -1797,6 +1804,8 @@ const ( LANDLOCK_ACCESS_NET_BIND_TCP = 0x1 LANDLOCK_ACCESS_NET_CONNECT_TCP = 0x2 LANDLOCK_CREATE_RULESET_VERSION = 0x1 + LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET = 0x1 + LANDLOCK_SCOPE_SIGNAL = 0x2 LINUX_REBOOT_CMD_CAD_OFF = 0x0 LINUX_REBOOT_CMD_CAD_ON = 0x89abcdef LINUX_REBOOT_CMD_HALT = 0xcdef0123 @@ -1861,6 +1870,19 @@ const ( MAP_FILE = 0x0 MAP_FIXED = 0x10 MAP_FIXED_NOREPLACE = 0x100000 + MAP_HUGE_16GB = 0x88000000 + MAP_HUGE_16KB = 0x38000000 + MAP_HUGE_16MB = 0x60000000 + MAP_HUGE_1GB = 0x78000000 + MAP_HUGE_1MB = 0x50000000 + MAP_HUGE_256MB = 0x70000000 + MAP_HUGE_2GB = 0x7c000000 + MAP_HUGE_2MB = 0x54000000 + MAP_HUGE_32MB = 0x64000000 + MAP_HUGE_512KB = 0x4c000000 + MAP_HUGE_512MB = 0x74000000 + MAP_HUGE_64KB = 0x40000000 + MAP_HUGE_8MB = 0x5c000000 MAP_HUGE_MASK = 0x3f MAP_HUGE_SHIFT = 0x1a MAP_PRIVATE = 0x2 @@ -1908,6 +1930,8 @@ const ( MNT_EXPIRE = 0x4 MNT_FORCE = 0x1 MNT_ID_REQ_SIZE_VER0 = 0x18 + MNT_ID_REQ_SIZE_VER1 = 0x20 + MNT_NS_INFO_SIZE_VER0 = 0x10 MODULE_INIT_COMPRESSED_FILE = 0x4 MODULE_INIT_IGNORE_MODVERSIONS = 0x1 MODULE_INIT_IGNORE_VERMAGIC = 0x2 @@ -2173,7 +2197,7 @@ const ( NFT_REG_SIZE = 0x10 NFT_REJECT_ICMPX_MAX = 0x3 NFT_RT_MAX = 0x4 - NFT_SECMARK_CTX_MAXLEN = 0x100 + NFT_SECMARK_CTX_MAXLEN = 0x1000 NFT_SET_MAXNAMELEN = 0x100 NFT_SOCKET_MAX = 0x3 NFT_TABLE_F_MASK = 0x7 @@ -2342,9 +2366,11 @@ const ( PERF_MEM_LVLNUM_IO = 0xa PERF_MEM_LVLNUM_L1 = 0x1 PERF_MEM_LVLNUM_L2 = 0x2 + PERF_MEM_LVLNUM_L2_MHB = 0x5 PERF_MEM_LVLNUM_L3 = 0x3 PERF_MEM_LVLNUM_L4 = 0x4 PERF_MEM_LVLNUM_LFB = 0xc + PERF_MEM_LVLNUM_MSC = 0x6 PERF_MEM_LVLNUM_NA = 0xf PERF_MEM_LVLNUM_PMEM = 0xe PERF_MEM_LVLNUM_RAM = 0xd @@ -2417,6 +2443,7 @@ const ( PRIO_PGRP = 0x1 PRIO_PROCESS = 0x0 PRIO_USER = 0x2 + PROCFS_IOCTL_MAGIC = 'f' PROC_SUPER_MAGIC = 0x9fa0 PROT_EXEC = 0x4 PROT_GROWSDOWN = 0x1000000 @@ -2498,6 +2525,23 @@ const ( PR_PAC_GET_ENABLED_KEYS = 0x3d PR_PAC_RESET_KEYS = 0x36 PR_PAC_SET_ENABLED_KEYS = 0x3c + PR_PPC_DEXCR_CTRL_CLEAR = 0x4 + PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC = 0x10 + PR_PPC_DEXCR_CTRL_EDITABLE = 0x1 + PR_PPC_DEXCR_CTRL_MASK = 0x1f + PR_PPC_DEXCR_CTRL_SET = 0x2 + PR_PPC_DEXCR_CTRL_SET_ONEXEC = 0x8 + PR_PPC_DEXCR_IBRTPD = 0x1 + PR_PPC_DEXCR_NPHIE = 0x3 + PR_PPC_DEXCR_SBHE = 0x0 + PR_PPC_DEXCR_SRAPD = 0x2 + PR_PPC_GET_DEXCR = 0x48 + PR_PPC_SET_DEXCR = 0x49 + PR_RISCV_CTX_SW_FENCEI_OFF = 0x1 + PR_RISCV_CTX_SW_FENCEI_ON = 0x0 + PR_RISCV_SCOPE_PER_PROCESS = 0x0 + PR_RISCV_SCOPE_PER_THREAD = 0x1 + PR_RISCV_SET_ICACHE_FLUSH_CTX = 0x47 PR_RISCV_V_GET_CONTROL = 0x46 PR_RISCV_V_SET_CONTROL = 0x45 PR_RISCV_V_VSTATE_CTRL_CUR_MASK = 0x3 @@ -2589,6 +2633,28 @@ const ( PR_UNALIGN_NOPRINT = 0x1 PR_UNALIGN_SIGBUS = 0x2 PSTOREFS_MAGIC = 0x6165676c + PTP_CLK_MAGIC = '=' + PTP_ENABLE_FEATURE = 0x1 + PTP_EXTTS_EDGES = 0x6 + PTP_EXTTS_EVENT_VALID = 0x1 + PTP_EXTTS_V1_VALID_FLAGS = 0x7 + PTP_EXTTS_VALID_FLAGS = 0x1f + PTP_EXT_OFFSET = 0x10 + PTP_FALLING_EDGE = 0x4 + PTP_MAX_SAMPLES = 0x19 + PTP_PEROUT_DUTY_CYCLE = 0x2 + PTP_PEROUT_ONE_SHOT = 0x1 + PTP_PEROUT_PHASE = 0x4 + PTP_PEROUT_V1_VALID_FLAGS = 0x0 + PTP_PEROUT_VALID_FLAGS = 0x7 + PTP_PIN_GETFUNC = 0xc0603d06 + PTP_PIN_GETFUNC2 = 0xc0603d0f + PTP_RISING_EDGE = 0x2 + PTP_STRICT_FLAGS = 0x8 + PTP_SYS_OFFSET_EXTENDED = 0xc4c03d09 + PTP_SYS_OFFSET_EXTENDED2 = 0xc4c03d12 + PTP_SYS_OFFSET_PRECISE = 0xc0403d08 + PTP_SYS_OFFSET_PRECISE2 = 0xc0403d11 PTRACE_ATTACH = 0x10 PTRACE_CONT = 0x7 PTRACE_DETACH = 0x11 @@ -2902,15 +2968,17 @@ const ( RUSAGE_SELF = 0x0 RUSAGE_THREAD = 0x1 RWF_APPEND = 0x10 + RWF_ATOMIC = 0x40 RWF_DSYNC = 0x2 RWF_HIPRI = 0x1 RWF_NOAPPEND = 0x20 RWF_NOWAIT = 0x8 - RWF_SUPPORTED = 0x3f + RWF_SUPPORTED = 0x7f RWF_SYNC = 0x4 RWF_WRITE_LIFE_NOT_SET = 0x0 SCHED_BATCH = 0x3 SCHED_DEADLINE = 0x6 + SCHED_EXT = 0x7 SCHED_FIFO = 0x1 SCHED_FLAG_ALL = 0x7f SCHED_FLAG_DL_OVERRUN = 0x4 @@ -3179,6 +3247,7 @@ const ( STATX_ATTR_MOUNT_ROOT = 0x2000 STATX_ATTR_NODUMP = 0x40 STATX_ATTR_VERITY = 0x100000 + STATX_ATTR_WRITE_ATOMIC = 0x400000 STATX_BASIC_STATS = 0x7ff STATX_BLOCKS = 0x400 STATX_BTIME = 0x800 @@ -3192,8 +3261,10 @@ const ( STATX_MTIME = 0x40 STATX_NLINK = 0x4 STATX_SIZE = 0x200 + STATX_SUBVOL = 0x8000 STATX_TYPE = 0x1 STATX_UID = 0x8 + STATX_WRITE_ATOMIC = 0x10000 STATX__RESERVED = 0x80000000 SYNC_FILE_RANGE_WAIT_AFTER = 0x4 SYNC_FILE_RANGE_WAIT_BEFORE = 0x1 @@ -3592,6 +3663,7 @@ const ( XDP_UMEM_PGOFF_COMPLETION_RING = 0x180000000 XDP_UMEM_PGOFF_FILL_RING = 0x100000000 XDP_UMEM_REG = 0x4 + XDP_UMEM_TX_METADATA_LEN = 0x4 XDP_UMEM_TX_SW_CSUM = 0x2 XDP_UMEM_UNALIGNED_CHUNK_FLAG = 0x1 XDP_USE_NEED_WAKEUP = 0x8 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go index e4bc0bd57c..c0d45e3205 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go @@ -78,6 +78,8 @@ const ( ECHOPRT = 0x400 EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x800 + EPIOCGPARAMS = 0x80088a02 + EPIOCSPARAMS = 0x40088a01 EPOLL_CLOEXEC = 0x80000 EXTPROC = 0x10000 FF1 = 0x8000 @@ -107,6 +109,7 @@ const ( HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 + HIDIOCREVOKE = 0x4004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 @@ -151,9 +154,14 @@ const ( NFDBITS = 0x20 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x8008b705 NS_GET_NSTYPE = 0xb703 NS_GET_OWNER_UID = 0xb704 NS_GET_PARENT = 0xb702 + NS_GET_PID_FROM_PIDNS = 0x8004b706 + NS_GET_PID_IN_PIDNS = 0x8004b708 + NS_GET_TGID_FROM_PIDNS = 0x8004b707 + NS_GET_TGID_IN_PIDNS = 0x8004b709 NS_GET_USERNS = 0xb701 OLCUC = 0x2 ONLCR = 0x4 @@ -230,6 +238,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x7434 PPPIOCXFERUNIT = 0x744e PR_SET_PTRACER_ANY = 0xffffffff + PTP_CLOCK_GETCAPS = 0x80503d01 + PTP_CLOCK_GETCAPS2 = 0x80503d0a + PTP_ENABLE_PPS = 0x40043d04 + PTP_ENABLE_PPS2 = 0x40043d0d + PTP_EXTTS_REQUEST = 0x40103d02 + PTP_EXTTS_REQUEST2 = 0x40103d0b + PTP_MASK_CLEAR_ALL = 0x3d13 + PTP_MASK_EN_SINGLE = 0x40043d14 + PTP_PEROUT_REQUEST = 0x40383d03 + PTP_PEROUT_REQUEST2 = 0x40383d0c + PTP_PIN_SETFUNC = 0x40603d07 + PTP_PIN_SETFUNC2 = 0x40603d10 + PTP_SYS_OFFSET = 0x43403d05 + PTP_SYS_OFFSET2 = 0x43403d0e PTRACE_GETFPREGS = 0xe PTRACE_GETFPXREGS = 0x12 PTRACE_GET_THREAD_AREA = 0x19 @@ -276,6 +298,8 @@ const ( RTC_WIE_ON = 0x700f RTC_WKALM_RD = 0x80287010 RTC_WKALM_SET = 0x4028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a @@ -314,6 +338,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go index 689317afdb..c731d24f02 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go @@ -78,6 +78,8 @@ const ( ECHOPRT = 0x400 EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x800 + EPIOCGPARAMS = 0x80088a02 + EPIOCSPARAMS = 0x40088a01 EPOLL_CLOEXEC = 0x80000 EXTPROC = 0x10000 FF1 = 0x8000 @@ -107,6 +109,7 @@ const ( HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 + HIDIOCREVOKE = 0x4004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 @@ -151,9 +154,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x8008b705 NS_GET_NSTYPE = 0xb703 NS_GET_OWNER_UID = 0xb704 NS_GET_PARENT = 0xb702 + NS_GET_PID_FROM_PIDNS = 0x8004b706 + NS_GET_PID_IN_PIDNS = 0x8004b708 + NS_GET_TGID_FROM_PIDNS = 0x8004b707 + NS_GET_TGID_IN_PIDNS = 0x8004b709 NS_GET_USERNS = 0xb701 OLCUC = 0x2 ONLCR = 0x4 @@ -230,6 +238,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x7434 PPPIOCXFERUNIT = 0x744e PR_SET_PTRACER_ANY = 0xffffffffffffffff + PTP_CLOCK_GETCAPS = 0x80503d01 + PTP_CLOCK_GETCAPS2 = 0x80503d0a + PTP_ENABLE_PPS = 0x40043d04 + PTP_ENABLE_PPS2 = 0x40043d0d + PTP_EXTTS_REQUEST = 0x40103d02 + PTP_EXTTS_REQUEST2 = 0x40103d0b + PTP_MASK_CLEAR_ALL = 0x3d13 + PTP_MASK_EN_SINGLE = 0x40043d14 + PTP_PEROUT_REQUEST = 0x40383d03 + PTP_PEROUT_REQUEST2 = 0x40383d0c + PTP_PIN_SETFUNC = 0x40603d07 + PTP_PIN_SETFUNC2 = 0x40603d10 + PTP_SYS_OFFSET = 0x43403d05 + PTP_SYS_OFFSET2 = 0x43403d0e PTRACE_ARCH_PRCTL = 0x1e PTRACE_GETFPREGS = 0xe PTRACE_GETFPXREGS = 0x12 @@ -277,6 +299,8 @@ const ( RTC_WIE_ON = 0x700f RTC_WKALM_RD = 0x80287010 RTC_WKALM_SET = 0x4028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a @@ -315,6 +339,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go index 5cca668ac3..680018a4a7 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go @@ -78,6 +78,8 @@ const ( ECHOPRT = 0x400 EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x800 + EPIOCGPARAMS = 0x80088a02 + EPIOCSPARAMS = 0x40088a01 EPOLL_CLOEXEC = 0x80000 EXTPROC = 0x10000 FF1 = 0x8000 @@ -106,6 +108,7 @@ const ( HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 + HIDIOCREVOKE = 0x4004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 @@ -148,9 +151,14 @@ const ( NFDBITS = 0x20 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x8008b705 NS_GET_NSTYPE = 0xb703 NS_GET_OWNER_UID = 0xb704 NS_GET_PARENT = 0xb702 + NS_GET_PID_FROM_PIDNS = 0x8004b706 + NS_GET_PID_IN_PIDNS = 0x8004b708 + NS_GET_TGID_FROM_PIDNS = 0x8004b707 + NS_GET_TGID_IN_PIDNS = 0x8004b709 NS_GET_USERNS = 0xb701 OLCUC = 0x2 ONLCR = 0x4 @@ -227,6 +235,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x7434 PPPIOCXFERUNIT = 0x744e PR_SET_PTRACER_ANY = 0xffffffff + PTP_CLOCK_GETCAPS = 0x80503d01 + PTP_CLOCK_GETCAPS2 = 0x80503d0a + PTP_ENABLE_PPS = 0x40043d04 + PTP_ENABLE_PPS2 = 0x40043d0d + PTP_EXTTS_REQUEST = 0x40103d02 + PTP_EXTTS_REQUEST2 = 0x40103d0b + PTP_MASK_CLEAR_ALL = 0x3d13 + PTP_MASK_EN_SINGLE = 0x40043d14 + PTP_PEROUT_REQUEST = 0x40383d03 + PTP_PEROUT_REQUEST2 = 0x40383d0c + PTP_PIN_SETFUNC = 0x40603d07 + PTP_PIN_SETFUNC2 = 0x40603d10 + PTP_SYS_OFFSET = 0x43403d05 + PTP_SYS_OFFSET2 = 0x43403d0e PTRACE_GETCRUNCHREGS = 0x19 PTRACE_GETFDPIC = 0x1f PTRACE_GETFDPIC_EXEC = 0x0 @@ -282,6 +304,8 @@ const ( RTC_WIE_ON = 0x700f RTC_WKALM_RD = 0x80287010 RTC_WKALM_SET = 0x4028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a @@ -320,6 +344,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go index 14270508b0..a63909f308 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go @@ -78,6 +78,8 @@ const ( ECHOPRT = 0x400 EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x800 + EPIOCGPARAMS = 0x80088a02 + EPIOCSPARAMS = 0x40088a01 EPOLL_CLOEXEC = 0x80000 ESR_MAGIC = 0x45535201 EXTPROC = 0x10000 @@ -110,6 +112,7 @@ const ( HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 + HIDIOCREVOKE = 0x4004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 @@ -152,9 +155,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x8008b705 NS_GET_NSTYPE = 0xb703 NS_GET_OWNER_UID = 0xb704 NS_GET_PARENT = 0xb702 + NS_GET_PID_FROM_PIDNS = 0x8004b706 + NS_GET_PID_IN_PIDNS = 0x8004b708 + NS_GET_TGID_FROM_PIDNS = 0x8004b707 + NS_GET_TGID_IN_PIDNS = 0x8004b709 NS_GET_USERNS = 0xb701 OLCUC = 0x2 ONLCR = 0x4 @@ -198,6 +206,7 @@ const ( PERF_EVENT_IOC_SET_BPF = 0x40042408 PERF_EVENT_IOC_SET_FILTER = 0x40082406 PERF_EVENT_IOC_SET_OUTPUT = 0x2405 + POE_MAGIC = 0x504f4530 PPPIOCATTACH = 0x4004743d PPPIOCATTCHAN = 0x40047438 PPPIOCBRIDGECHAN = 0x40047435 @@ -233,6 +242,20 @@ const ( PROT_BTI = 0x10 PROT_MTE = 0x20 PR_SET_PTRACER_ANY = 0xffffffffffffffff + PTP_CLOCK_GETCAPS = 0x80503d01 + PTP_CLOCK_GETCAPS2 = 0x80503d0a + PTP_ENABLE_PPS = 0x40043d04 + PTP_ENABLE_PPS2 = 0x40043d0d + PTP_EXTTS_REQUEST = 0x40103d02 + PTP_EXTTS_REQUEST2 = 0x40103d0b + PTP_MASK_CLEAR_ALL = 0x3d13 + PTP_MASK_EN_SINGLE = 0x40043d14 + PTP_PEROUT_REQUEST = 0x40383d03 + PTP_PEROUT_REQUEST2 = 0x40383d0c + PTP_PIN_SETFUNC = 0x40603d07 + PTP_PIN_SETFUNC2 = 0x40603d10 + PTP_SYS_OFFSET = 0x43403d05 + PTP_SYS_OFFSET2 = 0x43403d0e PTRACE_PEEKMTETAGS = 0x21 PTRACE_POKEMTETAGS = 0x22 PTRACE_SYSEMU = 0x1f @@ -273,6 +296,8 @@ const ( RTC_WIE_ON = 0x700f RTC_WKALM_RD = 0x80287010 RTC_WKALM_SET = 0x4028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a @@ -311,6 +336,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go index 28e39afdcb..9b0a2573fe 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go @@ -78,6 +78,8 @@ const ( ECHOPRT = 0x400 EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x800 + EPIOCGPARAMS = 0x80088a02 + EPIOCSPARAMS = 0x40088a01 EPOLL_CLOEXEC = 0x80000 EXTPROC = 0x10000 FF1 = 0x8000 @@ -107,6 +109,7 @@ const ( HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 + HIDIOCREVOKE = 0x4004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 @@ -152,9 +155,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x8008b705 NS_GET_NSTYPE = 0xb703 NS_GET_OWNER_UID = 0xb704 NS_GET_PARENT = 0xb702 + NS_GET_PID_FROM_PIDNS = 0x8004b706 + NS_GET_PID_IN_PIDNS = 0x8004b708 + NS_GET_TGID_FROM_PIDNS = 0x8004b707 + NS_GET_TGID_IN_PIDNS = 0x8004b709 NS_GET_USERNS = 0xb701 OLCUC = 0x2 ONLCR = 0x4 @@ -231,6 +239,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x7434 PPPIOCXFERUNIT = 0x744e PR_SET_PTRACER_ANY = 0xffffffffffffffff + PTP_CLOCK_GETCAPS = 0x80503d01 + PTP_CLOCK_GETCAPS2 = 0x80503d0a + PTP_ENABLE_PPS = 0x40043d04 + PTP_ENABLE_PPS2 = 0x40043d0d + PTP_EXTTS_REQUEST = 0x40103d02 + PTP_EXTTS_REQUEST2 = 0x40103d0b + PTP_MASK_CLEAR_ALL = 0x3d13 + PTP_MASK_EN_SINGLE = 0x40043d14 + PTP_PEROUT_REQUEST = 0x40383d03 + PTP_PEROUT_REQUEST2 = 0x40383d0c + PTP_PIN_SETFUNC = 0x40603d07 + PTP_PIN_SETFUNC2 = 0x40603d10 + PTP_SYS_OFFSET = 0x43403d05 + PTP_SYS_OFFSET2 = 0x43403d0e PTRACE_SYSEMU = 0x1f PTRACE_SYSEMU_SINGLESTEP = 0x20 RLIMIT_AS = 0x9 @@ -269,6 +291,8 @@ const ( RTC_WIE_ON = 0x700f RTC_WKALM_RD = 0x80287010 RTC_WKALM_SET = 0x4028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a @@ -307,6 +331,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go index cd66e92cb4..958e6e0645 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go @@ -78,6 +78,8 @@ const ( ECHOPRT = 0x400 EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x80 + EPIOCGPARAMS = 0x40088a02 + EPIOCSPARAMS = 0x80088a01 EPOLL_CLOEXEC = 0x80000 EXTPROC = 0x10000 FF1 = 0x8000 @@ -106,6 +108,7 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 + HIDIOCREVOKE = 0x8004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x100 @@ -148,9 +151,14 @@ const ( NFDBITS = 0x20 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x4008b705 NS_GET_NSTYPE = 0x2000b703 NS_GET_OWNER_UID = 0x2000b704 NS_GET_PARENT = 0x2000b702 + NS_GET_PID_FROM_PIDNS = 0x4004b706 + NS_GET_PID_IN_PIDNS = 0x4004b708 + NS_GET_TGID_FROM_PIDNS = 0x4004b707 + NS_GET_TGID_IN_PIDNS = 0x4004b709 NS_GET_USERNS = 0x2000b701 OLCUC = 0x2 ONLCR = 0x4 @@ -227,6 +235,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x20007434 PPPIOCXFERUNIT = 0x2000744e PR_SET_PTRACER_ANY = 0xffffffff + PTP_CLOCK_GETCAPS = 0x40503d01 + PTP_CLOCK_GETCAPS2 = 0x40503d0a + PTP_ENABLE_PPS = 0x80043d04 + PTP_ENABLE_PPS2 = 0x80043d0d + PTP_EXTTS_REQUEST = 0x80103d02 + PTP_EXTTS_REQUEST2 = 0x80103d0b + PTP_MASK_CLEAR_ALL = 0x20003d13 + PTP_MASK_EN_SINGLE = 0x80043d14 + PTP_PEROUT_REQUEST = 0x80383d03 + PTP_PEROUT_REQUEST2 = 0x80383d0c + PTP_PIN_SETFUNC = 0x80603d07 + PTP_PIN_SETFUNC2 = 0x80603d10 + PTP_SYS_OFFSET = 0x83403d05 + PTP_SYS_OFFSET2 = 0x83403d0e PTRACE_GETFPREGS = 0xe PTRACE_GET_THREAD_AREA = 0x19 PTRACE_GET_THREAD_AREA_3264 = 0xc4 @@ -275,6 +297,8 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a @@ -313,6 +337,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x1029 SO_DONTROUTE = 0x10 SO_ERROR = 0x1007 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go index c1595eba78..50c7f25bd1 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go @@ -78,6 +78,8 @@ const ( ECHOPRT = 0x400 EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x80 + EPIOCGPARAMS = 0x40088a02 + EPIOCSPARAMS = 0x80088a01 EPOLL_CLOEXEC = 0x80000 EXTPROC = 0x10000 FF1 = 0x8000 @@ -106,6 +108,7 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 + HIDIOCREVOKE = 0x8004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x100 @@ -148,9 +151,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x4008b705 NS_GET_NSTYPE = 0x2000b703 NS_GET_OWNER_UID = 0x2000b704 NS_GET_PARENT = 0x2000b702 + NS_GET_PID_FROM_PIDNS = 0x4004b706 + NS_GET_PID_IN_PIDNS = 0x4004b708 + NS_GET_TGID_FROM_PIDNS = 0x4004b707 + NS_GET_TGID_IN_PIDNS = 0x4004b709 NS_GET_USERNS = 0x2000b701 OLCUC = 0x2 ONLCR = 0x4 @@ -227,6 +235,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x20007434 PPPIOCXFERUNIT = 0x2000744e PR_SET_PTRACER_ANY = 0xffffffffffffffff + PTP_CLOCK_GETCAPS = 0x40503d01 + PTP_CLOCK_GETCAPS2 = 0x40503d0a + PTP_ENABLE_PPS = 0x80043d04 + PTP_ENABLE_PPS2 = 0x80043d0d + PTP_EXTTS_REQUEST = 0x80103d02 + PTP_EXTTS_REQUEST2 = 0x80103d0b + PTP_MASK_CLEAR_ALL = 0x20003d13 + PTP_MASK_EN_SINGLE = 0x80043d14 + PTP_PEROUT_REQUEST = 0x80383d03 + PTP_PEROUT_REQUEST2 = 0x80383d0c + PTP_PIN_SETFUNC = 0x80603d07 + PTP_PIN_SETFUNC2 = 0x80603d10 + PTP_SYS_OFFSET = 0x83403d05 + PTP_SYS_OFFSET2 = 0x83403d0e PTRACE_GETFPREGS = 0xe PTRACE_GET_THREAD_AREA = 0x19 PTRACE_GET_THREAD_AREA_3264 = 0xc4 @@ -275,6 +297,8 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a @@ -313,6 +337,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x1029 SO_DONTROUTE = 0x10 SO_ERROR = 0x1007 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go index ee9456b0da..ced21d66d9 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go @@ -78,6 +78,8 @@ const ( ECHOPRT = 0x400 EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x80 + EPIOCGPARAMS = 0x40088a02 + EPIOCSPARAMS = 0x80088a01 EPOLL_CLOEXEC = 0x80000 EXTPROC = 0x10000 FF1 = 0x8000 @@ -106,6 +108,7 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 + HIDIOCREVOKE = 0x8004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x100 @@ -148,9 +151,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x4008b705 NS_GET_NSTYPE = 0x2000b703 NS_GET_OWNER_UID = 0x2000b704 NS_GET_PARENT = 0x2000b702 + NS_GET_PID_FROM_PIDNS = 0x4004b706 + NS_GET_PID_IN_PIDNS = 0x4004b708 + NS_GET_TGID_FROM_PIDNS = 0x4004b707 + NS_GET_TGID_IN_PIDNS = 0x4004b709 NS_GET_USERNS = 0x2000b701 OLCUC = 0x2 ONLCR = 0x4 @@ -227,6 +235,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x20007434 PPPIOCXFERUNIT = 0x2000744e PR_SET_PTRACER_ANY = 0xffffffffffffffff + PTP_CLOCK_GETCAPS = 0x40503d01 + PTP_CLOCK_GETCAPS2 = 0x40503d0a + PTP_ENABLE_PPS = 0x80043d04 + PTP_ENABLE_PPS2 = 0x80043d0d + PTP_EXTTS_REQUEST = 0x80103d02 + PTP_EXTTS_REQUEST2 = 0x80103d0b + PTP_MASK_CLEAR_ALL = 0x20003d13 + PTP_MASK_EN_SINGLE = 0x80043d14 + PTP_PEROUT_REQUEST = 0x80383d03 + PTP_PEROUT_REQUEST2 = 0x80383d0c + PTP_PIN_SETFUNC = 0x80603d07 + PTP_PIN_SETFUNC2 = 0x80603d10 + PTP_SYS_OFFSET = 0x83403d05 + PTP_SYS_OFFSET2 = 0x83403d0e PTRACE_GETFPREGS = 0xe PTRACE_GET_THREAD_AREA = 0x19 PTRACE_GET_THREAD_AREA_3264 = 0xc4 @@ -275,6 +297,8 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a @@ -313,6 +337,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x1029 SO_DONTROUTE = 0x10 SO_ERROR = 0x1007 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go index 8cfca81e1b..226c044190 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go @@ -78,6 +78,8 @@ const ( ECHOPRT = 0x400 EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x80 + EPIOCGPARAMS = 0x40088a02 + EPIOCSPARAMS = 0x80088a01 EPOLL_CLOEXEC = 0x80000 EXTPROC = 0x10000 FF1 = 0x8000 @@ -106,6 +108,7 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 + HIDIOCREVOKE = 0x8004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x100 @@ -148,9 +151,14 @@ const ( NFDBITS = 0x20 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x4008b705 NS_GET_NSTYPE = 0x2000b703 NS_GET_OWNER_UID = 0x2000b704 NS_GET_PARENT = 0x2000b702 + NS_GET_PID_FROM_PIDNS = 0x4004b706 + NS_GET_PID_IN_PIDNS = 0x4004b708 + NS_GET_TGID_FROM_PIDNS = 0x4004b707 + NS_GET_TGID_IN_PIDNS = 0x4004b709 NS_GET_USERNS = 0x2000b701 OLCUC = 0x2 ONLCR = 0x4 @@ -227,6 +235,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x20007434 PPPIOCXFERUNIT = 0x2000744e PR_SET_PTRACER_ANY = 0xffffffff + PTP_CLOCK_GETCAPS = 0x40503d01 + PTP_CLOCK_GETCAPS2 = 0x40503d0a + PTP_ENABLE_PPS = 0x80043d04 + PTP_ENABLE_PPS2 = 0x80043d0d + PTP_EXTTS_REQUEST = 0x80103d02 + PTP_EXTTS_REQUEST2 = 0x80103d0b + PTP_MASK_CLEAR_ALL = 0x20003d13 + PTP_MASK_EN_SINGLE = 0x80043d14 + PTP_PEROUT_REQUEST = 0x80383d03 + PTP_PEROUT_REQUEST2 = 0x80383d0c + PTP_PIN_SETFUNC = 0x80603d07 + PTP_PIN_SETFUNC2 = 0x80603d10 + PTP_SYS_OFFSET = 0x83403d05 + PTP_SYS_OFFSET2 = 0x83403d0e PTRACE_GETFPREGS = 0xe PTRACE_GET_THREAD_AREA = 0x19 PTRACE_GET_THREAD_AREA_3264 = 0xc4 @@ -275,6 +297,8 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a @@ -313,6 +337,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x1029 SO_DONTROUTE = 0x10 SO_ERROR = 0x1007 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go index 60b0deb3af..3122737cd4 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go @@ -78,6 +78,8 @@ const ( ECHOPRT = 0x20 EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x800 + EPIOCGPARAMS = 0x40088a02 + EPIOCSPARAMS = 0x80088a01 EPOLL_CLOEXEC = 0x80000 EXTPROC = 0x10000000 FF1 = 0x4000 @@ -106,6 +108,7 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 + HIDIOCREVOKE = 0x8004480d HUPCL = 0x4000 ICANON = 0x100 IEXTEN = 0x400 @@ -150,9 +153,14 @@ const ( NL3 = 0x300 NLDLY = 0x300 NOFLSH = 0x80000000 + NS_GET_MNTNS_ID = 0x4008b705 NS_GET_NSTYPE = 0x2000b703 NS_GET_OWNER_UID = 0x2000b704 NS_GET_PARENT = 0x2000b702 + NS_GET_PID_FROM_PIDNS = 0x4004b706 + NS_GET_PID_IN_PIDNS = 0x4004b708 + NS_GET_TGID_FROM_PIDNS = 0x4004b707 + NS_GET_TGID_IN_PIDNS = 0x4004b709 NS_GET_USERNS = 0x2000b701 OLCUC = 0x4 ONLCR = 0x2 @@ -230,6 +238,20 @@ const ( PPPIOCXFERUNIT = 0x2000744e PROT_SAO = 0x10 PR_SET_PTRACER_ANY = 0xffffffff + PTP_CLOCK_GETCAPS = 0x40503d01 + PTP_CLOCK_GETCAPS2 = 0x40503d0a + PTP_ENABLE_PPS = 0x80043d04 + PTP_ENABLE_PPS2 = 0x80043d0d + PTP_EXTTS_REQUEST = 0x80103d02 + PTP_EXTTS_REQUEST2 = 0x80103d0b + PTP_MASK_CLEAR_ALL = 0x20003d13 + PTP_MASK_EN_SINGLE = 0x80043d14 + PTP_PEROUT_REQUEST = 0x80383d03 + PTP_PEROUT_REQUEST2 = 0x80383d0c + PTP_PIN_SETFUNC = 0x80603d07 + PTP_PIN_SETFUNC2 = 0x80603d10 + PTP_SYS_OFFSET = 0x83403d05 + PTP_SYS_OFFSET2 = 0x83403d0e PTRACE_GETEVRREGS = 0x14 PTRACE_GETFPREGS = 0xe PTRACE_GETREGS64 = 0x16 @@ -330,6 +352,8 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a @@ -368,6 +392,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go index f90aa7281b..eb5d3467ed 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go @@ -78,6 +78,8 @@ const ( ECHOPRT = 0x20 EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x800 + EPIOCGPARAMS = 0x40088a02 + EPIOCSPARAMS = 0x80088a01 EPOLL_CLOEXEC = 0x80000 EXTPROC = 0x10000000 FF1 = 0x4000 @@ -106,6 +108,7 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 + HIDIOCREVOKE = 0x8004480d HUPCL = 0x4000 ICANON = 0x100 IEXTEN = 0x400 @@ -150,9 +153,14 @@ const ( NL3 = 0x300 NLDLY = 0x300 NOFLSH = 0x80000000 + NS_GET_MNTNS_ID = 0x4008b705 NS_GET_NSTYPE = 0x2000b703 NS_GET_OWNER_UID = 0x2000b704 NS_GET_PARENT = 0x2000b702 + NS_GET_PID_FROM_PIDNS = 0x4004b706 + NS_GET_PID_IN_PIDNS = 0x4004b708 + NS_GET_TGID_FROM_PIDNS = 0x4004b707 + NS_GET_TGID_IN_PIDNS = 0x4004b709 NS_GET_USERNS = 0x2000b701 OLCUC = 0x4 ONLCR = 0x2 @@ -230,6 +238,20 @@ const ( PPPIOCXFERUNIT = 0x2000744e PROT_SAO = 0x10 PR_SET_PTRACER_ANY = 0xffffffffffffffff + PTP_CLOCK_GETCAPS = 0x40503d01 + PTP_CLOCK_GETCAPS2 = 0x40503d0a + PTP_ENABLE_PPS = 0x80043d04 + PTP_ENABLE_PPS2 = 0x80043d0d + PTP_EXTTS_REQUEST = 0x80103d02 + PTP_EXTTS_REQUEST2 = 0x80103d0b + PTP_MASK_CLEAR_ALL = 0x20003d13 + PTP_MASK_EN_SINGLE = 0x80043d14 + PTP_PEROUT_REQUEST = 0x80383d03 + PTP_PEROUT_REQUEST2 = 0x80383d0c + PTP_PIN_SETFUNC = 0x80603d07 + PTP_PIN_SETFUNC2 = 0x80603d10 + PTP_SYS_OFFSET = 0x83403d05 + PTP_SYS_OFFSET2 = 0x83403d0e PTRACE_GETEVRREGS = 0x14 PTRACE_GETFPREGS = 0xe PTRACE_GETREGS64 = 0x16 @@ -334,6 +356,8 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a @@ -372,6 +396,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go index ba9e015033..e921ebc60b 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go @@ -78,6 +78,8 @@ const ( ECHOPRT = 0x20 EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x800 + EPIOCGPARAMS = 0x40088a02 + EPIOCSPARAMS = 0x80088a01 EPOLL_CLOEXEC = 0x80000 EXTPROC = 0x10000000 FF1 = 0x4000 @@ -106,6 +108,7 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 + HIDIOCREVOKE = 0x8004480d HUPCL = 0x4000 ICANON = 0x100 IEXTEN = 0x400 @@ -150,9 +153,14 @@ const ( NL3 = 0x300 NLDLY = 0x300 NOFLSH = 0x80000000 + NS_GET_MNTNS_ID = 0x4008b705 NS_GET_NSTYPE = 0x2000b703 NS_GET_OWNER_UID = 0x2000b704 NS_GET_PARENT = 0x2000b702 + NS_GET_PID_FROM_PIDNS = 0x4004b706 + NS_GET_PID_IN_PIDNS = 0x4004b708 + NS_GET_TGID_FROM_PIDNS = 0x4004b707 + NS_GET_TGID_IN_PIDNS = 0x4004b709 NS_GET_USERNS = 0x2000b701 OLCUC = 0x4 ONLCR = 0x2 @@ -230,6 +238,20 @@ const ( PPPIOCXFERUNIT = 0x2000744e PROT_SAO = 0x10 PR_SET_PTRACER_ANY = 0xffffffffffffffff + PTP_CLOCK_GETCAPS = 0x40503d01 + PTP_CLOCK_GETCAPS2 = 0x40503d0a + PTP_ENABLE_PPS = 0x80043d04 + PTP_ENABLE_PPS2 = 0x80043d0d + PTP_EXTTS_REQUEST = 0x80103d02 + PTP_EXTTS_REQUEST2 = 0x80103d0b + PTP_MASK_CLEAR_ALL = 0x20003d13 + PTP_MASK_EN_SINGLE = 0x80043d14 + PTP_PEROUT_REQUEST = 0x80383d03 + PTP_PEROUT_REQUEST2 = 0x80383d0c + PTP_PIN_SETFUNC = 0x80603d07 + PTP_PIN_SETFUNC2 = 0x80603d10 + PTP_SYS_OFFSET = 0x83403d05 + PTP_SYS_OFFSET2 = 0x83403d0e PTRACE_GETEVRREGS = 0x14 PTRACE_GETFPREGS = 0xe PTRACE_GETREGS64 = 0x16 @@ -334,6 +356,8 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a @@ -372,6 +396,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go index 07cdfd6e9f..38ba81c55c 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go @@ -78,6 +78,8 @@ const ( ECHOPRT = 0x400 EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x800 + EPIOCGPARAMS = 0x80088a02 + EPIOCSPARAMS = 0x40088a01 EPOLL_CLOEXEC = 0x80000 EXTPROC = 0x10000 FF1 = 0x8000 @@ -106,6 +108,7 @@ const ( HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 + HIDIOCREVOKE = 0x4004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 @@ -148,9 +151,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x8008b705 NS_GET_NSTYPE = 0xb703 NS_GET_OWNER_UID = 0xb704 NS_GET_PARENT = 0xb702 + NS_GET_PID_FROM_PIDNS = 0x8004b706 + NS_GET_PID_IN_PIDNS = 0x8004b708 + NS_GET_TGID_FROM_PIDNS = 0x8004b707 + NS_GET_TGID_IN_PIDNS = 0x8004b709 NS_GET_USERNS = 0xb701 OLCUC = 0x2 ONLCR = 0x4 @@ -227,6 +235,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x7434 PPPIOCXFERUNIT = 0x744e PR_SET_PTRACER_ANY = 0xffffffffffffffff + PTP_CLOCK_GETCAPS = 0x80503d01 + PTP_CLOCK_GETCAPS2 = 0x80503d0a + PTP_ENABLE_PPS = 0x40043d04 + PTP_ENABLE_PPS2 = 0x40043d0d + PTP_EXTTS_REQUEST = 0x40103d02 + PTP_EXTTS_REQUEST2 = 0x40103d0b + PTP_MASK_CLEAR_ALL = 0x3d13 + PTP_MASK_EN_SINGLE = 0x40043d14 + PTP_PEROUT_REQUEST = 0x40383d03 + PTP_PEROUT_REQUEST2 = 0x40383d0c + PTP_PIN_SETFUNC = 0x40603d07 + PTP_PIN_SETFUNC2 = 0x40603d10 + PTP_SYS_OFFSET = 0x43403d05 + PTP_SYS_OFFSET2 = 0x43403d0e PTRACE_GETFDPIC = 0x21 PTRACE_GETFDPIC_EXEC = 0x0 PTRACE_GETFDPIC_INTERP = 0x1 @@ -266,6 +288,8 @@ const ( RTC_WIE_ON = 0x700f RTC_WKALM_RD = 0x80287010 RTC_WKALM_SET = 0x4028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a @@ -304,6 +328,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go index 2f1dd214a7..71f0400977 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go @@ -78,6 +78,8 @@ const ( ECHOPRT = 0x400 EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x800 + EPIOCGPARAMS = 0x80088a02 + EPIOCSPARAMS = 0x40088a01 EPOLL_CLOEXEC = 0x80000 EXTPROC = 0x10000 FF1 = 0x8000 @@ -106,6 +108,7 @@ const ( HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 + HIDIOCREVOKE = 0x4004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 @@ -148,9 +151,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x8008b705 NS_GET_NSTYPE = 0xb703 NS_GET_OWNER_UID = 0xb704 NS_GET_PARENT = 0xb702 + NS_GET_PID_FROM_PIDNS = 0x8004b706 + NS_GET_PID_IN_PIDNS = 0x8004b708 + NS_GET_TGID_FROM_PIDNS = 0x8004b707 + NS_GET_TGID_IN_PIDNS = 0x8004b709 NS_GET_USERNS = 0xb701 OLCUC = 0x2 ONLCR = 0x4 @@ -227,6 +235,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x7434 PPPIOCXFERUNIT = 0x744e PR_SET_PTRACER_ANY = 0xffffffffffffffff + PTP_CLOCK_GETCAPS = 0x80503d01 + PTP_CLOCK_GETCAPS2 = 0x80503d0a + PTP_ENABLE_PPS = 0x40043d04 + PTP_ENABLE_PPS2 = 0x40043d0d + PTP_EXTTS_REQUEST = 0x40103d02 + PTP_EXTTS_REQUEST2 = 0x40103d0b + PTP_MASK_CLEAR_ALL = 0x3d13 + PTP_MASK_EN_SINGLE = 0x40043d14 + PTP_PEROUT_REQUEST = 0x40383d03 + PTP_PEROUT_REQUEST2 = 0x40383d0c + PTP_PIN_SETFUNC = 0x40603d07 + PTP_PIN_SETFUNC2 = 0x40603d10 + PTP_SYS_OFFSET = 0x43403d05 + PTP_SYS_OFFSET2 = 0x43403d0e PTRACE_DISABLE_TE = 0x5010 PTRACE_ENABLE_TE = 0x5009 PTRACE_GET_LAST_BREAK = 0x5006 @@ -338,6 +360,8 @@ const ( RTC_WIE_ON = 0x700f RTC_WKALM_RD = 0x80287010 RTC_WKALM_SET = 0x4028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a @@ -376,6 +400,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go index f40519d901..c44a313322 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go @@ -82,6 +82,8 @@ const ( EFD_CLOEXEC = 0x400000 EFD_NONBLOCK = 0x4000 EMT_TAGOVF = 0x1 + EPIOCGPARAMS = 0x40088a02 + EPIOCSPARAMS = 0x80088a01 EPOLL_CLOEXEC = 0x400000 EXTPROC = 0x10000 FF1 = 0x8000 @@ -110,6 +112,7 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 + HIDIOCREVOKE = 0x8004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 @@ -153,9 +156,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x4008b705 NS_GET_NSTYPE = 0x2000b703 NS_GET_OWNER_UID = 0x2000b704 NS_GET_PARENT = 0x2000b702 + NS_GET_PID_FROM_PIDNS = 0x4004b706 + NS_GET_PID_IN_PIDNS = 0x4004b708 + NS_GET_TGID_FROM_PIDNS = 0x4004b707 + NS_GET_TGID_IN_PIDNS = 0x4004b709 NS_GET_USERNS = 0x2000b701 OLCUC = 0x2 ONLCR = 0x4 @@ -232,6 +240,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x20007434 PPPIOCXFERUNIT = 0x2000744e PR_SET_PTRACER_ANY = 0xffffffffffffffff + PTP_CLOCK_GETCAPS = 0x40503d01 + PTP_CLOCK_GETCAPS2 = 0x40503d0a + PTP_ENABLE_PPS = 0x80043d04 + PTP_ENABLE_PPS2 = 0x80043d0d + PTP_EXTTS_REQUEST = 0x80103d02 + PTP_EXTTS_REQUEST2 = 0x80103d0b + PTP_MASK_CLEAR_ALL = 0x20003d13 + PTP_MASK_EN_SINGLE = 0x80043d14 + PTP_PEROUT_REQUEST = 0x80383d03 + PTP_PEROUT_REQUEST2 = 0x80383d0c + PTP_PIN_SETFUNC = 0x80603d07 + PTP_PIN_SETFUNC2 = 0x80603d10 + PTP_SYS_OFFSET = 0x83403d05 + PTP_SYS_OFFSET2 = 0x83403d0e PTRACE_GETFPAREGS = 0x14 PTRACE_GETFPREGS = 0xe PTRACE_GETFPREGS64 = 0x19 @@ -329,6 +351,8 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f + SCM_DEVMEM_DMABUF = 0x58 + SCM_DEVMEM_LINEAR = 0x57 SCM_TIMESTAMPING = 0x23 SCM_TIMESTAMPING_OPT_STATS = 0x38 SCM_TIMESTAMPING_PKTINFO = 0x3c @@ -415,6 +439,9 @@ const ( SO_CNX_ADVICE = 0x37 SO_COOKIE = 0x3b SO_DETACH_REUSEPORT_BPF = 0x47 + SO_DEVMEM_DMABUF = 0x58 + SO_DEVMEM_DONTNEED = 0x59 + SO_DEVMEM_LINEAR = 0x57 SO_DOMAIN = 0x1029 SO_DONTROUTE = 0x10 SO_ERROR = 0x1007 diff --git a/vendor/golang.org/x/sys/unix/zerrors_zos_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_zos_s390x.go index da08b2ab3d..1ec2b1407b 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_zos_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_zos_s390x.go @@ -581,6 +581,8 @@ const ( AT_EMPTY_PATH = 0x1000 AT_REMOVEDIR = 0x200 RENAME_NOREPLACE = 1 << 0 + ST_RDONLY = 1 + ST_NOSUID = 2 ) const ( diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go index ccb02f240a..24b346e1a3 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go @@ -740,6 +740,54 @@ func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func renamexNp(from string, to string, flag uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(from) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(to) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_renamex_np_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flag)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_renamex_np_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_renamex_np renamex_np "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func renameatxNp(fromfd int, from string, tofd int, to string, flag uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(from) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(to) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_renameatx_np_trampoline_addr, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), uintptr(flag), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_renameatx_np_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_renameatx_np renameatx_np "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { var _p0 unsafe.Pointer if len(mib) > 0 { @@ -760,6 +808,59 @@ var libc_sysctl_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func pthread_chdir_np(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_pthread_chdir_np_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_pthread_chdir_np_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_pthread_chdir_np pthread_chdir_np "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func pthread_fchdir_np(fd int) (err error) { + _, _, e1 := syscall_syscall(libc_pthread_fchdir_np_trampoline_addr, uintptr(fd), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_pthread_fchdir_np_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_pthread_fchdir_np pthread_fchdir_np "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func connectx(fd int, endpoints *SaEndpoints, associd SaeAssocID, flags uint32, iov []Iovec, n *uintptr, connid *SaeConnID) (err error) { + var _p0 unsafe.Pointer + if len(iov) > 0 { + _p0 = unsafe.Pointer(&iov[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := syscall_syscall9(libc_connectx_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(endpoints)), uintptr(associd), uintptr(flags), uintptr(_p0), uintptr(len(iov)), uintptr(unsafe.Pointer(n)), uintptr(unsafe.Pointer(connid)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_connectx_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_connectx connectx "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) { _, _, e1 := syscall_syscall6(libc_sendfile_trampoline_addr, uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags)) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s index 8b8bb28402..ebd213100b 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s @@ -223,11 +223,36 @@ TEXT libc_ioctl_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_ioctl_trampoline_addr(SB), RODATA, $8 DATA ·libc_ioctl_trampoline_addr(SB)/8, $libc_ioctl_trampoline<>(SB) +TEXT libc_renamex_np_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_renamex_np(SB) +GLOBL ·libc_renamex_np_trampoline_addr(SB), RODATA, $8 +DATA ·libc_renamex_np_trampoline_addr(SB)/8, $libc_renamex_np_trampoline<>(SB) + +TEXT libc_renameatx_np_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_renameatx_np(SB) +GLOBL ·libc_renameatx_np_trampoline_addr(SB), RODATA, $8 +DATA ·libc_renameatx_np_trampoline_addr(SB)/8, $libc_renameatx_np_trampoline<>(SB) + TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sysctl(SB) GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8 DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB) +TEXT libc_pthread_chdir_np_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_pthread_chdir_np(SB) +GLOBL ·libc_pthread_chdir_np_trampoline_addr(SB), RODATA, $8 +DATA ·libc_pthread_chdir_np_trampoline_addr(SB)/8, $libc_pthread_chdir_np_trampoline<>(SB) + +TEXT libc_pthread_fchdir_np_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_pthread_fchdir_np(SB) +GLOBL ·libc_pthread_fchdir_np_trampoline_addr(SB), RODATA, $8 +DATA ·libc_pthread_fchdir_np_trampoline_addr(SB)/8, $libc_pthread_fchdir_np_trampoline<>(SB) + +TEXT libc_connectx_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_connectx(SB) +GLOBL ·libc_connectx_trampoline_addr(SB), RODATA, $8 +DATA ·libc_connectx_trampoline_addr(SB)/8, $libc_connectx_trampoline<>(SB) + TEXT libc_sendfile_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sendfile(SB) GLOBL ·libc_sendfile_trampoline_addr(SB), RODATA, $8 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go index 1b40b997b5..824b9c2d5e 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go @@ -740,6 +740,54 @@ func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func renamexNp(from string, to string, flag uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(from) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(to) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_renamex_np_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flag)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_renamex_np_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_renamex_np renamex_np "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func renameatxNp(fromfd int, from string, tofd int, to string, flag uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(from) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(to) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_renameatx_np_trampoline_addr, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), uintptr(flag), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_renameatx_np_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_renameatx_np renameatx_np "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { var _p0 unsafe.Pointer if len(mib) > 0 { @@ -760,6 +808,59 @@ var libc_sysctl_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func pthread_chdir_np(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := syscall_syscall(libc_pthread_chdir_np_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_pthread_chdir_np_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_pthread_chdir_np pthread_chdir_np "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func pthread_fchdir_np(fd int) (err error) { + _, _, e1 := syscall_syscall(libc_pthread_fchdir_np_trampoline_addr, uintptr(fd), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_pthread_fchdir_np_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_pthread_fchdir_np pthread_fchdir_np "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func connectx(fd int, endpoints *SaEndpoints, associd SaeAssocID, flags uint32, iov []Iovec, n *uintptr, connid *SaeConnID) (err error) { + var _p0 unsafe.Pointer + if len(iov) > 0 { + _p0 = unsafe.Pointer(&iov[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := syscall_syscall9(libc_connectx_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(endpoints)), uintptr(associd), uintptr(flags), uintptr(_p0), uintptr(len(iov)), uintptr(unsafe.Pointer(n)), uintptr(unsafe.Pointer(connid)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_connectx_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_connectx connectx "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) { _, _, e1 := syscall_syscall6(libc_sendfile_trampoline_addr, uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags)) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s index 08362c1ab7..4f178a2293 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s @@ -223,11 +223,36 @@ TEXT libc_ioctl_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_ioctl_trampoline_addr(SB), RODATA, $8 DATA ·libc_ioctl_trampoline_addr(SB)/8, $libc_ioctl_trampoline<>(SB) +TEXT libc_renamex_np_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_renamex_np(SB) +GLOBL ·libc_renamex_np_trampoline_addr(SB), RODATA, $8 +DATA ·libc_renamex_np_trampoline_addr(SB)/8, $libc_renamex_np_trampoline<>(SB) + +TEXT libc_renameatx_np_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_renameatx_np(SB) +GLOBL ·libc_renameatx_np_trampoline_addr(SB), RODATA, $8 +DATA ·libc_renameatx_np_trampoline_addr(SB)/8, $libc_renameatx_np_trampoline<>(SB) + TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sysctl(SB) GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8 DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB) +TEXT libc_pthread_chdir_np_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_pthread_chdir_np(SB) +GLOBL ·libc_pthread_chdir_np_trampoline_addr(SB), RODATA, $8 +DATA ·libc_pthread_chdir_np_trampoline_addr(SB)/8, $libc_pthread_chdir_np_trampoline<>(SB) + +TEXT libc_pthread_fchdir_np_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_pthread_fchdir_np(SB) +GLOBL ·libc_pthread_fchdir_np_trampoline_addr(SB), RODATA, $8 +DATA ·libc_pthread_fchdir_np_trampoline_addr(SB)/8, $libc_pthread_fchdir_np_trampoline<>(SB) + +TEXT libc_connectx_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_connectx(SB) +GLOBL ·libc_connectx_trampoline_addr(SB), RODATA, $8 +DATA ·libc_connectx_trampoline_addr(SB)/8, $libc_connectx_trampoline<>(SB) + TEXT libc_sendfile_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sendfile(SB) GLOBL ·libc_sendfile_trampoline_addr(SB), RODATA, $8 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux.go b/vendor/golang.org/x/sys/unix/zsyscall_linux.go index 87d8612a1d..5cc1e8eb2f 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux.go @@ -592,6 +592,16 @@ func ClockGettime(clockid int32, time *Timespec) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockSettime(clockid int32, time *Timespec) (err error) { + _, _, e1 := Syscall(SYS_CLOCK_SETTIME, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) { _, _, e1 := Syscall6(SYS_CLOCK_NANOSLEEP, uintptr(clockid), uintptr(flags), uintptr(unsafe.Pointer(request)), uintptr(unsafe.Pointer(remain)), 0, 0) if e1 != 0 { @@ -971,23 +981,6 @@ func Getpriority(which int, who int) (prio int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Getrandom(buf []byte, flags int) (n int, err error) { - var _p0 unsafe.Pointer - if len(buf) > 0 { - _p0 = unsafe.Pointer(&buf[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall(SYS_GETRANDOM, uintptr(_p0), uintptr(len(buf)), uintptr(flags)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Getrusage(who int, rusage *Rusage) (err error) { _, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0) if e1 != 0 { @@ -2229,3 +2222,19 @@ func Cachestat(fd uint, crange *CachestatRange, cstat *Cachestat_t, flags uint) } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mseal(b []byte, flags uint) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MSEAL, uintptr(_p0), uintptr(len(b)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go index 9dc42410b7..1851df14e8 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go @@ -1493,6 +1493,30 @@ var libc_mknodat_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Mount(fsType string, dir string, flags int, data unsafe.Pointer) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(fsType) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(dir) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_mount_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags), uintptr(data), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mount_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mount mount "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Nanosleep(time *Timespec, leftover *Timespec) (err error) { _, _, e1 := syscall_syscall(libc_nanosleep_trampoline_addr, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.s index 41b5617316..0b43c69365 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.s @@ -463,6 +463,11 @@ TEXT libc_mknodat_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_mknodat_trampoline_addr(SB), RODATA, $4 DATA ·libc_mknodat_trampoline_addr(SB)/4, $libc_mknodat_trampoline<>(SB) +TEXT libc_mount_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mount(SB) +GLOBL ·libc_mount_trampoline_addr(SB), RODATA, $4 +DATA ·libc_mount_trampoline_addr(SB)/4, $libc_mount_trampoline<>(SB) + TEXT libc_nanosleep_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_nanosleep(SB) GLOBL ·libc_nanosleep_trampoline_addr(SB), RODATA, $4 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go index 0d3a0751cd..e1ec0dbe4e 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go @@ -1493,6 +1493,30 @@ var libc_mknodat_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Mount(fsType string, dir string, flags int, data unsafe.Pointer) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(fsType) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(dir) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_mount_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags), uintptr(data), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mount_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mount mount "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Nanosleep(time *Timespec, leftover *Timespec) (err error) { _, _, e1 := syscall_syscall(libc_nanosleep_trampoline_addr, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.s index 4019a656f6..880c6d6e31 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.s @@ -463,6 +463,11 @@ TEXT libc_mknodat_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_mknodat_trampoline_addr(SB), RODATA, $8 DATA ·libc_mknodat_trampoline_addr(SB)/8, $libc_mknodat_trampoline<>(SB) +TEXT libc_mount_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mount(SB) +GLOBL ·libc_mount_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mount_trampoline_addr(SB)/8, $libc_mount_trampoline<>(SB) + TEXT libc_nanosleep_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_nanosleep(SB) GLOBL ·libc_nanosleep_trampoline_addr(SB), RODATA, $8 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go index c39f7776db..7c8452a63e 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go @@ -1493,6 +1493,30 @@ var libc_mknodat_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Mount(fsType string, dir string, flags int, data unsafe.Pointer) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(fsType) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(dir) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_mount_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags), uintptr(data), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mount_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mount mount "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Nanosleep(time *Timespec, leftover *Timespec) (err error) { _, _, e1 := syscall_syscall(libc_nanosleep_trampoline_addr, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.s index ac4af24f90..b8ef95b0fa 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.s @@ -463,6 +463,11 @@ TEXT libc_mknodat_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_mknodat_trampoline_addr(SB), RODATA, $4 DATA ·libc_mknodat_trampoline_addr(SB)/4, $libc_mknodat_trampoline<>(SB) +TEXT libc_mount_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mount(SB) +GLOBL ·libc_mount_trampoline_addr(SB), RODATA, $4 +DATA ·libc_mount_trampoline_addr(SB)/4, $libc_mount_trampoline<>(SB) + TEXT libc_nanosleep_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_nanosleep(SB) GLOBL ·libc_nanosleep_trampoline_addr(SB), RODATA, $4 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go index 57571d072f..2ffdf861f7 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go @@ -1493,6 +1493,30 @@ var libc_mknodat_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Mount(fsType string, dir string, flags int, data unsafe.Pointer) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(fsType) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(dir) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_mount_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags), uintptr(data), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mount_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mount mount "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Nanosleep(time *Timespec, leftover *Timespec) (err error) { _, _, e1 := syscall_syscall(libc_nanosleep_trampoline_addr, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.s index f77d532121..2af3b5c762 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.s @@ -463,6 +463,11 @@ TEXT libc_mknodat_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_mknodat_trampoline_addr(SB), RODATA, $8 DATA ·libc_mknodat_trampoline_addr(SB)/8, $libc_mknodat_trampoline<>(SB) +TEXT libc_mount_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mount(SB) +GLOBL ·libc_mount_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mount_trampoline_addr(SB)/8, $libc_mount_trampoline<>(SB) + TEXT libc_nanosleep_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_nanosleep(SB) GLOBL ·libc_nanosleep_trampoline_addr(SB), RODATA, $8 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go index e62963e67e..1da08d5267 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go @@ -1493,6 +1493,30 @@ var libc_mknodat_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Mount(fsType string, dir string, flags int, data unsafe.Pointer) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(fsType) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(dir) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_mount_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags), uintptr(data), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mount_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mount mount "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Nanosleep(time *Timespec, leftover *Timespec) (err error) { _, _, e1 := syscall_syscall(libc_nanosleep_trampoline_addr, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.s index fae140b62c..b7a251353b 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.s @@ -463,6 +463,11 @@ TEXT libc_mknodat_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_mknodat_trampoline_addr(SB), RODATA, $8 DATA ·libc_mknodat_trampoline_addr(SB)/8, $libc_mknodat_trampoline<>(SB) +TEXT libc_mount_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mount(SB) +GLOBL ·libc_mount_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mount_trampoline_addr(SB)/8, $libc_mount_trampoline<>(SB) + TEXT libc_nanosleep_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_nanosleep(SB) GLOBL ·libc_nanosleep_trampoline_addr(SB), RODATA, $8 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go index 00831354c8..6e85b0aac9 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go @@ -1493,6 +1493,30 @@ var libc_mknodat_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Mount(fsType string, dir string, flags int, data unsafe.Pointer) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(fsType) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(dir) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_mount_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags), uintptr(data), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mount_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mount mount "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Nanosleep(time *Timespec, leftover *Timespec) (err error) { _, _, e1 := syscall_syscall(libc_nanosleep_trampoline_addr, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.s index 9d1e0ff06d..f15dadf055 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.s @@ -555,6 +555,12 @@ TEXT libc_mknodat_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_mknodat_trampoline_addr(SB), RODATA, $8 DATA ·libc_mknodat_trampoline_addr(SB)/8, $libc_mknodat_trampoline<>(SB) +TEXT libc_mount_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_mount(SB) + RET +GLOBL ·libc_mount_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mount_trampoline_addr(SB)/8, $libc_mount_trampoline<>(SB) + TEXT libc_nanosleep_trampoline<>(SB),NOSPLIT,$0-0 CALL libc_nanosleep(SB) RET diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go index 79029ed584..28b487df25 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go @@ -1493,6 +1493,30 @@ var libc_mknodat_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Mount(fsType string, dir string, flags int, data unsafe.Pointer) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(fsType) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(dir) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(libc_mount_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags), uintptr(data), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_mount_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_mount mount "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Nanosleep(time *Timespec, leftover *Timespec) (err error) { _, _, e1 := syscall_syscall(libc_nanosleep_trampoline_addr, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.s index da115f9a4b..1e7f321e43 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.s @@ -463,6 +463,11 @@ TEXT libc_mknodat_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_mknodat_trampoline_addr(SB), RODATA, $8 DATA ·libc_mknodat_trampoline_addr(SB)/8, $libc_mknodat_trampoline<>(SB) +TEXT libc_mount_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_mount(SB) +GLOBL ·libc_mount_trampoline_addr(SB), RODATA, $8 +DATA ·libc_mount_trampoline_addr(SB)/8, $libc_mount_trampoline<>(SB) + TEXT libc_nanosleep_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_nanosleep(SB) GLOBL ·libc_nanosleep_trampoline_addr(SB), RODATA, $8 diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go index 53aef5dc58..524b0820cb 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go @@ -457,4 +457,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 459 SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go index 71d524763d..f485dbf456 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go @@ -341,6 +341,7 @@ const ( SYS_STATX = 332 SYS_IO_PGETEVENTS = 333 SYS_RSEQ = 334 + SYS_URETPROBE = 335 SYS_PIDFD_SEND_SIGNAL = 424 SYS_IO_URING_SETUP = 425 SYS_IO_URING_ENTER = 426 @@ -379,4 +380,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 459 SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go index c747706131..70b35bf3b0 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go @@ -421,4 +421,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 459 SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go index f96e214f6d..1893e2fe88 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go @@ -85,7 +85,7 @@ const ( SYS_SPLICE = 76 SYS_TEE = 77 SYS_READLINKAT = 78 - SYS_FSTATAT = 79 + SYS_NEWFSTATAT = 79 SYS_FSTAT = 80 SYS_SYNC = 81 SYS_FSYNC = 82 @@ -324,4 +324,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 459 SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go index 28425346cf..16a4017da0 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go @@ -84,6 +84,8 @@ const ( SYS_SPLICE = 76 SYS_TEE = 77 SYS_READLINKAT = 78 + SYS_NEWFSTATAT = 79 + SYS_FSTAT = 80 SYS_SYNC = 81 SYS_FSYNC = 82 SYS_FDATASYNC = 83 @@ -318,4 +320,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 459 SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go index d0953018da..7e567f1eff 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go @@ -441,4 +441,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 4459 SYS_LSM_SET_SELF_ATTR = 4460 SYS_LSM_LIST_MODULES = 4461 + SYS_MSEAL = 4462 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go index 295c7f4b81..38ae55e5ef 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go @@ -371,4 +371,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 5459 SYS_LSM_SET_SELF_ATTR = 5460 SYS_LSM_LIST_MODULES = 5461 + SYS_MSEAL = 5462 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go index d1a9eaca7a..55e92e60a8 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go @@ -371,4 +371,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 5459 SYS_LSM_SET_SELF_ATTR = 5460 SYS_LSM_LIST_MODULES = 5461 + SYS_MSEAL = 5462 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go index bec157c39f..60658d6a02 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go @@ -441,4 +441,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 4459 SYS_LSM_SET_SELF_ATTR = 4460 SYS_LSM_LIST_MODULES = 4461 + SYS_MSEAL = 4462 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go index 7ee7bdc435..e203e8a7ed 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go @@ -448,4 +448,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 459 SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go index fad1f25b44..5944b97d54 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go @@ -420,4 +420,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 459 SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go index 7d3e16357d..c66d416dad 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go @@ -420,4 +420,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 459 SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go index 0ed53ad9f7..a5459e766f 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go @@ -84,7 +84,7 @@ const ( SYS_SPLICE = 76 SYS_TEE = 77 SYS_READLINKAT = 78 - SYS_FSTATAT = 79 + SYS_NEWFSTATAT = 79 SYS_FSTAT = 80 SYS_SYNC = 81 SYS_FSYNC = 82 @@ -325,4 +325,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 459 SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go index 2fba04ad50..01d86825bb 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go @@ -386,4 +386,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 459 SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go index 621d00d741..7b703e77cd 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go @@ -399,4 +399,5 @@ const ( SYS_LSM_GET_SELF_ATTR = 459 SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 + SYS_MSEAL = 462 ) diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go index 091d107f3a..17c53bd9b3 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go @@ -306,6 +306,19 @@ type XVSockPgen struct { type _Socklen uint32 +type SaeAssocID uint32 + +type SaeConnID uint32 + +type SaEndpoints struct { + Srcif uint32 + Srcaddr *RawSockaddr + Srcaddrlen uint32 + Dstaddr *RawSockaddr + Dstaddrlen uint32 + _ [4]byte +} + type Xucred struct { Version uint32 Uid uint32 @@ -449,11 +462,14 @@ type FdSet struct { const ( SizeofIfMsghdr = 0x70 + SizeofIfMsghdr2 = 0xa0 SizeofIfData = 0x60 + SizeofIfData64 = 0x80 SizeofIfaMsghdr = 0x14 SizeofIfmaMsghdr = 0x10 SizeofIfmaMsghdr2 = 0x14 SizeofRtMsghdr = 0x5c + SizeofRtMsghdr2 = 0x5c SizeofRtMetrics = 0x38 ) @@ -467,6 +483,20 @@ type IfMsghdr struct { Data IfData } +type IfMsghdr2 struct { + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + Snd_len int32 + Snd_maxlen int32 + Snd_drops int32 + Timer int32 + Data IfData64 +} + type IfData struct { Type uint8 Typelen uint8 @@ -499,6 +529,34 @@ type IfData struct { Reserved2 uint32 } +type IfData64 struct { + Type uint8 + Typelen uint8 + Physical uint8 + Addrlen uint8 + Hdrlen uint8 + Recvquota uint8 + Xmitquota uint8 + Unused1 uint8 + Mtu uint32 + Metric uint32 + Baudrate uint64 + Ipackets uint64 + Ierrors uint64 + Opackets uint64 + Oerrors uint64 + Collisions uint64 + Ibytes uint64 + Obytes uint64 + Imcasts uint64 + Omcasts uint64 + Iqdrops uint64 + Noproto uint64 + Recvtiming uint32 + Xmittiming uint32 + Lastchange Timeval32 +} + type IfaMsghdr struct { Msglen uint16 Version uint8 @@ -544,6 +602,21 @@ type RtMsghdr struct { Rmx RtMetrics } +type RtMsghdr2 struct { + Msglen uint16 + Version uint8 + Type uint8 + Index uint16 + Flags int32 + Addrs int32 + Refcnt int32 + Parentflags int32 + Reserved int32 + Use int32 + Inits uint32 + Rmx RtMetrics +} + type RtMetrics struct { Locks uint32 Mtu uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go index 28ff4ef74d..2392226a74 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go @@ -306,6 +306,19 @@ type XVSockPgen struct { type _Socklen uint32 +type SaeAssocID uint32 + +type SaeConnID uint32 + +type SaEndpoints struct { + Srcif uint32 + Srcaddr *RawSockaddr + Srcaddrlen uint32 + Dstaddr *RawSockaddr + Dstaddrlen uint32 + _ [4]byte +} + type Xucred struct { Version uint32 Uid uint32 @@ -449,11 +462,14 @@ type FdSet struct { const ( SizeofIfMsghdr = 0x70 + SizeofIfMsghdr2 = 0xa0 SizeofIfData = 0x60 + SizeofIfData64 = 0x80 SizeofIfaMsghdr = 0x14 SizeofIfmaMsghdr = 0x10 SizeofIfmaMsghdr2 = 0x14 SizeofRtMsghdr = 0x5c + SizeofRtMsghdr2 = 0x5c SizeofRtMetrics = 0x38 ) @@ -467,6 +483,20 @@ type IfMsghdr struct { Data IfData } +type IfMsghdr2 struct { + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + Snd_len int32 + Snd_maxlen int32 + Snd_drops int32 + Timer int32 + Data IfData64 +} + type IfData struct { Type uint8 Typelen uint8 @@ -499,6 +529,34 @@ type IfData struct { Reserved2 uint32 } +type IfData64 struct { + Type uint8 + Typelen uint8 + Physical uint8 + Addrlen uint8 + Hdrlen uint8 + Recvquota uint8 + Xmitquota uint8 + Unused1 uint8 + Mtu uint32 + Metric uint32 + Baudrate uint64 + Ipackets uint64 + Ierrors uint64 + Opackets uint64 + Oerrors uint64 + Collisions uint64 + Ibytes uint64 + Obytes uint64 + Imcasts uint64 + Omcasts uint64 + Iqdrops uint64 + Noproto uint64 + Recvtiming uint32 + Xmittiming uint32 + Lastchange Timeval32 +} + type IfaMsghdr struct { Msglen uint16 Version uint8 @@ -544,6 +602,21 @@ type RtMsghdr struct { Rmx RtMetrics } +type RtMsghdr2 struct { + Msglen uint16 + Version uint8 + Type uint8 + Index uint16 + Flags int32 + Addrs int32 + Refcnt int32 + Parentflags int32 + Reserved int32 + Use int32 + Inits uint32 + Rmx RtMetrics +} + type RtMetrics struct { Locks uint32 Mtu uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go index 6cbd094a3a..51e13eb055 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go @@ -625,6 +625,7 @@ const ( POLLRDNORM = 0x40 POLLWRBAND = 0x100 POLLWRNORM = 0x4 + POLLRDHUP = 0x4000 ) type CapRights struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go index 7c03b6ee77..d002d8ef3c 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go @@ -630,6 +630,7 @@ const ( POLLRDNORM = 0x40 POLLWRBAND = 0x100 POLLWRNORM = 0x4 + POLLRDHUP = 0x4000 ) type CapRights struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go index 422107ee8b..3f863d898d 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go @@ -616,6 +616,7 @@ const ( POLLRDNORM = 0x40 POLLWRBAND = 0x100 POLLWRNORM = 0x4 + POLLRDHUP = 0x4000 ) type CapRights struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go index 505a12acfd..61c7293106 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go @@ -610,6 +610,7 @@ const ( POLLRDNORM = 0x40 POLLWRBAND = 0x100 POLLWRNORM = 0x4 + POLLRDHUP = 0x4000 ) type CapRights struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_riscv64.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_riscv64.go index cc986c7900..b5d17414f0 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_riscv64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_riscv64.go @@ -612,6 +612,7 @@ const ( POLLRDNORM = 0x40 POLLWRBAND = 0x100 POLLWRNORM = 0x4 + POLLRDHUP = 0x4000 ) type CapRights struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index 4740b83485..5537148dcb 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -87,30 +87,35 @@ type StatxTimestamp struct { } type Statx_t struct { - Mask uint32 - Blksize uint32 - Attributes uint64 - Nlink uint32 - Uid uint32 - Gid uint32 - Mode uint16 - _ [1]uint16 - Ino uint64 - Size uint64 - Blocks uint64 - Attributes_mask uint64 - Atime StatxTimestamp - Btime StatxTimestamp - Ctime StatxTimestamp - Mtime StatxTimestamp - Rdev_major uint32 - Rdev_minor uint32 - Dev_major uint32 - Dev_minor uint32 - Mnt_id uint64 - Dio_mem_align uint32 - Dio_offset_align uint32 - _ [12]uint64 + Mask uint32 + Blksize uint32 + Attributes uint64 + Nlink uint32 + Uid uint32 + Gid uint32 + Mode uint16 + _ [1]uint16 + Ino uint64 + Size uint64 + Blocks uint64 + Attributes_mask uint64 + Atime StatxTimestamp + Btime StatxTimestamp + Ctime StatxTimestamp + Mtime StatxTimestamp + Rdev_major uint32 + Rdev_minor uint32 + Dev_major uint32 + Dev_minor uint32 + Mnt_id uint64 + Dio_mem_align uint32 + Dio_offset_align uint32 + Subvol uint64 + Atomic_write_unit_min uint32 + Atomic_write_unit_max uint32 + Atomic_write_segments_max uint32 + _ [1]uint32 + _ [9]uint64 } type Fsid struct { @@ -515,6 +520,29 @@ type TCPInfo struct { Total_rto_time uint32 } +type TCPVegasInfo struct { + Enabled uint32 + Rttcnt uint32 + Rtt uint32 + Minrtt uint32 +} + +type TCPDCTCPInfo struct { + Enabled uint16 + Ce_state uint16 + Alpha uint32 + Ab_ecn uint32 + Ab_tot uint32 +} + +type TCPBBRInfo struct { + Bw_lo uint32 + Bw_hi uint32 + Min_rtt uint32 + Pacing_gain uint32 + Cwnd_gain uint32 +} + type CanFilter struct { Id uint32 Mask uint32 @@ -556,6 +584,7 @@ const ( SizeofICMPv6Filter = 0x20 SizeofUcred = 0xc SizeofTCPInfo = 0xf8 + SizeofTCPCCInfo = 0x14 SizeofCanFilter = 0x8 SizeofTCPRepairOpt = 0x8 ) @@ -1723,12 +1752,6 @@ const ( IFLA_IPVLAN_UNSPEC = 0x0 IFLA_IPVLAN_MODE = 0x1 IFLA_IPVLAN_FLAGS = 0x2 - NETKIT_NEXT = -0x1 - NETKIT_PASS = 0x0 - NETKIT_DROP = 0x2 - NETKIT_REDIRECT = 0x7 - NETKIT_L2 = 0x0 - NETKIT_L3 = 0x1 IFLA_NETKIT_UNSPEC = 0x0 IFLA_NETKIT_PEER_INFO = 0x1 IFLA_NETKIT_PRIMARY = 0x2 @@ -1767,6 +1790,7 @@ const ( IFLA_VXLAN_DF = 0x1d IFLA_VXLAN_VNIFILTER = 0x1e IFLA_VXLAN_LOCALBYPASS = 0x1f + IFLA_VXLAN_LABEL_POLICY = 0x20 IFLA_GENEVE_UNSPEC = 0x0 IFLA_GENEVE_ID = 0x1 IFLA_GENEVE_REMOTE = 0x2 @@ -1796,6 +1820,8 @@ const ( IFLA_GTP_ROLE = 0x4 IFLA_GTP_CREATE_SOCKETS = 0x5 IFLA_GTP_RESTART_COUNT = 0x6 + IFLA_GTP_LOCAL = 0x7 + IFLA_GTP_LOCAL6 = 0x8 IFLA_BOND_UNSPEC = 0x0 IFLA_BOND_MODE = 0x1 IFLA_BOND_ACTIVE_SLAVE = 0x2 @@ -1828,6 +1854,7 @@ const ( IFLA_BOND_AD_LACP_ACTIVE = 0x1d IFLA_BOND_MISSED_MAX = 0x1e IFLA_BOND_NS_IP6_TARGET = 0x1f + IFLA_BOND_COUPLED_CONTROL = 0x20 IFLA_BOND_AD_INFO_UNSPEC = 0x0 IFLA_BOND_AD_INFO_AGGREGATOR = 0x1 IFLA_BOND_AD_INFO_NUM_PORTS = 0x2 @@ -1896,6 +1923,7 @@ const ( IFLA_HSR_SEQ_NR = 0x5 IFLA_HSR_VERSION = 0x6 IFLA_HSR_PROTOCOL = 0x7 + IFLA_HSR_INTERLINK = 0x8 IFLA_STATS_UNSPEC = 0x0 IFLA_STATS_LINK_64 = 0x1 IFLA_STATS_LINK_XSTATS = 0x2 @@ -1948,6 +1976,15 @@ const ( IFLA_DSA_MASTER = 0x1 ) +const ( + NETKIT_NEXT = -0x1 + NETKIT_PASS = 0x0 + NETKIT_DROP = 0x2 + NETKIT_REDIRECT = 0x7 + NETKIT_L2 = 0x0 + NETKIT_L3 = 0x1 +) + const ( NF_INET_PRE_ROUTING = 0x0 NF_INET_LOCAL_IN = 0x1 @@ -2485,7 +2522,7 @@ type XDPMmapOffsets struct { type XDPUmemReg struct { Addr uint64 Len uint64 - Chunk_size uint32 + Size uint32 Headroom uint32 Flags uint32 Tx_metadata_len uint32 @@ -2557,8 +2594,8 @@ const ( SOF_TIMESTAMPING_BIND_PHC = 0x8000 SOF_TIMESTAMPING_OPT_ID_TCP = 0x10000 - SOF_TIMESTAMPING_LAST = 0x10000 - SOF_TIMESTAMPING_MASK = 0x1ffff + SOF_TIMESTAMPING_LAST = 0x20000 + SOF_TIMESTAMPING_MASK = 0x3ffff SCM_TSTAMP_SND = 0x0 SCM_TSTAMP_SCHED = 0x1 @@ -3473,7 +3510,7 @@ const ( DEVLINK_PORT_FN_ATTR_STATE = 0x2 DEVLINK_PORT_FN_ATTR_OPSTATE = 0x3 DEVLINK_PORT_FN_ATTR_CAPS = 0x4 - DEVLINK_PORT_FUNCTION_ATTR_MAX = 0x5 + DEVLINK_PORT_FUNCTION_ATTR_MAX = 0x6 ) type FsverityDigest struct { @@ -3504,7 +3541,7 @@ type Nhmsg struct { type NexthopGrp struct { Id uint32 Weight uint8 - Resvd1 uint8 + High uint8 Resvd2 uint16 } @@ -3765,7 +3802,7 @@ const ( ETHTOOL_MSG_PSE_GET = 0x24 ETHTOOL_MSG_PSE_SET = 0x25 ETHTOOL_MSG_RSS_GET = 0x26 - ETHTOOL_MSG_USER_MAX = 0x2b + ETHTOOL_MSG_USER_MAX = 0x2d ETHTOOL_MSG_KERNEL_NONE = 0x0 ETHTOOL_MSG_STRSET_GET_REPLY = 0x1 ETHTOOL_MSG_LINKINFO_GET_REPLY = 0x2 @@ -3805,12 +3842,15 @@ const ( ETHTOOL_MSG_MODULE_NTF = 0x24 ETHTOOL_MSG_PSE_GET_REPLY = 0x25 ETHTOOL_MSG_RSS_GET_REPLY = 0x26 - ETHTOOL_MSG_KERNEL_MAX = 0x2b + ETHTOOL_MSG_KERNEL_MAX = 0x2e + ETHTOOL_FLAG_COMPACT_BITSETS = 0x1 + ETHTOOL_FLAG_OMIT_REPLY = 0x2 + ETHTOOL_FLAG_STATS = 0x4 ETHTOOL_A_HEADER_UNSPEC = 0x0 ETHTOOL_A_HEADER_DEV_INDEX = 0x1 ETHTOOL_A_HEADER_DEV_NAME = 0x2 ETHTOOL_A_HEADER_FLAGS = 0x3 - ETHTOOL_A_HEADER_MAX = 0x3 + ETHTOOL_A_HEADER_MAX = 0x4 ETHTOOL_A_BITSET_BIT_UNSPEC = 0x0 ETHTOOL_A_BITSET_BIT_INDEX = 0x1 ETHTOOL_A_BITSET_BIT_NAME = 0x2 @@ -3947,7 +3987,7 @@ const ( ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL = 0x17 ETHTOOL_A_COALESCE_USE_CQE_MODE_TX = 0x18 ETHTOOL_A_COALESCE_USE_CQE_MODE_RX = 0x19 - ETHTOOL_A_COALESCE_MAX = 0x1c + ETHTOOL_A_COALESCE_MAX = 0x1e ETHTOOL_A_PAUSE_UNSPEC = 0x0 ETHTOOL_A_PAUSE_HEADER = 0x1 ETHTOOL_A_PAUSE_AUTONEG = 0x2 @@ -3975,7 +4015,7 @@ const ( ETHTOOL_A_TSINFO_TX_TYPES = 0x3 ETHTOOL_A_TSINFO_RX_FILTERS = 0x4 ETHTOOL_A_TSINFO_PHC_INDEX = 0x5 - ETHTOOL_A_TSINFO_MAX = 0x5 + ETHTOOL_A_TSINFO_MAX = 0x6 ETHTOOL_A_CABLE_TEST_UNSPEC = 0x0 ETHTOOL_A_CABLE_TEST_HEADER = 0x1 ETHTOOL_A_CABLE_TEST_MAX = 0x1 @@ -3991,11 +4031,11 @@ const ( ETHTOOL_A_CABLE_RESULT_UNSPEC = 0x0 ETHTOOL_A_CABLE_RESULT_PAIR = 0x1 ETHTOOL_A_CABLE_RESULT_CODE = 0x2 - ETHTOOL_A_CABLE_RESULT_MAX = 0x2 + ETHTOOL_A_CABLE_RESULT_MAX = 0x3 ETHTOOL_A_CABLE_FAULT_LENGTH_UNSPEC = 0x0 ETHTOOL_A_CABLE_FAULT_LENGTH_PAIR = 0x1 ETHTOOL_A_CABLE_FAULT_LENGTH_CM = 0x2 - ETHTOOL_A_CABLE_FAULT_LENGTH_MAX = 0x2 + ETHTOOL_A_CABLE_FAULT_LENGTH_MAX = 0x3 ETHTOOL_A_CABLE_TEST_NTF_STATUS_UNSPEC = 0x0 ETHTOOL_A_CABLE_TEST_NTF_STATUS_STARTED = 0x1 ETHTOOL_A_CABLE_TEST_NTF_STATUS_COMPLETED = 0x2 @@ -4078,6 +4118,107 @@ type EthtoolDrvinfo struct { Regdump_len uint32 } +type EthtoolTsInfo struct { + Cmd uint32 + So_timestamping uint32 + Phc_index int32 + Tx_types uint32 + Tx_reserved [3]uint32 + Rx_filters uint32 + Rx_reserved [3]uint32 +} + +type HwTstampConfig struct { + Flags int32 + Tx_type int32 + Rx_filter int32 +} + +const ( + HWTSTAMP_FILTER_NONE = 0x0 + HWTSTAMP_FILTER_ALL = 0x1 + HWTSTAMP_FILTER_SOME = 0x2 + HWTSTAMP_FILTER_PTP_V1_L4_EVENT = 0x3 + HWTSTAMP_FILTER_PTP_V2_L4_EVENT = 0x6 + HWTSTAMP_FILTER_PTP_V2_L2_EVENT = 0x9 + HWTSTAMP_FILTER_PTP_V2_EVENT = 0xc +) + +const ( + HWTSTAMP_TX_OFF = 0x0 + HWTSTAMP_TX_ON = 0x1 + HWTSTAMP_TX_ONESTEP_SYNC = 0x2 +) + +type ( + PtpClockCaps struct { + Max_adj int32 + N_alarm int32 + N_ext_ts int32 + N_per_out int32 + Pps int32 + N_pins int32 + Cross_timestamping int32 + Adjust_phase int32 + Max_phase_adj int32 + Rsv [11]int32 + } + PtpClockTime struct { + Sec int64 + Nsec uint32 + Reserved uint32 + } + PtpExttsEvent struct { + T PtpClockTime + Index uint32 + Flags uint32 + Rsv [2]uint32 + } + PtpExttsRequest struct { + Index uint32 + Flags uint32 + Rsv [2]uint32 + } + PtpPeroutRequest struct { + StartOrPhase PtpClockTime + Period PtpClockTime + Index uint32 + Flags uint32 + On PtpClockTime + } + PtpPinDesc struct { + Name [64]byte + Index uint32 + Func uint32 + Chan uint32 + Rsv [5]uint32 + } + PtpSysOffset struct { + Samples uint32 + Rsv [3]uint32 + Ts [51]PtpClockTime + } + PtpSysOffsetExtended struct { + Samples uint32 + Clockid int32 + Rsv [2]uint32 + Ts [25][3]PtpClockTime + } + PtpSysOffsetPrecise struct { + Device PtpClockTime + Realtime PtpClockTime + Monoraw PtpClockTime + Rsv [4]uint32 + } +) + +const ( + PTP_PF_NONE = 0x0 + PTP_PF_EXTTS = 0x1 + PTP_PF_PEROUT = 0x2 + PTP_PF_PHYSYNC = 0x3 +) + type ( HIDRawReportDescriptor struct { Size uint32 @@ -4259,6 +4400,7 @@ const ( type LandlockRulesetAttr struct { Access_fs uint64 Access_net uint64 + Scoped uint64 } type LandlockPathBeneathAttr struct { @@ -4605,7 +4747,7 @@ const ( NL80211_ATTR_MAC_HINT = 0xc8 NL80211_ATTR_MAC_MASK = 0xd7 NL80211_ATTR_MAX_AP_ASSOC_STA = 0xca - NL80211_ATTR_MAX = 0x14a + NL80211_ATTR_MAX = 0x14c NL80211_ATTR_MAX_CRIT_PROT_DURATION = 0xb4 NL80211_ATTR_MAX_CSA_COUNTERS = 0xce NL80211_ATTR_MAX_MATCH_SETS = 0x85 @@ -5209,7 +5351,7 @@ const ( NL80211_FREQUENCY_ATTR_GO_CONCURRENT = 0xf NL80211_FREQUENCY_ATTR_INDOOR_ONLY = 0xe NL80211_FREQUENCY_ATTR_IR_CONCURRENT = 0xf - NL80211_FREQUENCY_ATTR_MAX = 0x20 + NL80211_FREQUENCY_ATTR_MAX = 0x21 NL80211_FREQUENCY_ATTR_MAX_TX_POWER = 0x6 NL80211_FREQUENCY_ATTR_NO_10MHZ = 0x11 NL80211_FREQUENCY_ATTR_NO_160MHZ = 0xc diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go index 15adc04142..ad05b51a60 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go @@ -727,6 +727,37 @@ const ( RISCV_HWPROBE_EXT_ZBA = 0x8 RISCV_HWPROBE_EXT_ZBB = 0x10 RISCV_HWPROBE_EXT_ZBS = 0x20 + RISCV_HWPROBE_EXT_ZICBOZ = 0x40 + RISCV_HWPROBE_EXT_ZBC = 0x80 + RISCV_HWPROBE_EXT_ZBKB = 0x100 + RISCV_HWPROBE_EXT_ZBKC = 0x200 + RISCV_HWPROBE_EXT_ZBKX = 0x400 + RISCV_HWPROBE_EXT_ZKND = 0x800 + RISCV_HWPROBE_EXT_ZKNE = 0x1000 + RISCV_HWPROBE_EXT_ZKNH = 0x2000 + RISCV_HWPROBE_EXT_ZKSED = 0x4000 + RISCV_HWPROBE_EXT_ZKSH = 0x8000 + RISCV_HWPROBE_EXT_ZKT = 0x10000 + RISCV_HWPROBE_EXT_ZVBB = 0x20000 + RISCV_HWPROBE_EXT_ZVBC = 0x40000 + RISCV_HWPROBE_EXT_ZVKB = 0x80000 + RISCV_HWPROBE_EXT_ZVKG = 0x100000 + RISCV_HWPROBE_EXT_ZVKNED = 0x200000 + RISCV_HWPROBE_EXT_ZVKNHA = 0x400000 + RISCV_HWPROBE_EXT_ZVKNHB = 0x800000 + RISCV_HWPROBE_EXT_ZVKSED = 0x1000000 + RISCV_HWPROBE_EXT_ZVKSH = 0x2000000 + RISCV_HWPROBE_EXT_ZVKT = 0x4000000 + RISCV_HWPROBE_EXT_ZFH = 0x8000000 + RISCV_HWPROBE_EXT_ZFHMIN = 0x10000000 + RISCV_HWPROBE_EXT_ZIHINTNTL = 0x20000000 + RISCV_HWPROBE_EXT_ZVFH = 0x40000000 + RISCV_HWPROBE_EXT_ZVFHMIN = 0x80000000 + RISCV_HWPROBE_EXT_ZFA = 0x100000000 + RISCV_HWPROBE_EXT_ZTSO = 0x200000000 + RISCV_HWPROBE_EXT_ZACAS = 0x400000000 + RISCV_HWPROBE_EXT_ZICOND = 0x800000000 + RISCV_HWPROBE_EXT_ZIHINTPAUSE = 0x1000000000 RISCV_HWPROBE_KEY_CPUPERF_0 = 0x5 RISCV_HWPROBE_MISALIGNED_UNKNOWN = 0x0 RISCV_HWPROBE_MISALIGNED_EMULATED = 0x1 @@ -734,4 +765,6 @@ const ( RISCV_HWPROBE_MISALIGNED_FAST = 0x3 RISCV_HWPROBE_MISALIGNED_UNSUPPORTED = 0x4 RISCV_HWPROBE_MISALIGNED_MASK = 0x7 + RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE = 0x6 + RISCV_HWPROBE_WHICH_CPUS = 0x1 ) diff --git a/vendor/golang.org/x/sys/unix/ztypes_zos_s390x.go b/vendor/golang.org/x/sys/unix/ztypes_zos_s390x.go index d9a13af468..2e5d5a4435 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_zos_s390x.go +++ b/vendor/golang.org/x/sys/unix/ztypes_zos_s390x.go @@ -377,6 +377,12 @@ type Flock_t struct { Pid int32 } +type F_cnvrt struct { + Cvtcmd int32 + Pccsid int16 + Fccsid int16 +} + type Termios struct { Cflag uint32 Iflag uint32 diff --git a/vendor/golang.org/x/sys/windows/dll_windows.go b/vendor/golang.org/x/sys/windows/dll_windows.go index 115341fba6..3ca814f54d 100644 --- a/vendor/golang.org/x/sys/windows/dll_windows.go +++ b/vendor/golang.org/x/sys/windows/dll_windows.go @@ -43,8 +43,8 @@ type DLL struct { // LoadDLL loads DLL file into memory. // // Warning: using LoadDLL without an absolute path name is subject to -// DLL preloading attacks. To safely load a system DLL, use LazyDLL -// with System set to true, or use LoadLibraryEx directly. +// DLL preloading attacks. To safely load a system DLL, use [NewLazySystemDLL], +// or use [LoadLibraryEx] directly. func LoadDLL(name string) (dll *DLL, err error) { namep, err := UTF16PtrFromString(name) if err != nil { @@ -65,7 +65,7 @@ func LoadDLL(name string) (dll *DLL, err error) { return d, nil } -// MustLoadDLL is like LoadDLL but panics if load operation failes. +// MustLoadDLL is like LoadDLL but panics if load operation fails. func MustLoadDLL(name string) *DLL { d, e := LoadDLL(name) if e != nil { @@ -271,6 +271,9 @@ func (d *LazyDLL) NewProc(name string) *LazyProc { } // NewLazyDLL creates new LazyDLL associated with DLL file. +// +// Warning: using NewLazyDLL without an absolute path name is subject to +// DLL preloading attacks. To safely load a system DLL, use [NewLazySystemDLL]. func NewLazyDLL(name string) *LazyDLL { return &LazyDLL{Name: name} } @@ -410,7 +413,3 @@ func loadLibraryEx(name string, system bool) (*DLL, error) { } return &DLL{Name: name, Handle: h}, nil } - -type errString string - -func (s errString) Error() string { return string(s) } diff --git a/vendor/golang.org/x/sys/windows/security_windows.go b/vendor/golang.org/x/sys/windows/security_windows.go index 6f7d2ac70a..b6e1ab76f8 100644 --- a/vendor/golang.org/x/sys/windows/security_windows.go +++ b/vendor/golang.org/x/sys/windows/security_windows.go @@ -894,7 +894,7 @@ type ACL struct { aclRevision byte sbz1 byte aclSize uint16 - aceCount uint16 + AceCount uint16 sbz2 uint16 } @@ -1087,6 +1087,27 @@ type EXPLICIT_ACCESS struct { Trustee TRUSTEE } +// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header +type ACE_HEADER struct { + AceType uint8 + AceFlags uint8 + AceSize uint16 +} + +// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_allowed_ace +type ACCESS_ALLOWED_ACE struct { + Header ACE_HEADER + Mask ACCESS_MASK + SidStart uint32 +} + +const ( + // Constants for AceType + // https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header + ACCESS_ALLOWED_ACE_TYPE = 0 + ACCESS_DENIED_ACE_TYPE = 1 +) + // This type is the union inside of TRUSTEE and must be created using one of the TrusteeValueFrom* functions. type TrusteeValue uintptr @@ -1158,6 +1179,7 @@ type OBJECTS_AND_NAME struct { //sys makeSelfRelativeSD(absoluteSD *SECURITY_DESCRIPTOR, selfRelativeSD *SECURITY_DESCRIPTOR, selfRelativeSDSize *uint32) (err error) = advapi32.MakeSelfRelativeSD //sys setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCESS, oldACL *ACL, newACL **ACL) (ret error) = advapi32.SetEntriesInAclW +//sys GetAce(acl *ACL, aceIndex uint32, pAce **ACCESS_ALLOWED_ACE) (err error) = advapi32.GetAce // Control returns the security descriptor control bits. func (sd *SECURITY_DESCRIPTOR) Control() (control SECURITY_DESCRIPTOR_CONTROL, revision uint32, err error) { diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go index 6525c62f3c..4a32543868 100644 --- a/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -17,8 +17,10 @@ import ( "unsafe" ) -type Handle uintptr -type HWND uintptr +type ( + Handle uintptr + HWND uintptr +) const ( InvalidHandle = ^Handle(0) @@ -166,6 +168,8 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys CreateNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *SecurityAttributes) (handle Handle, err error) [failretval==InvalidHandle] = CreateNamedPipeW //sys ConnectNamedPipe(pipe Handle, overlapped *Overlapped) (err error) //sys DisconnectNamedPipe(pipe Handle) (err error) +//sys GetNamedPipeClientProcessId(pipe Handle, clientProcessID *uint32) (err error) +//sys GetNamedPipeServerProcessId(pipe Handle, serverProcessID *uint32) (err error) //sys GetNamedPipeInfo(pipe Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) //sys GetNamedPipeHandleState(pipe Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW //sys SetNamedPipeHandleState(pipe Handle, state *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32) (err error) = SetNamedPipeHandleState @@ -211,6 +215,10 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys OpenProcess(desiredAccess uint32, inheritHandle bool, processId uint32) (handle Handle, err error) //sys ShellExecute(hwnd Handle, verb *uint16, file *uint16, args *uint16, cwd *uint16, showCmd int32) (err error) [failretval<=32] = shell32.ShellExecuteW //sys GetWindowThreadProcessId(hwnd HWND, pid *uint32) (tid uint32, err error) = user32.GetWindowThreadProcessId +//sys LoadKeyboardLayout(name *uint16, flags uint32) (hkl Handle, err error) [failretval==0] = user32.LoadKeyboardLayoutW +//sys UnloadKeyboardLayout(hkl Handle) (err error) = user32.UnloadKeyboardLayout +//sys GetKeyboardLayout(tid uint32) (hkl Handle) = user32.GetKeyboardLayout +//sys ToUnicodeEx(vkey uint32, scancode uint32, keystate *byte, pwszBuff *uint16, cchBuff int32, flags uint32, hkl Handle) (ret int32) = user32.ToUnicodeEx //sys GetShellWindow() (shellWindow HWND) = user32.GetShellWindow //sys MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) [failretval==0] = user32.MessageBoxW //sys ExitWindowsEx(flags uint32, reason uint32) (err error) = user32.ExitWindowsEx @@ -307,6 +315,10 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys SetConsoleMode(console Handle, mode uint32) (err error) = kernel32.SetConsoleMode //sys GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) = kernel32.GetConsoleScreenBufferInfo //sys setConsoleCursorPosition(console Handle, position uint32) (err error) = kernel32.SetConsoleCursorPosition +//sys GetConsoleCP() (cp uint32, err error) = kernel32.GetConsoleCP +//sys GetConsoleOutputCP() (cp uint32, err error) = kernel32.GetConsoleOutputCP +//sys SetConsoleCP(cp uint32) (err error) = kernel32.SetConsoleCP +//sys SetConsoleOutputCP(cp uint32) (err error) = kernel32.SetConsoleOutputCP //sys WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW //sys ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW //sys resizePseudoConsole(pconsole Handle, size uint32) (hr error) = kernel32.ResizePseudoConsole @@ -715,20 +727,12 @@ func DurationSinceBoot() time.Duration { } func Ftruncate(fd Handle, length int64) (err error) { - curoffset, e := Seek(fd, 0, 1) - if e != nil { - return e - } - defer Seek(fd, curoffset, 0) - _, e = Seek(fd, length, 0) - if e != nil { - return e + type _FILE_END_OF_FILE_INFO struct { + EndOfFile int64 } - e = SetEndOfFile(fd) - if e != nil { - return e - } - return nil + var info _FILE_END_OF_FILE_INFO + info.EndOfFile = length + return SetFileInformationByHandle(fd, FileEndOfFileInfo, (*byte)(unsafe.Pointer(&info)), uint32(unsafe.Sizeof(info))) } func Gettimeofday(tv *Timeval) (err error) { @@ -884,6 +888,11 @@ const socket_error = uintptr(^uint32(0)) //sys GetACP() (acp uint32) = kernel32.GetACP //sys MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar //sys getBestInterfaceEx(sockaddr unsafe.Pointer, pdwBestIfIndex *uint32) (errcode error) = iphlpapi.GetBestInterfaceEx +//sys GetIfEntry2Ex(level uint32, row *MibIfRow2) (errcode error) = iphlpapi.GetIfEntry2Ex +//sys GetUnicastIpAddressEntry(row *MibUnicastIpAddressRow) (errcode error) = iphlpapi.GetUnicastIpAddressEntry +//sys NotifyIpInterfaceChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyIpInterfaceChange +//sys NotifyUnicastIpAddressChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyUnicastIpAddressChange +//sys CancelMibChangeNotify2(notificationHandle Handle) (errcode error) = iphlpapi.CancelMibChangeNotify2 // For testing: clients can set this flag to force // creation of IPv6 sockets to return EAFNOSUPPORT. @@ -1368,9 +1377,11 @@ func SetsockoptLinger(fd Handle, level, opt int, l *Linger) (err error) { func SetsockoptInet4Addr(fd Handle, level, opt int, value [4]byte) (err error) { return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&value[0])), 4) } + func SetsockoptIPMreq(fd Handle, level, opt int, mreq *IPMreq) (err error) { return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(mreq)), int32(unsafe.Sizeof(*mreq))) } + func SetsockoptIPv6Mreq(fd Handle, level, opt int, mreq *IPv6Mreq) (err error) { return syscall.EWINDOWS } @@ -1673,13 +1684,16 @@ func (s NTStatus) Error() string { // do not use NTUnicodeString, and instead UTF16PtrFromString should be used for // the more common *uint16 string type. func NewNTUnicodeString(s string) (*NTUnicodeString, error) { - var u NTUnicodeString - s16, err := UTF16PtrFromString(s) + s16, err := UTF16FromString(s) if err != nil { return nil, err } - RtlInitUnicodeString(&u, s16) - return &u, nil + n := uint16(len(s16) * 2) + return &NTUnicodeString{ + Length: n - 2, // subtract 2 bytes for the NULL terminator + MaximumLength: n, + Buffer: &s16[0], + }, nil } // Slice returns a uint16 slice that aliases the data in the NTUnicodeString. diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go index d8cb71db0a..9d138de5fe 100644 --- a/vendor/golang.org/x/sys/windows/types_windows.go +++ b/vendor/golang.org/x/sys/windows/types_windows.go @@ -176,6 +176,7 @@ const ( WAIT_FAILED = 0xFFFFFFFF // Access rights for process. + PROCESS_ALL_ACCESS = 0xFFFF PROCESS_CREATE_PROCESS = 0x0080 PROCESS_CREATE_THREAD = 0x0002 PROCESS_DUP_HANDLE = 0x0040 @@ -1060,6 +1061,7 @@ const ( SIO_GET_EXTENSION_FUNCTION_POINTER = IOC_INOUT | IOC_WS2 | 6 SIO_KEEPALIVE_VALS = IOC_IN | IOC_VENDOR | 4 SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12 + SIO_UDP_NETRESET = IOC_IN | IOC_VENDOR | 15 // cf. http://support.microsoft.com/default.aspx?scid=kb;en-us;257460 @@ -2003,7 +2005,21 @@ const ( MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x20 ) -const GAA_FLAG_INCLUDE_PREFIX = 0x00000010 +// Flags for GetAdaptersAddresses, see +// https://learn.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getadaptersaddresses. +const ( + GAA_FLAG_SKIP_UNICAST = 0x1 + GAA_FLAG_SKIP_ANYCAST = 0x2 + GAA_FLAG_SKIP_MULTICAST = 0x4 + GAA_FLAG_SKIP_DNS_SERVER = 0x8 + GAA_FLAG_INCLUDE_PREFIX = 0x10 + GAA_FLAG_SKIP_FRIENDLY_NAME = 0x20 + GAA_FLAG_INCLUDE_WINS_INFO = 0x40 + GAA_FLAG_INCLUDE_GATEWAYS = 0x80 + GAA_FLAG_INCLUDE_ALL_INTERFACES = 0x100 + GAA_FLAG_INCLUDE_ALL_COMPARTMENTS = 0x200 + GAA_FLAG_INCLUDE_TUNNEL_BINDINGORDER = 0x400 +) const ( IF_TYPE_OTHER = 1 @@ -2017,6 +2033,50 @@ const ( IF_TYPE_IEEE1394 = 144 ) +// Enum NL_PREFIX_ORIGIN for [IpAdapterUnicastAddress], see +// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_prefix_origin +const ( + IpPrefixOriginOther = 0 + IpPrefixOriginManual = 1 + IpPrefixOriginWellKnown = 2 + IpPrefixOriginDhcp = 3 + IpPrefixOriginRouterAdvertisement = 4 + IpPrefixOriginUnchanged = 1 << 4 +) + +// Enum NL_SUFFIX_ORIGIN for [IpAdapterUnicastAddress], see +// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_suffix_origin +const ( + NlsoOther = 0 + NlsoManual = 1 + NlsoWellKnown = 2 + NlsoDhcp = 3 + NlsoLinkLayerAddress = 4 + NlsoRandom = 5 + IpSuffixOriginOther = 0 + IpSuffixOriginManual = 1 + IpSuffixOriginWellKnown = 2 + IpSuffixOriginDhcp = 3 + IpSuffixOriginLinkLayerAddress = 4 + IpSuffixOriginRandom = 5 + IpSuffixOriginUnchanged = 1 << 4 +) + +// Enum NL_DAD_STATE for [IpAdapterUnicastAddress], see +// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_dad_state +const ( + NldsInvalid = 0 + NldsTentative = 1 + NldsDuplicate = 2 + NldsDeprecated = 3 + NldsPreferred = 4 + IpDadStateInvalid = 0 + IpDadStateTentative = 1 + IpDadStateDuplicate = 2 + IpDadStateDeprecated = 3 + IpDadStatePreferred = 4 +) + type SocketAddress struct { Sockaddr *syscall.RawSockaddrAny SockaddrLength int32 @@ -2144,6 +2204,132 @@ const ( IfOperStatusLowerLayerDown = 7 ) +const ( + IF_MAX_PHYS_ADDRESS_LENGTH = 32 + IF_MAX_STRING_SIZE = 256 +) + +// MIB_IF_ENTRY_LEVEL enumeration from netioapi.h or +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/nf-netioapi-getifentry2ex. +const ( + MibIfEntryNormal = 0 + MibIfEntryNormalWithoutStatistics = 2 +) + +// MIB_NOTIFICATION_TYPE enumeration from netioapi.h or +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ne-netioapi-mib_notification_type. +const ( + MibParameterNotification = 0 + MibAddInstance = 1 + MibDeleteInstance = 2 + MibInitialNotification = 3 +) + +// MibIfRow2 stores information about a particular interface. See +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_if_row2. +type MibIfRow2 struct { + InterfaceLuid uint64 + InterfaceIndex uint32 + InterfaceGuid GUID + Alias [IF_MAX_STRING_SIZE + 1]uint16 + Description [IF_MAX_STRING_SIZE + 1]uint16 + PhysicalAddressLength uint32 + PhysicalAddress [IF_MAX_PHYS_ADDRESS_LENGTH]uint8 + PermanentPhysicalAddress [IF_MAX_PHYS_ADDRESS_LENGTH]uint8 + Mtu uint32 + Type uint32 + TunnelType uint32 + MediaType uint32 + PhysicalMediumType uint32 + AccessType uint32 + DirectionType uint32 + InterfaceAndOperStatusFlags uint8 + OperStatus uint32 + AdminStatus uint32 + MediaConnectState uint32 + NetworkGuid GUID + ConnectionType uint32 + TransmitLinkSpeed uint64 + ReceiveLinkSpeed uint64 + InOctets uint64 + InUcastPkts uint64 + InNUcastPkts uint64 + InDiscards uint64 + InErrors uint64 + InUnknownProtos uint64 + InUcastOctets uint64 + InMulticastOctets uint64 + InBroadcastOctets uint64 + OutOctets uint64 + OutUcastPkts uint64 + OutNUcastPkts uint64 + OutDiscards uint64 + OutErrors uint64 + OutUcastOctets uint64 + OutMulticastOctets uint64 + OutBroadcastOctets uint64 + OutQLen uint64 +} + +// MIB_UNICASTIPADDRESS_ROW stores information about a unicast IP address. See +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_unicastipaddress_row. +type MibUnicastIpAddressRow struct { + Address RawSockaddrInet6 // SOCKADDR_INET union + InterfaceLuid uint64 + InterfaceIndex uint32 + PrefixOrigin uint32 + SuffixOrigin uint32 + ValidLifetime uint32 + PreferredLifetime uint32 + OnLinkPrefixLength uint8 + SkipAsSource uint8 + DadState uint32 + ScopeId uint32 + CreationTimeStamp Filetime +} + +const ScopeLevelCount = 16 + +// MIB_IPINTERFACE_ROW stores interface management information for a particular IP address family on a network interface. +// See https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_ipinterface_row. +type MibIpInterfaceRow struct { + Family uint16 + InterfaceLuid uint64 + InterfaceIndex uint32 + MaxReassemblySize uint32 + InterfaceIdentifier uint64 + MinRouterAdvertisementInterval uint32 + MaxRouterAdvertisementInterval uint32 + AdvertisingEnabled uint8 + ForwardingEnabled uint8 + WeakHostSend uint8 + WeakHostReceive uint8 + UseAutomaticMetric uint8 + UseNeighborUnreachabilityDetection uint8 + ManagedAddressConfigurationSupported uint8 + OtherStatefulConfigurationSupported uint8 + AdvertiseDefaultRoute uint8 + RouterDiscoveryBehavior uint32 + DadTransmits uint32 + BaseReachableTime uint32 + RetransmitTime uint32 + PathMtuDiscoveryTimeout uint32 + LinkLocalAddressBehavior uint32 + LinkLocalAddressTimeout uint32 + ZoneIndices [ScopeLevelCount]uint32 + SitePrefixLength uint32 + Metric uint32 + NlMtu uint32 + Connected uint8 + SupportsWakeUpPatterns uint8 + SupportsNeighborDiscovery uint8 + SupportsRouterDiscovery uint8 + ReachableTime uint32 + TransmitOffload uint32 + ReceiveOffload uint32 + DisableDefaultRoutes uint8 +} + // Console related constants used for the mode parameter to SetConsoleMode. See // https://docs.microsoft.com/en-us/windows/console/setconsolemode for details. @@ -3404,3 +3590,14 @@ type DCB struct { EvtChar byte wReserved1 uint16 } + +// Keyboard Layout Flags. +// See https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-loadkeyboardlayoutw +const ( + KLF_ACTIVATE = 0x00000001 + KLF_SUBSTITUTE_OK = 0x00000002 + KLF_REORDER = 0x00000008 + KLF_REPLACELANG = 0x00000010 + KLF_NOTELLSHELL = 0x00000080 + KLF_SETFORPROCESS = 0x00000100 +) diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go index 9f73df75b5..01c0716c2c 100644 --- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go +++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -91,6 +91,7 @@ var ( procEnumServicesStatusExW = modadvapi32.NewProc("EnumServicesStatusExW") procEqualSid = modadvapi32.NewProc("EqualSid") procFreeSid = modadvapi32.NewProc("FreeSid") + procGetAce = modadvapi32.NewProc("GetAce") procGetLengthSid = modadvapi32.NewProc("GetLengthSid") procGetNamedSecurityInfoW = modadvapi32.NewProc("GetNamedSecurityInfoW") procGetSecurityDescriptorControl = modadvapi32.NewProc("GetSecurityDescriptorControl") @@ -180,10 +181,15 @@ var ( procDnsRecordListFree = moddnsapi.NewProc("DnsRecordListFree") procDwmGetWindowAttribute = moddwmapi.NewProc("DwmGetWindowAttribute") procDwmSetWindowAttribute = moddwmapi.NewProc("DwmSetWindowAttribute") + procCancelMibChangeNotify2 = modiphlpapi.NewProc("CancelMibChangeNotify2") procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") procGetAdaptersInfo = modiphlpapi.NewProc("GetAdaptersInfo") procGetBestInterfaceEx = modiphlpapi.NewProc("GetBestInterfaceEx") procGetIfEntry = modiphlpapi.NewProc("GetIfEntry") + procGetIfEntry2Ex = modiphlpapi.NewProc("GetIfEntry2Ex") + procGetUnicastIpAddressEntry = modiphlpapi.NewProc("GetUnicastIpAddressEntry") + procNotifyIpInterfaceChange = modiphlpapi.NewProc("NotifyIpInterfaceChange") + procNotifyUnicastIpAddressChange = modiphlpapi.NewProc("NotifyUnicastIpAddressChange") procAddDllDirectory = modkernel32.NewProc("AddDllDirectory") procAssignProcessToJobObject = modkernel32.NewProc("AssignProcessToJobObject") procCancelIo = modkernel32.NewProc("CancelIo") @@ -246,7 +252,9 @@ var ( procGetCommandLineW = modkernel32.NewProc("GetCommandLineW") procGetComputerNameExW = modkernel32.NewProc("GetComputerNameExW") procGetComputerNameW = modkernel32.NewProc("GetComputerNameW") + procGetConsoleCP = modkernel32.NewProc("GetConsoleCP") procGetConsoleMode = modkernel32.NewProc("GetConsoleMode") + procGetConsoleOutputCP = modkernel32.NewProc("GetConsoleOutputCP") procGetConsoleScreenBufferInfo = modkernel32.NewProc("GetConsoleScreenBufferInfo") procGetCurrentDirectoryW = modkernel32.NewProc("GetCurrentDirectoryW") procGetCurrentProcessId = modkernel32.NewProc("GetCurrentProcessId") @@ -272,8 +280,10 @@ var ( procGetMaximumProcessorCount = modkernel32.NewProc("GetMaximumProcessorCount") procGetModuleFileNameW = modkernel32.NewProc("GetModuleFileNameW") procGetModuleHandleExW = modkernel32.NewProc("GetModuleHandleExW") + procGetNamedPipeClientProcessId = modkernel32.NewProc("GetNamedPipeClientProcessId") procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW") procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo") + procGetNamedPipeServerProcessId = modkernel32.NewProc("GetNamedPipeServerProcessId") procGetOverlappedResult = modkernel32.NewProc("GetOverlappedResult") procGetPriorityClass = modkernel32.NewProc("GetPriorityClass") procGetProcAddress = modkernel32.NewProc("GetProcAddress") @@ -346,8 +356,10 @@ var ( procSetCommMask = modkernel32.NewProc("SetCommMask") procSetCommState = modkernel32.NewProc("SetCommState") procSetCommTimeouts = modkernel32.NewProc("SetCommTimeouts") + procSetConsoleCP = modkernel32.NewProc("SetConsoleCP") procSetConsoleCursorPosition = modkernel32.NewProc("SetConsoleCursorPosition") procSetConsoleMode = modkernel32.NewProc("SetConsoleMode") + procSetConsoleOutputCP = modkernel32.NewProc("SetConsoleOutputCP") procSetCurrentDirectoryW = modkernel32.NewProc("SetCurrentDirectoryW") procSetDefaultDllDirectories = modkernel32.NewProc("SetDefaultDllDirectories") procSetDllDirectoryW = modkernel32.NewProc("SetDllDirectoryW") @@ -477,12 +489,16 @@ var ( procGetDesktopWindow = moduser32.NewProc("GetDesktopWindow") procGetForegroundWindow = moduser32.NewProc("GetForegroundWindow") procGetGUIThreadInfo = moduser32.NewProc("GetGUIThreadInfo") + procGetKeyboardLayout = moduser32.NewProc("GetKeyboardLayout") procGetShellWindow = moduser32.NewProc("GetShellWindow") procGetWindowThreadProcessId = moduser32.NewProc("GetWindowThreadProcessId") procIsWindow = moduser32.NewProc("IsWindow") procIsWindowUnicode = moduser32.NewProc("IsWindowUnicode") procIsWindowVisible = moduser32.NewProc("IsWindowVisible") + procLoadKeyboardLayoutW = moduser32.NewProc("LoadKeyboardLayoutW") procMessageBoxW = moduser32.NewProc("MessageBoxW") + procToUnicodeEx = moduser32.NewProc("ToUnicodeEx") + procUnloadKeyboardLayout = moduser32.NewProc("UnloadKeyboardLayout") procCreateEnvironmentBlock = moduserenv.NewProc("CreateEnvironmentBlock") procDestroyEnvironmentBlock = moduserenv.NewProc("DestroyEnvironmentBlock") procGetUserProfileDirectoryW = moduserenv.NewProc("GetUserProfileDirectoryW") @@ -788,6 +804,14 @@ func FreeSid(sid *SID) (err error) { return } +func GetAce(acl *ACL, aceIndex uint32, pAce **ACCESS_ALLOWED_ACE) (err error) { + r1, _, e1 := syscall.Syscall(procGetAce.Addr(), 3, uintptr(unsafe.Pointer(acl)), uintptr(aceIndex), uintptr(unsafe.Pointer(pAce))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func GetLengthSid(sid *SID) (len uint32) { r0, _, _ := syscall.Syscall(procGetLengthSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0) len = uint32(r0) @@ -1589,6 +1613,14 @@ func DwmSetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, si return } +func CancelMibChangeNotify2(notificationHandle Handle) (errcode error) { + r0, _, _ := syscall.Syscall(procCancelMibChangeNotify2.Addr(), 1, uintptr(notificationHandle), 0, 0) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) { r0, _, _ := syscall.Syscall6(procGetAdaptersAddresses.Addr(), 5, uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer)), 0) if r0 != 0 { @@ -1621,6 +1653,46 @@ func GetIfEntry(pIfRow *MibIfRow) (errcode error) { return } +func GetIfEntry2Ex(level uint32, row *MibIfRow2) (errcode error) { + r0, _, _ := syscall.Syscall(procGetIfEntry2Ex.Addr(), 2, uintptr(level), uintptr(unsafe.Pointer(row)), 0) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func GetUnicastIpAddressEntry(row *MibUnicastIpAddressRow) (errcode error) { + r0, _, _ := syscall.Syscall(procGetUnicastIpAddressEntry.Addr(), 1, uintptr(unsafe.Pointer(row)), 0, 0) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func NotifyIpInterfaceChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) { + var _p0 uint32 + if initialNotification { + _p0 = 1 + } + r0, _, _ := syscall.Syscall6(procNotifyIpInterfaceChange.Addr(), 5, uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle)), 0) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func NotifyUnicastIpAddressChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) { + var _p0 uint32 + if initialNotification { + _p0 = 1 + } + r0, _, _ := syscall.Syscall6(procNotifyUnicastIpAddressChange.Addr(), 5, uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle)), 0) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + func AddDllDirectory(path *uint16) (cookie uintptr, err error) { r0, _, e1 := syscall.Syscall(procAddDllDirectory.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) cookie = uintptr(r0) @@ -2149,6 +2221,15 @@ func GetComputerName(buf *uint16, n *uint32) (err error) { return } +func GetConsoleCP() (cp uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetConsoleCP.Addr(), 0, 0, 0, 0) + cp = uint32(r0) + if cp == 0 { + err = errnoErr(e1) + } + return +} + func GetConsoleMode(console Handle, mode *uint32) (err error) { r1, _, e1 := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(mode)), 0) if r1 == 0 { @@ -2157,6 +2238,15 @@ func GetConsoleMode(console Handle, mode *uint32) (err error) { return } +func GetConsoleOutputCP() (cp uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetConsoleOutputCP.Addr(), 0, 0, 0, 0) + cp = uint32(r0) + if cp == 0 { + err = errnoErr(e1) + } + return +} + func GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) { r1, _, e1 := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(info)), 0) if r1 == 0 { @@ -2358,6 +2448,14 @@ func GetModuleHandleEx(flags uint32, moduleName *uint16, module *Handle) (err er return } +func GetNamedPipeClientProcessId(pipe Handle, clientProcessID *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetNamedPipeClientProcessId.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(clientProcessID)), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func GetNamedPipeHandleState(pipe Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) { r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0) if r1 == 0 { @@ -2374,6 +2472,14 @@ func GetNamedPipeInfo(pipe Handle, flags *uint32, outSize *uint32, inSize *uint3 return } +func GetNamedPipeServerProcessId(pipe Handle, serverProcessID *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetNamedPipeServerProcessId.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(serverProcessID)), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func GetOverlappedResult(handle Handle, overlapped *Overlapped, done *uint32, wait bool) (err error) { var _p0 uint32 if wait { @@ -3025,6 +3131,14 @@ func SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) { return } +func SetConsoleCP(cp uint32) (err error) { + r1, _, e1 := syscall.Syscall(procSetConsoleCP.Addr(), 1, uintptr(cp), 0, 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func setConsoleCursorPosition(console Handle, position uint32) (err error) { r1, _, e1 := syscall.Syscall(procSetConsoleCursorPosition.Addr(), 2, uintptr(console), uintptr(position), 0) if r1 == 0 { @@ -3041,6 +3155,14 @@ func SetConsoleMode(console Handle, mode uint32) (err error) { return } +func SetConsoleOutputCP(cp uint32) (err error) { + r1, _, e1 := syscall.Syscall(procSetConsoleOutputCP.Addr(), 1, uintptr(cp), 0, 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func SetCurrentDirectory(path *uint16) (err error) { r1, _, e1 := syscall.Syscall(procSetCurrentDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) if r1 == 0 { @@ -4073,6 +4195,12 @@ func GetGUIThreadInfo(thread uint32, info *GUIThreadInfo) (err error) { return } +func GetKeyboardLayout(tid uint32) (hkl Handle) { + r0, _, _ := syscall.Syscall(procGetKeyboardLayout.Addr(), 1, uintptr(tid), 0, 0) + hkl = Handle(r0) + return +} + func GetShellWindow() (shellWindow HWND) { r0, _, _ := syscall.Syscall(procGetShellWindow.Addr(), 0, 0, 0, 0) shellWindow = HWND(r0) @@ -4106,6 +4234,15 @@ func IsWindowVisible(hwnd HWND) (isVisible bool) { return } +func LoadKeyboardLayout(name *uint16, flags uint32) (hkl Handle, err error) { + r0, _, e1 := syscall.Syscall(procLoadKeyboardLayoutW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(flags), 0) + hkl = Handle(r0) + if hkl == 0 { + err = errnoErr(e1) + } + return +} + func MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) { r0, _, e1 := syscall.Syscall6(procMessageBoxW.Addr(), 4, uintptr(hwnd), uintptr(unsafe.Pointer(text)), uintptr(unsafe.Pointer(caption)), uintptr(boxtype), 0, 0) ret = int32(r0) @@ -4115,6 +4252,20 @@ func MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret i return } +func ToUnicodeEx(vkey uint32, scancode uint32, keystate *byte, pwszBuff *uint16, cchBuff int32, flags uint32, hkl Handle) (ret int32) { + r0, _, _ := syscall.Syscall9(procToUnicodeEx.Addr(), 7, uintptr(vkey), uintptr(scancode), uintptr(unsafe.Pointer(keystate)), uintptr(unsafe.Pointer(pwszBuff)), uintptr(cchBuff), uintptr(flags), uintptr(hkl), 0, 0) + ret = int32(r0) + return +} + +func UnloadKeyboardLayout(hkl Handle) (err error) { + r1, _, e1 := syscall.Syscall(procUnloadKeyboardLayout.Addr(), 1, uintptr(hkl), 0, 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func CreateEnvironmentBlock(block **uint16, token Token, inheritExisting bool) (err error) { var _p0 uint32 if inheritExisting { diff --git a/vendor/golang.org/x/term/LICENSE b/vendor/golang.org/x/term/LICENSE index 6a66aea5ea..2a7cf70da6 100644 --- a/vendor/golang.org/x/term/LICENSE +++ b/vendor/golang.org/x/term/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. +Copyright 2009 The Go Authors. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer. copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Google Inc. nor the names of its + * Neither the name of Google LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. diff --git a/vendor/golang.org/x/term/README.md b/vendor/golang.org/x/term/README.md index d03d0aefef..05ff623f94 100644 --- a/vendor/golang.org/x/term/README.md +++ b/vendor/golang.org/x/term/README.md @@ -4,16 +4,13 @@ This repository provides Go terminal and console support packages. -## Download/Install - -The easiest way to install is to run `go get -u golang.org/x/term`. You can -also manually git clone the repository to `$GOPATH/src/golang.org/x/term`. - ## Report Issues / Send Patches This repository uses Gerrit for code changes. To learn how to submit changes to -this repository, see https://golang.org/doc/contribute.html. +this repository, see https://go.dev/doc/contribute. + +The git repository is https://go.googlesource.com/term. The main issue tracker for the term repository is located at -https://github.com/golang/go/issues. Prefix your issue with "x/term:" in the +https://go.dev/issues. Prefix your issue with "x/term:" in the subject line, so it is easy to find. diff --git a/vendor/golang.org/x/term/term_windows.go b/vendor/golang.org/x/term/term_windows.go index 465f560604..df6bf948e1 100644 --- a/vendor/golang.org/x/term/term_windows.go +++ b/vendor/golang.org/x/term/term_windows.go @@ -26,6 +26,7 @@ func makeRaw(fd int) (*State, error) { return nil, err } raw := st &^ (windows.ENABLE_ECHO_INPUT | windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_OUTPUT) + raw |= windows.ENABLE_VIRTUAL_TERMINAL_INPUT if err := windows.SetConsoleMode(windows.Handle(fd), raw); err != nil { return nil, err } diff --git a/vendor/golang.org/x/text/LICENSE b/vendor/golang.org/x/text/LICENSE index 6a66aea5ea..2a7cf70da6 100644 --- a/vendor/golang.org/x/text/LICENSE +++ b/vendor/golang.org/x/text/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. +Copyright 2009 The Go Authors. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer. copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Google Inc. nor the names of its + * Neither the name of Google LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. diff --git a/vendor/modules.txt b/vendor/modules.txt index 717a17d095..4f15786ed7 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -366,7 +366,7 @@ github.com/tidepool-org/clinic/client # github.com/tidepool-org/devices/api v0.0.0-20240806072455-2b18f22c9cf5 ## explicit; go 1.22 github.com/tidepool-org/devices/api -# github.com/tidepool-org/go-common v0.12.2-0.20240612192926-de6d5c5a742c +# github.com/tidepool-org/go-common v0.12.2-0.20250129210214-bd36b59b9733 ## explicit; go 1.22 github.com/tidepool-org/go-common/clients github.com/tidepool-org/go-common/clients/disc @@ -482,8 +482,8 @@ go.uber.org/zap/internal/exit go.uber.org/zap/internal/pool go.uber.org/zap/internal/stacktrace go.uber.org/zap/zapcore -# golang.org/x/crypto v0.24.0 -## explicit; go 1.18 +# golang.org/x/crypto v0.32.0 +## explicit; go 1.20 golang.org/x/crypto/md4 golang.org/x/crypto/ocsp golang.org/x/crypto/pbkdf2 @@ -503,7 +503,7 @@ golang.org/x/lint/golint golang.org/x/mod/internal/lazyregexp golang.org/x/mod/module golang.org/x/mod/semver -# golang.org/x/net v0.26.0 +# golang.org/x/net v0.34.0 ## explicit; go 1.18 golang.org/x/net/context golang.org/x/net/html @@ -522,20 +522,20 @@ golang.org/x/net/trace golang.org/x/oauth2 golang.org/x/oauth2/clientcredentials golang.org/x/oauth2/internal -# golang.org/x/sync v0.7.0 +# golang.org/x/sync v0.10.0 ## explicit; go 1.18 golang.org/x/sync/errgroup golang.org/x/sync/semaphore golang.org/x/sync/singleflight -# golang.org/x/sys v0.21.0 +# golang.org/x/sys v0.29.0 ## explicit; go 1.18 golang.org/x/sys/plan9 golang.org/x/sys/unix golang.org/x/sys/windows -# golang.org/x/term v0.21.0 +# golang.org/x/term v0.28.0 ## explicit; go 1.18 golang.org/x/term -# golang.org/x/text v0.16.0 +# golang.org/x/text v0.21.0 ## explicit; go 1.18 golang.org/x/text/encoding golang.org/x/text/encoding/charmap From 542c860c5ee657b975e23fa6552ea7cfd6235f7e Mon Sep 17 00:00:00 2001 From: Todd Kazakov Date: Fri, 21 Feb 2025 21:57:19 +0200 Subject: [PATCH 13/24] Prevent panics if ehr sync tasks don't have a cadence set --- ehr/sync/task.go | 8 +++++++- ehr/sync/task_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/ehr/sync/task.go b/ehr/sync/task.go index 803d4e3d43..7d32118966 100644 --- a/ehr/sync/task.go +++ b/ehr/sync/task.go @@ -57,7 +57,13 @@ func ScheduleNextExecution(tsk *task.Task) { } func GetCadence(data map[string]interface{}) *time.Duration { - cadence := data["cadence"].(string) + if data == nil { + return nil + } + cadence, ok := data["cadence"].(string) + if !ok { + return nil + } parsed, err := time.ParseDuration(cadence) if err != nil { return nil diff --git a/ehr/sync/task_test.go b/ehr/sync/task_test.go index 632748bbd4..e561aca722 100644 --- a/ehr/sync/task_test.go +++ b/ehr/sync/task_test.go @@ -1,6 +1,8 @@ package sync_test import ( + "time" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" . "github.com/onsi/gomega/gstruct" @@ -30,4 +32,27 @@ var _ = Describe("Task", func() { Expect(extracted).To(Equal(*clinic.Id)) }) }) + + Describe("GetCadence", func() { + It("returns nil if data is nil", func() { + result := sync.GetCadence(nil) + Expect(result).To(BeNil()) + }) + + It("returns nil if data doesn't have cadence", func() { + result := sync.GetCadence(map[string]interface{}{}) + Expect(result).To(BeNil()) + }) + + It("returns nil if cadence is invalid", func() { + result := sync.GetCadence(map[string]interface{}{"cadence": "invalid"}) + Expect(result).To(BeNil()) + }) + + It("returns the parses cadence correctly", func() { + period := time.Duration(14) * time.Hour * 24 + result := sync.GetCadence(map[string]interface{}{"cadence": period.String()}) + Expect(result).To(PointTo(Equal(period))) + }) + }) }) From 8d3ca978d34d85d656c11264159cb094187596db Mon Sep 17 00:00:00 2001 From: Darin Krauss Date: Wed, 5 Mar 2025 14:14:43 -0800 Subject: [PATCH 14/24] [BACK-3461] Add trend rate units to cbg data type - Add trend rate units to cbg data type - Update general blood glucose functionality - Use trend rate in Dexcom data - https://tidepool.atlassian.net/browse/BACK-3461 --- data/blood/glucose/glucose.go | 50 +- data/blood/glucose/glucose_test.go | 93 +++ data/blood/glucose/test/target.go | 20 + .../blood/glucose/continuous/continuous.go | 42 +- .../glucose/continuous/continuous_test.go | 586 ++++++++++++++---- data/types/settings/cgm/rate_alert.go | 21 +- data/types/settings/cgm/rate_alert_test.go | 18 +- data/types/settings/cgm/test/rate_alert.go | 3 +- dexcom/fetch/translate.go | 38 +- 9 files changed, 709 insertions(+), 162 deletions(-) diff --git a/data/blood/glucose/glucose.go b/data/blood/glucose/glucose.go index 32ca889dd9..f91f0d6716 100644 --- a/data/blood/glucose/glucose.go +++ b/data/blood/glucose/glucose.go @@ -10,15 +10,25 @@ const ( MmolL = "mmol/L" Mmoll = "mmol/l" + MmolLMinute = "mmol/L/minute" + MgdL = "mg/dL" Mgdl = "mg/dl" + MgdLMinute = "mg/dL/minute" + MmolLMinimum float64 = 0.0 MmolLMaximum float64 = 55.0 + MmolLMinuteMinimum float64 = -5.5 + MmolLMinuteMaximum float64 = 5.5 + MgdLMinimum float64 = 0.0 MgdLMaximum float64 = 1000.0 + MgdLMinuteMinimum float64 = -100.0 + MgdLMinuteMaximum float64 = 100.0 + // MmolLToMgdLConversionFactor is MgdL Per MmolL. // // Reminder: The molecular mass of glucose is ≈ 180 g/mol. @@ -34,6 +44,10 @@ func Units() []string { return []string{MmolL, Mmoll, MgdL, Mgdl} } +func RateUnits() []string { + return []string{MmolLMinute, MgdLMinute} +} + func ValueRangeForUnits(units *string) (float64, float64) { if units != nil { switch *units { @@ -60,7 +74,41 @@ func NormalizeValueForUnits(value *float64, units *string) *float64 { if value != nil && units != nil { switch *units { case MgdL, Mgdl: - intValue := int(*value/MmolLToMgdLConversionFactor*MmolLToMgdLPrecisionFactor + 0.5) + intValue := int(*value/MmolLToMgdLConversionFactor*MmolLToMgdLPrecisionFactor + math.Copysign(0.5, *value)) + floatValue := float64(intValue) / MmolLToMgdLPrecisionFactor + return &floatValue + } + } + return value +} + +func ValueRangeForRateUnits(rateUnits *string) (float64, float64) { + if rateUnits != nil { + switch *rateUnits { + case MmolLMinute: + return MmolLMinuteMinimum, MmolLMinuteMaximum + case MgdLMinute: + return MgdLMinuteMinimum, MgdLMinuteMaximum + } + } + return -math.MaxFloat64, math.MaxFloat64 +} + +func NormalizeRateUnits(rateUnits *string) *string { + if rateUnits != nil { + switch *rateUnits { + case MmolLMinute, MgdLMinute: + return pointer.FromString(MmolLMinute) + } + } + return rateUnits +} + +func NormalizeValueForRateUnits(value *float64, rateUnits *string) *float64 { + if value != nil && rateUnits != nil { + switch *rateUnits { + case MgdLMinute: + intValue := int(*value/MmolLToMgdLConversionFactor*MmolLToMgdLPrecisionFactor + math.Copysign(0.5, *value)) floatValue := float64(intValue) / MmolLToMgdLPrecisionFactor return &floatValue } diff --git a/data/blood/glucose/glucose_test.go b/data/blood/glucose/glucose_test.go index cf726fd967..3199407303 100644 --- a/data/blood/glucose/glucose_test.go +++ b/data/blood/glucose/glucose_test.go @@ -19,6 +19,10 @@ var _ = Describe("Glucose", func() { Expect(glucose.Mmoll).To(Equal("mmol/l")) }) + It("has MmolLMinute", func() { + Expect(glucose.MmolLMinute).To(Equal("mmol/L/minute")) + }) + It("has MgdL", func() { Expect(glucose.MgdL).To(Equal("mg/dL")) }) @@ -27,6 +31,10 @@ var _ = Describe("Glucose", func() { Expect(glucose.Mgdl).To(Equal("mg/dl")) }) + It("has MgdLMinute", func() { + Expect(glucose.MgdLMinute).To(Equal("mg/dL/minute")) + }) + It("has MmolLMinimum", func() { Expect(glucose.MmolLMinimum).To(Equal(0.0)) }) @@ -35,6 +43,14 @@ var _ = Describe("Glucose", func() { Expect(glucose.MmolLMaximum).To(Equal(55.0)) }) + It("has MmolLMinuteMinimum", func() { + Expect(glucose.MmolLMinuteMinimum).To(Equal(-5.5)) + }) + + It("has MmolLMinuteMaximum", func() { + Expect(glucose.MmolLMinuteMaximum).To(Equal(5.5)) + }) + It("has MgdLMinimum", func() { Expect(glucose.MgdLMinimum).To(Equal(0.0)) }) @@ -43,6 +59,14 @@ var _ = Describe("Glucose", func() { Expect(glucose.MgdLMaximum).To(Equal(1000.0)) }) + It("has MgdLMinuteMinimum", func() { + Expect(glucose.MgdLMinuteMinimum).To(Equal(-100.0)) + }) + + It("has MgdLMinuteMaximum", func() { + Expect(glucose.MgdLMinuteMaximum).To(Equal(100.0)) + }) + It("has MmolLToMgdLConversionFactor", func() { Expect(glucose.MmolLToMgdLConversionFactor).To(Equal(18.01559)) }) @@ -57,6 +81,12 @@ var _ = Describe("Glucose", func() { }) }) + Context("RateUnits", func() { + It("returns the expected units", func() { + Expect(glucose.RateUnits()).To(ConsistOf("mmol/L/minute", "mg/dL/minute")) + }) + }) + DescribeTable("ValueRangeForUnits", func(units *string, expectedLower float64, expectedUpper float64) { actualLower, actualUpper := glucose.ValueRangeForUnits(units) @@ -125,4 +155,67 @@ var _ = Describe("Glucose", func() { } }) }) + + DescribeTable("ValueRangeForRateUnits", + func(rateUnits *string, expectedLower float64, expectedUpper float64) { + actualLower, actualUpper := glucose.ValueRangeForRateUnits(rateUnits) + Expect(actualLower).To(Equal(expectedLower)) + Expect(actualUpper).To(Equal(expectedUpper)) + }, + Entry("returns no range for nil", nil, -math.MaxFloat64, math.MaxFloat64), + Entry("returns no range for unknown units", pointer.FromString("unknown"), -math.MaxFloat64, math.MaxFloat64), + Entry("returns expected range for mmol/L/minute units", pointer.FromString("mmol/L/minute"), -5.5, 5.5), + Entry("returns expected range for mg/dL/minute units", pointer.FromString("mg/dL/minute"), -100.0, 100.0), + ) + + DescribeTable("NormalizeRateUnits", + func(rateUnits *string, expectedRateUnits *string) { + actualRateUnits := glucose.NormalizeRateUnits(rateUnits) + if expectedRateUnits == nil { + Expect(actualRateUnits).To(BeNil()) + } else { + Expect(actualRateUnits).ToNot(BeNil()) + Expect(*actualRateUnits).To(Equal(*expectedRateUnits)) + } + }, + Entry("returns nil for nil", nil, nil), + Entry("returns unchanged units for unknown units", pointer.FromString("unknown"), pointer.FromString("unknown")), + Entry("returns mmol/L/minute for mmol/L/minute", pointer.FromString("mmol/L/minute"), pointer.FromString("mmol/L/minute")), + Entry("returns mmol/L/minute for mg/dL/minute", pointer.FromString("mg/dL/minute"), pointer.FromString("mmol/L/minute")), + ) + + Context("NormalizeValueForRateUnits", func() { + DescribeTable("given value and units", + func(value *float64, rateUnits *string, expectedValue *float64) { + actualValue := glucose.NormalizeValueForRateUnits(value, rateUnits) + if expectedValue == nil { + Expect(actualValue).To(BeNil()) + } else { + Expect(actualValue).ToNot(BeNil()) + Expect(*actualValue).To(Equal(*expectedValue)) + } + }, + Entry("returns nil for nil value", nil, pointer.FromString("mmol/L/minute"), nil), + Entry("returns unchanged value for nil units", pointer.FromFloat64(1.0), nil, pointer.FromFloat64(1.0)), + Entry("returns unchanged value for unknown units", pointer.FromFloat64(1.0), pointer.FromString("unknown"), pointer.FromFloat64(1.0)), + Entry("returns unchanged value for mmol/L/minute units", pointer.FromFloat64(1.0), pointer.FromString("mmol/L/minute"), pointer.FromFloat64(1.0)), + Entry("returns converted value for mg/dL/minute units", pointer.FromFloat64(18.0), pointer.FromString("mg/dL/minute"), pointer.FromFloat64(0.99913)), + ) + + It("properly normalizes a range of mmol/L/minute values", func() { + for value := glucose.MmolLMinuteMinimum; value <= glucose.MmolLMinuteMaximum; value += 0.1 { + normalizedValue := glucose.NormalizeValueForRateUnits(pointer.FromFloat64(float64(value)), pointer.FromString("mmol/L/minute")) + Expect(normalizedValue).ToNot(BeNil()) + Expect(*normalizedValue).To(Equal(value)) + } + }) + + It("properly normalizes a range of mg/dL/minute values", func() { + for value := int(glucose.MgdLMinuteMinimum); value <= int(glucose.MgdLMinuteMaximum); value++ { + normalizedValue := glucose.NormalizeValueForRateUnits(pointer.FromFloat64(float64(value)), pointer.FromString("mg/dL/minute")) + Expect(normalizedValue).ToNot(BeNil()) + Expect(int(*normalizedValue*18.01559 + math.Copysign(0.5, float64(value)))).To(Equal(value)) + } + }) + }) }) diff --git a/data/blood/glucose/test/target.go b/data/blood/glucose/test/target.go index 919748a125..303bc4cedc 100644 --- a/data/blood/glucose/test/target.go +++ b/data/blood/glucose/test/target.go @@ -84,6 +84,26 @@ func ExpectNormalizedValue(value *float64, expectedValue *float64, units *string } } +func ExpectNormalizedRateUnits(value *string, expectedValue *string) { + if expectedValue != nil { + gomega.Expect(value).ToNot(gomega.BeNil()) + gomega.Expect(*value).To(gomega.Equal(*dataBloodGlucose.NormalizeRateUnits(expectedValue))) + *expectedValue = *value + } else { + gomega.Expect(value).To(gomega.BeNil()) + } +} + +func ExpectNormalizedRateValue(value *float64, expectedValue *float64, units *string) { + if expectedValue != nil { + gomega.Expect(value).ToNot(gomega.BeNil()) + gomega.Expect(*value).To(gomega.Equal(*dataBloodGlucose.NormalizeValueForRateUnits(expectedValue, units))) + *expectedValue = *value + } else { + gomega.Expect(value).To(gomega.BeNil()) + } +} + func ExpectNormalizedTarget(datum *dataBloodGlucose.Target, expectedDatum *dataBloodGlucose.Target, units *string) { gomega.Expect(datum).ToNot(gomega.BeNil()) gomega.Expect(expectedDatum).ToNot(gomega.BeNil()) diff --git a/data/types/blood/glucose/continuous/continuous.go b/data/types/blood/glucose/continuous/continuous.go index a1d976f665..ff3a3ab5d0 100644 --- a/data/types/blood/glucose/continuous/continuous.go +++ b/data/types/blood/glucose/continuous/continuous.go @@ -2,7 +2,8 @@ package continuous import ( "github.com/tidepool-org/platform/data" - "github.com/tidepool-org/platform/data/types/blood/glucose" + dataBloodGlucose "github.com/tidepool-org/platform/data/blood/glucose" + dataTypesBloodGlucose "github.com/tidepool-org/platform/data/types/blood/glucose" "github.com/tidepool-org/platform/structure" ) @@ -17,27 +18,34 @@ const ( RapidFall = "rapidFall" RapidRise = "rapidRise" - TrendRateMaximum = 100 - TrendRateMinimum = -100 SampleIntervalMinimum = 0 SampleIntervalMaximum = 24 * 60 * 60 * 1000 ) func Trends() []string { - return []string{ConstantRate, SlowFall, SlowRise, ModerateFall, ModerateRise, RapidFall, RapidRise} + return []string{ + ConstantRate, + SlowFall, + SlowRise, + ModerateFall, + ModerateRise, + RapidFall, + RapidRise, + } } type Continuous struct { - glucose.Glucose `bson:",inline"` - Trend *string `json:"trend,omitempty" bson:"trend,omitempty"` - TrendRate *float64 `json:"trendRate,omitempty" bson:"trendRate,omitempty"` - SampleInterval *int `json:"sampleInterval,omitempty" bson:"sampleInterval,omitempty"` - Backfilled *bool `json:"backfilled,omitempty" bson:"backfilled,omitempty"` + dataTypesBloodGlucose.Glucose `bson:",inline"` + Trend *string `json:"trend,omitempty" bson:"trend,omitempty"` + TrendRateUnits *string `json:"trendRateUnits,omitempty" bson:"trendRateUnits,omitempty"` + TrendRate *float64 `json:"trendRate,omitempty" bson:"trendRate,omitempty"` + SampleInterval *int `json:"sampleInterval,omitempty" bson:"sampleInterval,omitempty"` + Backfilled *bool `json:"backfilled,omitempty" bson:"backfilled,omitempty"` } func New() *Continuous { return &Continuous{ - Glucose: glucose.New(Type), + Glucose: dataTypesBloodGlucose.New(Type), } } @@ -49,6 +57,7 @@ func (c *Continuous) Parse(parser structure.ObjectParser) { c.Glucose.Parse(parser) c.Trend = parser.String("trend") + c.TrendRateUnits = parser.String("trendRateUnits") c.TrendRate = parser.Float64("trendRate") c.SampleInterval = parser.Int("sampleInterval") c.Backfilled = parser.Bool("backfilled") @@ -66,7 +75,12 @@ func (c *Continuous) Validate(validator structure.Validator) { } validator.String("trend", c.Trend).OneOf(Trends()...) - validator.Float64("trendRate", c.TrendRate).InRange(TrendRateMinimum, TrendRateMaximum) + if trendRateUnitsValidator := validator.String("trendRateUnits", c.TrendRateUnits); c.TrendRate != nil { + trendRateUnitsValidator.Exists().OneOf(dataBloodGlucose.RateUnits()...) + } else { + trendRateUnitsValidator.NotExists() + } + validator.Float64("trendRate", c.TrendRate).InRange(dataBloodGlucose.ValueRangeForRateUnits(c.TrendRateUnits)) validator.Int("sampleInterval", c.SampleInterval).InRange(SampleIntervalMinimum, SampleIntervalMaximum) } @@ -76,4 +90,10 @@ func (c *Continuous) Normalize(normalizer data.Normalizer) { } c.Glucose.Normalize(normalizer) + + if normalizer.Origin() == structure.OriginExternal { + rateUnits := c.TrendRateUnits + c.TrendRateUnits = dataBloodGlucose.NormalizeRateUnits(rateUnits) + c.TrendRate = dataBloodGlucose.NormalizeValueForRateUnits(c.TrendRate, rateUnits) + } } diff --git a/data/types/blood/glucose/continuous/continuous_test.go b/data/types/blood/glucose/continuous/continuous_test.go index 6b3bea23fd..457624f42e 100644 --- a/data/types/blood/glucose/continuous/continuous_test.go +++ b/data/types/blood/glucose/continuous/continuous_test.go @@ -4,6 +4,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + dataBloodGlucose "github.com/tidepool-org/platform/data/blood/glucose" dataBloodGlucoseTest "github.com/tidepool-org/platform/data/blood/glucose/test" dataNormalizer "github.com/tidepool-org/platform/data/normalizer" "github.com/tidepool-org/platform/data/types" @@ -18,18 +19,21 @@ import ( "github.com/tidepool-org/platform/test" ) -func NewMeta() interface{} { +func NewMeta() any { return &types.Meta{ Type: "cbg", } } -func NewContinuous(units *string) *continuous.Continuous { +func RandomContinuous(units *string, rateUnits *string) *continuous.Continuous { datum := continuous.New() datum.Glucose = *dataTypesBloodGlucoseTest.NewGlucose(units) datum.Type = "cbg" datum.Trend = pointer.FromString(test.RandomStringFromArray(continuous.Trends())) - datum.TrendRate = pointer.FromFloat64(test.RandomFloat64FromRange(continuous.TrendRateMinimum, continuous.TrendRateMaximum)) + datum.TrendRateUnits = rateUnits + if datum.TrendRateUnits != nil { + datum.TrendRate = pointer.FromFloat64(test.RandomFloat64FromRange(dataBloodGlucose.ValueRangeForRateUnits(datum.TrendRateUnits))) + } datum.SampleInterval = pointer.FromInt(test.RandomIntFromRange(continuous.SampleIntervalMinimum, continuous.SampleIntervalMaximum)) datum.Backfilled = pointer.FromBool(test.RandomBool()) return datum @@ -42,6 +46,7 @@ func CloneContinuous(datum *continuous.Continuous) *continuous.Continuous { clone := continuous.New() clone.Glucose = *dataTypesBloodGlucoseTest.CloneGlucose(&datum.Glucose) clone.Trend = pointer.CloneString(datum.Trend) + clone.TrendRateUnits = pointer.CloneString(datum.TrendRateUnits) clone.TrendRate = pointer.CloneFloat64(datum.TrendRate) clone.SampleInterval = pointer.CloneInt(datum.SampleInterval) clone.Backfilled = pointer.CloneBool(datum.Backfilled) @@ -61,6 +66,7 @@ var _ = Describe("Continuous", func() { Expect(datum.Units).To(BeNil()) Expect(datum.Value).To(BeNil()) Expect(datum.Trend).To(BeNil()) + Expect(datum.TrendRateUnits).To(BeNil()) Expect(datum.TrendRate).To(BeNil()) Expect(datum.SampleInterval).To(BeNil()) Expect(datum.Backfilled).To(BeNil()) @@ -69,262 +75,525 @@ var _ = Describe("Continuous", func() { Context("Validate", func() { DescribeTable("validates the datum", - func(units *string, mutator func(datum *continuous.Continuous, units *string), expectedErrors ...error) { - datum := NewContinuous(units) - mutator(datum, units) + func(units *string, rateUnits *string, mutator func(datum *continuous.Continuous, units *string, rateUnits *string), expectedErrors ...error) { + datum := RandomContinuous(units, rateUnits) + mutator(datum, units, rateUnits) dataTypesTest.ValidateWithExpectedOrigins(datum, structure.Origins(), expectedErrors...) }, Entry("succeeds", pointer.FromString("mmol/L"), - func(datum *continuous.Continuous, units *string) {}, + pointer.FromString("mmol/L/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) {}, ), Entry("type missing", pointer.FromString("mmol/L"), - func(datum *continuous.Continuous, units *string) { datum.Type = "" }, + pointer.FromString("mmol/L/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) { datum.Type = "" }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueEmpty(), "/type", &types.Meta{}), ), Entry("type invalid", pointer.FromString("mmol/L"), - func(datum *continuous.Continuous, units *string) { datum.Type = "invalidType" }, + pointer.FromString("mmol/L/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) { datum.Type = "invalidType" }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotEqualTo("invalidType", "cbg"), "/type", &types.Meta{Type: "invalidType"}), ), Entry("type cbg", pointer.FromString("mmol/L"), - func(datum *continuous.Continuous, units *string) { datum.Type = "cbg" }, + pointer.FromString("mmol/L/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) { datum.Type = "cbg" }, ), Entry("units missing; value missing", nil, - func(datum *continuous.Continuous, units *string) { datum.Value = nil }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { datum.Value = nil }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/units", NewMeta()), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/value", NewMeta()), ), Entry("units missing; value out of range (lower)", nil, - func(datum *continuous.Continuous, units *string) { datum.Value = pointer.FromFloat64(-0.1) }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = pointer.FromFloat64(-0.1) + }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/units", NewMeta()), ), Entry("units missing; value in range (lower)", nil, - func(datum *continuous.Continuous, units *string) { datum.Value = pointer.FromFloat64(0.0) }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = pointer.FromFloat64(0.0) + }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/units", NewMeta()), ), Entry("units missing; value in range (upper)", nil, - func(datum *continuous.Continuous, units *string) { datum.Value = pointer.FromFloat64(55.0) }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = pointer.FromFloat64(55.0) + }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/units", NewMeta()), ), Entry("units missing; value out of range (upper)", nil, - func(datum *continuous.Continuous, units *string) { datum.Value = pointer.FromFloat64(1000.1) }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = pointer.FromFloat64(1000.1) + }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/units", NewMeta()), ), Entry("units invalid; value missing", pointer.FromString("invalid"), - func(datum *continuous.Continuous, units *string) { datum.Value = nil }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { datum.Value = nil }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"mmol/L", "mmol/l", "mg/dL", "mg/dl"}), "/units", NewMeta()), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/value", NewMeta()), ), Entry("units invalid; value out of range (lower)", pointer.FromString("invalid"), - func(datum *continuous.Continuous, units *string) { datum.Value = pointer.FromFloat64(-0.1) }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = pointer.FromFloat64(-0.1) + }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"mmol/L", "mmol/l", "mg/dL", "mg/dl"}), "/units", NewMeta()), ), Entry("units invalid; value in range (lower)", pointer.FromString("invalid"), - func(datum *continuous.Continuous, units *string) { datum.Value = pointer.FromFloat64(0.0) }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = pointer.FromFloat64(0.0) + }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"mmol/L", "mmol/l", "mg/dL", "mg/dl"}), "/units", NewMeta()), ), Entry("units invalid; value in range (upper)", pointer.FromString("invalid"), - func(datum *continuous.Continuous, units *string) { datum.Value = pointer.FromFloat64(55.0) }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = pointer.FromFloat64(55.0) + }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"mmol/L", "mmol/l", "mg/dL", "mg/dl"}), "/units", NewMeta()), ), Entry("units invalid; value out of range (upper)", pointer.FromString("invalid"), - func(datum *continuous.Continuous, units *string) { datum.Value = pointer.FromFloat64(1000.1) }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = pointer.FromFloat64(1000.1) + }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"mmol/L", "mmol/l", "mg/dL", "mg/dl"}), "/units", NewMeta()), ), Entry("units mmol/L; value missing", pointer.FromString("mmol/L"), - func(datum *continuous.Continuous, units *string) { datum.Value = nil }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = nil + }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/value", NewMeta()), ), Entry("units mmol/L; value out of range (lower)", pointer.FromString("mmol/L"), - func(datum *continuous.Continuous, units *string) { datum.Value = pointer.FromFloat64(-0.1) }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = pointer.FromFloat64(-0.1) + }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 55.0), "/value", NewMeta()), ), Entry("units mmol/L; value in range (lower)", pointer.FromString("mmol/L"), - func(datum *continuous.Continuous, units *string) { datum.Value = pointer.FromFloat64(0.0) }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = pointer.FromFloat64(0.0) + }, ), Entry("units mmol/L; value in range (upper)", pointer.FromString("mmol/L"), - func(datum *continuous.Continuous, units *string) { datum.Value = pointer.FromFloat64(55.0) }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = pointer.FromFloat64(55.0) + }, ), Entry("units mmol/L; value out of range (upper)", pointer.FromString("mmol/L"), - func(datum *continuous.Continuous, units *string) { datum.Value = pointer.FromFloat64(55.1) }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = pointer.FromFloat64(55.1) + }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(55.1, 0.0, 55.0), "/value", NewMeta()), ), Entry("units mmol/l; value missing", pointer.FromString("mmol/l"), - func(datum *continuous.Continuous, units *string) { datum.Value = nil }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = nil + }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/value", NewMeta()), ), Entry("units mmol/l; value out of range (lower)", pointer.FromString("mmol/l"), - func(datum *continuous.Continuous, units *string) { datum.Value = pointer.FromFloat64(-0.1) }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = pointer.FromFloat64(-0.1) + }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 55.0), "/value", NewMeta()), ), Entry("units mmol/l; value in range (lower)", pointer.FromString("mmol/l"), - func(datum *continuous.Continuous, units *string) { datum.Value = pointer.FromFloat64(0.0) }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = pointer.FromFloat64(0.0) + }, ), Entry("units mmol/l; value in range (upper)", pointer.FromString("mmol/l"), - func(datum *continuous.Continuous, units *string) { datum.Value = pointer.FromFloat64(55.0) }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = pointer.FromFloat64(55.0) + }, ), Entry("units mmol/l; value out of range (upper)", pointer.FromString("mmol/l"), - func(datum *continuous.Continuous, units *string) { datum.Value = pointer.FromFloat64(55.1) }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = pointer.FromFloat64(55.1) + }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(55.1, 0.0, 55.0), "/value", NewMeta()), ), Entry("units mg/dL; value missing", pointer.FromString("mg/dL"), - func(datum *continuous.Continuous, units *string) { datum.Value = nil }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = nil + }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/value", NewMeta()), ), Entry("units mg/dL; value out of range (lower)", pointer.FromString("mg/dL"), - func(datum *continuous.Continuous, units *string) { datum.Value = pointer.FromFloat64(-0.1) }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = pointer.FromFloat64(-0.1) + }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 1000.0), "/value", NewMeta()), ), Entry("units mg/dL; value in range (lower)", pointer.FromString("mg/dL"), - func(datum *continuous.Continuous, units *string) { datum.Value = pointer.FromFloat64(0.0) }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = pointer.FromFloat64(0.0) + }, ), Entry("units mg/dL; value in range (upper)", pointer.FromString("mg/dL"), - func(datum *continuous.Continuous, units *string) { datum.Value = pointer.FromFloat64(1000.0) }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = pointer.FromFloat64(1000.0) + }, ), Entry("units mg/dL; value out of range (upper)", pointer.FromString("mg/dL"), - func(datum *continuous.Continuous, units *string) { datum.Value = pointer.FromFloat64(1000.1) }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = pointer.FromFloat64(1000.1) + }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(1000.1, 0.0, 1000.0), "/value", NewMeta()), ), Entry("units mg/dl; value missing", pointer.FromString("mg/dl"), - func(datum *continuous.Continuous, units *string) { datum.Value = nil }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = nil + }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/value", NewMeta()), ), Entry("units mg/dl; value out of range (lower)", pointer.FromString("mg/dl"), - func(datum *continuous.Continuous, units *string) { datum.Value = pointer.FromFloat64(-0.1) }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = pointer.FromFloat64(-0.1) + }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-0.1, 0.0, 1000.0), "/value", NewMeta()), ), Entry("units mg/dl; value in range (lower)", pointer.FromString("mg/dl"), - func(datum *continuous.Continuous, units *string) { datum.Value = pointer.FromFloat64(0.0) }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = pointer.FromFloat64(0.0) + }, ), Entry("units mg/dl; value in range (upper)", pointer.FromString("mg/dl"), - func(datum *continuous.Continuous, units *string) { datum.Value = pointer.FromFloat64(1000.0) }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = pointer.FromFloat64(1000.0) + }, ), Entry("units mg/dl; value out of range (upper)", pointer.FromString("mg/dl"), - func(datum *continuous.Continuous, units *string) { datum.Value = pointer.FromFloat64(1000.1) }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = pointer.FromFloat64(1000.1) + }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(1000.1, 0.0, 1000.0), "/value", NewMeta()), ), Entry("trend missing", pointer.FromString("mg/dl"), - func(datum *continuous.Continuous, units *string) { datum.Trend = nil }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { datum.Trend = nil }, ), Entry("trend empty", pointer.FromString("mg/dl"), - func(datum *continuous.Continuous, units *string) { datum.Trend = pointer.FromString("") }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Trend = pointer.FromString("") + }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueStringNotOneOf("", continuous.Trends()), "/trend", NewMeta()), ), Entry("trend invalid", pointer.FromString("mg/dl"), - func(datum *continuous.Continuous, units *string) { datum.Trend = pointer.FromString("invalid") }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Trend = pointer.FromString("invalid") + }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueStringNotOneOf("invalid", continuous.Trends()), "/trend", NewMeta()), ), Entry("trend constant", pointer.FromString("mg/dl"), - func(datum *continuous.Continuous, units *string) { datum.Trend = pointer.FromString("constant") }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Trend = pointer.FromString("constant") + }, ), Entry("trend slowFall", pointer.FromString("mg/dl"), - func(datum *continuous.Continuous, units *string) { datum.Trend = pointer.FromString("slowFall") }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Trend = pointer.FromString("slowFall") + }, ), Entry("trend slowRise", pointer.FromString("mg/dl"), - func(datum *continuous.Continuous, units *string) { datum.Trend = pointer.FromString("slowRise") }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Trend = pointer.FromString("slowRise") + }, ), Entry("trend moderateFall", pointer.FromString("mg/dl"), - func(datum *continuous.Continuous, units *string) { datum.Trend = pointer.FromString("moderateFall") }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Trend = pointer.FromString("moderateFall") + }, ), Entry("trend moderateRise", pointer.FromString("mg/dl"), - func(datum *continuous.Continuous, units *string) { datum.Trend = pointer.FromString("moderateRise") }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Trend = pointer.FromString("moderateRise") + }, ), Entry("trend rapidFall", pointer.FromString("mg/dl"), - func(datum *continuous.Continuous, units *string) { datum.Trend = pointer.FromString("rapidFall") }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Trend = pointer.FromString("rapidFall") + }, ), Entry("trend rapidRise", pointer.FromString("mg/dl"), - func(datum *continuous.Continuous, units *string) { datum.Trend = pointer.FromString("rapidRise") }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Trend = pointer.FromString("rapidRise") + }, ), - Entry("trend rate missing", - pointer.FromString("mg/dl"), - func(datum *continuous.Continuous, units *string) { datum.TrendRate = nil }, + Entry("trend rate units missing; trend rate missing", + pointer.FromString("mmol/L"), + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { datum.TrendRate = nil }, ), - Entry("trend rate out of range (lower)", - pointer.FromString("mg/dl"), - func(datum *continuous.Continuous, units *string) { datum.TrendRate = pointer.FromFloat64(-100.1) }, + Entry("trend rate units missing; trend rate out of range (lower)", + pointer.FromString("mmol/L"), + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.TrendRate = pointer.FromFloat64(-5.51) + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/trendRateUnits", NewMeta()), + ), + Entry("trend rate units missing; trend rate in range (lower)", + pointer.FromString("mmol/L"), + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.TrendRate = pointer.FromFloat64(-5.5) + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/trendRateUnits", NewMeta()), + ), + Entry("trend rate units missing; trend rate in range (upper)", + pointer.FromString("mmol/L"), + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.TrendRate = pointer.FromFloat64(5.5) + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/trendRateUnits", NewMeta()), + ), + Entry("trend rate units missing; trend rate out of range (upper)", + pointer.FromString("mmol/L"), + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.TrendRate = pointer.FromFloat64(5.51) + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/trendRateUnits", NewMeta()), + ), + Entry("trend rate units invalid; trend rate missing", + pointer.FromString("mmol/L"), + pointer.FromString("invalid"), + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.TrendRate = nil + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueExists(), "/trendRateUnits", NewMeta()), + ), + Entry("trend rate units invalid; trend rate out of range (lower)", + pointer.FromString("mmol/L"), + pointer.FromString("invalid"), + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.TrendRate = pointer.FromFloat64(-5.51) + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"mmol/L/minute", "mg/dL/minute"}), "/trendRateUnits", NewMeta()), + ), + Entry("trend rate units invalid; trend rate in range (lower)", + pointer.FromString("mmol/L"), + pointer.FromString("invalid"), + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.TrendRate = pointer.FromFloat64(-5.5) + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"mmol/L/minute", "mg/dL/minute"}), "/trendRateUnits", NewMeta()), + ), + Entry("trend rate units invalid; trend rate in range (upper)", + pointer.FromString("mmol/L"), + pointer.FromString("invalid"), + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.TrendRate = pointer.FromFloat64(5.5) + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"mmol/L/minute", "mg/dL/minute"}), "/trendRateUnits", NewMeta()), + ), + Entry("trend rate units invalid; trend rate out of range (upper)", + pointer.FromString("mmol/L"), + pointer.FromString("invalid"), + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.TrendRate = pointer.FromFloat64(5.51) + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"mmol/L/minute", "mg/dL/minute"}), "/trendRateUnits", NewMeta()), + ), + Entry("trend rate units mmol/L/minute; trend rate missing", + pointer.FromString("mmol/L"), + pointer.FromString("mmol/L/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.TrendRate = nil + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueExists(), "/trendRateUnits", NewMeta()), + ), + Entry("trend rate units mmol/L/minute; trend rate out of range (lower)", + pointer.FromString("mmol/L"), + pointer.FromString("mmol/L/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.TrendRate = pointer.FromFloat64(-5.51) + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-5.51, -5.5, 5.5), "/trendRate", NewMeta()), + ), + Entry("trend rate units mmol/L/minute; trend rate in range (lower)", + pointer.FromString("mmol/L"), + pointer.FromString("mmol/L/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.TrendRate = pointer.FromFloat64(-5.5) + }, + ), + Entry("trend rate units mmol/L/minute; trend rate in range (upper)", + pointer.FromString("mmol/L"), + pointer.FromString("mmol/L/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.TrendRate = pointer.FromFloat64(5.5) + }, + ), + Entry("trend rate units mmol/L/minute; trend rate out of range (upper)", + pointer.FromString("mmol/L"), + pointer.FromString("mmol/L/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.TrendRate = pointer.FromFloat64(5.51) + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(5.51, -5.5, 5.5), "/trendRate", NewMeta()), + ), + Entry("trend rate units mg/dL/minute; trend rate missing", + pointer.FromString("mg/dL"), + pointer.FromString("mg/dL/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.TrendRate = nil + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueExists(), "/trendRateUnits", NewMeta()), + ), + Entry("trend rate units mg/dL/minute; trend rate out of range (lower)", + pointer.FromString("mg/dL"), + pointer.FromString("mg/dL/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.TrendRate = pointer.FromFloat64(-100.1) + }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-100.1, -100.0, 100.0), "/trendRate", NewMeta()), ), - Entry("trend rate in range (lower)", - pointer.FromString("mg/dl"), - func(datum *continuous.Continuous, units *string) { datum.TrendRate = pointer.FromFloat64(-100.0) }, + Entry("trend rate units mg/dL/minute; trend rate in range (lower)", + pointer.FromString("mg/dL"), + pointer.FromString("mg/dL/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.TrendRate = pointer.FromFloat64(-100.0) + }, ), - Entry("trend rate in range (upper)", - pointer.FromString("mg/dl"), - func(datum *continuous.Continuous, units *string) { datum.TrendRate = pointer.FromFloat64(100.0) }, + Entry("trend rate units mg/dL/minute; trend rate in range (upper)", + pointer.FromString("mg/dL"), + pointer.FromString("mg/dL/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.TrendRate = pointer.FromFloat64(100.0) + }, ), - Entry("trend rate out of range (upper)", - pointer.FromString("mg/dl"), - func(datum *continuous.Continuous, units *string) { datum.TrendRate = pointer.FromFloat64(100.1) }, + Entry("trend rate units mg/dL/minute; trend rate out of range (upper)", + pointer.FromString("mg/dL"), + pointer.FromString("mg/dL/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.TrendRate = pointer.FromFloat64(100.1) + }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(100.1, -100.0, 100.0), "/trendRate", NewMeta()), ), Entry("sample interval missing", pointer.FromString("mg/dl"), - func(datum *continuous.Continuous, units *string) { datum.SampleInterval = nil }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { datum.SampleInterval = nil }, ), Entry("sample interval out of range (lower)", pointer.FromString("mg/dl"), - func(datum *continuous.Continuous, units *string) { datum.SampleInterval = pointer.FromInt(-1) }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.SampleInterval = pointer.FromInt(-1) + }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 86400000), "/sampleInterval", NewMeta()), ), Entry("sample interval in range (lower)", pointer.FromString("mg/dl"), - func(datum *continuous.Continuous, units *string) { datum.SampleInterval = pointer.FromInt(0) }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.SampleInterval = pointer.FromInt(0) + }, ), Entry("sample interval in range (upper)", pointer.FromString("mg/dl"), - func(datum *continuous.Continuous, units *string) { datum.SampleInterval = pointer.FromInt(86400000) }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.SampleInterval = pointer.FromInt(86400000) + }, ), Entry("sample interval out of range (upper)", pointer.FromString("mg/dl"), - func(datum *continuous.Continuous, units *string) { datum.SampleInterval = pointer.FromInt(86400001) }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.SampleInterval = pointer.FromInt(86400001) + }, errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(86400001, 0, 86400000), "/sampleInterval", NewMeta()), ), Entry("multiple errors", nil, - func(datum *continuous.Continuous, units *string) { + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { datum.Type = "" datum.Value = nil datum.Trend = nil @@ -334,7 +603,7 @@ var _ = Describe("Continuous", func() { errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueEmpty(), "/type", &types.Meta{}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/units", &types.Meta{}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/value", &types.Meta{}), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-100.1, -100.0, 100.0), "/trendRate", &types.Meta{}), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/trendRateUnits", &types.Meta{}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 86400000), "/sampleInterval", &types.Meta{}), ), ) @@ -342,10 +611,10 @@ var _ = Describe("Continuous", func() { Context("Normalize", func() { DescribeTable("normalizes the datum", - func(units *string, mutator func(datum *continuous.Continuous, units *string), expectator func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string)) { + func(units *string, rateUnits *string, mutator func(datum *continuous.Continuous, units *string, rateUnits *string), expectator func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string, rateUnits *string)) { for _, origin := range structure.Origins() { - datum := NewContinuous(units) - mutator(datum, units) + datum := RandomContinuous(units, rateUnits) + mutator(datum, units, rateUnits) expectedDatum := CloneContinuous(datum) normalizer := dataNormalizer.New(logTest.NewLogger()) Expect(normalizer).ToNot(BeNil()) @@ -353,47 +622,70 @@ var _ = Describe("Continuous", func() { Expect(normalizer.Error()).To(BeNil()) Expect(normalizer.Data()).To(BeEmpty()) if expectator != nil { - expectator(datum, expectedDatum, units) + expectator(datum, expectedDatum, units, rateUnits) } Expect(datum).To(Equal(expectedDatum)) } }, Entry("does not modify the datum; units missing", nil, - func(datum *continuous.Continuous, units *string) {}, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) {}, nil, ), Entry("does not modify the datum; units missing; value missing", nil, - func(datum *continuous.Continuous, units *string) { datum.Value = nil }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { datum.Value = nil }, nil, ), Entry("does not modify the datum; units invalid", pointer.FromString("invalid"), - func(datum *continuous.Continuous, units *string) {}, + pointer.FromString("invalid"), + func(datum *continuous.Continuous, units *string, rateUnits *string) {}, nil, ), Entry("does not modify the datum; units invalid; value missing", pointer.FromString("invalid"), - func(datum *continuous.Continuous, units *string) { datum.Value = nil }, + pointer.FromString("invalid"), + func(datum *continuous.Continuous, units *string, rateUnits *string) { datum.Value = nil }, nil, ), Entry("does not modify the datum; trend missing", nil, - func(datum *continuous.Continuous, units *string) { datum.Trend = nil }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { datum.Trend = nil }, + nil, + ), + Entry("does not modify the datum; trend rate units invalid", + nil, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.TrendRateUnits = pointer.FromString("invalid") + }, + nil, + ), + Entry("does not modify the datum; trend rate units invalid; trend rate missing", + nil, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.TrendRateUnits = pointer.FromString("invalid") + datum.TrendRate = nil + }, nil, ), Entry("does not modify the datum; trend rate missing", nil, - func(datum *continuous.Continuous, units *string) { datum.TrendRate = nil }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { datum.TrendRate = nil }, nil, ), ) DescribeTable("normalizes the datum with origin external", - func(units *string, mutator func(datum *continuous.Continuous, units *string), expectator func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string)) { - datum := NewContinuous(units) - mutator(datum, units) + func(units *string, rateUnits *string, mutator func(datum *continuous.Continuous, units *string, rateUnits *string), expectator func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string, rateUnits *string)) { + datum := RandomContinuous(units, rateUnits) + mutator(datum, units, rateUnits) expectedDatum := CloneContinuous(datum) normalizer := dataNormalizer.New(logTest.NewLogger()) Expect(normalizer).ToNot(BeNil()) @@ -401,76 +693,106 @@ var _ = Describe("Continuous", func() { Expect(normalizer.Error()).To(BeNil()) Expect(normalizer.Data()).To(BeEmpty()) if expectator != nil { - expectator(datum, expectedDatum, units) + expectator(datum, expectedDatum, units, rateUnits) } Expect(datum).To(Equal(expectedDatum)) }, Entry("does not modify the datum; units invalid; value missing", pointer.FromString("invalid"), - func(datum *continuous.Continuous, units *string) { datum.Value = nil }, + pointer.FromString("invalid"), + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = nil + datum.TrendRate = nil + }, nil, ), Entry("does not modify the datum; units mmol/L", pointer.FromString("mmol/L"), - func(datum *continuous.Continuous, units *string) {}, + pointer.FromString("mmol/L/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) {}, nil, ), Entry("does not modify the datum; units mmol/L; value missing", pointer.FromString("mmol/L"), - func(datum *continuous.Continuous, units *string) { datum.Value = nil }, + pointer.FromString("mmol/L/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = nil + datum.TrendRate = nil + }, nil, ), Entry("modifies the datum; units mmol/l", pointer.FromString("mmol/l"), - func(datum *continuous.Continuous, units *string) {}, - func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string) { + pointer.FromString("mmol/L/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) {}, + func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string, rateUnits *string) { dataBloodGlucoseTest.ExpectNormalizedUnits(datum.Units, expectedDatum.Units) }, ), Entry("modifies the datum; units mmol/l; value missing", pointer.FromString("mmol/l"), - func(datum *continuous.Continuous, units *string) { datum.Value = nil }, - func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string) { + pointer.FromString("mmol/L/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = nil + datum.TrendRate = nil + }, + func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string, rateUnits *string) { dataBloodGlucoseTest.ExpectNormalizedUnits(datum.Units, expectedDatum.Units) }, ), Entry("modifies the datum; units mg/dL", pointer.FromString("mg/dL"), - func(datum *continuous.Continuous, units *string) {}, - func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string) { + pointer.FromString("mg/dL/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) {}, + func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string, rateUnits *string) { dataBloodGlucoseTest.ExpectNormalizedUnits(datum.Units, expectedDatum.Units) dataBloodGlucoseTest.ExpectNormalizedValue(datum.Value, expectedDatum.Value, units) + dataBloodGlucoseTest.ExpectNormalizedRateUnits(datum.TrendRateUnits, expectedDatum.TrendRateUnits) + dataBloodGlucoseTest.ExpectNormalizedRateValue(datum.TrendRate, expectedDatum.TrendRate, rateUnits) }, ), Entry("modifies the datum; units mg/dL; value missing", pointer.FromString("mg/dL"), - func(datum *continuous.Continuous, units *string) { datum.Value = nil }, - func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string) { + pointer.FromString("mg/dL/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = nil + datum.TrendRate = nil + }, + func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string, rateUnits *string) { dataBloodGlucoseTest.ExpectNormalizedUnits(datum.Units, expectedDatum.Units) + dataBloodGlucoseTest.ExpectNormalizedRateUnits(datum.TrendRateUnits, expectedDatum.TrendRateUnits) }, ), Entry("modifies the datum; units mg/dl", pointer.FromString("mg/dl"), - func(datum *continuous.Continuous, units *string) {}, - func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string) { + pointer.FromString("mg/dL/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) {}, + func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string, rateUnits *string) { dataBloodGlucoseTest.ExpectNormalizedUnits(datum.Units, expectedDatum.Units) dataBloodGlucoseTest.ExpectNormalizedValue(datum.Value, expectedDatum.Value, units) + dataBloodGlucoseTest.ExpectNormalizedRateUnits(datum.TrendRateUnits, expectedDatum.TrendRateUnits) + dataBloodGlucoseTest.ExpectNormalizedRateValue(datum.TrendRate, expectedDatum.TrendRate, rateUnits) }, ), Entry("modifies the datum; units mg/dl; value missing", pointer.FromString("mg/dl"), - func(datum *continuous.Continuous, units *string) { datum.Value = nil }, - func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string) { + pointer.FromString("mg/dL/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = nil + datum.TrendRate = nil + }, + func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string, rateUnits *string) { dataBloodGlucoseTest.ExpectNormalizedUnits(datum.Units, expectedDatum.Units) + dataBloodGlucoseTest.ExpectNormalizedRateUnits(datum.TrendRateUnits, expectedDatum.TrendRateUnits) }, ), ) DescribeTable("normalizes the datum with origin internal/store", - func(units *string, mutator func(datum *continuous.Continuous, units *string), expectator func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string)) { + func(units *string, rateUnits *string, mutator func(datum *continuous.Continuous, units *string, rateUnits *string), expectator func(datum *continuous.Continuous, expectedDatum *continuous.Continuous, units *string, rateUnits *string)) { for _, origin := range []structure.Origin{structure.OriginInternal, structure.OriginStore} { - datum := NewContinuous(units) - mutator(datum, units) + datum := RandomContinuous(units, rateUnits) + mutator(datum, units, rateUnits) expectedDatum := CloneContinuous(datum) normalizer := dataNormalizer.New(logTest.NewLogger()) Expect(normalizer).ToNot(BeNil()) @@ -478,69 +800,99 @@ var _ = Describe("Continuous", func() { Expect(normalizer.Error()).To(BeNil()) Expect(normalizer.Data()).To(BeEmpty()) if expectator != nil { - expectator(datum, expectedDatum, units) + expectator(datum, expectedDatum, units, rateUnits) } Expect(datum).To(Equal(expectedDatum)) } }, Entry("does not modify the datum; units missing", nil, - func(datum *continuous.Continuous, units *string) {}, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) {}, nil, ), Entry("does not modify the datum; units missing; value missing", nil, - func(datum *continuous.Continuous, units *string) { datum.Value = nil }, + nil, + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = nil + datum.TrendRate = nil + }, nil, ), Entry("does not modify the datum; units invalid", pointer.FromString("invalid"), - func(datum *continuous.Continuous, units *string) {}, + pointer.FromString("invalid"), + func(datum *continuous.Continuous, units *string, rateUnits *string) {}, nil, ), Entry("does not modify the datum; units invalid; value missing", pointer.FromString("invalid"), - func(datum *continuous.Continuous, units *string) { datum.Value = nil }, + pointer.FromString("invalid"), + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = nil + datum.TrendRate = nil + }, nil, ), Entry("does not modify the datum; units mmol/L", pointer.FromString("mmol/L"), - func(datum *continuous.Continuous, units *string) {}, + pointer.FromString("mmol/L/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) {}, nil, ), Entry("does not modify the datum; units mmol/L; value missing", pointer.FromString("mmol/L"), - func(datum *continuous.Continuous, units *string) { datum.Value = nil }, + pointer.FromString("mmol/L/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = nil + datum.TrendRate = nil + }, nil, ), Entry("does not modify the datum; units mmol/l", pointer.FromString("mmol/l"), - func(datum *continuous.Continuous, units *string) {}, + pointer.FromString("mmol/L/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) {}, nil, ), Entry("does not modify the datum; units mmol/l; value missing", pointer.FromString("mmol/l"), - func(datum *continuous.Continuous, units *string) { datum.Value = nil }, + pointer.FromString("mmol/L/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = nil + datum.TrendRate = nil + }, nil, ), Entry("does not modify the datum; units mg/dL", pointer.FromString("mg/dL"), - func(datum *continuous.Continuous, units *string) {}, + pointer.FromString("mg/dL/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) {}, nil, ), Entry("does not modify the datum; units mg/dL; value missing", pointer.FromString("mg/dL"), - func(datum *continuous.Continuous, units *string) { datum.Value = nil }, + pointer.FromString("mg/dL/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = nil + datum.TrendRate = nil + }, nil, ), Entry("does not modify the datum; units mg/dl", pointer.FromString("mg/dl"), - func(datum *continuous.Continuous, units *string) {}, + pointer.FromString("mg/dL/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) {}, nil, ), Entry("does not modify the datum; units mg/dl; value missing", pointer.FromString("mg/dl"), - func(datum *continuous.Continuous, units *string) { datum.Value = nil }, + pointer.FromString("mg/dL/minute"), + func(datum *continuous.Continuous, units *string, rateUnits *string) { + datum.Value = nil + datum.TrendRate = nil + }, nil, ), ) diff --git a/data/types/settings/cgm/rate_alert.go b/data/types/settings/cgm/rate_alert.go index 6f255b1918..5c8f3b36fe 100644 --- a/data/types/settings/cgm/rate_alert.go +++ b/data/types/settings/cgm/rate_alert.go @@ -3,13 +3,11 @@ package cgm import ( "math" + dataBloodGlucose "github.com/tidepool-org/platform/data/blood/glucose" "github.com/tidepool-org/platform/structure" ) const ( - RateAlertUnitsMgdLMinute = "mg/dL/minute" - RateAlertUnitsMmolLMinute = "mmol/L/minute" - FallAlertRateMgdLMinuteMaximum = 10.0 FallAlertRateMgdLMinuteMinimum = 0.0 FallAlertRateMmolLMinuteMaximum = 0.55507 @@ -20,13 +18,6 @@ const ( RiseAlertRateMmolLMinuteMinimum = 0.05551 ) -func RateAlertUnits() []string { - return []string{ - RateAlertUnitsMgdLMinute, - RateAlertUnitsMmolLMinute, - } -} - type RateAlert struct { Alert `bson:",inline"` Rate *float64 `json:"rate,omitempty" bson:"rate,omitempty"` @@ -42,7 +33,7 @@ func (r *RateAlert) Parse(parser structure.ObjectParser) { func (r *RateAlert) Validate(validator structure.Validator) { r.Alert.Validate(validator) if unitsValidator := validator.String("units", r.Units); r.Rate != nil { - unitsValidator.Exists().OneOf(RateAlertUnits()...) + unitsValidator.Exists().OneOf(dataBloodGlucose.RateUnits()...) } else { unitsValidator.NotExists() } @@ -73,9 +64,9 @@ func (f *FallAlert) Validate(validator structure.Validator) { func FallAlertRateRangeForUnits(units *string) (float64, float64) { if units != nil { switch *units { - case RateAlertUnitsMgdLMinute: + case dataBloodGlucose.MgdLMinute: return FallAlertRateMgdLMinuteMinimum, FallAlertRateMgdLMinuteMaximum - case RateAlertUnitsMmolLMinute: + case dataBloodGlucose.MmolLMinute: return FallAlertRateMmolLMinuteMinimum, FallAlertRateMmolLMinuteMaximum } } @@ -107,9 +98,9 @@ func (r *RiseAlert) Validate(validator structure.Validator) { func RiseAlertRateRangeForUnits(units *string) (float64, float64) { if units != nil { switch *units { - case RateAlertUnitsMgdLMinute: + case dataBloodGlucose.MgdLMinute: return RiseAlertRateMgdLMinuteMinimum, RiseAlertRateMgdLMinuteMaximum - case RateAlertUnitsMmolLMinute: + case dataBloodGlucose.MmolLMinute: return RiseAlertRateMmolLMinuteMinimum, RiseAlertRateMmolLMinuteMaximum } } diff --git a/data/types/settings/cgm/rate_alert_test.go b/data/types/settings/cgm/rate_alert_test.go index 668a1a9a69..439c666cb9 100644 --- a/data/types/settings/cgm/rate_alert_test.go +++ b/data/types/settings/cgm/rate_alert_test.go @@ -16,14 +16,6 @@ import ( ) var _ = Describe("RateAlert", func() { - It("RateAlertUnitsMgdLMinute is expected", func() { - Expect(dataTypesSettingsCgm.RateAlertUnitsMgdLMinute).To(Equal("mg/dL/minute")) - }) - - It("RateAlertUnitsMmolLMinute is expected", func() { - Expect(dataTypesSettingsCgm.RateAlertUnitsMmolLMinute).To(Equal("mmol/L/minute")) - }) - It("FallAlertRateMgdLMinuteMaximum is expected", func() { Expect(dataTypesSettingsCgm.FallAlertRateMgdLMinuteMaximum).To(Equal(10.0)) }) @@ -56,10 +48,6 @@ var _ = Describe("RateAlert", func() { Expect(dataTypesSettingsCgm.RiseAlertRateMmolLMinuteMinimum).To(Equal(0.05551)) }) - It("RateAlertUnits returns expected", func() { - Expect(dataTypesSettingsCgm.RateAlertUnits()).To(Equal([]string{"mg/dL/minute", "mmol/L/minute"})) - }) - Context("RateAlert", func() { DescribeTable("serializes the datum as expected", func(mutator func(datum *dataTypesSettingsCgm.RateAlert)) { @@ -135,7 +123,7 @@ var _ = Describe("RateAlert", func() { datum.Units = pointer.FromString("invalid") datum.Rate = pointer.FromFloat64(test.RandomFloat64()) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"mg/dL/minute", "mmol/L/minute"}), "/units"), + errorsTest.WithPointerSource(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"mmol/L/minute", "mg/dL/minute"}), "/units"), ), Entry("units mg/dL/minute; rate missing", func(datum *dataTypesSettingsCgm.RateAlert) { @@ -268,7 +256,7 @@ var _ = Describe("RateAlert", func() { datum.Units = pointer.FromString("invalid") datum.Rate = pointer.FromFloat64(test.RandomFloat64()) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"mg/dL/minute", "mmol/L/minute"}), "/units"), + errorsTest.WithPointerSource(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"mmol/L/minute", "mg/dL/minute"}), "/units"), ), Entry("units mg/dL/minute; rate missing", func(datum *dataTypesSettingsCgm.FallAlert) { @@ -467,7 +455,7 @@ var _ = Describe("RateAlert", func() { datum.Units = pointer.FromString("invalid") datum.Rate = pointer.FromFloat64(test.RandomFloat64()) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"mg/dL/minute", "mmol/L/minute"}), "/units"), + errorsTest.WithPointerSource(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"mmol/L/minute", "mg/dL/minute"}), "/units"), ), Entry("units mg/dL/minute; rate missing", func(datum *dataTypesSettingsCgm.RiseAlert) { diff --git a/data/types/settings/cgm/test/rate_alert.go b/data/types/settings/cgm/test/rate_alert.go index cfa977ae0d..9d08b2a75c 100644 --- a/data/types/settings/cgm/test/rate_alert.go +++ b/data/types/settings/cgm/test/rate_alert.go @@ -1,6 +1,7 @@ package test import ( + dataBloodGlucose "github.com/tidepool-org/platform/data/blood/glucose" dataTypesSettingsCgm "github.com/tidepool-org/platform/data/types/settings/cgm" "github.com/tidepool-org/platform/pointer" "github.com/tidepool-org/platform/test" @@ -10,7 +11,7 @@ func RandomRateAlert() *dataTypesSettingsCgm.RateAlert { datum := &dataTypesSettingsCgm.RateAlert{} datum.Alert = *RandomAlert() datum.Rate = pointer.FromFloat64(test.RandomFloat64()) - datum.Units = pointer.FromString(test.RandomStringFromArray(dataTypesSettingsCgm.RateAlertUnits())) + datum.Units = pointer.FromString(test.RandomStringFromArray(dataBloodGlucose.RateUnits())) return datum } diff --git a/dexcom/fetch/translate.go b/dexcom/fetch/translate.go index d6361a2c83..daede9e471 100644 --- a/dexcom/fetch/translate.go +++ b/dexcom/fetch/translate.go @@ -141,7 +141,7 @@ func translateDeviceToDatum(_ context.Context, device *dexcom.Device) data.Datum datum.DeviceID = TranslateDeviceIDFromTransmitter(device.TransmitterGeneration, device.TransmitterID) datum.Manufacturers = pointer.FromStringArray([]string{"Dexcom"}) datum.TransmitterID = pointer.CloneString(device.TransmitterID) - //TODO: potenially not true in the future. Currently the v3 API returns only MgdL but it does also have MmolL as valid units although it doesn't return them + //TODO: potentially not true in the future. Currently the v3 API returns only MgdL but it does also have MmolL as valid units although it doesn't return them datum.Units = pointer.FromString(dataBloodGlucose.MgdL) defaultAlertSchedule := device.AlertSchedules.Default() @@ -345,7 +345,7 @@ func translateAlertSettingUnitToRateAlertUnits(unit *string) *string { if unit != nil { switch *unit { case dexcom.AlertSettingUnitMgdLMinute: - return pointer.FromString(dataTypesSettingsCgm.RateAlertUnitsMgdLMinute) + return pointer.FromString(dataBloodGlucose.MgdLMinute) } } return nil @@ -390,6 +390,40 @@ func translateEGVToDatum(ctx context.Context, egv *dexcom.EGV) data.Datum { datum.Units = pointer.CloneString(egv.Unit) datum.Payload = metadata.NewMetadata() + if egv.RateUnit != nil && egv.TrendRate != nil { + switch *egv.RateUnit { + case dexcom.EGVRateUnitMmolLMinute: + datum.TrendRateUnits = pointer.FromString(dataBloodGlucose.MmolLMinute) + datum.TrendRate = egv.TrendRate + case dexcom.EGVRateUnitMgdLMinute: + datum.TrendRateUnits = pointer.FromString(dataBloodGlucose.MgdLMinute) + datum.TrendRate = egv.TrendRate + case dexcom.EGVRateUnitUnknown: + // NOP + } + } + + if egv.Trend != nil { + switch *egv.Trend { + case dexcom.EGVTrendDoubleUp: + datum.Trend = pointer.FromString(dataTypesBloodGlucoseContinuous.RapidRise) + case dexcom.EGVTrendSingleUp: + datum.Trend = pointer.FromString(dataTypesBloodGlucoseContinuous.ModerateRise) + case dexcom.EGVTrendFortyFiveUp: + datum.Trend = pointer.FromString(dataTypesBloodGlucoseContinuous.SlowRise) + case dexcom.EGVTrendFlat: + datum.Trend = pointer.FromString(dataTypesBloodGlucoseContinuous.ConstantRate) + case dexcom.EGVTrendFortyFiveDown: + datum.Trend = pointer.FromString(dataTypesBloodGlucoseContinuous.SlowFall) + case dexcom.EGVTrendSingleDown: + datum.Trend = pointer.FromString(dataTypesBloodGlucoseContinuous.ModerateFall) + case dexcom.EGVTrendDoubleDown: + datum.Trend = pointer.FromString(dataTypesBloodGlucoseContinuous.RapidFall) + case dexcom.EGVTrendUnknown, dexcom.EGVTrendNone, dexcom.EGVTrendNotComputable, dexcom.EGVTrendRateOutOfRange: + // NOP + } + } + if egv.Status != nil { (*datum.Payload)["status"] = *egv.Status } From 9f860586a08218f6bd2825fe4f4868fb914ce32a Mon Sep 17 00:00:00 2001 From: Darin Krauss Date: Fri, 7 Feb 2025 14:14:55 -0800 Subject: [PATCH 15/24] [BACK-3392] Add OpenID sector for Abbott OAuth --- data/service/api/v1/partners.go | 46 +++++++++++++++++++++++++++++++++ data/service/api/v1/v1.go | 2 ++ 2 files changed, 48 insertions(+) create mode 100644 data/service/api/v1/partners.go diff --git a/data/service/api/v1/partners.go b/data/service/api/v1/partners.go new file mode 100644 index 0000000000..61a89751ab --- /dev/null +++ b/data/service/api/v1/partners.go @@ -0,0 +1,46 @@ +package v1 + +import ( + "net/http" + "os" + + dataService "github.com/tidepool-org/platform/data/service" + "github.com/tidepool-org/platform/request" +) + +// TODO: https://tidepool.atlassian.net/browse/BACK-3394 - This implementation is a +// temporary placeholder to allow bootstrapping of the Abbott OAuth client workflow. +// Will need to migrate this to environment variables and add minimal authorization. +// For now, though, this is acceptable since it isn't revealing anything that is not +// already available in other locations (i.e. other public repos). + +func PartnersSector(dataServiceContext dataService.Context) { + res := dataServiceContext.Response() + req := dataServiceContext.Request() + responder := request.MustNewResponder(res, req) + + if partnerSectorIdentifers, ok := namespacePartnerSectorIdentifers[os.Getenv("POD_NAMESPACE")]; ok { + if sectorIdentifier, ok := partnerSectorIdentifers[req.PathParam("partner")]; ok { + responder.Data(http.StatusOK, sectorIdentifier) + return + } + } + + responder.Data(http.StatusOK, []string{}) +} + +var namespacePartnerSectorIdentifers = map[string]map[string][]string{ + "external": { + "abbott": { + "https://external.integration.tidepool.org/v1/oauth/abbott/redirect", + "https://external.integration.tidepool.org/v1/oauth/abbott-private-1/redirect", + "https://external.integration.tidepool.org/v1/oauth/abbott-private-2/redirect", + "https://qa1.development.tidepool.org/v1/oauth/abbott/redirect", + "https://qa2.development.tidepool.org/v1/oauth/abbott/redirect", + "https://qa3.development.tidepool.org/v1/oauth/abbott/redirect", + "https://qa4.development.tidepool.org/v1/oauth/abbott/redirect", + "https://qa5.development.tidepool.org/v1/oauth/abbott/redirect", + "https://dev1.dev.tidepool.org/v1/oauth/abbott/redirect", + }, + }, +} diff --git a/data/service/api/v1/v1.go b/data/service/api/v1/v1.go index 9cf17c9517..8dc3cca58f 100644 --- a/data/service/api/v1/v1.go +++ b/data/service/api/v1/v1.go @@ -20,6 +20,8 @@ func Routes() []service.Route { service.Put("/v1/data_sets/:dataSetId", DataSetsUpdate, api.RequireAuth), service.Get("/v1/time", TimeGet), service.Post("/v1/users/:userId/data_sets", UsersDataSetsCreate, api.RequireAuth), + + service.Get("/v1/partners/:partner/sector", PartnersSector), } routes = append(routes, DataSetsRoutes()...) From 34522a048ae1eba0de95b6da2fc3c03e810eaec9 Mon Sep 17 00:00:00 2001 From: Todd Kazakov Date: Wed, 12 Mar 2025 17:51:55 +0200 Subject: [PATCH 16/24] Make trend rate units optional --- .../blood/glucose/continuous/continuous.go | 2 +- .../glucose/continuous/continuous_test.go | 33 ------------------- 2 files changed, 1 insertion(+), 34 deletions(-) diff --git a/data/types/blood/glucose/continuous/continuous.go b/data/types/blood/glucose/continuous/continuous.go index ff3a3ab5d0..e378e3a448 100644 --- a/data/types/blood/glucose/continuous/continuous.go +++ b/data/types/blood/glucose/continuous/continuous.go @@ -76,7 +76,7 @@ func (c *Continuous) Validate(validator structure.Validator) { validator.String("trend", c.Trend).OneOf(Trends()...) if trendRateUnitsValidator := validator.String("trendRateUnits", c.TrendRateUnits); c.TrendRate != nil { - trendRateUnitsValidator.Exists().OneOf(dataBloodGlucose.RateUnits()...) + trendRateUnitsValidator.OneOf(dataBloodGlucose.RateUnits()...) } else { trendRateUnitsValidator.NotExists() } diff --git a/data/types/blood/glucose/continuous/continuous_test.go b/data/types/blood/glucose/continuous/continuous_test.go index 457624f42e..59cc1732db 100644 --- a/data/types/blood/glucose/continuous/continuous_test.go +++ b/data/types/blood/glucose/continuous/continuous_test.go @@ -407,38 +407,6 @@ var _ = Describe("Continuous", func() { nil, func(datum *continuous.Continuous, units *string, rateUnits *string) { datum.TrendRate = nil }, ), - Entry("trend rate units missing; trend rate out of range (lower)", - pointer.FromString("mmol/L"), - nil, - func(datum *continuous.Continuous, units *string, rateUnits *string) { - datum.TrendRate = pointer.FromFloat64(-5.51) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/trendRateUnits", NewMeta()), - ), - Entry("trend rate units missing; trend rate in range (lower)", - pointer.FromString("mmol/L"), - nil, - func(datum *continuous.Continuous, units *string, rateUnits *string) { - datum.TrendRate = pointer.FromFloat64(-5.5) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/trendRateUnits", NewMeta()), - ), - Entry("trend rate units missing; trend rate in range (upper)", - pointer.FromString("mmol/L"), - nil, - func(datum *continuous.Continuous, units *string, rateUnits *string) { - datum.TrendRate = pointer.FromFloat64(5.5) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/trendRateUnits", NewMeta()), - ), - Entry("trend rate units missing; trend rate out of range (upper)", - pointer.FromString("mmol/L"), - nil, - func(datum *continuous.Continuous, units *string, rateUnits *string) { - datum.TrendRate = pointer.FromFloat64(5.51) - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/trendRateUnits", NewMeta()), - ), Entry("trend rate units invalid; trend rate missing", pointer.FromString("mmol/L"), pointer.FromString("invalid"), @@ -603,7 +571,6 @@ var _ = Describe("Continuous", func() { errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueEmpty(), "/type", &types.Meta{}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/units", &types.Meta{}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/value", &types.Meta{}), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/trendRateUnits", &types.Meta{}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 86400000), "/sampleInterval", &types.Meta{}), ), ) From b6cdf7e8b3f279b608009098b3ff1fcd14a14037 Mon Sep 17 00:00:00 2001 From: Darin Krauss Date: Tue, 18 Mar 2025 11:20:39 -0700 Subject: [PATCH 17/24] [BACK-2773/3474/3475] Updates to data model for twiist integration - Use milliseconds for duration in pumpSettingsOverride - Use milliseconds for duration in pumpSettings.overridePresets - Add deliveryContext property to all bolus types - Remove pumpSettingsOverride validation of required properties - https://tidepool.atlassian.net/browse/BACK-2773 - https://tidepool.atlassian.net/browse/BACK-3474 - https://tidepool.atlassian.net/browse/BACK-3475 --- data/types/bolus/bolus.go | 21 +++ data/types/bolus/bolus_test.go | 121 ++++++++++++++---- .../device/override/settings/pump/pump.go | 6 +- .../override/settings/pump/pump_test.go | 49 +++---- data/types/settings/pump/override_preset.go | 2 +- .../settings/pump/override_preset_test.go | 12 +- 6 files changed, 146 insertions(+), 65 deletions(-) diff --git a/data/types/bolus/bolus.go b/data/types/bolus/bolus.go index fe969bb338..f442ceb080 100644 --- a/data/types/bolus/bolus.go +++ b/data/types/bolus/bolus.go @@ -10,13 +10,32 @@ import ( const ( Type = "bolus" + + DeliveryContextAlgorithm = "algorithm" + DeliveryContextDevice = "device" + DeliveryContextOneButton = "oneButton" + DeliveryContextRemote = "remote" + DeliveryContextUndetermined = "undetermined" + DeliveryContextWatch = "watch" ) +func DeliveryContexts() []string { + return []string{ + DeliveryContextAlgorithm, + DeliveryContextDevice, + DeliveryContextOneButton, + DeliveryContextRemote, + DeliveryContextUndetermined, + DeliveryContextWatch, + } +} + type Bolus struct { types.Base `bson:",inline"` SubType string `json:"subType,omitempty" bson:"subType,omitempty"` + DeliveryContext *string `json:"deliveryContext,omitempty" bson:"deliveryContext,omitempty"` InsulinFormulation *insulin.Formulation `json:"insulinFormulation,omitempty" bson:"insulinFormulation,omitempty"` } @@ -42,6 +61,7 @@ func (b *Bolus) Meta() interface{} { func (b *Bolus) Parse(parser structure.ObjectParser) { b.Base.Parse(parser) + b.DeliveryContext = parser.String("deliveryContext") b.InsulinFormulation = insulin.ParseFormulation(parser.WithReferenceObjectParser("insulinFormulation")) } @@ -54,6 +74,7 @@ func (b *Bolus) Validate(validator structure.Validator) { validator.String("subType", &b.SubType).Exists().NotEmpty() + validator.String("deliveryContext", b.DeliveryContext).OneOf(DeliveryContexts()...) if b.InsulinFormulation != nil { b.InsulinFormulation.Validate(validator.WithReference("insulinFormulation")) } diff --git a/data/types/bolus/bolus_test.go b/data/types/bolus/bolus_test.go index ceddc61feb..0004e3cff8 100644 --- a/data/types/bolus/bolus_test.go +++ b/data/types/bolus/bolus_test.go @@ -8,7 +8,7 @@ import ( "github.com/tidepool-org/platform/data" dataNormalizer "github.com/tidepool-org/platform/data/normalizer" - "github.com/tidepool-org/platform/data/types/bolus" + dataTypesBolus "github.com/tidepool-org/platform/data/types/bolus" dataTypesBolusTest "github.com/tidepool-org/platform/data/types/bolus/test" dataTypesInsulinTest "github.com/tidepool-org/platform/data/types/insulin/test" dataTypesTest "github.com/tidepool-org/platform/data/types/test" @@ -23,31 +23,67 @@ const ExpectedTimeFormat = time.RFC3339Nano var _ = Describe("Bolus", func() { It("Type is expected", func() { - Expect(bolus.Type).To(Equal("bolus")) + Expect(dataTypesBolus.Type).To(Equal("bolus")) + }) + + It("DeliveryContextAlgorithm is expected", func() { + Expect(dataTypesBolus.DeliveryContextAlgorithm).To(Equal("algorithm")) + }) + + It("DeliveryContextDevice is expected", func() { + Expect(dataTypesBolus.DeliveryContextDevice).To(Equal("device")) + }) + + It("DeliveryContextOneButton is expected", func() { + Expect(dataTypesBolus.DeliveryContextOneButton).To(Equal("oneButton")) + }) + + It("DeliveryContextRemote is expected", func() { + Expect(dataTypesBolus.DeliveryContextRemote).To(Equal("remote")) + }) + + It("DeliveryContextUndetermined is expected", func() { + Expect(dataTypesBolus.DeliveryContextUndetermined).To(Equal("undetermined")) + }) + + It("DeliveryContextWatch is expected", func() { + Expect(dataTypesBolus.DeliveryContextWatch).To(Equal("watch")) + }) + + It("DeliveryContexts returns expected", func() { + Expect(dataTypesBolus.DeliveryContexts()).To(ConsistOf([]string{ + dataTypesBolus.DeliveryContextAlgorithm, + dataTypesBolus.DeliveryContextDevice, + dataTypesBolus.DeliveryContextOneButton, + dataTypesBolus.DeliveryContextRemote, + dataTypesBolus.DeliveryContextUndetermined, + dataTypesBolus.DeliveryContextWatch, + })) }) Context("New", func() { It("creates a new datum with all values initialized", func() { subType := dataTypesTest.NewType() - datum := bolus.New(subType) + datum := dataTypesBolus.New(subType) Expect(datum.Type).To(Equal("bolus")) Expect(datum.SubType).To(Equal(subType)) + Expect(datum.DeliveryContext).To(BeNil()) Expect(datum.InsulinFormulation).To(BeNil()) }) }) Context("with new datum", func() { var subType string - var datum bolus.Bolus + var datum dataTypesBolus.Bolus BeforeEach(func() { subType = dataTypesTest.NewType() - datum = bolus.New(subType) + datum = dataTypesBolus.New(subType) }) Context("Meta", func() { It("returns the meta with delivery type", func() { - Expect(datum.Meta()).To(Equal(&bolus.Meta{Type: "bolus", SubType: subType})) + Expect(datum.Meta()).To(Equal(&dataTypesBolus.Meta{Type: "bolus", SubType: subType})) }) }) }) @@ -59,37 +95,74 @@ var _ = Describe("Bolus", func() { Context("Validate", func() { DescribeTable("validates the datum", - func(mutator func(datum *bolus.Bolus), expectedErrors ...error) { + func(mutator func(datum *dataTypesBolus.Bolus), expectedErrors ...error) { datum := dataTypesBolusTest.RandomBolus() mutator(datum) dataTypesTest.ValidateWithExpectedOrigins(datum, structure.Origins(), expectedErrors...) }, Entry("succeeds", - func(datum *bolus.Bolus) {}, + func(datum *dataTypesBolus.Bolus) {}, ), Entry("type missing", - func(datum *bolus.Bolus) { datum.Type = "" }, + func(datum *dataTypesBolus.Bolus) { datum.Type = "" }, errorsTest.WithPointerSource(structureValidator.ErrorValueEmpty(), "/type"), ), Entry("type invalid", - func(datum *bolus.Bolus) { datum.Type = "invalid" }, + func(datum *dataTypesBolus.Bolus) { datum.Type = "invalid" }, errorsTest.WithPointerSource(structureValidator.ErrorValueNotEqualTo("invalid", "bolus"), "/type"), ), Entry("type bolus", - func(datum *bolus.Bolus) { datum.Type = "bolus" }, + func(datum *dataTypesBolus.Bolus) { datum.Type = "bolus" }, ), Entry("sub type missing", - func(datum *bolus.Bolus) { datum.SubType = "" }, + func(datum *dataTypesBolus.Bolus) { datum.SubType = "" }, errorsTest.WithPointerSource(structureValidator.ErrorValueEmpty(), "/subType"), ), Entry("sub type valid", - func(datum *bolus.Bolus) { datum.SubType = dataTypesTest.NewType() }, + func(datum *dataTypesBolus.Bolus) { datum.SubType = dataTypesTest.NewType() }, + ), + Entry("delivery context missing", + func(datum *dataTypesBolus.Bolus) { datum.DeliveryContext = nil }, + ), + Entry("delivery context invalid", + func(datum *dataTypesBolus.Bolus) { datum.DeliveryContext = pointer.FromString("invalid") }, + errorsTest.WithPointerSource(structureValidator.ErrorValueStringNotOneOf("invalid", dataTypesBolus.DeliveryContexts()), "/deliveryContext"), + ), + Entry("delivery context algorithm", + func(datum *dataTypesBolus.Bolus) { + datum.DeliveryContext = pointer.FromString(dataTypesBolus.DeliveryContextAlgorithm) + }, + ), + Entry("delivery context device", + func(datum *dataTypesBolus.Bolus) { + datum.DeliveryContext = pointer.FromString(dataTypesBolus.DeliveryContextDevice) + }, + ), + Entry("delivery context one button", + func(datum *dataTypesBolus.Bolus) { + datum.DeliveryContext = pointer.FromString(dataTypesBolus.DeliveryContextOneButton) + }, + ), + Entry("delivery context remote", + func(datum *dataTypesBolus.Bolus) { + datum.DeliveryContext = pointer.FromString(dataTypesBolus.DeliveryContextRemote) + }, + ), + Entry("delivery context undetermined", + func(datum *dataTypesBolus.Bolus) { + datum.DeliveryContext = pointer.FromString(dataTypesBolus.DeliveryContextUndetermined) + }, + ), + Entry("delivery context watch", + func(datum *dataTypesBolus.Bolus) { + datum.DeliveryContext = pointer.FromString(dataTypesBolus.DeliveryContextWatch) + }, ), Entry("insulin formulation missing", - func(datum *bolus.Bolus) { datum.InsulinFormulation = nil }, + func(datum *dataTypesBolus.Bolus) { datum.InsulinFormulation = nil }, ), Entry("insulin formulation invalid", - func(datum *bolus.Bolus) { + func(datum *dataTypesBolus.Bolus) { datum.InsulinFormulation.Compounds = nil datum.InsulinFormulation.Name = nil datum.InsulinFormulation.Simple = nil @@ -97,10 +170,12 @@ var _ = Describe("Bolus", func() { errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/insulinFormulation/simple"), ), Entry("insulin formulation valid", - func(datum *bolus.Bolus) { datum.InsulinFormulation = dataTypesInsulinTest.RandomFormulation(3) }, + func(datum *dataTypesBolus.Bolus) { + datum.InsulinFormulation = dataTypesInsulinTest.RandomFormulation(3) + }, ), Entry("multiple errors", - func(datum *bolus.Bolus) { + func(datum *dataTypesBolus.Bolus) { datum.Type = "invalid" datum.SubType = "" datum.InsulinFormulation.Compounds = nil @@ -116,7 +191,7 @@ var _ = Describe("Bolus", func() { Context("Normalize", func() { DescribeTable("normalizes the datum", - func(mutator func(datum *bolus.Bolus)) { + func(mutator func(datum *dataTypesBolus.Bolus)) { for _, origin := range structure.Origins() { datum := dataTypesBolusTest.RandomBolus() mutator(datum) @@ -130,22 +205,22 @@ var _ = Describe("Bolus", func() { } }, Entry("does not modify the datum", - func(datum *bolus.Bolus) {}, + func(datum *dataTypesBolus.Bolus) {}, ), Entry("does not modify the datum; type missing", - func(datum *bolus.Bolus) { datum.Type = "" }, + func(datum *dataTypesBolus.Bolus) { datum.Type = "" }, ), Entry("does not modify the datum; sub type missing", - func(datum *bolus.Bolus) { datum.SubType = "" }, + func(datum *dataTypesBolus.Bolus) { datum.SubType = "" }, ), Entry("does not modify the datum; insulin formulation missing", - func(datum *bolus.Bolus) { datum.InsulinFormulation = nil }, + func(datum *dataTypesBolus.Bolus) { datum.InsulinFormulation = nil }, ), ) }) Context("IdentityFields", func() { - var datumBolus *bolus.Bolus + var datumBolus *dataTypesBolus.Bolus var datum data.Datum BeforeEach(func() { diff --git a/data/types/device/override/settings/pump/pump.go b/data/types/device/override/settings/pump/pump.go index 735cde3059..11c3949045 100644 --- a/data/types/device/override/settings/pump/pump.go +++ b/data/types/device/override/settings/pump/pump.go @@ -15,7 +15,7 @@ const ( BasalRateScaleFactorMinimum = 0.1 CarbohydrateRatioScaleFactorMaximum = 10.0 CarbohydrateRatioScaleFactorMinimum = 0.1 - DurationMaximum = 604800 // 7 days in seconds + DurationMaximum = 604800000 // 7 days in milliseconds DurationMinimum = 0 InsulinSensitivityScaleFactorMaximum = 10.0 InsulinSensitivityScaleFactorMinimum = 0.1 @@ -131,10 +131,6 @@ func (p *Pump) Validate(validator structure.Validator) { } else if p.BloodGlucoseTarget != nil { unitsValidator.ReportError(structureValidator.ErrorValueNotExists()) } - - if p.BloodGlucoseTarget == nil && p.BasalRateScaleFactor == nil && p.CarbohydrateRatioScaleFactor == nil && p.InsulinSensitivityScaleFactor == nil { - validator.ReportError(structureValidator.ErrorValuesNotExistForAny("bgTarget", "basalRateScaleFactor", "carbRatioScaleFactor", "insulinSensitivityScaleFactor")) - } } func (p *Pump) Normalize(normalizer data.Normalizer) { diff --git a/data/types/device/override/settings/pump/pump_test.go b/data/types/device/override/settings/pump/pump_test.go index c374cda083..cf4f485eba 100644 --- a/data/types/device/override/settings/pump/pump_test.go +++ b/data/types/device/override/settings/pump/pump_test.go @@ -49,7 +49,7 @@ var _ = Describe("Pump", func() { }) It("DurationMaximum is expected", func() { - Expect(dataTypesDeviceOverrideSettingsPump.DurationMaximum).To(Equal(604800)) + Expect(dataTypesDeviceOverrideSettingsPump.DurationMaximum).To(Equal(604800000)) }) It("DurationMinimum is expected", func() { @@ -370,7 +370,7 @@ var _ = Describe("Pump", func() { datum.Duration = pointer.FromInt(-1) datum.DurationExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800000), "/duration", NewMeta()), ), Entry("duration; in range (lower)", pointer.FromString("mmol/L"), @@ -382,22 +382,22 @@ var _ = Describe("Pump", func() { Entry("duration; in range (upper)", pointer.FromString("mmol/L"), func(datum *dataTypesDeviceOverrideSettingsPump.Pump, unitsBloodGlucose *string) { - datum.Duration = pointer.FromInt(604800) + datum.Duration = pointer.FromInt(604800000) datum.DurationExpected = nil }, ), Entry("duration; out of range (upper)", pointer.FromString("mmol/L"), func(datum *dataTypesDeviceOverrideSettingsPump.Pump, unitsBloodGlucose *string) { - datum.Duration = pointer.FromInt(604801) + datum.Duration = pointer.FromInt(604800001) datum.DurationExpected = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(604801, 0, 604800), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(604800001, 0, 604800000), "/duration", NewMeta()), ), Entry("duration expected missing", pointer.FromString("mmol/L"), func(datum *dataTypesDeviceOverrideSettingsPump.Pump, unitsBloodGlucose *string) { - datum.Duration = pointer.FromInt(test.RandomIntFromRange(0, 604800)) + datum.Duration = pointer.FromInt(test.RandomIntFromRange(0, 604800000)) datum.DurationExpected = nil }, ), @@ -407,7 +407,7 @@ var _ = Describe("Pump", func() { datum.Duration = nil datum.DurationExpected = pointer.FromInt(-1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800000), "/expectedDuration", NewMeta()), ), Entry("duration expected; duration missing; in range (lower)", pointer.FromString("mmol/L"), @@ -420,16 +420,16 @@ var _ = Describe("Pump", func() { pointer.FromString("mmol/L"), func(datum *dataTypesDeviceOverrideSettingsPump.Pump, unitsBloodGlucose *string) { datum.Duration = nil - datum.DurationExpected = pointer.FromInt(604800) + datum.DurationExpected = pointer.FromInt(604800000) }, ), Entry("duration expected; duration missing; out of range (upper)", pointer.FromString("mmol/L"), func(datum *dataTypesDeviceOverrideSettingsPump.Pump, unitsBloodGlucose *string) { datum.Duration = nil - datum.DurationExpected = pointer.FromInt(604801) + datum.DurationExpected = pointer.FromInt(604800001) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(604801, 0, 604800), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(604800001, 0, 604800000), "/expectedDuration", NewMeta()), ), Entry("duration expected; duration out of range; out of range (lower)", pointer.FromString("mmol/L"), @@ -437,8 +437,8 @@ var _ = Describe("Pump", func() { datum.Duration = pointer.FromInt(-1) datum.DurationExpected = pointer.FromInt(-1) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800), "/duration", NewMeta()), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800000), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800000), "/expectedDuration", NewMeta()), ), Entry("duration expected; duration out of range; in range (lower)", pointer.FromString("mmol/L"), @@ -446,7 +446,7 @@ var _ = Describe("Pump", func() { datum.Duration = pointer.FromInt(-1) datum.DurationExpected = pointer.FromInt(0) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800), "/duration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800000), "/duration", NewMeta()), ), Entry("duration expected; out of range (lower)", pointer.FromString("mmol/L"), @@ -454,7 +454,7 @@ var _ = Describe("Pump", func() { datum.Duration = pointer.FromInt(3600) datum.DurationExpected = pointer.FromInt(3599) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(3599, 3600, 604800), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(3599, 3600, 604800000), "/expectedDuration", NewMeta()), ), Entry("duration expected; in range (lower)", pointer.FromString("mmol/L"), @@ -467,16 +467,16 @@ var _ = Describe("Pump", func() { pointer.FromString("mmol/L"), func(datum *dataTypesDeviceOverrideSettingsPump.Pump, unitsBloodGlucose *string) { datum.Duration = pointer.FromInt(3600) - datum.DurationExpected = pointer.FromInt(604800) + datum.DurationExpected = pointer.FromInt(604800000) }, ), Entry("duration expected; out of range (upper)", pointer.FromString("mmol/L"), func(datum *dataTypesDeviceOverrideSettingsPump.Pump, unitsBloodGlucose *string) { datum.Duration = pointer.FromInt(3600) - datum.DurationExpected = pointer.FromInt(604801) + datum.DurationExpected = pointer.FromInt(604800001) }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(604801, 3600, 604800), "/expectedDuration", NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(604800001, 3600, 604800000), "/expectedDuration", NewMeta()), ), Entry("units mmol/L; blood glucose target missing", pointer.FromString("mmol/L"), @@ -679,17 +679,6 @@ var _ = Describe("Pump", func() { datum.BloodGlucoseTarget = dataBloodGlucoseTest.RandomTarget(unitsBloodGlucose) }, ), - Entry("one of required missing", - pointer.FromString("mmol/L"), - func(datum *dataTypesDeviceOverrideSettingsPump.Pump, unitsBloodGlucose *string) { - datum.BloodGlucoseTarget = nil - datum.BasalRateScaleFactor = nil - datum.CarbohydrateRatioScaleFactor = nil - datum.InsulinSensitivityScaleFactor = nil - datum.Units = nil - }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValuesNotExistForAny("bgTarget", "basalRateScaleFactor", "carbRatioScaleFactor", "insulinSensitivityScaleFactor"), "", NewMeta()), - ), Entry("multiple errors", pointer.FromString("mmol/L"), func(datum *dataTypesDeviceOverrideSettingsPump.Pump, unitsBloodGlucose *string) { @@ -708,8 +697,8 @@ var _ = Describe("Pump", func() { errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/overrideType", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueExists(), "/overridePreset", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueStringNotOneOf("invalid", []string{"automatic", "manual"}), "/method", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800), "/duration", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800), "/expectedDuration", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800000), "/duration", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(-1, 0, 604800000), "/expectedDuration", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(0.09, 0.1, 10.0), "/basalRateScaleFactor", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(0.09, 0.1, 10.0), "/carbRatioScaleFactor", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotInRange(0.09, 0.1, 10.0), "/insulinSensitivityScaleFactor", &dataTypesDevice.Meta{Type: "deviceEvent", SubType: "invalidSubType"}), diff --git a/data/types/settings/pump/override_preset.go b/data/types/settings/pump/override_preset.go index 8e8148fc8b..df14a81552 100644 --- a/data/types/settings/pump/override_preset.go +++ b/data/types/settings/pump/override_preset.go @@ -15,7 +15,7 @@ const ( BasalRateScaleFactorMinimum = 0.1 CarbohydrateRatioScaleFactorMaximum = 10.0 CarbohydrateRatioScaleFactorMinimum = 0.1 - DurationMaximum = 604800 // 7 days in seconds + DurationMaximum = 604800000 // 7 days in milliseconds DurationMinimum = 0 InsulinSensitivityScaleFactorMaximum = 10.0 InsulinSensitivityScaleFactorMinimum = 0.1 diff --git a/data/types/settings/pump/override_preset_test.go b/data/types/settings/pump/override_preset_test.go index d328fbc502..afc61c85ba 100644 --- a/data/types/settings/pump/override_preset_test.go +++ b/data/types/settings/pump/override_preset_test.go @@ -41,7 +41,7 @@ var _ = Describe("OverridePreset", func() { }) It("DurationMaximum is expected", func() { - Expect(dataTypesSettingsPump.DurationMaximum).To(Equal(604800)) + Expect(dataTypesSettingsPump.DurationMaximum).To(Equal(604800000)) }) It("DurationMinimum is expected", func() { @@ -193,7 +193,7 @@ var _ = Describe("OverridePreset", func() { func(datum *dataTypesSettingsPump.OverridePreset, unitsBloodGlucose *string) { datum.Duration = pointer.FromInt(-1) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-1, 0, 604800), "/duration"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-1, 0, 604800000), "/duration"), ), Entry("duration; in range (lower)", pointer.FromString("mmol/L"), @@ -204,15 +204,15 @@ var _ = Describe("OverridePreset", func() { Entry("duration; in range (upper)", pointer.FromString("mmol/L"), func(datum *dataTypesSettingsPump.OverridePreset, unitsBloodGlucose *string) { - datum.Duration = pointer.FromInt(604800) + datum.Duration = pointer.FromInt(604800000) }, ), Entry("duration; out of range (upper)", pointer.FromString("mmol/L"), func(datum *dataTypesSettingsPump.OverridePreset, unitsBloodGlucose *string) { - datum.Duration = pointer.FromInt(604801) + datum.Duration = pointer.FromInt(604800001) }, - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(604801, 0, 604800), "/duration"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(604800001, 0, 604800000), "/duration"), ), Entry("units mmol/L; blood glucose target missing", pointer.FromString("mmol/L"), @@ -389,7 +389,7 @@ var _ = Describe("OverridePreset", func() { datum.InsulinSensitivityScaleFactor = pointer.FromFloat64(0.09) }, errorsTest.WithPointerSource(structureValidator.ErrorValueEmpty(), "/abbreviation"), - errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-1, 0, 604800), "/duration"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(-1, 0, 604800000), "/duration"), errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(0.09, 0.1, 10.0), "/basalRateScaleFactor"), errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(0.09, 0.1, 10.0), "/carbRatioScaleFactor"), errorsTest.WithPointerSource(structureValidator.ErrorValueNotInRange(0.09, 0.1, 10.0), "/insulinSensitivityScaleFactor"), From c2a3788cabbf6a236efb3649d1e6702e21058a28 Mon Sep 17 00:00:00 2001 From: Darin Krauss Date: Wed, 2 Apr 2025 02:39:42 -0700 Subject: [PATCH 18/24] [BACK-3514] Handle out-of-order food and bolus data for twiist - Handle out-of-order food and bolus data for twiist - Add new deduplicator - https://tidepool.atlassian.net/browse/BACK-3514 --- data/data.go | 57 +- data/datum.go | 10 + .../deduplicator/data_set_delete_origin.go | 118 +--- .../data_set_delete_origin_base.go | 121 ++++ .../data_set_delete_origin_older.go | 83 +++ .../data_set_delete_origin_older_test.go | 609 ++++++++++++++++++ .../data_set_delete_origin_test.go | 2 +- data/service/service/standard.go | 8 + data/store/mongo/mongo_datum.go | 52 ++ data/store/store.go | 1 + data/store/test/data_repository.go | 26 + 11 files changed, 989 insertions(+), 98 deletions(-) create mode 100644 data/deduplicator/deduplicator/data_set_delete_origin_base.go create mode 100644 data/deduplicator/deduplicator/data_set_delete_origin_older.go create mode 100644 data/deduplicator/deduplicator/data_set_delete_origin_older_test.go diff --git a/data/data.go b/data/data.go index 476a3cf276..b39c5ac8dc 100644 --- a/data/data.go +++ b/data/data.go @@ -16,7 +16,8 @@ const ( ) type SelectorOrigin struct { - ID *string `json:"id,omitempty"` + ID *string `json:"id,omitempty" bson:"id,omitempty"` + Time *string `json:"time,omitempty" bson:"time,omitempty"` // Inclusive, currently NOT used in database query } func ParseSelectorOrigin(parser structure.ObjectParser) *SelectorOrigin { @@ -34,15 +35,38 @@ func NewSelectorOrigin() *SelectorOrigin { func (s *SelectorOrigin) Parse(parser structure.ObjectParser) { s.ID = parser.String("id") + s.Time = parser.String("time") } func (s *SelectorOrigin) Validate(validator structure.Validator) { validator.String("id", s.ID).Exists().NotEmpty().LengthLessThanOrEqualTo(SelectorOriginIDLengthMaximum) + validator.String("time", s.Time).AsTime(time.RFC3339Nano).NotZero() +} + +func (s *SelectorOrigin) Includes(other *SelectorOrigin) bool { + if s == nil || other == nil { // Must not be missing + return false + } else if s.ID != nil && (other.ID == nil || *s.ID != *other.ID) { // If id matters, then must include + return false + } else if s.Time == nil { // If time does not matter, success + return true + } else if other.Time == nil { // Must exist + return false + } else if sTime, err := time.Parse(time.RFC3339Nano, *s.Time); err != nil || sTime.IsZero() { // Must parse + return false + } else if otherTime, err := time.Parse(time.RFC3339Nano, *other.Time); err != nil || otherTime.IsZero() { // Must parse + return false + } else if sTime.After(otherTime) { // Must include + return false + } else { + return true + } } type Selector struct { - ID *string `json:"id,omitempty"` - Origin *SelectorOrigin `json:"origin,omitempty"` + ID *string `json:"id,omitempty" bson:"id,omitempty"` + Time *time.Time `json:"time,omitempty" bson:"time,omitempty"` // Inclusive, currently NOT used in database query + Origin *SelectorOrigin `json:"origin,omitempty" bson:"origin,omitempty"` } func ParseSelector(parser structure.ObjectParser) *Selector { @@ -60,6 +84,7 @@ func NewSelector() *Selector { func (s *Selector) Parse(parser structure.ObjectParser) { s.ID = parser.String("id") + s.Time = parser.Time("time", TimeFormat) s.Origin = ParseSelectorOrigin(parser.WithReferenceObjectParser("origin")) } @@ -68,11 +93,27 @@ func (s *Selector) Validate(validator structure.Validator) { validator.ReportError(structureValidator.ErrorValuesNotExistForOne("id", "origin")) } else if s.ID != nil { validator.String("id", s.ID).Using(IDValidator) + validator.Time("time", s.Time).NotZero() } else { + validator.Time("time", s.Time).NotExists() s.Origin.Validate(validator.WithReference("origin")) } } +func (s *Selector) Includes(other *Selector) bool { + if s == nil || other == nil { // Must not be missing + return false + } else if s.ID != nil && (other.ID == nil || *s.ID != *other.ID) { // If id matters, then must include + return false + } else if s.Time != nil && (other.Time == nil || s.Time.After(*other.Time)) { // If time matters, then must include + return false + } else if s.Origin != nil && (other.Origin == nil || !s.Origin.Includes(other.Origin)) { // If origin matters, then must include + return false + } else { + return true + } +} + type Selectors []*Selector func ParseSelectors(parser structure.ArrayParser) *Selectors { @@ -107,6 +148,16 @@ func (s *Selectors) Validate(validator structure.Validator) { } } +func (s *Selectors) Filter(predicate func(*Selector) bool) *Selectors { + filtered := Selectors{} + for _, selector := range *s { + if predicate(selector) { + filtered = append(filtered, selector) + } + } + return &filtered +} + func NewID() string { return id.Must(id.New(16)) } diff --git a/data/datum.go b/data/datum.go index a233e01940..2c11ea5aac 100644 --- a/data/datum.go +++ b/data/datum.go @@ -60,6 +60,16 @@ func (d Data) SetModifiedTime(modifiedTime *time.Time) { } } +func (d Data) Filter(predicate func(Datum) bool) Data { + filtered := Data{} + for _, datum := range d { + if predicate(datum) { + filtered = append(filtered, datum) + } + } + return filtered +} + // Provenance of a document. // // Useful for determining additional actions to take. For example, if the diff --git a/data/deduplicator/deduplicator/data_set_delete_origin.go b/data/deduplicator/deduplicator/data_set_delete_origin.go index 1e35c6d9a9..6dc6b1b5fa 100644 --- a/data/deduplicator/deduplicator/data_set_delete_origin.go +++ b/data/deduplicator/deduplicator/data_set_delete_origin.go @@ -6,24 +6,26 @@ import ( "github.com/tidepool-org/platform/data" dataStore "github.com/tidepool-org/platform/data/store" dataTypesUpload "github.com/tidepool-org/platform/data/types/upload" - "github.com/tidepool-org/platform/errors" "github.com/tidepool-org/platform/pointer" ) -const DataSetDeleteOriginName = "org.tidepool.deduplicator.dataset.delete.origin" +const ( + DataSetDeleteOriginName = "org.tidepool.deduplicator.dataset.delete.origin" + DataSetDeleteOriginVersion = "1.0.0" +) type DataSetDeleteOrigin struct { - *Base + *DataSetDeleteOriginBase } func NewDataSetDeleteOrigin() (*DataSetDeleteOrigin, error) { - base, err := NewBase(DataSetDeleteOriginName, "1.0.0") + dataSetDeleteOriginBase, err := NewDataSetDeleteOriginBase(DataSetDeleteOriginName, DataSetDeleteOriginVersion, &dataSetDeleteOriginProvider{}) if err != nil { return nil, err } return &DataSetDeleteOrigin{ - Base: base, + DataSetDeleteOriginBase: dataSetDeleteOriginBase, }, nil } @@ -32,106 +34,23 @@ func (d *DataSetDeleteOrigin) New(ctx context.Context, dataSet *dataTypesUpload. } func (d *DataSetDeleteOrigin) Get(ctx context.Context, dataSet *dataTypesUpload.Upload) (bool, error) { - if found, err := d.Base.Get(ctx, dataSet); err != nil || found { + if found, err := d.DataSetDeleteOriginBase.Get(ctx, dataSet); err != nil || found { return found, err } return dataSet.HasDeduplicatorNameMatch("org.tidepool.continuous.origin"), nil // TODO: DEPRECATED } -func (d *DataSetDeleteOrigin) Open(ctx context.Context, repository dataStore.DataRepository, dataSet *dataTypesUpload.Upload) (*dataTypesUpload.Upload, error) { - if ctx == nil { - return nil, errors.New("context is missing") - } - if repository == nil { - return nil, errors.New("repository is missing") - } - if dataSet == nil { - return nil, errors.New("data set is missing") - } - - if dataSet.HasDataSetTypeContinuous() { - dataSet.SetActive(true) - } - - return d.Base.Open(ctx, repository, dataSet) -} - -func (d *DataSetDeleteOrigin) AddData(ctx context.Context, repository dataStore.DataRepository, dataSet *dataTypesUpload.Upload, dataSetData data.Data) error { - if ctx == nil { - return errors.New("context is missing") - } - if repository == nil { - return errors.New("repository is missing") - } - if dataSet == nil { - return errors.New("data set is missing") - } - if dataSetData == nil { - return errors.New("data set data is missing") - } - - if dataSet.HasDataSetTypeContinuous() { - dataSetData.SetActive(true) - } - - if selectors := d.getSelectors(dataSetData); selectors != nil { - if err := repository.DeleteDataSetData(ctx, dataSet, selectors); err != nil { - return err - } - if err := d.Base.AddData(ctx, repository, dataSet, dataSetData); err != nil { - return err - } - return repository.DestroyDeletedDataSetData(ctx, dataSet, selectors) - } +type dataSetDeleteOriginProvider struct{} - return d.Base.AddData(ctx, repository, dataSet, dataSetData) +func (d *dataSetDeleteOriginProvider) FilterData(ctx context.Context, repository dataStore.DataRepository, dataSet *dataTypesUpload.Upload, dataSetData data.Data) (data.Data, error) { + return dataSetData, nil } -func (d *DataSetDeleteOrigin) DeleteData(ctx context.Context, repository dataStore.DataRepository, dataSet *dataTypesUpload.Upload, selectors *data.Selectors) error { - if ctx == nil { - return errors.New("context is missing") - } - if repository == nil { - return errors.New("repository is missing") - } - if dataSet == nil { - return errors.New("data set is missing") - } - if selectors == nil { - return errors.New("selectors is missing") - } - - return repository.ArchiveDataSetData(ctx, dataSet, selectors) -} - -func (d *DataSetDeleteOrigin) Close(ctx context.Context, repository dataStore.DataRepository, dataSet *dataTypesUpload.Upload) error { - if ctx == nil { - return errors.New("context is missing") - } - if repository == nil { - return errors.New("repository is missing") - } - if dataSet == nil { - return errors.New("data set is missing") - } - - if dataSet.HasDataSetTypeContinuous() { - return nil - } - - return d.Base.Close(ctx, repository, dataSet) -} - -func (d *DataSetDeleteOrigin) getSelectors(dataSetData data.Data) *data.Selectors { +func (d *dataSetDeleteOriginProvider) GetDataSelectors(dataSetData data.Data) *data.Selectors { selectors := data.Selectors{} for _, dataSetDatum := range dataSetData { - if origin := dataSetDatum.GetOrigin(); origin != nil && origin.ID != nil { - selector := &data.Selector{ - Origin: &data.SelectorOrigin{ - ID: pointer.CloneString(origin.ID), - }, - } + if selector := d.getDatumSelector(dataSetDatum); selector != nil { selectors = append(selectors, selector) } } @@ -140,3 +59,14 @@ func (d *DataSetDeleteOrigin) getSelectors(dataSetData data.Data) *data.Selector } return &selectors } + +func (d *dataSetDeleteOriginProvider) getDatumSelector(dataSetDatum data.Datum) *data.Selector { + if origin := dataSetDatum.GetOrigin(); origin != nil && origin.ID != nil { + return &data.Selector{ + Origin: &data.SelectorOrigin{ + ID: pointer.CloneString(origin.ID), + }, + } + } + return nil +} diff --git a/data/deduplicator/deduplicator/data_set_delete_origin_base.go b/data/deduplicator/deduplicator/data_set_delete_origin_base.go new file mode 100644 index 0000000000..978ae64006 --- /dev/null +++ b/data/deduplicator/deduplicator/data_set_delete_origin_base.go @@ -0,0 +1,121 @@ +package deduplicator + +import ( + "context" + + "github.com/tidepool-org/platform/data" + dataStore "github.com/tidepool-org/platform/data/store" + dataTypesUpload "github.com/tidepool-org/platform/data/types/upload" + "github.com/tidepool-org/platform/errors" +) + +type DataSetDeleteOriginProvider interface { + FilterData(ctx context.Context, repository dataStore.DataRepository, dataSet *dataTypesUpload.Upload, dataSetData data.Data) (data.Data, error) + GetDataSelectors(datum data.Data) *data.Selectors +} + +type DataSetDeleteOriginBase struct { + *Base + provider DataSetDeleteOriginProvider +} + +func NewDataSetDeleteOriginBase(name string, version string, provider DataSetDeleteOriginProvider) (*DataSetDeleteOriginBase, error) { + base, err := NewBase(name, version) + if err != nil { + return nil, err + } + + return &DataSetDeleteOriginBase{ + Base: base, + provider: provider, + }, nil +} + +func (d *DataSetDeleteOriginBase) Open(ctx context.Context, repository dataStore.DataRepository, dataSet *dataTypesUpload.Upload) (*dataTypesUpload.Upload, error) { + if ctx == nil { + return nil, errors.New("context is missing") + } + if repository == nil { + return nil, errors.New("repository is missing") + } + if dataSet == nil { + return nil, errors.New("data set is missing") + } + + if dataSet.HasDataSetTypeContinuous() { + dataSet.SetActive(true) + } + + return d.Base.Open(ctx, repository, dataSet) +} + +func (d *DataSetDeleteOriginBase) AddData(ctx context.Context, repository dataStore.DataRepository, dataSet *dataTypesUpload.Upload, dataSetData data.Data) error { + if ctx == nil { + return errors.New("context is missing") + } + if repository == nil { + return errors.New("repository is missing") + } + if dataSet == nil { + return errors.New("data set is missing") + } + if dataSetData == nil { + return errors.New("data set data is missing") + } + + if dataSet.HasDataSetTypeContinuous() { + dataSetData.SetActive(true) + } + + var err error + if dataSetData, err = d.provider.FilterData(ctx, repository, dataSet, dataSetData); err != nil { + return err + } + + if selectors := d.provider.GetDataSelectors(dataSetData); selectors != nil { + if err := repository.DeleteDataSetData(ctx, dataSet, selectors); err != nil { + return err + } + if err := d.Base.AddData(ctx, repository, dataSet, dataSetData); err != nil { + return err + } + return repository.DestroyDeletedDataSetData(ctx, dataSet, selectors) + } + + return d.Base.AddData(ctx, repository, dataSet, dataSetData) +} + +func (d *DataSetDeleteOriginBase) DeleteData(ctx context.Context, repository dataStore.DataRepository, dataSet *dataTypesUpload.Upload, selectors *data.Selectors) error { + if ctx == nil { + return errors.New("context is missing") + } + if repository == nil { + return errors.New("repository is missing") + } + if dataSet == nil { + return errors.New("data set is missing") + } + if selectors == nil { + return errors.New("selectors is missing") + } + + return repository.ArchiveDataSetData(ctx, dataSet, selectors) +} + +func (d *DataSetDeleteOriginBase) Close(ctx context.Context, repository dataStore.DataRepository, dataSet *dataTypesUpload.Upload) error { + if ctx == nil { + return errors.New("context is missing") + } + if repository == nil { + return errors.New("repository is missing") + } + if dataSet == nil { + return errors.New("data set is missing") + } + + if dataSet.HasDataSetTypeContinuous() { + return nil + } + + return d.Base.Close(ctx, repository, dataSet) +} diff --git a/data/deduplicator/deduplicator/data_set_delete_origin_older.go b/data/deduplicator/deduplicator/data_set_delete_origin_older.go new file mode 100644 index 0000000000..00dddf7172 --- /dev/null +++ b/data/deduplicator/deduplicator/data_set_delete_origin_older.go @@ -0,0 +1,83 @@ +package deduplicator + +import ( + "context" + "slices" + + "github.com/tidepool-org/platform/data" + dataStore "github.com/tidepool-org/platform/data/store" + dataTypesBolus "github.com/tidepool-org/platform/data/types/bolus" + dataTypesFood "github.com/tidepool-org/platform/data/types/food" + dataTypesUpload "github.com/tidepool-org/platform/data/types/upload" + "github.com/tidepool-org/platform/pointer" +) + +const ( + DataSetDeleteOriginOlderName = "org.tidepool.deduplicator.dataset.delete.origin.older" + DataSetDeleteOriginOlderVersion = "1.0.0" +) + +type DataSetDeleteOriginOlder struct { + *DataSetDeleteOriginBase +} + +func NewDataSetDeleteOriginOlder() (*DataSetDeleteOriginOlder, error) { + dataSetDeleteOriginBase, err := NewDataSetDeleteOriginBase(DataSetDeleteOriginOlderName, DataSetDeleteOriginOlderVersion, &dataSetDeleteOriginOlderProvider{}) + if err != nil { + return nil, err + } + + return &DataSetDeleteOriginOlder{ + DataSetDeleteOriginBase: dataSetDeleteOriginBase, + }, nil +} + +type dataSetDeleteOriginOlderProvider struct{} + +func (d *dataSetDeleteOriginOlderProvider) FilterData(ctx context.Context, repository dataStore.DataRepository, dataSet *dataTypesUpload.Upload, dataSetData data.Data) (data.Data, error) { + filterableDataSetData := dataSetData.Filter(func(datum data.Datum) bool { + return slices.Contains(filterableDataSetDataTypes, datum.GetType()) + }) + + if selectors := d.GetDataSelectors(filterableDataSetData); selectors != nil { + if existingSelectors, err := repository.NewerDataSetData(ctx, dataSet, selectors); err != nil { + return nil, err + } else if existingSelectors != nil && len(*existingSelectors) > 0 { + dataSetData = dataSetData.Filter(func(datum data.Datum) bool { + return !slices.ContainsFunc(*existingSelectors, d.getDatumSelector(datum).Includes) + }) + } + } + + return dataSetData, nil +} + +func (d *dataSetDeleteOriginOlderProvider) GetDataSelectors(dataSetData data.Data) *data.Selectors { + selectors := data.Selectors{} + for _, dataSetDatum := range dataSetData { + if selector := d.getDatumSelector(dataSetDatum); selector != nil { + selectors = append(selectors, selector) + } + } + if len(selectors) == 0 { + return nil + } + return &selectors +} + +func (d *dataSetDeleteOriginOlderProvider) getDatumSelector(dataSetDatum data.Datum) *data.Selector { + if origin := dataSetDatum.GetOrigin(); origin != nil && origin.ID != nil { + return &data.Selector{ + Origin: &data.SelectorOrigin{ + ID: pointer.CloneString(origin.ID), + Time: origin.Time, + }, + } + } + return nil +} + +var filterableDataSetDataTypes = []string{ + dataTypesBolus.Type, + dataTypesFood.Type, +} diff --git a/data/deduplicator/deduplicator/data_set_delete_origin_older_test.go b/data/deduplicator/deduplicator/data_set_delete_origin_older_test.go new file mode 100644 index 0000000000..eec7927dd8 --- /dev/null +++ b/data/deduplicator/deduplicator/data_set_delete_origin_older_test.go @@ -0,0 +1,609 @@ +package deduplicator_test + +import ( + "context" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "github.com/tidepool-org/platform/data" + dataDeduplicatorDeduplicator "github.com/tidepool-org/platform/data/deduplicator/deduplicator" + dataStoreTest "github.com/tidepool-org/platform/data/store/test" + dataTest "github.com/tidepool-org/platform/data/test" + dataTypes "github.com/tidepool-org/platform/data/types" + dataTypesTest "github.com/tidepool-org/platform/data/types/test" + dataTypesUpload "github.com/tidepool-org/platform/data/types/upload" + dataTypesUploadTest "github.com/tidepool-org/platform/data/types/upload/test" + errorsTest "github.com/tidepool-org/platform/errors/test" + netTest "github.com/tidepool-org/platform/net/test" + "github.com/tidepool-org/platform/pointer" + "github.com/tidepool-org/platform/test" +) + +var _ = Describe("DataSetDeleteOriginOlder", func() { + It("DataSetDeleteOriginOlderName is expected", func() { + Expect(dataDeduplicatorDeduplicator.DataSetDeleteOriginOlderName).To(Equal("org.tidepool.deduplicator.dataset.delete.origin.older")) + }) + + It("DataSetDeleteOriginOlderVersion is expected", func() { + Expect(dataDeduplicatorDeduplicator.DataSetDeleteOriginOlderVersion).To(Equal("1.0.0")) + }) + + Context("NewDataSetDeleteOriginOlder", func() { + It("returns successfully", func() { + Expect(dataDeduplicatorDeduplicator.NewDataSetDeleteOriginOlder()).ToNot(BeNil()) + }) + }) + + Context("with new deduplicator", func() { + var deduplicator *dataDeduplicatorDeduplicator.DataSetDeleteOriginOlder + var dataSet *dataTypesUpload.Upload + + BeforeEach(func() { + var err error + deduplicator, err = dataDeduplicatorDeduplicator.NewDataSetDeleteOriginOlder() + Expect(err).ToNot(HaveOccurred()) + Expect(deduplicator).ToNot(BeNil()) + dataSet = dataTypesUploadTest.RandomUpload() + dataSet.Deduplicator.Name = pointer.FromString("org.tidepool.deduplicator.dataset.delete.origin.older") + }) + + Context("New", func() { + It("returns an error when the data set is missing", func() { + found, err := deduplicator.New(context.Background(), nil) + Expect(err).To(MatchError("data set is missing")) + Expect(found).To(BeFalse()) + }) + + It("returns false when the deduplicator is missing", func() { + dataSet.Deduplicator = nil + Expect(deduplicator.New(context.Background(), dataSet)).To(BeFalse()) + }) + + It("returns false when the deduplicator name is missing", func() { + dataSet.Deduplicator.Name = nil + Expect(deduplicator.New(context.Background(), dataSet)).To(BeFalse()) + }) + + It("returns false when the deduplicator name does not match", func() { + dataSet.Deduplicator.Name = pointer.FromString(netTest.RandomReverseDomain()) + Expect(deduplicator.New(context.Background(), dataSet)).To(BeFalse()) + }) + + It("returns true when the deduplicator name matches", func() { + Expect(deduplicator.New(context.Background(), dataSet)).To(BeTrue()) + }) + }) + + Context("Get", func() { + It("returns an error when the data set is missing", func() { + found, err := deduplicator.Get(context.Background(), nil) + Expect(err).To(MatchError("data set is missing")) + Expect(found).To(BeFalse()) + }) + + It("returns false when the deduplicator is missing", func() { + dataSet.Deduplicator = nil + Expect(deduplicator.Get(context.Background(), dataSet)).To(BeFalse()) + }) + + It("returns false when the deduplicator name is missing", func() { + dataSet.Deduplicator.Name = nil + Expect(deduplicator.Get(context.Background(), dataSet)).To(BeFalse()) + }) + + It("returns false when the deduplicator name does not match", func() { + dataSet.Deduplicator.Name = pointer.FromString(netTest.RandomReverseDomain()) + Expect(deduplicator.Get(context.Background(), dataSet)).To(BeFalse()) + }) + + It("returns true when the deduplicator name matches", func() { + Expect(deduplicator.Get(context.Background(), dataSet)).To(BeTrue()) + }) + }) + + Context("with context and repository", func() { + var ctx context.Context + var repository *dataStoreTest.DataRepository + + BeforeEach(func() { + ctx = context.Background() + repository = dataStoreTest.NewDataRepository() + }) + + AfterEach(func() { + repository.AssertOutputsEmpty() + }) + + Context("Open", func() { + It("returns an error when the context is missing", func() { + result, err := deduplicator.Open(nil, repository, dataSet) + Expect(err).To(MatchError("context is missing")) + Expect(result).To(BeNil()) + }) + + It("returns an error when the repository is missing", func() { + result, err := deduplicator.Open(ctx, nil, dataSet) + Expect(err).To(MatchError("repository is missing")) + Expect(result).To(BeNil()) + }) + + It("returns an error when the data set is missing", func() { + result, err := deduplicator.Open(ctx, repository, nil) + Expect(err).To(MatchError("data set is missing")) + Expect(result).To(BeNil()) + }) + + When("UpdateDataSet is invoked", func() { + var update *data.DataSetUpdate + + BeforeEach(func() { + update = data.NewDataSetUpdate() + update.Deduplicator = &data.DeduplicatorDescriptor{ + Name: pointer.FromString("org.tidepool.deduplicator.dataset.delete.origin.older"), + Version: pointer.FromString("1.0.0"), + } + }) + + AfterEach(func() { + Expect(repository.UpdateDataSetInputs).To(Equal([]dataStoreTest.UpdateDataSetInput{{Context: ctx, ID: *dataSet.UploadID, Update: update}})) + }) + + updateAssertions := func() { + When("the data set does not have a deduplicator", func() { + BeforeEach(func() { + dataSet.Deduplicator = nil + }) + + It("returns an error when update data set returns an error", func() { + responseErr := errorsTest.RandomError() + repository.UpdateDataSetOutputs = []dataStoreTest.UpdateDataSetOutput{{DataSet: nil, Error: responseErr}} + result, err := deduplicator.Open(ctx, repository, dataSet) + Expect(err).To(Equal(responseErr)) + Expect(result).To(BeNil()) + }) + + It("returns successfully when update data set returns successfully", func() { + responseDataSet := dataTypesUploadTest.RandomUpload() + repository.UpdateDataSetOutputs = []dataStoreTest.UpdateDataSetOutput{{DataSet: responseDataSet, Error: nil}} + Expect(deduplicator.Open(ctx, repository, dataSet)).To(Equal(responseDataSet)) + }) + }) + + When("the data set has a deduplicator with matching name and version does not exist", func() { + BeforeEach(func() { + dataSet.Deduplicator.Version = nil + }) + + It("returns an error when update data set returns an error", func() { + responseErr := errorsTest.RandomError() + repository.UpdateDataSetOutputs = []dataStoreTest.UpdateDataSetOutput{{DataSet: nil, Error: responseErr}} + result, err := deduplicator.Open(ctx, repository, dataSet) + Expect(err).To(Equal(responseErr)) + Expect(result).To(BeNil()) + }) + + It("returns successfully when update data set returns successfully", func() { + responseDataSet := dataTypesUploadTest.RandomUpload() + repository.UpdateDataSetOutputs = []dataStoreTest.UpdateDataSetOutput{{DataSet: responseDataSet, Error: nil}} + Expect(deduplicator.Open(ctx, repository, dataSet)).To(Equal(responseDataSet)) + }) + }) + + When("the data set has a deduplicator with matching name and version exists", func() { + BeforeEach(func() { + dataSet.Deduplicator.Version = pointer.FromString(netTest.RandomSemanticVersion()) + }) + + It("returns an error when update data set returns an error", func() { + responseErr := errorsTest.RandomError() + repository.UpdateDataSetOutputs = []dataStoreTest.UpdateDataSetOutput{{DataSet: nil, Error: responseErr}} + result, err := deduplicator.Open(ctx, repository, dataSet) + Expect(err).To(Equal(responseErr)) + Expect(result).To(BeNil()) + }) + + It("returns successfully when update data set returns successfully", func() { + responseDataSet := dataTypesUploadTest.RandomUpload() + repository.UpdateDataSetOutputs = []dataStoreTest.UpdateDataSetOutput{{DataSet: responseDataSet, Error: nil}} + Expect(deduplicator.Open(ctx, repository, dataSet)).To(Equal(responseDataSet)) + }) + }) + } + + When("data set type is not specified", func() { + BeforeEach(func() { + dataSet.DataSetType = nil + update.Active = pointer.FromBool(false) + }) + + AfterEach(func() { + Expect(dataSet.Active).To(BeFalse()) + }) + + updateAssertions() + }) + + When("data set type is continuous", func() { + BeforeEach(func() { + dataSet.DataSetType = pointer.FromString("continuous") + update.Active = pointer.FromBool(true) + }) + + AfterEach(func() { + Expect(dataSet.Active).To(BeTrue()) + }) + + updateAssertions() + }) + + When("data set type is normal", func() { + BeforeEach(func() { + dataSet.DataSetType = pointer.FromString("normal") + update.Active = pointer.FromBool(false) + }) + + AfterEach(func() { + Expect(dataSet.Active).To(BeFalse()) + }) + + updateAssertions() + }) + }) + }) + + Context("AddData", func() { + var unfilteredDataSetData data.Data + var filteredDataSetData data.Data + var allDataSetData data.Data + var unfilteredSelectors *data.Selectors + var filteredSelectors *data.Selectors + + BeforeEach(func() { + unfilteredDataSetData = make(data.Data, test.RandomIntFromRange(1, 3)) + unfilteredSelectors = data.NewSelectors() + for index := range unfilteredDataSetData { + base := dataTypesTest.RandomBase() + unfilteredDataSetData[index] = base + *unfilteredSelectors = append(*unfilteredSelectors, &data.Selector{Origin: &data.SelectorOrigin{ID: pointer.CloneString(base.Origin.ID), Time: base.Origin.Time}}) + } + filteredDataSetData = make(data.Data, test.RandomIntFromRange(1, 3)) + filteredSelectors = data.NewSelectors() + for index := range filteredDataSetData { + base := dataTypesTest.RandomBase() + base.Type = test.RandomStringFromArray([]string{"bolus", "food"}) + filteredDataSetData[index] = base + *filteredSelectors = append(*filteredSelectors, &data.Selector{Origin: &data.SelectorOrigin{ID: pointer.CloneString(base.Origin.ID), Time: base.Origin.Time}}) + } + allDataSetData = append(unfilteredDataSetData, filteredDataSetData...) + }) + + It("returns an error when the context is missing", func() { + Expect(deduplicator.AddData(nil, repository, dataSet, allDataSetData)).To(MatchError("context is missing")) + }) + + It("returns an error when the repository is missing", func() { + Expect(deduplicator.AddData(ctx, nil, dataSet, allDataSetData)).To(MatchError("repository is missing")) + }) + + It("returns an error when the data set is missing", func() { + Expect(deduplicator.AddData(ctx, repository, nil, allDataSetData)).To(MatchError("data set is missing")) + }) + + It("returns an error when the data set data is missing", func() { + Expect(deduplicator.AddData(ctx, repository, dataSet, nil)).To(MatchError("data set data is missing")) + }) + + dataSetTypeAssertions := func() { + originAssertions := func() { + When("create data set data is invoked", func() { + AfterEach(func() { + Expect(repository.CreateDataSetDataInputs).To(Equal([]dataStoreTest.CreateDataSetDataInput{{Context: ctx, DataSet: dataSet, DataSetData: allDataSetData}})) + }) + + It("returns an error when create data set data returns an error", func() { + responseErr := errorsTest.RandomError() + repository.CreateDataSetDataOutputs = []error{responseErr} + Expect(deduplicator.AddData(ctx, repository, dataSet, allDataSetData)).To(Equal(responseErr)) + }) + + It("returns successfully when create data set data returns successfully", func() { + repository.CreateDataSetDataOutputs = []error{nil} + Expect(deduplicator.AddData(ctx, repository, dataSet, allDataSetData)).To(Succeed()) + }) + }) + } + + When("data set data does not have an origin", func() { + BeforeEach(func() { + for index := range allDataSetData { + base := dataTypesTest.RandomBase() + base.Origin = nil + allDataSetData[index] = base + } + }) + + originAssertions() + }) + + When("data set data does not have an origin id", func() { + BeforeEach(func() { + for index := range allDataSetData { + base := dataTypesTest.RandomBase() + base.Origin.ID = nil + allDataSetData[index] = base + } + }) + + originAssertions() + }) + + When("data set data has an origin id", func() { + When("newer data set data using origin ids is invoked", func() { + AfterEach(func() { + Expect(repository.NewerDataSetDataInputs).To(Equal([]dataStoreTest.NewerDataSetDataInput{{Context: ctx, DataSet: dataSet, Selectors: filteredSelectors}})) + }) + + It("returns an error when newer data set data using origin id returns an error", func() { + responseErr := errorsTest.RandomError() + repository.NewerDataSetDataOutputs = []dataStoreTest.NewerDataSetDataOutput{{Selectors: nil, Error: responseErr}} + Expect(deduplicator.AddData(ctx, repository, dataSet, allDataSetData)).To(Equal(responseErr)) + }) + + When("delete data set data using origin ids is invoked", func() { + BeforeEach(func() { + repository.NewerDataSetDataOutputs = []dataStoreTest.NewerDataSetDataOutput{{Selectors: filteredSelectors, Error: nil}} + }) + + AfterEach(func() { + Expect(repository.DeleteDataSetDataInputs).To(Equal([]dataStoreTest.DeleteDataSetDataInput{{Context: ctx, DataSet: dataSet, Selectors: unfilteredSelectors}})) + }) + + It("returns an error when delete data set data using origin id returns an error", func() { + responseErr := errorsTest.RandomError() + repository.DeleteDataSetDataOutputs = []error{responseErr} + Expect(deduplicator.AddData(ctx, repository, dataSet, allDataSetData)).To(Equal(responseErr)) + }) + + When("create data set data is invoked", func() { + BeforeEach(func() { + repository.DeleteDataSetDataOutputs = []error{nil} + }) + + AfterEach(func() { + Expect(repository.CreateDataSetDataInputs).To(Equal([]dataStoreTest.CreateDataSetDataInput{{Context: ctx, DataSet: dataSet, DataSetData: unfilteredDataSetData}})) + }) + + It("returns an error when create data set data returns an error", func() { + responseErr := errorsTest.RandomError() + repository.CreateDataSetDataOutputs = []error{responseErr} + Expect(deduplicator.AddData(ctx, repository, dataSet, allDataSetData)).To(Equal(responseErr)) + }) + + When("destroy deleted data set data is invoked", func() { + BeforeEach(func() { + repository.CreateDataSetDataOutputs = []error{nil} + }) + + AfterEach(func() { + Expect(repository.DestroyDeletedDataSetDataInputs).To(Equal([]dataStoreTest.DestroyDeletedDataSetDataInput{{Context: ctx, DataSet: dataSet, Selectors: unfilteredSelectors}})) + }) + + It("returns an error when destroy deleted data set data returns an error", func() { + responseErr := errorsTest.RandomError() + repository.DestroyDeletedDataSetDataOutputs = []error{responseErr} + Expect(deduplicator.AddData(ctx, repository, dataSet, allDataSetData)).To(Equal(responseErr)) + }) + + It("returns successfully when destroy deleted data set data returns successfully", func() { + repository.DestroyDeletedDataSetDataOutputs = []error{nil} + Expect(deduplicator.AddData(ctx, repository, dataSet, allDataSetData)).To(Succeed()) + }) + }) + }) + }) + }) + }) + } + + When("data set type is not specified", func() { + BeforeEach(func() { + dataSet.DataSetType = nil + }) + + AfterEach(func() { + for _, datum := range allDataSetData { + base, ok := datum.(*dataTypes.Base) + Expect(ok).To(BeTrue()) + Expect(base).ToNot(BeNil()) + Expect(base.Active).To(BeFalse()) + } + }) + + dataSetTypeAssertions() + }) + + When("data set type is continuous", func() { + BeforeEach(func() { + dataSet.DataSetType = pointer.FromString("continuous") + }) + + AfterEach(func() { + for _, datum := range allDataSetData { + base, ok := datum.(*dataTypes.Base) + Expect(ok).To(BeTrue()) + Expect(base).ToNot(BeNil()) + Expect(base.Active).To(BeTrue()) + } + }) + + dataSetTypeAssertions() + }) + + When("data set type is normal", func() { + BeforeEach(func() { + dataSet.DataSetType = pointer.FromString("normal") + }) + + AfterEach(func() { + for _, datum := range allDataSetData { + base, ok := datum.(*dataTypes.Base) + Expect(ok).To(BeTrue()) + Expect(base).ToNot(BeNil()) + Expect(base.Active).To(BeFalse()) + } + }) + + dataSetTypeAssertions() + }) + }) + + Context("DeleteData", func() { + var selectors *data.Selectors + + BeforeEach(func() { + selectors = dataTest.RandomSelectors() + }) + + It("returns an error when the context is missing", func() { + Expect(deduplicator.DeleteData(nil, repository, dataSet, selectors)).To(MatchError("context is missing")) + }) + + It("returns an error when the repository is missing", func() { + Expect(deduplicator.DeleteData(ctx, nil, dataSet, selectors)).To(MatchError("repository is missing")) + }) + + It("returns an error when the data set is missing", func() { + Expect(deduplicator.DeleteData(ctx, repository, nil, selectors)).To(MatchError("data set is missing")) + }) + + It("returns an error when the selectors is missing", func() { + Expect(deduplicator.DeleteData(ctx, repository, dataSet, nil)).To(MatchError("selectors is missing")) + }) + + When("archive data set data is invoked", func() { + AfterEach(func() { + Expect(repository.ArchiveDataSetDataInputs).To(Equal([]dataStoreTest.ArchiveDataSetDataInput{{Context: ctx, DataSet: dataSet, Selectors: selectors}})) + }) + + It("returns an error when archive data set data returns an error", func() { + responseErr := errorsTest.RandomError() + repository.ArchiveDataSetDataOutputs = []error{responseErr} + Expect(deduplicator.DeleteData(ctx, repository, dataSet, selectors)).To(Equal(responseErr)) + }) + + It("returns successfully when archive data set data returns successfully", func() { + repository.ArchiveDataSetDataOutputs = []error{nil} + Expect(deduplicator.DeleteData(ctx, repository, dataSet, selectors)).To(Succeed()) + }) + }) + }) + + Context("Close", func() { + It("returns an error when the context is missing", func() { + Expect(deduplicator.Close(nil, repository, dataSet)).To(MatchError("context is missing")) + }) + + It("returns an error when the repository is missing", func() { + Expect(deduplicator.Close(ctx, nil, dataSet)).To(MatchError("repository is missing")) + }) + + It("returns an error when the data set is missing", func() { + Expect(deduplicator.Close(ctx, repository, nil)).To(MatchError("data set is missing")) + }) + + When("data set type is continuous", func() { + BeforeEach(func() { + dataSet.DataSetType = pointer.FromString("continuous") + }) + + It("returns successfully", func() { + Expect(deduplicator.Close(ctx, repository, dataSet)).To(Succeed()) + }) + }) + + When("UpdateDataSet is invoked", func() { + AfterEach(func() { + Expect(repository.UpdateDataSetInputs).To(Equal([]dataStoreTest.UpdateDataSetInput{{Context: ctx, ID: *dataSet.UploadID, Update: &data.DataSetUpdate{Active: pointer.FromBool(true)}}})) + }) + + updateAssertions := func() { + It("returns an error when update data set data returns an error", func() { + responseErr := errorsTest.RandomError() + repository.UpdateDataSetOutputs = []dataStoreTest.UpdateDataSetOutput{{DataSet: nil, Error: responseErr}} + Expect(deduplicator.Close(ctx, repository, dataSet)).To(Equal(responseErr)) + }) + + When("activate data set data is invoked", func() { + BeforeEach(func() { + repository.UpdateDataSetOutputs = []dataStoreTest.UpdateDataSetOutput{{DataSet: dataSet, Error: nil}} + }) + + AfterEach(func() { + Expect(repository.ActivateDataSetDataInputs).To(Equal([]dataStoreTest.ActivateDataSetDataInput{{Context: ctx, DataSet: dataSet, Selectors: nil}})) + }) + + It("returns an error when active data set data returns an error", func() { + responseErr := errorsTest.RandomError() + repository.ActivateDataSetDataOutputs = []error{responseErr} + Expect(deduplicator.Close(ctx, repository, dataSet)).To(Equal(responseErr)) + }) + + It("returns successfully when active data set data returns successfully", func() { + repository.ActivateDataSetDataOutputs = []error{nil} + Expect(deduplicator.Close(ctx, repository, dataSet)).To(Succeed()) + }) + }) + } + + When("data set type is not specified", func() { + BeforeEach(func() { + dataSet.DataSetType = nil + }) + + updateAssertions() + }) + + When("data set type is normal", func() { + BeforeEach(func() { + dataSet.DataSetType = pointer.FromString("normal") + }) + + updateAssertions() + }) + }) + }) + + Context("Delete", func() { + It("returns an error when the context is missing", func() { + Expect(deduplicator.Delete(nil, repository, dataSet)).To(MatchError("context is missing")) + }) + + It("returns an error when the repository is missing", func() { + Expect(deduplicator.Delete(ctx, nil, dataSet)).To(MatchError("repository is missing")) + }) + + It("returns an error when the data set is missing", func() { + Expect(deduplicator.Delete(ctx, repository, nil)).To(MatchError("data set is missing")) + }) + + When("delete data set is invoked", func() { + AfterEach(func() { + Expect(repository.DeleteDataSetInputs).To(Equal([]dataStoreTest.DeleteDataSetInput{{Context: ctx, DataSet: dataSet}})) + }) + + It("returns an error when delete data set returns an error", func() { + responseErr := errorsTest.RandomError() + repository.DeleteDataSetOutputs = []error{responseErr} + Expect(deduplicator.Delete(ctx, repository, dataSet)).To(Equal(responseErr)) + }) + + It("returns successfully when delete data set returns successfully", func() { + repository.DeleteDataSetOutputs = []error{nil} + Expect(deduplicator.Delete(ctx, repository, dataSet)).To(Succeed()) + }) + }) + }) + }) + }) +}) diff --git a/data/deduplicator/deduplicator/data_set_delete_origin_test.go b/data/deduplicator/deduplicator/data_set_delete_origin_test.go index 6691479632..06be791803 100644 --- a/data/deduplicator/deduplicator/data_set_delete_origin_test.go +++ b/data/deduplicator/deduplicator/data_set_delete_origin_test.go @@ -26,7 +26,7 @@ var _ = Describe("DataSetDeleteOrigin", func() { }) Context("NewDataSetDeleteOrigin", func() { - It("returns succesfully", func() { + It("returns successfully", func() { Expect(dataDeduplicatorDeduplicator.NewDataSetDeleteOrigin()).ToNot(BeNil()) }) }) diff --git a/data/service/service/standard.go b/data/service/service/standard.go index cea18b84f5..7d3452f429 100644 --- a/data/service/service/standard.go +++ b/data/service/service/standard.go @@ -221,6 +221,13 @@ func (s *Standard) initializeDataDeduplicatorFactory() error { return errors.Wrap(err, "unable to create data set delete origin deduplicator") } + s.Logger().Debug("Creating data set delete origin older deduplicator") + + dataSetDeleteOriginOlderDeduplicator, err := dataDeduplicatorDeduplicator.NewDataSetDeleteOriginOlder() + if err != nil { + return errors.Wrap(err, "unable to create data set delete origin older deduplicator") + } + s.Logger().Debug("Creating none deduplicator") noneDeduplicator, err := dataDeduplicatorDeduplicator.NewNone() @@ -234,6 +241,7 @@ func (s *Standard) initializeDataDeduplicatorFactory() error { deviceDeactivateHashDeduplicator, deviceTruncateDataSetDeduplicator, dataSetDeleteOriginDeduplicator, + dataSetDeleteOriginOlderDeduplicator, noneDeduplicator, } diff --git a/data/store/mongo/mongo_datum.go b/data/store/mongo/mongo_datum.go index 59135e03fc..5d864b778d 100644 --- a/data/store/mongo/mongo_datum.go +++ b/data/store/mongo/mongo_datum.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "slices" "time" "go.mongodb.org/mongo-driver/bson" @@ -196,6 +197,53 @@ func (d *DatumRepository) CreateDataSetData(ctx context.Context, dataSet *upload return nil } +func (d *DatumRepository) NewerDataSetData(ctx context.Context, dataSet *upload.Upload, selectors *data.Selectors) (*data.Selectors, error) { + if ctx == nil { + return nil, errors.New("context is missing") + } + if err := validateDataSet(dataSet); err != nil { + return nil, err + } + selector, _, err := validateAndTranslateSelectors(ctx, selectors) + if err != nil { + return nil, err + } + + now := time.Now().UTC() + logger := log.LoggerFromContext(ctx).WithField("dataSetId", *dataSet.UploadID) + + selector["_userId"] = dataSet.UserID + selector["uploadId"] = dataSet.UploadID + selector["type"] = bson.M{"$ne": "upload"} // Note we WILL keep the "type" field in the UploadId index as that's a query need in tide-whisperer + selector["_active"] = false + selector["deletedTime"] = bson.M{"$exists": false} + + findOptions := options.Find() + findOptions.SetProjection(bson.M{"_id": 0, "id": 1, "origin.id": 1}) + + cursor, err := d.Find(ctx, selector, findOptions) + if err != nil { + logger.WithError(err).Error("Unable to get newer data set data selectors") + return nil, fmt.Errorf("unable to get newer data set data selectors: %w", err) + } + + var newerSelectors *data.Selectors + if err = cursor.All(ctx, &newerSelectors); err != nil { + logger.WithError(err).Error("Unable to decode newer data set data selectors") + return nil, fmt.Errorf("unable to decode newer data set data selectors: %w", err) + } + + // Post-process to exclude any not newer + newerSelectors = newerSelectors.Filter(func(newerSelector *data.Selector) bool { + return slices.ContainsFunc(*selectors, func(selector *data.Selector) bool { + return selector.Includes(newerSelector) + }) + }) + + logger.WithFields(log.Fields{"newerSelectors": newerSelectors, "duration": time.Since(now) / time.Microsecond}).Debug("NewerDataSetData") + return newerSelectors, nil +} + func (d *DatumRepository) ActivateDataSetData(ctx context.Context, dataSet *upload.Upload, selectors *data.Selectors) error { if ctx == nil { return errors.New("context is missing") @@ -538,6 +586,10 @@ func (d *DatumRepository) UnarchiveDeviceDataUsingHashesFromDataSet(ctx context. return overallErr } +// TODO: Currently does not translate time or origin.time fields. Since origin.time is currently persisted as a string +// (and not time.Time) we cannot reliably query for it due to potentially variable timezone offsets. Eventually, migrate +// origin.time to time.Time and add additional qualifiers to the database selector that document origin.time must be +// greater than or equal to the incoming selector origin.time. For now, we can only query on id and origin.id. func validateAndTranslateSelectors(ctx context.Context, selectors *data.Selectors) (filter bson.M, hasOriginID bool, err error) { if selectors == nil { return bson.M{}, false, nil diff --git a/data/store/store.go b/data/store/store.go index 7410d76c88..11ce0a5d03 100644 --- a/data/store/store.go +++ b/data/store/store.go @@ -50,6 +50,7 @@ type DatumRepository interface { EnsureIndexes() error CreateDataSetData(ctx context.Context, dataSet *upload.Upload, dataSetData []data.Datum) error + NewerDataSetData(ctx context.Context, dataSet *upload.Upload, selectors *data.Selectors) (*data.Selectors, error) ActivateDataSetData(ctx context.Context, dataSet *upload.Upload, selectors *data.Selectors) error ArchiveDataSetData(ctx context.Context, dataSet *upload.Upload, selectors *data.Selectors) error DeleteDataSetData(ctx context.Context, dataSet *upload.Upload, selectors *data.Selectors) error diff --git a/data/store/test/data_repository.go b/data/store/test/data_repository.go index ff5a857bcd..356a73ffab 100644 --- a/data/store/test/data_repository.go +++ b/data/store/test/data_repository.go @@ -64,6 +64,17 @@ type CreateDataSetDataInput struct { DataSetData []data.Datum } +type NewerDataSetDataInput struct { + Context context.Context + DataSet *upload.Upload + Selectors *data.Selectors +} + +type NewerDataSetDataOutput struct { + Selectors *data.Selectors + Error error +} + type ActivateDataSetDataInput struct { Context context.Context DataSet *upload.Upload @@ -210,6 +221,9 @@ type DataRepository struct { CreateDataSetDataInvocations int CreateDataSetDataInputs []CreateDataSetDataInput CreateDataSetDataOutputs []error + NewerDataSetDataInvocations int + NewerDataSetDataInputs []NewerDataSetDataInput + NewerDataSetDataOutputs []NewerDataSetDataOutput ActivateDataSetDataInvocations int ActivateDataSetDataInputs []ActivateDataSetDataInput ActivateDataSetDataOutputs []error @@ -348,6 +362,18 @@ func (d *DataRepository) CreateDataSetData(ctx context.Context, dataSet *upload. return output } +func (d *DataRepository) NewerDataSetData(ctx context.Context, dataSet *upload.Upload, selectors *data.Selectors) (*data.Selectors, error) { + d.NewerDataSetDataInvocations++ + + d.NewerDataSetDataInputs = append(d.NewerDataSetDataInputs, NewerDataSetDataInput{Context: ctx, DataSet: dataSet, Selectors: selectors}) + + gomega.Expect(d.NewerDataSetDataOutputs).ToNot(gomega.BeEmpty()) + + output := d.NewerDataSetDataOutputs[0] + d.NewerDataSetDataOutputs = d.NewerDataSetDataOutputs[1:] + return output.Selectors, output.Error +} + func (d *DataRepository) ActivateDataSetData(ctx context.Context, dataSet *upload.Upload, selectors *data.Selectors) error { d.ActivateDataSetDataInvocations++ From f3d1833f027ff01069e98e3719d30a0d56fafbff Mon Sep 17 00:00:00 2001 From: Darin Krauss Date: Wed, 2 Apr 2025 12:56:02 -0700 Subject: [PATCH 19/24] Minor updates to fix bugs --- data/store/mongo/mongo_datum.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/data/store/mongo/mongo_datum.go b/data/store/mongo/mongo_datum.go index 5d864b778d..0de7daeb25 100644 --- a/data/store/mongo/mongo_datum.go +++ b/data/store/mongo/mongo_datum.go @@ -214,12 +214,11 @@ func (d *DatumRepository) NewerDataSetData(ctx context.Context, dataSet *upload. selector["_userId"] = dataSet.UserID selector["uploadId"] = dataSet.UploadID - selector["type"] = bson.M{"$ne": "upload"} // Note we WILL keep the "type" field in the UploadId index as that's a query need in tide-whisperer - selector["_active"] = false + selector["_active"] = true selector["deletedTime"] = bson.M{"$exists": false} findOptions := options.Find() - findOptions.SetProjection(bson.M{"_id": 0, "id": 1, "origin.id": 1}) + findOptions.SetProjection(bson.M{"_id": 0, "id": 1, "time": 1, "origin.id": 1, "origin.time": 1}) cursor, err := d.Find(ctx, selector, findOptions) if err != nil { @@ -227,8 +226,8 @@ func (d *DatumRepository) NewerDataSetData(ctx context.Context, dataSet *upload. return nil, fmt.Errorf("unable to get newer data set data selectors: %w", err) } - var newerSelectors *data.Selectors - if err = cursor.All(ctx, &newerSelectors); err != nil { + newerSelectors := data.NewSelectors() + if err = cursor.All(ctx, newerSelectors); err != nil { logger.WithError(err).Error("Unable to decode newer data set data selectors") return nil, fmt.Errorf("unable to decode newer data set data selectors: %w", err) } From ebc8cf6657919bf61c141764fd0dde248c7cfa5d Mon Sep 17 00:00:00 2001 From: Darin Krauss Date: Thu, 3 Apr 2025 14:41:11 -0700 Subject: [PATCH 20/24] Updates based upon PR review --- data/data.go | 4 +- data/data_test.go | 66 ++++++++++++++++++- .../data_set_delete_origin_older.go | 13 +++- data/store/mongo/mongo_datum.go | 3 +- 4 files changed, 81 insertions(+), 5 deletions(-) diff --git a/data/data.go b/data/data.go index b39c5ac8dc..10e1d357a6 100644 --- a/data/data.go +++ b/data/data.go @@ -56,7 +56,7 @@ func (s *SelectorOrigin) Includes(other *SelectorOrigin) bool { return false } else if otherTime, err := time.Parse(time.RFC3339Nano, *other.Time); err != nil || otherTime.IsZero() { // Must parse return false - } else if sTime.After(otherTime) { // Must include + } else if otherTime.Before(sTime) { // Must include return false } else { return true @@ -105,7 +105,7 @@ func (s *Selector) Includes(other *Selector) bool { return false } else if s.ID != nil && (other.ID == nil || *s.ID != *other.ID) { // If id matters, then must include return false - } else if s.Time != nil && (other.Time == nil || s.Time.After(*other.Time)) { // If time matters, then must include + } else if s.Time != nil && (other.Time == nil || other.Time.Before(*s.Time)) { // If time matters, then must include return false } else if s.Origin != nil && (other.Origin == nil || !s.Origin.Includes(other.Origin)) { // If origin matters, then must include return false diff --git a/data/data_test.go b/data/data_test.go index 519cfac856..88a1796b8d 100644 --- a/data/data_test.go +++ b/data/data_test.go @@ -1,19 +1,83 @@ package data_test import ( + "time" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/tidepool-org/platform/data" errorsTest "github.com/tidepool-org/platform/errors/test" + "github.com/tidepool-org/platform/pointer" structureTest "github.com/tidepool-org/platform/structure/test" structureValidator "github.com/tidepool-org/platform/structure/validator" "github.com/tidepool-org/platform/test" ) var _ = Describe("Data", func() { + Context("SelectorOrigin", func() { + Context("Includes", func() { + now := time.Now() + tm := pointer.FromString(now.Format(time.RFC3339Nano)) + id := pointer.FromString(data.NewID()) + + DescribeTable("return the expected results when the selector origins", + func(origin *data.SelectorOrigin, otherOrigin *data.SelectorOrigin, expectedResult bool) { + Expect(origin.Includes(otherOrigin)).To(Equal(expectedResult)) + }, + Entry("both are nil", nil, nil, false), + Entry("origin is nil", nil, &data.SelectorOrigin{}, false), + Entry("other origin is nil", &data.SelectorOrigin{}, nil, false), + Entry("id and time are nil", &data.SelectorOrigin{}, &data.SelectorOrigin{}, true), + Entry("origin id is nil", &data.SelectorOrigin{}, &data.SelectorOrigin{ID: id}, true), + Entry("other origin id is nil", &data.SelectorOrigin{ID: id}, &data.SelectorOrigin{}, false), + Entry("id mismatch", &data.SelectorOrigin{ID: id}, &data.SelectorOrigin{ID: pointer.FromString("mismatch")}, false), + Entry("id includes", &data.SelectorOrigin{ID: id}, &data.SelectorOrigin{ID: id}, true), + Entry("origin time is nil", &data.SelectorOrigin{ID: id}, &data.SelectorOrigin{ID: id, Time: tm}, true), + Entry("other origin time is nil", &data.SelectorOrigin{ID: id, Time: tm}, &data.SelectorOrigin{ID: id}, false), + Entry("time earlier", &data.SelectorOrigin{ID: id, Time: tm}, &data.SelectorOrigin{ID: id, Time: pointer.FromString(now.Add(-time.Hour).Format(time.RFC3339Nano))}, false), + Entry("time same", &data.SelectorOrigin{ID: id, Time: tm}, &data.SelectorOrigin{ID: id, Time: tm}, true), + Entry("time same in different time zone", &data.SelectorOrigin{ID: id, Time: tm}, &data.SelectorOrigin{ID: id, Time: pointer.FromString(now.In(time.FixedZone("Etc/GMT-1", int(-time.Hour.Seconds()))).Format(time.RFC3339Nano))}, true), + Entry("time later", &data.SelectorOrigin{ID: id, Time: tm}, &data.SelectorOrigin{ID: id, Time: pointer.FromString(now.Add(time.Hour).Format(time.RFC3339Nano))}, true), + ) + }) + }) + + Context("Selector", func() { + Context("Includes", func() { + now := time.Now() + tm := pointer.FromTime(now) + id := pointer.FromString(data.NewID()) + originID := pointer.FromString(data.NewID()) + + DescribeTable("return the expected results when the selector origins", + func(origin *data.Selector, otherOrigin *data.Selector, expectedResult bool) { + Expect(origin.Includes(otherOrigin)).To(Equal(expectedResult)) + }, + Entry("both are nil", nil, nil, false), + Entry("selector is nil", nil, &data.Selector{}, false), + Entry("other selector is nil", &data.Selector{}, nil, false), + Entry("id, time, and origin are nil", &data.Selector{}, &data.Selector{}, true), + Entry("selector id is nil", &data.Selector{}, &data.Selector{ID: id}, true), + Entry("other selector id is nil", &data.Selector{ID: id}, &data.Selector{}, false), + Entry("id mismatch", &data.Selector{ID: id}, &data.Selector{ID: pointer.FromString("mismatch")}, false), + Entry("id includes", &data.Selector{ID: id}, &data.Selector{ID: id}, true), + Entry("selector time is nil", &data.Selector{ID: id}, &data.Selector{ID: id, Time: tm}, true), + Entry("other selector time is nil", &data.Selector{ID: id, Time: tm}, &data.Selector{ID: id}, false), + Entry("time earlier", &data.Selector{ID: id, Time: tm}, &data.Selector{ID: id, Time: pointer.FromTime(now.Add(-time.Hour))}, false), + Entry("time same", &data.Selector{ID: id, Time: tm}, &data.Selector{ID: id, Time: tm}, true), + Entry("time same in different time zone", &data.Selector{ID: id, Time: tm}, &data.Selector{ID: id, Time: pointer.FromTime(now.In(time.FixedZone("Etc/GMT-1", int(-time.Hour.Seconds()))))}, true), + Entry("time later", &data.Selector{ID: id, Time: tm}, &data.Selector{ID: id, Time: pointer.FromTime(now.Add(time.Hour))}, true), + Entry("selector origin is nil", &data.Selector{ID: id}, &data.Selector{ID: id, Origin: &data.SelectorOrigin{ID: originID}}, true), + Entry("other selector origin is nil", &data.Selector{ID: id, Origin: &data.SelectorOrigin{ID: originID}}, &data.Selector{ID: id}, false), + Entry("origin id mismatch", &data.Selector{ID: id, Origin: &data.SelectorOrigin{ID: originID}}, &data.Selector{ID: id, Origin: &data.SelectorOrigin{ID: pointer.FromString("mismatch")}}, false), + Entry("origin match", &data.Selector{ID: id, Origin: &data.SelectorOrigin{ID: originID}}, &data.Selector{ID: id, Origin: &data.SelectorOrigin{ID: originID}}, true), + ) + }) + }) + Context("NewID", func() { - It("returns a string of 32 lowercase hexidecimal characters", func() { + It("returns a string of 32 lowercase hexadecimal characters", func() { Expect(data.NewID()).To(MatchRegexp("^[0-9a-f]{32}$")) }) diff --git a/data/deduplicator/deduplicator/data_set_delete_origin_older.go b/data/deduplicator/deduplicator/data_set_delete_origin_older.go index 00dddf7172..d6887c2a13 100644 --- a/data/deduplicator/deduplicator/data_set_delete_origin_older.go +++ b/data/deduplicator/deduplicator/data_set_delete_origin_older.go @@ -43,8 +43,19 @@ func (d *dataSetDeleteOriginOlderProvider) FilterData(ctx context.Context, repos if existingSelectors, err := repository.NewerDataSetData(ctx, dataSet, selectors); err != nil { return nil, err } else if existingSelectors != nil && len(*existingSelectors) > 0 { + existingSelectorsMap := make(map[string]*data.Selector, len(*existingSelectors)) + for _, existingSelector := range *existingSelectors { + if existingSelector != nil && existingSelector.Origin != nil && existingSelector.Origin.ID != nil { + existingSelectorsMap[*existingSelector.Origin.ID] = existingSelector + } + } dataSetData = dataSetData.Filter(func(datum data.Datum) bool { - return !slices.ContainsFunc(*existingSelectors, d.getDatumSelector(datum).Includes) + if datumSelector := d.getDatumSelector(datum); datumSelector != nil && datumSelector.Origin != nil && datumSelector.Origin.ID != nil { + if existingSelector, ok := existingSelectorsMap[*datumSelector.Origin.ID]; ok && existingSelector != nil { + return !datumSelector.Includes(existingSelector) + } + } + return true }) } } diff --git a/data/store/mongo/mongo_datum.go b/data/store/mongo/mongo_datum.go index 0de7daeb25..c724977450 100644 --- a/data/store/mongo/mongo_datum.go +++ b/data/store/mongo/mongo_datum.go @@ -585,10 +585,11 @@ func (d *DatumRepository) UnarchiveDeviceDataUsingHashesFromDataSet(ctx context. return overallErr } -// TODO: Currently does not translate time or origin.time fields. Since origin.time is currently persisted as a string +// FUTURE: Currently does not translate time or origin.time fields. Since origin.time is currently persisted as a string // (and not time.Time) we cannot reliably query for it due to potentially variable timezone offsets. Eventually, migrate // origin.time to time.Time and add additional qualifiers to the database selector that document origin.time must be // greater than or equal to the incoming selector origin.time. For now, we can only query on id and origin.id. +// See: https://tidepool.atlassian.net/browse/BACK-3548 func validateAndTranslateSelectors(ctx context.Context, selectors *data.Selectors) (filter bson.M, hasOriginID bool, err error) { if selectors == nil { return bson.M{}, false, nil From cffbd7a6c9313545e275153d6b3236282b574d7e Mon Sep 17 00:00:00 2001 From: lostlevels Date: Wed, 23 Apr 2025 09:51:12 -0700 Subject: [PATCH 21/24] Put back upload type on deviceDataSets. --- data/store/mongo/mongo_data.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/data/store/mongo/mongo_data.go b/data/store/mongo/mongo_data.go index e8d1484f2e..4076a968af 100644 --- a/data/store/mongo/mongo_data.go +++ b/data/store/mongo/mongo_data.go @@ -88,6 +88,7 @@ func (d *DataRepository) DeleteDataSet(ctx context.Context, dataSet *upload.Uplo selector = bson.M{ "_userId": dataSet.UserID, "uploadId": dataSet.UploadID, + "type": "upload", "deletedTime": bson.M{"$exists": false}, "deletedUserId": bson.M{"$exists": false}, } @@ -143,6 +144,7 @@ func (d *DataRepository) DeleteOtherDataSetData(ctx context.Context, dataSet *up "_userId": dataSet.UserID, "deviceId": *dataSet.DeviceID, "uploadId": bson.M{"$ne": dataSet.UploadID}, + "type": "upload", "deletedTime": bson.M{"$exists": false}, "deletedUserId": bson.M{"$exists": false}, } From 20a1a08de362392679c09a6161f1c59160df976d Mon Sep 17 00:00:00 2001 From: lostlevels Date: Tue, 13 May 2025 09:03:51 -0700 Subject: [PATCH 22/24] Fix index after merge. --- data/store/mongo/mongo_summary.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/store/mongo/mongo_summary.go b/data/store/mongo/mongo_summary.go index eec5ada5a5..b1ca241788 100644 --- a/data/store/mongo/mongo_summary.go +++ b/data/store/mongo/mongo_summary.go @@ -29,11 +29,11 @@ func (d *SummaryRepository) EnsureIndexes() error { Keys: bson.D{ {Key: "type", Value: 1}, {Key: "dates.outdatedSince", Value: 1}, - {Key: "dates.lastUpdatedDate", Value: 1}, {Key: "config.schemaVersion", Value: 1}, + {Key: "dates.lastUpdatedDate", Value: 1}, }, Options: options.Index(). - SetName("OutdatedAndSchemaMigration"), + SetName("OutdatedSinceSchemaLastUpdated"), }, { Keys: bson.D{ From 975865bdb72d0463a1fe98d5ccb52c46898f937a Mon Sep 17 00:00:00 2001 From: lostlevels Date: Tue, 13 May 2025 09:23:26 -0700 Subject: [PATCH 23/24] Fix tests. --- data/store/mongo/mongo_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/store/mongo/mongo_test.go b/data/store/mongo/mongo_test.go index 08b647e616..4f0c121142 100644 --- a/data/store/mongo/mongo_test.go +++ b/data/store/mongo/mongo_test.go @@ -416,9 +416,9 @@ var _ = Describe("Mongo", Label("mongodb", "slow", "integration"), func() { "Name": Equal("UserIDTypeUnique"), }), MatchFields(IgnoreExtras, Fields{ - "Key": Equal(storeStructuredMongoTest.MakeKeySlice("type", "dates.outdatedSince", "dates.lastUpdatedDate", "config.schemaVersion")), + "Key": Equal(storeStructuredMongoTest.MakeKeySlice("type", "dates.outdatedSince", "config.schemaVersion", "dates.lastUpdatedDate")), "Background": Equal(false), - "Name": Equal("OutdatedAndSchemaMigration"), + "Name": Equal("OutdatedSinceSchemaLastUpdated"), }), MatchFields(IgnoreExtras, Fields{ "Key": Equal(storeStructuredMongoTest.MakeKeySlice("type", "dates.outdatedSince", "dates.lastUpdatedDate", "config.schemaVersion")), From 2fa84f34875deb2dbf6945d1a534f85709d33576 Mon Sep 17 00:00:00 2001 From: lostlevels Date: Tue, 13 May 2025 15:24:43 -0700 Subject: [PATCH 24/24] Don't log provenance error. --- data/service/api/v1/datasets_data_create.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data/service/api/v1/datasets_data_create.go b/data/service/api/v1/datasets_data_create.go index 9339b445c9..cc5e56d8f5 100644 --- a/data/service/api/v1/datasets_data_create.go +++ b/data/service/api/v1/datasets_data_create.go @@ -149,7 +149,8 @@ func CollectProvenanceInfo(ctx context.Context, req *rest.Request, authDetails r if token != "" && shouldHaveJWT(authDetails) { claims := &TokenClaims{} if _, _, err := jwt.NewParser().ParseUnverified(token, claims); err != nil { - lgr.WithError(err).Warn("Unable to parse access token for provenance") + // temp comment out because makes realtime viewing rough + // lgr.WithError(err).Warn("Unable to parse access token for provenance") } else { provenance.ClientID = claims.ClientID }