code.gitea.io/gitea@v1.22.3/tests/integration/api_actions_artifact_v4_test.go (about)

     1  // Copyright 2024 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package integration
     5  
     6  import (
     7  	"bytes"
     8  	"crypto/sha256"
     9  	"encoding/hex"
    10  	"io"
    11  	"net/http"
    12  	"strings"
    13  	"testing"
    14  	"time"
    15  
    16  	"code.gitea.io/gitea/routers/api/actions"
    17  	actions_service "code.gitea.io/gitea/services/actions"
    18  	"code.gitea.io/gitea/tests"
    19  
    20  	"github.com/stretchr/testify/assert"
    21  	"google.golang.org/protobuf/encoding/protojson"
    22  	"google.golang.org/protobuf/reflect/protoreflect"
    23  	"google.golang.org/protobuf/types/known/timestamppb"
    24  	"google.golang.org/protobuf/types/known/wrapperspb"
    25  )
    26  
    27  func toProtoJSON(m protoreflect.ProtoMessage) io.Reader {
    28  	resp, _ := protojson.Marshal(m)
    29  	buf := bytes.Buffer{}
    30  	buf.Write(resp)
    31  	return &buf
    32  }
    33  
    34  func TestActionsArtifactV4UploadSingleFile(t *testing.T) {
    35  	defer tests.PrepareTestEnv(t)()
    36  
    37  	token, err := actions_service.CreateAuthorizationToken(48, 792, 193)
    38  	assert.NoError(t, err)
    39  
    40  	// acquire artifact upload url
    41  	req := NewRequestWithBody(t, "POST", "/twirp/github.actions.results.api.v1.ArtifactService/CreateArtifact", toProtoJSON(&actions.CreateArtifactRequest{
    42  		Version:                 4,
    43  		Name:                    "artifact",
    44  		WorkflowRunBackendId:    "792",
    45  		WorkflowJobRunBackendId: "193",
    46  	})).AddTokenAuth(token)
    47  	resp := MakeRequest(t, req, http.StatusOK)
    48  	var uploadResp actions.CreateArtifactResponse
    49  	protojson.Unmarshal(resp.Body.Bytes(), &uploadResp)
    50  	assert.True(t, uploadResp.Ok)
    51  	assert.Contains(t, uploadResp.SignedUploadUrl, "/twirp/github.actions.results.api.v1.ArtifactService/UploadArtifact")
    52  
    53  	// get upload url
    54  	idx := strings.Index(uploadResp.SignedUploadUrl, "/twirp/")
    55  	url := uploadResp.SignedUploadUrl[idx:] + "&comp=block"
    56  
    57  	// upload artifact chunk
    58  	body := strings.Repeat("A", 1024)
    59  	req = NewRequestWithBody(t, "PUT", url, strings.NewReader(body))
    60  	MakeRequest(t, req, http.StatusCreated)
    61  
    62  	t.Logf("Create artifact confirm")
    63  
    64  	sha := sha256.Sum256([]byte(body))
    65  
    66  	// confirm artifact upload
    67  	req = NewRequestWithBody(t, "POST", "/twirp/github.actions.results.api.v1.ArtifactService/FinalizeArtifact", toProtoJSON(&actions.FinalizeArtifactRequest{
    68  		Name:                    "artifact",
    69  		Size:                    1024,
    70  		Hash:                    wrapperspb.String("sha256:" + hex.EncodeToString(sha[:])),
    71  		WorkflowRunBackendId:    "792",
    72  		WorkflowJobRunBackendId: "193",
    73  	})).
    74  		AddTokenAuth(token)
    75  	resp = MakeRequest(t, req, http.StatusOK)
    76  	var finalizeResp actions.FinalizeArtifactResponse
    77  	protojson.Unmarshal(resp.Body.Bytes(), &finalizeResp)
    78  	assert.True(t, finalizeResp.Ok)
    79  }
    80  
    81  func TestActionsArtifactV4UploadSingleFileWrongChecksum(t *testing.T) {
    82  	defer tests.PrepareTestEnv(t)()
    83  
    84  	token, err := actions_service.CreateAuthorizationToken(48, 792, 193)
    85  	assert.NoError(t, err)
    86  
    87  	// acquire artifact upload url
    88  	req := NewRequestWithBody(t, "POST", "/twirp/github.actions.results.api.v1.ArtifactService/CreateArtifact", toProtoJSON(&actions.CreateArtifactRequest{
    89  		Version:                 4,
    90  		Name:                    "artifact-invalid-checksum",
    91  		WorkflowRunBackendId:    "792",
    92  		WorkflowJobRunBackendId: "193",
    93  	})).AddTokenAuth(token)
    94  	resp := MakeRequest(t, req, http.StatusOK)
    95  	var uploadResp actions.CreateArtifactResponse
    96  	protojson.Unmarshal(resp.Body.Bytes(), &uploadResp)
    97  	assert.True(t, uploadResp.Ok)
    98  	assert.Contains(t, uploadResp.SignedUploadUrl, "/twirp/github.actions.results.api.v1.ArtifactService/UploadArtifact")
    99  
   100  	// get upload url
   101  	idx := strings.Index(uploadResp.SignedUploadUrl, "/twirp/")
   102  	url := uploadResp.SignedUploadUrl[idx:] + "&comp=block"
   103  
   104  	// upload artifact chunk
   105  	body := strings.Repeat("B", 1024)
   106  	req = NewRequestWithBody(t, "PUT", url, strings.NewReader(body))
   107  	MakeRequest(t, req, http.StatusCreated)
   108  
   109  	t.Logf("Create artifact confirm")
   110  
   111  	sha := sha256.Sum256([]byte(strings.Repeat("A", 1024)))
   112  
   113  	// confirm artifact upload
   114  	req = NewRequestWithBody(t, "POST", "/twirp/github.actions.results.api.v1.ArtifactService/FinalizeArtifact", toProtoJSON(&actions.FinalizeArtifactRequest{
   115  		Name:                    "artifact-invalid-checksum",
   116  		Size:                    1024,
   117  		Hash:                    wrapperspb.String("sha256:" + hex.EncodeToString(sha[:])),
   118  		WorkflowRunBackendId:    "792",
   119  		WorkflowJobRunBackendId: "193",
   120  	})).
   121  		AddTokenAuth(token)
   122  	MakeRequest(t, req, http.StatusInternalServerError)
   123  }
   124  
   125  func TestActionsArtifactV4UploadSingleFileWithRetentionDays(t *testing.T) {
   126  	defer tests.PrepareTestEnv(t)()
   127  
   128  	token, err := actions_service.CreateAuthorizationToken(48, 792, 193)
   129  	assert.NoError(t, err)
   130  
   131  	// acquire artifact upload url
   132  	req := NewRequestWithBody(t, "POST", "/twirp/github.actions.results.api.v1.ArtifactService/CreateArtifact", toProtoJSON(&actions.CreateArtifactRequest{
   133  		Version:                 4,
   134  		ExpiresAt:               timestamppb.New(time.Now().Add(5 * 24 * time.Hour)),
   135  		Name:                    "artifactWithRetentionDays",
   136  		WorkflowRunBackendId:    "792",
   137  		WorkflowJobRunBackendId: "193",
   138  	})).AddTokenAuth(token)
   139  	resp := MakeRequest(t, req, http.StatusOK)
   140  	var uploadResp actions.CreateArtifactResponse
   141  	protojson.Unmarshal(resp.Body.Bytes(), &uploadResp)
   142  	assert.True(t, uploadResp.Ok)
   143  	assert.Contains(t, uploadResp.SignedUploadUrl, "/twirp/github.actions.results.api.v1.ArtifactService/UploadArtifact")
   144  
   145  	// get upload url
   146  	idx := strings.Index(uploadResp.SignedUploadUrl, "/twirp/")
   147  	url := uploadResp.SignedUploadUrl[idx:] + "&comp=block"
   148  
   149  	// upload artifact chunk
   150  	body := strings.Repeat("A", 1024)
   151  	req = NewRequestWithBody(t, "PUT", url, strings.NewReader(body))
   152  	MakeRequest(t, req, http.StatusCreated)
   153  
   154  	t.Logf("Create artifact confirm")
   155  
   156  	sha := sha256.Sum256([]byte(body))
   157  
   158  	// confirm artifact upload
   159  	req = NewRequestWithBody(t, "POST", "/twirp/github.actions.results.api.v1.ArtifactService/FinalizeArtifact", toProtoJSON(&actions.FinalizeArtifactRequest{
   160  		Name:                    "artifactWithRetentionDays",
   161  		Size:                    1024,
   162  		Hash:                    wrapperspb.String("sha256:" + hex.EncodeToString(sha[:])),
   163  		WorkflowRunBackendId:    "792",
   164  		WorkflowJobRunBackendId: "193",
   165  	})).
   166  		AddTokenAuth(token)
   167  	resp = MakeRequest(t, req, http.StatusOK)
   168  	var finalizeResp actions.FinalizeArtifactResponse
   169  	protojson.Unmarshal(resp.Body.Bytes(), &finalizeResp)
   170  	assert.True(t, finalizeResp.Ok)
   171  }
   172  
   173  func TestActionsArtifactV4DownloadSingle(t *testing.T) {
   174  	defer tests.PrepareTestEnv(t)()
   175  
   176  	token, err := actions_service.CreateAuthorizationToken(48, 792, 193)
   177  	assert.NoError(t, err)
   178  
   179  	// acquire artifact upload url
   180  	req := NewRequestWithBody(t, "POST", "/twirp/github.actions.results.api.v1.ArtifactService/ListArtifacts", toProtoJSON(&actions.ListArtifactsRequest{
   181  		NameFilter:              wrapperspb.String("artifact"),
   182  		WorkflowRunBackendId:    "792",
   183  		WorkflowJobRunBackendId: "193",
   184  	})).AddTokenAuth(token)
   185  	resp := MakeRequest(t, req, http.StatusOK)
   186  	var listResp actions.ListArtifactsResponse
   187  	protojson.Unmarshal(resp.Body.Bytes(), &listResp)
   188  	assert.Len(t, listResp.Artifacts, 1)
   189  
   190  	// confirm artifact upload
   191  	req = NewRequestWithBody(t, "POST", "/twirp/github.actions.results.api.v1.ArtifactService/GetSignedArtifactURL", toProtoJSON(&actions.GetSignedArtifactURLRequest{
   192  		Name:                    "artifact",
   193  		WorkflowRunBackendId:    "792",
   194  		WorkflowJobRunBackendId: "193",
   195  	})).
   196  		AddTokenAuth(token)
   197  	resp = MakeRequest(t, req, http.StatusOK)
   198  	var finalizeResp actions.GetSignedArtifactURLResponse
   199  	protojson.Unmarshal(resp.Body.Bytes(), &finalizeResp)
   200  	assert.NotEmpty(t, finalizeResp.SignedUrl)
   201  
   202  	req = NewRequest(t, "GET", finalizeResp.SignedUrl)
   203  	resp = MakeRequest(t, req, http.StatusOK)
   204  	body := strings.Repeat("A", 1024)
   205  	assert.Equal(t, resp.Body.String(), body)
   206  }
   207  
   208  func TestActionsArtifactV4Delete(t *testing.T) {
   209  	defer tests.PrepareTestEnv(t)()
   210  
   211  	token, err := actions_service.CreateAuthorizationToken(48, 792, 193)
   212  	assert.NoError(t, err)
   213  
   214  	// delete artifact by name
   215  	req := NewRequestWithBody(t, "POST", "/twirp/github.actions.results.api.v1.ArtifactService/DeleteArtifact", toProtoJSON(&actions.DeleteArtifactRequest{
   216  		Name:                    "artifact",
   217  		WorkflowRunBackendId:    "792",
   218  		WorkflowJobRunBackendId: "193",
   219  	})).AddTokenAuth(token)
   220  	resp := MakeRequest(t, req, http.StatusOK)
   221  	var deleteResp actions.DeleteArtifactResponse
   222  	protojson.Unmarshal(resp.Body.Bytes(), &deleteResp)
   223  	assert.True(t, deleteResp.Ok)
   224  }