view tests/test-exchange-multi-source.t @ 47343:9f798c1b0d89 stable

cext: fix memory leak in phases computation Without this a buffer whose size in bytes is the number of changesets in the repository is leaked each time the repository is opened and changeset phases are computed. Impact: the current code in hgwebdir creates a new `localrepository` instance for each HTTP request. Since any pull or push is made of several requests, a team of 100 people can easily produce thousands of such requests per day. Being a low-level malloc, this leak can't be seen with the gc module and tools relying on that, but was spotted by valgrind immediately. Reproduction ------------ for i in range(cl_args.iterations): repo = hg.repository(baseui, repo_path) rev = repo.revs(rev).first() ctx = repo[rev] del ctx del repo # avoid any pollution by other type of leak # (that should be fixed in 5.8) repoview._filteredrepotypes.clear() gc.collect() Measurements ------------ Resident Set Size (RSS), taken on a clone of mozilla-central for performance analysis (440 000 changesets). before: 5.8+hg19.5ac0f2a8ba72 1000 iterations: 1606MB 5.8+hg19.5ac0f2a8ba72 10000 iterations: 5723MB after: 5.8+hg20.e2084d39e145 1000 iterations: 555MB 5.8+hg20.e2084d39e145 10000 iterations: 555MB (double checked, not a copy/paste error) (e2084d39e14 is the present changeset, before amendment of the message to add the measurements)
author Georges Racinet <georges.racinet@octobus.net>
date Sun, 06 Jun 2021 01:24:30 +0200
parents 946db89607c8
children 834f4e9d1af2
line wrap: on
line source

====================================================
Test push/pull from multiple source at the same time
====================================================


Setup
=====

main repository
---------------

  $ . $RUNTESTDIR/testlib/common.sh
  $ hg init main-repo
  $ cd main-repo
  $ mkcommit A
  $ mkcommit B
  $ mkcommit C
  $ mkcommit D
  $ mkcommit E
  $ hg up 'desc(B)'
  0 files updated, 0 files merged, 3 files removed, 0 files unresolved
  $ mkcommit F
  created new head
  $ mkcommit G
  $ hg up 'desc(C)'
  1 files updated, 0 files merged, 2 files removed, 0 files unresolved
  $ mkcommit H
  created new head
  $ hg up null --quiet
  $ hg log -T '{desc} {rev}\n' --rev 'sort(all(), "topo")' -G
  o  H 7
  |
  | o  E 4
  | |
  | o  D 3
  |/
  o  C 2
  |
  | o  G 6
  | |
  | o  F 5
  |/
  o  B 1
  |
  o  A 0
  
  $ cd ..

Various other repositories
--------------------------

  $ hg clone main-repo branch-E --rev 4 -U
  adding changesets
  adding manifests
  adding file changes
  added 5 changesets with 5 changes to 5 files
  new changesets 4a2df7238c3b:a603bfb5a83e
  $ hg clone main-repo branch-G --rev 6 -U
  adding changesets
  adding manifests
  adding file changes
  added 4 changesets with 4 changes to 4 files
  new changesets 4a2df7238c3b:c521a06b234b
  $ hg clone main-repo branch-H --rev 7 -U
  adding changesets
  adding manifests
  adding file changes
  added 4 changesets with 4 changes to 4 files
  new changesets 4a2df7238c3b:40faebb2ec45

Test simple bare operation
==========================

pull
----

  $ hg clone main-repo test-repo-bare --rev 0 -U
  adding changesets
  adding manifests
  adding file changes
  added 1 changesets with 1 changes to 1 files
  new changesets 4a2df7238c3b

  $ hg pull -R test-repo-bare ./branch-E ./branch-G ./branch-H
  pulling from ./branch-E
  searching for changes
  adding changesets
  adding manifests
  adding file changes
  added 4 changesets with 4 changes to 4 files
  new changesets 27547f69f254:a603bfb5a83e
  (run 'hg update' to get a working copy)
  pulling from ./branch-G
  searching for changes
  adding changesets
  adding manifests
  adding file changes
  added 2 changesets with 2 changes to 2 files (+1 heads)
  new changesets 2f3a4c5c1417:c521a06b234b
  (run 'hg heads' to see heads, 'hg merge' to merge)
  pulling from ./branch-H
  searching for changes
  adding changesets
  adding manifests
  adding file changes
  added 1 changesets with 1 changes to 1 files (+1 heads)
  new changesets 40faebb2ec45
  (run 'hg heads .' to see heads, 'hg merge' to merge)
  $ hg log -R test-repo-bare -T '{desc} {rev}\n' --rev 'sort(all(), "topo")' -G
  o  H 7
  |
  | o  E 4
  | |
  | o  D 3
  |/
  o  C 2
  |
  | o  G 6
  | |
  | o  F 5
  |/
  o  B 1
  |
  o  A 0
  

push
----

  $ cp -R ./branch-E ./branch-E-push
  $ cp -R ./branch-G ./branch-G-push
  $ cp -R ./branch-H ./branch-H-push
  $ hg out -G -R test-repo-bare ./branch-E-push ./branch-G-push ./branch-H-push
  comparing with ./branch-E-push
  searching for changes
  comparing with ./branch-G-push
  searching for changes
  comparing with ./branch-H-push
  searching for changes
  o  changeset:   7:40faebb2ec45
  |  tag:         tip
  |  parent:      2:f838bfaca5c7
  |  user:        test
  |  date:        Thu Jan 01 00:00:00 1970 +0000
  |  summary:     H
  |
  | o  changeset:   6:c521a06b234b
  | |  user:        test
  | |  date:        Thu Jan 01 00:00:00 1970 +0000
  | |  summary:     G
  | |
  | o  changeset:   5:2f3a4c5c1417
  |    parent:      1:27547f69f254
  |    user:        test
  |    date:        Thu Jan 01 00:00:00 1970 +0000
  |    summary:     F
  |
  | o  changeset:   4:a603bfb5a83e
  | |  user:        test
  | |  date:        Thu Jan 01 00:00:00 1970 +0000
  | |  summary:     E
  | |
  | o  changeset:   3:b3325c91a4d9
  |/   user:        test
  |    date:        Thu Jan 01 00:00:00 1970 +0000
  |    summary:     D
  |
  o  changeset:   2:f838bfaca5c7
     user:        test
     date:        Thu Jan 01 00:00:00 1970 +0000
     summary:     C
  
  $ hg bundle -R test-repo-bare bundle.hg ./branch-E-push ./branch-G-push ./branch-H-push
  searching for changes
  searching for changes
  searching for changes
  6 changesets found
  $ hg push --force -R test-repo-bare ./branch-E-push ./branch-G-push ./branch-H-push
  pushing to ./branch-E-push
  searching for changes
  adding changesets
  adding manifests
  adding file changes
  added 3 changesets with 3 changes to 3 files (+2 heads)
  pushing to ./branch-G-push
  searching for changes
  adding changesets
  adding manifests
  adding file changes
  added 4 changesets with 4 changes to 4 files (+2 heads)
  pushing to ./branch-H-push
  searching for changes
  adding changesets
  adding manifests
  adding file changes
  added 4 changesets with 4 changes to 4 files (+2 heads)
  $ hg log -R ./branch-E-push -T '{desc} {rev}\n' --rev 'sort(all(), "topo")' -G
  o  H 7
  |
  | o  E 4
  | |
  | o  D 3
  |/
  o  C 2
  |
  | o  G 6
  | |
  | o  F 5
  |/
  o  B 1
  |
  o  A 0
  
  $ hg log -R ./branch-G-push -T '{desc} {rev}\n' --rev 'sort(all(), "topo")' -G
  o  H 7
  |
  | o  E 6
  | |
  | o  D 5
  |/
  o  C 4
  |
  | o  G 3
  | |
  | o  F 2
  |/
  o  B 1
  |
  o  A 0
  
  $ hg log -R ./branch-H-push -T '{desc} {rev}\n' --rev 'sort(all(), "topo")' -G
  o  G 7
  |
  o  F 6
  |
  | o  E 5
  | |
  | o  D 4
  | |
  | | o  H 3
  | |/
  | o  C 2
  |/
  o  B 1
  |
  o  A 0
  
  $ rm -rf ./*-push

Test operation with a target
============================

pull
----

  $ hg clone main-repo test-repo-rev --rev 0 -U
  adding changesets
  adding manifests
  adding file changes
  added 1 changesets with 1 changes to 1 files
  new changesets 4a2df7238c3b

pulling an explicite revision

  $ node_b=`hg log -R main-repo --rev 'desc(B)' -T '{node}'`
  $ hg pull -R test-repo-rev ./branch-E ./branch-G ./branch-H --rev $node_b
  pulling from ./branch-E
  searching for changes
  adding changesets
  adding manifests
  adding file changes
  added 1 changesets with 1 changes to 1 files
  new changesets 27547f69f254
  (run 'hg update' to get a working copy)
  pulling from ./branch-G
  no changes found
  pulling from ./branch-H
  no changes found
  $ hg log -R test-repo-rev -T '{desc} {rev}\n' --rev 'sort(all(), "topo")' -G
  o  B 1
  |
  o  A 0
  

pulling a branch head, the branch head resolve to different revision on the
different repositories.

  $ hg pull -R test-repo-rev ./branch-E ./branch-G ./branch-H --rev default
  pulling from ./branch-E
  searching for changes
  adding changesets
  adding manifests
  adding file changes
  added 3 changesets with 3 changes to 3 files
  new changesets f838bfaca5c7:a603bfb5a83e
  (run 'hg update' to get a working copy)
  pulling from ./branch-G
  searching for changes
  adding changesets
  adding manifests
  adding file changes
  added 2 changesets with 2 changes to 2 files (+1 heads)
  new changesets 2f3a4c5c1417:c521a06b234b
  (run 'hg heads' to see heads, 'hg merge' to merge)
  pulling from ./branch-H
  searching for changes
  adding changesets
  adding manifests
  adding file changes
  added 1 changesets with 1 changes to 1 files (+1 heads)
  new changesets 40faebb2ec45
  (run 'hg heads .' to see heads, 'hg merge' to merge)
  $ hg log -R test-repo-rev -T '{desc} {rev}\n' --rev 'sort(all(), "topo")' -G
  o  H 7
  |
  | o  E 4
  | |
  | o  D 3
  |/
  o  C 2
  |
  | o  G 6
  | |
  | o  F 5
  |/
  o  B 1
  |
  o  A 0
  

push
----

We only push a specific branch with --rev

  $ cp -R ./branch-E ./branch-E-push
  $ cp -R ./branch-G ./branch-G-push
  $ cp -R ./branch-H ./branch-H-push
  $ hg out -G -R test-repo-bare ./branch-E-push ./branch-G-push ./branch-H-push --rev default
  comparing with ./branch-E-push
  searching for changes
  comparing with ./branch-G-push
  searching for changes
  comparing with ./branch-H-push
  searching for changes
  no changes found
  o  changeset:   7:40faebb2ec45
  |  tag:         tip
  |  parent:      2:f838bfaca5c7
  |  user:        test
  |  date:        Thu Jan 01 00:00:00 1970 +0000
  |  summary:     H
  |
  o  changeset:   2:f838bfaca5c7
     user:        test
     date:        Thu Jan 01 00:00:00 1970 +0000
     summary:     C
  
  $ hg bundle -R test-repo-bare bundle.hg ./branch-E-push ./branch-G-push ./branch-H-push --rev default
  searching for changes
  searching for changes
  searching for changes
  2 changesets found
  $ hg push --force -R test-repo-bare ./branch-E-push ./branch-G-push ./branch-H-push --rev default
  pushing to ./branch-E-push
  searching for changes
  adding changesets
  adding manifests
  adding file changes
  added 1 changesets with 1 changes to 1 files (+1 heads)
  pushing to ./branch-G-push
  searching for changes
  adding changesets
  adding manifests
  adding file changes
  added 2 changesets with 2 changes to 2 files (+1 heads)
  pushing to ./branch-H-push
  searching for changes
  no changes found
  $ hg log -R ./branch-E-push -T '{desc} {rev}\n' --rev 'sort(all(), "topo")' -G
  o  H 5
  |
  | o  E 4
  | |
  | o  D 3
  |/
  o  C 2
  |
  o  B 1
  |
  o  A 0
  
  $ hg log -R ./branch-G-push -T '{desc} {rev}\n' --rev 'sort(all(), "topo")' -G
  o  H 5
  |
  o  C 4
  |
  | o  G 3
  | |
  | o  F 2
  |/
  o  B 1
  |
  o  A 0
  
  $ hg log -R ./branch-H-push -T '{desc} {rev}\n' --rev 'sort(all(), "topo")' -G
  o  H 3
  |
  o  C 2
  |
  o  B 1
  |
  o  A 0
  
  $ rm -rf ./*-push

Same push, but the first one is a no-op

  $ cp -R ./branch-E ./branch-E-push
  $ cp -R ./branch-G ./branch-G-push
  $ cp -R ./branch-H ./branch-H-push
  $ hg out -G -R test-repo-bare ./branch-G-push ./branch-H-push ./branch-E-push --rev default
  comparing with ./branch-G-push
  searching for changes
  comparing with ./branch-H-push
  searching for changes
  no changes found
  comparing with ./branch-E-push
  searching for changes
  o  changeset:   7:40faebb2ec45
  |  tag:         tip
  |  parent:      2:f838bfaca5c7
  |  user:        test
  |  date:        Thu Jan 01 00:00:00 1970 +0000
  |  summary:     H
  |
  o  changeset:   2:f838bfaca5c7
     user:        test
     date:        Thu Jan 01 00:00:00 1970 +0000
     summary:     C
  
  $ hg bundle -R test-repo-bare bundle.hg ./branch-G-push ./branch-H-push ./branch-E-push --rev default
  searching for changes
  searching for changes
  searching for changes
  2 changesets found
  $ hg push --force -R test-repo-bare ./branch-G-push ./branch-H-push ./branch-E-push --rev default
  pushing to ./branch-G-push
  searching for changes
  adding changesets
  adding manifests
  adding file changes
  added 2 changesets with 2 changes to 2 files (+1 heads)
  pushing to ./branch-H-push
  searching for changes
  no changes found
  pushing to ./branch-E-push
  searching for changes
  adding changesets
  adding manifests
  adding file changes
  added 1 changesets with 1 changes to 1 files (+1 heads)
  $ hg log -R ./branch-E-push -T '{desc} {rev}\n' --rev 'sort(all(), "topo")' -G
  o  H 5
  |
  | o  E 4
  | |
  | o  D 3
  |/
  o  C 2
  |
  o  B 1
  |
  o  A 0
  
  $ hg log -R ./branch-G-push -T '{desc} {rev}\n' --rev 'sort(all(), "topo")' -G
  o  H 5
  |
  o  C 4
  |
  | o  G 3
  | |
  | o  F 2
  |/
  o  B 1
  |
  o  A 0
  
  $ hg log -R ./branch-H-push -T '{desc} {rev}\n' --rev 'sort(all(), "topo")' -G
  o  H 3
  |
  o  C 2
  |
  o  B 1
  |
  o  A 0
  
  $ rm -rf ./*-push


Test with --update
==================

update without conflicts
------------------------

  $ hg clone main-repo test-repo-update --rev 0
  adding changesets
  adding manifests
  adding file changes
  added 1 changesets with 1 changes to 1 files
  new changesets 4a2df7238c3b
  updating to branch default
  1 files updated, 0 files merged, 0 files removed, 0 files unresolved

We update for each pull, so the first on get into a branch independant from the
other and stay there. This is the expected behavior.

  $ hg log -R test-repo-update -T '{desc} {rev}\n' --rev 'sort(all(), "topo")' -G
  @  A 0
  
  $ hg pull -R test-repo-update ./branch-E ./branch-G ./branch-H --update
  pulling from ./branch-E
  searching for changes
  adding changesets
  adding manifests
  adding file changes
  added 4 changesets with 4 changes to 4 files
  new changesets 27547f69f254:a603bfb5a83e
  4 files updated, 0 files merged, 0 files removed, 0 files unresolved
  pulling from ./branch-G
  searching for changes
  adding changesets
  adding manifests
  adding file changes
  added 2 changesets with 2 changes to 2 files (+1 heads)
  new changesets 2f3a4c5c1417:c521a06b234b
  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
  updated to "a603bfb5a83e: E"
  1 other heads for branch "default"
  pulling from ./branch-H
  searching for changes
  adding changesets
  adding manifests
  adding file changes
  added 1 changesets with 1 changes to 1 files (+1 heads)
  new changesets 40faebb2ec45
  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
  updated to "a603bfb5a83e: E"
  2 other heads for branch "default"
  $ hg log -R test-repo-update -T '{desc} {rev}\n' --rev 'sort(all(), "topo")' -G
  o  H 7
  |
  | @  E 4
  | |
  | o  D 3
  |/
  o  C 2
  |
  | o  G 6
  | |
  | o  F 5
  |/
  o  B 1
  |
  o  A 0
  

update with conflicts
---------------------

  $ hg clone main-repo test-repo-conflict --rev 0
  adding changesets
  adding manifests
  adding file changes
  added 1 changesets with 1 changes to 1 files
  new changesets 4a2df7238c3b
  updating to branch default
  1 files updated, 0 files merged, 0 files removed, 0 files unresolved

The update has conflict and interrupt the pull.

  $ echo this-will-conflict > test-repo-conflict/D
  $ hg add -R test-repo-conflict test-repo-conflict/D
  $ hg log -R test-repo-conflict -T '{desc} {rev}\n' --rev 'sort(all(), "topo")' -G
  @  A 0
  
  $ hg pull -R test-repo-conflict ./branch-E ./branch-G ./branch-H --update
  pulling from ./branch-E
  searching for changes
  adding changesets
  adding manifests
  adding file changes
  added 4 changesets with 4 changes to 4 files
  new changesets 27547f69f254:a603bfb5a83e
  merging D
  warning: conflicts while merging D! (edit, then use 'hg resolve --mark')
  3 files updated, 0 files merged, 0 files removed, 1 files unresolved
  use 'hg resolve' to retry unresolved file merges
  [1]
  $ hg -R test-repo-conflict resolve -l
  U D
  $ hg log -R test-repo-conflict -T '{desc} {rev}\n' --rev 'sort(all(), "topo")' -G
  @  E 4
  |
  o  D 3
  |
  o  C 2
  |
  o  B 1
  |
  %  A 0