grpc_client_test.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /*
  2. Copyright © The ESO Authors
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. https://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package mysterybox
  14. import (
  15. "bytes"
  16. "context"
  17. "errors"
  18. "testing"
  19. mbox "github.com/nebius/gosdk/proto/nebius/mysterybox/v1"
  20. tassert "github.com/stretchr/testify/assert"
  21. "github.com/stretchr/testify/require"
  22. "google.golang.org/grpc"
  23. )
  24. const (
  25. defaultVersion = "version1"
  26. alternativeVersion = "version2"
  27. notFoundError = "not found"
  28. )
  29. type FakePayloadService struct {
  30. data map[string]map[string]*mbox.SecretPayload
  31. }
  32. func (f *FakePayloadService) Get(_ context.Context, r *mbox.GetPayloadRequest, _ ...grpc.CallOption) (*mbox.SecretPayload, error) {
  33. version := extractVersionFromRequest(r.VersionId)
  34. val, ok := f.data[r.GetSecretId()][version]
  35. if !ok {
  36. return nil, errors.New("secret not found")
  37. }
  38. return val, nil
  39. }
  40. func (f *FakePayloadService) GetByKey(_ context.Context, r *mbox.GetPayloadByKeyRequest, _ ...grpc.CallOption) (*mbox.SecretPayloadEntry, error) {
  41. version := extractVersionFromRequest(r.VersionId)
  42. payload, ok := f.data[r.GetSecretId()][version]
  43. if !ok {
  44. return nil, errors.New("secret not found")
  45. }
  46. for _, p := range payload.GetData() {
  47. if p.Key == r.GetKey() {
  48. return &mbox.SecretPayloadEntry{VersionId: payload.VersionId, Data: &mbox.Payload{Key: p.Key, Payload: p.Payload}}, nil
  49. }
  50. }
  51. return nil, errors.New(notFoundError)
  52. }
  53. func InitFakePayloadService() *FakePayloadService {
  54. mysteryboxData := map[string]map[string]*mbox.SecretPayload{}
  55. mysteryboxData["secret1Id"] = make(map[string]*mbox.SecretPayload)
  56. mysteryboxData["secret1Id"][defaultVersion] = &mbox.SecretPayload{
  57. VersionId: defaultVersion,
  58. Data: []*mbox.Payload{
  59. {
  60. Key: "key1",
  61. Payload: &mbox.Payload_StringValue{StringValue: "test string secret"},
  62. }, {
  63. Key: "key2",
  64. Payload: &mbox.Payload_BinaryValue{BinaryValue: []byte("test byte secret")},
  65. },
  66. },
  67. }
  68. mysteryboxData["secret2Id"] = make(map[string]*mbox.SecretPayload)
  69. mysteryboxData["secret2Id"][defaultVersion] = &mbox.SecretPayload{
  70. VersionId: defaultVersion,
  71. Data: []*mbox.Payload{
  72. {
  73. Key: "key3",
  74. Payload: &mbox.Payload_StringValue{StringValue: "test string secret"},
  75. },
  76. },
  77. }
  78. mysteryboxData["secret2Id"][alternativeVersion] = &mbox.SecretPayload{
  79. VersionId: alternativeVersion,
  80. Data: []*mbox.Payload{
  81. {
  82. Key: "key3",
  83. Payload: &mbox.Payload_StringValue{StringValue: "test string secret alternative"},
  84. },
  85. },
  86. }
  87. return &FakePayloadService{
  88. data: mysteryboxData,
  89. }
  90. }
  91. func TestGetSecret(t *testing.T) {
  92. t.Parallel()
  93. client := &GrpcClient{PayloadService: InitFakePayloadService()}
  94. tests := []struct {
  95. name string
  96. secretID string
  97. expected map[string][]byte
  98. version string
  99. wantErr string
  100. }{
  101. {
  102. name: "Get secret's payload",
  103. secretID: "secret1Id",
  104. expected: map[string][]byte{
  105. "key1": []byte("test string secret"),
  106. "key2": []byte("test byte secret"),
  107. }},
  108. {
  109. name: "Get secret's payload by version",
  110. secretID: "secret2Id",
  111. expected: map[string][]byte{
  112. "key3": []byte("test string secret alternative"),
  113. },
  114. version: alternativeVersion,
  115. },
  116. {
  117. name: "Get secret's payload by version not found",
  118. secretID: "secret2Id",
  119. wantErr: notFoundError,
  120. version: "another-version",
  121. },
  122. {
  123. name: "Not found secret",
  124. secretID: "nope",
  125. wantErr: notFoundError,
  126. },
  127. }
  128. for _, tt := range tests {
  129. t.Run(tt.name, func(t *testing.T) {
  130. t.Parallel()
  131. payload, err := client.GetSecret(context.Background(), "token", tt.secretID, tt.version)
  132. if tt.wantErr != "" {
  133. tassert.Error(t, err)
  134. tassert.Contains(t, err.Error(), tt.wantErr)
  135. return
  136. }
  137. require.NoError(t, err)
  138. if tt.version == "" {
  139. tassert.Equal(t, defaultVersion, payload.VersionID, "Payload version must be default")
  140. } else {
  141. tassert.Equal(t, tt.version, payload.VersionID)
  142. }
  143. expected := make(map[string][]byte, len(tt.expected))
  144. for k, v := range tt.expected {
  145. expected[k] = v
  146. }
  147. tassert.Equal(t, len(payload.Entries), len(expected))
  148. for _, entry := range payload.Entries {
  149. value, _ := expected[entry.Key]
  150. if (entry.BinaryValue != nil && bytes.Equal(value, entry.BinaryValue)) || (entry.StringValue != "" && bytes.Equal(value, []byte(entry.StringValue))) {
  151. delete(expected, entry.Key)
  152. continue
  153. }
  154. }
  155. tassert.Empty(t, expected, "not all expected entries found: %+v", expected)
  156. })
  157. }
  158. }
  159. func TestGetSecretByKey(t *testing.T) {
  160. t.Parallel()
  161. client := &GrpcClient{PayloadService: InitFakePayloadService()}
  162. tests := []struct {
  163. name string
  164. secretID string
  165. key string
  166. wantStr string
  167. wantBin []byte
  168. wantErr string
  169. }{
  170. {name: "Get secret's string payload", secretID: "secret1Id", key: "key1", wantStr: "test string secret"},
  171. {name: "Get secret's binary payload", secretID: "secret1Id", key: "key2", wantBin: []byte("test byte secret")},
  172. {name: "Not found key", secretID: "secret1Id", key: "missing", wantErr: notFoundError},
  173. {name: "Not found secret", secretID: "nope", key: "any", wantErr: notFoundError},
  174. }
  175. for _, tt := range tests {
  176. t.Run(tt.name, func(t *testing.T) {
  177. t.Parallel()
  178. payload, err := client.GetSecretByKey(context.Background(), "token", tt.secretID, "", tt.key)
  179. if tt.wantErr != "" {
  180. tassert.Error(t, err)
  181. tassert.Contains(t, err.Error(), tt.wantErr)
  182. return
  183. }
  184. require.NoError(t, err)
  185. require.NotNil(t, payload)
  186. require.NotNil(t, payload.Entry)
  187. if tt.wantStr != "" {
  188. tassert.Nil(t, payload.Entry.BinaryValue)
  189. tassert.Equal(t, tt.wantStr, payload.Entry.StringValue)
  190. }
  191. if tt.wantBin != nil {
  192. tassert.Empty(t, payload.Entry.StringValue)
  193. tassert.Equal(t, tt.wantBin, payload.Entry.BinaryValue)
  194. }
  195. })
  196. }
  197. }
  198. func extractVersionFromRequest(requestVersion string) string {
  199. if requestVersion == "" {
  200. return defaultVersion
  201. }
  202. return requestVersion
  203. }