From 03377550a4adcf7d37ef0ea6aab07f304034b258 Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Wed, 21 Jan 2015 09:25:13 +0000 Subject: [PATCH 01/62] Bug 650161 - Don't update non-background finalizable arenas in parallel r=terrence --- js/src/gc/GCRuntime.h | 4 ++-- js/src/jsgc.cpp | 54 ++++++++++++++++++++++++++++--------------- 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/js/src/gc/GCRuntime.h b/js/src/gc/GCRuntime.h index 1b836747ff3a..f96979dc2946 100644 --- a/js/src/gc/GCRuntime.h +++ b/js/src/gc/GCRuntime.h @@ -608,8 +608,8 @@ class GCRuntime void sweepTypesAfterCompacting(Zone *zone); void sweepZoneAfterCompacting(Zone *zone); ArenaHeader *relocateArenas(); - void updateAllCellPointersParallel(ArenasToUpdate &source); - void updateAllCellPointersSerial(MovingTracer *trc, ArenasToUpdate &source); + void updateAllCellPointersParallel(MovingTracer *trc); + void updateAllCellPointersSerial(MovingTracer *trc); void updatePointersToRelocatedCells(); void releaseRelocatedArenas(ArenaHeader *relocatedList); void releaseRelocatedArenasWithoutUnlocking(ArenaHeader *relocatedList, const AutoLockGC& lock); diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 16d279e6c584..1b0cf04cfa1f 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -2373,13 +2373,19 @@ namespace gc { struct ArenasToUpdate { - explicit ArenasToUpdate(JSRuntime *rt); + enum KindsToUpdate { + FOREGROUND = 1, + BACKGROUND = 2, + ALL = FOREGROUND | BACKGROUND + }; + ArenasToUpdate(JSRuntime *rt, KindsToUpdate kinds); bool done() { return initialized && arena == nullptr; } ArenaHeader* next(); ArenaHeader *getArenasToUpdate(AutoLockHelperThreadState& lock, unsigned max); private: bool initialized; + KindsToUpdate kinds; GCZonesIter zone; // Current zone to process, unless zone.done() unsigned kind; // Current alloc kind to process ArenaHeader *arena; // Next arena to process @@ -2390,16 +2396,25 @@ struct ArenasToUpdate bool ArenasToUpdate::shouldProcessKind(unsigned kind) { MOZ_ASSERT(kind < FINALIZE_LIMIT); - return - kind != FINALIZE_FAT_INLINE_STRING && - kind != FINALIZE_STRING && - kind != FINALIZE_EXTERNAL_STRING && - kind != FINALIZE_SYMBOL; + if (kind == FINALIZE_FAT_INLINE_STRING || + kind == FINALIZE_STRING || + kind == FINALIZE_EXTERNAL_STRING || + kind == FINALIZE_SYMBOL) + { + return false; + } + + if (kind > FINALIZE_OBJECT_LAST || js::gc::IsBackgroundFinalized(AllocKind(kind))) + return (kinds & BACKGROUND) != 0; + else + return (kinds & FOREGROUND) != 0; } -ArenasToUpdate::ArenasToUpdate(JSRuntime *rt) - : initialized(false), zone(rt, SkipAtoms) -{} +ArenasToUpdate::ArenasToUpdate(JSRuntime *rt, KindsToUpdate kinds) + : initialized(false), kinds(kinds), zone(rt, SkipAtoms) +{ + MOZ_ASSERT(kinds && !(kinds & ~ALL)); +} ArenaHeader * ArenasToUpdate::next() @@ -2526,20 +2541,23 @@ UpdateCellPointersTask::run() } // namespace js void -GCRuntime::updateAllCellPointersParallel(ArenasToUpdate &source) +GCRuntime::updateAllCellPointersParallel(MovingTracer *trc) { AutoDisableProxyCheck noProxyCheck(rt); // These checks assert when run in parallel. const size_t minTasks = 2; const size_t maxTasks = 8; unsigned taskCount = Min(Max(HelperThreadState().cpuCount / 2, minTasks), - maxTasks); + maxTasks) + 1; UpdateCellPointersTask updateTasks[maxTasks]; + ArenasToUpdate fgArenas(rt, ArenasToUpdate::FOREGROUND); + ArenasToUpdate bgArenas(rt, ArenasToUpdate::BACKGROUND); AutoLockHelperThreadState lock; unsigned i; - for (i = 0; i < taskCount && !source.done(); ++i) { - updateTasks[i].init(rt, &source, lock); + for (i = 0; i < taskCount && !bgArenas.done(); ++i) { + ArenasToUpdate *source = i == 0 ? &fgArenas : &bgArenas; + updateTasks[i].init(rt, source, lock); startTask(updateTasks[i], gcstats::PHASE_COMPACT_UPDATE_CELLS); } unsigned tasksStarted = i; @@ -2549,9 +2567,10 @@ GCRuntime::updateAllCellPointersParallel(ArenasToUpdate &source) } void -GCRuntime::updateAllCellPointersSerial(MovingTracer *trc, ArenasToUpdate &source) +GCRuntime::updateAllCellPointersSerial(MovingTracer *trc) { - while (ArenaHeader *arena = source.next()) + ArenasToUpdate allArenas(rt, ArenasToUpdate::ALL); + while (ArenaHeader *arena = allArenas.next()) UpdateCellPointers(trc, arena); } @@ -2580,11 +2599,10 @@ GCRuntime::updatePointersToRelocatedCells() // Iterate through all cells that can contain JSObject pointers to update // them. Since updating each cell is independent we try to parallelize this // as much as possible. - ArenasToUpdate source(rt); if (CanUseExtraThreads()) - updateAllCellPointersParallel(source); + updateAllCellPointersParallel(&trc); else - updateAllCellPointersSerial(&trc, source); + updateAllCellPointersSerial(&trc); // Mark roots to update them. { From 90c9dbbc91db4a122744d0fedfd6a035581a352b Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Wed, 21 Jan 2015 09:25:13 +0000 Subject: [PATCH 02/62] Bug 650161 - Don't trace contents of wrapped native scope in wrapped native proto's trace hook, just the scope's global r=billm --- js/xpconnect/src/xpcprivate.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index da7304faaaab..80cfb1454872 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -1065,9 +1065,12 @@ public: static void TraceWrappedNativesInAllScopes(JSTracer* trc, XPCJSRuntime* rt); - void TraceInside(JSTracer *trc) { + void TraceSelf(JSTracer *trc) { MOZ_ASSERT(mGlobalJSObject); mGlobalJSObject.trace(trc, "XPCWrappedNativeScope::mGlobalJSObject"); + } + + void TraceInside(JSTracer *trc) { if (mContentXBLScope) mContentXBLScope.trace(trc, "XPCWrappedNativeScope::mXBLScope"); for (size_t i = 0; i < mAddonScopes.Length(); i++) @@ -1847,7 +1850,7 @@ public: mScriptableInfo->Mark(); } - GetScope()->TraceInside(trc); + GetScope()->TraceSelf(trc); } void TraceJS(JSTracer *trc) { @@ -2162,7 +2165,7 @@ public: if (HasProto()) GetProto()->TraceSelf(trc); else - GetScope()->TraceInside(trc); + GetScope()->TraceSelf(trc); if (mFlatJSObject && JS_IsGlobalObject(mFlatJSObject)) { xpc::TraceXPCGlobal(trc, mFlatJSObject); From 8b0024a51a0bae5fa6679789fe7a7898ef97ef5b Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Fri, 16 Jan 2015 14:34:32 +0000 Subject: [PATCH 03/62] Bug 650161 - Enable compacting GC on GC_SHRINK collections r=terrence r=glandium --- js/src/configure.in | 12 ------------ js/src/gc/GCInternals.h | 2 -- js/src/gc/GCRuntime.h | 15 --------------- js/src/gc/Heap.h | 2 -- js/src/gc/Marking.cpp | 16 +--------------- js/src/js-config.h.in | 3 --- js/src/jsapi-tests/testWeakMap.cpp | 6 ------ js/src/jscompartment.cpp | 4 ---- js/src/jscompartment.h | 2 -- js/src/jsgc.cpp | 29 ++--------------------------- js/src/jsgc.h | 11 ----------- js/src/jsinfer.cpp | 4 ---- js/src/jsinfer.h | 5 ----- js/src/jspropertytree.cpp | 4 ---- js/src/jspubtd.h | 3 +-- js/src/vm/Shape-inl.h | 2 -- js/src/vm/Shape.cpp | 4 ---- js/src/vm/Shape.h | 8 -------- 18 files changed, 4 insertions(+), 128 deletions(-) diff --git a/js/src/configure.in b/js/src/configure.in index 854427fea800..5beb3dc6bb1e 100644 --- a/js/src/configure.in +++ b/js/src/configure.in @@ -3052,18 +3052,6 @@ MOZ_ARG_WITH_STRING(wrap-malloc, [ --with-wrap-malloc=DIR Location of malloc wrapper library], WRAP_LDFLAGS="${WRAP_LDFLAGS} $withval") -dnl ======================================================== -dnl = Use compacting GC -dnl ======================================================== -dnl Compact the heap by moving GC things when doing a shrinking colletion. -MOZ_ARG_ENABLE_BOOL(gccompacting, -[ --enable-gccompacting Compact the heap by moving GC things], - JSGC_COMPACTING=1, - JSGC_COMPACTING= ) -if test -n "$JSGC_COMPACTING"; then - AC_DEFINE(JSGC_COMPACTING) -fi - dnl ======================================================== dnl = Use a smaller chunk size for GC chunks dnl ======================================================== diff --git a/js/src/gc/GCInternals.h b/js/src/gc/GCInternals.h index 0a718a9ac32b..15b85f26dae4 100644 --- a/js/src/gc/GCInternals.h +++ b/js/src/gc/GCInternals.h @@ -143,7 +143,6 @@ void CheckHashTablesAfterMovingGC(JSRuntime *rt); #endif -#ifdef JSGC_COMPACTING struct MovingTracer : JSTracer { explicit MovingTracer(JSRuntime *rt) : JSTracer(rt, Visit, TraceWeakMapKeysValues) {} @@ -152,7 +151,6 @@ struct MovingTracer : JSTracer { return trc->callback == Visit; } }; -#endif } /* namespace gc */ } /* namespace js */ diff --git a/js/src/gc/GCRuntime.h b/js/src/gc/GCRuntime.h index f96979dc2946..f71effabace4 100644 --- a/js/src/gc/GCRuntime.h +++ b/js/src/gc/GCRuntime.h @@ -34,11 +34,8 @@ struct FinalizePhase; class MarkingValidator; struct AutoPrepareForTracing; class AutoTraceSession; - -#ifdef JSGC_COMPACTING struct ArenasToUpdate; struct MovingTracer; -#endif class ChunkPool { @@ -297,11 +294,7 @@ class GCRuntime bool isHeapMajorCollecting() { return heapState == js::MajorCollecting; } bool isHeapMinorCollecting() { return heapState == js::MinorCollecting; } bool isHeapCollecting() { return isHeapMajorCollecting() || isHeapMinorCollecting(); } -#ifdef JSGC_COMPACTING bool isHeapCompacting() { return isHeapMajorCollecting() && state() == COMPACT; } -#else - bool isHeapCompacting() { return false; } -#endif bool triggerGC(JS::gcreason::Reason reason); void maybeAllocTriggerZoneGC(Zone *zone, const AutoLockGC &lock); @@ -437,11 +430,9 @@ class GCRuntime void disableGenerationalGC(); void enableGenerationalGC(); -#ifdef JSGC_COMPACTING void disableCompactingGC(); void enableCompactingGC(); bool isCompactingGCEnabled(); -#endif void setGrayRootsTracer(JSTraceDataOp traceOp, void *data); bool addBlackRootsTracer(JSTraceDataOp traceOp, void *data); @@ -604,7 +595,6 @@ class GCRuntime void assertBackgroundSweepingFinished(); bool shouldCompact(); bool compactPhase(bool lastGC); -#ifdef JSGC_COMPACTING void sweepTypesAfterCompacting(Zone *zone); void sweepZoneAfterCompacting(Zone *zone); ArenaHeader *relocateArenas(); @@ -616,7 +606,6 @@ class GCRuntime #ifdef DEBUG void protectRelocatedArenas(ArenaHeader *relocatedList); void unprotectRelocatedArenas(ArenaHeader *relocatedList); -#endif #endif void finishCollection(); @@ -811,13 +800,11 @@ class GCRuntime */ unsigned generationalDisabled; -#ifdef JSGC_COMPACTING /* * Some code cannot tolerate compacting GC so it can be disabled with this * counter. */ unsigned compactingDisabled; -#endif /* * This is true if we are in the middle of a brain transplant (e.g., @@ -918,9 +905,7 @@ class GCRuntime size_t noGCOrAllocationCheck; -#ifdef JSGC_COMPACTING ArenaHeader* relocatedArenasToRelease; -#endif #endif diff --git a/js/src/gc/Heap.h b/js/src/gc/Heap.h index f18d82cd9325..6e53c16948be 100644 --- a/js/src/gc/Heap.h +++ b/js/src/gc/Heap.h @@ -642,10 +642,8 @@ struct ArenaHeader void unmarkAll(); -#ifdef JSGC_COMPACTING size_t countUsedCells(); size_t countFreeCells(); -#endif }; static_assert(ArenaZoneOffset == offsetof(ArenaHeader, zone), "The hardcoded API zone offset must match the actual offset."); diff --git a/js/src/gc/Marking.cpp b/js/src/gc/Marking.cpp index 94500b5ee718..9801a8bd39ea 100644 --- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -161,18 +161,14 @@ CheckMarkedThing(JSTracer *trc, T **thingp) T *thing = *thingp; MOZ_ASSERT(*thingp); -#ifdef JSGC_COMPACTING thing = MaybeForwarded(thing); -#endif /* This function uses data that's not available in the nursery. */ if (IsInsideNursery(thing)) return; -#ifdef JSGC_COMPACTING MOZ_ASSERT_IF(!MovingTracer::IsMovingTracer(trc) && !Nursery::IsMinorCollectionTracer(trc), !IsForwarded(*thingp)); -#endif /* * Permanent atoms are not associated with this runtime, but will be ignored @@ -184,13 +180,8 @@ CheckMarkedThing(JSTracer *trc, T **thingp) Zone *zone = thing->zoneFromAnyThread(); JSRuntime *rt = trc->runtime(); -#ifdef JSGC_COMPACTING MOZ_ASSERT_IF(!MovingTracer::IsMovingTracer(trc), CurrentThreadCanAccessZone(zone)); MOZ_ASSERT_IF(!MovingTracer::IsMovingTracer(trc), CurrentThreadCanAccessRuntime(rt)); -#else - MOZ_ASSERT(CurrentThreadCanAccessZone(zone)); - MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt)); -#endif MOZ_ASSERT(zone->runtimeFromAnyThread() == trc->runtime()); MOZ_ASSERT(trc->hasTracingDetails()); @@ -437,10 +428,8 @@ IsMarkedFromAnyThread(T **thingp) Zone *zone = (*thingp)->asTenured().zoneFromAnyThread(); if (!zone->isCollectingFromAnyThread() || zone->isGCFinished()) return true; -#ifdef JSGC_COMPACTING if (zone->isGCCompacting() && IsForwarded(*thingp)) *thingp = Forwarded(*thingp); -#endif return (*thingp)->asTenured().isMarked(); } @@ -481,12 +470,10 @@ IsAboutToBeFinalizedFromAnyThread(T **thingp) return false; return !thing->asTenured().isMarked(); } -#ifdef JSGC_COMPACTING else if (zone->isGCCompacting() && IsForwarded(thing)) { *thingp = Forwarded(thing); return false; } -#endif return false; } @@ -504,11 +491,10 @@ UpdateIfRelocated(JSRuntime *rt, T **thingp) return *thingp; } -#ifdef JSGC_COMPACTING Zone *zone = (*thingp)->zone(); if (zone->isGCCompacting() && IsForwarded(*thingp)) *thingp = Forwarded(*thingp); -#endif + return *thingp; } diff --git a/js/src/js-config.h.in b/js/src/js-config.h.in index b7a7e1a9f3cd..e7e3e1ed2562 100644 --- a/js/src/js-config.h.in +++ b/js/src/js-config.h.in @@ -31,9 +31,6 @@ /* Define to 1 if SpiderMonkey should use small chunks. */ #undef JS_GC_SMALL_CHUNK_SIZE -/* Define to 1 if SpiderMonkey should use Compacting GC. */ -#undef JSGC_COMPACTING - /* Define to 1 if the header is present and useable. See jscpucfg.h. */ #undef JS_HAVE_ENDIAN_H diff --git a/js/src/jsapi-tests/testWeakMap.cpp b/js/src/jsapi-tests/testWeakMap.cpp index a337bcc3ec63..b49967e9cbf1 100644 --- a/js/src/jsapi-tests/testWeakMap.cpp +++ b/js/src/jsapi-tests/testWeakMap.cpp @@ -66,10 +66,6 @@ checkSize(JS::HandleObject map, uint32_t expected) } END_TEST(testWeakMap_basicOperations) -// TODO: this test stores object pointers in a private slot which is not marked -// and so doesn't work with compacting GC. -#ifndef JSGC_COMPACTING - BEGIN_TEST(testWeakMap_keyDelegates) { JS_SetGCParameter(rt, JSGC_MODE, JSGC_MODE_INCREMENTAL); @@ -253,5 +249,3 @@ checkSize(JS::HandleObject map, uint32_t expected) return true; } END_TEST(testWeakMap_keyDelegates) - -#endif diff --git a/js/src/jscompartment.cpp b/js/src/jscompartment.cpp index b267be3d0ca2..d579615db44c 100644 --- a/js/src/jscompartment.cpp +++ b/js/src/jscompartment.cpp @@ -649,8 +649,6 @@ JSCompartment::sweepCrossCompartmentWrappers() } } -#ifdef JSGC_COMPACTING - void JSCompartment::fixupAfterMovingGC() { fixupGlobal(); @@ -667,8 +665,6 @@ JSCompartment::fixupGlobal() global_.set(MaybeForwarded(global)); } -#endif // JSGC_COMPACTING - void JSCompartment::purge() { diff --git a/js/src/jscompartment.h b/js/src/jscompartment.h index c6968cd45e22..732c445859f9 100644 --- a/js/src/jscompartment.h +++ b/js/src/jscompartment.h @@ -398,12 +398,10 @@ struct JSCompartment void purge(); void clearTables(); -#ifdef JSGC_COMPACTING void fixupInitialShapeTable(); void fixupNewTypeObjectTable(js::types::NewTypeObjectTable &table); void fixupAfterMovingGC(); void fixupGlobal(); -#endif bool hasObjectMetadataCallback() const { return objectMetadataCallback; } void setObjectMetadataCallback(js::ObjectMetadataCallback callback); diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 1b0cf04cfa1f..2680f0902f62 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -1112,9 +1112,7 @@ GCRuntime::GCRuntime(JSRuntime *rt) : sliceBudget(SliceBudget::Unlimited), incrementalAllowed(true), generationalDisabled(0), -#ifdef JSGC_COMPACTING compactingDisabled(0), -#endif manipulatingDeadZones(false), objectsMarkedInDeadZones(0), poked(false), @@ -1134,9 +1132,7 @@ GCRuntime::GCRuntime(JSRuntime *rt) : #ifdef DEBUG inUnsafeRegion(0), noGCOrAllocationCheck(0), -#ifdef JSGC_COMPACTING relocatedArenasToRelease(nullptr), -#endif #endif lock(nullptr), lockOwner(nullptr), @@ -1930,15 +1926,9 @@ ArenaLists::allocateFromArenaInner(JS::Zone *zone, ArenaHeader *aheader, AllocKi bool GCRuntime::shouldCompact() { -#ifdef JSGC_COMPACTING return invocationKind == GC_SHRINK && isCompactingGCEnabled(); -#else - return false; -#endif } -#ifdef JSGC_COMPACTING - void GCRuntime::disableCompactingGC() { @@ -2715,12 +2705,10 @@ GCRuntime::releaseRelocatedArenasWithoutUnlocking(ArenaHeader *relocatedList, co } } -#endif // JSGC_COMPACTING - void GCRuntime::releaseHeldRelocatedArenas() { -#if defined(JSGC_COMPACTING) && defined(DEBUG) +#ifdef DEBUG // In debug mode we don't release relocated arenas straight away. Instead // we protect them and hold onto them until the next GC sweep phase to catch // any pointers to them that didn't get forwarded. @@ -5480,9 +5468,6 @@ GCRuntime::endSweepPhase(bool lastGC) bool GCRuntime::compactPhase(bool lastGC) { -#ifndef JSGC_COMPACTING - MOZ_CRASH(); -#else gcstats::AutoPhase ap(stats, gcstats::PHASE_COMPACT); if (isIncremental) { @@ -5547,8 +5532,6 @@ GCRuntime::compactPhase(bool lastGC) } } #endif - -#endif // JSGC_COMPACTING return true; } @@ -5708,7 +5691,6 @@ GCRuntime::resetIncrementalGC(const char *reason) break; } -#ifdef JSGC_COMPACTING case COMPACT: { { gcstats::AutoPhase ap(stats, gcstats::PHASE_WAIT_BACKGROUND_THREAD); @@ -5724,7 +5706,6 @@ GCRuntime::resetIncrementalGC(const char *reason) invocationKind = oldInvocationKind; break; } -#endif default: MOZ_CRASH("Invalid incremental GC state"); @@ -6412,7 +6393,7 @@ GCRuntime::onOutOfMallocMemory(const AutoLockGC &lock) { // Release any relocated arenas we may be holding on to, without releasing // the GC lock. -#if defined(JSGC_COMPACTING) && defined(DEBUG) +#ifdef DEBUG unprotectRelocatedArenas(relocatedArenasToRelease); releaseRelocatedArenasWithoutUnlocking(relocatedArenasToRelease, lock); relocatedArenasToRelease = nullptr; @@ -7133,19 +7114,13 @@ JS::IsIncrementalGCEnabled(JSRuntime *rt) JS_PUBLIC_API(void) JS::DisableCompactingGC(JSRuntime *rt) { -#ifdef JSGC_COMPACTING rt->gc.disableCompactingGC(); -#endif } JS_PUBLIC_API(bool) JS::IsCompactingGCEnabled(JSRuntime *rt) { -#ifdef JSGC_COMPACTING return rt->gc.isCompactingGCEnabled(); -#else - return false; -#endif } JS_PUBLIC_API(bool) diff --git a/js/src/jsgc.h b/js/src/jsgc.h index 0bd8f37e1982..7cb3c6ed1649 100644 --- a/js/src/jsgc.h +++ b/js/src/jsgc.h @@ -454,11 +454,9 @@ class ArenaList { return *this; } -#ifdef JSGC_COMPACTING ArenaHeader *removeRemainingArenas(ArenaHeader **arenap, const AutoLockGC &lock); ArenaHeader *pickArenasToRelocate(JSRuntime *runtime); ArenaHeader *relocateArenas(ArenaHeader *toRelocate, ArenaHeader *relocated); -#endif }; /* @@ -785,9 +783,7 @@ class ArenaLists MOZ_ASSERT(freeLists[kind].isEmpty()); } -#ifdef JSGC_COMPACTING ArenaHeader *relocateArenas(ArenaHeader *relocatedList); -#endif void queueForegroundObjectsForSweep(FreeOp *fop); void queueForegroundThingsForSweep(FreeOp *fop); @@ -1270,9 +1266,7 @@ inline void CheckGCThingAfterMovingGC(T *t) { MOZ_ASSERT_IF(t, !IsInsideNursery(t)); -#ifdef JSGC_COMPACTING MOZ_ASSERT_IF(t, !IsForwarded(t)); -#endif } inline void @@ -1429,16 +1423,11 @@ struct AutoDisableProxyCheck struct AutoDisableCompactingGC { -#ifdef JSGC_COMPACTING explicit AutoDisableCompactingGC(JSRuntime *rt); ~AutoDisableCompactingGC(); private: gc::GCRuntime &gc; -#else - explicit AutoDisableCompactingGC(JSRuntime *rt) {} - ~AutoDisableCompactingGC() {} -#endif }; void diff --git a/js/src/jsinfer.cpp b/js/src/jsinfer.cpp index 8900558dc1be..0ea1d8d0dfa3 100644 --- a/js/src/jsinfer.cpp +++ b/js/src/jsinfer.cpp @@ -4891,8 +4891,6 @@ JSCompartment::sweepNewTypeObjectTable(NewTypeObjectTable &table) } } -#ifdef JSGC_COMPACTING - void JSCompartment::fixupNewTypeObjectTable(NewTypeObjectTable &table) { @@ -4966,8 +4964,6 @@ TypeObject::fixupAfterMovingGC() } } -#endif // JSGC_COMPACTING - #ifdef JSGC_HASH_TABLE_CHECKS void diff --git a/js/src/jsinfer.h b/js/src/jsinfer.h index 3d10cbae2961..2c42fd432b75 100644 --- a/js/src/jsinfer.h +++ b/js/src/jsinfer.h @@ -925,10 +925,7 @@ class TypeNewScript void trace(JSTracer *trc); void sweep(); - -#ifdef JSGC_COMPACTING void fixupAfterMovingGC(); -#endif void registerNewObject(PlainObject *res); void unregisterNewObject(PlainObject *res); @@ -1241,9 +1238,7 @@ struct TypeObject : public gc::TenuredCell flags_ |= generation << OBJECT_FLAG_GENERATION_SHIFT; } -#ifdef JSGC_COMPACTING void fixupAfterMovingGC(); -#endif size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const; diff --git a/js/src/jspropertytree.cpp b/js/src/jspropertytree.cpp index 9a3d005c4b71..8dcb4b6ebbd4 100644 --- a/js/src/jspropertytree.cpp +++ b/js/src/jspropertytree.cpp @@ -235,8 +235,6 @@ Shape::finalize(FreeOp *fop) fop->delete_(kids.toHash()); } -#ifdef JSGC_COMPACTING - void Shape::fixupDictionaryShapeAfterMovingGC() { @@ -322,8 +320,6 @@ Shape::fixupAfterMovingGC() fixupShapeTreeAfterMovingGC(); } -#endif // JSGC_COMPACTING - void ShapeGetterSetterRef::mark(JSTracer *trc) { diff --git a/js/src/jspubtd.h b/js/src/jspubtd.h index be8894f126ea..15e83e6e752e 100644 --- a/js/src/jspubtd.h +++ b/js/src/jspubtd.h @@ -20,8 +20,7 @@ #include "js/TypeDecls.h" -#if (defined(JS_GC_ZEAL)) || \ - (defined(JSGC_COMPACTING) && defined(DEBUG)) +#if (defined(JS_GC_ZEAL)) || defined(DEBUG) # define JSGC_HASH_TABLE_CHECKS #endif diff --git a/js/src/vm/Shape-inl.h b/js/src/vm/Shape-inl.h index a17755fed1ce..0b5c3ebeb807 100644 --- a/js/src/vm/Shape-inl.h +++ b/js/src/vm/Shape-inl.h @@ -224,14 +224,12 @@ GetShapeAttributes(JSObject *obj, Shape *shape) return shape->attributes(); } -#ifdef JSGC_COMPACTING inline void BaseShape::fixupAfterMovingGC() { if (hasTable()) table().fixupAfterMovingGC(); } -#endif } /* namespace js */ diff --git a/js/src/vm/Shape.cpp b/js/src/vm/Shape.cpp index 70b86fbb4505..5caf797d9287 100644 --- a/js/src/vm/Shape.cpp +++ b/js/src/vm/Shape.cpp @@ -256,7 +256,6 @@ ShapeTable::search(jsid id, bool adding) MOZ_CRASH("Shape::search failed to find an expected entry."); } -#ifdef JSGC_COMPACTING void ShapeTable::fixupAfterMovingGC() { @@ -268,7 +267,6 @@ ShapeTable::fixupAfterMovingGC() entry.setPreservingCollision(Forwarded(shape)); } } -#endif bool ShapeTable::change(int log2Delta, ExclusiveContext *cx) @@ -1693,7 +1691,6 @@ JSCompartment::sweepInitialShapeTable() } } -#ifdef JSGC_COMPACTING void JSCompartment::fixupInitialShapeTable() { @@ -1732,7 +1729,6 @@ JSCompartment::fixupInitialShapeTable() } } } -#endif // JSGC_COMPACTING void AutoRooterGetterSetter::Inner::trace(JSTracer *trc) diff --git a/js/src/vm/Shape.h b/js/src/vm/Shape.h index 37cf4e15fa74..a7416b02673d 100644 --- a/js/src/vm/Shape.h +++ b/js/src/vm/Shape.h @@ -227,10 +227,8 @@ class ShapeTable { bool change(int log2Delta, ExclusiveContext *cx); Entry &search(jsid id, bool adding); -#ifdef JSGC_COMPACTING /* Update entries whose shapes have been moved */ void fixupAfterMovingGC(); -#endif private: Entry &getEntry(uint32_t i) const { @@ -530,9 +528,7 @@ class BaseShape : public gc::TenuredCell gc::MarkObject(trc, &metadata, "metadata"); } -#ifdef JSGC_COMPACTING void fixupAfterMovingGC(); -#endif private: static void staticAsserts() { @@ -1061,9 +1057,7 @@ class Shape : public gc::TenuredCell inline Shape *search(ExclusiveContext *cx, jsid id); inline Shape *searchLinear(jsid id); -#ifdef JSGC_COMPACTING void fixupAfterMovingGC(); -#endif /* For JIT usage */ static inline size_t offsetOfBase() { return offsetof(Shape, base_); } @@ -1071,10 +1065,8 @@ class Shape : public gc::TenuredCell static inline uint32_t fixedSlotsMask() { return FIXED_SLOTS_MASK; } private: -#ifdef JSGC_COMPACTING void fixupDictionaryShapeAfterMovingGC(); void fixupShapeTreeAfterMovingGC(); -#endif static void staticAsserts() { JS_STATIC_ASSERT(offsetof(Shape, base_) == offsetof(js::shadow::Shape, base)); From f42106a9ce2208e45ce45987a022de3d30cc0443 Mon Sep 17 00:00:00 2001 From: Arpad Borsos Date: Tue, 9 Dec 2014 10:54:26 +0100 Subject: [PATCH 04/62] Bug 932080 - part0: Reflect.parse changes for destructuring; r=jorendorff --HG-- extra : rebase_source : 3050ae24cc23ed472b6cbd34079cd90547294c9e --- .../tests/js1_8_5/extensions/reflect-parse.js | 56 ++++++++++--------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/js/src/tests/js1_8_5/extensions/reflect-parse.js b/js/src/tests/js1_8_5/extensions/reflect-parse.js index 7e7d73c22594..405b169fadbf 100644 --- a/js/src/tests/js1_8_5/extensions/reflect-parse.js +++ b/js/src/tests/js1_8_5/extensions/reflect-parse.js @@ -112,6 +112,11 @@ function compOfBlock(left, right) Pattern({ type: "ComprehensionBlock", left: le function arrPatt(elts) Pattern({ type: "ArrayPattern", elements: elts }) function objPatt(elts) Pattern({ type: "ObjectPattern", properties: elts }) +function assignElem(target, defaultExpr = null, targetIdent = typeof target == 'string' ? ident(target) : target) defaultExpr ? aExpr('=', targetIdent, defaultExpr) : targetIdent +function assignProp(property, target, defaultExpr = null, shorthand = !target, targetProp = target || ident(property)) Pattern({ + type: "Property", key: ident(property), shorthand, + value: defaultExpr ? aExpr('=', targetProp, defaultExpr) : targetProp }) + function localSrc(src) "(function(){ " + src + " })" function localPatt(patt) program([exprStmt(funExpr(null, [], blockStmt([patt])))]) function blockSrc(src) "(function(){ { " + src + " } })" @@ -235,7 +240,7 @@ assertDecl("function f(a,b,c) { function b() { } }", funDecl(ident("f"), [ident("a"),ident("b"),ident("c")], blockStmt([funDecl(ident("b"), [], blockStmt([]))]))); assertDecl("function f(a,[x,y]) { function a() { } }", funDecl(ident("f"), - [ident("a"), arrPatt([ident("x"), ident("y")])], + [ident("a"), arrPatt([assignElem("x"), assignElem("y")])], blockStmt([funDecl(ident("a"), [], blockStmt([]))]))); // Bug 632027: array holes should reflect as null @@ -269,7 +274,7 @@ assertExpr("a => b => a", arrowExpr([ident("a")], arrowExpr([ident("b")], ident( assertExpr("a => {}", arrowExpr([ident("a")], blockStmt([]))); assertExpr("a => ({})", arrowExpr([ident("a")], objExpr([]))); assertExpr("(a, b, c) => {}", arrowExpr([ident("a"), ident("b"), ident("c")], blockStmt([]))); -assertExpr("([a, b]) => {}", arrowExpr([arrPatt([ident("a"), ident("b")])], blockStmt([]))); +assertExpr("([a, b]) => {}", arrowExpr([arrPatt([assignElem("a"), assignElem("b")])], blockStmt([]))); assertExpr("(++x)", updExpr("++", ident("x"), true)); assertExpr("(x++)", updExpr("++", ident("x"), false)); assertExpr("(+x)", unExpr("+", ident("x"))); @@ -566,9 +571,9 @@ assertStmt("function f() { var x = 42; var x = 43; }", varDecl([{ id: ident("x"), init: lit(43) }])]))); -assertDecl("var {x:y} = foo;", varDecl([{ id: objPatt([{ key: ident("x"), value: ident("y"), shorthand: false }]), +assertDecl("var {x:y} = foo;", varDecl([{ id: objPatt([assignProp("x", ident("y"))]), init: ident("foo") }])); -assertDecl("var {x} = foo;", varDecl([{ id: objPatt([{ key: ident("x"), value: ident("x"), shorthand: true }]), +assertDecl("var {x} = foo;", varDecl([{ id: objPatt([assignProp("x")]), init: ident("foo") }])); // Bug 632030: redeclarations between var and funargs, var and function @@ -581,16 +586,16 @@ assertProg("f.p = 1; var f; f.p; function f(){}", funDecl(ident("f"), [], blockStmt([]))]); // global let is var -assertGlobalDecl("let {x:y} = foo;", varDecl([{ id: objPatt([{ key: ident("x"), value: ident("y") }]), +assertGlobalDecl("let {x:y} = foo;", varDecl([{ id: objPatt([assignProp("x", ident("y"))]), init: ident("foo") }])); // function-global let is let -assertLocalDecl("let {x:y} = foo;", letDecl([{ id: objPatt([{ key: ident("x"), value: ident("y") }]), +assertLocalDecl("let {x:y} = foo;", letDecl([{ id: objPatt([assignProp("x", ident("y"))]), init: ident("foo") }])); // block-local let is let -assertBlockDecl("let {x:y} = foo;", letDecl([{ id: objPatt([{ key: ident("x"), value: ident("y") }]), +assertBlockDecl("let {x:y} = foo;", letDecl([{ id: objPatt([assignProp("x", ident("y"))]), init: ident("foo") }])); -assertDecl("const {x:y} = foo;", constDecl([{ id: objPatt([{ key: ident("x"), value: ident("y") }]), +assertDecl("const {x:y} = foo;", constDecl([{ id: objPatt([assignProp("x", ident("y"))]), init: ident("foo") }])); @@ -670,16 +675,15 @@ function testParamPatternCombinations(makePattSrc, makePattPatt) { } testParamPatternCombinations(function(n) ("{a" + n + ":x" + n + "," + "b" + n + ":y" + n + "," + "c" + n + ":z" + n + "}"), - function(n) (objPatt([{ key: ident("a" + n), value: ident("x" + n) }, - { key: ident("b" + n), value: ident("y" + n) }, - { key: ident("c" + n), value: ident("z" + n) }]))); + function(n) (objPatt([assignProp("a" + n, ident("x" + n)), + assignProp("b" + n, ident("y" + n)), + assignProp("c" + n, ident("z" + n))]))); testParamPatternCombinations(function(n) ("[x" + n + "," + "y" + n + "," + "z" + n + "]"), - function(n) (arrPatt([ident("x" + n), ident("y" + n), ident("z" + n)]))); + function(n) (arrPatt([assignElem("x" + n), assignElem("y" + n), assignElem("z" + n)]))); testParamPatternCombinations(function(n) ("[a" + n + ", ..." + "b" + n + "]"), - function(n) (arrPatt([ident("a" + n), spread(ident("b" + n))]))); - + function(n) (arrPatt([assignElem("a" + n), spread(ident("b" + n))]))); // destructuring variable declarations @@ -712,17 +716,17 @@ function testVarPatternCombinations(makePattSrc, makePattPatt) { } testVarPatternCombinations(function (n) ("{a" + n + ":x" + n + "," + "b" + n + ":y" + n + "," + "c" + n + ":z" + n + "} = 0"), - function (n) ({ id: objPatt([{ key: ident("a" + n), value: ident("x" + n) }, - { key: ident("b" + n), value: ident("y" + n) }, - { key: ident("c" + n), value: ident("z" + n) }]), + function (n) ({ id: objPatt([assignProp("a" + n, ident("x" + n)), + assignProp("b" + n, ident("y" + n)), + assignProp("c" + n, ident("z" + n))]), init: lit(0) })); testVarPatternCombinations(function(n) ("[x" + n + "," + "y" + n + "," + "z" + n + "] = 0"), - function(n) ({ id: arrPatt([ident("x" + n), ident("y" + n), ident("z" + n)]), + function(n) ({ id: arrPatt([assignElem("x" + n), assignElem("y" + n), assignElem("z" + n)]), init: lit(0) })); testVarPatternCombinations(function(n) ("[a" + n + ", ..." + "b" + n + "] = 0"), - function(n) ({ id: arrPatt([ident("a" + n), spread(ident("b" + n))]), + function(n) ({ id: arrPatt([assignElem("a" + n), spread(ident("b" + n))]), init: lit(0) })); // destructuring assignment @@ -746,18 +750,18 @@ function testAssignmentCombinations(makePattSrc, makePattPatt) { testAssignmentCombinations(function (n) ("{a" + n + ":x" + n + "," + "b" + n + ":y" + n + "," + "c" + n + ":z" + n + "} = 0"), function (n) (aExpr("=", - objPatt([{ key: ident("a" + n), value: ident("x" + n) }, - { key: ident("b" + n), value: ident("y" + n) }, - { key: ident("c" + n), value: ident("z" + n) }]), + objPatt([assignProp("a" + n, ident("x" + n)), + assignProp("b" + n, ident("y" + n)), + assignProp("c" + n, ident("z" + n))]), lit(0)))); // destructuring in for-in and for-each-in loop heads -var axbycz = objPatt([{ key: ident("a"), value: ident("x") }, - { key: ident("b"), value: ident("y") }, - { key: ident("c"), value: ident("z") }]); -var xyz = arrPatt([ident("x"), ident("y"), ident("z")]); +var axbycz = objPatt([assignProp("a", ident("x")), + assignProp("b", ident("y")), + assignProp("c", ident("z"))]); +var xyz = arrPatt([assignElem("x"), assignElem("y"), assignElem("z")]); assertStmt("for (var {a:x,b:y,c:z} in foo);", forInStmt(varDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt)); assertStmt("for (let {a:x,b:y,c:z} in foo);", forInStmt(letDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt)); From fb018eecf1d0e1c3274767eb177df5c633a60943 Mon Sep 17 00:00:00 2001 From: Arpad Borsos Date: Tue, 9 Dec 2014 10:33:51 +0100 Subject: [PATCH 05/62] Bug 932080 - part1: support default values in destructuring of array and full objects; r=jorendorff --HG-- extra : rebase_source : d89417a57082915cc447f477d2ab6e85f30d3a2a --- js/src/frontend/BytecodeEmitter.cpp | 93 +++++++--- js/src/frontend/Parser.cpp | 4 + .../tests/basic/destructuring-default.js | 166 ++++++++++++++++++ .../tests/js1_8_5/extensions/reflect-parse.js | 17 ++ 4 files changed, 258 insertions(+), 22 deletions(-) create mode 100644 js/src/jit-test/tests/basic/destructuring-default.js diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index 6068a14968fb..4f3ea5f61f11 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -3257,6 +3257,8 @@ EmitDestructuringDeclsWithEmitter(ExclusiveContext *cx, BytecodeEmitter *bce, JS MOZ_ASSERT(element->pn_kid->isKind(PNK_NAME)); target = element->pn_kid; } + if (target->isKind(PNK_ASSIGN)) + target = target->pn_left; if (target->isKind(PNK_NAME)) { if (!EmitName(cx, bce, prologOp, target)) return false; @@ -3276,6 +3278,8 @@ EmitDestructuringDeclsWithEmitter(ExclusiveContext *cx, BytecodeEmitter *bce, JS ParseNode *target = member->isKind(PNK_MUTATEPROTO) ? member->pn_kid : member->pn_right; + if (target->isKind(PNK_ASSIGN)) + target = target->pn_left; if (target->isKind(PNK_NAME)) { if (!EmitName(cx, bce, prologOp, target)) return false; @@ -3341,7 +3345,7 @@ EmitDestructuringOpsHelper(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode * lhs expression. (Same post-condition as EmitDestructuringOpsHelper) */ static bool -EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, VarEmitOption emitOption) +EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *target, VarEmitOption emitOption) { MOZ_ASSERT(emitOption != DefineVars); @@ -3349,10 +3353,12 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, // destructuring initialiser-form, call ourselves to handle it, then pop // the matched value. Otherwise emit an lvalue bytecode sequence followed // by an assignment op. - if (pn->isKind(PNK_SPREAD)) - pn = pn->pn_kid; - if (pn->isKind(PNK_ARRAY) || pn->isKind(PNK_OBJECT)) { - if (!EmitDestructuringOpsHelper(cx, bce, pn, emitOption)) + if (target->isKind(PNK_SPREAD)) + target = target->pn_kid; + else if (target->isKind(PNK_ASSIGN)) + target = target->pn_left; + if (target->isKind(PNK_ARRAY) || target->isKind(PNK_OBJECT)) { + if (!EmitDestructuringOpsHelper(cx, bce, target, emitOption)) return false; if (emitOption == InitializeVars) { // Per its post-condition, EmitDestructuringOpsHelper has left the @@ -3363,15 +3369,15 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, } else if (emitOption == PushInitialValues) { // The lhs is a simple name so the to-be-destructured value is // its initial value and there is nothing to do. - MOZ_ASSERT(pn->getOp() == JSOP_SETLOCAL || pn->getOp() == JSOP_INITLEXICAL); - MOZ_ASSERT(pn->pn_dflags & PND_BOUND); + MOZ_ASSERT(target->getOp() == JSOP_SETLOCAL || target->getOp() == JSOP_INITLEXICAL); + MOZ_ASSERT(target->pn_dflags & PND_BOUND); } else { - switch (pn->getKind()) { + switch (target->getKind()) { case PNK_NAME: - if (!BindNameToSlot(cx, bce, pn)) + if (!BindNameToSlot(cx, bce, target)) return false; - switch (pn->getOp()) { + switch (target->getOp()) { case JSOP_SETNAME: case JSOP_STRICTSETNAME: case JSOP_SETGNAME: @@ -3388,11 +3394,11 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, // but the operands are on the stack in the wrong order for // JSOP_SETPROP, so we have to add a JSOP_SWAP. jsatomid atomIndex; - if (!bce->makeAtomIndex(pn->pn_atom, &atomIndex)) + if (!bce->makeAtomIndex(target->pn_atom, &atomIndex)) return false; - if (!pn->isOp(JSOP_SETCONST)) { - bool global = pn->isOp(JSOP_SETGNAME) || pn->isOp(JSOP_STRICTSETGNAME); + if (!target->isOp(JSOP_SETCONST)) { + bool global = target->isOp(JSOP_SETGNAME) || target->isOp(JSOP_STRICTSETGNAME); JSOp bindOp = global ? JSOP_BINDGNAME : JSOP_BINDNAME; if (!EmitIndex32(cx, bindOp, atomIndex, bce)) return false; @@ -3400,7 +3406,7 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, return false; } - if (!EmitIndexOp(cx, pn->getOp(), atomIndex, bce)) + if (!EmitIndexOp(cx, target->getOp(), atomIndex, bce)) return false; break; } @@ -3408,7 +3414,7 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, case JSOP_SETLOCAL: case JSOP_SETARG: case JSOP_INITLEXICAL: - if (!EmitVarOp(cx, pn, pn->getOp(), bce)) + if (!EmitVarOp(cx, target, target->getOp(), bce)) return false; break; @@ -3427,12 +3433,12 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, // In `[a.x] = [b]`, per spec, `b` is evaluated before `a`. Then we // need a property set -- but the operands are on the stack in the // wrong order for JSOP_SETPROP, so we have to add a JSOP_SWAP. - if (!EmitTree(cx, bce, pn->pn_expr)) + if (!EmitTree(cx, bce, target->pn_expr)) return false; if (Emit1(cx, bce, JSOP_SWAP) < 0) return false; JSOp setOp = bce->sc->strict ? JSOP_STRICTSETPROP : JSOP_SETPROP; - if (!EmitAtomOp(cx, pn, setOp, bce)) + if (!EmitAtomOp(cx, target, setOp, bce)) return false; break; } @@ -3443,14 +3449,14 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, // `[a[x]] = [b]`, is handled much the same way. The JSOP_SWAP // is emitted by EmitElemOperands. JSOp setOp = bce->sc->strict ? JSOP_STRICTSETELEM : JSOP_SETELEM; - if (!EmitElemOp(cx, pn, setOp, bce)) + if (!EmitElemOp(cx, target, setOp, bce)) return false; break; } case PNK_CALL: - MOZ_ASSERT(pn->pn_xflags & PNX_SETCALL); - if (!EmitTree(cx, bce, pn)) + MOZ_ASSERT(target->pn_xflags & PNX_SETCALL); + if (!EmitTree(cx, bce, target)) return false; // Pop the call return value. Below, we pop the RHS too, balancing @@ -3500,6 +3506,33 @@ EmitIteratorNext(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn=nullp return true; } +/** + * EmitDefault will check if the value on top of the stack is "undefined". + * If so, it will replace that value on the stack with the value defined by |defaultExpr|. + */ +static bool +EmitDefault(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *defaultExpr) +{ + if (Emit1(cx, bce, JSOP_DUP) < 0) // VALUE VALUE + return false; + if (Emit1(cx, bce, JSOP_UNDEFINED) < 0) // VALUE VALUE UNDEFINED + return false; + if (Emit1(cx, bce, JSOP_STRICTEQ) < 0) // VALUE EQL? + return false; + // Emit source note to enable ion compilation. + if (NewSrcNote(cx, bce, SRC_IF) < 0) + return false; + ptrdiff_t jump = EmitJump(cx, bce, JSOP_IFEQ, 0); // VALUE + if (jump < 0) + return false; + if (Emit1(cx, bce, JSOP_POP) < 0) // . + return false; + if (!EmitTree(cx, bce, defaultExpr)) // DEFAULTVALUE + return false; + SetJumpOffsetAt(bce, jump); + return true; +} + static bool EmitDestructuringOpsArrayHelper(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pattern, VarEmitOption emitOption) @@ -3526,7 +3559,14 @@ EmitDestructuringOpsArrayHelper(ExclusiveContext *cx, BytecodeEmitter *bce, Pars * current property name "label" on the left of a colon in the object * initializer. */ - if (member->isKind(PNK_SPREAD)) { + ParseNode *pndefault = nullptr; + ParseNode *elem = member; + if (elem->isKind(PNK_ASSIGN)) { + pndefault = elem->pn_right; + elem = elem->pn_left; + } + + if (elem->isKind(PNK_SPREAD)) { /* Create a new array with the rest of the iterator */ ptrdiff_t off = EmitN(cx, bce, JSOP_NEWARRAY, 3); // ... OBJ? ITER ARRAY if (off < 0) @@ -3581,8 +3621,11 @@ EmitDestructuringOpsArrayHelper(ExclusiveContext *cx, BytecodeEmitter *bce, Pars return false; } + if (pndefault && !EmitDefault(cx, bce, pndefault)) + return false; + // Destructure into the pattern the element contains. - ParseNode *subpattern = member; + ParseNode *subpattern = elem; if (subpattern->isKind(PNK_ELISION)) { // The value destructuring into an elision just gets ignored. if (Emit1(cx, bce, JSOP_POP) < 0) // ... OBJ? ITER @@ -3684,6 +3727,12 @@ EmitDestructuringOpsObjectHelper(ExclusiveContext *cx, BytecodeEmitter *bce, Par if (needsGetElem && !EmitElemOpBase(cx, bce, JSOP_GETELEM)) // ... OBJ PROP return false; + if (subpattern->isKind(PNK_ASSIGN)) { + if (!EmitDefault(cx, bce, subpattern->pn_right)) + return false; + subpattern = subpattern->pn_left; + } + // Destructure PROP per this member's subpattern. int32_t depthBefore = bce->stackDepth; if (!EmitDestructuringLHS(cx, bce, subpattern, emitOption)) diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index 2c1e3efc7526..a57ae2464813 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -3385,6 +3385,8 @@ Parser::checkDestructuringObject(BindData *d MOZ_ASSERT(member->isKind(PNK_COLON) || member->isKind(PNK_SHORTHAND)); expr = member->pn_right; } + if (expr->isKind(PNK_ASSIGN)) + expr = expr->pn_left; bool ok; if (expr->isKind(PNK_ARRAY) || expr->isKind(PNK_OBJECT)) { @@ -3429,6 +3431,8 @@ Parser::checkDestructuringArray(BindData *da report(ParseError, false, target, JSMSG_BAD_DESTRUCT_TARGET); return false; } + } else if (target->isKind(PNK_ASSIGN)) { + target = target->pn_left; } bool ok; diff --git a/js/src/jit-test/tests/basic/destructuring-default.js b/js/src/jit-test/tests/basic/destructuring-default.js new file mode 100644 index 000000000000..d5d22d412a38 --- /dev/null +++ b/js/src/jit-test/tests/basic/destructuring-default.js @@ -0,0 +1,166 @@ + +load(libdir + 'asserts.js'); +load(libdir + 'eqArrayHelper.js'); + +var arrayPattern = '[a = 1, b = 2, c = 3, d = 4, e = 5, f = 6]'; +var objectPattern = '{0: a = 1, 1: b = 2, 2: c = 3, 3: d = 4, 4: e = 5, 5: f = 6}'; +var nestedPattern = '{a: a = 1, b: [b = 2] = [], c: {c: [c]} = {c: [3]}, d: {d, e} = {d: 4, e: 5}, f: f = 6}'; + +function testAll(fn) { + assertEqArray(fn(arrayPattern, []), [1, 2, 3, 4, 5, 6]); + assertEqArray(fn(arrayPattern, [2, 3, 4, 5, 6, 7, 8, 9]), [2, 3, 4, 5, 6, 7]); + assertEqArray(fn(arrayPattern, [undefined, 0, false, null, "", undefined]), [1, 0, false, null, "", 6]); + assertEqArray(fn(arrayPattern, [0, false]), [0, false, 3, 4, 5, 6]); + + assertEqArray(fn(objectPattern, []), [1, 2, 3, 4, 5, 6]); + assertEqArray(fn(objectPattern, [2, 3, 4, 5, 6, 7, 8, 9]), [2, 3, 4, 5, 6, 7]); + assertEqArray(fn(objectPattern, [undefined, 0, false, null, "", undefined]), [1, 0, false, null, "", 6]); + assertEqArray(fn(objectPattern, [0, false]), [0, false, 3, 4, 5, 6]); + + assertEqArray(fn(nestedPattern, {}), [1, 2, 3, 4, 5, 6]); + assertEqArray(fn(nestedPattern, {a: 2, b: [], c: undefined}), [2, 2, 3, 4, 5, 6]); + assertEqArray(fn(nestedPattern, {a: undefined, b: [3], c: {c: [4]}}), [1, 3, 4, 4, 5, 6]); + assertEqArray(fn(nestedPattern, {a: undefined, b: [3], c: {c: [4]}, d: {d: 5, e: 6}}), [1, 3, 4, 5, 6, 6]); +} + +function testVar(pattern, input) { + return new Function('input', + 'var ' + pattern + ' = input;' + + 'return [a, b, c, d, e, f];' + )(input); +} +testAll(testVar); + +function testLet(pattern, input) { + return new Function('input', + 'let ' + pattern + ' = input;' + + 'return [a, b, c, d, e, f];' + )(input); +} +testAll(testLet); + +function testConst(pattern, input) { + return new Function('input', + 'const ' + pattern + ' = input;' + + 'return [a, b, c, d, e, f];' + )(input); +} +testAll(testConst); + +function testGlobal(pattern, input) { + return new Function('input', + '(' + pattern + ') = input;' + + 'return [a, b, c, d, e, f];' + )(input); +} +testAll(testGlobal); + +function testClosure(pattern, input) { + return new Function('input', + 'var rest; (function () {' + + '(' + pattern + ') = input;' + + '})();' + + 'return [a, b, c, d, e, f];' + )(input); +} +testAll(testClosure); + +function testArgument(pattern, input) { + return new Function('input', + 'return (function (' + pattern + ') {' + + 'return [a, b, c, d, e, f]; })(input);' + )(input); +} +testAll(testArgument); + +function testArgumentFunction(pattern, input) { + return new Function(pattern, + 'return [a, b, c, d, e, f];' + )(input); +} +// XXX: ES6 requires the `Function` constructor to accept arbitrary +// `BindingElement`s as formal parameters. See Bug 1037939. +// Once fixed, please update the assertions below. +assertThrowsInstanceOf(() => testAll(testArgumentFunction), SyntaxError); + +function testThrow(pattern, input) { + return new Function('input', + 'try { throw input }' + + 'catch(' + pattern + ') {' + + 'return [a, b, c, d, e, f]; }' + )(input); +} +testAll(testThrow); + +// XXX: Support for let blocks and expressions will be removed in bug 1023609. +// However, they test a special code path in destructuring assignment so having +// these tests here for now seems like a good idea. +function testLetBlock(pattern, input) { + return new Function('input', + 'let (' + pattern + ' = input)' + + '{ return [a, b, c, d, e, f]; }' + )(input); +} +testAll(testLetBlock); + +function testLetExpression(pattern, input) { + return new Function('input', + 'return (let (' + pattern + ' = input) [a, b, c, d, e, f]);' + )(input); +} +testAll(testLetExpression); + +// test global const +const [ca = 1, cb = 2] = []; +assertEq(ca, 1); +assertEq(cb, 2); + +const {a: {a: cc = 3} = {a: undefined}} = {}; +assertEq(cc, 3); + +// test that the assignment happens in source order +var a = undefined, b = undefined, c = undefined; +({a: a = 1, c: c = 2, b: b = 3}) = { + get a() { + assertEq(a, undefined); + assertEq(c, undefined); + assertEq(b, undefined); + return undefined; + }, + get b() { + assertEq(a, 1); + assertEq(c, 2); + assertEq(b, undefined); + return 4; + }, + get c() { + assertEq(a, 1); + assertEq(c, undefined); + assertEq(b, undefined); + return undefined; + } +}; +assertEq(b, 4); + +assertThrowsInstanceOf(() => { var {a: {a} = null} = {}; }, TypeError); +assertThrowsInstanceOf(() => { var [[a] = 2] = []; }, TypeError); + +// destructuring assignment might have duplicate variable names. +var [a = 1, a = 2] = [3]; +assertEq(a, 2); + +// assignment to properties of default params +[a = {y: 2}, a.x = 1] = []; +assertEq(typeof a, 'object'); +assertEq(a.x, 1); +assertEq(a.y, 2); + +// defaults are evaluated even if there is no binding +var evaled = false; +({a: {} = (evaled = true, null)}) = {}; +assertEq(evaled, true); +evaled = false; +assertThrowsInstanceOf(() => { [[] = (evaled = true, 2)] = [] }, TypeError); +assertEq(evaled, true); + +assertThrowsInstanceOf(() => new Function('var [...rest = defaults] = [];'), SyntaxError); diff --git a/js/src/tests/js1_8_5/extensions/reflect-parse.js b/js/src/tests/js1_8_5/extensions/reflect-parse.js index 405b169fadbf..d3cade96f0e1 100644 --- a/js/src/tests/js1_8_5/extensions/reflect-parse.js +++ b/js/src/tests/js1_8_5/extensions/reflect-parse.js @@ -679,12 +679,20 @@ testParamPatternCombinations(function(n) ("{a" + n + ":x" + n + "," + "b" + n + assignProp("b" + n, ident("y" + n)), assignProp("c" + n, ident("z" + n))]))); +testParamPatternCombinations(function(n) ("{a" + n + ":x" + n + " = 10," + "b" + n + ":y" + n + " = 10," + "c" + n + ":z" + n + " = 10}"), + function(n) (objPatt([assignProp("a" + n, ident("x" + n), lit(10)), + assignProp("b" + n, ident("y" + n), lit(10)), + assignProp("c" + n, ident("z" + n), lit(10))]))); + testParamPatternCombinations(function(n) ("[x" + n + "," + "y" + n + "," + "z" + n + "]"), function(n) (arrPatt([assignElem("x" + n), assignElem("y" + n), assignElem("z" + n)]))); testParamPatternCombinations(function(n) ("[a" + n + ", ..." + "b" + n + "]"), function(n) (arrPatt([assignElem("a" + n), spread(ident("b" + n))]))); +testParamPatternCombinations(function(n) ("[a" + n + ", " + "b" + n + " = 10]"), + function(n) (arrPatt([assignElem("a" + n), assignElem("b" + n, lit(10))]))); + // destructuring variable declarations function testVarPatternCombinations(makePattSrc, makePattPatt) { @@ -721,6 +729,12 @@ testVarPatternCombinations(function (n) ("{a" + n + ":x" + n + "," + "b" + n + " assignProp("c" + n, ident("z" + n))]), init: lit(0) })); +testVarPatternCombinations(function (n) ("{a" + n + ":x" + n + " = 10," + "b" + n + ":y" + n + " = 10," + "c" + n + ":z" + n + " = 10} = 0"), + function (n) ({ id: objPatt([assignProp("a" + n, ident("x" + n), lit(10)), + assignProp("b" + n, ident("y" + n), lit(10)), + assignProp("c" + n, ident("z" + n), lit(10))]), + init: lit(0) })); + testVarPatternCombinations(function(n) ("[x" + n + "," + "y" + n + "," + "z" + n + "] = 0"), function(n) ({ id: arrPatt([assignElem("x" + n), assignElem("y" + n), assignElem("z" + n)]), init: lit(0) })); @@ -729,6 +743,9 @@ testVarPatternCombinations(function(n) ("[a" + n + ", ..." + "b" + n + "] = 0"), function(n) ({ id: arrPatt([assignElem("a" + n), spread(ident("b" + n))]), init: lit(0) })); +testVarPatternCombinations(function(n) ("[a" + n + ", " + "b" + n + " = 10] = 0"), + function(n) ({ id: arrPatt([assignElem("a" + n), assignElem("b" + n, lit(10))]), + init: lit(0) })); // destructuring assignment function testAssignmentCombinations(makePattSrc, makePattPatt) { From 1b718aa75f1c7fe43840fcccc6aa4366be4775f2 Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Wed, 21 Jan 2015 10:53:32 +0000 Subject: [PATCH 06/62] Bug 1123394 - Stop spurious re-entry of shell interrupt callback r=shu --- js/src/shell/js.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 35fdc2047490..59a6ef3a5f2a 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -357,6 +357,12 @@ ShellInterruptCallback(JSContext *cx) if (!gServiceInterrupt) return true; + // Reset gServiceInterrupt. CancelExecution or InterruptIf will set it to + // true to distinguish watchdog or user triggered interrupts. + // Do this first to prevent other interrupts that may occur while the + // user-supplied callback is executing from re-entering the handler. + gServiceInterrupt = false; + bool result; RootedValue interruptFunc(cx, *gInterruptFunc); if (!interruptFunc.isNull()) { @@ -379,10 +385,6 @@ ShellInterruptCallback(JSContext *cx) if (!result && gExitCode == 0) gExitCode = EXITCODE_TIMEOUT; - // Reset gServiceInterrupt. CancelExecution or InterruptIf will set it to - // true to distinguish watchdog or user triggered interrupts. - gServiceInterrupt = false; - return result; } From 951e6e1657d0c36e0bde5a81d284cfee4f71e0b0 Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Wed, 21 Jan 2015 10:53:32 +0000 Subject: [PATCH 07/62] Bug 1088214 - Assert JSCLASS_IMPLEMENTS_BARRIERS is implemented everywhere r=terrence --- js/src/gc/Marking.cpp | 6 ++--- js/src/jsapi-tests/testPersistentRooted.cpp | 2 +- js/src/jsobj.cpp | 26 ++------------------- 3 files changed, 5 insertions(+), 29 deletions(-) diff --git a/js/src/gc/Marking.cpp b/js/src/gc/Marking.cpp index 9801a8bd39ea..9f8b71600987 100644 --- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -1801,10 +1801,8 @@ GCMarker::processMarkStackTop(SliceBudget &budget) // Global objects all have the same trace hook. That hook is safe without barriers // if the global has no custom trace hook of its own, or has been moved to a different // compartment, and so can't have one. - MOZ_ASSERT_IF(runtime()->gc.isIncrementalGCEnabled() && - !(clasp->trace == JS_GlobalObjectTraceHook && - (!obj->compartment()->options().getTrace() || - !obj->isOwnGlobal())), + MOZ_ASSERT_IF(!(clasp->trace == JS_GlobalObjectTraceHook && + (!obj->compartment()->options().getTrace() || !obj->isOwnGlobal())), clasp->flags & JSCLASS_IMPLEMENTS_BARRIERS); if (clasp->trace == InlineTypedObject::obj_trace) goto scan_typed_obj; diff --git a/js/src/jsapi-tests/testPersistentRooted.cpp b/js/src/jsapi-tests/testPersistentRooted.cpp index ea8f7d960e0f..3ebdb592aba7 100644 --- a/js/src/jsapi-tests/testPersistentRooted.cpp +++ b/js/src/jsapi-tests/testPersistentRooted.cpp @@ -21,7 +21,7 @@ int BarkWhenTracedClass::finalizeCount; int BarkWhenTracedClass::traceCount; const JSClass BarkWhenTracedClass::class_ = { - "BarkWhenTracedClass", 0, + "BarkWhenTracedClass", JSCLASS_IMPLEMENTS_BARRIERS, nullptr, nullptr, nullptr, diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 6eea5ebb399e..e8717301d872 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -1232,32 +1232,10 @@ NewObject(ExclusiveContext *cx, types::TypeObject *type_, JSObject *parent, gc:: obj = nobj; } - /* - * This will cancel an already-running incremental GC from doing any more - * slices, and it will prevent any future incremental GCs. - */ bool globalWithoutCustomTrace = clasp->trace == JS_GlobalObjectTraceHook && !cx->compartment()->options().getTrace(); - if (clasp->trace && - !globalWithoutCustomTrace && - !(clasp->flags & JSCLASS_IMPLEMENTS_BARRIERS)) - { - if (!cx->shouldBeJSContext()) - return nullptr; - JSRuntime *rt = cx->asJSContext()->runtime(); - rt->gc.disallowIncrementalGC(); - -#ifdef DEBUG - if (rt->gc.gcMode() == JSGC_MODE_INCREMENTAL) { - fprintf(stderr, - "The class %s has a trace hook but does not declare the\n" - "JSCLASS_IMPLEMENTS_BARRIERS flag. Please ensure that it correctly\n" - "implements write barriers and then set the flag.\n", - clasp->name); - MOZ_CRASH(); - } -#endif - } + if (clasp->trace && !globalWithoutCustomTrace) + MOZ_RELEASE_ASSERT(clasp->flags & JSCLASS_IMPLEMENTS_BARRIERS); probes::CreateObject(cx, obj); return obj; From 1e8333dd1a07debed3d45000bb8c4e391cc89b74 Mon Sep 17 00:00:00 2001 From: James Graham Date: Tue, 13 Jan 2015 18:01:03 +0000 Subject: [PATCH 08/62] Bug 1121563 - Setup environment for certutil correctly when running wpt on OSX, r=ted --- .../harness/wptrunner/browsers/firefox.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/testing/web-platform/harness/wptrunner/browsers/firefox.py b/testing/web-platform/harness/wptrunner/browsers/firefox.py index 50c99f4d1d83..a1c3a620f6ff 100644 --- a/testing/web-platform/harness/wptrunner/browsers/firefox.py +++ b/testing/web-platform/harness/wptrunner/browsers/firefox.py @@ -186,8 +186,16 @@ class FirefoxBrowser(Browser): # TODO: Maybe only set this if certutil won't launch? env = os.environ.copy() certutil_dir = os.path.dirname(self.binary) - env["LD_LIBRARY_PATH"] = certutil_dir - env["PATH"] = os.path.pathsep.join([certutil_dir, env["PATH"]]) + if mozinfo.isMac: + env_var = "DYLD_LIBRARY_PATH" + elif mozinfo.isUnix: + env_var = "LD_LIBRARY_PATH" + else: + env_var = "PATH" + + + env[env_var] = (os.path.pathsep.join([certutil_dir, env[env_var]]) + if env_var in env else certutil_dir) def certutil(*args): cmd = [self.certutil_binary] + list(args) From 8d1a51d8ab8852b0eb4fa0c1899d522307d9a66b Mon Sep 17 00:00:00 2001 From: Olli Pettay Date: Wed, 21 Jan 2015 13:45:47 +0200 Subject: [PATCH 09/62] Bug 1089861 - Don't dispatch activate/deactivate to content window objects., r=masayuki --HG-- extra : rebase_source : 0a6ba0807afeffdbf15176bb2230293881103314 --- .../test/general/browser_windowactivation.js | 27 +++++++++++++++ dom/base/nsContentUtils.cpp | 15 +++++++- dom/base/nsContentUtils.h | 34 +++++++++++++++++-- dom/base/nsFocusManager.cpp | 11 +++--- 4 files changed, 79 insertions(+), 8 deletions(-) diff --git a/browser/base/content/test/general/browser_windowactivation.js b/browser/base/content/test/general/browser_windowactivation.js index ab686287377b..481d80818d51 100644 --- a/browser/base/content/test/general/browser_windowactivation.js +++ b/browser/base/content/test/general/browser_windowactivation.js @@ -84,6 +84,14 @@ function test() { } }); + window.messageManager.addMessageListener("Test:ActivateEvent", function(message) { + ok(message.data.ok, "Test:ActivateEvent"); + }); + + window.messageManager.addMessageListener("Test:DeactivateEvent", function(message) { + ok(message.data.ok, "Test:DeactivateEvent"); + }); + browser1.addEventListener("load", check, true); browser2.addEventListener("load", check, true); browser1.contentWindow.location = testPage; @@ -132,6 +140,25 @@ function childFunction() sendAsyncMessage("Test:FocusReceived", { }); }, false); + var windowGotActivate = false; + var windowGotDeactivate = false; + addEventListener("activate", function() { + sendAsyncMessage("Test:ActivateEvent", { ok: !windowGotActivate }); + windowGotActivate = false; + }); + + addEventListener("deactivate", function() { + sendAsyncMessage("Test:DeactivateEvent", { ok: !windowGotDeactivate }); + windowGotDeactivate = false; + }); + content.addEventListener("activate", function() { + windowGotActivate = true;; + }); + + content.addEventListener("deactivate", function() { + windowGotDeactivate = true; + }); + content.setInterval(function () { if (!expectingResponse) { return; diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index dde489d71b0b..fc02c48a29f2 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -3620,7 +3620,8 @@ nsresult nsContentUtils::DispatchEvent(nsIDocument* aDoc, nsISupports* aTarget, const nsAString& aEventName, bool aCanBubble, bool aCancelable, - bool aTrusted, bool *aDefaultAction) + bool aTrusted, bool *aDefaultAction, + bool aOnlyChromeDispatch) { nsCOMPtr event; nsCOMPtr target; @@ -3628,6 +3629,7 @@ nsContentUtils::DispatchEvent(nsIDocument* aDoc, nsISupports* aTarget, aCancelable, aTrusted, getter_AddRefs(event), getter_AddRefs(target)); NS_ENSURE_SUCCESS(rv, rv); + event->GetInternalNSEvent()->mFlags.mOnlyChromeDispatch = aOnlyChromeDispatch; bool dummy; return target->DispatchEvent(event, aDefaultAction ? aDefaultAction : &dummy); @@ -3664,6 +3666,17 @@ nsContentUtils::DispatchChromeEvent(nsIDocument *aDoc, return rv; } +nsresult +nsContentUtils::DispatchEventOnlyToChrome(nsIDocument* aDoc, + nsISupports* aTarget, + const nsAString& aEventName, + bool aCanBubble, bool aCancelable, + bool* aDefaultAction) +{ + return DispatchEvent(aDoc, aTarget, aEventName, aCanBubble, aCancelable, + true, aDefaultAction, true); +} + /* static */ Element* nsContentUtils::MatchElementId(nsIContent *aContent, const nsIAtom* aId) diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index 34a95c6519f7..548a50ebedaf 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -987,7 +987,10 @@ public: /** * This method creates and dispatches a trusted event to the chrome - * event handler. + * event handler (the parent object of the DOM Window in the event target + * chain). Note, chrome event handler is used even if aTarget is a chrome + * object. Use DispatchEventOnlyToChrome if the normal event dispatching is + * wanted in case aTarget is a chrome object. * Works only with events which can be created by calling * nsIDOMDocument::CreateEvent() with parameter "Events". * @param aDocument The document which will be used to create the event, @@ -1007,6 +1010,32 @@ public: bool aCancelable, bool *aDefaultAction = nullptr); + + /** + * This method creates and dispatches a trusted event. + * If aTarget is not a chrome object, the nearest chrome object in the + * propagation path will be used as the start of the event target chain. + * This method is different than DispatchChromeEvent, which always dispatches + * events to chrome event handler. DispatchEventOnlyToChrome works like + * DispatchTrustedEvent in the case aTarget is a chrome object. + * Works only with events which can be created by calling + * nsIDOMDocument::CreateEvent() with parameter "Events". + * @param aDoc The document which will be used to create the event. + * @param aTarget The target of the event, should be QIable to + * nsIDOMEventTarget. + * @param aEventName The name of the event. + * @param aCanBubble Whether the event can bubble. + * @param aCancelable Is the event cancelable. + * @param aDefaultAction Set to true if default action should be taken, + * see nsIDOMEventTarget::DispatchEvent. + */ + static nsresult DispatchEventOnlyToChrome(nsIDocument* aDoc, + nsISupports* aTarget, + const nsAString& aEventName, + bool aCanBubble, + bool aCancelable, + bool *aDefaultAction = nullptr); + /** * Determines if an event attribute name (such as onclick) is valid for * a given element type. Types are from the EventNameType enumeration @@ -2253,7 +2282,8 @@ private: bool aCanBubble, bool aCancelable, bool aTrusted, - bool *aDefaultAction = nullptr); + bool *aDefaultAction = nullptr, + bool aOnlyChromeDispatch = false); static void InitializeModifierStrings(); diff --git a/dom/base/nsFocusManager.cpp b/dom/base/nsFocusManager.cpp index 5e001d9f73cc..3e028ae197c1 100644 --- a/dom/base/nsFocusManager.cpp +++ b/dom/base/nsFocusManager.cpp @@ -1145,11 +1145,12 @@ nsFocusManager::ActivateOrDeactivate(nsPIDOMWindow* aWindow, bool aActive) aWindow->ActivateOrDeactivate(aActive); // Send the activate event. - nsContentUtils::DispatchTrustedEvent(aWindow->GetExtantDoc(), - aWindow, - aActive ? NS_LITERAL_STRING("activate") : - NS_LITERAL_STRING("deactivate"), - true, true, nullptr); + nsContentUtils::DispatchEventOnlyToChrome(aWindow->GetExtantDoc(), + aWindow, + aActive ? + NS_LITERAL_STRING("activate") : + NS_LITERAL_STRING("deactivate"), + true, true, nullptr); // Look for any remote child frames, iterate over them and send the activation notification. nsContentUtils::CallOnAllRemoteChildren(aWindow, ActivateOrDeactivateChild, From f5d6a607f5ecc8d1058e480583f150263b1f12d9 Mon Sep 17 00:00:00 2001 From: Robert Longson Date: Wed, 21 Jan 2015 13:01:00 +0000 Subject: [PATCH 10/62] Bug 1122761 - Avoid dividing by zero when calculating turbulence gradients. r=mstange --- gfx/2d/SVGTurbulenceRenderer-inl.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/gfx/2d/SVGTurbulenceRenderer-inl.h b/gfx/2d/SVGTurbulenceRenderer-inl.h index b784bd8a4738..006f842e383b 100644 --- a/gfx/2d/SVGTurbulenceRenderer-inl.h +++ b/gfx/2d/SVGTurbulenceRenderer-inl.h @@ -125,8 +125,11 @@ SVGTurbulenceRenderer::InitFromSeed(int32_t float gradient[4][sBSize][2]; for (int32_t k = 0; k < 4; k++) { for (int32_t i = 0; i < sBSize; i++) { - float a = float((rand.Next() % (sBSize + sBSize)) - sBSize) / sBSize; - float b = float((rand.Next() % (sBSize + sBSize)) - sBSize) / sBSize; + float a, b; + do { + a = float((rand.Next() % (sBSize + sBSize)) - sBSize) / sBSize; + b = float((rand.Next() % (sBSize + sBSize)) - sBSize) / sBSize; + } while (a == 0 && b == 0); float s = sqrt(a * a + b * b); gradient[k][i][0] = a / s; gradient[k][i][1] = b / s; From 3ed3b0f84946cddcadff60332e359bc16b86b739 Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Wed, 21 Jan 2015 05:07:46 -0800 Subject: [PATCH 11/62] Bug 1124072 - Flip on decode-on-draw on APZ platforms. r=tn --- b2g/app/b2g.js | 2 +- gfx/thebes/gfxPrefs.h | 2 +- mobile/android/app/mobile.js | 2 +- modules/libpref/init/all.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/b2g/app/b2g.js b/b2g/app/b2g.js index f6c6931f586a..ac24677a863c 100644 --- a/b2g/app/b2g.js +++ b/b2g/app/b2g.js @@ -322,7 +322,7 @@ pref("media.fragmented-mp4.gonk.enabled", true); pref("media.video-queue.default-size", 3); // optimize images' memory usage -pref("image.mem.decodeondraw", false); +pref("image.mem.decodeondraw", true); pref("image.mem.allow_locking_in_content_processes", false); /* don't allow image locking */ // Limit the surface cache to 1/8 of main memory or 128MB, whichever is smaller. // Almost everything that was factored into 'max_decoded_image_kb' is now stored diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h index 6ec0ed99745f..3271af05dc8f 100644 --- a/gfx/thebes/gfxPrefs.h +++ b/gfx/thebes/gfxPrefs.h @@ -239,7 +239,7 @@ private: DECL_GFX_PREF(Live, "image.high_quality_downscaling.min_factor", ImageHQDownscalingMinFactor, uint32_t, 1000); DECL_GFX_PREF(Live, "image.high_quality_upscaling.max_size", ImageHQUpscalingMaxSize, uint32_t, 20971520); DECL_GFX_PREF(Once, "image.mem.decode_bytes_at_a_time", ImageMemDecodeBytesAtATime, uint32_t, 200000); - DECL_GFX_PREF(Live, "image.mem.decodeondraw", ImageMemDecodeOnDraw, bool, false); + DECL_GFX_PREF(Live, "image.mem.decodeondraw", ImageMemDecodeOnDraw, bool, true); DECL_GFX_PREF(Live, "image.mem.discardable", ImageMemDiscardable, bool, false); DECL_GFX_PREF(Once, "image.mem.surfacecache.discard_factor", ImageMemSurfaceCacheDiscardFactor, uint32_t, 1); DECL_GFX_PREF(Once, "image.mem.surfacecache.max_size_kb", ImageMemSurfaceCacheMaxSizeKB, uint32_t, 100 * 1024); diff --git a/mobile/android/app/mobile.js b/mobile/android/app/mobile.js index 7212cbd6ff8e..d17d219b7898 100644 --- a/mobile/android/app/mobile.js +++ b/mobile/android/app/mobile.js @@ -563,7 +563,7 @@ pref("media.fragmented-mp4.android-media-codec.enabled", true); pref("media.fragmented-mp4.android-media-codec.preferred", true); // optimize images memory usage -pref("image.mem.decodeondraw", false); +pref("image.mem.decodeondraw", true); #ifdef NIGHTLY_BUILD // Shumway component (SWF player) is disabled by default. Also see bug 904346. diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index afb30fea4a66..9b13643ff3ee 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -3789,7 +3789,7 @@ pref("image.mem.discardable", true); // Prevents images from automatically being decoded on load, instead allowing // them to be decoded on demand when they are drawn. -pref("image.mem.decodeondraw", false); +pref("image.mem.decodeondraw", true); // Allows image locking of decoded image data in content processes. pref("image.mem.allow_locking_in_content_processes", true); From 2b14e5ff2e4a30bf231e44e2fd79b899db966cc8 Mon Sep 17 00:00:00 2001 From: Robert Longson Date: Wed, 21 Jan 2015 13:09:45 +0000 Subject: [PATCH 12/62] Bug 1110337 - Get bounds of image element using maths. r=jwatt --- dom/svg/SVGCircleElement.cpp | 3 +-- dom/svg/SVGEllipseElement.cpp | 3 +-- dom/svg/SVGImageElement.cpp | 17 +++++++++++++++++ dom/svg/SVGImageElement.h | 2 ++ dom/svg/SVGRectElement.cpp | 3 ++- 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/dom/svg/SVGCircleElement.cpp b/dom/svg/SVGCircleElement.cpp index 9bc447dfdd1d..deac6112db1c 100644 --- a/dom/svg/SVGCircleElement.cpp +++ b/dom/svg/SVGCircleElement.cpp @@ -90,8 +90,7 @@ SVGCircleElement::GetGeometryBounds(Rect* aBounds, Float aStrokeWidth, if (r <= 0.f) { // Rendering of the element is disabled - aBounds->MoveTo(x, y); - aBounds->SetEmpty(); + *aBounds = Rect(aTransform * Point(x, y), Size()); return true; } diff --git a/dom/svg/SVGEllipseElement.cpp b/dom/svg/SVGEllipseElement.cpp index 47dc8eb3f91d..a0ae35bb6111 100644 --- a/dom/svg/SVGEllipseElement.cpp +++ b/dom/svg/SVGEllipseElement.cpp @@ -101,8 +101,7 @@ SVGEllipseElement::GetGeometryBounds(Rect* aBounds, Float aStrokeWidth, if (rx <= 0.f || ry <= 0.f) { // Rendering of the element is disabled - aBounds->MoveTo(x, y); - aBounds->SetEmpty(); + *aBounds = Rect(aTransform * Point(x, y), Size()); return true; } diff --git a/dom/svg/SVGImageElement.cpp b/dom/svg/SVGImageElement.cpp index 863e96f234fd..31cde149d927 100644 --- a/dom/svg/SVGImageElement.cpp +++ b/dom/svg/SVGImageElement.cpp @@ -226,6 +226,23 @@ SVGImageElement::IsAttributeMapped(const nsIAtom* name) const /* For the purposes of the update/invalidation logic pretend to be a rectangle. */ +bool +SVGImageElement::GetGeometryBounds(Rect* aBounds, Float aStrokeWidth, + const Matrix& aTransform) +{ + Rect rect; + GetAnimatedLengthValues(&rect.x, &rect.y, &rect.width, + &rect.height, nullptr); + + if (rect.IsEmpty()) { + // Rendering of the element disabled + rect.SetEmpty(); // Make sure width/height are zero and not negative + } + + *aBounds = aTransform.TransformBounds(rect); + return true; +} + TemporaryRef SVGImageElement::BuildPath(PathBuilder* aBuilder) { diff --git a/dom/svg/SVGImageElement.h b/dom/svg/SVGImageElement.h index 0494df94a8c7..c083c28d260f 100644 --- a/dom/svg/SVGImageElement.h +++ b/dom/svg/SVGImageElement.h @@ -53,6 +53,8 @@ public: NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const MOZ_OVERRIDE; // nsSVGPathGeometryElement methods: + virtual bool GetGeometryBounds(Rect* aBounds, Float aStrokeWidth, + const Matrix& aTransform) MOZ_OVERRIDE; virtual TemporaryRef BuildPath(PathBuilder* aBuilder) MOZ_OVERRIDE; // nsSVGSVGElement methods: diff --git a/dom/svg/SVGRectElement.cpp b/dom/svg/SVGRectElement.cpp index 5b00e54b3117..8bd69f458e3e 100644 --- a/dom/svg/SVGRectElement.cpp +++ b/dom/svg/SVGRectElement.cpp @@ -122,7 +122,8 @@ SVGRectElement::GetGeometryBounds(Rect* aBounds, Float aStrokeWidth, if (rect.IsEmpty()) { // Rendering of the element disabled rect.SetEmpty(); // Make sure width/height are zero and not negative - *aBounds = rect; // We still want the x/y position from 'rect' + // We still want the x/y position from 'rect' + *aBounds = aTransform.TransformBounds(rect); return true; } From b3ba25489849f05f57c1555787aa0429fe6024e2 Mon Sep 17 00:00:00 2001 From: Tom Schuster Date: Wed, 21 Jan 2015 14:09:43 +0100 Subject: [PATCH 13/62] Bug 1122913 - Remove object out-parameter from native LookupOwnProperty. r=jorendorff --- js/src/jsobj.cpp | 7 ++++- js/src/vm/NativeObject-inl.h | 53 ++++++++++++++---------------------- js/src/vm/NativeObject.cpp | 14 ++-------- 3 files changed, 28 insertions(+), 46 deletions(-) diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index e8717301d872..9dc13a923a68 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -2906,13 +2906,18 @@ js::NonProxyLookupOwnProperty(JSContext *cx, LookupGenericOp lookup, MaybeRooted::template downcastHandle(obj); bool done; - if (!LookupOwnPropertyInline(cx, nobj, id, objp, propp, &done)) + if (!LookupOwnPropertyInline(cx, nobj, id, propp, &done)) return false; if (!done) { objp.set(nullptr); propp.set(nullptr); return true; } + + if (propp) + objp.set(obj); + else + objp.set(nullptr); } if (!propp) diff --git a/js/src/vm/NativeObject-inl.h b/js/src/vm/NativeObject-inl.h index 96a99a9be795..3a0d8f8d9bd3 100644 --- a/js/src/vm/NativeObject-inl.h +++ b/js/src/vm/NativeObject-inl.h @@ -400,38 +400,30 @@ NewNativeObjectWithClassProto(ExclusiveContext *cx, const js::Class *clasp, JSOb /* * Call obj's resolve hook. * - * cx, id, and flags are the parameters initially passed to the ongoing lookup; - * objp and propp are its out parameters. obj is an object along the prototype - * chain from where the lookup started. + * cx and id are the parameters initially passed to the ongoing lookup; + * propp and recursedp are its out parameters. * * There are four possible outcomes: * * - On failure, report an error or exception and return false. * - * - If we are already resolving a property of *curobjp, set *recursedp = true, + * - If we are already resolving a property of obj, set *recursedp = true, * and return true. * - * - If the resolve hook finds or defines the sought property, set *objp and - * *propp appropriately, set *recursedp = false, and return true. + * - If the resolve hook finds or defines the sought property, set propp + * appropriately, set *recursedp = false, and return true. * - * - Otherwise no property was resolved. Set *propp = nullptr and + * - Otherwise no property was resolved. Set propp to nullptr and * *recursedp = false and return true. */ static MOZ_ALWAYS_INLINE bool -CallResolveOp(JSContext *cx, HandleNativeObject obj, HandleId id, MutableHandleObject objp, - MutableHandleShape propp, bool *recursedp) +CallResolveOp(JSContext *cx, HandleNativeObject obj, HandleId id, MutableHandleShape propp, + bool *recursedp) { - /* - * Avoid recursion on (obj, id) already being resolved on cx. - * - * Once we have successfully added an entry for (obj, key) to - * cx->resolvingTable, control must go through cleanup: before - * returning. But note that JS_DHASH_ADD may find an existing - * entry, in which case we bail to suppress runaway recursion. - */ + // Avoid recursion on (obj, id) already being resolved on cx. AutoResolving resolving(cx, obj, id); if (resolving.alreadyStarted()) { - /* Already resolving id in obj -- suppress recursion. */ + // Already resolving id in obj, suppress recursion. *recursedp = true; return true; } @@ -444,18 +436,14 @@ CallResolveOp(JSContext *cx, HandleNativeObject obj, HandleId id, MutableHandleO if (!resolved) return true; - objp.set(obj); - if (JSID_IS_INT(id) && obj->containsDenseElement(JSID_TO_INT(id))) { MarkDenseOrTypedArrayElementFound(propp); return true; } - if (Shape *shape = obj->lookup(cx, id)) - propp.set(shape); - else - objp.set(nullptr); + MOZ_ASSERT(!IsAnyTypedArray(obj)); + propp.set(obj->lookup(cx, id)); return true; } @@ -464,13 +452,11 @@ static MOZ_ALWAYS_INLINE bool LookupOwnPropertyInline(ExclusiveContext *cx, typename MaybeRooted::HandleType obj, typename MaybeRooted::HandleType id, - typename MaybeRooted::MutableHandleType objp, typename MaybeRooted::MutableHandleType propp, bool *donep) { // Check for a native dense element. if (JSID_IS_INT(id) && obj->containsDenseElement(JSID_TO_INT(id))) { - objp.set(obj); MarkDenseOrTypedArrayElementFound(propp); *donep = true; return true; @@ -483,10 +469,8 @@ LookupOwnPropertyInline(ExclusiveContext *cx, uint64_t index; if (IsTypedArrayIndex(id, &index)) { if (index < AnyTypedArrayLength(obj)) { - objp.set(obj); MarkDenseOrTypedArrayElementFound(propp); } else { - objp.set(nullptr); propp.set(nullptr); } *donep = true; @@ -496,7 +480,6 @@ LookupOwnPropertyInline(ExclusiveContext *cx, // Check for a native property. if (Shape *shape = obj->lookup(cx, id)) { - objp.set(obj); propp.set(shape); *donep = true; return true; @@ -512,7 +495,6 @@ LookupOwnPropertyInline(ExclusiveContext *cx, if (!CallResolveOp(cx->asJSContext(), MaybeRooted::toHandle(obj), MaybeRooted::toHandle(id), - MaybeRooted::toMutableHandle(objp), MaybeRooted::toMutableHandle(propp), &recursed)) { @@ -520,7 +502,6 @@ LookupOwnPropertyInline(ExclusiveContext *cx, } if (recursed) { - objp.set(nullptr); propp.set(nullptr); *donep = true; return true; @@ -532,6 +513,7 @@ LookupOwnPropertyInline(ExclusiveContext *cx, } } + propp.set(nullptr); *donep = false; return true; } @@ -584,10 +566,15 @@ LookupPropertyInline(ExclusiveContext *cx, while (true) { bool done; - if (!LookupOwnPropertyInline(cx, current, id, objp, propp, &done)) + if (!LookupOwnPropertyInline(cx, current, id, propp, &done)) return false; - if (done) + if (done) { + if (propp) + objp.set(current); + else + objp.set(nullptr); return true; + } typename MaybeRooted::RootType proto(cx, current->getProto()); diff --git a/js/src/vm/NativeObject.cpp b/js/src/vm/NativeObject.cpp index b56df98e56ac..0277e9aa4dbd 100644 --- a/js/src/vm/NativeObject.cpp +++ b/js/src/vm/NativeObject.cpp @@ -1458,14 +1458,8 @@ static bool NativeLookupOwnProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId id, MutableHandle shapep) { - RootedObject pobj(cx); bool done; - - if (!LookupOwnPropertyInline(cx, obj, id, &pobj, shapep, &done)) - return false; - if (!done || pobj != obj) - shapep.set(nullptr); - return true; + return LookupOwnPropertyInline(cx, obj, id, shapep, &done); } template @@ -2072,13 +2066,9 @@ js::NativeSetProperty(JSContext *cx, HandleNativeObject obj, HandleObject receiv for (;;) { // Steps 2-3. ('done' is a SpiderMonkey-specific thing, used below.) bool done; - RootedObject ancestor(cx); - if (!LookupOwnPropertyInline(cx, pobj, id, &ancestor, &shape, &done)) + if (!LookupOwnPropertyInline(cx, pobj, id, &shape, &done)) return false; - if (!done || ancestor != pobj) - shape = nullptr; - if (shape) { // Steps 5-6. return SetExistingProperty(cx, obj, receiver, id, pobj, shape, vp, strict); From 9656ec51c332cb876f088c23a736685fca0725cb Mon Sep 17 00:00:00 2001 From: Masatoshi Kimura Date: Wed, 21 Jan 2015 22:35:19 +0900 Subject: [PATCH 14/62] Bug 895582 - Get rid of MOZ_ENUM_TYPE. r=waldo --- accessible/base/RelationType.h | 4 ++-- dom/base/nsContentUtils.h | 4 ++-- dom/camera/CameraPreferences.cpp | 6 ----- dom/camera/CameraPreferences.h | 11 --------- dom/events/EventListenerManager.h | 2 +- dom/events/EventStateManager.h | 2 +- dom/media/webaudio/AudioEventTimeline.h | 2 +- dom/svg/SVGPreserveAspectRatio.h | 4 ++-- js/src/jsinfer.h | 4 ++-- js/src/vm/StructuredClone.cpp | 2 +- mfbt/TypedEnum.h | 27 +---------------------- mfbt/TypedEnumInternal.h | 3 --- uriloader/prefetch/nsOfflineCacheUpdate.h | 2 +- widget/EventForwards.h | 4 ++-- widget/nsIWidget.h | 4 ++-- widget/windows/nsTextStore.h | 4 ++-- xpcom/base/nsError.h | 17 +------------- 17 files changed, 21 insertions(+), 81 deletions(-) diff --git a/accessible/base/RelationType.h b/accessible/base/RelationType.h index b3c14e19f8c0..17b40352b1f4 100644 --- a/accessible/base/RelationType.h +++ b/accessible/base/RelationType.h @@ -12,7 +12,7 @@ namespace mozilla { namespace a11y { -MOZ_BEGIN_ENUM_CLASS(RelationType) +enum class RelationType { /** * This object is labelled by a target object. @@ -131,7 +131,7 @@ MOZ_BEGIN_ENUM_CLASS(RelationType) LAST = CONTAINING_APPLICATION -MOZ_END_ENUM_CLASS(RelationType) +}; } // namespace a11y } // namespace mozilla diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index 548a50ebedaf..4cbff1d26506 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -1281,7 +1281,7 @@ public: * @param aDiscoverMode Set to eRecurseIntoChildren to descend recursively * into children. */ - enum TextContentDiscoverMode MOZ_ENUM_TYPE(uint8_t) { + enum TextContentDiscoverMode : uint8_t { eRecurseIntoChildren, eDontRecurseIntoChildren }; @@ -2075,7 +2075,7 @@ public: */ static bool IsAutocompleteEnabled(nsIDOMHTMLInputElement* aInput); - enum AutocompleteAttrState MOZ_ENUM_TYPE(uint8_t) + enum AutocompleteAttrState : uint8_t { eAutocompleteAttrState_Unknown = 1, eAutocompleteAttrState_Invalid, diff --git a/dom/camera/CameraPreferences.cpp b/dom/camera/CameraPreferences.cpp index afe78342b650..0c8d4fc2fa13 100644 --- a/dom/camera/CameraPreferences.cpp +++ b/dom/camera/CameraPreferences.cpp @@ -37,7 +37,6 @@ StaticRefPtr CameraPreferences::sObserver; NS_IMPL_ISUPPORTS(CameraPreferences, nsIObserver); #endif -#ifdef CAMERAPREFERENCES_HAVE_SEPARATE_UINT32_AND_NSRESULT /* static */ nsresult CameraPreferences::UpdatePref(const char* aPref, nsresult& aVal) @@ -49,7 +48,6 @@ CameraPreferences::UpdatePref(const char* aPref, nsresult& aVal) } return rv; } -#endif /* static */ nsresult @@ -156,7 +154,6 @@ CameraPreferences::PreferenceChanged(const char* aPref, void* aClosure) nsresult rv; switch (p.mValueType) { case kPrefValueIsNsResult: - #ifdef CAMERAPREFERENCES_HAVE_SEPARATE_UINT32_AND_NSRESULT { nsresult& v = *p.mValue.mAsNsResult; rv = UpdatePref(aPref, v); @@ -165,7 +162,6 @@ CameraPreferences::PreferenceChanged(const char* aPref, void* aClosure) } } break; - #endif case kPrefValueIsUint32: { @@ -331,7 +327,6 @@ CameraPreferences::GetPref(const char* aPref, nsACString& aVal) return true; } -#ifdef CAMERAPREFERENCES_HAVE_SEPARATE_UINT32_AND_NSRESULT /* static */ bool CameraPreferences::GetPref(const char* aPref, nsresult& aVal) @@ -359,7 +354,6 @@ CameraPreferences::GetPref(const char* aPref, nsresult& aVal) aVal = v; return true; } -#endif /* static */ bool diff --git a/dom/camera/CameraPreferences.h b/dom/camera/CameraPreferences.h index 3d260a3f31af..7fd09aeb40a5 100644 --- a/dom/camera/CameraPreferences.h +++ b/dom/camera/CameraPreferences.h @@ -12,13 +12,6 @@ #include "mozilla/StaticPtr.h" #endif -#if defined(MOZ_HAVE_CXX11_STRONG_ENUMS) || defined(MOZ_HAVE_CXX11_ENUM_TYPE) -// Older compilers that don't support strongly-typed enums -// just typedef uint32_t to nsresult, which results in conflicting -// overloaded members in CameraPreferences. -#define CAMERAPREFERENCES_HAVE_SEPARATE_UINT32_AND_NSRESULT -#endif - namespace mozilla { template class StaticAutoPtr; @@ -38,9 +31,7 @@ public: static void Shutdown(); static bool GetPref(const char* aPref, nsACString& aVal); -#ifdef CAMERAPREFERENCES_HAVE_SEPARATE_UINT32_AND_NSRESULT static bool GetPref(const char* aPref, nsresult& aVal); -#endif static bool GetPref(const char* aPref, uint32_t& aVal); static bool GetPref(const char* aPref, bool& aVal); @@ -49,9 +40,7 @@ protected: static uint32_t PrefToIndex(const char* aPref); static void PreferenceChanged(const char* aPref, void* aClosure); -#ifdef CAMERAPREFERENCES_HAVE_SEPARATE_UINT32_AND_NSRESULT static nsresult UpdatePref(const char* aPref, nsresult& aVar); -#endif static nsresult UpdatePref(const char* aPref, uint32_t& aVar); static nsresult UpdatePref(const char* aPref, nsACString& aVar); static nsresult UpdatePref(const char* aPref, bool& aVar); diff --git a/dom/events/EventListenerManager.h b/dom/events/EventListenerManager.h index a71b861486c3..bcd1f034bb11 100644 --- a/dom/events/EventListenerManager.h +++ b/dom/events/EventListenerManager.h @@ -162,7 +162,7 @@ public: nsString mTypeString; // for non-main-threads uint16_t mEventType; - enum ListenerType MOZ_ENUM_TYPE(uint8_t) + enum ListenerType : uint8_t { eNativeListener = 0, eJSEventListener, diff --git a/dom/events/EventStateManager.h b/dom/events/EventStateManager.h index 3b509f0a8a5a..73de63a3eaac 100644 --- a/dom/events/EventStateManager.h +++ b/dom/events/EventStateManager.h @@ -429,7 +429,7 @@ protected: /** * Computes the default action for the aEvent with the prefs. */ - enum Action MOZ_ENUM_TYPE(uint8_t) + enum Action : uint8_t { ACTION_NONE = 0, ACTION_SCROLL, diff --git a/dom/media/webaudio/AudioEventTimeline.h b/dom/media/webaudio/AudioEventTimeline.h index bd9a385d2407..f97c20d55a57 100644 --- a/dom/media/webaudio/AudioEventTimeline.h +++ b/dom/media/webaudio/AudioEventTimeline.h @@ -23,7 +23,7 @@ namespace dom { // This is an internal helper class and should not be used outside of this header. struct AudioTimelineEvent { - enum Type MOZ_ENUM_TYPE(uint32_t) { + enum Type : uint32_t { SetValue, LinearRamp, ExponentialRamp, diff --git a/dom/svg/SVGPreserveAspectRatio.h b/dom/svg/SVGPreserveAspectRatio.h index e1e6a5cbb3eb..43ce2426d63f 100644 --- a/dom/svg/SVGPreserveAspectRatio.h +++ b/dom/svg/SVGPreserveAspectRatio.h @@ -17,7 +17,7 @@ namespace mozilla { // Alignment Types -enum SVGAlign MOZ_ENUM_TYPE(uint8_t) { +enum SVGAlign : uint8_t { SVG_PRESERVEASPECTRATIO_UNKNOWN = 0, SVG_PRESERVEASPECTRATIO_NONE = 1, SVG_PRESERVEASPECTRATIO_XMINYMIN = 2, @@ -37,7 +37,7 @@ const uint16_t SVG_ALIGN_MIN_VALID = SVG_PRESERVEASPECTRATIO_NONE; const uint16_t SVG_ALIGN_MAX_VALID = SVG_PRESERVEASPECTRATIO_XMAXYMAX; // Meet-or-slice Types -enum SVGMeetOrSlice MOZ_ENUM_TYPE(uint8_t) { +enum SVGMeetOrSlice : uint8_t { SVG_MEETORSLICE_UNKNOWN = 0, SVG_MEETORSLICE_MEET = 1, SVG_MEETORSLICE_SLICE = 2 diff --git a/js/src/jsinfer.h b/js/src/jsinfer.h index 2c42fd432b75..b8b1d46751cb 100644 --- a/js/src/jsinfer.h +++ b/js/src/jsinfer.h @@ -293,7 +293,7 @@ public: }; /* Flags and other state stored in TypeSet::flags */ -enum MOZ_ENUM_TYPE(uint32_t) { +enum : uint32_t { TYPE_FLAG_UNDEFINED = 0x1, TYPE_FLAG_NULL = 0x2, TYPE_FLAG_BOOLEAN = 0x4, @@ -352,7 +352,7 @@ enum MOZ_ENUM_TYPE(uint32_t) { typedef uint32_t TypeFlags; /* Flags and other state stored in TypeObject::flags */ -enum MOZ_ENUM_TYPE(uint32_t) { +enum : uint32_t { /* Whether this type object is associated with some allocation site. */ OBJECT_FLAG_FROM_ALLOCATION_SITE = 0x1, diff --git a/js/src/vm/StructuredClone.cpp b/js/src/vm/StructuredClone.cpp index 1ce3b9cc67f6..e3adc3246dca 100644 --- a/js/src/vm/StructuredClone.cpp +++ b/js/src/vm/StructuredClone.cpp @@ -65,7 +65,7 @@ using JS::CanonicalizeNaN; // a stable ID, it need not be at the end of the list and should not be used for // sizing data structures. -enum StructuredDataType MOZ_ENUM_TYPE(uint32_t) { +enum StructuredDataType : uint32_t { /* Structured data types provided by the engine */ SCTAG_FLOAT_MAX = 0xFFF00000, SCTAG_NULL = 0xFFFF0000, diff --git a/mfbt/TypedEnum.h b/mfbt/TypedEnum.h index 31215151931d..9c8d9b49e46b 100644 --- a/mfbt/TypedEnum.h +++ b/mfbt/TypedEnum.h @@ -14,31 +14,6 @@ #if defined(__cplusplus) -/** - * MOZ_ENUM_TYPE specifies the underlying numeric type for an enum. It's - * specified by placing MOZ_ENUM_TYPE(type) immediately after the enum name in - * its declaration, and before the opening curly brace, like - * - * enum MyEnum MOZ_ENUM_TYPE(uint16_t) - * { - * A, - * B = 7, - * C - * }; - * - * In supporting compilers, the macro will expand to ": uint16_t". The - * compiler will allocate exactly two bytes for MyEnum and will require all - * enumerators to have values between 0 and 65535. (Thus specifying "B = - * 100000" instead of "B = 7" would fail to compile.) In old compilers the - * macro expands to the empty string, and the underlying type is generally - * undefined. - */ -#ifdef MOZ_HAVE_CXX11_ENUM_TYPE -# define MOZ_ENUM_TYPE(type) : type -#else -# define MOZ_ENUM_TYPE(type) /* no support */ -#endif - /** * MOZ_BEGIN_ENUM_CLASS and MOZ_END_ENUM_CLASS provide access to the * strongly-typed enumeration feature of C++11 ("enum class"). If supported @@ -155,7 +130,7 @@ class Name \ { \ public: \ - enum Enum MOZ_ENUM_TYPE(type) \ + enum Enum : type \ { # define MOZ_END_NESTED_ENUM_CLASS(Name) \ }; \ diff --git a/mfbt/TypedEnumInternal.h b/mfbt/TypedEnumInternal.h index 5af19e20202e..a2c1c998c80e 100644 --- a/mfbt/TypedEnumInternal.h +++ b/mfbt/TypedEnumInternal.h @@ -26,18 +26,15 @@ # define __has_extension __has_feature /* compatibility, for older versions of clang */ # endif # if __has_extension(cxx_strong_enums) -# define MOZ_HAVE_CXX11_ENUM_TYPE # define MOZ_HAVE_CXX11_STRONG_ENUMS # endif #elif defined(__GNUC__) # if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L # if MOZ_GCC_VERSION_AT_LEAST(4, 6, 3) -# define MOZ_HAVE_CXX11_ENUM_TYPE # define MOZ_HAVE_CXX11_STRONG_ENUMS # endif # endif #elif defined(_MSC_VER) -# define MOZ_HAVE_CXX11_ENUM_TYPE # define MOZ_HAVE_CXX11_STRONG_ENUMS #endif diff --git a/uriloader/prefetch/nsOfflineCacheUpdate.h b/uriloader/prefetch/nsOfflineCacheUpdate.h index 89367c1650fc..3edfa2f6b0e3 100644 --- a/uriloader/prefetch/nsOfflineCacheUpdate.h +++ b/uriloader/prefetch/nsOfflineCacheUpdate.h @@ -76,7 +76,7 @@ public: nsresult GetStatus(uint16_t *aStatus); private: - enum LoadStatus MOZ_ENUM_TYPE(uint16_t) { + enum LoadStatus : uint16_t { UNINITIALIZED = 0U, REQUESTED = 1U, RECEIVING = 2U, diff --git a/widget/EventForwards.h b/widget/EventForwards.h index d1e4a7fa8be4..f9260f71e7ee 100644 --- a/widget/EventForwards.h +++ b/widget/EventForwards.h @@ -32,7 +32,7 @@ namespace mozilla { typedef uint8_t EventClassIDType; -enum EventClassID MOZ_ENUM_TYPE(EventClassIDType) +enum EventClassID : EventClassIDType { // The event class name will be: // eBasicEventClass for WidgetEvent @@ -77,7 +77,7 @@ enum CodeNameIndex #define NS_DEFINE_COMMAND(aName, aCommandStr) , Command##aName typedef int8_t CommandInt; -enum Command MOZ_ENUM_TYPE(CommandInt) +enum Command : CommandInt { CommandDoNothing diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h index 460641c9aa4b..8e329e453eab 100644 --- a/widget/nsIWidget.h +++ b/widget/nsIWidget.h @@ -225,7 +225,7 @@ struct nsIMEUpdatePreference { typedef uint8_t Notifications; - enum MOZ_ENUM_TYPE(Notifications) + enum : Notifications { NOTIFY_NOTHING = 0, NOTIFY_SELECTION_CHANGE = 1 << 0, @@ -519,7 +519,7 @@ struct SizeConstraints { // Update values in GeckoEditable.java if you make changes here. // XXX Negative values are used in Android... typedef int8_t IMEMessageType; -enum IMEMessage MOZ_ENUM_TYPE(IMEMessageType) +enum IMEMessage : IMEMessageType { // An editable content is getting focus NOTIFY_IME_OF_FOCUS = 1, diff --git a/widget/windows/nsTextStore.h b/widget/windows/nsTextStore.h index 85169478ed4b..8b57847a91e1 100644 --- a/widget/windows/nsTextStore.h +++ b/widget/windows/nsTextStore.h @@ -480,7 +480,7 @@ protected: struct PendingAction MOZ_FINAL { - enum ActionType MOZ_ENUM_TYPE(uint8_t) + enum ActionType : uint8_t { COMPOSITION_START, COMPOSITION_UPDATE, @@ -635,7 +635,7 @@ protected: nsTextStore::Selection& mSelection; // The minimum offset of modified part of the text. - enum MOZ_ENUM_TYPE(uint32_t) + enum : uint32_t { NOT_MODIFIED = UINT32_MAX }; diff --git a/xpcom/base/nsError.h b/xpcom/base/nsError.h index ce6a45ef9b50..f6392f107acd 100644 --- a/xpcom/base/nsError.h +++ b/xpcom/base/nsError.h @@ -136,7 +136,7 @@ * #define's for compatibility with old code. */ #include "ErrorListCxxDefines.h" -#elif defined(MOZ_HAVE_CXX11_ENUM_TYPE) +#elif defined(__cplusplus) typedef enum tag_nsresult : uint32_t { #undef ERROR @@ -144,21 +144,6 @@ #include "ErrorList.h" #undef ERROR } nsresult; -#elif defined(__cplusplus) - /* - * We're C++ in an old compiler lacking enum classes *and* typed enums (likely - * gcc < 4.5.1 as clang/MSVC have long supported one or both), or compiler - * support is unknown. Yet nsresult must have unsigned 32-bit representation. - * So just make it a typedef, and implement the constants with global consts. - */ - typedef uint32_t nsresult; - - const nsresult - #undef ERROR - #define ERROR(key, val) key = val - #include "ErrorList.h" - #undef ERROR - ; #else /* * C doesn't have any way to fix the type underlying an enum, and enum From cb7df25aff10683e99864bb3d208633ce6189e4d Mon Sep 17 00:00:00 2001 From: David Burns Date: Tue, 9 Dec 2014 20:14:23 +0000 Subject: [PATCH 15/62] Bug 1107336: Update mach for newly created MarionetteDriver; r=jgriffin --HG-- extra : rebase_source : 1ca3a7047dbaec3f29ec28e7914db1c9760a6f11 --- build/mach_bootstrap.py | 1 + build/virtualenv_packages.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/build/mach_bootstrap.py b/build/mach_bootstrap.py index ea72431c0b41..e95eddd7bdff 100644 --- a/build/mach_bootstrap.py +++ b/build/mach_bootstrap.py @@ -47,6 +47,7 @@ SEARCH_PATHS = [ 'testing/web-platform/harness', 'testing/marionette/client/marionette', 'testing/marionette/transport', + 'testing/marionette/driver', 'testing/mozbase/mozcrash', 'testing/mozbase/mozdebug', 'testing/mozbase/mozdevice', diff --git a/build/virtualenv_packages.txt b/build/virtualenv_packages.txt index c442dc5ea249..1dace34d23f2 100644 --- a/build/virtualenv_packages.txt +++ b/build/virtualenv_packages.txt @@ -1,4 +1,5 @@ marionette_transport.pth:testing/marionette/transport +marionette_driver.pth:testing/marionette/driver marionette.pth:testing/marionette/client blessings.pth:python/blessings configobj.pth:python/configobj From 54d0aaf618ce7d809ea8d0ea5ec2faed3f67bbe2 Mon Sep 17 00:00:00 2001 From: David Burns Date: Tue, 9 Dec 2014 20:17:56 +0000 Subject: [PATCH 16/62] Bug 1107337: Update Marionette unit tests to use Marionette Driver modules; r=jgriffin --HG-- extra : rebase_source : db859b19823fa6b05fe5f529458584f571e4e21d --- .../tests/unit/single_finger_functions.py | 4 ++-- .../tests/unit/test_anonymous_content.py | 9 +++++---- .../marionette/tests/unit/test_appcache.py | 4 ++-- .../marionette/tests/unit/test_clearing.py | 4 ++-- .../client/marionette/tests/unit/test_click.py | 6 +++--- .../marionette/tests/unit/test_click_chrome.py | 2 +- .../tests/unit/test_click_scrolling.py | 4 ++-- .../tests/unit/test_date_time_value.py | 2 +- .../client/marionette/tests/unit/test_errors.py | 5 ++--- .../tests/unit/test_execute_async_script.py | 4 +++- .../tests/unit/test_execute_isolate.py | 4 +++- .../marionette/tests/unit/test_execute_script.py | 4 ++-- .../marionette/tests/unit/test_expected.py | 5 +++-- .../marionette/tests/unit/test_findelement.py | 6 +++--- .../tests/unit/test_findelement_chrome.py | 6 +++--- .../marionette/tests/unit/test_implicit_waits.py | 2 +- .../marionette/tests/unit/test_import_script.py | 12 ++++++------ .../marionette/tests/unit/test_navigation.py | 16 ---------------- .../tests/unit/test_profile_management.py | 2 +- .../tests/unit/test_screen_orientation.py | 2 +- .../tests/unit/test_set_window_size.py | 2 +- .../tests/unit/test_simpletest_sanity.py | 4 +++- .../marionette/tests/unit/test_single_finger.py | 4 ++-- .../tests/unit/test_single_finger_desktop.py | 4 ++-- .../marionette/tests/unit/test_specialpowers.py | 4 ++-- .../client/marionette/tests/unit/test_submit.py | 7 +++---- .../marionette/tests/unit/test_switch_frame.py | 4 ++-- .../tests/unit/test_switch_frame_chrome.py | 6 ------ .../client/marionette/tests/unit/test_text.py | 2 +- .../marionette/tests/unit/test_timeouts.py | 7 +++++-- .../client/marionette/tests/unit/test_typing.py | 4 ++-- .../client/marionette/tests/unit/test_wait.py | 7 ++++--- .../tests/unit/test_window_position.py | 2 +- .../tests/unit/test_window_switching.py | 7 ++++--- .../tests/unit/test_with_using_context.py | 2 +- 35 files changed, 79 insertions(+), 90 deletions(-) diff --git a/testing/marionette/client/marionette/tests/unit/single_finger_functions.py b/testing/marionette/client/marionette/tests/unit/single_finger_functions.py index c233cec1d538..5ecb14f138d8 100644 --- a/testing/marionette/client/marionette/tests/unit/single_finger_functions.py +++ b/testing/marionette/client/marionette/tests/unit/single_finger_functions.py @@ -1,5 +1,5 @@ -from marionette import Actions -from errors import TimeoutException +from marionette_driver.marionette import Actions +from marionette_driver.errors import TimeoutException def wait_for_condition_else_raise(marionette, wait_for_condition, expected, script): try: diff --git a/testing/marionette/client/marionette/tests/unit/test_anonymous_content.py b/testing/marionette/client/marionette/tests/unit/test_anonymous_content.py index 3949e29d3495..0b66233c2c85 100644 --- a/testing/marionette/client/marionette/tests/unit/test_anonymous_content.py +++ b/testing/marionette/client/marionette/tests/unit/test_anonymous_content.py @@ -2,11 +2,12 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from marionette import HTMLElement from marionette_test import MarionetteTestCase -from errors import NoSuchElementException -from expected import element_present -from wait import Wait + +from marionette_driver.errors import NoSuchElementException +from marionette_driver.expected import element_present +from marionette_driver.marionette import HTMLElement +from marionette_driver.wait import Wait class TestAnonymousContent(MarionetteTestCase): def setUp(self): diff --git a/testing/marionette/client/marionette/tests/unit/test_appcache.py b/testing/marionette/client/marionette/tests/unit/test_appcache.py index c017de4379f7..7e0380124d79 100644 --- a/testing/marionette/client/marionette/tests/unit/test_appcache.py +++ b/testing/marionette/client/marionette/tests/unit/test_appcache.py @@ -13,7 +13,7 @@ #See the License for the specific language governing permissions and #limitations under the License. -from application_cache import ApplicationCache +from marionette_driver.application_cache import ApplicationCache from marionette_test import MarionetteTestCase @@ -24,7 +24,7 @@ class AppCacheTests(MarionetteTestCase): self.marionette.navigate(test_url) app_cache = self.marionette.application_cache - status = app_cache.status + status = app_cache.status while status == ApplicationCache.DOWNLOADING: status = app_cache.status diff --git a/testing/marionette/client/marionette/tests/unit/test_clearing.py b/testing/marionette/client/marionette/tests/unit/test_clearing.py index 53716ccbb2a1..a9b3f1163472 100644 --- a/testing/marionette/client/marionette/tests/unit/test_clearing.py +++ b/testing/marionette/client/marionette/tests/unit/test_clearing.py @@ -3,7 +3,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from errors import InvalidElementStateException +from marionette_driver.errors import InvalidElementStateException class TestClear(MarionetteTestCase): def testWriteableTextInputShouldClear(self): @@ -56,7 +56,7 @@ class TestClear(MarionetteTestCase): element = self.marionette.find_element("id","content-editable") element.clear() self.assertEqual("", element.text) - + def testTextInputShouldNotClearWhenDisabled(self): test_html = self.marionette.absolute_url("test_clearing.html") self.marionette.navigate(test_html) diff --git a/testing/marionette/client/marionette/tests/unit/test_click.py b/testing/marionette/client/marionette/tests/unit/test_click.py index d4fccbfbe91a..91f08314f557 100644 --- a/testing/marionette/client/marionette/tests/unit/test_click.py +++ b/testing/marionette/client/marionette/tests/unit/test_click.py @@ -2,10 +2,10 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from by import By -from errors import NoSuchElementException, ElementNotVisibleException +from marionette_driver.by import By +from marionette_driver.errors import NoSuchElementException, ElementNotVisibleException from marionette_test import MarionetteTestCase -from wait import Wait +from marionette_driver.wait import Wait class TestClick(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_click_chrome.py b/testing/marionette/client/marionette/tests/unit/test_click_chrome.py index 35e441958d30..5c6f733c38bb 100644 --- a/testing/marionette/client/marionette/tests/unit/test_click_chrome.py +++ b/testing/marionette/client/marionette/tests/unit/test_click_chrome.py @@ -3,7 +3,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from by import By +from marionette_driver.by import By class TestClickChrome(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_click_scrolling.py b/testing/marionette/client/marionette/tests/unit/test_click_scrolling.py index 3d7f640a6094..4a88e118067e 100644 --- a/testing/marionette/client/marionette/tests/unit/test_click_scrolling.py +++ b/testing/marionette/client/marionette/tests/unit/test_click_scrolling.py @@ -2,8 +2,8 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from by import By -from errors import MoveTargetOutOfBoundsException +from marionette_driver.by import By +from marionette_driver.errors import MoveTargetOutOfBoundsException from marionette_test import MarionetteTestCase, skip diff --git a/testing/marionette/client/marionette/tests/unit/test_date_time_value.py b/testing/marionette/client/marionette/tests/unit/test_date_time_value.py index 9c89153ce5d6..d2fe490026a5 100644 --- a/testing/marionette/client/marionette/tests/unit/test_date_time_value.py +++ b/testing/marionette/client/marionette/tests/unit/test_date_time_value.py @@ -4,7 +4,7 @@ from marionette_test import MarionetteTestCase from datetime import datetime -from date_time_value import DateTimeValue +from marionette_driver.date_time_value import DateTimeValue class TestDateTime(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_errors.py b/testing/marionette/client/marionette/tests/unit/test_errors.py index ba5dc3f973b4..342f9b69bd4d 100644 --- a/testing/marionette/client/marionette/tests/unit/test_errors.py +++ b/testing/marionette/client/marionette/tests/unit/test_errors.py @@ -4,10 +4,9 @@ import sys -import errors import marionette_test - -from errors import ErrorCodes +from marionette_driver import errors +from marionette_driver.errors import ErrorCodes def fake_cause(): try: diff --git a/testing/marionette/client/marionette/tests/unit/test_execute_async_script.py b/testing/marionette/client/marionette/tests/unit/test_execute_async_script.py index 2456b6e3c4a2..d03d95b23bf4 100644 --- a/testing/marionette/client/marionette/tests/unit/test_execute_async_script.py +++ b/testing/marionette/client/marionette/tests/unit/test_execute_async_script.py @@ -3,7 +3,9 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from errors import JavascriptException, MarionetteException, ScriptTimeoutException +from marionette_driver.errors import ( JavascriptException, + MarionetteException, + ScriptTimeoutException ) import time diff --git a/testing/marionette/client/marionette/tests/unit/test_execute_isolate.py b/testing/marionette/client/marionette/tests/unit/test_execute_isolate.py index 016ce06de663..23db19e7b3c1 100644 --- a/testing/marionette/client/marionette/tests/unit/test_execute_isolate.py +++ b/testing/marionette/client/marionette/tests/unit/test_execute_isolate.py @@ -3,7 +3,9 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase, skip_if_b2g -from errors import JavascriptException, MarionetteException, ScriptTimeoutException +from marionette_driver.errors import (JavascriptException, + MarionetteException, + ScriptTimeoutException) class TestExecuteIsolationContent(MarionetteTestCase): def setUp(self): diff --git a/testing/marionette/client/marionette/tests/unit/test_execute_script.py b/testing/marionette/client/marionette/tests/unit/test_execute_script.py index 803b685e1e0a..da8ce6318a7d 100644 --- a/testing/marionette/client/marionette/tests/unit/test_execute_script.py +++ b/testing/marionette/client/marionette/tests/unit/test_execute_script.py @@ -4,8 +4,8 @@ import urllib -from by import By -from errors import JavascriptException, MarionetteException +from marionette_driver.by import By +from marionette_driver.errors import JavascriptException, MarionetteException from marionette_test import MarionetteTestCase def inline(doc): diff --git a/testing/marionette/client/marionette/tests/unit/test_expected.py b/testing/marionette/client/marionette/tests/unit/test_expected.py index 3881d4c1f245..99baec9396fd 100644 --- a/testing/marionette/client/marionette/tests/unit/test_expected.py +++ b/testing/marionette/client/marionette/tests/unit/test_expected.py @@ -4,10 +4,11 @@ import urllib -import expected +from marionette_driver import expected +from marionette_driver.by import By + import marionette_test -from by import By def inline(doc): return "data:text/html;charset=utf-8,%s" % urllib.quote(doc) diff --git a/testing/marionette/client/marionette/tests/unit/test_findelement.py b/testing/marionette/client/marionette/tests/unit/test_findelement.py index 587f118fcdd1..23365bb7927b 100644 --- a/testing/marionette/client/marionette/tests/unit/test_findelement.py +++ b/testing/marionette/client/marionette/tests/unit/test_findelement.py @@ -3,9 +3,9 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from marionette import HTMLElement -from by import By -from errors import NoSuchElementException, InvalidSelectorException +from marionette_driver.marionette import HTMLElement +from marionette_driver.by import By +from marionette_driver.errors import NoSuchElementException, InvalidSelectorException class TestElements(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_findelement_chrome.py b/testing/marionette/client/marionette/tests/unit/test_findelement_chrome.py index 4d13b1f6b295..ee6f2e208789 100644 --- a/testing/marionette/client/marionette/tests/unit/test_findelement_chrome.py +++ b/testing/marionette/client/marionette/tests/unit/test_findelement_chrome.py @@ -3,9 +3,9 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from marionette import HTMLElement -from by import By -from errors import NoSuchElementException +from marionette_driver.marionette import HTMLElement +from marionette_driver.by import By +from marionette_driver.errors import NoSuchElementException class TestElementsChrome(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_implicit_waits.py b/testing/marionette/client/marionette/tests/unit/test_implicit_waits.py index 241dfb0926e4..67da1543ab07 100644 --- a/testing/marionette/client/marionette/tests/unit/test_implicit_waits.py +++ b/testing/marionette/client/marionette/tests/unit/test_implicit_waits.py @@ -3,7 +3,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from errors import NoSuchElementException +from marionette_driver.errors import NoSuchElementException class TestImplicitWaits(MarionetteTestCase): def testShouldImplicitlyWaitForASingleElement(self): diff --git a/testing/marionette/client/marionette/tests/unit/test_import_script.py b/testing/marionette/client/marionette/tests/unit/test_import_script.py index c47f98f1b529..0254dd8ba25c 100644 --- a/testing/marionette/client/marionette/tests/unit/test_import_script.py +++ b/testing/marionette/client/marionette/tests/unit/test_import_script.py @@ -4,7 +4,7 @@ import os from marionette_test import MarionetteTestCase -from errors import JavascriptException +from marionette_driver.errors import JavascriptException class TestImportScript(MarionetteTestCase): def setUp(self): @@ -18,14 +18,14 @@ class TestImportScript(MarionetteTestCase): def check_file_exists(self): return self.marionette.execute_script(""" let FileUtils = SpecialPowers.Cu.import("resource://gre/modules/FileUtils.jsm", {}).FileUtils; - let importedScripts = FileUtils.getFile('TmpD', ['marionetteContentScripts']); + let importedScripts = FileUtils.getFile('TmpD', ['marionetteContentScripts']); return importedScripts.exists(); """, special_powers=True) def get_file_size(self): return self.marionette.execute_script(""" let FileUtils = SpecialPowers.Cu.import("resource://gre/modules/FileUtils.jsm", {}).FileUtils; - let importedScripts = FileUtils.getFile('TmpD', ['marionetteContentScripts']); + let importedScripts = FileUtils.getFile('TmpD', ['marionetteContentScripts']); return importedScripts.fileSize; """, special_powers=True) @@ -109,7 +109,7 @@ class TestImportScript(MarionetteTestCase): self.marionette.import_script(firstjs) self.marionette.import_script(secondjs) - self.assertEqual("i'm a test function!", + self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();")) self.assertEqual("i'm yet another test function!", @@ -129,14 +129,14 @@ class TestImportScriptChrome(TestImportScript): def check_file_exists(self): return self.marionette.execute_async_script(""" let FileUtils = Components.utils.import("resource://gre/modules/FileUtils.jsm", {}).FileUtils; - let importedScripts = FileUtils.getFile('TmpD', ['marionetteChromeScripts']); + let importedScripts = FileUtils.getFile('TmpD', ['marionetteChromeScripts']); marionetteScriptFinished(importedScripts.exists()); """) def get_file_size(self): return self.marionette.execute_async_script(""" let FileUtils = Components.utils.import("resource://gre/modules/FileUtils.jsm", {}).FileUtils; - let importedScripts = FileUtils.getFile('TmpD', ['marionetteChromeScripts']); + let importedScripts = FileUtils.getFile('TmpD', ['marionetteChromeScripts']); marionetteScriptFinished(importedScripts.fileSize); """) diff --git a/testing/marionette/client/marionette/tests/unit/test_navigation.py b/testing/marionette/client/marionette/tests/unit/test_navigation.py index e95ee42467c4..fb574ffda44e 100644 --- a/testing/marionette/client/marionette/tests/unit/test_navigation.py +++ b/testing/marionette/client/marionette/tests/unit/test_navigation.py @@ -2,14 +2,11 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from marionette_test import MarionetteTestCase, skip_if_b2g, skip_if_e10s -from errors import MarionetteException, TimeoutException class TestNavigate(MarionetteTestCase): def test_navigate(self): self.assertTrue(self.marionette.execute_script("window.location.href = 'about:blank'; return true;")) self.assertEqual("about:blank", self.marionette.execute_script("return window.location.href;")) - test_html = self.marionette.absolute_url("test.html") self.marionette.navigate(test_html) self.assertNotEqual("about:blank", self.marionette.execute_script("return window.location.href;")) self.assertEqual("Marionette Test", self.marionette.title) @@ -77,7 +74,6 @@ class TestNavigate(MarionetteTestCase): self.assertTrue('test_iframe.html' in self.marionette.get_url()) ''' - @skip_if_e10s # Interactions with about: pages need e10s support (bug 1096488). def test_shouldnt_error_if_nonexistent_url_used(self): try: self.marionette.navigate("thisprotocoldoesnotexist://") @@ -85,20 +81,8 @@ class TestNavigate(MarionetteTestCase): except TimeoutException: self.fail("The socket shouldn't have timed out when navigating to a non-existent URL") except MarionetteException as e: - self.assertIn("Error loading page", str(e)) - except Exception as inst: - import traceback - print traceback.format_exc() - self.fail("Should have thrown a MarionetteException instead of %s" % type(inst)) - @skip_if_e10s # Interactions with about: pages need e10s support (bug 1096488). - @skip_if_b2g # about:blocked isn't a well formed uri on b2g - def test_should_navigate_to_requested_about_page(self): - self.marionette.navigate("about:neterror") - self.assertEqual(self.marionette.get_url(), "about:neterror") - self.marionette.navigate(self.marionette.absolute_url("test.html")) self.marionette.navigate("about:blocked") - self.assertEqual(self.marionette.get_url(), "about:blocked") def test_find_element_state_complete(self): test_html = self.marionette.absolute_url("test.html") diff --git a/testing/marionette/client/marionette/tests/unit/test_profile_management.py b/testing/marionette/client/marionette/tests/unit/test_profile_management.py index 28b9477c2e97..92b6a3782868 100644 --- a/testing/marionette/client/marionette/tests/unit/test_profile_management.py +++ b/testing/marionette/client/marionette/tests/unit/test_profile_management.py @@ -3,7 +3,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. import os -from errors import JavascriptException +from marionette_driver.errors import JavascriptException from marionette_test import MarionetteTestCase class TestLog(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_screen_orientation.py b/testing/marionette/client/marionette/tests/unit/test_screen_orientation.py index 4e5c83a8b627..06079be936da 100644 --- a/testing/marionette/client/marionette/tests/unit/test_screen_orientation.py +++ b/testing/marionette/client/marionette/tests/unit/test_screen_orientation.py @@ -4,7 +4,7 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from errors import MarionetteException +from marionette_driver.errors import MarionetteException from marionette_test import MarionetteTestCase from mozrunner.devices.emulator_screen import EmulatorScreen diff --git a/testing/marionette/client/marionette/tests/unit/test_set_window_size.py b/testing/marionette/client/marionette/tests/unit/test_set_window_size.py index 044c201d2ebe..bac5d713c231 100644 --- a/testing/marionette/client/marionette/tests/unit/test_set_window_size.py +++ b/testing/marionette/client/marionette/tests/unit/test_set_window_size.py @@ -2,7 +2,7 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from errors import MarionetteException +from marionette_driver.errors import MarionetteException from marionette_test import MarionetteTestCase class TestSetWindowSize(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_simpletest_sanity.py b/testing/marionette/client/marionette/tests/unit/test_simpletest_sanity.py index fe51a1a47f7c..7e08be1bc665 100644 --- a/testing/marionette/client/marionette/tests/unit/test_simpletest_sanity.py +++ b/testing/marionette/client/marionette/tests/unit/test_simpletest_sanity.py @@ -3,7 +3,9 @@ # You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from errors import JavascriptException, MarionetteException, ScriptTimeoutException +from marionette_driver.errors import (JavascriptException, + MarionetteException, + ScriptTimeoutException) class SimpletestSanityTest(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_single_finger.py b/testing/marionette/client/marionette/tests/unit/test_single_finger.py index 49a053e95182..63afbe837cf5 100644 --- a/testing/marionette/client/marionette/tests/unit/test_single_finger.py +++ b/testing/marionette/client/marionette/tests/unit/test_single_finger.py @@ -3,8 +3,8 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from marionette import Actions -from errors import MarionetteException +from marionette_driver.marionette import Actions +from marionette_driver.errors import MarionetteException #add this directory to the path import os import sys diff --git a/testing/marionette/client/marionette/tests/unit/test_single_finger_desktop.py b/testing/marionette/client/marionette/tests/unit/test_single_finger_desktop.py index d185b36fe080..264b691a18fe 100644 --- a/testing/marionette/client/marionette/tests/unit/test_single_finger_desktop.py +++ b/testing/marionette/client/marionette/tests/unit/test_single_finger_desktop.py @@ -1,6 +1,6 @@ from marionette_test import MarionetteTestCase -from marionette import Actions -from errors import MarionetteException +from marionette_driver.marionette import Actions +from marionette_driver.errors import MarionetteException #add this directory to the path import os import sys diff --git a/testing/marionette/client/marionette/tests/unit/test_specialpowers.py b/testing/marionette/client/marionette/tests/unit/test_specialpowers.py index aea11a878f04..835ede56b15d 100644 --- a/testing/marionette/client/marionette/tests/unit/test_specialpowers.py +++ b/testing/marionette/client/marionette/tests/unit/test_specialpowers.py @@ -3,7 +3,7 @@ # You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from errors import JavascriptException, MarionetteException +from marionette_driver.errors import JavascriptException, MarionetteException class TestSpecialPowersContent(MarionetteTestCase): @@ -15,7 +15,7 @@ class TestSpecialPowersContent(MarionetteTestCase): SpecialPowers.setCharPref("%(pref)s", "%(value)s"); return SpecialPowers.getCharPref("%(pref)s") """ % {'pref': self.testpref, 'value': self.testvalue}, special_powers=True); - self.assertEqual(result, self.testvalue) + self.assertEqual(result, self.testvalue) def test_prefs_after_navigate(self): test_html = self.marionette.absolute_url("test.html") diff --git a/testing/marionette/client/marionette/tests/unit/test_submit.py b/testing/marionette/client/marionette/tests/unit/test_submit.py index 272f9e272b7a..c80542777182 100644 --- a/testing/marionette/client/marionette/tests/unit/test_submit.py +++ b/testing/marionette/client/marionette/tests/unit/test_submit.py @@ -4,11 +4,10 @@ import time -from by import By -from errors import NoSuchElementException +from marionette_driver.by import By +from marionette_driver.errors import NoSuchElementException +from marionette_driver.wait import Wait from marionette_test import MarionetteTestCase -from wait import Wait - class TestSubmit(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_switch_frame.py b/testing/marionette/client/marionette/tests/unit/test_switch_frame.py index 6a56c75cf082..57cfe7df516c 100644 --- a/testing/marionette/client/marionette/tests/unit/test_switch_frame.py +++ b/testing/marionette/client/marionette/tests/unit/test_switch_frame.py @@ -3,8 +3,8 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from errors import JavascriptException -from errors import NoSuchFrameException +from marionette_driver.errors import (JavascriptException, + NoSuchFrameException) class TestSwitchFrame(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_switch_frame_chrome.py b/testing/marionette/client/marionette/tests/unit/test_switch_frame_chrome.py index d6b49cd39b15..5e476231ef83 100644 --- a/testing/marionette/client/marionette/tests/unit/test_switch_frame_chrome.py +++ b/testing/marionette/client/marionette/tests/unit/test_switch_frame_chrome.py @@ -48,9 +48,3 @@ class TestSwitchFrameChrome(MarionetteTestCase): self.marionette.execute_async_script("foo();") except JavascriptException as e: self.assertIn("foo", e.msg) - - def test_we_can_switch_to_a_browser_frame(self): - self.assertIn("test.xul", self.marionette.get_url(), "Initial navigation has failed") - browser = self.marionette.find_element(By.ID, 'aBrowser') - self.marionette.switch_to_frame(browser) - self.assertIn("test2.xul", self.marionette.get_url(), "Switching by element failed") diff --git a/testing/marionette/client/marionette/tests/unit/test_text.py b/testing/marionette/client/marionette/tests/unit/test_text.py index a6ada51aa33d..53cc340ff2aa 100644 --- a/testing/marionette/client/marionette/tests/unit/test_text.py +++ b/testing/marionette/client/marionette/tests/unit/test_text.py @@ -3,7 +3,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from keys import Keys +from marionette_driver.keys import Keys class TestText(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_timeouts.py b/testing/marionette/client/marionette/tests/unit/test_timeouts.py index 6e066851b0b7..10ba6ccd4da9 100644 --- a/testing/marionette/client/marionette/tests/unit/test_timeouts.py +++ b/testing/marionette/client/marionette/tests/unit/test_timeouts.py @@ -4,8 +4,11 @@ import os from marionette_test import MarionetteTestCase -from marionette import HTMLElement -from errors import NoSuchElementException, JavascriptException, MarionetteException, ScriptTimeoutException +from marionette_driver.marionette import HTMLElement +from marionette_driver.errors import (NoSuchElementException, + JavascriptException, + MarionetteException, + ScriptTimeoutException) class TestTimeouts(MarionetteTestCase): def test_pagetimeout_notdefinetimeout_pass(self): diff --git a/testing/marionette/client/marionette/tests/unit/test_typing.py b/testing/marionette/client/marionette/tests/unit/test_typing.py index 969c9587e432..638ba2da8145 100644 --- a/testing/marionette/client/marionette/tests/unit/test_typing.py +++ b/testing/marionette/client/marionette/tests/unit/test_typing.py @@ -3,8 +3,8 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase, skip_if_b2g -from keys import Keys -from errors import ElementNotVisibleException +from marionette_driver.keys import Keys +from marionette_driver.errors import ElementNotVisibleException class TestTyping(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_wait.py b/testing/marionette/client/marionette/tests/unit/test_wait.py index b17742249a1e..775b505569d7 100644 --- a/testing/marionette/client/marionette/tests/unit/test_wait.py +++ b/testing/marionette/client/marionette/tests/unit/test_wait.py @@ -5,11 +5,12 @@ import sys import time -import errors -import wait +from marionette_driver import errors +from marionette_driver import wait +from marionette_driver.wait import Wait from marionette_test import MarionetteTestCase -from wait import Wait + class TickingClock(object): def __init__(self, incr=1): diff --git a/testing/marionette/client/marionette/tests/unit/test_window_position.py b/testing/marionette/client/marionette/tests/unit/test_window_position.py index 70879f8d1c98..220010677474 100644 --- a/testing/marionette/client/marionette/tests/unit/test_window_position.py +++ b/testing/marionette/client/marionette/tests/unit/test_window_position.py @@ -13,7 +13,7 @@ #limitations under the License. from marionette_test import MarionetteTestCase -from errors import MarionetteException +from marionette_driver.errors import MarionetteException class TestWindowPosition(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_window_switching.py b/testing/marionette/client/marionette/tests/unit/test_window_switching.py index bf689b74b3cc..18bd0b426582 100644 --- a/testing/marionette/client/marionette/tests/unit/test_window_switching.py +++ b/testing/marionette/client/marionette/tests/unit/test_window_switching.py @@ -2,10 +2,11 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. -from by import By -from errors import NoSuchElementException from marionette_test import MarionetteTestCase -from wait import Wait + +from marionette_driver.by import By +from marionette_driver.errors import NoSuchElementException +from marionette_driver.wait import Wait class TestWindowSwitching(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_with_using_context.py b/testing/marionette/client/marionette/tests/unit/test_with_using_context.py index d8b72a791aa4..cfe83f531eb1 100644 --- a/testing/marionette/client/marionette/tests/unit/test_with_using_context.py +++ b/testing/marionette/client/marionette/tests/unit/test_with_using_context.py @@ -3,7 +3,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from errors import MarionetteException +from marionette_driver.errors import MarionetteException class TestSetContext(MarionetteTestCase): From 988973a3d8dec4d0bb763dede4b9fec965052831 Mon Sep 17 00:00:00 2001 From: David Burns Date: Tue, 9 Dec 2014 20:21:32 +0000 Subject: [PATCH 17/62] Bug 1107336: Update layout tests that use marionette to use new Marionette Driver module; r=jgriffin --HG-- extra : rebase_source : 645d09af73a9072a8c39a4f85cf741fb945a52d1 --- layout/base/tests/marionette/test_touchcaret.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/layout/base/tests/marionette/test_touchcaret.py b/layout/base/tests/marionette/test_touchcaret.py index 9ef93af1b431..61a37760936f 100644 --- a/layout/base/tests/marionette/test_touchcaret.py +++ b/layout/base/tests/marionette/test_touchcaret.py @@ -3,10 +3,10 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from by import By -from marionette import Actions +from marionette_driver.by import By +from marionette_driver.marionette import Actions +from marionette_driver.selection import SelectionManager from marionette_test import MarionetteTestCase -from selection import SelectionManager class TouchCaretTest(MarionetteTestCase): From 79f2d9d1f32004f656837f2506ebd3a4b0d79684 Mon Sep 17 00:00:00 2001 From: David Burns Date: Tue, 9 Dec 2014 20:33:03 +0000 Subject: [PATCH 18/62] Bug 1107336: Move marionette code for driving the browser out of the runner; r=jgriffin --HG-- rename : testing/marionette/client/marionette/application_cache.py => testing/marionette/driver/marionette_driver/application_cache.py rename : testing/marionette/client/marionette/by.py => testing/marionette/driver/marionette_driver/by.py rename : testing/marionette/client/marionette/date_time_value.py => testing/marionette/driver/marionette_driver/date_time_value.py rename : testing/marionette/client/marionette/decorators.py => testing/marionette/driver/marionette_driver/decorators.py rename : testing/marionette/client/marionette/errors.py => testing/marionette/driver/marionette_driver/errors.py rename : testing/marionette/client/marionette/expected.py => testing/marionette/driver/marionette_driver/expected.py rename : testing/marionette/client/marionette/geckoinstance.py => testing/marionette/driver/marionette_driver/geckoinstance.py rename : testing/marionette/client/marionette/gestures.py => testing/marionette/driver/marionette_driver/gestures.py rename : testing/marionette/client/marionette/keys.py => testing/marionette/driver/marionette_driver/keys.py rename : testing/marionette/client/marionette/marionette.py => testing/marionette/driver/marionette_driver/marionette.py rename : testing/marionette/client/marionette/selection.py => testing/marionette/driver/marionette_driver/selection.py rename : testing/marionette/client/marionette/wait.py => testing/marionette/driver/marionette_driver/wait.py extra : rebase_source : 4fa2501172cc1dedf20e2f236b32fe3bbfc30b4f --- testing/config/marionette_requirements.txt | 1 + .../client/marionette/marionette_test.py | 9 ++++--- .../client/marionette/runner/base.py | 2 +- .../driver/marionette_driver/__init__.py | 3 +++ .../marionette_driver}/application_cache.py | 0 .../marionette_driver}/by.py | 0 .../marionette_driver}/date_time_value.py | 0 .../marionette_driver}/decorators.py | 0 .../marionette_driver}/errors.py | 0 .../marionette_driver}/expected.py | 0 .../marionette_driver}/geckoinstance.py | 0 .../marionette_driver}/gestures.py | 0 .../marionette_driver}/keys.py | 0 .../marionette_driver}/marionette.py | 0 .../marionette_driver}/selection.py | 0 .../marionette_driver}/wait.py | 0 testing/marionette/driver/requirements.txt | 1 + testing/marionette/driver/setup.py | 27 +++++++++++++++++++ 18 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 testing/marionette/driver/marionette_driver/__init__.py rename testing/marionette/{client/marionette => driver/marionette_driver}/application_cache.py (100%) rename testing/marionette/{client/marionette => driver/marionette_driver}/by.py (100%) rename testing/marionette/{client/marionette => driver/marionette_driver}/date_time_value.py (100%) rename testing/marionette/{client/marionette => driver/marionette_driver}/decorators.py (100%) rename testing/marionette/{client/marionette => driver/marionette_driver}/errors.py (100%) rename testing/marionette/{client/marionette => driver/marionette_driver}/expected.py (100%) rename testing/marionette/{client/marionette => driver/marionette_driver}/geckoinstance.py (100%) rename testing/marionette/{client/marionette => driver/marionette_driver}/gestures.py (100%) rename testing/marionette/{client/marionette => driver/marionette_driver}/keys.py (100%) rename testing/marionette/{client/marionette => driver/marionette_driver}/marionette.py (100%) rename testing/marionette/{client/marionette => driver/marionette_driver}/selection.py (100%) rename testing/marionette/{client/marionette => driver/marionette_driver}/wait.py (100%) create mode 100644 testing/marionette/driver/requirements.txt create mode 100644 testing/marionette/driver/setup.py diff --git a/testing/config/marionette_requirements.txt b/testing/config/marionette_requirements.txt index 186360841e52..ab683343728d 100644 --- a/testing/config/marionette_requirements.txt +++ b/testing/config/marionette_requirements.txt @@ -1,3 +1,4 @@ -r mozbase_requirements.txt ../marionette/transport +../marionette/driver ../marionette diff --git a/testing/marionette/client/marionette/marionette_test.py b/testing/marionette/client/marionette/marionette_test.py index cd45db52a8b9..80356a4f81d0 100644 --- a/testing/marionette/client/marionette/marionette_test.py +++ b/testing/marionette/client/marionette/marionette_test.py @@ -14,7 +14,8 @@ import unittest import weakref import warnings -from errors import ( + +from marionette_driver.errors import ( ErrorCodes, MarionetteException, InstallGeckoError, TimeoutException, InvalidResponseException, JavascriptException, NoSuchElementException, XPathLookupException, NoSuchWindowException, StaleElementException, ScriptTimeoutException, ElementNotVisibleException, @@ -22,10 +23,10 @@ from errors import ( InvalidCookieDomainException, UnableToSetCookieException, InvalidSelectorException, MoveTargetOutOfBoundsException, FrameSendNotInitializedError, FrameSendFailureError ) -from marionette import Marionette +from marionette_driver.marionette import Marionette from mozlog.structured.structuredlog import get_default_logger -from wait import Wait -from expected import element_present, element_not_present +from marionette_driver.wait import Wait +from marionette_driver.expected import element_present, element_not_present class SkipTest(Exception): diff --git a/testing/marionette/client/marionette/runner/base.py b/testing/marionette/client/marionette/runner/base.py index fd1e56fdb528..ae4aa453d203 100644 --- a/testing/marionette/client/marionette/runner/base.py +++ b/testing/marionette/client/marionette/runner/base.py @@ -17,7 +17,7 @@ import unittest import xml.dom.minidom as dom from manifestparser import TestManifest -from marionette import Marionette +from marionette_driver.marionette import Marionette from mixins.b2g import B2GTestResultMixin, get_b2g_pid, get_dm from mozhttpd import MozHttpd from mozlog.structured.structuredlog import get_default_logger diff --git a/testing/marionette/driver/marionette_driver/__init__.py b/testing/marionette/driver/marionette_driver/__init__.py new file mode 100644 index 000000000000..aff2e13acace --- /dev/null +++ b/testing/marionette/driver/marionette_driver/__init__.py @@ -0,0 +1,3 @@ +from marionette_driver import ( errors, by, decorators, expected, geckoinstance, + gestures, keys, marionette, selection, wait, + application_cache, date_time_value ) \ No newline at end of file diff --git a/testing/marionette/client/marionette/application_cache.py b/testing/marionette/driver/marionette_driver/application_cache.py similarity index 100% rename from testing/marionette/client/marionette/application_cache.py rename to testing/marionette/driver/marionette_driver/application_cache.py diff --git a/testing/marionette/client/marionette/by.py b/testing/marionette/driver/marionette_driver/by.py similarity index 100% rename from testing/marionette/client/marionette/by.py rename to testing/marionette/driver/marionette_driver/by.py diff --git a/testing/marionette/client/marionette/date_time_value.py b/testing/marionette/driver/marionette_driver/date_time_value.py similarity index 100% rename from testing/marionette/client/marionette/date_time_value.py rename to testing/marionette/driver/marionette_driver/date_time_value.py diff --git a/testing/marionette/client/marionette/decorators.py b/testing/marionette/driver/marionette_driver/decorators.py similarity index 100% rename from testing/marionette/client/marionette/decorators.py rename to testing/marionette/driver/marionette_driver/decorators.py diff --git a/testing/marionette/client/marionette/errors.py b/testing/marionette/driver/marionette_driver/errors.py similarity index 100% rename from testing/marionette/client/marionette/errors.py rename to testing/marionette/driver/marionette_driver/errors.py diff --git a/testing/marionette/client/marionette/expected.py b/testing/marionette/driver/marionette_driver/expected.py similarity index 100% rename from testing/marionette/client/marionette/expected.py rename to testing/marionette/driver/marionette_driver/expected.py diff --git a/testing/marionette/client/marionette/geckoinstance.py b/testing/marionette/driver/marionette_driver/geckoinstance.py similarity index 100% rename from testing/marionette/client/marionette/geckoinstance.py rename to testing/marionette/driver/marionette_driver/geckoinstance.py diff --git a/testing/marionette/client/marionette/gestures.py b/testing/marionette/driver/marionette_driver/gestures.py similarity index 100% rename from testing/marionette/client/marionette/gestures.py rename to testing/marionette/driver/marionette_driver/gestures.py diff --git a/testing/marionette/client/marionette/keys.py b/testing/marionette/driver/marionette_driver/keys.py similarity index 100% rename from testing/marionette/client/marionette/keys.py rename to testing/marionette/driver/marionette_driver/keys.py diff --git a/testing/marionette/client/marionette/marionette.py b/testing/marionette/driver/marionette_driver/marionette.py similarity index 100% rename from testing/marionette/client/marionette/marionette.py rename to testing/marionette/driver/marionette_driver/marionette.py diff --git a/testing/marionette/client/marionette/selection.py b/testing/marionette/driver/marionette_driver/selection.py similarity index 100% rename from testing/marionette/client/marionette/selection.py rename to testing/marionette/driver/marionette_driver/selection.py diff --git a/testing/marionette/client/marionette/wait.py b/testing/marionette/driver/marionette_driver/wait.py similarity index 100% rename from testing/marionette/client/marionette/wait.py rename to testing/marionette/driver/marionette_driver/wait.py diff --git a/testing/marionette/driver/requirements.txt b/testing/marionette/driver/requirements.txt new file mode 100644 index 000000000000..4259e1971495 --- /dev/null +++ b/testing/marionette/driver/requirements.txt @@ -0,0 +1 @@ +marionette-transport == 0.4 \ No newline at end of file diff --git a/testing/marionette/driver/setup.py b/testing/marionette/driver/setup.py new file mode 100644 index 000000000000..bd544e676658 --- /dev/null +++ b/testing/marionette/driver/setup.py @@ -0,0 +1,27 @@ +import os +from setuptools import setup, find_packages +import sys + +version = '0.1.0' + +# dependencies +with open('requirements.txt') as f: + deps = f.read().splitlines() + +setup(name='marionette_driver', + version=version, + description="Marionette Driver", + long_description='See http://marionette-driver.readthedocs.org/', + classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers + keywords='mozilla', + author='Auto-tools', + author_email='tools-marionette@lists.mozilla.org', + url='https://wiki.mozilla.org/Auto-tools/Projects/Marionette', + license='MPL', + packages=find_packages(), + #package_data={'marionette_driver': ['touch/*.js']}, + include_package_data=True, + zip_safe=False, + install_requires=deps, + ) + From be2083e5ac7f86a3b787a44324584301a128bc14 Mon Sep 17 00:00:00 2001 From: David Burns Date: Wed, 10 Dec 2014 23:54:15 +0000 Subject: [PATCH 19/62] Bug 1107336: Update testsuite targets to make sure MarionetteDriver is available; r=jgriffin --HG-- extra : rebase_source : 25ec9270b94e4cae73466888a5aa7235b2eebfd2 --- testing/testsuite-targets.mk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/testing/testsuite-targets.mk b/testing/testsuite-targets.mk index 3793c3d7595a..14d93e3d59c4 100644 --- a/testing/testsuite-targets.mk +++ b/testing/testsuite-targets.mk @@ -536,8 +536,10 @@ MARIONETTE_DIR=$(PKG_STAGE)/marionette stage-marionette: make-stage-dir $(NSINSTALL) -D $(MARIONETTE_DIR)/tests $(NSINSTALL) -D $(MARIONETTE_DIR)/transport + $(NSINSTALL) -D $(MARIONETTE_DIR)/driver @(cd $(topsrcdir)/testing/marionette/client && tar --exclude marionette/tests $(TAR_CREATE_FLAGS) - *) | (cd $(MARIONETTE_DIR)/ && tar -xf -) @(cd $(topsrcdir)/testing/marionette/transport && tar $(TAR_CREATE_FLAGS) - *) | (cd $(MARIONETTE_DIR)/transport && tar -xf -) + @(cd $(topsrcdir)/testing/marionette/driver && tar $(TAR_CREATE_FLAGS) - *) | (cd $(MARIONETTE_DIR)/driver && tar -xf -) $(PYTHON) $(topsrcdir)/testing/marionette/client/marionette/tests/print-manifest-dirs.py \ $(topsrcdir) \ $(topsrcdir)/testing/marionette/client/marionette/tests/unit-tests.ini \ From 9687636fa51a4b733ddee04d3873c42dbe0145d6 Mon Sep 17 00:00:00 2001 From: David Burns Date: Thu, 11 Dec 2014 15:56:44 +0000 Subject: [PATCH 20/62] Bug 1107336: update tests not covered by manifest for when they are ready; r=jgriffin --HG-- extra : rebase_source : 88ec67c56d415ba716a4b062a549732f03868b2d --- testing/marionette/client/marionette/b2g_update_test.py | 4 ++-- .../client/marionette/tests/unit/test_element_touch.py | 2 +- .../marionette/client/marionette/tests/unit/test_emulator.py | 3 ++- .../client/marionette/tests/unit/test_switch_frame_chrome.py | 4 ++-- testing/marionette/driver/marionette_driver/__init__.py | 3 ++- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/testing/marionette/client/marionette/b2g_update_test.py b/testing/marionette/client/marionette/b2g_update_test.py index ea1c4d2b04e7..5c832922e469 100644 --- a/testing/marionette/client/marionette/b2g_update_test.py +++ b/testing/marionette/client/marionette/b2g_update_test.py @@ -12,8 +12,8 @@ import types import weakref from b2ginstance import B2GInstance -from errors import InvalidResponseException -from marionette import Marionette +from marionette_driver.errors import InvalidResponseException +from marionette_driver.marionette import Marionette from marionette_test import MarionetteTestCase from marionette_transport import MarionetteTransport from runtests import MarionetteTestRunner, cli diff --git a/testing/marionette/client/marionette/tests/unit/test_element_touch.py b/testing/marionette/client/marionette/tests/unit/test_element_touch.py index 7b9f047a9576..539782ace7e1 100644 --- a/testing/marionette/client/marionette/tests/unit/test_element_touch.py +++ b/testing/marionette/client/marionette/tests/unit/test_element_touch.py @@ -3,7 +3,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from errors import MarionetteException +from marionette_driver.errors import MarionetteException class testElementTouch(MarionetteTestCase): def test_touch(self): diff --git a/testing/marionette/client/marionette/tests/unit/test_emulator.py b/testing/marionette/client/marionette/tests/unit/test_emulator.py index f330d983dba7..e69d996d27b0 100644 --- a/testing/marionette/client/marionette/tests/unit/test_emulator.py +++ b/testing/marionette/client/marionette/tests/unit/test_emulator.py @@ -3,7 +3,8 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from errors import JavascriptException, MarionetteException +from marionette_driver.errors import (JavascriptException, + MarionetteException) class TestEmulatorContent(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_switch_frame_chrome.py b/testing/marionette/client/marionette/tests/unit/test_switch_frame_chrome.py index 5e476231ef83..992007d1c208 100644 --- a/testing/marionette/client/marionette/tests/unit/test_switch_frame_chrome.py +++ b/testing/marionette/client/marionette/tests/unit/test_switch_frame_chrome.py @@ -3,8 +3,8 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from errors import JavascriptException -from by import By +from marionette_driver.errors import JavascriptException +from marionette_driver.by import By class TestSwitchFrameChrome(MarionetteTestCase): def setUp(self): diff --git a/testing/marionette/driver/marionette_driver/__init__.py b/testing/marionette/driver/marionette_driver/__init__.py index aff2e13acace..0c82dcdad253 100644 --- a/testing/marionette/driver/marionette_driver/__init__.py +++ b/testing/marionette/driver/marionette_driver/__init__.py @@ -1,3 +1,4 @@ from marionette_driver import ( errors, by, decorators, expected, geckoinstance, gestures, keys, marionette, selection, wait, - application_cache, date_time_value ) \ No newline at end of file + application_cache, date_time_value ) +from marionette_driver.gestures import smooth_scroll, pinch \ No newline at end of file From f30ab30a2035b6f043e5072e42f95116e4999ca5 Mon Sep 17 00:00:00 2001 From: David Burns Date: Mon, 5 Jan 2015 21:51:03 +0000 Subject: [PATCH 21/62] Bug 1107336: Update imports to new Marionette Driver from runner; r=jgriffin --HG-- extra : rebase_source : 5c91d5a35bf2707a04cb5b65acfb1a9688f2f3ac --- .../marionette/client/marionette/__init__.py | 14 ++--- .../tests/unit/test_accessibility.py | 4 +- .../marionette/tests/unit/test_marionette.py | 2 +- .../tests/unit/test_window_handles.py | 62 ------------------- 4 files changed, 10 insertions(+), 72 deletions(-) diff --git a/testing/marionette/client/marionette/__init__.py b/testing/marionette/client/marionette/__init__.py index 67a263367d59..9923b91cbdea 100644 --- a/testing/marionette/client/marionette/__init__.py +++ b/testing/marionette/client/marionette/__init__.py @@ -2,11 +2,11 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from gestures import smooth_scroll, pinch -from by import By -from marionette import Marionette, HTMLElement, Actions, MultiActions +from marionette_driver.gestures import smooth_scroll, pinch +from marionette_driver.by import By +from marionette_driver.marionette import Marionette, HTMLElement, Actions, MultiActions from marionette_test import MarionetteTestCase, MarionetteJSTestCase, CommonTestCase, expectedFailure, skip, SkipTest -from errors import ( +from marionette_driver.errors import ( ElementNotVisibleException, ElementNotAccessibleException, ErrorCodes, @@ -50,6 +50,6 @@ from runner import ( TestResult, TestResultCollection ) -from wait import Wait -from date_time_value import DateTimeValue -import decorators +from marionette_driver.wait import Wait +from marionette_driver.date_time_value import DateTimeValue +import marionette_driver.decorators diff --git a/testing/marionette/client/marionette/tests/unit/test_accessibility.py b/testing/marionette/client/marionette/tests/unit/test_accessibility.py index ee3ca9e6f1f9..d0a63f855dbc 100644 --- a/testing/marionette/client/marionette/tests/unit/test_accessibility.py +++ b/testing/marionette/client/marionette/tests/unit/test_accessibility.py @@ -3,8 +3,8 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from errors import ElementNotAccessibleException -from errors import ElementNotVisibleException +from marionette_driver.errors import (ElementNotAccessibleException, + ElementNotVisibleException) class TestAccessibility(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_marionette.py b/testing/marionette/client/marionette/tests/unit/test_marionette.py index 4e9fd4f7e4da..d25a800683a7 100644 --- a/testing/marionette/client/marionette/tests/unit/test_marionette.py +++ b/testing/marionette/client/marionette/tests/unit/test_marionette.py @@ -2,7 +2,7 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -import errors +from marionette_driver import errors import marionette_test diff --git a/testing/marionette/client/marionette/tests/unit/test_window_handles.py b/testing/marionette/client/marionette/tests/unit/test_window_handles.py index 080d6e9e965a..bb090af95f7f 100644 --- a/testing/marionette/client/marionette/tests/unit/test_window_handles.py +++ b/testing/marionette/client/marionette/tests/unit/test_window_handles.py @@ -2,13 +2,10 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from marionette_test import MarionetteTestCase, skip_if_e10s from marionette import Keys -class TestWindowHandles(MarionetteTestCase): - @skip_if_e10s # Interactions with about: pages need e10s support (bug 1096488). def test_new_tab_window_handles(self): keys = [Keys.SHIFT] if self.marionette.session_capabilities['platformName'] == 'DARWIN': @@ -93,63 +90,4 @@ class TestWindowHandles(MarionetteTestCase): self.marionette.switch_to_window(start_tab) def test_tab_and_window_handles(self): - start_tab = self.marionette.current_window_handle - start_chrome_window = self.marionette.current_chrome_window_handle - tab_open_page = self.marionette.absolute_url("windowHandles.html") - window_open_page = self.marionette.absolute_url("test_windows.html") - # Open a new tab and switch to it. - self.marionette.navigate(tab_open_page) - link = self.marionette.find_element("id", "new-tab") - link.click() - - self.wait_for_condition(lambda mn: len(mn.window_handles) == 2) - self.assertEqual(len(self.marionette.chrome_window_handles), 1) - self.assertEqual(self.marionette.current_chrome_window_handle, start_chrome_window) - - handles = self.marionette.window_handles - handles.remove(start_tab) - - new_tab = handles.pop() - self.marionette.switch_to_window(new_tab) - self.assertEqual(self.marionette.get_url(), "about:blank") - - # Open a new window from the new tab. - self.marionette.navigate(window_open_page) - - link = self.marionette.find_element("link text", "Open new window") - link.click() - self.wait_for_condition(lambda mn: len(mn.window_handles) == 3) - - self.assertEqual(len(self.marionette.chrome_window_handles), 2) - self.assertEqual(self.marionette.current_chrome_window_handle, start_chrome_window) - - # Find the new window and switch to it. - handles = self.marionette.window_handles - handles.remove(start_tab) - handles.remove(new_tab) - new_window = handles.pop() - - self.marionette.switch_to_window(new_window) - results_page = self.marionette.absolute_url("resultPage.html") - self.assertEqual(self.marionette.get_url(), results_page) - - self.assertEqual(len(self.marionette.chrome_window_handles), 2) - self.assertNotEqual(self.marionette.current_chrome_window_handle, start_chrome_window) - - # Return to our original tab and close it. - self.marionette.switch_to_window(start_tab) - self.marionette.close() - self.assertEquals(len(self.marionette.window_handles), 2) - - # Close the opened window and carry on in our new tab. - self.marionette.switch_to_window(new_window) - self.marionette.close() - self.assertEqual(len(self.marionette.window_handles), 1) - - self.marionette.switch_to_window(new_tab) - self.assertEqual(self.marionette.get_url(), results_page) - self.marionette.navigate("about:blank") - - self.assertEqual(len(self.marionette.chrome_window_handles), 1) - self.assertEqual(self.marionette.current_chrome_window_handle, start_chrome_window) From 03e28488ef8f2fa01326612c279cd21e756305a9 Mon Sep 17 00:00:00 2001 From: David Burns Date: Mon, 5 Jan 2015 21:52:06 +0000 Subject: [PATCH 22/62] Bug 1107336: correct loop imports for marionette; r=jgriffin --HG-- extra : rebase_source : 3ada170c463cd26221fc67a19b88a1f607ab311c --- browser/components/loop/test/shared/frontend_tester.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/components/loop/test/shared/frontend_tester.py b/browser/components/loop/test/shared/frontend_tester.py index 7835fae0b9d4..d5364853a173 100644 --- a/browser/components/loop/test/shared/frontend_tester.py +++ b/browser/components/loop/test/shared/frontend_tester.py @@ -1,5 +1,5 @@ from marionette_test import MarionetteTestCase -from errors import NoSuchElementException +from marionette_driver.errors import NoSuchElementException import threading import SimpleHTTPServer import SocketServer From 19f70f4fb906145f7858b29d5b18c99295803642 Mon Sep 17 00:00:00 2001 From: David Burns Date: Fri, 9 Jan 2015 21:42:06 +0000 Subject: [PATCH 23/62] Bug 1107336: selection tests imports for marionette; r=jgriffin --HG-- extra : rebase_source : 807b6f129b932445da3355b11bd3c7ff569c852e --- .../tests/marionette/test_selectioncarets.py | 8 ++--- .../test_selectioncarets_multiplerange.py | 8 ++--- .../marionette/client/marionette/__init__.py | 29 ------------------- .../driver/marionette_driver/__init__.py | 6 +++- 4 files changed, 13 insertions(+), 38 deletions(-) diff --git a/layout/base/tests/marionette/test_selectioncarets.py b/layout/base/tests/marionette/test_selectioncarets.py index 082d10712359..21248d1484d6 100644 --- a/layout/base/tests/marionette/test_selectioncarets.py +++ b/layout/base/tests/marionette/test_selectioncarets.py @@ -3,11 +3,11 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from by import By -from marionette import Actions +from marionette_driver.by import By +from marionette_driver.marionette import Actions from marionette_test import MarionetteTestCase -from selection import SelectionManager -from gestures import long_press_without_contextmenu +from marionette_driver.selection import SelectionManager +from marionette_driver.gestures import long_press_without_contextmenu class SelectionCaretsTest(MarionetteTestCase): diff --git a/layout/base/tests/marionette/test_selectioncarets_multiplerange.py b/layout/base/tests/marionette/test_selectioncarets_multiplerange.py index cc164865441a..9cfbe4652680 100644 --- a/layout/base/tests/marionette/test_selectioncarets_multiplerange.py +++ b/layout/base/tests/marionette/test_selectioncarets_multiplerange.py @@ -3,11 +3,11 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from by import By -from marionette import Actions +from marionette_driver.by import By +from marionette_driver.marionette import Actions from marionette_test import MarionetteTestCase -from selection import SelectionManager -from gestures import long_press_without_contextmenu +from marionette_driver.selection import SelectionManager +from marionette_driver.gestures import long_press_without_contextmenu class SelectionCaretsMultipleRangeTest(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/__init__.py b/testing/marionette/client/marionette/__init__.py index 9923b91cbdea..78b88f62dcce 100644 --- a/testing/marionette/client/marionette/__init__.py +++ b/testing/marionette/client/marionette/__init__.py @@ -2,33 +2,7 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from marionette_driver.gestures import smooth_scroll, pinch -from marionette_driver.by import By -from marionette_driver.marionette import Marionette, HTMLElement, Actions, MultiActions from marionette_test import MarionetteTestCase, MarionetteJSTestCase, CommonTestCase, expectedFailure, skip, SkipTest -from marionette_driver.errors import ( - ElementNotVisibleException, - ElementNotAccessibleException, - ErrorCodes, - FrameSendFailureError, - FrameSendNotInitializedError, - InvalidCookieDomainException, - InvalidElementStateException, - InvalidResponseException, - InvalidSelectorException, - JavascriptException, - MarionetteException, - MoveTargetOutOfBoundsException, - NoAlertPresentException, - NoSuchElementException, - NoSuchFrameException, - NoSuchWindowException, - ScriptTimeoutException, - StaleElementException, - TimeoutException, - UnableToSetCookieException, - XPathLookupException, -) from runner import ( B2GTestCaseMixin, B2GTestResultMixin, @@ -50,6 +24,3 @@ from runner import ( TestResult, TestResultCollection ) -from marionette_driver.wait import Wait -from marionette_driver.date_time_value import DateTimeValue -import marionette_driver.decorators diff --git a/testing/marionette/driver/marionette_driver/__init__.py b/testing/marionette/driver/marionette_driver/__init__.py index 0c82dcdad253..23395d320d03 100644 --- a/testing/marionette/driver/marionette_driver/__init__.py +++ b/testing/marionette/driver/marionette_driver/__init__.py @@ -1,4 +1,8 @@ from marionette_driver import ( errors, by, decorators, expected, geckoinstance, gestures, keys, marionette, selection, wait, application_cache, date_time_value ) -from marionette_driver.gestures import smooth_scroll, pinch \ No newline at end of file +from marionette_driver.by import By +from marionette_driver.date_time_value import DateTimeValue +from marionette_driver.gestures import smooth_scroll, pinch +from marionette_driver.wait import Wait + From 07a8a918eccb025c8dcd3789b959b9ba41e36382 Mon Sep 17 00:00:00 2001 From: David Burns Date: Fri, 16 Jan 2015 15:13:26 +0000 Subject: [PATCH 24/62] Bug 1107336: Update imports for loop tests; r=jgriffin --HG-- extra : rebase_source : 5bcb1d7f8585033618197eed259688e034361d75 --- .../test/functional/test_1_browser_call.py | 11 ++-- .../marionette/tests/unit/test_navigation.py | 16 +++++ .../tests/unit/test_window_handles.py | 66 ++++++++++++++++++- 3 files changed, 87 insertions(+), 6 deletions(-) diff --git a/browser/components/loop/test/functional/test_1_browser_call.py b/browser/components/loop/test/functional/test_1_browser_call.py index 078dbdfbbf1f..4a2778d01a7e 100644 --- a/browser/components/loop/test/functional/test_1_browser_call.py +++ b/browser/components/loop/test/functional/test_1_browser_call.py @@ -1,13 +1,14 @@ from marionette_test import MarionetteTestCase -from by import By -import urlparse -from errors import NoSuchElementException, StaleElementException + +from marionette_driver.by import By +from marionette_driver.errors import NoSuchElementException, StaleElementException # noinspection PyUnresolvedReferences -from wait import Wait -from time import sleep +from marionette_driver.wait import Wait import os import sys +import urlparse +from time import sleep sys.path.insert(1, os.path.dirname(os.path.abspath(__file__))) from serversetup import LoopTestServers diff --git a/testing/marionette/client/marionette/tests/unit/test_navigation.py b/testing/marionette/client/marionette/tests/unit/test_navigation.py index fb574ffda44e..e20733c4e7be 100644 --- a/testing/marionette/client/marionette/tests/unit/test_navigation.py +++ b/testing/marionette/client/marionette/tests/unit/test_navigation.py @@ -2,11 +2,14 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. +from marionette_test import MarionetteTestCase, skip_if_b2g, skip_if_e10s +from marionette_driver.errors import MarionetteException, TimeoutException class TestNavigate(MarionetteTestCase): def test_navigate(self): self.assertTrue(self.marionette.execute_script("window.location.href = 'about:blank'; return true;")) self.assertEqual("about:blank", self.marionette.execute_script("return window.location.href;")) + test_html = self.marionette.absolute_url("test.html") self.marionette.navigate(test_html) self.assertNotEqual("about:blank", self.marionette.execute_script("return window.location.href;")) self.assertEqual("Marionette Test", self.marionette.title) @@ -74,6 +77,7 @@ class TestNavigate(MarionetteTestCase): self.assertTrue('test_iframe.html' in self.marionette.get_url()) ''' + @skip_if_e10s # Interactions with about: pages need e10s support (bug 1096488). def test_shouldnt_error_if_nonexistent_url_used(self): try: self.marionette.navigate("thisprotocoldoesnotexist://") @@ -81,8 +85,20 @@ class TestNavigate(MarionetteTestCase): except TimeoutException: self.fail("The socket shouldn't have timed out when navigating to a non-existent URL") except MarionetteException as e: + self.assertIn("Error loading page", str(e)) + except Exception as inst: + import traceback + print traceback.format_exc() + self.fail("Should have thrown a MarionetteException instead of %s" % type(inst)) + @skip_if_e10s # Interactions with about: pages need e10s support (bug 1096488). + @skip_if_b2g # about:blocked isn't a well formed uri on b2g + def test_should_navigate_to_requested_about_page(self): + self.marionette.navigate("about:neterror") + self.assertEqual(self.marionette.get_url(), "about:neterror") + self.marionette.navigate(self.marionette.absolute_url("test.html")) self.marionette.navigate("about:blocked") + self.assertEqual(self.marionette.get_url(), "about:blocked") def test_find_element_state_complete(self): test_html = self.marionette.absolute_url("test.html") diff --git a/testing/marionette/client/marionette/tests/unit/test_window_handles.py b/testing/marionette/client/marionette/tests/unit/test_window_handles.py index bb090af95f7f..e3e192c44ec1 100644 --- a/testing/marionette/client/marionette/tests/unit/test_window_handles.py +++ b/testing/marionette/client/marionette/tests/unit/test_window_handles.py @@ -2,10 +2,13 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from marionette import Keys +from marionette_test import MarionetteTestCase, skip_if_e10s +from marionette_driver.keys import Keys +class TestWindowHandles(MarionetteTestCase): + @skip_if_e10s # Interactions with about: pages need e10s support (bug 1096488). def test_new_tab_window_handles(self): keys = [Keys.SHIFT] if self.marionette.session_capabilities['platformName'] == 'DARWIN': @@ -89,5 +92,66 @@ from marionette import Keys self.assertEqual(len(self.marionette.window_handles), 1) self.marionette.switch_to_window(start_tab) + # This sequence triggers an exception in Marionette:register with e10s on (bug 1120809). + @skip_if_e10s def test_tab_and_window_handles(self): + start_tab = self.marionette.current_window_handle + start_chrome_window = self.marionette.current_chrome_window_handle + tab_open_page = self.marionette.absolute_url("windowHandles.html") + window_open_page = self.marionette.absolute_url("test_windows.html") + # Open a new tab and switch to it. + self.marionette.navigate(tab_open_page) + link = self.marionette.find_element("id", "new-tab") + link.click() + + self.wait_for_condition(lambda mn: len(mn.window_handles) == 2) + self.assertEqual(len(self.marionette.chrome_window_handles), 1) + self.assertEqual(self.marionette.current_chrome_window_handle, start_chrome_window) + + handles = self.marionette.window_handles + handles.remove(start_tab) + + new_tab = handles.pop() + self.marionette.switch_to_window(new_tab) + self.assertEqual(self.marionette.get_url(), "about:blank") + + # Open a new window from the new tab. + self.marionette.navigate(window_open_page) + + link = self.marionette.find_element("link text", "Open new window") + link.click() + self.wait_for_condition(lambda mn: len(mn.window_handles) == 3) + + self.assertEqual(len(self.marionette.chrome_window_handles), 2) + self.assertEqual(self.marionette.current_chrome_window_handle, start_chrome_window) + + # Find the new window and switch to it. + handles = self.marionette.window_handles + handles.remove(start_tab) + handles.remove(new_tab) + new_window = handles.pop() + + self.marionette.switch_to_window(new_window) + results_page = self.marionette.absolute_url("resultPage.html") + self.assertEqual(self.marionette.get_url(), results_page) + + self.assertEqual(len(self.marionette.chrome_window_handles), 2) + self.assertNotEqual(self.marionette.current_chrome_window_handle, start_chrome_window) + + # Return to our original tab and close it. + self.marionette.switch_to_window(start_tab) + self.marionette.close() + self.assertEquals(len(self.marionette.window_handles), 2) + + # Close the opened window and carry on in our new tab. + self.marionette.switch_to_window(new_window) + self.marionette.close() + self.assertEqual(len(self.marionette.window_handles), 1) + + self.marionette.switch_to_window(new_tab) + self.assertEqual(self.marionette.get_url(), results_page) + self.marionette.navigate("about:blank") + + self.assertEqual(len(self.marionette.chrome_window_handles), 1) + self.assertEqual(self.marionette.current_chrome_window_handle, start_chrome_window) From 28f424d90b92dbfd84608bd8227e83d089da3243 Mon Sep 17 00:00:00 2001 From: David Burns Date: Wed, 21 Jan 2015 00:32:24 +0000 Subject: [PATCH 25/62] Bug 1107336: update Marionette-Client dependencies to include marionette driver; r=jgriffin --HG-- extra : rebase_source : 36c159f68debeae4f442035233a90919b06d43b1 --- testing/marionette/client/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/testing/marionette/client/requirements.txt b/testing/marionette/client/requirements.txt index 6cfc18169db3..fa552232a473 100644 --- a/testing/marionette/client/requirements.txt +++ b/testing/marionette/client/requirements.txt @@ -1,4 +1,5 @@ marionette-transport == 0.4 +marionette-driver == 0.1 manifestparser mozhttpd >= 0.5 mozinfo >= 0.7 From 4d8dc1898a2cd7e1d2c0a3d7b22205f2737fe519 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Wed, 21 Jan 2015 09:16:38 -0500 Subject: [PATCH 26/62] Bug 1116586 - Fix hit region for items with rounded corners. r=tn --- layout/base/FrameLayerBuilder.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/layout/base/FrameLayerBuilder.cpp b/layout/base/FrameLayerBuilder.cpp index eccbbd03387b..b1ed38498adf 100644 --- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -2343,11 +2343,14 @@ ContainerState::PopPaintedLayerData() EventRegions regions; regions.mHitRegion = ScaleRegionToOutsidePixels(data->mHitRegion); // Points whose hit-region status we're not sure about need to be dispatched - // to the content thread. + // to the content thread. If a point is in both maybeHitRegion and hitRegion + // then it's not a "maybe" any more, and doesn't go into the dispatch-to- + // content region. nsIntRegion maybeHitRegion = ScaleRegionToOutsidePixels(data->mMaybeHitRegion); regions.mDispatchToContentHitRegion.Sub(maybeHitRegion, regions.mHitRegion); - regions.mDispatchToContentHitRegion.Or(regions.mDispatchToContentHitRegion, - ScaleRegionToOutsidePixels(data->mDispatchToContentHitRegion)); + regions.mDispatchToContentHitRegion.OrWith( + ScaleRegionToOutsidePixels(data->mDispatchToContentHitRegion)); + regions.mHitRegion.OrWith(maybeHitRegion); nsIntPoint translation = -GetTranslationForPaintedLayer(data->mLayer); regions.mHitRegion.MoveBy(translation); From 87ad8029de5a88804534b873114389071f0b02d7 Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Wed, 21 Jan 2015 16:10:27 +0100 Subject: [PATCH 27/62] Backed out changeset 4ac07f1f2998 (bug 1107336) --- testing/marionette/client/requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/testing/marionette/client/requirements.txt b/testing/marionette/client/requirements.txt index fa552232a473..6cfc18169db3 100644 --- a/testing/marionette/client/requirements.txt +++ b/testing/marionette/client/requirements.txt @@ -1,5 +1,4 @@ marionette-transport == 0.4 -marionette-driver == 0.1 manifestparser mozhttpd >= 0.5 mozinfo >= 0.7 From 7137cb17aab9082b7b56e0d10e482c55f12dc563 Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Wed, 21 Jan 2015 16:10:44 +0100 Subject: [PATCH 28/62] Backed out changeset 3c4e0437ace5 (bug 1107336) --- .../test/functional/test_1_browser_call.py | 11 ++-- .../marionette/tests/unit/test_navigation.py | 16 ----- .../tests/unit/test_window_handles.py | 66 +------------------ 3 files changed, 6 insertions(+), 87 deletions(-) diff --git a/browser/components/loop/test/functional/test_1_browser_call.py b/browser/components/loop/test/functional/test_1_browser_call.py index 4a2778d01a7e..078dbdfbbf1f 100644 --- a/browser/components/loop/test/functional/test_1_browser_call.py +++ b/browser/components/loop/test/functional/test_1_browser_call.py @@ -1,14 +1,13 @@ from marionette_test import MarionetteTestCase - -from marionette_driver.by import By -from marionette_driver.errors import NoSuchElementException, StaleElementException +from by import By +import urlparse +from errors import NoSuchElementException, StaleElementException # noinspection PyUnresolvedReferences -from marionette_driver.wait import Wait +from wait import Wait +from time import sleep import os import sys -import urlparse -from time import sleep sys.path.insert(1, os.path.dirname(os.path.abspath(__file__))) from serversetup import LoopTestServers diff --git a/testing/marionette/client/marionette/tests/unit/test_navigation.py b/testing/marionette/client/marionette/tests/unit/test_navigation.py index e20733c4e7be..fb574ffda44e 100644 --- a/testing/marionette/client/marionette/tests/unit/test_navigation.py +++ b/testing/marionette/client/marionette/tests/unit/test_navigation.py @@ -2,14 +2,11 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from marionette_test import MarionetteTestCase, skip_if_b2g, skip_if_e10s -from marionette_driver.errors import MarionetteException, TimeoutException class TestNavigate(MarionetteTestCase): def test_navigate(self): self.assertTrue(self.marionette.execute_script("window.location.href = 'about:blank'; return true;")) self.assertEqual("about:blank", self.marionette.execute_script("return window.location.href;")) - test_html = self.marionette.absolute_url("test.html") self.marionette.navigate(test_html) self.assertNotEqual("about:blank", self.marionette.execute_script("return window.location.href;")) self.assertEqual("Marionette Test", self.marionette.title) @@ -77,7 +74,6 @@ class TestNavigate(MarionetteTestCase): self.assertTrue('test_iframe.html' in self.marionette.get_url()) ''' - @skip_if_e10s # Interactions with about: pages need e10s support (bug 1096488). def test_shouldnt_error_if_nonexistent_url_used(self): try: self.marionette.navigate("thisprotocoldoesnotexist://") @@ -85,20 +81,8 @@ class TestNavigate(MarionetteTestCase): except TimeoutException: self.fail("The socket shouldn't have timed out when navigating to a non-existent URL") except MarionetteException as e: - self.assertIn("Error loading page", str(e)) - except Exception as inst: - import traceback - print traceback.format_exc() - self.fail("Should have thrown a MarionetteException instead of %s" % type(inst)) - @skip_if_e10s # Interactions with about: pages need e10s support (bug 1096488). - @skip_if_b2g # about:blocked isn't a well formed uri on b2g - def test_should_navigate_to_requested_about_page(self): - self.marionette.navigate("about:neterror") - self.assertEqual(self.marionette.get_url(), "about:neterror") - self.marionette.navigate(self.marionette.absolute_url("test.html")) self.marionette.navigate("about:blocked") - self.assertEqual(self.marionette.get_url(), "about:blocked") def test_find_element_state_complete(self): test_html = self.marionette.absolute_url("test.html") diff --git a/testing/marionette/client/marionette/tests/unit/test_window_handles.py b/testing/marionette/client/marionette/tests/unit/test_window_handles.py index e3e192c44ec1..bb090af95f7f 100644 --- a/testing/marionette/client/marionette/tests/unit/test_window_handles.py +++ b/testing/marionette/client/marionette/tests/unit/test_window_handles.py @@ -2,13 +2,10 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from marionette_test import MarionetteTestCase, skip_if_e10s -from marionette_driver.keys import Keys +from marionette import Keys -class TestWindowHandles(MarionetteTestCase): - @skip_if_e10s # Interactions with about: pages need e10s support (bug 1096488). def test_new_tab_window_handles(self): keys = [Keys.SHIFT] if self.marionette.session_capabilities['platformName'] == 'DARWIN': @@ -92,66 +89,5 @@ class TestWindowHandles(MarionetteTestCase): self.assertEqual(len(self.marionette.window_handles), 1) self.marionette.switch_to_window(start_tab) - # This sequence triggers an exception in Marionette:register with e10s on (bug 1120809). - @skip_if_e10s def test_tab_and_window_handles(self): - start_tab = self.marionette.current_window_handle - start_chrome_window = self.marionette.current_chrome_window_handle - tab_open_page = self.marionette.absolute_url("windowHandles.html") - window_open_page = self.marionette.absolute_url("test_windows.html") - # Open a new tab and switch to it. - self.marionette.navigate(tab_open_page) - link = self.marionette.find_element("id", "new-tab") - link.click() - - self.wait_for_condition(lambda mn: len(mn.window_handles) == 2) - self.assertEqual(len(self.marionette.chrome_window_handles), 1) - self.assertEqual(self.marionette.current_chrome_window_handle, start_chrome_window) - - handles = self.marionette.window_handles - handles.remove(start_tab) - - new_tab = handles.pop() - self.marionette.switch_to_window(new_tab) - self.assertEqual(self.marionette.get_url(), "about:blank") - - # Open a new window from the new tab. - self.marionette.navigate(window_open_page) - - link = self.marionette.find_element("link text", "Open new window") - link.click() - self.wait_for_condition(lambda mn: len(mn.window_handles) == 3) - - self.assertEqual(len(self.marionette.chrome_window_handles), 2) - self.assertEqual(self.marionette.current_chrome_window_handle, start_chrome_window) - - # Find the new window and switch to it. - handles = self.marionette.window_handles - handles.remove(start_tab) - handles.remove(new_tab) - new_window = handles.pop() - - self.marionette.switch_to_window(new_window) - results_page = self.marionette.absolute_url("resultPage.html") - self.assertEqual(self.marionette.get_url(), results_page) - - self.assertEqual(len(self.marionette.chrome_window_handles), 2) - self.assertNotEqual(self.marionette.current_chrome_window_handle, start_chrome_window) - - # Return to our original tab and close it. - self.marionette.switch_to_window(start_tab) - self.marionette.close() - self.assertEquals(len(self.marionette.window_handles), 2) - - # Close the opened window and carry on in our new tab. - self.marionette.switch_to_window(new_window) - self.marionette.close() - self.assertEqual(len(self.marionette.window_handles), 1) - - self.marionette.switch_to_window(new_tab) - self.assertEqual(self.marionette.get_url(), results_page) - self.marionette.navigate("about:blank") - - self.assertEqual(len(self.marionette.chrome_window_handles), 1) - self.assertEqual(self.marionette.current_chrome_window_handle, start_chrome_window) From b038666e4a041875938c66201f57bdc313fdc31c Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Wed, 21 Jan 2015 16:10:57 +0100 Subject: [PATCH 29/62] Backed out changeset 5a2e085824ae (bug 1107336) --- .../tests/marionette/test_selectioncarets.py | 8 ++--- .../test_selectioncarets_multiplerange.py | 8 ++--- .../marionette/client/marionette/__init__.py | 29 +++++++++++++++++++ .../driver/marionette_driver/__init__.py | 6 +--- 4 files changed, 38 insertions(+), 13 deletions(-) diff --git a/layout/base/tests/marionette/test_selectioncarets.py b/layout/base/tests/marionette/test_selectioncarets.py index 21248d1484d6..082d10712359 100644 --- a/layout/base/tests/marionette/test_selectioncarets.py +++ b/layout/base/tests/marionette/test_selectioncarets.py @@ -3,11 +3,11 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from marionette_driver.by import By -from marionette_driver.marionette import Actions +from by import By +from marionette import Actions from marionette_test import MarionetteTestCase -from marionette_driver.selection import SelectionManager -from marionette_driver.gestures import long_press_without_contextmenu +from selection import SelectionManager +from gestures import long_press_without_contextmenu class SelectionCaretsTest(MarionetteTestCase): diff --git a/layout/base/tests/marionette/test_selectioncarets_multiplerange.py b/layout/base/tests/marionette/test_selectioncarets_multiplerange.py index 9cfbe4652680..cc164865441a 100644 --- a/layout/base/tests/marionette/test_selectioncarets_multiplerange.py +++ b/layout/base/tests/marionette/test_selectioncarets_multiplerange.py @@ -3,11 +3,11 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from marionette_driver.by import By -from marionette_driver.marionette import Actions +from by import By +from marionette import Actions from marionette_test import MarionetteTestCase -from marionette_driver.selection import SelectionManager -from marionette_driver.gestures import long_press_without_contextmenu +from selection import SelectionManager +from gestures import long_press_without_contextmenu class SelectionCaretsMultipleRangeTest(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/__init__.py b/testing/marionette/client/marionette/__init__.py index 78b88f62dcce..9923b91cbdea 100644 --- a/testing/marionette/client/marionette/__init__.py +++ b/testing/marionette/client/marionette/__init__.py @@ -2,7 +2,33 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. +from marionette_driver.gestures import smooth_scroll, pinch +from marionette_driver.by import By +from marionette_driver.marionette import Marionette, HTMLElement, Actions, MultiActions from marionette_test import MarionetteTestCase, MarionetteJSTestCase, CommonTestCase, expectedFailure, skip, SkipTest +from marionette_driver.errors import ( + ElementNotVisibleException, + ElementNotAccessibleException, + ErrorCodes, + FrameSendFailureError, + FrameSendNotInitializedError, + InvalidCookieDomainException, + InvalidElementStateException, + InvalidResponseException, + InvalidSelectorException, + JavascriptException, + MarionetteException, + MoveTargetOutOfBoundsException, + NoAlertPresentException, + NoSuchElementException, + NoSuchFrameException, + NoSuchWindowException, + ScriptTimeoutException, + StaleElementException, + TimeoutException, + UnableToSetCookieException, + XPathLookupException, +) from runner import ( B2GTestCaseMixin, B2GTestResultMixin, @@ -24,3 +50,6 @@ from runner import ( TestResult, TestResultCollection ) +from marionette_driver.wait import Wait +from marionette_driver.date_time_value import DateTimeValue +import marionette_driver.decorators diff --git a/testing/marionette/driver/marionette_driver/__init__.py b/testing/marionette/driver/marionette_driver/__init__.py index 23395d320d03..0c82dcdad253 100644 --- a/testing/marionette/driver/marionette_driver/__init__.py +++ b/testing/marionette/driver/marionette_driver/__init__.py @@ -1,8 +1,4 @@ from marionette_driver import ( errors, by, decorators, expected, geckoinstance, gestures, keys, marionette, selection, wait, application_cache, date_time_value ) -from marionette_driver.by import By -from marionette_driver.date_time_value import DateTimeValue -from marionette_driver.gestures import smooth_scroll, pinch -from marionette_driver.wait import Wait - +from marionette_driver.gestures import smooth_scroll, pinch \ No newline at end of file From 9b7a278cf8ce53e7f92ddffe333caf93a4549e1f Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Wed, 21 Jan 2015 16:11:13 +0100 Subject: [PATCH 30/62] Backed out changeset 9aec81381396 (bug 1107336) --- browser/components/loop/test/shared/frontend_tester.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/components/loop/test/shared/frontend_tester.py b/browser/components/loop/test/shared/frontend_tester.py index d5364853a173..7835fae0b9d4 100644 --- a/browser/components/loop/test/shared/frontend_tester.py +++ b/browser/components/loop/test/shared/frontend_tester.py @@ -1,5 +1,5 @@ from marionette_test import MarionetteTestCase -from marionette_driver.errors import NoSuchElementException +from errors import NoSuchElementException import threading import SimpleHTTPServer import SocketServer From 8baf30102c6b12aa15cace3604e184a6c9f70274 Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Wed, 21 Jan 2015 16:11:28 +0100 Subject: [PATCH 31/62] Backed out changeset 6aca01a96d37 (bug 1107336) --- .../marionette/client/marionette/__init__.py | 14 ++--- .../tests/unit/test_accessibility.py | 4 +- .../marionette/tests/unit/test_marionette.py | 2 +- .../tests/unit/test_window_handles.py | 62 +++++++++++++++++++ 4 files changed, 72 insertions(+), 10 deletions(-) diff --git a/testing/marionette/client/marionette/__init__.py b/testing/marionette/client/marionette/__init__.py index 9923b91cbdea..67a263367d59 100644 --- a/testing/marionette/client/marionette/__init__.py +++ b/testing/marionette/client/marionette/__init__.py @@ -2,11 +2,11 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from marionette_driver.gestures import smooth_scroll, pinch -from marionette_driver.by import By -from marionette_driver.marionette import Marionette, HTMLElement, Actions, MultiActions +from gestures import smooth_scroll, pinch +from by import By +from marionette import Marionette, HTMLElement, Actions, MultiActions from marionette_test import MarionetteTestCase, MarionetteJSTestCase, CommonTestCase, expectedFailure, skip, SkipTest -from marionette_driver.errors import ( +from errors import ( ElementNotVisibleException, ElementNotAccessibleException, ErrorCodes, @@ -50,6 +50,6 @@ from runner import ( TestResult, TestResultCollection ) -from marionette_driver.wait import Wait -from marionette_driver.date_time_value import DateTimeValue -import marionette_driver.decorators +from wait import Wait +from date_time_value import DateTimeValue +import decorators diff --git a/testing/marionette/client/marionette/tests/unit/test_accessibility.py b/testing/marionette/client/marionette/tests/unit/test_accessibility.py index d0a63f855dbc..ee3ca9e6f1f9 100644 --- a/testing/marionette/client/marionette/tests/unit/test_accessibility.py +++ b/testing/marionette/client/marionette/tests/unit/test_accessibility.py @@ -3,8 +3,8 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from marionette_driver.errors import (ElementNotAccessibleException, - ElementNotVisibleException) +from errors import ElementNotAccessibleException +from errors import ElementNotVisibleException class TestAccessibility(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_marionette.py b/testing/marionette/client/marionette/tests/unit/test_marionette.py index d25a800683a7..4e9fd4f7e4da 100644 --- a/testing/marionette/client/marionette/tests/unit/test_marionette.py +++ b/testing/marionette/client/marionette/tests/unit/test_marionette.py @@ -2,7 +2,7 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from marionette_driver import errors +import errors import marionette_test diff --git a/testing/marionette/client/marionette/tests/unit/test_window_handles.py b/testing/marionette/client/marionette/tests/unit/test_window_handles.py index bb090af95f7f..080d6e9e965a 100644 --- a/testing/marionette/client/marionette/tests/unit/test_window_handles.py +++ b/testing/marionette/client/marionette/tests/unit/test_window_handles.py @@ -2,10 +2,13 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. +from marionette_test import MarionetteTestCase, skip_if_e10s from marionette import Keys +class TestWindowHandles(MarionetteTestCase): + @skip_if_e10s # Interactions with about: pages need e10s support (bug 1096488). def test_new_tab_window_handles(self): keys = [Keys.SHIFT] if self.marionette.session_capabilities['platformName'] == 'DARWIN': @@ -90,4 +93,63 @@ from marionette import Keys self.marionette.switch_to_window(start_tab) def test_tab_and_window_handles(self): + start_tab = self.marionette.current_window_handle + start_chrome_window = self.marionette.current_chrome_window_handle + tab_open_page = self.marionette.absolute_url("windowHandles.html") + window_open_page = self.marionette.absolute_url("test_windows.html") + # Open a new tab and switch to it. + self.marionette.navigate(tab_open_page) + link = self.marionette.find_element("id", "new-tab") + link.click() + + self.wait_for_condition(lambda mn: len(mn.window_handles) == 2) + self.assertEqual(len(self.marionette.chrome_window_handles), 1) + self.assertEqual(self.marionette.current_chrome_window_handle, start_chrome_window) + + handles = self.marionette.window_handles + handles.remove(start_tab) + + new_tab = handles.pop() + self.marionette.switch_to_window(new_tab) + self.assertEqual(self.marionette.get_url(), "about:blank") + + # Open a new window from the new tab. + self.marionette.navigate(window_open_page) + + link = self.marionette.find_element("link text", "Open new window") + link.click() + self.wait_for_condition(lambda mn: len(mn.window_handles) == 3) + + self.assertEqual(len(self.marionette.chrome_window_handles), 2) + self.assertEqual(self.marionette.current_chrome_window_handle, start_chrome_window) + + # Find the new window and switch to it. + handles = self.marionette.window_handles + handles.remove(start_tab) + handles.remove(new_tab) + new_window = handles.pop() + + self.marionette.switch_to_window(new_window) + results_page = self.marionette.absolute_url("resultPage.html") + self.assertEqual(self.marionette.get_url(), results_page) + + self.assertEqual(len(self.marionette.chrome_window_handles), 2) + self.assertNotEqual(self.marionette.current_chrome_window_handle, start_chrome_window) + + # Return to our original tab and close it. + self.marionette.switch_to_window(start_tab) + self.marionette.close() + self.assertEquals(len(self.marionette.window_handles), 2) + + # Close the opened window and carry on in our new tab. + self.marionette.switch_to_window(new_window) + self.marionette.close() + self.assertEqual(len(self.marionette.window_handles), 1) + + self.marionette.switch_to_window(new_tab) + self.assertEqual(self.marionette.get_url(), results_page) + self.marionette.navigate("about:blank") + + self.assertEqual(len(self.marionette.chrome_window_handles), 1) + self.assertEqual(self.marionette.current_chrome_window_handle, start_chrome_window) From 15cd83bcf5ab9b7fc2308823cf906979a84ae247 Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Wed, 21 Jan 2015 16:11:42 +0100 Subject: [PATCH 32/62] Backed out changeset 805dce7ae79f (bug 1107336) --- testing/marionette/client/marionette/b2g_update_test.py | 4 ++-- .../client/marionette/tests/unit/test_element_touch.py | 2 +- .../marionette/client/marionette/tests/unit/test_emulator.py | 3 +-- .../client/marionette/tests/unit/test_switch_frame_chrome.py | 4 ++-- testing/marionette/driver/marionette_driver/__init__.py | 3 +-- 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/testing/marionette/client/marionette/b2g_update_test.py b/testing/marionette/client/marionette/b2g_update_test.py index 5c832922e469..ea1c4d2b04e7 100644 --- a/testing/marionette/client/marionette/b2g_update_test.py +++ b/testing/marionette/client/marionette/b2g_update_test.py @@ -12,8 +12,8 @@ import types import weakref from b2ginstance import B2GInstance -from marionette_driver.errors import InvalidResponseException -from marionette_driver.marionette import Marionette +from errors import InvalidResponseException +from marionette import Marionette from marionette_test import MarionetteTestCase from marionette_transport import MarionetteTransport from runtests import MarionetteTestRunner, cli diff --git a/testing/marionette/client/marionette/tests/unit/test_element_touch.py b/testing/marionette/client/marionette/tests/unit/test_element_touch.py index 539782ace7e1..7b9f047a9576 100644 --- a/testing/marionette/client/marionette/tests/unit/test_element_touch.py +++ b/testing/marionette/client/marionette/tests/unit/test_element_touch.py @@ -3,7 +3,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from marionette_driver.errors import MarionetteException +from errors import MarionetteException class testElementTouch(MarionetteTestCase): def test_touch(self): diff --git a/testing/marionette/client/marionette/tests/unit/test_emulator.py b/testing/marionette/client/marionette/tests/unit/test_emulator.py index e69d996d27b0..f330d983dba7 100644 --- a/testing/marionette/client/marionette/tests/unit/test_emulator.py +++ b/testing/marionette/client/marionette/tests/unit/test_emulator.py @@ -3,8 +3,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from marionette_driver.errors import (JavascriptException, - MarionetteException) +from errors import JavascriptException, MarionetteException class TestEmulatorContent(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_switch_frame_chrome.py b/testing/marionette/client/marionette/tests/unit/test_switch_frame_chrome.py index 992007d1c208..5e476231ef83 100644 --- a/testing/marionette/client/marionette/tests/unit/test_switch_frame_chrome.py +++ b/testing/marionette/client/marionette/tests/unit/test_switch_frame_chrome.py @@ -3,8 +3,8 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from marionette_driver.errors import JavascriptException -from marionette_driver.by import By +from errors import JavascriptException +from by import By class TestSwitchFrameChrome(MarionetteTestCase): def setUp(self): diff --git a/testing/marionette/driver/marionette_driver/__init__.py b/testing/marionette/driver/marionette_driver/__init__.py index 0c82dcdad253..aff2e13acace 100644 --- a/testing/marionette/driver/marionette_driver/__init__.py +++ b/testing/marionette/driver/marionette_driver/__init__.py @@ -1,4 +1,3 @@ from marionette_driver import ( errors, by, decorators, expected, geckoinstance, gestures, keys, marionette, selection, wait, - application_cache, date_time_value ) -from marionette_driver.gestures import smooth_scroll, pinch \ No newline at end of file + application_cache, date_time_value ) \ No newline at end of file From a34e998db6de6c73c63dbe848c59e7d7c1e88e48 Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Wed, 21 Jan 2015 16:11:55 +0100 Subject: [PATCH 33/62] Backed out changeset 3c3d31607785 (bug 1107336) --- testing/testsuite-targets.mk | 2 -- 1 file changed, 2 deletions(-) diff --git a/testing/testsuite-targets.mk b/testing/testsuite-targets.mk index 14d93e3d59c4..3793c3d7595a 100644 --- a/testing/testsuite-targets.mk +++ b/testing/testsuite-targets.mk @@ -536,10 +536,8 @@ MARIONETTE_DIR=$(PKG_STAGE)/marionette stage-marionette: make-stage-dir $(NSINSTALL) -D $(MARIONETTE_DIR)/tests $(NSINSTALL) -D $(MARIONETTE_DIR)/transport - $(NSINSTALL) -D $(MARIONETTE_DIR)/driver @(cd $(topsrcdir)/testing/marionette/client && tar --exclude marionette/tests $(TAR_CREATE_FLAGS) - *) | (cd $(MARIONETTE_DIR)/ && tar -xf -) @(cd $(topsrcdir)/testing/marionette/transport && tar $(TAR_CREATE_FLAGS) - *) | (cd $(MARIONETTE_DIR)/transport && tar -xf -) - @(cd $(topsrcdir)/testing/marionette/driver && tar $(TAR_CREATE_FLAGS) - *) | (cd $(MARIONETTE_DIR)/driver && tar -xf -) $(PYTHON) $(topsrcdir)/testing/marionette/client/marionette/tests/print-manifest-dirs.py \ $(topsrcdir) \ $(topsrcdir)/testing/marionette/client/marionette/tests/unit-tests.ini \ From 6ac5c09770cc010298eb30ae4ec2be0e440e8480 Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Wed, 21 Jan 2015 16:12:13 +0100 Subject: [PATCH 34/62] Backed out changeset c886cd910936 (bug 1107336) --HG-- rename : testing/marionette/driver/marionette_driver/application_cache.py => testing/marionette/client/marionette/application_cache.py rename : testing/marionette/driver/marionette_driver/by.py => testing/marionette/client/marionette/by.py rename : testing/marionette/driver/marionette_driver/date_time_value.py => testing/marionette/client/marionette/date_time_value.py rename : testing/marionette/driver/marionette_driver/decorators.py => testing/marionette/client/marionette/decorators.py rename : testing/marionette/driver/marionette_driver/errors.py => testing/marionette/client/marionette/errors.py rename : testing/marionette/driver/marionette_driver/expected.py => testing/marionette/client/marionette/expected.py rename : testing/marionette/driver/marionette_driver/geckoinstance.py => testing/marionette/client/marionette/geckoinstance.py rename : testing/marionette/driver/marionette_driver/gestures.py => testing/marionette/client/marionette/gestures.py rename : testing/marionette/driver/marionette_driver/keys.py => testing/marionette/client/marionette/keys.py rename : testing/marionette/driver/marionette_driver/marionette.py => testing/marionette/client/marionette/marionette.py rename : testing/marionette/driver/marionette_driver/selection.py => testing/marionette/client/marionette/selection.py rename : testing/marionette/driver/marionette_driver/wait.py => testing/marionette/client/marionette/wait.py --- testing/config/marionette_requirements.txt | 1 - .../marionette}/application_cache.py | 0 .../marionette}/by.py | 0 .../marionette}/date_time_value.py | 0 .../marionette}/decorators.py | 0 .../marionette}/errors.py | 0 .../marionette}/expected.py | 0 .../marionette}/geckoinstance.py | 0 .../marionette}/gestures.py | 0 .../marionette}/keys.py | 0 .../marionette}/marionette.py | 0 .../client/marionette/marionette_test.py | 9 +++---- .../client/marionette/runner/base.py | 2 +- .../marionette}/selection.py | 0 .../marionette}/wait.py | 0 .../driver/marionette_driver/__init__.py | 3 --- testing/marionette/driver/requirements.txt | 1 - testing/marionette/driver/setup.py | 27 ------------------- 18 files changed, 5 insertions(+), 38 deletions(-) rename testing/marionette/{driver/marionette_driver => client/marionette}/application_cache.py (100%) rename testing/marionette/{driver/marionette_driver => client/marionette}/by.py (100%) rename testing/marionette/{driver/marionette_driver => client/marionette}/date_time_value.py (100%) rename testing/marionette/{driver/marionette_driver => client/marionette}/decorators.py (100%) rename testing/marionette/{driver/marionette_driver => client/marionette}/errors.py (100%) rename testing/marionette/{driver/marionette_driver => client/marionette}/expected.py (100%) rename testing/marionette/{driver/marionette_driver => client/marionette}/geckoinstance.py (100%) rename testing/marionette/{driver/marionette_driver => client/marionette}/gestures.py (100%) rename testing/marionette/{driver/marionette_driver => client/marionette}/keys.py (100%) rename testing/marionette/{driver/marionette_driver => client/marionette}/marionette.py (100%) rename testing/marionette/{driver/marionette_driver => client/marionette}/selection.py (100%) rename testing/marionette/{driver/marionette_driver => client/marionette}/wait.py (100%) delete mode 100644 testing/marionette/driver/marionette_driver/__init__.py delete mode 100644 testing/marionette/driver/requirements.txt delete mode 100644 testing/marionette/driver/setup.py diff --git a/testing/config/marionette_requirements.txt b/testing/config/marionette_requirements.txt index ab683343728d..186360841e52 100644 --- a/testing/config/marionette_requirements.txt +++ b/testing/config/marionette_requirements.txt @@ -1,4 +1,3 @@ -r mozbase_requirements.txt ../marionette/transport -../marionette/driver ../marionette diff --git a/testing/marionette/driver/marionette_driver/application_cache.py b/testing/marionette/client/marionette/application_cache.py similarity index 100% rename from testing/marionette/driver/marionette_driver/application_cache.py rename to testing/marionette/client/marionette/application_cache.py diff --git a/testing/marionette/driver/marionette_driver/by.py b/testing/marionette/client/marionette/by.py similarity index 100% rename from testing/marionette/driver/marionette_driver/by.py rename to testing/marionette/client/marionette/by.py diff --git a/testing/marionette/driver/marionette_driver/date_time_value.py b/testing/marionette/client/marionette/date_time_value.py similarity index 100% rename from testing/marionette/driver/marionette_driver/date_time_value.py rename to testing/marionette/client/marionette/date_time_value.py diff --git a/testing/marionette/driver/marionette_driver/decorators.py b/testing/marionette/client/marionette/decorators.py similarity index 100% rename from testing/marionette/driver/marionette_driver/decorators.py rename to testing/marionette/client/marionette/decorators.py diff --git a/testing/marionette/driver/marionette_driver/errors.py b/testing/marionette/client/marionette/errors.py similarity index 100% rename from testing/marionette/driver/marionette_driver/errors.py rename to testing/marionette/client/marionette/errors.py diff --git a/testing/marionette/driver/marionette_driver/expected.py b/testing/marionette/client/marionette/expected.py similarity index 100% rename from testing/marionette/driver/marionette_driver/expected.py rename to testing/marionette/client/marionette/expected.py diff --git a/testing/marionette/driver/marionette_driver/geckoinstance.py b/testing/marionette/client/marionette/geckoinstance.py similarity index 100% rename from testing/marionette/driver/marionette_driver/geckoinstance.py rename to testing/marionette/client/marionette/geckoinstance.py diff --git a/testing/marionette/driver/marionette_driver/gestures.py b/testing/marionette/client/marionette/gestures.py similarity index 100% rename from testing/marionette/driver/marionette_driver/gestures.py rename to testing/marionette/client/marionette/gestures.py diff --git a/testing/marionette/driver/marionette_driver/keys.py b/testing/marionette/client/marionette/keys.py similarity index 100% rename from testing/marionette/driver/marionette_driver/keys.py rename to testing/marionette/client/marionette/keys.py diff --git a/testing/marionette/driver/marionette_driver/marionette.py b/testing/marionette/client/marionette/marionette.py similarity index 100% rename from testing/marionette/driver/marionette_driver/marionette.py rename to testing/marionette/client/marionette/marionette.py diff --git a/testing/marionette/client/marionette/marionette_test.py b/testing/marionette/client/marionette/marionette_test.py index 80356a4f81d0..cd45db52a8b9 100644 --- a/testing/marionette/client/marionette/marionette_test.py +++ b/testing/marionette/client/marionette/marionette_test.py @@ -14,8 +14,7 @@ import unittest import weakref import warnings - -from marionette_driver.errors import ( +from errors import ( ErrorCodes, MarionetteException, InstallGeckoError, TimeoutException, InvalidResponseException, JavascriptException, NoSuchElementException, XPathLookupException, NoSuchWindowException, StaleElementException, ScriptTimeoutException, ElementNotVisibleException, @@ -23,10 +22,10 @@ from marionette_driver.errors import ( InvalidCookieDomainException, UnableToSetCookieException, InvalidSelectorException, MoveTargetOutOfBoundsException, FrameSendNotInitializedError, FrameSendFailureError ) -from marionette_driver.marionette import Marionette +from marionette import Marionette from mozlog.structured.structuredlog import get_default_logger -from marionette_driver.wait import Wait -from marionette_driver.expected import element_present, element_not_present +from wait import Wait +from expected import element_present, element_not_present class SkipTest(Exception): diff --git a/testing/marionette/client/marionette/runner/base.py b/testing/marionette/client/marionette/runner/base.py index ae4aa453d203..fd1e56fdb528 100644 --- a/testing/marionette/client/marionette/runner/base.py +++ b/testing/marionette/client/marionette/runner/base.py @@ -17,7 +17,7 @@ import unittest import xml.dom.minidom as dom from manifestparser import TestManifest -from marionette_driver.marionette import Marionette +from marionette import Marionette from mixins.b2g import B2GTestResultMixin, get_b2g_pid, get_dm from mozhttpd import MozHttpd from mozlog.structured.structuredlog import get_default_logger diff --git a/testing/marionette/driver/marionette_driver/selection.py b/testing/marionette/client/marionette/selection.py similarity index 100% rename from testing/marionette/driver/marionette_driver/selection.py rename to testing/marionette/client/marionette/selection.py diff --git a/testing/marionette/driver/marionette_driver/wait.py b/testing/marionette/client/marionette/wait.py similarity index 100% rename from testing/marionette/driver/marionette_driver/wait.py rename to testing/marionette/client/marionette/wait.py diff --git a/testing/marionette/driver/marionette_driver/__init__.py b/testing/marionette/driver/marionette_driver/__init__.py deleted file mode 100644 index aff2e13acace..000000000000 --- a/testing/marionette/driver/marionette_driver/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from marionette_driver import ( errors, by, decorators, expected, geckoinstance, - gestures, keys, marionette, selection, wait, - application_cache, date_time_value ) \ No newline at end of file diff --git a/testing/marionette/driver/requirements.txt b/testing/marionette/driver/requirements.txt deleted file mode 100644 index 4259e1971495..000000000000 --- a/testing/marionette/driver/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -marionette-transport == 0.4 \ No newline at end of file diff --git a/testing/marionette/driver/setup.py b/testing/marionette/driver/setup.py deleted file mode 100644 index bd544e676658..000000000000 --- a/testing/marionette/driver/setup.py +++ /dev/null @@ -1,27 +0,0 @@ -import os -from setuptools import setup, find_packages -import sys - -version = '0.1.0' - -# dependencies -with open('requirements.txt') as f: - deps = f.read().splitlines() - -setup(name='marionette_driver', - version=version, - description="Marionette Driver", - long_description='See http://marionette-driver.readthedocs.org/', - classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers - keywords='mozilla', - author='Auto-tools', - author_email='tools-marionette@lists.mozilla.org', - url='https://wiki.mozilla.org/Auto-tools/Projects/Marionette', - license='MPL', - packages=find_packages(), - #package_data={'marionette_driver': ['touch/*.js']}, - include_package_data=True, - zip_safe=False, - install_requires=deps, - ) - From a6cfd84dc651e26ebafef17b481083dda677536f Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Wed, 21 Jan 2015 16:12:28 +0100 Subject: [PATCH 35/62] Backed out changeset d1847f46d293 (bug 1107336) --- layout/base/tests/marionette/test_touchcaret.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/layout/base/tests/marionette/test_touchcaret.py b/layout/base/tests/marionette/test_touchcaret.py index 61a37760936f..9ef93af1b431 100644 --- a/layout/base/tests/marionette/test_touchcaret.py +++ b/layout/base/tests/marionette/test_touchcaret.py @@ -3,10 +3,10 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from marionette_driver.by import By -from marionette_driver.marionette import Actions -from marionette_driver.selection import SelectionManager +from by import By +from marionette import Actions from marionette_test import MarionetteTestCase +from selection import SelectionManager class TouchCaretTest(MarionetteTestCase): From 4d0b9273e4c39347c7f4c3b9a015747abb2acefc Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Wed, 21 Jan 2015 16:14:03 +0100 Subject: [PATCH 36/62] Backed out changeset e6d21c2fa111 (bug 1107336) for breaking Web Platform Reftests on a CLOSED TREE --- build/mach_bootstrap.py | 1 - build/virtualenv_packages.txt | 1 - 2 files changed, 2 deletions(-) diff --git a/build/mach_bootstrap.py b/build/mach_bootstrap.py index e95eddd7bdff..ea72431c0b41 100644 --- a/build/mach_bootstrap.py +++ b/build/mach_bootstrap.py @@ -47,7 +47,6 @@ SEARCH_PATHS = [ 'testing/web-platform/harness', 'testing/marionette/client/marionette', 'testing/marionette/transport', - 'testing/marionette/driver', 'testing/mozbase/mozcrash', 'testing/mozbase/mozdebug', 'testing/mozbase/mozdevice', diff --git a/build/virtualenv_packages.txt b/build/virtualenv_packages.txt index 1dace34d23f2..c442dc5ea249 100644 --- a/build/virtualenv_packages.txt +++ b/build/virtualenv_packages.txt @@ -1,5 +1,4 @@ marionette_transport.pth:testing/marionette/transport -marionette_driver.pth:testing/marionette/driver marionette.pth:testing/marionette/client blessings.pth:python/blessings configobj.pth:python/configobj From aeeb9d2f8b29a27f9f9910a4809adcf1dff3536a Mon Sep 17 00:00:00 2001 From: Patrick McManus Date: Wed, 21 Jan 2015 10:01:07 -0500 Subject: [PATCH 37/62] bug 1102923 test_spdy/test_http2 run-sequentially r=test-only --- netwerk/test/unit/xpcshell.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/netwerk/test/unit/xpcshell.ini b/netwerk/test/unit/xpcshell.ini index ed8ad166cb94..1f2f29cb9ebe 100644 --- a/netwerk/test/unit/xpcshell.ini +++ b/netwerk/test/unit/xpcshell.ini @@ -263,8 +263,10 @@ fail-if = os == "android" # spdy and http2 unit tests require us to have node available to run the spdy and http2 server [test_spdy.js] run-if = hasNode +run-sequentially = node server exceptions dont replay well [test_http2.js] run-if = hasNode +run-sequentially = node server exceptions dont replay well [test_speculative_connect.js] [test_standardurl.js] [test_standardurl_port.js] From 3823a536a2e54e570dd320d250de889399a25d9f Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Wed, 21 Jan 2015 16:46:54 +0100 Subject: [PATCH 38/62] Backed out changeset c197752ff132 (bug 1107337) for fixing mn bustage on a CLOSED TREE --- .../tests/unit/single_finger_functions.py | 4 ++-- .../tests/unit/test_anonymous_content.py | 9 ++++----- .../marionette/tests/unit/test_appcache.py | 4 ++-- .../marionette/tests/unit/test_clearing.py | 4 ++-- .../client/marionette/tests/unit/test_click.py | 6 +++--- .../marionette/tests/unit/test_click_chrome.py | 2 +- .../tests/unit/test_click_scrolling.py | 4 ++-- .../tests/unit/test_date_time_value.py | 2 +- .../client/marionette/tests/unit/test_errors.py | 5 +++-- .../tests/unit/test_execute_async_script.py | 4 +--- .../tests/unit/test_execute_isolate.py | 4 +--- .../marionette/tests/unit/test_execute_script.py | 4 ++-- .../marionette/tests/unit/test_expected.py | 5 ++--- .../marionette/tests/unit/test_findelement.py | 6 +++--- .../tests/unit/test_findelement_chrome.py | 6 +++--- .../marionette/tests/unit/test_implicit_waits.py | 2 +- .../marionette/tests/unit/test_import_script.py | 12 ++++++------ .../marionette/tests/unit/test_navigation.py | 16 ++++++++++++++++ .../tests/unit/test_profile_management.py | 2 +- .../tests/unit/test_screen_orientation.py | 2 +- .../tests/unit/test_set_window_size.py | 2 +- .../tests/unit/test_simpletest_sanity.py | 4 +--- .../marionette/tests/unit/test_single_finger.py | 4 ++-- .../tests/unit/test_single_finger_desktop.py | 4 ++-- .../marionette/tests/unit/test_specialpowers.py | 4 ++-- .../client/marionette/tests/unit/test_submit.py | 7 ++++--- .../marionette/tests/unit/test_switch_frame.py | 4 ++-- .../tests/unit/test_switch_frame_chrome.py | 6 ++++++ .../client/marionette/tests/unit/test_text.py | 2 +- .../marionette/tests/unit/test_timeouts.py | 7 ++----- .../client/marionette/tests/unit/test_typing.py | 4 ++-- .../client/marionette/tests/unit/test_wait.py | 7 +++---- .../tests/unit/test_window_position.py | 2 +- .../tests/unit/test_window_switching.py | 7 +++---- .../tests/unit/test_with_using_context.py | 2 +- 35 files changed, 90 insertions(+), 79 deletions(-) diff --git a/testing/marionette/client/marionette/tests/unit/single_finger_functions.py b/testing/marionette/client/marionette/tests/unit/single_finger_functions.py index 5ecb14f138d8..c233cec1d538 100644 --- a/testing/marionette/client/marionette/tests/unit/single_finger_functions.py +++ b/testing/marionette/client/marionette/tests/unit/single_finger_functions.py @@ -1,5 +1,5 @@ -from marionette_driver.marionette import Actions -from marionette_driver.errors import TimeoutException +from marionette import Actions +from errors import TimeoutException def wait_for_condition_else_raise(marionette, wait_for_condition, expected, script): try: diff --git a/testing/marionette/client/marionette/tests/unit/test_anonymous_content.py b/testing/marionette/client/marionette/tests/unit/test_anonymous_content.py index 0b66233c2c85..3949e29d3495 100644 --- a/testing/marionette/client/marionette/tests/unit/test_anonymous_content.py +++ b/testing/marionette/client/marionette/tests/unit/test_anonymous_content.py @@ -2,12 +2,11 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. +from marionette import HTMLElement from marionette_test import MarionetteTestCase - -from marionette_driver.errors import NoSuchElementException -from marionette_driver.expected import element_present -from marionette_driver.marionette import HTMLElement -from marionette_driver.wait import Wait +from errors import NoSuchElementException +from expected import element_present +from wait import Wait class TestAnonymousContent(MarionetteTestCase): def setUp(self): diff --git a/testing/marionette/client/marionette/tests/unit/test_appcache.py b/testing/marionette/client/marionette/tests/unit/test_appcache.py index 7e0380124d79..c017de4379f7 100644 --- a/testing/marionette/client/marionette/tests/unit/test_appcache.py +++ b/testing/marionette/client/marionette/tests/unit/test_appcache.py @@ -13,7 +13,7 @@ #See the License for the specific language governing permissions and #limitations under the License. -from marionette_driver.application_cache import ApplicationCache +from application_cache import ApplicationCache from marionette_test import MarionetteTestCase @@ -24,7 +24,7 @@ class AppCacheTests(MarionetteTestCase): self.marionette.navigate(test_url) app_cache = self.marionette.application_cache - status = app_cache.status + status = app_cache.status while status == ApplicationCache.DOWNLOADING: status = app_cache.status diff --git a/testing/marionette/client/marionette/tests/unit/test_clearing.py b/testing/marionette/client/marionette/tests/unit/test_clearing.py index a9b3f1163472..53716ccbb2a1 100644 --- a/testing/marionette/client/marionette/tests/unit/test_clearing.py +++ b/testing/marionette/client/marionette/tests/unit/test_clearing.py @@ -3,7 +3,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from marionette_driver.errors import InvalidElementStateException +from errors import InvalidElementStateException class TestClear(MarionetteTestCase): def testWriteableTextInputShouldClear(self): @@ -56,7 +56,7 @@ class TestClear(MarionetteTestCase): element = self.marionette.find_element("id","content-editable") element.clear() self.assertEqual("", element.text) - + def testTextInputShouldNotClearWhenDisabled(self): test_html = self.marionette.absolute_url("test_clearing.html") self.marionette.navigate(test_html) diff --git a/testing/marionette/client/marionette/tests/unit/test_click.py b/testing/marionette/client/marionette/tests/unit/test_click.py index 91f08314f557..d4fccbfbe91a 100644 --- a/testing/marionette/client/marionette/tests/unit/test_click.py +++ b/testing/marionette/client/marionette/tests/unit/test_click.py @@ -2,10 +2,10 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from marionette_driver.by import By -from marionette_driver.errors import NoSuchElementException, ElementNotVisibleException +from by import By +from errors import NoSuchElementException, ElementNotVisibleException from marionette_test import MarionetteTestCase -from marionette_driver.wait import Wait +from wait import Wait class TestClick(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_click_chrome.py b/testing/marionette/client/marionette/tests/unit/test_click_chrome.py index 5c6f733c38bb..35e441958d30 100644 --- a/testing/marionette/client/marionette/tests/unit/test_click_chrome.py +++ b/testing/marionette/client/marionette/tests/unit/test_click_chrome.py @@ -3,7 +3,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from marionette_driver.by import By +from by import By class TestClickChrome(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_click_scrolling.py b/testing/marionette/client/marionette/tests/unit/test_click_scrolling.py index 4a88e118067e..3d7f640a6094 100644 --- a/testing/marionette/client/marionette/tests/unit/test_click_scrolling.py +++ b/testing/marionette/client/marionette/tests/unit/test_click_scrolling.py @@ -2,8 +2,8 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from marionette_driver.by import By -from marionette_driver.errors import MoveTargetOutOfBoundsException +from by import By +from errors import MoveTargetOutOfBoundsException from marionette_test import MarionetteTestCase, skip diff --git a/testing/marionette/client/marionette/tests/unit/test_date_time_value.py b/testing/marionette/client/marionette/tests/unit/test_date_time_value.py index d2fe490026a5..9c89153ce5d6 100644 --- a/testing/marionette/client/marionette/tests/unit/test_date_time_value.py +++ b/testing/marionette/client/marionette/tests/unit/test_date_time_value.py @@ -4,7 +4,7 @@ from marionette_test import MarionetteTestCase from datetime import datetime -from marionette_driver.date_time_value import DateTimeValue +from date_time_value import DateTimeValue class TestDateTime(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_errors.py b/testing/marionette/client/marionette/tests/unit/test_errors.py index 342f9b69bd4d..ba5dc3f973b4 100644 --- a/testing/marionette/client/marionette/tests/unit/test_errors.py +++ b/testing/marionette/client/marionette/tests/unit/test_errors.py @@ -4,9 +4,10 @@ import sys +import errors import marionette_test -from marionette_driver import errors -from marionette_driver.errors import ErrorCodes + +from errors import ErrorCodes def fake_cause(): try: diff --git a/testing/marionette/client/marionette/tests/unit/test_execute_async_script.py b/testing/marionette/client/marionette/tests/unit/test_execute_async_script.py index d03d95b23bf4..2456b6e3c4a2 100644 --- a/testing/marionette/client/marionette/tests/unit/test_execute_async_script.py +++ b/testing/marionette/client/marionette/tests/unit/test_execute_async_script.py @@ -3,9 +3,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from marionette_driver.errors import ( JavascriptException, - MarionetteException, - ScriptTimeoutException ) +from errors import JavascriptException, MarionetteException, ScriptTimeoutException import time diff --git a/testing/marionette/client/marionette/tests/unit/test_execute_isolate.py b/testing/marionette/client/marionette/tests/unit/test_execute_isolate.py index 23db19e7b3c1..016ce06de663 100644 --- a/testing/marionette/client/marionette/tests/unit/test_execute_isolate.py +++ b/testing/marionette/client/marionette/tests/unit/test_execute_isolate.py @@ -3,9 +3,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase, skip_if_b2g -from marionette_driver.errors import (JavascriptException, - MarionetteException, - ScriptTimeoutException) +from errors import JavascriptException, MarionetteException, ScriptTimeoutException class TestExecuteIsolationContent(MarionetteTestCase): def setUp(self): diff --git a/testing/marionette/client/marionette/tests/unit/test_execute_script.py b/testing/marionette/client/marionette/tests/unit/test_execute_script.py index da8ce6318a7d..803b685e1e0a 100644 --- a/testing/marionette/client/marionette/tests/unit/test_execute_script.py +++ b/testing/marionette/client/marionette/tests/unit/test_execute_script.py @@ -4,8 +4,8 @@ import urllib -from marionette_driver.by import By -from marionette_driver.errors import JavascriptException, MarionetteException +from by import By +from errors import JavascriptException, MarionetteException from marionette_test import MarionetteTestCase def inline(doc): diff --git a/testing/marionette/client/marionette/tests/unit/test_expected.py b/testing/marionette/client/marionette/tests/unit/test_expected.py index 99baec9396fd..3881d4c1f245 100644 --- a/testing/marionette/client/marionette/tests/unit/test_expected.py +++ b/testing/marionette/client/marionette/tests/unit/test_expected.py @@ -4,11 +4,10 @@ import urllib -from marionette_driver import expected -from marionette_driver.by import By - +import expected import marionette_test +from by import By def inline(doc): return "data:text/html;charset=utf-8,%s" % urllib.quote(doc) diff --git a/testing/marionette/client/marionette/tests/unit/test_findelement.py b/testing/marionette/client/marionette/tests/unit/test_findelement.py index 23365bb7927b..587f118fcdd1 100644 --- a/testing/marionette/client/marionette/tests/unit/test_findelement.py +++ b/testing/marionette/client/marionette/tests/unit/test_findelement.py @@ -3,9 +3,9 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from marionette_driver.marionette import HTMLElement -from marionette_driver.by import By -from marionette_driver.errors import NoSuchElementException, InvalidSelectorException +from marionette import HTMLElement +from by import By +from errors import NoSuchElementException, InvalidSelectorException class TestElements(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_findelement_chrome.py b/testing/marionette/client/marionette/tests/unit/test_findelement_chrome.py index ee6f2e208789..4d13b1f6b295 100644 --- a/testing/marionette/client/marionette/tests/unit/test_findelement_chrome.py +++ b/testing/marionette/client/marionette/tests/unit/test_findelement_chrome.py @@ -3,9 +3,9 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from marionette_driver.marionette import HTMLElement -from marionette_driver.by import By -from marionette_driver.errors import NoSuchElementException +from marionette import HTMLElement +from by import By +from errors import NoSuchElementException class TestElementsChrome(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_implicit_waits.py b/testing/marionette/client/marionette/tests/unit/test_implicit_waits.py index 67da1543ab07..241dfb0926e4 100644 --- a/testing/marionette/client/marionette/tests/unit/test_implicit_waits.py +++ b/testing/marionette/client/marionette/tests/unit/test_implicit_waits.py @@ -3,7 +3,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from marionette_driver.errors import NoSuchElementException +from errors import NoSuchElementException class TestImplicitWaits(MarionetteTestCase): def testShouldImplicitlyWaitForASingleElement(self): diff --git a/testing/marionette/client/marionette/tests/unit/test_import_script.py b/testing/marionette/client/marionette/tests/unit/test_import_script.py index 0254dd8ba25c..c47f98f1b529 100644 --- a/testing/marionette/client/marionette/tests/unit/test_import_script.py +++ b/testing/marionette/client/marionette/tests/unit/test_import_script.py @@ -4,7 +4,7 @@ import os from marionette_test import MarionetteTestCase -from marionette_driver.errors import JavascriptException +from errors import JavascriptException class TestImportScript(MarionetteTestCase): def setUp(self): @@ -18,14 +18,14 @@ class TestImportScript(MarionetteTestCase): def check_file_exists(self): return self.marionette.execute_script(""" let FileUtils = SpecialPowers.Cu.import("resource://gre/modules/FileUtils.jsm", {}).FileUtils; - let importedScripts = FileUtils.getFile('TmpD', ['marionetteContentScripts']); + let importedScripts = FileUtils.getFile('TmpD', ['marionetteContentScripts']); return importedScripts.exists(); """, special_powers=True) def get_file_size(self): return self.marionette.execute_script(""" let FileUtils = SpecialPowers.Cu.import("resource://gre/modules/FileUtils.jsm", {}).FileUtils; - let importedScripts = FileUtils.getFile('TmpD', ['marionetteContentScripts']); + let importedScripts = FileUtils.getFile('TmpD', ['marionetteContentScripts']); return importedScripts.fileSize; """, special_powers=True) @@ -109,7 +109,7 @@ class TestImportScript(MarionetteTestCase): self.marionette.import_script(firstjs) self.marionette.import_script(secondjs) - self.assertEqual("i'm a test function!", + self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();")) self.assertEqual("i'm yet another test function!", @@ -129,14 +129,14 @@ class TestImportScriptChrome(TestImportScript): def check_file_exists(self): return self.marionette.execute_async_script(""" let FileUtils = Components.utils.import("resource://gre/modules/FileUtils.jsm", {}).FileUtils; - let importedScripts = FileUtils.getFile('TmpD', ['marionetteChromeScripts']); + let importedScripts = FileUtils.getFile('TmpD', ['marionetteChromeScripts']); marionetteScriptFinished(importedScripts.exists()); """) def get_file_size(self): return self.marionette.execute_async_script(""" let FileUtils = Components.utils.import("resource://gre/modules/FileUtils.jsm", {}).FileUtils; - let importedScripts = FileUtils.getFile('TmpD', ['marionetteChromeScripts']); + let importedScripts = FileUtils.getFile('TmpD', ['marionetteChromeScripts']); marionetteScriptFinished(importedScripts.fileSize); """) diff --git a/testing/marionette/client/marionette/tests/unit/test_navigation.py b/testing/marionette/client/marionette/tests/unit/test_navigation.py index fb574ffda44e..e95ee42467c4 100644 --- a/testing/marionette/client/marionette/tests/unit/test_navigation.py +++ b/testing/marionette/client/marionette/tests/unit/test_navigation.py @@ -2,11 +2,14 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. +from marionette_test import MarionetteTestCase, skip_if_b2g, skip_if_e10s +from errors import MarionetteException, TimeoutException class TestNavigate(MarionetteTestCase): def test_navigate(self): self.assertTrue(self.marionette.execute_script("window.location.href = 'about:blank'; return true;")) self.assertEqual("about:blank", self.marionette.execute_script("return window.location.href;")) + test_html = self.marionette.absolute_url("test.html") self.marionette.navigate(test_html) self.assertNotEqual("about:blank", self.marionette.execute_script("return window.location.href;")) self.assertEqual("Marionette Test", self.marionette.title) @@ -74,6 +77,7 @@ class TestNavigate(MarionetteTestCase): self.assertTrue('test_iframe.html' in self.marionette.get_url()) ''' + @skip_if_e10s # Interactions with about: pages need e10s support (bug 1096488). def test_shouldnt_error_if_nonexistent_url_used(self): try: self.marionette.navigate("thisprotocoldoesnotexist://") @@ -81,8 +85,20 @@ class TestNavigate(MarionetteTestCase): except TimeoutException: self.fail("The socket shouldn't have timed out when navigating to a non-existent URL") except MarionetteException as e: + self.assertIn("Error loading page", str(e)) + except Exception as inst: + import traceback + print traceback.format_exc() + self.fail("Should have thrown a MarionetteException instead of %s" % type(inst)) + @skip_if_e10s # Interactions with about: pages need e10s support (bug 1096488). + @skip_if_b2g # about:blocked isn't a well formed uri on b2g + def test_should_navigate_to_requested_about_page(self): + self.marionette.navigate("about:neterror") + self.assertEqual(self.marionette.get_url(), "about:neterror") + self.marionette.navigate(self.marionette.absolute_url("test.html")) self.marionette.navigate("about:blocked") + self.assertEqual(self.marionette.get_url(), "about:blocked") def test_find_element_state_complete(self): test_html = self.marionette.absolute_url("test.html") diff --git a/testing/marionette/client/marionette/tests/unit/test_profile_management.py b/testing/marionette/client/marionette/tests/unit/test_profile_management.py index 92b6a3782868..28b9477c2e97 100644 --- a/testing/marionette/client/marionette/tests/unit/test_profile_management.py +++ b/testing/marionette/client/marionette/tests/unit/test_profile_management.py @@ -3,7 +3,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. import os -from marionette_driver.errors import JavascriptException +from errors import JavascriptException from marionette_test import MarionetteTestCase class TestLog(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_screen_orientation.py b/testing/marionette/client/marionette/tests/unit/test_screen_orientation.py index 06079be936da..4e5c83a8b627 100644 --- a/testing/marionette/client/marionette/tests/unit/test_screen_orientation.py +++ b/testing/marionette/client/marionette/tests/unit/test_screen_orientation.py @@ -4,7 +4,7 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from marionette_driver.errors import MarionetteException +from errors import MarionetteException from marionette_test import MarionetteTestCase from mozrunner.devices.emulator_screen import EmulatorScreen diff --git a/testing/marionette/client/marionette/tests/unit/test_set_window_size.py b/testing/marionette/client/marionette/tests/unit/test_set_window_size.py index bac5d713c231..044c201d2ebe 100644 --- a/testing/marionette/client/marionette/tests/unit/test_set_window_size.py +++ b/testing/marionette/client/marionette/tests/unit/test_set_window_size.py @@ -2,7 +2,7 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from marionette_driver.errors import MarionetteException +from errors import MarionetteException from marionette_test import MarionetteTestCase class TestSetWindowSize(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_simpletest_sanity.py b/testing/marionette/client/marionette/tests/unit/test_simpletest_sanity.py index 7e08be1bc665..fe51a1a47f7c 100644 --- a/testing/marionette/client/marionette/tests/unit/test_simpletest_sanity.py +++ b/testing/marionette/client/marionette/tests/unit/test_simpletest_sanity.py @@ -3,9 +3,7 @@ # You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from marionette_driver.errors import (JavascriptException, - MarionetteException, - ScriptTimeoutException) +from errors import JavascriptException, MarionetteException, ScriptTimeoutException class SimpletestSanityTest(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_single_finger.py b/testing/marionette/client/marionette/tests/unit/test_single_finger.py index 63afbe837cf5..49a053e95182 100644 --- a/testing/marionette/client/marionette/tests/unit/test_single_finger.py +++ b/testing/marionette/client/marionette/tests/unit/test_single_finger.py @@ -3,8 +3,8 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from marionette_driver.marionette import Actions -from marionette_driver.errors import MarionetteException +from marionette import Actions +from errors import MarionetteException #add this directory to the path import os import sys diff --git a/testing/marionette/client/marionette/tests/unit/test_single_finger_desktop.py b/testing/marionette/client/marionette/tests/unit/test_single_finger_desktop.py index 264b691a18fe..d185b36fe080 100644 --- a/testing/marionette/client/marionette/tests/unit/test_single_finger_desktop.py +++ b/testing/marionette/client/marionette/tests/unit/test_single_finger_desktop.py @@ -1,6 +1,6 @@ from marionette_test import MarionetteTestCase -from marionette_driver.marionette import Actions -from marionette_driver.errors import MarionetteException +from marionette import Actions +from errors import MarionetteException #add this directory to the path import os import sys diff --git a/testing/marionette/client/marionette/tests/unit/test_specialpowers.py b/testing/marionette/client/marionette/tests/unit/test_specialpowers.py index 835ede56b15d..aea11a878f04 100644 --- a/testing/marionette/client/marionette/tests/unit/test_specialpowers.py +++ b/testing/marionette/client/marionette/tests/unit/test_specialpowers.py @@ -3,7 +3,7 @@ # You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from marionette_driver.errors import JavascriptException, MarionetteException +from errors import JavascriptException, MarionetteException class TestSpecialPowersContent(MarionetteTestCase): @@ -15,7 +15,7 @@ class TestSpecialPowersContent(MarionetteTestCase): SpecialPowers.setCharPref("%(pref)s", "%(value)s"); return SpecialPowers.getCharPref("%(pref)s") """ % {'pref': self.testpref, 'value': self.testvalue}, special_powers=True); - self.assertEqual(result, self.testvalue) + self.assertEqual(result, self.testvalue) def test_prefs_after_navigate(self): test_html = self.marionette.absolute_url("test.html") diff --git a/testing/marionette/client/marionette/tests/unit/test_submit.py b/testing/marionette/client/marionette/tests/unit/test_submit.py index c80542777182..272f9e272b7a 100644 --- a/testing/marionette/client/marionette/tests/unit/test_submit.py +++ b/testing/marionette/client/marionette/tests/unit/test_submit.py @@ -4,10 +4,11 @@ import time -from marionette_driver.by import By -from marionette_driver.errors import NoSuchElementException -from marionette_driver.wait import Wait +from by import By +from errors import NoSuchElementException from marionette_test import MarionetteTestCase +from wait import Wait + class TestSubmit(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_switch_frame.py b/testing/marionette/client/marionette/tests/unit/test_switch_frame.py index 57cfe7df516c..6a56c75cf082 100644 --- a/testing/marionette/client/marionette/tests/unit/test_switch_frame.py +++ b/testing/marionette/client/marionette/tests/unit/test_switch_frame.py @@ -3,8 +3,8 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from marionette_driver.errors import (JavascriptException, - NoSuchFrameException) +from errors import JavascriptException +from errors import NoSuchFrameException class TestSwitchFrame(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_switch_frame_chrome.py b/testing/marionette/client/marionette/tests/unit/test_switch_frame_chrome.py index 5e476231ef83..d6b49cd39b15 100644 --- a/testing/marionette/client/marionette/tests/unit/test_switch_frame_chrome.py +++ b/testing/marionette/client/marionette/tests/unit/test_switch_frame_chrome.py @@ -48,3 +48,9 @@ class TestSwitchFrameChrome(MarionetteTestCase): self.marionette.execute_async_script("foo();") except JavascriptException as e: self.assertIn("foo", e.msg) + + def test_we_can_switch_to_a_browser_frame(self): + self.assertIn("test.xul", self.marionette.get_url(), "Initial navigation has failed") + browser = self.marionette.find_element(By.ID, 'aBrowser') + self.marionette.switch_to_frame(browser) + self.assertIn("test2.xul", self.marionette.get_url(), "Switching by element failed") diff --git a/testing/marionette/client/marionette/tests/unit/test_text.py b/testing/marionette/client/marionette/tests/unit/test_text.py index 53cc340ff2aa..a6ada51aa33d 100644 --- a/testing/marionette/client/marionette/tests/unit/test_text.py +++ b/testing/marionette/client/marionette/tests/unit/test_text.py @@ -3,7 +3,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from marionette_driver.keys import Keys +from keys import Keys class TestText(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_timeouts.py b/testing/marionette/client/marionette/tests/unit/test_timeouts.py index 10ba6ccd4da9..6e066851b0b7 100644 --- a/testing/marionette/client/marionette/tests/unit/test_timeouts.py +++ b/testing/marionette/client/marionette/tests/unit/test_timeouts.py @@ -4,11 +4,8 @@ import os from marionette_test import MarionetteTestCase -from marionette_driver.marionette import HTMLElement -from marionette_driver.errors import (NoSuchElementException, - JavascriptException, - MarionetteException, - ScriptTimeoutException) +from marionette import HTMLElement +from errors import NoSuchElementException, JavascriptException, MarionetteException, ScriptTimeoutException class TestTimeouts(MarionetteTestCase): def test_pagetimeout_notdefinetimeout_pass(self): diff --git a/testing/marionette/client/marionette/tests/unit/test_typing.py b/testing/marionette/client/marionette/tests/unit/test_typing.py index 638ba2da8145..969c9587e432 100644 --- a/testing/marionette/client/marionette/tests/unit/test_typing.py +++ b/testing/marionette/client/marionette/tests/unit/test_typing.py @@ -3,8 +3,8 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase, skip_if_b2g -from marionette_driver.keys import Keys -from marionette_driver.errors import ElementNotVisibleException +from keys import Keys +from errors import ElementNotVisibleException class TestTyping(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_wait.py b/testing/marionette/client/marionette/tests/unit/test_wait.py index 775b505569d7..b17742249a1e 100644 --- a/testing/marionette/client/marionette/tests/unit/test_wait.py +++ b/testing/marionette/client/marionette/tests/unit/test_wait.py @@ -5,12 +5,11 @@ import sys import time -from marionette_driver import errors -from marionette_driver import wait -from marionette_driver.wait import Wait +import errors +import wait from marionette_test import MarionetteTestCase - +from wait import Wait class TickingClock(object): def __init__(self, incr=1): diff --git a/testing/marionette/client/marionette/tests/unit/test_window_position.py b/testing/marionette/client/marionette/tests/unit/test_window_position.py index 220010677474..70879f8d1c98 100644 --- a/testing/marionette/client/marionette/tests/unit/test_window_position.py +++ b/testing/marionette/client/marionette/tests/unit/test_window_position.py @@ -13,7 +13,7 @@ #limitations under the License. from marionette_test import MarionetteTestCase -from marionette_driver.errors import MarionetteException +from errors import MarionetteException class TestWindowPosition(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_window_switching.py b/testing/marionette/client/marionette/tests/unit/test_window_switching.py index 18bd0b426582..bf689b74b3cc 100644 --- a/testing/marionette/client/marionette/tests/unit/test_window_switching.py +++ b/testing/marionette/client/marionette/tests/unit/test_window_switching.py @@ -2,11 +2,10 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. +from by import By +from errors import NoSuchElementException from marionette_test import MarionetteTestCase - -from marionette_driver.by import By -from marionette_driver.errors import NoSuchElementException -from marionette_driver.wait import Wait +from wait import Wait class TestWindowSwitching(MarionetteTestCase): diff --git a/testing/marionette/client/marionette/tests/unit/test_with_using_context.py b/testing/marionette/client/marionette/tests/unit/test_with_using_context.py index cfe83f531eb1..d8b72a791aa4 100644 --- a/testing/marionette/client/marionette/tests/unit/test_with_using_context.py +++ b/testing/marionette/client/marionette/tests/unit/test_with_using_context.py @@ -3,7 +3,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_test import MarionetteTestCase -from marionette_driver.errors import MarionetteException +from errors import MarionetteException class TestSetContext(MarionetteTestCase): From c88d8c371691ce3fe1af0c48a4d204f482eeb61e Mon Sep 17 00:00:00 2001 From: Daniel Holbert Date: Wed, 21 Jan 2015 07:44:12 -0800 Subject: [PATCH 39/62] Bug 1123890: Add MOZ_OVERRIDE annotations to overriding methods in dom/broadcastchannel. r=baku --- dom/broadcastchannel/BroadcastChannel.cpp | 12 ++++++------ dom/broadcastchannel/BroadcastChannelChild.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/dom/broadcastchannel/BroadcastChannel.cpp b/dom/broadcastchannel/BroadcastChannel.cpp index c3f4101cbbfa..1a526b5921e9 100644 --- a/dom/broadcastchannel/BroadcastChannel.cpp +++ b/dom/broadcastchannel/BroadcastChannel.cpp @@ -187,7 +187,7 @@ public: MOZ_ASSERT(mActor); } - NS_IMETHODIMP Run() + NS_IMETHODIMP Run() MOZ_OVERRIDE { MOZ_ASSERT(mActor); if (mActor->IsActorDestroyed()) { @@ -221,7 +221,7 @@ public: return NS_OK; } - NS_IMETHODIMP Cancel() + NS_IMETHODIMP Cancel() MOZ_OVERRIDE { mActor = nullptr; return NS_OK; @@ -247,13 +247,13 @@ public: MOZ_ASSERT(mBC); } - NS_IMETHODIMP Run() + NS_IMETHODIMP Run() MOZ_OVERRIDE { mBC->Shutdown(); return NS_OK; } - NS_IMETHODIMP Cancel() + NS_IMETHODIMP Cancel() MOZ_OVERRIDE { mBC = nullptr; return NS_OK; @@ -278,7 +278,7 @@ public: MOZ_ASSERT(mActor); } - NS_IMETHODIMP Run() + NS_IMETHODIMP Run() MOZ_OVERRIDE { MOZ_ASSERT(mActor); if (!mActor->IsActorDestroyed()) { @@ -287,7 +287,7 @@ public: return NS_OK; } - NS_IMETHODIMP Cancel() + NS_IMETHODIMP Cancel() MOZ_OVERRIDE { mActor = nullptr; return NS_OK; diff --git a/dom/broadcastchannel/BroadcastChannelChild.h b/dom/broadcastchannel/BroadcastChannelChild.h index 8f7a22092625..011d2c5a110d 100644 --- a/dom/broadcastchannel/BroadcastChannelChild.h +++ b/dom/broadcastchannel/BroadcastChannelChild.h @@ -42,7 +42,7 @@ private: ~BroadcastChannelChild(); - void ActorDestroy(ActorDestroyReason aWhy); + virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE; // This raw pointer is actually the parent object. // It's set to null when the parent object is deleted. From 09de8e21b25928f859b1d4bf805453dabe08c929 Mon Sep 17 00:00:00 2001 From: "Nicolas B. Pierron" Date: Wed, 21 Jan 2015 16:57:12 +0100 Subject: [PATCH 40/62] Bug 1123631 - SIMD Ion: Disable inlining of Float64x2. r=bbouvier --- js/src/jit-test/tests/ion/simd-bug1123631.js | 9 +++++++++ js/src/jit/MCallOptimize.cpp | 5 ++--- 2 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 js/src/jit-test/tests/ion/simd-bug1123631.js diff --git a/js/src/jit-test/tests/ion/simd-bug1123631.js b/js/src/jit-test/tests/ion/simd-bug1123631.js new file mode 100644 index 000000000000..38309f6b15cb --- /dev/null +++ b/js/src/jit-test/tests/ion/simd-bug1123631.js @@ -0,0 +1,9 @@ +if (!this.hasOwnProperty("SIMD")) + quit(); + +var float64x2 = SIMD.float64x2; +function test() { + var a = float64x2(1, 2); +} +test(); +test(); diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index 15afa27b5783..6147b13e54a9 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -2530,9 +2530,8 @@ IonBuilder::inlineConstructSimdObject(CallInfo &callInfo, SimdTypeDescr *descr) case SimdTypeDescr::TYPE_FLOAT32: simdType = MIRType_Float32x4; break; - default: - MOZ_CRASH("Unknown SIMD kind when generating MSimdBox instruction."); - return InliningStatus_NotInlined; + case SimdTypeDescr::TYPE_FLOAT64: + return InliningStatus_NotInlined; // :TODO: NYI (Bug 1124205) } // We do not inline SIMD constructors if the number of arguments does not From 8f8e24c41b4a23bd82802bb170d132dab1cf691f Mon Sep 17 00:00:00 2001 From: Markus Stange Date: Wed, 21 Jan 2015 11:09:00 -0500 Subject: [PATCH 41/62] Bug 1123852 - Update talos.json in order to pick up bug 1119780 and bug 1121571. Also, actually use e10s for the *-snow-e10s tests. r=jmaher --- testing/talos/talos.json | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/testing/talos/talos.json b/testing/talos/talos.json index a75772999df9..1fc45bac6a28 100644 --- a/testing/talos/talos.json +++ b/testing/talos/talos.json @@ -5,7 +5,7 @@ }, "global": { "talos_repo": "https://hg.mozilla.org/build/talos", - "talos_revision": "ebc4327b8cb8" + "talos_revision": "39c9c9b33cfc" }, "extra_options": { "android": [ "--apkPath=%(apk_path)s" ] @@ -39,7 +39,8 @@ "tests": ["tpaint"] }, "other-snow-e10s": { - "tests": ["tpaint"] + "tests": ["tpaint"], + "talos_options": ["--e10s"] }, "other_nol64": { "tests": ["a11yr", "ts_paint", "tpaint", "sessionrestore", "sessionrestore_no_auto_restore"] @@ -80,7 +81,8 @@ "tests": ["glterrain"] }, "g1-snow-e10s": { - "tests": ["glterrain"] + "tests": ["glterrain"], + "talos_options": ["--e10s"] }, "svgr": { "tests": ["tsvgx", "tsvgr_opacity", "tart", "tscrollx", "cart"] @@ -93,7 +95,8 @@ "tests": ["tsvgx", "tscrollx"] }, "svgr-snow-e10s": { - "tests": ["tsvgx", "tscrollx"] + "tests": ["tsvgx", "tscrollx"], + "talos_options": ["--e10s"] }, "tp5o": { "tests": ["tp5o"], From 4dd401ec2fe9426391ec1f92853f14391146bd9a Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Sun, 18 Jan 2015 14:11:34 -0500 Subject: [PATCH 42/62] Bug 1123113 - Mark ParentObject as stack class, and its mObject member as non-owning; r=bzbarsky --- dom/bindings/BindingDeclarations.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dom/bindings/BindingDeclarations.h b/dom/bindings/BindingDeclarations.h index 38ef6ce3ffc6..5b84610e9a15 100644 --- a/dom/bindings/BindingDeclarations.h +++ b/dom/bindings/BindingDeclarations.h @@ -461,7 +461,7 @@ GetWrapperCache(const SmartPtr& aObject) return GetWrapperCache(aObject.get()); } -struct ParentObject { +struct MOZ_STACK_CLASS ParentObject { template ParentObject(T* aObject) : mObject(aObject), @@ -482,7 +482,9 @@ struct ParentObject { mUseXBLScope(false) {} - nsISupports* const mObject; + // We don't want to make this an nsCOMPtr because of performance reasons, but + // it's safe because ParentObject is a stack class. + nsISupports* const MOZ_NON_OWNING_REF mObject; nsWrapperCache* const mWrapperCache; bool mUseXBLScope; }; From acfa245a0af67c71e23cb0bf41390a6b6f299e94 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Tue, 20 Jan 2015 22:46:48 -0500 Subject: [PATCH 43/62] Bug 1124041 - Move TestPipes.cpp to gtest and enable it; r=froydnj --- xpcom/tests/{ => gtest}/TestPipes.cpp | 218 +++++++++----------------- xpcom/tests/gtest/moz.build | 1 + xpcom/tests/moz.build | 1 - 3 files changed, 71 insertions(+), 149 deletions(-) rename xpcom/tests/{ => gtest}/TestPipes.cpp (60%) diff --git a/xpcom/tests/TestPipes.cpp b/xpcom/tests/gtest/TestPipes.cpp similarity index 60% rename from xpcom/tests/TestPipes.cpp rename to xpcom/tests/gtest/TestPipes.cpp index c630e930efed..5ec57e041b62 100644 --- a/xpcom/tests/TestPipes.cpp +++ b/xpcom/tests/gtest/TestPipes.cpp @@ -3,8 +3,9 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "TestHarness.h" - +#include +#include "nsIAsyncInputStream.h" +#include "nsIAsyncOutputStream.h" #include "nsIThread.h" #include "nsIRunnable.h" #include "nsThreadUtils.h" @@ -13,76 +14,11 @@ #include "nsCRT.h" #include "nsIPipe.h" // new implementation -#include "mozilla/Monitor.h" +#include "mozilla/ReentrantMonitor.h" + +#include "gtest/gtest.h" using namespace mozilla; -/** NS_NewPipe2 reimplemented, because it's not exported by XPCOM */ -nsresult TP_NewPipe2(nsIAsyncInputStream** input, - nsIAsyncOutputStream** output, - bool nonBlockingInput, - bool nonBlockingOutput, - uint32_t segmentSize, - uint32_t segmentCount, - nsIMemory* segmentAlloc) -{ - nsCOMPtr pipe = do_CreateInstance("@mozilla.org/pipe;1"); - if (!pipe) - return NS_ERROR_OUT_OF_MEMORY; - - nsresult rv = pipe->Init(nonBlockingInput, - nonBlockingOutput, - segmentSize, - segmentCount, - segmentAlloc); - - if (NS_FAILED(rv)) - return rv; - - pipe->GetInputStream(input); - pipe->GetOutputStream(output); - return NS_OK; -} - -/** NS_NewPipe reimplemented, because it's not exported by XPCOM */ -#define TP_DEFAULT_SEGMENT_SIZE 4096 -nsresult TP_NewPipe(nsIInputStream **pipeIn, - nsIOutputStream **pipeOut, - uint32_t segmentSize = 0, - uint32_t maxSize = 0, - bool nonBlockingInput = false, - bool nonBlockingOutput = false, - nsIMemory *segmentAlloc = nullptr); -nsresult TP_NewPipe(nsIInputStream **pipeIn, - nsIOutputStream **pipeOut, - uint32_t segmentSize, - uint32_t maxSize, - bool nonBlockingInput, - bool nonBlockingOutput, - nsIMemory *segmentAlloc) -{ - if (segmentSize == 0) - segmentSize = TP_DEFAULT_SEGMENT_SIZE; - - // Handle maxSize of UINT32_MAX as a special case - uint32_t segmentCount; - if (maxSize == UINT32_MAX) - segmentCount = UINT32_MAX; - else - segmentCount = maxSize / segmentSize; - - nsIAsyncInputStream *in; - nsIAsyncOutputStream *out; - nsresult rv = TP_NewPipe2(&in, &out, nonBlockingInput, nonBlockingOutput, - segmentSize, segmentCount, segmentAlloc); - if (NS_FAILED(rv)) return rv; - - *pipeIn = in; - *pipeOut = out; - return NS_OK; -} - - -#define KEY 0xa7 #define ITERATIONS 33333 char kTestPattern[] = "My hovercraft is full of eels.\n"; @@ -104,11 +40,11 @@ WriteAll(nsIOutputStream *os, const char *buf, uint32_t bufLen, uint32_t *lenWri return NS_OK; } -class nsReceiver : public nsIRunnable { +class nsReceiver MOZ_FINAL : public nsIRunnable { public: NS_DECL_THREADSAFE_ISUPPORTS - NS_IMETHOD Run() { + NS_IMETHOD Run() MOZ_OVERRIDE { nsresult rv; char buf[101]; uint32_t count; @@ -136,11 +72,14 @@ public: return rv; } - nsReceiver(nsIInputStream* in) : mIn(in), mCount(0) { + explicit nsReceiver(nsIInputStream* in) : mIn(in), mCount(0) { } uint32_t GetBytesRead() { return mCount; } +private: + ~nsReceiver() {} + protected: nsCOMPtr mIn; uint32_t mCount; @@ -151,7 +90,7 @@ NS_IMPL_ISUPPORTS(nsReceiver, nsIRunnable) nsresult TestPipe(nsIInputStream* in, nsIOutputStream* out) { - nsCOMPtr receiver = new nsReceiver(in); + nsRefPtr receiver = new nsReceiver(in); if (!receiver) return NS_ERROR_OUT_OF_MEMORY; @@ -188,18 +127,18 @@ TestPipe(nsIInputStream* in, nsIOutputStream* out) printf("wrote %d bytes, time = %dms\n", total, PR_IntervalToMilliseconds(end - start)); - NS_ASSERTION(receiver->GetBytesRead() == total, "didn't read everything"); + EXPECT_EQ(receiver->GetBytesRead(), total); return NS_OK; } //////////////////////////////////////////////////////////////////////////////// -class nsShortReader : public nsIRunnable { +class nsShortReader MOZ_FINAL : public nsIRunnable { public: NS_DECL_THREADSAFE_ISUPPORTS - NS_IMETHOD Run() { + NS_IMETHOD Run() MOZ_OVERRIDE { nsresult rv; char buf[101]; uint32_t count; @@ -230,24 +169,24 @@ public: return rv; } - nsShortReader(nsIInputStream* in) : mIn(in), mReceived(0) { - mMon = new Monitor("nsShortReader"); + explicit nsShortReader(nsIInputStream* in) : mIn(in), mReceived(0) { + mMon = new ReentrantMonitor("nsShortReader"); } void Received(uint32_t count) { - MonitorAutoEnter mon(*mMon); + ReentrantMonitorAutoEnter mon(*mMon); mReceived += count; mon.Notify(); } uint32_t WaitForReceipt(const uint32_t aWriteCount) { - MonitorAutoEnter mon(*mMon); + ReentrantMonitorAutoEnter mon(*mMon); uint32_t result = mReceived; while (result < aWriteCount) { mon.Wait(); - NS_ASSERTION(mReceived > result, "failed to receive"); + EXPECT_TRUE(mReceived > result); result = mReceived; } @@ -255,10 +194,13 @@ public: return result; } +private: + ~nsShortReader() {} + protected: nsCOMPtr mIn; uint32_t mReceived; - Monitor* mMon; + ReentrantMonitor* mMon; }; NS_IMPL_ISUPPORTS(nsShortReader, nsIRunnable) @@ -266,7 +208,7 @@ NS_IMPL_ISUPPORTS(nsShortReader, nsIRunnable) nsresult TestShortWrites(nsIInputStream* in, nsIOutputStream* out) { - nsCOMPtr receiver = new nsShortReader(in); + nsRefPtr receiver = new nsShortReader(in); if (!receiver) return NS_ERROR_OUT_OF_MEMORY; @@ -282,10 +224,10 @@ TestShortWrites(nsIInputStream* in, nsIOutputStream* out) char* buf = PR_smprintf("%d %s", i, kTestPattern); uint32_t len = strlen(buf); len = len * rand() / RAND_MAX; - len = XPCOM_MAX(1, len); + len = std::min(1u, len); rv = WriteAll(out, buf, len, &writeCount); if (NS_FAILED(rv)) return rv; - NS_ASSERTION(writeCount == len, "didn't write enough"); + EXPECT_EQ(writeCount, len); total += writeCount; if (gTrace) @@ -297,9 +239,9 @@ TestShortWrites(nsIInputStream* in, nsIOutputStream* out) #ifdef DEBUG const uint32_t received = -#endif receiver->WaitForReceipt(writeCount); - NS_ASSERTION(received == writeCount, "received wrong amount"); + EXPECT_EQ(received, writeCount); +#endif } rv = out->Close(); if (NS_FAILED(rv)) return rv; @@ -313,12 +255,12 @@ TestShortWrites(nsIInputStream* in, nsIOutputStream* out) //////////////////////////////////////////////////////////////////////////////// -class nsPump : public nsIRunnable +class nsPump MOZ_FINAL : public nsIRunnable { public: NS_DECL_THREADSAFE_ISUPPORTS - NS_IMETHOD Run() { + NS_IMETHOD Run() MOZ_OVERRIDE { nsresult rv; uint32_t count; while (true) { @@ -346,6 +288,9 @@ public: : mIn(in), mOut(out), mCount(0) { } +private: + ~nsPump() {} + protected: nsCOMPtr mIn; nsCOMPtr mOut; @@ -354,35 +299,36 @@ protected: NS_IMPL_ISUPPORTS(nsPump, nsIRunnable) -nsresult -TestChainedPipes() +TEST(Pipes, ChainedPipes) { nsresult rv; - printf("TestChainedPipes\n"); + if (gTrace) { + printf("TestChainedPipes\n"); + } nsCOMPtr in1; nsCOMPtr out1; - rv = TP_NewPipe(getter_AddRefs(in1), getter_AddRefs(out1), 20, 1999); - if (NS_FAILED(rv)) return rv; + rv = NS_NewPipe(getter_AddRefs(in1), getter_AddRefs(out1), 20, 1999); + if (NS_FAILED(rv)) return; nsCOMPtr in2; nsCOMPtr out2; - rv = TP_NewPipe(getter_AddRefs(in2), getter_AddRefs(out2), 200, 401); - if (NS_FAILED(rv)) return rv; + rv = NS_NewPipe(getter_AddRefs(in2), getter_AddRefs(out2), 200, 401); + if (NS_FAILED(rv)) return; - nsCOMPtr pump = new nsPump(in1, out2); - if (pump == nullptr) return NS_ERROR_OUT_OF_MEMORY; + nsRefPtr pump = new nsPump(in1, out2); + if (pump == nullptr) return; nsCOMPtr thread; rv = NS_NewThread(getter_AddRefs(thread), pump); - if (NS_FAILED(rv)) return rv; + if (NS_FAILED(rv)) return; - nsCOMPtr receiver = new nsReceiver(in2); - if (receiver == nullptr) return NS_ERROR_OUT_OF_MEMORY; + nsRefPtr receiver = new nsReceiver(in2); + if (receiver == nullptr) return; nsCOMPtr receiverThread; rv = NS_NewThread(getter_AddRefs(receiverThread), receiver); - if (NS_FAILED(rv)) return rv; + if (NS_FAILED(rv)) return; uint32_t total = 0; for (uint32_t i = 0; i < ITERATIONS; i++) { @@ -390,10 +336,10 @@ TestChainedPipes() char* buf = PR_smprintf("%d %s", i, kTestPattern); uint32_t len = strlen(buf); len = len * rand() / RAND_MAX; - len = XPCOM_MAX(1, len); + len = std::max(1u, len); rv = WriteAll(out1, buf, len, &writeCount); - if (NS_FAILED(rv)) return rv; - NS_ASSERTION(writeCount == len, "didn't write enough"); + if (NS_FAILED(rv)) return; + EXPECT_EQ(writeCount, len); total += writeCount; if (gTrace) @@ -401,14 +347,14 @@ TestChainedPipes() PR_smprintf_free(buf); } - printf("wrote total of %d bytes\n", total); + if (gTrace) { + printf("wrote total of %d bytes\n", total); + } rv = out1->Close(); - if (NS_FAILED(rv)) return rv; + if (NS_FAILED(rv)) return; thread->Shutdown(); receiverThread->Shutdown(); - - return NS_OK; } //////////////////////////////////////////////////////////////////////////////// @@ -420,50 +366,26 @@ RunTests(uint32_t segSize, uint32_t segCount) nsCOMPtr in; nsCOMPtr out; uint32_t bufSize = segSize * segCount; - printf("Testing New Pipes: segment size %d buffer size %d\n", segSize, bufSize); - - printf("Testing long writes...\n"); - rv = TP_NewPipe(getter_AddRefs(in), getter_AddRefs(out), segSize, bufSize); - NS_ASSERTION(NS_SUCCEEDED(rv), "TP_NewPipe failed"); + if (gTrace) { + printf("Testing New Pipes: segment size %d buffer size %d\n", segSize, bufSize); + printf("Testing long writes...\n"); + } + rv = NS_NewPipe(getter_AddRefs(in), getter_AddRefs(out), segSize, bufSize); + EXPECT_TRUE(NS_SUCCEEDED(rv)); rv = TestPipe(in, out); - NS_ASSERTION(NS_SUCCEEDED(rv), "TestPipe failed"); + EXPECT_TRUE(NS_SUCCEEDED(rv)); - printf("Testing short writes...\n"); - rv = TP_NewPipe(getter_AddRefs(in), getter_AddRefs(out), segSize, bufSize); - NS_ASSERTION(NS_SUCCEEDED(rv), "TP_NewPipe failed"); + if (gTrace) { + printf("Testing short writes...\n"); + } + rv = NS_NewPipe(getter_AddRefs(in), getter_AddRefs(out), segSize, bufSize); + EXPECT_TRUE(NS_SUCCEEDED(rv)); rv = TestShortWrites(in, out); - NS_ASSERTION(NS_SUCCEEDED(rv), "TestPipe failed"); + EXPECT_TRUE(NS_SUCCEEDED(rv)); } -//////////////////////////////////////////////////////////////////////////////// - -#if 0 -extern void -TestSegmentedBuffer(); -#endif - -int -main(int argc, char* argv[]) +TEST(Pipes, Main) { - nsresult rv; - - nsCOMPtr servMgr; - rv = NS_InitXPCOM2(getter_AddRefs(servMgr), nullptr, nullptr); - if (NS_FAILED(rv)) return rv; - - if (argc > 1 && nsCRT::strcmp(argv[1], "-trace") == 0) - gTrace = true; - - rv = TestChainedPipes(); - NS_ASSERTION(NS_SUCCEEDED(rv), "TestChainedPipes failed"); RunTests(16, 1); RunTests(4096, 16); - - servMgr = 0; - rv = NS_ShutdownXPCOM(nullptr); - NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed"); - - return 0; } - -//////////////////////////////////////////////////////////////////////////////// diff --git a/xpcom/tests/gtest/moz.build b/xpcom/tests/gtest/moz.build index 50fffc042896..a244bb605918 100644 --- a/xpcom/tests/gtest/moz.build +++ b/xpcom/tests/gtest/moz.build @@ -8,6 +8,7 @@ UNIFIED_SOURCES += [ 'TestCRT.cpp', 'TestEncoding.cpp', 'TestExpirationTracker.cpp', + 'TestPipes.cpp', 'TestSnappyStreams.cpp', 'TestStrings.cpp', ] diff --git a/xpcom/tests/moz.build b/xpcom/tests/moz.build index 131cacdf5452..de6a36ddeb2a 100644 --- a/xpcom/tests/moz.build +++ b/xpcom/tests/moz.build @@ -80,7 +80,6 @@ if CONFIG['MOZ_MEMORY']: # XXX Make these tests work in libxul builds. #CPP_UNIT_TESTS += [ -# 'TestPipes', # 'TestPriorityQueue', # 'TestStorageStream', # 'TestSynchronization', From db61f1b3f7248d14e084cf7e7e88f522bdf788dc Mon Sep 17 00:00:00 2001 From: Jonathan Watt Date: Tue, 20 Jan 2015 14:27:16 +0000 Subject: [PATCH 44/62] Bug 1086284 - Avoid using refcounting when determining an SVG-as-an-image's intrinsic size so that the image doesn't end up in the CC graph. r=dholbert --HG-- extra : rebase_source : e5a36117622a402eba9b2819b2ee2802ae70fc14 --- dom/svg/SVGSVGElement.cpp | 27 +++++++++++++++++++++++++++ dom/svg/SVGSVGElement.h | 8 ++++++++ image/src/SVGDocumentWrapper.cpp | 31 ++++++------------------------- 3 files changed, 41 insertions(+), 25 deletions(-) diff --git a/dom/svg/SVGSVGElement.cpp b/dom/svg/SVGSVGElement.cpp index 61b09878f5ce..6fe293300858 100644 --- a/dom/svg/SVGSVGElement.cpp +++ b/dom/svg/SVGSVGElement.cpp @@ -7,6 +7,7 @@ #include "mozilla/ArrayUtils.h" #include "mozilla/ContentEvents.h" #include "mozilla/EventDispatcher.h" +#include "mozilla/FloatingPoint.h" #include "mozilla/Likely.h" #include "nsGkAtoms.h" @@ -1247,5 +1248,31 @@ SVGSVGElement::ClearTransformProperty() return UnsetProperty(nsGkAtoms::transform); } +float +SVGSVGElement::GetIntrinsicWidth() +{ + if (mLengthAttributes[ATTR_WIDTH].IsPercentage()) { + return UnspecifiedNaN(); + } + // Passing |this| as a SVGSVGElement* invokes the variant of GetAnimValue + // that uses the passed argument as the context, but that's fine since we + // know the length isn't a percentage so the context won't be used (and we + // need to pass the element to be able to resolve em/ex units). + return std::max(mLengthAttributes[ATTR_WIDTH].GetAnimValue(this), 0.f); +} + +float +SVGSVGElement::GetIntrinsicHeight() +{ + if (mLengthAttributes[ATTR_HEIGHT].IsPercentage()) { + return UnspecifiedNaN(); + } + // Passing |this| as a SVGSVGElement* invokes the variant of GetAnimValue + // that uses the passed argument as the context, but that's fine since we + // know the length isn't a percentage so the context won't be used (and we + // need to pass the element to be able to resolve em/ex units). + return std::max(mLengthAttributes[ATTR_HEIGHT].GetAnimValue(this), 0.f); +} + } // namespace dom } // namespace mozilla diff --git a/dom/svg/SVGSVGElement.h b/dom/svg/SVGSVGElement.h index 30591581218d..0962d326c72b 100644 --- a/dom/svg/SVGSVGElement.h +++ b/dom/svg/SVGSVGElement.h @@ -147,6 +147,14 @@ public: // public helpers: + /** + * Returns the user-unit width/height if those dimensions are not specified + * as percentage values. If they are specified as percentage values then this + * element does not have intrinsic width/height and these methods return NaN. + */ + float GetIntrinsicWidth(); + float GetIntrinsicHeight(); + /** * Returns true if this element has a base/anim value for its "viewBox" * attribute that defines a viewBox rectangle with finite values, or diff --git a/image/src/SVGDocumentWrapper.cpp b/image/src/SVGDocumentWrapper.cpp index b7d086b243a8..c0a53f3b293c 100644 --- a/image/src/SVGDocumentWrapper.cpp +++ b/image/src/SVGDocumentWrapper.cpp @@ -6,6 +6,7 @@ #include "SVGDocumentWrapper.h" #include "mozilla/dom/Element.h" +#include "mozilla/FloatingPoint.h" #include "nsICategoryManager.h" #include "nsIChannel.h" #include "nsIContentViewer.h" @@ -76,34 +77,14 @@ SVGDocumentWrapper::GetWidthOrHeight(Dimension aDimension, NS_ABORT_IF_FALSE(rootElem, "root elem missing or of wrong type"); // Get the width or height SVG object - nsRefPtr domAnimLength; - if (aDimension == eWidth) { - domAnimLength = rootElem->Width(); - } else { - NS_ABORT_IF_FALSE(aDimension == eHeight, "invalid dimension"); - domAnimLength = rootElem->Height(); - } - NS_ENSURE_TRUE(domAnimLength, false); + float length = (aDimension == eWidth) ? rootElem->GetIntrinsicWidth() + : rootElem->GetIntrinsicHeight(); - // Get the animated value from the object - nsRefPtr domLength = domAnimLength->AnimVal(); - NS_ENSURE_TRUE(domLength, false); - - // Check if it's a percent value (and fail if so) - uint16_t unitType; - nsresult rv = domLength->GetUnitType(&unitType); - NS_ENSURE_SUCCESS(rv, false); - if (unitType == nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE) { - return false; + if (!IsFinite(length)) { + return false; // Percentage size } - // Non-percent value - woot! Grab it & return it. - float floatLength; - rv = domLength->GetValue(&floatLength); - NS_ENSURE_SUCCESS(rv, false); - - aResult = nsSVGUtils::ClampToInt(floatLength); - + aResult = nsSVGUtils::ClampToInt(length); return true; } From efd4391efb60e4add9cfcff20d6d3d1e94061d7a Mon Sep 17 00:00:00 2001 From: Jonathan Watt Date: Tue, 20 Jan 2015 19:12:54 +0000 Subject: [PATCH 45/62] Bug 1112533 - Get rid of SVGDocumentWrapper::GetWidthOrHeight(). r=dholbert --HG-- extra : rebase_source : c9f3af74bc0c93bd482873daf92f0a27152c5816 --- dom/svg/SVGSVGElement.cpp | 15 +++++----- dom/svg/SVGSVGElement.h | 11 +++---- image/src/SVGDocumentWrapper.cpp | 20 ------------- image/src/SVGDocumentWrapper.h | 15 ---------- image/src/VectorImage.cpp | 51 +++++++++++++++----------------- 5 files changed, 38 insertions(+), 74 deletions(-) diff --git a/dom/svg/SVGSVGElement.cpp b/dom/svg/SVGSVGElement.cpp index 6fe293300858..ef61c8582641 100644 --- a/dom/svg/SVGSVGElement.cpp +++ b/dom/svg/SVGSVGElement.cpp @@ -7,7 +7,6 @@ #include "mozilla/ArrayUtils.h" #include "mozilla/ContentEvents.h" #include "mozilla/EventDispatcher.h" -#include "mozilla/FloatingPoint.h" #include "mozilla/Likely.h" #include "nsGkAtoms.h" @@ -1248,30 +1247,32 @@ SVGSVGElement::ClearTransformProperty() return UnsetProperty(nsGkAtoms::transform); } -float +int32_t SVGSVGElement::GetIntrinsicWidth() { if (mLengthAttributes[ATTR_WIDTH].IsPercentage()) { - return UnspecifiedNaN(); + return -1; } // Passing |this| as a SVGSVGElement* invokes the variant of GetAnimValue // that uses the passed argument as the context, but that's fine since we // know the length isn't a percentage so the context won't be used (and we // need to pass the element to be able to resolve em/ex units). - return std::max(mLengthAttributes[ATTR_WIDTH].GetAnimValue(this), 0.f); + float width = mLengthAttributes[ATTR_WIDTH].GetAnimValue(this); + return nsSVGUtils::ClampToInt(width); } -float +int32_t SVGSVGElement::GetIntrinsicHeight() { if (mLengthAttributes[ATTR_HEIGHT].IsPercentage()) { - return UnspecifiedNaN(); + return -1; } // Passing |this| as a SVGSVGElement* invokes the variant of GetAnimValue // that uses the passed argument as the context, but that's fine since we // know the length isn't a percentage so the context won't be used (and we // need to pass the element to be able to resolve em/ex units). - return std::max(mLengthAttributes[ATTR_HEIGHT].GetAnimValue(this), 0.f); + float height = mLengthAttributes[ATTR_HEIGHT].GetAnimValue(this); + return nsSVGUtils::ClampToInt(height); } } // namespace dom diff --git a/dom/svg/SVGSVGElement.h b/dom/svg/SVGSVGElement.h index 0962d326c72b..34176ce26e00 100644 --- a/dom/svg/SVGSVGElement.h +++ b/dom/svg/SVGSVGElement.h @@ -148,12 +148,13 @@ public: // public helpers: /** - * Returns the user-unit width/height if those dimensions are not specified - * as percentage values. If they are specified as percentage values then this - * element does not have intrinsic width/height and these methods return NaN. + * Returns -1 if the width/height is a percentage, else returns the user unit + * length clamped to fit in a int32_t. + * XXX see bug 1112533 comment 3 - we should fix drawImage so that we can + * change these methods to make zero the error flag for percentages. */ - float GetIntrinsicWidth(); - float GetIntrinsicHeight(); + int32_t GetIntrinsicWidth(); + int32_t GetIntrinsicHeight(); /** * Returns true if this element has a base/anim value for its "viewBox" diff --git a/image/src/SVGDocumentWrapper.cpp b/image/src/SVGDocumentWrapper.cpp index c0a53f3b293c..dc2d6d894ab5 100644 --- a/image/src/SVGDocumentWrapper.cpp +++ b/image/src/SVGDocumentWrapper.cpp @@ -6,7 +6,6 @@ #include "SVGDocumentWrapper.h" #include "mozilla/dom/Element.h" -#include "mozilla/FloatingPoint.h" #include "nsICategoryManager.h" #include "nsIChannel.h" #include "nsIContentViewer.h" @@ -69,25 +68,6 @@ SVGDocumentWrapper::DestroyViewer() } } -bool -SVGDocumentWrapper::GetWidthOrHeight(Dimension aDimension, - int32_t& aResult) -{ - SVGSVGElement* rootElem = GetRootSVGElem(); - NS_ABORT_IF_FALSE(rootElem, "root elem missing or of wrong type"); - - // Get the width or height SVG object - float length = (aDimension == eWidth) ? rootElem->GetIntrinsicWidth() - : rootElem->GetIntrinsicHeight(); - - if (!IsFinite(length)) { - return false; // Percentage size - } - - aResult = nsSVGUtils::ClampToInt(length); - return true; -} - nsIFrame* SVGDocumentWrapper::GetRootLayoutFrame() { diff --git a/image/src/SVGDocumentWrapper.h b/image/src/SVGDocumentWrapper.h index 4904592b0eed..81923768a428 100644 --- a/image/src/SVGDocumentWrapper.h +++ b/image/src/SVGDocumentWrapper.h @@ -52,21 +52,6 @@ public: eHeight }; - /** - * Looks up the value of the wrapped SVG document's |width| or |height| - * attribute in CSS pixels, and returns it by reference. If the document has - * a percent value for the queried attribute, then this method fails - * (returns false). - * - * @param aDimension Indicates whether the width or height is desired. - * @param[out] aResult If this method succeeds, then this outparam will be - populated with the width or height in CSS pixels. - * @return false to indicate failure, if the queried attribute has a - * percent value. Otherwise, true. - * - */ - bool GetWidthOrHeight(Dimension aDimension, int32_t& aResult); - /** * Returns the wrapped document, or nullptr on failure. (No AddRef.) */ diff --git a/image/src/VectorImage.cpp b/image/src/VectorImage.cpp index df5cb642c336..76d62500ff2a 100644 --- a/image/src/VectorImage.cpp +++ b/image/src/VectorImage.cpp @@ -472,17 +472,14 @@ NS_IMETHODIMP VectorImage::GetWidth(int32_t* aWidth) { if (mError || !mIsFullyLoaded) { - *aWidth = 0; - return NS_ERROR_FAILURE; + *aWidth = -1; + } else { + SVGSVGElement* rootElem = mSVGDocumentWrapper->GetRootSVGElem(); + MOZ_ASSERT(rootElem, "Should have a root SVG elem, since we finished " + "loading without errors"); + *aWidth = rootElem->GetIntrinsicWidth(); } - - if (!mSVGDocumentWrapper->GetWidthOrHeight(SVGDocumentWrapper::eWidth, - *aWidth)) { - *aWidth = 0; - return NS_ERROR_FAILURE; - } - - return NS_OK; + return *aWidth >= 0 ? NS_OK : NS_ERROR_FAILURE; } //****************************************************************************** @@ -541,17 +538,14 @@ NS_IMETHODIMP VectorImage::GetHeight(int32_t* aHeight) { if (mError || !mIsFullyLoaded) { - *aHeight = 0; - return NS_ERROR_FAILURE; + *aHeight = -1; + } else { + SVGSVGElement* rootElem = mSVGDocumentWrapper->GetRootSVGElem(); + MOZ_ASSERT(rootElem, "Should have a root SVG elem, since we finished " + "loading without errors"); + *aHeight = rootElem->GetIntrinsicHeight(); } - - if (!mSVGDocumentWrapper->GetWidthOrHeight(SVGDocumentWrapper::eHeight, - *aHeight)) { - *aHeight = 0; - return NS_ERROR_FAILURE; - } - - return NS_OK; + return *aHeight >= 0 ? NS_OK : NS_ERROR_FAILURE; } //****************************************************************************** @@ -663,17 +657,20 @@ VectorImage::GetFrame(uint32_t aWhichFrame, if (aWhichFrame > FRAME_MAX_VALUE) return nullptr; - if (mError) + if (mError || !mIsFullyLoaded) return nullptr; // Look up height & width // ---------------------- - nsIntSize imageIntSize; - if (!mSVGDocumentWrapper->GetWidthOrHeight(SVGDocumentWrapper::eWidth, - imageIntSize.width) || - !mSVGDocumentWrapper->GetWidthOrHeight(SVGDocumentWrapper::eHeight, - imageIntSize.height)) { - // We'll get here if our SVG doc has a percent-valued width or height. + SVGSVGElement* svgElem = mSVGDocumentWrapper->GetRootSVGElem(); + MOZ_ASSERT(svgElem, "Should have a root SVG elem, since we finished " + "loading without errors"); + nsIntSize imageIntSize(svgElem->GetIntrinsicWidth(), + svgElem->GetIntrinsicHeight()); + + if (imageIntSize.IsEmpty()) { + // We'll get here if our SVG doc has a percent-valued or negative width or + // height. return nullptr; } From 609bc285a8b65f8e57c661bf6381777197eb2456 Mon Sep 17 00:00:00 2001 From: Jonathan Watt Date: Wed, 21 Jan 2015 16:23:28 +0000 Subject: [PATCH 46/62] Bug 1123939 - Convert nsComboboxControlFrame::PaintFocus to Moz2D. r=Bas --HG-- extra : rebase_source : 5f5bce0cb6e403b9479fd13f9cdff9646d67d268 --- layout/forms/nsComboboxControlFrame.cpp | 21 +++++++++------------ layout/forms/nsComboboxControlFrame.h | 10 +++++++++- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp index 175013a135b9..b59dcd8116f8 100644 --- a/layout/forms/nsComboboxControlFrame.cpp +++ b/layout/forms/nsComboboxControlFrame.cpp @@ -1469,7 +1469,7 @@ void nsDisplayComboboxFocus::Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) { static_cast(mFrame) - ->PaintFocus(*aCtx, ToReferenceFrame()); + ->PaintFocus(*aCtx->GetDrawTarget(), ToReferenceFrame()); } void @@ -1511,7 +1511,7 @@ nsComboboxControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, DisplaySelectionOverlay(aBuilder, aLists.Content()); } -void nsComboboxControlFrame::PaintFocus(nsRenderingContext& aRenderingContext, +void nsComboboxControlFrame::PaintFocus(DrawTarget& aDrawTarget, nsPoint aPt) { /* Do we need to do anything? */ @@ -1519,13 +1519,12 @@ void nsComboboxControlFrame::PaintFocus(nsRenderingContext& aRenderingContext, if (eventStates.HasState(NS_EVENT_STATE_DISABLED) || sFocused != this) return; - gfxContext* gfx = aRenderingContext.ThebesContext(); + int32_t appUnitsPerDevPixel = PresContext()->AppUnitsPerDevPixel(); - gfx->Save(); nsRect clipRect = mDisplayFrame->GetRect() + aPt; - gfx->Clip(NSRectToSnappedRect(clipRect, - PresContext()->AppUnitsPerDevPixel(), - *aRenderingContext.GetDrawTarget())); + aDrawTarget.PushClipRect(NSRectToSnappedRect(clipRect, + appUnitsPerDevPixel, + aDrawTarget)); // REVIEW: Why does the old code paint mDisplayFrame again? We've // already painted it in the children above. So clipping it here won't do @@ -1540,12 +1539,10 @@ void nsComboboxControlFrame::PaintFocus(nsRenderingContext& aRenderingContext, nscoord onePixel = nsPresContext::CSSPixelsToAppUnits(1); clipRect.width -= onePixel; clipRect.height -= onePixel; - Rect r = - ToRect(nsLayoutUtils::RectToGfxRect(clipRect, PresContext()->AppUnitsPerDevPixel())); - StrokeSnappedEdgesOfRect(r, *aRenderingContext.GetDrawTarget(), - color, strokeOptions); + Rect r = ToRect(nsLayoutUtils::RectToGfxRect(clipRect, appUnitsPerDevPixel)); + StrokeSnappedEdgesOfRect(r, aDrawTarget, color, strokeOptions); - gfx->Restore(); + aDrawTarget.PopClip(); } //--------------------------------------------------------- diff --git a/layout/forms/nsComboboxControlFrame.h b/layout/forms/nsComboboxControlFrame.h index cfa29eb2265a..39fa6ce82d4b 100644 --- a/layout/forms/nsComboboxControlFrame.h +++ b/layout/forms/nsComboboxControlFrame.h @@ -37,6 +37,12 @@ class nsComboboxDisplayFrame; class nsIDOMEventListener; class nsIScrollableFrame; +namespace mozilla { +namespace gfx { +class DrawTarget; +} +} + class nsComboboxControlFrame MOZ_FINAL : public nsBlockFrame, public nsIFormControlFrame, public nsIComboboxControlFrame, @@ -45,6 +51,8 @@ class nsComboboxControlFrame MOZ_FINAL : public nsBlockFrame, public nsIRollupListener, public nsIStatefulFrame { + typedef mozilla::gfx::DrawTarget DrawTarget; + public: friend nsContainerFrame* NS_NewComboboxControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, @@ -84,7 +92,7 @@ public: const nsRect& aDirtyRect, const nsDisplayListSet& aLists) MOZ_OVERRIDE; - void PaintFocus(nsRenderingContext& aRenderingContext, nsPoint aPt); + void PaintFocus(DrawTarget& aDrawTarget, nsPoint aPt); // XXXbz this is only needed to prevent the quirk percent height stuff from // leaking out of the combobox. We may be able to get rid of this as more From e64fcabbe1899b19210f0fac760297bc5f8525e5 Mon Sep 17 00:00:00 2001 From: Jonathan Watt Date: Wed, 21 Jan 2015 16:23:30 +0000 Subject: [PATCH 47/62] Bug 1123946 - Convert SVGTextDrawPathCallbacks filling to Moz2D. r=Bas --HG-- extra : rebase_source : fc52ac0a4cb4e64e76e11984b36ba04ee42abdfe --- layout/svg/SVGTextFrame.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/layout/svg/SVGTextFrame.cpp b/layout/svg/SVGTextFrame.cpp index cbd60543e193..927bfe5636e9 100644 --- a/layout/svg/SVGTextFrame.cpp +++ b/layout/svg/SVGTextFrame.cpp @@ -2916,8 +2916,9 @@ void SVGTextDrawPathCallbacks::HandleTextGeometry() { if (IsClipPathChild()) { - gfx->SetColor(gfxRGBA(1.0f, 1.0f, 1.0f, 1.0f)); - gfx->Fill(); + RefPtr path = gfx->GetPath(); + ColorPattern white(Color(1.f, 1.f, 1.f, 1.f)); // for masking, so no ToDeviceColor + gfx->GetDrawTarget()->Fill(path, white); } else { // Normal painting. gfxContextMatrixAutoSaveRestore saveMatrix(gfx); @@ -2984,11 +2985,15 @@ SVGTextDrawPathCallbacks::FillGeometry() GeneralPattern fillPattern; MakeFillPattern(&fillPattern); if (fillPattern.GetPattern()) { - gfx->SetFillRule( - nsSVGUtils::ToFillRule( - IsClipPathChild() ? - mFrame->StyleSVG()->mClipRule : mFrame->StyleSVG()->mFillRule)); - gfx->Fill(fillPattern); + RefPtr path = gfx->GetPath(); + FillRule fillRule = nsSVGUtils::ToFillRule(IsClipPathChild() ? + mFrame->StyleSVG()->mClipRule : + mFrame->StyleSVG()->mFillRule); + if (fillRule != path->GetFillRule()) { + RefPtr builder = path->CopyToBuilder(fillRule); + path = builder->Finish(); + } + gfx->GetDrawTarget()->Fill(path, fillPattern); } } From 5fc11331954f03c4bd08a959e38cd479ca67b856 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Tue, 20 Jan 2015 23:00:08 -0500 Subject: [PATCH 48/62] Bug 1124047 - Move TestPriorityQueue.cpp to gtest and enable it; r=froydnj --- xpcom/tests/{ => gtest}/TestPriorityQueue.cpp | 42 +++++-------------- xpcom/tests/gtest/moz.build | 1 + xpcom/tests/moz.build | 1 - 3 files changed, 12 insertions(+), 32 deletions(-) rename xpcom/tests/{ => gtest}/TestPriorityQueue.cpp (60%) diff --git a/xpcom/tests/TestPriorityQueue.cpp b/xpcom/tests/gtest/TestPriorityQueue.cpp similarity index 60% rename from xpcom/tests/TestPriorityQueue.cpp rename to xpcom/tests/gtest/TestPriorityQueue.cpp index 74e86f79effa..7aec8ca009a7 100644 --- a/xpcom/tests/TestPriorityQueue.cpp +++ b/xpcom/tests/gtest/TestPriorityQueue.cpp @@ -7,6 +7,7 @@ #include "nsTPriorityQueue.h" #include #include +#include "gtest/gtest.h" template void @@ -16,32 +17,13 @@ CheckPopSequence(const nsTPriorityQueue& aQueue, nsTPriorityQueue copy(aQueue); for (uint32_t i = 0; i < aSequenceLength; i++) { - if (copy.IsEmpty()) { - printf("Number of elements in the queue is too short by %d.\n", - aSequenceLength - i); - exit(-1); - } + EXPECT_FALSE(copy.IsEmpty()); T pop = copy.Pop(); - if (pop != aExpectedSequence[i]) { - printf("Unexpected value in pop sequence at position %d\n", i); - printf(" Sequence:"); - for (size_t j = 0; j < aSequenceLength; j++) { - printf(" %d", aExpectedSequence[j]); - if (j == i) { - printf("**"); - } - } - printf("\n ** Got %d instead\n", pop); - exit(-1); - } + EXPECT_EQ(pop, aExpectedSequence[i]); } - if (!copy.IsEmpty()) { - printf("Number of elements in the queue is too long by %d.\n", - copy.Length()); - exit(-1); - } + EXPECT_TRUE(copy.IsEmpty()); } template @@ -52,11 +34,11 @@ public: } }; -int main() +TEST(PriorityQueue, Main) { nsTPriorityQueue queue; - NS_ABORT_IF_FALSE(queue.IsEmpty(), "Queue not initially empty"); + EXPECT_TRUE(queue.IsEmpty()); queue.Push(8); queue.Push(6); @@ -64,9 +46,9 @@ int main() queue.Push(2); queue.Push(10); queue.Push(6); - NS_ABORT_IF_FALSE(queue.Top() == 2, "Unexpected queue top"); - NS_ABORT_IF_FALSE(queue.Length() == 6, "Unexpected queue length"); - NS_ABORT_IF_FALSE(!queue.IsEmpty(), "Queue empty when populated"); + EXPECT_EQ(queue.Top(), 2); + EXPECT_EQ(queue.Length(), 6u); + EXPECT_FALSE(queue.IsEmpty()); int expected[] = { 2, 4, 6, 6, 8, 10 }; CheckPopSequence(queue, expected, sizeof(expected) / sizeof(expected[0])); @@ -77,7 +59,7 @@ int main() CheckPopSequence(queue2, expected, sizeof(expected) / sizeof(expected[0])); queue.Clear(); - NS_ABORT_IF_FALSE(queue.IsEmpty(), "Queue not emptied by Clear"); + EXPECT_TRUE(queue.IsEmpty()); // try same sequence with a max heap nsTPriorityQueue > max_queue; @@ -87,10 +69,8 @@ int main() max_queue.Push(2); max_queue.Push(10); max_queue.Push(6); - NS_ABORT_IF_FALSE(max_queue.Top() == 10, "Unexpected queue top for max heap"); + EXPECT_EQ(max_queue.Top(), 10); int expected_max[] = { 10, 8, 6, 6, 4, 2 }; CheckPopSequence(max_queue, expected_max, sizeof(expected_max) / sizeof(expected_max[0])); - - return 0; } diff --git a/xpcom/tests/gtest/moz.build b/xpcom/tests/gtest/moz.build index a244bb605918..2be3491191d8 100644 --- a/xpcom/tests/gtest/moz.build +++ b/xpcom/tests/gtest/moz.build @@ -9,6 +9,7 @@ UNIFIED_SOURCES += [ 'TestEncoding.cpp', 'TestExpirationTracker.cpp', 'TestPipes.cpp', + 'TestPriorityQueue.cpp', 'TestSnappyStreams.cpp', 'TestStrings.cpp', ] diff --git a/xpcom/tests/moz.build b/xpcom/tests/moz.build index de6a36ddeb2a..a451a102923e 100644 --- a/xpcom/tests/moz.build +++ b/xpcom/tests/moz.build @@ -80,7 +80,6 @@ if CONFIG['MOZ_MEMORY']: # XXX Make these tests work in libxul builds. #CPP_UNIT_TESTS += [ -# 'TestPriorityQueue', # 'TestStorageStream', # 'TestSynchronization', # 'TestTArray', From 875d20f5be838ff88df84708e188336feff4248a Mon Sep 17 00:00:00 2001 From: Geoff Brown Date: Wed, 21 Jan 2015 09:26:38 -0700 Subject: [PATCH 49/62] Bug 1123443 - Add in-tree test configuration for Android 4.4 emulator unit tests; r=armenzg --- .../mozharness/android_arm_4_4_config.py | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 testing/config/mozharness/android_arm_4_4_config.py diff --git a/testing/config/mozharness/android_arm_4_4_config.py b/testing/config/mozharness/android_arm_4_4_config.py new file mode 100644 index 000000000000..0d2f0b0588b8 --- /dev/null +++ b/testing/config/mozharness/android_arm_4_4_config.py @@ -0,0 +1,105 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +config = { + "suite_definitions": { + "mochitest": { + "run_filename": "runtestsremote.py", + "testsdir": "mochitest", + "options": ["--autorun", "--close-when-done", "--dm_trans=adb", + "--console-level=INFO", "--app=%(app)s", "--remote-webserver=%(remote_webserver)s", + "--xre-path=%(xre_path)s", "--utility-path=%(utility_path)s", + "--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s", + "--certificate-path=%(certs_path)s", "--symbols-path=%(symbols_path)s", + "--quiet", "--log-raw=%(raw_log_file)s", + "--total-chunks=16", + "--run-only-tests=android23.json", + ], + }, + "mochitest-gl": { + "run_filename": "runtestsremote.py", + "testsdir": "mochitest", + "options": ["--autorun", "--close-when-done", "--dm_trans=adb", + "--console-level=INFO", "--app=%(app)s", "--remote-webserver=%(remote_webserver)s", + "--xre-path=%(xre_path)s", "--utility-path=%(utility_path)s", + "--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s", + "--certificate-path=%(certs_path)s", "--symbols-path=%(symbols_path)s", + "--quiet", "--log-raw=%(raw_log_file)s", + "--total-chunks=2", + "--test-manifest=gl.json", + ], + }, + "robocop": { + "run_filename": "runtestsremote.py", + "testsdir": "mochitest", + "options": ["--autorun", "--close-when-done", "--dm_trans=adb", + "--console-level=INFO", "--app=%(app)s", "--remote-webserver=%(remote_webserver)s", + "--xre-path=%(xre_path)s", "--utility-path=%(utility_path)s", + "--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s", + "--certificate-path=%(certs_path)s", "--symbols-path=%(symbols_path)s", + "--quiet", "--log-raw=%(raw_log_file)s", + "--total-chunks=4", + "--robocop-path=../..", + "--robocop-ids=fennec_ids.txt", + "--robocop=robocop.ini", + ], + }, + "reftest": { + "run_filename": "remotereftest.py", + "testsdir": "reftest", + "options": [ "--app=%(app)s", "--ignore-window-size", + "--dm_trans=adb", + "--bootstrap", + "--remote-webserver=%(remote_webserver)s", "--xre-path=%(xre_path)s", + "--utility-path=%(utility_path)s", "--http-port=%(http_port)s", + "--ssl-port=%(ssl_port)s", "--httpd-path", "%(modules_dir)s", + "--symbols-path=%(symbols_path)s", + "--total-chunks=16", + "tests/layout/reftests/reftest.list", + ], + }, + "crashtest": { + "run_filename": "remotereftest.py", + "testsdir": "reftest", + "options": [ "--app=%(app)s", "--ignore-window-size", + "--dm_trans=adb", + "--bootstrap", + "--remote-webserver=%(remote_webserver)s", "--xre-path=%(xre_path)s", + "--utility-path=%(utility_path)s", "--http-port=%(http_port)s", + "--ssl-port=%(ssl_port)s", "--httpd-path", "%(modules_dir)s", + "--symbols-path=%(symbols_path)s", + "--total-chunks=2", + "tests/testing/crashtest/crashtests.list", + ], + }, + "jsreftest": { + "run_filename": "remotereftest.py", + "testsdir": "reftest", + "options": [ "--app=%(app)s", "--ignore-window-size", + "--dm_trans=adb", + "--bootstrap", + "--remote-webserver=%(remote_webserver)s", "--xre-path=%(xre_path)s", + "--utility-path=%(utility_path)s", "--http-port=%(http_port)s", + "--ssl-port=%(ssl_port)s", "--httpd-path", "%(modules_dir)s", + "--symbols-path=%(symbols_path)s", + "../jsreftest/tests/jstests.list", + "--total-chunks=6", + "--extra-profile-file=jsreftest/tests/user.js", + ], + }, + "xpcshell": { + "run_filename": "remotexpcshelltests.py", + "testsdir": "xpcshell", + "options": [ + "--dm_trans=adb", + "--xre-path=%(xre_path)s", "--testing-modules-dir=%(modules_dir)s", + "--apk=%(installer_path)s", "--no-logfiles", + "--symbols-path=%(symbols_path)s", + "--manifest=tests/xpcshell.ini", + "--log-raw=%(raw_log_file)s", + "--total-chunks=3", + ], + }, + }, # end suite_definitions +} From c9abc4481d50a26b6ef8e94405089bddec641b16 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Tue, 20 Jan 2015 23:09:58 -0500 Subject: [PATCH 50/62] Bug 1124048 - Move TestStorageStream.cpp to gtest and enable it; r=froydnj --- xpcom/tests/{ => gtest}/TestStorageStream.cpp | 58 +++++++------------ xpcom/tests/gtest/moz.build | 1 + xpcom/tests/moz.build | 1 - 3 files changed, 21 insertions(+), 39 deletions(-) rename xpcom/tests/{ => gtest}/TestStorageStream.cpp (71%) diff --git a/xpcom/tests/TestStorageStream.cpp b/xpcom/tests/gtest/TestStorageStream.cpp similarity index 71% rename from xpcom/tests/TestStorageStream.cpp rename to xpcom/tests/gtest/TestStorageStream.cpp index 7b1dad018d1d..f8a92fd69638 100644 --- a/xpcom/tests/TestStorageStream.cpp +++ b/xpcom/tests/gtest/TestStorageStream.cpp @@ -7,8 +7,9 @@ #include "nsIInputStream.h" #include "nsIOutputStream.h" #include "nsCOMPtr.h" +#include "gtest/gtest.h" -int main() +TEST(TestStorageStreams, Main) { char kData[4096]; memset(kData, 0, sizeof(kData)); @@ -17,94 +18,75 @@ int main() nsCOMPtr stor; rv = NS_NewStorageStream(4096, UINT32_MAX, getter_AddRefs(stor)); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); nsCOMPtr out; rv = stor->GetOutputStream(0, getter_AddRefs(out)); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); uint32_t n; rv = out->Write(kData, sizeof(kData), &n); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); rv = out->Write(kData, sizeof(kData), &n); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); rv = out->Close(); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); out = nullptr; - + nsCOMPtr in; rv = stor->NewInputStream(0, getter_AddRefs(in)); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); char buf[4096]; // consume contents of input stream do { rv = in->Read(buf, sizeof(buf), &n); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); } while (n != 0); rv = in->Close(); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); in = nullptr; // now, write 3 more full 4k segments + 11 bytes, starting at 8192 // total written equals 20491 bytes rv = stor->GetOutputStream(8192, getter_AddRefs(out)); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); rv = out->Write(kData, sizeof(kData), &n); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); rv = out->Write(kData, sizeof(kData), &n); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); rv = out->Write(kData, sizeof(kData), &n); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); rv = out->Write(kData, 11, &n); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); rv = out->Close(); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); out = nullptr; // now, read all rv = stor->NewInputStream(0, getter_AddRefs(in)); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); // consume contents of input stream do { rv = in->Read(buf, sizeof(buf), &n); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); } while (n != 0); rv = in->Close(); - if (NS_FAILED(rv)) - return -1; + EXPECT_TRUE(NS_SUCCEEDED(rv)); in = nullptr; - - return 0; } diff --git a/xpcom/tests/gtest/moz.build b/xpcom/tests/gtest/moz.build index 2be3491191d8..e0e23b953d20 100644 --- a/xpcom/tests/gtest/moz.build +++ b/xpcom/tests/gtest/moz.build @@ -11,6 +11,7 @@ UNIFIED_SOURCES += [ 'TestPipes.cpp', 'TestPriorityQueue.cpp', 'TestSnappyStreams.cpp', + 'TestStorageStream.cpp', 'TestStrings.cpp', ] diff --git a/xpcom/tests/moz.build b/xpcom/tests/moz.build index a451a102923e..ad73e74f82e2 100644 --- a/xpcom/tests/moz.build +++ b/xpcom/tests/moz.build @@ -80,7 +80,6 @@ if CONFIG['MOZ_MEMORY']: # XXX Make these tests work in libxul builds. #CPP_UNIT_TESTS += [ -# 'TestStorageStream', # 'TestSynchronization', # 'TestTArray', # 'TestThreadPool', From eb37c238cfafdcff6d56083fd73faa4413696202 Mon Sep 17 00:00:00 2001 From: Michael Lopez Date: Wed, 24 Dec 2014 17:50:00 -0500 Subject: [PATCH 51/62] Bug 822177 - Don't delete site data for disabled addons. r=bsmedberg --- dom/plugins/base/nsPluginHost.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp index 0fd634003cb0..3720cc8e7cc4 100644 --- a/dom/plugins/base/nsPluginHost.cpp +++ b/dom/plugins/base/nsPluginHost.cpp @@ -1557,6 +1557,10 @@ nsPluginHost::ClearSiteData(nsIPluginTag* plugin, const nsACString& domain, nsPluginTag* tag = static_cast(plugin); + if (!tag->IsEnabled()) { + return NS_ERROR_NOT_AVAILABLE; + } + // We only ensure support for clearing Flash site data for now. // We will also attempt to clear data for any plugin that happens // to be loaded already. From dd25a84c04a414afaaaeeaf38fc78d74cc3f6413 Mon Sep 17 00:00:00 2001 From: Jan-Ivar Bruaroey Date: Tue, 20 Jan 2015 10:08:00 -0500 Subject: [PATCH 52/62] Bug 1115998 - Support RTCIceServer.urls (plural) array form. r=smaug, r=mt --- CLOBBER | 3 +- dom/media/PeerConnection.js | 60 ++++++++------ .../test_peerConnection_bug825703.html | 82 ++++++++----------- dom/webidl/RTCConfiguration.webidl | 3 +- .../src/peerconnection/PeerConnectionImpl.cpp | 28 +++++-- .../src/peerconnection/PeerConnectionImpl.h | 4 + mobile/android/modules/TabMirror.jsm | 2 +- modules/libpref/init/all.js | 2 +- 8 files changed, 101 insertions(+), 83 deletions(-) diff --git a/CLOBBER b/CLOBBER index c9cf3ca2da40..eaa1f125c045 100644 --- a/CLOBBER +++ b/CLOBBER @@ -22,5 +22,4 @@ # changes to stick? As of bug 928195, this shouldn't be necessary! Please # don't change CLOBBER for WebIDL changes any more. -Bug 1100184 - Lots of file moves from the /netwerk flattening and zero faith -in the build system to properly handle them. +Bug 1115998 - (DOMString or sequence) needs binding flush (Bug 1103153) diff --git a/dom/media/PeerConnection.js b/dom/media/PeerConnection.js index f388d52973ab..6350afd58a66 100644 --- a/dom/media/PeerConnection.js +++ b/dom/media/PeerConnection.js @@ -323,13 +323,24 @@ RTCPeerConnection.prototype = { init: function(win) { this._win = win; }, __init: function(rtcConfig) { + this._winID = this._win.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindowUtils).currentInnerWindowID; + if (!rtcConfig.iceServers || !Services.prefs.getBoolPref("media.peerconnection.use_document_iceservers")) { rtcConfig.iceServers = JSON.parse(Services.prefs.getCharPref("media.peerconnection.default_iceservers")); } - this._winID = this._win.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindowUtils).currentInnerWindowID; + // Normalize iceServers input + rtcConfig.iceServers.forEach(server => { + if (typeof server.urls === "string") { + server.urls = [server.urls]; + } else if (!server.urls && server.url) { + // TODO: Remove support for legacy iceServer.url eventually (Bug 1116766) + server.urls = [server.url]; + this.logWarning("RTCIceServer.url is deprecated! Use urls instead.", null, 0); + } + }); this._mustValidateRTCConfiguration(rtcConfig, "RTCPeerConnection constructor passed invalid RTCConfiguration"); if (_globalPCList._networkdown || !this._win.navigator.onLine) { @@ -432,10 +443,11 @@ RTCPeerConnection.prototype = { }, /** - * An RTCConfiguration looks like this: + * An RTCConfiguration may look like this: * - * { "iceServers": [ { url:"stun:stun.example.org" }, - * { url:"turn:turn.example.org", + * { "iceServers": [ { urls: "stun:stun.example.org", }, + * { url: "stun:stun.example.org", }, // deprecated version + * { urls: ["turn:turn1.x.org", "turn:turn2.x.org"], * username:"jib", credential:"mypass"} ] } * * WebIDL normalizes structure for us, so we test well-formed stun/turn urls, @@ -456,27 +468,29 @@ RTCPeerConnection.prototype = { }; rtcConfig.iceServers.forEach(server => { - if (!server.url) { - throw new this._win.DOMException(msg + " - missing url", "InvalidAccessError"); + if (!server.urls) { + throw new this._win.DOMException(msg + " - missing urls", "InvalidAccessError"); } - let url = nicerNewURI(server.url); - if (url.scheme in { turn:1, turns:1 }) { - if (!server.username) { - throw new this._win.DOMException(msg + " - missing username: " + server.url, - "InvalidAccessError"); + server.urls.forEach(urlStr => { + let url = nicerNewURI(urlStr); + if (url.scheme in { turn:1, turns:1 }) { + if (!server.username) { + throw new this._win.DOMException(msg + " - missing username: " + urlStr, + "InvalidAccessError"); + } + if (!server.credential) { + throw new this._win.DOMException(msg + " - missing credential: " + urlStr, + "InvalidAccessError"); + } } - if (!server.credential) { - throw new this._win.DOMException(msg + " - missing credential: " + server.url, - "InvalidAccessError"); + else if (!(url.scheme in { stun:1, stuns:1 })) { + throw new this._win.DOMException(msg + " - improper scheme: " + url.scheme, + "SyntaxError"); } - } - else if (!(url.scheme in { stun:1, stuns:1 })) { - throw new this._win.DOMException(msg + " - improper scheme: " + url.scheme, - "SyntaxError"); - } - if (url.scheme in { stuns:1, turns:1 }) { - this.logWarning(url.scheme.toUpperCase() + " is not yet supported.", null, 0); - } + if (url.scheme in { stuns:1, turns:1 }) { + this.logWarning(url.scheme.toUpperCase() + " is not yet supported.", null, 0); + } + }); }); }, diff --git a/dom/media/tests/mochitest/test_peerConnection_bug825703.html b/dom/media/tests/mochitest/test_peerConnection_bug825703.html index 84d43efbf2e2..9b5e729a9a85 100644 --- a/dom/media/tests/mochitest/test_peerConnection_bug825703.html +++ b/dom/media/tests/mochitest/test_peerConnection_bug825703.html @@ -14,78 +14,66 @@ title: "RTCConfiguration valid/invalid permutations" }); - makePC = function (config, expect_success) { - var exception = null; - var pc = null; - - try { - pc = new mozRTCPeerConnection(config); - } catch (e) { - exception = e; - } - if (pc !== null) { - pc.close(); - } - pc = null - - if (expect_success) { - ok(!exception, "mozRTCPeerConnection(" + - JSON.stringify(config) + ") succeeds"); - } else { - ok(exception, "mozRTCPeerConnection(" + - JSON.stringify(config) + ") throws"); - } + makePC = (config, expected_error) => { + var exception; + try { + new mozRTCPeerConnection(config).close(); + } catch (e) { + exception = e; + } + is((exception? exception.name : "success"), expected_error || "success", + "mozRTCPeerConnection(" + JSON.stringify(config) + ")"); } // This is a test of the iceServers parsing code + readable errors runNetworkTest(function () { - var pcs = null; var exception = null; - var config; try { - pcs = new mozRTCPeerConnection(); + new mozRTCPeerConnection().close(); } catch (e) { exception = e; } ok(!exception, "mozRTCPeerConnection() succeeds"); - if (pcs !== null) { - pcs.close(); - } - pcs = null; exception = null; - makePC(1, false); + makePC(); - makePC({}, true); + makePC(1, "TypeError"); - makePC({ iceServers: [] }, true); + makePC({}); - makePC({ iceServers: [{ url:"" }] }, false); + makePC({ iceServers: [] }); + + makePC({ iceServers: [{ urls:"" }] }, "SyntaxError"); makePC({ iceServers: [ - { url:"stun:127.0.0.1" }, - { url:"stuns:localhost", foo:"" }, - { url:"turn:[::1]:3478", username:"p", credential:"p" }, - { url:"turns:localhost:3478?transport=udp", username:"p", credential:"p" } - ]}, true); + { urls:"stun:127.0.0.1" }, + { urls:"stun:localhost", foo:"" }, + { urls: ["stun:127.0.0.1", "stun:localhost"] }, + { urls:"stuns:localhost", foo:"" }, + { urls:"turn:[::1]:3478", username:"p", credential:"p" }, + { urls:"turn:localhost:3478?transport=udp", username:"p", credential:"p" }, + { urls: ["turn:[::1]:3478", "turn:localhost"], username:"p", credential:"p" }, + { urls:"turns:localhost:3478?transport=udp", username:"p", credential:"p" }, + { url:"stun:localhost", foo:"" }, + { url:"turn:localhost", username:"p", credential:"p" } + ]}); - makePC({ iceServers: [{ url:"turns:localhost:3478", username:"p" }] }, false); + makePC({ iceServers: [{ urls: ["stun:127.0.0.1", ""] }] }, "SyntaxError"); - makePC({ iceServers: [{ url:"turns:localhost:3478", credential:"p" }] }, false); + makePC({ iceServers: [{ urls:"turns:localhost:3478", username:"p" }] }, "InvalidAccessError"); - makePC({ iceServers: [{ url:"http:0.0.0.0" }] }, false); + makePC({ iceServers: [{ url:"turns:localhost:3478", credential:"p" }] }, "InvalidAccessError"); + + makePC({ iceServers: [{ urls:"http:0.0.0.0" }] }, "SyntaxError"); try { - pcs = new mozRTCPeerConnection({ iceServers: [{ url:"http:0.0.0.0" }] }); + new mozRTCPeerConnection({ iceServers: [{ url:"http:0.0.0.0" }] }).close(); } catch (e) { - ok(e.message.indexOf("http") > 0, - "mozRTCPeerConnection() constructor has readable exceptions"); + ok(e.message.indexOf("http") > 0, + "mozRTCPeerConnection() constructor has readable exceptions"); } - if (pcs !== null) { - pcs.close(); - } - pcs = null; networkTestFinished(); }); diff --git a/dom/webidl/RTCConfiguration.webidl b/dom/webidl/RTCConfiguration.webidl index 7553fcb4da9b..02e7c8e465e8 100644 --- a/dom/webidl/RTCConfiguration.webidl +++ b/dom/webidl/RTCConfiguration.webidl @@ -8,7 +8,8 @@ */ dictionary RTCIceServer { - DOMString url; + (DOMString or sequence) urls; + DOMString url; //deprecated DOMString? credential = null; DOMString? username = null; }; diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp index b8112fe2f65d..34b1c46136d8 100644 --- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp +++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp @@ -468,20 +468,32 @@ PeerConnectionImpl::ConvertRTCConfiguration(const RTCConfiguration& aSrc, IceConfiguration *aDst) { #ifdef MOZILLA_INTERNAL_API - if (!aSrc.mIceServers.WasPassed()) { - return NS_OK; + if (aSrc.mIceServers.WasPassed()) { + for (size_t i = 0; i < aSrc.mIceServers.Value().Length(); i++) { + nsresult rv = AddIceServer(aSrc.mIceServers.Value()[i], aDst); + NS_ENSURE_SUCCESS(rv, rv); + } } - for (uint32_t i = 0; i < aSrc.mIceServers.Value().Length(); i++) { - const RTCIceServer& server = aSrc.mIceServers.Value()[i]; - NS_ENSURE_TRUE(server.mUrl.WasPassed(), NS_ERROR_UNEXPECTED); +#endif + return NS_OK; +} +nsresult +PeerConnectionImpl::AddIceServer(const RTCIceServer &aServer, + IceConfiguration *aDst) +{ +#ifdef MOZILLA_INTERNAL_API + NS_ENSURE_STATE(aServer.mUrls.WasPassed()); + NS_ENSURE_STATE(aServer.mUrls.Value().IsStringSequence()); + auto &urls = aServer.mUrls.Value().GetAsStringSequence(); + for (size_t i = 0; i < urls.Length(); i++) { // Without STUN/TURN handlers, NS_NewURI returns nsSimpleURI rather than // nsStandardURL. To parse STUN/TURN URI's to spec // http://tools.ietf.org/html/draft-nandakumar-rtcweb-stun-uri-02#section-3 // http://tools.ietf.org/html/draft-petithuguenin-behave-turn-uri-03#section-3 // we parse out the query-string, and use ParseAuthority() on the rest nsRefPtr url; - nsresult rv = NS_NewURI(getter_AddRefs(url), server.mUrl.Value()); + nsresult rv = NS_NewURI(getter_AddRefs(url), urls[i]); NS_ENSURE_SUCCESS(rv, rv); bool isStun = false, isStuns = false, isTurn = false, isTurns = false; url->SchemeIs("stun", &isStun); @@ -542,8 +554,8 @@ PeerConnectionImpl::ConvertRTCConfiguration(const RTCConfiguration& aSrc, port = (isStuns || isTurns)? 5349 : 3478; if (isTurn || isTurns) { - NS_ConvertUTF16toUTF8 credential(server.mCredential); - NS_ConvertUTF16toUTF8 username(server.mUsername); + NS_ConvertUTF16toUTF8 credential(aServer.mCredential); + NS_ConvertUTF16toUTF8 username(aServer.mUsername); // Bug 1039655 - TURN TCP is not e10s ready if ((transport == kNrIceTransportTcp) && diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h index c95f36e0c31e..5ddad70707ee 100644 --- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h +++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h @@ -78,6 +78,7 @@ class DOMMediaStream; namespace dom { struct RTCConfiguration; +struct RTCIceServer; struct RTCOfferOptions; #ifdef USE_FAKE_MEDIA_STREAMS typedef Fake_MediaStreamTrack MediaStreamTrack; @@ -118,6 +119,7 @@ namespace mozilla { using mozilla::dom::PeerConnectionObserver; using mozilla::dom::RTCConfiguration; +using mozilla::dom::RTCIceServer; using mozilla::dom::RTCOfferOptions; using mozilla::DOMMediaStream; using mozilla::NrIceCtx; @@ -259,6 +261,8 @@ public: static PeerConnectionImpl* CreatePeerConnection(); static nsresult ConvertRTCConfiguration(const RTCConfiguration& aSrc, IceConfiguration *aDst); + static nsresult AddIceServer(const RTCIceServer& aServer, + IceConfiguration* aDst); already_AddRefed MakeMediaStream(uint32_t aHint); nsresult CreateRemoteSourceStreamInfo(nsRefPtr* aInfo, diff --git a/mobile/android/modules/TabMirror.jsm b/mobile/android/modules/TabMirror.jsm index f7a38851d5ce..2d5f53c32320 100644 --- a/mobile/android/modules/TabMirror.jsm +++ b/mobile/android/modules/TabMirror.jsm @@ -7,7 +7,7 @@ const { classes: Cc, interfaces: Ci, utils: Cu } = Components; Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Messaging.jsm"); -const CONFIG = { iceServers: [{ "url": "stun:stun.services.mozilla.com" }] }; +const CONFIG = { iceServers: [{ "urls": ["stun:stun.services.mozilla.com"] }] }; let log = Cu.import("resource://gre/modules/AndroidLog.jsm", {}).AndroidLog.d.bind(null, "TabMirror"); diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 9b13643ff3ee..af6281a27e13 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -360,7 +360,7 @@ pref("media.peerconnection.video.start_bitrate", 300); pref("media.peerconnection.video.max_bitrate", 2000); #endif pref("media.navigator.permission.disabled", false); -pref("media.peerconnection.default_iceservers", "[{\"url\": \"stun:stun.services.mozilla.com\"}]"); +pref("media.peerconnection.default_iceservers", "[{\"urls\": [\"stun:stun.services.mozilla.com\"]}]"); pref("media.peerconnection.ice.loopback", false); // Set only for testing in offline environments. pref("media.peerconnection.use_document_iceservers", true); // Do not enable identity before ensuring that the UX cannot be spoofed From 3c404639d0f32bae263f3287fcca04fe3d33e728 Mon Sep 17 00:00:00 2001 From: Ethan Tseng Date: Tue, 6 Jan 2015 16:25:14 +0800 Subject: [PATCH 53/62] Bug 1116715 - [NetworkStats] DB upgrade pattern of NetworkStats is error-prone. r=albert, f=bent --- dom/network/NetworkStatsDB.jsm | 241 ++++++++++++++++++++++----------- 1 file changed, 165 insertions(+), 76 deletions(-) diff --git a/dom/network/NetworkStatsDB.jsm b/dom/network/NetworkStatsDB.jsm index dbc5f3c9e591..103588c9ee55 100644 --- a/dom/network/NetworkStatsDB.jsm +++ b/dom/network/NetworkStatsDB.jsm @@ -48,18 +48,33 @@ NetworkStatsDB.prototype = { return this.newTxn(txn_type, store_name, callback, successCb, errorCb); }, + /** + * The onupgradeneeded handler of the IDBOpenDBRequest. + * This function is called in IndexedDBHelper open() method. + * + * @param {IDBTransaction} aTransaction + * {IDBDatabase} aDb + * {64-bit integer} aOldVersion The version number on local storage. + * {64-bit integer} aNewVersion The version number to be upgraded to. + * + * @note Be careful with the database upgrade pattern. + * Because IndexedDB operations are performed asynchronously, we must + * apply a recursive approach instead of an iterative approach while + * upgrading versions. + */ upgradeSchema: function upgradeSchema(aTransaction, aDb, aOldVersion, aNewVersion) { if (DEBUG) { debug("upgrade schema from: " + aOldVersion + " to " + aNewVersion + " called!"); } let db = aDb; let objectStore; - for (let currVersion = aOldVersion; currVersion < aNewVersion; currVersion++) { - if (currVersion == 0) { - /** - * Create the initial database schema. - */ + // An array of upgrade functions for each version. + let upgradeSteps = [ + function upgrade0to1() { + if (DEBUG) debug("Upgrade 0 to 1: Create object stores and indexes."); + + // Create the initial database schema. objectStore = db.createObjectStore(DEPRECATED_STORE_NAME, { keyPath: ["connectionType", "timestamp"] }); objectStore.createIndex("connectionType", "connectionType", { unique: false }); objectStore.createIndex("timestamp", "timestamp", { unique: false }); @@ -67,10 +82,18 @@ NetworkStatsDB.prototype = { objectStore.createIndex("txBytes", "txBytes", { unique: false }); objectStore.createIndex("rxTotalBytes", "rxTotalBytes", { unique: false }); objectStore.createIndex("txTotalBytes", "txTotalBytes", { unique: false }); - if (DEBUG) { - debug("Created object stores and indexes"); - } - } else if (currVersion == 2) { + + upgradeNextVersion(); + }, + + function upgrade1to2() { + if (DEBUG) debug("Upgrade 1 to 2: Do nothing."); + upgradeNextVersion(); + }, + + function upgrade2to3() { + if (DEBUG) debug("Upgrade 2 to 3: Add keyPath appId to object store."); + // In order to support per-app traffic data storage, the original // objectStore needs to be replaced by a new objectStore with new // key path ("appId") and new index ("appId"). @@ -99,11 +122,13 @@ NetworkStatsDB.prototype = { objectStore.createIndex("rxTotalBytes", "rxTotalBytes", { unique: false }); objectStore.createIndex("txTotalBytes", "txTotalBytes", { unique: false }); - if (DEBUG) { - debug("Created object stores and indexes for version 3"); - } - } else if (currVersion == 3) { - // Delete redundent indexes (leave "network" only). + upgradeNextVersion(); + }, + + function upgrade3to4() { + if (DEBUG) debug("Upgrade 3 to 4: Delete redundant indexes."); + + // Delete redundant indexes (leave "network" only). objectStore = aTransaction.objectStore(DEPRECATED_STORE_NAME); if (objectStore.indexNames.contains("appId")) { objectStore.deleteIndex("appId"); @@ -127,10 +152,12 @@ NetworkStatsDB.prototype = { objectStore.deleteIndex("txTotalBytes"); } - if (DEBUG) { - debug("Deleted redundent indexes for version 4"); - } - } else if (currVersion == 4) { + upgradeNextVersion(); + }, + + function upgrade4to5() { + if (DEBUG) debug("Upgrade 4 to 5: Create object store for alarms."); + // In order to manage alarms, it is necessary to use a global counter // (totalBytes) that will increase regardless of the system reboot. objectStore = aTransaction.objectStore(DEPRECATED_STORE_NAME); @@ -143,6 +170,8 @@ NetworkStatsDB.prototype = { objectStore.openCursor().onsuccess = function(event) { let cursor = event.target.result; if (!cursor){ + // upgrade4to5 completed now. + upgradeNextVersion(); return; } @@ -188,11 +217,11 @@ NetworkStatsDB.prototype = { objectStore = db.createObjectStore(ALARMS_STORE_NAME, { keyPath: "id", autoIncrement: true }); objectStore.createIndex("alarm", ['networkId','threshold'], { unique: false }); objectStore.createIndex("manifestURL", "manifestURL", { unique: false }); + }, + + function upgrade5to6() { + if (DEBUG) debug("Upgrade 5 to 6: Add keyPath serviceType to object store."); - if (DEBUG) { - debug("Created alarms store for version 5"); - } - } else if (currVersion == 5) { // In contrast to "per-app" traffic data, "system-only" traffic data // refers to data which can not be identified by any applications. // To further support "system-only" data storage, the data can be @@ -209,6 +238,8 @@ NetworkStatsDB.prototype = { let cursor = event.target.result; if (!cursor) { db.deleteObjectStore(DEPRECATED_STORE_NAME); + // upgrade5to6 completed now. + upgradeNextVersion(); return; } @@ -217,11 +248,11 @@ NetworkStatsDB.prototype = { newObjectStore.put(newStats); cursor.continue(); }; + }, + + function upgrade6to7() { + if (DEBUG) debug("Upgrade 6 to 7: Replace alarm threshold by relativeThreshold."); - if (DEBUG) { - debug("Added new key 'serviceType' for version 6"); - } - } else if (currVersion == 6) { // Replace threshold attribute of alarm index by relativeThreshold in alarms DB. // Now alarms are indexed by relativeThreshold, which is the threshold relative // to current system stats. @@ -239,6 +270,7 @@ NetworkStatsDB.prototype = { alarmsStore.openCursor().onsuccess = function(event) { let cursor = event.target.result; if (!cursor) { + upgrade6to7_updateTotalBytes(); return; } @@ -250,75 +282,132 @@ NetworkStatsDB.prototype = { cursor.continue(); } - // Previous versions save accumulative totalBytes, increasing althought the system - // reboots or resets stats. But is necessary to reset the total counters when reset - // through 'clearInterfaceStats'. - let statsStore = aTransaction.objectStore(STATS_STORE_NAME); - let networks = []; - // Find networks stored in the database. - statsStore.index("network").openKeyCursor(null, "nextunique").onsuccess = function(event) { - let cursor = event.target.result; - if (cursor) { - networks.push(cursor.key); - cursor.continue(); - return; - } + function upgrade6to7_updateTotalBytes() { + if (DEBUG) debug("Upgrade 6 to 7: Update TotalBytes."); + // Previous versions save accumulative totalBytes, increasing although the system + // reboots or resets stats. But is necessary to reset the total counters when reset + // through 'clearInterfaceStats'. + let statsStore = aTransaction.objectStore(STATS_STORE_NAME); + let networks = []; - networks.forEach(function(network) { - let lowerFilter = [0, "", network, 0]; - let upperFilter = [0, "", network, ""]; - let range = IDBKeyRange.bound(lowerFilter, upperFilter, false, false); + // Find networks stored in the database. + statsStore.index("network").openKeyCursor(null, "nextunique").onsuccess = function(event) { + let cursor = event.target.result; - // Find number of samples for a given network. - statsStore.count(range).onsuccess = function(event) { - // If there are more samples than the max allowed, there is no way to know - // when does reset take place. - if (event.target.result >= VALUES_MAX_LENGTH) { - return; - } + // Store each network into an array. + if (cursor) { + networks.push(cursor.key); + cursor.continue(); + return; + } - let last = null; - // Reset detected if the first sample totalCounters are different than bytes - // counters. If so, the total counters should be recalculated. - statsStore.openCursor(range).onsuccess = function(event) { - let cursor = event.target.result; - if (!cursor) { + // Start to deal with each network. + let pending = networks.length; + + if (pending === 0) { + // Found no records of network. upgrade6to7 completed now. + upgradeNextVersion(); + return; + } + + networks.forEach(function(network) { + let lowerFilter = [0, "", network, 0]; + let upperFilter = [0, "", network, ""]; + let range = IDBKeyRange.bound(lowerFilter, upperFilter, false, false); + + // Find number of samples for a given network. + statsStore.count(range).onsuccess = function(event) { + let recordCount = event.target.result; + + // If there are more samples than the max allowed, there is no way to know + // when does reset take place. + if (recordCount === 0 || recordCount >= VALUES_MAX_LENGTH) { + pending--; + if (pending === 0) { + upgradeNextVersion(); + } return; } - if (!last) { - if (cursor.value.rxTotalBytes == cursor.value.rxBytes && - cursor.value.txTotalBytes == cursor.value.txBytes) { + + let last = null; + // Reset detected if the first sample totalCounters are different than bytes + // counters. If so, the total counters should be recalculated. + statsStore.openCursor(range).onsuccess = function(event) { + let cursor = event.target.result; + if (!cursor) { + pending--; + if (pending === 0) { + upgradeNextVersion(); + } + return; + } + if (!last) { + if (cursor.value.rxTotalBytes == cursor.value.rxBytes && + cursor.value.txTotalBytes == cursor.value.txBytes) { + pending--; + if (pending === 0) { + upgradeNextVersion(); + } + return; + } + + cursor.value.rxTotalBytes = cursor.value.rxBytes; + cursor.value.txTotalBytes = cursor.value.txBytes; + cursor.update(cursor.value); + last = cursor.value; + cursor.continue(); return; } - cursor.value.rxTotalBytes = cursor.value.rxBytes; - cursor.value.txTotalBytes = cursor.value.txBytes; + // Recalculate the total counter for last / current sample + cursor.value.rxTotalBytes = last.rxTotalBytes + cursor.value.rxBytes; + cursor.value.txTotalBytes = last.txTotalBytes + cursor.value.txBytes; cursor.update(cursor.value); last = cursor.value; cursor.continue(); - return; } - - // Recalculate the total counter for last / current sample - cursor.value.rxTotalBytes = last.rxTotalBytes + cursor.value.rxBytes; - cursor.value.txTotalBytes = last.txTotalBytes + cursor.value.txBytes; - cursor.update(cursor.value); - last = cursor.value; - cursor.continue(); } - } - }, this); - }; - } else if (currVersion == 7) { + }, this); // end of networks.forEach() + }; // end of statsStore.index("network").openKeyCursor().onsuccess callback + } // end of function upgrade6to7_updateTotalBytes + }, + + function upgrade7to8() { + if (DEBUG) debug("Upgrade 7 to 8: Create index serviceType."); + // Create index for 'ServiceType' in order to make it retrievable. let statsStore = aTransaction.objectStore(STATS_STORE_NAME); statsStore.createIndex("serviceType", "serviceType", { unique: false }); + }, + ]; - if (DEBUG) { - debug("Create index of 'serviceType' for version 8"); - } + let index = aOldVersion; + let outer = this; + + function upgradeNextVersion() { + if (index == aNewVersion) { + debug("Upgrade finished."); + return; + } + + try { + var i = index++; + if (DEBUG) debug("Upgrade step: " + i + "\n"); + upgradeSteps[i].call(outer); + } catch (ex) { + dump("Caught exception " + ex); + throw ex; + return; } } + + if (aNewVersion > upgradeSteps.length) { + debug("No migration steps for the new version!"); + aTransaction.abort(); + return; + } + + upgradeNextVersion(); }, importData: function importData(aStats) { From 27f5250355b5ce3cf0e1fa82fc80d5697e218f77 Mon Sep 17 00:00:00 2001 From: Hector Zhao Date: Sat, 17 Jan 2015 11:30:04 +0800 Subject: [PATCH 54/62] Bug 1123345 - Use MOZ_ICU_CFLAGS instead of in-tree paths for build with system icu. r=glandium --- intl/build/moz.build | 3 +-- intl/locale/mac/moz.build | 3 +-- layout/forms/moz.build | 6 +----- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/intl/build/moz.build b/intl/build/moz.build index b5ea4aeea918..26bae09dd299 100644 --- a/intl/build/moz.build +++ b/intl/build/moz.build @@ -9,9 +9,8 @@ SOURCES += [ ] FINAL_LIBRARY = 'xul' +CXXFLAGS += CONFIG['MOZ_ICU_CFLAGS'] LOCAL_INCLUDES += [ - '../icu/source/common', - '../icu/source/i18n', '../locale', '../lwbrk', '../strres', diff --git a/intl/locale/mac/moz.build b/intl/locale/mac/moz.build index 277cf2fba306..226a516f38f0 100644 --- a/intl/locale/mac/moz.build +++ b/intl/locale/mac/moz.build @@ -11,10 +11,9 @@ UNIFIED_SOURCES += [ ] FINAL_LIBRARY = 'xul' +CXXFLAGS += CONFIG['MOZ_ICU_CFLAGS'] LOCAL_INCLUDES += [ '..', - '../../icu/source/common', - '../../icu/source/i18n', ] FAIL_ON_WARNINGS = True diff --git a/layout/forms/moz.build b/layout/forms/moz.build index bd961dad0d16..a77aa5f31db3 100644 --- a/layout/forms/moz.build +++ b/layout/forms/moz.build @@ -56,8 +56,4 @@ LOCAL_INCLUDES += [ if CONFIG['ENABLE_INTL_API']: # nsNumberControlFrame.cpp requires ICUUtils.h which in turn requires # i18n/unum.h - LOCAL_INCLUDES += [ - '../../intl/icu/source/common', - '../../intl/icu/source/i18n', - ] - + CXXFLAGS += CONFIG['MOZ_ICU_CFLAGS'] From 837bd03db3e5335adf729d4a4c2a5adc05832366 Mon Sep 17 00:00:00 2001 From: JerryShih Date: Tue, 20 Jan 2015 08:21:00 -0500 Subject: [PATCH 55/62] Bug 1123734 - Notify global VsyncSource in hwc. r=mwu, r=mchang --- widget/gonk/HwcComposer2D.cpp | 6 ++++-- widget/gonk/nsWindow.cpp | 15 --------------- widget/gonk/nsWindow.h | 1 - 3 files changed, 4 insertions(+), 18 deletions(-) diff --git a/widget/gonk/HwcComposer2D.cpp b/widget/gonk/HwcComposer2D.cpp index fec58ec3fb47..e57e897f690a 100644 --- a/widget/gonk/HwcComposer2D.cpp +++ b/widget/gonk/HwcComposer2D.cpp @@ -30,7 +30,8 @@ #include "mozilla/StaticPtr.h" #include "cutils/properties.h" #include "gfx2DGlue.h" -#include "nsWindow.h" +#include "gfxPlatform.h" +#include "VsyncSource.h" #if ANDROID_VERSION >= 17 #include "libdisplay/FramebufferSurface.h" @@ -227,7 +228,8 @@ HwcComposer2D::Vsync(int aDisplay, nsecs_t aVsyncTimestamp) LOGE("Non-uniform vsync interval: %lld\n", vsyncInterval); } mLastVsyncTime = aVsyncTimestamp; - nsWindow::NotifyVsync(vsyncTime); + + gfxPlatform::GetPlatform()->GetHardwareVsync()->GetGlobalDisplay().NotifyVsync(vsyncTime); } // Called on the "invalidator" thread (run from HAL). diff --git a/widget/gonk/nsWindow.cpp b/widget/gonk/nsWindow.cpp index a394dbbf68e4..544805bd19fb 100644 --- a/widget/gonk/nsWindow.cpp +++ b/widget/gonk/nsWindow.cpp @@ -215,21 +215,6 @@ nsWindow::DoDraw(void) } } -/* static */ void -nsWindow::NotifyVsync(TimeStamp aVsyncTimestamp) -{ - if (!gFocusedWindow) { - return; - } - - CompositorVsyncDispatcher* vsyncDispatcher = gFocusedWindow->GetCompositorVsyncDispatcher(); - // During bootup, there is a delay between when the nsWindow is created - // and when the Compositor is created, but vsync is already turned on - if (vsyncDispatcher) { - vsyncDispatcher->NotifyVsync(aVsyncTimestamp); - } -} - /*static*/ nsEventStatus nsWindow::DispatchInputEvent(WidgetGUIEvent& aEvent) { diff --git a/widget/gonk/nsWindow.h b/widget/gonk/nsWindow.h index 67d7529a8438..cf816ab2dda3 100644 --- a/widget/gonk/nsWindow.h +++ b/widget/gonk/nsWindow.h @@ -50,7 +50,6 @@ public: nsWindow(); virtual ~nsWindow(); - static void NotifyVsync(mozilla::TimeStamp aVsyncTimestamp); static void DoDraw(void); static nsEventStatus DispatchInputEvent(mozilla::WidgetGUIEvent& aEvent); static void DispatchTouchInput(mozilla::MultiTouchInput& aInput); From 3b62ac5b76e0a59c0c8fb7233c098732033d82b9 Mon Sep 17 00:00:00 2001 From: Bas Schouten Date: Wed, 21 Jan 2015 18:00:31 +0100 Subject: [PATCH 56/62] Bug 1117925: Make sure to invalidate the entire window when the size changes. r=jrmuizel --- gfx/layers/d3d11/CompositorD3D11.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/gfx/layers/d3d11/CompositorD3D11.cpp b/gfx/layers/d3d11/CompositorD3D11.cpp index 63e1d3e60465..28b1bb8778ea 100644 --- a/gfx/layers/d3d11/CompositorD3D11.cpp +++ b/gfx/layers/d3d11/CompositorD3D11.cpp @@ -1050,6 +1050,7 @@ CompositorD3D11::BeginFrame(const nsIntRegion& aInvalidRegion, return; } + nsIntSize oldSize = mSize; UpdateRenderTarget(); // Failed to create a render target or the view. @@ -1069,7 +1070,13 @@ CompositorD3D11::BeginFrame(const nsIntRegion& aInvalidRegion, nsIntRect intRect = nsIntRect(nsIntPoint(0, 0), mSize); // Sometimes the invalid region is larger than we want to draw. nsIntRegion invalidRegionSafe; - invalidRegionSafe.And(aInvalidRegion, intRect); + + if (mSize != oldSize) { + invalidRegionSafe = intRect; + } else { + invalidRegionSafe.And(aInvalidRegion, intRect); + } + nsIntRect invalidRect = invalidRegionSafe.GetBounds(); mInvalidRect = IntRect(invalidRect.x, invalidRect.y, invalidRect.width, invalidRect.height); mInvalidRegion = invalidRegionSafe; From b0ba31bcc7af230f583b555063b66fdef8eb4714 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Wed, 21 Jan 2015 13:46:11 -0500 Subject: [PATCH 57/62] Bug 1124072 - Disable decode-on-draw on B2G due to frequent reftest failures. --- b2g/app/b2g.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/app/b2g.js b/b2g/app/b2g.js index ac24677a863c..f6c6931f586a 100644 --- a/b2g/app/b2g.js +++ b/b2g/app/b2g.js @@ -322,7 +322,7 @@ pref("media.fragmented-mp4.gonk.enabled", true); pref("media.video-queue.default-size", 3); // optimize images' memory usage -pref("image.mem.decodeondraw", true); +pref("image.mem.decodeondraw", false); pref("image.mem.allow_locking_in_content_processes", false); /* don't allow image locking */ // Limit the surface cache to 1/8 of main memory or 128MB, whichever is smaller. // Almost everything that was factored into 'max_decoded_image_kb' is now stored From 5afda9bae38b7653b705096170ba0d7abaeb65fb Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Wed, 21 Jan 2015 13:46:11 -0500 Subject: [PATCH 58/62] Bug 1075573 - Disable test_videocontrols_standalone.html on Android 2.3 due to frequent failures. --- toolkit/content/tests/widgets/mochitest.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/toolkit/content/tests/widgets/mochitest.ini b/toolkit/content/tests/widgets/mochitest.ini index 298424b523e1..eb8214b86e0d 100644 --- a/toolkit/content/tests/widgets/mochitest.ini +++ b/toolkit/content/tests/widgets/mochitest.ini @@ -28,5 +28,6 @@ skip-if = toolkit == 'android' #TIMED_OUT [test_videocontrols_audio.html] [test_videocontrols_audio_direction.html] [test_videocontrols_standalone.html] +skip-if = android_version == '10' # bug 1075573 [test_videocontrols_video_direction.html] [test_bug898940.html] From a94e410cac3e09508e596dee127233a60df0722b Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Wed, 21 Jan 2015 13:46:11 -0500 Subject: [PATCH 59/62] Bug 1078267 - Skip netwerk/test/mochitests/ on Android due to frequent failures. --- netwerk/test/mochitests/mochitest.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netwerk/test/mochitests/mochitest.ini b/netwerk/test/mochitests/mochitest.ini index ebd580569ce7..ded6d4e902f0 100644 --- a/netwerk/test/mochitests/mochitest.ini +++ b/netwerk/test/mochitests/mochitest.ini @@ -1,5 +1,6 @@ [DEFAULT] -skip-if = buildapp == 'b2g' || e10s +skip-if = buildapp == 'b2g' || e10s || toolkit == 'android' # Android: Bug 1111137 & 1078267 +skip-if = support-files = method.sjs partial_content.sjs @@ -10,7 +11,6 @@ support-files = [test_partially_cached_content.html] [test_uri_scheme.html] [test_user_agent_overrides.html] -skip-if = toolkit == 'android' # Bug 1111137 [test_user_agent_updates.html] [test_user_agent_updates_reset.html] [test_xhr_method_case.html] From 277b23af8a4b236edd258e3cb48ae78d8bc925e1 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Wed, 21 Jan 2015 13:46:11 -0500 Subject: [PATCH 60/62] Bug 1115131 - Disable browser_share.js for frequent leaks on all platforms. CLOSED TREE --- browser/base/content/test/social/browser.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/browser/base/content/test/social/browser.ini b/browser/base/content/test/social/browser.ini index 34622de1cdea..fa86776729b7 100644 --- a/browser/base/content/test/social/browser.ini +++ b/browser/base/content/test/social/browser.ini @@ -31,6 +31,7 @@ skip-if = e10s # Bug 1053965 "cw.ensureSnippetsMapThen is not a function", also [browser_addons.js] [browser_blocklist.js] [browser_share.js] +skip-if = true # bug 1115131 [browser_social_activation.js] skip-if = e10s # Bug 933103 synthesizeMouseAtCenter not e10s friendly [browser_social_chatwindow.js] From fd8619b2dd0a745c2c611bb370d49ff2ef25f9d1 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Wed, 21 Jan 2015 13:59:42 -0500 Subject: [PATCH 61/62] Bug 1078267 - Remove extraneous skip-if added accidentally. CLOSED TREE --- netwerk/test/mochitests/mochitest.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netwerk/test/mochitests/mochitest.ini b/netwerk/test/mochitests/mochitest.ini index ded6d4e902f0..008c964287cc 100644 --- a/netwerk/test/mochitests/mochitest.ini +++ b/netwerk/test/mochitests/mochitest.ini @@ -1,6 +1,6 @@ [DEFAULT] skip-if = buildapp == 'b2g' || e10s || toolkit == 'android' # Android: Bug 1111137 & 1078267 -skip-if = + support-files = method.sjs partial_content.sjs From c0d4e14e92c48e603f6816471b390333c5362085 Mon Sep 17 00:00:00 2001 From: Honza Bambas Date: Tue, 20 Jan 2015 08:30:00 -0500 Subject: [PATCH 62/62] Bug 1123732 - Null-check uri before trying to use it. r=mcmanus CLOSED TREE --- netwerk/protocol/http/HttpBaseChannel.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp index f32fb093e36a..9e4d3916a038 100644 --- a/netwerk/protocol/http/HttpBaseChannel.cpp +++ b/netwerk/protocol/http/HttpBaseChannel.cpp @@ -2183,8 +2183,10 @@ HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI, nsCOMPtr uri; mRedirects[i]->GetURI(getter_AddRefs(uri)); nsCString spec; - uri->GetSpec(spec); - LOG(("HttpBaseChannel::SetupReplacementChannel adding redirect %s " + if (uri) { + uri->GetSpec(spec); + } + LOG(("HttpBaseChannel::SetupReplacementChannel adding redirect \'%s\' " "[this=%p]", spec.get(), this)); #endif httpInternal->AddRedirect(mRedirects[i]);