github.com/nais/knorten@v0.0.0-20240104110906-55926958e361/pkg/api/compute_test.go (about) 1 package api 2 3 import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 "io" 8 "net/http" 9 "net/url" 10 "strconv" 11 "testing" 12 13 "github.com/google/go-cmp/cmp" 14 "github.com/nais/knorten/pkg/database" 15 "github.com/nais/knorten/pkg/database/gensql" 16 ) 17 18 func TestComputeAPI(t *testing.T) { 19 ctx := context.Background() 20 21 t.Run("create compute", func(t *testing.T) { 22 oldEvents, err := repo.EventsGetType(ctx, database.EventTypeCreateCompute) 23 if err != nil { 24 t.Error(err) 25 } 26 27 resp, err := server.Client().PostForm(fmt.Sprintf("%v/compute/new", server.URL), nil) 28 if err != nil { 29 t.Error(err) 30 } 31 defer resp.Body.Close() 32 33 events, err := repo.EventsGetType(ctx, database.EventTypeCreateCompute) 34 if err != nil { 35 t.Error(err) 36 } 37 38 newEvents := getNewEvents(oldEvents, events) 39 eventPayload, err := getComputeEvent(newEvents, testUser.Email) 40 if err != nil { 41 t.Error(err) 42 } 43 44 if eventPayload.Owner == "" { 45 t.Errorf("create compute: no event registered for user %v", testUser.Email) 46 } 47 48 if eventPayload.Owner != testUser.Email { 49 t.Errorf("create compute: email expected %v, got %v", testUser.Email, eventPayload.Owner) 50 } 51 52 if eventPayload.Name != "compute-"+getNormalizedNameFromEmail(testUser.Email) { 53 t.Errorf("create compute: name expected %v, got %v", "compute-"+getNormalizedNameFromEmail(testUser.Email), eventPayload.Name) 54 } 55 }) 56 57 t.Run("resize compute disk", func(t *testing.T) { 58 instance := gensql.ComputeInstance{ 59 Owner: testUser.Email, 60 Name: "compute-" + getNormalizedNameFromEmail(testUser.Email), 61 DiskSize: 10, 62 } 63 if err := repo.ComputeInstanceCreate(ctx, instance); err != nil { 64 t.Error(err) 65 } 66 67 t.Cleanup(func() { 68 if err := repo.ComputeInstanceDelete(ctx, testUser.Email); err != nil { 69 t.Error(err) 70 } 71 }) 72 73 oldEvents, err := repo.EventsGetType(ctx, database.EventTypeResizeCompute) 74 if err != nil { 75 t.Error(err) 76 } 77 78 diskSize := 200 79 data := url.Values{"diskSize": {strconv.Itoa(diskSize)}} 80 resp, err := server.Client().PostForm(fmt.Sprintf("%v/compute/edit", server.URL), data) 81 if err != nil { 82 t.Error(err) 83 } 84 defer resp.Body.Close() 85 86 events, err := repo.EventsGetType(ctx, database.EventTypeResizeCompute) 87 if err != nil { 88 t.Error(err) 89 } 90 91 newEvents := getNewEvents(oldEvents, events) 92 eventPayload, err := getComputeEvent(newEvents, testUser.Email) 93 if err != nil { 94 t.Error(err) 95 } 96 97 if eventPayload.Owner == "" { 98 t.Errorf("resize compute disk: no event registered for user %v", testUser.Email) 99 } 100 101 if eventPayload.Owner != testUser.Email { 102 t.Errorf("resize compute disk: email expected %v, got %v", testUser.Email, eventPayload.Owner) 103 } 104 105 if eventPayload.Name != "compute-"+getNormalizedNameFromEmail(testUser.Email) { 106 t.Errorf("resize compute disk: name expected %v, got %v", "compute-"+getNormalizedNameFromEmail(testUser.Email), eventPayload.Name) 107 } 108 109 if eventPayload.DiskSize != int32(diskSize) { 110 t.Errorf("resize compute disk: diskSize expected %v, got %v", diskSize, eventPayload.DiskSize) 111 } 112 }) 113 114 t.Run("get edit compute html", func(t *testing.T) { 115 instance := gensql.ComputeInstance{ 116 Owner: testUser.Email, 117 Name: "compute-" + getNormalizedNameFromEmail(testUser.Email), 118 DiskSize: 100, 119 } 120 if err := repo.ComputeInstanceCreate(ctx, instance); err != nil { 121 t.Error(err) 122 } 123 124 t.Cleanup(func() { 125 if err := repo.ComputeInstanceDelete(ctx, testUser.Email); err != nil { 126 t.Error(err) 127 } 128 }) 129 130 resp, err := server.Client().Get(fmt.Sprintf("%v/compute/edit", server.URL)) 131 if err != nil { 132 t.Error(err) 133 } 134 defer resp.Body.Close() 135 136 if resp.StatusCode != http.StatusOK { 137 t.Errorf("Status code is %v, should be %v", resp.StatusCode, http.StatusOK) 138 } 139 140 if resp.Header.Get("Content-Type") != htmlContentType { 141 t.Errorf("Content-Type header is %v, should be %v", resp.Header.Get("Content-Type"), htmlContentType) 142 } 143 144 received, err := io.ReadAll(resp.Body) 145 if err != nil { 146 t.Error(err) 147 } 148 receivedMinimized, err := minimizeHTML(string(received)) 149 if err != nil { 150 t.Error(err) 151 } 152 153 expected, err := createExpectedHTML("compute/edit", map[string]any{ 154 "name": instance.Name, 155 "diskSize": instance.DiskSize, 156 }) 157 if err != nil { 158 t.Error(err) 159 } 160 expectedMinimized, err := minimizeHTML(expected) 161 if err != nil { 162 t.Error(err) 163 } 164 165 if diff := cmp.Diff(expectedMinimized, receivedMinimized); diff != "" { 166 t.Errorf("mismatch (-want +got):\n%s", diff) 167 } 168 }) 169 170 t.Run("delete compute", func(t *testing.T) { 171 resp, err := server.Client().PostForm(fmt.Sprintf("%v/compute/delete", server.URL), nil) 172 if err != nil { 173 t.Error(err) 174 } 175 defer resp.Body.Close() 176 177 events, err := repo.EventsGetType(ctx, database.EventTypeDeleteCompute) 178 if err != nil { 179 t.Error(err) 180 } 181 182 if !deleteEventCreatedForTeam(events, testUser.Email) { 183 t.Errorf("delete compute: no event registered for user %v", testUser.Email) 184 } 185 }) 186 } 187 188 func getComputeEvent(events []gensql.Event, user string) (gensql.ComputeInstance, error) { 189 for _, event := range events { 190 payload := gensql.ComputeInstance{} 191 err := json.Unmarshal(event.Payload, &payload) 192 if err != nil { 193 return gensql.ComputeInstance{}, err 194 } 195 196 if payload.Owner == user { 197 return payload, nil 198 } 199 } 200 201 return gensql.ComputeInstance{}, nil 202 }