github.com/daaku/docker@v1.5.0/pkg/graphdb/graphdb_test.go (about)

     1  package graphdb
     2  
     3  import (
     4  	"database/sql"
     5  	"fmt"
     6  	"os"
     7  	"path"
     8  	"strconv"
     9  	"testing"
    10  
    11  	_ "code.google.com/p/gosqlite/sqlite3"
    12  )
    13  
    14  func newTestDb(t *testing.T) (*Database, string) {
    15  	p := path.Join(os.TempDir(), "sqlite.db")
    16  	conn, err := sql.Open("sqlite3", p)
    17  	db, err := NewDatabase(conn)
    18  	if err != nil {
    19  		t.Fatal(err)
    20  	}
    21  	return db, p
    22  }
    23  
    24  func destroyTestDb(dbPath string) {
    25  	os.Remove(dbPath)
    26  }
    27  
    28  func TestNewDatabase(t *testing.T) {
    29  	db, dbpath := newTestDb(t)
    30  	if db == nil {
    31  		t.Fatal("Database should not be nil")
    32  	}
    33  	db.Close()
    34  	defer destroyTestDb(dbpath)
    35  }
    36  
    37  func TestCreateRootEntity(t *testing.T) {
    38  	db, dbpath := newTestDb(t)
    39  	defer destroyTestDb(dbpath)
    40  	root := db.RootEntity()
    41  	if root == nil {
    42  		t.Fatal("Root entity should not be nil")
    43  	}
    44  }
    45  
    46  func TestGetRootEntity(t *testing.T) {
    47  	db, dbpath := newTestDb(t)
    48  	defer destroyTestDb(dbpath)
    49  
    50  	e := db.Get("/")
    51  	if e == nil {
    52  		t.Fatal("Entity should not be nil")
    53  	}
    54  	if e.ID() != "0" {
    55  		t.Fatalf("Enity id should be 0, got %s", e.ID())
    56  	}
    57  }
    58  
    59  func TestSetEntityWithDifferentName(t *testing.T) {
    60  	db, dbpath := newTestDb(t)
    61  	defer destroyTestDb(dbpath)
    62  
    63  	db.Set("/test", "1")
    64  	if _, err := db.Set("/other", "1"); err != nil {
    65  		t.Fatal(err)
    66  	}
    67  }
    68  
    69  func TestSetDuplicateEntity(t *testing.T) {
    70  	db, dbpath := newTestDb(t)
    71  	defer destroyTestDb(dbpath)
    72  
    73  	if _, err := db.Set("/foo", "42"); err != nil {
    74  		t.Fatal(err)
    75  	}
    76  	if _, err := db.Set("/foo", "43"); err == nil {
    77  		t.Fatalf("Creating an entry with a duplciate path did not cause an error")
    78  	}
    79  }
    80  
    81  func TestCreateChild(t *testing.T) {
    82  	db, dbpath := newTestDb(t)
    83  	defer destroyTestDb(dbpath)
    84  
    85  	child, err := db.Set("/db", "1")
    86  	if err != nil {
    87  		t.Fatal(err)
    88  	}
    89  	if child == nil {
    90  		t.Fatal("Child should not be nil")
    91  	}
    92  	if child.ID() != "1" {
    93  		t.Fail()
    94  	}
    95  }
    96  
    97  func TestParents(t *testing.T) {
    98  	db, dbpath := newTestDb(t)
    99  	defer destroyTestDb(dbpath)
   100  
   101  	for i := 1; i < 6; i++ {
   102  		a := strconv.Itoa(i)
   103  		if _, err := db.Set("/"+a, a); err != nil {
   104  			t.Fatal(err)
   105  		}
   106  	}
   107  
   108  	for i := 6; i < 11; i++ {
   109  		a := strconv.Itoa(i)
   110  		p := strconv.Itoa(i - 5)
   111  
   112  		key := fmt.Sprintf("/%s/%s", p, a)
   113  
   114  		if _, err := db.Set(key, a); err != nil {
   115  			t.Fatal(err)
   116  		}
   117  
   118  		parents, err := db.Parents(key)
   119  		if err != nil {
   120  			t.Fatal(err)
   121  		}
   122  
   123  		if len(parents) != 1 {
   124  			t.Fatalf("Expected 2 entries for %s got %d", key, len(parents))
   125  		}
   126  
   127  		if parents[0] != p {
   128  			t.Fatalf("ID %s received, %s expected", parents[0], p)
   129  		}
   130  	}
   131  }
   132  
   133  func TestChildren(t *testing.T) {
   134  	db, dbpath := newTestDb(t)
   135  	defer destroyTestDb(dbpath)
   136  
   137  	str := "/"
   138  	for i := 1; i < 6; i++ {
   139  		a := strconv.Itoa(i)
   140  		if _, err := db.Set(str+a, a); err != nil {
   141  			t.Fatal(err)
   142  		}
   143  
   144  		str = str + a + "/"
   145  	}
   146  
   147  	str = "/"
   148  	for i := 10; i < 30; i++ { // 20 entities
   149  		a := strconv.Itoa(i)
   150  		if _, err := db.Set(str+a, a); err != nil {
   151  			t.Fatal(err)
   152  		}
   153  
   154  		str = str + a + "/"
   155  	}
   156  	entries, err := db.Children("/", 5)
   157  	if err != nil {
   158  		t.Fatal(err)
   159  	}
   160  
   161  	if len(entries) != 11 {
   162  		t.Fatalf("Expect 11 entries for / got %d", len(entries))
   163  	}
   164  
   165  	entries, err = db.Children("/", 20)
   166  	if err != nil {
   167  		t.Fatal(err)
   168  	}
   169  
   170  	if len(entries) != 25 {
   171  		t.Fatalf("Expect 25 entries for / got %d", len(entries))
   172  	}
   173  }
   174  
   175  func TestListAllRootChildren(t *testing.T) {
   176  	db, dbpath := newTestDb(t)
   177  	defer destroyTestDb(dbpath)
   178  
   179  	for i := 1; i < 6; i++ {
   180  		a := strconv.Itoa(i)
   181  		if _, err := db.Set("/"+a, a); err != nil {
   182  			t.Fatal(err)
   183  		}
   184  	}
   185  	entries := db.List("/", -1)
   186  	if len(entries) != 5 {
   187  		t.Fatalf("Expect 5 entries for / got %d", len(entries))
   188  	}
   189  }
   190  
   191  func TestListAllSubChildren(t *testing.T) {
   192  	db, dbpath := newTestDb(t)
   193  	defer destroyTestDb(dbpath)
   194  
   195  	_, err := db.Set("/webapp", "1")
   196  	if err != nil {
   197  		t.Fatal(err)
   198  	}
   199  	child2, err := db.Set("/db", "2")
   200  	if err != nil {
   201  		t.Fatal(err)
   202  	}
   203  	child4, err := db.Set("/logs", "4")
   204  	if err != nil {
   205  		t.Fatal(err)
   206  	}
   207  	if _, err := db.Set("/db/logs", child4.ID()); err != nil {
   208  		t.Fatal(err)
   209  	}
   210  
   211  	child3, err := db.Set("/sentry", "3")
   212  	if err != nil {
   213  		t.Fatal(err)
   214  	}
   215  	if _, err := db.Set("/webapp/sentry", child3.ID()); err != nil {
   216  		t.Fatal(err)
   217  	}
   218  	if _, err := db.Set("/webapp/db", child2.ID()); err != nil {
   219  		t.Fatal(err)
   220  	}
   221  
   222  	entries := db.List("/webapp", 1)
   223  	if len(entries) != 3 {
   224  		t.Fatalf("Expect 3 entries for / got %d", len(entries))
   225  	}
   226  
   227  	entries = db.List("/webapp", 0)
   228  	if len(entries) != 2 {
   229  		t.Fatalf("Expect 2 entries for / got %d", len(entries))
   230  	}
   231  }
   232  
   233  func TestAddSelfAsChild(t *testing.T) {
   234  	db, dbpath := newTestDb(t)
   235  	defer destroyTestDb(dbpath)
   236  
   237  	child, err := db.Set("/test", "1")
   238  	if err != nil {
   239  		t.Fatal(err)
   240  	}
   241  	if _, err := db.Set("/test/other", child.ID()); err == nil {
   242  		t.Fatal("Error should not be nil")
   243  	}
   244  }
   245  
   246  func TestAddChildToNonExistantRoot(t *testing.T) {
   247  	db, dbpath := newTestDb(t)
   248  	defer destroyTestDb(dbpath)
   249  
   250  	if _, err := db.Set("/myapp", "1"); err != nil {
   251  		t.Fatal(err)
   252  	}
   253  
   254  	if _, err := db.Set("/myapp/proxy/db", "2"); err == nil {
   255  		t.Fatal("Error should not be nil")
   256  	}
   257  }
   258  
   259  func TestWalkAll(t *testing.T) {
   260  	db, dbpath := newTestDb(t)
   261  	defer destroyTestDb(dbpath)
   262  	_, err := db.Set("/webapp", "1")
   263  	if err != nil {
   264  		t.Fatal(err)
   265  	}
   266  	child2, err := db.Set("/db", "2")
   267  	if err != nil {
   268  		t.Fatal(err)
   269  	}
   270  	child4, err := db.Set("/db/logs", "4")
   271  	if err != nil {
   272  		t.Fatal(err)
   273  	}
   274  	if _, err := db.Set("/webapp/logs", child4.ID()); err != nil {
   275  		t.Fatal(err)
   276  	}
   277  
   278  	child3, err := db.Set("/sentry", "3")
   279  	if err != nil {
   280  		t.Fatal(err)
   281  	}
   282  	if _, err := db.Set("/webapp/sentry", child3.ID()); err != nil {
   283  		t.Fatal(err)
   284  	}
   285  	if _, err := db.Set("/webapp/db", child2.ID()); err != nil {
   286  		t.Fatal(err)
   287  	}
   288  
   289  	child5, err := db.Set("/gograph", "5")
   290  	if err != nil {
   291  		t.Fatal(err)
   292  	}
   293  	if _, err := db.Set("/webapp/same-ref-diff-name", child5.ID()); err != nil {
   294  		t.Fatal(err)
   295  	}
   296  
   297  	if err := db.Walk("/", func(p string, e *Entity) error {
   298  		t.Logf("Path: %s Entity: %s", p, e.ID())
   299  		return nil
   300  	}, -1); err != nil {
   301  		t.Fatal(err)
   302  	}
   303  }
   304  
   305  func TestGetEntityByPath(t *testing.T) {
   306  	db, dbpath := newTestDb(t)
   307  	defer destroyTestDb(dbpath)
   308  	_, err := db.Set("/webapp", "1")
   309  	if err != nil {
   310  		t.Fatal(err)
   311  	}
   312  	child2, err := db.Set("/db", "2")
   313  	if err != nil {
   314  		t.Fatal(err)
   315  	}
   316  	child4, err := db.Set("/logs", "4")
   317  	if err != nil {
   318  		t.Fatal(err)
   319  	}
   320  	if _, err := db.Set("/db/logs", child4.ID()); err != nil {
   321  		t.Fatal(err)
   322  	}
   323  
   324  	child3, err := db.Set("/sentry", "3")
   325  	if err != nil {
   326  		t.Fatal(err)
   327  	}
   328  	if _, err := db.Set("/webapp/sentry", child3.ID()); err != nil {
   329  		t.Fatal(err)
   330  	}
   331  	if _, err := db.Set("/webapp/db", child2.ID()); err != nil {
   332  		t.Fatal(err)
   333  	}
   334  
   335  	child5, err := db.Set("/gograph", "5")
   336  	if err != nil {
   337  		t.Fatal(err)
   338  	}
   339  	if _, err := db.Set("/webapp/same-ref-diff-name", child5.ID()); err != nil {
   340  		t.Fatal(err)
   341  	}
   342  
   343  	entity := db.Get("/webapp/db/logs")
   344  	if entity == nil {
   345  		t.Fatal("Entity should not be nil")
   346  	}
   347  	if entity.ID() != "4" {
   348  		t.Fatalf("Expected to get entity with id 4, got %s", entity.ID())
   349  	}
   350  }
   351  
   352  func TestEnitiesPaths(t *testing.T) {
   353  	db, dbpath := newTestDb(t)
   354  	defer destroyTestDb(dbpath)
   355  	_, err := db.Set("/webapp", "1")
   356  	if err != nil {
   357  		t.Fatal(err)
   358  	}
   359  	child2, err := db.Set("/db", "2")
   360  	if err != nil {
   361  		t.Fatal(err)
   362  	}
   363  	child4, err := db.Set("/logs", "4")
   364  	if err != nil {
   365  		t.Fatal(err)
   366  	}
   367  	if _, err := db.Set("/db/logs", child4.ID()); err != nil {
   368  		t.Fatal(err)
   369  	}
   370  
   371  	child3, err := db.Set("/sentry", "3")
   372  	if err != nil {
   373  		t.Fatal(err)
   374  	}
   375  	if _, err := db.Set("/webapp/sentry", child3.ID()); err != nil {
   376  		t.Fatal(err)
   377  	}
   378  	if _, err := db.Set("/webapp/db", child2.ID()); err != nil {
   379  		t.Fatal(err)
   380  	}
   381  
   382  	child5, err := db.Set("/gograph", "5")
   383  	if err != nil {
   384  		t.Fatal(err)
   385  	}
   386  	if _, err := db.Set("/webapp/same-ref-diff-name", child5.ID()); err != nil {
   387  		t.Fatal(err)
   388  	}
   389  
   390  	out := db.List("/", -1)
   391  	for _, p := range out.Paths() {
   392  		t.Log(p)
   393  	}
   394  }
   395  
   396  func TestDeleteRootEntity(t *testing.T) {
   397  	db, dbpath := newTestDb(t)
   398  	defer destroyTestDb(dbpath)
   399  
   400  	if err := db.Delete("/"); err == nil {
   401  		t.Fatal("Error should not be nil")
   402  	}
   403  }
   404  
   405  func TestDeleteEntity(t *testing.T) {
   406  	db, dbpath := newTestDb(t)
   407  	defer destroyTestDb(dbpath)
   408  	_, err := db.Set("/webapp", "1")
   409  	if err != nil {
   410  		t.Fatal(err)
   411  	}
   412  	child2, err := db.Set("/db", "2")
   413  	if err != nil {
   414  		t.Fatal(err)
   415  	}
   416  	child4, err := db.Set("/logs", "4")
   417  	if err != nil {
   418  		t.Fatal(err)
   419  	}
   420  	if _, err := db.Set("/db/logs", child4.ID()); err != nil {
   421  		t.Fatal(err)
   422  	}
   423  
   424  	child3, err := db.Set("/sentry", "3")
   425  	if err != nil {
   426  		t.Fatal(err)
   427  	}
   428  	if _, err := db.Set("/webapp/sentry", child3.ID()); err != nil {
   429  		t.Fatal(err)
   430  	}
   431  	if _, err := db.Set("/webapp/db", child2.ID()); err != nil {
   432  		t.Fatal(err)
   433  	}
   434  
   435  	child5, err := db.Set("/gograph", "5")
   436  	if err != nil {
   437  		t.Fatal(err)
   438  	}
   439  	if _, err := db.Set("/webapp/same-ref-diff-name", child5.ID()); err != nil {
   440  		t.Fatal(err)
   441  	}
   442  
   443  	if err := db.Delete("/webapp/sentry"); err != nil {
   444  		t.Fatal(err)
   445  	}
   446  	entity := db.Get("/webapp/sentry")
   447  	if entity != nil {
   448  		t.Fatal("Entity /webapp/sentry should be nil")
   449  	}
   450  }
   451  
   452  func TestCountRefs(t *testing.T) {
   453  	db, dbpath := newTestDb(t)
   454  	defer destroyTestDb(dbpath)
   455  
   456  	db.Set("/webapp", "1")
   457  
   458  	if db.Refs("1") != 1 {
   459  		t.Fatal("Expect reference count to be 1")
   460  	}
   461  
   462  	db.Set("/db", "2")
   463  	db.Set("/webapp/db", "2")
   464  	if db.Refs("2") != 2 {
   465  		t.Fatal("Expect reference count to be 2")
   466  	}
   467  }
   468  
   469  func TestPurgeId(t *testing.T) {
   470  	db, dbpath := newTestDb(t)
   471  	defer destroyTestDb(dbpath)
   472  
   473  	db.Set("/webapp", "1")
   474  
   475  	if db.Refs("1") != 1 {
   476  		t.Fatal("Expect reference count to be 1")
   477  	}
   478  
   479  	db.Set("/db", "2")
   480  	db.Set("/webapp/db", "2")
   481  
   482  	count, err := db.Purge("2")
   483  	if err != nil {
   484  		t.Fatal(err)
   485  	}
   486  	if count != 2 {
   487  		t.Fatal("Expected 2 references to be removed")
   488  	}
   489  }
   490  
   491  func TestRename(t *testing.T) {
   492  	db, dbpath := newTestDb(t)
   493  	defer destroyTestDb(dbpath)
   494  
   495  	db.Set("/webapp", "1")
   496  
   497  	if db.Refs("1") != 1 {
   498  		t.Fatal("Expect reference count to be 1")
   499  	}
   500  
   501  	db.Set("/db", "2")
   502  	db.Set("/webapp/db", "2")
   503  
   504  	if db.Get("/webapp/db") == nil {
   505  		t.Fatal("Cannot find entity at path /webapp/db")
   506  	}
   507  
   508  	if err := db.Rename("/webapp/db", "/webapp/newdb"); err != nil {
   509  		t.Fatal(err)
   510  	}
   511  	if db.Get("/webapp/db") != nil {
   512  		t.Fatal("Entity should not exist at /webapp/db")
   513  	}
   514  	if db.Get("/webapp/newdb") == nil {
   515  		t.Fatal("Cannot find entity at path /webapp/newdb")
   516  	}
   517  
   518  }
   519  
   520  func TestCreateMultipleNames(t *testing.T) {
   521  	db, dbpath := newTestDb(t)
   522  	defer destroyTestDb(dbpath)
   523  
   524  	db.Set("/db", "1")
   525  	if _, err := db.Set("/myapp", "1"); err != nil {
   526  		t.Fatal(err)
   527  	}
   528  
   529  	db.Walk("/", func(p string, e *Entity) error {
   530  		t.Logf("%s\n", p)
   531  		return nil
   532  	}, -1)
   533  }
   534  
   535  func TestRefPaths(t *testing.T) {
   536  	db, dbpath := newTestDb(t)
   537  	defer destroyTestDb(dbpath)
   538  
   539  	db.Set("/webapp", "1")
   540  
   541  	db.Set("/db", "2")
   542  	db.Set("/webapp/db", "2")
   543  
   544  	refs := db.RefPaths("2")
   545  	if len(refs) != 2 {
   546  		t.Fatalf("Expected reference count to be 2, got %d", len(refs))
   547  	}
   548  }
   549  
   550  func TestExistsTrue(t *testing.T) {
   551  	db, dbpath := newTestDb(t)
   552  	defer destroyTestDb(dbpath)
   553  
   554  	db.Set("/testing", "1")
   555  
   556  	if !db.Exists("/testing") {
   557  		t.Fatalf("/tesing should exist")
   558  	}
   559  }
   560  
   561  func TestExistsFalse(t *testing.T) {
   562  	db, dbpath := newTestDb(t)
   563  	defer destroyTestDb(dbpath)
   564  
   565  	db.Set("/toerhe", "1")
   566  
   567  	if db.Exists("/testing") {
   568  		t.Fatalf("/tesing should not exist")
   569  	}
   570  
   571  }
   572  
   573  func TestGetNameWithTrailingSlash(t *testing.T) {
   574  	db, dbpath := newTestDb(t)
   575  	defer destroyTestDb(dbpath)
   576  
   577  	db.Set("/todo", "1")
   578  
   579  	e := db.Get("/todo/")
   580  	if e == nil {
   581  		t.Fatalf("Entity should not be nil")
   582  	}
   583  }
   584  
   585  func TestConcurrentWrites(t *testing.T) {
   586  	db, dbpath := newTestDb(t)
   587  	defer destroyTestDb(dbpath)
   588  
   589  	errs := make(chan error, 2)
   590  
   591  	save := func(name string, id string) {
   592  		if _, err := db.Set(fmt.Sprintf("/%s", name), id); err != nil {
   593  			errs <- err
   594  		}
   595  		errs <- nil
   596  	}
   597  	purge := func(id string) {
   598  		if _, err := db.Purge(id); err != nil {
   599  			errs <- err
   600  		}
   601  		errs <- nil
   602  	}
   603  
   604  	save("/1", "1")
   605  
   606  	go purge("1")
   607  	go save("/2", "2")
   608  
   609  	any := false
   610  	for i := 0; i < 2; i++ {
   611  		if err := <-errs; err != nil {
   612  			any = true
   613  			t.Log(err)
   614  		}
   615  	}
   616  	if any {
   617  		t.Fail()
   618  	}
   619  }