diff --git a/.gitignore b/.gitignore index 1b37ea61..64cc9d45 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,9 @@ kubeconfig_* .local dist providers + +# ignore for mock api server +mock_server.crt +mock_server.key +MockBuild +mock_api_server.log \ No newline at end of file diff --git a/go.mod b/go.mod index 8a1ef173..c3766d77 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.22.5 require ( github.com/go-openapi/strfmt v0.23.0 github.com/google/go-cmp v0.6.0 + github.com/gorilla/mux v1.8.0 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 github.com/hashicorp/terraform-plugin-docs v0.16.0 github.com/hashicorp/terraform-plugin-sdk/v2 v2.30.0 diff --git a/go.sum b/go.sum index 977c1f3c..56836701 100644 --- a/go.sum +++ b/go.sum @@ -319,6 +319,7 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= diff --git a/spectrocloud/common_test.go b/spectrocloud/common_test.go index a1ed154e..3a89f1f6 100644 --- a/spectrocloud/common_test.go +++ b/spectrocloud/common_test.go @@ -1,61 +1,189 @@ package spectrocloud import ( + "context" + "crypto/tls" + "errors" "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/spectrocloud/palette-sdk-go/client" + "net/http" "os" + "os/exec" + "path/filepath" "testing" + "time" ) -type Cred struct { - hubbleHost string - project string - apikey string - component string - AlertUid string -} +//type Cred struct { +// hubbleHost string +// project string +// apikey string +// component string +// AlertUid string +//} + +const ( + negativeHost = "127.0.0.1:8888" + host = "127.0.0.1:8080" + trace = false + retryAttempts = 10 + apiKey = "12345" + projectName = "unittest" + projectUID = "testprojectuid" +) -var baseConfig Cred +// var baseConfig Cred +var unitTestMockAPIClient interface{} +var unitTestMockAPINegativeClient interface{} + +var basePath = "" +var startMockApiServerScript = "" +var stopMockApiServerScript = "" func TestMain(m *testing.M) { - setup() + cwd, _ := os.Getwd() + _ = os.Setenv("TF_SRC", filepath.Dir(cwd)) + basePath = os.Getenv("TF_SRC") + startMockApiServerScript = basePath + "/tests/mockApiServer/start_mock_api_server.sh" + stopMockApiServerScript = basePath + "/tests/mockApiServer/stop_mock_api_server.sh" + + err := setup() + if err != nil { + fmt.Printf("Error during setup: %v\n", err) + os.Exit(1) + } code := m.Run() teardown() os.Exit(code) } -func setup() { - // Setting up test credentials & base config from env variables - baseConfig.hubbleHost = getEnvWithFallBack("TEST_HOST") - baseConfig.project = getEnvWithFallBack("TEST_PROJECT") - baseConfig.apikey = getEnvWithFallBack("TEST_API_KEY") - baseConfig.component = "ClusterHealth" - baseConfig.AlertUid = "" - if IsIntegrationTestEnvSet(baseConfig) { - fmt.Printf("\033[1;36m%s\033[0m", "> Credentials & Base config setup completed\n") - fmt.Printf("\033[1;36m%s\033[0m", "-- Test Runnig with below crdentials & base config\n") - fmt.Printf("* Test host - %s \n", baseConfig.hubbleHost) - fmt.Printf("* Test project - %s \n", baseConfig.project) - fmt.Printf("* Test key - %s \n", "***********************") - fmt.Printf("\033[1;36m%s\033[0m", "-------------------------------\n") - } else { - fmt.Printf("\033[1;36m%s\033[0m", "> Since env variable not sipping integration test\n") - } - fmt.Printf("\033[1;36m%s\033[0m", "> Setup completed \n") +func unitTestProviderConfigure(ctx context.Context) (interface{}, diag.Diagnostics) { + host := host + apiKey := apiKey + retryAttempts := retryAttempts + + // Warning or errors can be collected in a slice type + var diags diag.Diagnostics + + c := client.New( + client.WithPaletteURI(host), + client.WithAPIKey(apiKey), + client.WithRetries(retryAttempts), + client.WithInsecureSkipVerify(true), + client.WithRetries(1)) + + //// comment to trace flag + //client.WithTransportDebug()(c) + + uid := projectUID + ProviderInitProjectUid = uid + client.WithScopeProject(uid)(c) + return c, diags +} + +func unitTestNegativeCaseProviderConfigure(ctx context.Context) (interface{}, diag.Diagnostics) { + apiKey := apiKey + retryAttempts := retryAttempts + + // Warning or errors can be collected in a slice type + var diags diag.Diagnostics + + c := client.New( + client.WithPaletteURI(negativeHost), + client.WithAPIKey(apiKey), + client.WithRetries(retryAttempts), + client.WithInsecureSkipVerify(true), + client.WithRetries(1)) + + //// comment to trace flag + //client.WithTransportDebug()(c) + + uid := projectUID + ProviderInitProjectUid = uid + client.WithScopeProject(uid)(c) + return c, diags } -func IsIntegrationTestEnvSet(config Cred) (envSet bool) { - if config.hubbleHost != "" && config.project != "" && config.apikey != "" { - return true - } else { - return false + +func checkMockServerHealth() error { + maxRetries := 5 + delay := 2 * time.Second + + // Skip TLS verification (use with caution; not recommended for production) + tr := &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } + c := &http.Client{Transport: tr} + + for i := 0; i < maxRetries; i++ { + // Create a new HTTP request + req, err := http.NewRequest("GET", "https://127.0.0.1:8080/v1/health", nil) + if err != nil { + return err + } + + // Add the API key as a header + req.Header.Set("ApiKey", "12345") + + // Send the request + resp, err := c.Do(req) + if err == nil && resp.StatusCode == http.StatusOK { + // Server is up and running + err := resp.Body.Close() + if err != nil { + return err + } + return nil + } + + if resp != nil { + err := resp.Body.Close() + if err != nil { + return err + } + } + + // Wait before retrying + time.Sleep(delay) + } + + return errors.New("server is not responding after multiple attempts") } -func getEnvWithFallBack(key string) (response string) { - value := os.Getenv(key) - if len(value) == 0 { - return "" + +func setup() error { + fmt.Printf("\033[1;36m%s\033[0m", "> Starting Mock API Server \n") + var ctx context.Context + + cmd := exec.Command("sh", startMockApiServerScript) + output, err := cmd.CombinedOutput() + err = checkMockServerHealth() + if err != nil { + fmt.Printf("Failed to run start api server script: %s\nError: %s", output, err) + return err } - return value + + fmt.Printf("\033[1;36m%s\033[0m", "> Started Mock Api Server at https://127.0.0.1:8080 \n") + unitTestMockAPIClient, _ = unitTestProviderConfigure(ctx) + unitTestMockAPINegativeClient, _ = unitTestNegativeCaseProviderConfigure(ctx) + fmt.Printf("\033[1;36m%s\033[0m", "> Setup completed \n") + return nil } + func teardown() { + cmd := exec.Command("bash", stopMockApiServerScript) + _, _ = cmd.CombinedOutput() + fmt.Printf("\033[1;36m%s\033[0m", "> Stopped Mock Api Server \n") fmt.Printf("\033[1;36m%s\033[0m", "> Teardown completed \n") + err := deleteBuild() + if err != nil { + fmt.Printf("Test Clean up is incomplete: %v\n", err) + } +} + +func deleteBuild() error { + err := os.Remove(basePath + "/tests/mockApiServer/MockBuild") + if err != nil { + return err + } + return nil } diff --git a/spectrocloud/data_source_appliance_test.go b/spectrocloud/data_source_appliance_test.go new file mode 100644 index 00000000..56553b5a --- /dev/null +++ b/spectrocloud/data_source_appliance_test.go @@ -0,0 +1,55 @@ +package spectrocloud + +import ( + "context" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/stretchr/testify/assert" + "testing" +) + +func prepareBaseDataSourceApplianceSchema() *schema.ResourceData { + d := dataSourceAppliance().TestResourceData() + d.SetId("test123") + err := d.Set("name", "test-edge-01") + if err != nil { + return nil + } + err = d.Set("tags", map[string]string{"test": "true"}) + if err != nil { + return nil + } + err = d.Set("status", "ready") + if err != nil { + return nil + } + err = d.Set("health", "healthy") + if err != nil { + return nil + } + err = d.Set("architecture", "amd") + if err != nil { + return nil + } + return d +} + +func TestDataSourceApplianceReadFunc(t *testing.T) { + d := prepareBaseDataSourceApplianceSchema() + var diags diag.Diagnostics + + var ctx context.Context + diags = dataSourceApplianceRead(ctx, d, unitTestMockAPIClient) + assert.Equal(t, 0, len(diags)) +} + +func TestDataSourceApplianceReadNegativeFunc(t *testing.T) { + d := prepareBaseDataSourceApplianceSchema() + var diags diag.Diagnostics + + var ctx context.Context + diags = dataSourceApplianceRead(ctx, d, unitTestMockAPINegativeClient) + if assert.NotEmpty(t, diags, "Expected diags to contain at least one element") { + assert.Contains(t, diags[0].Summary, "No edge host found", "The first diagnostic message does not contain the expected error message") + } +} diff --git a/spectrocloud/data_source_appliances_test.go b/spectrocloud/data_source_appliances_test.go new file mode 100644 index 00000000..351a8289 --- /dev/null +++ b/spectrocloud/data_source_appliances_test.go @@ -0,0 +1,55 @@ +package spectrocloud + +import ( + "context" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/stretchr/testify/assert" + "testing" +) + +func prepareBaseDataSourceAppliancesSchema() *schema.ResourceData { + d := dataSourceAppliances().TestResourceData() + d.SetId("test123") + err := d.Set("context", "project") + if err != nil { + return nil + } + err = d.Set("tags", map[string]string{"test": "true"}) + if err != nil { + return nil + } + err = d.Set("status", "ready") + if err != nil { + return nil + } + err = d.Set("health", "healthy") + if err != nil { + return nil + } + err = d.Set("architecture", "amd") + if err != nil { + return nil + } + return d +} + +func TestDataSourceAppliancesReadFunc(t *testing.T) { + d := prepareBaseDataSourceAppliancesSchema() + var diags diag.Diagnostics + + var ctx context.Context + diags = dataSourcesApplianceRead(ctx, d, unitTestMockAPIClient) + assert.Equal(t, 0, len(diags)) +} + +func TestDataSourceAppliancesReadNegativeFunc(t *testing.T) { + d := prepareBaseDataSourceAppliancesSchema() + var diags diag.Diagnostics + + var ctx context.Context + diags = dataSourcesApplianceRead(ctx, d, unitTestMockAPINegativeClient) + if assert.NotEmpty(t, diags, "Expected diags to contain at least one element") { + assert.Contains(t, diags[0].Summary, "No edge host found", "The first diagnostic message does not contain the expected error message") + } +} diff --git a/spectrocloud/resource_project_test.go b/spectrocloud/resource_project_test.go index e0212b6e..544c92c5 100644 --- a/spectrocloud/resource_project_test.go +++ b/spectrocloud/resource_project_test.go @@ -1,6 +1,8 @@ package spectrocloud import ( + "context" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -8,6 +10,16 @@ import ( "github.com/stretchr/testify/assert" ) +func prepareBaseProjectSchema() *schema.ResourceData { + d := resourceProject().TestResourceData() + d.SetId("test123") + err := d.Set("name", "Default") + if err != nil { + return nil + } + return d +} + // TestToProject tests the toProject function func TestToProject(t *testing.T) { tests := []struct { @@ -81,3 +93,98 @@ func TestToProject(t *testing.T) { }) } } + +func TestCreateProjectFunc(t *testing.T) { + d := prepareBaseProjectSchema() + var diags diag.Diagnostics + err := d.Set("name", "dev") + if err != nil { + return + } + var ctx context.Context + diags = resourceProjectCreate(ctx, d, unitTestMockAPIClient) + assert.Equal(t, 0, len(diags)) +} + +func TestReadProjectFunc(t *testing.T) { + d := resourceProject().TestResourceData() + var diags diag.Diagnostics + d.SetId("test123") + + var ctx context.Context + diags = resourceProjectRead(ctx, d, unitTestMockAPIClient) + assert.Equal(t, 0, len(diags)) +} + +func TestResourceProjectUpdate(t *testing.T) { + // Prepare the schema data for the test. + d := prepareBaseProjectSchema() + // Call the function you want to test. + ctx := context.Background() + diags := resourceProjectUpdate(ctx, d, unitTestMockAPIClient) + // Assert that no diagnostics were returned (i.e., no errors). + assert.Empty(t, diags) +} + +func TestResourceProjectDelete(t *testing.T) { + // Prepare the schema data for the test. + d := prepareBaseProjectSchema() + // Call the function you want to test. + ctx := context.Background() + diags := resourceProjectDelete(ctx, d, unitTestMockAPIClient) + // Assert that no diagnostics were returned (i.e., no errors). + assert.Empty(t, diags) +} + +// Negative case's + +func TestCreateProjectNegativeFunc(t *testing.T) { + d := prepareBaseProjectSchema() + var diags diag.Diagnostics + err := d.Set("name", "dev") + if err != nil { + return + } + var ctx context.Context + diags = resourceProjectCreate(ctx, d, unitTestMockAPINegativeClient) + if assert.NotEmpty(t, diags, "Expected diags to contain at least one element") { + assert.Contains(t, diags[0].Summary, "Project already exist", "The first diagnostic message does not contain the expected error message") + } +} + +func TestReadProjectNegativeFunc(t *testing.T) { + d := resourceProject().TestResourceData() + var diags diag.Diagnostics + d.SetId("test123") + + var ctx context.Context + diags = resourceProjectRead(ctx, d, unitTestMockAPINegativeClient) + if assert.NotEmpty(t, diags, "Expected diags to contain at least one element") { + assert.Contains(t, diags[0].Summary, "Project not found", "The first diagnostic message does not contain the expected error message") + } +} + +func TestUpdateProjectNegativeFunc(t *testing.T) { + d := prepareBaseProjectSchema() + var diags diag.Diagnostics + err := d.Set("name", "dev") + if err != nil { + return + } + var ctx context.Context + diags = resourceProjectUpdate(ctx, d, unitTestMockAPINegativeClient) + if assert.NotEmpty(t, diags, "Expected diags to contain at least one element") { + assert.Contains(t, diags[0].Summary, "Operation not allowed", "The first diagnostic message does not contain the expected error message") + } +} + +func TestResourceProjectInvalidDelete(t *testing.T) { + // Prepare the schema data for the test. + d := prepareBaseProjectSchema() + ctx := context.Background() + // Call the function you want to test. + diags := resourceProjectDelete(ctx, d, unitTestMockAPINegativeClient) + if assert.NotEmpty(t, diags, "Expected diags to contain at least one element") { + assert.Contains(t, diags[0].Summary, "Project not found", "The first diagnostic message does not contain the expected error message") + } +} diff --git a/tests/mockApiServer/apiServerMock.go b/tests/mockApiServer/apiServerMock.go new file mode 100644 index 00000000..bfb545f6 --- /dev/null +++ b/tests/mockApiServer/apiServerMock.go @@ -0,0 +1,91 @@ +package main + +import ( + "encoding/json" + "github.com/gorilla/mux" + "github.com/spectrocloud/terraform-provider-spectrocloud/tests/mockApiServer/routes" + "log" + "net/http" +) + +// API key for authentication +const apiKey = "12345" + +// Aggregate all routes into slices for different servers +var allRoutesPositive []routes.Route +var allRoutesNegative []routes.Route + +// Middleware to check for the API key and log the Project-ID if present +func apiKeyAuthMiddleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Header.Get("ApiKey") != apiKey { + http.Error(w, "Forbidden", http.StatusForbidden) + return + } + // Log the Project-ID if it is present + if projectID := r.Header.Get("Project-ID"); projectID != "" { + log.Printf("Project-ID: %s", projectID) + } + next.ServeHTTP(w, r) + }) +} + +func main() { + // Create routers for different ports + router8080 := mux.NewRouter() + router8888 := mux.NewRouter() + + // Set up routes for port 8080 + setupRoutes(router8080, allRoutesPositive) + + // Set up routes for port 8888 + setupRoutes(router8888, allRoutesNegative) + + // Start servers on different ports + go func() { + log.Println("Starting server on :8080...") + if err := http.ListenAndServeTLS(":8080", "mock_server.crt", "mock_server.key", router8080); err != nil { + log.Fatalf("Server failed to start on port 8080: %v", err) + } + }() + + log.Println("Starting server on :8888...") + + if err := http.ListenAndServeTLS(":8888", "mock_server.crt", "mock_server.key", router8888); err != nil { + log.Fatalf("Server failed to start on port 8080: %v", err) + } +} + +// setupRoutes configures the given router with the provided routes +func setupRoutes(router *mux.Router, routes []routes.Route) { + // Apply API key middleware to all routes + router.Use(apiKeyAuthMiddleware) + + // Register all routes + for _, route := range routes { + route := route // capture the range variable + + router.HandleFunc(route.Path, func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(route.Response.StatusCode) + if route.Response.Payload != nil { + err := json.NewEncoder(w).Encode(route.Response.Payload) + if err != nil { + return + } + } + }).Methods(route.Method) + } +} + +func init() { + // Initialize routes for port 8080 + allRoutesPositive = append(allRoutesPositive, routes.ProjectRoutes()...) + allRoutesPositive = append(allRoutesPositive, routes.AppliancesRoutes()...) + allRoutesPositive = append(allRoutesPositive, routes.CommonProjectRoutes()...) + + // Initialize routes for port 8888 + allRoutesNegative = append(allRoutesNegative, routes.ProjectNegativeRoutes()...) + allRoutesNegative = append(allRoutesNegative, routes.AppliancesNegativeRoutes()...) + allRoutesNegative = append(allRoutesNegative, routes.CommonProjectRoutes()...) +} diff --git a/tests/mockApiServer/routes/common.go b/tests/mockApiServer/routes/common.go new file mode 100644 index 00000000..a824a568 --- /dev/null +++ b/tests/mockApiServer/routes/common.go @@ -0,0 +1,54 @@ +package routes + +import ( + "crypto/rand" + "encoding/hex" + "github.com/spectrocloud/palette-sdk-go/api/models" + "net/http" +) + +// ResponseData defines the structure of mock responses +type ResponseData struct { + StatusCode int + Payload interface{} +} + +// Route defines a mock route with method, path, and response +type Route struct { + Method string + Path string + Response ResponseData +} + +func generateRandomStringUID() string { + bytes := make([]byte, 24/2) + _, err := rand.Read(bytes) + if err != nil { + return "test" + } + return hex.EncodeToString(bytes) +} + +func CommonProjectRoutes() []Route { + return []Route{ + { + Method: "GET", + Path: "/v1/health", + Response: ResponseData{ + StatusCode: http.StatusOK, + Payload: map[string]interface{}{ + "healthy": true, + }, + }, + }, + } +} + +func getError(code string, msg string) models.V1Error { + return models.V1Error{ + Code: code, + Details: nil, + Message: msg, + Ref: "ref-" + generateRandomStringUID(), + } +} diff --git a/tests/mockApiServer/routes/mockAppliances.go b/tests/mockApiServer/routes/mockAppliances.go new file mode 100644 index 00000000..6bedc902 --- /dev/null +++ b/tests/mockApiServer/routes/mockAppliances.go @@ -0,0 +1,185 @@ +package routes + +import ( + "github.com/spectrocloud/gomi/pkg/ptr" + "github.com/spectrocloud/palette-sdk-go/api/models" + "net/http" + "strconv" +) + +func getEdgeHostSearchSummary() models.V1EdgeHostsSearchSummary { + var items []*models.V1EdgeHostsMetadata + var profileSummary []*models.V1ProfileTemplateSummary + profileSummary = append(profileSummary, &models.V1ProfileTemplateSummary{ + CloudType: "aws", + Name: "test-profile-1", + Packs: []*models.V1PackRefSummary{{ + AddonType: "", + Annotations: nil, + DisplayName: "k8", + Layer: "infra", + LogoURL: "", + Name: "kubernetes_pack", + PackUID: generateRandomStringUID(), + Tag: "", + Type: "", + Version: "1.28.0", + }}, + Type: "cluster", + UID: generateRandomStringUID(), + Version: "1.0", + }) + items = append(items, &models.V1EdgeHostsMetadata{ + Metadata: &models.V1ObjectMeta{ + Annotations: nil, + CreationTimestamp: models.V1Time{}, + DeletionTimestamp: models.V1Time{}, + Labels: nil, + LastModifiedTimestamp: models.V1Time{}, + Name: "test-edge-01", + UID: generateRandomStringUID(), + }, + Spec: &models.V1EdgeHostsMetadataSpec{ + ClusterProfileTemplates: profileSummary, + Device: &models.V1DeviceSpec{ + ArchType: ptr.StringPtr("AMD"), + CPU: &models.V1CPU{ + Cores: 2, + }, + Disks: []*models.V1Disk{{ + Controller: "", + Partitions: nil, + Size: 50, + Vendor: "", + }}, + Gpus: []*models.V1GPUDeviceSpec{ + { + Addresses: map[string]string{ + "test": "121.0.0.1", + }, + Model: "xyz", + Vendor: "abc", + }, + }, + Memory: nil, + Nics: nil, + Os: nil, + }, + Host: &models.V1EdgeHostSpecHost{ + HostAddress: "192.168.1.100", + MacAddress: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", + }, + ProjectMeta: nil, + Type: "", + }, + Status: &models.V1EdgeHostsMetadataStatus{ + Health: &models.V1EdgeHostHealth{ + AgentVersion: "", + Message: "", + State: "healthy", + }, + InUseClusters: nil, + State: "", + }, + }) + return models.V1EdgeHostsSearchSummary{ + Items: items, + Listmeta: &models.V1ListMetaData{ + Continue: "", + Count: 1, + Limit: 50, + Offset: 0, + }, + } +} + +func getEdgeHostPayload() models.V1EdgeHostDevice { + return models.V1EdgeHostDevice{ + Aclmeta: &models.V1ACLMeta{ + OwnerUID: generateRandomStringUID(), + ProjectUID: generateRandomStringUID(), + TenantUID: generateRandomStringUID(), + }, + Metadata: &models.V1ObjectMeta{ + Annotations: nil, + CreationTimestamp: models.V1Time{}, + DeletionTimestamp: models.V1Time{}, + Labels: map[string]string{"type": "test"}, + LastModifiedTimestamp: models.V1Time{}, + Name: "test-edge-01", + UID: generateRandomStringUID(), + }, + Spec: &models.V1EdgeHostDeviceSpec{ + CloudProperties: nil, + ClusterProfileTemplates: nil, + Device: &models.V1DeviceSpec{ + ArchType: ptr.StringPtr("amd64"), + CPU: nil, + Disks: nil, + Gpus: nil, + Memory: nil, + Nics: nil, + Os: nil, + }, + Host: nil, + Properties: nil, + Service: nil, + Type: "", + Version: "1.0", + }, + Status: &models.V1EdgeHostDeviceStatus{ + Health: &models.V1EdgeHostHealth{ + AgentVersion: "", + Message: "", + State: "healthy", + }, + InUseClusters: nil, + Packs: nil, + ProfileStatus: nil, + ServiceAuthToken: "", + State: "ready", + }, + } +} + +func AppliancesRoutes() []Route { + return []Route{ + { + Method: "POST", + Path: "/v1/dashboard/edgehosts/search", + Response: ResponseData{ + StatusCode: http.StatusOK, + Payload: getEdgeHostSearchSummary(), + }, + }, + { + Method: "GET", + Path: "/v1/edgehosts/{uid}", + Response: ResponseData{ + StatusCode: http.StatusOK, + Payload: getEdgeHostPayload(), + }, + }, + } +} + +func AppliancesNegativeRoutes() []Route { + return []Route{ + { + Method: "POST", + Path: "/v1/dashboard/edgehosts/search", + Response: ResponseData{ + StatusCode: http.StatusNotFound, + Payload: getError(strconv.Itoa(http.StatusNotFound), "No edge host found"), + }, + }, + { + Method: "GET", + Path: "/v1/edgehosts/{uid}", + Response: ResponseData{ + StatusCode: http.StatusNotFound, + Payload: getError(strconv.Itoa(http.StatusNotFound), "No edge host found"), + }, + }, + } +} diff --git a/tests/mockApiServer/routes/mockProjects.go b/tests/mockApiServer/routes/mockProjects.go new file mode 100644 index 00000000..40ab5fdc --- /dev/null +++ b/tests/mockApiServer/routes/mockProjects.go @@ -0,0 +1,108 @@ +package routes + +import ( + "github.com/spectrocloud/palette-sdk-go/api/models" + "net/http" + "strconv" +) + +func getMockProjectPayload() models.V1Project { + return models.V1Project{ + Metadata: &models.V1ObjectMeta{ + Annotations: nil, + CreationTimestamp: models.V1Time{}, + DeletionTimestamp: models.V1Time{}, + Labels: map[string]string{ + "description": "default project", + }, + LastModifiedTimestamp: models.V1Time{}, + Name: "Default", + UID: generateRandomStringUID(), + }, + Spec: &models.V1ProjectSpec{ + Alerts: nil, + LogoURL: "", + Teams: nil, + Users: nil, + }, + Status: &models.V1ProjectStatus{ + CleanUpStatus: nil, + IsDisabled: false, + }, + } + +} + +func ProjectRoutes() []Route { + return []Route{ + { + Method: "POST", + Path: "/v1/projects", + Response: ResponseData{ + StatusCode: http.StatusCreated, + Payload: map[string]interface{}{"UID": generateRandomStringUID()}, + }, + }, + { + Method: "GET", + Path: "/v1/projects/{uid}", + Response: ResponseData{ + StatusCode: http.StatusOK, + Payload: getMockProjectPayload(), + }, + }, + { + Method: "PUT", + Path: "/v1/projects/{uid}", + Response: ResponseData{ + StatusCode: http.StatusNoContent, + Payload: map[string]interface{}{"UID": generateRandomStringUID()}, + }, + }, + { + Method: "DELETE", + Path: "/v1/projects/{uid}", + Response: ResponseData{ + StatusCode: http.StatusNoContent, + Payload: nil, + }, + }, + } +} + +func ProjectNegativeRoutes() []Route { + return []Route{ + { + Method: "POST", + Path: "/v1/projects", + Response: ResponseData{ + StatusCode: http.StatusConflict, + Payload: getError(strconv.Itoa(http.StatusConflict), "Project already exist"), + }, + }, + { + Method: "GET", + Path: "/v1/projects/{uid}", + Response: ResponseData{ + StatusCode: http.StatusNotFound, + Payload: getError(strconv.Itoa(http.StatusOK), "Project not found"), + }, + }, + { + Method: "PUT", + Path: "/v1/projects/{uid}", + Response: ResponseData{ + StatusCode: http.StatusMethodNotAllowed, + Payload: getError(strconv.Itoa(http.StatusNoContent), "Operation not allowed"), + }, + }, + { + Method: "DELETE", + Path: "/v1/projects/{uid}", + Response: ResponseData{ + StatusCode: http.StatusNotFound, + Payload: getError(strconv.Itoa(http.StatusOK), "Project not found"), + }, + }, + } +} diff --git a/tests/mockApiServer/start_mock_api_server.sh b/tests/mockApiServer/start_mock_api_server.sh new file mode 100755 index 00000000..dc068d17 --- /dev/null +++ b/tests/mockApiServer/start_mock_api_server.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +export MOCK_SERVER_PATH="$TF_SRC/tests/mockApiServer" + +# Navigate to the mock API server directory +cd $MOCK_SERVER_PATH || exit + +# Generate the private key +openssl genpkey -algorithm RSA -out mock_server.key -pkeyopt rsa_keygen_bits:2048 + +# Generate the self-signed certificate with default input +openssl req -new -x509 -key mock_server.key -out mock_server.crt -days 365 -subj "/C=US/ST=CA/L=City/O=Organization/OU=Department/CN=localhost" + +# Build the Go project +go build -o MockBuild apiServerMock.go + +# Run the server in the background and redirect output to server.log +nohup ./MockBuild > mock_api_server.log 2>&1 & \ No newline at end of file diff --git a/tests/mockApiServer/stop_mock_api_server.sh b/tests/mockApiServer/stop_mock_api_server.sh new file mode 100755 index 00000000..5b376f15 --- /dev/null +++ b/tests/mockApiServer/stop_mock_api_server.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Find the process ID of the running mockApiserver +PID=$(pgrep -f MockBuild) + +if [ -z "$PID" ]; then + echo "MockAPIServer is not running." +else + # Kill the process + kill $PID + kill -9 $(lsof -t -i :8080) $(lsof -t -i :8888) + echo "MockAPIServer (PID: $PID) has been stopped." +fi \ No newline at end of file