From aaca6d8987b2a9aa75abf2f3f7c6c9b44c8a2f04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frank=20Schr=C3=B6der?= Date: Thu, 27 Jan 2022 07:24:48 +0100 Subject: [PATCH 1/6] client: add missing WithContext methods --- client.go | 10 +++++++++- subscription.go | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/client.go b/client.go index f6c9b289..31ac35b1 100644 --- a/client.go +++ b/client.go @@ -552,12 +552,20 @@ func (c *Client) Dial(ctx context.Context) error { } // Close closes the session and the secure channel. +// +// Note: Starting with v0.5 this method will require a context +// and the corresponding XXXWithContext(ctx) method will be removed. func (c *Client) Close() error { + return c.CloseWithContext(context.Background()) +} + +// Note: Starting with v0.5 this method is superseded by the non 'WithContext' method. +func (c *Client) CloseWithContext(ctx context.Context) error { stats.Client().Add("Close", 1) // try to close the session but ignore any error // so that we close the underlying channel and connection. - c.CloseSession() + c.CloseSessionWithContext(ctx) c.setState(Closed) if c.mcancel != nil { diff --git a/subscription.go b/subscription.go index 73062e60..de87f41e 100644 --- a/subscription.go +++ b/subscription.go @@ -289,13 +289,21 @@ func (s *Subscription) notify(ctx context.Context, data *PublishNotificationData } // Stats returns a diagnostic struct with metadata about the current subscription +// +// Note: Starting with v0.5 this method will require a context +// and the corresponding XXXWithContext(ctx) method will be removed. func (s *Subscription) Stats() (*ua.SubscriptionDiagnosticsDataType, error) { + return s.StatsWithContext(context.Background()) +} + +// Note: Starting with v0.5 this method is superseded by the non 'WithContext' method. +func (s *Subscription) StatsWithContext(ctx context.Context) (*ua.SubscriptionDiagnosticsDataType, error) { // TODO(kung-foo): once browsing feature is merged, attempt to get direct access to the // diagnostics node. for example, Prosys lists them like: // i=2290/ns=1;g=918ee6f4-2d25-4506-980d-e659441c166d // maybe cache the nodeid to speed up future stats queries node := s.c.Node(ua.NewNumericNodeID(0, id.Server_ServerDiagnostics_SubscriptionDiagnosticsArray)) - v, err := node.Value() + v, err := node.ValueWithContext(ctx) if err != nil { return nil, err } From 50419c12cc4db5e264d6ad48d2a2e0faa8a2fc6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frank=20Schr=C3=B6der?= Date: Thu, 27 Jan 2022 07:25:01 +0100 Subject: [PATCH 2/6] monitor: add missing WithContext methods --- monitor/subscription.go | 82 +++++++++++++++++++++++++++++++++-------- 1 file changed, 67 insertions(+), 15 deletions(-) diff --git a/monitor/subscription.go b/monitor/subscription.go index 4eec9174..58698859 100644 --- a/monitor/subscription.go +++ b/monitor/subscription.go @@ -88,7 +88,7 @@ func NewNodeMonitor(client *opcua.Client) (*NodeMonitor, error) { return m, nil } -func newSubscription(m *NodeMonitor, params *opcua.SubscriptionParameters, notifyChanLength int, nodes ...string) (*Subscription, error) { +func newSubscription(ctx context.Context, m *NodeMonitor, params *opcua.SubscriptionParameters, notifyChanLength int, nodes ...string) (*Subscription, error) { if params == nil { params = &opcua.SubscriptionParameters{} } @@ -102,11 +102,11 @@ func newSubscription(m *NodeMonitor, params *opcua.SubscriptionParameters, notif } var err error - if s.sub, err = m.client.Subscribe(params, s.internalNotifyCh); err != nil { + if s.sub, err = m.client.SubscribeWithContext(ctx, params, s.internalNotifyCh); err != nil { return nil, err } - if err = s.AddNodes(nodes...); err != nil { + if err = s.AddNodesWithContext(ctx, nodes...); err != nil { return nil, err } @@ -122,7 +122,7 @@ func (m *NodeMonitor) SetErrorHandler(cb ErrHandler) { // The caller must call `Unsubscribe` to stop and clean up resources. Canceling the context // will also cause the subscription to stop, but `Unsubscribe` must still be called. func (m *NodeMonitor) Subscribe(ctx context.Context, params *opcua.SubscriptionParameters, cb MsgHandler, nodes ...string) (*Subscription, error) { - sub, err := newSubscription(m, params, DefaultCallbackBufferLen, nodes...) + sub, err := newSubscription(ctx, m, params, DefaultCallbackBufferLen, nodes...) if err != nil { return nil, err } @@ -138,7 +138,7 @@ func (m *NodeMonitor) Subscribe(ctx context.Context, params *opcua.SubscriptionP // The caller must call `Unsubscribe` to stop and clean up resources. Canceling the context // will also cause the subscription to stop, but `Unsubscribe` must still be called. func (m *NodeMonitor) ChanSubscribe(ctx context.Context, params *opcua.SubscriptionParameters, ch chan<- *DataChangeMessage, nodes ...string) (*Subscription, error) { - sub, err := newSubscription(m, params, 16, nodes...) + sub, err := newSubscription(ctx, m, params, 16, nodes...) if err != nil { return nil, err } @@ -254,17 +254,32 @@ func (s *Subscription) Dropped() uint64 { } // AddNodes adds nodes defined by their string representation +// +// Note: Starting with v0.5 this method will require a context +// and the corresponding XXXWithContext(ctx) method will be removed. func (s *Subscription) AddNodes(nodes ...string) error { + return s.AddNodesWithContext(context.Background(), nodes...) +} +// Note: Starting with v0.5 this method is superseded by the non 'WithContext' method. +func (s *Subscription) AddNodesWithContext(ctx context.Context, nodes ...string) error { nodeIDs, err := parseNodeSlice(nodes...) if err != nil { return err } - return s.AddNodeIDs(nodeIDs...) + return s.AddNodeIDsWithContext(ctx, nodeIDs...) } // AddNodeIDs adds nodes +// +// Note: Starting with v0.5 this method will require a context +// and the corresponding XXXWithContext(ctx) method will be removed. func (s *Subscription) AddNodeIDs(nodes ...*ua.NodeID) error { + return s.AddNodeIDsWithContext(context.Background(), nodes...) +} + +// Note: Starting with v0.5 this method is superseded by the non 'WithContext' method. +func (s *Subscription) AddNodeIDsWithContext(ctx context.Context, nodes ...*ua.NodeID) error { requests := make([]Request, len(nodes)) for i, node := range nodes { @@ -273,12 +288,20 @@ func (s *Subscription) AddNodeIDs(nodes ...*ua.NodeID) error { MonitoringMode: ua.MonitoringModeReporting, } } - _, err := s.AddMonitorItems(requests...) + _, err := s.AddMonitorItemsWithContext(ctx, requests...) return err } // AddMonitorItems adds nodes with monitoring parameters to the subscription +// +// Note: Starting with v0.5 this method will require a context +// and the corresponding XXXWithContext(ctx) method will be removed. func (s *Subscription) AddMonitorItems(nodes ...Request) ([]Item, error) { + return s.AddMonitorItemsWithContext(context.Background(), nodes...) +} + +// Note: Starting with v0.5 this method is superseded by the non 'WithContext' method. +func (s *Subscription) AddMonitorItemsWithContext(ctx context.Context, nodes ...Request) ([]Item, error) { s.mu.Lock() defer s.mu.Unlock() @@ -305,7 +328,7 @@ func (s *Subscription) AddMonitorItems(nodes ...Request) ([]Item, error) { } toAdd = append(toAdd, request) } - resp, err := s.sub.Monitor(ua.TimestampsToReturnBoth, toAdd...) + resp, err := s.sub.MonitorWithContext(ctx, ua.TimestampsToReturnBoth, toAdd...) if err != nil { return nil, err } @@ -335,22 +358,37 @@ func (s *Subscription) AddMonitorItems(nodes ...Request) ([]Item, error) { } // RemoveNodes removes nodes defined by their string representation +// +// Note: Starting with v0.5 this method will require a context +// and the corresponding XXXWithContext(ctx) method will be removed. func (s *Subscription) RemoveNodes(nodes ...string) error { + return s.RemoveNodesWithContext(context.Background(), nodes...) +} + +// Note: Starting with v0.5 this method is superseded by the non 'WithContext' method. +func (s *Subscription) RemoveNodesWithContext(ctx context.Context, nodes ...string) error { nodeIDs, err := parseNodeSlice(nodes...) if err != nil { return err } - return s.RemoveNodeIDs(nodeIDs...) + return s.RemoveNodeIDsWithContext(ctx, nodeIDs...) } // RemoveNodeIDs removes nodes +// +// Note: Starting with v0.5 this method will require a context +// and the corresponding XXXWithContext(ctx) method will be removed. func (s *Subscription) RemoveNodeIDs(nodes ...*ua.NodeID) error { + return s.RemoveNodeIDsWithContext(context.Background(), nodes...) +} + +// Note: Starting with v0.5 this method is superseded by the non 'WithContext' method. +func (s *Subscription) RemoveNodeIDsWithContext(ctx context.Context, nodes ...*ua.NodeID) error { if len(nodes) == 0 { return nil } var toRemove []Item - for _, node := range nodes { for _, item := range s.itemLookup { if item.nodeID.String() == node.String() { @@ -360,11 +398,19 @@ func (s *Subscription) RemoveNodeIDs(nodes ...*ua.NodeID) error { } } - return s.RemoveMonitorItems(toRemove...) + return s.RemoveMonitorItemsWithContext(ctx, toRemove...) } // RemoveMonitorItems removes nodes +// +// Note: Starting with v0.5 this method will require a context +// and the corresponding XXXWithContext(ctx) method will be removed. func (s *Subscription) RemoveMonitorItems(items ...Item) error { + return s.RemoveMonitorItemsWithContext(context.Background()) +} + +// Note: Starting with v0.5 this method is superseded by the non 'WithContext' method. +func (s *Subscription) RemoveMonitorItemsWithContext(ctx context.Context, items ...Item) error { s.mu.Lock() defer s.mu.Unlock() @@ -373,9 +419,7 @@ func (s *Subscription) RemoveMonitorItems(items ...Item) error { } var toRemove []uint32 - for _, item := range items { - _, ok := s.itemLookup[item.id] if !ok { return errors.Errorf("item not found: %s", item.id) @@ -385,7 +429,7 @@ func (s *Subscription) RemoveMonitorItems(items ...Item) error { toRemove = append(toRemove, item.id) } - resp, err := s.sub.Unmonitor(toRemove...) + resp, err := s.sub.UnmonitorWithContext(ctx, toRemove...) if err != nil { return err } @@ -408,8 +452,16 @@ func (s *Subscription) RemoveMonitorItems(items ...Item) error { } // Stats returns statistics for the subscription +// +// Note: Starting with v0.5 this method will require a context +// and the corresponding XXXWithContext(ctx) method will be removed. func (s *Subscription) Stats() (*ua.SubscriptionDiagnosticsDataType, error) { - return s.sub.Stats() + return s.StatsWithContext(context.Background()) +} + +// Note: Starting with v0.5 this method is superseded by the non 'WithContext' method. +func (s *Subscription) StatsWithContext(ctx context.Context) (*ua.SubscriptionDiagnosticsDataType, error) { + return s.sub.StatsWithContext(ctx) } func parseNodeSlice(nodes ...string) ([]*ua.NodeID, error) { From 3b9868f9b2d685c4e86acb466ad87fca61137056 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frank=20Schr=C3=B6der?= Date: Thu, 27 Jan 2022 07:27:52 +0100 Subject: [PATCH 3/6] client: use context --- client.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client.go b/client.go index 31ac35b1..1ab9e14d 100644 --- a/client.go +++ b/client.go @@ -34,7 +34,7 @@ func GetEndpoints(ctx context.Context, endpoint string, opts ...Option) ([]*ua.E if err := c.Dial(ctx); err != nil { return nil, err } - defer c.Close() + defer c.CloseWithContext(ctx) res, err := c.GetEndpointsWithContext(ctx) if err != nil { return nil, err @@ -195,14 +195,14 @@ func (c *Client) Connect(ctx context.Context) (err error) { s, err := c.CreateSessionWithContext(ctx, c.cfg.session) if err != nil { - c.Close() + c.CloseWithContext(ctx) stats.RecordError(err) return err } if err := c.ActivateSessionWithContext(ctx, s); err != nil { - c.Close() + c.CloseWithContext(ctx) stats.RecordError(err) return err @@ -221,7 +221,7 @@ func (c *Client) Connect(ctx context.Context) (err error) { // todo(fs): see the discussion in https://github.com/gopcua/opcua/pull/512 // todo(fs): and you should find a commit that implements this option. if err := c.UpdateNamespacesWithContext(ctx); err != nil { - c.Close() + c.CloseWithContext(ctx) stats.RecordError(err) return err From 73ac88ca9d2bfbacc89d33dcc29b6fa43c7c596c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frank=20Schr=C3=B6der?= Date: Thu, 27 Jan 2022 07:28:07 +0100 Subject: [PATCH 4/6] examples: use context --- examples/crypto/crypto.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/crypto/crypto.go b/examples/crypto/crypto.go index ef80c304..f8029f31 100644 --- a/examples/crypto/crypto.go +++ b/examples/crypto/crypto.go @@ -16,12 +16,12 @@ import ( "strings" "syscall" + "golang.org/x/crypto/ssh/terminal" + "github.com/gopcua/opcua" "github.com/gopcua/opcua/debug" "github.com/gopcua/opcua/errors" "github.com/gopcua/opcua/ua" - - "golang.org/x/crypto/ssh/terminal" ) var ( @@ -68,7 +68,7 @@ func main() { defer c.CloseSessionWithContext(ctx) // Use our connection (read the server's time) - v, err := c.Node(ua.NewNumericNodeID(0, 2258)).Value() + v, err := c.Node(ua.NewNumericNodeID(0, 2258)).ValueWithContext(ctx) if err != nil { log.Fatal(err) } @@ -79,7 +79,7 @@ func main() { } // Detach our session and try re-establish it on a different secure channel - s, err := c.DetachSession() + s, err := c.DetachSessionWithContext(ctx) if err != nil { log.Fatalf("Error detaching session: %s", err) } @@ -88,16 +88,16 @@ func main() { // Create a channel only and do not activate it automatically d.Dial(ctx) - defer d.Close() + defer d.CloseWithContext(ctx) // Activate the previous session on the new channel - err = d.ActivateSession(s) + err = d.ActivateSessionWithContext(ctx, s) if err != nil { log.Fatalf("Error reactivating session: %s", err) } // Read the time again to prove our session is still OK - v, err = d.Node(ua.NewNumericNodeID(0, 2258)).Value() + v, err = d.Node(ua.NewNumericNodeID(0, 2258)).ValueWithContext(ctx) if err != nil { log.Fatal(err) } From e3a606e8b67a329906549186d50cad3941871d13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frank=20Schr=C3=B6der?= Date: Thu, 27 Jan 2022 07:37:39 +0100 Subject: [PATCH 5/6] uatest: use context --- uatest/method_test.go | 8 +++++--- uatest/namespace_test.go | 12 ++++++----- uatest/read_test.go | 33 ++++++++++++++++-------------- uatest/read_unknow_node_id_test.go | 8 +++++--- uatest/reconnection_test.go | 9 ++++---- uatest/stats_test.go | 9 +++++--- uatest/write_test.go | 15 ++++++++------ 7 files changed, 55 insertions(+), 39 deletions(-) diff --git a/uatest/method_test.go b/uatest/method_test.go index fe5e565e..e9e00da6 100644 --- a/uatest/method_test.go +++ b/uatest/method_test.go @@ -54,18 +54,20 @@ func TestCallMethod(t *testing.T) { }, } + ctx := context.Background() + srv := NewServer("method_server.py") defer srv.Close() c := opcua.NewClient(srv.Endpoint, srv.Opts...) - if err := c.Connect(context.Background()); err != nil { + if err := c.Connect(ctx); err != nil { t.Fatal(err) } - defer c.Close() + defer c.CloseWithContext(ctx) for _, tt := range tests { t.Run(tt.req.ObjectID.String(), func(t *testing.T) { - resp, err := c.Call(tt.req) + resp, err := c.CallWithContext(ctx, tt.req) if err != nil { t.Fatal(err) } diff --git a/uatest/namespace_test.go b/uatest/namespace_test.go index c97f67ed..cb74f813 100644 --- a/uatest/namespace_test.go +++ b/uatest/namespace_test.go @@ -13,17 +13,19 @@ import ( ) func TestNamespace(t *testing.T) { + ctx := context.Background() + srv := NewServer("rw_server.py") defer srv.Close() c := opcua.NewClient(srv.Endpoint, srv.Opts...) - if err := c.Connect(context.Background()); err != nil { + if err := c.Connect(ctx); err != nil { t.Fatal(err) } - defer c.Close() + defer c.CloseWithContext(ctx) t.Run("NamespaceArray", func(t *testing.T) { - got, err := c.NamespaceArray() + got, err := c.NamespaceArrayWithContext(ctx) if err != nil { t.Fatal(err) } @@ -35,7 +37,7 @@ func TestNamespace(t *testing.T) { verify.Values(t, "", got, want) }) t.Run("FindNamespace", func(t *testing.T) { - ns, err := c.FindNamespace("http://gopcua.com/") + ns, err := c.FindNamespaceWithContext(ctx, "http://gopcua.com/") if err != nil { t.Fatal(err) } @@ -44,7 +46,7 @@ func TestNamespace(t *testing.T) { } }) t.Run("UpdateNamespaces", func(t *testing.T) { - err := c.UpdateNamespaces() + err := c.UpdateNamespacesWithContext(ctx) if err != nil { t.Fatal(err) } diff --git a/uatest/read_test.go b/uatest/read_test.go index eb09c56e..e14a732d 100644 --- a/uatest/read_test.go +++ b/uatest/read_test.go @@ -7,9 +7,10 @@ import ( "context" "testing" + "github.com/pascaldekloe/goe/verify" + "github.com/gopcua/opcua" "github.com/gopcua/opcua/ua" - "github.com/pascaldekloe/goe/verify" ) // TestRead performs an integration test to read values @@ -27,31 +28,33 @@ func TestRead(t *testing.T) { {ua.NewStringNodeID(2, "2d_array_int32"), [][]int32{{1}, {2}, {3}}}, } + ctx := context.Background() + srv := NewServer("rw_server.py") defer srv.Close() c := opcua.NewClient(srv.Endpoint, srv.Opts...) - if err := c.Connect(context.Background()); err != nil { + if err := c.Connect(ctx); err != nil { t.Fatal(err) } - defer c.Close() + defer c.CloseWithContext(ctx) for _, tt := range tests { t.Run(tt.id.String(), func(t *testing.T) { t.Run("Read", func(t *testing.T) { - testRead(t, c, tt.v, tt.id) + testRead(t, ctx, c, tt.v, tt.id) }) t.Run("RegisteredRead", func(t *testing.T) { - testRegisteredRead(t, c, tt.v, tt.id) + testRegisteredRead(t, ctx, c, tt.v, tt.id) }) }) } } -func testRead(t *testing.T, c *opcua.Client, v interface{}, id *ua.NodeID) { +func testRead(t *testing.T, ctx context.Context, c *opcua.Client, v interface{}, id *ua.NodeID) { t.Helper() - resp, err := c.Read(&ua.ReadRequest{ + resp, err := c.ReadWithContext(ctx, &ua.ReadRequest{ NodesToRead: []*ua.ReadValueID{ &ua.ReadValueID{NodeID: id}, }, @@ -68,23 +71,23 @@ func testRead(t *testing.T, c *opcua.Client, v interface{}, id *ua.NodeID) { } } -func testRegisteredRead(t *testing.T, c *opcua.Client, v interface{}, id *ua.NodeID) { +func testRegisteredRead(t *testing.T, ctx context.Context, c *opcua.Client, v interface{}, id *ua.NodeID) { t.Helper() - resp, err := c.RegisterNodes(&ua.RegisterNodesRequest{ + resp, err := c.RegisterNodesWithContext(ctx, &ua.RegisterNodesRequest{ NodesToRegister: []*ua.NodeID{id}, }) if err != nil { t.Fatalf("RegisterNodes failed: %s", err) } - testRead(t, c, v, resp.RegisteredNodeIDs[0]) - testRead(t, c, v, resp.RegisteredNodeIDs[0]) - testRead(t, c, v, resp.RegisteredNodeIDs[0]) - testRead(t, c, v, resp.RegisteredNodeIDs[0]) - testRead(t, c, v, resp.RegisteredNodeIDs[0]) + testRead(t, ctx, c, v, resp.RegisteredNodeIDs[0]) + testRead(t, ctx, c, v, resp.RegisteredNodeIDs[0]) + testRead(t, ctx, c, v, resp.RegisteredNodeIDs[0]) + testRead(t, ctx, c, v, resp.RegisteredNodeIDs[0]) + testRead(t, ctx, c, v, resp.RegisteredNodeIDs[0]) - _, err = c.UnregisterNodes(&ua.UnregisterNodesRequest{ + _, err = c.UnregisterNodesWithContext(ctx, &ua.UnregisterNodesRequest{ NodesToUnregister: []*ua.NodeID{id}, }) if err != nil { diff --git a/uatest/read_unknow_node_id_test.go b/uatest/read_unknow_node_id_test.go index ed11aba7..a9b27b85 100644 --- a/uatest/read_unknow_node_id_test.go +++ b/uatest/read_unknow_node_id_test.go @@ -15,14 +15,16 @@ import ( // TestRead performs an integration test to read values // from an OPC/UA server. func TestReadUnknowNodeID(t *testing.T) { + ctx := context.Background() + srv := NewServer("read_unknow_node_id_server.py") defer srv.Close() c := opcua.NewClient(srv.Endpoint, srv.Opts...) - if err := c.Connect(context.Background()); err != nil { + if err := c.Connect(ctx); err != nil { t.Fatal(err) } - defer c.Close() + defer c.CloseWithContext(ctx) // read node with unknown extension object // This should be OK @@ -41,7 +43,7 @@ func TestReadUnknowNodeID(t *testing.T) { } // check that the connection is still usable by reading another node. - _, err = c.Read(&ua.ReadRequest{ + _, err = c.ReadWithContext(ctx, &ua.ReadRequest{ NodesToRead: []*ua.ReadValueID{ { NodeID: ua.NewNumericNodeID(0, id.Server_ServerStatus_State), diff --git a/uatest/reconnection_test.go b/uatest/reconnection_test.go index ccfaaf9a..f16f5ff7 100644 --- a/uatest/reconnection_test.go +++ b/uatest/reconnection_test.go @@ -22,22 +22,23 @@ const ( // TestAutoReconnection performs an integration test the auto reconnection // from an OPC/UA server. func TestAutoReconnection(t *testing.T) { + ctx := context.Background() srv := NewServer("reconnection_server.py") defer srv.Close() c := opcua.NewClient(srv.Endpoint, srv.Opts...) - if err := c.Connect(context.Background()); err != nil { + if err := c.Connect(ctx); err != nil { t.Fatal(err) } - defer c.Close() + defer c.CloseWithContext(ctx) m, err := monitor.NewNodeMonitor(c) if err != nil { t.Fatal(err) } - ctx, cancel := context.WithCancel(context.Background()) + ctx, cancel := context.WithCancel(ctx) defer cancel() tests := []struct { @@ -102,7 +103,7 @@ func TestAutoReconnection(t *testing.T) { downC := make(chan struct{}, 1) dTimeout := time.NewTimer(disconnectTimeout) - go c.Call(tt.req) + go c.CallWithContext(ctx, tt.req) ctx, cancel := context.WithCancel(context.Background()) go func() { diff --git a/uatest/stats_test.go b/uatest/stats_test.go index 20ffcf22..89bd3468 100644 --- a/uatest/stats_test.go +++ b/uatest/stats_test.go @@ -8,9 +8,10 @@ import ( "expvar" "testing" + "github.com/pascaldekloe/goe/verify" + "github.com/gopcua/opcua" "github.com/gopcua/opcua/stats" - "github.com/pascaldekloe/goe/verify" ) func newExpVarInt(i int64) *expvar.Int { @@ -22,15 +23,17 @@ func newExpVarInt(i int64) *expvar.Int { func TestStats(t *testing.T) { stats.Reset() + ctx := context.Background() + srv := NewServer("rw_server.py") defer srv.Close() c := opcua.NewClient(srv.Endpoint, srv.Opts...) - if err := c.Connect(context.Background()); err != nil { + if err := c.Connect(ctx); err != nil { t.Fatal(err) } - c.Close() + c.CloseWithContext(ctx) want := map[string]*expvar.Int{ "Dial": newExpVarInt(1), diff --git a/uatest/write_test.go b/uatest/write_test.go index 69200925..a4ffa5f7 100644 --- a/uatest/write_test.go +++ b/uatest/write_test.go @@ -1,3 +1,4 @@ +//go:build integration // +build integration package uatest @@ -26,18 +27,20 @@ func TestWrite(t *testing.T) { {ua.NewStringNodeID(2, "ro_bool"), false, ua.StatusBadUserAccessDenied}, } + ctx := context.Background() + srv := NewServer("rw_server.py") defer srv.Close() c := opcua.NewClient(srv.Endpoint, srv.Opts...) - if err := c.Connect(context.Background()); err != nil { + if err := c.Connect(ctx); err != nil { t.Fatal(err) } - defer c.Close() + defer c.CloseWithContext(ctx) for _, tt := range tests { t.Run(tt.id.String(), func(t *testing.T) { - testWrite(t, c, tt.status, &ua.WriteRequest{ + testWrite(t, ctx, c, tt.status, &ua.WriteRequest{ NodesToWrite: []*ua.WriteValue{ &ua.WriteValue{ NodeID: tt.id, @@ -55,15 +58,15 @@ func TestWrite(t *testing.T) { return } - testRead(t, c, tt.v, tt.id) + testRead(t, ctx, c, tt.v, tt.id) }) } } -func testWrite(t *testing.T, c *opcua.Client, status ua.StatusCode, req *ua.WriteRequest) { +func testWrite(t *testing.T, ctx context.Context, c *opcua.Client, status ua.StatusCode, req *ua.WriteRequest) { t.Helper() - resp, err := c.Write(req) + resp, err := c.WriteWithContext(ctx, req) if err != nil { t.Fatalf("Write failed: %s", err) } From 17436a2afe0a2aa841e8ec57c97ea581889324e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frank=20Schr=C3=B6der?= Date: Thu, 27 Jan 2022 07:42:10 +0100 Subject: [PATCH 6/6] examples: use correct close method --- examples/accesslevel/accesslevel.go | 2 +- examples/browse/browse.go | 2 +- examples/crypto/crypto.go | 2 +- examples/datetime/datetime.go | 2 +- examples/history-read/history-read.go | 2 +- examples/method/method.go | 2 +- examples/monitor/monitor.go | 2 +- examples/read/read.go | 2 +- examples/regread/regread.go | 2 +- examples/subscribe/subscribe.go | 2 +- examples/translate/translate.go | 2 +- examples/trigger/trigger.go | 2 +- examples/udt/udt.go | 2 +- examples/write/write.go | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/examples/accesslevel/accesslevel.go b/examples/accesslevel/accesslevel.go index d28a7d66..fad940ee 100644 --- a/examples/accesslevel/accesslevel.go +++ b/examples/accesslevel/accesslevel.go @@ -29,7 +29,7 @@ func main() { if err := c.Connect(ctx); err != nil { log.Fatal(err) } - defer c.CloseSessionWithContext(ctx) + defer c.CloseWithContext(ctx) id, err := ua.ParseNodeID(*nodeID) if err != nil { diff --git a/examples/browse/browse.go b/examples/browse/browse.go index 3e564a4e..68678650 100644 --- a/examples/browse/browse.go +++ b/examples/browse/browse.go @@ -178,7 +178,7 @@ func main() { if err := c.Connect(ctx); err != nil { log.Fatal(err) } - defer c.CloseSessionWithContext(ctx) + defer c.CloseWithContext(ctx) id, err := ua.ParseNodeID(*nodeID) if err != nil { diff --git a/examples/crypto/crypto.go b/examples/crypto/crypto.go index f8029f31..9a48ce7b 100644 --- a/examples/crypto/crypto.go +++ b/examples/crypto/crypto.go @@ -65,7 +65,7 @@ func main() { if err := c.Connect(ctx); err != nil { log.Fatal(err) } - defer c.CloseSessionWithContext(ctx) + defer c.CloseWithContext(ctx) // Use our connection (read the server's time) v, err := c.Node(ua.NewNumericNodeID(0, 2258)).ValueWithContext(ctx) diff --git a/examples/datetime/datetime.go b/examples/datetime/datetime.go index 88a865d0..59a22f33 100644 --- a/examples/datetime/datetime.go +++ b/examples/datetime/datetime.go @@ -51,7 +51,7 @@ func main() { if err := c.Connect(ctx); err != nil { log.Fatal(err) } - defer c.CloseSessionWithContext(ctx) + defer c.CloseWithContext(ctx) v, err := c.Node(ua.NewNumericNodeID(0, 2258)).ValueWithContext(ctx) switch { diff --git a/examples/history-read/history-read.go b/examples/history-read/history-read.go index 2fed4a28..e514ddc5 100644 --- a/examples/history-read/history-read.go +++ b/examples/history-read/history-read.go @@ -28,7 +28,7 @@ func main() { if err := c.Connect(ctx); err != nil { log.Fatal(err) } - defer c.CloseSessionWithContext(ctx) + defer c.CloseWithContext(ctx) id, err := ua.ParseNodeID(*nodeID) if err != nil { diff --git a/examples/method/method.go b/examples/method/method.go index b1cf17d7..34dc47d0 100644 --- a/examples/method/method.go +++ b/examples/method/method.go @@ -28,7 +28,7 @@ func main() { if err := c.Connect(ctx); err != nil { log.Fatal(err) } - defer c.CloseSessionWithContext(ctx) + defer c.CloseWithContext(ctx) in := int64(12) req := &ua.CallMethodRequest{ diff --git a/examples/monitor/monitor.go b/examples/monitor/monitor.go index 4e4118ac..581d629b 100644 --- a/examples/monitor/monitor.go +++ b/examples/monitor/monitor.go @@ -68,7 +68,7 @@ func main() { log.Fatal(err) } - defer c.CloseSessionWithContext(ctx) + defer c.CloseWithContext(ctx) m, err := monitor.NewNodeMonitor(c) if err != nil { diff --git a/examples/read/read.go b/examples/read/read.go index 2e5beac5..27716c91 100644 --- a/examples/read/read.go +++ b/examples/read/read.go @@ -29,7 +29,7 @@ func main() { if err := c.Connect(ctx); err != nil { log.Fatal(err) } - defer c.CloseSessionWithContext(ctx) + defer c.CloseWithContext(ctx) id, err := ua.ParseNodeID(*nodeID) if err != nil { diff --git a/examples/regread/regread.go b/examples/regread/regread.go index db5d1da7..dd86c401 100644 --- a/examples/regread/regread.go +++ b/examples/regread/regread.go @@ -29,7 +29,7 @@ func main() { if err := c.Connect(ctx); err != nil { log.Fatal(err) } - defer c.CloseSessionWithContext(ctx) + defer c.CloseWithContext(ctx) id, err := ua.ParseNodeID(*nodeID) if err != nil { diff --git a/examples/subscribe/subscribe.go b/examples/subscribe/subscribe.go index 006cd65f..47ddc9b6 100644 --- a/examples/subscribe/subscribe.go +++ b/examples/subscribe/subscribe.go @@ -62,7 +62,7 @@ func main() { if err := c.Connect(ctx); err != nil { log.Fatal(err) } - defer c.CloseSessionWithContext(ctx) + defer c.CloseWithContext(ctx) notifyCh := make(chan *opcua.PublishNotificationData) diff --git a/examples/translate/translate.go b/examples/translate/translate.go index ad4b669b..91c8cdbe 100644 --- a/examples/translate/translate.go +++ b/examples/translate/translate.go @@ -31,7 +31,7 @@ func main() { if err := c.Connect(ctx); err != nil { log.Fatal(err) } - defer c.CloseSessionWithContext(ctx) + defer c.CloseWithContext(ctx) root := c.Node(ua.NewTwoByteNodeID(id.ObjectsFolder)) nodeID, err := root.TranslateBrowsePathInNamespaceToNodeIDWithContext(ctx, uint16(*ns), *nodePath) diff --git a/examples/trigger/trigger.go b/examples/trigger/trigger.go index 2cc37293..5502272d 100644 --- a/examples/trigger/trigger.go +++ b/examples/trigger/trigger.go @@ -63,7 +63,7 @@ func main() { if err := c.Connect(ctx); err != nil { log.Fatal(err) } - defer c.CloseSessionWithContext(ctx) + defer c.CloseWithContext(ctx) notifyCh := make(chan *opcua.PublishNotificationData) diff --git a/examples/udt/udt.go b/examples/udt/udt.go index 7cba5163..a67fc846 100644 --- a/examples/udt/udt.go +++ b/examples/udt/udt.go @@ -59,7 +59,7 @@ func main() { if err := c.Connect(ctx); err != nil { log.Fatal(err) } - defer c.CloseSessionWithContext(ctx) + defer c.CloseWithContext(ctx) v, err := c.Node(id).ValueWithContext(ctx) switch { diff --git a/examples/write/write.go b/examples/write/write.go index 1521a6c2..1b3ae6c2 100644 --- a/examples/write/write.go +++ b/examples/write/write.go @@ -30,7 +30,7 @@ func main() { if err := c.Connect(ctx); err != nil { log.Fatal(err) } - defer c.CloseSessionWithContext(ctx) + defer c.CloseWithContext(ctx) id, err := ua.ParseNodeID(*nodeID) if err != nil {