408 lines
10 KiB
Go
408 lines
10 KiB
Go
// ABOUTME: Unit tests for Cloudlet management APIs using httptest mock server
|
|
// ABOUTME: Tests create, show, list, delete, manifest, and resource usage operations
|
|
|
|
package v2
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestCreateCloudlet(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input *NewCloudletInput
|
|
mockStatusCode int
|
|
mockResponse string
|
|
expectError bool
|
|
}{
|
|
{
|
|
name: "successful creation",
|
|
input: &NewCloudletInput{
|
|
Region: "us-west",
|
|
Cloudlet: Cloudlet{
|
|
Key: CloudletKey{
|
|
Organization: "cloudletorg",
|
|
Name: "testcloudlet",
|
|
},
|
|
Location: Location{
|
|
Latitude: 37.7749,
|
|
Longitude: -122.4194,
|
|
},
|
|
IpSupport: "IpSupportDynamic",
|
|
NumDynamicIps: 10,
|
|
},
|
|
},
|
|
mockStatusCode: 200,
|
|
mockResponse: `{"message": "success"}`,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "validation error",
|
|
input: &NewCloudletInput{
|
|
Region: "us-west",
|
|
Cloudlet: Cloudlet{
|
|
Key: CloudletKey{
|
|
Organization: "",
|
|
Name: "testcloudlet",
|
|
},
|
|
},
|
|
},
|
|
mockStatusCode: 400,
|
|
mockResponse: `{"message": "organization is required"}`,
|
|
expectError: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Create mock server
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
assert.Equal(t, "POST", r.Method)
|
|
assert.Equal(t, "/api/v1/auth/ctrl/CreateCloudlet", r.URL.Path)
|
|
assert.Equal(t, "application/json", r.Header.Get("Content-Type"))
|
|
|
|
w.WriteHeader(tt.mockStatusCode)
|
|
_, _ = w.Write([]byte(tt.mockResponse))
|
|
}))
|
|
defer server.Close()
|
|
|
|
// Create client
|
|
client := NewClient(server.URL,
|
|
WithHTTPClient(&http.Client{Timeout: 5 * time.Second}),
|
|
WithAuthProvider(NewStaticTokenProvider("test-token")),
|
|
)
|
|
|
|
// Execute test
|
|
ctx := context.Background()
|
|
err := client.CreateCloudlet(ctx, tt.input)
|
|
|
|
// Verify results
|
|
if tt.expectError {
|
|
assert.Error(t, err)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestShowCloudlet(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
cloudletKey CloudletKey
|
|
region string
|
|
mockStatusCode int
|
|
mockResponse string
|
|
expectError bool
|
|
expectNotFound bool
|
|
}{
|
|
{
|
|
name: "successful show",
|
|
cloudletKey: CloudletKey{
|
|
Organization: "cloudletorg",
|
|
Name: "testcloudlet",
|
|
},
|
|
region: "us-west",
|
|
mockStatusCode: 200,
|
|
mockResponse: `{"data": {"key": {"organization": "cloudletorg", "name": "testcloudlet"}, "state": "Ready", "location": {"latitude": 37.7749, "longitude": -122.4194}}}
|
|
`,
|
|
expectError: false,
|
|
expectNotFound: false,
|
|
},
|
|
{
|
|
name: "cloudlet not found",
|
|
cloudletKey: CloudletKey{
|
|
Organization: "cloudletorg",
|
|
Name: "nonexistent",
|
|
},
|
|
region: "us-west",
|
|
mockStatusCode: 404,
|
|
mockResponse: "",
|
|
expectError: true,
|
|
expectNotFound: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Create mock server
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
assert.Equal(t, "POST", r.Method)
|
|
assert.Equal(t, "/api/v1/auth/ctrl/ShowCloudlet", r.URL.Path)
|
|
|
|
w.WriteHeader(tt.mockStatusCode)
|
|
if tt.mockResponse != "" {
|
|
_, _ = w.Write([]byte(tt.mockResponse))
|
|
}
|
|
}))
|
|
defer server.Close()
|
|
|
|
// Create client
|
|
client := NewClient(server.URL,
|
|
WithHTTPClient(&http.Client{Timeout: 5 * time.Second}),
|
|
)
|
|
|
|
// Execute test
|
|
ctx := context.Background()
|
|
cloudlet, err := client.ShowCloudlet(ctx, tt.cloudletKey, tt.region)
|
|
|
|
// Verify results
|
|
if tt.expectError {
|
|
assert.Error(t, err)
|
|
if tt.expectNotFound {
|
|
assert.Contains(t, err.Error(), "resource not found")
|
|
}
|
|
} else {
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tt.cloudletKey.Organization, cloudlet.Key.Organization)
|
|
assert.Equal(t, tt.cloudletKey.Name, cloudlet.Key.Name)
|
|
assert.Equal(t, "Ready", cloudlet.State)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestShowCloudlets(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
assert.Equal(t, "POST", r.Method)
|
|
assert.Equal(t, "/api/v1/auth/ctrl/ShowCloudlet", r.URL.Path)
|
|
|
|
// Verify request body
|
|
var filter CloudletFilter
|
|
err := json.NewDecoder(r.Body).Decode(&filter)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "cloudletorg", filter.Cloudlet.Key.Organization)
|
|
assert.Equal(t, "us-west", filter.Region)
|
|
|
|
// Return multiple cloudlets
|
|
response := `{"data": {"key": {"organization": "cloudletorg", "name": "cloudlet1"}, "state": "Ready"}}
|
|
{"data": {"key": {"organization": "cloudletorg", "name": "cloudlet2"}, "state": "Creating"}}
|
|
`
|
|
w.WriteHeader(200)
|
|
_, _ = w.Write([]byte(response))
|
|
}))
|
|
defer server.Close()
|
|
|
|
client := NewClient(server.URL)
|
|
ctx := context.Background()
|
|
|
|
cloudlets, err := client.ShowCloudlets(ctx, CloudletKey{Organization: "cloudletorg"}, "us-west")
|
|
|
|
require.NoError(t, err)
|
|
assert.Len(t, cloudlets, 2)
|
|
assert.Equal(t, "cloudlet1", cloudlets[0].Key.Name)
|
|
assert.Equal(t, "Ready", cloudlets[0].State)
|
|
assert.Equal(t, "cloudlet2", cloudlets[1].Key.Name)
|
|
assert.Equal(t, "Creating", cloudlets[1].State)
|
|
}
|
|
|
|
func TestDeleteCloudlet(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
cloudletKey CloudletKey
|
|
region string
|
|
mockStatusCode int
|
|
expectError bool
|
|
}{
|
|
{
|
|
name: "successful deletion",
|
|
cloudletKey: CloudletKey{
|
|
Organization: "cloudletorg",
|
|
Name: "testcloudlet",
|
|
},
|
|
region: "us-west",
|
|
mockStatusCode: 200,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "already deleted (404 ok)",
|
|
cloudletKey: CloudletKey{
|
|
Organization: "cloudletorg",
|
|
Name: "testcloudlet",
|
|
},
|
|
region: "us-west",
|
|
mockStatusCode: 404,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "server error",
|
|
cloudletKey: CloudletKey{
|
|
Organization: "cloudletorg",
|
|
Name: "testcloudlet",
|
|
},
|
|
region: "us-west",
|
|
mockStatusCode: 500,
|
|
expectError: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
assert.Equal(t, "POST", r.Method)
|
|
assert.Equal(t, "/api/v1/auth/ctrl/DeleteCloudlet", r.URL.Path)
|
|
|
|
w.WriteHeader(tt.mockStatusCode)
|
|
}))
|
|
defer server.Close()
|
|
|
|
client := NewClient(server.URL)
|
|
ctx := context.Background()
|
|
|
|
err := client.DeleteCloudlet(ctx, tt.cloudletKey, tt.region)
|
|
|
|
if tt.expectError {
|
|
assert.Error(t, err)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetCloudletManifest(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
cloudletKey CloudletKey
|
|
region string
|
|
mockStatusCode int
|
|
mockResponse string
|
|
expectError bool
|
|
expectNotFound bool
|
|
}{
|
|
{
|
|
name: "successful manifest retrieval",
|
|
cloudletKey: CloudletKey{
|
|
Organization: "cloudletorg",
|
|
Name: "testcloudlet",
|
|
},
|
|
region: "us-west",
|
|
mockStatusCode: 200,
|
|
mockResponse: `{"manifest": "apiVersion: v1\nkind: Deployment\nmetadata:\n name: test", "last_modified": "2024-01-01T00:00:00Z"}`,
|
|
expectError: false,
|
|
expectNotFound: false,
|
|
},
|
|
{
|
|
name: "manifest not found",
|
|
cloudletKey: CloudletKey{
|
|
Organization: "cloudletorg",
|
|
Name: "nonexistent",
|
|
},
|
|
region: "us-west",
|
|
mockStatusCode: 404,
|
|
mockResponse: "",
|
|
expectError: true,
|
|
expectNotFound: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
assert.Equal(t, "POST", r.Method)
|
|
assert.Equal(t, "/api/v1/auth/ctrl/GetCloudletManifest", r.URL.Path)
|
|
|
|
w.WriteHeader(tt.mockStatusCode)
|
|
if tt.mockResponse != "" {
|
|
_, _ = w.Write([]byte(tt.mockResponse))
|
|
}
|
|
}))
|
|
defer server.Close()
|
|
|
|
client := NewClient(server.URL)
|
|
ctx := context.Background()
|
|
|
|
manifest, err := client.GetCloudletManifest(ctx, tt.cloudletKey, tt.region)
|
|
|
|
if tt.expectError {
|
|
assert.Error(t, err)
|
|
if tt.expectNotFound {
|
|
assert.Contains(t, err.Error(), "resource not found")
|
|
}
|
|
} else {
|
|
require.NoError(t, err)
|
|
assert.NotNil(t, manifest)
|
|
assert.Contains(t, manifest.Manifest, "apiVersion: v1")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetCloudletResourceUsage(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
cloudletKey CloudletKey
|
|
region string
|
|
mockStatusCode int
|
|
mockResponse string
|
|
expectError bool
|
|
expectNotFound bool
|
|
}{
|
|
{
|
|
name: "successful usage retrieval",
|
|
cloudletKey: CloudletKey{
|
|
Organization: "cloudletorg",
|
|
Name: "testcloudlet",
|
|
},
|
|
region: "us-west",
|
|
mockStatusCode: 200,
|
|
mockResponse: `{"cloudlet_key": {"organization": "cloudletorg", "name": "testcloudlet"}, "region": "us-west", "usage": {"cpu": "50%", "memory": "30%", "disk": "20%"}}`,
|
|
expectError: false,
|
|
expectNotFound: false,
|
|
},
|
|
{
|
|
name: "usage not found",
|
|
cloudletKey: CloudletKey{
|
|
Organization: "cloudletorg",
|
|
Name: "nonexistent",
|
|
},
|
|
region: "us-west",
|
|
mockStatusCode: 404,
|
|
mockResponse: "",
|
|
expectError: true,
|
|
expectNotFound: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
assert.Equal(t, "POST", r.Method)
|
|
assert.Equal(t, "/api/v1/auth/ctrl/GetCloudletResourceUsage", r.URL.Path)
|
|
|
|
w.WriteHeader(tt.mockStatusCode)
|
|
if tt.mockResponse != "" {
|
|
_, _ = w.Write([]byte(tt.mockResponse))
|
|
}
|
|
}))
|
|
defer server.Close()
|
|
|
|
client := NewClient(server.URL)
|
|
ctx := context.Background()
|
|
|
|
usage, err := client.GetCloudletResourceUsage(ctx, tt.cloudletKey, tt.region)
|
|
|
|
if tt.expectError {
|
|
assert.Error(t, err)
|
|
if tt.expectNotFound {
|
|
assert.Contains(t, err.Error(), "resource not found")
|
|
}
|
|
} else {
|
|
require.NoError(t, err)
|
|
assert.NotNil(t, usage)
|
|
assert.Equal(t, "cloudletorg", usage.CloudletKey.Organization)
|
|
assert.Equal(t, "testcloudlet", usage.CloudletKey.Name)
|
|
assert.Equal(t, "us-west", usage.Region)
|
|
assert.Contains(t, usage.Usage, "cpu")
|
|
}
|
|
})
|
|
}
|
|
}
|