2019-01-23 08:56:51 +00:00
// Copyright 2019 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package integrations
import (
"archive/zip"
"bytes"
2021-09-22 13:38:34 +08:00
"io"
2019-01-23 08:56:51 +00:00
"net/http"
2020-05-11 09:37:59 +01:00
"net/http/httptest"
2019-01-23 08:56:51 +00:00
"testing"
"code.gitea.io/gitea/models"
2021-12-10 09:27:50 +08:00
repo_model "code.gitea.io/gitea/models/repo"
2021-06-26 19:28:55 +08:00
"code.gitea.io/gitea/modules/git"
2021-07-25 00:03:58 +08:00
"code.gitea.io/gitea/modules/json"
2019-01-23 08:56:51 +00:00
"code.gitea.io/gitea/modules/lfs"
"code.gitea.io/gitea/modules/setting"
2021-06-09 07:33:54 +08:00
"code.gitea.io/gitea/routers/web"
2019-01-23 08:56:51 +00:00
gzipp "github.com/klauspost/compress/gzip"
2019-08-23 09:40:30 -07:00
"github.com/stretchr/testify/assert"
2019-01-23 08:56:51 +00:00
)
func storeObjectInRepo ( t * testing . T , repositoryID int64 , content * [ ] byte ) string {
2021-04-09 00:25:57 +02:00
pointer , err := lfs . GeneratePointer ( bytes . NewReader ( * content ) )
2019-01-23 08:56:51 +00:00
assert . NoError ( t , err )
2021-06-06 01:59:27 +02:00
_ , err = models . NewLFSMetaObject ( & models . LFSMetaObject { Pointer : pointer , RepositoryID : repositoryID } )
2019-01-23 08:56:51 +00:00
assert . NoError ( t , err )
2021-04-09 00:25:57 +02:00
contentStore := lfs . NewContentStore ( )
exist , err := contentStore . Exists ( pointer )
2020-09-08 23:45:10 +08:00
assert . NoError ( t , err )
if ! exist {
2021-04-09 00:25:57 +02:00
err := contentStore . Put ( pointer , bytes . NewReader ( * content ) )
2019-01-23 08:56:51 +00:00
assert . NoError ( t , err )
}
2021-04-09 00:25:57 +02:00
return pointer . Oid
2019-01-23 08:56:51 +00:00
}
2020-05-11 09:37:59 +01:00
func storeAndGetLfs ( t * testing . T , content * [ ] byte , extraHeader * http . Header , expectedStatus int ) * httptest . ResponseRecorder {
2021-12-10 09:27:50 +08:00
repo , err := repo_model . GetRepositoryByOwnerAndName ( "user2" , "repo1" )
2019-01-23 08:56:51 +00:00
assert . NoError ( t , err )
oid := storeObjectInRepo ( t , repo . ID , content )
2021-12-10 09:27:50 +08:00
defer models . RemoveLFSMetaObjectByOid ( repo . ID , oid )
2019-01-23 08:56:51 +00:00
session := loginUser ( t , "user2" )
// Request OID
req := NewRequest ( t , "GET" , "/user2/repo1.git/info/lfs/objects/" + oid + "/test" )
req . Header . Set ( "Accept-Encoding" , "gzip" )
2020-05-11 09:37:59 +01:00
if extraHeader != nil {
for key , values := range * extraHeader {
for _ , value := range values {
req . Header . Add ( key , value )
}
}
}
2020-11-01 04:51:48 +08:00
2020-05-11 09:37:59 +01:00
resp := session . MakeRequest ( t , req , expectedStatus )
2019-01-23 08:56:51 +00:00
2020-05-11 09:37:59 +01:00
return resp
}
func checkResponseTestContentEncoding ( t * testing . T , content * [ ] byte , resp * httptest . ResponseRecorder , expectGzip bool ) {
2019-01-23 08:56:51 +00:00
contentEncoding := resp . Header ( ) . Get ( "Content-Encoding" )
if ! expectGzip || ! setting . EnableGzip {
assert . NotContains ( t , contentEncoding , "gzip" )
result := resp . Body . Bytes ( )
assert . Equal ( t , * content , result )
} else {
assert . Contains ( t , contentEncoding , "gzip" )
gzippReader , err := gzipp . NewReader ( resp . Body )
assert . NoError ( t , err )
2021-09-22 13:38:34 +08:00
result , err := io . ReadAll ( gzippReader )
2019-01-23 08:56:51 +00:00
assert . NoError ( t , err )
assert . Equal ( t , * content , result )
}
}
func TestGetLFSSmall ( t * testing . T ) {
2020-05-11 09:37:59 +01:00
defer prepareTestEnv ( t ) ( )
2021-06-26 19:28:55 +08:00
git . CheckLFSVersion ( )
2020-05-11 09:37:59 +01:00
if ! setting . LFS . StartServer {
t . Skip ( )
return
}
2019-01-23 08:56:51 +00:00
content := [ ] byte ( "A very small file\n" )
2020-05-11 09:37:59 +01:00
resp := storeAndGetLfs ( t , & content , nil , http . StatusOK )
checkResponseTestContentEncoding ( t , & content , resp , false )
2019-01-23 08:56:51 +00:00
}
func TestGetLFSLarge ( t * testing . T ) {
2020-05-11 09:37:59 +01:00
defer prepareTestEnv ( t ) ( )
2021-06-26 19:28:55 +08:00
git . CheckLFSVersion ( )
2020-05-11 09:37:59 +01:00
if ! setting . LFS . StartServer {
t . Skip ( )
return
}
2021-06-09 07:33:54 +08:00
content := make ( [ ] byte , web . GzipMinSize * 10 )
2019-01-23 08:56:51 +00:00
for i := range content {
content [ i ] = byte ( i % 256 )
}
2020-05-11 09:37:59 +01:00
resp := storeAndGetLfs ( t , & content , nil , http . StatusOK )
checkResponseTestContentEncoding ( t , & content , resp , true )
2019-01-23 08:56:51 +00:00
}
func TestGetLFSGzip ( t * testing . T ) {
2020-05-11 09:37:59 +01:00
defer prepareTestEnv ( t ) ( )
2021-06-26 19:28:55 +08:00
git . CheckLFSVersion ( )
2020-05-11 09:37:59 +01:00
if ! setting . LFS . StartServer {
t . Skip ( )
return
}
2021-06-09 07:33:54 +08:00
b := make ( [ ] byte , web . GzipMinSize * 10 )
2019-01-23 08:56:51 +00:00
for i := range b {
b [ i ] = byte ( i % 256 )
}
outputBuffer := bytes . NewBuffer ( [ ] byte { } )
gzippWriter := gzipp . NewWriter ( outputBuffer )
gzippWriter . Write ( b )
gzippWriter . Close ( )
content := outputBuffer . Bytes ( )
2020-05-11 09:37:59 +01:00
resp := storeAndGetLfs ( t , & content , nil , http . StatusOK )
checkResponseTestContentEncoding ( t , & content , resp , false )
2019-01-23 08:56:51 +00:00
}
func TestGetLFSZip ( t * testing . T ) {
2020-05-11 09:37:59 +01:00
defer prepareTestEnv ( t ) ( )
2021-06-26 19:28:55 +08:00
git . CheckLFSVersion ( )
2020-05-11 09:37:59 +01:00
if ! setting . LFS . StartServer {
t . Skip ( )
return
}
2021-06-09 07:33:54 +08:00
b := make ( [ ] byte , web . GzipMinSize * 10 )
2019-01-23 08:56:51 +00:00
for i := range b {
b [ i ] = byte ( i % 256 )
}
outputBuffer := bytes . NewBuffer ( [ ] byte { } )
zipWriter := zip . NewWriter ( outputBuffer )
fileWriter , err := zipWriter . Create ( "default" )
assert . NoError ( t , err )
fileWriter . Write ( b )
zipWriter . Close ( )
content := outputBuffer . Bytes ( )
2020-05-11 09:37:59 +01:00
resp := storeAndGetLfs ( t , & content , nil , http . StatusOK )
checkResponseTestContentEncoding ( t , & content , resp , false )
}
func TestGetLFSRangeNo ( t * testing . T ) {
defer prepareTestEnv ( t ) ( )
2021-06-26 19:28:55 +08:00
git . CheckLFSVersion ( )
2020-05-11 09:37:59 +01:00
if ! setting . LFS . StartServer {
t . Skip ( )
return
}
content := [ ] byte ( "123456789\n" )
resp := storeAndGetLfs ( t , & content , nil , http . StatusOK )
assert . Equal ( t , content , resp . Body . Bytes ( ) )
}
func TestGetLFSRange ( t * testing . T ) {
defer prepareTestEnv ( t ) ( )
2021-06-26 19:28:55 +08:00
git . CheckLFSVersion ( )
2020-05-11 09:37:59 +01:00
if ! setting . LFS . StartServer {
t . Skip ( )
return
}
content := [ ] byte ( "123456789\n" )
tests := [ ] struct {
in string
out string
status int
} {
{ "bytes=0-0" , "1" , http . StatusPartialContent } ,
{ "bytes=0-1" , "12" , http . StatusPartialContent } ,
{ "bytes=1-1" , "2" , http . StatusPartialContent } ,
{ "bytes=1-3" , "234" , http . StatusPartialContent } ,
{ "bytes=1-" , "23456789\n" , http . StatusPartialContent } ,
// end-range smaller than start-range is ignored
{ "bytes=1-0" , "23456789\n" , http . StatusPartialContent } ,
{ "bytes=0-10" , "123456789\n" , http . StatusPartialContent } ,
// end-range bigger than length-1 is ignored
{ "bytes=0-11" , "123456789\n" , http . StatusPartialContent } ,
2020-11-01 04:51:48 +08:00
{ "bytes=11-" , "Requested Range Not Satisfiable" , http . StatusRequestedRangeNotSatisfiable } ,
2020-05-11 09:37:59 +01:00
// incorrect header value cause whole header to be ignored
{ "bytes=-" , "123456789\n" , http . StatusOK } ,
{ "foobar" , "123456789\n" , http . StatusOK } ,
}
for _ , tt := range tests {
t . Run ( tt . in , func ( t * testing . T ) {
h := http . Header {
"Range" : [ ] string { tt . in } ,
}
resp := storeAndGetLfs ( t , & content , & h , tt . status )
2021-06-06 01:59:27 +02:00
if tt . status == http . StatusPartialContent || tt . status == http . StatusOK {
assert . Equal ( t , tt . out , resp . Body . String ( ) )
} else {
var er lfs . ErrorResponse
2021-07-25 00:03:58 +08:00
err := json . Unmarshal ( resp . Body . Bytes ( ) , & er )
2021-06-06 01:59:27 +02:00
assert . NoError ( t , err )
assert . Equal ( t , tt . out , er . Message )
}
2020-05-11 09:37:59 +01:00
} )
}
2019-01-23 08:56:51 +00:00
}