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

feat: Auto select workspace proxy based on lowest latency#7515

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
Emyrk merged 16 commits intomainfromstevenmasley/proxy_latency_pick
May 22, 2023
Merged
Show file tree
Hide file tree
Changes from1 commit
Commits
Show all changes
16 commits
Select commitHold shift + click to select a range
159538c
WIP: Proxy auto select and user selection state
EmyrkMay 11, 2023
1305931
chore: Auto select based on latency
EmyrkMay 12, 2023
d1c9f3f
Add extra test for unknown latencies
EmyrkMay 12, 2023
c739f24
Move arg inside the funcs
EmyrkMay 12, 2023
ae26777
Fmt
EmyrkMay 12, 2023
523e492
Duplicate import
EmyrkMay 12, 2023
877c0c9
PR feedback
EmyrkMay 12, 2023
8d26643
Merge remote-tracking branch 'origin/main' into stevenmasley/proxy_la…
EmyrkMay 12, 2023
5c534fa
Refactor
EmyrkMay 12, 2023
a3703e1
Fix useEffect dep
EmyrkMay 18, 2023
c210e8d
Merge remote-tracking branch 'origin/main' into stevenmasley/proxy_la…
EmyrkMay 18, 2023
a358258
Fix deps comment
EmyrkMay 18, 2023
ec860c3
Remove comment
EmyrkMay 22, 2023
3197eb1
Merge remote-tracking branch 'origin/main' into stevenmasley/proxy_la…
EmyrkMay 22, 2023
ebb6a76
Mock the hook with a hook
EmyrkMay 22, 2023
549093e
Remove unused dep
EmyrkMay 22, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
PrevPrevious commit
NextNext commit
chore: Auto select based on latency
  • Loading branch information
@Emyrk
Emyrk committedMay 12, 2023
commit13059311bcdcde1c8405f1e52a679e15c2931865
229 changes: 201 additions & 28 deletionssite/src/contexts/ProxyContext.test.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,31 +10,52 @@ import {
saveUserSelectedProxy,
useProxy,
} from "./ProxyContext"
import * asProxyContextModule from "./ProxyContext"
import * asProxyLatency from "./useProxyLatency"
import {
renderWithAuth,
waitForLoaderToBeRemoved,
} from "testHelpers/renderHelpers"
import { screen } from "@testing-library/react"
import { server } from "testHelpers/server"
import "testHelpers/localstorage"
import { rest } from "msw"
import { Region } from "api/typesGenerated"
import "testHelpers/localstorage"
import userEvent from "@testing-library/user-event"

// Mock useProxyLatency to use a hard-coded latency. 'jest.mock' must be called
// here and not inside a unit test.
jest.mock("contexts/useProxyLatency", () => ({
useProxyLatency: () => {
return hardCodedLatencies
},
}))

let hardCodedLatencies: Record<string, ProxyLatency.ProxyLatencyReport> = {}

const fakeLatency = (ms: number): ProxyLatency.ProxyLatencyReport => {
return {
latencyMS: ms,
accurate: true,
at: new Date(),
}
}

describe("ProxyContextGetURLs", () => {
it.each([
["empty", [], undefined, "", ""],
["empty", [],{},undefined, "", ""],
// Primary has no path app URL. Uses relative links
[
"primary",
[MockPrimaryWorkspaceProxy],
{},
MockPrimaryWorkspaceProxy,
"",
MockPrimaryWorkspaceProxy.wildcard_hostname,
],
[
"regions selected",
MockWorkspaceProxies,
{},
MockHealthyWildWorkspaceProxy,
MockHealthyWildWorkspaceProxy.path_app_url,
MockHealthyWildWorkspaceProxy.wildcard_hostname,
Expand All@@ -43,13 +64,15 @@ describe("ProxyContextGetURLs", () => {
[
"no selected",
[MockPrimaryWorkspaceProxy],
{},
undefined,
"",
MockPrimaryWorkspaceProxy.wildcard_hostname,
],
[
"regions no select primary default",
MockWorkspaceProxies,
{},
undefined,
"",
MockPrimaryWorkspaceProxy.wildcard_hostname,
Expand All@@ -58,16 +81,40 @@ describe("ProxyContextGetURLs", () => {
[
"unhealthy selection",
MockWorkspaceProxies,
{},
MockUnhealthyWildWorkspaceProxy,
"",
MockPrimaryWorkspaceProxy.wildcard_hostname,
],
// This should never happen, when there is no primary
["no primary", [MockHealthyWildWorkspaceProxy], undefined, "", ""],
["no primary", [MockHealthyWildWorkspaceProxy], {}, undefined, "", ""],
// Latency behavior
[
"best latency",
MockWorkspaceProxies,
{
[MockPrimaryWorkspaceProxy.id]: fakeLatency(100),
[MockHealthyWildWorkspaceProxy.id]: fakeLatency(50),
// This should be ignored because it's unhealthy
[MockUnhealthyWildWorkspaceProxy.id]: fakeLatency(25),
// This should be ignored because it is not in the list.
["not a proxy"]: fakeLatency(10),
},
undefined,
MockHealthyWildWorkspaceProxy.path_app_url,
MockHealthyWildWorkspaceProxy.wildcard_hostname,
],
])(
`%p`,
(_, regions, selected, preferredPathAppURL, preferredWildcardHostname) => {
const preferred = getPreferredProxy(regions, selected)
(
_,
regions,
latencies,
selected,
preferredPathAppURL,
preferredWildcardHostname,
) => {
const preferred = getPreferredProxy(regions, selected, latencies)
expect(preferred.preferredPathAppURL).toBe(preferredPathAppURL)
expect(preferred.preferredWildcardHostname).toBe(
preferredWildcardHostname,
Expand All@@ -76,11 +123,6 @@ describe("ProxyContextGetURLs", () => {
)
})

// interface ProxySelectTest {
// name: string
// actions: ()
// }

const TestingComponent = () => {
return renderWithAuth(
<ProxyProvider>
Expand All@@ -95,7 +137,8 @@ const TestingComponent = () => {

// TestingScreen just mounts some components that we can check in the unit test.
const TestingScreen = () => {
const { proxy, isFetched, isLoading } = useProxy()
const { proxy, userProxy, isFetched, isLoading, clearProxy, setProxy } =
useProxy()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

You probably don't need this to test a hook. You can use therenderHook from@testing-library/react. I think it can make the test way easier to reason about. More about its usage:https://kentcdodds.com/blog/how-to-test-custom-react-hooks

Kira-Pilot reacted with eyes emoji
Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This looks like exactly what I was looking for.

In the example they have this:

const{result}=renderHook(()=>useUndo('one'))

The only caveat I have is I also need theuseDashboard provider present until this leaves experimental. So I'd need to souseProxy with the Dashboard context available 🤔

return (
<>
<div data-testid="isFetched" title={isFetched.toString()}></div>
Expand All@@ -104,49 +147,182 @@ const TestingScreen = () => {
data-testid="preferredProxy"
title={proxy.selectedProxy && proxy.selectedProxy.id}
></div>
<div data-testid="userProxy" title={userProxy && userProxy.id}></div>
<button data-testid="clearProxy" onClick={clearProxy}></button>
<div data-testid="userSelectProxyData"></div>
<button
data-testid="userSelectProxy"
onClick={() => {
const data = screen.getByTestId("userSelectProxyData")
if (data.innerText) {
setProxy(JSON.parse(data.innerText))
}
}}
></button>
</>
)
}

interface ProxyContextSelectionTest {
expSelectedProxyID: string
regions: Region[]
storageProxy: Region | undefined
latencies?: Record<string, ProxyLatency.ProxyLatencyReport>
afterLoad?: (user: typeof userEvent) => Promise<void>

expProxyID: string
expUserProxyID?: string
}

describe("ProxyContextSelection", () => {
beforeEach(() => {
// Object.defineProperty(window, "localStorage", { value: localStorageMock })
window.localStorage.clear()
})

// A way to simulate a user clearing the proxy selection.
const clearProxyAction = async (user: typeof userEvent): Promise<void> => {
const clearProxyButton = screen.getByTestId("clearProxy")
await user.click(clearProxyButton)
}

const userSelectProxy = (
proxy: Region,
): ((user: typeof userEvent) => Promise<void>) => {
return async (user): Promise<void> => {
const selectData = screen.getByTestId("userSelectProxyData")
selectData.innerText = JSON.stringify(proxy)

const selectProxyButton = screen.getByTestId("userSelectProxy")
await user.click(selectProxyButton)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Nice helpers!

Emyrk reacted with thumbs up emoji

it.each([
// Not latency behavior
[
"empty",
{
expSelectedProxyID: "",
expProxyID: "",
regions: [],
storageProxy: undefined,
latencies: {},
},
],
[
"regions_no_selection",
{
expSelectedProxyID: MockPrimaryWorkspaceProxy.id,
expProxyID: MockPrimaryWorkspaceProxy.id,
regions: MockWorkspaceProxies,
storageProxy: undefined,
},
],
[
"regions_selected_unhealthy",
{
expSelectedProxyID: MockPrimaryWorkspaceProxy.id,
expProxyID: MockPrimaryWorkspaceProxy.id,
regions: MockWorkspaceProxies,
storageProxy: MockUnhealthyWildWorkspaceProxy,
expUserProxyID: MockUnhealthyWildWorkspaceProxy.id,
},
],
[
"regions_selected_healthy",
{
expProxyID: MockHealthyWildWorkspaceProxy.id,
regions: MockWorkspaceProxies,
storageProxy: MockHealthyWildWorkspaceProxy,
expUserProxyID: MockHealthyWildWorkspaceProxy.id,
},
],
[
"regions_selected_clear",
{
expProxyID: MockPrimaryWorkspaceProxy.id,
regions: MockWorkspaceProxies,
storageProxy: MockHealthyWildWorkspaceProxy,
afterLoad: clearProxyAction,
expUserProxyID: undefined,
},
],
[
"regions_make_selection",
{
expProxyID: MockHealthyWildWorkspaceProxy.id,
regions: MockWorkspaceProxies,
afterLoad: userSelectProxy(MockHealthyWildWorkspaceProxy),
expUserProxyID: MockHealthyWildWorkspaceProxy.id,
},
],
// Latency behavior
[
"regions_default_low_latency",
{
expProxyID: MockHealthyWildWorkspaceProxy.id,
regions: MockWorkspaceProxies,
storageProxy: undefined,
latencies: {
[MockPrimaryWorkspaceProxy.id]: fakeLatency(100),
[MockHealthyWildWorkspaceProxy.id]: fakeLatency(50),
// This is a trick. It's unhealthy so should be ignored.
[MockUnhealthyWildWorkspaceProxy.id]: fakeLatency(25),
},
},
],
[
// User intentionally selected a high latency proxy.
"regions_select_high_latency",
{
expProxyID: MockHealthyWildWorkspaceProxy.id,
regions: MockWorkspaceProxies,
storageProxy: undefined,
afterLoad: userSelectProxy(MockHealthyWildWorkspaceProxy),
expUserProxyID: MockHealthyWildWorkspaceProxy.id,
latencies: {
[MockHealthyWildWorkspaceProxy.id]: fakeLatency(500),
[MockPrimaryWorkspaceProxy.id]: fakeLatency(100),
// This is a trick. It's unhealthy so should be ignored.
[MockUnhealthyWildWorkspaceProxy.id]: fakeLatency(25),
},
},
],
[
// Low latency proxy is selected, but it is unhealthy
"regions_select_unhealthy_low_latency",
{
expProxyID: MockPrimaryWorkspaceProxy.id,
regions: MockWorkspaceProxies,
storageProxy: MockUnhealthyWildWorkspaceProxy,
expUserProxyID: MockUnhealthyWildWorkspaceProxy.id,
latencies: {
[MockHealthyWildWorkspaceProxy.id]: fakeLatency(500),
[MockPrimaryWorkspaceProxy.id]: fakeLatency(100),
// This is a trick. It's unhealthy so should be ignored.
[MockUnhealthyWildWorkspaceProxy.id]: fakeLatency(25),
},
},
],
] as [string, ProxyContextSelectionTest][])(
`%s`,
async (_, { expSelectedProxyID, regions, storageProxy }) => {
async (
_,
{
expUserProxyID,
expProxyID: expSelectedProxyID,
regions,
storageProxy,
latencies = {},
afterLoad,
},
) => {
// Mock the latencies
hardCodedLatencies = latencies

// jest.mock("contexts/useProxyLatency", () => ({
// useProxyLatency: () => {
// return latencies
// },
// }))

// Initial selection if present
if (storageProxy) {
saveUserSelectedProxy(storageProxy)
Expand All@@ -167,6 +343,11 @@ describe("ProxyContextSelection", () => {
TestingComponent()
await waitForLoaderToBeRemoved()

const user = userEvent.setup()
if (afterLoad) {
await afterLoad(user)
}

await screen.findByTestId("isFetched").then((x) => {
expect(x.title).toBe("true")
})
Expand All@@ -176,17 +357,9 @@ describe("ProxyContextSelection", () => {
await screen.findByTestId("preferredProxy").then((x) => {
expect(x.title).toBe(expSelectedProxyID)
})

// const { proxy, proxies, isFetched, isLoading, proxyLatencies } = useProxy()
// expect(isLoading).toBe(false)
// expect(isFetched).toBe(true)

// expect(x).toBe(2)
// const preferred = getPreferredProxy(regions, selected)
// expect(preferred.preferredPathAppURL).toBe(preferredPathAppURL)
// expect(preferred.preferredWildcardHostname).toBe(
// preferredWildcardHostname,
// )
await screen.findByTestId("userProxy").then((x) => {
expect(x.title).toBe(expUserProxyID || "")
})
},
)
})
Loading

[8]ページ先頭

©2009-2025 Movatter.jp