github.com/sentienttechnologies/studio-go-runner@v0.0.0-20201118202441-6d21f2ced8ee/internal/runner/minio_test.go (about)

     1  // Copyright 2018-2020 (c) Cognizant Digital Business, Evolutionary AI. All rights reserved. Issued under the Apache 2.0 License.
     2  
     3  package runner
     4  
     5  import (
     6  	"context"
     7  	"math/rand"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/davecgh/go-spew/spew" // MIT License
    12  	"github.com/leaf-ai/studio-go-runner/pkg/studio"
    13  	minio "github.com/minio/minio-go"
    14  	"github.com/rs/xid"
    15  )
    16  
    17  // This file contains tests related to accessing and using the S3 APIs
    18  // used by the runner
    19  
    20  func s3AnonAccess(t *testing.T, logger *studio.Logger) {
    21  
    22  	// Check that the minio local server has initialized before continuing
    23  	ctx := context.Background()
    24  
    25  	timeoutAlive, aliveCancel := context.WithTimeout(ctx, time.Minute)
    26  	defer aliveCancel()
    27  
    28  	if alive, err := MinioTest.IsAlive(timeoutAlive); !alive || err != nil {
    29  		if err != nil {
    30  			t.Fatal(err)
    31  		}
    32  		t.Fatal("The minio test server is not available to run this test", MinioTest.Address)
    33  	}
    34  	logger.Info("Alive checked", "addr", MinioTest.Address)
    35  
    36  	type blob struct {
    37  		key  string
    38  		size int
    39  	}
    40  
    41  	type testData struct {
    42  		bucket string
    43  		blobs  []blob
    44  	}
    45  
    46  	// Create multiple buckets and upload to all
    47  	bucketsAndFiles := []testData{
    48  		{xid.New().String(), []blob{{xid.New().String(), rand.Intn(8192)}}},
    49  		{xid.New().String(), []blob{{xid.New().String(), rand.Intn(8192)}}},
    50  	}
    51  
    52  	// Cleanup after ourselves as best as we can on the remote minio server
    53  	defer func() {
    54  		for _, item := range bucketsAndFiles {
    55  			MinioTest.RemoveBucketAll(item.bucket)
    56  		}
    57  	}()
    58  
    59  	for _, item := range bucketsAndFiles {
    60  		for _, blob := range item.blobs {
    61  			if err := MinioTest.UploadTestFile(item.bucket, blob.key, (int64)(blob.size)); err != nil {
    62  				t.Fatal(err)
    63  			}
    64  		}
    65  	}
    66  
    67  	// Make the last bucket public and its contents
    68  	if err := MinioTest.SetPublic(bucketsAndFiles[len(bucketsAndFiles)-1].bucket); err != nil {
    69  		t.Fatal(err)
    70  	}
    71  
    72  	// access using both secured and unsecured the buckets we have to validate access
    73  	env := map[string]string{
    74  		"MINIO_ACCESS_KEY":  MinioTest.AccessKeyId,
    75  		"MINIO_SECRET_KEY":  MinioTest.SecretAccessKeyId,
    76  		"MINIO_TEST_SERVER": MinioTest.Address,
    77  	}
    78  	creds := ""
    79  
    80  	for i, item := range bucketsAndFiles {
    81  		authS3, err := NewS3storage(ctx, "testProject", creds, env, MinioTest.Address, item.bucket, "", false, false)
    82  		if err != nil {
    83  			t.Fatal(err)
    84  		}
    85  		for _, blob := range item.blobs {
    86  			if _, err = authS3.Hash(ctx, blob.key); err != nil {
    87  				t.Fatal(err)
    88  			}
    89  		}
    90  		authS3.Close()
    91  
    92  		// The last bucket is the one with the anonymous access
    93  		if i == len(bucketsAndFiles)-1 {
    94  			anonS3, err := NewS3storage(ctx, "testProject", creds, map[string]string{"MINIO_TEST_SERVER": MinioTest.Address}, "", item.bucket, "", false, false)
    95  			if err != nil {
    96  				t.Fatal(err)
    97  			}
    98  			for _, blob := range item.blobs {
    99  				if _, err = anonS3.Hash(ctx, blob.key); err != nil {
   100  					t.Fatal(err)
   101  				}
   102  			}
   103  			anonS3.Close()
   104  		}
   105  
   106  		// Take the first bucket and make sure we cannot access it and get an error of some description as a negative test
   107  		if i == 0 {
   108  			anonS3, err := NewS3storage(ctx, "testProject", creds, map[string]string{"MINIO_TEST_SERVER": MinioTest.Address}, "", item.bucket, "", false, false)
   109  			if err != nil {
   110  				continue
   111  			}
   112  			for _, blob := range item.blobs {
   113  				if _, err = anonS3.Hash(ctx, blob.key); err != nil {
   114  					if unwrap, ok := err.(interface{ Unwrap() error }); ok {
   115  						if minio.ToErrorResponse(unwrap.Unwrap()).Code == "AccessDenied" {
   116  							continue
   117  						}
   118  					}
   119  					t.Fatal("A private bucket when accessed using anonymous credentials raise an unexpected type of error", spew.Sdump(err))
   120  				} else {
   121  					t.Fatal("A private bucket when accessed using anonymous credentials did not raise an error")
   122  				}
   123  			}
   124  			anonS3.Close()
   125  		}
   126  	}
   127  }
   128  
   129  // TestS3Anon will test anonymous access to S3 public resources using Minio
   130  //
   131  func TestS3MinioAnon(t *testing.T) {
   132  
   133  	logger := studio.NewLogger("s3_anon_access")
   134  
   135  	InitTestingMinio(context.Background(), false)
   136  
   137  	s3AnonAccess(t, logger)
   138  }