github.com/google/go-github/v70@v70.0.0/github/enterprise_actions_hosted_runners_test.go (about) 1 // Copyright 2025 The go-github AUTHORS. All rights reserved. 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 package github 7 8 import ( 9 "context" 10 "fmt" 11 "net/http" 12 "testing" 13 "time" 14 15 "github.com/google/go-cmp/cmp" 16 ) 17 18 func TestEnterpriseService_ListHostedRunners(t *testing.T) { 19 t.Parallel() 20 client, mux, _ := setup(t) 21 22 mux.HandleFunc("/enterprises/o/actions/hosted-runners", func(w http.ResponseWriter, r *http.Request) { 23 testMethod(t, r, "GET") 24 fmt.Fprint(w, `{ 25 "total_count": 2, 26 "runners": [ 27 { 28 "id": 5, 29 "name": "My hosted ubuntu runner", 30 "runner_group_id": 2, 31 "platform": "linux-x64", 32 "image_details": { 33 "id": "ubuntu-20.04", 34 "size_gb": 86 35 }, 36 "machine_size_details": { 37 "id": "4-core", 38 "cpu_cores": 4, 39 "memory_gb": 16, 40 "storage_gb": 150 41 }, 42 "status": "Ready", 43 "maximum_runners": 10, 44 "public_ip_enabled": true, 45 "public_ips": [ 46 { 47 "enabled": true, 48 "prefix": "20.80.208.150", 49 "length": 31 50 } 51 ], 52 "last_active_on": "2023-04-26T15:23:37Z" 53 }, 54 { 55 "id": 7, 56 "name": "My hosted Windows runner", 57 "runner_group_id": 2, 58 "platform": "win-x64", 59 "image_details": { 60 "id": "windows-latest", 61 "size_gb": 256 62 }, 63 "machine_size_details": { 64 "id": "8-core", 65 "cpu_cores": 8, 66 "memory_gb": 32, 67 "storage_gb": 300 68 }, 69 "status": "Ready", 70 "maximum_runners": 20, 71 "public_ip_enabled": false, 72 "public_ips": [], 73 "last_active_on": "2023-04-26T15:23:37Z" 74 } 75 ] 76 }`) 77 }) 78 opts := &ListOptions{Page: 1, PerPage: 1} 79 ctx := context.Background() 80 hostedRunners, _, err := client.Enterprise.ListHostedRunners(ctx, "o", opts) 81 if err != nil { 82 t.Errorf("Enterprise.ListHostedRunners returned error: %v", err) 83 } 84 85 lastActiveOn := Timestamp{time.Date(2023, 4, 26, 15, 23, 37, 0, time.UTC)} 86 87 want := &HostedRunners{ 88 TotalCount: 2, 89 Runners: []*HostedRunner{ 90 { 91 ID: Ptr(int64(5)), 92 Name: Ptr("My hosted ubuntu runner"), 93 RunnerGroupID: Ptr(int64(2)), 94 Platform: Ptr("linux-x64"), 95 ImageDetails: &HostedRunnerImageDetail{ 96 ID: Ptr("ubuntu-20.04"), 97 SizeGB: Ptr(int64(86)), 98 }, 99 MachineSizeDetails: &HostedRunnerMachineSpec{ 100 ID: "4-core", 101 CPUCores: 4, 102 MemoryGB: 16, 103 StorageGB: 150, 104 }, 105 Status: Ptr("Ready"), 106 MaximumRunners: Ptr(int64(10)), 107 PublicIPEnabled: Ptr(true), 108 PublicIPs: []*HostedRunnerPublicIP{ 109 { 110 Enabled: true, 111 Prefix: "20.80.208.150", 112 Length: 31, 113 }, 114 }, 115 LastActiveOn: Ptr(lastActiveOn), 116 }, 117 { 118 ID: Ptr(int64(7)), 119 Name: Ptr("My hosted Windows runner"), 120 RunnerGroupID: Ptr(int64(2)), 121 Platform: Ptr("win-x64"), 122 ImageDetails: &HostedRunnerImageDetail{ 123 ID: Ptr("windows-latest"), 124 SizeGB: Ptr(int64(256)), 125 }, 126 MachineSizeDetails: &HostedRunnerMachineSpec{ 127 ID: "8-core", 128 CPUCores: 8, 129 MemoryGB: 32, 130 StorageGB: 300, 131 }, 132 Status: Ptr("Ready"), 133 MaximumRunners: Ptr(int64(20)), 134 PublicIPEnabled: Ptr(false), 135 PublicIPs: []*HostedRunnerPublicIP{}, 136 LastActiveOn: Ptr(lastActiveOn), 137 }, 138 }, 139 } 140 if !cmp.Equal(hostedRunners, want) { 141 t.Errorf("Enterprise.ListHostedRunners returned %+v, want %+v", hostedRunners, want) 142 } 143 144 const methodName = "ListHostedRunners" 145 testBadOptions(t, methodName, func() (err error) { 146 _, _, err = client.Enterprise.ListHostedRunners(ctx, "\n", opts) 147 return err 148 }) 149 150 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 151 got, resp, err := client.Enterprise.ListHostedRunners(ctx, "o", opts) 152 if got != nil { 153 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 154 } 155 return resp, err 156 }) 157 } 158 159 func TestEnterpriseService_CreateHostedRunner(t *testing.T) { 160 t.Parallel() 161 client, mux, _ := setup(t) 162 163 mux.HandleFunc("/enterprises/o/actions/hosted-runners", func(w http.ResponseWriter, r *http.Request) { 164 testMethod(t, r, "POST") 165 fmt.Fprint(w, `{ 166 "id": 5, 167 "name": "My hosted ubuntu runner", 168 "runner_group_id": 2, 169 "platform": "linux-x64", 170 "image_details": { 171 "id": "ubuntu-20.04", 172 "size_gb": 86 173 }, 174 "machine_size_details": { 175 "id": "4-core", 176 "cpu_cores": 4, 177 "memory_gb": 16, 178 "storage_gb": 150 179 }, 180 "status": "Ready", 181 "maximum_runners": 10, 182 "public_ip_enabled": true, 183 "public_ips": [ 184 { 185 "enabled": true, 186 "prefix": "20.80.208.150", 187 "length": 31 188 } 189 ], 190 "last_active_on": "2023-04-26T15:23:37Z" 191 }`) 192 }) 193 194 ctx := context.Background() 195 req := &HostedRunnerRequest{ 196 Name: "My Hosted runner", 197 Image: HostedRunnerImage{ 198 ID: "ubuntu-latest", 199 Source: "github", 200 Version: "latest", 201 }, 202 RunnerGroupID: 1, 203 Size: "4-core", 204 MaximumRunners: 50, 205 EnableStaticIP: false, 206 } 207 hostedRunner, _, err := client.Enterprise.CreateHostedRunner(ctx, "o", req) 208 if err != nil { 209 t.Errorf("Enterprise.CreateHostedRunner returned error: %v", err) 210 } 211 212 lastActiveOn := Timestamp{time.Date(2023, 4, 26, 15, 23, 37, 0, time.UTC)} 213 want := &HostedRunner{ 214 ID: Ptr(int64(5)), 215 Name: Ptr("My hosted ubuntu runner"), 216 RunnerGroupID: Ptr(int64(2)), 217 Platform: Ptr("linux-x64"), 218 ImageDetails: &HostedRunnerImageDetail{ 219 ID: Ptr("ubuntu-20.04"), 220 SizeGB: Ptr(int64(86)), 221 }, 222 MachineSizeDetails: &HostedRunnerMachineSpec{ 223 ID: "4-core", 224 CPUCores: 4, 225 MemoryGB: 16, 226 StorageGB: 150, 227 }, 228 Status: Ptr("Ready"), 229 MaximumRunners: Ptr(int64(10)), 230 PublicIPEnabled: Ptr(true), 231 PublicIPs: []*HostedRunnerPublicIP{ 232 { 233 Enabled: true, 234 Prefix: "20.80.208.150", 235 Length: 31, 236 }, 237 }, 238 LastActiveOn: Ptr(lastActiveOn), 239 } 240 241 if !cmp.Equal(hostedRunner, want) { 242 t.Errorf("Enterprise.CreateHostedRunner returned %+v, want %+v", hostedRunner, want) 243 } 244 245 // Validation tests 246 testCases := []struct { 247 name string 248 request *HostedRunnerRequest 249 expectedError string 250 }{ 251 { 252 name: "Missing Size", 253 request: &HostedRunnerRequest{ 254 Name: "My Hosted runner", 255 Image: HostedRunnerImage{ 256 ID: "ubuntu-latest", 257 Source: "github", 258 Version: "latest", 259 }, 260 RunnerGroupID: 1, 261 }, 262 expectedError: "validation failed: size is required for creating a hosted runner", 263 }, 264 { 265 name: "Missing Image", 266 request: &HostedRunnerRequest{ 267 Name: "My Hosted runner", 268 RunnerGroupID: 1, 269 Size: "4-core", 270 }, 271 expectedError: "validation failed: image is required for creating a hosted runner", 272 }, 273 { 274 name: "Missing Name", 275 request: &HostedRunnerRequest{ 276 Image: HostedRunnerImage{ 277 ID: "ubuntu-latest", 278 Source: "github", 279 Version: "latest", 280 }, 281 RunnerGroupID: 1, 282 Size: "4-core", 283 }, 284 expectedError: "validation failed: name is required for creating a hosted runner", 285 }, 286 { 287 name: "Missing RunnerGroupID", 288 request: &HostedRunnerRequest{ 289 Name: "My Hosted runner", 290 Image: HostedRunnerImage{ 291 ID: "ubuntu-latest", 292 Source: "github", 293 Version: "latest", 294 }, 295 Size: "4-core", 296 }, 297 expectedError: "validation failed: runner group ID is required for creating a hosted runner", 298 }, 299 { 300 name: "ImageVersion Set Instead of Image Struct", 301 request: &HostedRunnerRequest{ 302 Name: "My Hosted runner", 303 Image: HostedRunnerImage{ 304 ID: "ubuntu-latest", 305 Source: "github", 306 Version: "latest", 307 }, 308 RunnerGroupID: 1, 309 Size: "4-core", 310 ImageVersion: "1.0.0", 311 MaximumRunners: 50, 312 EnableStaticIP: false, 313 }, 314 expectedError: "validation failed: imageVersion should not be set directly; use the Image struct to specify image details", 315 }, 316 } 317 318 for _, tt := range testCases { 319 _, _, err := client.Enterprise.CreateHostedRunner(ctx, "o", tt.request) 320 if err == nil || err.Error() != tt.expectedError { 321 t.Errorf("expected error: %v, got: %v", tt.expectedError, err) 322 } 323 } 324 325 const methodName = "CreateHostedRunner" 326 testBadOptions(t, methodName, func() (err error) { 327 _, _, err = client.Enterprise.CreateHostedRunner(ctx, "\n", req) 328 return err 329 }) 330 331 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 332 got, resp, err := client.Enterprise.CreateHostedRunner(ctx, "o", req) 333 if got != nil { 334 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 335 } 336 return resp, err 337 }) 338 } 339 340 func TestEnterpriseService_GetHostedRunnerGitHubOwnedImages(t *testing.T) { 341 t.Parallel() 342 client, mux, _ := setup(t) 343 344 mux.HandleFunc("/enterprises/o/actions/hosted-runners/images/github-owned", func(w http.ResponseWriter, r *http.Request) { 345 testMethod(t, r, "GET") 346 fmt.Fprint(w, `{ 347 "total_count": 1, 348 "images": [ 349 { 350 "id": "ubuntu-20.04", 351 "platform": "linux-x64", 352 "size_gb": 86, 353 "display_name": "20.04", 354 "source": "github" 355 } 356 ] 357 }`) 358 }) 359 360 ctx := context.Background() 361 hostedRunnerImages, _, err := client.Enterprise.GetHostedRunnerGitHubOwnedImages(ctx, "o") 362 if err != nil { 363 t.Errorf("Enterprise.GetHostedRunnerGitHubOwnedImages returned error: %v", err) 364 } 365 366 want := &HostedRunnerImages{ 367 TotalCount: 1, 368 Images: []*HostedRunnerImageSpecs{ 369 { 370 ID: "ubuntu-20.04", 371 Platform: "linux-x64", 372 SizeGB: 86, 373 DisplayName: "20.04", 374 Source: "github", 375 }, 376 }, 377 } 378 379 if !cmp.Equal(hostedRunnerImages, want) { 380 t.Errorf("Enterprise.GetHostedRunnerGitHubOwnedImages returned %+v, want %+v", hostedRunnerImages, want) 381 } 382 383 const methodName = "GetHostedRunnerGitHubOwnedImages" 384 testBadOptions(t, methodName, func() (err error) { 385 _, _, err = client.Enterprise.GetHostedRunnerGitHubOwnedImages(ctx, "\n") 386 return err 387 }) 388 389 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 390 got, resp, err := client.Enterprise.GetHostedRunnerGitHubOwnedImages(ctx, "o") 391 if got != nil { 392 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 393 } 394 return resp, err 395 }) 396 } 397 398 func TestEnterpriseService_GetHostedRunnerPartnerImages(t *testing.T) { 399 t.Parallel() 400 client, mux, _ := setup(t) 401 402 mux.HandleFunc("/enterprises/o/actions/hosted-runners/images/partner", func(w http.ResponseWriter, r *http.Request) { 403 testMethod(t, r, "GET") 404 fmt.Fprint(w, `{ 405 "total_count": 1, 406 "images": [ 407 { 408 "id": "ubuntu-20.04", 409 "platform": "linux-x64", 410 "size_gb": 86, 411 "display_name": "20.04", 412 "source": "partner" 413 } 414 ] 415 }`) 416 }) 417 418 ctx := context.Background() 419 hostedRunnerImages, _, err := client.Enterprise.GetHostedRunnerPartnerImages(ctx, "o") 420 if err != nil { 421 t.Errorf("Enterprise.GetHostedRunnerPartnerImages returned error: %v", err) 422 } 423 424 want := &HostedRunnerImages{ 425 TotalCount: 1, 426 Images: []*HostedRunnerImageSpecs{ 427 { 428 ID: "ubuntu-20.04", 429 Platform: "linux-x64", 430 SizeGB: 86, 431 DisplayName: "20.04", 432 Source: "partner", 433 }, 434 }, 435 } 436 437 if !cmp.Equal(hostedRunnerImages, want) { 438 t.Errorf("Enterprise.GetHostedRunnerPartnerImages returned %+v, want %+v", hostedRunnerImages, want) 439 } 440 441 const methodName = "GetHostedRunnerPartnerImages" 442 testBadOptions(t, methodName, func() (err error) { 443 _, _, err = client.Enterprise.GetHostedRunnerPartnerImages(ctx, "\n") 444 return err 445 }) 446 447 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 448 got, resp, err := client.Enterprise.GetHostedRunnerPartnerImages(ctx, "o") 449 if got != nil { 450 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 451 } 452 return resp, err 453 }) 454 } 455 456 func TestEnterpriseService_GetHostedRunnerLimits(t *testing.T) { 457 t.Parallel() 458 client, mux, _ := setup(t) 459 mux.HandleFunc("/enterprises/o/actions/hosted-runners/limits", func(w http.ResponseWriter, r *http.Request) { 460 testMethod(t, r, "GET") 461 fmt.Fprint(w, `{ 462 "public_ips": { 463 "current_usage": 17, 464 "maximum": 50 465 } 466 }`) 467 }) 468 469 ctx := context.Background() 470 publicIPLimits, _, err := client.Enterprise.GetHostedRunnerLimits(ctx, "o") 471 if err != nil { 472 t.Errorf("Enterprise.GetPartnerImages returned error: %v", err) 473 } 474 475 want := &HostedRunnerPublicIPLimits{ 476 PublicIPs: &PublicIPUsage{ 477 CurrentUsage: 17, 478 Maximum: 50, 479 }, 480 } 481 482 if !cmp.Equal(publicIPLimits, want) { 483 t.Errorf("Enterprise.GetHostedRunnerLimits returned %+v, want %+v", publicIPLimits, want) 484 } 485 486 const methodName = "GetHostedRunnerLimits" 487 testBadOptions(t, methodName, func() (err error) { 488 _, _, err = client.Enterprise.GetHostedRunnerLimits(ctx, "\n") 489 return err 490 }) 491 492 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 493 got, resp, err := client.Enterprise.GetHostedRunnerLimits(ctx, "o") 494 if got != nil { 495 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 496 } 497 return resp, err 498 }) 499 } 500 501 func TestEnterpriseService_GetHostedRunnerMachineSpecs(t *testing.T) { 502 t.Parallel() 503 client, mux, _ := setup(t) 504 505 mux.HandleFunc("/enterprises/o/actions/hosted-runners/machine-sizes", func(w http.ResponseWriter, r *http.Request) { 506 testMethod(t, r, "GET") 507 fmt.Fprint(w, `{ 508 "total_count": 1, 509 "machine_specs": [ 510 { 511 "id": "4-core", 512 "cpu_cores": 4, 513 "memory_gb": 16, 514 "storage_gb": 150 515 } 516 ] 517 }`) 518 }) 519 520 ctx := context.Background() 521 machineSpecs, _, err := client.Enterprise.GetHostedRunnerMachineSpecs(ctx, "o") 522 if err != nil { 523 t.Errorf("Enterprise.GetHostedRunnerMachineSpecs returned error: %v", err) 524 } 525 want := &HostedRunnerMachineSpecs{ 526 TotalCount: 1, 527 MachineSpecs: []*HostedRunnerMachineSpec{ 528 { 529 ID: "4-core", 530 CPUCores: 4, 531 MemoryGB: 16, 532 StorageGB: 150, 533 }, 534 }, 535 } 536 537 if !cmp.Equal(machineSpecs, want) { 538 t.Errorf("Enterprise.GetHostedRunnerMachineSpecs returned %+v, want %+v", machineSpecs, want) 539 } 540 541 const methodName = "GetHostedRunnerMachineSpecs" 542 testBadOptions(t, methodName, func() (err error) { 543 _, _, err = client.Enterprise.GetHostedRunnerMachineSpecs(ctx, "\n") 544 return err 545 }) 546 547 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 548 got, resp, err := client.Enterprise.GetHostedRunnerMachineSpecs(ctx, "o") 549 if got != nil { 550 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 551 } 552 return resp, err 553 }) 554 } 555 556 func TestEnterpriseService_GetHostedRunnerPlatforms(t *testing.T) { 557 t.Parallel() 558 client, mux, _ := setup(t) 559 560 mux.HandleFunc("/enterprises/o/actions/hosted-runners/platforms", func(w http.ResponseWriter, r *http.Request) { 561 testMethod(t, r, "GET") 562 fmt.Fprint(w, `{ 563 "total_count": 1, 564 "platforms": [ 565 "linux-x64", 566 "win-x64" 567 ] 568 }`) 569 }) 570 571 ctx := context.Background() 572 platforms, _, err := client.Enterprise.GetHostedRunnerPlatforms(ctx, "o") 573 if err != nil { 574 t.Errorf("Enterprise.GetHostedRunnerPlatforms returned error: %v", err) 575 } 576 want := &HostedRunnerPlatforms{ 577 TotalCount: 1, 578 Platforms: []string{ 579 "linux-x64", 580 "win-x64", 581 }, 582 } 583 584 if !cmp.Equal(platforms, want) { 585 t.Errorf("Enterprise.GetHostedRunnerPlatforms returned %+v, want %+v", platforms, want) 586 } 587 588 const methodName = "GetHostedRunnerPlatforms" 589 testBadOptions(t, methodName, func() (err error) { 590 _, _, err = client.Enterprise.GetHostedRunnerPlatforms(ctx, "\n") 591 return err 592 }) 593 594 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 595 got, resp, err := client.Enterprise.GetHostedRunnerPlatforms(ctx, "o") 596 if got != nil { 597 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 598 } 599 return resp, err 600 }) 601 } 602 603 func TestEnterpriseService_GetHostedRunner(t *testing.T) { 604 t.Parallel() 605 client, mux, _ := setup(t) 606 607 mux.HandleFunc("/enterprises/o/actions/hosted-runners/23", func(w http.ResponseWriter, r *http.Request) { 608 testMethod(t, r, "GET") 609 fmt.Fprint(w, `{ 610 "id": 5, 611 "name": "My hosted ubuntu runner", 612 "runner_group_id": 2, 613 "platform": "linux-x64", 614 "image_details": { 615 "id": "ubuntu-20.04", 616 "size_gb": 86 617 }, 618 "machine_size_details": { 619 "id": "4-core", 620 "cpu_cores": 4, 621 "memory_gb": 16, 622 "storage_gb": 150 623 }, 624 "status": "Ready", 625 "maximum_runners": 10, 626 "public_ip_enabled": true, 627 "public_ips": [ 628 { 629 "enabled": true, 630 "prefix": "20.80.208.150", 631 "length": 31 632 } 633 ], 634 "last_active_on": "2023-04-26T15:23:37Z" 635 }`) 636 }) 637 638 ctx := context.Background() 639 hostedRunner, _, err := client.Enterprise.GetHostedRunner(ctx, "o", 23) 640 if err != nil { 641 t.Errorf("Enterprise.GetHostedRunner returned error: %v", err) 642 } 643 644 lastActiveOn := Timestamp{time.Date(2023, 4, 26, 15, 23, 37, 0, time.UTC)} 645 want := &HostedRunner{ 646 ID: Ptr(int64(5)), 647 Name: Ptr("My hosted ubuntu runner"), 648 RunnerGroupID: Ptr(int64(2)), 649 Platform: Ptr("linux-x64"), 650 ImageDetails: &HostedRunnerImageDetail{ 651 ID: Ptr("ubuntu-20.04"), 652 SizeGB: Ptr(int64(86)), 653 }, 654 MachineSizeDetails: &HostedRunnerMachineSpec{ 655 ID: "4-core", 656 CPUCores: 4, 657 MemoryGB: 16, 658 StorageGB: 150, 659 }, 660 Status: Ptr("Ready"), 661 MaximumRunners: Ptr(int64(10)), 662 PublicIPEnabled: Ptr(true), 663 PublicIPs: []*HostedRunnerPublicIP{ 664 { 665 Enabled: true, 666 Prefix: "20.80.208.150", 667 Length: 31, 668 }, 669 }, 670 LastActiveOn: Ptr(lastActiveOn), 671 } 672 673 if !cmp.Equal(hostedRunner, want) { 674 t.Errorf("Enterprise.GetHostedRunner returned %+v, want %+v", hostedRunner, want) 675 } 676 677 const methodName = "GetHostedRunner" 678 testBadOptions(t, methodName, func() (err error) { 679 _, _, err = client.Enterprise.GetHostedRunner(ctx, "\n", 23) 680 return err 681 }) 682 683 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 684 got, resp, err := client.Enterprise.GetHostedRunner(ctx, "o", 23) 685 if got != nil { 686 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 687 } 688 return resp, err 689 }) 690 } 691 692 func TestEnterpriseService_UpdateHostedRunner(t *testing.T) { 693 t.Parallel() 694 client, mux, _ := setup(t) 695 696 mux.HandleFunc("/enterprises/o/actions/hosted-runners/23", func(w http.ResponseWriter, r *http.Request) { 697 testMethod(t, r, "PATCH") 698 fmt.Fprint(w, `{ 699 "id": 5, 700 "name": "My hosted ubuntu runner", 701 "runner_group_id": 2, 702 "platform": "linux-x64", 703 "image_details": { 704 "id": "ubuntu-20.04", 705 "size_gb": 86 706 }, 707 "machine_size_details": { 708 "id": "4-core", 709 "cpu_cores": 4, 710 "memory_gb": 16, 711 "storage_gb": 150 712 }, 713 "status": "Ready", 714 "maximum_runners": 10, 715 "public_ip_enabled": true, 716 "public_ips": [ 717 { 718 "enabled": true, 719 "prefix": "20.80.208.150", 720 "length": 31 721 } 722 ], 723 "last_active_on": "2023-04-26T15:23:37Z" 724 }`) 725 }) 726 727 // Test for a valid update without `Size` 728 ctx := context.Background() 729 validReq := HostedRunnerRequest{ 730 Name: "My larger runner", 731 RunnerGroupID: 1, 732 MaximumRunners: 50, 733 EnableStaticIP: false, 734 ImageVersion: "1.0.0", 735 } 736 hostedRunner, _, err := client.Enterprise.UpdateHostedRunner(ctx, "o", 23, validReq) 737 if err != nil { 738 t.Errorf("Enterprise.UpdateHostedRunner returned error: %v", err) 739 } 740 741 lastActiveOn := Timestamp{time.Date(2023, 4, 26, 15, 23, 37, 0, time.UTC)} 742 want := &HostedRunner{ 743 ID: Ptr(int64(5)), 744 Name: Ptr("My hosted ubuntu runner"), 745 RunnerGroupID: Ptr(int64(2)), 746 Platform: Ptr("linux-x64"), 747 ImageDetails: &HostedRunnerImageDetail{ 748 ID: Ptr("ubuntu-20.04"), 749 SizeGB: Ptr(int64(86)), 750 }, 751 MachineSizeDetails: &HostedRunnerMachineSpec{ 752 ID: "4-core", 753 CPUCores: 4, 754 MemoryGB: 16, 755 StorageGB: 150, 756 }, 757 Status: Ptr("Ready"), 758 MaximumRunners: Ptr(int64(10)), 759 PublicIPEnabled: Ptr(true), 760 PublicIPs: []*HostedRunnerPublicIP{ 761 { 762 Enabled: true, 763 Prefix: "20.80.208.150", 764 Length: 31, 765 }, 766 }, 767 LastActiveOn: Ptr(lastActiveOn), 768 } 769 770 if !cmp.Equal(hostedRunner, want) { 771 t.Errorf("Enterprise.UpdateHostedRunner returned %+v, want %+v", hostedRunner, want) 772 } 773 774 testCases := []struct { 775 name string 776 request HostedRunnerRequest 777 expectedError string 778 }{ 779 { 780 name: "Size Set in Update Request", 781 request: HostedRunnerRequest{ 782 Name: "My larger runner", 783 RunnerGroupID: 1, 784 MaximumRunners: 50, 785 EnableStaticIP: false, 786 ImageVersion: "1.0.0", 787 Size: "4-core", // Should cause validation error 788 }, 789 expectedError: "validation failed: size cannot be updated, API does not support updating size", 790 }, 791 { 792 name: "Image Set in Update Request", 793 request: HostedRunnerRequest{ 794 Name: "My larger runner", 795 RunnerGroupID: 1, 796 MaximumRunners: 50, 797 EnableStaticIP: false, 798 ImageVersion: "1.0.0", 799 Image: HostedRunnerImage{ // Should cause validation error 800 ID: "ubuntu-latest", 801 Source: "github", 802 Version: "latest", 803 }, 804 }, 805 expectedError: "validation failed: image struct should not be set directly; use the ImageVersion to specify version details", 806 }, 807 } 808 for _, tt := range testCases { 809 _, _, err := client.Enterprise.UpdateHostedRunner(ctx, "o", 23, tt.request) 810 if err == nil || err.Error() != tt.expectedError { 811 t.Errorf("expected error: %v, got: %v", tt.expectedError, err) 812 } 813 } 814 815 const methodName = "UpdateHostedRunner" 816 testBadOptions(t, methodName, func() (err error) { 817 _, _, err = client.Enterprise.UpdateHostedRunner(ctx, "\n", 23, validReq) 818 return err 819 }) 820 821 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 822 got, resp, err := client.Enterprise.UpdateHostedRunner(ctx, "o", 23, validReq) 823 if got != nil { 824 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 825 } 826 return resp, err 827 }) 828 } 829 830 func TestEnterpriseService_DeleteHostedRunner(t *testing.T) { 831 t.Parallel() 832 client, mux, _ := setup(t) 833 834 mux.HandleFunc("/enterprises/o/actions/hosted-runners/23", func(w http.ResponseWriter, r *http.Request) { 835 testMethod(t, r, "DELETE") 836 fmt.Fprint(w, `{ 837 "id": 5, 838 "name": "My hosted ubuntu runner", 839 "runner_group_id": 2, 840 "platform": "linux-x64", 841 "image_details": { 842 "id": "ubuntu-20.04", 843 "size_gb": 86 844 }, 845 "machine_size_details": { 846 "id": "4-core", 847 "cpu_cores": 4, 848 "memory_gb": 16, 849 "storage_gb": 150 850 }, 851 "status": "Ready", 852 "maximum_runners": 10, 853 "public_ip_enabled": true, 854 "public_ips": [ 855 { 856 "enabled": true, 857 "prefix": "20.80.208.150", 858 "length": 31 859 } 860 ], 861 "last_active_on": "2023-04-26T15:23:37Z" 862 }`) 863 }) 864 865 ctx := context.Background() 866 hostedRunner, _, err := client.Enterprise.DeleteHostedRunner(ctx, "o", 23) 867 if err != nil { 868 t.Errorf("Enterprise.GetHostedRunner returned error: %v", err) 869 } 870 871 lastActiveOn := Timestamp{time.Date(2023, 4, 26, 15, 23, 37, 0, time.UTC)} 872 want := &HostedRunner{ 873 ID: Ptr(int64(5)), 874 Name: Ptr("My hosted ubuntu runner"), 875 RunnerGroupID: Ptr(int64(2)), 876 Platform: Ptr("linux-x64"), 877 ImageDetails: &HostedRunnerImageDetail{ 878 ID: Ptr("ubuntu-20.04"), 879 SizeGB: Ptr(int64(86)), 880 }, 881 MachineSizeDetails: &HostedRunnerMachineSpec{ 882 ID: "4-core", 883 CPUCores: 4, 884 MemoryGB: 16, 885 StorageGB: 150, 886 }, 887 Status: Ptr("Ready"), 888 MaximumRunners: Ptr(int64(10)), 889 PublicIPEnabled: Ptr(true), 890 PublicIPs: []*HostedRunnerPublicIP{ 891 { 892 Enabled: true, 893 Prefix: "20.80.208.150", 894 Length: 31, 895 }, 896 }, 897 LastActiveOn: Ptr(lastActiveOn), 898 } 899 900 if !cmp.Equal(hostedRunner, want) { 901 t.Errorf("Enterprise.DeleteHostedRunner returned %+v, want %+v", hostedRunner, want) 902 } 903 904 const methodName = "DeleteHostedRunner" 905 testBadOptions(t, methodName, func() (err error) { 906 _, _, err = client.Enterprise.DeleteHostedRunner(ctx, "\n", 23) 907 return err 908 }) 909 910 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 911 got, resp, err := client.Enterprise.DeleteHostedRunner(ctx, "o", 23) 912 if got != nil { 913 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 914 } 915 return resp, err 916 }) 917 }