Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/compile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ on:

push:
paths: [ '**.go' ]
branches-ignore:
- master
branches:
- '**'

jobs:
build:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ on:

push:
paths: [ '**.go' ]
branches-ignore:
- master
branches:
- '**'

jobs:
vulns:
Expand Down
12 changes: 9 additions & 3 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ on:

push:
paths: [ '**.go' ]
branches-ignore:
- master
branches:
- '**'

jobs:
test:
Expand All @@ -36,4 +36,10 @@ jobs:
run: go test -v -count=1 -race -shuffle=on ./internal/distlog

- name: Test ./internal/conf
run: go test -v -count=1 -race -shuffle=on ./internal/conf
run: go test -v -count=1 -race -shuffle=on ./internal/conf

# objectify is causing data races, that needs to be fixed
# run: go test -v -count=1 -race -shuffle=on ./internal/provider
- name: Test ./internal/provider
run: go test -v -count=1 -shuffle=on ./internal/provider

16 changes: 2 additions & 14 deletions cmd/s3p/cmds/use.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ func addUseCmd() {
}

func useProfile(cmd *cobra.Command, args []string) {

filename, err := cmd.Flags().GetString(UseProfileFilenameFlag)
if err != nil {
log.Fatalf(fmt.Sprintf("Failed to retrieve '%s' flag: %v", UseProfileFilenameFlag, err))
Expand All @@ -42,8 +41,8 @@ func useProfile(cmd *cobra.Command, args []string) {
log.Fatalf("Failed to load profile: %v", err)
}

fmt.Printf("\ns3p\n\n")
fmt.Printf("Logging [file:%v] [console:%v]\n", app.LogOpts.File, app.LogOpts.Console)
fmt.Printf("\ns3p\n")
fmt.Printf("Using %s and bucket %q\n\n", app.Provider.Is.Title(), app.Bucket)
time.Sleep(1 * time.Second)

stats, err := appInit(app)
Expand All @@ -62,7 +61,6 @@ func useProfile(cmd *cobra.Command, args []string) {
}

func appInit(app *conf.AppConfig) (*provider.Stats, error) {

operFn, objFn, err := getProviderFunctions(app.Provider.Is)
if err != nil {
return nil, errors.New("unable to find the correct provider")
Expand All @@ -81,38 +79,28 @@ func appInit(app *conf.AppConfig) (*provider.Stats, error) {
app.Log.Info("Finished.")

return handler.Stats, nil

}

func getProviderFunctions(name conf.ProviderName) (provider.OperGenFunc, provider.ObjectGenFunc, error) {

switch name {
case conf.ProviderNameAWS:
return s3aws.NewAwsOperator, s3aws.NewAwsObject, nil

case conf.ProviderNameGoogle:
return s3gcloud.NewGCloudOperator, s3gcloud.NewCloudObject, nil

case conf.ProviderNameLinode:
return s3linode.NewLinodeOperator, s3linode.NewLinodeObject, nil

case conf.ProviderNameOCI:
return s3oracle.NewOracleOperator, s3oracle.NewOracleObject, nil

default:
return nil, nil, fmt.Errorf("unable to determine the provider")

}

}

func startSigWatcher() {

sig := make(chan os.Signal, 1)
signal.Notify(sig, syscall.SIGINT)
go func() {
<-sig
os.Exit(0)
}()

}
2 changes: 2 additions & 0 deletions internal/conf/type_opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ type Opts struct {
func (o *Opts) build(inc *ProfileIncoming) error {

o.MaxUploads = inc.Options.MaxUploads
o.WalkDirs = inc.Options.WalkDirs
o.FollowSymlinks = inc.Options.FollowSymlinks

switch tidyLowerString(inc.Options.OverwriteObjects) {

Expand Down
2 changes: 1 addition & 1 deletion internal/distlog/type_logbot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ func TestRouteLogMsg_File(t *testing.T) {
lb.Output.Console = false
lb.Output.File = true

msg := "route file test"
msg := "route message test"
lb.SetLogLevel(zerolog.InfoLevel)
lb.RouteLogMsg(zerolog.InfoLevel, msg)

Expand Down
250 changes: 250 additions & 0 deletions internal/provider/interfaces_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
package provider

import (
"fmt"
"log"
"testing"
"time"

"github.com/google/uuid"
"github.com/stretchr/testify/require"
"s3p/internal/conf"
)

type testOperator struct {
c *conf.AppConfig
state *testState
}

type testState struct {
bucket bool
bucketName string
tags map[string]string
uploaded []*testFile
}

type testFile struct {
name string
exists bool
tags map[string]string
}

func operatorGenFuncTest(app *conf.AppConfig) (oper Operator, err error) {
oper = &testOperator{
c: app,
state: &testState{
bucket: false,
bucketName: "",
uploaded: []*testFile{},
},
}

return oper, nil
}

func (oper *testOperator) BucketCreate() error {
if oper.state.bucket {
return fmt.Errorf("bucket already exists")
}
oper.state.bucket = true
oper.state.bucketName = oper.c.Bucket.Name
return nil
}

func (oper *testOperator) BucketExists() (bool, error) {
if oper.state.bucket == true && oper.state.bucketName == "" {
return true, fmt.Errorf("bucket does not exist but name is set")
}
return oper.state.bucket && (oper.state.bucketName == oper.c.Bucket.Name), nil
}

func (oper *testOperator) BucketDelete() error {
if oper.state.bucket {
oper.state.bucket = false
oper.state.bucketName = ""
return nil
}
return fmt.Errorf("bucket does not exist")
}

func (oper *testOperator) ObjectDelete(key string) error {
for _, k := range oper.state.uploaded {
if k.name == key && k.exists == true {
k.exists = false
}
if k.name == key && k.exists == false {
return fmt.Errorf("object already deleted")
}
}
return fmt.Errorf("object does not exist")
}

func (oper *testOperator) ObjectExists(obj Object) (bool, error) {
tObj, ok := obj.(*testObject)
if !ok {
return false, fmt.Errorf("object is not a test object")
}

for _, k := range oper.state.uploaded {
if k.name == tObj.key {
if k.exists == true {
return true, nil
} else {
return false, fmt.Errorf("object exists but was deleted")
}
}
}
return false, fmt.Errorf("object does not exist")
}

func (oper *testOperator) ObjectUpload(obj Object) error {
tObj, ok := obj.(*testObject)
if !ok {
return fmt.Errorf("object is not a test object")
}

exists, err := oper.ObjectExists(obj)
if err != nil {
if err.Error() != "object does not exist" {
return err
}
}
if exists {
return fmt.Errorf("object already exists")
}
if tObj.ready == true {
file := &testFile{
name: tObj.key,
exists: true,
tags: tObj.tags,
}
oper.state.uploaded = append(oper.state.uploaded, file)
return nil
}
return nil
}

func (oper *testOperator) GetObjectTags(key string) (map[string]string, error) {
for _, k := range oper.state.uploaded {
if k.name == key {
if k.exists == true {
return k.tags, nil
} else {
return nil, fmt.Errorf("object does not exist")
}
}
}
return nil, fmt.Errorf("object does not exist")
}

func (oper *testOperator) Support() *Supports {
return NewSupports(true, true, true, true)
}

type testObject struct {
key string
tags map[string]string
ready bool
job *Job
}

func (o *testObject) Destroy() error {
return o.Post()
}

func (o *testObject) Generate() error {
o.key = uuid.New().String()
o.tags = map[string]string{
"test": "yes",
uuid.NewString(): uuid.NewString(),
}
return nil
}

func (o *testObject) Post() error {
if o.ready == false {
return fmt.Errorf("object not ready, already false")
}
o.ready = false
return nil
}

func (o *testObject) Pre() error {
if o.ready == true {
return fmt.Errorf("object ready, already true")
}
if o.key == "" {
return fmt.Errorf("key not initialized")
}
o.key = ""
o.tags = nil
o.ready = false
return nil
}

func objectGenFuncTest(job *Job) Object {
return &testObject{
key: job.Key,
tags: job.AppTags,
ready: false,
job: job,
}
}

func TestInterfaces(t *testing.T) {
app := conf.NewAppConfig()
err := app.ImportFromProfile(newIncomingProfile())
require.NoError(t, err)

log.Printf("Walking: %v\n", app.Opts.WalkDirs)
log.Printf("Following Links: %v\n", app.Opts.FollowSymlinks)
time.Sleep(time.Second * 2)

handler, err := NewHandler(app, operatorGenFuncTest, objectGenFuncTest)
require.NoError(t, err)
require.NotNil(t, handler)
require.NotNil(t, handler.oper)
require.NotNil(t, handler.app)
require.NotNil(t, handler.queue)
require.NotNil(t, handler.Stats)
require.NotNil(t, handler.supports)

err = handler.Init()
require.NoError(t, err)
require.NotNil(t, handler.Stats)

require.Zero(t, handler.Stats.Failed)

app.Dirs = []string{
fmt.Sprintf("1/%s/%s/%s", uuid.NewString(), uuid.NewString(), uuid.NewString()),
fmt.Sprintf("2/%s/%s/%s", uuid.NewString(), uuid.NewString(), uuid.NewString()),
}
app.Files = []string{
fmt.Sprintf("A/%s/%s/%s", uuid.NewString(), uuid.NewString(), uuid.NewString()),
fmt.Sprintf("B/%s/%s/%s", uuid.NewString(), uuid.NewString(), uuid.NewString()),
}

handler, err = NewHandler(app, operatorGenFuncTest, objectGenFuncTest)
require.NoError(t, err)
require.NotNil(t, handler)

// this SHOULD fail, but it currently does not.
// the files and dirs passed to handler do not exist, so they should be reported as failed.
// needs to be fixed in the handler or queue
err = handler.Init()
require.NoError(t, err) // should be: require.Error(t, err, "handler init should fail with bad dirs/files")

s := handler.oper.(*testOperator).Support()
require.True(t, s.BucketCreate, "bucket create should be supported")
require.True(t, s.BucketDelete, "bucket delete should be supported")

handler.Stats.IncFailed(1, 100)
handler.Stats.IncObjects(1, 100)
handler.Stats.IncSkipped(1, 1024*1024*1024*1024*56)
require.EqualValues(t, 1, handler.Stats.Failed, "failed should be 1")
require.EqualValues(t, 1, handler.Stats.Objects, "objects should be 1")
require.EqualValues(t, 1, handler.Stats.Skipped, "skipped should be 1")
require.EqualValues(t, "1 objects uploaded, 1 skipped, and 1 failed.", handler.Stats.String(), "stats string should match")

require.IsType(t, make(map[int64]string), handler.Stats.ReadableString(), "readable string should be a map")
}
1 change: 0 additions & 1 deletion internal/provider/type_conf.go

This file was deleted.

Loading
Loading