chore_: test, improvements

This commit is contained in:
Igor Sirotin 2024-09-19 15:54:44 +01:00
parent 860b8dd052
commit 1acd8d8c6e
No known key found for this signature in database
GPG Key ID: 425E227CAAB81F95
4 changed files with 167 additions and 114 deletions

View File

@ -1,73 +1,76 @@
// Code generated by parse-api/main.go. DO NOT EDIT.
// source: parse-api/main.go
package server package server
import statusgo "github.com/status-im/status-go/mobile" import statusgo "github.com/status-im/status-go/mobile"
var EndpointsWithResponse = []func(string) string{ var EndpointsWithResponse = map[string]func(string) string{
statusgo.InitializeApplication, "/statusgo/InitializeApplication": statusgo.InitializeApplication,
statusgo.ExtractGroupMembershipSignatures, "/statusgo/ExtractGroupMembershipSignatures": statusgo.ExtractGroupMembershipSignatures,
statusgo.SignGroupMembership, "/statusgo/SignGroupMembership": statusgo.SignGroupMembership,
statusgo.ValidateNodeConfig, "/statusgo/ValidateNodeConfig": statusgo.ValidateNodeConfig,
statusgo.CallRPC, "/statusgo/CallRPC": statusgo.CallRPC,
statusgo.CallPrivateRPC, "/statusgo/CallPrivateRPC": statusgo.CallPrivateRPC,
statusgo.CreateAccountAndLogin, "/statusgo/CreateAccountAndLogin": statusgo.CreateAccountAndLogin,
statusgo.LoginAccount, "/statusgo/LoginAccount": statusgo.LoginAccount,
statusgo.RestoreAccountAndLogin, "/statusgo/RestoreAccountAndLogin": statusgo.RestoreAccountAndLogin,
statusgo.InitKeystore, "/statusgo/InitKeystore": statusgo.InitKeystore,
statusgo.SignMessage, "/statusgo/SignMessage": statusgo.SignMessage,
statusgo.HashTypedData, "/statusgo/HashTypedData": statusgo.HashTypedData,
statusgo.HashTypedDataV4, "/statusgo/HashTypedDataV4": statusgo.HashTypedDataV4,
statusgo.Recover, "/statusgo/Recover": statusgo.Recover,
statusgo.HashTransaction, "/statusgo/HashTransaction": statusgo.HashTransaction,
statusgo.HashMessage, "/statusgo/HashMessage": statusgo.HashMessage,
statusgo.StartCPUProfile, "/statusgo/StartCPUProfile": statusgo.StartCPUProfile,
statusgo.WriteHeapProfile, "/statusgo/WriteHeapProfile": statusgo.WriteHeapProfile,
statusgo.AddPeer, "/statusgo/AddPeer": statusgo.AddPeer,
statusgo.SignHash, "/statusgo/SignHash": statusgo.SignHash,
statusgo.GenerateAlias, "/statusgo/GenerateAlias": statusgo.GenerateAlias,
statusgo.IsAlias, "/statusgo/IsAlias": statusgo.IsAlias,
statusgo.Identicon, "/statusgo/Identicon": statusgo.Identicon,
statusgo.EmojiHash, "/statusgo/EmojiHash": statusgo.EmojiHash,
statusgo.ColorHash, "/statusgo/ColorHash": statusgo.ColorHash,
statusgo.ColorID, "/statusgo/ColorID": statusgo.ColorID,
statusgo.ValidateMnemonic, "/statusgo/ValidateMnemonic": statusgo.ValidateMnemonic,
statusgo.DecompressPublicKey, "/statusgo/DecompressPublicKey": statusgo.DecompressPublicKey,
statusgo.CompressPublicKey, "/statusgo/CompressPublicKey": statusgo.CompressPublicKey,
statusgo.SerializeLegacyKey, "/statusgo/SerializeLegacyKey": statusgo.SerializeLegacyKey,
statusgo.GetPasswordStrength, "/statusgo/GetPasswordStrength": statusgo.GetPasswordStrength,
statusgo.GetPasswordStrengthScore, "/statusgo/GetPasswordStrengthScore": statusgo.GetPasswordStrengthScore,
statusgo.GetConnectionStringForBeingBootstrapped, "/statusgo/GetConnectionStringForBeingBootstrapped": statusgo.GetConnectionStringForBeingBootstrapped,
statusgo.GetConnectionStringForBootstrappingAnotherDevice, "/statusgo/GetConnectionStringForBootstrappingAnotherDevice": statusgo.GetConnectionStringForBootstrappingAnotherDevice,
statusgo.GetConnectionStringForExportingKeypairsKeystores, "/statusgo/GetConnectionStringForExportingKeypairsKeystores": statusgo.GetConnectionStringForExportingKeypairsKeystores,
statusgo.ValidateConnectionString, "/statusgo/ValidateConnectionString": statusgo.ValidateConnectionString,
statusgo.DecodeParameters, "/statusgo/DecodeParameters": statusgo.DecodeParameters,
statusgo.HexToNumber, "/statusgo/HexToNumber": statusgo.HexToNumber,
statusgo.NumberToHex, "/statusgo/NumberToHex": statusgo.NumberToHex,
statusgo.Sha3, "/statusgo/Sha3": statusgo.Sha3,
statusgo.Utf8ToHex, "/statusgo/Utf8ToHex": statusgo.Utf8ToHex,
statusgo.HexToUtf8, "/statusgo/HexToUtf8": statusgo.HexToUtf8,
statusgo.CheckAddressChecksum, "/statusgo/CheckAddressChecksum": statusgo.CheckAddressChecksum,
statusgo.IsAddress, "/statusgo/IsAddress": statusgo.IsAddress,
statusgo.ToChecksumAddress, "/statusgo/ToChecksumAddress": statusgo.ToChecksumAddress,
statusgo.DeserializeAndCompressKey, "/statusgo/DeserializeAndCompressKey": statusgo.DeserializeAndCompressKey,
statusgo.InitLogging, "/statusgo/InitLogging": statusgo.InitLogging,
statusgo.ToggleCentralizedMetrics, "/statusgo/ToggleCentralizedMetrics": statusgo.ToggleCentralizedMetrics,
statusgo.AddCentralizedMetric, "/statusgo/AddCentralizedMetric": statusgo.AddCentralizedMetric,
} }
var EndpointsNoRequest = []func() string{ var EndpointsNoRequest = map[string]func() string{
statusgo.GetNodeConfig, "/statusgo/GetNodeConfig": statusgo.GetNodeConfig,
statusgo.ResetChainData, "/statusgo/ResetChainData": statusgo.ResetChainData,
statusgo.Logout, "/statusgo/Logout": statusgo.Logout,
statusgo.StopCPUProfiling, "/statusgo/StopCPUProfiling": statusgo.StopCPUProfiling,
statusgo.StartLocalNotifications, "/statusgo/StartLocalNotifications": statusgo.StartLocalNotifications,
statusgo.StopLocalNotifications, "/statusgo/StopLocalNotifications": statusgo.StopLocalNotifications,
statusgo.ExportNodeLogs, "/statusgo/ExportNodeLogs": statusgo.ExportNodeLogs,
statusgo.ImageServerTLSCert, "/statusgo/ImageServerTLSCert": statusgo.ImageServerTLSCert,
statusgo.Fleets, "/statusgo/Fleets": statusgo.Fleets,
statusgo.LocalPairingPreflightOutboundCheck, "/statusgo/LocalPairingPreflightOutboundCheck": statusgo.LocalPairingPreflightOutboundCheck,
statusgo.StartSearchForLocalPairingPeers, "/statusgo/StartSearchForLocalPairingPeers": statusgo.StartSearchForLocalPairingPeers,
statusgo.GetRandomMnemonic, "/statusgo/GetRandomMnemonic": statusgo.GetRandomMnemonic,
statusgo.CentralizedMetricsInfo, "/statusgo/CentralizedMetricsInfo": statusgo.CentralizedMetricsInfo,
} }
var EndpointsUnsupported = []string{ var EndpointsUnsupported = []string{

View File

@ -1,16 +1,19 @@
// Code generated by parse-api/main.go. DO NOT EDIT.
// source: parse-api/main.go
package server package server
import statusgo "github.com/status-im/status-go/mobile" import statusgo "github.com/status-im/status-go/mobile"
var EndpointsWithResponse = []func(string) string{ var EndpointsWithResponse = map[string]func(string) string{
{{- range .FunctionsWithResp }} {{- range .FunctionsWithResp }}
{{ $.PackageName }}.{{ . }}, "/{{ $.PackageName }}/{{ . }}": {{ $.PackageName }}.{{ . }},
{{- end }} {{- end }}
} }
var EndpointsNoRequest = []func() string{ var EndpointsNoRequest = map[string]func() string{
{{- range .FunctionsNoArgs }} {{- range .FunctionsNoArgs }}
{{ $.PackageName }}.{{ . }}, "/{{ $.PackageName }}/{{ . }}": {{ $.PackageName }}.{{ . }},
{{- end }} {{- end }}
} }

View File

@ -3,13 +3,10 @@ package server
import ( import (
"context" "context"
"errors" "errors"
"fmt"
"io" "io"
"net" "net"
"net/http" "net/http"
"reflect" "strconv"
"runtime"
"strings"
"sync" "sync"
"time" "time"
@ -39,6 +36,14 @@ func (s *Server) Address() string {
return s.address return s.address
} }
func (s *Server) Port() (int, error) {
_, portString, err := net.SplitHostPort(s.address)
if err != nil {
return 0, err
}
return strconv.Atoi(portString)
}
func (s *Server) Setup() { func (s *Server) Setup() {
signal.SetMobileSignalHandler(s.signalHandler) signal.SetMobileSignalHandler(s.signalHandler)
} }
@ -124,10 +129,9 @@ func (s *Server) signals(w http.ResponseWriter, r *http.Request) {
s.connections[connection] = struct{}{} s.connections[connection] = struct{}{}
} }
func (s *Server) addEndpointWithResponse(handler func(string) string) { func (s *Server) addEndpointWithResponse(name string, handler func(string) string) {
endpoint := endpointName(functionName(handler)) log.Info("adding endpoint", "name", name)
log.Debug("adding endpoint", "name", endpoint) s.mux.HandleFunc(name, func(w http.ResponseWriter, r *http.Request) {
s.mux.HandleFunc(endpoint, func(w http.ResponseWriter, r *http.Request) {
request, err := io.ReadAll(r.Body) request, err := io.ReadAll(r.Body)
if err != nil { if err != nil {
log.Error("failed to read request: %w", err) log.Error("failed to read request: %w", err)
@ -143,10 +147,9 @@ func (s *Server) addEndpointWithResponse(handler func(string) string) {
}) })
} }
func (s *Server) addEndpointNoRequest(handler func() string) { func (s *Server) addEndpointNoRequest(name string, handler func() string) {
endpoint := endpointName(functionName(handler)) log.Debug("adding endpoint", "name", name)
log.Debug("adding endpoint", "name", endpoint) s.mux.HandleFunc(name, func(w http.ResponseWriter, r *http.Request) {
s.mux.HandleFunc(endpoint, func(w http.ResponseWriter, r *http.Request) {
response := handler() response := handler()
_, err := w.Write([]byte(response)) _, err := w.Write([]byte(response))
@ -157,34 +160,20 @@ func (s *Server) addEndpointNoRequest(handler func() string) {
} }
func (s *Server) addUnsupportedEndpoint(name string) { func (s *Server) addUnsupportedEndpoint(name string) {
endpoint := endpointName(name) log.Debug("marking unsupported endpoint", "name", name)
log.Debug("marking unsupported endpoint", "name", endpoint) s.mux.HandleFunc(name, func(w http.ResponseWriter, r *http.Request) {
s.mux.HandleFunc(endpoint, func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotImplemented) w.WriteHeader(http.StatusNotImplemented)
}) })
} }
func (s *Server) RegisterMobileAPI() { func (s *Server) RegisterMobileAPI() {
for _, endpoint := range EndpointsWithResponse { for name, endpoint := range EndpointsWithResponse {
s.addEndpointWithResponse(endpoint) s.addEndpointWithResponse(name, endpoint)
} }
for _, endpoint := range EndpointsNoRequest { for name, endpoint := range EndpointsNoRequest {
s.addEndpointNoRequest(endpoint) s.addEndpointNoRequest(name, endpoint)
} }
for _, endpoint := range EndpointsUnsupported { for _, name := range EndpointsUnsupported {
s.addUnsupportedEndpoint(endpoint) s.addUnsupportedEndpoint(name)
} }
} }
func functionName(fn any) string {
fullName := runtime.FuncForPC(reflect.ValueOf(fn).Pointer()).Name()
parts := strings.Split(fullName, "/")
lastPart := parts[len(parts)-1]
nameParts := strings.Split(lastPart, ".")
return nameParts[len(nameParts)-1]
}
func endpointName(functionName string) string {
const base = "statusgo"
return fmt.Sprintf("/%s/%s", base, functionName)
}

View File

@ -1,9 +1,12 @@
package server package server
import ( import (
"bytes"
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
"net/http"
"net/url" "net/url"
"testing" "testing"
"time" "time"
@ -16,24 +19,37 @@ import (
"github.com/status-im/status-go/signal" "github.com/status-im/status-go/signal"
) )
func TestSignalsServer(t *testing.T) { func setupServer(t *testing.T) (*Server, string) {
server := NewServer() srv := NewServer()
server.Setup() srv.Setup()
err := server.Listen("localhost:0") err := srv.Listen("localhost:0")
require.NoError(t, err) require.NoError(t, err)
defer func() {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
server.Stop(ctx)
}()
addr := server.Address() addr := srv.Address()
serverURLString := fmt.Sprintf("ws://%s", addr)
// Check URL
serverURLString := fmt.Sprintf("http://%s", addr)
serverURL, err := url.Parse(serverURLString) serverURL, err := url.Parse(serverURLString)
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, serverURL)
require.NotZero(t, serverURL.Port()) require.NotZero(t, serverURL.Port())
connection, _, err := websocket.DefaultDialer.Dial(serverURLString+"/signals", nil) return srv, addr
}
func shutdownServer(srv *Server) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
srv.Stop(ctx)
}
func TestSignals(t *testing.T) {
srv, serverURLString := setupServer(t)
go srv.Serve()
defer shutdownServer(srv)
signalsURL := fmt.Sprintf("ws://%s/signals", serverURLString)
connection, _, err := websocket.DefaultDialer.Dial(signalsURL, nil)
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, connection) require.NotNil(t, connection)
defer func() { defer func() {
@ -68,6 +84,48 @@ func TestSignalsServer(t *testing.T) {
require.Equal(t, sentEvent, receivedEvent) require.Equal(t, sentEvent, receivedEvent)
} }
func TestMobileAPI(t *testing.T) {
const method = "/echo"
randomResponsePostfix := randomAlphabeticalString(t, 5)
endpointsWithResponse := EndpointsWithResponse
endpointsNoRequest := EndpointsNoRequest
endpointsUnsupported := EndpointsUnsupported
t.Cleanup(func() {
EndpointsWithResponse = endpointsWithResponse
EndpointsNoRequest = endpointsNoRequest
EndpointsUnsupported = endpointsUnsupported
})
EndpointsWithResponse = map[string]func(string) string{
method: func(request string) string {
return request + randomResponsePostfix
},
}
srv, _ := setupServer(t)
defer shutdownServer(srv)
go srv.Serve()
srv.RegisterMobileAPI()
requestBody := []byte(randomAlphabeticalString(t, 5))
bodyReader := bytes.NewReader(requestBody)
port, err := srv.Port()
require.NoError(t, err)
requestURL := fmt.Sprintf("http://127.0.0.1:%d%s", port, method)
resp, err := http.Post(requestURL, "application/text", bodyReader)
require.NoError(t, err)
require.NotNil(t, resp)
responseBody, err := io.ReadAll(resp.Body)
require.NoError(t, err)
require.Equal(t, 200, resp.StatusCode)
require.Equal(t, string(requestBody)+randomResponsePostfix, string(responseBody))
}
func randomAlphabeticalString(t *testing.T, n int) string { func randomAlphabeticalString(t *testing.T, n int) string {
s, err := common.RandomAlphabeticalString(n) s, err := common.RandomAlphabeticalString(n)
require.NoError(t, err) require.NoError(t, err)