Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1305931

Browse files
committed
chore: Auto select based on latency
1 parent159538c commit1305931

File tree

4 files changed

+297
-67
lines changed

4 files changed

+297
-67
lines changed

‎site/src/contexts/ProxyContext.test.tsx

Lines changed: 201 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,31 +10,52 @@ import {
1010
saveUserSelectedProxy,
1111
useProxy,
1212
}from"./ProxyContext"
13-
import*asProxyContextModulefrom"./ProxyContext"
13+
import*asProxyLatencyfrom"./useProxyLatency"
1414
import{
1515
renderWithAuth,
1616
waitForLoaderToBeRemoved,
1717
}from"testHelpers/renderHelpers"
1818
import{screen}from"@testing-library/react"
1919
import{server}from"testHelpers/server"
20-
import"testHelpers/localstorage"
2120
import{rest}from"msw"
2221
import{Region}from"api/typesGenerated"
22+
import"testHelpers/localstorage"
23+
importuserEventfrom"@testing-library/user-event"
24+
25+
// Mock useProxyLatency to use a hard-coded latency. 'jest.mock' must be called
26+
// here and not inside a unit test.
27+
jest.mock("contexts/useProxyLatency",()=>({
28+
useProxyLatency:()=>{
29+
returnhardCodedLatencies
30+
},
31+
}))
32+
33+
lethardCodedLatencies:Record<string,ProxyLatency.ProxyLatencyReport>={}
34+
35+
constfakeLatency=(ms:number):ProxyLatency.ProxyLatencyReport=>{
36+
return{
37+
latencyMS:ms,
38+
accurate:true,
39+
at:newDate(),
40+
}
41+
}
2342

2443
describe("ProxyContextGetURLs",()=>{
2544
it.each([
26-
["empty",[],undefined,"",""],
45+
["empty",[],{},undefined,"",""],
2746
// Primary has no path app URL. Uses relative links
2847
[
2948
"primary",
3049
[MockPrimaryWorkspaceProxy],
50+
{},
3151
MockPrimaryWorkspaceProxy,
3252
"",
3353
MockPrimaryWorkspaceProxy.wildcard_hostname,
3454
],
3555
[
3656
"regions selected",
3757
MockWorkspaceProxies,
58+
{},
3859
MockHealthyWildWorkspaceProxy,
3960
MockHealthyWildWorkspaceProxy.path_app_url,
4061
MockHealthyWildWorkspaceProxy.wildcard_hostname,
@@ -43,13 +64,15 @@ describe("ProxyContextGetURLs", () => {
4364
[
4465
"no selected",
4566
[MockPrimaryWorkspaceProxy],
67+
{},
4668
undefined,
4769
"",
4870
MockPrimaryWorkspaceProxy.wildcard_hostname,
4971
],
5072
[
5173
"regions no select primary default",
5274
MockWorkspaceProxies,
75+
{},
5376
undefined,
5477
"",
5578
MockPrimaryWorkspaceProxy.wildcard_hostname,
@@ -58,16 +81,40 @@ describe("ProxyContextGetURLs", () => {
5881
[
5982
"unhealthy selection",
6083
MockWorkspaceProxies,
84+
{},
6185
MockUnhealthyWildWorkspaceProxy,
6286
"",
6387
MockPrimaryWorkspaceProxy.wildcard_hostname,
6488
],
6589
// This should never happen, when there is no primary
66-
["no primary",[MockHealthyWildWorkspaceProxy],undefined,"",""],
90+
["no primary",[MockHealthyWildWorkspaceProxy],{},undefined,"",""],
91+
// Latency behavior
92+
[
93+
"best latency",
94+
MockWorkspaceProxies,
95+
{
96+
[MockPrimaryWorkspaceProxy.id]:fakeLatency(100),
97+
[MockHealthyWildWorkspaceProxy.id]:fakeLatency(50),
98+
// This should be ignored because it's unhealthy
99+
[MockUnhealthyWildWorkspaceProxy.id]:fakeLatency(25),
100+
// This should be ignored because it is not in the list.
101+
["not a proxy"]:fakeLatency(10),
102+
},
103+
undefined,
104+
MockHealthyWildWorkspaceProxy.path_app_url,
105+
MockHealthyWildWorkspaceProxy.wildcard_hostname,
106+
],
67107
])(
68108
`%p`,
69-
(_,regions,selected,preferredPathAppURL,preferredWildcardHostname)=>{
70-
constpreferred=getPreferredProxy(regions,selected)
109+
(
110+
_,
111+
regions,
112+
latencies,
113+
selected,
114+
preferredPathAppURL,
115+
preferredWildcardHostname,
116+
)=>{
117+
constpreferred=getPreferredProxy(regions,selected,latencies)
71118
expect(preferred.preferredPathAppURL).toBe(preferredPathAppURL)
72119
expect(preferred.preferredWildcardHostname).toBe(
73120
preferredWildcardHostname,
@@ -76,11 +123,6 @@ describe("ProxyContextGetURLs", () => {
76123
)
77124
})
78125

79-
// interface ProxySelectTest {
80-
// name: string
81-
// actions: ()
82-
// }
83-
84126
constTestingComponent=()=>{
85127
returnrenderWithAuth(
86128
<ProxyProvider>
@@ -95,7 +137,8 @@ const TestingComponent = () => {
95137

96138
// TestingScreen just mounts some components that we can check in the unit test.
97139
constTestingScreen=()=>{
98-
const{ proxy, isFetched, isLoading}=useProxy()
140+
const{ proxy, userProxy, isFetched, isLoading, clearProxy, setProxy}=
141+
useProxy()
99142
return(
100143
<>
101144
<divdata-testid="isFetched"title={isFetched.toString()}></div>
@@ -104,49 +147,182 @@ const TestingScreen = () => {
104147
data-testid="preferredProxy"
105148
title={proxy.selectedProxy&&proxy.selectedProxy.id}
106149
></div>
150+
<divdata-testid="userProxy"title={userProxy&&userProxy.id}></div>
151+
<buttondata-testid="clearProxy"onClick={clearProxy}></button>
152+
<divdata-testid="userSelectProxyData"></div>
153+
<button
154+
data-testid="userSelectProxy"
155+
onClick={()=>{
156+
constdata=screen.getByTestId("userSelectProxyData")
157+
if(data.innerText){
158+
setProxy(JSON.parse(data.innerText))
159+
}
160+
}}
161+
></button>
107162
</>
108163
)
109164
}
110165

111166
interfaceProxyContextSelectionTest{
112-
expSelectedProxyID:string
113167
regions:Region[]
114168
storageProxy:Region|undefined
169+
latencies?:Record<string,ProxyLatency.ProxyLatencyReport>
170+
afterLoad?:(user:typeofuserEvent)=>Promise<void>
171+
172+
expProxyID:string
173+
expUserProxyID?:string
115174
}
116175

117176
describe("ProxyContextSelection",()=>{
118177
beforeEach(()=>{
178+
// Object.defineProperty(window, "localStorage", { value: localStorageMock })
119179
window.localStorage.clear()
120180
})
121181

182+
// A way to simulate a user clearing the proxy selection.
183+
constclearProxyAction=async(user:typeofuserEvent):Promise<void>=>{
184+
constclearProxyButton=screen.getByTestId("clearProxy")
185+
awaituser.click(clearProxyButton)
186+
}
187+
188+
constuserSelectProxy=(
189+
proxy:Region,
190+
):((user:typeofuserEvent)=>Promise<void>)=>{
191+
returnasync(user):Promise<void>=>{
192+
constselectData=screen.getByTestId("userSelectProxyData")
193+
selectData.innerText=JSON.stringify(proxy)
194+
195+
constselectProxyButton=screen.getByTestId("userSelectProxy")
196+
awaituser.click(selectProxyButton)
197+
}
198+
}
199+
122200
it.each([
201+
// Not latency behavior
123202
[
124203
"empty",
125204
{
126-
expSelectedProxyID:"",
205+
expProxyID:"",
127206
regions:[],
128207
storageProxy:undefined,
208+
latencies:{},
129209
},
130210
],
131211
[
132212
"regions_no_selection",
133213
{
134-
expSelectedProxyID:MockPrimaryWorkspaceProxy.id,
214+
expProxyID:MockPrimaryWorkspaceProxy.id,
135215
regions:MockWorkspaceProxies,
136216
storageProxy:undefined,
137217
},
138218
],
139219
[
140220
"regions_selected_unhealthy",
141221
{
142-
expSelectedProxyID:MockPrimaryWorkspaceProxy.id,
222+
expProxyID:MockPrimaryWorkspaceProxy.id,
143223
regions:MockWorkspaceProxies,
144224
storageProxy:MockUnhealthyWildWorkspaceProxy,
225+
expUserProxyID:MockUnhealthyWildWorkspaceProxy.id,
226+
},
227+
],
228+
[
229+
"regions_selected_healthy",
230+
{
231+
expProxyID:MockHealthyWildWorkspaceProxy.id,
232+
regions:MockWorkspaceProxies,
233+
storageProxy:MockHealthyWildWorkspaceProxy,
234+
expUserProxyID:MockHealthyWildWorkspaceProxy.id,
235+
},
236+
],
237+
[
238+
"regions_selected_clear",
239+
{
240+
expProxyID:MockPrimaryWorkspaceProxy.id,
241+
regions:MockWorkspaceProxies,
242+
storageProxy:MockHealthyWildWorkspaceProxy,
243+
afterLoad:clearProxyAction,
244+
expUserProxyID:undefined,
245+
},
246+
],
247+
[
248+
"regions_make_selection",
249+
{
250+
expProxyID:MockHealthyWildWorkspaceProxy.id,
251+
regions:MockWorkspaceProxies,
252+
afterLoad:userSelectProxy(MockHealthyWildWorkspaceProxy),
253+
expUserProxyID:MockHealthyWildWorkspaceProxy.id,
254+
},
255+
],
256+
// Latency behavior
257+
[
258+
"regions_default_low_latency",
259+
{
260+
expProxyID:MockHealthyWildWorkspaceProxy.id,
261+
regions:MockWorkspaceProxies,
262+
storageProxy:undefined,
263+
latencies:{
264+
[MockPrimaryWorkspaceProxy.id]:fakeLatency(100),
265+
[MockHealthyWildWorkspaceProxy.id]:fakeLatency(50),
266+
// This is a trick. It's unhealthy so should be ignored.
267+
[MockUnhealthyWildWorkspaceProxy.id]:fakeLatency(25),
268+
},
269+
},
270+
],
271+
[
272+
// User intentionally selected a high latency proxy.
273+
"regions_select_high_latency",
274+
{
275+
expProxyID:MockHealthyWildWorkspaceProxy.id,
276+
regions:MockWorkspaceProxies,
277+
storageProxy:undefined,
278+
afterLoad:userSelectProxy(MockHealthyWildWorkspaceProxy),
279+
expUserProxyID:MockHealthyWildWorkspaceProxy.id,
280+
latencies:{
281+
[MockHealthyWildWorkspaceProxy.id]:fakeLatency(500),
282+
[MockPrimaryWorkspaceProxy.id]:fakeLatency(100),
283+
// This is a trick. It's unhealthy so should be ignored.
284+
[MockUnhealthyWildWorkspaceProxy.id]:fakeLatency(25),
285+
},
286+
},
287+
],
288+
[
289+
// Low latency proxy is selected, but it is unhealthy
290+
"regions_select_unhealthy_low_latency",
291+
{
292+
expProxyID:MockPrimaryWorkspaceProxy.id,
293+
regions:MockWorkspaceProxies,
294+
storageProxy:MockUnhealthyWildWorkspaceProxy,
295+
expUserProxyID:MockUnhealthyWildWorkspaceProxy.id,
296+
latencies:{
297+
[MockHealthyWildWorkspaceProxy.id]:fakeLatency(500),
298+
[MockPrimaryWorkspaceProxy.id]:fakeLatency(100),
299+
// This is a trick. It's unhealthy so should be ignored.
300+
[MockUnhealthyWildWorkspaceProxy.id]:fakeLatency(25),
301+
},
145302
},
146303
],
147304
]as[string,ProxyContextSelectionTest][])(
148305
`%s`,
149-
async(_,{ expSelectedProxyID, regions, storageProxy})=>{
306+
async(
307+
_,
308+
{
309+
expUserProxyID,
310+
expProxyID:expSelectedProxyID,
311+
regions,
312+
storageProxy,
313+
latencies={},
314+
afterLoad,
315+
},
316+
)=>{
317+
// Mock the latencies
318+
hardCodedLatencies=latencies
319+
320+
// jest.mock("contexts/useProxyLatency", () => ({
321+
// useProxyLatency: () => {
322+
// return latencies
323+
// },
324+
// }))
325+
150326
// Initial selection if present
151327
if(storageProxy){
152328
saveUserSelectedProxy(storageProxy)
@@ -167,6 +343,11 @@ describe("ProxyContextSelection", () => {
167343
TestingComponent()
168344
awaitwaitForLoaderToBeRemoved()
169345

346+
constuser=userEvent.setup()
347+
if(afterLoad){
348+
awaitafterLoad(user)
349+
}
350+
170351
awaitscreen.findByTestId("isFetched").then((x)=>{
171352
expect(x.title).toBe("true")
172353
})
@@ -176,17 +357,9 @@ describe("ProxyContextSelection", () => {
176357
awaitscreen.findByTestId("preferredProxy").then((x)=>{
177358
expect(x.title).toBe(expSelectedProxyID)
178359
})
179-
180-
// const { proxy, proxies, isFetched, isLoading, proxyLatencies } = useProxy()
181-
// expect(isLoading).toBe(false)
182-
// expect(isFetched).toBe(true)
183-
184-
// expect(x).toBe(2)
185-
// const preferred = getPreferredProxy(regions, selected)
186-
// expect(preferred.preferredPathAppURL).toBe(preferredPathAppURL)
187-
// expect(preferred.preferredWildcardHostname).toBe(
188-
// preferredWildcardHostname,
189-
// )
360+
awaitscreen.findByTestId("userProxy").then((x)=>{
361+
expect(x.title).toBe(expUserProxyID||"")
362+
})
190363
},
191364
)
192365
})

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp