summaryrefslogtreecommitdiffstats
path: root/patchwork/tests
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2015-05-24 16:57:33 +0800
committerJeremy Kerr <jk@ozlabs.org>2015-05-27 10:26:41 +0800
commitad2762cf775a8dde508de47164d6429f3fd724f1 (patch)
treee63015a468cfe32c961908f0338d423227799815 /patchwork/tests
parentf09e982f58384946111d4157fd2b7c2b31b78612 (diff)
downloadpatchwork-ad2762cf775a8dde508de47164d6429f3fd724f1.tar.bz2
patchwork-ad2762cf775a8dde508de47164d6429f3fd724f1.tar.xz
Move to a more recent django project structure
This change updates patchwor to the newer project struture: we've moved the actual application out of the apps/ directory, and the patchwork-specific templates to under the patchwork application. This gives us the manage.py script in the top-level now. Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Diffstat (limited to 'patchwork/tests')
-rw-r--r--patchwork/tests/__init__.py34
-rw-r--r--patchwork/tests/mail/0001-git-pull-request.mbox348
-rw-r--r--patchwork/tests/mail/0002-git-pull-request-wrapped.mbox349
-rw-r--r--patchwork/tests/mail/0003-git-pull-request-with-diff.mbox141
-rw-r--r--patchwork/tests/mail/0004-git-pull-request-git+ssh.mbox348
-rw-r--r--patchwork/tests/mail/0005-git-pull-request-ssh.mbox348
-rw-r--r--patchwork/tests/mail/0006-git-pull-request-http.mbox348
-rw-r--r--patchwork/tests/mail/0007-cvs-format-diff.mbox134
-rw-r--r--patchwork/tests/mail/0008-git-rename.mbox24
-rw-r--r--patchwork/tests/mail/0009-git-rename-with-diff.mbox32
-rw-r--r--patchwork/tests/mail/0010-invalid-charset.mbox90
-rw-r--r--patchwork/tests/mail/0011-no-newline-at-end-of-file.mbox45
-rw-r--r--patchwork/tests/patches/0001-add-line.patch7
-rw-r--r--patchwork/tests/patches/0002-utf-8.patch7
-rw-r--r--patchwork/tests/test_bundles.py646
-rw-r--r--patchwork/tests/test_confirm.py67
-rw-r--r--patchwork/tests/test_encodings.py87
-rw-r--r--patchwork/tests/test_expiry.py121
-rw-r--r--patchwork/tests/test_filters.py45
-rw-r--r--patchwork/tests/test_list.py116
-rw-r--r--patchwork/tests/test_mail_settings.py299
-rw-r--r--patchwork/tests/test_mboxviews.py209
-rw-r--r--patchwork/tests/test_notifications.py255
-rw-r--r--patchwork/tests/test_patchparser.py554
-rw-r--r--patchwork/tests/test_person.py55
-rw-r--r--patchwork/tests/test_registration.py210
-rw-r--r--patchwork/tests/test_updates.py118
-rw-r--r--patchwork/tests/test_user.py195
-rw-r--r--patchwork/tests/test_xmlrpc.py55
-rw-r--r--patchwork/tests/utils.py138
30 files changed, 5425 insertions, 0 deletions
diff --git a/patchwork/tests/__init__.py b/patchwork/tests/__init__.py
new file mode 100644
index 0000000..85200bd
--- /dev/null
+++ b/patchwork/tests/__init__.py
@@ -0,0 +1,34 @@
+# Patchwork - automated patch tracking system
+# Copyright (C) 2008 Jeremy Kerr <jk@ozlabs.org>
+#
+# This file is part of the Patchwork package.
+#
+# Patchwork is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# Patchwork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Patchwork; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+from patchwork.tests.test_patchparser import *
+from patchwork.tests.test_encodings import *
+from patchwork.tests.test_bundles import *
+from patchwork.tests.test_mboxviews import *
+from patchwork.tests.test_updates import *
+from patchwork.tests.test_filters import *
+from patchwork.tests.test_confirm import *
+from patchwork.tests.test_registration import *
+from patchwork.tests.test_user import *
+from patchwork.tests.test_mail_settings import *
+from patchwork.tests.test_notifications import *
+from patchwork.tests.test_list import *
+from patchwork.tests.test_person import *
+from patchwork.tests.test_expiry import *
+from patchwork.tests.test_xmlrpc import *
diff --git a/patchwork/tests/mail/0001-git-pull-request.mbox b/patchwork/tests/mail/0001-git-pull-request.mbox
new file mode 100644
index 0000000..0dbedbe
--- /dev/null
+++ b/patchwork/tests/mail/0001-git-pull-request.mbox
@@ -0,0 +1,348 @@
+From benh@kernel.crashing.org Fri Oct 22 11:51:02 2010
+Return-Path: <linuxppc-dev-bounces+jk=ozlabs.org@lists.ozlabs.org>
+X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on bilbo.ozlabs.org
+X-Spam-Level:
+X-Spam-Status: No, score=0.0 required=3.0 tests=none autolearn=disabled
+ version=3.3.1
+X-Original-To: jk@ozlabs.org
+Delivered-To: jk@ozlabs.org
+Received: from bilbo.ozlabs.org (localhost [127.0.0.1])
+ by ozlabs.org (Postfix) with ESMTP id ED4B3100937
+ for <jk@ozlabs.org>; Fri, 22 Oct 2010 14:51:54 +1100 (EST)
+Received: by ozlabs.org (Postfix)
+ id BF799B70CB; Fri, 22 Oct 2010 14:51:50 +1100 (EST)
+Delivered-To: linuxppc-dev@ozlabs.org
+Received: from gate.crashing.org (gate.crashing.org [63.228.1.57])
+ (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
+ (Client did not present a certificate)
+ by ozlabs.org (Postfix) with ESMTPS id 94629B7043
+ for <linuxppc-dev@ozlabs.org>; Fri, 22 Oct 2010 14:51:49 +1100 (EST)
+Received: from [IPv6:::1] (localhost.localdomain [127.0.0.1])
+ by gate.crashing.org (8.14.1/8.13.8) with ESMTP id o9M3p3SP018234;
+ Thu, 21 Oct 2010 22:51:04 -0500
+Subject: [git pull] Please pull powerpc.git next branch
+From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+To: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Fri, 22 Oct 2010 14:51:02 +1100
+Message-ID: <1287719462.2198.37.camel@pasglop>
+Mime-Version: 1.0
+X-Mailer: Evolution 2.30.3
+Cc: linuxppc-dev list <linuxppc-dev@ozlabs.org>,
+ Andrew Morton <akpm@linux-foundation.org>,
+ Linux Kernel list <linux-kernel@vger.kernel.org>
+X-BeenThere: linuxppc-dev@lists.ozlabs.org
+X-Mailman-Version: 2.1.13
+Precedence: list
+List-Id: Linux on PowerPC Developers Mail List <cbe-oss-dev.ozlabs.org>
+List-Unsubscribe: <https://lists.ozlabs.org/options/linuxppc-dev>,
+ <mailto:linuxppc-dev-request@lists.ozlabs.org?subject=unsubscribe>
+List-Archive: <http://lists.ozlabs.org/pipermail/linuxppc-dev>
+List-Post: <mailto:linuxppc-dev@lists.ozlabs.org>
+List-Help: <mailto:linuxppc-dev-request@lists.ozlabs.org?subject=help>
+List-Subscribe: <https://lists.ozlabs.org/listinfo/linuxppc-dev>,
+ <mailto:linuxppc-dev-request@lists.ozlabs.org?subject=subscribe>
+Content-Type: text/plain;
+ charset="us-ascii"
+Content-Transfer-Encoding: 7bit
+Sender: linuxppc-dev-bounces+jk=ozlabs.org@lists.ozlabs.org
+Errors-To: linuxppc-dev-bounces+jk=ozlabs.org@lists.ozlabs.org
+X-UID: 11446
+X-Length: 16781
+Status: R
+X-Status: N
+X-KMail-EncryptionState:
+X-KMail-SignatureState:
+X-KMail-MDN-Sent:
+
+Hi Linus !
+
+Here's powerpc's batch for this merge window. Mostly bits and pieces,
+such as Anton doing some performance tuning left and right, and the
+usual churn. One hilight is the support for the new Freescale e5500 core
+(64-bit BookE). Another one is that we now wire up the whole lot of
+socket calls as direct syscalls in addition to the old style indirect
+method.
+
+Cheers,
+Ben.
+
+The following changes since commit e10117d36ef758da0690c95ecffc09d5dd7da479:
+ Linus Torvalds (1):
+ Merge branch 'upstream-linus' of git://git.kernel.org/.../jgarzik/libata-dev
+
+are available in the git repository at:
+
+ git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git next
+
+Andreas Schwab (1):
+ powerpc: Remove fpscr use from [kvm_]cvt_{fd,df}
+
+Anton Blanchard (5):
+ powerpc: Optimise 64bit csum_partial
+ powerpc: Optimise 64bit csum_partial_copy_generic and add csum_and_copy_from_user
+ powerpc: Add 64bit csum_and_copy_to_user
+ powerpc: Feature nop out reservation clear when stcx checks address
+ powerpc: Check end of stack canary at oops time
+
+Arnd Bergmann (1):
+ powerpc/spufs: Use llseek in all file operations
+
+Benjamin Herrenschmidt (4):
+ powerpc/dma: Add optional platform override of dma_set_mask()
+ powerpc/dart_iommu: Support for 64-bit iommu bypass window on PCIe
+ Merge remote branch 'kumar/merge' into next
+ Merge remote branch 'jwb/next' into next
+
+Denis Kirjanov (1):
+ powerpc: Use is_32bit_task() helper to test 32-bit binary
+
+Harninder Rai (1):
+ powerpc/85xx: add cache-sram support
+
+Ian Munsie (1):
+ powerpc: Wire up direct socket system calls
+
+Ilya Yanok (1):
+ powerpc/mpc83xx: Support for MPC8308 P1M board
+
+Joe Perches (2):
+ powerpc: Use static const char arrays
+ powerpc: Remove pr_<level> uses of KERN_<level>
+
+Josh Boyer (1):
+ powerpc/44x: Update ppc44x_defconfig
+
+Julia Lawall (7):
+ powerpc/via-pmu-led.c: Add of_node_put to avoid memory leak
+ powerpc/maple: Add of_node_put to avoid memory leak
+ powerpc/powermac/pfunc_core.c: Add of_node_put to avoid memory leak
+ powerpc/cell: Add of_node_put to avoid memory leak
+ powerpc/chrp/nvram.c: Add of_node_put to avoid memory leak
+ powerpc/irq.c: Add of_node_put to avoid memory leak
+ i2c/i2c-pasemi.c: Fix unsigned return type
+
+Kumar Gala (11):
+ powerpc/ppc64e: Fix link problem when building ppc64e_defconfig
+ powerpc/fsl-pci: Fix MSI support on 83xx platforms
+ powerpc/mpc8xxx_gpio: Add support for 'qoriq-gpio' controllers
+ powerpc/fsl-booke: Add PCI device ids for P2040/P3041/P5010/P5020 QoirQ chips
+ powerpc/fsl-booke: Add p3041 DS board support
+ powerpc: Fix compile error with paca code on ppc64e
+ powerpc/fsl-booke: Add support for FSL 64-bit e5500 core
+ powerpc/fsl-booke: Add support for FSL Arch v1.0 MMU in setup_page_sizes
+ powerpc/fsl-booke64: Use TLB CAMs to cover linear mapping on FSL 64-bit chips
+ powerpc/fsl-booke: Add p5020 DS board support
+ powerpc/fsl-booke: Add e55xx (64-bit) smp defconfig
+
+Matthew McClintock (7):
+ powerpc/mm: Assume first cpu is boot_cpuid not 0
+ powerpc/kexec: make masking/disabling interrupts generic
+ powerpc/85xx: Remove call to mpic_teardown_this_cpu in kexec
+ powerpc/85xx: Minor fixups for kexec on 85xx
+ powerpc/85xx: flush dcache before resetting cores
+ powerpc/fsl_soc: Search all global-utilities nodes for rstccr
+ powerpc/fsl_booke: Add support to boot from core other than 0
+
+Michael Neuling (1):
+ powerpc: Move arch_sd_sibling_asym_packing() to smp.c
+
+Nathan Fontenot (3):
+ powerpc/pseries: Export device tree updating routines
+ powerpc/pseries: Export rtas_ibm_suspend_me()
+ powerpc/pseries: Partition migration in the kernel
+
+Nishanth Aravamudan (8):
+ powerpc/pci: Fix return type of BUID_{HI,LO} macros
+ powerpc/dma: Fix dma_iommu_dma_supported compare
+ powerpc/dma: Fix check for direct DMA support
+ powerpc/vio: Use put_device() on device_register failure
+ powerpc/viobus: Free TCE table on device release
+ powerpc/pseries: Use kmemdup
+ powerpc/pci: Cleanup device dma setup code
+ powerpc/pseries/xics: Use cpu_possible_mask rather than cpu_all_mask
+
+Paul Gortmaker (1):
+ powerpc: Fix invalid page flags in create TLB CAM path for PTE_64BIT
+
+Paul Mackerras (5):
+ powerpc: Abstract indexing of lppaca structs
+ powerpc: Dynamically allocate most lppaca structs
+ powerpc: Account time using timebase rather than PURR
+ powerpc/pseries: Re-enable dispatch trace log userspace interface
+ powerpc/perf: Fix sampling enable for PPC970
+
+Scott Wood (1):
+ oprofile/fsl emb: Don't set MSR[PMM] until after clearing the interrupt.
+
+Sean MacLennan (2):
+ powerpc: Fix incorrect .stabs entry for copy_32.S
+ powerpc: mtmsrd not defined
+
+Shaohui Xie (1):
+ fsl_rio: Add comments for sRIO registers.
+
+Stephen Rothwell (1):
+ powerpc: define a compat_sys_recv cond_syscall
+
+Timur Tabi (5):
+ powerpc: export ppc_proc_freq and ppc_tb_freq as GPL symbols
+ powerpc/watchdog: Allow the Book-E driver to be compiled as a module
+ powerpc/p1022: Add probing for individual DMA channels
+ powerpc/85xx: add ngPIXIS FPGA device tree node to the P1022DS board
+ powerpc/watchdog: Make default timeout for Book-E watchdog a Kconfig option
+
+Tirumala Marri (1):
+ powerpc/44x: Add support for the AMCC APM821xx SoC
+
+matt mooney (1):
+ powerpc/Makefiles: Change to new flag variables
+
+ arch/powerpc/boot/addnote.c | 4 +-
+ arch/powerpc/boot/dts/bluestone.dts | 254 +++++++++++++
+ arch/powerpc/boot/dts/mpc8308_p1m.dts | 332 ++++++++++++++++
+ arch/powerpc/boot/dts/p1022ds.dts | 11 +
+ arch/powerpc/configs/44x/bluestone_defconfig | 68 ++++
+ arch/powerpc/configs/e55xx_smp_defconfig | 84 ++++
+ arch/powerpc/configs/ppc44x_defconfig | 9 +-
+ arch/powerpc/configs/ppc64e_defconfig | 4 +-
+ arch/powerpc/include/asm/checksum.h | 10 +
+ arch/powerpc/include/asm/compat.h | 4 +-
+ arch/powerpc/include/asm/cputable.h | 14 +-
+ arch/powerpc/include/asm/dma-mapping.h | 14 +-
+ arch/powerpc/include/asm/elf.h | 2 +-
+ arch/powerpc/include/asm/exception-64s.h | 3 +-
+ arch/powerpc/include/asm/fsl_85xx_cache_sram.h | 48 +++
+ arch/powerpc/include/asm/kexec.h | 1 +
+ arch/powerpc/include/asm/kvm_fpu.h | 4 +-
+ arch/powerpc/include/asm/lppaca.h | 29 ++
+ arch/powerpc/include/asm/machdep.h | 3 +
+ arch/powerpc/include/asm/mmu-book3e.h | 15 +
+ arch/powerpc/include/asm/paca.h | 10 +-
+ arch/powerpc/include/asm/page_64.h | 4 +-
+ arch/powerpc/include/asm/ppc-pci.h | 4 +-
+ arch/powerpc/include/asm/ppc_asm.h | 50 ++-
+ arch/powerpc/include/asm/processor.h | 4 +-
+ arch/powerpc/include/asm/pte-common.h | 7 +
+ arch/powerpc/include/asm/rtas.h | 1 +
+ arch/powerpc/include/asm/systbl.h | 19 +
+ arch/powerpc/include/asm/system.h | 4 +-
+ arch/powerpc/include/asm/time.h | 5 -
+ arch/powerpc/include/asm/unistd.h | 21 +-
+ arch/powerpc/kernel/Makefile | 4 +-
+ arch/powerpc/kernel/align.c | 4 +-
+ arch/powerpc/kernel/asm-offsets.c | 12 +-
+ arch/powerpc/kernel/cpu_setup_44x.S | 1 +
+ arch/powerpc/kernel/cpu_setup_fsl_booke.S | 15 +
+ arch/powerpc/kernel/cputable.c | 43 ++-
+ arch/powerpc/kernel/crash.c | 13 +-
+ arch/powerpc/kernel/dma-iommu.c | 21 +-
+ arch/powerpc/kernel/dma.c | 20 +-
+ arch/powerpc/kernel/entry_64.S | 40 ++
+ arch/powerpc/kernel/fpu.S | 10 -
+ arch/powerpc/kernel/head_fsl_booke.S | 10 +-
+ arch/powerpc/kernel/irq.c | 6 +-
+ arch/powerpc/kernel/lparcfg.c | 14 +-
+ arch/powerpc/kernel/machine_kexec.c | 24 ++
+ arch/powerpc/kernel/machine_kexec_32.c | 4 +
+ arch/powerpc/kernel/paca.c | 70 ++++-
+ arch/powerpc/kernel/pci-common.c | 4 +-
+ arch/powerpc/kernel/ppc970-pmu.c | 2 +
+ arch/powerpc/kernel/process.c | 12 -
+ arch/powerpc/kernel/ptrace.c | 2 +-
+ arch/powerpc/kernel/rtas.c | 4 +-
+ arch/powerpc/kernel/setup_32.c | 2 +-
+ arch/powerpc/kernel/smp.c | 14 +-
+ arch/powerpc/kernel/time.c | 275 +++++++-------
+ arch/powerpc/kernel/traps.c | 5 +
+ arch/powerpc/kernel/vdso.c | 6 +-
+ arch/powerpc/kernel/vdso32/Makefile | 6 +-
+ arch/powerpc/kernel/vdso64/Makefile | 6 +-
+ arch/powerpc/kernel/vio.c | 10 +-
+ arch/powerpc/kvm/Makefile | 2 +-
+ arch/powerpc/kvm/book3s_paired_singles.c | 44 +--
+ arch/powerpc/kvm/emulate.c | 4 +-
+ arch/powerpc/kvm/fpu.S | 8 -
+ arch/powerpc/lib/Makefile | 7 +-
+ arch/powerpc/lib/checksum_64.S | 482 +++++++++++++++++-------
+ arch/powerpc/lib/checksum_wrappers_64.c | 102 +++++
+ arch/powerpc/lib/copy_32.S | 2 +-
+ arch/powerpc/lib/ldstfp.S | 36 +-
+ arch/powerpc/lib/locks.c | 4 +-
+ arch/powerpc/lib/sstep.c | 8 +
+ arch/powerpc/math-emu/Makefile | 2 +-
+ arch/powerpc/mm/Makefile | 6 +-
+ arch/powerpc/mm/fault.c | 6 +
+ arch/powerpc/mm/fsl_booke_mmu.c | 15 +-
+ arch/powerpc/mm/mmu_context_nohash.c | 6 +-
+ arch/powerpc/mm/mmu_decl.h | 5 +-
+ arch/powerpc/mm/tlb_nohash.c | 56 +++-
+ arch/powerpc/mm/tlb_nohash_low.S | 2 +-
+ arch/powerpc/oprofile/Makefile | 4 +-
+ arch/powerpc/oprofile/backtrace.c | 2 +-
+ arch/powerpc/oprofile/op_model_fsl_emb.c | 15 +-
+ arch/powerpc/platforms/44x/Kconfig | 16 +
+ arch/powerpc/platforms/44x/ppc44x_simple.c | 1 +
+ arch/powerpc/platforms/83xx/Kconfig | 4 +-
+ arch/powerpc/platforms/83xx/mpc830x_rdb.c | 3 +-
+ arch/powerpc/platforms/85xx/Kconfig | 28 ++-
+ arch/powerpc/platforms/85xx/Makefile | 2 +
+ arch/powerpc/platforms/85xx/p1022_ds.c | 2 +
+ arch/powerpc/platforms/85xx/p3041_ds.c | 64 ++++
+ arch/powerpc/platforms/85xx/p5020_ds.c | 69 ++++
+ arch/powerpc/platforms/85xx/smp.c | 83 ++++-
+ arch/powerpc/platforms/Kconfig.cputype | 8 +-
+ arch/powerpc/platforms/cell/ras.c | 4 +-
+ arch/powerpc/platforms/cell/spider-pic.c | 4 +-
+ arch/powerpc/platforms/cell/spufs/file.c | 18 +
+ arch/powerpc/platforms/chrp/nvram.c | 4 +-
+ arch/powerpc/platforms/iseries/Makefile | 2 +-
+ arch/powerpc/platforms/iseries/dt.c | 4 +-
+ arch/powerpc/platforms/iseries/smp.c | 2 +-
+ arch/powerpc/platforms/maple/setup.c | 1 +
+ arch/powerpc/platforms/powermac/pfunc_core.c | 9 +-
+ arch/powerpc/platforms/pseries/Makefile | 13 +-
+ arch/powerpc/platforms/pseries/dlpar.c | 7 +-
+ arch/powerpc/platforms/pseries/dtl.c | 224 +++++++++---
+ arch/powerpc/platforms/pseries/lpar.c | 25 ++-
+ arch/powerpc/platforms/pseries/mobility.c | 362 ++++++++++++++++++
+ arch/powerpc/platforms/pseries/pseries.h | 9 +
+ arch/powerpc/platforms/pseries/setup.c | 52 +++
+ arch/powerpc/platforms/pseries/xics.c | 2 +-
+ arch/powerpc/sysdev/Makefile | 5 +-
+ arch/powerpc/sysdev/dart_iommu.c | 74 ++++-
+ arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h | 101 +++++
+ arch/powerpc/sysdev/fsl_85xx_cache_sram.c | 159 ++++++++
+ arch/powerpc/sysdev/fsl_85xx_l2ctlr.c | 231 +++++++++++
+ arch/powerpc/sysdev/fsl_msi.c | 9 +-
+ arch/powerpc/sysdev/fsl_pci.c | 60 +++-
+ arch/powerpc/sysdev/fsl_pci.h | 1 +
+ arch/powerpc/sysdev/fsl_rio.c | 65 ++--
+ arch/powerpc/sysdev/fsl_soc.c | 20 +-
+ arch/powerpc/sysdev/mpc8xxx_gpio.c | 3 +
+ arch/powerpc/sysdev/pmi.c | 2 +-
+ arch/powerpc/xmon/Makefile | 4 +-
+ drivers/i2c/busses/i2c-pasemi.c | 2 +-
+ drivers/macintosh/via-pmu-led.c | 4 +-
+ drivers/watchdog/Kconfig | 22 +-
+ drivers/watchdog/booke_wdt.c | 47 ++-
+ include/linux/pci_ids.h | 8 +
+ kernel/sys_ni.c | 1 +
+ 130 files changed, 3676 insertions(+), 683 deletions(-)
+ create mode 100644 arch/powerpc/boot/dts/bluestone.dts
+ create mode 100644 arch/powerpc/boot/dts/mpc8308_p1m.dts
+ create mode 100644 arch/powerpc/configs/44x/bluestone_defconfig
+ create mode 100644 arch/powerpc/configs/e55xx_smp_defconfig
+ create mode 100644 arch/powerpc/include/asm/fsl_85xx_cache_sram.h
+ create mode 100644 arch/powerpc/lib/checksum_wrappers_64.c
+ create mode 100644 arch/powerpc/platforms/85xx/p3041_ds.c
+ create mode 100644 arch/powerpc/platforms/85xx/p5020_ds.c
+ create mode 100644 arch/powerpc/platforms/pseries/mobility.c
+ create mode 100644 arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h
+ create mode 100644 arch/powerpc/sysdev/fsl_85xx_cache_sram.c
+ create mode 100644 arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
+
+
+_______________________________________________
+Linuxppc-dev mailing list
+Linuxppc-dev@lists.ozlabs.org
+https://lists.ozlabs.org/listinfo/linuxppc-dev
diff --git a/patchwork/tests/mail/0002-git-pull-request-wrapped.mbox b/patchwork/tests/mail/0002-git-pull-request-wrapped.mbox
new file mode 100644
index 0000000..d3ccee1
--- /dev/null
+++ b/patchwork/tests/mail/0002-git-pull-request-wrapped.mbox
@@ -0,0 +1,349 @@
+From benh@kernel.crashing.org Fri Oct 22 11:51:02 2010
+Return-Path: <linuxppc-dev-bounces+jk=ozlabs.org@lists.ozlabs.org>
+X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on bilbo.ozlabs.org
+X-Spam-Level:
+X-Spam-Status: No, score=0.0 required=3.0 tests=none autolearn=disabled
+ version=3.3.1
+X-Original-To: jk@ozlabs.org
+Delivered-To: jk@ozlabs.org
+Received: from bilbo.ozlabs.org (localhost [127.0.0.1])
+ by ozlabs.org (Postfix) with ESMTP id ED4B3100937
+ for <jk@ozlabs.org>; Fri, 22 Oct 2010 14:51:54 +1100 (EST)
+Received: by ozlabs.org (Postfix)
+ id BF799B70CB; Fri, 22 Oct 2010 14:51:50 +1100 (EST)
+Delivered-To: linuxppc-dev@ozlabs.org
+Received: from gate.crashing.org (gate.crashing.org [63.228.1.57])
+ (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
+ (Client did not present a certificate)
+ by ozlabs.org (Postfix) with ESMTPS id 94629B7043
+ for <linuxppc-dev@ozlabs.org>; Fri, 22 Oct 2010 14:51:49 +1100 (EST)
+Received: from [IPv6:::1] (localhost.localdomain [127.0.0.1])
+ by gate.crashing.org (8.14.1/8.13.8) with ESMTP id o9M3p3SP018234;
+ Thu, 21 Oct 2010 22:51:04 -0500
+Subject: [git pull] Please pull powerpc.git next branch
+From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+To: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Fri, 22 Oct 2010 14:51:02 +1100
+Message-ID: <1287719462.2198.37.camel@pasglop>
+Mime-Version: 1.0
+X-Mailer: Evolution 2.30.3
+Cc: linuxppc-dev list <linuxppc-dev@ozlabs.org>,
+ Andrew Morton <akpm@linux-foundation.org>,
+ Linux Kernel list <linux-kernel@vger.kernel.org>
+X-BeenThere: linuxppc-dev@lists.ozlabs.org
+X-Mailman-Version: 2.1.13
+Precedence: list
+List-Id: Linux on PowerPC Developers Mail List <cbe-oss-dev.ozlabs.org>
+List-Unsubscribe: <https://lists.ozlabs.org/options/linuxppc-dev>,
+ <mailto:linuxppc-dev-request@lists.ozlabs.org?subject=unsubscribe>
+List-Archive: <http://lists.ozlabs.org/pipermail/linuxppc-dev>
+List-Post: <mailto:linuxppc-dev@lists.ozlabs.org>
+List-Help: <mailto:linuxppc-dev-request@lists.ozlabs.org?subject=help>
+List-Subscribe: <https://lists.ozlabs.org/listinfo/linuxppc-dev>,
+ <mailto:linuxppc-dev-request@lists.ozlabs.org?subject=subscribe>
+Content-Type: text/plain;
+ charset="us-ascii"
+Content-Transfer-Encoding: 7bit
+Sender: linuxppc-dev-bounces+jk=ozlabs.org@lists.ozlabs.org
+Errors-To: linuxppc-dev-bounces+jk=ozlabs.org@lists.ozlabs.org
+X-UID: 11446
+X-Length: 16781
+Status: R
+X-Status: N
+X-KMail-EncryptionState:
+X-KMail-SignatureState:
+X-KMail-MDN-Sent:
+
+Hi Linus !
+
+Here's powerpc's batch for this merge window. Mostly bits and pieces,
+such as Anton doing some performance tuning left and right, and the
+usual churn. One hilight is the support for the new Freescale e5500 core
+(64-bit BookE). Another one is that we now wire up the whole lot of
+socket calls as direct syscalls in addition to the old style indirect
+method.
+
+Cheers,
+Ben.
+
+The following changes since commit
+e10117d36ef758da0690c95ecffc09d5dd7da479:
+ Linus Torvalds (1):
+ Merge branch 'upstream-linus' of git://git.kernel.org/.../jgarzik/libata-dev
+
+are available in the git repository at:
+
+ git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git next
+
+Andreas Schwab (1):
+ powerpc: Remove fpscr use from [kvm_]cvt_{fd,df}
+
+Anton Blanchard (5):
+ powerpc: Optimise 64bit csum_partial
+ powerpc: Optimise 64bit csum_partial_copy_generic and add csum_and_copy_from_user
+ powerpc: Add 64bit csum_and_copy_to_user
+ powerpc: Feature nop out reservation clear when stcx checks address
+ powerpc: Check end of stack canary at oops time
+
+Arnd Bergmann (1):
+ powerpc/spufs: Use llseek in all file operations
+
+Benjamin Herrenschmidt (4):
+ powerpc/dma: Add optional platform override of dma_set_mask()
+ powerpc/dart_iommu: Support for 64-bit iommu bypass window on PCIe
+ Merge remote branch 'kumar/merge' into next
+ Merge remote branch 'jwb/next' into next
+
+Denis Kirjanov (1):
+ powerpc: Use is_32bit_task() helper to test 32-bit binary
+
+Harninder Rai (1):
+ powerpc/85xx: add cache-sram support
+
+Ian Munsie (1):
+ powerpc: Wire up direct socket system calls
+
+Ilya Yanok (1):
+ powerpc/mpc83xx: Support for MPC8308 P1M board
+
+Joe Perches (2):
+ powerpc: Use static const char arrays
+ powerpc: Remove pr_<level> uses of KERN_<level>
+
+Josh Boyer (1):
+ powerpc/44x: Update ppc44x_defconfig
+
+Julia Lawall (7):
+ powerpc/via-pmu-led.c: Add of_node_put to avoid memory leak
+ powerpc/maple: Add of_node_put to avoid memory leak
+ powerpc/powermac/pfunc_core.c: Add of_node_put to avoid memory leak
+ powerpc/cell: Add of_node_put to avoid memory leak
+ powerpc/chrp/nvram.c: Add of_node_put to avoid memory leak
+ powerpc/irq.c: Add of_node_put to avoid memory leak
+ i2c/i2c-pasemi.c: Fix unsigned return type
+
+Kumar Gala (11):
+ powerpc/ppc64e: Fix link problem when building ppc64e_defconfig
+ powerpc/fsl-pci: Fix MSI support on 83xx platforms
+ powerpc/mpc8xxx_gpio: Add support for 'qoriq-gpio' controllers
+ powerpc/fsl-booke: Add PCI device ids for P2040/P3041/P5010/P5020 QoirQ chips
+ powerpc/fsl-booke: Add p3041 DS board support
+ powerpc: Fix compile error with paca code on ppc64e
+ powerpc/fsl-booke: Add support for FSL 64-bit e5500 core
+ powerpc/fsl-booke: Add support for FSL Arch v1.0 MMU in setup_page_sizes
+ powerpc/fsl-booke64: Use TLB CAMs to cover linear mapping on FSL 64-bit chips
+ powerpc/fsl-booke: Add p5020 DS board support
+ powerpc/fsl-booke: Add e55xx (64-bit) smp defconfig
+
+Matthew McClintock (7):
+ powerpc/mm: Assume first cpu is boot_cpuid not 0
+ powerpc/kexec: make masking/disabling interrupts generic
+ powerpc/85xx: Remove call to mpic_teardown_this_cpu in kexec
+ powerpc/85xx: Minor fixups for kexec on 85xx
+ powerpc/85xx: flush dcache before resetting cores
+ powerpc/fsl_soc: Search all global-utilities nodes for rstccr
+ powerpc/fsl_booke: Add support to boot from core other than 0
+
+Michael Neuling (1):
+ powerpc: Move arch_sd_sibling_asym_packing() to smp.c
+
+Nathan Fontenot (3):
+ powerpc/pseries: Export device tree updating routines
+ powerpc/pseries: Export rtas_ibm_suspend_me()
+ powerpc/pseries: Partition migration in the kernel
+
+Nishanth Aravamudan (8):
+ powerpc/pci: Fix return type of BUID_{HI,LO} macros
+ powerpc/dma: Fix dma_iommu_dma_supported compare
+ powerpc/dma: Fix check for direct DMA support
+ powerpc/vio: Use put_device() on device_register failure
+ powerpc/viobus: Free TCE table on device release
+ powerpc/pseries: Use kmemdup
+ powerpc/pci: Cleanup device dma setup code
+ powerpc/pseries/xics: Use cpu_possible_mask rather than cpu_all_mask
+
+Paul Gortmaker (1):
+ powerpc: Fix invalid page flags in create TLB CAM path for PTE_64BIT
+
+Paul Mackerras (5):
+ powerpc: Abstract indexing of lppaca structs
+ powerpc: Dynamically allocate most lppaca structs
+ powerpc: Account time using timebase rather than PURR
+ powerpc/pseries: Re-enable dispatch trace log userspace interface
+ powerpc/perf: Fix sampling enable for PPC970
+
+Scott Wood (1):
+ oprofile/fsl emb: Don't set MSR[PMM] until after clearing the interrupt.
+
+Sean MacLennan (2):
+ powerpc: Fix incorrect .stabs entry for copy_32.S
+ powerpc: mtmsrd not defined
+
+Shaohui Xie (1):
+ fsl_rio: Add comments for sRIO registers.
+
+Stephen Rothwell (1):
+ powerpc: define a compat_sys_recv cond_syscall
+
+Timur Tabi (5):
+ powerpc: export ppc_proc_freq and ppc_tb_freq as GPL symbols
+ powerpc/watchdog: Allow the Book-E driver to be compiled as a module
+ powerpc/p1022: Add probing for individual DMA channels
+ powerpc/85xx: add ngPIXIS FPGA device tree node to the P1022DS board
+ powerpc/watchdog: Make default timeout for Book-E watchdog a Kconfig option
+
+Tirumala Marri (1):
+ powerpc/44x: Add support for the AMCC APM821xx SoC
+
+matt mooney (1):
+ powerpc/Makefiles: Change to new flag variables
+
+ arch/powerpc/boot/addnote.c | 4 +-
+ arch/powerpc/boot/dts/bluestone.dts | 254 +++++++++++++
+ arch/powerpc/boot/dts/mpc8308_p1m.dts | 332 ++++++++++++++++
+ arch/powerpc/boot/dts/p1022ds.dts | 11 +
+ arch/powerpc/configs/44x/bluestone_defconfig | 68 ++++
+ arch/powerpc/configs/e55xx_smp_defconfig | 84 ++++
+ arch/powerpc/configs/ppc44x_defconfig | 9 +-
+ arch/powerpc/configs/ppc64e_defconfig | 4 +-
+ arch/powerpc/include/asm/checksum.h | 10 +
+ arch/powerpc/include/asm/compat.h | 4 +-
+ arch/powerpc/include/asm/cputable.h | 14 +-
+ arch/powerpc/include/asm/dma-mapping.h | 14 +-
+ arch/powerpc/include/asm/elf.h | 2 +-
+ arch/powerpc/include/asm/exception-64s.h | 3 +-
+ arch/powerpc/include/asm/fsl_85xx_cache_sram.h | 48 +++
+ arch/powerpc/include/asm/kexec.h | 1 +
+ arch/powerpc/include/asm/kvm_fpu.h | 4 +-
+ arch/powerpc/include/asm/lppaca.h | 29 ++
+ arch/powerpc/include/asm/machdep.h | 3 +
+ arch/powerpc/include/asm/mmu-book3e.h | 15 +
+ arch/powerpc/include/asm/paca.h | 10 +-
+ arch/powerpc/include/asm/page_64.h | 4 +-
+ arch/powerpc/include/asm/ppc-pci.h | 4 +-
+ arch/powerpc/include/asm/ppc_asm.h | 50 ++-
+ arch/powerpc/include/asm/processor.h | 4 +-
+ arch/powerpc/include/asm/pte-common.h | 7 +
+ arch/powerpc/include/asm/rtas.h | 1 +
+ arch/powerpc/include/asm/systbl.h | 19 +
+ arch/powerpc/include/asm/system.h | 4 +-
+ arch/powerpc/include/asm/time.h | 5 -
+ arch/powerpc/include/asm/unistd.h | 21 +-
+ arch/powerpc/kernel/Makefile | 4 +-
+ arch/powerpc/kernel/align.c | 4 +-
+ arch/powerpc/kernel/asm-offsets.c | 12 +-
+ arch/powerpc/kernel/cpu_setup_44x.S | 1 +
+ arch/powerpc/kernel/cpu_setup_fsl_booke.S | 15 +
+ arch/powerpc/kernel/cputable.c | 43 ++-
+ arch/powerpc/kernel/crash.c | 13 +-
+ arch/powerpc/kernel/dma-iommu.c | 21 +-
+ arch/powerpc/kernel/dma.c | 20 +-
+ arch/powerpc/kernel/entry_64.S | 40 ++
+ arch/powerpc/kernel/fpu.S | 10 -
+ arch/powerpc/kernel/head_fsl_booke.S | 10 +-
+ arch/powerpc/kernel/irq.c | 6 +-
+ arch/powerpc/kernel/lparcfg.c | 14 +-
+ arch/powerpc/kernel/machine_kexec.c | 24 ++
+ arch/powerpc/kernel/machine_kexec_32.c | 4 +
+ arch/powerpc/kernel/paca.c | 70 ++++-
+ arch/powerpc/kernel/pci-common.c | 4 +-
+ arch/powerpc/kernel/ppc970-pmu.c | 2 +
+ arch/powerpc/kernel/process.c | 12 -
+ arch/powerpc/kernel/ptrace.c | 2 +-
+ arch/powerpc/kernel/rtas.c | 4 +-
+ arch/powerpc/kernel/setup_32.c | 2 +-
+ arch/powerpc/kernel/smp.c | 14 +-
+ arch/powerpc/kernel/time.c | 275 +++++++-------
+ arch/powerpc/kernel/traps.c | 5 +
+ arch/powerpc/kernel/vdso.c | 6 +-
+ arch/powerpc/kernel/vdso32/Makefile | 6 +-
+ arch/powerpc/kernel/vdso64/Makefile | 6 +-
+ arch/powerpc/kernel/vio.c | 10 +-
+ arch/powerpc/kvm/Makefile | 2 +-
+ arch/powerpc/kvm/book3s_paired_singles.c | 44 +--
+ arch/powerpc/kvm/emulate.c | 4 +-
+ arch/powerpc/kvm/fpu.S | 8 -
+ arch/powerpc/lib/Makefile | 7 +-
+ arch/powerpc/lib/checksum_64.S | 482 +++++++++++++++++-------
+ arch/powerpc/lib/checksum_wrappers_64.c | 102 +++++
+ arch/powerpc/lib/copy_32.S | 2 +-
+ arch/powerpc/lib/ldstfp.S | 36 +-
+ arch/powerpc/lib/locks.c | 4 +-
+ arch/powerpc/lib/sstep.c | 8 +
+ arch/powerpc/math-emu/Makefile | 2 +-
+ arch/powerpc/mm/Makefile | 6 +-
+ arch/powerpc/mm/fault.c | 6 +
+ arch/powerpc/mm/fsl_booke_mmu.c | 15 +-
+ arch/powerpc/mm/mmu_context_nohash.c | 6 +-
+ arch/powerpc/mm/mmu_decl.h | 5 +-
+ arch/powerpc/mm/tlb_nohash.c | 56 +++-
+ arch/powerpc/mm/tlb_nohash_low.S | 2 +-
+ arch/powerpc/oprofile/Makefile | 4 +-
+ arch/powerpc/oprofile/backtrace.c | 2 +-
+ arch/powerpc/oprofile/op_model_fsl_emb.c | 15 +-
+ arch/powerpc/platforms/44x/Kconfig | 16 +
+ arch/powerpc/platforms/44x/ppc44x_simple.c | 1 +
+ arch/powerpc/platforms/83xx/Kconfig | 4 +-
+ arch/powerpc/platforms/83xx/mpc830x_rdb.c | 3 +-
+ arch/powerpc/platforms/85xx/Kconfig | 28 ++-
+ arch/powerpc/platforms/85xx/Makefile | 2 +
+ arch/powerpc/platforms/85xx/p1022_ds.c | 2 +
+ arch/powerpc/platforms/85xx/p3041_ds.c | 64 ++++
+ arch/powerpc/platforms/85xx/p5020_ds.c | 69 ++++
+ arch/powerpc/platforms/85xx/smp.c | 83 ++++-
+ arch/powerpc/platforms/Kconfig.cputype | 8 +-
+ arch/powerpc/platforms/cell/ras.c | 4 +-
+ arch/powerpc/platforms/cell/spider-pic.c | 4 +-
+ arch/powerpc/platforms/cell/spufs/file.c | 18 +
+ arch/powerpc/platforms/chrp/nvram.c | 4 +-
+ arch/powerpc/platforms/iseries/Makefile | 2 +-
+ arch/powerpc/platforms/iseries/dt.c | 4 +-
+ arch/powerpc/platforms/iseries/smp.c | 2 +-
+ arch/powerpc/platforms/maple/setup.c | 1 +
+ arch/powerpc/platforms/powermac/pfunc_core.c | 9 +-
+ arch/powerpc/platforms/pseries/Makefile | 13 +-
+ arch/powerpc/platforms/pseries/dlpar.c | 7 +-
+ arch/powerpc/platforms/pseries/dtl.c | 224 +++++++++---
+ arch/powerpc/platforms/pseries/lpar.c | 25 ++-
+ arch/powerpc/platforms/pseries/mobility.c | 362 ++++++++++++++++++
+ arch/powerpc/platforms/pseries/pseries.h | 9 +
+ arch/powerpc/platforms/pseries/setup.c | 52 +++
+ arch/powerpc/platforms/pseries/xics.c | 2 +-
+ arch/powerpc/sysdev/Makefile | 5 +-
+ arch/powerpc/sysdev/dart_iommu.c | 74 ++++-
+ arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h | 101 +++++
+ arch/powerpc/sysdev/fsl_85xx_cache_sram.c | 159 ++++++++
+ arch/powerpc/sysdev/fsl_85xx_l2ctlr.c | 231 +++++++++++
+ arch/powerpc/sysdev/fsl_msi.c | 9 +-
+ arch/powerpc/sysdev/fsl_pci.c | 60 +++-
+ arch/powerpc/sysdev/fsl_pci.h | 1 +
+ arch/powerpc/sysdev/fsl_rio.c | 65 ++--
+ arch/powerpc/sysdev/fsl_soc.c | 20 +-
+ arch/powerpc/sysdev/mpc8xxx_gpio.c | 3 +
+ arch/powerpc/sysdev/pmi.c | 2 +-
+ arch/powerpc/xmon/Makefile | 4 +-
+ drivers/i2c/busses/i2c-pasemi.c | 2 +-
+ drivers/macintosh/via-pmu-led.c | 4 +-
+ drivers/watchdog/Kconfig | 22 +-
+ drivers/watchdog/booke_wdt.c | 47 ++-
+ include/linux/pci_ids.h | 8 +
+ kernel/sys_ni.c | 1 +
+ 130 files changed, 3676 insertions(+), 683 deletions(-)
+ create mode 100644 arch/powerpc/boot/dts/bluestone.dts
+ create mode 100644 arch/powerpc/boot/dts/mpc8308_p1m.dts
+ create mode 100644 arch/powerpc/configs/44x/bluestone_defconfig
+ create mode 100644 arch/powerpc/configs/e55xx_smp_defconfig
+ create mode 100644 arch/powerpc/include/asm/fsl_85xx_cache_sram.h
+ create mode 100644 arch/powerpc/lib/checksum_wrappers_64.c
+ create mode 100644 arch/powerpc/platforms/85xx/p3041_ds.c
+ create mode 100644 arch/powerpc/platforms/85xx/p5020_ds.c
+ create mode 100644 arch/powerpc/platforms/pseries/mobility.c
+ create mode 100644 arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h
+ create mode 100644 arch/powerpc/sysdev/fsl_85xx_cache_sram.c
+ create mode 100644 arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
+
+
+_______________________________________________
+Linuxppc-dev mailing list
+Linuxppc-dev@lists.ozlabs.org
+https://lists.ozlabs.org/listinfo/linuxppc-dev
diff --git a/patchwork/tests/mail/0003-git-pull-request-with-diff.mbox b/patchwork/tests/mail/0003-git-pull-request-with-diff.mbox
new file mode 100644
index 0000000..b4d578c
--- /dev/null
+++ b/patchwork/tests/mail/0003-git-pull-request-with-diff.mbox
@@ -0,0 +1,141 @@
+From benh@kernel.crashing.org Fri Oct 22 11:51:02 2010
+Return-Path: <linuxppc-dev-bounces+jk=ozlabs.org@lists.ozlabs.org>
+X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on bilbo.ozlabs.org
+X-Spam-Level:
+X-Spam-Status: No, score=0.0 required=3.0 tests=none autolearn=disabled
+ version=3.3.1
+X-Original-To: jk@ozlabs.org
+Delivered-To: jk@ozlabs.org
+Received: from bilbo.ozlabs.org (localhost [127.0.0.1])
+ by ozlabs.org (Postfix) with ESMTP id ED4B3100937
+ for <jk@ozlabs.org>; Fri, 22 Oct 2010 14:51:54 +1100 (EST)
+Received: by ozlabs.org (Postfix)
+ id BF799B70CB; Fri, 22 Oct 2010 14:51:50 +1100 (EST)
+Delivered-To: linuxppc-dev@ozlabs.org
+Received: from gate.crashing.org (gate.crashing.org [63.228.1.57])
+ (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
+ (Client did not present a certificate)
+ by ozlabs.org (Postfix) with ESMTPS id 94629B7043
+ for <linuxppc-dev@ozlabs.org>; Fri, 22 Oct 2010 14:51:49 +1100 (EST)
+Received: from [IPv6:::1] (localhost.localdomain [127.0.0.1])
+ by gate.crashing.org (8.14.1/8.13.8) with ESMTP id o9M3p3SP018234;
+ Thu, 21 Oct 2010 22:51:04 -0500
+Subject: [git pull] Please pull powerpc.git next branch
+From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+To: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Fri, 22 Oct 2010 14:51:02 +1100
+Message-ID: <1287719462.2198.37.camel@pasglop>
+Mime-Version: 1.0
+X-Mailer: Evolution 2.30.3
+Cc: linuxppc-dev list <linuxppc-dev@ozlabs.org>,
+ Andrew Morton <akpm@linux-foundation.org>,
+ Linux Kernel list <linux-kernel@vger.kernel.org>
+X-BeenThere: linuxppc-dev@lists.ozlabs.org
+X-Mailman-Version: 2.1.13
+Precedence: list
+List-Id: Linux on PowerPC Developers Mail List <cbe-oss-dev.ozlabs.org>
+List-Unsubscribe: <https://lists.ozlabs.org/options/linuxppc-dev>,
+ <mailto:linuxppc-dev-request@lists.ozlabs.org?subject=unsubscribe>
+List-Archive: <http://lists.ozlabs.org/pipermail/linuxppc-dev>
+List-Post: <mailto:linuxppc-dev@lists.ozlabs.org>
+List-Help: <mailto:linuxppc-dev-request@lists.ozlabs.org?subject=help>
+List-Subscribe: <https://lists.ozlabs.org/listinfo/linuxppc-dev>,
+ <mailto:linuxppc-dev-request@lists.ozlabs.org?subject=subscribe>
+Content-Type: text/plain;
+ charset="us-ascii"
+Content-Transfer-Encoding: 7bit
+Sender: linuxppc-dev-bounces+jk=ozlabs.org@lists.ozlabs.org
+Errors-To: linuxppc-dev-bounces+jk=ozlabs.org@lists.ozlabs.org
+X-UID: 11446
+X-Length: 16781
+Status: R
+X-Status: N
+X-KMail-EncryptionState:
+X-KMail-SignatureState:
+X-KMail-MDN-Sent:
+
+The following changes since commit e10117d36ef758da0690c95ecffc09d5dd7da479:
+ Linus Torvalds (1):
+ Merge branch 'upstream-linus' of git://git.kernel.org/.../jgarzik/libata-dev
+
+are available in the git repository at:
+
+ git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git x86-fixes-for-linus
+
+------------------>
+H. Peter Anvin (1):
+ x86-32: Make sure the stack is set up before we use it
+Matthieu CASTET (1):
+ x86, nx: Don't force pages RW when setting NX bits
+
+Suresh Siddha (1):
+ x86, mtrr: Avoid MTRR reprogramming on BP during boot on UP platforms
+
+
+ arch/x86/include/asm/smp.h | 5 +----
+ arch/x86/kernel/acpi/sleep.c | 2 +-
+ arch/x86/kernel/cpu/mtrr/main.c | 10 +++++++++-
+ arch/x86/kernel/head_32.S | 30 +++++++++++++-----------------
+ arch/x86/kernel/smpboot.c | 4 ++--
+ arch/x86/mm/pageattr.c | 8 --------
+ 6 files changed, 26 insertions(+), 33 deletions(-)
+diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
+index 4c2f63c..1f46951 100644
+--- a/arch/x86/include/asm/smp.h
++++ b/arch/x86/include/asm/smp.h
+@@ -40,10 +40,7 @@ DECLARE_EARLY_PER_CPU(u16, x86_cpu_to_apicid);
+ DECLARE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid);
+
+ /* Static state in head.S used to set up a CPU */
+-extern struct {
+- void *sp;
+- unsigned short ss;
+-} stack_start;
++extern unsigned long stack_start; /* Initial stack pointer address */
+
+ struct smp_ops {
+ void (*smp_prepare_boot_cpu)(void);
+diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
+index 69fd72a..4d9ebba 100644
+--- a/arch/x86/kernel/acpi/sleep.c
++++ b/arch/x86/kernel/acpi/sleep.c
+@@ -100,7 +100,7 @@ int acpi_save_state_mem(void)
+ #else /* CONFIG_64BIT */
+ header->trampoline_segment = setup_trampoline() >> 4;
+ #ifdef CONFIG_SMP
+- stack_start.sp = temp_stack + sizeof(temp_stack);
++ stack_start = (unsigned long)temp_stack + sizeof(temp_stack);
+ early_gdt_descr.address =
+ (unsigned long)get_cpu_gdt_table(smp_processor_id());
+ initial_gs = per_cpu_offset(smp_processor_id());
+diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
+index 01c0f3e..bebabec 100644
+--- a/arch/x86/kernel/cpu/mtrr/main.c
++++ b/arch/x86/kernel/cpu/mtrr/main.c
+@@ -793,13 +793,21 @@ void set_mtrr_aps_delayed_init(void)
+ }
+
+ /*
+- * MTRR initialization for all AP's
++ * Delayed MTRR initialization for all AP's
+ */
+ void mtrr_aps_init(void)
+ {
+ if (!use_intel())
+ return;
+
++ /*
++ * Check if someone has requested the delay of AP MTRR initialization,
++ * by doing set_mtrr_aps_delayed_init(), prior to this point. If not,
++ * then we are done.
++ */
++ if (!mtrr_aps_delayed_init)
++ return;
++
+ set_mtrr(~0U, 0, 0, 0);
+ mtrr_aps_delayed_init = false;
+ }
+_______________________________________________
+Linuxppc-dev mailing list
+Linuxppc-dev@lists.ozlabs.org
+https://lists.ozlabs.org/listinfo/linuxppc-dev
diff --git a/patchwork/tests/mail/0004-git-pull-request-git+ssh.mbox b/patchwork/tests/mail/0004-git-pull-request-git+ssh.mbox
new file mode 100644
index 0000000..da96465
--- /dev/null
+++ b/patchwork/tests/mail/0004-git-pull-request-git+ssh.mbox
@@ -0,0 +1,348 @@
+From benh@kernel.crashing.org Fri Oct 22 11:51:02 2010
+Return-Path: <linuxppc-dev-bounces+jk=ozlabs.org@lists.ozlabs.org>
+X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on bilbo.ozlabs.org
+X-Spam-Level:
+X-Spam-Status: No, score=0.0 required=3.0 tests=none autolearn=disabled
+ version=3.3.1
+X-Original-To: jk@ozlabs.org
+Delivered-To: jk@ozlabs.org
+Received: from bilbo.ozlabs.org (localhost [127.0.0.1])
+ by ozlabs.org (Postfix) with ESMTP id ED4B3100937
+ for <jk@ozlabs.org>; Fri, 22 Oct 2010 14:51:54 +1100 (EST)
+Received: by ozlabs.org (Postfix)
+ id BF799B70CB; Fri, 22 Oct 2010 14:51:50 +1100 (EST)
+Delivered-To: linuxppc-dev@ozlabs.org
+Received: from gate.crashing.org (gate.crashing.org [63.228.1.57])
+ (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
+ (Client did not present a certificate)
+ by ozlabs.org (Postfix) with ESMTPS id 94629B7043
+ for <linuxppc-dev@ozlabs.org>; Fri, 22 Oct 2010 14:51:49 +1100 (EST)
+Received: from [IPv6:::1] (localhost.localdomain [127.0.0.1])
+ by gate.crashing.org (8.14.1/8.13.8) with ESMTP id o9M3p3SP018234;
+ Thu, 21 Oct 2010 22:51:04 -0500
+Subject: [git pull] Please pull powerpc.git next branch
+From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+To: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Fri, 22 Oct 2010 14:51:02 +1100
+Message-ID: <1287719462.2198.37.camel@pasglop>
+Mime-Version: 1.0
+X-Mailer: Evolution 2.30.3
+Cc: linuxppc-dev list <linuxppc-dev@ozlabs.org>,
+ Andrew Morton <akpm@linux-foundation.org>,
+ Linux Kernel list <linux-kernel@vger.kernel.org>
+X-BeenThere: linuxppc-dev@lists.ozlabs.org
+X-Mailman-Version: 2.1.13
+Precedence: list
+List-Id: Linux on PowerPC Developers Mail List <cbe-oss-dev.ozlabs.org>
+List-Unsubscribe: <https://lists.ozlabs.org/options/linuxppc-dev>,
+ <mailto:linuxppc-dev-request@lists.ozlabs.org?subject=unsubscribe>
+List-Archive: <http://lists.ozlabs.org/pipermail/linuxppc-dev>
+List-Post: <mailto:linuxppc-dev@lists.ozlabs.org>
+List-Help: <mailto:linuxppc-dev-request@lists.ozlabs.org?subject=help>
+List-Subscribe: <https://lists.ozlabs.org/listinfo/linuxppc-dev>,
+ <mailto:linuxppc-dev-request@lists.ozlabs.org?subject=subscribe>
+Content-Type: text/plain;
+ charset="us-ascii"
+Content-Transfer-Encoding: 7bit
+Sender: linuxppc-dev-bounces+jk=ozlabs.org@lists.ozlabs.org
+Errors-To: linuxppc-dev-bounces+jk=ozlabs.org@lists.ozlabs.org
+X-UID: 11446
+X-Length: 16781
+Status: R
+X-Status: N
+X-KMail-EncryptionState:
+X-KMail-SignatureState:
+X-KMail-MDN-Sent:
+
+Hi Linus !
+
+Here's powerpc's batch for this merge window. Mostly bits and pieces,
+such as Anton doing some performance tuning left and right, and the
+usual churn. One hilight is the support for the new Freescale e5500 core
+(64-bit BookE). Another one is that we now wire up the whole lot of
+socket calls as direct syscalls in addition to the old style indirect
+method.
+
+Cheers,
+Ben.
+
+The following changes since commit e10117d36ef758da0690c95ecffc09d5dd7da479:
+ Linus Torvalds (1):
+ Merge branch 'upstream-linus' of git://git.kernel.org/.../jgarzik/libata-dev
+
+are available in the git repository at:
+
+ git+ssh://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git next
+
+Andreas Schwab (1):
+ powerpc: Remove fpscr use from [kvm_]cvt_{fd,df}
+
+Anton Blanchard (5):
+ powerpc: Optimise 64bit csum_partial
+ powerpc: Optimise 64bit csum_partial_copy_generic and add csum_and_copy_from_user
+ powerpc: Add 64bit csum_and_copy_to_user
+ powerpc: Feature nop out reservation clear when stcx checks address
+ powerpc: Check end of stack canary at oops time
+
+Arnd Bergmann (1):
+ powerpc/spufs: Use llseek in all file operations
+
+Benjamin Herrenschmidt (4):
+ powerpc/dma: Add optional platform override of dma_set_mask()
+ powerpc/dart_iommu: Support for 64-bit iommu bypass window on PCIe
+ Merge remote branch 'kumar/merge' into next
+ Merge remote branch 'jwb/next' into next
+
+Denis Kirjanov (1):
+ powerpc: Use is_32bit_task() helper to test 32-bit binary
+
+Harninder Rai (1):
+ powerpc/85xx: add cache-sram support
+
+Ian Munsie (1):
+ powerpc: Wire up direct socket system calls
+
+Ilya Yanok (1):
+ powerpc/mpc83xx: Support for MPC8308 P1M board
+
+Joe Perches (2):
+ powerpc: Use static const char arrays
+ powerpc: Remove pr_<level> uses of KERN_<level>
+
+Josh Boyer (1):
+ powerpc/44x: Update ppc44x_defconfig
+
+Julia Lawall (7):
+ powerpc/via-pmu-led.c: Add of_node_put to avoid memory leak
+ powerpc/maple: Add of_node_put to avoid memory leak
+ powerpc/powermac/pfunc_core.c: Add of_node_put to avoid memory leak
+ powerpc/cell: Add of_node_put to avoid memory leak
+ powerpc/chrp/nvram.c: Add of_node_put to avoid memory leak
+ powerpc/irq.c: Add of_node_put to avoid memory leak
+ i2c/i2c-pasemi.c: Fix unsigned return type
+
+Kumar Gala (11):
+ powerpc/ppc64e: Fix link problem when building ppc64e_defconfig
+ powerpc/fsl-pci: Fix MSI support on 83xx platforms
+ powerpc/mpc8xxx_gpio: Add support for 'qoriq-gpio' controllers
+ powerpc/fsl-booke: Add PCI device ids for P2040/P3041/P5010/P5020 QoirQ chips
+ powerpc/fsl-booke: Add p3041 DS board support
+ powerpc: Fix compile error with paca code on ppc64e
+ powerpc/fsl-booke: Add support for FSL 64-bit e5500 core
+ powerpc/fsl-booke: Add support for FSL Arch v1.0 MMU in setup_page_sizes
+ powerpc/fsl-booke64: Use TLB CAMs to cover linear mapping on FSL 64-bit chips
+ powerpc/fsl-booke: Add p5020 DS board support
+ powerpc/fsl-booke: Add e55xx (64-bit) smp defconfig
+
+Matthew McClintock (7):
+ powerpc/mm: Assume first cpu is boot_cpuid not 0
+ powerpc/kexec: make masking/disabling interrupts generic
+ powerpc/85xx: Remove call to mpic_teardown_this_cpu in kexec
+ powerpc/85xx: Minor fixups for kexec on 85xx
+ powerpc/85xx: flush dcache before resetting cores
+ powerpc/fsl_soc: Search all global-utilities nodes for rstccr
+ powerpc/fsl_booke: Add support to boot from core other than 0
+
+Michael Neuling (1):
+ powerpc: Move arch_sd_sibling_asym_packing() to smp.c
+
+Nathan Fontenot (3):
+ powerpc/pseries: Export device tree updating routines
+ powerpc/pseries: Export rtas_ibm_suspend_me()
+ powerpc/pseries: Partition migration in the kernel
+
+Nishanth Aravamudan (8):
+ powerpc/pci: Fix return type of BUID_{HI,LO} macros
+ powerpc/dma: Fix dma_iommu_dma_supported compare
+ powerpc/dma: Fix check for direct DMA support
+ powerpc/vio: Use put_device() on device_register failure
+ powerpc/viobus: Free TCE table on device release
+ powerpc/pseries: Use kmemdup
+ powerpc/pci: Cleanup device dma setup code
+ powerpc/pseries/xics: Use cpu_possible_mask rather than cpu_all_mask
+
+Paul Gortmaker (1):
+ powerpc: Fix invalid page flags in create TLB CAM path for PTE_64BIT
+
+Paul Mackerras (5):
+ powerpc: Abstract indexing of lppaca structs
+ powerpc: Dynamically allocate most lppaca structs
+ powerpc: Account time using timebase rather than PURR
+ powerpc/pseries: Re-enable dispatch trace log userspace interface
+ powerpc/perf: Fix sampling enable for PPC970
+
+Scott Wood (1):
+ oprofile/fsl emb: Don't set MSR[PMM] until after clearing the interrupt.
+
+Sean MacLennan (2):
+ powerpc: Fix incorrect .stabs entry for copy_32.S
+ powerpc: mtmsrd not defined
+
+Shaohui Xie (1):
+ fsl_rio: Add comments for sRIO registers.
+
+Stephen Rothwell (1):
+ powerpc: define a compat_sys_recv cond_syscall
+
+Timur Tabi (5):
+ powerpc: export ppc_proc_freq and ppc_tb_freq as GPL symbols
+ powerpc/watchdog: Allow the Book-E driver to be compiled as a module
+ powerpc/p1022: Add probing for individual DMA channels
+ powerpc/85xx: add ngPIXIS FPGA device tree node to the P1022DS board
+ powerpc/watchdog: Make default timeout for Book-E watchdog a Kconfig option
+
+Tirumala Marri (1):
+ powerpc/44x: Add support for the AMCC APM821xx SoC
+
+matt mooney (1):
+ powerpc/Makefiles: Change to new flag variables
+
+ arch/powerpc/boot/addnote.c | 4 +-
+ arch/powerpc/boot/dts/bluestone.dts | 254 +++++++++++++
+ arch/powerpc/boot/dts/mpc8308_p1m.dts | 332 ++++++++++++++++
+ arch/powerpc/boot/dts/p1022ds.dts | 11 +
+ arch/powerpc/configs/44x/bluestone_defconfig | 68 ++++
+ arch/powerpc/configs/e55xx_smp_defconfig | 84 ++++
+ arch/powerpc/configs/ppc44x_defconfig | 9 +-
+ arch/powerpc/configs/ppc64e_defconfig | 4 +-
+ arch/powerpc/include/asm/checksum.h | 10 +
+ arch/powerpc/include/asm/compat.h | 4 +-
+ arch/powerpc/include/asm/cputable.h | 14 +-
+ arch/powerpc/include/asm/dma-mapping.h | 14 +-
+ arch/powerpc/include/asm/elf.h | 2 +-
+ arch/powerpc/include/asm/exception-64s.h | 3 +-
+ arch/powerpc/include/asm/fsl_85xx_cache_sram.h | 48 +++
+ arch/powerpc/include/asm/kexec.h | 1 +
+ arch/powerpc/include/asm/kvm_fpu.h | 4 +-
+ arch/powerpc/include/asm/lppaca.h | 29 ++
+ arch/powerpc/include/asm/machdep.h | 3 +
+ arch/powerpc/include/asm/mmu-book3e.h | 15 +
+ arch/powerpc/include/asm/paca.h | 10 +-
+ arch/powerpc/include/asm/page_64.h | 4 +-
+ arch/powerpc/include/asm/ppc-pci.h | 4 +-
+ arch/powerpc/include/asm/ppc_asm.h | 50 ++-
+ arch/powerpc/include/asm/processor.h | 4 +-
+ arch/powerpc/include/asm/pte-common.h | 7 +
+ arch/powerpc/include/asm/rtas.h | 1 +
+ arch/powerpc/include/asm/systbl.h | 19 +
+ arch/powerpc/include/asm/system.h | 4 +-
+ arch/powerpc/include/asm/time.h | 5 -
+ arch/powerpc/include/asm/unistd.h | 21 +-
+ arch/powerpc/kernel/Makefile | 4 +-
+ arch/powerpc/kernel/align.c | 4 +-
+ arch/powerpc/kernel/asm-offsets.c | 12 +-
+ arch/powerpc/kernel/cpu_setup_44x.S | 1 +
+ arch/powerpc/kernel/cpu_setup_fsl_booke.S | 15 +
+ arch/powerpc/kernel/cputable.c | 43 ++-
+ arch/powerpc/kernel/crash.c | 13 +-
+ arch/powerpc/kernel/dma-iommu.c | 21 +-
+ arch/powerpc/kernel/dma.c | 20 +-
+ arch/powerpc/kernel/entry_64.S | 40 ++
+ arch/powerpc/kernel/fpu.S | 10 -
+ arch/powerpc/kernel/head_fsl_booke.S | 10 +-
+ arch/powerpc/kernel/irq.c | 6 +-
+ arch/powerpc/kernel/lparcfg.c | 14 +-
+ arch/powerpc/kernel/machine_kexec.c | 24 ++
+ arch/powerpc/kernel/machine_kexec_32.c | 4 +
+ arch/powerpc/kernel/paca.c | 70 ++++-
+ arch/powerpc/kernel/pci-common.c | 4 +-
+ arch/powerpc/kernel/ppc970-pmu.c | 2 +
+ arch/powerpc/kernel/process.c | 12 -
+ arch/powerpc/kernel/ptrace.c | 2 +-
+ arch/powerpc/kernel/rtas.c | 4 +-
+ arch/powerpc/kernel/setup_32.c | 2 +-
+ arch/powerpc/kernel/smp.c | 14 +-
+ arch/powerpc/kernel/time.c | 275 +++++++-------
+ arch/powerpc/kernel/traps.c | 5 +
+ arch/powerpc/kernel/vdso.c | 6 +-
+ arch/powerpc/kernel/vdso32/Makefile | 6 +-
+ arch/powerpc/kernel/vdso64/Makefile | 6 +-
+ arch/powerpc/kernel/vio.c | 10 +-
+ arch/powerpc/kvm/Makefile | 2 +-
+ arch/powerpc/kvm/book3s_paired_singles.c | 44 +--
+ arch/powerpc/kvm/emulate.c | 4 +-
+ arch/powerpc/kvm/fpu.S | 8 -
+ arch/powerpc/lib/Makefile | 7 +-
+ arch/powerpc/lib/checksum_64.S | 482 +++++++++++++++++-------
+ arch/powerpc/lib/checksum_wrappers_64.c | 102 +++++
+ arch/powerpc/lib/copy_32.S | 2 +-
+ arch/powerpc/lib/ldstfp.S | 36 +-
+ arch/powerpc/lib/locks.c | 4 +-
+ arch/powerpc/lib/sstep.c | 8 +
+ arch/powerpc/math-emu/Makefile | 2 +-
+ arch/powerpc/mm/Makefile | 6 +-
+ arch/powerpc/mm/fault.c | 6 +
+ arch/powerpc/mm/fsl_booke_mmu.c | 15 +-
+ arch/powerpc/mm/mmu_context_nohash.c | 6 +-
+ arch/powerpc/mm/mmu_decl.h | 5 +-
+ arch/powerpc/mm/tlb_nohash.c | 56 +++-
+ arch/powerpc/mm/tlb_nohash_low.S | 2 +-
+ arch/powerpc/oprofile/Makefile | 4 +-
+ arch/powerpc/oprofile/backtrace.c | 2 +-
+ arch/powerpc/oprofile/op_model_fsl_emb.c | 15 +-
+ arch/powerpc/platforms/44x/Kconfig | 16 +
+ arch/powerpc/platforms/44x/ppc44x_simple.c | 1 +
+ arch/powerpc/platforms/83xx/Kconfig | 4 +-
+ arch/powerpc/platforms/83xx/mpc830x_rdb.c | 3 +-
+ arch/powerpc/platforms/85xx/Kconfig | 28 ++-
+ arch/powerpc/platforms/85xx/Makefile | 2 +
+ arch/powerpc/platforms/85xx/p1022_ds.c | 2 +
+ arch/powerpc/platforms/85xx/p3041_ds.c | 64 ++++
+ arch/powerpc/platforms/85xx/p5020_ds.c | 69 ++++
+ arch/powerpc/platforms/85xx/smp.c | 83 ++++-
+ arch/powerpc/platforms/Kconfig.cputype | 8 +-
+ arch/powerpc/platforms/cell/ras.c | 4 +-
+ arch/powerpc/platforms/cell/spider-pic.c | 4 +-
+ arch/powerpc/platforms/cell/spufs/file.c | 18 +
+ arch/powerpc/platforms/chrp/nvram.c | 4 +-
+ arch/powerpc/platforms/iseries/Makefile | 2 +-
+ arch/powerpc/platforms/iseries/dt.c | 4 +-
+ arch/powerpc/platforms/iseries/smp.c | 2 +-
+ arch/powerpc/platforms/maple/setup.c | 1 +
+ arch/powerpc/platforms/powermac/pfunc_core.c | 9 +-
+ arch/powerpc/platforms/pseries/Makefile | 13 +-
+ arch/powerpc/platforms/pseries/dlpar.c | 7 +-
+ arch/powerpc/platforms/pseries/dtl.c | 224 +++++++++---
+ arch/powerpc/platforms/pseries/lpar.c | 25 ++-
+ arch/powerpc/platforms/pseries/mobility.c | 362 ++++++++++++++++++
+ arch/powerpc/platforms/pseries/pseries.h | 9 +
+ arch/powerpc/platforms/pseries/setup.c | 52 +++
+ arch/powerpc/platforms/pseries/xics.c | 2 +-
+ arch/powerpc/sysdev/Makefile | 5 +-
+ arch/powerpc/sysdev/dart_iommu.c | 74 ++++-
+ arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h | 101 +++++
+ arch/powerpc/sysdev/fsl_85xx_cache_sram.c | 159 ++++++++
+ arch/powerpc/sysdev/fsl_85xx_l2ctlr.c | 231 +++++++++++
+ arch/powerpc/sysdev/fsl_msi.c | 9 +-
+ arch/powerpc/sysdev/fsl_pci.c | 60 +++-
+ arch/powerpc/sysdev/fsl_pci.h | 1 +
+ arch/powerpc/sysdev/fsl_rio.c | 65 ++--
+ arch/powerpc/sysdev/fsl_soc.c | 20 +-
+ arch/powerpc/sysdev/mpc8xxx_gpio.c | 3 +
+ arch/powerpc/sysdev/pmi.c | 2 +-
+ arch/powerpc/xmon/Makefile | 4 +-
+ drivers/i2c/busses/i2c-pasemi.c | 2 +-
+ drivers/macintosh/via-pmu-led.c | 4 +-
+ drivers/watchdog/Kconfig | 22 +-
+ drivers/watchdog/booke_wdt.c | 47 ++-
+ include/linux/pci_ids.h | 8 +
+ kernel/sys_ni.c | 1 +
+ 130 files changed, 3676 insertions(+), 683 deletions(-)
+ create mode 100644 arch/powerpc/boot/dts/bluestone.dts
+ create mode 100644 arch/powerpc/boot/dts/mpc8308_p1m.dts
+ create mode 100644 arch/powerpc/configs/44x/bluestone_defconfig
+ create mode 100644 arch/powerpc/configs/e55xx_smp_defconfig
+ create mode 100644 arch/powerpc/include/asm/fsl_85xx_cache_sram.h
+ create mode 100644 arch/powerpc/lib/checksum_wrappers_64.c
+ create mode 100644 arch/powerpc/platforms/85xx/p3041_ds.c
+ create mode 100644 arch/powerpc/platforms/85xx/p5020_ds.c
+ create mode 100644 arch/powerpc/platforms/pseries/mobility.c
+ create mode 100644 arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h
+ create mode 100644 arch/powerpc/sysdev/fsl_85xx_cache_sram.c
+ create mode 100644 arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
+
+
+_______________________________________________
+Linuxppc-dev mailing list
+Linuxppc-dev@lists.ozlabs.org
+https://lists.ozlabs.org/listinfo/linuxppc-dev
diff --git a/patchwork/tests/mail/0005-git-pull-request-ssh.mbox b/patchwork/tests/mail/0005-git-pull-request-ssh.mbox
new file mode 100644
index 0000000..7f4c93e
--- /dev/null
+++ b/patchwork/tests/mail/0005-git-pull-request-ssh.mbox
@@ -0,0 +1,348 @@
+From benh@kernel.crashing.org Fri Oct 22 11:51:02 2010
+Return-Path: <linuxppc-dev-bounces+jk=ozlabs.org@lists.ozlabs.org>
+X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on bilbo.ozlabs.org
+X-Spam-Level:
+X-Spam-Status: No, score=0.0 required=3.0 tests=none autolearn=disabled
+ version=3.3.1
+X-Original-To: jk@ozlabs.org
+Delivered-To: jk@ozlabs.org
+Received: from bilbo.ozlabs.org (localhost [127.0.0.1])
+ by ozlabs.org (Postfix) with ESMTP id ED4B3100937
+ for <jk@ozlabs.org>; Fri, 22 Oct 2010 14:51:54 +1100 (EST)
+Received: by ozlabs.org (Postfix)
+ id BF799B70CB; Fri, 22 Oct 2010 14:51:50 +1100 (EST)
+Delivered-To: linuxppc-dev@ozlabs.org
+Received: from gate.crashing.org (gate.crashing.org [63.228.1.57])
+ (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
+ (Client did not present a certificate)
+ by ozlabs.org (Postfix) with ESMTPS id 94629B7043
+ for <linuxppc-dev@ozlabs.org>; Fri, 22 Oct 2010 14:51:49 +1100 (EST)
+Received: from [IPv6:::1] (localhost.localdomain [127.0.0.1])
+ by gate.crashing.org (8.14.1/8.13.8) with ESMTP id o9M3p3SP018234;
+ Thu, 21 Oct 2010 22:51:04 -0500
+Subject: [git pull] Please pull powerpc.git next branch
+From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+To: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Fri, 22 Oct 2010 14:51:02 +1100
+Message-ID: <1287719462.2198.37.camel@pasglop>
+Mime-Version: 1.0
+X-Mailer: Evolution 2.30.3
+Cc: linuxppc-dev list <linuxppc-dev@ozlabs.org>,
+ Andrew Morton <akpm@linux-foundation.org>,
+ Linux Kernel list <linux-kernel@vger.kernel.org>
+X-BeenThere: linuxppc-dev@lists.ozlabs.org
+X-Mailman-Version: 2.1.13
+Precedence: list
+List-Id: Linux on PowerPC Developers Mail List <cbe-oss-dev.ozlabs.org>
+List-Unsubscribe: <https://lists.ozlabs.org/options/linuxppc-dev>,
+ <mailto:linuxppc-dev-request@lists.ozlabs.org?subject=unsubscribe>
+List-Archive: <http://lists.ozlabs.org/pipermail/linuxppc-dev>
+List-Post: <mailto:linuxppc-dev@lists.ozlabs.org>
+List-Help: <mailto:linuxppc-dev-request@lists.ozlabs.org?subject=help>
+List-Subscribe: <https://lists.ozlabs.org/listinfo/linuxppc-dev>,
+ <mailto:linuxppc-dev-request@lists.ozlabs.org?subject=subscribe>
+Content-Type: text/plain;
+ charset="us-ascii"
+Content-Transfer-Encoding: 7bit
+Sender: linuxppc-dev-bounces+jk=ozlabs.org@lists.ozlabs.org
+Errors-To: linuxppc-dev-bounces+jk=ozlabs.org@lists.ozlabs.org
+X-UID: 11446
+X-Length: 16781
+Status: R
+X-Status: N
+X-KMail-EncryptionState:
+X-KMail-SignatureState:
+X-KMail-MDN-Sent:
+
+Hi Linus !
+
+Here's powerpc's batch for this merge window. Mostly bits and pieces,
+such as Anton doing some performance tuning left and right, and the
+usual churn. One hilight is the support for the new Freescale e5500 core
+(64-bit BookE). Another one is that we now wire up the whole lot of
+socket calls as direct syscalls in addition to the old style indirect
+method.
+
+Cheers,
+Ben.
+
+The following changes since commit e10117d36ef758da0690c95ecffc09d5dd7da479:
+ Linus Torvalds (1):
+ Merge branch 'upstream-linus' of git://git.kernel.org/.../jgarzik/libata-dev
+
+are available in the git repository at:
+
+ ssh://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git next
+
+Andreas Schwab (1):
+ powerpc: Remove fpscr use from [kvm_]cvt_{fd,df}
+
+Anton Blanchard (5):
+ powerpc: Optimise 64bit csum_partial
+ powerpc: Optimise 64bit csum_partial_copy_generic and add csum_and_copy_from_user
+ powerpc: Add 64bit csum_and_copy_to_user
+ powerpc: Feature nop out reservation clear when stcx checks address
+ powerpc: Check end of stack canary at oops time
+
+Arnd Bergmann (1):
+ powerpc/spufs: Use llseek in all file operations
+
+Benjamin Herrenschmidt (4):
+ powerpc/dma: Add optional platform override of dma_set_mask()
+ powerpc/dart_iommu: Support for 64-bit iommu bypass window on PCIe
+ Merge remote branch 'kumar/merge' into next
+ Merge remote branch 'jwb/next' into next
+
+Denis Kirjanov (1):
+ powerpc: Use is_32bit_task() helper to test 32-bit binary
+
+Harninder Rai (1):
+ powerpc/85xx: add cache-sram support
+
+Ian Munsie (1):
+ powerpc: Wire up direct socket system calls
+
+Ilya Yanok (1):
+ powerpc/mpc83xx: Support for MPC8308 P1M board
+
+Joe Perches (2):
+ powerpc: Use static const char arrays
+ powerpc: Remove pr_<level> uses of KERN_<level>
+
+Josh Boyer (1):
+ powerpc/44x: Update ppc44x_defconfig
+
+Julia Lawall (7):
+ powerpc/via-pmu-led.c: Add of_node_put to avoid memory leak
+ powerpc/maple: Add of_node_put to avoid memory leak
+ powerpc/powermac/pfunc_core.c: Add of_node_put to avoid memory leak
+ powerpc/cell: Add of_node_put to avoid memory leak
+ powerpc/chrp/nvram.c: Add of_node_put to avoid memory leak
+ powerpc/irq.c: Add of_node_put to avoid memory leak
+ i2c/i2c-pasemi.c: Fix unsigned return type
+
+Kumar Gala (11):
+ powerpc/ppc64e: Fix link problem when building ppc64e_defconfig
+ powerpc/fsl-pci: Fix MSI support on 83xx platforms
+ powerpc/mpc8xxx_gpio: Add support for 'qoriq-gpio' controllers
+ powerpc/fsl-booke: Add PCI device ids for P2040/P3041/P5010/P5020 QoirQ chips
+ powerpc/fsl-booke: Add p3041 DS board support
+ powerpc: Fix compile error with paca code on ppc64e
+ powerpc/fsl-booke: Add support for FSL 64-bit e5500 core
+ powerpc/fsl-booke: Add support for FSL Arch v1.0 MMU in setup_page_sizes
+ powerpc/fsl-booke64: Use TLB CAMs to cover linear mapping on FSL 64-bit chips
+ powerpc/fsl-booke: Add p5020 DS board support
+ powerpc/fsl-booke: Add e55xx (64-bit) smp defconfig
+
+Matthew McClintock (7):
+ powerpc/mm: Assume first cpu is boot_cpuid not 0
+ powerpc/kexec: make masking/disabling interrupts generic
+ powerpc/85xx: Remove call to mpic_teardown_this_cpu in kexec
+ powerpc/85xx: Minor fixups for kexec on 85xx
+ powerpc/85xx: flush dcache before resetting cores
+ powerpc/fsl_soc: Search all global-utilities nodes for rstccr
+ powerpc/fsl_booke: Add support to boot from core other than 0
+
+Michael Neuling (1):
+ powerpc: Move arch_sd_sibling_asym_packing() to smp.c
+
+Nathan Fontenot (3):
+ powerpc/pseries: Export device tree updating routines
+ powerpc/pseries: Export rtas_ibm_suspend_me()
+ powerpc/pseries: Partition migration in the kernel
+
+Nishanth Aravamudan (8):
+ powerpc/pci: Fix return type of BUID_{HI,LO} macros
+ powerpc/dma: Fix dma_iommu_dma_supported compare
+ powerpc/dma: Fix check for direct DMA support
+ powerpc/vio: Use put_device() on device_register failure
+ powerpc/viobus: Free TCE table on device release
+ powerpc/pseries: Use kmemdup
+ powerpc/pci: Cleanup device dma setup code
+ powerpc/pseries/xics: Use cpu_possible_mask rather than cpu_all_mask
+
+Paul Gortmaker (1):
+ powerpc: Fix invalid page flags in create TLB CAM path for PTE_64BIT
+
+Paul Mackerras (5):
+ powerpc: Abstract indexing of lppaca structs
+ powerpc: Dynamically allocate most lppaca structs
+ powerpc: Account time using timebase rather than PURR
+ powerpc/pseries: Re-enable dispatch trace log userspace interface
+ powerpc/perf: Fix sampling enable for PPC970
+
+Scott Wood (1):
+ oprofile/fsl emb: Don't set MSR[PMM] until after clearing the interrupt.
+
+Sean MacLennan (2):
+ powerpc: Fix incorrect .stabs entry for copy_32.S
+ powerpc: mtmsrd not defined
+
+Shaohui Xie (1):
+ fsl_rio: Add comments for sRIO registers.
+
+Stephen Rothwell (1):
+ powerpc: define a compat_sys_recv cond_syscall
+
+Timur Tabi (5):
+ powerpc: export ppc_proc_freq and ppc_tb_freq as GPL symbols
+ powerpc/watchdog: Allow the Book-E driver to be compiled as a module
+ powerpc/p1022: Add probing for individual DMA channels
+ powerpc/85xx: add ngPIXIS FPGA device tree node to the P1022DS board
+ powerpc/watchdog: Make default timeout for Book-E watchdog a Kconfig option
+
+Tirumala Marri (1):
+ powerpc/44x: Add support for the AMCC APM821xx SoC
+
+matt mooney (1):
+ powerpc/Makefiles: Change to new flag variables
+
+ arch/powerpc/boot/addnote.c | 4 +-
+ arch/powerpc/boot/dts/bluestone.dts | 254 +++++++++++++
+ arch/powerpc/boot/dts/mpc8308_p1m.dts | 332 ++++++++++++++++
+ arch/powerpc/boot/dts/p1022ds.dts | 11 +
+ arch/powerpc/configs/44x/bluestone_defconfig | 68 ++++
+ arch/powerpc/configs/e55xx_smp_defconfig | 84 ++++
+ arch/powerpc/configs/ppc44x_defconfig | 9 +-
+ arch/powerpc/configs/ppc64e_defconfig | 4 +-
+ arch/powerpc/include/asm/checksum.h | 10 +
+ arch/powerpc/include/asm/compat.h | 4 +-
+ arch/powerpc/include/asm/cputable.h | 14 +-
+ arch/powerpc/include/asm/dma-mapping.h | 14 +-
+ arch/powerpc/include/asm/elf.h | 2 +-
+ arch/powerpc/include/asm/exception-64s.h | 3 +-
+ arch/powerpc/include/asm/fsl_85xx_cache_sram.h | 48 +++
+ arch/powerpc/include/asm/kexec.h | 1 +
+ arch/powerpc/include/asm/kvm_fpu.h | 4 +-
+ arch/powerpc/include/asm/lppaca.h | 29 ++
+ arch/powerpc/include/asm/machdep.h | 3 +
+ arch/powerpc/include/asm/mmu-book3e.h | 15 +
+ arch/powerpc/include/asm/paca.h | 10 +-
+ arch/powerpc/include/asm/page_64.h | 4 +-
+ arch/powerpc/include/asm/ppc-pci.h | 4 +-
+ arch/powerpc/include/asm/ppc_asm.h | 50 ++-
+ arch/powerpc/include/asm/processor.h | 4 +-
+ arch/powerpc/include/asm/pte-common.h | 7 +
+ arch/powerpc/include/asm/rtas.h | 1 +
+ arch/powerpc/include/asm/systbl.h | 19 +
+ arch/powerpc/include/asm/system.h | 4 +-
+ arch/powerpc/include/asm/time.h | 5 -
+ arch/powerpc/include/asm/unistd.h | 21 +-
+ arch/powerpc/kernel/Makefile | 4 +-
+ arch/powerpc/kernel/align.c | 4 +-
+ arch/powerpc/kernel/asm-offsets.c | 12 +-
+ arch/powerpc/kernel/cpu_setup_44x.S | 1 +
+ arch/powerpc/kernel/cpu_setup_fsl_booke.S | 15 +
+ arch/powerpc/kernel/cputable.c | 43 ++-
+ arch/powerpc/kernel/crash.c | 13 +-
+ arch/powerpc/kernel/dma-iommu.c | 21 +-
+ arch/powerpc/kernel/dma.c | 20 +-
+ arch/powerpc/kernel/entry_64.S | 40 ++
+ arch/powerpc/kernel/fpu.S | 10 -
+ arch/powerpc/kernel/head_fsl_booke.S | 10 +-
+ arch/powerpc/kernel/irq.c | 6 +-
+ arch/powerpc/kernel/lparcfg.c | 14 +-
+ arch/powerpc/kernel/machine_kexec.c | 24 ++
+ arch/powerpc/kernel/machine_kexec_32.c | 4 +
+ arch/powerpc/kernel/paca.c | 70 ++++-
+ arch/powerpc/kernel/pci-common.c | 4 +-
+ arch/powerpc/kernel/ppc970-pmu.c | 2 +
+ arch/powerpc/kernel/process.c | 12 -
+ arch/powerpc/kernel/ptrace.c | 2 +-
+ arch/powerpc/kernel/rtas.c | 4 +-
+ arch/powerpc/kernel/setup_32.c | 2 +-
+ arch/powerpc/kernel/smp.c | 14 +-
+ arch/powerpc/kernel/time.c | 275 +++++++-------
+ arch/powerpc/kernel/traps.c | 5 +
+ arch/powerpc/kernel/vdso.c | 6 +-
+ arch/powerpc/kernel/vdso32/Makefile | 6 +-
+ arch/powerpc/kernel/vdso64/Makefile | 6 +-
+ arch/powerpc/kernel/vio.c | 10 +-
+ arch/powerpc/kvm/Makefile | 2 +-
+ arch/powerpc/kvm/book3s_paired_singles.c | 44 +--
+ arch/powerpc/kvm/emulate.c | 4 +-
+ arch/powerpc/kvm/fpu.S | 8 -
+ arch/powerpc/lib/Makefile | 7 +-
+ arch/powerpc/lib/checksum_64.S | 482 +++++++++++++++++-------
+ arch/powerpc/lib/checksum_wrappers_64.c | 102 +++++
+ arch/powerpc/lib/copy_32.S | 2 +-
+ arch/powerpc/lib/ldstfp.S | 36 +-
+ arch/powerpc/lib/locks.c | 4 +-
+ arch/powerpc/lib/sstep.c | 8 +
+ arch/powerpc/math-emu/Makefile | 2 +-
+ arch/powerpc/mm/Makefile | 6 +-
+ arch/powerpc/mm/fault.c | 6 +
+ arch/powerpc/mm/fsl_booke_mmu.c | 15 +-
+ arch/powerpc/mm/mmu_context_nohash.c | 6 +-
+ arch/powerpc/mm/mmu_decl.h | 5 +-
+ arch/powerpc/mm/tlb_nohash.c | 56 +++-
+ arch/powerpc/mm/tlb_nohash_low.S | 2 +-
+ arch/powerpc/oprofile/Makefile | 4 +-
+ arch/powerpc/oprofile/backtrace.c | 2 +-
+ arch/powerpc/oprofile/op_model_fsl_emb.c | 15 +-
+ arch/powerpc/platforms/44x/Kconfig | 16 +
+ arch/powerpc/platforms/44x/ppc44x_simple.c | 1 +
+ arch/powerpc/platforms/83xx/Kconfig | 4 +-
+ arch/powerpc/platforms/83xx/mpc830x_rdb.c | 3 +-
+ arch/powerpc/platforms/85xx/Kconfig | 28 ++-
+ arch/powerpc/platforms/85xx/Makefile | 2 +
+ arch/powerpc/platforms/85xx/p1022_ds.c | 2 +
+ arch/powerpc/platforms/85xx/p3041_ds.c | 64 ++++
+ arch/powerpc/platforms/85xx/p5020_ds.c | 69 ++++
+ arch/powerpc/platforms/85xx/smp.c | 83 ++++-
+ arch/powerpc/platforms/Kconfig.cputype | 8 +-
+ arch/powerpc/platforms/cell/ras.c | 4 +-
+ arch/powerpc/platforms/cell/spider-pic.c | 4 +-
+ arch/powerpc/platforms/cell/spufs/file.c | 18 +
+ arch/powerpc/platforms/chrp/nvram.c | 4 +-
+ arch/powerpc/platforms/iseries/Makefile | 2 +-
+ arch/powerpc/platforms/iseries/dt.c | 4 +-
+ arch/powerpc/platforms/iseries/smp.c | 2 +-
+ arch/powerpc/platforms/maple/setup.c | 1 +
+ arch/powerpc/platforms/powermac/pfunc_core.c | 9 +-
+ arch/powerpc/platforms/pseries/Makefile | 13 +-
+ arch/powerpc/platforms/pseries/dlpar.c | 7 +-
+ arch/powerpc/platforms/pseries/dtl.c | 224 +++++++++---
+ arch/powerpc/platforms/pseries/lpar.c | 25 ++-
+ arch/powerpc/platforms/pseries/mobility.c | 362 ++++++++++++++++++
+ arch/powerpc/platforms/pseries/pseries.h | 9 +
+ arch/powerpc/platforms/pseries/setup.c | 52 +++
+ arch/powerpc/platforms/pseries/xics.c | 2 +-
+ arch/powerpc/sysdev/Makefile | 5 +-
+ arch/powerpc/sysdev/dart_iommu.c | 74 ++++-
+ arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h | 101 +++++
+ arch/powerpc/sysdev/fsl_85xx_cache_sram.c | 159 ++++++++
+ arch/powerpc/sysdev/fsl_85xx_l2ctlr.c | 231 +++++++++++
+ arch/powerpc/sysdev/fsl_msi.c | 9 +-
+ arch/powerpc/sysdev/fsl_pci.c | 60 +++-
+ arch/powerpc/sysdev/fsl_pci.h | 1 +
+ arch/powerpc/sysdev/fsl_rio.c | 65 ++--
+ arch/powerpc/sysdev/fsl_soc.c | 20 +-
+ arch/powerpc/sysdev/mpc8xxx_gpio.c | 3 +
+ arch/powerpc/sysdev/pmi.c | 2 +-
+ arch/powerpc/xmon/Makefile | 4 +-
+ drivers/i2c/busses/i2c-pasemi.c | 2 +-
+ drivers/macintosh/via-pmu-led.c | 4 +-
+ drivers/watchdog/Kconfig | 22 +-
+ drivers/watchdog/booke_wdt.c | 47 ++-
+ include/linux/pci_ids.h | 8 +
+ kernel/sys_ni.c | 1 +
+ 130 files changed, 3676 insertions(+), 683 deletions(-)
+ create mode 100644 arch/powerpc/boot/dts/bluestone.dts
+ create mode 100644 arch/powerpc/boot/dts/mpc8308_p1m.dts
+ create mode 100644 arch/powerpc/configs/44x/bluestone_defconfig
+ create mode 100644 arch/powerpc/configs/e55xx_smp_defconfig
+ create mode 100644 arch/powerpc/include/asm/fsl_85xx_cache_sram.h
+ create mode 100644 arch/powerpc/lib/checksum_wrappers_64.c
+ create mode 100644 arch/powerpc/platforms/85xx/p3041_ds.c
+ create mode 100644 arch/powerpc/platforms/85xx/p5020_ds.c
+ create mode 100644 arch/powerpc/platforms/pseries/mobility.c
+ create mode 100644 arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h
+ create mode 100644 arch/powerpc/sysdev/fsl_85xx_cache_sram.c
+ create mode 100644 arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
+
+
+_______________________________________________
+Linuxppc-dev mailing list
+Linuxppc-dev@lists.ozlabs.org
+https://lists.ozlabs.org/listinfo/linuxppc-dev
diff --git a/patchwork/tests/mail/0006-git-pull-request-http.mbox b/patchwork/tests/mail/0006-git-pull-request-http.mbox
new file mode 100644
index 0000000..e4f9007
--- /dev/null
+++ b/patchwork/tests/mail/0006-git-pull-request-http.mbox
@@ -0,0 +1,348 @@
+From benh@kernel.crashing.org Fri Oct 22 11:51:02 2010
+Return-Path: <linuxppc-dev-bounces+jk=ozlabs.org@lists.ozlabs.org>
+X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on bilbo.ozlabs.org
+X-Spam-Level:
+X-Spam-Status: No, score=0.0 required=3.0 tests=none autolearn=disabled
+ version=3.3.1
+X-Original-To: jk@ozlabs.org
+Delivered-To: jk@ozlabs.org
+Received: from bilbo.ozlabs.org (localhost [127.0.0.1])
+ by ozlabs.org (Postfix) with ESMTP id ED4B3100937
+ for <jk@ozlabs.org>; Fri, 22 Oct 2010 14:51:54 +1100 (EST)
+Received: by ozlabs.org (Postfix)
+ id BF799B70CB; Fri, 22 Oct 2010 14:51:50 +1100 (EST)
+Delivered-To: linuxppc-dev@ozlabs.org
+Received: from gate.crashing.org (gate.crashing.org [63.228.1.57])
+ (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
+ (Client did not present a certificate)
+ by ozlabs.org (Postfix) with ESMTPS id 94629B7043
+ for <linuxppc-dev@ozlabs.org>; Fri, 22 Oct 2010 14:51:49 +1100 (EST)
+Received: from [IPv6:::1] (localhost.localdomain [127.0.0.1])
+ by gate.crashing.org (8.14.1/8.13.8) with ESMTP id o9M3p3SP018234;
+ Thu, 21 Oct 2010 22:51:04 -0500
+Subject: [git pull] Please pull powerpc.git next branch
+From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+To: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Fri, 22 Oct 2010 14:51:02 +1100
+Message-ID: <1287719462.2198.37.camel@pasglop>
+Mime-Version: 1.0
+X-Mailer: Evolution 2.30.3
+Cc: linuxppc-dev list <linuxppc-dev@ozlabs.org>,
+ Andrew Morton <akpm@linux-foundation.org>,
+ Linux Kernel list <linux-kernel@vger.kernel.org>
+X-BeenThere: linuxppc-dev@lists.ozlabs.org
+X-Mailman-Version: 2.1.13
+Precedence: list
+List-Id: Linux on PowerPC Developers Mail List <cbe-oss-dev.ozlabs.org>
+List-Unsubscribe: <https://lists.ozlabs.org/options/linuxppc-dev>,
+ <mailto:linuxppc-dev-request@lists.ozlabs.org?subject=unsubscribe>
+List-Archive: <http://lists.ozlabs.org/pipermail/linuxppc-dev>
+List-Post: <mailto:linuxppc-dev@lists.ozlabs.org>
+List-Help: <mailto:linuxppc-dev-request@lists.ozlabs.org?subject=help>
+List-Subscribe: <https://lists.ozlabs.org/listinfo/linuxppc-dev>,
+ <mailto:linuxppc-dev-request@lists.ozlabs.org?subject=subscribe>
+Content-Type: text/plain;
+ charset="us-ascii"
+Content-Transfer-Encoding: 7bit
+Sender: linuxppc-dev-bounces+jk=ozlabs.org@lists.ozlabs.org
+Errors-To: linuxppc-dev-bounces+jk=ozlabs.org@lists.ozlabs.org
+X-UID: 11446
+X-Length: 16781
+Status: R
+X-Status: N
+X-KMail-EncryptionState:
+X-KMail-SignatureState:
+X-KMail-MDN-Sent:
+
+Hi Linus !
+
+Here's powerpc's batch for this merge window. Mostly bits and pieces,
+such as Anton doing some performance tuning left and right, and the
+usual churn. One hilight is the support for the new Freescale e5500 core
+(64-bit BookE). Another one is that we now wire up the whole lot of
+socket calls as direct syscalls in addition to the old style indirect
+method.
+
+Cheers,
+Ben.
+
+The following changes since commit e10117d36ef758da0690c95ecffc09d5dd7da479:
+ Linus Torvalds (1):
+ Merge branch 'upstream-linus' of git://git.kernel.org/.../jgarzik/libata-dev
+
+are available in the git repository at:
+
+ http://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git next
+
+Andreas Schwab (1):
+ powerpc: Remove fpscr use from [kvm_]cvt_{fd,df}
+
+Anton Blanchard (5):
+ powerpc: Optimise 64bit csum_partial
+ powerpc: Optimise 64bit csum_partial_copy_generic and add csum_and_copy_from_user
+ powerpc: Add 64bit csum_and_copy_to_user
+ powerpc: Feature nop out reservation clear when stcx checks address
+ powerpc: Check end of stack canary at oops time
+
+Arnd Bergmann (1):
+ powerpc/spufs: Use llseek in all file operations
+
+Benjamin Herrenschmidt (4):
+ powerpc/dma: Add optional platform override of dma_set_mask()
+ powerpc/dart_iommu: Support for 64-bit iommu bypass window on PCIe
+ Merge remote branch 'kumar/merge' into next
+ Merge remote branch 'jwb/next' into next
+
+Denis Kirjanov (1):
+ powerpc: Use is_32bit_task() helper to test 32-bit binary
+
+Harninder Rai (1):
+ powerpc/85xx: add cache-sram support
+
+Ian Munsie (1):
+ powerpc: Wire up direct socket system calls
+
+Ilya Yanok (1):
+ powerpc/mpc83xx: Support for MPC8308 P1M board
+
+Joe Perches (2):
+ powerpc: Use static const char arrays
+ powerpc: Remove pr_<level> uses of KERN_<level>
+
+Josh Boyer (1):
+ powerpc/44x: Update ppc44x_defconfig
+
+Julia Lawall (7):
+ powerpc/via-pmu-led.c: Add of_node_put to avoid memory leak
+ powerpc/maple: Add of_node_put to avoid memory leak
+ powerpc/powermac/pfunc_core.c: Add of_node_put to avoid memory leak
+ powerpc/cell: Add of_node_put to avoid memory leak
+ powerpc/chrp/nvram.c: Add of_node_put to avoid memory leak
+ powerpc/irq.c: Add of_node_put to avoid memory leak
+ i2c/i2c-pasemi.c: Fix unsigned return type
+
+Kumar Gala (11):
+ powerpc/ppc64e: Fix link problem when building ppc64e_defconfig
+ powerpc/fsl-pci: Fix MSI support on 83xx platforms
+ powerpc/mpc8xxx_gpio: Add support for 'qoriq-gpio' controllers
+ powerpc/fsl-booke: Add PCI device ids for P2040/P3041/P5010/P5020 QoirQ chips
+ powerpc/fsl-booke: Add p3041 DS board support
+ powerpc: Fix compile error with paca code on ppc64e
+ powerpc/fsl-booke: Add support for FSL 64-bit e5500 core
+ powerpc/fsl-booke: Add support for FSL Arch v1.0 MMU in setup_page_sizes
+ powerpc/fsl-booke64: Use TLB CAMs to cover linear mapping on FSL 64-bit chips
+ powerpc/fsl-booke: Add p5020 DS board support
+ powerpc/fsl-booke: Add e55xx (64-bit) smp defconfig
+
+Matthew McClintock (7):
+ powerpc/mm: Assume first cpu is boot_cpuid not 0
+ powerpc/kexec: make masking/disabling interrupts generic
+ powerpc/85xx: Remove call to mpic_teardown_this_cpu in kexec
+ powerpc/85xx: Minor fixups for kexec on 85xx
+ powerpc/85xx: flush dcache before resetting cores
+ powerpc/fsl_soc: Search all global-utilities nodes for rstccr
+ powerpc/fsl_booke: Add support to boot from core other than 0
+
+Michael Neuling (1):
+ powerpc: Move arch_sd_sibling_asym_packing() to smp.c
+
+Nathan Fontenot (3):
+ powerpc/pseries: Export device tree updating routines
+ powerpc/pseries: Export rtas_ibm_suspend_me()
+ powerpc/pseries: Partition migration in the kernel
+
+Nishanth Aravamudan (8):
+ powerpc/pci: Fix return type of BUID_{HI,LO} macros
+ powerpc/dma: Fix dma_iommu_dma_supported compare
+ powerpc/dma: Fix check for direct DMA support
+ powerpc/vio: Use put_device() on device_register failure
+ powerpc/viobus: Free TCE table on device release
+ powerpc/pseries: Use kmemdup
+ powerpc/pci: Cleanup device dma setup code
+ powerpc/pseries/xics: Use cpu_possible_mask rather than cpu_all_mask
+
+Paul Gortmaker (1):
+ powerpc: Fix invalid page flags in create TLB CAM path for PTE_64BIT
+
+Paul Mackerras (5):
+ powerpc: Abstract indexing of lppaca structs
+ powerpc: Dynamically allocate most lppaca structs
+ powerpc: Account time using timebase rather than PURR
+ powerpc/pseries: Re-enable dispatch trace log userspace interface
+ powerpc/perf: Fix sampling enable for PPC970
+
+Scott Wood (1):
+ oprofile/fsl emb: Don't set MSR[PMM] until after clearing the interrupt.
+
+Sean MacLennan (2):
+ powerpc: Fix incorrect .stabs entry for copy_32.S
+ powerpc: mtmsrd not defined
+
+Shaohui Xie (1):
+ fsl_rio: Add comments for sRIO registers.
+
+Stephen Rothwell (1):
+ powerpc: define a compat_sys_recv cond_syscall
+
+Timur Tabi (5):
+ powerpc: export ppc_proc_freq and ppc_tb_freq as GPL symbols
+ powerpc/watchdog: Allow the Book-E driver to be compiled as a module
+ powerpc/p1022: Add probing for individual DMA channels
+ powerpc/85xx: add ngPIXIS FPGA device tree node to the P1022DS board
+ powerpc/watchdog: Make default timeout for Book-E watchdog a Kconfig option
+
+Tirumala Marri (1):
+ powerpc/44x: Add support for the AMCC APM821xx SoC
+
+matt mooney (1):
+ powerpc/Makefiles: Change to new flag variables
+
+ arch/powerpc/boot/addnote.c | 4 +-
+ arch/powerpc/boot/dts/bluestone.dts | 254 +++++++++++++
+ arch/powerpc/boot/dts/mpc8308_p1m.dts | 332 ++++++++++++++++
+ arch/powerpc/boot/dts/p1022ds.dts | 11 +
+ arch/powerpc/configs/44x/bluestone_defconfig | 68 ++++
+ arch/powerpc/configs/e55xx_smp_defconfig | 84 ++++
+ arch/powerpc/configs/ppc44x_defconfig | 9 +-
+ arch/powerpc/configs/ppc64e_defconfig | 4 +-
+ arch/powerpc/include/asm/checksum.h | 10 +
+ arch/powerpc/include/asm/compat.h | 4 +-
+ arch/powerpc/include/asm/cputable.h | 14 +-
+ arch/powerpc/include/asm/dma-mapping.h | 14 +-
+ arch/powerpc/include/asm/elf.h | 2 +-
+ arch/powerpc/include/asm/exception-64s.h | 3 +-
+ arch/powerpc/include/asm/fsl_85xx_cache_sram.h | 48 +++
+ arch/powerpc/include/asm/kexec.h | 1 +
+ arch/powerpc/include/asm/kvm_fpu.h | 4 +-
+ arch/powerpc/include/asm/lppaca.h | 29 ++
+ arch/powerpc/include/asm/machdep.h | 3 +
+ arch/powerpc/include/asm/mmu-book3e.h | 15 +
+ arch/powerpc/include/asm/paca.h | 10 +-
+ arch/powerpc/include/asm/page_64.h | 4 +-
+ arch/powerpc/include/asm/ppc-pci.h | 4 +-
+ arch/powerpc/include/asm/ppc_asm.h | 50 ++-
+ arch/powerpc/include/asm/processor.h | 4 +-
+ arch/powerpc/include/asm/pte-common.h | 7 +
+ arch/powerpc/include/asm/rtas.h | 1 +
+ arch/powerpc/include/asm/systbl.h | 19 +
+ arch/powerpc/include/asm/system.h | 4 +-
+ arch/powerpc/include/asm/time.h | 5 -
+ arch/powerpc/include/asm/unistd.h | 21 +-
+ arch/powerpc/kernel/Makefile | 4 +-
+ arch/powerpc/kernel/align.c | 4 +-
+ arch/powerpc/kernel/asm-offsets.c | 12 +-
+ arch/powerpc/kernel/cpu_setup_44x.S | 1 +
+ arch/powerpc/kernel/cpu_setup_fsl_booke.S | 15 +
+ arch/powerpc/kernel/cputable.c | 43 ++-
+ arch/powerpc/kernel/crash.c | 13 +-
+ arch/powerpc/kernel/dma-iommu.c | 21 +-
+ arch/powerpc/kernel/dma.c | 20 +-
+ arch/powerpc/kernel/entry_64.S | 40 ++
+ arch/powerpc/kernel/fpu.S | 10 -
+ arch/powerpc/kernel/head_fsl_booke.S | 10 +-
+ arch/powerpc/kernel/irq.c | 6 +-
+ arch/powerpc/kernel/lparcfg.c | 14 +-
+ arch/powerpc/kernel/machine_kexec.c | 24 ++
+ arch/powerpc/kernel/machine_kexec_32.c | 4 +
+ arch/powerpc/kernel/paca.c | 70 ++++-
+ arch/powerpc/kernel/pci-common.c | 4 +-
+ arch/powerpc/kernel/ppc970-pmu.c | 2 +
+ arch/powerpc/kernel/process.c | 12 -
+ arch/powerpc/kernel/ptrace.c | 2 +-
+ arch/powerpc/kernel/rtas.c | 4 +-
+ arch/powerpc/kernel/setup_32.c | 2 +-
+ arch/powerpc/kernel/smp.c | 14 +-
+ arch/powerpc/kernel/time.c | 275 +++++++-------
+ arch/powerpc/kernel/traps.c | 5 +
+ arch/powerpc/kernel/vdso.c | 6 +-
+ arch/powerpc/kernel/vdso32/Makefile | 6 +-
+ arch/powerpc/kernel/vdso64/Makefile | 6 +-
+ arch/powerpc/kernel/vio.c | 10 +-
+ arch/powerpc/kvm/Makefile | 2 +-
+ arch/powerpc/kvm/book3s_paired_singles.c | 44 +--
+ arch/powerpc/kvm/emulate.c | 4 +-
+ arch/powerpc/kvm/fpu.S | 8 -
+ arch/powerpc/lib/Makefile | 7 +-
+ arch/powerpc/lib/checksum_64.S | 482 +++++++++++++++++-------
+ arch/powerpc/lib/checksum_wrappers_64.c | 102 +++++
+ arch/powerpc/lib/copy_32.S | 2 +-
+ arch/powerpc/lib/ldstfp.S | 36 +-
+ arch/powerpc/lib/locks.c | 4 +-
+ arch/powerpc/lib/sstep.c | 8 +
+ arch/powerpc/math-emu/Makefile | 2 +-
+ arch/powerpc/mm/Makefile | 6 +-
+ arch/powerpc/mm/fault.c | 6 +
+ arch/powerpc/mm/fsl_booke_mmu.c | 15 +-
+ arch/powerpc/mm/mmu_context_nohash.c | 6 +-
+ arch/powerpc/mm/mmu_decl.h | 5 +-
+ arch/powerpc/mm/tlb_nohash.c | 56 +++-
+ arch/powerpc/mm/tlb_nohash_low.S | 2 +-
+ arch/powerpc/oprofile/Makefile | 4 +-
+ arch/powerpc/oprofile/backtrace.c | 2 +-
+ arch/powerpc/oprofile/op_model_fsl_emb.c | 15 +-
+ arch/powerpc/platforms/44x/Kconfig | 16 +
+ arch/powerpc/platforms/44x/ppc44x_simple.c | 1 +
+ arch/powerpc/platforms/83xx/Kconfig | 4 +-
+ arch/powerpc/platforms/83xx/mpc830x_rdb.c | 3 +-
+ arch/powerpc/platforms/85xx/Kconfig | 28 ++-
+ arch/powerpc/platforms/85xx/Makefile | 2 +
+ arch/powerpc/platforms/85xx/p1022_ds.c | 2 +
+ arch/powerpc/platforms/85xx/p3041_ds.c | 64 ++++
+ arch/powerpc/platforms/85xx/p5020_ds.c | 69 ++++
+ arch/powerpc/platforms/85xx/smp.c | 83 ++++-
+ arch/powerpc/platforms/Kconfig.cputype | 8 +-
+ arch/powerpc/platforms/cell/ras.c | 4 +-
+ arch/powerpc/platforms/cell/spider-pic.c | 4 +-
+ arch/powerpc/platforms/cell/spufs/file.c | 18 +
+ arch/powerpc/platforms/chrp/nvram.c | 4 +-
+ arch/powerpc/platforms/iseries/Makefile | 2 +-
+ arch/powerpc/platforms/iseries/dt.c | 4 +-
+ arch/powerpc/platforms/iseries/smp.c | 2 +-
+ arch/powerpc/platforms/maple/setup.c | 1 +
+ arch/powerpc/platforms/powermac/pfunc_core.c | 9 +-
+ arch/powerpc/platforms/pseries/Makefile | 13 +-
+ arch/powerpc/platforms/pseries/dlpar.c | 7 +-
+ arch/powerpc/platforms/pseries/dtl.c | 224 +++++++++---
+ arch/powerpc/platforms/pseries/lpar.c | 25 ++-
+ arch/powerpc/platforms/pseries/mobility.c | 362 ++++++++++++++++++
+ arch/powerpc/platforms/pseries/pseries.h | 9 +
+ arch/powerpc/platforms/pseries/setup.c | 52 +++
+ arch/powerpc/platforms/pseries/xics.c | 2 +-
+ arch/powerpc/sysdev/Makefile | 5 +-
+ arch/powerpc/sysdev/dart_iommu.c | 74 ++++-
+ arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h | 101 +++++
+ arch/powerpc/sysdev/fsl_85xx_cache_sram.c | 159 ++++++++
+ arch/powerpc/sysdev/fsl_85xx_l2ctlr.c | 231 +++++++++++
+ arch/powerpc/sysdev/fsl_msi.c | 9 +-
+ arch/powerpc/sysdev/fsl_pci.c | 60 +++-
+ arch/powerpc/sysdev/fsl_pci.h | 1 +
+ arch/powerpc/sysdev/fsl_rio.c | 65 ++--
+ arch/powerpc/sysdev/fsl_soc.c | 20 +-
+ arch/powerpc/sysdev/mpc8xxx_gpio.c | 3 +
+ arch/powerpc/sysdev/pmi.c | 2 +-
+ arch/powerpc/xmon/Makefile | 4 +-
+ drivers/i2c/busses/i2c-pasemi.c | 2 +-
+ drivers/macintosh/via-pmu-led.c | 4 +-
+ drivers/watchdog/Kconfig | 22 +-
+ drivers/watchdog/booke_wdt.c | 47 ++-
+ include/linux/pci_ids.h | 8 +
+ kernel/sys_ni.c | 1 +
+ 130 files changed, 3676 insertions(+), 683 deletions(-)
+ create mode 100644 arch/powerpc/boot/dts/bluestone.dts
+ create mode 100644 arch/powerpc/boot/dts/mpc8308_p1m.dts
+ create mode 100644 arch/powerpc/configs/44x/bluestone_defconfig
+ create mode 100644 arch/powerpc/configs/e55xx_smp_defconfig
+ create mode 100644 arch/powerpc/include/asm/fsl_85xx_cache_sram.h
+ create mode 100644 arch/powerpc/lib/checksum_wrappers_64.c
+ create mode 100644 arch/powerpc/platforms/85xx/p3041_ds.c
+ create mode 100644 arch/powerpc/platforms/85xx/p5020_ds.c
+ create mode 100644 arch/powerpc/platforms/pseries/mobility.c
+ create mode 100644 arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h
+ create mode 100644 arch/powerpc/sysdev/fsl_85xx_cache_sram.c
+ create mode 100644 arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
+
+
+_______________________________________________
+Linuxppc-dev mailing list
+Linuxppc-dev@lists.ozlabs.org
+https://lists.ozlabs.org/listinfo/linuxppc-dev
diff --git a/patchwork/tests/mail/0007-cvs-format-diff.mbox b/patchwork/tests/mail/0007-cvs-format-diff.mbox
new file mode 100644
index 0000000..99735fa
--- /dev/null
+++ b/patchwork/tests/mail/0007-cvs-format-diff.mbox
@@ -0,0 +1,134 @@
+Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 06 Dec 2011 01:49:42 +0100 (CET)
+Received: from mail3.caviumnetworks.com ([12.108.191.235]:14337 "EHLO
+ mail3.caviumnetworks.com" rhost-flags-OK-OK-OK-OK)
+ by eddie.linux-mips.org with ESMTP id S1903632Ab1LFAth (ORCPT
+ <rfc822;linux-mips@linux-mips.org>); Tue, 6 Dec 2011 01:49:37 +0100
+Received: from caexch01.caveonetworks.com (Not Verified[192.168.16.9]) by mail3.caviumnetworks.com with MailMarshal (v6,7,2,8378)
+ id <B4edd66f80000>; Mon, 05 Dec 2011 16:51:04 -0800
+Received: from caexch01.caveonetworks.com ([192.168.16.9]) by caexch01.caveonetworks.com with Microsoft SMTPSVC(6.0.3790.4675);
+ Mon, 5 Dec 2011 16:49:36 -0800
+Received: from dd1.caveonetworks.com ([64.2.3.195]) by caexch01.caveonetworks.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675);
+ Mon, 5 Dec 2011 16:49:35 -0800
+Message-ID: <4EDD669F.30207@cavium.com>
+Date: Mon, 05 Dec 2011 16:49:35 -0800
+From: David Daney <david.daney@cavium.com>
+User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.15) Gecko/20101027 Fedora/3.0.10-1.fc12 Thunderbird/3.0.10
+MIME-Version: 1.0
+To: binutils <binutils@sourceware.org>
+CC: linux-mips <linux-mips@linux-mips.org>,
+ Manuel Lauss <manuel.lauss@googlemail.com>,
+ Debian MIPS <debian-mips@lists.debian.org>
+Subject: [Patch]: Fix ld pr11138 FAILures on mips*.
+Content-Type: multipart/mixed;
+ boundary="------------080709040708040308010506"
+X-OriginalArrivalTime: 06 Dec 2011 00:49:35.0825 (UTC) FILETIME=[ECF8DC10:01CCB3B0]
+Return-Path: <David.Daney@caviumnetworks.com>
+X-Envelope-To: <"|/home/ecartis/ecartis -s linux-mips"> (uid 0)
+X-Orcpt: rfc822;linux-mips@linux-mips.org
+Original-Recipient: rfc822;linux-mips@linux-mips.org
+X-archive-position: 32041
+X-ecartis-version: Ecartis v1.0.0
+Sender: linux-mips-bounce@linux-mips.org
+Errors-to: linux-mips-bounce@linux-mips.org
+X-original-sender: david.daney@cavium.com
+Precedence: bulk
+X-list: linux-mips
+
+This is a multi-part message in MIME format.
+--------------080709040708040308010506
+Content-Type: text/plain; charset=ISO-8859-1; format=flowed
+Content-Transfer-Encoding: 7bit
+
+The pr11138 testcase links an executable with a version script. On
+mips64-linux the presence of a version script was causing the
+MIPS_RLD_MAP dynamic tag to be populated with a NULL value. When such
+an executable was run ld.so would try to dereference this and receive
+SIGSEGV, thus killing the process.
+
+The root cause of this is that the mips linker synthesizes a special
+symbol "__RLD_MAP", and then sets MIPS_RLD_MAP to point to it. When a
+version script is present, this symbol gets versioned along with all the
+rest, and when it is time to take its address, the symbol can no longer
+be found as it has had version information appended to its name.
+
+Since "__RLD_MAP" is really part of the ABI, we want to exclude it from
+symbol versioning. To this end, I introduced a new symbol flag
+'no_sym_version' to tag this type of symbol. When the "__RLD_MAP"
+symbol is created, we set this flag.
+
+In _bfd_elf_link_assign_sym_version, we then skip all symbols that have
+'no_sym_version' set, and everything now works.
+
+This problem has also been reported in the wild when linking the firefox
+executable.
+
+Tested on mips64-linux-gnu and x86_64-linux-gnu
+
+Ok to commit?
+
+2011-12-05 David Daney <david.daney@cavium.com>
+
+ * elf-bfd.h (elf_link_hash_entry): Add no_sym_version field.
+ * elflink.c (_bfd_elf_link_assign_sym_version): Don't assign a
+ version if no_sym_version is set.
+ * elfxx-mips.c (_bfd_mips_elf_create_dynamic_sections): Set
+ no_sym_version for "__RLD_MAP".
+
+--------------080709040708040308010506
+Content-Type: text/plain;
+ name="dd-2.patch"
+Content-Transfer-Encoding: 7bit
+Content-Disposition: attachment;
+ filename="dd-2.patch"
+
+Index: bfd/elf-bfd.h
+===================================================================
+RCS file: /cvs/src/src/bfd/elf-bfd.h,v
+retrieving revision 1.329
+diff -u -p -r1.329 elf-bfd.h
+--- bfd/elf-bfd.h 17 Aug 2011 00:39:38 -0000 1.329
++++ bfd/elf-bfd.h 5 Dec 2011 20:15:49 -0000
+@@ -198,6 +198,8 @@ struct elf_link_hash_entry
+ unsigned int pointer_equality_needed : 1;
+ /* Symbol is a unique global symbol. */
+ unsigned int unique_global : 1;
++ /* Symbol should not be versioned. It is part of the ABI */
++ unsigned int no_sym_version : 1;
+
+ /* String table index in .dynstr if this is a dynamic symbol. */
+ unsigned long dynstr_index;
+Index: bfd/elflink.c
+===================================================================
+RCS file: /cvs/src/src/bfd/elflink.c,v
+retrieving revision 1.430
+diff -u -p -r1.430 elflink.c
+--- bfd/elflink.c 15 Nov 2011 11:33:57 -0000 1.430
++++ bfd/elflink.c 5 Dec 2011 20:15:50 -0000
+@@ -1946,6 +1946,9 @@ _bfd_elf_link_assign_sym_version (struct
+ if (!h->def_regular)
+ return TRUE;
+
++ if (h->no_sym_version)
++ return TRUE;
++
+ bed = get_elf_backend_data (info->output_bfd);
+ p = strchr (h->root.root.string, ELF_VER_CHR);
+ if (p != NULL && h->verinfo.vertree == NULL)
+Index: bfd/elfxx-mips.c
+===================================================================
+RCS file: /cvs/src/src/bfd/elfxx-mips.c,v
+retrieving revision 1.296
+diff -u -p -r1.296 elfxx-mips.c
+--- bfd/elfxx-mips.c 29 Nov 2011 20:28:54 -0000 1.296
++++ bfd/elfxx-mips.c 5 Dec 2011 20:15:50 -0000
+@@ -7260,6 +7260,7 @@ _bfd_mips_elf_create_dynamic_sections (b
+ h = (struct elf_link_hash_entry *) bh;
+ h->non_elf = 0;
+ h->def_regular = 1;
++ h->no_sym_version = 1;
+ h->type = STT_OBJECT;
+
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+
+--------------080709040708040308010506--
+
diff --git a/patchwork/tests/mail/0008-git-rename.mbox b/patchwork/tests/mail/0008-git-rename.mbox
new file mode 100644
index 0000000..8277049
--- /dev/null
+++ b/patchwork/tests/mail/0008-git-rename.mbox
@@ -0,0 +1,24 @@
+From: "Yann E. MORIN" <yann.morin.1998@free.fr>
+Subject: [Buildroot] [PATCH 01/11] package/rpi-userland: rename patches
+Date: Tue, 8 Oct 2013 22:09:47 +0000
+
+Rename patches to follow standard naming scheme.
+
+Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
+---
+ ...d-pkgconfig-files.patch => rpi-userland-000-add-pkgconfig-files.patch} | 0
+ ...erland-001-makefiles-cmake-vmcs.cmake-allow-to-override-VMCS_IN.patch} | 0
+ 2 files changed, 0 insertions(+), 0 deletions(-)
+ rename package/rpi-userland/{rpi-userland-add-pkgconfig-files.patch => rpi-userland-000-add-pkgconfig-files.patch} (100%)
+ rename package/rpi-userland/{rpi-userland-makefiles-0001-cmake-vmcs.cmake-allow-to-override-VMCS_IN.patch => rpi-userland-001-makefiles-cmake-vmcs.cmake-allow-to-override-VMCS_IN.patch} (100%)
+
+diff --git a/package/rpi-userland/rpi-userland-add-pkgconfig-files.patch b/package/rpi-userland/rpi-userland-000-add-pkgconfig-files.patch
+similarity index 100%
+rename from package/rpi-userland/rpi-userland-add-pkgconfig-files.patch
+rename to package/rpi-userland/rpi-userland-000-add-pkgconfig-files.patch
+diff --git a/package/rpi-userland/rpi-userland-makefiles-0001-cmake-vmcs.cmake-allow-to-override-VMCS_IN.patch b/package/rpi-userland/rpi-userland-001-makefiles-cmake-vmcs.cmake-allow-to-override-VMCS_IN.patch
+similarity index 100%
+rename from package/rpi-userland/rpi-userland-makefiles-0001-cmake-vmcs.cmake-allow-to-override-VMCS_IN.patch
+rename to package/rpi-userland/rpi-userland-001-makefiles-cmake-vmcs.cmake-allow-to-override-VMCS_IN.patch
+--
+1.8.1.2
diff --git a/patchwork/tests/mail/0009-git-rename-with-diff.mbox b/patchwork/tests/mail/0009-git-rename-with-diff.mbox
new file mode 100644
index 0000000..761cfc1
--- /dev/null
+++ b/patchwork/tests/mail/0009-git-rename-with-diff.mbox
@@ -0,0 +1,32 @@
+From: "Yann E. MORIN" <yann.morin.1998@free.fr>
+Subject: [Buildroot] [PATCH 01/11] package/rpi-userland: rename patches
+Date: Tue, 8 Oct 2013 22:09:47 +0000
+
+Rename patches to follow standard naming scheme.
+
+Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
+---
+ ...d-pkgconfig-files.patch => rpi-userland-000-add-pkgconfig-files.patch} | 0
+ ...erland-001-makefiles-cmake-vmcs.cmake-allow-to-override-VMCS_IN.patch} | 0
+ 2 files changed, 0 insertions(+), 0 deletions(-)
+ rename package/rpi-userland/{rpi-userland-add-pkgconfig-files.patch => rpi-userland-000-add-pkgconfig-files.patch} (100%)
+ rename package/rpi-userland/{rpi-userland-makefiles-0001-cmake-vmcs.cmake-allow-to-override-VMCS_IN.patch => rpi-userland-001-makefiles-cmake-vmcs.cmake-allow-to-override-VMCS_IN.patch} (100%)
+
+diff --git a/package/rpi-userland/rpi-userland-add-pkgconfig-files.patch b/package/rpi-userland/rpi-userland-000-add-pkgconfig-files.patch
+similarity index 100%
+rename from package/rpi-userland/rpi-userland-add-pkgconfig-files.patch
+rename to package/rpi-userland/rpi-userland-000-add-pkgconfig-files.patch
+@@ -100,7 +100,7 @@
+ a
+ a
+-a
++b
+ c
+ c
+ c
+diff --git a/package/rpi-userland/rpi-userland-makefiles-0001-cmake-vmcs.cmake-allow-to-override-VMCS_IN.patch b/package/rpi-userland/rpi-userland-001-makefiles-cmake-vmcs.cmake-allow-to-override-VMCS_IN.patch
+similarity index 100%
+rename from package/rpi-userland/rpi-userland-makefiles-0001-cmake-vmcs.cmake-allow-to-override-VMCS_IN.patch
+rename to package/rpi-userland/rpi-userland-001-makefiles-cmake-vmcs.cmake-allow-to-override-VMCS_IN.patch
+--
+1.8.1.2
diff --git a/patchwork/tests/mail/0010-invalid-charset.mbox b/patchwork/tests/mail/0010-invalid-charset.mbox
new file mode 100644
index 0000000..10b369d
--- /dev/null
+++ b/patchwork/tests/mail/0010-invalid-charset.mbox
@@ -0,0 +1,90 @@
+From libc-alpha-return-50517-siddhesh=redhat.com@sourceware.org Thu Jun 5 10:36:33 2014
+Received: (qmail 11948 invoked by alias); 4 Jun 2014 17:51:01 -0000
+Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm
+List-Id: <libc-alpha.sourceware.org>
+Sender: libc-alpha-owner@sourceware.org
+Date: Wed, 4 Jun 2014 17:50:46 +0000
+From: "Joseph S. Myers" <joseph@codesourcery.com>
+To: <libc-alpha@sourceware.org>
+Subject: Fix pow overflow in non-default rounding modes (bug 16315)
+Message-ID: <Pine.LNX.4.64.1406041749420.3719@digraph.polyomino.org.uk>
+MIME-Version: 1.0
+Content-Type: multipart/mixed;
+ boundary="-1152306461-1522705971-1401904246=:3719"
+Content-Length: 24171
+
+---1152306461-1522705971-1401904246=:3719
+Content-Type: text/plain; charset="none"
+Content-Transfer-Encoding: QUOTED-PRINTABLE
+
+This patch, relative to a tree with
+<https://sourceware.org/ml/libc-alpha/2014-06/msg00076.html> applied,
+fixes bug 16315, bad pow handling of overflow/underflow in non-default
+rounding modes. Tests of pow are duly converted to ALL_RM_TEST to run
+all tests in all rounding modes.
+
+There are two main issues here. First, various implementations
+compute a negative result by negating a positive result, but this
+yields inappropriate overflow / underflow values for directed
+rounding, so either overflow / underflow results need recomputing in
+the correct sign, or the relevant overflowing / underflowing operation
+needs to be made to have a result of the correct sign. Second, the
+dbl-64 implementation sets FE_TONEAREST internally; in the overflow /
+underflow case, the result needs recomputing in the original rounding
+mode.
+
+Tested x86_64 and x86 and ulps updated accordingly.
+
+(auto-libm-test-out diffs omitted below.)
+
+2014-06-04 Joseph Myers <joseph@codesourcery.com>
+
+=09[BZ #16315]
+=09* sysdeps/i386/fpu/e_pow.S (__ieee754_pow): Ensure possibly
+=09overflowing or underflowing operations take place with sign of
+=09result.
+=09* sysdeps/i386/fpu/e_powf.S (__ieee754_powf): Likewise.
+=09* sysdeps/i386/fpu/e_powl.S (__ieee754_powl): Likewise.
+=09* sysdeps/ieee754/dbl-64/e_pow.c: Include <math.h>.
+=09(__ieee754_pow): Recompute overflowing and underflowing results in
+=09original rounding mode.
+=09* sysdeps/x86/fpu/powl_helper.c: Include <stdbool.h>.
+=09(__powl_helper): Allow negative argument X and scale negated value
+=09as needed. Avoid passing value outside [-1, 1] to f2xm1.
+=09* sysdeps/x86_64/fpu/e_powl.S (__ieee754_powl): Ensure possibly
+=09overflowing or underflowing operations take place with sign of
+=09result.
+=09* sysdeps/x86_64/fpu/multiarch/e_pow.c [HAVE_FMA4_SUPPORT]:
+=09Include <math.h>.
+=09* math/auto-libm-test-in: Add more tests of pow.
+=09* math/auto-libm-test-out: Regenerated.
+=09* math/libm-test.inc (pow_test): Use ALL_RM_TEST.
+=09(pow_tonearest_test_data): Remove.
+=09(pow_test_tonearest): Likewise.
+=09(pow_towardzero_test_data): Likewise.
+=09(pow_test_towardzero): Likewise.
+=09(pow_downward_test_data): Likewise.
+=09(pow_test_downward): Likewise.
+=09(pow_upward_test_data): Likewise.
+=09(pow_test_upward): Likewise.
+=09(main): Don't call removed functions.
+=09* sysdeps/i386/fpu/libm-test-ulps: Update.
+=09* sysdeps/x86_64/fpu/libm-test-ulps: Likewise.
+
+diff --git a/sysdeps/x86_64/fpu/multiarch/e_pow.c b/sysdeps/x86_64/fpu/mult=
+iarch/e_pow.c
+index a740b6c..433cce0 100644
+--- a/sysdeps/x86_64/fpu/multiarch/e_pow.c
++++ b/sysdeps/x86_64/fpu/multiarch/e_pow.c
+@@ -1,5 +1,6 @@
+ #ifdef HAVE_FMA4_SUPPORT
+ # include <init-arch.h>
++# include <math.h>
+ # include <math_private.h>
+=20
+ extern double __ieee754_pow_sse2 (double, double);
+
+--=20
+Joseph S. Myers
+joseph@codesourcery.com
+---1152306461-1522705971-1401904246=:3719--
diff --git a/patchwork/tests/mail/0011-no-newline-at-end-of-file.mbox b/patchwork/tests/mail/0011-no-newline-at-end-of-file.mbox
new file mode 100644
index 0000000..3ed0597
--- /dev/null
+++ b/patchwork/tests/mail/0011-no-newline-at-end-of-file.mbox
@@ -0,0 +1,45 @@
+Subject: [PATCH v3 5/5] selftests, powerpc: Add test for VPHN
+From: Greg Kurz <gkurz@linux.vnet.ibm.com>
+To: Michael Ellerman <mpe@ellerman.id.au>
+Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>,
+ linuxppc-dev@lists.ozlabs.org
+Date: Mon, 23 Feb 2015 16:14:44 +0100
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+The goal is to verify vphn_unpack_associativity() parses VPHN numbers
+correctly. We feed it with a variety of input values and compare with
+expected results.
+
+diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile
+index 1d5e7ad..476b8dd 100644
+--- a/tools/testing/selftests/powerpc/Makefile
++++ b/tools/testing/selftests/powerpc/Makefile
+@@ -13,7 +13,7 @@ CFLAGS := -Wall -O2 -flto -Wall -Werror -DGIT_VERSION='"$(GIT_VERSION)"' -I$(CUR
+
+ export CC CFLAGS
+
+-TARGETS = pmu copyloops mm tm primitives stringloops
++TARGETS = pmu copyloops mm tm primitives stringloops vphn
+
+ endif
+
+diff --git a/tools/testing/selftests/powerpc/vphn/vphn.c b/tools/testing/selftests/powerpc/vphn/vphn.c
+new file mode 120000
+index 0000000..186b906
+--- /dev/null
++++ b/tools/testing/selftests/powerpc/vphn/vphn.c
+@@ -0,0 +1 @@
++../../../../../arch/powerpc/mm/vphn.c
+\ No newline at end of file
+diff --git a/tools/testing/selftests/powerpc/vphn/vphn.h b/tools/testing/selftests/powerpc/vphn/vphn.h
+new file mode 120000
+index 0000000..7131efe
+--- /dev/null
++++ b/tools/testing/selftests/powerpc/vphn/vphn.h
+@@ -0,0 +1 @@
++../../../../../arch/powerpc/mm/vphn.h
+\ No newline at end of file
+
+
diff --git a/patchwork/tests/patches/0001-add-line.patch b/patchwork/tests/patches/0001-add-line.patch
new file mode 100644
index 0000000..c6cb9f1
--- /dev/null
+++ b/patchwork/tests/patches/0001-add-line.patch
@@ -0,0 +1,7 @@
+diff --git a/meep.text b/meep.text
+index 3d75d48..a57f4dd 100644
+--- a/meep.text
++++ b/meep.text
+@@ -1,1 +1,2 @@
+ meep
++meep
diff --git a/patchwork/tests/patches/0002-utf-8.patch b/patchwork/tests/patches/0002-utf-8.patch
new file mode 100644
index 0000000..71a2f24
--- /dev/null
+++ b/patchwork/tests/patches/0002-utf-8.patch
@@ -0,0 +1,7 @@
+diff --git a/meep.text b/meep.text
+index 3d75d48..a57f4dd 100644
+--- a/meep.text
++++ b/meep.text
+@@ -1,1 +1,2 @@
+ meep
++meëp
diff --git a/patchwork/tests/test_bundles.py b/patchwork/tests/test_bundles.py
new file mode 100644
index 0000000..38f3a2c
--- /dev/null
+++ b/patchwork/tests/test_bundles.py
@@ -0,0 +1,646 @@
+# Patchwork - automated patch tracking system
+# Copyright (C) 2009 Jeremy Kerr <jk@ozlabs.org>
+#
+# This file is part of the Patchwork package.
+#
+# Patchwork is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# Patchwork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Patchwork; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import unittest
+import datetime
+from django.test import TestCase
+from django.test.client import Client
+from django.utils.http import urlencode
+from django.conf import settings
+from patchwork.models import Patch, Bundle, BundlePatch, Person
+from patchwork.tests.utils import defaults, create_user, find_in_context
+
+def bundle_url(bundle):
+ return '/bundle/%s/%s/' % (bundle.owner.username, bundle.name)
+
+class BundleListTest(TestCase):
+ def setUp(self):
+ self.user = create_user()
+ self.client.login(username = self.user.username,
+ password = self.user.username)
+
+ def testNoBundles(self):
+ response = self.client.get('/user/bundles/')
+ self.failUnlessEqual(response.status_code, 200)
+ self.failUnlessEqual(
+ len(find_in_context(response.context, 'bundles')), 0)
+
+ def testSingleBundle(self):
+ defaults.project.save()
+ bundle = Bundle(owner = self.user, project = defaults.project)
+ bundle.save()
+ response = self.client.get('/user/bundles/')
+ self.failUnlessEqual(response.status_code, 200)
+ self.failUnlessEqual(
+ len(find_in_context(response.context, 'bundles')), 1)
+
+ def tearDown(self):
+ self.user.delete()
+
+class BundleTestBase(TestCase):
+ def setUp(self, patch_count=3):
+ patch_names = ['testpatch%d' % (i) for i in range(1, patch_count+1)]
+ self.user = create_user()
+ self.client.login(username = self.user.username,
+ password = self.user.username)
+ defaults.project.save()
+ self.bundle = Bundle(owner = self.user, project = defaults.project,
+ name = 'testbundle')
+ self.bundle.save()
+ self.patches = []
+
+ for patch_name in patch_names:
+ patch = Patch(project = defaults.project,
+ msgid = patch_name, name = patch_name,
+ submitter = Person.objects.get(user = self.user),
+ content = '')
+ patch.save()
+ self.patches.append(patch)
+
+ def tearDown(self):
+ for patch in self.patches:
+ patch.delete()
+ self.bundle.delete()
+ self.user.delete()
+
+class BundleViewTest(BundleTestBase):
+
+ def testEmptyBundle(self):
+ response = self.client.get(bundle_url(self.bundle))
+ self.failUnlessEqual(response.status_code, 200)
+ page = find_in_context(response.context, 'page')
+ self.failUnlessEqual(len(page.object_list), 0)
+
+ def testNonEmptyBundle(self):
+ self.bundle.append_patch(self.patches[0])
+
+ response = self.client.get(bundle_url(self.bundle))
+ self.failUnlessEqual(response.status_code, 200)
+ page = find_in_context(response.context, 'page')
+ self.failUnlessEqual(len(page.object_list), 1)
+
+ def testBundleOrder(self):
+ for patch in self.patches:
+ self.bundle.append_patch(patch)
+
+ response = self.client.get(bundle_url(self.bundle))
+
+ pos = 0
+ for patch in self.patches:
+ next_pos = response.content.find(patch.name)
+ # ensure that this patch is after the previous
+ self.failUnless(next_pos > pos)
+ pos = next_pos
+
+ # reorder and recheck
+ i = 0
+ for patch in self.patches.__reversed__():
+ bundlepatch = BundlePatch.objects.get(bundle = self.bundle,
+ patch = patch)
+ bundlepatch.order = i
+ bundlepatch.save()
+ i += 1
+
+ response = self.client.get(bundle_url(self.bundle))
+ pos = len(response.content)
+ for patch in self.patches:
+ next_pos = response.content.find(patch.name)
+ # ensure that this patch is now *before* the previous
+ self.failUnless(next_pos < pos)
+ pos = next_pos
+
+class BundleUpdateTest(BundleTestBase):
+
+ def setUp(self):
+ super(BundleUpdateTest, self).setUp()
+ self.newname = 'newbundlename'
+
+ def checkPatchformErrors(self, response):
+ formname = 'patchform'
+ if not formname in response.context:
+ return
+ form = response.context[formname]
+ if not form:
+ return
+ self.assertEquals(form.errors, {})
+
+ def publicString(self, public):
+ if public:
+ return 'on'
+ return ''
+
+ def testNoAction(self):
+ data = {
+ 'form': 'bundle',
+ 'name': self.newname,
+ 'public': self.publicString(not self.bundle.public)
+ }
+ response = self.client.post(bundle_url(self.bundle), data)
+ self.assertEqual(response.status_code, 200)
+
+ bundle = Bundle.objects.get(pk = self.bundle.pk)
+ self.assertEqual(bundle.name, self.bundle.name)
+ self.assertEqual(bundle.public, self.bundle.public)
+
+ def testUpdateName(self):
+ newname = 'newbundlename'
+ data = {
+ 'form': 'bundle',
+ 'action': 'update',
+ 'name': newname,
+ 'public': self.publicString(self.bundle.public)
+ }
+ response = self.client.post(bundle_url(self.bundle), data)
+ bundle = Bundle.objects.get(pk = self.bundle.pk)
+ self.assertRedirects(response, bundle_url(bundle))
+ self.assertEqual(bundle.name, newname)
+ self.assertEqual(bundle.public, self.bundle.public)
+
+ def testUpdatePublic(self):
+ newname = 'newbundlename'
+ data = {
+ 'form': 'bundle',
+ 'action': 'update',
+ 'name': self.bundle.name,
+ 'public': self.publicString(not self.bundle.public)
+ }
+ response = self.client.post(bundle_url(self.bundle), data)
+ self.assertEqual(response.status_code, 200)
+ bundle = Bundle.objects.get(pk = self.bundle.pk)
+ self.assertEqual(bundle.name, self.bundle.name)
+ self.assertEqual(bundle.public, not self.bundle.public)
+
+ # check other forms for errors
+ self.checkPatchformErrors(response)
+
+class BundleMaintainerUpdateTest(BundleUpdateTest):
+
+ def setUp(self):
+ super(BundleMaintainerUpdateTest, self).setUp()
+ profile = self.user.profile
+ profile.maintainer_projects.add(defaults.project)
+ profile.save()
+
+class BundlePublicViewTest(BundleTestBase):
+
+ def setUp(self):
+ super(BundlePublicViewTest, self).setUp()
+ self.client.logout()
+ self.bundle.append_patch(self.patches[0])
+ self.url = bundle_url(self.bundle)
+
+ def testPublicBundle(self):
+ self.bundle.public = True
+ self.bundle.save()
+ response = self.client.get(self.url)
+ self.assertEqual(response.status_code, 200)
+ self.assertContains(response, self.patches[0].name)
+
+ def testPrivateBundle(self):
+ self.bundle.public = False
+ self.bundle.save()
+ response = self.client.get(self.url)
+ self.assertEqual(response.status_code, 404)
+
+class BundlePublicViewMboxTest(BundlePublicViewTest):
+ def setUp(self):
+ super(BundlePublicViewMboxTest, self).setUp()
+ self.url = bundle_url(self.bundle) + "mbox/"
+
+class BundlePublicModifyTest(BundleTestBase):
+ """Ensure that non-owners can't modify bundles"""
+
+ def setUp(self):
+ super(BundlePublicModifyTest, self).setUp()
+ self.bundle.public = True
+ self.bundle.save()
+ self.other_user = create_user()
+
+ def testBundleFormPresence(self):
+ """Check for presence of the modify form on the bundle"""
+ self.client.login(username = self.other_user.username,
+ password = self.other_user.username)
+ response = self.client.get(bundle_url(self.bundle))
+ self.assertNotContains(response, 'name="form" value="bundle"')
+ self.assertNotContains(response, 'Change order')
+
+ def testBundleFormSubmission(self):
+ oldname = 'oldbundlename'
+ newname = 'newbundlename'
+ data = {
+ 'form': 'bundle',
+ 'action': 'update',
+ 'name': newname,
+ }
+ self.bundle.name = oldname
+ self.bundle.save()
+
+ # first, check that we can modify with the owner
+ self.client.login(username = self.user.username,
+ password = self.user.username)
+ response = self.client.post(bundle_url(self.bundle), data)
+ self.bundle = Bundle.objects.get(pk = self.bundle.pk)
+ self.assertEqual(self.bundle.name, newname)
+
+ # reset bundle name
+ self.bundle.name = oldname
+ self.bundle.save()
+
+ # log in with a different user, and check that we can no longer modify
+ self.client.login(username = self.other_user.username,
+ password = self.other_user.username)
+ response = self.client.post(bundle_url(self.bundle), data)
+ self.bundle = Bundle.objects.get(pk = self.bundle.pk)
+ self.assertNotEqual(self.bundle.name, newname)
+
+class BundleCreateFromListTest(BundleTestBase):
+ def testCreateEmptyBundle(self):
+ newbundlename = 'testbundle-new'
+ params = {'form': 'patchlistform',
+ 'bundle_name': newbundlename,
+ 'action': 'Create',
+ 'project': defaults.project.id}
+
+ response = self.client.post(
+ '/project/%s/list/' % defaults.project.linkname,
+ params)
+
+ self.assertContains(response, 'Bundle %s created' % newbundlename)
+
+ def testCreateNonEmptyBundle(self):
+ newbundlename = 'testbundle-new'
+ patch = self.patches[0]
+
+ params = {'form': 'patchlistform',
+ 'bundle_name': newbundlename,
+ 'action': 'Create',
+ 'project': defaults.project.id,
+ 'patch_id:%d' % patch.id: 'checked'}
+
+ response = self.client.post(
+ '/project/%s/list/' % defaults.project.linkname,
+ params)
+
+ self.assertContains(response, 'Bundle %s created' % newbundlename)
+ self.assertContains(response, 'added to bundle %s' % newbundlename,
+ count = 1)
+
+ bundle = Bundle.objects.get(name = newbundlename)
+ self.failUnlessEqual(bundle.patches.count(), 1)
+ self.failUnlessEqual(bundle.patches.all()[0], patch)
+
+ def testCreateNonEmptyBundleEmptyName(self):
+ newbundlename = 'testbundle-new'
+ patch = self.patches[0]
+
+ n_bundles = Bundle.objects.count()
+
+ params = {'form': 'patchlistform',
+ 'bundle_name': '',
+ 'action': 'Create',
+ 'project': defaults.project.id,
+ 'patch_id:%d' % patch.id: 'checked'}
+
+ response = self.client.post(
+ '/project/%s/list/' % defaults.project.linkname,
+ params)
+
+ self.assertContains(response, 'No bundle name was specified',
+ status_code = 200)
+
+ # test that no new bundles are present
+ self.failUnlessEqual(n_bundles, Bundle.objects.count())
+
+ def testCreateDuplicateName(self):
+ newbundlename = 'testbundle-dup'
+ patch = self.patches[0]
+
+ params = {'form': 'patchlistform',
+ 'bundle_name': newbundlename,
+ 'action': 'Create',
+ 'project': defaults.project.id,
+ 'patch_id:%d' % patch.id: 'checked'}
+
+ response = self.client.post(
+ '/project/%s/list/' % defaults.project.linkname,
+ params)
+
+ n_bundles = Bundle.objects.count()
+ self.assertContains(response, 'Bundle %s created' % newbundlename)
+ self.assertContains(response, 'added to bundle %s' % newbundlename,
+ count = 1)
+
+ bundle = Bundle.objects.get(name = newbundlename)
+ self.failUnlessEqual(bundle.patches.count(), 1)
+ self.failUnlessEqual(bundle.patches.all()[0], patch)
+
+ response = self.client.post(
+ '/project/%s/list/' % defaults.project.linkname,
+ params)
+
+ self.assertNotContains(response, 'Bundle %s created' % newbundlename)
+ self.assertContains(response, 'You already have a bundle called')
+ self.assertEqual(Bundle.objects.count(), n_bundles)
+ self.assertEqual(bundle.patches.count(), 1)
+
+class BundleCreateFromPatchTest(BundleTestBase):
+ def testCreateNonEmptyBundle(self):
+ newbundlename = 'testbundle-new'
+ patch = self.patches[0]
+
+ params = {'name': newbundlename,
+ 'action': 'createbundle'}
+
+ response = self.client.post('/patch/%d/' % patch.id, params)
+
+ self.assertContains(response,
+ 'Bundle %s created' % newbundlename)
+
+ bundle = Bundle.objects.get(name = newbundlename)
+ self.failUnlessEqual(bundle.patches.count(), 1)
+ self.failUnlessEqual(bundle.patches.all()[0], patch)
+
+ def testCreateWithExistingName(self):
+ newbundlename = self.bundle.name
+ patch = self.patches[0]
+
+ params = {'name': newbundlename,
+ 'action': 'createbundle'}
+
+ response = self.client.post('/patch/%d/' % patch.id, params)
+
+ self.assertContains(response,
+ 'A bundle called %s already exists' % newbundlename)
+
+ count = Bundle.objects.count()
+ self.failUnlessEqual(Bundle.objects.count(), 1)
+
+class BundleAddFromListTest(BundleTestBase):
+ def testAddToEmptyBundle(self):
+ patch = self.patches[0]
+ params = {'form': 'patchlistform',
+ 'action': 'Add',
+ 'project': defaults.project.id,
+ 'bundle_id': self.bundle.id,
+ 'patch_id:%d' % patch.id: 'checked'}
+
+ response = self.client.post(
+ '/project/%s/list/' % defaults.project.linkname,
+ params)
+
+ self.assertContains(response, 'added to bundle %s' % self.bundle.name,
+ count = 1)
+
+ self.failUnlessEqual(self.bundle.patches.count(), 1)
+ self.failUnlessEqual(self.bundle.patches.all()[0], patch)
+
+ def testAddToNonEmptyBundle(self):
+ self.bundle.append_patch(self.patches[0])
+ patch = self.patches[1]
+ params = {'form': 'patchlistform',
+ 'action': 'Add',
+ 'project': defaults.project.id,
+ 'bundle_id': self.bundle.id,
+ 'patch_id:%d' % patch.id: 'checked'}
+
+ response = self.client.post(
+ '/project/%s/list/' % defaults.project.linkname,
+ params)
+
+ self.assertContains(response, 'added to bundle %s' % self.bundle.name,
+ count = 1)
+
+ self.failUnlessEqual(self.bundle.patches.count(), 2)
+ self.failUnless(self.patches[0] in self.bundle.patches.all())
+ self.failUnless(self.patches[1] in self.bundle.patches.all())
+
+ # check order
+ bps = [ BundlePatch.objects.get(bundle = self.bundle,
+ patch = self.patches[i]) \
+ for i in [0, 1] ]
+ self.failUnless(bps[0].order < bps[1].order)
+
+ def testAddDuplicate(self):
+ self.bundle.append_patch(self.patches[0])
+ count = self.bundle.patches.count()
+ patch = self.patches[0]
+
+ params = {'form': 'patchlistform',
+ 'action': 'Add',
+ 'project': defaults.project.id,
+ 'bundle_id': self.bundle.id,
+ 'patch_id:%d' % patch.id: 'checked'}
+
+ response = self.client.post(
+ '/project/%s/list/' % defaults.project.linkname,
+ params)
+
+ self.assertContains(response, 'Patch &#39;%s&#39; already in bundle' \
+ % patch.name, count = 1, status_code = 200)
+
+ self.assertEquals(count, self.bundle.patches.count())
+
+ def testAddNewAndDuplicate(self):
+ self.bundle.append_patch(self.patches[0])
+ count = self.bundle.patches.count()
+ patch = self.patches[0]
+
+ params = {'form': 'patchlistform',
+ 'action': 'Add',
+ 'project': defaults.project.id,
+ 'bundle_id': self.bundle.id,
+ 'patch_id:%d' % patch.id: 'checked',
+ 'patch_id:%d' % self.patches[1].id: 'checked'}
+
+ response = self.client.post(
+ '/project/%s/list/' % defaults.project.linkname,
+ params)
+
+ self.assertContains(response, 'Patch &#39;%s&#39; already in bundle' \
+ % patch.name, count = 1, status_code = 200)
+ self.assertContains(response, 'Patch &#39;%s&#39; added to bundle' \
+ % self.patches[1].name, count = 1,
+ status_code = 200)
+ self.assertEquals(count + 1, self.bundle.patches.count())
+
+class BundleAddFromPatchTest(BundleTestBase):
+ def testAddToEmptyBundle(self):
+ patch = self.patches[0]
+ params = {'action': 'addtobundle',
+ 'bundle_id': self.bundle.id}
+
+ response = self.client.post('/patch/%d/' % patch.id, params)
+
+ self.assertContains(response,
+ 'added to bundle &quot;%s&quot;' % self.bundle.name,
+ count = 1)
+
+ self.failUnlessEqual(self.bundle.patches.count(), 1)
+ self.failUnlessEqual(self.bundle.patches.all()[0], patch)
+
+ def testAddToNonEmptyBundle(self):
+ self.bundle.append_patch(self.patches[0])
+ patch = self.patches[1]
+ params = {'action': 'addtobundle',
+ 'bundle_id': self.bundle.id}
+
+ response = self.client.post('/patch/%d/' % patch.id, params)
+
+ self.assertContains(response,
+ 'added to bundle &quot;%s&quot;' % self.bundle.name,
+ count = 1)
+
+ self.failUnlessEqual(self.bundle.patches.count(), 2)
+ self.failUnless(self.patches[0] in self.bundle.patches.all())
+ self.failUnless(self.patches[1] in self.bundle.patches.all())
+
+ # check order
+ bps = [ BundlePatch.objects.get(bundle = self.bundle,
+ patch = self.patches[i]) \
+ for i in [0, 1] ]
+ self.failUnless(bps[0].order < bps[1].order)
+
+class BundleInitialOrderTest(BundleTestBase):
+ """When creating bundles from a patch list, ensure that the patches in the
+ bundle are ordered by date"""
+
+ def setUp(self):
+ super(BundleInitialOrderTest, self).setUp(5)
+
+ # put patches in an arbitrary order
+ idxs = [2, 4, 3, 1, 0]
+ self.patches = [ self.patches[i] for i in idxs ]
+
+ # set dates to be sequential
+ last_patch = self.patches[0]
+ for patch in self.patches[1:]:
+ patch.date = last_patch.date + datetime.timedelta(0, 1)
+ patch.save()
+ last_patch = patch
+
+ def _testOrder(self, ids, expected_order):
+ newbundlename = 'testbundle-new'
+
+ # need to define our querystring explicity to enforce ordering
+ params = {'form': 'patchlistform',
+ 'bundle_name': newbundlename,
+ 'action': 'Create',
+ 'project': defaults.project.id,
+ }
+
+ data = urlencode(params) + \
+ ''.join([ '&patch_id:%d=checked' % i for i in ids ])
+
+ response = self.client.post(
+ '/project/%s/list/' % defaults.project.linkname,
+ data = data,
+ content_type = 'application/x-www-form-urlencoded',
+ )
+
+ self.assertContains(response, 'Bundle %s created' % newbundlename)
+ self.assertContains(response, 'added to bundle %s' % newbundlename,
+ count = 5)
+
+ bundle = Bundle.objects.get(name = newbundlename)
+
+ # BundlePatches should be sorted by .order by default
+ bps = BundlePatch.objects.filter(bundle = bundle)
+
+ for (bp, p) in zip(bps, expected_order):
+ self.assertEqual(bp.patch.pk, p.pk)
+
+ bundle.delete()
+
+ def testBundleForwardOrder(self):
+ ids = map(lambda p: p.id, self.patches)
+ self._testOrder(ids, self.patches)
+
+ def testBundleReverseOrder(self):
+ ids = map(lambda p: p.id, self.patches)
+ ids.reverse()
+ self._testOrder(ids, self.patches)
+
+class BundleReorderTest(BundleTestBase):
+ def setUp(self):
+ super(BundleReorderTest, self).setUp(5)
+ for i in range(5):
+ self.bundle.append_patch(self.patches[i])
+
+ def checkReordering(self, neworder, start, end):
+ neworder_ids = [ self.patches[i].id for i in neworder ]
+
+ firstpatch = BundlePatch.objects.get(bundle = self.bundle,
+ patch = self.patches[start]).patch
+
+ slice_ids = neworder_ids[start:end]
+ params = {'form': 'reorderform',
+ 'order_start': firstpatch.id,
+ 'neworder': slice_ids}
+
+ response = self.client.post(bundle_url(self.bundle), params)
+
+ self.failUnlessEqual(response.status_code, 200)
+
+ bps = BundlePatch.objects.filter(bundle = self.bundle) \
+ .order_by('order')
+
+ # check if patch IDs are in the expected order:
+ bundle_ids = [ bp.patch.id for bp in bps ]
+ self.failUnlessEqual(neworder_ids, bundle_ids)
+
+ # check if order field is still sequential:
+ order_numbers = [ bp.order for bp in bps ]
+ expected_order = range(1, len(neworder)+1) # [1 ... len(neworder)]
+ self.failUnlessEqual(order_numbers, expected_order)
+
+ def testBundleReorderAll(self):
+ # reorder all patches:
+ self.checkReordering([2,1,4,0,3], 0, 5)
+
+ def testBundleReorderEnd(self):
+ # reorder only the last three patches
+ self.checkReordering([0,1,3,2,4], 2, 5)
+
+ def testBundleReorderBegin(self):
+ # reorder only the first three patches
+ self.checkReordering([2,0,1,3,4], 0, 3)
+
+ def testBundleReorderMiddle(self):
+ # reorder only 2nd, 3rd, and 4th patches
+ self.checkReordering([0,2,3,1,4], 1, 4)
+
+class BundleRedirTest(BundleTestBase):
+ # old URL: private bundles used to be under /user/bundle/<id>
+
+ def setUp(self):
+ super(BundleRedirTest, self).setUp()
+
+ @unittest.skipIf(not settings.COMPAT_REDIR, "compat redirections disabled")
+ def testBundleRedir(self):
+ url = '/user/bundle/%d/' % self.bundle.id
+ response = self.client.get(url)
+ self.assertRedirects(response, bundle_url(self.bundle))
+
+ @unittest.skipIf(not settings.COMPAT_REDIR, "compat redirections disabled")
+ def testMboxRedir(self):
+ url = '/user/bundle/%d/mbox/' % self.bundle.id
+ response = self.client.get(url)
+ self.assertRedirects(response,'/bundle/%s/%s/mbox/' %
+ (self.bundle.owner.username,
+ self.bundle.name))
diff --git a/patchwork/tests/test_confirm.py b/patchwork/tests/test_confirm.py
new file mode 100644
index 0000000..fad5125
--- /dev/null
+++ b/patchwork/tests/test_confirm.py
@@ -0,0 +1,67 @@
+# Patchwork - automated patch tracking system
+# Copyright (C) 2011 Jeremy Kerr <jk@ozlabs.org>
+#
+# This file is part of the Patchwork package.
+#
+# Patchwork is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# Patchwork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Patchwork; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import unittest
+from django.test import TestCase
+from django.contrib.auth.models import User
+from django.core.urlresolvers import reverse
+from patchwork.models import EmailConfirmation, Person
+
+def _confirmation_url(conf):
+ return reverse('patchwork.views.confirm', kwargs = {'key': conf.key})
+
+class TestUser(object):
+ username = 'testuser'
+ email = 'test@example.com'
+ secondary_email = 'test2@example.com'
+ password = None
+
+ def __init__(self):
+ self.password = User.objects.make_random_password()
+ self.user = User.objects.create_user(self.username,
+ self.email, self.password)
+
+class InvalidConfirmationTest(TestCase):
+ def setUp(self):
+ EmailConfirmation.objects.all().delete()
+ Person.objects.all().delete()
+ self.user = TestUser()
+ self.conf = EmailConfirmation(type = 'userperson',
+ email = self.user.secondary_email,
+ user = self.user.user)
+ self.conf.save()
+
+ def testInactiveConfirmation(self):
+ self.conf.active = False
+ self.conf.save()
+ response = self.client.get(_confirmation_url(self.conf))
+ self.assertEquals(response.status_code, 200)
+ self.assertTemplateUsed(response, 'patchwork/confirm-error.html')
+ self.assertEqual(response.context['error'], 'inactive')
+ self.assertEqual(response.context['conf'], self.conf)
+
+ def testExpiredConfirmation(self):
+ self.conf.date -= self.conf.validity
+ self.conf.save()
+ response = self.client.get(_confirmation_url(self.conf))
+ self.assertEquals(response.status_code, 200)
+ self.assertTemplateUsed(response, 'patchwork/confirm-error.html')
+ self.assertEqual(response.context['error'], 'expired')
+ self.assertEqual(response.context['conf'], self.conf)
+
diff --git a/patchwork/tests/test_encodings.py b/patchwork/tests/test_encodings.py
new file mode 100644
index 0000000..b9032bb
--- /dev/null
+++ b/patchwork/tests/test_encodings.py
@@ -0,0 +1,87 @@
+# Patchwork - automated patch tracking system
+# Copyright (C) 2008 Jeremy Kerr <jk@ozlabs.org>
+#
+# This file is part of the Patchwork package.
+#
+# Patchwork is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# Patchwork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Patchwork; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import unittest
+import os
+import time
+from patchwork.models import Patch, Person
+from patchwork.tests.utils import defaults, read_patch
+from django.test import TestCase
+from django.test.client import Client
+
+class UTF8PatchViewTest(TestCase):
+ patch_filename = '0002-utf-8.patch'
+ patch_encoding = 'utf-8'
+
+ def setUp(self):
+ defaults.project.save()
+ defaults.patch_author_person.save()
+ self.patch_content = read_patch(self.patch_filename,
+ encoding = self.patch_encoding)
+ self.patch = Patch(project = defaults.project,
+ msgid = 'x', name = defaults.patch_name,
+ submitter = defaults.patch_author_person,
+ content = self.patch_content)
+ self.patch.save()
+ self.client = Client()
+
+ def testPatchView(self):
+ response = self.client.get('/patch/%d/' % self.patch.id)
+ self.assertContains(response, self.patch.name)
+
+ def testMboxView(self):
+ response = self.client.get('/patch/%d/mbox/' % self.patch.id)
+ self.assertEquals(response.status_code, 200)
+ self.assertTrue(self.patch.content in \
+ response.content.decode(self.patch_encoding))
+
+ def testRawView(self):
+ response = self.client.get('/patch/%d/raw/' % self.patch.id)
+ self.assertEquals(response.status_code, 200)
+ self.assertEquals(response.content.decode(self.patch_encoding),
+ self.patch.content)
+
+ def tearDown(self):
+ self.patch.delete()
+ defaults.patch_author_person.delete()
+ defaults.project.delete()
+
+class UTF8HeaderPatchViewTest(UTF8PatchViewTest):
+ patch_filename = '0002-utf-8.patch'
+ patch_encoding = 'utf-8'
+ patch_author_name = u'P\xe4tch Author'
+
+ def setUp(self):
+ defaults.project.save()
+ self.patch_author = Person(name = self.patch_author_name,
+ email = defaults.patch_author_person.email)
+ self.patch_author.save()
+ self.patch_content = read_patch(self.patch_filename,
+ encoding = self.patch_encoding)
+ self.patch = Patch(project = defaults.project,
+ msgid = 'x', name = defaults.patch_name,
+ submitter = self.patch_author,
+ content = self.patch_content)
+ self.patch.save()
+ self.client = Client()
+
+ def tearDown(self):
+ self.patch.delete()
+ self.patch_author.delete()
+ defaults.project.delete()
diff --git a/patchwork/tests/test_expiry.py b/patchwork/tests/test_expiry.py
new file mode 100644
index 0000000..844ed4b
--- /dev/null
+++ b/patchwork/tests/test_expiry.py
@@ -0,0 +1,121 @@
+# Patchwork - automated patch tracking system
+# Copyright (C) 2014 Jeremy Kerr <jk@ozlabs.org>
+#
+# This file is part of the Patchwork package.
+#
+# Patchwork is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# Patchwork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Patchwork; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import unittest
+import datetime
+from django.test import TestCase
+from django.contrib.auth.models import User
+from patchwork.models import EmailConfirmation, Person, Patch
+from patchwork.tests.utils import create_user, defaults
+from patchwork.utils import do_expiry
+
+class TestRegistrationExpiry(TestCase):
+
+ def register(self, date):
+ user = create_user()
+ user.is_active = False
+ user.date_joined = user.last_login = date
+ user.save()
+
+ conf = EmailConfirmation(type='registration', user=user,
+ email=user.email)
+ conf.date = date
+ conf.save()
+
+ return (user, conf)
+
+ def testOldRegistrationExpiry(self):
+ date = ((datetime.datetime.now() - EmailConfirmation.validity) -
+ datetime.timedelta(hours = 1))
+ (user, conf) = self.register(date)
+
+ do_expiry()
+
+ self.assertFalse(User.objects.filter(pk = user.pk).exists())
+ self.assertFalse(EmailConfirmation.objects.filter(pk = conf.pk)
+ .exists())
+
+
+ def testRecentRegistrationExpiry(self):
+ date = ((datetime.datetime.now() - EmailConfirmation.validity) +
+ datetime.timedelta(hours = 1))
+ (user, conf) = self.register(date)
+
+ do_expiry()
+
+ self.assertTrue(User.objects.filter(pk = user.pk).exists())
+ self.assertTrue(EmailConfirmation.objects.filter(pk = conf.pk)
+ .exists())
+
+ def testInactiveRegistrationExpiry(self):
+ (user, conf) = self.register(datetime.datetime.now())
+
+ # confirm registration
+ conf.user.is_active = True
+ conf.user.save()
+ conf.deactivate()
+
+ do_expiry()
+
+ self.assertTrue(User.objects.filter(pk = user.pk).exists())
+ self.assertFalse(EmailConfirmation.objects.filter(pk = conf.pk)
+ .exists())
+
+ def testPatchSubmitterExpiry(self):
+ defaults.project.save()
+ defaults.patch_author_person.save()
+
+ # someone submits a patch...
+ patch = Patch(project = defaults.project,
+ msgid = 'test@example.com', name = 'test patch',
+ submitter = defaults.patch_author_person,
+ content = defaults.patch)
+ patch.save()
+
+ # ... then starts registration...
+ date = ((datetime.datetime.now() - EmailConfirmation.validity) -
+ datetime.timedelta(hours = 1))
+ userid = 'test-user'
+ user = User.objects.create_user(userid,
+ defaults.patch_author_person.email, userid)
+ user.is_active = False
+ user.date_joined = user.last_login = date
+ user.save()
+
+ self.assertEqual(user.email, patch.submitter.email)
+
+ conf = EmailConfirmation(type='registration', user=user,
+ email=user.email)
+ conf.date = date
+ conf.save()
+
+ # ... which expires
+ do_expiry()
+
+ # we should see no matching user
+ self.assertFalse(User.objects.filter(email = patch.submitter.email)
+ .exists())
+ # but the patch and person should still be present
+ self.assertTrue(Person.objects.filter(
+ pk = defaults.patch_author_person.pk).exists())
+ self.assertTrue(Patch.objects.filter(pk = patch.pk).exists())
+
+ # and there should be no user associated with the person
+ self.assertEqual(Person.objects.get(pk =
+ defaults.patch_author_person.pk).user, None)
diff --git a/patchwork/tests/test_filters.py b/patchwork/tests/test_filters.py
new file mode 100644
index 0000000..2c464e5
--- /dev/null
+++ b/patchwork/tests/test_filters.py
@@ -0,0 +1,45 @@
+# Patchwork - automated patch tracking system
+# Copyright (C) 2011 Jeremy Kerr <jk@ozlabs.org>
+#
+# This file is part of the Patchwork package.
+#
+# Patchwork is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# Patchwork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Patchwork; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import unittest
+from django.test import TestCase
+from django.test.client import Client
+from patchwork.tests.utils import defaults, create_user, find_in_context
+
+class FilterQueryStringTest(TestCase):
+ def testFilterQSEscaping(self):
+ """test that filter fragments in a query string are properly escaped,
+ and stray ampersands don't get reflected back in the filter
+ links"""
+ project = defaults.project
+ defaults.project.save()
+ url = '/project/%s/list/?submitter=a%%26b=c' % project.linkname
+ response = self.client.get(url)
+ self.failUnlessEqual(response.status_code, 200)
+ self.failIf('submitter=a&amp;b=c' in response.content)
+ self.failIf('submitter=a&b=c' in response.content)
+
+ def testUTF8QSHandling(self):
+ """test that non-ascii characters can be handled by the filter
+ code"""
+ project = defaults.project
+ defaults.project.save()
+ url = '/project/%s/list/?submitter=%%E2%%98%%83' % project.linkname
+ response = self.client.get(url)
+ self.failUnlessEqual(response.status_code, 200)
diff --git a/patchwork/tests/test_list.py b/patchwork/tests/test_list.py
new file mode 100644
index 0000000..a795a5f
--- /dev/null
+++ b/patchwork/tests/test_list.py
@@ -0,0 +1,116 @@
+# Patchwork - automated patch tracking system
+# Copyright (C) 2012 Jeremy Kerr <jk@ozlabs.org>
+#
+# This file is part of the Patchwork package.
+#
+# Patchwork is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# Patchwork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Patchwork; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import unittest
+import random
+import datetime
+import string
+import re
+from django.test import TestCase
+from django.test.client import Client
+from patchwork.tests.utils import defaults, create_user, find_in_context
+from patchwork.models import Person, Patch
+from django.core.urlresolvers import reverse
+
+class EmptyPatchListTest(TestCase):
+
+ def testEmptyPatchList(self):
+ """test that we don't output an empty table when there are no
+ patches present"""
+ project = defaults.project
+ defaults.project.save()
+ url = reverse('patchwork.views.patch.list',
+ kwargs={'project_id': project.linkname})
+ response = self.client.get(url)
+ self.assertContains(response, 'No patches to display')
+ self.assertNotContains(response, 'tbody')
+
+class PatchOrderTest(TestCase):
+
+ d = datetime.datetime
+ patchmeta = [
+ ('AlCMyjOsx', 'AlxMyjOsx@nRbqkQV.wBw', d(2014,3,16,13, 4,50, 155643)),
+ ('MMZnrcDjT', 'MMmnrcDjT@qGaIfOl.tbk', d(2014,1,25,13, 4,50, 162814)),
+ ('WGirwRXgK', 'WGSrwRXgK@TriIETY.GhE', d(2014,2,14,13, 4,50, 169305)),
+ ('isjNIuiAc', 'issNIuiAc@OsEirYx.EJh', d(2014,3,15,13, 4,50, 176264)),
+ ('XkAQpYGws', 'XkFQpYGws@hzntTcm.JSE', d(2014,1,18,13, 4,50, 182493)),
+ ('uJuCPWMvi', 'uJACPWMvi@AVRBOBl.ecy', d(2014,3,12,13, 4,50, 189554)),
+ ('TyQmWtcbg', 'TylmWtcbg@DzrNeNH.JuB', d(2014,2, 3,13, 4,50, 195685)),
+ ('FpvAhWRdX', 'FpKAhWRdX@agxnCAI.wFO', d(2014,3,15,13, 4,50, 201398)),
+ ('bmoYvnyWa', 'bmdYvnyWa@aeoPnlX.juy', d(2014,3, 4,13, 4,50, 206800)),
+ ('CiReUQsAq', 'CiieUQsAq@DnOYRuf.TTI', d(2014,3,28,13, 4,50, 212169)),
+ ]
+
+ def setUp(self):
+ defaults.project.save()
+
+ for (name, email, date) in self.patchmeta:
+ patch_name = 'testpatch' + name
+ person = Person(name = name, email = email)
+ person.save()
+ patch = Patch(project = defaults.project, msgid = patch_name,
+ submitter = person, content = '', date = date)
+ patch.save()
+
+ def _extract_patch_ids(self, response):
+ id_re = re.compile('<tr id="patch_row:(\d+)" ')
+ ids = [ int(m.group(1)) for m in id_re.finditer(response.content) ]
+ return ids
+
+ def _test_sequence(self, response, test_fn):
+ ids = self._extract_patch_ids(response)
+ self.assertTrue(bool(ids))
+ patches = [ Patch.objects.get(id = i) for i in ids ]
+ pairs = zip(patches, patches[1:])
+ [ test_fn(p1, p2) for (p1, p2) in pairs ]
+
+ def testDateOrder(self):
+ url = reverse('patchwork.views.patch.list',
+ kwargs={'project_id': defaults.project.linkname})
+ response = self.client.get(url + '?order=date')
+ def test_fn(p1, p2):
+ self.assertLessEqual(p1.date, p2.date)
+ self._test_sequence(response, test_fn)
+
+ def testDateReverseOrder(self):
+ url = reverse('patchwork.views.patch.list',
+ kwargs={'project_id': defaults.project.linkname})
+ response = self.client.get(url + '?order=-date')
+ def test_fn(p1, p2):
+ self.assertGreaterEqual(p1.date, p2.date)
+ self._test_sequence(response, test_fn)
+
+ def testSubmitterOrder(self):
+ url = reverse('patchwork.views.patch.list',
+ kwargs={'project_id': defaults.project.linkname})
+ response = self.client.get(url + '?order=submitter')
+ def test_fn(p1, p2):
+ self.assertLessEqual(p1.submitter.name.lower(),
+ p2.submitter.name.lower())
+ self._test_sequence(response, test_fn)
+
+ def testSubmitterReverseOrder(self):
+ url = reverse('patchwork.views.patch.list',
+ kwargs={'project_id': defaults.project.linkname})
+ response = self.client.get(url + '?order=-submitter')
+ def test_fn(p1, p2):
+ self.assertGreaterEqual(p1.submitter.name.lower(),
+ p2.submitter.name.lower())
+ self._test_sequence(response, test_fn)
+
diff --git a/patchwork/tests/test_mail_settings.py b/patchwork/tests/test_mail_settings.py
new file mode 100644
index 0000000..a193c97
--- /dev/null
+++ b/patchwork/tests/test_mail_settings.py
@@ -0,0 +1,299 @@
+# Patchwork - automated patch tracking system
+# Copyright (C) 2010 Jeremy Kerr <jk@ozlabs.org>
+#
+# This file is part of the Patchwork package.
+#
+# Patchwork is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# Patchwork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Patchwork; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import unittest
+import re
+from django.test import TestCase
+from django.test.client import Client
+from django.core import mail
+from django.core.urlresolvers import reverse
+from django.contrib.auth.models import User
+from patchwork.models import EmailOptout, EmailConfirmation, Person
+from patchwork.tests.utils import create_user, error_strings
+
+class MailSettingsTest(TestCase):
+ view = 'patchwork.views.mail.settings'
+ url = reverse(view)
+
+ def testMailSettingsGET(self):
+ response = self.client.get(self.url)
+ self.assertEquals(response.status_code, 200)
+ self.assertTrue(response.context['form'])
+
+ def testMailSettingsPOST(self):
+ email = u'foo@example.com'
+ response = self.client.post(self.url, {'email': email})
+ self.assertEquals(response.status_code, 200)
+ self.assertTemplateUsed(response, 'patchwork/mail-settings.html')
+ self.assertEquals(response.context['email'], email)
+
+ def testMailSettingsPOSTEmpty(self):
+ response = self.client.post(self.url, {'email': ''})
+ self.assertEquals(response.status_code, 200)
+ self.assertTemplateUsed(response, 'patchwork/mail-form.html')
+ self.assertFormError(response, 'form', 'email',
+ 'This field is required.')
+
+ def testMailSettingsPOSTInvalid(self):
+ response = self.client.post(self.url, {'email': 'foo'})
+ self.assertEquals(response.status_code, 200)
+ self.assertTemplateUsed(response, 'patchwork/mail-form.html')
+ self.assertFormError(response, 'form', 'email', error_strings['email'])
+
+ def testMailSettingsPOSTOptedIn(self):
+ email = u'foo@example.com'
+ response = self.client.post(self.url, {'email': email})
+ self.assertEquals(response.status_code, 200)
+ self.assertTemplateUsed(response, 'patchwork/mail-settings.html')
+ self.assertEquals(response.context['is_optout'], False)
+ self.assertTrue('<strong>may</strong>' in response.content)
+ optout_url = reverse('patchwork.views.mail.optout')
+ self.assertTrue(('action="%s"' % optout_url) in response.content)
+
+ def testMailSettingsPOSTOptedOut(self):
+ email = u'foo@example.com'
+ EmailOptout(email = email).save()
+ response = self.client.post(self.url, {'email': email})
+ self.assertEquals(response.status_code, 200)
+ self.assertTemplateUsed(response, 'patchwork/mail-settings.html')
+ self.assertEquals(response.context['is_optout'], True)
+ self.assertTrue('<strong>may not</strong>' in response.content)
+ optin_url = reverse('patchwork.views.mail.optin')
+ self.assertTrue(('action="%s"' % optin_url) in response.content)
+
+class OptoutRequestTest(TestCase):
+ view = 'patchwork.views.mail.optout'
+ url = reverse(view)
+
+ def testOptOutRequestGET(self):
+ response = self.client.get(self.url)
+ self.assertRedirects(response, reverse('patchwork.views.mail.settings'))
+
+ def testOptoutRequestValidPOST(self):
+ email = u'foo@example.com'
+ response = self.client.post(self.url, {'email': email})
+
+ # check for a confirmation object
+ self.assertEquals(EmailConfirmation.objects.count(), 1)
+ conf = EmailConfirmation.objects.get(email = email)
+
+ # check confirmation page
+ self.assertEquals(response.status_code, 200)
+ self.assertEquals(response.context['confirmation'], conf)
+ self.assertTrue(email in response.content)
+
+ # check email
+ url = reverse('patchwork.views.confirm', kwargs = {'key': conf.key})
+ self.assertEquals(len(mail.outbox), 1)
+ msg = mail.outbox[0]
+ self.assertEquals(msg.to, [email])
+ self.assertEquals(msg.subject, 'Patchwork opt-out confirmation')
+ self.assertTrue(url in msg.body)
+
+ def testOptoutRequestInvalidPOSTEmpty(self):
+ response = self.client.post(self.url, {'email': ''})
+ self.assertEquals(response.status_code, 200)
+ self.assertFormError(response, 'form', 'email',
+ 'This field is required.')
+ self.assertTrue(response.context['error'])
+ self.assertTrue('email_sent' not in response.context)
+ self.assertEquals(len(mail.outbox), 0)
+
+ def testOptoutRequestInvalidPOSTNonEmail(self):
+ response = self.client.post(self.url, {'email': 'foo'})
+ self.assertEquals(response.status_code, 200)
+ self.assertFormError(response, 'form', 'email', error_strings['email'])
+ self.assertTrue(response.context['error'])
+ self.assertTrue('email_sent' not in response.context)
+ self.assertEquals(len(mail.outbox), 0)
+
+class OptoutTest(TestCase):
+ view = 'patchwork.views.mail.optout'
+ url = reverse(view)
+
+ def setUp(self):
+ self.email = u'foo@example.com'
+ self.conf = EmailConfirmation(type = 'optout', email = self.email)
+ self.conf.save()
+
+ def testOptoutValidHash(self):
+ url = reverse('patchwork.views.confirm',
+ kwargs = {'key': self.conf.key})
+ response = self.client.get(url)
+
+ self.assertEquals(response.status_code, 200)
+ self.assertTemplateUsed(response, 'patchwork/optout.html')
+ self.assertTrue(self.email in response.content)
+
+ # check that we've got an optout in the list
+ self.assertEquals(EmailOptout.objects.count(), 1)
+ self.assertEquals(EmailOptout.objects.all()[0].email, self.email)
+
+ # check that the confirmation is now inactive
+ self.assertFalse(EmailConfirmation.objects.get(
+ pk = self.conf.pk).active)
+
+
+class OptoutPreexistingTest(OptoutTest):
+ """Test that a duplicated opt-out behaves the same as the initial one"""
+ def setUp(self):
+ super(OptoutPreexistingTest, self).setUp()
+ EmailOptout(email = self.email).save()
+
+class OptinRequestTest(TestCase):
+ view = 'patchwork.views.mail.optin'
+ url = reverse(view)
+
+ def setUp(self):
+ self.email = u'foo@example.com'
+ EmailOptout(email = self.email).save()
+
+ def testOptInRequestGET(self):
+ response = self.client.get(self.url)
+ self.assertRedirects(response, reverse('patchwork.views.mail.settings'))
+
+ def testOptInRequestValidPOST(self):
+ response = self.client.post(self.url, {'email': self.email})
+
+ # check for a confirmation object
+ self.assertEquals(EmailConfirmation.objects.count(), 1)
+ conf = EmailConfirmation.objects.get(email = self.email)
+
+ # check confirmation page
+ self.assertEquals(response.status_code, 200)
+ self.assertEquals(response.context['confirmation'], conf)
+ self.assertTrue(self.email in response.content)
+
+ # check email
+ url = reverse('patchwork.views.confirm', kwargs = {'key': conf.key})
+ self.assertEquals(len(mail.outbox), 1)
+ msg = mail.outbox[0]
+ self.assertEquals(msg.to, [self.email])
+ self.assertEquals(msg.subject, 'Patchwork opt-in confirmation')
+ self.assertTrue(url in msg.body)
+
+ def testOptoutRequestInvalidPOSTEmpty(self):
+ response = self.client.post(self.url, {'email': ''})
+ self.assertEquals(response.status_code, 200)
+ self.assertFormError(response, 'form', 'email',
+ 'This field is required.')
+ self.assertTrue(response.context['error'])
+ self.assertTrue('email_sent' not in response.context)
+ self.assertEquals(len(mail.outbox), 0)
+
+ def testOptoutRequestInvalidPOSTNonEmail(self):
+ response = self.client.post(self.url, {'email': 'foo'})
+ self.assertEquals(response.status_code, 200)
+ self.assertFormError(response, 'form', 'email', error_strings['email'])
+ self.assertTrue(response.context['error'])
+ self.assertTrue('email_sent' not in response.context)
+ self.assertEquals(len(mail.outbox), 0)
+
+class OptinTest(TestCase):
+
+ def setUp(self):
+ self.email = u'foo@example.com'
+ self.optout = EmailOptout(email = self.email)
+ self.optout.save()
+ self.conf = EmailConfirmation(type = 'optin', email = self.email)
+ self.conf.save()
+
+ def testOptinValidHash(self):
+ url = reverse('patchwork.views.confirm',
+ kwargs = {'key': self.conf.key})
+ response = self.client.get(url)
+
+ self.assertEquals(response.status_code, 200)
+ self.assertTemplateUsed(response, 'patchwork/optin.html')
+ self.assertTrue(self.email in response.content)
+
+ # check that there's no optout remaining
+ self.assertEquals(EmailOptout.objects.count(), 0)
+
+ # check that the confirmation is now inactive
+ self.assertFalse(EmailConfirmation.objects.get(
+ pk = self.conf.pk).active)
+
+class OptinWithoutOptoutTest(TestCase):
+ """Test an opt-in with no existing opt-out"""
+ view = 'patchwork.views.mail.optin'
+ url = reverse(view)
+
+ def testOptInWithoutOptout(self):
+ email = u'foo@example.com'
+ response = self.client.post(self.url, {'email': email})
+
+ # check for an error message
+ self.assertEquals(response.status_code, 200)
+ self.assertTrue(bool(response.context['error']))
+ self.assertTrue('not on the patchwork opt-out list' in response.content)
+
+class UserProfileOptoutFormTest(TestCase):
+ """Test that the correct optin/optout forms appear on the user profile
+ page, for logged-in users"""
+
+ view = 'patchwork.views.user.profile'
+ url = reverse(view)
+ optout_url = reverse('patchwork.views.mail.optout')
+ optin_url = reverse('patchwork.views.mail.optin')
+ form_re_template = ('<form\s+[^>]*action="%(url)s"[^>]*>'
+ '.*?<input\s+[^>]*value="%(email)s"[^>]*>.*?'
+ '</form>')
+ secondary_email = 'test2@example.com'
+
+ def setUp(self):
+ self.user = create_user()
+ self.client.login(username = self.user.username,
+ password = self.user.username)
+
+ def _form_re(self, url, email):
+ return re.compile(self.form_re_template % {'url': url, 'email': email},
+ re.DOTALL)
+
+ def testMainEmailOptoutForm(self):
+ form_re = self._form_re(self.optout_url, self.user.email)
+ response = self.client.get(self.url)
+ self.assertEquals(response.status_code, 200)
+ self.assertTrue(form_re.search(response.content) is not None)
+
+ def testMainEmailOptinForm(self):
+ EmailOptout(email = self.user.email).save()
+ form_re = self._form_re(self.optin_url, self.user.email)
+ response = self.client.get(self.url)
+ self.assertEquals(response.status_code, 200)
+ self.assertTrue(form_re.search(response.content) is not None)
+
+ def testSecondaryEmailOptoutForm(self):
+ p = Person(email = self.secondary_email, user = self.user)
+ p.save()
+
+ form_re = self._form_re(self.optout_url, p.email)
+ response = self.client.get(self.url)
+ self.assertEquals(response.status_code, 200)
+ self.assertTrue(form_re.search(response.content) is not None)
+
+ def testSecondaryEmailOptinForm(self):
+ p = Person(email = self.secondary_email, user = self.user)
+ p.save()
+ EmailOptout(email = p.email).save()
+
+ form_re = self._form_re(self.optin_url, p.email)
+ response = self.client.get(self.url)
+ self.assertEquals(response.status_code, 200)
+ self.assertTrue(form_re.search(response.content) is not None)
diff --git a/patchwork/tests/test_mboxviews.py b/patchwork/tests/test_mboxviews.py
new file mode 100644
index 0000000..0e57f42
--- /dev/null
+++ b/patchwork/tests/test_mboxviews.py
@@ -0,0 +1,209 @@
+# vim: set fileencoding=utf-8 :
+#
+# Patchwork - automated patch tracking system
+# Copyright (C) 2009 Jeremy Kerr <jk@ozlabs.org>
+#
+# This file is part of the Patchwork package.
+#
+# Patchwork is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# Patchwork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Patchwork; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import unittest
+import email
+import datetime
+import dateutil.parser, dateutil.tz
+from django.test import TestCase
+from django.test.client import Client
+from patchwork.models import Patch, Comment, Person
+from patchwork.tests.utils import defaults, create_user, find_in_context
+
+class MboxPatchResponseTest(TestCase):
+ """ Test that the mbox view appends the Acked-by from a patch comment """
+ def setUp(self):
+ defaults.project.save()
+
+ self.person = defaults.patch_author_person
+ self.person.save()
+
+ self.patch = Patch(project = defaults.project,
+ msgid = 'p1', name = 'testpatch',
+ submitter = self.person, content = '')
+ self.patch.save()
+ comment = Comment(patch = self.patch, msgid = 'p1',
+ submitter = self.person,
+ content = 'comment 1 text\nAcked-by: 1\n')
+ comment.save()
+
+ comment = Comment(patch = self.patch, msgid = 'p2',
+ submitter = self.person,
+ content = 'comment 2 text\nAcked-by: 2\n')
+ comment.save()
+
+ def testPatchResponse(self):
+ response = self.client.get('/patch/%d/mbox/' % self.patch.id)
+ self.assertContains(response,
+ 'Acked-by: 1\nAcked-by: 2\n')
+
+class MboxPatchSplitResponseTest(TestCase):
+ """ Test that the mbox view appends the Acked-by from a patch comment,
+ and places it before an '---' update line. """
+ def setUp(self):
+ defaults.project.save()
+
+ self.person = defaults.patch_author_person
+ self.person.save()
+
+ self.patch = Patch(project = defaults.project,
+ msgid = 'p1', name = 'testpatch',
+ submitter = self.person, content = '')
+ self.patch.save()
+ comment = Comment(patch = self.patch, msgid = 'p1',
+ submitter = self.person,
+ content = 'comment 1 text\nAcked-by: 1\n---\nupdate\n')
+ comment.save()
+
+ comment = Comment(patch = self.patch, msgid = 'p2',
+ submitter = self.person,
+ content = 'comment 2 text\nAcked-by: 2\n')
+ comment.save()
+
+ def testPatchResponse(self):
+ response = self.client.get('/patch/%d/mbox/' % self.patch.id)
+ self.assertContains(response,
+ 'Acked-by: 1\nAcked-by: 2\n')
+
+class MboxPassThroughHeaderTest(TestCase):
+ """ Test that we see 'Cc' and 'To' headers passed through from original
+ message to mbox view """
+
+ def setUp(self):
+ defaults.project.save()
+ self.person = defaults.patch_author_person
+ self.person.save()
+
+ self.cc_header = 'Cc: CC Person <cc@example.com>'
+ self.to_header = 'To: To Person <to@example.com>'
+ self.date_header = 'Date: Fri, 7 Jun 2013 15:42:54 +1000'
+
+ self.patch = Patch(project = defaults.project,
+ msgid = 'p1', name = 'testpatch',
+ submitter = self.person, content = '')
+
+ def testCCHeader(self):
+ self.patch.headers = self.cc_header + '\n'
+ self.patch.save()
+
+ response = self.client.get('/patch/%d/mbox/' % self.patch.id)
+ self.assertContains(response, self.cc_header)
+
+ def testToHeader(self):
+ self.patch.headers = self.to_header + '\n'
+ self.patch.save()
+
+ response = self.client.get('/patch/%d/mbox/' % self.patch.id)
+ self.assertContains(response, self.to_header)
+
+ def testDateHeader(self):
+ self.patch.headers = self.date_header + '\n'
+ self.patch.save()
+
+ response = self.client.get('/patch/%d/mbox/' % self.patch.id)
+ self.assertContains(response, self.date_header)
+
+class MboxBrokenFromHeaderTest(TestCase):
+ """ Test that a person with characters outside ASCII in his name do
+ produce correct From header. As RFC 2822 state we must retain the
+ <user@doamin.tld> format for the mail while the name part may be coded
+ in some ways. """
+
+ def setUp(self):
+ defaults.project.save()
+ self.person = defaults.patch_author_person
+ self.person.name = u'©ool guŷ'
+ self.person.save()
+
+ self.patch = Patch(project = defaults.project,
+ msgid = 'p1', name = 'testpatch',
+ submitter = self.person, content = '')
+
+ def testFromHeader(self):
+ self.patch.save()
+ from_email = '<' + self.person.email + '>'
+
+ response = self.client.get('/patch/%d/mbox/' % self.patch.id)
+ self.assertContains(response, from_email)
+
+class MboxDateHeaderTest(TestCase):
+ """ Test that the date provided in the patch mail view is correct """
+
+ def setUp(self):
+ defaults.project.save()
+ self.person = defaults.patch_author_person
+ self.person.save()
+
+ self.patch = Patch(project = defaults.project,
+ msgid = 'p1', name = 'testpatch',
+ submitter = self.person, content = '')
+ self.patch.save()
+
+ def testDateHeader(self):
+ response = self.client.get('/patch/%d/mbox/' % self.patch.id)
+ mail = email.message_from_string(response.content)
+ mail_date = dateutil.parser.parse(mail['Date'])
+ # patch dates are all in UTC
+ patch_date = self.patch.date.replace(tzinfo=dateutil.tz.tzutc(),
+ microsecond=0)
+ self.assertEqual(mail_date, patch_date)
+
+ def testSuppliedDateHeader(self):
+ hour_offset = 3
+ tz = dateutil.tz.tzoffset(None, hour_offset * 60 * 60)
+ date = datetime.datetime.utcnow() - datetime.timedelta(days = 1)
+ date = date.replace(tzinfo=tz, microsecond=0)
+
+ self.patch.headers = 'Date: %s\n' % date.strftime("%a, %d %b %Y %T %z")
+ self.patch.save()
+
+ response = self.client.get('/patch/%d/mbox/' % self.patch.id)
+ mail = email.message_from_string(response.content)
+ mail_date = dateutil.parser.parse(mail['Date'])
+ self.assertEqual(mail_date, date)
+
+class MboxCommentPostcriptUnchangedTest(TestCase):
+ """ Test that the mbox view doesn't change the postscript part of a mail.
+ There where always a missing blank right after the postscript
+ delimiter '---' and an additional newline right before. """
+ def setUp(self):
+ defaults.project.save()
+
+ self.person = defaults.patch_author_person
+ self.person.save()
+
+ self.patch = Patch(project = defaults.project,
+ msgid = 'p1', name = 'testpatch',
+ submitter = self.person, content = '')
+ self.patch.save()
+
+ self.txt = 'some comment\n---\n some/file | 1 +\n'
+
+ comment = Comment(patch = self.patch, msgid = 'p1',
+ submitter = self.person,
+ content = self.txt)
+ comment.save()
+
+ def testCommentUnchanged(self):
+ response = self.client.get('/patch/%d/mbox/' % self.patch.id)
+ self.assertContains(response, self.txt)
+ self.txt += "\n"
+ self.assertNotContains(response, self.txt)
diff --git a/patchwork/tests/test_notifications.py b/patchwork/tests/test_notifications.py
new file mode 100644
index 0000000..ed35140
--- /dev/null
+++ b/patchwork/tests/test_notifications.py
@@ -0,0 +1,255 @@
+# Patchwork - automated patch tracking system
+# Copyright (C) 2011 Jeremy Kerr <jk@ozlabs.org>
+#
+# This file is part of the Patchwork package.
+#
+# Patchwork is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# Patchwork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Patchwork; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import datetime
+from django.test import TestCase
+from django.core.urlresolvers import reverse
+from django.core import mail
+from django.conf import settings
+from django.db.utils import IntegrityError
+from patchwork.models import Patch, State, PatchChangeNotification, EmailOptout
+from patchwork.tests.utils import defaults, create_maintainer
+from patchwork.utils import send_notifications
+
+class PatchNotificationModelTest(TestCase):
+ """Tests for the creation & update of the PatchChangeNotification model"""
+
+ def setUp(self):
+ self.project = defaults.project
+ self.project.send_notifications = True
+ self.project.save()
+ self.submitter = defaults.patch_author_person
+ self.submitter.save()
+ self.patch = Patch(project = self.project, msgid = 'testpatch',
+ name = 'testpatch', content = '',
+ submitter = self.submitter)
+
+ def tearDown(self):
+ self.patch.delete()
+ self.submitter.delete()
+ self.project.delete()
+
+ def testPatchCreation(self):
+ """Ensure we don't get a notification on create"""
+ self.patch.save()
+ self.assertEqual(PatchChangeNotification.objects.count(), 0)
+
+ def testPatchUninterestingChange(self):
+ """Ensure we don't get a notification for "uninteresting" changes"""
+ self.patch.save()
+ self.patch.archived = True
+ self.patch.save()
+ self.assertEqual(PatchChangeNotification.objects.count(), 0)
+
+ def testPatchChange(self):
+ """Ensure we get a notification for interesting patch changes"""
+ self.patch.save()
+ oldstate = self.patch.state
+ state = State.objects.exclude(pk = oldstate.pk)[0]
+
+ self.patch.state = state
+ self.patch.save()
+ self.assertEqual(PatchChangeNotification.objects.count(), 1)
+ notification = PatchChangeNotification.objects.all()[0]
+ self.assertEqual(notification.patch, self.patch)
+ self.assertEqual(notification.orig_state, oldstate)
+
+ def testNotificationCancelled(self):
+ """Ensure we cancel notifications that are no longer valid"""
+ self.patch.save()
+ oldstate = self.patch.state
+ state = State.objects.exclude(pk = oldstate.pk)[0]
+
+ self.patch.state = state
+ self.patch.save()
+ self.assertEqual(PatchChangeNotification.objects.count(), 1)
+
+ self.patch.state = oldstate
+ self.patch.save()
+ self.assertEqual(PatchChangeNotification.objects.count(), 0)
+
+ def testNotificationUpdated(self):
+ """Ensure we update notifications when the patch has a second change,
+ but keep the original patch details"""
+ self.patch.save()
+ oldstate = self.patch.state
+ newstates = State.objects.exclude(pk = oldstate.pk)[:2]
+
+ self.patch.state = newstates[0]
+ self.patch.save()
+ self.assertEqual(PatchChangeNotification.objects.count(), 1)
+ notification = PatchChangeNotification.objects.all()[0]
+ self.assertEqual(notification.orig_state, oldstate)
+ orig_timestamp = notification.last_modified
+
+ self.patch.state = newstates[1]
+ self.patch.save()
+ self.assertEqual(PatchChangeNotification.objects.count(), 1)
+ notification = PatchChangeNotification.objects.all()[0]
+ self.assertEqual(notification.orig_state, oldstate)
+ self.assertTrue(notification.last_modified >= orig_timestamp)
+
+ def testProjectNotificationsDisabled(self):
+ """Ensure we don't see notifications created when a project is
+ configured not to send them"""
+ self.project.send_notifications = False
+ self.project.save()
+
+ self.patch.save()
+ oldstate = self.patch.state
+ state = State.objects.exclude(pk = oldstate.pk)[0]
+
+ self.patch.state = state
+ self.patch.save()
+ self.assertEqual(PatchChangeNotification.objects.count(), 0)
+
+class PatchNotificationEmailTest(TestCase):
+
+ def setUp(self):
+ self.project = defaults.project
+ self.project.send_notifications = True
+ self.project.save()
+ self.submitter = defaults.patch_author_person
+ self.submitter.save()
+ self.patch = Patch(project = self.project, msgid = 'testpatch',
+ name = 'testpatch', content = '',
+ submitter = self.submitter)
+ self.patch.save()
+
+ def tearDown(self):
+ self.patch.delete()
+ self.submitter.delete()
+ self.project.delete()
+
+ def _expireNotifications(self, **kwargs):
+ timestamp = datetime.datetime.now() - \
+ datetime.timedelta(minutes =
+ settings.NOTIFICATION_DELAY_MINUTES + 1)
+
+ qs = PatchChangeNotification.objects.all()
+ if kwargs:
+ qs = qs.filter(**kwargs)
+
+ qs.update(last_modified = timestamp)
+
+ def testNoNotifications(self):
+ self.assertEquals(send_notifications(), [])
+
+ def testNoReadyNotifications(self):
+ """ We shouldn't see immediate notifications"""
+ PatchChangeNotification(patch = self.patch,
+ orig_state = self.patch.state).save()
+
+ errors = send_notifications()
+ self.assertEquals(errors, [])
+ self.assertEquals(len(mail.outbox), 0)
+
+ def testNotifications(self):
+ PatchChangeNotification(patch = self.patch,
+ orig_state = self.patch.state).save()
+ self._expireNotifications()
+
+ errors = send_notifications()
+ self.assertEquals(errors, [])
+ self.assertEquals(len(mail.outbox), 1)
+ msg = mail.outbox[0]
+ self.assertEquals(msg.to, [self.submitter.email])
+ self.assertTrue(self.patch.get_absolute_url() in msg.body)
+
+ def testNotificationEscaping(self):
+ self.patch.name = 'Patch name with " character'
+ self.patch.save()
+ PatchChangeNotification(patch = self.patch,
+ orig_state = self.patch.state).save()
+ self._expireNotifications()
+
+ errors = send_notifications()
+ self.assertEquals(errors, [])
+ self.assertEquals(len(mail.outbox), 1)
+ msg = mail.outbox[0]
+ self.assertEquals(msg.to, [self.submitter.email])
+ self.assertFalse('&quot;' in msg.body)
+
+ def testNotificationOptout(self):
+ """ensure opt-out addresses don't get notifications"""
+ PatchChangeNotification(patch = self.patch,
+ orig_state = self.patch.state).save()
+ self._expireNotifications()
+
+ EmailOptout(email = self.submitter.email).save()
+
+ errors = send_notifications()
+ self.assertEquals(errors, [])
+ self.assertEquals(len(mail.outbox), 0)
+
+ def testNotificationMerge(self):
+ patches = [self.patch,
+ Patch(project = self.project, msgid = 'testpatch-2',
+ name = 'testpatch 2', content = '',
+ submitter = self.submitter)]
+
+ for patch in patches:
+ patch.save()
+ PatchChangeNotification(patch = patch,
+ orig_state = patch.state).save()
+
+ self.assertEquals(PatchChangeNotification.objects.count(), len(patches))
+ self._expireNotifications()
+ errors = send_notifications()
+ self.assertEquals(errors, [])
+ self.assertEquals(len(mail.outbox), 1)
+ msg = mail.outbox[0]
+ self.assertTrue(patches[0].get_absolute_url() in msg.body)
+ self.assertTrue(patches[1].get_absolute_url() in msg.body)
+
+ def testUnexpiredNotificationMerge(self):
+ """Test that when there are multiple pending notifications, with
+ at least one within the notification delay, that other notifications
+ are held"""
+ patches = [self.patch,
+ Patch(project = self.project, msgid = 'testpatch-2',
+ name = 'testpatch 2', content = '',
+ submitter = self.submitter)]
+
+ for patch in patches:
+ patch.save()
+ PatchChangeNotification(patch = patch,
+ orig_state = patch.state).save()
+
+ self.assertEquals(PatchChangeNotification.objects.count(), len(patches))
+ self._expireNotifications()
+
+ # update one notification, to bring it out of the notification delay
+ patches[0].state = State.objects.exclude(pk = patches[0].state.pk)[0]
+ patches[0].save()
+
+ # the updated notification should prevent the other from being sent
+ errors = send_notifications()
+ self.assertEquals(errors, [])
+ self.assertEquals(len(mail.outbox), 0)
+
+ # expire the updated notification
+ self._expireNotifications()
+
+ errors = send_notifications()
+ self.assertEquals(errors, [])
+ self.assertEquals(len(mail.outbox), 1)
+ msg = mail.outbox[0]
+ self.assertTrue(patches[0].get_absolute_url() in msg.body)
+ self.assertTrue(patches[1].get_absolute_url() in msg.body)
diff --git a/patchwork/tests/test_patchparser.py b/patchwork/tests/test_patchparser.py
new file mode 100644
index 0000000..119936a
--- /dev/null
+++ b/patchwork/tests/test_patchparser.py
@@ -0,0 +1,554 @@
+# Patchwork - automated patch tracking system
+# Copyright (C) 2008 Jeremy Kerr <jk@ozlabs.org>
+#
+# This file is part of the Patchwork package.
+#
+# Patchwork is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# Patchwork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Patchwork; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import os
+from email import message_from_string
+from django.test import TestCase
+from patchwork.models import Project, Person, Patch, Comment, State, \
+ get_default_initial_patch_state
+from patchwork.tests.utils import read_patch, read_mail, create_email, \
+ defaults, create_user
+
+try:
+ from email.mime.text import MIMEText
+except ImportError:
+ # Python 2.4 compatibility
+ from email.MIMEText import MIMEText
+
+class PatchTest(TestCase):
+ default_sender = defaults.sender
+ default_subject = defaults.subject
+ project = defaults.project
+
+from patchwork.bin.parsemail import find_content, find_author, find_project, \
+ parse_mail
+
+class InlinePatchTest(PatchTest):
+ patch_filename = '0001-add-line.patch'
+ test_comment = 'Test for attached patch'
+
+ def setUp(self):
+ self.orig_patch = read_patch(self.patch_filename)
+ email = create_email(self.test_comment + '\n' + self.orig_patch)
+ (self.patch, self.comment) = find_content(self.project, email)
+
+ def testPatchPresence(self):
+ self.assertTrue(self.patch is not None)
+
+ def testPatchContent(self):
+ self.assertEquals(self.patch.content, self.orig_patch)
+
+ def testCommentPresence(self):
+ self.assertTrue(self.comment is not None)
+
+ def testCommentContent(self):
+ self.assertEquals(self.comment.content, self.test_comment)
+
+
+class AttachmentPatchTest(InlinePatchTest):
+ patch_filename = '0001-add-line.patch'
+ test_comment = 'Test for attached patch'
+ content_subtype = 'x-patch'
+
+ def setUp(self):
+ self.orig_patch = read_patch(self.patch_filename)
+ email = create_email(self.test_comment, multipart = True)
+ attachment = MIMEText(self.orig_patch, _subtype = self.content_subtype)
+ email.attach(attachment)
+ (self.patch, self.comment) = find_content(self.project, email)
+
+class AttachmentXDiffPatchTest(AttachmentPatchTest):
+ content_subtype = 'x-diff'
+
+class UTF8InlinePatchTest(InlinePatchTest):
+ patch_filename = '0002-utf-8.patch'
+ patch_encoding = 'utf-8'
+
+ def setUp(self):
+ self.orig_patch = read_patch(self.patch_filename, self.patch_encoding)
+ email = create_email(self.test_comment + '\n' + self.orig_patch,
+ content_encoding = self.patch_encoding)
+ (self.patch, self.comment) = find_content(self.project, email)
+
+class NoCharsetInlinePatchTest(InlinePatchTest):
+ """ Test mails with no content-type or content-encoding header """
+ patch_filename = '0001-add-line.patch'
+
+ def setUp(self):
+ self.orig_patch = read_patch(self.patch_filename)
+ email = create_email(self.test_comment + '\n' + self.orig_patch)
+ del email['Content-Type']
+ del email['Content-Transfer-Encoding']
+ (self.patch, self.comment) = find_content(self.project, email)
+
+class SignatureCommentTest(InlinePatchTest):
+ patch_filename = '0001-add-line.patch'
+ test_comment = 'Test comment\nmore comment'
+
+ def setUp(self):
+ self.orig_patch = read_patch(self.patch_filename)
+ email = create_email( \
+ self.test_comment + '\n' + \
+ '-- \nsig\n' + self.orig_patch)
+ (self.patch, self.comment) = find_content(self.project, email)
+
+
+class ListFooterTest(InlinePatchTest):
+ patch_filename = '0001-add-line.patch'
+ test_comment = 'Test comment\nmore comment'
+
+ def setUp(self):
+ self.orig_patch = read_patch(self.patch_filename)
+ email = create_email( \
+ self.test_comment + '\n' + \
+ '_______________________________________________\n' + \
+ 'Linuxppc-dev mailing list\n' + \
+ self.orig_patch)
+ (self.patch, self.comment) = find_content(self.project, email)
+
+
+class DiffWordInCommentTest(InlinePatchTest):
+ test_comment = 'Lines can start with words beginning in "diff"\n' + \
+ 'difficult\nDifferent'
+
+
+class UpdateCommentTest(InlinePatchTest):
+ """ Test for '---\nUpdate: v2' style comments to patches. """
+ patch_filename = '0001-add-line.patch'
+ test_comment = 'Test comment\nmore comment\n---\nUpdate: test update'
+
+class UpdateSigCommentTest(SignatureCommentTest):
+ """ Test for '---\nUpdate: v2' style comments to patches, with a sig """
+ patch_filename = '0001-add-line.patch'
+ test_comment = 'Test comment\nmore comment\n---\nUpdate: test update'
+
+class SenderEncodingTest(TestCase):
+ sender_name = u'example user'
+ sender_email = 'user@example.com'
+ from_header = 'example user <user@example.com>'
+
+ def setUp(self):
+ mail = 'From: %s\n' % self.from_header + \
+ 'Subject: test\n\n' + \
+ 'test'
+ self.email = message_from_string(mail)
+ (self.person, new) = find_author(self.email)
+ self.person.save()
+
+ def tearDown(self):
+ self.person.delete()
+
+ def testName(self):
+ self.assertEquals(self.person.name, self.sender_name)
+
+ def testEmail(self):
+ self.assertEquals(self.person.email, self.sender_email)
+
+ def testDBQueryName(self):
+ db_person = Person.objects.get(name = self.sender_name)
+ self.assertEquals(self.person, db_person)
+
+ def testDBQueryEmail(self):
+ db_person = Person.objects.get(email = self.sender_email)
+ self.assertEquals(self.person, db_person)
+
+
+class SenderUTF8QPEncodingTest(SenderEncodingTest):
+ sender_name = u'\xe9xample user'
+ from_header = '=?utf-8?q?=C3=A9xample=20user?= <user@example.com>'
+
+class SenderUTF8QPSplitEncodingTest(SenderEncodingTest):
+ sender_name = u'\xe9xample user'
+ from_header = '=?utf-8?q?=C3=A9xample?= user <user@example.com>'
+
+class SenderUTF8B64EncodingTest(SenderUTF8QPEncodingTest):
+ from_header = '=?utf-8?B?w6l4YW1wbGUgdXNlcg==?= <user@example.com>'
+
+class SubjectEncodingTest(PatchTest):
+ sender = 'example user <user@example.com>'
+ subject = 'test subject'
+ subject_header = 'test subject'
+
+ def setUp(self):
+ mail = 'From: %s\n' % self.sender + \
+ 'Subject: %s\n\n' % self.subject_header + \
+ 'test\n\n' + defaults.patch
+ self.projects = defaults.project
+ self.email = message_from_string(mail)
+
+ def testSubjectEncoding(self):
+ (patch, comment) = find_content(self.project, self.email)
+ self.assertEquals(patch.name, self.subject)
+
+class SubjectUTF8QPEncodingTest(SubjectEncodingTest):
+ subject = u'test s\xfcbject'
+ subject_header = '=?utf-8?q?test=20s=c3=bcbject?='
+
+class SubjectUTF8QPMultipleEncodingTest(SubjectEncodingTest):
+ subject = u'test s\xfcbject'
+ subject_header = 'test =?utf-8?q?s=c3=bcbject?='
+
+class SenderCorrelationTest(TestCase):
+ existing_sender = 'Existing Sender <existing@example.com>'
+ non_existing_sender = 'Non-existing Sender <nonexisting@example.com>'
+
+ def mail(self, sender):
+ return message_from_string('From: %s\nSubject: Test\n\ntest\n' % sender)
+
+ def setUp(self):
+ self.existing_sender_mail = self.mail(self.existing_sender)
+ self.non_existing_sender_mail = self.mail(self.non_existing_sender)
+ (self.person, new) = find_author(self.existing_sender_mail)
+ self.person.save()
+
+ def testExisingSender(self):
+ (person, new) = find_author(self.existing_sender_mail)
+ self.assertEqual(new, False)
+ self.assertEqual(person.id, self.person.id)
+
+ def testNonExisingSender(self):
+ (person, new) = find_author(self.non_existing_sender_mail)
+ self.assertEqual(new, True)
+ self.assertEqual(person.id, None)
+
+ def testExistingDifferentFormat(self):
+ mail = self.mail('existing@example.com')
+ (person, new) = find_author(mail)
+ self.assertEqual(new, False)
+ self.assertEqual(person.id, self.person.id)
+
+ def testExistingDifferentCase(self):
+ mail = self.mail(self.existing_sender.upper())
+ (person, new) = find_author(mail)
+ self.assertEqual(new, False)
+ self.assertEqual(person.id, self.person.id)
+
+ def tearDown(self):
+ self.person.delete()
+
+class MultipleProjectPatchTest(TestCase):
+ """ Test that patches sent to multiple patchwork projects are
+ handled correctly """
+
+ test_comment = 'Test Comment'
+ patch_filename = '0001-add-line.patch'
+ msgid = '<1@example.com>'
+
+ def setUp(self):
+ self.p1 = Project(linkname = 'test-project-1', name = 'Project 1',
+ listid = '1.example.com', listemail='1@example.com')
+ self.p2 = Project(linkname = 'test-project-2', name = 'Project 2',
+ listid = '2.example.com', listemail='2@example.com')
+
+ self.p1.save()
+ self.p2.save()
+
+ patch = read_patch(self.patch_filename)
+ email = create_email(self.test_comment + '\n' + patch)
+ email['Message-Id'] = self.msgid
+
+ del email['List-ID']
+ email['List-ID'] = '<' + self.p1.listid + '>'
+ parse_mail(email)
+
+ del email['List-ID']
+ email['List-ID'] = '<' + self.p2.listid + '>'
+ parse_mail(email)
+
+ def testParsedProjects(self):
+ self.assertEquals(Patch.objects.filter(project = self.p1).count(), 1)
+ self.assertEquals(Patch.objects.filter(project = self.p2).count(), 1)
+
+ def tearDown(self):
+ self.p1.delete()
+ self.p2.delete()
+
+
+class MultipleProjectPatchCommentTest(MultipleProjectPatchTest):
+ """ Test that followups to multiple-project patches end up on the
+ correct patch """
+
+ comment_msgid = '<2@example.com>'
+ comment_content = 'test comment'
+
+ def setUp(self):
+ super(MultipleProjectPatchCommentTest, self).setUp()
+
+ for project in [self.p1, self.p2]:
+ email = MIMEText(self.comment_content)
+ email['From'] = defaults.sender
+ email['Subject'] = defaults.subject
+ email['Message-Id'] = self.comment_msgid
+ email['List-ID'] = '<' + project.listid + '>'
+ email['In-Reply-To'] = self.msgid
+ parse_mail(email)
+
+ def testParsedComment(self):
+ for project in [self.p1, self.p2]:
+ patch = Patch.objects.filter(project = project)[0]
+ # we should see two comments now - the original mail with the patch,
+ # and the one we parsed in setUp()
+ self.assertEquals(Comment.objects.filter(patch = patch).count(), 2)
+
+class ListIdHeaderTest(TestCase):
+ """ Test that we parse List-Id headers from mails correctly """
+ def setUp(self):
+ self.project = Project(linkname = 'test-project-1', name = 'Project 1',
+ listid = '1.example.com', listemail='1@example.com')
+ self.project.save()
+
+ def testNoListId(self):
+ email = MIMEText('')
+ project = find_project(email)
+ self.assertEquals(project, None)
+
+ def testBlankListId(self):
+ email = MIMEText('')
+ email['List-Id'] = ''
+ project = find_project(email)
+ self.assertEquals(project, None)
+
+ def testWhitespaceListId(self):
+ email = MIMEText('')
+ email['List-Id'] = ' '
+ project = find_project(email)
+ self.assertEquals(project, None)
+
+ def testSubstringListId(self):
+ email = MIMEText('')
+ email['List-Id'] = 'example.com'
+ project = find_project(email)
+ self.assertEquals(project, None)
+
+ def testShortListId(self):
+ """ Some mailing lists have List-Id headers in short formats, where it
+ is only the list ID itself (without enclosing angle-brackets). """
+ email = MIMEText('')
+ email['List-Id'] = self.project.listid
+ project = find_project(email)
+ self.assertEquals(project, self.project)
+
+ def testLongListId(self):
+ email = MIMEText('')
+ email['List-Id'] = 'Test text <%s>' % self.project.listid
+ project = find_project(email)
+ self.assertEquals(project, self.project)
+
+ def tearDown(self):
+ self.project.delete()
+
+class MBoxPatchTest(PatchTest):
+ def setUp(self):
+ self.mail = read_mail(self.mail_file, project = self.project)
+
+class GitPullTest(MBoxPatchTest):
+ mail_file = '0001-git-pull-request.mbox'
+
+ def testGitPullRequest(self):
+ (patch, comment) = find_content(self.project, self.mail)
+ self.assertTrue(patch is not None)
+ self.assertTrue(patch.pull_url is not None)
+ self.assertTrue(patch.content is None)
+ self.assertTrue(comment is not None)
+
+class GitPullWrappedTest(GitPullTest):
+ mail_file = '0002-git-pull-request-wrapped.mbox'
+
+class GitPullWithDiffTest(MBoxPatchTest):
+ mail_file = '0003-git-pull-request-with-diff.mbox'
+
+ def testGitPullWithDiff(self):
+ (patch, comment) = find_content(self.project, self.mail)
+ self.assertTrue(patch is not None)
+ self.assertEqual('git://git.kernel.org/pub/scm/linux/kernel/git/tip/' +
+ 'linux-2.6-tip.git x86-fixes-for-linus', patch.pull_url)
+ self.assertTrue(
+ patch.content.startswith('diff --git a/arch/x86/include/asm/smp.h'),
+ patch.content)
+ self.assertTrue(comment is not None)
+
+class GitPullGitSSHUrlTest(GitPullTest):
+ mail_file = '0004-git-pull-request-git+ssh.mbox'
+
+class GitPullSSHUrlTest(GitPullTest):
+ mail_file = '0005-git-pull-request-ssh.mbox'
+
+class GitPullHTTPUrlTest(GitPullTest):
+ mail_file = '0006-git-pull-request-http.mbox'
+
+class GitRenameOnlyTest(MBoxPatchTest):
+ mail_file = '0008-git-rename.mbox'
+
+ def testGitRename(self):
+ (patch, comment) = find_content(self.project, self.mail)
+ self.assertTrue(patch is not None)
+ self.assertTrue(comment is not None)
+ self.assertEqual(patch.content.count("\nrename from "), 2)
+ self.assertEqual(patch.content.count("\nrename to "), 2)
+
+class GitRenameWithDiffTest(MBoxPatchTest):
+ mail_file = '0009-git-rename-with-diff.mbox'
+
+ def testGitRename(self):
+ (patch, comment) = find_content(self.project, self.mail)
+ self.assertTrue(patch is not None)
+ self.assertTrue(comment is not None)
+ self.assertEqual(patch.content.count("\nrename from "), 2)
+ self.assertEqual(patch.content.count("\nrename to "), 2)
+ self.assertEqual(patch.content.count('\n-a\n+b'), 1)
+
+class CVSFormatPatchTest(MBoxPatchTest):
+ mail_file = '0007-cvs-format-diff.mbox'
+
+ def testPatch(self):
+ (patch, comment) = find_content(self.project, self.mail)
+ self.assertTrue(patch is not None)
+ self.assertTrue(comment is not None)
+ self.assertTrue(patch.content.startswith('Index'))
+
+class CharsetFallbackPatchTest(MBoxPatchTest):
+ """ Test mail with and invalid charset name, and check that we can parse
+ with one of the fallback encodings"""
+
+ mail_file = '0010-invalid-charset.mbox'
+
+ def testPatch(self):
+ (patch, comment) = find_content(self.project, self.mail)
+ self.assertTrue(patch is not None)
+ self.assertTrue(comment is not None)
+
+class NoNewlineAtEndOfFilePatchTest(MBoxPatchTest):
+ mail_file = '0011-no-newline-at-end-of-file.mbox'
+
+ def testPatch(self):
+ (patch, comment) = find_content(self.project, self.mail)
+ self.assertTrue(patch is not None)
+ self.assertTrue(comment is not None)
+ self.assertTrue(patch.content.startswith('diff --git a/tools/testing/selftests/powerpc/Makefile'))
+ # Confirm the trailing no newline marker doesn't end up in the comment
+ self.assertFalse(comment.content.rstrip().endswith('\ No newline at end of file'))
+ # Confirm it's instead at the bottom of the patch
+ self.assertTrue(patch.content.rstrip().endswith('\ No newline at end of file'))
+ # Confirm we got both markers
+ self.assertEqual(2, patch.content.count('\ No newline at end of file'))
+
+class DelegateRequestTest(TestCase):
+ patch_filename = '0001-add-line.patch'
+ msgid = '<1@example.com>'
+ invalid_delegate_email = "nobody"
+
+ def setUp(self):
+ self.patch = read_patch(self.patch_filename)
+ self.user = create_user()
+ self.p1 = Project(linkname = 'test-project-1', name = 'Project 1',
+ listid = '1.example.com', listemail='1@example.com')
+ self.p1.save()
+
+ def get_email(self):
+ email = create_email(self.patch)
+ del email['List-ID']
+ email['List-ID'] = '<' + self.p1.listid + '>'
+ email['Message-Id'] = self.msgid
+ return email
+
+ def _assertDelegate(self, delegate):
+ query = Patch.objects.filter(project=self.p1)
+ self.assertEquals(query.count(), 1)
+ self.assertEquals(query[0].delegate, delegate)
+
+ def testDelegate(self):
+ email = self.get_email()
+ email['X-Patchwork-Delegate'] = self.user.email
+ parse_mail(email)
+ self._assertDelegate(self.user)
+
+ def testNoDelegate(self):
+ email = self.get_email()
+ parse_mail(email)
+ self._assertDelegate(None)
+
+ def testInvalidDelegateFallsBackToNoDelegate(self):
+ email = self.get_email()
+ email['X-Patchwork-Delegate'] = self.invalid_delegate_email
+ parse_mail(email)
+ self._assertDelegate(None)
+
+ def tearDown(self):
+ self.p1.delete()
+ self.user.delete()
+
+class InitialPatchStateTest(TestCase):
+ patch_filename = '0001-add-line.patch'
+ msgid = '<1@example.com>'
+ invalid_state_name = "Nonexistent Test State"
+
+ def setUp(self):
+ self.patch = read_patch(self.patch_filename)
+ self.user = create_user()
+ self.p1 = Project(linkname = 'test-project-1', name = 'Project 1',
+ listid = '1.example.com', listemail='1@example.com')
+ self.p1.save()
+ self.default_state = get_default_initial_patch_state()
+ self.nondefault_state = State.objects.get(name="Accepted")
+
+ def get_email(self):
+ email = create_email(self.patch)
+ del email['List-ID']
+ email['List-ID'] = '<' + self.p1.listid + '>'
+ email['Message-Id'] = self.msgid
+ return email
+
+ def _assertState(self, state):
+ query = Patch.objects.filter(project=self.p1)
+ self.assertEquals(query.count(), 1)
+ self.assertEquals(query[0].state, state)
+
+ def testNonDefaultStateIsActuallyNotTheDefaultState(self):
+ self.assertNotEqual(self.default_state, self.nondefault_state)
+
+ def testExplicitNonDefaultStateRequest(self):
+ email = self.get_email()
+ email['X-Patchwork-State'] = self.nondefault_state.name
+ parse_mail(email)
+ self._assertState(self.nondefault_state)
+
+ def testExplicitDefaultStateRequest(self):
+ email = self.get_email()
+ email['X-Patchwork-State'] = self.default_state.name
+ parse_mail(email)
+ self._assertState(self.default_state)
+
+ def testImplicitDefaultStateRequest(self):
+ email = self.get_email()
+ parse_mail(email)
+ self._assertState(self.default_state)
+
+ def testInvalidTestStateDoesNotExist(self):
+ with self.assertRaises(State.DoesNotExist):
+ State.objects.get(name=self.invalid_state_name)
+
+ def testInvalidStateRequestFallsBackToDefaultState(self):
+ email = self.get_email()
+ email['X-Patchwork-State'] = self.invalid_state_name
+ parse_mail(email)
+ self._assertState(self.default_state)
+
+ def tearDown(self):
+ self.p1.delete()
+ self.user.delete()
diff --git a/patchwork/tests/test_person.py b/patchwork/tests/test_person.py
new file mode 100644
index 0000000..d948096
--- /dev/null
+++ b/patchwork/tests/test_person.py
@@ -0,0 +1,55 @@
+# Patchwork - automated patch tracking system
+# Copyright (C) 2013 Jeremy Kerr <jk@ozlabs.org>
+#
+# This file is part of the Patchwork package.
+#
+# Patchwork is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# Patchwork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Patchwork; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import unittest
+from django.test import TestCase
+from django.test.client import Client
+from patchwork.models import EmailConfirmation, Person, Bundle
+import json
+
+class SubmitterCompletionTest(TestCase):
+ def setUp(self):
+ self.people = [
+ Person(name = "Test Name", email = "test1@example.com"),
+ Person(email = "test2@example.com"),
+ ]
+ map(lambda p: p.save(), self.people)
+
+ def testNameComplete(self):
+ response = self.client.get('/submitter/', {'q': 'name'})
+ self.assertEquals(response.status_code, 200)
+ data = json.loads(response.content)
+ self.assertEquals(len(data), 1)
+ self.assertEquals(data[0]['fields']['name'], 'Test Name')
+
+ def testEmailComplete(self):
+ response = self.client.get('/submitter/', {'q': 'test2'})
+ self.assertEquals(response.status_code, 200)
+ data = json.loads(response.content)
+ self.assertEquals(len(data), 1)
+ self.assertEquals(data[0]['fields']['email'], 'test2@example.com')
+
+ def testCompleteLimit(self):
+ for i in range(3,10):
+ person = Person(email = 'test%d@example.com' % i)
+ person.save()
+ response = self.client.get('/submitter/', {'q': 'test', 'l': 5})
+ self.assertEquals(response.status_code, 200)
+ data = json.loads(response.content)
+ self.assertEquals(len(data), 5)
diff --git a/patchwork/tests/test_registration.py b/patchwork/tests/test_registration.py
new file mode 100644
index 0000000..845b60b
--- /dev/null
+++ b/patchwork/tests/test_registration.py
@@ -0,0 +1,210 @@
+# Patchwork - automated patch tracking system
+# Copyright (C) 2010 Jeremy Kerr <jk@ozlabs.org>
+#
+# This file is part of the Patchwork package.
+#
+# Patchwork is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# Patchwork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Patchwork; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import unittest
+from django.test import TestCase
+from django.test.client import Client
+from django.core import mail
+from django.core.urlresolvers import reverse
+from django.contrib.auth.models import User
+from patchwork.models import EmailConfirmation, Person
+from patchwork.tests.utils import create_user
+
+def _confirmation_url(conf):
+ return reverse('patchwork.views.confirm', kwargs = {'key': conf.key})
+
+class TestUser(object):
+ firstname = 'Test'
+ lastname = 'User'
+ username = 'testuser'
+ email = 'test@example.com'
+ password = 'foobar'
+
+class RegistrationTest(TestCase):
+ def setUp(self):
+ self.user = TestUser()
+ self.client = Client()
+ self.default_data = {'username': self.user.username,
+ 'first_name': self.user.firstname,
+ 'last_name': self.user.lastname,
+ 'email': self.user.email,
+ 'password': self.user.password}
+ self.required_error = 'This field is required.'
+ self.invalid_error = 'Enter a valid value.'
+
+ def testRegistrationForm(self):
+ response = self.client.get('/register/')
+ self.assertEquals(response.status_code, 200)
+ self.assertTemplateUsed(response, 'patchwork/registration_form.html')
+
+ def testBlankFields(self):
+ for field in ['username', 'email', 'password']:
+ data = self.default_data.copy()
+ del data[field]
+ response = self.client.post('/register/', data)
+ self.assertEquals(response.status_code, 200)
+ self.assertFormError(response, 'form', field, self.required_error)
+
+ def testInvalidUsername(self):
+ data = self.default_data.copy()
+ data['username'] = 'invalid user'
+ response = self.client.post('/register/', data)
+ self.assertEquals(response.status_code, 200)
+ self.assertFormError(response, 'form', 'username', self.invalid_error)
+
+ def testExistingUsername(self):
+ user = create_user()
+ data = self.default_data.copy()
+ data['username'] = user.username
+ response = self.client.post('/register/', data)
+ self.assertEquals(response.status_code, 200)
+ self.assertFormError(response, 'form', 'username',
+ 'This username is already taken. Please choose another.')
+
+ def testExistingEmail(self):
+ user = create_user()
+ data = self.default_data.copy()
+ data['email'] = user.email
+ response = self.client.post('/register/', data)
+ self.assertEquals(response.status_code, 200)
+ self.assertFormError(response, 'form', 'email',
+ 'This email address is already in use ' + \
+ 'for the account "%s".\n' % user.username)
+
+ def testValidRegistration(self):
+ response = self.client.post('/register/', self.default_data)
+ self.assertEquals(response.status_code, 200)
+ self.assertContains(response, 'confirmation email has been sent')
+
+ # check for presence of an inactive user object
+ users = User.objects.filter(username = self.user.username)
+ self.assertEquals(users.count(), 1)
+ user = users[0]
+ self.assertEquals(user.username, self.user.username)
+ self.assertEquals(user.email, self.user.email)
+ self.assertEquals(user.is_active, False)
+
+ # check for confirmation object
+ confs = EmailConfirmation.objects.filter(user = user,
+ type = 'registration')
+ self.assertEquals(len(confs), 1)
+ conf = confs[0]
+ self.assertEquals(conf.email, self.user.email)
+
+ # check for a sent mail
+ self.assertEquals(len(mail.outbox), 1)
+ msg = mail.outbox[0]
+ self.assertEquals(msg.subject, 'Patchwork account confirmation')
+ self.assertTrue(self.user.email in msg.to)
+ self.assertTrue(_confirmation_url(conf) in msg.body)
+
+ # ...and that the URL is valid
+ response = self.client.get(_confirmation_url(conf))
+ self.assertEquals(response.status_code, 200)
+
+class RegistrationConfirmationTest(TestCase):
+
+ def setUp(self):
+ self.user = TestUser()
+ self.default_data = {'username': self.user.username,
+ 'first_name': self.user.firstname,
+ 'last_name': self.user.lastname,
+ 'email': self.user.email,
+ 'password': self.user.password}
+
+ def testRegistrationConfirmation(self):
+ self.assertEqual(EmailConfirmation.objects.count(), 0)
+ response = self.client.post('/register/', self.default_data)
+ self.assertEquals(response.status_code, 200)
+ self.assertContains(response, 'confirmation email has been sent')
+
+ self.assertEqual(EmailConfirmation.objects.count(), 1)
+ conf = EmailConfirmation.objects.filter()[0]
+ self.assertFalse(conf.user.is_active)
+ self.assertTrue(conf.active)
+
+ response = self.client.get(_confirmation_url(conf))
+ self.assertEquals(response.status_code, 200)
+ self.assertTemplateUsed(response, 'patchwork/registration-confirm.html')
+
+ conf = EmailConfirmation.objects.get(pk = conf.pk)
+ self.assertTrue(conf.user.is_active)
+ self.assertFalse(conf.active)
+
+ def testRegistrationNewPersonSetup(self):
+ """ Check that the person object created after registration has the
+ correct details """
+
+ # register
+ self.assertEqual(EmailConfirmation.objects.count(), 0)
+ response = self.client.post('/register/', self.default_data)
+ self.assertEquals(response.status_code, 200)
+ self.assertFalse(Person.objects.exists())
+
+ # confirm
+ conf = EmailConfirmation.objects.filter()[0]
+ response = self.client.get(_confirmation_url(conf))
+ self.assertEquals(response.status_code, 200)
+
+ qs = Person.objects.filter(email = self.user.email)
+ self.assertTrue(qs.exists())
+ person = Person.objects.get(email = self.user.email)
+
+ self.assertEquals(person.name,
+ self.user.firstname + ' ' + self.user.lastname)
+
+ def testRegistrationExistingPersonSetup(self):
+ """ Check that the person object created after registration has the
+ correct details """
+
+ fullname = self.user.firstname + ' ' + self.user.lastname
+ person = Person(name = fullname, email = self.user.email)
+ person.save()
+
+ # register
+ self.assertEqual(EmailConfirmation.objects.count(), 0)
+ response = self.client.post('/register/', self.default_data)
+ self.assertEquals(response.status_code, 200)
+
+ # confirm
+ conf = EmailConfirmation.objects.filter()[0]
+ response = self.client.get(_confirmation_url(conf))
+ self.assertEquals(response.status_code, 200)
+
+ person = Person.objects.get(email = self.user.email)
+
+ self.assertEquals(person.name, fullname)
+
+ def testRegistrationExistingPersonUnmodified(self):
+ """ Check that an unconfirmed registration can't modify an existing
+ Person object"""
+
+ fullname = self.user.firstname + ' ' + self.user.lastname
+ person = Person(name = fullname, email = self.user.email)
+ person.save()
+
+ # register
+ data = self.default_data.copy()
+ data['first_name'] = 'invalid'
+ data['last_name'] = 'invalid'
+ self.assertEquals(data['email'], person.email)
+ response = self.client.post('/register/', data)
+ self.assertEquals(response.status_code, 200)
+
+ self.assertEquals(Person.objects.get(pk = person.pk).name, fullname)
diff --git a/patchwork/tests/test_updates.py b/patchwork/tests/test_updates.py
new file mode 100644
index 0000000..177ee78
--- /dev/null
+++ b/patchwork/tests/test_updates.py
@@ -0,0 +1,118 @@
+# Patchwork - automated patch tracking system
+# Copyright (C) 2010 Jeremy Kerr <jk@ozlabs.org>
+#
+# This file is part of the Patchwork package.
+#
+# Patchwork is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# Patchwork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Patchwork; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+from django.test import TestCase
+from django.core.urlresolvers import reverse
+from patchwork.models import Patch, Person, State
+from patchwork.tests.utils import defaults, create_maintainer
+
+class MultipleUpdateTest(TestCase):
+ def setUp(self):
+ defaults.project.save()
+ self.user = create_maintainer(defaults.project)
+ self.client.login(username = self.user.username,
+ password = self.user.username)
+ self.properties_form_id = 'patchform-properties'
+ self.url = reverse(
+ 'patchwork.views.patch.list', args = [defaults.project.linkname])
+ self.base_data = {
+ 'action': 'Update', 'project': str(defaults.project.id),
+ 'form': 'patchlistform', 'archived': '*', 'delegate': '*',
+ 'state': '*'}
+ self.patches = []
+ for name in ['patch one', 'patch two', 'patch three']:
+ patch = Patch(project = defaults.project, msgid = name,
+ name = name, content = '',
+ submitter = Person.objects.get(user = self.user))
+ patch.save()
+ self.patches.append(patch)
+
+ def _selectAllPatches(self, data):
+ for patch in self.patches:
+ data['patch_id:%d' % patch.id] = 'checked'
+
+ def testArchivingPatches(self):
+ data = self.base_data.copy()
+ data.update({'archived': 'True'})
+ self._selectAllPatches(data)
+ response = self.client.post(self.url, data)
+ self.assertContains(response, 'No patches to display',
+ status_code = 200)
+ for patch in [Patch.objects.get(pk = p.pk) for p in self.patches]:
+ self.assertTrue(patch.archived)
+
+ def testUnArchivingPatches(self):
+ # Start with one patch archived and the remaining ones unarchived.
+ self.patches[0].archived = True
+ self.patches[0].save()
+ data = self.base_data.copy()
+ data.update({'archived': 'False'})
+ self._selectAllPatches(data)
+ response = self.client.post(self.url, data)
+ self.assertContains(response, self.properties_form_id,
+ status_code = 200)
+ for patch in [Patch.objects.get(pk = p.pk) for p in self.patches]:
+ self.assertFalse(patch.archived)
+
+ def _testStateChange(self, state):
+ data = self.base_data.copy()
+ data.update({'state': str(state)})
+ self._selectAllPatches(data)
+ response = self.client.post(self.url, data)
+ self.assertContains(response, self.properties_form_id,
+ status_code = 200)
+ return response
+
+ def testStateChangeValid(self):
+ states = [patch.state.pk for patch in self.patches]
+ state = State.objects.exclude(pk__in = states)[0]
+ self._testStateChange(state.pk)
+ for p in self.patches:
+ self.assertEquals(Patch.objects.get(pk = p.pk).state, state)
+
+ def testStateChangeInvalid(self):
+ state = max(State.objects.all().values_list('id', flat = True)) + 1
+ orig_states = [patch.state for patch in self.patches]
+ response = self._testStateChange(state)
+ self.assertEquals( \
+ [Patch.objects.get(pk = p.pk).state for p in self.patches],
+ orig_states)
+ self.assertFormError(response, 'patchform', 'state',
+ 'Select a valid choice. That choice is not one ' + \
+ 'of the available choices.')
+
+ def _testDelegateChange(self, delegate_str):
+ data = self.base_data.copy()
+ data.update({'delegate': delegate_str})
+ self._selectAllPatches(data)
+ response = self.client.post(self.url, data)
+ self.assertContains(response, self.properties_form_id,
+ status_code=200)
+ return response
+
+ def testDelegateChangeValid(self):
+ delegate = create_maintainer(defaults.project)
+ response = self._testDelegateChange(str(delegate.pk))
+ for p in self.patches:
+ self.assertEquals(Patch.objects.get(pk = p.pk).delegate, delegate)
+
+ def testDelegateClear(self):
+ response = self._testDelegateChange('')
+ for p in self.patches:
+ self.assertEquals(Patch.objects.get(pk = p.pk).delegate, None)
diff --git a/patchwork/tests/test_user.py b/patchwork/tests/test_user.py
new file mode 100644
index 0000000..0faa970
--- /dev/null
+++ b/patchwork/tests/test_user.py
@@ -0,0 +1,195 @@
+# Patchwork - automated patch tracking system
+# Copyright (C) 2010 Jeremy Kerr <jk@ozlabs.org>
+#
+# This file is part of the Patchwork package.
+#
+# Patchwork is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# Patchwork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Patchwork; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import unittest
+from django.test import TestCase
+from django.test.client import Client
+from django.core import mail
+from django.core.urlresolvers import reverse
+from django.conf import settings
+from django.contrib.auth.models import User
+from patchwork.models import EmailConfirmation, Person, Bundle
+from patchwork.tests.utils import defaults, error_strings
+
+def _confirmation_url(conf):
+ return reverse('patchwork.views.confirm', kwargs = {'key': conf.key})
+
+class TestUser(object):
+ username = 'testuser'
+ email = 'test@example.com'
+ secondary_email = 'test2@example.com'
+ password = None
+
+ def __init__(self):
+ self.password = User.objects.make_random_password()
+ self.user = User.objects.create_user(self.username,
+ self.email, self.password)
+
+class UserPersonRequestTest(TestCase):
+ def setUp(self):
+ self.user = TestUser()
+ self.client.login(username = self.user.username,
+ password = self.user.password)
+ EmailConfirmation.objects.all().delete()
+
+ def testUserPersonRequestForm(self):
+ response = self.client.get('/user/link/')
+ self.assertEquals(response.status_code, 200)
+ self.assertTrue(response.context['linkform'])
+
+ def testUserPersonRequestEmpty(self):
+ response = self.client.post('/user/link/', {'email': ''})
+ self.assertEquals(response.status_code, 200)
+ self.assertTrue(response.context['linkform'])
+ self.assertFormError(response, 'linkform', 'email',
+ 'This field is required.')
+
+ def testUserPersonRequestInvalid(self):
+ response = self.client.post('/user/link/', {'email': 'foo'})
+ self.assertEquals(response.status_code, 200)
+ self.assertTrue(response.context['linkform'])
+ self.assertFormError(response, 'linkform', 'email',
+ error_strings['email'])
+
+ def testUserPersonRequestValid(self):
+ response = self.client.post('/user/link/',
+ {'email': self.user.secondary_email})
+ self.assertEquals(response.status_code, 200)
+ self.assertTrue(response.context['confirmation'])
+
+ # check that we have a confirmation saved
+ self.assertEquals(EmailConfirmation.objects.count(), 1)
+ conf = EmailConfirmation.objects.all()[0]
+ self.assertEquals(conf.user, self.user.user)
+ self.assertEquals(conf.email, self.user.secondary_email)
+ self.assertEquals(conf.type, 'userperson')
+
+ # check that an email has gone out...
+ self.assertEquals(len(mail.outbox), 1)
+ msg = mail.outbox[0]
+ self.assertEquals(msg.subject, 'Patchwork email address confirmation')
+ self.assertTrue(self.user.secondary_email in msg.to)
+ self.assertTrue(_confirmation_url(conf) in msg.body)
+
+ # ...and that the URL is valid
+ response = self.client.get(_confirmation_url(conf))
+ self.assertEquals(response.status_code, 200)
+ self.assertTemplateUsed(response, 'patchwork/user-link-confirm.html')
+
+class UserPersonConfirmTest(TestCase):
+ def setUp(self):
+ EmailConfirmation.objects.all().delete()
+ Person.objects.all().delete()
+ self.user = TestUser()
+ self.client.login(username = self.user.username,
+ password = self.user.password)
+ self.conf = EmailConfirmation(type = 'userperson',
+ email = self.user.secondary_email,
+ user = self.user.user)
+ self.conf.save()
+
+ def testUserPersonConfirm(self):
+ self.assertEquals(Person.objects.count(), 0)
+ response = self.client.get(_confirmation_url(self.conf))
+ self.assertEquals(response.status_code, 200)
+
+ # check that the Person object has been created and linked
+ self.assertEquals(Person.objects.count(), 1)
+ person = Person.objects.get(email = self.user.secondary_email)
+ self.assertEquals(person.email, self.user.secondary_email)
+ self.assertEquals(person.user, self.user.user)
+
+ # check that the confirmation has been marked as inactive. We
+ # need to reload the confirmation to check this.
+ conf = EmailConfirmation.objects.get(pk = self.conf.pk)
+ self.assertEquals(conf.active, False)
+
+class UserLoginRedirectTest(TestCase):
+
+ def testUserLoginRedirect(self):
+ url = '/user/'
+ response = self.client.get(url)
+ self.assertRedirects(response, settings.LOGIN_URL + '?next=' + url)
+
+class UserProfileTest(TestCase):
+
+ def setUp(self):
+ self.user = TestUser()
+ self.client.login(username = self.user.username,
+ password = self.user.password)
+
+ def testUserProfile(self):
+ response = self.client.get('/user/')
+ self.assertContains(response, 'User Profile: %s' % self.user.username)
+ self.assertContains(response, 'User Profile: %s' % self.user.username)
+
+ def testUserProfileNoBundles(self):
+ response = self.client.get('/user/')
+ self.assertContains(response, 'You have no bundles')
+
+ def testUserProfileBundles(self):
+ project = defaults.project
+ project.save()
+
+ bundle = Bundle(project = project, name = 'test-1',
+ owner = self.user.user)
+ bundle.save()
+
+ response = self.client.get('/user/')
+
+ self.assertContains(response, 'You have the following bundle')
+ self.assertContains(response, bundle.get_absolute_url())
+
+class UserPasswordChangeTest(TestCase):
+ form_url = reverse('django.contrib.auth.views.password_change')
+ done_url = reverse('django.contrib.auth.views.password_change_done')
+
+ def testPasswordChangeForm(self):
+ self.user = TestUser()
+ self.client.login(username = self.user.username,
+ password = self.user.password)
+
+ response = self.client.get(self.form_url)
+ self.assertContains(response, 'Change my password')
+
+ def testPasswordChange(self):
+ self.user = TestUser()
+ self.client.login(username = self.user.username,
+ password = self.user.password)
+
+ old_password = self.user.password
+ new_password = User.objects.make_random_password()
+
+ data = {
+ 'old_password': old_password,
+ 'new_password1': new_password,
+ 'new_password2': new_password,
+ }
+
+ response = self.client.post(self.form_url, data)
+ self.assertRedirects(response, self.done_url)
+
+ user = User.objects.get(id = self.user.user.id)
+
+ self.assertFalse(user.check_password(old_password))
+ self.assertTrue(user.check_password(new_password))
+
+ response = self.client.get(self.done_url)
+ self.assertContains(response,
+ "Your password has been changed sucessfully")
diff --git a/patchwork/tests/test_xmlrpc.py b/patchwork/tests/test_xmlrpc.py
new file mode 100644
index 0000000..2b459b2
--- /dev/null
+++ b/patchwork/tests/test_xmlrpc.py
@@ -0,0 +1,55 @@
+# Patchwork - automated patch tracking system
+# Copyright (C) 2014 Jeremy Kerr <jk@ozlabs.org>
+#
+# This file is part of the Patchwork package.
+#
+# Patchwork is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# Patchwork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Patchwork; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import unittest
+import xmlrpclib
+from django.test import LiveServerTestCase
+from django.core.urlresolvers import reverse
+from django.conf import settings
+from patchwork.models import Person, Patch
+from patchwork.tests.utils import defaults
+
+@unittest.skipUnless(settings.ENABLE_XMLRPC,
+ "requires xmlrpc interface (use the ENABLE_XMLRPC setting)")
+class XMLRPCTest(LiveServerTestCase):
+
+ def setUp(self):
+ settings.STATIC_URL = '/'
+ self.url = (self.live_server_url +
+ reverse('patchwork.views.xmlrpc.xmlrpc'))
+ self.rpc = xmlrpclib.Server(self.url)
+
+ def testGetRedirect(self):
+ response = self.client.get(self.url)
+ self.assertRedirects(response,
+ reverse('patchwork.views.help',
+ kwargs = {'path': 'pwclient/'}))
+
+ def testList(self):
+ defaults.project.save()
+ defaults.patch_author_person.save()
+ patch = Patch(project = defaults.project,
+ submitter = defaults.patch_author_person,
+ msgid = defaults.patch_name,
+ content = defaults.patch)
+ patch.save()
+
+ patches = self.rpc.patch_list()
+ self.assertEqual(len(patches), 1)
+ self.assertEqual(patches[0]['id'], patch.id)
diff --git a/patchwork/tests/utils.py b/patchwork/tests/utils.py
new file mode 100644
index 0000000..782ed36
--- /dev/null
+++ b/patchwork/tests/utils.py
@@ -0,0 +1,138 @@
+# Patchwork - automated patch tracking system
+# Copyright (C) 2008 Jeremy Kerr <jk@ozlabs.org>
+#
+# This file is part of the Patchwork package.
+#
+# Patchwork is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# Patchwork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Patchwork; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import os
+import codecs
+from patchwork.models import Project, Person
+from django.contrib.auth.models import User
+from django.forms.fields import EmailField
+
+from email import message_from_file
+try:
+ from email.mime.text import MIMEText
+ from email.mime.multipart import MIMEMultipart
+except ImportError:
+ # Python 2.4 compatibility
+ from email.MIMEText import MIMEText
+ from email.MIMEMultipart import MIMEMultipart
+
+# helper functions for tests
+_test_mail_dir = os.path.join(os.path.dirname(__file__), 'mail')
+_test_patch_dir = os.path.join(os.path.dirname(__file__), 'patches')
+
+class defaults(object):
+ project = Project(linkname = 'test-project', name = 'Test Project',
+ listid = 'test.example.com')
+
+ patch_author = 'Patch Author <patch-author@example.com>'
+ patch_author_person = Person(name = 'Patch Author',
+ email = 'patch-author@example.com')
+
+ comment_author = 'Comment Author <comment-author@example.com>'
+
+ sender = 'Test Author <test-author@example.com>'
+
+ subject = 'Test Subject'
+
+ patch_name = 'Test Patch'
+
+ patch = """--- /dev/null 2011-01-01 00:00:00.000000000 +0800
++++ a 2011-01-01 00:00:00.000000000 +0800
+@@ -0,0 +1 @@
++a
+"""
+
+error_strings = {
+ 'email': 'Enter a valid email address.',
+}
+
+_user_idx = 1
+def create_user():
+ global _user_idx
+ userid = 'test%d' % _user_idx
+ email = '%s@example.com' % userid
+ _user_idx += 1
+
+ user = User.objects.create_user(userid, email, userid)
+ user.save()
+
+ person = Person(email = email, name = userid, user = user)
+ person.save()
+
+ return user
+
+def create_maintainer(project):
+ user = create_user()
+ profile = user.profile
+ profile.maintainer_projects.add(project)
+ profile.save()
+ return user
+
+def find_in_context(context, key):
+ if isinstance(context, list):
+ for c in context:
+ v = find_in_context(c, key)
+ if v is not None:
+ return v
+ else:
+ if key in context:
+ return context[key]
+ return None
+
+def read_patch(filename, encoding = None):
+ file_path = os.path.join(_test_patch_dir, filename)
+ if encoding is not None:
+ f = codecs.open(file_path, encoding = encoding)
+ else:
+ f = file(file_path)
+
+ return f.read()
+
+def read_mail(filename, project = None):
+ file_path = os.path.join(_test_mail_dir, filename)
+ mail = message_from_file(open(file_path))
+ if project is not None:
+ mail['List-Id'] = project.listid
+ return mail
+
+def create_email(content, subject = None, sender = None, multipart = False,
+ project = None, content_encoding = None):
+ if subject is None:
+ subject = defaults.subject
+ if sender is None:
+ sender = defaults.sender
+ if project is None:
+ project = defaults.project
+ if content_encoding is None:
+ content_encoding = 'us-ascii'
+
+ if multipart:
+ msg = MIMEMultipart()
+ body = MIMEText(content, _subtype = 'plain',
+ _charset = content_encoding)
+ msg.attach(body)
+ else:
+ msg = MIMEText(content, _charset = content_encoding)
+
+ msg['Subject'] = subject
+ msg['From'] = sender
+ msg['List-Id'] = project.listid
+
+
+ return msg