Refactor actions.Client with options to help extensibility (#2193)
This commit is contained in:
parent
282f2dd09c
commit
3327f620fb
|
|
@ -84,7 +84,13 @@ func run(rc RunnerScaleSetListenerConfig, logger logr.Logger) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
actionsServiceClient, err := actions.NewClient(ctx, rc.ConfigureUrl, creds, fmt.Sprintf("actions-runner-controller/%s", build.Version), logger)
|
actionsServiceClient, err := actions.NewClient(
|
||||||
|
ctx,
|
||||||
|
rc.ConfigureUrl,
|
||||||
|
creds,
|
||||||
|
actions.WithUserAgent(fmt.Sprintf("actions-runner-controller/%s", build.Version)),
|
||||||
|
actions.WithLogger(logger),
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create an Actions Service client: %w", err)
|
return fmt.Errorf("failed to create an Actions Service client: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
package actions_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/golang-jwt/jwt/v4"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
// newActionsServer returns a new httptest.Server that handles the
|
||||||
|
// authentication requests neeeded to create a new client. Any requests not
|
||||||
|
// made to the /actions/runners/registration-token or
|
||||||
|
// /actions/runner-registration endpoints will be handled by the provided
|
||||||
|
// handler. The returned server is started and will be automatically closed
|
||||||
|
// when the test ends.
|
||||||
|
func newActionsServer(t *testing.T, handler http.Handler) *actionsServer {
|
||||||
|
var u string
|
||||||
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// handle getRunnerRegistrationToken
|
||||||
|
if strings.HasSuffix(r.URL.Path, "/runners/registration-token") {
|
||||||
|
w.WriteHeader(http.StatusCreated)
|
||||||
|
w.Write([]byte(`{"token":"token"}`))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle getActionsServiceAdminConnection
|
||||||
|
if strings.HasSuffix(r.URL.Path, "/actions/runner-registration") {
|
||||||
|
claims := &jwt.RegisteredClaims{
|
||||||
|
IssuedAt: jwt.NewNumericDate(time.Now().Add(-1 * time.Minute)),
|
||||||
|
ExpiresAt: jwt.NewNumericDate(time.Now().Add(1 * time.Minute)),
|
||||||
|
Issuer: "123",
|
||||||
|
}
|
||||||
|
|
||||||
|
token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
|
||||||
|
privateKey, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(samplePrivateKey))
|
||||||
|
require.NoError(t, err)
|
||||||
|
tokenString, err := token.SignedString(privateKey)
|
||||||
|
require.NoError(t, err)
|
||||||
|
w.Write([]byte(`{"url":"` + u + `","token":"` + tokenString + `"}`))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
handler.ServeHTTP(w, r)
|
||||||
|
}))
|
||||||
|
|
||||||
|
u = server.URL
|
||||||
|
|
||||||
|
t.Cleanup(func() {
|
||||||
|
server.Close()
|
||||||
|
})
|
||||||
|
|
||||||
|
return &actionsServer{server}
|
||||||
|
}
|
||||||
|
|
||||||
|
type actionsServer struct {
|
||||||
|
*httptest.Server
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *actionsServer) configURLForOrg(org string) string {
|
||||||
|
return s.URL + "/" + org
|
||||||
|
}
|
||||||
|
|
||||||
|
const samplePrivateKey = `-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIICWgIBAAKBgHXfRT9cv9UY9fAAD4+1RshpfSSZe277urfEmPfX3/Og9zJYRk//
|
||||||
|
CZrJVD1CaBZDiIyQsNEzjta7r4UsqWdFOggiNN2E7ZTFQjMSaFkVgrzHqWuiaCBf
|
||||||
|
/BjbKPn4SMDmTzHvIe7Nel76hBdCaVgu6mYCW5jmuSH5qz/yR1U1J/WJAgMBAAEC
|
||||||
|
gYARWGWsSU3BYgbu5lNj5l0gKMXNmPhdAJYdbMTF0/KUu18k/XB7XSBgsre+vALt
|
||||||
|
I8r4RGKApoGif8P4aPYUyE8dqA1bh0X3Fj1TCz28qoUL5//dA+pigCRS20H7HM3C
|
||||||
|
ojoqF7+F+4F2sXmzFNd1NgY5RxFPYosTT7OnUiFuu2IisQJBALnMLe09LBnjuHXR
|
||||||
|
xxR65DDNxWPQLBjW3dL+ubLcwr7922l6ZIQsVjdeE0ItEUVRjjJ9/B/Jq9VJ/Lw4
|
||||||
|
g9LCkkMCQQCiaM2f7nYmGivPo9hlAbq5lcGJ5CCYFfeeYzTxMqum7Mbqe4kk5lgb
|
||||||
|
X6gWd0Izg2nGdAEe/97DClO6VpKcPbpDAkBTR/JOJN1fvXMxXJaf13XxakrQMr+R
|
||||||
|
Yr6LlSInykyAz8lJvlLP7A+5QbHgN9NF/wh+GXqpxPwA3ukqdSqhjhWBAkBn6mDv
|
||||||
|
HPgR5xrzL6XM8y9TgaOlJAdK6HtYp6d/UOmN0+Butf6JUq07TphRT5tXNJVgemch
|
||||||
|
O5x/9UKfbrc+KyzbAkAo97TfFC+mZhU1N5fFelaRu4ikPxlp642KRUSkOh8GEkNf
|
||||||
|
jQ97eJWiWtDcsMUhcZgoB5ydHcFlrBIn6oBcpge5
|
||||||
|
-----END RSA PRIVATE KEY-----`
|
||||||
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"path"
|
"path"
|
||||||
|
|
@ -62,8 +63,8 @@ type Client struct {
|
||||||
ActionsServiceAdminTokenExpiresAt *time.Time
|
ActionsServiceAdminTokenExpiresAt *time.Time
|
||||||
ActionsServiceURL *string
|
ActionsServiceURL *string
|
||||||
|
|
||||||
RetryMax *int
|
retryMax int
|
||||||
RetryWaitMax *time.Duration
|
retryWaitMax time.Duration
|
||||||
|
|
||||||
creds *ActionsAuth
|
creds *ActionsAuth
|
||||||
githubConfigURL string
|
githubConfigURL string
|
||||||
|
|
@ -71,14 +72,57 @@ type Client struct {
|
||||||
userAgent string
|
userAgent string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClient(ctx context.Context, githubConfigURL string, creds *ActionsAuth, userAgent string, logger logr.Logger) (ActionsService, error) {
|
type ClientOption func(*Client)
|
||||||
|
|
||||||
|
func WithUserAgent(userAgent string) ClientOption {
|
||||||
|
return func(c *Client) {
|
||||||
|
c.userAgent = userAgent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithLogger(logger logr.Logger) ClientOption {
|
||||||
|
return func(c *Client) {
|
||||||
|
c.logger = logger
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithRetryMax(retryMax int) ClientOption {
|
||||||
|
return func(c *Client) {
|
||||||
|
c.retryMax = retryMax
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithRetryWaitMax(retryWaitMax time.Duration) ClientOption {
|
||||||
|
return func(c *Client) {
|
||||||
|
c.retryWaitMax = retryWaitMax
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewClient(ctx context.Context, githubConfigURL string, creds *ActionsAuth, options ...ClientOption) (ActionsService, error) {
|
||||||
ac := &Client{
|
ac := &Client{
|
||||||
creds: creds,
|
creds: creds,
|
||||||
githubConfigURL: githubConfigURL,
|
githubConfigURL: githubConfigURL,
|
||||||
logger: logger,
|
logger: logr.Discard(),
|
||||||
userAgent: userAgent,
|
|
||||||
|
// retryablehttp defaults
|
||||||
|
retryMax: 4,
|
||||||
|
retryWaitMax: 30 * time.Second,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, option := range options {
|
||||||
|
option(ac)
|
||||||
|
}
|
||||||
|
|
||||||
|
retryClient := retryablehttp.NewClient()
|
||||||
|
|
||||||
|
// TODO: this silences retryclient default logger, do we want to provide one
|
||||||
|
// instead? by default retryablehttp logs all requests to stderr
|
||||||
|
retryClient.Logger = log.New(io.Discard, "", log.LstdFlags)
|
||||||
|
|
||||||
|
retryClient.RetryMax = ac.retryMax
|
||||||
|
retryClient.RetryWaitMax = ac.retryWaitMax
|
||||||
|
ac.Client = retryClient.StandardClient()
|
||||||
|
|
||||||
rt, err := ac.getRunnerRegistrationToken(ctx, githubConfigURL, *creds)
|
rt, err := ac.getRunnerRegistrationToken(ctx, githubConfigURL, *creds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to get runner registration token: %w", err)
|
return nil, fmt.Errorf("failed to get runner registration token: %w", err)
|
||||||
|
|
@ -121,9 +165,7 @@ func (c *Client) GetRunnerScaleSet(ctx context.Context, runnerScaleSetName strin
|
||||||
req.Header.Set("User-Agent", c.userAgent)
|
req.Header.Set("User-Agent", c.userAgent)
|
||||||
}
|
}
|
||||||
|
|
||||||
httpClient := c.getHTTPClient()
|
resp, err := c.Do(req)
|
||||||
|
|
||||||
resp, err := httpClient.Do(req)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -165,9 +207,7 @@ func (c *Client) GetRunnerScaleSetById(ctx context.Context, runnerScaleSetId int
|
||||||
req.Header.Set("User-Agent", c.userAgent)
|
req.Header.Set("User-Agent", c.userAgent)
|
||||||
}
|
}
|
||||||
|
|
||||||
httpClient := c.getHTTPClient()
|
resp, err := c.Do(req)
|
||||||
|
|
||||||
resp, err := httpClient.Do(req)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -182,7 +222,6 @@ func (c *Client) GetRunnerScaleSetById(ctx context.Context, runnerScaleSetId int
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return runnerScaleSet, nil
|
return runnerScaleSet, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) GetRunnerGroupByName(ctx context.Context, runnerGroup string) (*RunnerGroup, error) {
|
func (c *Client) GetRunnerGroupByName(ctx context.Context, runnerGroup string) (*RunnerGroup, error) {
|
||||||
|
|
@ -204,9 +243,7 @@ func (c *Client) GetRunnerGroupByName(ctx context.Context, runnerGroup string) (
|
||||||
req.Header.Set("User-Agent", c.userAgent)
|
req.Header.Set("User-Agent", c.userAgent)
|
||||||
}
|
}
|
||||||
|
|
||||||
httpClient := c.getHTTPClient()
|
resp, err := c.Do(req)
|
||||||
|
|
||||||
resp, err := httpClient.Do(req)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -260,9 +297,7 @@ func (c *Client) CreateRunnerScaleSet(ctx context.Context, runnerScaleSet *Runne
|
||||||
req.Header.Set("User-Agent", c.userAgent)
|
req.Header.Set("User-Agent", c.userAgent)
|
||||||
}
|
}
|
||||||
|
|
||||||
httpClient := c.getHTTPClient()
|
resp, err := c.Do(req)
|
||||||
|
|
||||||
resp, err := httpClient.Do(req)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -278,49 +313,6 @@ func (c *Client) CreateRunnerScaleSet(ctx context.Context, runnerScaleSet *Runne
|
||||||
return createdRunnerScaleSet, nil
|
return createdRunnerScaleSet, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) UpdateRunnerScaleSet(ctx context.Context, runnerScaleSetId int, runnerScaleSet *RunnerScaleSet) (*RunnerScaleSet, error) {
|
|
||||||
u := fmt.Sprintf("%s/%s/%d?api-version=6.0-preview", *c.ActionsServiceURL, scaleSetEndpoint, runnerScaleSetId)
|
|
||||||
|
|
||||||
if err := c.refreshTokenIfNeeded(ctx); err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to refresh admin token if needed: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
body, err := json.Marshal(runnerScaleSet)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodPut, u, bytes.NewBuffer(body))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
req.Header.Set("Content-Type", "application/json")
|
|
||||||
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", *c.ActionsServiceAdminToken))
|
|
||||||
|
|
||||||
if c.userAgent != "" {
|
|
||||||
req.Header.Set("User-Agent", c.userAgent)
|
|
||||||
}
|
|
||||||
|
|
||||||
httpClient := c.getHTTPClient()
|
|
||||||
|
|
||||||
resp, err := httpClient.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
return nil, ParseActionsErrorFromResponse(resp)
|
|
||||||
}
|
|
||||||
|
|
||||||
var createdRunnerScaleSet *RunnerScaleSet
|
|
||||||
err = unmarshalBody(resp, &createdRunnerScaleSet)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return createdRunnerScaleSet, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) DeleteRunnerScaleSet(ctx context.Context, runnerScaleSetId int) error {
|
func (c *Client) DeleteRunnerScaleSet(ctx context.Context, runnerScaleSetId int) error {
|
||||||
u := fmt.Sprintf("%s/%s/%d?api-version=6.0-preview", *c.ActionsServiceURL, scaleSetEndpoint, runnerScaleSetId)
|
u := fmt.Sprintf("%s/%s/%d?api-version=6.0-preview", *c.ActionsServiceURL, scaleSetEndpoint, runnerScaleSetId)
|
||||||
|
|
||||||
|
|
@ -340,9 +332,7 @@ func (c *Client) DeleteRunnerScaleSet(ctx context.Context, runnerScaleSetId int)
|
||||||
req.Header.Set("User-Agent", c.userAgent)
|
req.Header.Set("User-Agent", c.userAgent)
|
||||||
}
|
}
|
||||||
|
|
||||||
httpClient := c.getHTTPClient()
|
resp, err := c.Do(req)
|
||||||
|
|
||||||
resp, err := httpClient.Do(req)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -372,9 +362,7 @@ func (c *Client) GetMessage(ctx context.Context, messageQueueUrl, messageQueueAc
|
||||||
req.Header.Set("User-Agent", c.userAgent)
|
req.Header.Set("User-Agent", c.userAgent)
|
||||||
}
|
}
|
||||||
|
|
||||||
httpClient := c.getHTTPClient()
|
resp, err := c.Do(req)
|
||||||
|
|
||||||
resp, err := httpClient.Do(req)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -425,9 +413,7 @@ func (c *Client) DeleteMessage(ctx context.Context, messageQueueUrl, messageQueu
|
||||||
req.Header.Set("User-Agent", c.userAgent)
|
req.Header.Set("User-Agent", c.userAgent)
|
||||||
}
|
}
|
||||||
|
|
||||||
httpClient := c.getHTTPClient()
|
resp, err := c.Do(req)
|
||||||
|
|
||||||
resp, err := httpClient.Do(req)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -497,9 +483,7 @@ func (c *Client) doSessionRequest(ctx context.Context, method, url string, reque
|
||||||
req.Header.Set("User-Agent", c.userAgent)
|
req.Header.Set("User-Agent", c.userAgent)
|
||||||
}
|
}
|
||||||
|
|
||||||
httpClient := c.getHTTPClient()
|
resp, err := c.Do(req)
|
||||||
|
|
||||||
resp, err := httpClient.Do(req)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -542,9 +526,7 @@ func (c *Client) AcquireJobs(ctx context.Context, runnerScaleSetId int, messageQ
|
||||||
req.Header.Set("User-Agent", c.userAgent)
|
req.Header.Set("User-Agent", c.userAgent)
|
||||||
}
|
}
|
||||||
|
|
||||||
httpClient := c.getHTTPClient()
|
resp, err := c.Do(req)
|
||||||
|
|
||||||
resp, err := httpClient.Do(req)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -581,9 +563,7 @@ func (c *Client) GetAcquirableJobs(ctx context.Context, runnerScaleSetId int) (*
|
||||||
req.Header.Set("User-Agent", c.userAgent)
|
req.Header.Set("User-Agent", c.userAgent)
|
||||||
}
|
}
|
||||||
|
|
||||||
httpClient := c.getHTTPClient()
|
resp, err := c.Do(req)
|
||||||
|
|
||||||
resp, err := httpClient.Do(req)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -629,9 +609,7 @@ func (c *Client) GenerateJitRunnerConfig(ctx context.Context, jitRunnerSetting *
|
||||||
req.Header.Set("User-Agent", c.userAgent)
|
req.Header.Set("User-Agent", c.userAgent)
|
||||||
}
|
}
|
||||||
|
|
||||||
httpClient := c.getHTTPClient()
|
resp, err := c.Do(req)
|
||||||
|
|
||||||
resp, err := httpClient.Do(req)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -667,9 +645,7 @@ func (c *Client) GetRunner(ctx context.Context, runnerId int64) (*RunnerReferenc
|
||||||
req.Header.Set("User-Agent", c.userAgent)
|
req.Header.Set("User-Agent", c.userAgent)
|
||||||
}
|
}
|
||||||
|
|
||||||
httpClient := c.getHTTPClient()
|
resp, err := c.Do(req)
|
||||||
|
|
||||||
resp, err := httpClient.Do(req)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -705,9 +681,7 @@ func (c *Client) GetRunnerByName(ctx context.Context, runnerName string) (*Runne
|
||||||
req.Header.Set("User-Agent", c.userAgent)
|
req.Header.Set("User-Agent", c.userAgent)
|
||||||
}
|
}
|
||||||
|
|
||||||
httpClient := c.getHTTPClient()
|
resp, err := c.Do(req)
|
||||||
|
|
||||||
resp, err := httpClient.Do(req)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -752,9 +726,7 @@ func (c *Client) RemoveRunner(ctx context.Context, runnerId int64) error {
|
||||||
req.Header.Set("User-Agent", c.userAgent)
|
req.Header.Set("User-Agent", c.userAgent)
|
||||||
}
|
}
|
||||||
|
|
||||||
httpClient := c.getHTTPClient()
|
resp, err := c.Do(req)
|
||||||
|
|
||||||
resp, err := httpClient.Do(req)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -1012,24 +984,6 @@ func createJWTForGitHubApp(appAuth *GitHubAppAuth) (string, error) {
|
||||||
return token.SignedString(privateKey)
|
return token.SignedString(privateKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) getHTTPClient() *http.Client {
|
|
||||||
if c.Client != nil {
|
|
||||||
return c.Client
|
|
||||||
}
|
|
||||||
|
|
||||||
retryClient := retryablehttp.NewClient()
|
|
||||||
|
|
||||||
if c.RetryMax != nil {
|
|
||||||
retryClient.RetryMax = *c.RetryMax
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.RetryWaitMax != nil {
|
|
||||||
retryClient.RetryWaitMax = *c.RetryWaitMax
|
|
||||||
}
|
|
||||||
|
|
||||||
return retryClient.StandardClient()
|
|
||||||
}
|
|
||||||
|
|
||||||
func unmarshalBody(response *http.Response, v interface{}) (err error) {
|
func unmarshalBody(response *http.Response, v interface{}) (err error) {
|
||||||
if response != nil && response.Body != nil {
|
if response != nil && response.Body != nil {
|
||||||
var err error
|
var err error
|
||||||
|
|
|
||||||
|
|
@ -3,73 +3,60 @@ package actions_test
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/actions/actions-runner-controller/github/actions"
|
"github.com/actions/actions-runner-controller/github/actions"
|
||||||
"github.com/google/go-cmp/cmp"
|
|
||||||
"github.com/hashicorp/go-retryablehttp"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGenerateJitRunnerConfig(t *testing.T) {
|
func TestGenerateJitRunnerConfig(t *testing.T) {
|
||||||
token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjI1MTYyMzkwMjJ9.tlrHslTmDkoqnc4Kk9ISoKoUNDfHo-kjlH-ByISBqzE"
|
ctx := context.Background()
|
||||||
|
auth := &actions.ActionsAuth{
|
||||||
|
Token: "token",
|
||||||
|
}
|
||||||
|
|
||||||
t.Run("Get JIT Config for Runner", func(t *testing.T) {
|
t.Run("Get JIT Config for Runner", func(t *testing.T) {
|
||||||
name := "Get JIT Config for Runner"
|
|
||||||
want := &actions.RunnerScaleSetJitRunnerConfig{}
|
want := &actions.RunnerScaleSetJitRunnerConfig{}
|
||||||
response := []byte(`{"count":1,"value":[{"id":1,"name":"scale-set-name"}]}`)
|
response := []byte(`{"count":1,"value":[{"id":1,"name":"scale-set-name"}]}`)
|
||||||
|
|
||||||
runnerSettings := &actions.RunnerScaleSetJitRunnerSetting{}
|
runnerSettings := &actions.RunnerScaleSetJitRunnerSetting{}
|
||||||
|
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
server := newActionsServer(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||||
w.Write(response)
|
w.Write(response)
|
||||||
}))
|
}))
|
||||||
defer s.Close()
|
client, err := actions.NewClient(ctx, server.configURLForOrg("my-org"), auth)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
actionsClient := actions.Client{
|
got, err := client.GenerateJitRunnerConfig(ctx, runnerSettings, 1)
|
||||||
ActionsServiceURL: &s.URL,
|
require.NoError(t, err)
|
||||||
ActionsServiceAdminToken: &token,
|
assert.Equal(t, want, got)
|
||||||
ActionsServiceAdminTokenExpiresAt: &tokenExpireAt,
|
|
||||||
}
|
|
||||||
|
|
||||||
got, err := actionsClient.GenerateJitRunnerConfig(context.Background(), runnerSettings, 1)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("GenerateJitRunnerConfig got unexepected error, %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if diff := cmp.Diff(want, got); diff != "" {
|
|
||||||
t.Errorf("GenerateJitRunnerConfig(%v) mismatch (-want +got):\n%s", name, diff)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Default retries on server error", func(t *testing.T) {
|
t.Run("Default retries on server error", func(t *testing.T) {
|
||||||
runnerSettings := &actions.RunnerScaleSetJitRunnerSetting{}
|
runnerSettings := &actions.RunnerScaleSetJitRunnerSetting{}
|
||||||
|
|
||||||
retryClient := retryablehttp.NewClient()
|
retryMax := 1
|
||||||
retryClient.RetryWaitMax = 1 * time.Millisecond
|
|
||||||
retryClient.RetryMax = 1
|
|
||||||
|
|
||||||
actualRetry := 0
|
actualRetry := 0
|
||||||
expectedRetry := retryClient.RetryMax + 1
|
expectedRetry := retryMax + 1
|
||||||
|
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
server := newActionsServer(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||||
w.WriteHeader(http.StatusServiceUnavailable)
|
w.WriteHeader(http.StatusServiceUnavailable)
|
||||||
actualRetry++
|
actualRetry++
|
||||||
}))
|
}))
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
httpClient := retryClient.StandardClient()
|
client, err := actions.NewClient(
|
||||||
actionsClient := actions.Client{
|
ctx,
|
||||||
Client: httpClient,
|
server.configURLForOrg("my-org"),
|
||||||
ActionsServiceURL: &s.URL,
|
auth,
|
||||||
ActionsServiceAdminToken: &token,
|
actions.WithRetryMax(1),
|
||||||
ActionsServiceAdminTokenExpiresAt: &tokenExpireAt,
|
actions.WithRetryWaitMax(1*time.Millisecond),
|
||||||
}
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
_, _ = actionsClient.GenerateJitRunnerConfig(context.Background(), runnerSettings, 1)
|
|
||||||
|
|
||||||
|
_, err = client.GenerateJitRunnerConfig(ctx, runnerSettings, 1)
|
||||||
|
assert.NotNil(t, err)
|
||||||
assert.Equalf(t, actualRetry, expectedRetry, "A retry was expected after the first request but got: %v", actualRetry)
|
assert.Equalf(t, actualRetry, expectedRetry, "A retry was expected after the first request but got: %v", actualRetry)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,22 +3,21 @@ package actions_test
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/actions/actions-runner-controller/github/actions"
|
"github.com/actions/actions-runner-controller/github/actions"
|
||||||
"github.com/google/go-cmp/cmp"
|
|
||||||
"github.com/hashicorp/go-retryablehttp"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAcquireJobs(t *testing.T) {
|
func TestAcquireJobs(t *testing.T) {
|
||||||
token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjI1MTYyMzkwMjJ9.tlrHslTmDkoqnc4Kk9ISoKoUNDfHo-kjlH-ByISBqzE"
|
ctx := context.Background()
|
||||||
|
auth := &actions.ActionsAuth{
|
||||||
|
Token: "token",
|
||||||
|
}
|
||||||
|
|
||||||
t.Run("Acquire Job", func(t *testing.T) {
|
t.Run("Acquire Job", func(t *testing.T) {
|
||||||
name := "Acquire Job"
|
|
||||||
|
|
||||||
want := []int64{1}
|
want := []int64{1}
|
||||||
response := []byte(`{"value": [1]}`)
|
response := []byte(`{"value": [1]}`)
|
||||||
|
|
||||||
|
|
@ -28,24 +27,16 @@ func TestAcquireJobs(t *testing.T) {
|
||||||
}
|
}
|
||||||
requestIDs := want
|
requestIDs := want
|
||||||
|
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
server := newActionsServer(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||||
w.Write(response)
|
w.Write(response)
|
||||||
}))
|
}))
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
actionsClient := actions.Client{
|
client, err := actions.NewClient(ctx, server.configURLForOrg("my-org"), auth)
|
||||||
ActionsServiceURL: &s.URL,
|
require.NoError(t, err)
|
||||||
ActionsServiceAdminToken: &token,
|
|
||||||
}
|
|
||||||
|
|
||||||
got, err := actionsClient.AcquireJobs(context.Background(), session.RunnerScaleSet.Id, session.MessageQueueAccessToken, requestIDs)
|
got, err := client.AcquireJobs(ctx, session.RunnerScaleSet.Id, session.MessageQueueAccessToken, requestIDs)
|
||||||
if err != nil {
|
require.NoError(t, err)
|
||||||
t.Fatalf("CreateRunnerScaleSet got unexepected error, %v", err)
|
assert.Equal(t, want, got)
|
||||||
}
|
|
||||||
|
|
||||||
if diff := cmp.Diff(want, got); diff != "" {
|
|
||||||
t.Errorf("GetRunnerScaleSet(%v) mismatch (-want +got):\n%s", name, diff)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Default retries on server error", func(t *testing.T) {
|
t.Run("Default retries on server error", func(t *testing.T) {
|
||||||
|
|
@ -55,90 +46,78 @@ func TestAcquireJobs(t *testing.T) {
|
||||||
}
|
}
|
||||||
var requestIDs []int64 = []int64{1}
|
var requestIDs []int64 = []int64{1}
|
||||||
|
|
||||||
retryClient := retryablehttp.NewClient()
|
retryMax := 1
|
||||||
retryClient.RetryWaitMax = 1 * time.Millisecond
|
|
||||||
retryClient.RetryMax = 1
|
|
||||||
|
|
||||||
actualRetry := 0
|
actualRetry := 0
|
||||||
expectedRetry := retryClient.RetryMax + 1
|
expectedRetry := retryMax + 1
|
||||||
|
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
server := newActionsServer(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||||
w.WriteHeader(http.StatusServiceUnavailable)
|
w.WriteHeader(http.StatusServiceUnavailable)
|
||||||
actualRetry++
|
actualRetry++
|
||||||
}))
|
}))
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
httpClient := retryClient.StandardClient()
|
client, err := actions.NewClient(
|
||||||
actionsClient := actions.Client{
|
ctx,
|
||||||
Client: httpClient,
|
server.configURLForOrg("my-org"),
|
||||||
ActionsServiceURL: &s.URL,
|
auth,
|
||||||
ActionsServiceAdminToken: &token,
|
actions.WithRetryMax(retryMax),
|
||||||
}
|
actions.WithRetryWaitMax(1*time.Millisecond),
|
||||||
|
)
|
||||||
_, _ = actionsClient.AcquireJobs(context.Background(), session.RunnerScaleSet.Id, session.MessageQueueAccessToken, requestIDs)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
_, err = client.AcquireJobs(context.Background(), session.RunnerScaleSet.Id, session.MessageQueueAccessToken, requestIDs)
|
||||||
|
assert.NotNil(t, err)
|
||||||
assert.Equalf(t, actualRetry, expectedRetry, "A retry was expected after the first request but got: %v", actualRetry)
|
assert.Equalf(t, actualRetry, expectedRetry, "A retry was expected after the first request but got: %v", actualRetry)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetAcquirableJobs(t *testing.T) {
|
func TestGetAcquirableJobs(t *testing.T) {
|
||||||
token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjI1MTYyMzkwMjJ9.tlrHslTmDkoqnc4Kk9ISoKoUNDfHo-kjlH-ByISBqzE"
|
ctx := context.Background()
|
||||||
|
auth := &actions.ActionsAuth{
|
||||||
|
Token: "token",
|
||||||
|
}
|
||||||
|
|
||||||
t.Run("Acquire Job", func(t *testing.T) {
|
t.Run("Acquire Job", func(t *testing.T) {
|
||||||
name := "Acquire Job"
|
|
||||||
|
|
||||||
want := &actions.AcquirableJobList{}
|
want := &actions.AcquirableJobList{}
|
||||||
response := []byte(`{"count": 0}`)
|
response := []byte(`{"count": 0}`)
|
||||||
|
|
||||||
runnerScaleSet := &actions.RunnerScaleSet{Id: 1}
|
runnerScaleSet := &actions.RunnerScaleSet{Id: 1}
|
||||||
|
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
server := newActionsServer(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||||
w.Write(response)
|
w.Write(response)
|
||||||
}))
|
}))
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
actionsClient := actions.Client{
|
client, err := actions.NewClient(ctx, server.configURLForOrg("my-org"), auth)
|
||||||
ActionsServiceURL: &s.URL,
|
require.NoError(t, err)
|
||||||
ActionsServiceAdminToken: &token,
|
|
||||||
ActionsServiceAdminTokenExpiresAt: &tokenExpireAt,
|
|
||||||
}
|
|
||||||
|
|
||||||
got, err := actionsClient.GetAcquirableJobs(context.Background(), runnerScaleSet.Id)
|
got, err := client.GetAcquirableJobs(context.Background(), runnerScaleSet.Id)
|
||||||
if err != nil {
|
require.NoError(t, err)
|
||||||
t.Fatalf("GetAcquirableJobs got unexepected error, %v", err)
|
assert.Equal(t, want, got)
|
||||||
}
|
|
||||||
|
|
||||||
if diff := cmp.Diff(want, got); diff != "" {
|
|
||||||
t.Errorf("GetAcquirableJobs(%v) mismatch (-want +got):\n%s", name, diff)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Default retries on server error", func(t *testing.T) {
|
t.Run("Default retries on server error", func(t *testing.T) {
|
||||||
runnerScaleSet := &actions.RunnerScaleSet{Id: 1}
|
runnerScaleSet := &actions.RunnerScaleSet{Id: 1}
|
||||||
|
|
||||||
retryClient := retryablehttp.NewClient()
|
retryMax := 1
|
||||||
retryClient.RetryWaitMax = 1 * time.Millisecond
|
|
||||||
retryClient.RetryMax = 1
|
|
||||||
|
|
||||||
actualRetry := 0
|
actualRetry := 0
|
||||||
expectedRetry := retryClient.RetryMax + 1
|
expectedRetry := retryMax + 1
|
||||||
|
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
server := newActionsServer(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||||
w.WriteHeader(http.StatusServiceUnavailable)
|
w.WriteHeader(http.StatusServiceUnavailable)
|
||||||
actualRetry++
|
actualRetry++
|
||||||
}))
|
}))
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
httpClient := retryClient.StandardClient()
|
client, err := actions.NewClient(
|
||||||
actionsClient := actions.Client{
|
context.Background(),
|
||||||
Client: httpClient,
|
server.configURLForOrg("my-org"),
|
||||||
ActionsServiceURL: &s.URL,
|
auth,
|
||||||
ActionsServiceAdminToken: &token,
|
actions.WithRetryMax(retryMax),
|
||||||
ActionsServiceAdminTokenExpiresAt: &tokenExpireAt,
|
actions.WithRetryWaitMax(1*time.Millisecond),
|
||||||
}
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
_, _ = actionsClient.GetAcquirableJobs(context.Background(), runnerScaleSet.Id)
|
|
||||||
|
|
||||||
|
_, err = client.GetAcquirableJobs(context.Background(), runnerScaleSet.Id)
|
||||||
|
require.Error(t, err)
|
||||||
assert.Equalf(t, actualRetry, expectedRetry, "A retry was expected after the first request but got: %v", actualRetry)
|
assert.Equalf(t, actualRetry, expectedRetry, "A retry was expected after the first request but got: %v", actualRetry)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,18 +5,20 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/actions/actions-runner-controller/github/actions"
|
"github.com/actions/actions-runner-controller/github/actions"
|
||||||
"github.com/google/go-cmp/cmp"
|
|
||||||
"github.com/hashicorp/go-retryablehttp"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGetMessage(t *testing.T) {
|
func TestGetMessage(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
auth := &actions.ActionsAuth{
|
||||||
|
Token: "token",
|
||||||
|
}
|
||||||
|
|
||||||
token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjI1MTYyMzkwMjJ9.tlrHslTmDkoqnc4Kk9ISoKoUNDfHo-kjlH-ByISBqzE"
|
token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjI1MTYyMzkwMjJ9.tlrHslTmDkoqnc4Kk9ISoKoUNDfHo-kjlH-ByISBqzE"
|
||||||
runnerScaleSetMessage := &actions.RunnerScaleSetMessage{
|
runnerScaleSetMessage := &actions.RunnerScaleSetMessage{
|
||||||
MessageId: 1,
|
MessageId: 1,
|
||||||
|
|
@ -26,89 +28,54 @@ func TestGetMessage(t *testing.T) {
|
||||||
t.Run("Get Runner Scale Set Message", func(t *testing.T) {
|
t.Run("Get Runner Scale Set Message", func(t *testing.T) {
|
||||||
want := runnerScaleSetMessage
|
want := runnerScaleSetMessage
|
||||||
response := []byte(`{"messageId":1,"messageType":"rssType"}`)
|
response := []byte(`{"messageId":1,"messageType":"rssType"}`)
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
s := newActionsServer(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||||
w.Write(response)
|
w.Write(response)
|
||||||
}))
|
}))
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
actionsClient := actions.Client{
|
client, err := actions.NewClient(ctx, s.configURLForOrg("my-org"), auth)
|
||||||
ActionsServiceURL: &s.URL,
|
require.NoError(t, err)
|
||||||
ActionsServiceAdminToken: &token,
|
|
||||||
ActionsServiceAdminTokenExpiresAt: &tokenExpireAt,
|
|
||||||
}
|
|
||||||
|
|
||||||
got, err := actionsClient.GetMessage(context.Background(), s.URL, token, 0)
|
got, err := client.GetMessage(ctx, s.URL, token, 0)
|
||||||
if err != nil {
|
require.NoError(t, err)
|
||||||
t.Fatalf("GetMessage got unexepected error, %v", err)
|
assert.Equal(t, want, got)
|
||||||
}
|
|
||||||
|
|
||||||
if diff := cmp.Diff(want, got); diff != "" {
|
|
||||||
t.Errorf("GetMessage mismatch (-want +got):\n%s", diff)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Default retries on server error", func(t *testing.T) {
|
t.Run("Default retries on server error", func(t *testing.T) {
|
||||||
retryClient := retryablehttp.NewClient()
|
retryMax := 1
|
||||||
retryClient.RetryWaitMax = 1 * time.Nanosecond
|
|
||||||
retryClient.RetryMax = 1
|
|
||||||
|
|
||||||
actualRetry := 0
|
actualRetry := 0
|
||||||
expectedRetry := retryClient.RetryMax + 1
|
expectedRetry := retryMax + 1
|
||||||
|
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
server := newActionsServer(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||||
w.WriteHeader(http.StatusServiceUnavailable)
|
w.WriteHeader(http.StatusServiceUnavailable)
|
||||||
actualRetry++
|
actualRetry++
|
||||||
}))
|
}))
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
httpClient := retryClient.StandardClient()
|
client, err := actions.NewClient(
|
||||||
actionsClient := actions.Client{
|
ctx,
|
||||||
Client: httpClient,
|
server.configURLForOrg("my-org"),
|
||||||
ActionsServiceURL: &s.URL,
|
auth,
|
||||||
ActionsServiceAdminToken: &token,
|
actions.WithRetryMax(retryMax),
|
||||||
ActionsServiceAdminTokenExpiresAt: &tokenExpireAt,
|
actions.WithRetryWaitMax(1*time.Millisecond),
|
||||||
}
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
_, _ = actionsClient.GetMessage(context.Background(), s.URL, token, 0)
|
|
||||||
|
|
||||||
|
_, err = client.GetMessage(ctx, server.URL, token, 0)
|
||||||
|
assert.NotNil(t, err)
|
||||||
assert.Equalf(t, actualRetry, expectedRetry, "A retry was expected after the first request but got: %v", actualRetry)
|
assert.Equalf(t, actualRetry, expectedRetry, "A retry was expected after the first request but got: %v", actualRetry)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Custom retries on server error", func(t *testing.T) {
|
|
||||||
actualRetry := 0
|
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
||||||
w.WriteHeader(http.StatusServiceUnavailable)
|
|
||||||
actualRetry++
|
|
||||||
}))
|
|
||||||
defer s.Close()
|
|
||||||
retryMax := 1
|
|
||||||
retryWaitMax := 1 * time.Nanosecond
|
|
||||||
actionsClient := actions.Client{
|
|
||||||
ActionsServiceURL: &s.URL,
|
|
||||||
ActionsServiceAdminToken: &token,
|
|
||||||
RetryMax: &retryMax,
|
|
||||||
RetryWaitMax: &retryWaitMax,
|
|
||||||
}
|
|
||||||
_, _ = actionsClient.GetMessage(context.Background(), s.URL, token, 0)
|
|
||||||
expectedRetry := retryMax + 1
|
|
||||||
assert.Equalf(t, actualRetry, expectedRetry, "A retry was expected after the first request but got: %v", actualRetry)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
t.Run("Message token expired", func(t *testing.T) {
|
t.Run("Message token expired", func(t *testing.T) {
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
server := newActionsServer(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
}))
|
}))
|
||||||
defer s.Close()
|
|
||||||
actionsClient := actions.Client{
|
client, err := actions.NewClient(ctx, server.configURLForOrg("my-org"), auth)
|
||||||
ActionsServiceURL: &s.URL,
|
require.NoError(t, err)
|
||||||
ActionsServiceAdminToken: &token,
|
|
||||||
ActionsServiceAdminTokenExpiresAt: &tokenExpireAt,
|
_, err = client.GetMessage(ctx, server.URL, token, 0)
|
||||||
}
|
require.NotNil(t, err)
|
||||||
_, err := actionsClient.GetMessage(context.Background(), s.URL, token, 0)
|
|
||||||
if err == nil {
|
|
||||||
t.Fatalf("GetMessage did not get exepected error, ")
|
|
||||||
}
|
|
||||||
var expectedErr *actions.MessageQueueTokenExpiredError
|
var expectedErr *actions.MessageQueueTokenExpiredError
|
||||||
require.True(t, errors.As(err, &expectedErr))
|
require.True(t, errors.As(err, &expectedErr))
|
||||||
},
|
},
|
||||||
|
|
@ -119,45 +86,38 @@ func TestGetMessage(t *testing.T) {
|
||||||
Message: "Request returned status: 404 Not Found",
|
Message: "Request returned status: 404 Not Found",
|
||||||
StatusCode: 404,
|
StatusCode: 404,
|
||||||
}
|
}
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
server := newActionsServer(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
}))
|
}))
|
||||||
defer s.Close()
|
|
||||||
actionsClient := actions.Client{
|
client, err := actions.NewClient(ctx, server.configURLForOrg("my-org"), auth)
|
||||||
ActionsServiceURL: &s.URL,
|
require.NoError(t, err)
|
||||||
ActionsServiceAdminToken: &token,
|
|
||||||
ActionsServiceAdminTokenExpiresAt: &tokenExpireAt,
|
_, err = client.GetMessage(ctx, server.URL, token, 0)
|
||||||
}
|
require.NotNil(t, err)
|
||||||
_, err := actionsClient.GetMessage(context.Background(), s.URL, token, 0)
|
assert.Equal(t, want.Error(), err.Error())
|
||||||
if err == nil {
|
})
|
||||||
t.Fatalf("GetMessage did not get exepected error, ")
|
|
||||||
}
|
|
||||||
if diff := cmp.Diff(want.Error(), err.Error()); diff != "" {
|
|
||||||
t.Errorf("GetMessage mismatch (-want +got):\n%s", diff)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
t.Run("Error when Content-Type is text/plain", func(t *testing.T) {
|
t.Run("Error when Content-Type is text/plain", func(t *testing.T) {
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
server := newActionsServer(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
w.Header().Set("Content-Type", "text/plain")
|
w.Header().Set("Content-Type", "text/plain")
|
||||||
}))
|
}))
|
||||||
defer s.Close()
|
|
||||||
actionsClient := actions.Client{
|
client, err := actions.NewClient(ctx, server.configURLForOrg("my-org"), auth)
|
||||||
ActionsServiceURL: &s.URL,
|
require.NoError(t, err)
|
||||||
ActionsServiceAdminToken: &token,
|
|
||||||
ActionsServiceAdminTokenExpiresAt: &tokenExpireAt,
|
_, err = client.GetMessage(ctx, server.URL, token, 0)
|
||||||
}
|
assert.NotNil(t, err)
|
||||||
_, err := actionsClient.GetMessage(context.Background(), s.URL, token, 0)
|
})
|
||||||
if err == nil {
|
|
||||||
t.Fatalf("GetMessage did not get exepected error,")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeleteMessage(t *testing.T) {
|
func TestDeleteMessage(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
auth := &actions.ActionsAuth{
|
||||||
|
Token: "token",
|
||||||
|
}
|
||||||
|
|
||||||
token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjI1MTYyMzkwMjJ9.tlrHslTmDkoqnc4Kk9ISoKoUNDfHo-kjlH-ByISBqzE"
|
token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjI1MTYyMzkwMjJ9.tlrHslTmDkoqnc4Kk9ISoKoUNDfHo-kjlH-ByISBqzE"
|
||||||
runnerScaleSetMessage := &actions.RunnerScaleSetMessage{
|
runnerScaleSetMessage := &actions.RunnerScaleSetMessage{
|
||||||
MessageId: 1,
|
MessageId: 1,
|
||||||
|
|
@ -165,105 +125,83 @@ func TestDeleteMessage(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Run("Delete existing message", func(t *testing.T) {
|
t.Run("Delete existing message", func(t *testing.T) {
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
server := newActionsServer(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||||
w.WriteHeader(http.StatusNoContent)
|
w.WriteHeader(http.StatusNoContent)
|
||||||
}))
|
}))
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
actionsClient := actions.Client{
|
client, err := actions.NewClient(ctx, server.configURLForOrg("my-org"), auth)
|
||||||
ActionsServiceURL: &s.URL,
|
require.NoError(t, err)
|
||||||
ActionsServiceAdminToken: &token,
|
|
||||||
ActionsServiceAdminTokenExpiresAt: &tokenExpireAt,
|
err = client.DeleteMessage(ctx, server.URL, token, runnerScaleSetMessage.MessageId)
|
||||||
}
|
assert.Nil(t, err)
|
||||||
err := actionsClient.DeleteMessage(context.Background(), s.URL, token, runnerScaleSetMessage.MessageId)
|
})
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("DeleteMessage got unexepected error, %v", err)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
t.Run("Message token expired", func(t *testing.T) {
|
t.Run("Message token expired", func(t *testing.T) {
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
server := newActionsServer(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
}))
|
}))
|
||||||
defer s.Close()
|
|
||||||
actionsClient := actions.Client{
|
client, err := actions.NewClient(ctx, server.configURLForOrg("my-org"), auth)
|
||||||
ActionsServiceURL: &s.URL,
|
require.NoError(t, err)
|
||||||
ActionsServiceAdminToken: &token,
|
|
||||||
ActionsServiceAdminTokenExpiresAt: &tokenExpireAt,
|
err = client.DeleteMessage(ctx, server.URL, token, 0)
|
||||||
}
|
require.NotNil(t, err)
|
||||||
err := actionsClient.DeleteMessage(context.Background(), s.URL, token, 0)
|
|
||||||
if err == nil {
|
|
||||||
t.Fatalf("DeleteMessage did not get exepected error, ")
|
|
||||||
}
|
|
||||||
var expectedErr *actions.MessageQueueTokenExpiredError
|
var expectedErr *actions.MessageQueueTokenExpiredError
|
||||||
require.True(t, errors.As(err, &expectedErr))
|
assert.True(t, errors.As(err, &expectedErr))
|
||||||
},
|
})
|
||||||
)
|
|
||||||
|
|
||||||
t.Run("Error when Content-Type is text/plain", func(t *testing.T) {
|
t.Run("Error when Content-Type is text/plain", func(t *testing.T) {
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
server := newActionsServer(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
w.Header().Set("Content-Type", "text/plain")
|
w.Header().Set("Content-Type", "text/plain")
|
||||||
}))
|
}))
|
||||||
defer s.Close()
|
|
||||||
actionsClient := actions.Client{
|
client, err := actions.NewClient(ctx, server.configURLForOrg("my-org"), auth)
|
||||||
ActionsServiceURL: &s.URL,
|
require.NoError(t, err)
|
||||||
ActionsServiceAdminToken: &token,
|
|
||||||
ActionsServiceAdminTokenExpiresAt: &tokenExpireAt,
|
err = client.DeleteMessage(ctx, server.URL, token, runnerScaleSetMessage.MessageId)
|
||||||
}
|
require.NotNil(t, err)
|
||||||
err := actionsClient.DeleteMessage(context.Background(), s.URL, token, runnerScaleSetMessage.MessageId)
|
|
||||||
if err == nil {
|
|
||||||
t.Fatalf("DeleteMessage did not get exepected error")
|
|
||||||
}
|
|
||||||
var expectedErr *actions.ActionsError
|
var expectedErr *actions.ActionsError
|
||||||
require.True(t, errors.As(err, &expectedErr))
|
assert.True(t, errors.As(err, &expectedErr))
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
t.Run("Default retries on server error", func(t *testing.T) {
|
t.Run("Default retries on server error", func(t *testing.T) {
|
||||||
actualRetry := 0
|
actualRetry := 0
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
server := newActionsServer(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||||
w.WriteHeader(http.StatusServiceUnavailable)
|
w.WriteHeader(http.StatusServiceUnavailable)
|
||||||
actualRetry++
|
actualRetry++
|
||||||
}))
|
}))
|
||||||
defer s.Close()
|
|
||||||
retryClient := retryablehttp.NewClient()
|
|
||||||
retryMax := 1
|
retryMax := 1
|
||||||
retryClient.RetryWaitMax = time.Nanosecond
|
client, err := actions.NewClient(
|
||||||
retryClient.RetryMax = retryMax
|
ctx,
|
||||||
httpClient := retryClient.StandardClient()
|
server.configURLForOrg("my-org"),
|
||||||
actionsClient := actions.Client{
|
auth,
|
||||||
Client: httpClient,
|
actions.WithRetryMax(retryMax),
|
||||||
ActionsServiceURL: &s.URL,
|
actions.WithRetryWaitMax(1*time.Nanosecond),
|
||||||
ActionsServiceAdminToken: &token,
|
)
|
||||||
ActionsServiceAdminTokenExpiresAt: &tokenExpireAt,
|
require.NoError(t, err)
|
||||||
}
|
err = client.DeleteMessage(ctx, server.URL, token, runnerScaleSetMessage.MessageId)
|
||||||
_ = actionsClient.DeleteMessage(context.Background(), s.URL, token, runnerScaleSetMessage.MessageId)
|
assert.NotNil(t, err)
|
||||||
expectedRetry := retryMax + 1
|
expectedRetry := retryMax + 1
|
||||||
assert.Equalf(t, actualRetry, expectedRetry, "A retry was expected after the first request but got: %v", actualRetry)
|
assert.Equalf(t, actualRetry, expectedRetry, "A retry was expected after the first request but got: %v", actualRetry)
|
||||||
},
|
})
|
||||||
)
|
|
||||||
|
|
||||||
t.Run("No message found", func(t *testing.T) {
|
t.Run("No message found", func(t *testing.T) {
|
||||||
want := (*actions.RunnerScaleSetMessage)(nil)
|
want := (*actions.RunnerScaleSetMessage)(nil)
|
||||||
rsl, err := json.Marshal(want)
|
rsl, err := json.Marshal(want)
|
||||||
if err != nil {
|
require.NoError(t, err)
|
||||||
t.Fatalf("%v", err)
|
|
||||||
}
|
server := newActionsServer(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
||||||
w.Write(rsl)
|
w.Write(rsl)
|
||||||
}))
|
}))
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
actionsClient := actions.Client{
|
client, err := actions.NewClient(ctx, server.configURLForOrg("my-org"), auth)
|
||||||
ActionsServiceURL: &s.URL,
|
require.NoError(t, err)
|
||||||
ActionsServiceAdminToken: &token,
|
|
||||||
ActionsServiceAdminTokenExpiresAt: &tokenExpireAt,
|
err = client.DeleteMessage(ctx, server.URL, token, runnerScaleSetMessage.MessageId+1)
|
||||||
}
|
|
||||||
err = actionsClient.DeleteMessage(context.Background(), s.URL, token, runnerScaleSetMessage.MessageId+1)
|
|
||||||
var expectedErr *actions.ActionsError
|
var expectedErr *actions.ActionsError
|
||||||
require.True(t, errors.As(err, &expectedErr))
|
require.True(t, errors.As(err, &expectedErr))
|
||||||
},
|
})
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,19 +4,22 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/actions/actions-runner-controller/github/actions"
|
"github.com/actions/actions-runner-controller/github/actions"
|
||||||
"github.com/google/go-cmp/cmp"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCreateMessageSession(t *testing.T) {
|
func TestCreateMessageSession(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
auth := &actions.ActionsAuth{
|
||||||
|
Token: "token",
|
||||||
|
}
|
||||||
|
|
||||||
t.Run("CreateMessageSession unmarshals correctly", func(t *testing.T) {
|
t.Run("CreateMessageSession unmarshals correctly", func(t *testing.T) {
|
||||||
token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjI1MTYyMzkwMjJ9.tlrHslTmDkoqnc4Kk9ISoKoUNDfHo-kjlH-ByISBqzE"
|
|
||||||
owner := "foo"
|
owner := "foo"
|
||||||
runnerScaleSet := actions.RunnerScaleSet{
|
runnerScaleSet := actions.RunnerScaleSet{
|
||||||
Id: 1,
|
Id: 1,
|
||||||
|
|
@ -35,7 +38,7 @@ func TestCreateMessageSession(t *testing.T) {
|
||||||
MessageQueueAccessToken: "fake.jwt.here",
|
MessageQueueAccessToken: "fake.jwt.here",
|
||||||
}
|
}
|
||||||
|
|
||||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
server := newActionsServer(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||||
resp := []byte(`{
|
resp := []byte(`{
|
||||||
"ownerName": "foo",
|
"ownerName": "foo",
|
||||||
"runnerScaleSet": {
|
"runnerScaleSet": {
|
||||||
|
|
@ -47,31 +50,16 @@ func TestCreateMessageSession(t *testing.T) {
|
||||||
}`)
|
}`)
|
||||||
w.Write(resp)
|
w.Write(resp)
|
||||||
}))
|
}))
|
||||||
defer srv.Close()
|
|
||||||
|
|
||||||
retryMax := 1
|
client, err := actions.NewClient(ctx, server.configURLForOrg("my-org"), auth)
|
||||||
retryWaitMax := 1 * time.Microsecond
|
require.NoError(t, err)
|
||||||
|
|
||||||
actionsClient := actions.Client{
|
got, err := client.CreateMessageSession(ctx, runnerScaleSet.Id, owner)
|
||||||
ActionsServiceURL: &srv.URL,
|
require.NoError(t, err)
|
||||||
ActionsServiceAdminToken: &token,
|
assert.Equal(t, want, got)
|
||||||
ActionsServiceAdminTokenExpiresAt: &tokenExpireAt,
|
|
||||||
RetryMax: &retryMax,
|
|
||||||
RetryWaitMax: &retryWaitMax,
|
|
||||||
}
|
|
||||||
|
|
||||||
got, err := actionsClient.CreateMessageSession(context.Background(), runnerScaleSet.Id, owner)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("CreateMessageSession got unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if diff := cmp.Diff(got, want); diff != "" {
|
|
||||||
t.Fatalf("CreateMessageSession got unexpected diff: -want +got: %v", diff)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("CreateMessageSession unmarshals errors into ActionsError", func(t *testing.T) {
|
t.Run("CreateMessageSession unmarshals errors into ActionsError", func(t *testing.T) {
|
||||||
token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjI1MTYyMzkwMjJ9.tlrHslTmDkoqnc4Kk9ISoKoUNDfHo-kjlH-ByISBqzE"
|
|
||||||
owner := "foo"
|
owner := "foo"
|
||||||
runnerScaleSet := actions.RunnerScaleSet{
|
runnerScaleSet := actions.RunnerScaleSet{
|
||||||
Id: 1,
|
Id: 1,
|
||||||
|
|
@ -86,44 +74,32 @@ func TestCreateMessageSession(t *testing.T) {
|
||||||
StatusCode: http.StatusBadRequest,
|
StatusCode: http.StatusBadRequest,
|
||||||
}
|
}
|
||||||
|
|
||||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
server := newActionsServer(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
resp := []byte(`{"typeName": "CSharpExceptionNameHere","message": "could not do something"}`)
|
resp := []byte(`{"typeName": "CSharpExceptionNameHere","message": "could not do something"}`)
|
||||||
w.Write(resp)
|
w.Write(resp)
|
||||||
}))
|
}))
|
||||||
defer srv.Close()
|
|
||||||
|
|
||||||
retryMax := 1
|
client, err := actions.NewClient(ctx, server.configURLForOrg("my-org"), auth)
|
||||||
retryWaitMax := 1 * time.Microsecond
|
require.NoError(t, err)
|
||||||
|
|
||||||
actionsClient := actions.Client{
|
_, err = client.CreateMessageSession(ctx, runnerScaleSet.Id, owner)
|
||||||
ActionsServiceURL: &srv.URL,
|
require.NotNil(t, err)
|
||||||
ActionsServiceAdminToken: &token,
|
|
||||||
ActionsServiceAdminTokenExpiresAt: &tokenExpireAt,
|
|
||||||
RetryMax: &retryMax,
|
|
||||||
RetryWaitMax: &retryWaitMax,
|
|
||||||
}
|
|
||||||
|
|
||||||
got, err := actionsClient.CreateMessageSession(context.Background(), runnerScaleSet.Id, owner)
|
|
||||||
if err == nil {
|
|
||||||
t.Fatalf("CreateMessageSession did not get expected error: %v", got)
|
|
||||||
}
|
|
||||||
|
|
||||||
errorTypeForComparison := &actions.ActionsError{}
|
errorTypeForComparison := &actions.ActionsError{}
|
||||||
if isActionsError := errors.As(err, &errorTypeForComparison); !isActionsError {
|
assert.True(
|
||||||
t.Fatalf("CreateMessageSession expected to be able to parse the error into ActionsError type: %v", err)
|
t,
|
||||||
}
|
errors.As(err, &errorTypeForComparison),
|
||||||
|
"CreateMessageSession expected to be able to parse the error into ActionsError type: %v",
|
||||||
|
err,
|
||||||
|
)
|
||||||
|
|
||||||
gotErr := err.(*actions.ActionsError)
|
gotErr := err.(*actions.ActionsError)
|
||||||
|
assert.Equal(t, want, gotErr)
|
||||||
if diff := cmp.Diff(want, gotErr); diff != "" {
|
|
||||||
t.Fatalf("CreateMessageSession got unexpected diff: -want +got: %v", diff)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("CreateMessageSession call is retried the correct amount of times", func(t *testing.T) {
|
t.Run("CreateMessageSession call is retried the correct amount of times", func(t *testing.T) {
|
||||||
token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjI1MTYyMzkwMjJ9.tlrHslTmDkoqnc4Kk9ISoKoUNDfHo-kjlH-ByISBqzE"
|
|
||||||
owner := "foo"
|
owner := "foo"
|
||||||
runnerScaleSet := actions.RunnerScaleSet{
|
runnerScaleSet := actions.RunnerScaleSet{
|
||||||
Id: 1,
|
Id: 1,
|
||||||
|
|
@ -133,37 +109,38 @@ func TestCreateMessageSession(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
gotRetries := 0
|
gotRetries := 0
|
||||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
server := newActionsServer(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
gotRetries++
|
gotRetries++
|
||||||
}))
|
}))
|
||||||
defer srv.Close()
|
|
||||||
|
|
||||||
retryMax := 3
|
retryMax := 3
|
||||||
retryWaitMax, err := time.ParseDuration("1µs")
|
retryWaitMax := 1 * time.Microsecond
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
wantRetries := retryMax + 1
|
wantRetries := retryMax + 1
|
||||||
|
|
||||||
actionsClient := actions.Client{
|
client, err := actions.NewClient(
|
||||||
ActionsServiceURL: &srv.URL,
|
ctx,
|
||||||
ActionsServiceAdminToken: &token,
|
server.configURLForOrg("my-org"),
|
||||||
ActionsServiceAdminTokenExpiresAt: &tokenExpireAt,
|
auth,
|
||||||
RetryMax: &retryMax,
|
actions.WithRetryMax(retryMax),
|
||||||
RetryWaitMax: &retryWaitMax,
|
actions.WithRetryWaitMax(retryWaitMax),
|
||||||
}
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
_, _ = actionsClient.CreateMessageSession(context.Background(), runnerScaleSet.Id, owner)
|
|
||||||
|
|
||||||
|
_, err = client.CreateMessageSession(ctx, runnerScaleSet.Id, owner)
|
||||||
|
assert.NotNil(t, err)
|
||||||
assert.Equalf(t, gotRetries, wantRetries, "CreateMessageSession got unexpected retry count: got=%v, want=%v", gotRetries, wantRetries)
|
assert.Equalf(t, gotRetries, wantRetries, "CreateMessageSession got unexpected retry count: got=%v, want=%v", gotRetries, wantRetries)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeleteMessageSession(t *testing.T) {
|
func TestDeleteMessageSession(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
auth := &actions.ActionsAuth{
|
||||||
|
Token: "token",
|
||||||
|
}
|
||||||
|
|
||||||
t.Run("DeleteMessageSession call is retried the correct amount of times", func(t *testing.T) {
|
t.Run("DeleteMessageSession call is retried the correct amount of times", func(t *testing.T) {
|
||||||
token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjI1MTYyMzkwMjJ9.tlrHslTmDkoqnc4Kk9ISoKoUNDfHo-kjlH-ByISBqzE"
|
|
||||||
runnerScaleSet := actions.RunnerScaleSet{
|
runnerScaleSet := actions.RunnerScaleSet{
|
||||||
Id: 1,
|
Id: 1,
|
||||||
Name: "ScaleSet",
|
Name: "ScaleSet",
|
||||||
|
|
@ -172,39 +149,40 @@ func TestDeleteMessageSession(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
gotRetries := 0
|
gotRetries := 0
|
||||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
server := newActionsServer(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
gotRetries++
|
gotRetries++
|
||||||
}))
|
}))
|
||||||
defer srv.Close()
|
|
||||||
|
|
||||||
retryMax := 3
|
retryMax := 3
|
||||||
retryWaitMax, err := time.ParseDuration("1µs")
|
retryWaitMax := 1 * time.Microsecond
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
wantRetries := retryMax + 1
|
wantRetries := retryMax + 1
|
||||||
|
|
||||||
actionsClient := actions.Client{
|
client, err := actions.NewClient(
|
||||||
ActionsServiceURL: &srv.URL,
|
ctx,
|
||||||
ActionsServiceAdminToken: &token,
|
server.configURLForOrg("my-org"),
|
||||||
ActionsServiceAdminTokenExpiresAt: &tokenExpireAt,
|
auth,
|
||||||
RetryMax: &retryMax,
|
actions.WithRetryMax(retryMax),
|
||||||
RetryWaitMax: &retryWaitMax,
|
actions.WithRetryWaitMax(retryWaitMax),
|
||||||
}
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
sessionId := uuid.New()
|
sessionId := uuid.New()
|
||||||
|
|
||||||
_ = actionsClient.DeleteMessageSession(context.Background(), runnerScaleSet.Id, &sessionId)
|
err = client.DeleteMessageSession(ctx, runnerScaleSet.Id, &sessionId)
|
||||||
|
assert.NotNil(t, err)
|
||||||
assert.Equalf(t, gotRetries, wantRetries, "CreateMessageSession got unexpected retry count: got=%v, want=%v", gotRetries, wantRetries)
|
assert.Equalf(t, gotRetries, wantRetries, "CreateMessageSession got unexpected retry count: got=%v, want=%v", gotRetries, wantRetries)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRefreshMessageSession(t *testing.T) {
|
func TestRefreshMessageSession(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
auth := &actions.ActionsAuth{
|
||||||
|
Token: "token",
|
||||||
|
}
|
||||||
|
|
||||||
t.Run("RefreshMessageSession call is retried the correct amount of times", func(t *testing.T) {
|
t.Run("RefreshMessageSession call is retried the correct amount of times", func(t *testing.T) {
|
||||||
token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjI1MTYyMzkwMjJ9.tlrHslTmDkoqnc4Kk9ISoKoUNDfHo-kjlH-ByISBqzE"
|
|
||||||
runnerScaleSet := actions.RunnerScaleSet{
|
runnerScaleSet := actions.RunnerScaleSet{
|
||||||
Id: 1,
|
Id: 1,
|
||||||
Name: "ScaleSet",
|
Name: "ScaleSet",
|
||||||
|
|
@ -213,32 +191,29 @@ func TestRefreshMessageSession(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
gotRetries := 0
|
gotRetries := 0
|
||||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
server := newActionsServer(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
gotRetries++
|
gotRetries++
|
||||||
}))
|
}))
|
||||||
defer srv.Close()
|
|
||||||
|
|
||||||
retryMax := 3
|
retryMax := 3
|
||||||
retryWaitMax, err := time.ParseDuration("1µs")
|
retryWaitMax := 1 * time.Microsecond
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
wantRetries := retryMax + 1
|
wantRetries := retryMax + 1
|
||||||
|
|
||||||
actionsClient := actions.Client{
|
client, err := actions.NewClient(
|
||||||
ActionsServiceURL: &srv.URL,
|
ctx,
|
||||||
ActionsServiceAdminToken: &token,
|
server.configURLForOrg("my-org"),
|
||||||
ActionsServiceAdminTokenExpiresAt: &tokenExpireAt,
|
auth,
|
||||||
RetryMax: &retryMax,
|
actions.WithRetryMax(retryMax),
|
||||||
RetryWaitMax: &retryWaitMax,
|
actions.WithRetryWaitMax(retryWaitMax),
|
||||||
}
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
sessionId := uuid.New()
|
sessionId := uuid.New()
|
||||||
|
|
||||||
_, _ = actionsClient.RefreshMessageSession(context.Background(), runnerScaleSet.Id, &sessionId)
|
_, err = client.RefreshMessageSession(context.Background(), runnerScaleSet.Id, &sessionId)
|
||||||
|
assert.NotNil(t, err)
|
||||||
assert.Equalf(t, gotRetries, wantRetries, "CreateMessageSession got unexpected retry count: got=%v, want=%v", gotRetries, wantRetries)
|
assert.Equalf(t, gotRetries, wantRetries, "CreateMessageSession got unexpected retry count: got=%v, want=%v", gotRetries, wantRetries)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -3,23 +3,21 @@ package actions_test
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/actions/actions-runner-controller/github/actions"
|
"github.com/actions/actions-runner-controller/github/actions"
|
||||||
"github.com/google/go-cmp/cmp"
|
|
||||||
"github.com/hashicorp/go-retryablehttp"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
var tokenExpireAt = time.Now().Add(10 * time.Minute)
|
|
||||||
|
|
||||||
func TestGetRunner(t *testing.T) {
|
func TestGetRunner(t *testing.T) {
|
||||||
token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjI1MTYyMzkwMjJ9.tlrHslTmDkoqnc4Kk9ISoKoUNDfHo-kjlH-ByISBqzE"
|
ctx := context.Background()
|
||||||
|
auth := &actions.ActionsAuth{
|
||||||
|
Token: "token",
|
||||||
|
}
|
||||||
|
|
||||||
t.Run("Get Runner", func(t *testing.T) {
|
t.Run("Get Runner", func(t *testing.T) {
|
||||||
name := "Get Runner"
|
|
||||||
var runnerID int64 = 1
|
var runnerID int64 = 1
|
||||||
want := &actions.RunnerReference{
|
want := &actions.RunnerReference{
|
||||||
Id: int(runnerID),
|
Id: int(runnerID),
|
||||||
|
|
@ -27,59 +25,45 @@ func TestGetRunner(t *testing.T) {
|
||||||
}
|
}
|
||||||
response := []byte(`{"id": 1, "name": "self-hosted-ubuntu"}`)
|
response := []byte(`{"id": 1, "name": "self-hosted-ubuntu"}`)
|
||||||
|
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
server := newActionsServer(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Write(response)
|
w.Write(response)
|
||||||
}))
|
}))
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
actionsClient := actions.Client{
|
client, err := actions.NewClient(ctx, server.configURLForOrg("my-org"), auth)
|
||||||
ActionsServiceURL: &s.URL,
|
require.NoError(t, err)
|
||||||
ActionsServiceAdminToken: &token,
|
|
||||||
ActionsServiceAdminTokenExpiresAt: &tokenExpireAt,
|
|
||||||
}
|
|
||||||
|
|
||||||
got, err := actionsClient.GetRunner(context.Background(), runnerID)
|
got, err := client.GetRunner(ctx, runnerID)
|
||||||
if err != nil {
|
require.NoError(t, err)
|
||||||
t.Fatalf("GetRunner got unexepected error, %v", err)
|
assert.Equal(t, want, got)
|
||||||
}
|
|
||||||
|
|
||||||
if diff := cmp.Diff(want, got); diff != "" {
|
|
||||||
t.Errorf("GetRunner(%v) mismatch (-want +got):\n%s", name, diff)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Default retries on server error", func(t *testing.T) {
|
t.Run("Default retries on server error", func(t *testing.T) {
|
||||||
var runnerID int64 = 1
|
var runnerID int64 = 1
|
||||||
retryClient := retryablehttp.NewClient()
|
retryWaitMax := 1 * time.Millisecond
|
||||||
retryClient.RetryWaitMax = 1 * time.Millisecond
|
retryMax := 1
|
||||||
retryClient.RetryMax = 1
|
|
||||||
|
|
||||||
actualRetry := 0
|
actualRetry := 0
|
||||||
expectedRetry := retryClient.RetryMax + 1
|
expectedRetry := retryMax + 1
|
||||||
|
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
server := newActionsServer(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.WriteHeader(http.StatusServiceUnavailable)
|
w.WriteHeader(http.StatusServiceUnavailable)
|
||||||
actualRetry++
|
actualRetry++
|
||||||
}))
|
}))
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
httpClient := retryClient.StandardClient()
|
client, err := actions.NewClient(ctx, server.configURLForOrg("my-org"), auth, actions.WithRetryMax(retryMax), actions.WithRetryWaitMax(retryWaitMax))
|
||||||
|
require.NoError(t, err)
|
||||||
actionsClient := actions.Client{
|
|
||||||
Client: httpClient,
|
|
||||||
ActionsServiceURL: &s.URL,
|
|
||||||
ActionsServiceAdminToken: &token,
|
|
||||||
ActionsServiceAdminTokenExpiresAt: &tokenExpireAt,
|
|
||||||
}
|
|
||||||
|
|
||||||
_, _ = actionsClient.GetRunner(context.Background(), runnerID)
|
|
||||||
|
|
||||||
|
_, err = client.GetRunner(ctx, runnerID)
|
||||||
|
require.Error(t, err)
|
||||||
assert.Equalf(t, actualRetry, expectedRetry, "A retry was expected after the first request but got: %v", actualRetry)
|
assert.Equalf(t, actualRetry, expectedRetry, "A retry was expected after the first request but got: %v", actualRetry)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetRunnerByName(t *testing.T) {
|
func TestGetRunnerByName(t *testing.T) {
|
||||||
token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjI1MTYyMzkwMjJ9.tlrHslTmDkoqnc4Kk9ISoKoUNDfHo-kjlH-ByISBqzE"
|
ctx := context.Background()
|
||||||
|
auth := &actions.ActionsAuth{
|
||||||
|
Token: "token",
|
||||||
|
}
|
||||||
|
|
||||||
t.Run("Get Runner by Name", func(t *testing.T) {
|
t.Run("Get Runner by Name", func(t *testing.T) {
|
||||||
var runnerID int64 = 1
|
var runnerID int64 = 1
|
||||||
|
|
@ -90,130 +74,102 @@ func TestGetRunnerByName(t *testing.T) {
|
||||||
}
|
}
|
||||||
response := []byte(`{"count": 1, "value": [{"id": 1, "name": "self-hosted-ubuntu"}]}`)
|
response := []byte(`{"count": 1, "value": [{"id": 1, "name": "self-hosted-ubuntu"}]}`)
|
||||||
|
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
server := newActionsServer(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Write(response)
|
w.Write(response)
|
||||||
}))
|
}))
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
actionsClient := actions.Client{
|
client, err := actions.NewClient(ctx, server.configURLForOrg("my-org"), auth)
|
||||||
ActionsServiceURL: &s.URL,
|
require.NoError(t, err)
|
||||||
ActionsServiceAdminToken: &token,
|
|
||||||
ActionsServiceAdminTokenExpiresAt: &tokenExpireAt,
|
|
||||||
}
|
|
||||||
|
|
||||||
got, err := actionsClient.GetRunnerByName(context.Background(), runnerName)
|
got, err := client.GetRunnerByName(ctx, runnerName)
|
||||||
if err != nil {
|
require.NoError(t, err)
|
||||||
t.Fatalf("GetRunnerByName got unexepected error, %v", err)
|
assert.Equal(t, want, got)
|
||||||
}
|
|
||||||
|
|
||||||
if diff := cmp.Diff(want, got); diff != "" {
|
|
||||||
t.Errorf("GetRunnerByName(%v) mismatch (-want +got):\n%s", runnerName, diff)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Get Runner by name with not exist runner", func(t *testing.T) {
|
t.Run("Get Runner by name with not exist runner", func(t *testing.T) {
|
||||||
var runnerName string = "self-hosted-ubuntu"
|
var runnerName string = "self-hosted-ubuntu"
|
||||||
response := []byte(`{"count": 0, "value": []}`)
|
response := []byte(`{"count": 0, "value": []}`)
|
||||||
|
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
server := newActionsServer(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Write(response)
|
w.Write(response)
|
||||||
}))
|
}))
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
actionsClient := actions.Client{
|
client, err := actions.NewClient(ctx, server.configURLForOrg("my-org"), auth)
|
||||||
ActionsServiceURL: &s.URL,
|
require.NoError(t, err)
|
||||||
ActionsServiceAdminToken: &token,
|
|
||||||
ActionsServiceAdminTokenExpiresAt: &tokenExpireAt,
|
|
||||||
}
|
|
||||||
|
|
||||||
got, err := actionsClient.GetRunnerByName(context.Background(), runnerName)
|
got, err := client.GetRunnerByName(ctx, runnerName)
|
||||||
if err != nil {
|
require.NoError(t, err)
|
||||||
t.Fatalf("GetRunnerByName got unexepected error, %v", err)
|
assert.Nil(t, got)
|
||||||
}
|
|
||||||
|
|
||||||
if diff := cmp.Diff((*actions.RunnerReference)(nil), got); diff != "" {
|
|
||||||
t.Errorf("GetRunnerByName(%v) mismatch (-want +got):\n%s", runnerName, diff)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Default retries on server error", func(t *testing.T) {
|
t.Run("Default retries on server error", func(t *testing.T) {
|
||||||
var runnerName string = "self-hosted-ubuntu"
|
var runnerName string = "self-hosted-ubuntu"
|
||||||
retryClient := retryablehttp.NewClient()
|
|
||||||
retryClient.RetryWaitMax = 1 * time.Millisecond
|
retryWaitMax := 1 * time.Millisecond
|
||||||
retryClient.RetryMax = 1
|
retryMax := 1
|
||||||
|
|
||||||
actualRetry := 0
|
actualRetry := 0
|
||||||
expectedRetry := retryClient.RetryMax + 1
|
expectedRetry := retryMax + 1
|
||||||
|
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
server := newActionsServer(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.WriteHeader(http.StatusServiceUnavailable)
|
w.WriteHeader(http.StatusServiceUnavailable)
|
||||||
actualRetry++
|
actualRetry++
|
||||||
}))
|
}))
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
httpClient := retryClient.StandardClient()
|
client, err := actions.NewClient(ctx, server.configURLForOrg("my-org"), auth, actions.WithRetryMax(retryMax), actions.WithRetryWaitMax(retryWaitMax))
|
||||||
|
require.NoError(t, err)
|
||||||
actionsClient := actions.Client{
|
|
||||||
Client: httpClient,
|
|
||||||
ActionsServiceURL: &s.URL,
|
|
||||||
ActionsServiceAdminToken: &token,
|
|
||||||
ActionsServiceAdminTokenExpiresAt: &tokenExpireAt,
|
|
||||||
}
|
|
||||||
|
|
||||||
_, _ = actionsClient.GetRunnerByName(context.Background(), runnerName)
|
|
||||||
|
|
||||||
|
_, err = client.GetRunnerByName(ctx, runnerName)
|
||||||
|
require.Error(t, err)
|
||||||
assert.Equalf(t, actualRetry, expectedRetry, "A retry was expected after the first request but got: %v", actualRetry)
|
assert.Equalf(t, actualRetry, expectedRetry, "A retry was expected after the first request but got: %v", actualRetry)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeleteRunner(t *testing.T) {
|
func TestDeleteRunner(t *testing.T) {
|
||||||
token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjI1MTYyMzkwMjJ9.tlrHslTmDkoqnc4Kk9ISoKoUNDfHo-kjlH-ByISBqzE"
|
ctx := context.Background()
|
||||||
|
auth := &actions.ActionsAuth{
|
||||||
|
Token: "token",
|
||||||
|
}
|
||||||
|
|
||||||
t.Run("Delete Runner", func(t *testing.T) {
|
t.Run("Delete Runner", func(t *testing.T) {
|
||||||
var runnerID int64 = 1
|
var runnerID int64 = 1
|
||||||
|
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
server := newActionsServer(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||||
w.WriteHeader(http.StatusNoContent)
|
w.WriteHeader(http.StatusNoContent)
|
||||||
}))
|
}))
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
actionsClient := actions.Client{
|
client, err := actions.NewClient(ctx, server.configURLForOrg("my-org"), auth)
|
||||||
ActionsServiceURL: &s.URL,
|
require.NoError(t, err)
|
||||||
ActionsServiceAdminToken: &token,
|
|
||||||
ActionsServiceAdminTokenExpiresAt: &tokenExpireAt,
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := actionsClient.RemoveRunner(context.Background(), runnerID); err != nil {
|
err = client.RemoveRunner(ctx, runnerID)
|
||||||
t.Fatalf("RemoveRunner got unexepected error, %v", err)
|
assert.NoError(t, err)
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Default retries on server error", func(t *testing.T) {
|
t.Run("Default retries on server error", func(t *testing.T) {
|
||||||
var runnerID int64 = 1
|
var runnerID int64 = 1
|
||||||
|
|
||||||
retryClient := retryablehttp.NewClient()
|
retryWaitMax := 1 * time.Millisecond
|
||||||
retryClient.RetryWaitMax = 1 * time.Millisecond
|
retryMax := 1
|
||||||
retryClient.RetryMax = 1
|
|
||||||
|
|
||||||
actualRetry := 0
|
actualRetry := 0
|
||||||
expectedRetry := retryClient.RetryMax + 1
|
expectedRetry := retryMax + 1
|
||||||
|
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
server := newActionsServer(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||||
w.WriteHeader(http.StatusServiceUnavailable)
|
w.WriteHeader(http.StatusServiceUnavailable)
|
||||||
actualRetry++
|
actualRetry++
|
||||||
}))
|
}))
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
httpClient := retryClient.StandardClient()
|
client, err := actions.NewClient(
|
||||||
actionsClient := actions.Client{
|
ctx,
|
||||||
Client: httpClient,
|
server.configURLForOrg("my-org"),
|
||||||
ActionsServiceURL: &s.URL,
|
auth,
|
||||||
ActionsServiceAdminToken: &token,
|
actions.WithRetryMax(retryMax),
|
||||||
ActionsServiceAdminTokenExpiresAt: &tokenExpireAt,
|
actions.WithRetryWaitMax(retryWaitMax),
|
||||||
}
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
_ = actionsClient.RemoveRunner(context.Background(), runnerID)
|
|
||||||
|
|
||||||
|
err = client.RemoveRunner(ctx, runnerID)
|
||||||
|
require.Error(t, err)
|
||||||
assert.Equalf(t, actualRetry, expectedRetry, "A retry was expected after the first request but got: %v", actualRetry)
|
assert.Equalf(t, actualRetry, expectedRetry, "A retry was expected after the first request but got: %v", actualRetry)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,13 @@ func (m *multiClient) GetClientFor(ctx context.Context, githubConfigURL string,
|
||||||
|
|
||||||
m.logger.Info("creating new client", "githubConfigURL", githubConfigURL, "namespace", namespace)
|
m.logger.Info("creating new client", "githubConfigURL", githubConfigURL, "namespace", namespace)
|
||||||
|
|
||||||
client, err := NewClient(ctx, githubConfigURL, &creds, m.userAgent, m.logger)
|
client, err := NewClient(
|
||||||
|
ctx,
|
||||||
|
githubConfigURL,
|
||||||
|
&creds,
|
||||||
|
WithUserAgent(m.userAgent),
|
||||||
|
WithLogger(m.logger),
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,20 +6,15 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/actions/actions-runner-controller/logging"
|
"github.com/go-logr/logr"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAddClient(t *testing.T) {
|
func TestAddClient(t *testing.T) {
|
||||||
logger, err := logging.NewLogger(logging.LogLevelDebug, logging.LogFormatText)
|
logger := logr.Discard()
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "Error: creating logger: %v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
multiClient := NewMultiClient("test-user-agent", logger).(*multiClient)
|
multiClient := NewMultiClient("test-user-agent", logger).(*multiClient)
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue