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