Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 339990 - [Repo view] Module disappears in CVS Repositories view
Summary: [Repo view] Module disappears in CVS Repositories view
Status: VERIFIED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: CVS (show other bugs)
Version: 3.7   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.8 M3   Edit
Assignee: Malgorzata Janczarska CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on: 360532
Blocks: 361926 361927 361928 361930 366016
  Show dependency tree
 
Reported: 2011-03-15 06:03 EDT by Krzysztof Daniel CLA
Modified: 2012-01-23 14:54 EST (History)
6 users (show)

See Also:
tomasz.zarna: review+


Attachments
test which does not fail (3.71 KB, patch)
2011-05-12 08:01 EDT, Krzysztof Daniel CLA
no flags Details | Diff
patch caching only the first segment (968 bytes, patch)
2011-08-12 11:25 EDT, Malgorzata Janczarska CLA
no flags Details | Diff
Test that fails (4.93 KB, patch)
2011-08-31 10:08 EDT, Malgorzata Janczarska CLA
no flags Details | Diff
test (46.68 KB, patch)
2011-09-02 08:41 EDT, Malgorzata Janczarska CLA
no flags Details | Diff
test (4.56 KB, patch)
2011-09-16 10:34 EDT, Malgorzata Janczarska CLA
no flags Details | Diff
fix with test (7.19 KB, text/plain)
2011-10-04 13:58 EDT, Malgorzata Janczarska CLA
no flags Details
fix with tests (7.80 KB, patch)
2011-10-11 09:17 EDT, Malgorzata Janczarska CLA
no flags Details | Diff
fix with tests (7.86 KB, patch)
2011-10-11 09:25 EDT, Malgorzata Janczarska CLA
no flags Details | Diff
fix with tests (9.67 KB, patch)
2011-10-13 09:45 EDT, Malgorzata Janczarska CLA
no flags Details | Diff
fix with tests (8.69 KB, patch)
2011-10-14 03:20 EDT, Malgorzata Janczarska CLA
no flags Details | Diff
verification result (70.31 KB, image/png)
2011-10-18 08:26 EDT, Krzysztof Daniel CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Krzysztof Daniel CLA 2011-03-15 06:03:21 EDT
Steps:
1. Create a project.
2. Share it in a module, so the path to the project is like 'CVSROOT/TestModule/TestProject'
3. Create a branch

IS: a branch contains a project tagged with the branch name
SHOULD BE: a branch contains module tagged with the branch name and the project as a module child.

Refreshing branches causes the TestModule to be added next to the project name, so the view is practically unusable - it offers informations without real value.

+ Branches
  + Branch1
    + Project Branch1
    + TestModule Branch1
      + Project

Important: if you delete and add the repo (it involves closing/disconnecting workspace projects) the branches will be rendered properly till the next branching is performed.
Comment 1 Krzysztof Daniel CLA 2011-03-15 07:54:35 EDT
The first issue I have found is that the information about module tag is not stored anywhere. That's why the module does not appear until the refresh is finished.

The separate issue is why the projects are displayed - situation may change if information about the module tag will be properly processed.
Comment 2 Krzysztof Daniel CLA 2011-05-11 06:39:46 EDT
Tomasz,

could you look into that and suggest where to start?
Comment 3 Tomasz Zarna CLA 2011-05-11 07:28:58 EDT
I would start from looking at RepositoriesView and its content provider - RemoteContentProvider. Any chances for a test case?
Comment 4 Krzysztof Daniel CLA 2011-05-11 09:07:12 EDT
The steps are described in the beginning of the bug report.


When you browse the repo, all information about modules and branches are retrieved and cached. Each project is identified by module/project path, and everything is correctly rendered.

+ Branches
  + Branch1
     + TestModule Branch1
        + Project

Then branching happens. Only projects are branched, and projects in Eclipse have only project name, not module/project. So Eclipse caches project/branch, and when display happens, following structure is presented:

+ Branches
  + Branch2
     + Project Branch2

The module has been skipped, because in the cache there are only projects without modules. If you refresh the repo, you will get something like:

+ Branches
  + Branch2
     + Project Branch2
     + TestModule Branch2
       + Project

Changes are merged. Cached local resources are not equal to the remote one, because local => project, and remote => module/project.

So the cause is more or less known. The question is what to do next.
Comment 5 Tomasz Zarna CLA 2011-05-11 13:00:33 EDT
(In reply to comment #4)
> The steps are described in the beginning of the bug report.

I was referring to a JUnit test case, failing at the moment.
Comment 6 Krzysztof Daniel CLA 2011-05-12 08:01:12 EDT
Created attachment 195490 [details]
test which does not fail

I tried to come up with a testcase but it worked properly - a module is a child of the branch.

The difference may be related to the way in which resources are mapped. 

I am off tomorrow.
Comment 7 Szymon Brandys CLA 2011-06-28 11:01:29 EDT
Changing the assignee to match the reality. Krzysztof, AFAIK it should be fixed in the nearest future.
Comment 8 Szymon Ptaszkiewicz CLA 2011-06-29 04:02:45 EDT
Krzysztof is not going to work on it. I will take it.
Comment 9 Szymon Brandys CLA 2011-06-29 04:41:37 EDT
(In reply to comment #8)
> Krzysztof is not going to work on it. I will take it.
Thanks :-)
Comment 10 Malgorzata Janczarska CLA 2011-06-29 07:43:38 EDT
I'll have a look at it.
Comment 11 Malgorzata Janczarska CLA 2011-08-12 11:15:06 EDT
I think that the problem is indeed in caching. Look at RepositoryRoot#addTags(String, CVSTag[]). It adds tags for given path to cache. It's javadoc says:
"Accept the tags for any remote path that represents a folder. However, for the time being, the given version tags are added to the list of known tags for the remote ancestor of the resource that is a direct child of the remote root."
The way I understand this sentence is that we store only direct children of remote root. That's why it works correctly for projects that are situated in the module top level. But when we add (from the comment 0) "TestModule/TestProject" this is not a direct child of the remote root. To be consistent with the javadoc we should add "TestModule" only. If we had project in a module like this: "TestModule/TestSubmodule/TestProject" we should also add "TestModule" only.
Comment 12 Malgorzata Janczarska CLA 2011-08-12 11:25:35 EDT
Created attachment 201405 [details]
patch caching only the first segment

This patch solves the problem. It adds the first segment of the path to the cache, not the full path. The path separators are "/" and "\".
Comment 13 Tomasz Zarna CLA 2011-08-16 05:10:19 EDT
(In reply to comment #12)
> This patch solves the problem. It adds the first segment of the path to the
> cache, not the full path. The path separators are "/" and "\".

The doc on org.eclipse.team.internal.ccvs.ui.repo.RepositoryRoot.addTags(String, CVSTag[]) also says that "It is the responsibility of the caller to ensure that the given remote path is valid." and your patch changes that by allowing the caller to provide a path which is not precise. IMO we should either change the doc or fix the caller so it provides a proper value.

Moreover, a test case would be nice to have. The one provided by Krzysztof in comment 6 could be a good start, but it's not very useful in its current shape. It passes even without a fix.
Comment 14 Malgorzata Janczarska CLA 2011-08-30 14:13:55 EDT
(In reply to comment #13)
> The doc on org.eclipse.team.internal.ccvs.ui.repo.RepositoryRoot.addTags(String,
> CVSTag[]) also says that "It is the responsibility of the caller to ensure that
> the given remote path is valid." and your patch changes that by allowing the
> caller to provide a path which is not precise. IMO we should either change the
> doc or fix the caller so it provides a proper value.
I have to say that I understand this comment differently. We want to add a tag for a resource of a given path, this *is* a correct path. The caller made sure that resource under this path really exists. However the rest of the javadoc says that for the time being we store only information about tags for top folder in the repository. So adding the full path is incorrect, because this is not the path of the top folder. As javadoc says that the solution of storing tags for the top folders is "for the time being" I believe it's better to leave callers passing full paths of the resources, because it seems that someday in future we will really store tags more detailed, for every resource. I suppose it's not a bad idea to rewrite javadoc to be more unambiguous.
Comment 15 Malgorzata Janczarska CLA 2011-08-31 10:08:20 EDT
Created attachment 202528 [details]
Test that fails
Comment 16 Tomasz Zarna CLA 2011-09-01 07:54:55 EDT
(In reply to comment #15)
> Created attachment 202528 [details]
> Test that fails

Quick comment:
* There is no "folder1/b.txt" file in the test project at the time you're trying to delete it.
* Do we actually need to make any changes to create a branch?
* Do you really need moduleName and branchName to be fields? Limiting scope is good.
* How many elements do you expect to be returned from RemoteContentProvider? Isn't it always 1? If so, I would skip the loop.
* Since you're using a content provider to verify if the the branch is properly created I think we could consider moving the test to the "ui" package.
Comment 17 Malgorzata Janczarska CLA 2011-09-02 08:41:11 EDT
Created attachment 202665 [details]
test

> Quick comment:
> * There is no "folder1/b.txt" file in the test project at the time you're trying
> to delete it.
corrected.
> * Do we actually need to make any changes to create a branch?
the branch is not created if there are no changes
> * Do you really need moduleName and branchName to be fields? Limiting scope is
> good.
corrected
> * How many elements do you expect to be returned from RemoteContentProvider?
> Isn't it always 1? If so, I would skip the loop.
What if there are more than one repository defined in the workspace? Then there would be more elements.
> * Since you're using a content provider to verify if the the branch is properly
> created I think we could consider moving the test to the "ui" package.
done
Comment 18 Tomasz Zarna CLA 2011-09-12 10:57:13 EDT
(In reply to comment #17)
> What if there are more than one repository defined in the workspace? Then there
> would be more elements.

As long as tests are run in isolation such case should not take place.
Comment 19 Malgorzata Janczarska CLA 2011-09-16 10:34:21 EDT
Created attachment 203490 [details]
test

So if we always have one repository in tests than we can skip the loop.
Comment 20 Tomasz Zarna CLA 2011-10-03 07:49:07 EDT
To be honest, I don't like that we're using only the first segment of the remote path as the cache key, but given the fact that this is how refreshing works I think it's the easiest way to fix it. The patch works and it's definitely heads in the right direction, I would change couple things:
* update the comment on org.eclipse.team.internal.ccvs.ui.repo.RepositoryRoot.getCachePathFor(String)
* the body could be simplified to return new Path(remotePath).segment(0);
* add a similar test for tagging
* name them with something like "testBranchSubmoduleChildren"
* in the test, instead of calling #collectBranchChildren I would add a sequence of easy to read checks:

// check if module is the only branch child
RemoteContentProvider rcp = new RemoteContentProvider();
AllRootsElement are = new AllRootsElement();
Object[] repositoryRoots = rcp.getElements(are);
assertEquals(1, repositoryRoots.length);
Object[] categories = rcp.getChildren(repositoryRoots[0]);
assertEquals(4, categories.length);
assertTrue(categories[1] instanceof BranchCategory);
Object[] tags = rcp.getChildren(categories[1]);
assertEquals(1, tags.length);
assertTrue(tags[0] instanceof CVSTagElement);
assertEquals(branchName, ((CVSTagElement) tags[0]).getTag().getName());
Object[] modules = rcp.getChildren(tags[0]);
assertEquals(1, modules.length);
assertTrue(modules[0] instanceof RemoteResource);
assertEquals(moduleName, ((RemoteResource) modules[0]).getName());
		
or even simpler:
//...
assertEquals(moduleName, ((RemoteResource) rcp.getChildren(tags[0])[0]).getName());
Comment 21 Malgorzata Janczarska CLA 2011-10-04 13:58:11 EDT
Created attachment 204535 [details]
fix with test

(In reply to comment #20)
> * update the comment on
> org.eclipse.team.internal.ccvs.ui.repo.RepositoryRoot.getCachePathFor(String)
done
> * the body could be simplified to return new Path(remotePath).segment(0);
done
> * add a similar test for tagging
done
> * name them with something like "testBranchSubmoduleChildren"
done
> * in the test, instead of calling #collectBranchChildren I would add a sequence
> of easy to read checks:
> [...] 
> rcp.getChildren(tags[0])[0]).getName());

I wanted to keep on the safe site so I didn't rely on the tree structure, but I suppose you're right that it's well defined. I agree with everything but one: you assumed that our branch will be the only branch in the tree. This is true if branches cache was empty at the begining, but I don't think it's cleaned before every test, so there might be some more branches in it. So I added iteration though branches and I'm looking for our branch by name.
Comment 22 Tomasz Zarna CLA 2011-10-05 09:48:19 EDT
(In reply to comment #21)
> you assumed that our branch will be the only branch in the tree. This is true if
> branches cache was empty at the begining, but I don't think it's cleaned before
> every test, so there might be some more branches in it

Good point. If it's trivial I would clean up the cache in a #setUp(). This way we will be able to focus on the case being tested and not on navigating thru other test leftovers. 

I'm not sure if this is just me, but after applying the latest patch I get 2 errors complaining about a local variable not used. Please check your Java>Compiler>Error/Warnings settings.

There is a typo in both tests: "brancheExists" should be "branchExists". But you can ignore it once #setUp() is added. Moreover, in the second test the variable should be about tag not branch. "// refresh branches" is not the best choice in #testTagSubmoduleChildren(). These are probably copy-paste typos. You could also consider extracting those few lines with assertions into a method common for both test cases.

Out of curiosity, why didn't you use Path(String) in RepositoryRoot.getCachePathFor(String)?
Comment 23 Tomasz Zarna CLA 2011-10-07 08:22:35 EDT
From our offline discussion I remember we were worried what would happen if you removed a branch/tag which had been used for more then one project under a module. Our first guess was that all projects for the given tag/branch will be removed from the cache even if we meant to remove only one of them. After looking at the code I can see that removing a tag can only happen when you're moving it (replacing) so the cache content should be fine. 

That finding and the fact we always display all folders under a selected module no matter if they were branched with the given branch name or not lead me to a conclusion that your patch is fine. I mean, once my comments from comment 22 are applied.
Comment 24 Malgorzata Janczarska CLA 2011-10-11 09:17:55 EDT
Created attachment 204949 [details]
fix with tests
Comment 25 Malgorzata Janczarska CLA 2011-10-11 09:25:56 EDT
Created attachment 204950 [details]
fix with tests
Comment 26 Malgorzata Janczarska CLA 2011-10-11 09:34:28 EDT
(In reply to comment #22)
> Good point. If it's trivial I would clean up the cache in a #setUp(). This way
> we will be able to focus on the case being tested and not on navigating thru
> other test leftovers.
This was not so trivial, but I've created new Test suite and it's done only for tests that test RepositoryView.

> 
> I'm not sure if this is just me, but after applying the latest patch I get 2
> errors complaining about a local variable not used. Please check your
> Java>Compiler>Error/Warnings settings.

Sorry about that. My settings were fine, but there had to be a bug in one of the nightly builds. I've upgraded my Eclipse and it started to show unused variables errors again.

> There is a typo in both tests: "brancheExists" should be "branchExists". But you
> can ignore it once #setUp() is added. Moreover, in the second test the variable
> should be about tag not branch. "// refresh branches" is not the best choice in
> #testTagSubmoduleChildren(). These are probably copy-paste typos. You could also
> consider extracting those few lines with assertions into a method common for
> both test cases.

This was not a typo. I was tagging the project by branch. From our offline discussion I know you wanted it to be tagged by version. I modified the test and we have it now, but it doesn't really check this error, because versions weren't cached anyway. But while writing it I discovered bug 360532.

> Out of curiosity, why didn't you use Path(String) in
> RepositoryRoot.getCachePathFor(String)?

I found that a few years back it was used in this very same place. The change that caused this bug was made with only explanation in the comment to RepositoryRoot.getCachePathFor(String) (no bug for it). The explanation said that it's to "better support subdirectories", however from this bug we can see that our CVS support is not ready for it, so this bug is actually reverting a very old change.
Comment 27 Tomasz Zarna CLA 2011-10-13 07:07:08 EDT
Both tests fail when the test case is run as part of a larger suite (e.g. CVS UI Tests.launched). Actually, the test case is not added to the AllUITests.java so I had to do that first. The message is the same for both:

junit.framework.AssertionFailedError: expected:<1> but was:<2>
	at junit.framework.Assert.fail(Assert.java:47)
	at junit.framework.Assert.failNotEquals(Assert.java:283)
	at junit.framework.Assert.assertEquals(Assert.java:64)
	at junit.framework.Assert.assertEquals(Assert.java:195)
	at junit.framework.Assert.assertEquals(Assert.java:201)
	at org.eclipse.team.tests.ccvs.ui.RepositoriesViewTests.getRepositoryRoot(RepositoriesViewTests.java:54)
	at org.eclipse.team.tests.ccvs.ui.RepositoriesViewTests.setUp(RepositoriesViewTests.java:43)
[...]

Other then that the patch looks good.
Comment 28 Malgorzata Janczarska CLA 2011-10-13 09:45:34 EDT
Created attachment 205121 [details]
fix with tests

There were two repositories in the workspace. Probably one of them was left by one of previous tests. I've added searching for our repository and tests pass.
Comment 29 Tomasz Zarna CLA 2011-10-13 12:23:08 EDT
I'm not able to apply your latest patch, please use the git repo.
Comment 30 Malgorzata Janczarska CLA 2011-10-14 03:20:28 EDT
Created attachment 205178 [details]
fix with tests

Corrected, it conflicted with fix for bug 360532.
Comment 31 Tomasz Zarna CLA 2011-10-14 05:32:38 EDT
The latest patch + some minor changes = 960dba32547fb75ebcb6cd0310340f23c6e61b62. The fix will be available in builds >=N20111014-2000. 

Krzysztof, could you please grab one of these and verify the fix?
Comment 32 Malgorzata Janczarska CLA 2011-10-14 09:11:18 EDT
While fixing it I found another bug: bug 360959. It is unrelated to this fix, but this fix has improved it a little.
Comment 33 Krzysztof Daniel CLA 2011-10-18 08:26:46 EDT
Created attachment 205420 [details]
verification result

At first glance, everything looks fine.

I have a module "testdocs" and three projects (TestProject with branch, TestProject2 with testbrunch and TestProject3 with testbranch). 

After branching, a proper module appears, and the tree structure is correct, but after branch refresh, all three projects are visible for all branches. 

If you try to checkout a project from a branch that does not exist, the project is empty.
Comment 34 Malgorzata Janczarska CLA 2011-10-18 09:53:42 EDT
(In reply to comment #33)
> After branching, a proper module appears, and the tree structure is correct,
> but after branch refresh, all three projects are visible for all branches. 
This happened also before this fix. This is how we work in this view: we get a directory that contains given tag and then we return its content no meter if it's tagged or not.

For the example from comment 0 if we had also /TestModule/Project2 that is not branched we would see:
+ Branches
  + Branch1
    + Project Branch1
    + TestModule Branch1
      + Project
      + Project2

and now we get:

+ Branches
  + Branch1
    + TestModule Branch1
      + Project
      + Project2

> If you try to checkout a project from a branch that does not exist, the project
> is empty.
This is expected, it always happens when you checkout a branch for a project that does not exist for this project.
Comment 35 Krzysztof Daniel CLA 2011-10-25 09:13:44 EDT
Marking as verified, as the problematic scenario is solved and works for me.
Comment 36 Szymon Brandys CLA 2012-01-23 05:34:04 EST
(In reply to comment #35)
> Marking as verified, as the problematic scenario is solved and works for me.

The fix for the bug caused a regression, see bug 339990.
Comment 37 Tomasz Zarna CLA 2012-01-23 14:43:27 EST
(In reply to comment #36)
> The fix for the bug caused a regression, see bug 339990.

It should read "bug 366016".
Comment 38 Tomasz Zarna CLA 2012-01-23 14:54:11 EST
See also bug 360959.