blob: 67c2b32dbc27f03fccbdc5737d1a20589fa8c6c9 [file] [log] [blame]
/*
* Copyright 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.dev.jjs.impl.codesplitter;
import com.google.gwt.dev.jjs.SourceOrigin;
import com.google.gwt.dev.jjs.ast.JNullLiteral;
import com.google.gwt.dev.jjs.ast.JRunAsync;
import com.google.gwt.thirdparty.guava.common.collect.Lists;
import junit.framework.TestCase;
import java.util.List;
/**
* Tests {@link FragmentPartitioningResult#getCommonAncestorFragmentId(int, int)}.
*/
public class FragmentPartitioningResultTest extends TestCase {
private final int NUM_RUNASYNCS = 10;
private final JRunAsync[] runAsyncs = new JRunAsync[NUM_RUNASYNCS + 1];
@Override
public void setUp() {
// Create some runAsyncs.
for (int i = 1; i <= NUM_RUNASYNCS; i++) {
runAsyncs[i] = new JRunAsync(SourceOrigin.UNKNOWN, i, "runAsync" + i, false,
JNullLiteral.INSTANCE, JNullLiteral.INSTANCE);
}
}
public void testBasics() {
// TODO(rluble): replace all this setup with mocks once mockito is in.
// Begin setup
List<JRunAsync> initialSequence = Lists.newArrayList(runAsyncs[4], runAsyncs[3], runAsyncs[2]);
List<Fragment> fragments = Lists.newArrayList();
// Create fragment 0 that is not associated with any runAsync and represent the code live
// from the entry point.
Fragment entryFragment = new Fragment(Fragment.Type.INITIAL);
entryFragment.setFragmentId(0);
fragments.add(entryFragment);
Fragment lastInitialFragment = entryFragment;
int nextId = 1;
for (JRunAsync runAsync : initialSequence) {
Fragment initialFragment = new Fragment(Fragment.Type.INITIAL, lastInitialFragment);
initialFragment.addRunAsync(runAsync);
initialFragment.setFragmentId(nextId++);
lastInitialFragment = initialFragment;
fragments.add(initialFragment);
}
// create leftover fragment
final int LEFTOVERS_ID = NUM_RUNASYNCS + 1;
Fragment leftoversFragment = new Fragment(Fragment.Type.NOT_EXCLUSIVE, lastInitialFragment);
leftoversFragment.setFragmentId(LEFTOVERS_ID);
// Create exclusive fragments.
for (JRunAsync runAsync : runAsyncs) {
if (runAsync == null || initialSequence.contains(runAsync)) {
continue;
}
Fragment exclusiveFragment = new Fragment(Fragment.Type.EXCLUSIVE, leftoversFragment);
exclusiveFragment.addRunAsync(runAsync);
assert nextId < LEFTOVERS_ID;
exclusiveFragment.setFragmentId(nextId++);
fragments.add(exclusiveFragment);
}
// leftover fragment is the last one.
// TODO(rluble): make fragment numbering independent to the load partial ordering.
fragments.add(leftoversFragment);
// End setup.
FragmentPartitioningResult fragmentPartitioningResult =
new FragmentPartitioningResult(fragments, NUM_RUNASYNCS);
// The closest common ancestor is itself.
assertEquals(0, fragmentPartitioningResult.getCommonAncestorFragmentId(0, 0));
assertEquals(1, fragmentPartitioningResult.getCommonAncestorFragmentId(1, 1));
assertEquals(3, fragmentPartitioningResult.getCommonAncestorFragmentId(3, 3));
assertEquals(6, fragmentPartitioningResult.getCommonAncestorFragmentId(6, 6));
assertEquals(11, fragmentPartitioningResult.getCommonAncestorFragmentId(11, 11));
// Lowest number in the initial sequence is the closest common ancestor.
assertEquals(0, fragmentPartitioningResult.getCommonAncestorFragmentId(11, 0));
assertEquals(0, fragmentPartitioningResult.getCommonAncestorFragmentId(10, 0));
assertEquals(0, fragmentPartitioningResult.getCommonAncestorFragmentId(3, 0));
// Initial sequence fragments load before all others
assertEquals(3, fragmentPartitioningResult.getCommonAncestorFragmentId(3, 10));
assertEquals(3, fragmentPartitioningResult.getCommonAncestorFragmentId(10, 3));
// Earlier initial sequence fragments load before the others
assertEquals(1, fragmentPartitioningResult.getCommonAncestorFragmentId(1, 2));
assertEquals(1, fragmentPartitioningResult.getCommonAncestorFragmentId(2, 1));
assertEquals(2, fragmentPartitioningResult.getCommonAncestorFragmentId(2, 3));
// For non-equal exclusive fragments, leftovers is the common predecessor
assertEquals(LEFTOVERS_ID, fragmentPartitioningResult.getCommonAncestorFragmentId(6, 8));
assertEquals(LEFTOVERS_ID, fragmentPartitioningResult.getCommonAncestorFragmentId(9, 8));
// Leftovers is before any exclusive
assertEquals(LEFTOVERS_ID, fragmentPartitioningResult.getCommonAncestorFragmentId(LEFTOVERS_ID, 8));
// Inintial are before leftover
assertEquals(1, fragmentPartitioningResult.getCommonAncestorFragmentId(LEFTOVERS_ID, 1));
}
public void testWithEmptyInitial() {
// TODO(rluble): replace all this setup with mocks once mockito is in.
// Begin setup
List<Fragment> fragments = Lists.newArrayList();
// Create fragment 0 that is not associated with any runAsync and represent the code live
// from the entry point.
Fragment entryFragment = new Fragment(Fragment.Type.INITIAL);
entryFragment.setFragmentId(0);
fragments.add(entryFragment);
Fragment lastInitialFragment = entryFragment;
int nextId = 1;
// create leftover fragment
final int LEFTOVERS_ID = NUM_RUNASYNCS + 1;
Fragment leftoversFragment = new Fragment(Fragment.Type.NOT_EXCLUSIVE, lastInitialFragment);
leftoversFragment.setFragmentId(LEFTOVERS_ID);
// Create exclusive fragments.
for (JRunAsync runAsync : runAsyncs) {
if (runAsync == null) {
continue;
}
Fragment exclusiveFragment = new Fragment(Fragment.Type.EXCLUSIVE, leftoversFragment);
exclusiveFragment.addRunAsync(runAsync);
assert nextId < LEFTOVERS_ID;
exclusiveFragment.setFragmentId(nextId++);
fragments.add(exclusiveFragment);
}
// leftover fragment is the last one.
// TODO(rluble): make fragment numbering independent to the load partial ordering.
fragments.add(leftoversFragment);
// End setup.
FragmentPartitioningResult fragmentPartitioningResult =
new FragmentPartitioningResult(fragments, NUM_RUNASYNCS);
// The closest common ancestor is itself.
assertEquals(0, fragmentPartitioningResult.getCommonAncestorFragmentId(0, 0));
assertEquals(1, fragmentPartitioningResult.getCommonAncestorFragmentId(1, 1));
assertEquals(3, fragmentPartitioningResult.getCommonAncestorFragmentId(3, 3));
assertEquals(6, fragmentPartitioningResult.getCommonAncestorFragmentId(6, 6));
assertEquals(11, fragmentPartitioningResult.getCommonAncestorFragmentId(11, 11));
// Lowest number in the initial sequence is the closest common ancestor.
assertEquals(0, fragmentPartitioningResult.getCommonAncestorFragmentId(11, 0));
assertEquals(0, fragmentPartitioningResult.getCommonAncestorFragmentId(10, 0));
assertEquals(0, fragmentPartitioningResult.getCommonAncestorFragmentId(3, 0));
// For non-equal exclusive fragments, leftovers is the common predecessor
assertEquals(LEFTOVERS_ID, fragmentPartitioningResult.getCommonAncestorFragmentId(6, 8));
assertEquals(LEFTOVERS_ID, fragmentPartitioningResult.getCommonAncestorFragmentId(9, 8));
// Leftovers is before any exclusive
assertEquals(LEFTOVERS_ID, fragmentPartitioningResult.getCommonAncestorFragmentId(LEFTOVERS_ID, 8));
// Inintial are before leftover
assertEquals(0, fragmentPartitioningResult.getCommonAncestorFragmentId(LEFTOVERS_ID, 0));
}
}