Parallelize PlatformAbstraction image loading tests 31/31231/5
authorAndrew Cox <andrew.cox@partner.samsung.com>
Tue, 2 Dec 2014 22:21:25 +0000 (22:21 +0000)
committerAndrew Cox <andrew.cox@partner.samsung.com>
Wed, 3 Dec 2014 17:28:55 +0000 (17:28 +0000)
Broke them into three test cases so they can run in parallel.
Sped them up a bit individually.
Made all three test harness apps work with a number of test cases < the
parallel batch size.

Change-Id: Iafdb26772f35154e4ade092650b3fc23cc168cd6
Signed-off-by: Andrew Cox <andrew.cox@partner.samsung.com>
14 files changed:
automated-tests/src/dali-adaptor-internal/tct-dali-adaptor-internal-core.cpp
automated-tests/src/dali-adaptor/tct-dali-adaptor-core.cpp
automated-tests/src/dali-platform-abstraction/CMakeLists.txt
automated-tests/src/dali-platform-abstraction/resource-collector.cpp
automated-tests/src/dali-platform-abstraction/resource-collector.h
automated-tests/src/dali-platform-abstraction/tct-dali-platform-abstraction-core.cpp
automated-tests/src/dali-platform-abstraction/utc-image-loading-cancel-all-loads.cpp [new file with mode: 0644]
automated-tests/src/dali-platform-abstraction/utc-image-loading-cancel-some-loads.cpp [new file with mode: 0644]
automated-tests/src/dali-platform-abstraction/utc-image-loading-common.cpp [new file with mode: 0644]
automated-tests/src/dali-platform-abstraction/utc-image-loading-common.h [new file with mode: 0644]
automated-tests/src/dali-platform-abstraction/utc-image-loading-load-completion.cpp [new file with mode: 0644]
automated-tests/src/dali-platform-abstraction/utc-image-loading.cpp [deleted file]
platform-abstractions/slp/resource-loader/resource-loader.cpp
platform-abstractions/slp/resource-loader/resource-loader.h

index f90b8ef..69062a2 100644 (file)
@@ -78,7 +78,7 @@ int RunAllInParallel(const char* processName, bool reRunFailed)
   {
     if( nextTestCase < numTestCases )
     {
-      while( numRunningChildren < MAX_NUM_CHILDREN )
+      while( numRunningChildren < MAX_NUM_CHILDREN && nextTestCase < numTestCases )
       {
         int pid = fork();
         if( pid == 0 ) // Child process
index 90b7203..aabf91f 100644 (file)
@@ -78,7 +78,7 @@ int RunAllInParallel(const char* processName, bool reRunFailed)
   {
     if( nextTestCase < numTestCases )
     {
-      while( numRunningChildren < MAX_NUM_CHILDREN )
+      while( numRunningChildren < MAX_NUM_CHILDREN && nextTestCase < numTestCases )
       {
         int pid = fork();
         if( pid == 0 ) // Child process
index be41232..ce1a854 100644 (file)
@@ -6,13 +6,16 @@ SET(RPM_NAME "core-${PKG_NAME}-tests")
 SET(CAPI_LIB "dali-platform-abstraction")
 
 SET(TC_SOURCES
-    utc-image-loading.cpp
+    utc-image-loading-load-completion.cpp
+    utc-image-loading-cancel-all-loads.cpp
+    utc-image-loading-cancel-some-loads.cpp
 )
 
 LIST(APPEND TC_SOURCES
     resource-collector.cpp
     ../dali-adaptor/dali-test-suite-utils/dali-test-suite-utils.cpp
     tct-dali-platform-abstraction-core.cpp
+    utc-image-loading-common.cpp
 )
 
 PKG_CHECK_MODULES(${CAPI_LIB} REQUIRED
index 7d78fb1..bf95844 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include "resource-collector.h"
+#include "slp-platform-abstraction.h"
 #include <dali/integration-api/debug.h>
 
 namespace Dali
@@ -27,7 +28,8 @@ namespace Platform
 using namespace Dali::Integration;
 
 ResourceCollector::ResourceCollector() :
-  mGrandTotalCompletions(0)
+  mGrandTotalCompletions(0),
+  mGrandTotalNotifications(0)
 {
 }
 
@@ -35,6 +37,7 @@ ResourceCollector::~ResourceCollector() {}
 
 void ResourceCollector::LoadResponse( Dali::Integration::ResourceId id, Dali::Integration::ResourceTypeId type, Dali::Integration::ResourcePointer resource, Dali::Integration::LoadStatus status )
 {
+  ++mGrandTotalNotifications;
   if( status == RESOURCE_COMPLETELY_LOADED )
   {
     DALI_ASSERT_DEBUG( mCompletionCounts.find(id) == mCompletionCounts.end() && "A resource can only complete once." );
@@ -52,8 +55,23 @@ void ResourceCollector::LoadFailed( Dali::Integration::ResourceId id, Dali::Inte
   ++mFailureCounts[id];
   mCompletionSequence.push_back( id );
   ++mGrandTotalCompletions;
+  ++mGrandTotalNotifications;
 }
 
+void PollForNotification( ResourceCollector& collector, Integration::PlatformAbstraction&  abstraction, const unsigned maxPolls )
+{
+  // Poll for at least one completed or partially completed load:
+  const unsigned outstandingNotifications = collector.mGrandTotalNotifications;
+  for( unsigned poll = 0; poll < maxPolls; ++poll )
+  {
+    abstraction.GetResources( collector );
+    if( collector.mGrandTotalNotifications > outstandingNotifications )
+    {
+      break;
+    }
+    usleep( 3 ); //< Wait 3 microseconds each time around.
+  }
+}
 
 } /* namespace Platform */
 } /* namespace Internal */
index 8553e62..b4593ec 100644 (file)
 
 namespace Dali
 {
+
+namespace Integration
+{
+class PlatformAbstraction;
+}
+
 namespace Internal
 {
 namespace Platform
@@ -73,9 +79,17 @@ public:
   ResourceSequence mCompletionSequence;
   /** Count of all successes and failures.*/
   unsigned mGrandTotalCompletions;
+  /** Count of all successes, failures, loading notifications and partially loaded notifications.*/
+  unsigned mGrandTotalNotifications;
 
 };
 
+/**
+ * Helper to poll the abstraction for notifications assuming loads have been
+ * issued to it previously and are in-flight.
+ */
+void PollForNotification( ResourceCollector& collector, Integration::PlatformAbstraction&  abstraction, const unsigned maxPolls = 100 );
+
 } /* namespace Platform */
 } /* namespace Internal */
 } /* namespace Dali */
index 6636584..4bf95fe 100644 (file)
@@ -59,67 +59,110 @@ struct TestCase
 
 typedef std::map<int, TestCase> RunningTestCases;
 
-int RunAll(const char* processName, bool reRunFailed)
+// Constantly runs up to MAX_NUM_CHILDREN processes
+int RunAllInParallel(const char* processName, bool reRunFailed)
 {
   int numFailures = 0;
   int numPasses = 0;
-  unsigned int numTestCases = sizeof(tc_array)/sizeof(struct testcase_s) - 1;
+  int numTestCases = sizeof(tc_array)/sizeof(struct testcase_s) - 1;
 
-  // Run test cases in child process( to kill output ), but run serially.
-  for( unsigned int i=0; i<numTestCases; i++)
+  RunningTestCases children;
+  std::vector<int> failedTestCases;
+
+  // Fork up to MAX_NUM_CHILDREN processes, then
+  // wait. As soon as a proc completes, fork the next.
+
+  int nextTestCase = 0;
+  int numRunningChildren = 0;
+  while( nextTestCase < numTestCases || numRunningChildren > 0)
   {
-    int pid = fork();
-    if( pid == 0 ) // Child process
+    // Spawn more children if there any left to start and a slot to run one in:
+    if( nextTestCase < numTestCases )
     {
-      close(STDOUT_FILENO);
-      close(STDERR_FILENO);
-      exit( RunTestCase( tc_array[i] ) );
+      while( numRunningChildren < MAX_NUM_CHILDREN && nextTestCase < numTestCases )
+      {
+        int pid = fork();
+        if( pid == 0 ) // Child process
+        {
+          close(STDOUT_FILENO);
+          close(STDERR_FILENO);
+          exit( RunTestCase( tc_array[nextTestCase] ) );
+        }
+        else if(pid == -1)
+        {
+          perror("fork");
+          exit(2);
+        }
+        else // Parent process
+        {
+          TestCase tc(nextTestCase, tc_array[nextTestCase].name);
+          children[pid] = tc;
+          nextTestCase++;
+          numRunningChildren++;
+        }
+      }
     }
-    else if(pid == -1)
+
+    int status=0;
+    int childPid = waitpid(-1, &status, 0);
+    if( childPid == -1 )
     {
-      perror("fork");
+      perror("waitpid");
       exit(2);
     }
-    else // Parent process
+
+    if( WIFEXITED(status) )
     {
-      int status = 0;
-      int childPid = waitpid(-1, &status, 0);
-      if( childPid == -1 )
+      if( childPid > 0 )
       {
-        perror("waitpid");
-        exit(2);
-      }
-      if( WIFEXITED(status) )
-      {
-        if( childPid > 0 )
+        int testResult = WEXITSTATUS(status);
+        if( testResult )
+        {
+          printf("Test case %s failed: %d\n", children[childPid].testCaseName, testResult);
+          failedTestCases.push_back(children[childPid].testCase);
+          numFailures++;
+        }
+        else
         {
-          int testResult = WEXITSTATUS(status);
-          if( testResult )
-          {
-            printf("Test case %s failed: %d\n", tc_array[i].name, testResult);
-            numFailures++;
-          }
-          else
-          {
-            numPasses++;
-          }
+          numPasses++;
         }
+        numRunningChildren--;
       }
-      else if(WIFSIGNALED(status) )
+    }
+
+    else if( WIFSIGNALED(status) )
+    {
+      if( childPid > 0 )
       {
-        if( childPid > 0 )
+        RunningTestCases::iterator iter = children.find(childPid);
+        if( iter != children.end() )
         {
-          printf("Test case %s exited with signal %d\n", tc_array[i].name, WTERMSIG(status));
-          numFailures++;
+          printf("Test case %s exited with signal %d\n", iter->second.testCaseName, WTERMSIG(status));
+          failedTestCases.push_back(iter->second.testCase);
+        }
+        else
+        {
+          printf("Unknown child process: %d signaled %d\n", childPid, WTERMSIG(status));
         }
+
+        numFailures++;
+        numRunningChildren--;
       }
     }
   }
 
-
-  printf("\rNumber of test passes: %d\n", numPasses);
+  printf("\rNumber of test passes: %d                                        \n", numPasses);
   printf("Number of test failures: %d\n", numFailures);
 
+  if( reRunFailed )
+  {
+    for( unsigned int i=0; i<failedTestCases.size(); i++)
+    {
+      printf("Running test case %s:\n", tc_array[failedTestCases[i]].name );
+      RunTestCase( tc_array[failedTestCases[i] ] );
+    }
+  }
+
   return numFailures;
 }
 
@@ -164,8 +207,7 @@ int main(int argc, char * const argv[])
 
   if( optParallel )
   {
-    // For this test harness, run tests only in serial ( but without output )
-    result = RunAll(argv[0], optRerunFailed);
+    result = RunAllInParallel(argv[0], optRerunFailed);
   }
   else
   {
diff --git a/automated-tests/src/dali-platform-abstraction/utc-image-loading-cancel-all-loads.cpp b/automated-tests/src/dali-platform-abstraction/utc-image-loading-cancel-all-loads.cpp
new file mode 100644 (file)
index 0000000..037fb7c
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ *
+ */
+
+#include "utc-image-loading-common.h"
+
+void utc_image_loading_cancel_all_loads_startup(void)
+{
+  utc_dali_loading_startup();
+}
+
+void utc_image_loading_cancel_all_loads_cleanup(void)
+{
+  utc_dali_loading_cleanup();
+}
+
+/**
+ * @brief Test case for load cancellation.
+ *
+ * Load lots of images in batches, cancelling all in a batch after a small delay to
+ * allow the first of a batch to be launched before cancellation starts.
+ * Assert that all loads issued are either completed or cancelled.
+ *
+ * @note Many loads will succeed despite our cancellations due to the coarse
+ * granularity of the waits we introduce after loading each batch. That is
+ * expected.
+ */
+int UtcDaliCancelAllLoads(void)
+{
+  tet_printf( "Running load cancel-all test.\n" );
+
+  DALI_ASSERT_ALWAYS( gAbstraction != 0 );
+
+  // Start a bunch of loads that should work:
+
+  Dali::Integration::LoadResourcePriority priority = LoadPriorityNormal;
+  unsigned loadsLaunched = 0;
+  Dali::Internal::Platform::ResourceCollector resourceSink;
+
+  for( unsigned loadGroup = 0; loadGroup < NUM_CANCELLED_LOAD_GROUPS_TO_ISSUE; ++loadGroup )
+  {
+    // Issue load requests for a batch of images:
+    for( unsigned validImage = 0; validImage < NUM_VALID_IMAGES; ++validImage )
+    {
+      const BitmapResourceType bitmapResourceType( gCancelAttributes[ loadsLaunched % gCancelAttributes.size() ] );
+      const ResourceId resourceId = loadGroup * NUM_VALID_IMAGES + validImage + 1;
+      gAbstraction->LoadResource( ResourceRequest( resourceId, bitmapResourceType, VALID_IMAGES[validImage], priority ) );
+      loadsLaunched += 1;
+    }
+
+    // Poll for at least one completed load so we have a good chance of catching an
+    // in-flight load as we run through the cancellations further below:
+    PollForNotification( resourceSink, *gAbstraction, 100 );
+
+    // Cancel all the launched loads in the batch from oldest to newest:
+    for( unsigned validImage = 0; validImage < NUM_VALID_IMAGES; ++validImage )
+    {
+      const ResourceId resourceId = loadGroup * NUM_VALID_IMAGES + validImage + 1;
+      gAbstraction->CancelLoad( resourceId, ResourceBitmap );
+    }
+  }
+
+  // Drain the completed loads:
+
+  unsigned lastNotifications = -1;
+  for( unsigned i = 0; resourceSink.mGrandTotalCompletions < loadsLaunched && resourceSink.mGrandTotalNotifications != lastNotifications; )
+  {
+    lastNotifications = resourceSink.mGrandTotalNotifications;
+    gAbstraction->GetResources( resourceSink );
+
+    ++i;
+    if( i < MAX_NUM_RESOURCE_TRIES && resourceSink.mGrandTotalCompletions < loadsLaunched )
+    {
+      usleep( 1000 * 10 );
+    }
+    else
+    {
+      break;
+    }
+  }
+
+  // Check the loads completed as expected:
+
+  tet_printf( "Issued Loads: %u, Completed Loads: %u, Successful Loads: %u, Failed Loads: %u \n", loadsLaunched, resourceSink.mGrandTotalCompletions, unsigned(resourceSink.mSuccessCounts.size()), unsigned(resourceSink.mFailureCounts.size()) );
+  DALI_TEST_CHECK( loadsLaunched > resourceSink.mGrandTotalCompletions );
+  DALI_TEST_CHECK( loadsLaunched > resourceSink.mSuccessCounts.size() );
+  DALI_TEST_CHECK( 0 == resourceSink.mFailureCounts.size() );
+
+  // Check that each success was reported exactly once:
+  for( ResourceCounterMap::const_iterator it = resourceSink.mSuccessCounts.begin(), end = resourceSink.mSuccessCounts.end(); it != end; ++it )
+  {
+    DALI_TEST_CHECK( it->second == 1u );
+  }
+
+  END_TEST;
+}
diff --git a/automated-tests/src/dali-platform-abstraction/utc-image-loading-cancel-some-loads.cpp b/automated-tests/src/dali-platform-abstraction/utc-image-loading-cancel-some-loads.cpp
new file mode 100644 (file)
index 0000000..0a89566
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ *
+ */
+
+#include "utc-image-loading-common.h"
+
+void utc_image_loading_cancel_some_loads_startup(void)
+{
+  utc_dali_loading_startup();
+}
+
+void utc_image_loading_cancel_some_loads_cleanup(void)
+{
+  utc_dali_loading_cleanup();
+}
+
+/**
+ * @brief Test case for load cancellation.
+ *
+ * Load lots, cancel a subset and be sure the wrong loads are never cancelled
+ * and that all loads issued are either completed or cancelled.
+ */
+int UtcDaliCancelSomeLoads(void)
+{
+  tet_printf( "Running load cancel load subset test.\n" );
+
+  DALI_ASSERT_ALWAYS( gAbstraction != 0 );
+
+  // Start a bunch of loads that should work:
+
+  Dali::Integration::LoadResourcePriority priority = LoadPriorityNormal;
+  unsigned loadsLaunched = 0;
+
+  std::set<Integration::ResourceId> cancelledLoadSet;
+  Dali::Internal::Platform::ResourceCollector resourceSink;
+
+  for( unsigned loadGroup = 0; loadGroup < NUM_LOAD_GROUPS_TO_ISSUE; ++loadGroup )
+  {
+    const unsigned preIterationCompletions = resourceSink.mGrandTotalCompletions;
+
+    // Issue load requests for a batch of images:
+    for( unsigned validImage = 0; validImage < NUM_VALID_IMAGES; ++validImage )
+    {
+      const BitmapResourceType bitmapResourceType( gCancelAttributes[ loadsLaunched % gCancelAttributes.size() ] );
+      const ResourceId resourceId = loadGroup * NUM_VALID_IMAGES + validImage + 1;
+      gAbstraction->LoadResource( ResourceRequest( resourceId, bitmapResourceType, VALID_IMAGES[validImage], priority ) );
+      loadsLaunched += 1;
+    }
+
+    // Let the first image in the batch start to load so we can try to cancel it in-flight:
+    usleep( 1 * 1000 ); //< 1 ms is enough to let an image start to load.
+    ///@Note: The log should show cancellations of many in-flight loads in desktop builds with info-level logging enabled (e.g., "INFO: DALI: : CheckForCancellation: Cancelled in-flight resource (21)."). If it doesn't, the above delay may need to be adjusted.
+
+    // Cancel just two loads (hopefully one in-flight and one queued):
+
+    // Cancel first load, hopefully while it is in-flight:
+    const ResourceId cancelledInFlight = loadGroup * NUM_VALID_IMAGES + 1;
+    gAbstraction->CancelLoad( cancelledInFlight, ResourceBitmap );
+    cancelledLoadSet.insert( cancelledInFlight );
+
+    // Cancel second load, that is still queued:
+    const ResourceId cancelledFromQueue = loadGroup * NUM_VALID_IMAGES + NUM_VALID_IMAGES;
+    gAbstraction->CancelLoad( cancelledFromQueue, ResourceBitmap );
+    cancelledLoadSet.insert( cancelledFromQueue );
+
+    // Drain a group worth of images so the cancellations hit in-flight loads on the next iteration:
+    for( unsigned i = 0; i < NUM_VALID_IMAGES * 1000 * 1000 * 10 / (5 * 1000)  && resourceSink.mGrandTotalCompletions < preIterationCompletions + NUM_VALID_IMAGES - 2; ++i )
+    {
+      gAbstraction->GetResources( resourceSink );
+      usleep( 5 * 1000 );
+    }
+  }
+
+  // Drain any spare completed loads until no new loads complete on an iteration:
+  unsigned lastNotifications = -1;
+  for( unsigned i = 0; i < MAX_NUM_RESOURCE_TRIES && resourceSink.mGrandTotalCompletions < loadsLaunched && resourceSink.mGrandTotalNotifications != lastNotifications; ++i )
+  {
+    lastNotifications = resourceSink.mGrandTotalNotifications;
+    gAbstraction->GetResources( resourceSink );
+    usleep( 70 * 1000 ); //< 70 ms should allow at least one medium image to load. You  might to increase this to run on a slow device.
+    gAbstraction->GetResources( resourceSink );
+    usleep( 70 * 1000 );
+    gAbstraction->GetResources( resourceSink );
+    usleep( 70 * 1000 );
+    gAbstraction->GetResources( resourceSink );
+  }
+
+  // Check the loads completed as expected:
+
+  tet_printf( "Issued Loads: %u, Completed Loads: %u, Successful Loads: %u, Failed Loads: %u \n", loadsLaunched, resourceSink.mGrandTotalCompletions, unsigned(resourceSink.mSuccessCounts.size()), unsigned(resourceSink.mFailureCounts.size()) );
+  DALI_TEST_CHECK( loadsLaunched >= resourceSink.mGrandTotalCompletions );
+  DALI_TEST_CHECK( loadsLaunched >= resourceSink.mSuccessCounts.size() );
+  DALI_TEST_CHECK( 0 == resourceSink.mFailureCounts.size() );
+
+  // Check that if an image was not loaded, it is one of the ones that was cancelled:
+  // This is the main point of this test case.
+  std::vector<Integration::ResourceId> missingLoads;
+  for( unsigned resourceId = 1; resourceId <= NUM_LOAD_GROUPS_TO_ISSUE * NUM_VALID_IMAGES; ++resourceId )
+  {
+    // Was the load (not) completed?
+    if( resourceSink.mCompletionStatuses.find( resourceId ) == resourceSink.mCompletionStatuses.end() )
+    {
+      // Was the load (not) cancelled?
+      if( cancelledLoadSet.find( resourceId ) == cancelledLoadSet.end() )
+      {
+        // Whoa, the load was not completed and not cancelled either... so where did it go then?
+        missingLoads.push_back( resourceId );
+        tet_printf( "Missing load. ResourceId %u was not completed but was also not cancelled.\n", resourceId );
+        ///@note If this fires, you are probably not waiting long enough in the draining loop above (usleep( 70 * 1000 );).
+      }
+    }
+  }
+  DALI_TEST_CHECK( missingLoads.size() == 0U );
+
+  // Check that each success was reported exactly once:
+  for(ResourceCounterMap::const_iterator it = resourceSink.mSuccessCounts.begin(), end = resourceSink.mSuccessCounts.end(); it != end; ++it )
+  {
+    DALI_TEST_CHECK( it->second == 1u );
+  }
+
+  END_TEST;
+}
diff --git a/automated-tests/src/dali-platform-abstraction/utc-image-loading-common.cpp b/automated-tests/src/dali-platform-abstraction/utc-image-loading-common.cpp
new file mode 100644 (file)
index 0000000..181ff67
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ *
+ */
+
+#include "utc-image-loading-common.h"
+
+/** Live platform abstraction recreated for each test case. */
+Integration::PlatformAbstraction * gAbstraction = 0;
+
+/** A variety of ImageAttributes to reach different code paths that have embedded code paths. */
+std::vector<ImageAttributes> gCancelAttributes;
+
+void utc_dali_loading_startup(void)
+{
+  test_return_value = TET_UNDEF;
+  gAbstraction = CreatePlatformAbstraction();
+
+  // Setup some ImageAttributes to engage post-processing stages:
+
+  ImageAttributes scaleToFillAttributes;
+  scaleToFillAttributes.SetScalingMode( ImageAttributes::ScaleToFill );
+  scaleToFillAttributes.SetSize( 160, 120 );
+  gCancelAttributes.push_back( scaleToFillAttributes );
+
+  // Hit the derived dimensions code:
+  ImageAttributes scaleToFillAttributesDeriveWidth = scaleToFillAttributes;
+  scaleToFillAttributesDeriveWidth.SetSize( 0, 120 );
+  gCancelAttributes.push_back( scaleToFillAttributesDeriveWidth );
+
+  ImageAttributes scaleToFillAttributesDeriveHeight = scaleToFillAttributes;
+  scaleToFillAttributesDeriveHeight.SetSize( 160, 0 );
+  gCancelAttributes.push_back( scaleToFillAttributesDeriveHeight );
+
+  // Try to push a tall crop:
+  ImageAttributes scaleToFillAttributesTall = scaleToFillAttributes;
+  scaleToFillAttributesTall.SetSize( 160, 480 );
+  ImageAttributes scaleToFillAttributesTall2 = scaleToFillAttributes;
+  scaleToFillAttributesTall2.SetSize( 160, 509 );
+  ImageAttributes scaleToFillAttributesTall3 = scaleToFillAttributes;
+  scaleToFillAttributesTall3.SetSize( 37, 251 );
+  gCancelAttributes.push_back( scaleToFillAttributesTall );
+  gCancelAttributes.push_back( scaleToFillAttributesTall2 );
+  gCancelAttributes.push_back( scaleToFillAttributesTall3 );
+
+  // Try to push a wide crop:
+  ImageAttributes scaleToFillAttributesWide = scaleToFillAttributes;
+  scaleToFillAttributesWide.SetSize( 320, 60 );
+  ImageAttributes scaleToFillAttributesWide2 = scaleToFillAttributes;
+  scaleToFillAttributesWide2.SetSize( 317, 60 );
+  ImageAttributes scaleToFillAttributesWide3 = scaleToFillAttributes;
+  scaleToFillAttributesWide3.SetSize( 317, 53 );
+  gCancelAttributes.push_back( scaleToFillAttributesWide );
+  gCancelAttributes.push_back( scaleToFillAttributesWide2 );
+  gCancelAttributes.push_back( scaleToFillAttributesWide3 );
+
+  ImageAttributes shrinkToFitAttributes = scaleToFillAttributes;
+  shrinkToFitAttributes.SetScalingMode( ImageAttributes::ShrinkToFit );
+  gCancelAttributes.push_back( shrinkToFitAttributes );
+
+  ImageAttributes fitWidthAttributes = scaleToFillAttributes;
+  fitWidthAttributes.SetScalingMode( ImageAttributes::FitWidth );
+  gCancelAttributes.push_back( fitWidthAttributes );
+
+  ImageAttributes fitHeightAttributes = scaleToFillAttributes;
+  fitHeightAttributes.SetScalingMode( ImageAttributes::FitHeight );
+  gCancelAttributes.push_back( fitHeightAttributes );
+
+  ///@ToDo: Add attribute variants for all scale modes.
+
+  // Pad the array to a prime number to mitigate any accidental periodic
+  // patterns in which image file has which attributes applied to its load:
+  srand48( 104729 );
+  const float lastUniques = gCancelAttributes.size() - 0.001f;
+  while( gCancelAttributes.size() < 61u )
+  {
+    gCancelAttributes.push_back( gCancelAttributes[unsigned(drand48() * lastUniques)] );
+  }
+}
+
+void utc_dali_loading_cleanup(void)
+{
+  delete gAbstraction;
+  gAbstraction = 0;
+
+  test_return_value = TET_PASS;
+}
diff --git a/automated-tests/src/dali-platform-abstraction/utc-image-loading-common.h b/automated-tests/src/dali-platform-abstraction/utc-image-loading-common.h
new file mode 100644 (file)
index 0000000..7ca44b3
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __DALI_TEST_SUITE_IMAGE_LOADING_COMMON_H__
+#define __DALI_TEST_SUITE_IMAGE_LOADING_COMMON_H__
+#include <unistd.h>
+#include <iostream>
+#include <stdlib.h>
+#include <dali/dali.h>
+#include <dali-test-suite-utils.h>
+#include "slp-platform-abstraction.h"
+#include "resource-collector.h"
+
+using namespace Dali;
+using namespace Dali::Integration;
+using namespace Dali::Internal::Platform;
+
+namespace
+{
+/**
+ * The number of loads issued in test cases is a multiple of this. The higher it
+ * is, the more the tests stress the system but the longer they take to run.
+ * A value of 1000 is enough to make load tests take tens of seconds each
+ * on desktop. */
+const unsigned NUM_LOAD_GROUPS_TO_ISSUE = 158;
+
+/**
+ * The number of loads to issue when they will be cancelled.
+ * Cancelled loads are cheap so we do a lot.
+ */
+const unsigned NUM_CANCELLED_LOAD_GROUPS_TO_ISSUE = NUM_LOAD_GROUPS_TO_ISSUE * 10;
+
+/** The number of times to ask for resource load status. */
+const unsigned MAX_NUM_RESOURCE_TRIES = 10;
+
+/** The maximum time to wait for loads to complete when the number of expected loads is known. */
+const unsigned MAX_MILLIS_TO_WAIT_FOR_KNOWN_LOADS = 1000 * 60;
+
+/** Images that should load without issue. */
+const char* const VALID_IMAGES[] = {
+  TEST_IMAGE_DIR "/frac.jpg",
+  TEST_IMAGE_DIR "/frac.24.bmp",
+  TEST_IMAGE_DIR "/frac.png",
+  TEST_IMAGE_DIR "/interlaced.gif",
+  TEST_IMAGE_DIR "/pattern.gif"
+};
+const unsigned NUM_VALID_IMAGES = sizeof(VALID_IMAGES) / sizeof(VALID_IMAGES[0]);
+
+///@ToDo: Add valid ktx, ico, and wbmp image examples.
+
+/** Returns elapsed milliseconds. */
+double GetTimeMilliseconds( Integration::PlatformAbstraction& abstraction )
+{
+  unsigned int seconds;
+  unsigned int microseconds;
+  abstraction.GetTimeMicroseconds( seconds, microseconds );
+  double milliseconds = seconds * 1000.0 + microseconds / 1000.0;
+  return milliseconds;
+}
+
+} // anon namespace
+
+/** Live platform abstraction recreated for each test case. */
+extern Integration::PlatformAbstraction * gAbstraction;
+
+/** A variety of ImageAttributes to reach different code paths that have embedded code paths. */
+extern std::vector<ImageAttributes> gCancelAttributes;
+
+
+void utc_dali_loading_startup(void);
+void utc_dali_loading_cleanup(void);
+
+#endif // __DALI_TEST_SUITE_IMAGE_LOADING_COMMON_H__
diff --git a/automated-tests/src/dali-platform-abstraction/utc-image-loading-load-completion.cpp b/automated-tests/src/dali-platform-abstraction/utc-image-loading-load-completion.cpp
new file mode 100644 (file)
index 0000000..65014b6
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ *
+ */
+
+#include "utc-image-loading-common.h"
+
+void utc_image_loading_load_completion_startup(void)
+{
+  utc_dali_loading_startup();
+}
+
+void utc_image_loading_load_completion_cleanup(void)
+{
+  utc_dali_loading_cleanup();
+}
+
+// Positive test case for loading. Load lots and be sure it has succeeded.
+int UtcDaliLoadCompletion(void)
+{
+  tet_printf("Running load completion test \n");
+
+  DALI_ASSERT_ALWAYS( gAbstraction != 0 );
+
+  // Start a bunch of loads that should work:
+
+  const Dali::ImageAttributes attributes;
+  const Dali::Integration::BitmapResourceType bitmapResourceType( attributes );
+  Dali::Integration::LoadResourcePriority priority = Dali::Integration::LoadPriorityNormal;
+  unsigned loadsLaunched = 0;
+
+  for( unsigned loadGroup = 0; loadGroup < NUM_LOAD_GROUPS_TO_ISSUE; ++loadGroup )
+  {
+    for( unsigned validImage = 0; validImage < NUM_VALID_IMAGES; ++validImage )
+    {
+      gAbstraction->LoadResource( ResourceRequest( loadGroup * NUM_VALID_IMAGES + validImage + 1, bitmapResourceType, VALID_IMAGES[validImage], priority ) );
+    }
+    loadsLaunched += NUM_VALID_IMAGES;
+  }
+
+  // Drain the completed loads:
+  Dali::Internal::Platform::ResourceCollector resourceSink;
+  usleep( 1000 * 1000 );
+  gAbstraction->GetResources( resourceSink );
+  usleep( 500 * 1000 );
+  gAbstraction->GetResources( resourceSink );
+
+  const double startDrainTime = GetTimeMilliseconds( *gAbstraction );
+  while( resourceSink.mGrandTotalCompletions < loadsLaunched && GetTimeMilliseconds( *gAbstraction ) - startDrainTime < MAX_MILLIS_TO_WAIT_FOR_KNOWN_LOADS )
+  {
+    usleep( 100 * 40 );
+    gAbstraction->GetResources( resourceSink );
+  }
+
+  // Check the loads completed as expected:
+
+  tet_printf( "Issued Loads: %u, Completed Loads: %u, Successful Loads: %u, Failed Loads: %u \n", loadsLaunched, resourceSink.mGrandTotalCompletions, unsigned(resourceSink.mSuccessCounts.size()), unsigned(resourceSink.mFailureCounts.size()) );
+  DALI_TEST_CHECK( loadsLaunched == resourceSink.mGrandTotalCompletions );
+  DALI_TEST_CHECK( loadsLaunched == resourceSink.mSuccessCounts.size() );
+  DALI_TEST_CHECK( 0 == resourceSink.mFailureCounts.size() );
+
+  // Check that each success was reported exactly once:
+  for( ResourceCounterMap::const_iterator it = resourceSink.mSuccessCounts.begin(), end = resourceSink.mSuccessCounts.end(); it != end; ++it )
+  {
+    DALI_TEST_CHECK( it->second == 1u );
+  }
+
+  END_TEST;
+}
diff --git a/automated-tests/src/dali-platform-abstraction/utc-image-loading.cpp b/automated-tests/src/dali-platform-abstraction/utc-image-loading.cpp
deleted file mode 100644 (file)
index 4e41883..0000000
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * 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.
- *
- */
-
-#include <unistd.h>
-#include <iostream>
-#include <stdlib.h>
-#include <dali/dali.h>
-#include <dali-test-suite-utils.h>
-#include "slp-platform-abstraction.h"
-#include "resource-collector.h"
-
-using namespace Dali;
-using namespace Dali::Integration;
-using namespace Dali::Internal::Platform;
-
-namespace
-{
-/**
- * The number of loads issued in test cases is a multiple of this. The higher it
- * is, the more the tests stress the system but the longer they take to run.
- * A value of 1000 is enough to make load tests take tens of seconds each
- * on desktop. */
-const unsigned NUM_LOAD_GROUPS_TO_ISSUE = 200;
-
-/**
- * The number of loads to issue when they will be cancelled.
- * Cancelled loads are cheap so we do a lot.
- */
-const unsigned NUM_CANCELLED_LOAD_GROUPS_TO_ISSUE = NUM_LOAD_GROUPS_TO_ISSUE * 10;
-
-/** The number of times to ask for resource load status. */
-const unsigned MAX_NUM_RESOURCE_TRIES = 5;
-
-/** Images that should load without issue. */
-const char* const VALID_IMAGES[] = {
-  TEST_IMAGE_DIR "/frac.jpg",
-  TEST_IMAGE_DIR "/frac.24.bmp",
-  TEST_IMAGE_DIR "/frac.png",
-  TEST_IMAGE_DIR "/interlaced.gif",
-  TEST_IMAGE_DIR "/pattern.gif"
-};
-const unsigned NUM_VALID_IMAGES = sizeof(VALID_IMAGES) / sizeof(VALID_IMAGES[0]);
-
-///@ToDo: Add valid ktx, ico, and wbmp image examples.
-
-/** Live platform abstraction recreated for each test case. */
-Integration::PlatformAbstraction * gAbstraction = 0;
-
-/** A variety of ImageAttributes to reach different code paths that have embedded code paths. */
-std::vector<ImageAttributes> gCancelAttributes;
-
-} // anon namespace
-
-void utc_dali_loading_startup(void)
-{
-  test_return_value = TET_UNDEF;
-  gAbstraction = CreatePlatformAbstraction();
-
-  // Setup some ImageAttributes to engage post-processing stages:
-
-  ImageAttributes scaleToFillAttributes;
-  scaleToFillAttributes.SetScalingMode( ImageAttributes::ScaleToFill );
-  scaleToFillAttributes.SetSize( 160, 120 );
-  gCancelAttributes.push_back( scaleToFillAttributes );
-
-  // Hit the derived dimensions code:
-  ImageAttributes scaleToFillAttributesDeriveWidth = scaleToFillAttributes;
-  scaleToFillAttributesDeriveWidth.SetSize( 0, 120 );
-  gCancelAttributes.push_back( scaleToFillAttributesDeriveWidth );
-
-  ImageAttributes scaleToFillAttributesDeriveHeight = scaleToFillAttributes;
-  scaleToFillAttributesDeriveHeight.SetSize( 160, 0 );
-  gCancelAttributes.push_back( scaleToFillAttributesDeriveHeight );
-
-  // Try to push a tall crop:
-  ImageAttributes scaleToFillAttributesTall = scaleToFillAttributes;
-  scaleToFillAttributesTall.SetSize( 160, 480 );
-  ImageAttributes scaleToFillAttributesTall2 = scaleToFillAttributes;
-  scaleToFillAttributesTall2.SetSize( 160, 509 );
-  ImageAttributes scaleToFillAttributesTall3 = scaleToFillAttributes;
-  scaleToFillAttributesTall3.SetSize( 37, 251 );
-  gCancelAttributes.push_back( scaleToFillAttributesTall );
-  gCancelAttributes.push_back( scaleToFillAttributesTall2 );
-  gCancelAttributes.push_back( scaleToFillAttributesTall3 );
-
-  // Try to push a wide crop:
-  ImageAttributes scaleToFillAttributesWide = scaleToFillAttributes;
-  scaleToFillAttributesWide.SetSize( 320, 60 );
-  ImageAttributes scaleToFillAttributesWide2 = scaleToFillAttributes;
-  scaleToFillAttributesWide2.SetSize( 317, 60 );
-  ImageAttributes scaleToFillAttributesWide3 = scaleToFillAttributes;
-  scaleToFillAttributesWide3.SetSize( 317, 53 );
-  gCancelAttributes.push_back( scaleToFillAttributesWide );
-  gCancelAttributes.push_back( scaleToFillAttributesWide2 );
-  gCancelAttributes.push_back( scaleToFillAttributesWide3 );
-
-  ImageAttributes shrinkToFitAttributes = scaleToFillAttributes;
-  shrinkToFitAttributes.SetScalingMode( ImageAttributes::ShrinkToFit );
-  gCancelAttributes.push_back( shrinkToFitAttributes );
-
-  ImageAttributes fitWidthAttributes = scaleToFillAttributes;
-  fitWidthAttributes.SetScalingMode( ImageAttributes::FitWidth );
-  gCancelAttributes.push_back( fitWidthAttributes );
-
-  ImageAttributes fitHeightAttributes = scaleToFillAttributes;
-  fitHeightAttributes.SetScalingMode( ImageAttributes::FitHeight );
-  gCancelAttributes.push_back( fitHeightAttributes );
-
-  ///@ToDo: Add attribute variants for all scale modes.
-
-  // Pad the array to a prime number to mitigate any accidental periodic
-  // patterns in which image file has which attributes applied to its load:
-  srand48( 104729 );
-  const float lastUniques = gCancelAttributes.size() - 0.001f;
-  while( gCancelAttributes.size() < 61u )
-  {
-    gCancelAttributes.push_back( gCancelAttributes[unsigned(drand48() * lastUniques)] );
-  }
-}
-
-void utc_dali_loading_cleanup(void)
-{
-  delete gAbstraction;
-  gAbstraction = 0;
-
-  test_return_value = TET_PASS;
-}
-
-// Positive test case for loading. Load lots and be sure it has succeeded.
-int UtcDaliLoadCompletion(void)
-{
-  tet_printf("Running load completion test \n");
-
-  DALI_ASSERT_ALWAYS( gAbstraction != 0 );
-
-  // Start a bunch of loads that should work:
-
-  const Dali::ImageAttributes attributes;
-  const Dali::Integration::BitmapResourceType bitmapResourceType( attributes );
-  Dali::Integration::LoadResourcePriority priority = Dali::Integration::LoadPriorityNormal;
-  unsigned loadsLaunched = 0;
-
-  for( unsigned loadGroup = 0; loadGroup < NUM_LOAD_GROUPS_TO_ISSUE; ++loadGroup )
-  {
-    for( unsigned validImage = 0; validImage < NUM_VALID_IMAGES; ++validImage )
-    {
-      gAbstraction->LoadResource( ResourceRequest( loadGroup * NUM_VALID_IMAGES + validImage + 1, bitmapResourceType, VALID_IMAGES[validImage], priority ) );
-    }
-    loadsLaunched += NUM_VALID_IMAGES;
-  }
-
-  // Drain the completed loads:
-
-  Dali::Internal::Platform::ResourceCollector resourceSink;
-
-  for( unsigned i = 0; i < MAX_NUM_RESOURCE_TRIES && resourceSink.mGrandTotalCompletions < loadsLaunched; ++i )
-  {
-    tet_printf( "Draining sleep %u, at total completion count %u of %u.\n", i, resourceSink.mGrandTotalCompletions, loadsLaunched );
-    usleep( 1200 * 1000 );
-    gAbstraction->GetResources( resourceSink );
-  }
-
-  // Check the loads completed as expected:
-
-  tet_printf( "Issued Loads: %u, Completed Loads: %u, Successful Loads: %u, Failed Loads: %u \n", loadsLaunched, resourceSink.mGrandTotalCompletions, unsigned(resourceSink.mSuccessCounts.size()), unsigned(resourceSink.mFailureCounts.size()) );
-  DALI_TEST_CHECK( loadsLaunched == resourceSink.mGrandTotalCompletions );
-  DALI_TEST_CHECK( loadsLaunched == resourceSink.mSuccessCounts.size() );
-  DALI_TEST_CHECK( 0 == resourceSink.mFailureCounts.size() );
-
-  // Check that each success was reported exactly once:
-  for( ResourceCounterMap::const_iterator it = resourceSink.mSuccessCounts.begin(), end = resourceSink.mSuccessCounts.end(); it != end; ++it )
-  {
-    DALI_TEST_CHECK( it->second == 1u );
-  }
-
-  END_TEST;
-}
-
-/**
- * @brief Test case for load cancellation.
- *
- * Load lots of images in batches, cancelling all in a batch after a small delay to
- * allow the first of a batch to be launched before cancellation starts.
- * Assert that all loads issued are either completed or cancelled.
- */
-int UtcDaliCancelAllLoads(void)
-{
-  tet_printf( "Running load cancel-all test.\n" );
-
-  DALI_ASSERT_ALWAYS( gAbstraction != 0 );
-
-  // Start a bunch of loads that should work:
-
-  Dali::Integration::LoadResourcePriority priority = LoadPriorityNormal;
-  unsigned loadsLaunched = 0;
-
-  for( unsigned loadGroup = 0; loadGroup < NUM_CANCELLED_LOAD_GROUPS_TO_ISSUE; ++loadGroup )
-  {
-    // Issue load requests for a batch of images:
-    for( unsigned validImage = 0; validImage < NUM_VALID_IMAGES; ++validImage )
-    {
-      const BitmapResourceType bitmapResourceType( gCancelAttributes[ loadsLaunched % gCancelAttributes.size() ] );
-      const ResourceId resourceId = loadGroup * NUM_VALID_IMAGES + validImage + 1;
-      gAbstraction->LoadResource( ResourceRequest( resourceId, bitmapResourceType, VALID_IMAGES[validImage], priority ) );
-      loadsLaunched += 1;
-    }
-
-    // Let the first image in the batch start to load:
-    usleep( 5000 ); // This number is tuned. Turn it up too much and all loads will complete and the test will take so long it seems to hang.
-
-    // Cancel all the launched loads from oldest to newest:
-    for( unsigned validImage = 0; validImage < NUM_VALID_IMAGES; ++validImage )
-    {
-      const ResourceId resourceId = loadGroup * NUM_VALID_IMAGES + validImage + 1;
-      gAbstraction->CancelLoad( resourceId, ResourceBitmap );
-    }
-  }
-
-  // Drain the completed loads:
-  Dali::Internal::Platform::ResourceCollector resourceSink;
-
-  unsigned lastCompletions = -1;
-  for( unsigned i = 0; i < MAX_NUM_RESOURCE_TRIES && resourceSink.mGrandTotalCompletions < loadsLaunched && resourceSink.mGrandTotalCompletions != lastCompletions; ++i )
-  {
-    lastCompletions = resourceSink.mGrandTotalCompletions;
-    gAbstraction->GetResources( resourceSink );
-    tet_printf( "Draining sleep %u, at total completion count %u of %u.\n", i, resourceSink.mGrandTotalCompletions, loadsLaunched );
-    usleep( 100 * 1000 );
-  }
-
-  // Check the loads completed as expected:
-
-  tet_printf( "Issued Loads: %u, Completed Loads: %u, Successful Loads: %u, Failed Loads: %u \n", loadsLaunched, resourceSink.mGrandTotalCompletions, unsigned(resourceSink.mSuccessCounts.size()), unsigned(resourceSink.mFailureCounts.size()) );
-  DALI_TEST_CHECK( loadsLaunched > resourceSink.mGrandTotalCompletions );
-  DALI_TEST_CHECK( loadsLaunched > resourceSink.mSuccessCounts.size() );
-  DALI_TEST_CHECK( 0 == resourceSink.mFailureCounts.size() );
-
-  // Check that each success was reported exactly once:
-  for( ResourceCounterMap::const_iterator it = resourceSink.mSuccessCounts.begin(), end = resourceSink.mSuccessCounts.end(); it != end; ++it )
-  {
-    DALI_TEST_CHECK( it->second == 1u );
-  }
-
-  END_TEST;
-}
-
-/**
- * @brief Test case for load cancellation.
- *
- * Load lots, cancel a subset and be sure the wrong loads are never cancelled
- * and that all loads issued are either completed or cancelled.
- */
-int UtcDaliCancelSomeLoads(void)
-{
-  tet_printf( "Running load cancel load subset test.\n" );
-
-  DALI_ASSERT_ALWAYS( gAbstraction != 0 );
-
-  // Start a bunch of loads that should work:
-
-  Dali::Integration::LoadResourcePriority priority = LoadPriorityNormal;
-  unsigned loadsLaunched = 0;
-
-  std::set<Integration::ResourceId> cancelledLoadSet;
-
-  for( unsigned loadGroup = 0; loadGroup < NUM_LOAD_GROUPS_TO_ISSUE; ++loadGroup )
-  {
-    // Issue load requests for a batch of images:
-    for( unsigned validImage = 0; validImage < NUM_VALID_IMAGES; ++validImage )
-    {
-      const BitmapResourceType bitmapResourceType( gCancelAttributes[ loadsLaunched % gCancelAttributes.size() ] );
-      const ResourceId resourceId = loadGroup * NUM_VALID_IMAGES + validImage + 1;
-      gAbstraction->LoadResource( ResourceRequest( resourceId, bitmapResourceType, VALID_IMAGES[validImage], priority ) );
-      loadsLaunched += 1;
-    }
-
-    // Let the first image in the batch start to load so we can try to cancel it in-flight:
-    usleep( 17000 );
-    ///@Note: The log should show cancellations of many in-flight loads in desktop builds with info-level logging enabled (e.g., "INFO: DALI: : CheckForCancellation: Cancelled in-flight resource (21)."). If it doesn't, the above delay may need to be adjusted.
-
-    // Cancel just two loads (hopefully one in-flight and one queued):
-
-    // Cancel first load, hopefully while it is in-flight:
-    const ResourceId cancelledInFlight = loadGroup * NUM_VALID_IMAGES + 1;
-    gAbstraction->CancelLoad( cancelledInFlight, ResourceBitmap );
-    cancelledLoadSet.insert( cancelledInFlight );
-
-    // Cancel second load, that is still queued:
-    const ResourceId cancelledFromQueue = loadGroup * NUM_VALID_IMAGES + NUM_VALID_IMAGES;
-    gAbstraction->CancelLoad( cancelledFromQueue, ResourceBitmap );
-    cancelledLoadSet.insert( cancelledFromQueue );
-  }
-
-  // Drain the completed loads:
-
-  Dali::Internal::Platform::ResourceCollector resourceSink;
-
-  unsigned lastCompletions = -1;
-  for( unsigned i = 0; i < MAX_NUM_RESOURCE_TRIES && resourceSink.mGrandTotalCompletions < loadsLaunched && resourceSink.mGrandTotalCompletions != lastCompletions; ++i )
-  {
-    lastCompletions = resourceSink.mGrandTotalCompletions;
-    gAbstraction->GetResources( resourceSink );
-    tet_printf( "Draining sleep %u, at total completion count %u of %u.\n", i, resourceSink.mGrandTotalCompletions, loadsLaunched );
-    usleep( 100 * 1000 );
-  }
-
-  // Check the loads completed as expected:
-
-  tet_printf( "Issued Loads: %u, Completed Loads: %u, Successful Loads: %u, Failed Loads: %u \n", loadsLaunched, resourceSink.mGrandTotalCompletions, unsigned(resourceSink.mSuccessCounts.size()), unsigned(resourceSink.mFailureCounts.size()) );
-  DALI_TEST_CHECK( loadsLaunched >= resourceSink.mGrandTotalCompletions );
-  DALI_TEST_CHECK( loadsLaunched >= resourceSink.mSuccessCounts.size() );
-  DALI_TEST_CHECK( 0 == resourceSink.mFailureCounts.size() );
-
-  // Check that if an image was not loaded, it is one of the ones that was cancelled:
-  // This is the main point of this test case.
-  for( unsigned resourceId = 1; resourceId <= NUM_LOAD_GROUPS_TO_ISSUE * NUM_VALID_IMAGES; ++resourceId )
-  {
-    if( resourceSink.mCompletionStatuses.find( resourceId ) == resourceSink.mCompletionStatuses.end() )
-    {
-      DALI_TEST_CHECK( cancelledLoadSet.find( resourceId ) != cancelledLoadSet.end() );
-    }
-  }
-
-  // Check that each success was reported exactly once:
-  for(ResourceCounterMap::const_iterator it = resourceSink.mSuccessCounts.begin(), end = resourceSink.mSuccessCounts.end(); it != end; ++it )
-  {
-    DALI_TEST_CHECK( it->second == 1u );
-  }
-
-  END_TEST;
-}
index 7312f6c..309328a 100755 (executable)
@@ -242,6 +242,7 @@ struct ResourceLoader::ResourceLoaderImpl
   bool IsLoading()
   {
     // TODO - not used - remove?
+    DALI_ASSERT_DEBUG( 0 == "IsLoading() Is not implemented so don't call it." );
     return true;
   }
 
index 9d216f2..dccb366 100644 (file)
@@ -252,6 +252,7 @@ public:
 
   /**
    * @copydoc PlatformAbstraction::IsLoading()
+   * @deprecated This is not implemented: always returns true.
    */
   bool IsLoading();