go.dedis.ch/onet/v3@v3.2.11-0.20210930124529-e36530bca7ef/context_test.go (about) 1 package onet 2 3 import ( 4 "crypto/sha256" 5 "fmt" 6 "io/ioutil" 7 "os" 8 "path" 9 "strings" 10 "sync" 11 "testing" 12 13 "github.com/stretchr/testify/require" 14 "go.dedis.ch/kyber/v3/util/key" 15 "go.dedis.ch/onet/v3/log" 16 "go.dedis.ch/onet/v3/network" 17 bbolt "go.etcd.io/bbolt" 18 "golang.org/x/xerrors" 19 ) 20 21 type ContextData struct { 22 I int64 23 S string 24 } 25 26 func TestContextSaveLoad(t *testing.T) { 27 tmp, err := ioutil.TempDir("", "conode") 28 defer os.RemoveAll(tmp) 29 os.Setenv("CONODE_SERVICE_PATH", tmp) 30 p := dbPathFromEnv() 31 require.Equal(t, p, tmp) 32 33 nbr := 10 34 c := make([]*Context, nbr) 35 for i := range c { 36 c[i] = createContext(t, p) 37 } 38 39 testSaveFailure(t, c[0]) 40 41 var wg sync.WaitGroup 42 wg.Add(nbr) 43 for i := range c { 44 go func(i int) { 45 // defer insures the call even on a panic 46 defer wg.Done() 47 testLoadSave(t, c[i]) 48 }(i) 49 } 50 wg.Wait() 51 files, err := ioutil.ReadDir(tmp) 52 log.ErrFatal(err) 53 require.False(t, files[0].IsDir()) 54 require.True(t, files[0].Mode().IsRegular()) 55 require.True(t, strings.HasSuffix(files[0].Name(), ".db")) 56 57 v, err := c[0].LoadVersion() 58 require.Nil(t, err) 59 require.Equal(t, 0, v) 60 err = c[0].SaveVersion(1) 61 require.Nil(t, err) 62 v, err = c[0].LoadVersion() 63 require.Nil(t, err) 64 require.Equal(t, 1, v) 65 } 66 67 func testLoadSave(t *testing.T, c *Context) { 68 key := []byte("test") 69 cd := &ContextData{42, "meaning of life"} 70 network.RegisterMessage(ContextData{}) 71 require.Nil(t, c.Save(key, cd)) 72 73 msg, err := c.Load(append(key, byte('_'))) 74 if err != nil || msg != nil { 75 log.Fatal("this should not exist") 76 } 77 cdInt, err := c.Load(key) 78 require.Nil(t, err) 79 cd2, ok := cdInt.(*ContextData) 80 if !ok { 81 log.Fatal("contextData should exist") 82 } 83 84 cdBuf, err := c.LoadRaw(key) 85 require.Nil(t, err) 86 cdBuf2, err := network.Marshal(cd) 87 require.EqualValues(t, cdBuf, cdBuf2) 88 89 if cd.I != cd2.I || cd.S != cd2.S { 90 log.Fatal("stored and loaded data should be equal", cd, cd2) 91 } 92 } 93 94 func testSaveFailure(t *testing.T, c *Context) { 95 key := []byte("test") 96 cd := &ContextData{42, "meaning of life"} 97 // should fail because ContextData is not registered 98 if c.Save(key, cd) == nil { 99 log.Fatal("Save should fail") 100 } 101 } 102 103 func TestContext_GetAdditionalBucket(t *testing.T) { 104 tmp, err := ioutil.TempDir("", "conode") 105 log.ErrFatal(err) 106 defer os.RemoveAll(tmp) 107 108 c := createContext(t, tmp) 109 db, name := c.GetAdditionalBucket([]byte("new")) 110 require.NotNil(t, db) 111 require.Equal(t, "testService_new", string(name)) 112 // Need to accept a second run with an existing bucket 113 db, name = c.GetAdditionalBucket([]byte("new")) 114 require.NotNil(t, db) 115 require.Equal(t, "testService_new", string(name)) 116 } 117 118 func TestContext_Path(t *testing.T) { 119 tmp, err := ioutil.TempDir("", "conode") 120 log.ErrFatal(err) 121 defer os.RemoveAll(tmp) 122 123 c := createContext(t, tmp) 124 pub, _ := c.ServerIdentity().Public.MarshalBinary() 125 h := sha256.New() 126 h.Write(pub) 127 dbPath := path.Join(tmp, fmt.Sprintf("%x.db", h.Sum(nil))) 128 _, err = os.Stat(dbPath) 129 if err != nil { 130 t.Error(err) 131 } 132 os.Remove(dbPath) 133 134 tmp, err = ioutil.TempDir("", "conode") 135 log.ErrFatal(err) 136 defer os.RemoveAll(tmp) 137 138 c = createContext(t, tmp) 139 140 _, err = os.Stat(tmp) 141 log.ErrFatal(err) 142 pub, _ = c.ServerIdentity().Public.MarshalBinary() 143 h = sha256.New() 144 h.Write(pub) 145 _, err = os.Stat(path.Join(tmp, fmt.Sprintf("%x.db", h.Sum(nil)))) 146 log.ErrFatal(err) 147 } 148 149 // createContext creates the minimum number of things required for the test 150 func createContext(t *testing.T, dbPath string) *Context { 151 kp := key.NewKeyPair(tSuite) 152 si := network.NewServerIdentity(kp.Public, 153 network.NewAddress(network.Local, "localhost:0")) 154 cn := &Server{ 155 Router: &network.Router{ 156 ServerIdentity: si, 157 }, 158 } 159 160 name := "testService" 161 RegisterNewService(name, func(c *Context) (Service, error) { 162 return nil, nil 163 }) 164 165 sm := &serviceManager{ 166 server: cn, 167 dbPath: dbPath, 168 } 169 170 db, err := openDb(sm.dbFileName()) 171 require.Nil(t, err) 172 173 err = db.Update(func(tx *bbolt.Tx) error { 174 _, err := tx.CreateBucket([]byte(name)) 175 if err != nil { 176 return xerrors.Errorf("creating bucket: %v", err) 177 } 178 return nil 179 }) 180 require.Nil(t, err) 181 sm.db = db 182 183 return newContext(cn, nil, ServiceFactory.ServiceID(name), sm) 184 }