github.com/voedger/voedger@v0.0.0-20240520144910-273e84102129/pkg/istructsmem/internal/containers/impl_test.go (about) 1 /* 2 * Copyright (c) 2021-present Sigma-Soft, Ltd. 3 * @author: Nikolay Nikitin 4 */ 5 6 package containers 7 8 import ( 9 "errors" 10 "fmt" 11 "testing" 12 13 "github.com/stretchr/testify/require" 14 15 "github.com/voedger/voedger/pkg/appdef" 16 "github.com/voedger/voedger/pkg/istorage/mem" 17 istorageimpl "github.com/voedger/voedger/pkg/istorage/provider" 18 "github.com/voedger/voedger/pkg/istructs" 19 "github.com/voedger/voedger/pkg/istructsmem/internal/consts" 20 "github.com/voedger/voedger/pkg/istructsmem/internal/teststore" 21 "github.com/voedger/voedger/pkg/istructsmem/internal/utils" 22 "github.com/voedger/voedger/pkg/istructsmem/internal/vers" 23 ) 24 25 func TestContainers(t *testing.T) { 26 require := require.New(t) 27 28 sp := istorageimpl.Provide(mem.Provide()) 29 storage, err := sp.AppStorage(istructs.AppQName_test1_app1) 30 require.NoError(err) 31 32 versions := vers.New() 33 if err := versions.Prepare(storage); err != nil { 34 panic(err) 35 } 36 37 containerName := "test" 38 39 containers := New() 40 if err := containers.Prepare(storage, versions, 41 func() appdef.IAppDef { 42 objName := appdef.NewQName("test", "object") 43 adb := appdef.New() 44 adb.AddPackage("test", "test.com/test") 45 adb.AddObject(objName). 46 AddContainer(containerName, objName, 0, 1) 47 result, err := adb.Build() 48 require.NoError(err) 49 return result 50 }()); err != nil { 51 panic(err) 52 } 53 54 t.Run("basic Containers methods", func(t *testing.T) { 55 56 check := func(containers *Containers, name string) ContainerID { 57 id, err := containers.ID(name) 58 require.NoError(err) 59 require.NotEqual(NullContainerID, id) 60 61 n, err := containers.Container(id) 62 require.NoError(err) 63 require.Equal(name, n) 64 65 return id 66 } 67 68 id := check(containers, containerName) 69 70 t.Run("must be ok to load early stored names", func(t *testing.T) { 71 versions1 := vers.New() 72 if err := versions1.Prepare(storage); err != nil { 73 panic(err) 74 } 75 76 containers1 := New() 77 if err := containers1.Prepare(storage, versions, nil); err != nil { 78 panic(err) 79 } 80 81 require.Equal(id, check(containers1, containerName)) 82 }) 83 84 t.Run("must be ok to redeclare containers", func(t *testing.T) { 85 versions2 := vers.New() 86 if err := versions2.Prepare(storage); err != nil { 87 panic(err) 88 } 89 90 containers2 := New() 91 if err := containers2.Prepare(storage, versions, 92 func() appdef.IAppDef { 93 objName := appdef.NewQName("test", "object") 94 adb := appdef.New() 95 adb.AddPackage("test", "test.com/test") 96 adb.AddObject(objName). 97 AddContainer(containerName, objName, 0, 1) 98 result, err := adb.Build() 99 require.NoError(err) 100 return result 101 }()); err != nil { 102 panic(err) 103 } 104 105 require.Equal(id, check(containers2, containerName)) 106 }) 107 }) 108 109 t.Run("must be error if unknown container", func(t *testing.T) { 110 id, err := containers.ID("unknown") 111 require.Equal(NullContainerID, id) 112 require.ErrorIs(err, ErrContainerNotFound) 113 }) 114 115 t.Run("must be error if unknown id", func(t *testing.T) { 116 n, err := containers.Container(ContainerID(MaxAvailableContainerID)) 117 require.Equal("", n) 118 require.ErrorIs(err, ErrContainerIDNotFound) 119 }) 120 } 121 122 func TestContainersPrepareErrors(t *testing.T) { 123 require := require.New(t) 124 125 t.Run("must be error if unknown system view version", func(t *testing.T) { 126 sp := istorageimpl.Provide(mem.Provide()) 127 storage, _ := sp.AppStorage(istructs.AppQName_test1_app1) 128 129 versions := vers.New() 130 if err := versions.Prepare(storage); err != nil { 131 panic(err) 132 } 133 134 versions.Put(vers.SysContainersVersion, latestVersion+1) 135 136 names := New() 137 err := names.Prepare(storage, versions, nil) 138 require.ErrorIs(err, vers.ErrorInvalidVersion) 139 }) 140 141 t.Run("must be error if invalid Container loaded from system view ", func(t *testing.T) { 142 sp := istorageimpl.Provide(mem.Provide()) 143 storage, _ := sp.AppStorage(istructs.AppQName_test1_app1) 144 145 versions := vers.New() 146 if err := versions.Prepare(storage); err != nil { 147 panic(err) 148 } 149 150 versions.Put(vers.SysContainersVersion, latestVersion) 151 const badName = "-test-error-name-" 152 storage.Put(utils.ToBytes(consts.SysView_Containers, ver01), []byte(badName), utils.ToBytes(ContainerID(512))) 153 154 names := New() 155 err := names.Prepare(storage, versions, nil) 156 require.ErrorIs(err, appdef.ErrInvalidError) 157 }) 158 159 t.Run("must be ok if deleted Container loaded from system view ", func(t *testing.T) { 160 sp := istorageimpl.Provide(mem.Provide()) 161 storage, _ := sp.AppStorage(istructs.AppQName_test1_app1) 162 163 versions := vers.New() 164 if err := versions.Prepare(storage); err != nil { 165 panic(err) 166 } 167 168 versions.Put(vers.SysContainersVersion, latestVersion) 169 storage.Put(utils.ToBytes(consts.SysView_Containers, ver01), []byte("deleted"), utils.ToBytes(NullContainerID)) 170 171 names := New() 172 err := names.Prepare(storage, versions, nil) 173 require.NoError(err) 174 }) 175 176 t.Run("must be error if invalid (small) ContainerID loaded from system view ", func(t *testing.T) { 177 sp := istorageimpl.Provide(mem.Provide()) 178 storage, _ := sp.AppStorage(istructs.AppQName_test1_app1) 179 180 versions := vers.New() 181 if err := versions.Prepare(storage); err != nil { 182 panic(err) 183 } 184 185 versions.Put(vers.SysContainersVersion, latestVersion) 186 storage.Put(utils.ToBytes(consts.SysView_Containers, ver01), []byte("test"), utils.ToBytes(ContainerID(1))) 187 188 names := New() 189 err := names.Prepare(storage, versions, nil) 190 require.ErrorIs(err, ErrWrongContainerID) 191 }) 192 193 t.Run("must be error if too many Containers", func(t *testing.T) { 194 sp := istorageimpl.Provide(mem.Provide()) 195 storage, _ := sp.AppStorage(istructs.AppQName_test1_app1) 196 197 versions := vers.New() 198 if err := versions.Prepare(storage); err != nil { 199 panic(err) 200 } 201 202 names := New() 203 err := names.Prepare(storage, versions, 204 func() appdef.IAppDef { 205 adb := appdef.New() 206 adb.AddPackage("test", "test.com/test") 207 qName := appdef.NewQName("test", "test") 208 obj := adb.AddObject(qName) 209 for i := 0; i <= MaxAvailableContainerID; i++ { 210 obj.AddContainer(fmt.Sprintf("cont_%d", i), qName, 0, 1) 211 } 212 result, err := adb.Build() 213 require.NoError(err) 214 return result 215 }()) 216 require.ErrorIs(err, ErrContainerIDsExceeds) 217 }) 218 219 t.Run("must be error if write to storage failed", func(t *testing.T) { 220 containerName := "testContainerName" 221 writeError := errors.New("storage write error") 222 223 t.Run("must be error if write some name failed", func(t *testing.T) { 224 storage := teststore.NewStorage() 225 226 versions := vers.New() 227 if err := versions.Prepare(storage); err != nil { 228 panic(err) 229 } 230 231 storage.SchedulePutError(writeError, utils.ToBytes(consts.SysView_Containers, ver01), []byte(containerName)) 232 233 names := New() 234 err := names.Prepare(storage, versions, 235 func() appdef.IAppDef { 236 objName := appdef.NewQName("test", "object") 237 adb := appdef.New() 238 adb.AddPackage("test", "test.com/test") 239 adb.AddObject(objName). 240 AddContainer(containerName, objName, 0, 1) 241 result, err := adb.Build() 242 require.NoError(err) 243 return result 244 }()) 245 require.ErrorIs(err, writeError) 246 }) 247 248 t.Run("must be error if write system view version failed", func(t *testing.T) { 249 storage := teststore.NewStorage() 250 251 versions := vers.New() 252 if err := versions.Prepare(storage); err != nil { 253 panic(err) 254 } 255 256 storage.SchedulePutError(writeError, utils.ToBytes(consts.SysView_Versions), utils.ToBytes(vers.SysContainersVersion)) 257 258 names := New() 259 err := names.Prepare(storage, versions, 260 func() appdef.IAppDef { 261 objName := appdef.NewQName("test", "object") 262 adb := appdef.New() 263 adb.AddPackage("test", "test.com/test") 264 adb.AddObject(objName). 265 AddContainer(containerName, objName, 0, 1) 266 result, err := adb.Build() 267 require.NoError(err) 268 return result 269 }()) 270 require.ErrorIs(err, writeError) 271 }) 272 }) 273 }