Files
portainer/api/s3/s3_client_test.go
T
Dmitry Salakhov 37baabe134 EE-292: backup to and restore from s3 (#240)
* EE-384: add endpoint to set auto backup (#224)

* EE-383: add endpoint to fetch backup settings (#231)

* add get backup settings handler
* add api docs desc

* EE-382: restore from s3 (#233)

* EE-381: add GET backup status handler (#234)

* EE-385: Add S3 backup execute handler (#237)

* add s3 backup execute handler

* refactories inside `./api/backup/backup_scheduler.go` and `./api/backup/backup_scheduler.go`

* fix tests

* EE-375: added backup to S3 form

* EE-376: added restore from S3 form

* EE-377: Update Home screen to display last backup run status

* update backup service with back end endpoints.

* restart admin monitor during s3 restores

* use go 1.13

* go 1.13 compatibility

* EE-375: added cron-validator lib

* EE-375: using enum to compare form types

* EE-375: validate cron rule field

* try fix windows build

* EE-375 EE-376 backup and restore forms validation changes

* fix(autobackup): update autobackup settings validation rules (#260)

* fix(autobackup): automate backup to s3 fe update (#261)

* EE-292: fixed typo in property.

* EE-292: updated auto backup front end validation.

* EE-292: updated lib to validate cron rule in front end

* fix dependencies

* bumped libcompose version

Co-authored-by: Hui <arris_li@hotmail.com>
Co-authored-by: Felix Han <felix.han@portainer.io>
Co-authored-by: fhanportainer <79428273+fhanportainer@users.noreply.github.com>
2021-04-15 12:12:53 +12:00

119 lines
3.5 KiB
Go

package s3
import (
"fmt"
"log"
"net/http"
"os"
"os/exec"
"strings"
"testing"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/pkg/errors"
portainer "github.com/portainer/portainer/api"
"github.com/stretchr/testify/assert"
)
var s3session *session.Session
const (
existingBucket = "testbucket"
key = "testfile"
)
func TestMain(m *testing.M) {
sess, stopMinio := startMinio()
s3session = sess
if _, err := s3.New(s3session).CreateBucket(&s3.CreateBucketInput{Bucket: aws.String(existingBucket)}); err != nil {
log.Fatal(errors.Wrap(err, "failed to create bucket"))
}
m.Run()
s3.New(s3session).DeleteObject(&s3.DeleteObjectInput{Bucket: aws.String(existingBucket), Key: aws.String(key)})
s3.New(s3session).DeleteBucket(&s3.DeleteBucketInput{Bucket: aws.String(existingBucket)})
stopMinio()
}
func Test_upload_shouldFail_whenBucketIsMissing(t *testing.T) {
if err := Upload(s3session, strings.NewReader("test"), "unknown-bucket", key); err != nil {
assert.Error(t, err, "should fail uploading to non existing bucket")
}
}
func Test_upload_shouldFail_whenBucketExists(t *testing.T) {
if err := Upload(s3session, strings.NewReader("test"), existingBucket, key); err != nil {
assert.Nil(t, err, "should succeed uploading to existing bucket")
}
}
func Test_download_shouldFail_whenBucketIsMissing(t *testing.T) {
buf := aws.NewWriteAtBuffer([]byte{})
err := Download(s3session, buf, portainer.S3Location{BucketName: "missing", Filename: key})
assert.Error(t, err, "should fail downloading from a missing bucket")
}
func Test_download_shouldFail_whenFileIsMissing(t *testing.T) {
buf := aws.NewWriteAtBuffer([]byte{})
err := Download(s3session, buf, portainer.S3Location{BucketName: existingBucket, Filename: "missing-file"})
assert.Error(t, err, "should fail downloading because file is missing")
}
func Test_download_shouldSucceed_whenFileExists(t *testing.T) {
Upload(s3session, strings.NewReader("test"), existingBucket, key)
buf := aws.NewWriteAtBuffer([]byte{})
err := Download(s3session, buf, portainer.S3Location{BucketName: existingBucket, Filename: key})
assert.Nil(t, err, "should succeed when file exists")
}
func startMinio() (*session.Session, func()) {
up := exec.Command("docker-compose", "-f", "docker-compose.test.yml", "up", "-d")
up.Stderr = os.Stderr
if err := up.Run(); err != nil {
log.Fatal(errors.Wrap(err, "failed to run docker-compose up"))
}
minioHost := "http://localhost:9090"
// wait for minio to get up and running
client := http.Client{
Timeout: 50 * time.Millisecond,
}
for i := 0; i < 10; i++ {
resp, _ := client.Get(fmt.Sprintf("%s/minio/health/live", minioHost))
if resp != nil && resp.StatusCode == http.StatusOK {
log.Println("[DEBUG] Minio is up and running")
break
}
<-time.After(500 * time.Millisecond)
}
// create session
sess, err := session.NewSessionWithOptions(session.Options{
Config: aws.Config{
Credentials: credentials.NewStaticCredentials("minioadmin", "minioadmin", ""),
Endpoint: aws.String(minioHost),
Region: aws.String("us-east-1"),
DisableSSL: aws.Bool(true),
S3ForcePathStyle: aws.Bool(true),
}})
if err != nil {
log.Fatal(errors.Wrap(err, "failed to create minio session"))
}
return sess, func() {
down := exec.Command("docker-compose", "-f", "docker-compose.test.yml", "rm", "-sfv")
if err := down.Run(); err != nil {
log.Fatal(errors.Wrap(err, "failed to run docker-compose rm"))
}
}
}