github.com/fastly/cli@v1.7.2-0.20240304164155-9d0f1d77c3bf/pkg/commands/logging/scalyr/scalyr_integration_test.go (about)

     1  package scalyr_test
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"io"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/fastly/go-fastly/v9/fastly"
    11  
    12  	"github.com/fastly/cli/pkg/app"
    13  	fsterrs "github.com/fastly/cli/pkg/errors"
    14  	"github.com/fastly/cli/pkg/global"
    15  	"github.com/fastly/cli/pkg/mock"
    16  	"github.com/fastly/cli/pkg/testutil"
    17  )
    18  
    19  func TestScalyrCreate(t *testing.T) {
    20  	args := testutil.Args
    21  	scenarios := []struct {
    22  		args       []string
    23  		api        mock.API
    24  		wantError  string
    25  		wantOutput string
    26  	}{
    27  		{
    28  			args: args("logging scalyr create --name log --service-id  --version 1 --auth-token abc --autoclone"),
    29  			api: mock.API{
    30  				ListVersionsFn: testutil.ListVersions,
    31  				CloneVersionFn: testutil.CloneVersionResult(4),
    32  			},
    33  			wantError: fsterrs.ErrNoServiceID.Error(),
    34  		},
    35  		{
    36  			args: args("logging scalyr create --service-id 123 --version 1 --name log --auth-token abc --autoclone"),
    37  			api: mock.API{
    38  				ListVersionsFn: testutil.ListVersions,
    39  				CloneVersionFn: testutil.CloneVersionResult(4),
    40  				CreateScalyrFn: createScalyrOK,
    41  			},
    42  			wantOutput: "Created Scalyr logging endpoint log (service 123 version 4)",
    43  		},
    44  		{
    45  			args: args("logging scalyr create --service-id 123 --version 1 --name log --auth-token abc --autoclone"),
    46  			api: mock.API{
    47  				ListVersionsFn: testutil.ListVersions,
    48  				CloneVersionFn: testutil.CloneVersionResult(4),
    49  				CreateScalyrFn: createScalyrError,
    50  			},
    51  			wantError: errTest.Error(),
    52  		},
    53  	}
    54  	for testcaseIdx := range scenarios {
    55  		testcase := &scenarios[testcaseIdx]
    56  		t.Run(strings.Join(testcase.args, " "), func(t *testing.T) {
    57  			var stdout bytes.Buffer
    58  			app.Init = func(_ []string, _ io.Reader) (*global.Data, error) {
    59  				opts := testutil.MockGlobalData(testcase.args, &stdout)
    60  				opts.APIClientFactory = mock.APIClient(testcase.api)
    61  				return opts, nil
    62  			}
    63  			err := app.Run(testcase.args, nil)
    64  			testutil.AssertErrorContains(t, err, testcase.wantError)
    65  			testutil.AssertStringContains(t, stdout.String(), testcase.wantOutput)
    66  		})
    67  	}
    68  }
    69  
    70  func TestScalyrList(t *testing.T) {
    71  	args := testutil.Args
    72  	scenarios := []struct {
    73  		args       []string
    74  		api        mock.API
    75  		wantError  string
    76  		wantOutput string
    77  	}{
    78  		{
    79  			args: args("logging scalyr list --service-id 123 --version 1"),
    80  			api: mock.API{
    81  				ListVersionsFn: testutil.ListVersions,
    82  				ListScalyrsFn:  listScalyrsOK,
    83  			},
    84  			wantOutput: listScalyrsShortOutput,
    85  		},
    86  		{
    87  			args: args("logging scalyr list --service-id 123 --version 1 --verbose"),
    88  			api: mock.API{
    89  				ListVersionsFn: testutil.ListVersions,
    90  				ListScalyrsFn:  listScalyrsOK,
    91  			},
    92  			wantOutput: listScalyrsVerboseOutput,
    93  		},
    94  		{
    95  			args: args("logging scalyr list --service-id 123 --version 1 -v"),
    96  			api: mock.API{
    97  				ListVersionsFn: testutil.ListVersions,
    98  				ListScalyrsFn:  listScalyrsOK,
    99  			},
   100  			wantOutput: listScalyrsVerboseOutput,
   101  		},
   102  		{
   103  			args: args("logging scalyr --verbose list --service-id 123 --version 1"),
   104  			api: mock.API{
   105  				ListVersionsFn: testutil.ListVersions,
   106  				ListScalyrsFn:  listScalyrsOK,
   107  			},
   108  			wantOutput: listScalyrsVerboseOutput,
   109  		},
   110  		{
   111  			args: args("logging -v scalyr list --service-id 123 --version 1"),
   112  			api: mock.API{
   113  				ListVersionsFn: testutil.ListVersions,
   114  				ListScalyrsFn:  listScalyrsOK,
   115  			},
   116  			wantOutput: listScalyrsVerboseOutput,
   117  		},
   118  		{
   119  			args: args("logging scalyr list --service-id 123 --version 1"),
   120  			api: mock.API{
   121  				ListVersionsFn: testutil.ListVersions,
   122  				ListScalyrsFn:  listScalyrsError,
   123  			},
   124  			wantError: errTest.Error(),
   125  		},
   126  	}
   127  	for testcaseIdx := range scenarios {
   128  		testcase := &scenarios[testcaseIdx]
   129  		t.Run(strings.Join(testcase.args, " "), func(t *testing.T) {
   130  			var stdout bytes.Buffer
   131  			app.Init = func(_ []string, _ io.Reader) (*global.Data, error) {
   132  				opts := testutil.MockGlobalData(testcase.args, &stdout)
   133  				opts.APIClientFactory = mock.APIClient(testcase.api)
   134  				return opts, nil
   135  			}
   136  			err := app.Run(testcase.args, nil)
   137  			testutil.AssertErrorContains(t, err, testcase.wantError)
   138  			testutil.AssertString(t, testcase.wantOutput, stdout.String())
   139  		})
   140  	}
   141  }
   142  
   143  func TestScalyrDescribe(t *testing.T) {
   144  	args := testutil.Args
   145  	scenarios := []struct {
   146  		args       []string
   147  		api        mock.API
   148  		wantError  string
   149  		wantOutput string
   150  	}{
   151  		{
   152  			args:      args("logging scalyr describe --service-id 123 --version 1"),
   153  			wantError: "error parsing arguments: required flag --name not provided",
   154  		},
   155  		{
   156  			args: args("logging scalyr describe --service-id 123 --version 1 --name logs"),
   157  			api: mock.API{
   158  				ListVersionsFn: testutil.ListVersions,
   159  				GetScalyrFn:    getScalyrError,
   160  			},
   161  			wantError: errTest.Error(),
   162  		},
   163  		{
   164  			args: args("logging scalyr describe --service-id 123 --version 1 --name logs"),
   165  			api: mock.API{
   166  				ListVersionsFn: testutil.ListVersions,
   167  				GetScalyrFn:    getScalyrOK,
   168  			},
   169  			wantOutput: describeScalyrOutput,
   170  		},
   171  	}
   172  	for testcaseIdx := range scenarios {
   173  		testcase := &scenarios[testcaseIdx]
   174  		t.Run(strings.Join(testcase.args, " "), func(t *testing.T) {
   175  			var stdout bytes.Buffer
   176  			app.Init = func(_ []string, _ io.Reader) (*global.Data, error) {
   177  				opts := testutil.MockGlobalData(testcase.args, &stdout)
   178  				opts.APIClientFactory = mock.APIClient(testcase.api)
   179  				return opts, nil
   180  			}
   181  			err := app.Run(testcase.args, nil)
   182  			testutil.AssertErrorContains(t, err, testcase.wantError)
   183  			testutil.AssertString(t, testcase.wantOutput, stdout.String())
   184  		})
   185  	}
   186  }
   187  
   188  func TestScalyrUpdate(t *testing.T) {
   189  	args := testutil.Args
   190  	scenarios := []struct {
   191  		args       []string
   192  		api        mock.API
   193  		wantError  string
   194  		wantOutput string
   195  	}{
   196  		{
   197  			args:      args("logging scalyr update --service-id 123 --version 1 --new-name log"),
   198  			wantError: "error parsing arguments: required flag --name not provided",
   199  		},
   200  		{
   201  			args: args("logging scalyr update --service-id 123 --version 1 --name logs --new-name log --autoclone"),
   202  			api: mock.API{
   203  				ListVersionsFn: testutil.ListVersions,
   204  				CloneVersionFn: testutil.CloneVersionResult(4),
   205  				UpdateScalyrFn: updateScalyrError,
   206  			},
   207  			wantError: errTest.Error(),
   208  		},
   209  		{
   210  			args: args("logging scalyr update --service-id 123 --version 1 --name logs --new-name log --autoclone"),
   211  			api: mock.API{
   212  				ListVersionsFn: testutil.ListVersions,
   213  				CloneVersionFn: testutil.CloneVersionResult(4),
   214  				UpdateScalyrFn: updateScalyrOK,
   215  			},
   216  			wantOutput: "Updated Scalyr logging endpoint log (service 123 version 4)",
   217  		},
   218  	}
   219  	for testcaseIdx := range scenarios {
   220  		testcase := &scenarios[testcaseIdx]
   221  		t.Run(strings.Join(testcase.args, " "), func(t *testing.T) {
   222  			var stdout bytes.Buffer
   223  			app.Init = func(_ []string, _ io.Reader) (*global.Data, error) {
   224  				opts := testutil.MockGlobalData(testcase.args, &stdout)
   225  				opts.APIClientFactory = mock.APIClient(testcase.api)
   226  				return opts, nil
   227  			}
   228  			err := app.Run(testcase.args, nil)
   229  			testutil.AssertErrorContains(t, err, testcase.wantError)
   230  			testutil.AssertStringContains(t, stdout.String(), testcase.wantOutput)
   231  		})
   232  	}
   233  }
   234  
   235  func TestScalyrDelete(t *testing.T) {
   236  	args := testutil.Args
   237  	scenarios := []struct {
   238  		args       []string
   239  		api        mock.API
   240  		wantError  string
   241  		wantOutput string
   242  	}{
   243  		{
   244  			args:      args("logging scalyr delete --service-id 123 --version 1"),
   245  			wantError: "error parsing arguments: required flag --name not provided",
   246  		},
   247  		{
   248  			args: args("logging scalyr delete --service-id 123 --version 1 --name logs --autoclone"),
   249  			api: mock.API{
   250  				ListVersionsFn: testutil.ListVersions,
   251  				CloneVersionFn: testutil.CloneVersionResult(4),
   252  				DeleteScalyrFn: deleteScalyrError,
   253  			},
   254  			wantError: errTest.Error(),
   255  		},
   256  		{
   257  			args: args("logging scalyr delete --service-id 123 --version 1 --name logs --autoclone"),
   258  			api: mock.API{
   259  				ListVersionsFn: testutil.ListVersions,
   260  				CloneVersionFn: testutil.CloneVersionResult(4),
   261  				DeleteScalyrFn: deleteScalyrOK,
   262  			},
   263  			wantOutput: "Deleted Scalyr logging endpoint logs (service 123 version 4)",
   264  		},
   265  	}
   266  	for testcaseIdx := range scenarios {
   267  		testcase := &scenarios[testcaseIdx]
   268  		t.Run(strings.Join(testcase.args, " "), func(t *testing.T) {
   269  			var stdout bytes.Buffer
   270  			app.Init = func(_ []string, _ io.Reader) (*global.Data, error) {
   271  				opts := testutil.MockGlobalData(testcase.args, &stdout)
   272  				opts.APIClientFactory = mock.APIClient(testcase.api)
   273  				return opts, nil
   274  			}
   275  			err := app.Run(testcase.args, nil)
   276  			testutil.AssertErrorContains(t, err, testcase.wantError)
   277  			testutil.AssertStringContains(t, stdout.String(), testcase.wantOutput)
   278  		})
   279  	}
   280  }
   281  
   282  var errTest = errors.New("fixture error")
   283  
   284  func createScalyrOK(i *fastly.CreateScalyrInput) (*fastly.Scalyr, error) {
   285  	s := fastly.Scalyr{
   286  		ServiceID:      fastly.ToPointer(i.ServiceID),
   287  		ServiceVersion: fastly.ToPointer(i.ServiceVersion),
   288  	}
   289  
   290  	// Avoids null pointer dereference for test cases with missing required params.
   291  	// If omitted, tests are guaranteed to panic.
   292  	if i.Name != nil {
   293  		s.Name = i.Name
   294  	}
   295  
   296  	if i.Token != nil {
   297  		s.Token = i.Token
   298  	}
   299  
   300  	if i.Format != nil {
   301  		s.Format = i.Format
   302  	}
   303  
   304  	if i.FormatVersion != nil {
   305  		s.FormatVersion = i.FormatVersion
   306  	}
   307  
   308  	if i.ResponseCondition != nil {
   309  		s.ResponseCondition = i.ResponseCondition
   310  	}
   311  
   312  	if i.Placement != nil {
   313  		s.Placement = i.Placement
   314  	}
   315  
   316  	return &s, nil
   317  }
   318  
   319  func createScalyrError(_ *fastly.CreateScalyrInput) (*fastly.Scalyr, error) {
   320  	return nil, errTest
   321  }
   322  
   323  func listScalyrsOK(i *fastly.ListScalyrsInput) ([]*fastly.Scalyr, error) {
   324  	return []*fastly.Scalyr{
   325  		{
   326  			ServiceID:         fastly.ToPointer(i.ServiceID),
   327  			ServiceVersion:    fastly.ToPointer(i.ServiceVersion),
   328  			Name:              fastly.ToPointer("logs"),
   329  			Token:             fastly.ToPointer("abc"),
   330  			Region:            fastly.ToPointer("US"),
   331  			Format:            fastly.ToPointer(`%h %l %u %t "%r" %>s %b`),
   332  			FormatVersion:     fastly.ToPointer(2),
   333  			ResponseCondition: fastly.ToPointer("Prevent default logging"),
   334  			Placement:         fastly.ToPointer("none"),
   335  		},
   336  		{
   337  			ServiceID:         fastly.ToPointer(i.ServiceID),
   338  			ServiceVersion:    fastly.ToPointer(i.ServiceVersion),
   339  			Name:              fastly.ToPointer("analytics"),
   340  			Token:             fastly.ToPointer("abc"),
   341  			Region:            fastly.ToPointer("US"),
   342  			Format:            fastly.ToPointer(`%h %l %u %t "%r" %>s %b`),
   343  			FormatVersion:     fastly.ToPointer(2),
   344  			ResponseCondition: fastly.ToPointer("Prevent default logging"),
   345  			Placement:         fastly.ToPointer("none"),
   346  		},
   347  	}, nil
   348  }
   349  
   350  func listScalyrsError(_ *fastly.ListScalyrsInput) ([]*fastly.Scalyr, error) {
   351  	return nil, errTest
   352  }
   353  
   354  var listScalyrsShortOutput = strings.TrimSpace(`
   355  SERVICE  VERSION  NAME
   356  123      1        logs
   357  123      1        analytics
   358  `) + "\n"
   359  
   360  var listScalyrsVerboseOutput = strings.TrimSpace(`
   361  Fastly API endpoint: https://api.fastly.com
   362  Fastly API token provided via config file (profile: user)
   363  
   364  Service ID (via --service-id): 123
   365  
   366  Version: 1
   367  	Scalyr 1/2
   368  		Service ID: 123
   369  		Version: 1
   370  		Name: logs
   371  		Token: abc
   372  		Region: US
   373  		Format: %h %l %u %t "%r" %>s %b
   374  		Format version: 2
   375  		Response condition: Prevent default logging
   376  		Placement: none
   377  	Scalyr 2/2
   378  		Service ID: 123
   379  		Version: 1
   380  		Name: analytics
   381  		Token: abc
   382  		Region: US
   383  		Format: %h %l %u %t "%r" %>s %b
   384  		Format version: 2
   385  		Response condition: Prevent default logging
   386  		Placement: none
   387  `) + "\n\n"
   388  
   389  func getScalyrOK(i *fastly.GetScalyrInput) (*fastly.Scalyr, error) {
   390  	return &fastly.Scalyr{
   391  		ServiceID:         fastly.ToPointer(i.ServiceID),
   392  		ServiceVersion:    fastly.ToPointer(i.ServiceVersion),
   393  		Name:              fastly.ToPointer("logs"),
   394  		Token:             fastly.ToPointer("abc"),
   395  		Region:            fastly.ToPointer("US"),
   396  		Format:            fastly.ToPointer(`%h %l %u %t "%r" %>s %b`),
   397  		FormatVersion:     fastly.ToPointer(2),
   398  		ResponseCondition: fastly.ToPointer("Prevent default logging"),
   399  		Placement:         fastly.ToPointer("none"),
   400  	}, nil
   401  }
   402  
   403  func getScalyrError(_ *fastly.GetScalyrInput) (*fastly.Scalyr, error) {
   404  	return nil, errTest
   405  }
   406  
   407  var describeScalyrOutput = "\n" + strings.TrimSpace(`
   408  Format: %h %l %u %t "%r" %>s %b
   409  Format version: 2
   410  Name: logs
   411  Placement: none
   412  Region: US
   413  Response condition: Prevent default logging
   414  Service ID: 123
   415  Token: abc
   416  Version: 1
   417  `) + "\n"
   418  
   419  func updateScalyrOK(i *fastly.UpdateScalyrInput) (*fastly.Scalyr, error) {
   420  	return &fastly.Scalyr{
   421  		ServiceID:         fastly.ToPointer(i.ServiceID),
   422  		ServiceVersion:    fastly.ToPointer(i.ServiceVersion),
   423  		Name:              fastly.ToPointer("log"),
   424  		Token:             fastly.ToPointer("abc"),
   425  		Region:            fastly.ToPointer("EU"),
   426  		Format:            fastly.ToPointer(`%h %l %u %t "%r" %>s %b`),
   427  		FormatVersion:     fastly.ToPointer(2),
   428  		ResponseCondition: fastly.ToPointer("Prevent default logging"),
   429  		Placement:         fastly.ToPointer("none"),
   430  	}, nil
   431  }
   432  
   433  func updateScalyrError(_ *fastly.UpdateScalyrInput) (*fastly.Scalyr, error) {
   434  	return nil, errTest
   435  }
   436  
   437  func deleteScalyrOK(_ *fastly.DeleteScalyrInput) error {
   438  	return nil
   439  }
   440  
   441  func deleteScalyrError(_ *fastly.DeleteScalyrInput) error {
   442  	return errTest
   443  }