OLD | NEW |
1 // Copyright 2015 The LUCI Authors. All rights reserved. | 1 // Copyright 2015 The LUCI Authors. All rights reserved. |
2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
4 | 4 |
5 package memory | 5 package memory |
6 | 6 |
7 import ( | 7 import ( |
8 "errors" | 8 "errors" |
| 9 "flag" |
9 "fmt" | 10 "fmt" |
| 11 "runtime" |
10 "testing" | 12 "testing" |
11 "time" | 13 "time" |
12 | 14 |
13 ds "github.com/luci/gae/service/datastore" | 15 ds "github.com/luci/gae/service/datastore" |
14 "github.com/luci/gae/service/datastore/serialize" | 16 "github.com/luci/gae/service/datastore/serialize" |
15 infoS "github.com/luci/gae/service/info" | 17 infoS "github.com/luci/gae/service/info" |
16 | 18 |
17 "golang.org/x/net/context" | 19 "golang.org/x/net/context" |
18 | 20 |
19 . "github.com/luci/luci-go/common/testing/assertions" | 21 . "github.com/luci/luci-go/common/testing/assertions" |
20 . "github.com/smartystreets/goconvey/convey" | 22 . "github.com/smartystreets/goconvey/convey" |
21 ) | 23 ) |
22 | 24 |
| 25 var enableMemoryTest = flag.Bool("test.memusage", false, "Enable memory usage te
st.") |
| 26 |
23 type MetaGroup struct { | 27 type MetaGroup struct { |
24 _id int64 `gae:"$id,1"` | 28 _id int64 `gae:"$id,1"` |
25 _kind string `gae:"$kind,__entity_group__"` | 29 _kind string `gae:"$kind,__entity_group__"` |
26 Parent *ds.Key `gae:"$parent"` | 30 Parent *ds.Key `gae:"$parent"` |
27 | 31 |
28 Version int64 `gae:"__version__"` | 32 Version int64 `gae:"__version__"` |
29 } | 33 } |
30 | 34 |
31 func testGetMeta(c context.Context, k *ds.Key) int64 { | 35 func testGetMeta(c context.Context, k *ds.Key) int64 { |
32 mg := &MetaGroup{Parent: k.Root()} | 36 mg := &MetaGroup{Parent: k.Root()} |
(...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
808 // Add "foos" to a new namespace, then confirm that it g
ets indexed. | 812 // Add "foos" to a new namespace, then confirm that it g
ets indexed. |
809 So(ds.Put(infoS.MustNamespace(ctx, "qux"), foos), Should
BeNil) | 813 So(ds.Put(infoS.MustNamespace(ctx, "qux"), foos), Should
BeNil) |
810 ds.GetTestable(ctx).CatchupIndexes() | 814 ds.GetTestable(ctx).CatchupIndexes() |
811 | 815 |
812 results = nil | 816 results = nil |
813 So(ds.GetAll(infoS.MustNamespace(ctx, "qux"), q, &result
s), ShouldBeNil) | 817 So(ds.GetAll(infoS.MustNamespace(ctx, "qux"), q, &result
s), ShouldBeNil) |
814 So(len(results), ShouldEqual, 2) | 818 So(len(results), ShouldEqual, 2) |
815 }) | 819 }) |
816 }) | 820 }) |
817 } | 821 } |
| 822 |
| 823 // TestMemoryUsage performs a series of datastore operations, profiling the |
| 824 // memory usage before and after. |
| 825 // |
| 826 // This is an expensive test, and it's not really sufficiently deterministic to |
| 827 // be enabled by default. If you want to run this, use the '-test.memusage' |
| 828 // flag. |
| 829 func TestMemoryUsage(t *testing.T) { |
| 830 if !*enableMemoryTest { |
| 831 return |
| 832 } |
| 833 |
| 834 Convey("A datastore instance does not leak memory.", t, func() { |
| 835 const rounds, items = 10, 200 |
| 836 |
| 837 // Initial memory stats. |
| 838 var ms runtime.MemStats |
| 839 runtime.MemProfileRate = 1 |
| 840 runtime.GC() |
| 841 runtime.ReadMemStats(&ms) |
| 842 initialAlloc := ms.Alloc |
| 843 |
| 844 // Run the memory test entirely within its own function scope. T
his will |
| 845 // provide a hard boundary where all associated resources should
be |
| 846 // free-able. |
| 847 func() { |
| 848 c := Use(context.Background()) |
| 849 for i := 0; i < rounds; i++ { |
| 850 toPut := make([]ds.PropertyMap, items) |
| 851 for j := range toPut { |
| 852 toPut[j] = ds.PropertyMap{ |
| 853 "$kind": ds.MkProperty(fmt.Sprin
tf("kind-%d", j)), |
| 854 "$id": ds.MkProperty(1), |
| 855 } |
| 856 } |
| 857 if err := ds.Put(c, toPut); err != nil { |
| 858 panic(err) |
| 859 } |
| 860 |
| 861 runtime.GC() |
| 862 } |
| 863 }() |
| 864 |
| 865 for i := 0; i < 3; i++ { |
| 866 time.Sleep(100 * time.Millisecond) |
| 867 runtime.GC() |
| 868 } |
| 869 runtime.ReadMemStats(&ms) |
| 870 |
| 871 t.Logf("Memory alloc difference is: %d", ms.Alloc-initialAlloc) |
| 872 }) |
| 873 } |
OLD | NEW |