code.vegaprotocol.io/vega@v0.79.0/wallet/network/store/v1/file_store_test.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package v1_test 17 18 import ( 19 "os" 20 "path/filepath" 21 "testing" 22 23 vgrand "code.vegaprotocol.io/vega/libs/rand" 24 vgtest "code.vegaprotocol.io/vega/libs/test" 25 "code.vegaprotocol.io/vega/paths" 26 "code.vegaprotocol.io/vega/wallet/api" 27 "code.vegaprotocol.io/vega/wallet/network" 28 v1 "code.vegaprotocol.io/vega/wallet/network/store/v1" 29 30 "github.com/stretchr/testify/assert" 31 "github.com/stretchr/testify/require" 32 ) 33 34 func TestFileStoreV1(t *testing.T) { 35 t.Run("New store succeeds", testNewStoreSucceeds) 36 t.Run("Saving already existing network succeeds", testFileStoreV1SaveAlreadyExistingNetworkSucceeds) 37 t.Run("Saving network succeeds", testFileStoreV1SaveNetworkSucceeds) 38 t.Run("Saving network with bad name fails", testFileStoreV1SaveNetworkWithBadNameFails) 39 t.Run("Verifying non-existing network fails", testFileStoreV1VerifyingNonExistingNetworkFails) 40 t.Run("Verifying existing network succeeds", testFileStoreV1VerifyingExistingNetworkSucceeds) 41 t.Run("Getting non-existing network fails", testFileStoreV1GetNonExistingNetworkFails) 42 t.Run("Getting existing network succeeds", testFileStoreV1GetExistingNetworkSucceeds) 43 t.Run("Getting network path succeeds", testFileStoreV1GetNetworkPathSucceeds) 44 t.Run("Getting networks path succeeds", testFileStoreV1GetNetworksPathSucceeds) 45 t.Run("Listing networks succeeds", testFileStoreV1ListingNetworksSucceeds) 46 t.Run("Deleting network succeeds", testFileStoreV1DeleteNetworkSucceeds) 47 t.Run("Renaming network succeeds", testFileStoreV1RenamingNetworkSucceeds) 48 t.Run("Renaming non-existing network fails", testFileStoreV1RenamingNonExistingNetworkFails) 49 t.Run("Renaming network with invalid name fails", testFileStoreV1RenamingNetworkWithInvalidNameFails) 50 } 51 52 func testNewStoreSucceeds(t *testing.T) { 53 vegaHome := newVegaHome(t) 54 55 s, err := v1.InitialiseStore(vegaHome) 56 57 require.NoError(t, err) 58 assert.NotNil(t, s) 59 vgtest.AssertDirAccess(t, networksHome(t, vegaHome)) 60 } 61 62 func testFileStoreV1SaveAlreadyExistingNetworkSucceeds(t *testing.T) { 63 vegaHome := newVegaHome(t) 64 65 // given 66 s := initialiseFromPath(t, vegaHome) 67 net := &network.Network{ 68 Name: "test", 69 } 70 71 // when 72 err := s.SaveNetwork(net) 73 74 // then 75 require.NoError(t, err) 76 77 // when 78 err = s.SaveNetwork(net) 79 80 // then 81 require.NoError(t, err) 82 } 83 84 func testFileStoreV1SaveNetworkSucceeds(t *testing.T) { 85 vegaHome := newVegaHome(t) 86 87 // given 88 s := initialiseFromPath(t, vegaHome) 89 net := &network.Network{ 90 Name: vgrand.RandomStr(10), 91 } 92 93 // when 94 err := s.SaveNetwork(net) 95 96 // then 97 require.NoError(t, err) 98 vgtest.AssertFileAccess(t, networkPath(t, vegaHome, net.Name)) 99 100 // confirm that the network name is not saved in the file 101 netpath := networkPath(t, vegaHome, net.Name) 102 b, err := os.ReadFile(netpath) 103 assert.NoError(t, err) 104 assert.NotContains(t, string(b), net.Name) 105 106 // when 107 returnedNet, err := s.GetNetwork(net.Name) 108 109 // then 110 require.NoError(t, err) 111 assert.Equal(t, net, returnedNet) 112 assert.Equal(t, net.Name, returnedNet.Name) 113 } 114 115 func testFileStoreV1SaveNetworkWithBadNameFails(t *testing.T) { 116 vegaHome := newVegaHome(t) 117 118 // given 119 s := initialiseFromPath(t, vegaHome) 120 121 tcs := []struct { 122 name string 123 network string 124 expectedErr error 125 }{ 126 { 127 name: "when empty", 128 network: "", 129 expectedErr: v1.ErrNetworkNameCannotBeEmpty, 130 }, { 131 name: "starting with `.`", 132 network: "." + vgrand.RandomStr(3), 133 expectedErr: v1.ErrNetworkNameCannotStartWithDot, 134 }, { 135 name: "with `/`", 136 network: "\\" + vgrand.RandomStr(3) + "/" + vgrand.RandomStr(3), 137 expectedErr: v1.ErrNetworkNameCannotContainSlash, 138 }, 139 } 140 141 for _, tc := range tcs { 142 t.Run(tc.name, func(tt *testing.T) { 143 net := &network.Network{ 144 Name: tc.network, 145 } 146 147 // when 148 err := s.SaveNetwork(net) 149 150 // then 151 require.ErrorIs(tt, err, tc.expectedErr) 152 }) 153 } 154 } 155 156 func testFileStoreV1VerifyingNonExistingNetworkFails(t *testing.T) { 157 vegaHome := newVegaHome(t) 158 159 // given 160 s := initialiseFromPath(t, vegaHome) 161 162 // when 163 exists, err := s.NetworkExists("test") 164 165 // then 166 assert.NoError(t, err) 167 assert.False(t, exists) 168 } 169 170 func testFileStoreV1VerifyingExistingNetworkSucceeds(t *testing.T) { 171 vegaHome := newVegaHome(t) 172 173 // given 174 s := initialiseFromPath(t, vegaHome) 175 net := &network.Network{ 176 Name: "test", 177 } 178 179 // when 180 err := s.SaveNetwork(net) 181 182 // then 183 require.NoError(t, err) 184 vgtest.AssertFileAccess(t, networkPath(t, vegaHome, net.Name)) 185 186 // when 187 exists, err := s.NetworkExists("test") 188 189 // then 190 require.NoError(t, err) 191 assert.True(t, exists) 192 } 193 194 func testFileStoreV1GetNonExistingNetworkFails(t *testing.T) { 195 vegaHome := newVegaHome(t) 196 197 // given 198 s := initialiseFromPath(t, vegaHome) 199 200 // when 201 keys, err := s.GetNetwork("test") 202 203 // then 204 assert.Error(t, err) 205 assert.Nil(t, keys) 206 } 207 208 func testFileStoreV1GetExistingNetworkSucceeds(t *testing.T) { 209 vegaHome := newVegaHome(t) 210 211 // given 212 s := initialiseFromPath(t, vegaHome) 213 net := &network.Network{ 214 Name: "testnet2", 215 Metadata: []network.Metadata{ 216 { 217 Key: "network", 218 Value: "testnet", 219 }, { 220 Key: "description", 221 Value: "Some network", 222 }, 223 }, 224 API: network.APIConfig{ 225 GRPC: network.HostConfig{ 226 Hosts: []string{ 227 vgrand.RandomStr(10), 228 vgrand.RandomStr(10), 229 vgrand.RandomStr(10), 230 }, 231 }, 232 REST: network.HostConfig{ 233 Hosts: []string{ 234 vgrand.RandomStr(10), 235 vgrand.RandomStr(10), 236 }, 237 }, 238 GraphQL: network.HostConfig{ 239 Hosts: []string{ 240 vgrand.RandomStr(10), 241 vgrand.RandomStr(10), 242 vgrand.RandomStr(10), 243 vgrand.RandomStr(10), 244 }, 245 }, 246 }, 247 Apps: network.AppsConfig{ 248 Console: vgrand.RandomStr(10), 249 Governance: vgrand.RandomStr(10), 250 Explorer: vgrand.RandomStr(10), 251 }, 252 } 253 254 // when 255 err := s.SaveNetwork(net) 256 257 // then 258 require.NoError(t, err) 259 vgtest.AssertFileAccess(t, networkPath(t, vegaHome, net.Name)) 260 261 // when 262 returnedNet, err := s.GetNetwork("testnet2") 263 264 // then 265 require.NoError(t, err) 266 assert.Equal(t, net, returnedNet) 267 } 268 269 func testFileStoreV1GetNetworkPathSucceeds(t *testing.T) { 270 vegaHome := newVegaHome(t) 271 272 // given 273 s := initialiseFromPath(t, vegaHome) 274 275 // when 276 returnedPath := s.GetNetworkPath("test") 277 278 // then 279 assert.Equal(t, networkPath(t, vegaHome, "test"), returnedPath) 280 } 281 282 func testFileStoreV1GetNetworksPathSucceeds(t *testing.T) { 283 vegaHome := newVegaHome(t) 284 285 // given 286 s := initialiseFromPath(t, vegaHome) 287 288 // when 289 returnedPath := s.GetNetworksPath() 290 291 // then 292 assert.Equal(t, networksHome(t, vegaHome), returnedPath) 293 } 294 295 func testFileStoreV1ListingNetworksSucceeds(t *testing.T) { 296 vegaHome := newVegaHome(t) 297 298 // given 299 s := initialiseFromPath(t, vegaHome) 300 net := &network.Network{ 301 // we use "toml" as name on purpose since we want to verify it's not 302 // stripped by the ListNetwork() function. 303 Name: "toml", 304 } 305 306 // when 307 err := s.SaveNetwork(net) 308 309 // then 310 require.NoError(t, err) 311 vgtest.AssertFileAccess(t, networkPath(t, vegaHome, net.Name)) 312 313 // when 314 nets, err := s.ListNetworks() 315 316 // then 317 require.NoError(t, err) 318 assert.Equal(t, []string{"toml"}, nets) 319 } 320 321 func testFileStoreV1DeleteNetworkSucceeds(t *testing.T) { 322 vegaHome := newVegaHome(t) 323 324 // Create a network for us to delete 325 s, err := v1.InitialiseStore(vegaHome) 326 require.NoError(t, err) 327 assert.NotNil(t, s) 328 329 net := &network.Network{ 330 Name: "test", 331 } 332 333 err = s.SaveNetwork(net) 334 require.NoError(t, err) 335 336 // Check it's really there 337 returnedNet, err := s.GetNetwork("test") 338 require.NoError(t, err) 339 assert.Equal(t, net, returnedNet) 340 341 // Now delete it 342 err = s.DeleteNetwork("test") 343 require.NoError(t, err) 344 345 // Check it's no longer there 346 returnedNet, err = s.GetNetwork("test") 347 require.Error(t, err) 348 assert.Nil(t, returnedNet) 349 } 350 351 func testFileStoreV1RenamingNetworkSucceeds(t *testing.T) { 352 vegaHome := newVegaHome(t) 353 354 // Create a network for us to rename 355 s, err := v1.InitialiseStore(vegaHome) 356 require.NoError(t, err) 357 assert.NotNil(t, s) 358 359 // given 360 net := &network.Network{ 361 Name: "test", 362 } 363 364 // when 365 err = s.SaveNetwork(net) 366 367 // then 368 require.NoError(t, err) 369 vgtest.AssertFileAccess(t, s.GetNetworkPath(net.Name)) 370 371 // given 372 newName := vgrand.RandomStr(5) 373 374 // when 375 err = s.RenameNetwork(net.Name, newName) 376 377 // then 378 assert.NoError(t, err) 379 vgtest.AssertNoFile(t, s.GetNetworkPath(net.Name)) 380 vgtest.AssertFileAccess(t, s.GetNetworkPath(newName)) 381 382 // when 383 w1, err := s.GetNetwork(net.Name) 384 385 // then 386 assert.Error(t, err, api.ErrNetworkDoesNotExist) 387 assert.Nil(t, w1) 388 389 // when 390 w2, err := s.GetNetwork(newName) 391 392 // then 393 require.NoError(t, err) 394 assert.NotEmpty(t, w2) 395 } 396 397 func testFileStoreV1RenamingNonExistingNetworkFails(t *testing.T) { 398 vegaHome := newVegaHome(t) 399 400 // given 401 s, err := v1.InitialiseStore(vegaHome) 402 require.NoError(t, err) 403 assert.NotNil(t, s) 404 405 // given 406 unknownName := vgrand.RandomStr(5) 407 newName := vgrand.RandomStr(5) 408 409 // when 410 err = s.RenameNetwork(unknownName, newName) 411 412 // then 413 assert.ErrorIs(t, err, api.ErrNetworkDoesNotExist) 414 vgtest.AssertNoFile(t, s.GetNetworkPath(unknownName)) 415 vgtest.AssertNoFile(t, s.GetNetworkPath(newName)) 416 } 417 418 func testFileStoreV1RenamingNetworkWithInvalidNameFails(t *testing.T) { 419 vegaHome := newVegaHome(t) 420 421 // given 422 s, err := v1.InitialiseStore(vegaHome) 423 require.NoError(t, err) 424 assert.NotNil(t, s) 425 426 // given 427 net := &network.Network{ 428 Name: "test", 429 } 430 431 // when 432 err = s.SaveNetwork(net) 433 434 // then 435 require.NoError(t, err) 436 vgtest.AssertFileAccess(t, s.GetNetworkPath(net.Name)) 437 438 tcs := []struct { 439 name string 440 newName string 441 err error 442 }{ 443 { 444 name: "empty", 445 newName: "", 446 err: v1.ErrNetworkNameCannotBeEmpty, 447 }, { 448 name: "starting with a dot", 449 newName: ".start-with-dot", 450 err: v1.ErrNetworkNameCannotStartWithDot, 451 }, { 452 name: "containing slashes", 453 newName: "contains/multiple/slashes/", 454 err: v1.ErrNetworkNameCannotContainSlash, 455 }, { 456 name: "containing back-slashes", 457 newName: "contains\\multiple\\slashes\\", 458 err: v1.ErrNetworkNameCannotContainSlash, 459 }, 460 } 461 462 for _, tc := range tcs { 463 t.Run(tc.name, func(tt *testing.T) { 464 // when 465 err := s.RenameNetwork(net.Name, tc.newName) 466 467 // then 468 require.ErrorIs(tt, err, tc.err) 469 vgtest.AssertNoFile(tt, s.GetNetworkPath(tc.newName)) 470 }) 471 } 472 } 473 474 func initialiseFromPath(t *testing.T, vegaHome paths.Paths) *v1.FileStore { 475 t.Helper() 476 s, err := v1.InitialiseStore(vegaHome) 477 if err != nil { 478 t.Fatalf("couldn't initialise store: %v", err) 479 } 480 return s 481 } 482 483 func newVegaHome(t *testing.T) *paths.CustomPaths { 484 t.Helper() 485 return &paths.CustomPaths{CustomHome: t.TempDir()} 486 } 487 488 func networksHome(t *testing.T, vegaHome *paths.CustomPaths) string { 489 t.Helper() 490 return vegaHome.ConfigPathFor(paths.WalletServiceNetworksConfigHome) 491 } 492 493 func networkPath(t *testing.T, vegaHome *paths.CustomPaths, name string) string { 494 t.Helper() 495 return filepath.Join(networksHome(t, vegaHome), name+".toml") 496 }