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