-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathdevice_rpc_offline_provide_test.go
More file actions
138 lines (121 loc) · 4.3 KB
/
Copy pathdevice_rpc_offline_provide_test.go
File metadata and controls
138 lines (121 loc) · 4.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package sdk
import (
"context"
"testing"
"time"
"github.com/urnetwork/connect"
)
type testOfflineProvideListener struct {
modes chan ProvideMode
enabled chan bool
keys chan *ProvideSecretKeyList
}
func (self *testOfflineProvideListener) ProvideModeChanged(provideMode ProvideMode) {
select {
case self.modes <- provideMode:
default:
}
}
func (self *testOfflineProvideListener) ProvideChanged(provideEnabled bool) {
select {
case self.enabled <- provideEnabled:
default:
}
}
func (self *testOfflineProvideListener) ProvideSecretKeysChanged(provideSecretKeyList *ProvideSecretKeyList) {
select {
case self.keys <- provideSecretKeyList:
default:
}
}
// TestDeviceRemoteOfflineProvideState covers the rpc-disconnected paths: with
// no service, the queued control mode must OWN the derived provide mode and
// enabled state (ProvideMode is a bit set — per-case, never ranges), setters
// must fire the local listeners with the derived values, and loading provide
// secret keys must announce them locally (the ui's has-network-key signal).
// Regression for the iOS symptoms where a Network control mode read as "not
// providing" until the rpc connected.
func TestDeviceRemoteOfflineProvideState(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
networkSpace, byJwt, err := testing_newNetworkSpace(ctx)
connect.AssertEqual(t, err, nil)
// no DeviceLocal rpc server exists: the remote stays disconnected and
// every mutation queues in the local sync state
deviceRemote, err := newDeviceRemoteWithOverrides(
networkSpace,
byJwt,
NewId(),
defaultDeviceRpcSettings(),
connect.NewId(),
testing_deviceRpcDialerDefault(),
)
connect.AssertEqual(t, err, nil)
defer deviceRemote.Close()
listener := &testOfflineProvideListener{
modes: make(chan ProvideMode, 16),
enabled: make(chan bool, 16),
keys: make(chan *ProvideSecretKeyList, 16),
}
modeSub := deviceRemote.AddProvideModeChangeListener(listener)
defer modeSub.Close()
enabledSub := deviceRemote.AddProvideChangeListener(listener)
defer enabledSub.Close()
keysSub := deviceRemote.AddProvideSecretKeysListener(listener)
defer keysSub.Close()
expectMode := func(expected ProvideMode) {
select {
case provideMode := <-listener.modes:
connect.AssertEqual(t, provideMode, expected)
case <-time.After(5 * time.Second):
t.Fatalf("timeout waiting for provide mode %d", expected)
}
}
expectEnabled := func(expected bool) {
select {
case provideEnabled := <-listener.enabled:
connect.AssertEqual(t, provideEnabled, expected)
case <-time.After(5 * time.Second):
t.Fatalf("timeout waiting for provide enabled %t", expected)
}
}
// a stale raw provide mode queued first (the app's persisted-mode replay
// at init). The default control mode is manual, so the raw mode is the
// truth here.
deviceRemote.SetProvideMode(ProvideModePublic)
expectMode(ProvideModePublic)
expectEnabled(true)
// the control mode OWNS the derived mode from here on — the stale raw
// Public above must not leak through a Network control mode (the iOS
// red-light-at-startup bug)
deviceRemote.SetProvideControlMode(ProvideControlModeNetwork)
expectMode(ProvideModeNetwork)
expectEnabled(true)
connect.AssertEqual(t, deviceRemote.GetProvideMode(), ProvideModeNetwork)
connect.AssertEqual(t, deviceRemote.GetProvideEnabled(), true)
deviceRemote.SetProvideControlMode(ProvideControlModeAlways)
expectMode(ProvideModePublic)
expectEnabled(true)
// auto while idle: network (peer-reachable), provider on
deviceRemote.SetProvideControlMode(ProvideControlModeAuto)
expectMode(ProvideModeNetwork)
expectEnabled(true)
deviceRemote.SetProvideControlMode(ProvideControlModeNever)
expectMode(ProvideModeNone)
expectEnabled(false)
// loading keys while disconnected announces them locally — nothing else
// will until the rpc connects
provideSecretKeys := NewProvideSecretKeyList()
provideSecretKeys.addAll(&ProvideSecretKey{
ProvideMode: ProvideModeNetwork,
ProvideSecretKey: "test-network-key",
})
deviceRemote.LoadProvideSecretKeys(provideSecretKeys)
select {
case keys := <-listener.keys:
connect.AssertEqual(t, keys.Len(), 1)
connect.AssertEqual(t, keys.Get(0).ProvideMode, ProvideModeNetwork)
case <-time.After(5 * time.Second):
t.Fatal("timeout waiting for the loaded provide secret keys")
}
}