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  }