Skip to content

Commit

Permalink
test: add unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
LinuxSuRen committed Jul 31, 2023
1 parent c90018c commit 234a0d5
Show file tree
Hide file tree
Showing 7 changed files with 472 additions and 142 deletions.
54 changes: 54 additions & 0 deletions extensions/store-s3/cmd/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package cmd

import (
"fmt"
"net"

"github.com/linuxsuren/api-testing/extensions/store-s3/pkg"
"github.com/linuxsuren/api-testing/pkg/testing/remote"
"github.com/spf13/cobra"
"google.golang.org/grpc"
)

func NewRootCmd(s3Creator pkg.S3Creator) (cmd *cobra.Command) {
opt := &option{
S3Creator: s3Creator,
}
cmd = &cobra.Command{
Use: "store-s3",
Short: "S3 storage extension of api-testing",
RunE: opt.runE,
}
flags := cmd.Flags()
flags.IntVarP(&opt.port, "port", "p", 7072, "The port of gRPC server")
return cmd
}

func (o *option) runE(cmd *cobra.Command, args []string) (err error) {
removeServer := pkg.NewRemoteServer(o.S3Creator)

var lis net.Listener
lis, err = net.Listen("tcp", fmt.Sprintf(":%d", o.port))
if err != nil {
return
}

gRPCServer := grpc.NewServer()
remote.RegisterLoaderServer(gRPCServer, removeServer)
cmd.Println("S3 storage extension is running at port", o.port)

go func() {
<-cmd.Context().Done()
gRPCServer.Stop()
}()

err = gRPCServer.Serve(lis)
return
}

type option struct {
port int

// inner fields
S3Creator pkg.S3Creator
}
44 changes: 44 additions & 0 deletions extensions/store-s3/cmd/root_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package cmd

import (
"context"
"io"
"testing"
"time"

"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
)

func TestNewRootCmd(t *testing.T) {
t.Run("not run", func(t *testing.T) {
cmd := newRootCmdForTest()
assert.NotNil(t, cmd)
assert.Equal(t, "store-s3", cmd.Use)
assert.Equal(t, "7072", cmd.Flags().Lookup("port").Value.String())
})

t.Run("invalid port", func(t *testing.T) {
cmd := newRootCmdForTest()
cmd.SetArgs([]string{"--port", "-1"})
err := cmd.Execute()
assert.Error(t, err)
})

t.Run("stop the command", func(t *testing.T) {
ctx, cancel := context.WithTimeout(context.TODO(), time.Second)
defer cancel()

cmd := newRootCmdForTest()
cmd.SetContext(ctx)
cmd.SetArgs([]string{"--port", "0"})
err := cmd.Execute()
assert.NoError(t, err)
})
}

func newRootCmdForTest() *cobra.Command {
cmd := NewRootCmd(nil)
cmd.SetOut(io.Discard)
return cmd
}
38 changes: 2 additions & 36 deletions extensions/store-s3/main.go
Original file line number Diff line number Diff line change
@@ -1,49 +1,15 @@
package main

import (
"fmt"
"net"
"os"

"github.com/linuxsuren/api-testing/extensions/store-s3/cmd"
"github.com/linuxsuren/api-testing/extensions/store-s3/pkg"
"github.com/linuxsuren/api-testing/pkg/testing/remote"
"github.com/spf13/cobra"
"google.golang.org/grpc"
)

func main() {
opt := &option{}
cmd := &cobra.Command{
Use: "store-s3",
Short: "S3 storage extension of api-testing",
RunE: opt.runE,
}
flags := cmd.Flags()
flags.IntVarP(&opt.port, "port", "p", 7072, "The port of gRPC server")
cmd := cmd.NewRootCmd(&pkg.DefaultS3Creator{})
if err := cmd.Execute(); err != nil {
os.Exit(1)
}
}

func (o *option) runE(cmd *cobra.Command, args []string) (err error) {
var removeServer remote.LoaderServer
if removeServer, err = pkg.NewRemoteServer(); err != nil {
return
}

var lis net.Listener
lis, err = net.Listen("tcp", fmt.Sprintf(":%d", o.port))
if err != nil {
return
}

gRPCServer := grpc.NewServer()
remote.RegisterLoaderServer(gRPCServer, removeServer)
cmd.Println("S3 storage extension is running at port", o.port)
err = gRPCServer.Serve(lis)
return
}

type option struct {
port int
}
71 changes: 71 additions & 0 deletions extensions/store-s3/pkg/fake_s3.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package pkg

import (
"bytes"
"io"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/client"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/service/s3"
)

type S3API interface {
ListObjectsWithContext(ctx aws.Context, input *s3.ListObjectsInput, opts ...request.Option) (*s3.ListObjectsOutput, error)
PutObjectWithContext(ctx aws.Context, input *s3.PutObjectInput, opts ...request.Option) (*s3.PutObjectOutput, error)
GetObjectWithContext(ctx aws.Context, input *s3.GetObjectInput, opts ...request.Option) (*s3.GetObjectOutput, error)
DeleteObjectWithContext(ctx aws.Context, input *s3.DeleteObjectInput, opts ...request.Option) (*s3.DeleteObjectOutput, error)
}

type S3Creator interface {
New(p client.ConfigProvider, cfgs ...*aws.Config) S3API
}

type DefaultS3Creator struct{}

func (d *DefaultS3Creator) New(p client.ConfigProvider, cfgs ...*aws.Config) S3API {
return s3.New(p, cfgs...)
}

type fakeS3 struct {
data map[*string][]byte
}

func (f *fakeS3) New(p client.ConfigProvider, cfgs ...*aws.Config) S3API {
return f
}

func (f *fakeS3) ListObjectsWithContext(ctx aws.Context, input *s3.ListObjectsInput, opts ...request.Option) (output *s3.ListObjectsOutput, err error) {
output = &s3.ListObjectsOutput{}
for k := range f.data {
output.Contents = append(output.Contents, &s3.Object{
Key: k,
})
}
return
}
func (f *fakeS3) PutObjectWithContext(ctx aws.Context, input *s3.PutObjectInput, opts ...request.Option) (*s3.PutObjectOutput, error) {
data, err := io.ReadAll(input.Body)
f.data[input.Key] = data
return nil, err
}
func (f *fakeS3) GetObjectWithContext(ctx aws.Context, input *s3.GetObjectInput, opts ...request.Option) (output *s3.GetObjectOutput, err error) {
for k := range f.data {
if *input.Key == *k {
output = &s3.GetObjectOutput{
Body: io.NopCloser(bytes.NewReader(f.data[k])),
}
break
}
}
return
}
func (f *fakeS3) DeleteObjectWithContext(ctx aws.Context, input *s3.DeleteObjectInput, opts ...request.Option) (*s3.DeleteObjectOutput, error) {
for k := range f.data {
if *input.Key == *k {
delete(f.data, k)
break
}
}
return nil, nil
}

0 comments on commit 234a0d5

Please sign in to comment.