github.com/fastly/cli@v1.7.2-0.20240304164155-9d0f1d77c3bf/pkg/commands/logging/openstack/openstack_test.go (about) 1 package openstack_test 2 3 import ( 4 "bytes" 5 "testing" 6 7 "github.com/fastly/go-fastly/v9/fastly" 8 9 "github.com/fastly/cli/pkg/argparser" 10 "github.com/fastly/cli/pkg/commands/logging/openstack" 11 "github.com/fastly/cli/pkg/config" 12 "github.com/fastly/cli/pkg/errors" 13 "github.com/fastly/cli/pkg/global" 14 "github.com/fastly/cli/pkg/manifest" 15 "github.com/fastly/cli/pkg/mock" 16 "github.com/fastly/cli/pkg/testutil" 17 ) 18 19 func TestCreateOpenstackInput(t *testing.T) { 20 for _, testcase := range []struct { 21 name string 22 cmd *openstack.CreateCommand 23 want *fastly.CreateOpenstackInput 24 wantError string 25 }{ 26 { 27 name: "required values set flag serviceID", 28 cmd: createCommandRequired(), 29 want: &fastly.CreateOpenstackInput{ 30 ServiceID: "123", 31 ServiceVersion: 4, 32 Name: fastly.ToPointer("log"), 33 BucketName: fastly.ToPointer("bucket"), 34 AccessKey: fastly.ToPointer("access"), 35 User: fastly.ToPointer("user"), 36 URL: fastly.ToPointer("https://example.com"), 37 }, 38 }, 39 { 40 name: "all values set flag serviceID", 41 cmd: createCommandAll(), 42 want: &fastly.CreateOpenstackInput{ 43 ServiceID: "123", 44 ServiceVersion: 4, 45 Name: fastly.ToPointer("log"), 46 BucketName: fastly.ToPointer("bucket"), 47 AccessKey: fastly.ToPointer("access"), 48 User: fastly.ToPointer("user"), 49 URL: fastly.ToPointer("https://example.com"), 50 Path: fastly.ToPointer("/log"), 51 Period: fastly.ToPointer(3600), 52 Format: fastly.ToPointer(`%h %l %u %t "%r" %>s %b`), 53 MessageType: fastly.ToPointer("classic"), 54 FormatVersion: fastly.ToPointer(2), 55 ResponseCondition: fastly.ToPointer("Prevent default logging"), 56 TimestampFormat: fastly.ToPointer("%Y-%m-%dT%H:%M:%S.000"), 57 Placement: fastly.ToPointer("none"), 58 PublicKey: fastly.ToPointer(pgpPublicKey()), 59 CompressionCodec: fastly.ToPointer("zstd"), 60 }, 61 }, 62 { 63 name: "error missing serviceID", 64 cmd: createCommandMissingServiceID(), 65 want: nil, 66 wantError: errors.ErrNoServiceID.Error(), 67 }, 68 } { 69 t.Run(testcase.name, func(t *testing.T) { 70 var bs []byte 71 out := bytes.NewBuffer(bs) 72 verboseMode := true 73 74 serviceID, serviceVersion, err := argparser.ServiceDetails(argparser.ServiceDetailsOpts{ 75 AutoCloneFlag: testcase.cmd.AutoClone, 76 APIClient: testcase.cmd.Globals.APIClient, 77 Manifest: testcase.cmd.Manifest, 78 Out: out, 79 ServiceVersionFlag: testcase.cmd.ServiceVersion, 80 VerboseMode: verboseMode, 81 }) 82 83 switch { 84 case err != nil && testcase.wantError == "": 85 t.Fatalf("unexpected error getting service details: %v", err) 86 return 87 case err != nil && testcase.wantError != "": 88 testutil.AssertErrorContains(t, err, testcase.wantError) 89 return 90 case err == nil && testcase.wantError != "": 91 t.Fatalf("expected error, have nil (service details: %s, %d)", serviceID, serviceVersion.Number) 92 case err == nil && testcase.wantError == "": 93 have, err := testcase.cmd.ConstructInput(serviceID, fastly.ToValue(serviceVersion.Number)) 94 testutil.AssertErrorContains(t, err, testcase.wantError) 95 testutil.AssertEqual(t, testcase.want, have) 96 } 97 }) 98 } 99 } 100 101 func TestUpdateOpenstackInput(t *testing.T) { 102 scenarios := []struct { 103 name string 104 cmd *openstack.UpdateCommand 105 api mock.API 106 want *fastly.UpdateOpenstackInput 107 wantError string 108 }{ 109 { 110 name: "all values set flag serviceID", 111 cmd: updateCommandAll(), 112 api: mock.API{ 113 ListVersionsFn: testutil.ListVersions, 114 CloneVersionFn: testutil.CloneVersionResult(4), 115 GetOpenstackFn: getOpenstackOK, 116 }, 117 want: &fastly.UpdateOpenstackInput{ 118 ServiceID: "123", 119 ServiceVersion: 4, 120 Name: "log", 121 NewName: fastly.ToPointer("new1"), 122 BucketName: fastly.ToPointer("new2"), 123 User: fastly.ToPointer("new3"), 124 AccessKey: fastly.ToPointer("new4"), 125 URL: fastly.ToPointer("new5"), 126 Path: fastly.ToPointer("new6"), 127 Period: fastly.ToPointer(3601), 128 GzipLevel: fastly.ToPointer(0), 129 Format: fastly.ToPointer("new7"), 130 FormatVersion: fastly.ToPointer(3), 131 ResponseCondition: fastly.ToPointer("new8"), 132 MessageType: fastly.ToPointer("new9"), 133 TimestampFormat: fastly.ToPointer("new10"), 134 Placement: fastly.ToPointer("new11"), 135 PublicKey: fastly.ToPointer("new12"), 136 CompressionCodec: fastly.ToPointer("new13"), 137 }, 138 }, 139 { 140 name: "no updates", 141 cmd: updateCommandNoUpdates(), 142 api: mock.API{ 143 ListVersionsFn: testutil.ListVersions, 144 CloneVersionFn: testutil.CloneVersionResult(4), 145 GetOpenstackFn: getOpenstackOK, 146 }, 147 want: &fastly.UpdateOpenstackInput{ 148 ServiceID: "123", 149 ServiceVersion: 4, 150 Name: "log", 151 }, 152 }, 153 { 154 name: "error missing serviceID", 155 cmd: updateCommandMissingServiceID(), 156 want: nil, 157 wantError: errors.ErrNoServiceID.Error(), 158 }, 159 } 160 for testcaseIdx := range scenarios { 161 testcase := &scenarios[testcaseIdx] 162 t.Run(testcase.name, func(t *testing.T) { 163 testcase.cmd.Globals.APIClient = testcase.api 164 165 var bs []byte 166 out := bytes.NewBuffer(bs) 167 verboseMode := true 168 169 serviceID, serviceVersion, err := argparser.ServiceDetails(argparser.ServiceDetailsOpts{ 170 AutoCloneFlag: testcase.cmd.AutoClone, 171 APIClient: testcase.api, 172 Manifest: testcase.cmd.Manifest, 173 Out: out, 174 ServiceVersionFlag: testcase.cmd.ServiceVersion, 175 VerboseMode: verboseMode, 176 }) 177 178 switch { 179 case err != nil && testcase.wantError == "": 180 t.Fatalf("unexpected error getting service details: %v", err) 181 return 182 case err != nil && testcase.wantError != "": 183 testutil.AssertErrorContains(t, err, testcase.wantError) 184 return 185 case err == nil && testcase.wantError != "": 186 t.Fatalf("expected error, have nil (service details: %s, %d)", serviceID, serviceVersion.Number) 187 case err == nil && testcase.wantError == "": 188 have, err := testcase.cmd.ConstructInput(serviceID, fastly.ToValue(serviceVersion.Number)) 189 testutil.AssertErrorContains(t, err, testcase.wantError) 190 testutil.AssertEqual(t, testcase.want, have) 191 } 192 }) 193 } 194 } 195 196 func createCommandRequired() *openstack.CreateCommand { 197 var b bytes.Buffer 198 199 g := global.Data{ 200 Config: config.File{}, 201 Env: config.Environment{}, 202 Output: &b, 203 } 204 g.APIClient, _ = mock.APIClient(mock.API{ 205 ListVersionsFn: testutil.ListVersions, 206 CloneVersionFn: testutil.CloneVersionResult(4), 207 })("token", "endpoint", false) 208 209 return &openstack.CreateCommand{ 210 Base: argparser.Base{ 211 Globals: &g, 212 }, 213 Manifest: manifest.Data{ 214 Flag: manifest.Flag{ 215 ServiceID: "123", 216 }, 217 }, 218 ServiceVersion: argparser.OptionalServiceVersion{ 219 OptionalString: argparser.OptionalString{Value: "1"}, 220 }, 221 AutoClone: argparser.OptionalAutoClone{ 222 OptionalBool: argparser.OptionalBool{ 223 Optional: argparser.Optional{ 224 WasSet: true, 225 }, 226 Value: true, 227 }, 228 }, 229 EndpointName: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "log"}, 230 BucketName: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "bucket"}, 231 AccessKey: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "access"}, 232 User: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "user"}, 233 URL: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "https://example.com"}, 234 } 235 } 236 237 func createCommandAll() *openstack.CreateCommand { 238 var b bytes.Buffer 239 240 g := global.Data{ 241 Config: config.File{}, 242 Env: config.Environment{}, 243 Output: &b, 244 } 245 g.APIClient, _ = mock.APIClient(mock.API{ 246 ListVersionsFn: testutil.ListVersions, 247 CloneVersionFn: testutil.CloneVersionResult(4), 248 })("token", "endpoint", false) 249 250 return &openstack.CreateCommand{ 251 Base: argparser.Base{ 252 Globals: &g, 253 }, 254 Manifest: manifest.Data{ 255 Flag: manifest.Flag{ 256 ServiceID: "123", 257 }, 258 }, 259 ServiceVersion: argparser.OptionalServiceVersion{ 260 OptionalString: argparser.OptionalString{Value: "1"}, 261 }, 262 AutoClone: argparser.OptionalAutoClone{ 263 OptionalBool: argparser.OptionalBool{ 264 Optional: argparser.Optional{ 265 WasSet: true, 266 }, 267 Value: true, 268 }, 269 }, 270 EndpointName: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "log"}, 271 BucketName: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "bucket"}, 272 AccessKey: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "access"}, 273 User: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "user"}, 274 URL: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "https://example.com"}, 275 Path: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "/log"}, 276 Period: argparser.OptionalInt{Optional: argparser.Optional{WasSet: true}, Value: 3600}, 277 Format: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: `%h %l %u %t "%r" %>s %b`}, 278 FormatVersion: argparser.OptionalInt{Optional: argparser.Optional{WasSet: true}, Value: 2}, 279 ResponseCondition: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "Prevent default logging"}, 280 TimestampFormat: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "%Y-%m-%dT%H:%M:%S.000"}, 281 Placement: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "none"}, 282 MessageType: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "classic"}, 283 PublicKey: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: pgpPublicKey()}, 284 CompressionCodec: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "zstd"}, 285 } 286 } 287 288 func createCommandMissingServiceID() *openstack.CreateCommand { 289 res := createCommandAll() 290 res.Manifest = manifest.Data{} 291 return res 292 } 293 294 func updateCommandNoUpdates() *openstack.UpdateCommand { 295 var b bytes.Buffer 296 297 g := global.Data{ 298 Config: config.File{}, 299 Env: config.Environment{}, 300 Output: &b, 301 } 302 303 return &openstack.UpdateCommand{ 304 Base: argparser.Base{ 305 Globals: &g, 306 }, 307 Manifest: manifest.Data{ 308 Flag: manifest.Flag{ 309 ServiceID: "123", 310 }, 311 }, 312 EndpointName: "log", 313 ServiceVersion: argparser.OptionalServiceVersion{ 314 OptionalString: argparser.OptionalString{Value: "1"}, 315 }, 316 AutoClone: argparser.OptionalAutoClone{ 317 OptionalBool: argparser.OptionalBool{ 318 Optional: argparser.Optional{ 319 WasSet: true, 320 }, 321 Value: true, 322 }, 323 }, 324 } 325 } 326 327 func updateCommandAll() *openstack.UpdateCommand { 328 var b bytes.Buffer 329 330 g := global.Data{ 331 Config: config.File{}, 332 Env: config.Environment{}, 333 Output: &b, 334 } 335 336 return &openstack.UpdateCommand{ 337 Base: argparser.Base{ 338 Globals: &g, 339 }, 340 Manifest: manifest.Data{ 341 Flag: manifest.Flag{ 342 ServiceID: "123", 343 }, 344 }, 345 EndpointName: "log", 346 ServiceVersion: argparser.OptionalServiceVersion{ 347 OptionalString: argparser.OptionalString{Value: "1"}, 348 }, 349 AutoClone: argparser.OptionalAutoClone{ 350 OptionalBool: argparser.OptionalBool{ 351 Optional: argparser.Optional{ 352 WasSet: true, 353 }, 354 Value: true, 355 }, 356 }, 357 NewName: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new1"}, 358 BucketName: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new2"}, 359 User: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new3"}, 360 AccessKey: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new4"}, 361 URL: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new5"}, 362 Path: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new6"}, 363 Period: argparser.OptionalInt{Optional: argparser.Optional{WasSet: true}, Value: 3601}, 364 GzipLevel: argparser.OptionalInt{Optional: argparser.Optional{WasSet: true}, Value: 0}, 365 Format: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new7"}, 366 FormatVersion: argparser.OptionalInt{Optional: argparser.Optional{WasSet: true}, Value: 3}, 367 ResponseCondition: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new8"}, 368 MessageType: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new9"}, 369 TimestampFormat: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new10"}, 370 Placement: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new11"}, 371 PublicKey: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new12"}, 372 CompressionCodec: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new13"}, 373 } 374 } 375 376 func updateCommandMissingServiceID() *openstack.UpdateCommand { 377 res := updateCommandAll() 378 res.Manifest = manifest.Data{} 379 return res 380 }