Merge branch '7167-keep-rsync-test-setup' into 7167-keep-rsync
[arvados.git] / tools / keep-rsync / keep-rsync_test.go
index c2a8112dc5c9d93a5489dd82df48a0d451fa8367..c612e537258bf1c05742f27a7997ca99f1b6c369 100644 (file)
@@ -40,8 +40,8 @@ func (s *ServerRequiredSuite) TearDownSuite(c *C) {
 }
 
 // Testing keep-rsync needs two sets of keep services: src and dst.
-// The test setup hence tweaks keep-rsync initialzation to achieve this.
-// First invoke initializeKeepRsync and then invoke StartKeepAdditional
+// The test setup hence tweaks keep-rsync initialization to achieve this.
+// First invoke initializeKeepRsync and then invoke StartKeepWithParams
 // to create the keep servers to be used as destination.
 func setupRsync(c *C, enforcePermissions bool) {
        // srcConfig
@@ -54,7 +54,6 @@ func setupRsync(c *C, enforcePermissions bool) {
        dstConfig.APIToken = os.Getenv("ARVADOS_API_TOKEN")
        dstConfig.APIHostInsecure = matchTrue.MatchString(os.Getenv("ARVADOS_API_HOST_INSECURE"))
 
-       replications = 1
        if enforcePermissions {
                blobSigningKey = "zfhgfenhffzltr9dixws36j1yhksjoll2grmku38mi7yxd66h5j4q9w4jzanezacp8s6q0ro3hxakfye02152hncy6zml2ed0uc"
        }
@@ -70,7 +69,7 @@ func setupRsync(c *C, enforcePermissions bool) {
        // Create two more keep servers to be used as destination
        arvadostest.StartKeepWithParams(true, enforcePermissions)
 
-       // load kcDst
+       // load kcDst; set Want_replicas as 1 since that is how many keep servers are created for dst.
        kcDst, err = keepclient.MakeKeepClient(&arvDst)
        c.Assert(err, Equals, nil)
        kcDst.Want_replicas = 1
@@ -138,11 +137,11 @@ func (s *ServerRequiredSuite) TestRsyncPutInOne_GetFromOtherShouldFail(c *C) {
        all, err = ioutil.ReadAll(reader)
        c.Check(all, DeepEquals, dstData)
 
-       // Get srcLocator using kcDst should fail with NotFound error
+       // Get srcLocator using kcDst should fail with Not Found error
        _, _, _, err = kcDst.Get(locatorInSrc)
        c.Assert(err.Error(), Equals, "Block not found")
 
-       // Get dstLocator using kcSrc should fail with NotFound error
+       // Get dstLocator using kcSrc should fail with Not Found error
        _, _, _, err = kcSrc.Get(locatorInDst)
        c.Assert(err.Error(), Equals, "Block not found")
 }
@@ -173,7 +172,7 @@ func (s *ServerRequiredSuite) TestRsyncInitializeWithKeepServicesJSON(c *C) {
        c.Check(foundIt, Equals, true)
 }
 
-// Test keep-rsync initialization, with src and dst keep servers with blobSingingKey.
+// Test keep-rsync initialization, with src and dst keep servers with blobSigningKey.
 // Do a Put and Get in src, both of which should succeed.
 // Do a Put and Get in dst, both of which should succeed.
 // Do a Get in dst for the src hash, which should raise block not found error.
@@ -216,13 +215,144 @@ func (s *ServerRequiredSuite) TestRsyncWithBlobSigning_PutInOne_GetFromOtherShou
        all, err = ioutil.ReadAll(reader)
        c.Check(all, DeepEquals, dstData)
 
-       // Get srcLocator using kcDst should fail with NotFound error
+       // Get srcLocator using kcDst should fail with Not Found error
        signedLocator = keepclient.SignLocator(locatorInSrc, arvDst.ApiToken, tomorrow, []byte(blobSigningKey))
        _, _, _, err = kcDst.Get(locatorInSrc)
        c.Assert(err.Error(), Equals, "Block not found")
 
-       // Get dstLocator using kcSrc should fail with NotFound error
+       // Get dstLocator using kcSrc should fail with Not Found error
        signedLocator = keepclient.SignLocator(locatorInDst, arvSrc.ApiToken, tomorrow, []byte(blobSigningKey))
        _, _, _, err = kcSrc.Get(locatorInDst)
        c.Assert(err.Error(), Equals, "Block not found")
 }
+
+// Test keep-rsync initialization with default replications count
+func (s *ServerRequiredSuite) TestInitializeRsyncDefaultReplicationsCount(c *C) {
+       setupRsync(c, false)
+
+       // Must have got default replications value as 2 from dst discovery document
+       c.Assert(replications, Equals, 2)
+}
+
+// Test keep-rsync initialization with replications count argument
+func (s *ServerRequiredSuite) TestInitializeRsyncReplicationsCount(c *C) {
+       // set replications to 3 to mimic passing input argument
+       replications = 3
+
+       setupRsync(c, false)
+
+       // Since replications value is provided, default is not used
+       c.Assert(replications, Equals, 3)
+}
+
+// Put some blocks in Src and some more in Dst
+// And copy missing blocks from Src to Dst
+func (s *ServerRequiredSuite) TestKeepRsync(c *C) {
+       testKeepRsync(c, false)
+}
+
+// Put some blocks in Src and some more in Dst with blob signing enabled.
+// And copy missing blocks from Src to Dst
+func (s *ServerRequiredSuite) TestKeepRsync_WithBlobSigning(c *C) {
+       testKeepRsync(c, true)
+}
+
+// Put 5 blocks in src. Put 2 of those blocks in dst
+// Hence there are 3 additional blocks in src
+// Also, put 2 extra blocks in dst; they are hence only in dst
+// Run rsync and verify that those 7 blocks are now available in dst
+func testKeepRsync(c *C, enforcePermissions bool) {
+       setupRsync(c, enforcePermissions)
+
+       tomorrow := time.Now().AddDate(0, 0, 1)
+
+       // Put a few blocks in src using kcSrc
+       var srcLocators []string
+       for i := 0; i < 5; i++ {
+               data := []byte(fmt.Sprintf("test-data-%d", i))
+               hash := fmt.Sprintf("%x", md5.Sum(data))
+
+               hash2, rep, err := kcSrc.PutB(data)
+               c.Check(hash2, Matches, fmt.Sprintf(`^%s\+11(\+.+)?$`, hash))
+               c.Check(rep, Equals, 2)
+               c.Check(err, Equals, nil)
+
+               getLocator := hash
+               if enforcePermissions {
+                       getLocator = keepclient.SignLocator(getLocator, arvSrc.ApiToken, tomorrow, []byte(blobSigningKey))
+               }
+
+               reader, blocklen, _, err := kcSrc.Get(getLocator)
+               c.Assert(err, Equals, nil)
+               c.Check(blocklen, Equals, int64(11))
+               all, err := ioutil.ReadAll(reader)
+               c.Check(all, DeepEquals, data)
+
+               srcLocators = append(srcLocators, fmt.Sprintf("%s+%d", hash, blocklen))
+       }
+
+       // Put just two of those blocks in dst using kcDst
+       var dstLocators []string
+       for i := 0; i < 2; i++ {
+               data := []byte(fmt.Sprintf("test-data-%d", i))
+               hash := fmt.Sprintf("%x", md5.Sum(data))
+
+               hash2, rep, err := kcDst.PutB(data)
+               c.Check(hash2, Matches, fmt.Sprintf(`^%s\+11(\+.+)?$`, hash))
+               c.Check(rep, Equals, 1)
+               c.Check(err, Equals, nil)
+
+               getLocator := hash
+               if enforcePermissions {
+                       getLocator = keepclient.SignLocator(getLocator, arvDst.ApiToken, tomorrow, []byte(blobSigningKey))
+               }
+
+               reader, blocklen, _, err := kcDst.Get(getLocator)
+               c.Assert(err, Equals, nil)
+               c.Check(blocklen, Equals, int64(11))
+               all, err := ioutil.ReadAll(reader)
+               c.Check(all, DeepEquals, data)
+
+               dstLocators = append(dstLocators, fmt.Sprintf("%s+%d", hash, blocklen))
+       }
+
+       // Put two more blocks in dst; they are not in src at all
+       var extraDstLocators []string
+       for i := 0; i < 2; i++ {
+               data := []byte(fmt.Sprintf("other-data-%d", i))
+               hash := fmt.Sprintf("%x", md5.Sum(data))
+
+               hash2, rep, err := kcDst.PutB(data)
+               c.Check(hash2, Matches, fmt.Sprintf(`^%s\+12(\+.+)?$`, hash))
+               c.Check(rep, Equals, 1)
+               c.Check(err, Equals, nil)
+
+               getLocator := hash
+               if enforcePermissions {
+                       getLocator = keepclient.SignLocator(getLocator, arvDst.ApiToken, tomorrow, []byte(blobSigningKey))
+               }
+
+               reader, blocklen, _, err := kcDst.Get(getLocator)
+               c.Assert(err, Equals, nil)
+               c.Check(blocklen, Equals, int64(12))
+               all, err := ioutil.ReadAll(reader)
+               c.Check(all, DeepEquals, data)
+
+               extraDstLocators = append(extraDstLocators, fmt.Sprintf("%s+%d", hash, blocklen))
+       }
+
+       err := performKeepRsync()
+       c.Check(err, Equals, nil)
+
+       // Now GetIndex from dst and verify that all 5 from src and the 2 extra blocks are found
+       dstIndex, err := getUniqueLocators(kcDst, "")
+       c.Check(err, Equals, nil)
+       for _, locator := range srcLocators {
+               _, ok := dstIndex[locator]
+               c.Assert(ok, Equals, true)
+       }
+       for _, locator := range extraDstLocators {
+               _, ok := dstIndex[locator]
+               c.Assert(ok, Equals, true)
+       }
+}