github.com/verrazzano/verrazzano@v1.7.0/tools/vz/test/helpers/fake_cmd_context.go (about)

     1  // Copyright (c) 2022, 2023, Oracle and/or its affiliates.
     2  // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
     3  
     4  package helpers
     5  
     6  import (
     7  	"bytes"
     8  	"encoding/json"
     9  	"fmt"
    10  	"io"
    11  
    12  	"k8s.io/client-go/discovery"
    13  	discoveryFake "k8s.io/client-go/discovery/fake"
    14  
    15  	"net/http"
    16  	"os"
    17  	"strings"
    18  	"time"
    19  
    20  	"github.com/spf13/cobra"
    21  	"github.com/verrazzano/verrazzano/tools/vz/pkg/github"
    22  	"k8s.io/cli-runtime/pkg/genericclioptions"
    23  	"k8s.io/client-go/dynamic"
    24  	"k8s.io/client-go/kubernetes"
    25  	"k8s.io/client-go/kubernetes/fake"
    26  	"sigs.k8s.io/controller-runtime/pkg/client"
    27  )
    28  
    29  type FakeRootCmdContext struct {
    30  	client        client.Client
    31  	kubeClient    kubernetes.Interface
    32  	dynamicClient dynamic.Interface
    33  	genericclioptions.IOStreams
    34  }
    35  
    36  // GetOutputStream - return the output stream
    37  func (rc *FakeRootCmdContext) GetOutputStream() io.Writer {
    38  	return rc.IOStreams.Out
    39  }
    40  
    41  // GetErrorStream - return the error stream
    42  func (rc *FakeRootCmdContext) GetErrorStream() io.Writer {
    43  	return rc.IOStreams.ErrOut
    44  }
    45  
    46  // GetInputStream - return the input stream
    47  func (rc *FakeRootCmdContext) GetInputStream() io.Reader {
    48  	return rc.IOStreams.In
    49  }
    50  
    51  // GetClient - return a controller runtime client that supports the schemes used by the CLI
    52  func (rc *FakeRootCmdContext) GetClient(cmd *cobra.Command) (client.Client, error) {
    53  	return rc.client, nil
    54  }
    55  
    56  // GetKubeClient - return a Kubernetes clientset for use with the fake go-client
    57  func (rc *FakeRootCmdContext) GetKubeClient(cmd *cobra.Command) (kubernetes.Interface, error) {
    58  	return rc.kubeClient, nil
    59  }
    60  
    61  // SetClient - set the client
    62  func (rc *FakeRootCmdContext) SetClient(client client.Client) {
    63  	rc.client = client
    64  }
    65  
    66  // RoundTripFunc - define the type for the Transport function
    67  type RoundTripFunc func(req *http.Request) *http.Response
    68  
    69  // RoundTrip - define the implementation for the Transport function
    70  func (f RoundTripFunc) RoundTrip(req *http.Request) (*http.Response, error) {
    71  	return f(req), nil
    72  }
    73  
    74  // GetHTTPClient - return an HTTP client for testing that always responds with a 200
    75  // and a pre-defined list of releases
    76  func (rc *FakeRootCmdContext) GetHTTPClient() *http.Client {
    77  	// Predefined response for the list of releases
    78  	releaseResponse := []github.ReleaseAsset{
    79  		{
    80  			TagName: "v1.3.0",
    81  		},
    82  		{
    83  			TagName: "v1.2.0",
    84  		},
    85  		{
    86  			TagName: "v1.3.1",
    87  		},
    88  	}
    89  	jsonResp, _ := json.Marshal(releaseResponse)
    90  
    91  	// Predefined response for getting operator.yaml
    92  	jsonOperResp, err := os.ReadFile("../../test/testdata/operator-file-fake.yaml")
    93  	if err != nil {
    94  		panic(err)
    95  	}
    96  
    97  	return &http.Client{
    98  		Timeout: time.Second * 30,
    99  		Transport: RoundTripFunc(func(req *http.Request) *http.Response {
   100  			if strings.Contains(req.URL.Path, "/releases/download") {
   101  				return &http.Response{
   102  					StatusCode: http.StatusOK,
   103  					Body:       io.NopCloser(bytes.NewBuffer(jsonOperResp)),
   104  					Header:     http.Header{"Content-Type": {"application/octet-stream"}},
   105  				}
   106  			}
   107  			return &http.Response{
   108  				StatusCode: http.StatusOK,
   109  				Body:       io.NopCloser(bytes.NewBuffer(jsonResp)),
   110  				Header:     http.Header{"Content-Type": {"application/json"}},
   111  			}
   112  		}),
   113  	}
   114  }
   115  
   116  // GetDynamicClient - return a dynamic client for use with the fake go-client
   117  func (rc *FakeRootCmdContext) GetDynamicClient(cmd *cobra.Command) (dynamic.Interface, error) {
   118  	return rc.dynamicClient, nil
   119  }
   120  
   121  // SetDynamicClient - set a dynamic client for use with the fake go-client (used for testing)
   122  func (rc *FakeRootCmdContext) SetDynamicClient(dynClient dynamic.Interface) {
   123  	rc.dynamicClient = dynClient
   124  }
   125  
   126  func NewFakeRootCmdContext(streams genericclioptions.IOStreams) *FakeRootCmdContext {
   127  	return &FakeRootCmdContext{
   128  		IOStreams:  streams,
   129  		kubeClient: fake.NewSimpleClientset(),
   130  	}
   131  }
   132  
   133  func (rc *FakeRootCmdContext) GetDiscoveryClient(cmd *cobra.Command) (discovery.DiscoveryInterface, error) {
   134  	client := rc.kubeClient
   135  	discoveryClient, ok := client.Discovery().(*discoveryFake.FakeDiscovery)
   136  	if !ok {
   137  		return nil, fmt.Errorf("DiscoveryClient was not successfully created")
   138  	}
   139  	return discoveryClient, nil
   140  }
   141  
   142  func (rc *FakeRootCmdContext) VerifyCLIArgsNil(cmd *cobra.Command) error {
   143  	cmd.Args = func(cmd *cobra.Command, args []string) error {
   144  		// In unit-tests the TestName is an arg. So to avoid tests failing because of the TestName
   145  		// we're now checking that the arg list is greater than 1.
   146  		if len(args) > 1 {
   147  			return fmt.Errorf("invalid arguments specified: %s", args)
   148  		}
   149  		return nil
   150  	}
   151  	return nil
   152  }