1
0
Fork 0
mirror of https://github.com/anyproto/anytype-heart.git synced 2025-06-08 05:47:07 +09:00

added support for perftests on windows

This commit is contained in:
Kirill Shklyaev 2024-12-13 15:12:45 +03:00
parent f4ad2c8c2f
commit ffd8601fc9
3 changed files with 295 additions and 18 deletions

View file

@ -2,10 +2,14 @@
on:
workflow_dispatch:
inputs:
run-on-runner:
description: 'Specify the runner to use'
run-on-runner-mac:
description: 'Specify the runner to use on MacOS'
required: true
default: 'ARM64'
run-on-runner-win:
description: 'Specify the runner to use on Windows'
required: true
default: 'windows-perftests'
perf-test:
description: 'Run perf test times'
required: true
@ -17,7 +21,6 @@ on:
include:
- 'main'
permissions:
actions: 'write'
contents: 'write'
@ -25,7 +28,7 @@ permissions:
name: Perf tests
jobs:
build:
perftests-macos:
timeout-minutes: 60
runs-on: 'ARM64'
steps:
@ -76,7 +79,7 @@ jobs:
RUN_COUNT=${{ github.event.inputs.perf-test }}
if [[ "${{ github.event_name }}" == "schedule" ]]; then
RUN_COUNT=10
fi
fi
echo $PERF_CONFIG_STAGING > config.json
mv .github/staging_fake.yml staging_fake.yml
PERF_CONFIG=$PWD/config.json
@ -97,6 +100,171 @@ jobs:
- name: Archive perf tests results
uses: actions/upload-artifact@v4
with:
name: traces
name: traces-macos
path: |
*.log
perftests-windows:
timeout-minutes: 60
runs-on: 'windows-perftests'
steps:
- name: Install windows utils
run: C:\ProgramData\chocolatey\bin\choco install gzip mingw git -y
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: '1.23'
cache: false
- name: Setup Go env
run: |
go version
echo GOPATH=$(go env GOPATH) >> $env:GITHUB_ENV
echo GOBIN=$(go env GOPATH)\bin >> $env:GITHUB_ENV
echo $(go env GOPATH)\bin >> $env:GITHUB_PATH
- name: Checkout
uses: actions/checkout@v4.2.2
- name: Set env vars
env:
UNSPLASH_KEY: ${{ secrets.UNSPLASH_KEY }}
INHOUSE_KEY: ${{ secrets.INHOUSE_KEY }}
run: |
$GIT_SUMMARY = git describe --tags --always
echo "FLAGS=-X github.com/anyproto/anytype-heart/util/vcs.GitSummary=$GIT_SUMMARY -X github.com/anyproto/anytype-heart/metrics.DefaultInHouseKey=$env:INHOUSE_KEY -X github.com/anyproto/anytype-heart/util/unsplash.DefaultToken=$env:UNSPLASH_KEY" >> $env:GITHUB_ENV
if ($env:GITHUB_EVENT_NAME -eq "workflow_dispatch") {
$VERSION = ${{ github.event.inputs.alpha_version }}
if (-not $VERSION) {
$VERSION = git rev-parse --short HEAD
}
}
if (-not $VERSION) {
$VERSION = ($env:GITHUB_REF -split "/")[-1]
}
echo "VERSION=$VERSION" >> $env:GITHUB_ENV
echo "MAVEN_ARTIFACT_VERSION=$VERSION" >> $env:GITHUB_ENV
echo "GOPRIVATE=github.com/anyproto" >> $env:GITHUB_ENV
echo "$(Get-Location)\deps" >> $env:GITHUB_PATH
echo "$env:GOBIN" >> $env:GITHUB_PATH
git config --global url."https://${{ secrets.ANYTYPE_PAT }}@github.com/".insteadOf "https://github.com/"
- name: Go mod download
run: |
go mod download
- name: Setup network config
env:
CUSTOM_NETWORK_FILE: ./core/anytype/config/nodes/custom.yml
run: |
if (-not $env:ANY_SYNC_NETWORK) {
echo "Using the default production Any Sync Network"
} elseif (-not (Test-Path $env:ANY_SYNC_NETWORK)) {
echo "Network configuration file not found at $env:ANY_SYNC_NETWORK"
exit 1
} else {
echo "Using Any Sync Network configuration at $env:ANY_SYNC_NETWORK"
Copy-Item -Path $env:ANY_SYNC_NETWORK -Destination $CUSTOM_NETWORK_FILE -Force
}
- name: Check and download tantivy
env:
TANTIVY_GO_PATH: ../tantivy-go
OUTPUT_DIR: deps/libs
REPO: anyproto/tantivy-go
run: |
$TANTIVY_VERSION = (Get-Content go.mod | Select-String "github.com/anyproto/tantivy-go" | ForEach-Object { ($_ -split " ")[1] }).Trim()
$TANTIVY_LIBS = @(
"android-386.tar.gz",
"android-amd64.tar.gz",
"android-arm.tar.gz",
"android-arm64.tar.gz",
"darwin-amd64.tar.gz",
"darwin-arm64.tar.gz",
"ios-amd64.tar.gz",
"ios-arm64.tar.gz",
"ios-arm64-sim.tar.gz",
"linux-amd64-musl.tar.gz",
"windows-amd64.tar.gz"
)
if (-not (Test-Path "$env:OUTPUT_DIR/.verified") -or (Get-Content "$env:OUTPUT_DIR/.verified").Trim() -ne $TANTIVY_VERSION) {
if (Test-Path "$env:OUTPUT_DIR") {
Remove-Item -Recurse -Force "$env:OUTPUT_DIR/*"
}
if (-not (Test-Path "$env:OUTPUT_DIR")) {
New-Item -ItemType Directory -Path "$env:OUTPUT_DIR" | Out-Null
}
foreach ($lib in $TANTIVY_LIBS) {
$downloadUrl = "https://github.com/$env:REPO/releases/download/$TANTIVY_VERSION/$lib"
$localFilePath = "$env:OUTPUT_DIR/$lib"
Invoke-WebRequest -Uri $downloadUrl -OutFile $localFilePath
$extractDir = "$env:OUTPUT_DIR/$($lib -replace '.tar.gz', '')"
if (-not (Test-Path $extractDir)) {
New-Item -ItemType Directory -Path $extractDir | Out-Null
}
tar -C $extractDir -xvzf $localFilePath
}
Get-ChildItem -Path "$env:OUTPUT_DIR" -Filter "*.tar.gz" | Remove-Item -Force
Set-Content -Path "$env:OUTPUT_DIR/.verified" -Value $TANTIVY_VERSION
echo "Tantivy libraries updated successfully."
} else {
echo "Tantivy libraries are up to date."
}
- name: Install grpcurl and govvv
run: |
go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest
go install github.com/ahmetb/govvv@v0.2.0
- name: Run perf tests
run: |
echo "Running perf tests in staging mode..."
$RUN_COUNT = ${{ github.event.inputs.perf-test }}
if ($env:GITHUB_EVENT_NAME -eq "schedule") {
$RUN_COUNT = 10
}
Set-Content -Path config.json -Value $env:PERF_CONFIG_STAGING
(Get-Content config.json).Replace('"/Users/user1/account30000"', '"C:/Users/' + $env:USERNAME + '"') | Set-Content -Path config.json
Move-Item -Path .\.github\staging_fake.yml -Destination .\staging_fake.yml -Force
$PERF_CONFIG = ((Get-Location).Path -replace '\\', '/') + "/config.json"
Set-Location cmd\perfstand\account_create
$env:CGO_ENABLED = "1"
go run main.go $PERF_CONFIG $RUN_COUNT
Set-Location ..\account_select
go run main.go $PERF_CONFIG $RUN_COUNT
echo "Perf test with staging - done"
echo "Running perf tests in local mode..."
Set-Location (Resolve-Path "../../..")
Set-Content -Path config.json -Value $env:PERF_CONFIG_LOCAL
(Get-Content config.json).Replace('"/Users/user1/account30000"', '"C:/Users/' + $env:USERNAME + '"') | Set-Content -Path config.json
Set-Location cmd\perfstand\account_create
$env:CGO_ENABLED = "1"
go run main.go $PERF_CONFIG $RUN_COUNT
Set-Location ..\account_select
go run main.go $PERF_CONFIG $RUN_COUNT
echo "Perf test in local mode - done"
env:
PERF_CONFIG_STAGING: ${{ secrets.PERF_CONFIG_STAGING }}
PERF_CONFIG_LOCAL: ${{ secrets.PERF_CONFIG_LOCAL }}
CH_API_KEY: ${{ secrets.CH_PERF_API_KEY }}
- name: Clean /tmp
run: |
echo "Clean workspaces in /Temp"
Get-ChildItem "C:/Users/$env:USERNAME/AppData/Local/Temp/" -Directory -Force | Where-Object { $_.Name -like "workspace*" } | ForEach-Object { Remove-Item $_.FullName -Recurse -Force -ErrorAction SilentlyContinue }
- name: Archive perf tests results
uses: actions/upload-artifact@v4
with:
name: traces-win
path: |
*.log

View file

@ -5,6 +5,7 @@ import (
"fmt"
"os"
"os/exec"
"runtime"
"go.uber.org/atomic"
@ -33,6 +34,7 @@ func NewResults(networkMode string) internal.PerfResult {
}
}
func main() {
prep := NewInput()
err := internal.Prepare(prep, nil)
@ -58,10 +60,18 @@ func main() {
func iterate(prep *input, result internal.PerfResult) error {
workspace, err := os.MkdirTemp("", "workspace")
prep.Workspace = workspace
if err != nil {
return err
}
if runtime.GOOS == "windows" {
workspace, err = internal.WinFixPath(workspace)
if err != nil {
return err
}
}
prep.Workspace = workspace
defer os.RemoveAll(workspace)
fmt.Println("Created temporary directory:", workspace)
@ -79,7 +89,13 @@ func iterate(prep *input, result internal.PerfResult) error {
return err
}
walletStr, err := exec.Command("bash", "-c", internal.GrpcWalletCreate(workspace)).Output()
var walletStr []byte
if runtime.GOOS == "windows" {
walletStr, err = exec.Command("powershell", "-Command", internal.GrpcWalletCreate(workspace)).Output()
} else {
walletStr, err = exec.Command("bash", "-c", internal.GrpcWalletCreate(workspace)).Output()
}
if err != nil {
return err
}

View file

@ -80,12 +80,23 @@ func SendResultsToHttp(apiKey string, events []Event) error {
}
func KillServer() error {
return ExecuteCommand("kill -9 $(lsof -i :31007 -t) ; echo \"Server killed\"")
var cmd string
if runtime.GOOS == "windows" {
cmd = `(Get-NetTCPConnection -LocalPort 31007 -State Listen | Select-Object -ExpandProperty OwningProcess | ForEach-Object { Stop-Process -Id $_ -Force -ErrorAction SilentlyContinue }) ; Write-Host "Server killed"`
} else {
cmd = "kill -9 $(lsof -i :31007 -t) ; echo \"Server killed\""
}
return ExecuteCommand(cmd)
}
func ExecuteCommand(command string) error {
fmt.Println(command)
cmd := exec.Command("bash", "-c", command)
var cmd *exec.Cmd
if runtime.GOOS == "windows" {
cmd = exec.Command("powershell", "-Command", command)
} else {
cmd = exec.Command("bash", "-c", command)
}
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Run()
@ -96,7 +107,10 @@ func ExecuteCommand(command string) error {
}
func UnpackZip(path string, workspace string) error {
return ExecuteCommand("unzip -o " + path + " -d " + workspace)
if runtime.GOOS == "windows" {
return ExecuteCommand("Expand-Archive -Path " + path + " -DestinationPath " + workspace + " -Force")
}
return ExecuteCommand("unzip -qq -o " + path + " -d " + workspace)
}
func BuildAnytype(err error) error {
@ -117,6 +131,10 @@ func LoadEnv(env string) (string, error) {
return res, nil
}
func WinFixPath(winPath string) (string, error) {
return strings.ReplaceAll(winPath, "\\", "/"), nil
}
func SetupWd() (string, error) {
err := os.Chdir("../../..")
if err != nil {
@ -128,22 +146,39 @@ func SetupWd() (string, error) {
return "", err
}
if runtime.GOOS == "windows" {
getwd, err = WinFixPath(getwd)
if err != nil {
return "", err
}
}
fmt.Println("Current working directory:", getwd)
return getwd, nil
}
func GrpcWorkspaceOpen(workspace string) string {
if runtime.GOOS == "windows" {
return `cmd.exe /c 'grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d "{\"spaceId\":\"` + workspace + `\"}" localhost:31007 anytype.ClientCommands.WorkspaceOpen'`
}
return `grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d '{
"spaceId": "` + workspace + `"
}' localhost:31007 anytype.ClientCommands.WorkspaceOpen`
}
func GrpcWorkspaceCreate() string {
if runtime.GOOS == "windows" {
return `cmd.exe /c 'grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d "{}" localhost:31007 anytype.ClientCommands.WorkspaceCreate'`
}
return `grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d '{
}' localhost:31007 anytype.ClientCommands.WorkspaceCreate`
}
func GrpcAccountSelect(accHash, workspace, networkMode, staging string) string {
if runtime.GOOS == "windows" {
staging, _ = WinFixPath(staging)
return `cmd.exe /c 'grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d "{\"id\":\"` + accHash + `\",\"rootPath\":\"` + workspace + `\",\"disableLocalNetworkSync\":false,\"networkMode\":` + networkMode + `,\"networkCustomConfigFilePath\":\"` + staging + `\"}" localhost:31007 anytype.ClientCommands.AccountSelect'`
}
return `grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d '{
"id": "` + accHash + `",
"rootPath": "` + workspace + `",
@ -154,12 +189,18 @@ func GrpcAccountSelect(accHash, workspace, networkMode, staging string) string {
}
func GrpcWalletCreateSession(mnemonic string) string {
if runtime.GOOS == "windows" {
return `cmd.exe /c 'grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d "{\"mnemonic\":\"` + mnemonic + `\"}" localhost:31007 anytype.ClientCommands.WalletCreateSession'`
}
return `grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d '{
"mnemonic": "` + mnemonic + `"
}' localhost:31007 anytype.ClientCommands.WalletCreateSession`
}
func GrpcWalletRecover(workspace, mnemonic string) string {
if runtime.GOOS == "windows" {
return `cmd.exe /c 'grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d "{\"rootPath\":\"` + workspace + `\",\"mnemonic\":\"` + mnemonic + `\"}" localhost:31007 anytype.ClientCommands.WalletRecover'`
}
return `grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d '{
"rootPath": "` + workspace + `",
"mnemonic": "` + mnemonic + `"
@ -167,12 +208,19 @@ func GrpcWalletRecover(workspace, mnemonic string) string {
}
func GrpcWalletCreate(workspace string) string {
if runtime.GOOS == "windows" {
return `cmd.exe /c 'grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d "{\"rootPath\":\"` + workspace + `\"}" localhost:31007 anytype.ClientCommands.WalletCreate'`
}
return `grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d '{
"rootPath": "` + workspace + `"
}' localhost:31007 anytype.ClientCommands.WalletCreate`
}
func GrpcAccountCreate(workspace, networkMode, staging string) string {
if runtime.GOOS == "windows" {
staging, _ = WinFixPath(staging)
return `cmd.exe /c 'grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d "{\"icon\":13,\"networkMode\":` + networkMode + `,\"storePath\":\"` + workspace + `\",\"networkCustomConfigFilePath\":\"` + staging + `\"}" localhost:31007 anytype.ClientCommands.AccountCreate'`
}
return `grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d '{
"icon": 13,
"networkMode": ` + networkMode + `,
@ -182,6 +230,9 @@ func GrpcAccountCreate(workspace, networkMode, staging string) string {
}
func GrpcInitialSetParameters() string {
if runtime.GOOS == "windows" {
return `cmd.exe /c 'grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d "{\"platform\":\"test\",\"version\":\"0.0.0-test\"}" localhost:31007 anytype.ClientCommands.InitialSetParameters'`
}
return `grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d '{
"platform": "test",
"version": "0.0.0-test"
@ -189,7 +240,12 @@ func GrpcInitialSetParameters() string {
}
func StartAnytypeBackground() error {
runServer := exec.Command("./dist/server")
var runServer *exec.Cmd
if runtime.GOOS == "windows" {
runServer = exec.Command("./dist/server.exe")
} else {
runServer = exec.Command("./dist/server")
}
runServer.Stdout = os.Stdout
runServer.Stderr = os.Stderr
runServer.Env = append(os.Environ(), `ANYPROF=:6060`)
@ -200,7 +256,15 @@ func StartAnytypeBackground() error {
// Wait for the server to start
for {
err = ExecuteCommand(`pids=$(lsof -i :31007 -t) && [ -n "$pids" ] && echo "Found process: $pids" || { echo "No process found"; exit 1; }`)
var cmd string
if runtime.GOOS == "windows" {
cmd = `$pids = (Get-NetTCPConnection -LocalPort 31007 -State Listen -ErrorAction SilentlyContinue | Select-Object -ExpandProperty OwningProcess); if ($pids) { Write-Output "Found process: $pids" } else { Write-Output "No process found"; exit 1 }`
} else {
cmd = `pids=$(lsof -i :31007 -t) && [ -n "$pids" ] && echo "Found process: $pids" || { echo "No process found"; exit 1; }`
}
err = ExecuteCommand(cmd)
if err == nil {
break
} else {
@ -466,8 +530,18 @@ func Prepare[T BasicInputtable](prep T, f func(T) error) error {
if err != nil {
return err
}
fmt.Println("Created temporary directory:", workspace)
prep.SetWorkspace(workspace)
if runtime.GOOS == "windows" {
winWorkspace, err := WinFixPath(workspace)
if err != nil {
return err
}
fmt.Println("Created temporary directory:", winWorkspace)
prep.SetWorkspace(winWorkspace)
} else {
fmt.Println("Created temporary directory:", workspace)
prep.SetWorkspace(workspace)
}
_, err = SetupWd()
if err != nil {
@ -486,10 +560,29 @@ func Prepare[T BasicInputtable](prep T, f func(T) error) error {
}
}
err = BuildAnytype(err)
if err != nil {
return err
if runtime.GOOS == "windows" {
fmt.Printf("Build GRPC server on Windows...")
command := `
$Env:GOOS="windows";
$Env:GOARCH="amd64";
$Env:CGO_ENABLED="1";
$Env:CC="x86_64-w64-mingw32-gcc";
$Env:CXX="x86_64-w64-mingw32-g++";
go build -o dist/server.exe -ldflags "$env:FLAGS -linkmode external -extldflags=-static" --tags "noauth nosigar nowatchdog" $env:BUILD_FLAGS github.com/anyproto/anytype-heart/cmd/grpcserver
`
err := ExecuteCommand(command)
if err != nil {
fmt.Printf("Error on building: %v\n", err)
} else {
fmt.Println("Build completed successfully")
}
} else {
err = BuildAnytype(err)
if err != nil {
return err
}
}
return nil
}