mirror of
https://github.com/DeBrosOfficial/network.git
synced 2025-12-11 07:38:49 +00:00
- Added new E2E tests for authentication, cache operations, and IPFS interactions to improve coverage and reliability. - Introduced concurrency tests for cache operations to validate performance under load. - Updated `go.mod` to include `github.com/mattn/go-sqlite3` as a dependency for database interactions. - Refined Makefile to simplify E2E test execution and configuration discovery. - Removed outdated client E2E tests and consolidated related functionality for better maintainability.
512 lines
11 KiB
Go
512 lines
11 KiB
Go
//go:build e2e
|
|
|
|
package e2e
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestCache_Health(t *testing.T) {
|
|
SkipIfMissingGateway(t)
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
defer cancel()
|
|
|
|
req := &HTTPRequest{
|
|
Method: http.MethodGet,
|
|
URL: GetGatewayURL() + "/v1/cache/health",
|
|
}
|
|
|
|
body, status, err := req.Do(ctx)
|
|
if err != nil {
|
|
t.Fatalf("health check failed: %v", err)
|
|
}
|
|
|
|
if status != http.StatusOK {
|
|
t.Fatalf("expected status 200, got %d", status)
|
|
}
|
|
|
|
var resp map[string]interface{}
|
|
if err := DecodeJSON(body, &resp); err != nil {
|
|
t.Fatalf("failed to decode response: %v", err)
|
|
}
|
|
|
|
if resp["status"] != "ok" {
|
|
t.Fatalf("expected status 'ok', got %v", resp["status"])
|
|
}
|
|
|
|
if resp["service"] != "olric" {
|
|
t.Fatalf("expected service 'olric', got %v", resp["service"])
|
|
}
|
|
}
|
|
|
|
func TestCache_PutGet(t *testing.T) {
|
|
SkipIfMissingGateway(t)
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
defer cancel()
|
|
|
|
dmap := GenerateDMapName()
|
|
key := "test-key"
|
|
value := "test-value"
|
|
|
|
// Put value
|
|
putReq := &HTTPRequest{
|
|
Method: http.MethodPost,
|
|
URL: GetGatewayURL() + "/v1/cache/put",
|
|
Body: map[string]interface{}{
|
|
"dmap": dmap,
|
|
"key": key,
|
|
"value": value,
|
|
},
|
|
}
|
|
|
|
body, status, err := putReq.Do(ctx)
|
|
if err != nil {
|
|
t.Fatalf("put failed: %v", err)
|
|
}
|
|
|
|
if status != http.StatusOK {
|
|
t.Fatalf("expected status 200, got %d: %s", status, string(body))
|
|
}
|
|
|
|
// Get value
|
|
getReq := &HTTPRequest{
|
|
Method: http.MethodPost,
|
|
URL: GetGatewayURL() + "/v1/cache/get",
|
|
Body: map[string]interface{}{
|
|
"dmap": dmap,
|
|
"key": key,
|
|
},
|
|
}
|
|
|
|
body, status, err = getReq.Do(ctx)
|
|
if err != nil {
|
|
t.Fatalf("get failed: %v", err)
|
|
}
|
|
|
|
if status != http.StatusOK {
|
|
t.Fatalf("expected status 200, got %d", status)
|
|
}
|
|
|
|
var getResp map[string]interface{}
|
|
if err := DecodeJSON(body, &getResp); err != nil {
|
|
t.Fatalf("failed to decode response: %v", err)
|
|
}
|
|
|
|
if getResp["value"] != value {
|
|
t.Fatalf("expected value %q, got %v", value, getResp["value"])
|
|
}
|
|
}
|
|
|
|
func TestCache_PutGetJSON(t *testing.T) {
|
|
SkipIfMissingGateway(t)
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
defer cancel()
|
|
|
|
dmap := GenerateDMapName()
|
|
key := "json-key"
|
|
jsonValue := map[string]interface{}{
|
|
"name": "John",
|
|
"age": 30,
|
|
"tags": []string{"developer", "golang"},
|
|
}
|
|
|
|
// Put JSON value
|
|
putReq := &HTTPRequest{
|
|
Method: http.MethodPost,
|
|
URL: GetGatewayURL() + "/v1/cache/put",
|
|
Body: map[string]interface{}{
|
|
"dmap": dmap,
|
|
"key": key,
|
|
"value": jsonValue,
|
|
},
|
|
}
|
|
|
|
_, status, err := putReq.Do(ctx)
|
|
if err != nil {
|
|
t.Fatalf("put failed: %v", err)
|
|
}
|
|
|
|
if status != http.StatusOK {
|
|
t.Fatalf("expected status 200, got %d", status)
|
|
}
|
|
|
|
// Get JSON value
|
|
getReq := &HTTPRequest{
|
|
Method: http.MethodPost,
|
|
URL: GetGatewayURL() + "/v1/cache/get",
|
|
Body: map[string]interface{}{
|
|
"dmap": dmap,
|
|
"key": key,
|
|
},
|
|
}
|
|
|
|
body, status, err := getReq.Do(ctx)
|
|
if err != nil {
|
|
t.Fatalf("get failed: %v", err)
|
|
}
|
|
|
|
if status != http.StatusOK {
|
|
t.Fatalf("expected status 200, got %d", status)
|
|
}
|
|
|
|
var getResp map[string]interface{}
|
|
if err := DecodeJSON(body, &getResp); err != nil {
|
|
t.Fatalf("failed to decode response: %v", err)
|
|
}
|
|
|
|
retrievedValue := getResp["value"].(map[string]interface{})
|
|
if retrievedValue["name"] != jsonValue["name"] {
|
|
t.Fatalf("expected name %q, got %v", jsonValue["name"], retrievedValue["name"])
|
|
}
|
|
if retrievedValue["age"] != float64(30) {
|
|
t.Fatalf("expected age 30, got %v", retrievedValue["age"])
|
|
}
|
|
}
|
|
|
|
func TestCache_Delete(t *testing.T) {
|
|
SkipIfMissingGateway(t)
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
defer cancel()
|
|
|
|
dmap := GenerateDMapName()
|
|
key := "delete-key"
|
|
value := "delete-value"
|
|
|
|
// Put value
|
|
putReq := &HTTPRequest{
|
|
Method: http.MethodPost,
|
|
URL: GetGatewayURL() + "/v1/cache/put",
|
|
Body: map[string]interface{}{
|
|
"dmap": dmap,
|
|
"key": key,
|
|
"value": value,
|
|
},
|
|
}
|
|
|
|
_, status, err := putReq.Do(ctx)
|
|
if err != nil || status != http.StatusOK {
|
|
t.Fatalf("put failed: status %d, err %v", status, err)
|
|
}
|
|
|
|
// Delete value
|
|
deleteReq := &HTTPRequest{
|
|
Method: http.MethodPost,
|
|
URL: GetGatewayURL() + "/v1/cache/delete",
|
|
Body: map[string]interface{}{
|
|
"dmap": dmap,
|
|
"key": key,
|
|
},
|
|
}
|
|
|
|
_, status, err = deleteReq.Do(ctx)
|
|
if err != nil {
|
|
t.Fatalf("delete failed: %v", err)
|
|
}
|
|
|
|
if status != http.StatusOK {
|
|
t.Fatalf("expected status 200, got %d", status)
|
|
}
|
|
|
|
// Verify deletion
|
|
getReq := &HTTPRequest{
|
|
Method: http.MethodPost,
|
|
URL: GetGatewayURL() + "/v1/cache/get",
|
|
Body: map[string]interface{}{
|
|
"dmap": dmap,
|
|
"key": key,
|
|
},
|
|
}
|
|
|
|
_, status, err = getReq.Do(ctx)
|
|
// Should get 404 for missing key
|
|
if status != http.StatusNotFound {
|
|
t.Fatalf("expected status 404 for deleted key, got %d", status)
|
|
}
|
|
}
|
|
|
|
func TestCache_TTL(t *testing.T) {
|
|
SkipIfMissingGateway(t)
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
defer cancel()
|
|
|
|
dmap := GenerateDMapName()
|
|
key := "ttl-key"
|
|
value := "ttl-value"
|
|
|
|
// Put value with TTL
|
|
putReq := &HTTPRequest{
|
|
Method: http.MethodPost,
|
|
URL: GetGatewayURL() + "/v1/cache/put",
|
|
Body: map[string]interface{}{
|
|
"dmap": dmap,
|
|
"key": key,
|
|
"value": value,
|
|
"ttl": "2s",
|
|
},
|
|
}
|
|
|
|
_, status, err := putReq.Do(ctx)
|
|
if err != nil {
|
|
t.Fatalf("put with TTL failed: %v", err)
|
|
}
|
|
|
|
if status != http.StatusOK {
|
|
t.Fatalf("expected status 200, got %d", status)
|
|
}
|
|
|
|
// Verify value exists
|
|
getReq := &HTTPRequest{
|
|
Method: http.MethodPost,
|
|
URL: GetGatewayURL() + "/v1/cache/get",
|
|
Body: map[string]interface{}{
|
|
"dmap": dmap,
|
|
"key": key,
|
|
},
|
|
}
|
|
|
|
_, status, err = getReq.Do(ctx)
|
|
if err != nil || status != http.StatusOK {
|
|
t.Fatalf("get immediately after put failed: status %d, err %v", status, err)
|
|
}
|
|
|
|
// Wait for TTL expiry (2 seconds + buffer)
|
|
Delay(2500)
|
|
|
|
// Verify value is expired
|
|
_, status, err = getReq.Do(ctx)
|
|
if status != http.StatusNotFound {
|
|
t.Logf("warning: TTL expiry may not be fully implemented; got status %d", status)
|
|
}
|
|
}
|
|
|
|
func TestCache_Scan(t *testing.T) {
|
|
SkipIfMissingGateway(t)
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
defer cancel()
|
|
|
|
dmap := GenerateDMapName()
|
|
|
|
// Put multiple keys
|
|
keys := []string{"user-1", "user-2", "session-1", "session-2"}
|
|
for _, key := range keys {
|
|
putReq := &HTTPRequest{
|
|
Method: http.MethodPost,
|
|
URL: GetGatewayURL() + "/v1/cache/put",
|
|
Body: map[string]interface{}{
|
|
"dmap": dmap,
|
|
"key": key,
|
|
"value": "value-" + key,
|
|
},
|
|
}
|
|
|
|
_, status, err := putReq.Do(ctx)
|
|
if err != nil || status != http.StatusOK {
|
|
t.Fatalf("put failed: status %d, err %v", status, err)
|
|
}
|
|
}
|
|
|
|
// Scan all keys
|
|
scanReq := &HTTPRequest{
|
|
Method: http.MethodPost,
|
|
URL: GetGatewayURL() + "/v1/cache/scan",
|
|
Body: map[string]interface{}{
|
|
"dmap": dmap,
|
|
},
|
|
}
|
|
|
|
body, status, err := scanReq.Do(ctx)
|
|
if err != nil {
|
|
t.Fatalf("scan failed: %v", err)
|
|
}
|
|
|
|
if status != http.StatusOK {
|
|
t.Fatalf("expected status 200, got %d", status)
|
|
}
|
|
|
|
var scanResp map[string]interface{}
|
|
if err := DecodeJSON(body, &scanResp); err != nil {
|
|
t.Fatalf("failed to decode response: %v", err)
|
|
}
|
|
|
|
keysResp := scanResp["keys"].([]interface{})
|
|
if len(keysResp) < 4 {
|
|
t.Fatalf("expected at least 4 keys, got %d", len(keysResp))
|
|
}
|
|
}
|
|
|
|
func TestCache_ScanWithRegex(t *testing.T) {
|
|
SkipIfMissingGateway(t)
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
defer cancel()
|
|
|
|
dmap := GenerateDMapName()
|
|
|
|
// Put keys with different patterns
|
|
keys := []string{"user-1", "user-2", "session-1", "session-2"}
|
|
for _, key := range keys {
|
|
putReq := &HTTPRequest{
|
|
Method: http.MethodPost,
|
|
URL: GetGatewayURL() + "/v1/cache/put",
|
|
Body: map[string]interface{}{
|
|
"dmap": dmap,
|
|
"key": key,
|
|
"value": "value-" + key,
|
|
},
|
|
}
|
|
|
|
_, status, err := putReq.Do(ctx)
|
|
if err != nil || status != http.StatusOK {
|
|
t.Fatalf("put failed: status %d, err %v", status, err)
|
|
}
|
|
}
|
|
|
|
// Scan with regex pattern
|
|
scanReq := &HTTPRequest{
|
|
Method: http.MethodPost,
|
|
URL: GetGatewayURL() + "/v1/cache/scan",
|
|
Body: map[string]interface{}{
|
|
"dmap": dmap,
|
|
"pattern": "^user-",
|
|
},
|
|
}
|
|
|
|
body, status, err := scanReq.Do(ctx)
|
|
if err != nil {
|
|
t.Fatalf("scan with regex failed: %v", err)
|
|
}
|
|
|
|
if status != http.StatusOK {
|
|
t.Fatalf("expected status 200, got %d", status)
|
|
}
|
|
|
|
var scanResp map[string]interface{}
|
|
if err := DecodeJSON(body, &scanResp); err != nil {
|
|
t.Fatalf("failed to decode response: %v", err)
|
|
}
|
|
|
|
keysResp := scanResp["keys"].([]interface{})
|
|
if len(keysResp) < 2 {
|
|
t.Fatalf("expected at least 2 keys matching pattern, got %d", len(keysResp))
|
|
}
|
|
}
|
|
|
|
func TestCache_MultiGet(t *testing.T) {
|
|
SkipIfMissingGateway(t)
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
defer cancel()
|
|
|
|
dmap := GenerateDMapName()
|
|
keys := []string{"key-1", "key-2", "key-3"}
|
|
|
|
// Put values
|
|
for i, key := range keys {
|
|
putReq := &HTTPRequest{
|
|
Method: http.MethodPost,
|
|
URL: GetGatewayURL() + "/v1/cache/put",
|
|
Body: map[string]interface{}{
|
|
"dmap": dmap,
|
|
"key": key,
|
|
"value": fmt.Sprintf("value-%d", i),
|
|
},
|
|
}
|
|
|
|
_, status, err := putReq.Do(ctx)
|
|
if err != nil || status != http.StatusOK {
|
|
t.Fatalf("put failed: status %d, err %v", status, err)
|
|
}
|
|
}
|
|
|
|
// Multi-get
|
|
multiGetReq := &HTTPRequest{
|
|
Method: http.MethodPost,
|
|
URL: GetGatewayURL() + "/v1/cache/mget",
|
|
Body: map[string]interface{}{
|
|
"dmap": dmap,
|
|
"keys": keys,
|
|
},
|
|
}
|
|
|
|
body, status, err := multiGetReq.Do(ctx)
|
|
if err != nil {
|
|
t.Fatalf("mget failed: %v", err)
|
|
}
|
|
|
|
if status != http.StatusOK {
|
|
t.Fatalf("expected status 200, got %d", status)
|
|
}
|
|
|
|
var mgetResp map[string]interface{}
|
|
if err := DecodeJSON(body, &mgetResp); err != nil {
|
|
t.Fatalf("failed to decode response: %v", err)
|
|
}
|
|
|
|
results := mgetResp["results"].([]interface{})
|
|
if len(results) != 3 {
|
|
t.Fatalf("expected 3 results, got %d", len(results))
|
|
}
|
|
}
|
|
|
|
func TestCache_MissingDMap(t *testing.T) {
|
|
SkipIfMissingGateway(t)
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
defer cancel()
|
|
|
|
getReq := &HTTPRequest{
|
|
Method: http.MethodPost,
|
|
URL: GetGatewayURL() + "/v1/cache/get",
|
|
Body: map[string]interface{}{
|
|
"dmap": "",
|
|
"key": "any-key",
|
|
},
|
|
}
|
|
|
|
_, status, err := getReq.Do(ctx)
|
|
if err != nil {
|
|
t.Fatalf("request failed: %v", err)
|
|
}
|
|
|
|
if status != http.StatusBadRequest {
|
|
t.Fatalf("expected status 400 for missing dmap, got %d", status)
|
|
}
|
|
}
|
|
|
|
func TestCache_MissingKey(t *testing.T) {
|
|
SkipIfMissingGateway(t)
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
defer cancel()
|
|
|
|
dmap := GenerateDMapName()
|
|
|
|
getReq := &HTTPRequest{
|
|
Method: http.MethodPost,
|
|
URL: GetGatewayURL() + "/v1/cache/get",
|
|
Body: map[string]interface{}{
|
|
"dmap": dmap,
|
|
"key": "non-existent-key",
|
|
},
|
|
}
|
|
|
|
_, status, err := getReq.Do(ctx)
|
|
if err != nil {
|
|
t.Fatalf("request failed: %v", err)
|
|
}
|
|
|
|
if status != http.StatusNotFound {
|
|
t.Fatalf("expected status 404 for missing key, got %d", status)
|
|
}
|
|
}
|