code.gitea.io/gitea@v1.22.3/services/repository/archiver/archiver_test.go (about)

     1  // Copyright 2020 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package archiver
     5  
     6  import (
     7  	"errors"
     8  	"testing"
     9  	"time"
    10  
    11  	"code.gitea.io/gitea/models/db"
    12  	"code.gitea.io/gitea/models/unittest"
    13  	"code.gitea.io/gitea/services/contexttest"
    14  
    15  	_ "code.gitea.io/gitea/models/actions"
    16  
    17  	"github.com/stretchr/testify/assert"
    18  )
    19  
    20  func TestMain(m *testing.M) {
    21  	unittest.MainTest(m)
    22  }
    23  
    24  func TestArchive_Basic(t *testing.T) {
    25  	assert.NoError(t, unittest.PrepareTestDatabase())
    26  
    27  	ctx, _ := contexttest.MockContext(t, "user27/repo49")
    28  	firstCommit, secondCommit := "51f84af23134", "aacbdfe9e1c4"
    29  
    30  	contexttest.LoadRepo(t, ctx, 49)
    31  	contexttest.LoadGitRepo(t, ctx)
    32  	defer ctx.Repo.GitRepo.Close()
    33  
    34  	bogusReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".zip")
    35  	assert.NoError(t, err)
    36  	assert.NotNil(t, bogusReq)
    37  	assert.EqualValues(t, firstCommit+".zip", bogusReq.GetArchiveName())
    38  
    39  	// Check a series of bogus requests.
    40  	// Step 1, valid commit with a bad extension.
    41  	bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".dilbert")
    42  	assert.Error(t, err)
    43  	assert.Nil(t, bogusReq)
    44  
    45  	// Step 2, missing commit.
    46  	bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "dbffff.zip")
    47  	assert.Error(t, err)
    48  	assert.Nil(t, bogusReq)
    49  
    50  	// Step 3, doesn't look like branch/tag/commit.
    51  	bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "db.zip")
    52  	assert.Error(t, err)
    53  	assert.Nil(t, bogusReq)
    54  
    55  	bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "master.zip")
    56  	assert.NoError(t, err)
    57  	assert.NotNil(t, bogusReq)
    58  	assert.EqualValues(t, "master.zip", bogusReq.GetArchiveName())
    59  
    60  	bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "test/archive.zip")
    61  	assert.NoError(t, err)
    62  	assert.NotNil(t, bogusReq)
    63  	assert.EqualValues(t, "test-archive.zip", bogusReq.GetArchiveName())
    64  
    65  	// Now two valid requests, firstCommit with valid extensions.
    66  	zipReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".zip")
    67  	assert.NoError(t, err)
    68  	assert.NotNil(t, zipReq)
    69  
    70  	tgzReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".tar.gz")
    71  	assert.NoError(t, err)
    72  	assert.NotNil(t, tgzReq)
    73  
    74  	secondReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, secondCommit+".zip")
    75  	assert.NoError(t, err)
    76  	assert.NotNil(t, secondReq)
    77  
    78  	inFlight := make([]*ArchiveRequest, 3)
    79  	inFlight[0] = zipReq
    80  	inFlight[1] = tgzReq
    81  	inFlight[2] = secondReq
    82  
    83  	ArchiveRepository(db.DefaultContext, zipReq)
    84  	ArchiveRepository(db.DefaultContext, tgzReq)
    85  	ArchiveRepository(db.DefaultContext, secondReq)
    86  
    87  	// Make sure sending an unprocessed request through doesn't affect the queue
    88  	// count.
    89  	ArchiveRepository(db.DefaultContext, zipReq)
    90  
    91  	// Sleep two seconds to make sure the queue doesn't change.
    92  	time.Sleep(2 * time.Second)
    93  
    94  	zipReq2, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".zip")
    95  	assert.NoError(t, err)
    96  	// This zipReq should match what's sitting in the queue, as we haven't
    97  	// let it release yet.  From the consumer's point of view, this looks like
    98  	// a long-running archive task.
    99  	assert.Equal(t, zipReq, zipReq2)
   100  
   101  	// We still have the other three stalled at completion, waiting to remove
   102  	// from archiveInProgress.  Try to submit this new one before its
   103  	// predecessor has cleared out of the queue.
   104  	ArchiveRepository(db.DefaultContext, zipReq2)
   105  
   106  	// Now we'll submit a request and TimedWaitForCompletion twice, before and
   107  	// after we release it.  We should trigger both the timeout and non-timeout
   108  	// cases.
   109  	timedReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, secondCommit+".tar.gz")
   110  	assert.NoError(t, err)
   111  	assert.NotNil(t, timedReq)
   112  	ArchiveRepository(db.DefaultContext, timedReq)
   113  
   114  	zipReq2, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".zip")
   115  	assert.NoError(t, err)
   116  	// Now, we're guaranteed to have released the original zipReq from the queue.
   117  	// Ensure that we don't get handed back the released entry somehow, but they
   118  	// should remain functionally equivalent in all fields.  The exception here
   119  	// is zipReq.cchan, which will be non-nil because it's a completed request.
   120  	// It's fine to go ahead and set it to nil now.
   121  
   122  	assert.Equal(t, zipReq, zipReq2)
   123  	assert.False(t, zipReq == zipReq2)
   124  
   125  	// Same commit, different compression formats should have different names.
   126  	// Ideally, the extension would match what we originally requested.
   127  	assert.NotEqual(t, zipReq.GetArchiveName(), tgzReq.GetArchiveName())
   128  	assert.NotEqual(t, zipReq.GetArchiveName(), secondReq.GetArchiveName())
   129  }
   130  
   131  func TestErrUnknownArchiveFormat(t *testing.T) {
   132  	err := ErrUnknownArchiveFormat{RequestFormat: "master"}
   133  	assert.True(t, errors.Is(err, ErrUnknownArchiveFormat{}))
   134  }