view tests/test-fix-topology.t @ 37187:03ff17a4bf53

infinitepush: move the extension to core from fb-hgext This patch moves the infinitepush extension from fb-hgext to core. The extension is used to store incoming bundles during a push in bundlestore rather than applying them to the revlog. The extension was copied from the repository revision at f27f094e91553d3cae5167c0b1c42ae940f888d5 and following changes were made: * added `from __future__ import absolute_import` where missing * fixed module imports to follow the core style * minor fixes for test-check-code.t * registered the configs * adding the testedwith value to match core's convention * removed double newlines to make test-check-commit.t happy * added one line doc about extension and marked it as experimental Only one test file test-infinitepush-bundlestore.t is moved to core and following changes are made to file: * remove dependency of library.sh * split the tests into two tests i.e. test-infinitepush.t and test-infinitepush-bundlestore.t * removed testing related to other facebook's extensions pushrebase, inhibit, fbamend library-infinitepush.sh is also copied from fb-hgext from the same revision and following changes are made: * change the path to infinitepush extension as it's in core with this patch * removed sql handling from the file as we are not testing that initially Currently at this revision, test-check-module-imports.t does not pass as there is import of a module from fb/hgext in one the of the file which will be removed in the next patch. This extension right now has a lot of things which we don't require in core like `--to`, `--create` flags to `hg bookmark`, logic related to remotenames extension and another facebook's extensions, custom bundle2parts which can be prevented by using bookmarks bundle part and also logic related to sql store which is probably we don't want initially. The next patches in this series will remove all the unwanted and unrequired things from the extension and will make this a nice one. The end goal is to have a very lighweight extension with no or very less wrapping on the client side. Differential Revision: https://phab.mercurial-scm.org/D2096
author Pulkit Goyal <7895pulkit@gmail.com>
date Fri, 09 Feb 2018 13:39:15 +0530
parents ded5ea279a93
children 41ba336d9f1e
line wrap: on
line source

Tests for the fix extension's behavior around non-trivial history topologies.
Looks for correct incremental fixing and reproduction of parent/child
relationships. We indicate fixed file content by uppercasing it.

  $ cat >> $HGRCPATH <<EOF
  > [extensions]
  > fix =
  > [fix]
  > uppercase-whole-file:command=sed -e 's/.*/\U&/'
  > uppercase-whole-file:fileset=set:**
  > EOF

This tests the only behavior that should really be affected by obsolescence, so
we'll test it with evolution off and on. This only changes the revision
numbers, if all is well.

#testcases obsstore-off obsstore-on
#if obsstore-on
  $ cat >> $HGRCPATH <<EOF
  > [experimental]
  > evolution.createmarkers=True
  > evolution.allowunstable=True
  > EOF
#endif

Setting up the test topology. Scroll down to see the graph produced. We make it
clear which files were modified in each revision. It's enough to test at the
file granularity, because that demonstrates which baserevs were diffed against.
The computation of changed lines is orthogonal and tested separately.

  $ hg init repo
  $ cd repo

  $ printf "aaaa\n" > a
  $ hg commit -Am "change A"
  adding a
  $ printf "bbbb\n" > b
  $ hg commit -Am "change B"
  adding b
  $ printf "cccc\n" > c
  $ hg commit -Am "change C"
  adding c
  $ hg checkout 0
  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
  $ printf "dddd\n" > d
  $ hg commit -Am "change D"
  adding d
  created new head
  $ hg merge -r 2
  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
  (branch merge, don't forget to commit)
  $ printf "eeee\n" > e
  $ hg commit -Am "change E"
  adding e
  $ hg checkout 0
  0 files updated, 0 files merged, 4 files removed, 0 files unresolved
  $ printf "ffff\n" > f
  $ hg commit -Am "change F"
  adding f
  created new head
  $ hg checkout 0
  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
  $ printf "gggg\n" > g
  $ hg commit -Am "change G"
  adding g
  created new head
  $ hg merge -r 5
  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  (branch merge, don't forget to commit)
  $ printf "hhhh\n" > h
  $ hg commit -Am "change H"
  adding h
  $ hg merge -r 4
  4 files updated, 0 files merged, 0 files removed, 0 files unresolved
  (branch merge, don't forget to commit)
  $ printf "iiii\n" > i
  $ hg commit -Am "change I"
  adding i
  $ hg checkout 2
  0 files updated, 0 files merged, 6 files removed, 0 files unresolved
  $ printf "jjjj\n" > j
  $ hg commit -Am "change J"
  adding j
  created new head
  $ hg checkout 7
  3 files updated, 0 files merged, 3 files removed, 0 files unresolved
  $ printf "kkkk\n" > k
  $ hg add
  adding k

  $ hg log --graph --template '{rev} {desc}\n'
  o  9 change J
  |
  | o    8 change I
  | |\
  | | @    7 change H
  | | |\
  | | | o  6 change G
  | | | |
  | | o |  5 change F
  | | |/
  | o |  4 change E
  |/| |
  | o |  3 change D
  | |/
  o |  2 change C
  | |
  o |  1 change B
  |/
  o  0 change A
  

Fix all but the root revision and its four children.

#if obsstore-on
  $ hg fix -r '2|4|7|8|9' --working-dir
#else
  $ hg fix -r '2|4|7|8|9' --working-dir
  saved backup bundle to * (glob)
#endif

The five revisions remain, but the other revisions were fixed and replaced. All
parent pointers have been accurately set to reproduce the previous topology
(though it is rendered in a slightly different order now).

#if obsstore-on
  $ hg log --graph --template '{rev} {desc}\n'
  o  14 change J
  |
  | o    13 change I
  | |\
  | | @    12 change H
  | | |\
  | o | |  11 change E
  |/| | |
  o | | |  10 change C
  | | | |
  | | | o  6 change G
  | | | |
  | | o |  5 change F
  | | |/
  | o /  3 change D
  | |/
  o /  1 change B
  |/
  o  0 change A
  
  $ C=10
  $ E=11
  $ H=12
  $ I=13
  $ J=14
#else
  $ hg log --graph --template '{rev} {desc}\n'
  o  9 change J
  |
  | o    8 change I
  | |\
  | | @    7 change H
  | | |\
  | o | |  6 change E
  |/| | |
  o | | |  5 change C
  | | | |
  | | | o  4 change G
  | | | |
  | | o |  3 change F
  | | |/
  | o /  2 change D
  | |/
  o /  1 change B
  |/
  o  0 change A
  
  $ C=5
  $ E=6
  $ H=7
  $ I=8
  $ J=9
#endif

Change C is a root of the set being fixed, so all we fix is what has changed
since its parent. That parent, change B, is its baserev.

  $ hg cat -r $C 'set:**'
  aaaa
  bbbb
  CCCC

Change E is a merge with only one parent being fixed. Its baserevs are the
unfixed parent plus the baserevs of the other parent. This evaluates to changes
B and D. We now have to decide what it means to incrementally fix a merge
commit. We choose to fix anything that has changed versus any baserev. Only the
undisturbed content of the common ancestor, change A, is unfixed.

  $ hg cat -r $E 'set:**'
  aaaa
  BBBB
  CCCC
  DDDD
  EEEE

Change H is a merge with neither parent being fixed. This is essentially
equivalent to the previous case because there is still only one baserev for
each parent of the merge.

  $ hg cat -r $H 'set:**'
  aaaa
  FFFF
  GGGG
  HHHH

Change I is a merge that has four baserevs; two from each parent. We handle
multiple baserevs in the same way regardless of how many came from each parent.
So, fixing change H will fix any files that were not exactly the same in each
baserev.

  $ hg cat -r $I 'set:**'
  aaaa
  BBBB
  CCCC
  DDDD
  EEEE
  FFFF
  GGGG
  HHHH
  IIII

Change J is a simple case with one baserev, but its baserev is not its parent,
change C. Its baserev is its grandparent, change B.

  $ hg cat -r $J 'set:**'
  aaaa
  bbbb
  CCCC
  JJJJ

The working copy was dirty, so it is treated much like a revision. The baserevs
for the working copy are inherited from its parent, change H, because it is
also being fixed.

  $ cat *
  aaaa
  FFFF
  GGGG
  HHHH
  KKKK

Change A was never a baserev because none of its children were to be fixed.

  $ cd ..