1// Copyright (C) MongoDB, Inc. 2014-present.
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may
4// not use this file except in compliance with the License. You may obtain
5// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
7package mongorestore
8
9import (
10	"github.com/mongodb/mongo-tools/common/db"
11	"github.com/mongodb/mongo-tools/common/log"
12	"github.com/mongodb/mongo-tools/common/options"
13	"github.com/mongodb/mongo-tools/common/testtype"
14	"github.com/mongodb/mongo-tools/common/testutil"
15	"github.com/mongodb/mongo-tools/common/util"
16
17	"os"
18	"testing"
19
20	. "github.com/smartystreets/goconvey/convey"
21)
22
23func init() {
24	// bump up the verbosity to make checking debug log output possible
25	log.SetVerbosity(&options.Verbosity{
26		VLevel: 4,
27	})
28}
29
30var (
31	testServer = "localhost"
32	testPort   = db.DefaultTestPort
33)
34
35func TestMongorestore(t *testing.T) {
36	testtype.VerifyTestType(t, testtype.IntegrationTestType)
37	_, err := testutil.GetBareSession()
38	if err != nil {
39		t.Fatalf("No server available")
40	}
41
42	Convey("With a test MongoRestore", t, func() {
43		inputOptions := &InputOptions{}
44		outputOptions := &OutputOptions{
45			NumParallelCollections: 1,
46			NumInsertionWorkers:    1,
47		}
48		nsOptions := &NSOptions{}
49		provider, toolOpts, err := testutil.GetBareSessionProvider()
50		if err != nil {
51			log.Logvf(log.Always, "error connecting to host: %v", err)
52			os.Exit(util.ExitError)
53		}
54		restore := MongoRestore{
55			ToolOptions:     toolOpts,
56			OutputOptions:   outputOptions,
57			InputOptions:    inputOptions,
58			NSOptions:       nsOptions,
59			SessionProvider: provider,
60		}
61		session, _ := provider.GetSession()
62		defer session.Close()
63		c1 := session.DB("db1").C("c1")
64		c1.DropCollection()
65		Convey("and an explicit target restores from that dump directory", func() {
66			restore.TargetDirectory = "testdata/testdirs"
67			err = restore.Restore()
68			So(err, ShouldBeNil)
69			count, err := c1.Count()
70			So(err, ShouldBeNil)
71			So(count, ShouldEqual, 100)
72		})
73
74		Convey("and an target of '-' restores from standard input", func() {
75			bsonFile, err := os.Open("testdata/testdirs/db1/c1.bson")
76			restore.NSOptions.Collection = "c1"
77			restore.NSOptions.DB = "db1"
78			So(err, ShouldBeNil)
79			restore.InputReader = bsonFile
80			restore.TargetDirectory = "-"
81			err = restore.Restore()
82			So(err, ShouldBeNil)
83			count, err := c1.Count()
84			So(err, ShouldBeNil)
85			So(count, ShouldEqual, 100)
86		})
87
88	})
89}
90
91func TestRestoreUsersOrRoles(t *testing.T) {
92	testtype.VerifyTestType(t, testtype.IntegrationTestType)
93
94	nsOptions := &NSOptions{}
95	provider, toolOpts, err := testutil.GetBareSessionProvider()
96	if err != nil {
97		log.Logvf(log.Always, "error connecting to host: %v", err)
98		os.Exit(util.ExitError)
99	}
100
101	Convey("With a test MongoRestore", t, func() {
102		inputOptions := &InputOptions{}
103		outputOptions := &OutputOptions{
104			NumParallelCollections: 1,
105			NumInsertionWorkers:    1,
106			TempUsersColl:          "tempusers",
107			TempRolesColl:          "temproles",
108		}
109		restore := MongoRestore{
110			ToolOptions:     toolOpts,
111			OutputOptions:   outputOptions,
112			InputOptions:    inputOptions,
113			NSOptions:       nsOptions,
114			SessionProvider: provider,
115		}
116		session, _ := provider.GetSession()
117		defer session.Close()
118
119		db := session.DB("admin")
120
121		Convey("Restoring users and roles should drop tempusers and temproles", func() {
122			restore.TargetDirectory = "testdata/usersdump"
123			err := restore.Restore()
124			So(err, ShouldBeNil)
125
126			adminCollections, err := db.CollectionNames()
127			So(err, ShouldBeNil)
128
129			for _, collName := range adminCollections {
130				So(collName, ShouldNotEqual, "tempusers")
131				So(collName, ShouldNotEqual, "temproles")
132			}
133		})
134	})
135}
136
137func TestKnownCollections(t *testing.T) {
138	testtype.VerifyTestType(t, testtype.IntegrationTestType)
139
140	Convey("With a test MongoRestore", t, func() {
141		inputOptions := &InputOptions{}
142		outputOptions := &OutputOptions{
143			NumParallelCollections: 1,
144			NumInsertionWorkers:    1,
145		}
146		nsOptions := &NSOptions{}
147		provider, toolOpts, err := testutil.GetBareSessionProvider()
148		if err != nil {
149			log.Logvf(log.Always, "error connecting to host: %v", err)
150			os.Exit(util.ExitError)
151		}
152		restore := MongoRestore{
153			ToolOptions:     toolOpts,
154			OutputOptions:   outputOptions,
155			InputOptions:    inputOptions,
156			NSOptions:       nsOptions,
157			SessionProvider: provider,
158		}
159		session, _ := provider.GetSession()
160		defer session.Close()
161
162		db := session.DB("test")
163		defer func() {
164			db.C("foo").DropCollection()
165		}()
166
167		Convey("Once collection foo has been restored, it should exist in restore.knownCollections", func() {
168			restore.TargetDirectory = "testdata/foodump"
169			err := restore.Restore()
170			So(err, ShouldBeNil)
171
172			var namespaceExistsInCache bool
173			if cols, ok := restore.knownCollections["test"]; ok {
174				for _, collName := range cols {
175					if collName == "foo" {
176						namespaceExistsInCache = true
177					}
178				}
179			}
180			So(namespaceExistsInCache, ShouldBeTrue)
181		})
182	})
183}
184