public void Push_RemoteRepoDbNotExistsAndSetsCorrectlyWithRevHash_Success()
        {
            using (var e = new TestEnvironment("hgresumetest", ApiServerType.Dummy))
                using (var provider = GetTransportProviderForTest(e))
                {
                    e.LocalAddAndCommit();
                    e.ApiServer.AddResponse(ApiResponses.Revisions(e.Local.Repository.GetTip().Number.Hash + ':' + e.Local.Repository.GetTip().Branch));
                    e.LocalAddAndCommit();
                    e.ApiServer.AddResponse(ApiResponses.PushComplete());

                    var transport = provider.Transport;

                    string dbStoragePath = transport.PathToLocalStorage;
                    string dbFilePath    = Path.Combine(dbStoragePath, HgResumeTransport.RevisionCacheFilename);
                    Assert.That(File.Exists(dbFilePath), Is.False);

                    var tipHash = e.Local.Repository.GetTip().Number.Hash;
                    transport.Push();
                    Assert.That(File.Exists(dbFilePath), Is.True);
                    var cacheContents = HgResumeTransport.ReadServerRevisionCache(dbFilePath);
                    Assert.True(cacheContents.Count == 1, "should only be one entry in the cache.");
                    Assert.True(cacheContents.FirstOrDefault().RemoteId == e.ApiServer.Host &&
                                cacheContents.FirstOrDefault().Revision.Number.Hash == tipHash, "Cache contents incorrect");
                    Assert.That(e.Progress.AllMessages, Contains.Item("Finished sending"));
                }
        }
 public void Pull_UnknownServerResponse_Fails()
 {
     using (var e = new TestEnvironment("hgresumetest", ApiServerType.Dummy))
         using (var provider = GetTransportProviderForTest(e))
         {
             e.LocalAddAndCommit();
             e.ApiServer.AddResponse(ApiResponses.Custom(HttpStatusCode.ServiceUnavailable));
             var transport = provider.Transport;
             Assert.That(() => transport.Pull(), Throws.Exception.TypeOf <HgResumeOperationFailed>());
         }
 }
 public void Push_SingleResponse_OK()
 {
     using (var e = new TestEnvironment("hgresumetest", ApiServerType.Dummy))
         using (var provider = GetTransportProviderForTest(e))
         {
             e.LocalAddAndCommit();
             e.ApiServer.AddResponse(ApiResponses.Revisions(e.Local.Repository.GetTip().Number.Hash + ':' + e.Local.Repository.GetTip().Branch));
             e.LocalAddAndCommit();
             e.ApiServer.AddResponse(ApiResponses.PushComplete());
             var transport = provider.Transport;
             transport.Push();
             Assert.That(e.Progress.AllMessages, Contains.Item("Finished sending"));
         }
 }
 public void Push_InitialServerResponseServerNotAvailable_NotAvailableMessage()
 {
     using (var e = new TestEnvironment("hgresumetest", ApiServerType.Dummy))
         using (var provider = GetTransportProviderForTest(e))
         {
             e.LocalAddAndCommit();
             var serverMessage = "The server is down for scheduled maintenance";
             e.ApiServer.AddResponse(ApiResponses.NotAvailable(serverMessage));
             e.ApiServer.AddResponse(ApiResponses.PushComplete());
             var transport = provider.Transport;
             Assert.Throws <HgResumeOperationFailed>(transport.Push);
             Assert.That(e.Progress.AllMessages, Contains.Item("Server temporarily unavailable: " + serverMessage));
             Assert.That(e.Progress.AllMessages, Has.No.Member("The pull operation completed successfully"));
         }
 }
 public void Push_MultiChunkBundleAndUnBundleFails_Fail()
 {
     using (var e = new TestEnvironment("hgresumetest", ApiServerType.Dummy))
         using (var provider = GetTransportProviderForTest(e))
         {
             e.LocalAddAndCommit();
             e.ApiServer.AddResponse(ApiResponses.Revisions(e.Local.Repository.GetTip().Number.Hash + ':' + e.Local.Repository.GetTip().Branch));
             e.LocalAddAndCommit();
             e.ApiServer.AddResponse(ApiResponses.PushAccepted(1));
             e.ApiServer.AddResponse(ApiResponses.PushAccepted(2));
             e.ApiServer.AddResponse(ApiResponses.Reset());
             var transport = provider.Transport;
             Assert.That(() => transport.Push(), Throws.Exception.TypeOf <HgResumeOperationFailed>());
         }
 }
        public void Push_2DifferentApiServers_HgRepoFileUpdatedWithBothEntries()
        {
            using (var e1 = new TestEnvironment("api1", ApiServerType.Dummy))
                using (var provider = GetTransportProviderForTest(e1))
                {
                    var api2       = new DummyApiServerForTest("api3");
                    var transport2 = new HgResumeTransport(e1.Local.Repository, "api3", api2, e1.MultiProgress);

                    // push to ApiServer 1
                    e1.LocalAddAndCommit();
                    var revisionResponse = ApiResponses.Revisions(e1.Local.Repository.GetTip().Number.Hash + ':' + e1.Local.Repository.GetTip().Branch);
                    e1.ApiServer.AddResponse(revisionResponse);
                    e1.LocalAddAndCommit();
                    e1.ApiServer.AddResponse(ApiResponses.PushComplete());
                    var tipHash1  = e1.Local.Repository.GetTip().Number.Hash;
                    var transport = provider.Transport;
                    transport.Push();
                    e1.ApiServer.AddResponse(ApiResponses.PushComplete());              // finishPushBundle

                    // push to ApiServer 2
                    api2.AddResponse(revisionResponse);
                    api2.AddResponse(ApiResponses.PushComplete());
                    transport2.Push();

                    // check contents of remoteRepoDb
                    string dbStoragePath = transport.PathToLocalStorage;
                    string dbFilePath    = Path.Combine(dbStoragePath, HgResumeTransport.RevisionCacheFilename);
                    var    cacheContents = HgResumeTransport.ReadServerRevisionCache(dbFilePath);
                    Assert.True(cacheContents.Count == 2, "should be two api server entries in the cache.");
                    Assert.True(cacheContents.SingleOrDefault(x => x.RemoteId == e1.ApiServer.Host).Revision.Number.Hash == tipHash1, "Cache contents incorrect");
                    Assert.True(cacheContents.SingleOrDefault(x => x.RemoteId == api2.Host).Revision.Number.Hash == tipHash1, "Cache contents incorrect");

                    // second push
                    e1.LocalAddAndCommit();
                    e1.LocalAddAndCommit();
                    string tipHash2 = e1.Local.Repository.GetTip().Number.Hash;
                    e1.ApiServer.AddResponse(ApiResponses.PushAccepted(1));
                    e1.ApiServer.AddResponse(ApiResponses.PushComplete());
                    transport.Push();

                    cacheContents = HgResumeTransport.ReadServerRevisionCache(dbFilePath);
                    Assert.True(cacheContents.Count == 2, "should be two api server entries in the cache.");
                    Assert.True(cacheContents.SingleOrDefault(x => x.RemoteId == e1.ApiServer.Host).Revision.Number.Hash == tipHash2, "Cache contents incorrect");
                    Assert.True(cacheContents.SingleOrDefault(x => x.RemoteId == api2.Host).Revision.Number.Hash == tipHash1, "Cache contents incorrect");

                    Assert.That(e1.Progress.AllMessages, Contains.Item("Finished sending"));
                }
        }
 public void Push_InitialServerResponseServerNotAvailable_NotAvailableMessage()
 {
     using (var e = new TestEnvironment("hgresumetest", ApiServerType.Dummy))
         using (var provider = GetTransportProviderForTest(e))
         {
             e.LocalAddAndCommit();
             var serverMessage    = "The server is down for scheduled maintenance";
             var revisionResponse = ApiResponses.Custom(HttpStatusCode.OK);
             revisionResponse.Content = Encoding.UTF8.GetBytes("0:default").ToArray();
             e.ApiServer.AddResponse(revisionResponse);
             e.ApiServer.AddResponse(ApiResponses.NotAvailable(serverMessage));
             e.ApiServer.AddResponse(ApiResponses.PushComplete());
             var transport = provider.Transport;
             transport.Push();
             Assert.That(e.Progress.AllMessages, Contains.Item("Server temporarily unavailable: " + serverMessage));
             Assert.That(e.Progress.AllMessages, Has.No.Member("The pull operation completed successfully"));
         }
 }
 public void Pull_GetRevisionServerResponseServerNotAvailable_NotAvailableMessageAndFails()
 {
     using (var e = new TestEnvironment("hgresumetest", ApiServerType.Dummy))
         using (var provider = GetTransportProviderForTest(e))
         {
             e.LocalAddAndCommit();
             var serverMessage = "The server is down for scheduled maintenance";
             e.ApiServer.AddResponse(ApiResponses.NotAvailable(serverMessage));
             e.ApiServer.AddResponse(ApiResponses.NotAvailable(serverMessage));
             var revisionResponse = ApiResponses.Custom(HttpStatusCode.OK);
             revisionResponse.Content = Encoding.UTF8.GetBytes((e.Local.Repository.GetTip().Number.Hash + ":").ToArray());
             e.ApiServer.AddResponse(revisionResponse);
             e.ApiServer.AddResponse(ApiResponses.PullNoChange());
             var transport = provider.Transport;
             Assert.Throws(typeof(HgResumeOperationFailed), () => transport.Pull());
             Assert.That(e.Progress.AllMessages, Contains.Item("Server temporarily unavailable: " + serverMessage));
             Assert.That(e.Progress.AllMessages, Has.No.Member("No changes"));
         }
 }
        public void Push_RemoteRevisionCacheWorksWhenReceivingMoreThanRequestedRevisions()
        {
            using (var e = new BranchingTestEnvironment("hgresumetest", ApiServerType.Dummy))
                using (var provider = GetTransportProviderForTest(e))
                {
                    provider.Transport.RevisionRequestQuantity = 2;
                    var first2revs   = "";
                    var changingFile = e.LocalAddAndCommit();
                    first2revs += e.Local.Repository.GetTip().Number.Hash + ':' + e.Local.Repository.GetTip().Branch + "|";
                    e.LocalChangeAndCommit(changingFile);
                    first2revs += e.Local.Repository.GetTip().Number.Hash + ':' + e.Local.Repository.GetTip().Branch;
                    var second2revs = "";
                    e.LocalChangeAndCommit(changingFile);
                    second2revs += e.Local.Repository.GetTip().Number.Hash + ':' + e.Local.Repository.GetTip().Branch + "|";
                    e.LocalChangeAndCommit(changingFile);
                    second2revs += e.Local.Repository.GetTip().Number.Hash + ':' + e.Local.Repository.GetTip().Branch;

                    e.ApiServer.AddResponse(ApiResponses.Revisions(first2revs));
                    e.ApiServer.AddResponse(ApiResponses.Revisions(second2revs));
                    e.ApiServer.AddResponse(ApiResponses.Revisions(""));
                    e.SetLocalAdjunct(new ProgrammableSynchronizerAdjunct("newbranch"));
                    e.LocalAddAndCommit();
                    e.ApiServer.AddResponse(ApiResponses.PushComplete());

                    var transport = provider.Transport;

                    var dbStoragePath = transport.PathToLocalStorage;
                    var dbFilePath    = Path.Combine(dbStoragePath, HgResumeTransport.RevisionCacheFilename);
                    Assert.That(File.Exists(dbFilePath), Is.False);

                    var tipHash       = e.Local.Repository.GetTip().Number.Hash;
                    var cacheContents = HgResumeTransport.ReadServerRevisionCache(dbFilePath);
                    transport.Push();
                    Assert.That(File.Exists(dbFilePath), Is.True);
                    cacheContents = HgResumeTransport.ReadServerRevisionCache(dbFilePath);
                    Assert.True(cacheContents.Count == 2, "should be 2 entries in the cache at this point.");
                    Assert.True(cacheContents.FirstOrDefault().RemoteId == e.ApiServer.Host &&
                                cacheContents.FirstOrDefault().Revision.Number.Hash == tipHash, "Cache contents incorrect");
                    Assert.That(e.Progress.AllMessages, Contains.Item("Finished sending"));
                }
        }
Exemple #10
0
        public HgResumeApiResponse Execute(string method, HgResumeApiParameters request, byte[] bytesToWrite, int secondsBeforeTimeout)
        {
            ValidateParameters(method, request, bytesToWrite, secondsBeforeTimeout);
            _executeCount++;
            if (method == "finishPullBundle")
            {
                if (CurrentTip != OriginalTip)
                {
                    PrepareBundle(HgResumeTransport.GetHashStringsFromRevisions(_repo.BranchingHelper.GetBranches()));
                    return(ApiResponses.Reset());                    // repo changed in between pulls
                }
                return(ApiResponses.Custom(HttpStatusCode.OK));
            }
            if (method == "getRevisions")
            {
                IEnumerable <string> revisions = _repo.GetAllRevisions().Select(rev => rev.Number.Hash + ':' + rev.Branch);
                return(ApiResponses.Revisions(string.Join("|", revisions.ToArray())));
            }
            if (method == "pullBundleChunk")
            {
                if (_cancelCount == _executeCount)
                {
                    _progress.CancelRequested = true;
                    return(ApiResponses.Failed(""));
                }
                if (_failCount == _executeCount)
                {
                    return(ApiResponses.Failed(""));
                }
                if (_timeoutList.Contains(_executeCount))
                {
                    return(null);
                }
                if (_serverUnavailableList.Any(i => i.ExecuteCount == _executeCount))
                {
                    return(ApiResponses.NotAvailable(
                               _serverUnavailableList.Where(i => i.ExecuteCount == _executeCount).First().Message
                               ));
                }
                if (Array.BinarySearch(request.BaseHashes, 0, request.BaseHashes.Length, CurrentTip) >= 0)
                {
                    return(ApiResponses.PullNoChange());
                }

                var bundleFileInfo = new FileInfo(_helper.BundlePath);
                if (bundleFileInfo.Exists && bundleFileInfo.Length == 0 || !bundleFileInfo.Exists)
                {
                    PrepareBundle(request.BaseHashes);
                }
                //int offset = Convert.ToInt32(request["offset"]);
                //int chunkSize = Convert.ToInt32(request["chunkSize"]);
                var bundleFile = new FileInfo(_helper.BundlePath);
                if (request.StartOfWindow >= bundleFile.Length)
                {
                    return(ApiResponses.Failed("offset greater than bundleSize"));
                }
                var chunk = _helper.GetChunk(request.StartOfWindow, request.ChunkSize);
                return(ApiResponses.PullOk(Convert.ToInt32(bundleFile.Length), chunk));
            }
            return(ApiResponses.Custom(HttpStatusCode.InternalServerError));
        }
Exemple #11
0
        public HgResumeApiResponse Execute(string method, HgResumeApiParameters request, byte[] bytesToWrite, int secondsBeforeTimeout)
        {
            ValidateParameters(method, request, bytesToWrite, secondsBeforeTimeout);
            if (method == "getRevisions")
            {
                IEnumerable <Revision> revisions = _repo.GetAllRevisions();

                if (revisions.Count() == 0)
                {
                    return(ApiResponses.Revisions("0:default"));
                }
                var revisionStrings = _repo.GetAllRevisions().Select(rev => rev.Number.Hash + ':' + rev.Branch);
                return(ApiResponses.Revisions(string.Join("|", revisionStrings.ToArray())));
            }
            if (method == "finishPushBundle")
            {
                return(ApiResponses.PushComplete());
            }
            if (method == "pushBundleChunk")
            {
                _executeCount++;
                if (_cancelCount == _executeCount)
                {
                    _progress.CancelRequested = true;
                    return(ApiResponses.Failed(""));
                }
                if (_failCount == _executeCount)
                {
                    return(ApiResponses.Failed(""));
                }
                if (_timeoutList.Contains(_executeCount))
                {
                    return(null);
                }
                if (_serverUnavailableList.Any(i => i.ExecuteCount == _executeCount))
                {
                    return(ApiResponses.NotAvailable(
                               _serverUnavailableList.Where(i => i.ExecuteCount == _executeCount).First().Message
                               ));
                }
                _helper = new PullStorageManager(_localStorage.Path, request.TransId);

                //int bundleSize = Convert.ToInt32(parameters["bundleSize"]);
                //int offset = Convert.ToInt32(parameters["offset"]);
                //int chunkSize = bytesToWrite.Length;

                _helper.WriteChunk(request.StartOfWindow, bytesToWrite);

                if (request.StartOfWindow + request.ChunkSize == request.BundleSize)
                {
                    if (_repo.Unbundle(_helper.BundlePath))
                    {
                        return(ApiResponses.PushComplete());
                    }
                    return(ApiResponses.Reset());
                }
                if (request.StartOfWindow + request.ChunkSize < request.BundleSize)
                {
                    return(ApiResponses.PushAccepted(_helper.StartOfWindow));
                }
                return(ApiResponses.Failed("offset + chunkSize > bundleSize !"));
            }
            return(ApiResponses.Custom(HttpStatusCode.InternalServerError));
        }