subtree updates
meta-raspberrypi: fde68b24f0..4c033eb074:
Harunobu Kurokawa (1):
rpi-cmdline, rpi-u-boot-src: Support USB boot
meta-arm: 0b61cc659a..4d22f982bc:
Debbie Martin (2):
arm-systemready: Add parted dependency and inherit testimage
ci: Add Arm SystemReady firmware and IR ACS builds
Harsimran Singh Tungal (3):
arm-bsp/documentation: corstone1000: fix the steps in the user guide and instructions
corstone1000:arm-bsp/optee: Update optee to v4.0
corstone1000:arm-bsp/tftf: Fix tftf tests on mps3
Jon Mason (5):
arm/trusted-firmware-a: move patch file to bbappend
arm/trusted-firmware-a: update to 2.10
arm/hafnium: update to v2.10
CI: rename meta-secure-core directory
arm/edk2: update to 202311
Ross Burton (1):
CI: switch back to master
poky: 028b6f6226..4675bbb757:
Adrian Freihofer (4):
cmake-qemu.bbclass: make it more usable
oe-selftest: add a cpp-example recipe
oeqa/core/decorator: add skip if not qemu-usermode
oe-selftest: add tests for C and C++ build tools
Alassane Yattara (22):
bitbake: toaster/test: bug-fix on tests/browser/test_all_builds_page
bitbake: toaster/test: from test_no_builds_message.py wait for the empty state div to appear
bitbake: toaster/test: delay driver action until elements to appear
bitbake: toaster/tests: Ensure to kill toaster process create for tests functional
bitbake: toaster/tests: Added functional/utils, contains useful methods using by functional tests
bitbake: toaster/tests: Refactorize tests/functional
bitbake: toaster/tests: Bug fixes, functional tests dependent on each other
bitbake: toaster/tests: Fixes warnings in autobuilder
bitbake: toaster/tests: bug-fix tests writing files into /tmp on the autobuilders
bitbake: toaster/test: fix Copyright
bitbake: toaster/tests: logging warning in console, trying to kill unavailable Runbuilds process
bitbake: toaster/tests: Removed all time.sleep occurrence
bitbake: toaster/tests: Bug-Fix testcase functional/test_project_page_tab_config.py
bitbake: toaster/tests: bug-fix element click intercepted in browser/test_layerdetails_page.py
bitbake: toaster/tests: Update tests/functional/functional_helpers test_functional_basic
bitbake: toaster/tests: Fixes functional tests warning on autobuilder
bitbake: toaster/tests: Bug-fix test_functional_basic, delay driver actions
bitbake: toaster/tests: bug-fix An element matching "#projectstable" should be visible
bitbake: toaster/tests: bug-fix An element matching "#lastest_builds" should be on the page
bitbake: toaster/tests: Skip to show more then 100 item in ToasterTable
bitbake: toaster/tests: Bug-fix "#project-created-notification" should be visible
bitbake: toaster/toastergui: Bug-fix verify given layer path only if import/add local layer
Alex Bennée (1):
qemurunner: more cleanups for output blocking
Alex Kiernan (17):
cargo: Rename MANIFEST_PATH -> CARGO_MANIFEST_PATH
cargo: Move CARGO_MANIFEST_PATH/CARGO_SRC_DIR to cargo_common
rust: cargo: Convert single-valued variables to weak defaults
cargo: Add CARGO_LOCK_PATH for path to Cargo.lock
rust: Upgrade 1.70.0 -> 1.71.0
rust: Upgrade 1.71.0 -> 1.71.1
sstate-cache-management: Rewrite in python
devtool: selftest: Fix test_devtool_modify_git_crates_subpath inequality
devtool: selftest: Fix test_devtool_modify_git_crates_subpath bbappend check
meta-selftest: hello-rs: Simple rust test recipe
devtool: selftest: Swap to hello-rs for crates testing
zvariant: Drop recipe
rust: Upgrade 1.71.1 -> 1.72.0
rust: Upgrade 1.72.0 -> 1.72.1
rust: Upgrade 1.72.1 -> 1.73.0
rust: Upgrade 1.73.0 -> 1.74.0
rust: Upgrade 1.74.0 -> 1.74.1
Alexander Kanavin (21):
selftest/sstatetest: print output from bitbake with actual newlines, not \n
selftest/sstatetests: do not delete custom $TMPDIRs under build-st when testing printdiff
sstatesig/find_siginfo: special-case gcc-source when looking in sstate caches
oeqa/selftest/sstatetests: re-work CDN tests, add local cache tests
gobject-introspection: depend on setuptools to obtain distutils module
libcap-ng-python: depend on setuptools to obtain distutils copy
dnf: remove obsolete python3-gpg dependency (provided by gpgme)
gpgme: disable python support (until upstream fixes 3.12 compatibility)
python3-setuptools-rust: remove distutils dependency
python3-babel: replace distutils with setuptools, as supported by upstream
python3-pip: remove distutils depedency
glib-2.0: replace distutils dependency with setuptools
python3-pytest-runner: remove distutils dependency
python3-numpy: distutils is no longer required
bitbake: bitbake/codeparser.py: address ast module deprecations in py 3.12
glibc-y2038-tests: do not run tests using 32 bit time APIs
bitbake: bitbake/runqueue: add debugging for find_siginfo() calls
bitbake: bitbake-diffsigs/runqueue: adapt to reworked find_siginfo()
bitbake: bitbake/runqueue: prioritize local stamps over sstate signatures in printdiff
sstatesig/find_siginfo: unify a disjointed API
lib/sstatesig/find_siginfo: raise an error instead of returning None when obtaining mtime
Alexander Lussier-Cullen (6):
bitbake: toaster: fix pytest build test execution and test discovery
bitbake: toaster: Add verbose printout for missing chrome(driver) dependencies
bitbake: bitbake: toaster: add functional testing toaster error details
bitbake: toaster/tests: Exit tests on chromedriver creation failure
bitbake: toaster/tests: fix functional tests setup and teardown
bitbake: toaster/tests: fix chrome argument syntax and wait for driver exit
Alexandre Belloni (1):
oeqa/selftest/recipetool: stop looking for md5sum
Anuj Mittal (9):
sqlite3: upgrade 3.44.0 -> 3.44.2
base-passwd: upgrade 3.6.2 -> 3.6.3
bluez5: upgrade 5.70 -> 5.71
glib-2.0: upgrade 2.78.1 -> 2.78.3
glib-networking: upgrade 2.76.1 -> 2.78.0
puzzles: upgrade to latest revision
stress-ng: upgrade 0.17.01 -> 0.17.03
libusb1: fix upstream version check
enchant2: upgrade 2.6.2 -> 2.6.4
Archana Polampalli (1):
bluez5: fix CVE-2023-45866
Bruce Ashfield (31):
linux-yocto/6.5: cfg: split runtime and symbol debug
linux-yocto/6.5: update to v6.5.11
linux-yocto/6.1: update to v6.1.62
linux-yocto-dev: bump to v6.7
linux-yocto/6.5: update to v6.5.12
linux-yocto/6.5: update to v6.5.13
linux-yocto/6.1: update to v6.1.65
linux-yocto/6.1: drop removed IMA option
linux-yocto/6.5: drop removed IMA option
linux-yocto-rt/6.1: update to -rt18
linux-yocto/6.1: update to v6.1.66
linux-yocto/6.1: update to v6.1.67
linux-yocto/6.5: fix AB-INT: QEMU kernel panic: No irq handler for vector
linux-yocto/6.1: update to v6.1.68
oeqa/runtime/parselogs: add qemux86 ACPI ignore for kernel v6.6+
linux-libc-headers: update to v6.6-lts
linux-yocto: introduce 6.6 reference kernel
linux-yocto/6.6: fix AB-INT: QEMU kernel panic: No irq handler for vector
linux-yocto-rt/6.6: fix CVE exclusion include
linux-yocto/6.6: update CVE exclusions
linux-yocto/6.6: update to v6.6.8
linux-yocto/6.1: update to v6.1.69
linux-yocto/6.5: drop 6.5 recipes
linux-yocto-rt/6.6: correct meta data branch
linux-yocto/6.6: update to v6.6.9
linux-yocto/6.6: update CVE exclusions
linux-yocto/6.1: update to v6.1.70
linux-yocto/6.1: update CVE exclusions
linux-yocto/6.6: ARM fix configuration audit warning
linux-yocto/6.6: arm: jitter entropy backport
poky/poky-tiny: make 6.6 the default kernel
Changqing Li (1):
man-pages: remove conflict pages
Chen Qi (1):
devtool: use straight print in check-upgrade-status output
Clay Chang (1):
devtool: deploy: provide max_process to strip_execs
Daniel Ammann (1):
base: Unpack .7z files with p7zip
Deepthi Hemraj (1):
autoconf: Add missing perl modules to RDEPENDS
Dhairya Nagodra (2):
cve-update-nvd2-native: faster requests with API keys
cve-update-nvd2-native: increase the delay between subsequent request failures
Eilís 'pidge' Ní Fhlannagáin (3):
useradd: Fix issues with useradd dependencies
useradd: Add testcase for bugzilla issue (currently disabled)
usergrouptests.py: Add test for switching between static-ids
Enrico Scholz (1):
tcp-wrappers: drop libnsl2 build dependency
Etienne Cordonnier (2):
gdb/systemd: enable minidebuginfo support conditionally
manuals: document minidebuginfo
Fabio Estevam (3):
libdrm: Upgrade to 2.4.119
kmscube: Upgrade to latest revision
bmap-tools: Upgrade to 3.7
Hongxu Jia (2):
socat: 1.7.4.4 -> 1.8.0.0
man-db: 2.11.2 -> 2.12.0
Jason Andryuk (3):
linux-firmware: Package iwlwifi .pnvm files
linux-firmware: Change bnx2 packaging
linux-firmware: Create bnx2x subpackage
Jeremy A. Puhlman (1):
create-spdx-2.2: combine spdx can try to write before dir creation
Jermain Horsman (2):
lib/bblayers/makesetup.py: Remove unused imports
lib/bblayers/buildconf.py: Remove unused imports/variables
Jose Quaresma (2):
go: update 1.20.10 -> 1.20.11
go: update 1.20.11 -> 1.20.12
Joshua Watt (11):
bitbake: bitbake-hashserv: Add description of permissions
bitbake.conf: Add runtimedir
rpcbind: Specify state directory under /run
libinput: Add packageconfig for tests
ipk: Switch to using zstd compression
lib/oe/path.py: Add relsymlink()
lib/packagedata.py: Fix broken symlinks for providers with a '/'
bitbake: contrib/vim: Syntax improvements
classes-global/sstate: Fix variable typo
lib/packagedata.py: Add API to iterate over rprovides
classes-global/insane: Look up all runtime providers for file-rdeps
Julien Stephan (19):
recipetool: create_buildsys_python.py: initialize metadata
recipetool: create: add trailing newlines
recipetool: create: add new optional process_url callback for plugins
recipetool: create_buildsys_python: add pypi support
oeqa/selftest/recipetool: remove spaces on empty lines
oeqa/selftest/recipetool/devtool: add test for pypi class
recipetool: appendsrcfile(s): add dry-run mode
recipeutils: bbappend_recipe: fix undefined variable
recipeutils: bbappend_recipe: fix docstring
recipeutils: bbappend_recipe: add a way to specify the name of the file to add
recipeutils: bbappend_recipe: remove old srcuri entry if parameters are different
recipetool: appendsrcfile(s): use params instead of extraline
recipeutils: bbappend_recipe: allow to patch the recipe itself
recipetool: appendsrcfile(s): add a mode to update the recipe itself
oeqa/selftest/recipetool: appendsrfile: add test for machine
oeqa/selftest/recipetool: appendsrc: add test for update mode
oeqa/selftest/recipetool: add back checksum checks on pypi tests
oeqa/selftest/recipetool: remove left over from development
oeqa/selftest/recipetool: fix metadata corruption on meta layer
Kevin Hao (2):
beaglebone-yocto: Remove the redundant kernel-devicetree
beaglebone-yocto: Remove the obsolete variables for uImage
Khem Raj (13):
tiff: Backport fixes for CVE-2023-6277
kmod: Fix build with latest musl
elfutils: Use own basename API implementation
util-linux: Fix build with latest musl
sysvinit: Include libgen.h for basename API
attr: Fix build with latest musl
opkg: Use own version of portable basename function
util-linux: Delete md-raid tests
gdb: Update to gdb 14.1 release
systemd: Fix build with latest musl
qemu: Fix build with latest musl
qemu: Add packageconfig knob to enable pipewire support
weston: Include libgen.h for basename
Lee Chee Yang (5):
migration-guides: reword fix in release-notes-4.3.1
migration-guides: add release notes for 4.0.15
perlcross: update to 1.5.2
perl: 5.38.0 -> 5.38.2
curl: update to 8.5.0
Lucas Stach (1):
mesa: upgrade 23.2.1 -> 23.3.1
Ludovic Jozeau (1):
image-live.bbclass: LIVE_ROOTFS_TYPE support compression
Lukas Funke (1):
selftest: wic: add test for zerorize option of empty plugin
Malte Schmidt (1):
wic: extend empty plugin with options to write zeros to partiton
Markus Volk (3):
gtk4: upgrade 4.12.3 -> 4.12.4
libadwaita: update 1.4.0 -> 1.4.2
appstream: Upgrade 0.16.3 -> 1.0.0
Marlon Rodriguez Garcia (5):
bitbake: toaster/tests: Update build test
bitbake: toaster: Added new feature to import eventlogs from command line into toaster using replay functionality
bitbake: toaster: remove test and update setup to avoid rebuilding image
bitbake: toaster: Commandline build import table improvements
bitbake: toaster: Added validation to stop import if there is a build in progress
Marta Rybczynska (1):
bitbake: toastergui: verify that an existing layer path is given
Massimiliano Minella (1):
zstd: fix LICENSE statement
Michael Opdenacker (8):
test-manual: text and formatting fixes
test-manual: resource updates
test-manual: use working example
test-manual: add links to python unittest
test-manual: explicit or fix file paths
test-manual: add or improve hyperlinks
dev-manual: runtime-testing: fix test module name
poky.conf: update SANITY_TESTED_DISTROS to match autobuilder
Mikko Rapeli (1):
runqemu: match .rootfs. in addition to -image- for rootfs
Ming Liu (1):
grub: fs/fat: Don't error when mtime is 0
Mingli Yu (2):
python3-license-expression: Fix the ptest failure
ptest-packagelists.inc: Add python3-license-expression
Pavel Zhukov (2):
bitbake: utils: Do not create directories with ${ in the name
oeqa/selftest/bbtests: Add test for unexpanded variables in the dirname
Peter Kjellerstedt (11):
oeqa/selftest/devtool: Correct git clone of local repository
oeqa/selftest/devtool: Avoid global Git hooks when amending a patch
oeqa/selftest/devtool: Make test_devtool_load_plugin more resilient
oeqa/selftest/recipetool: Make test_recipetool_load_plugin more resilient
lib/oe/recipeutils: Avoid wrapping any SRC_URI[sha*sum] variables
recipetool: create: Improve identification of licenses
recipetool: create: Only include the expected SRC_URI checksums
devtool: upgrade: Update all existing checksums for the SRC_URI
devtool: modify: Make --no-extract work again
devtool: modify: Handle recipes with a menuconfig task correctly
dev-manual: Discourage the use of SRC_URI[md5sum]
Peter Marko (1):
dtc: preserve version also from shallow git clones
Philip Balister (1):
sanity.bbclass: Check for additional native perl modules.
Renat Khalikov (1):
python3-maturin: Add missing space appending to CFLAGS
Richard Purdie (41):
bitbake: runqueue: Improve inter setscene task dependency handling
bitbake: bb/toaster: Fix assertEquals deprecation warnings
bitbake: toaster: Fix assertRegexpMatches deprecation warnings
bitbake: toastermain/settings: Avoid python filehandle closure warnings
bitbake: toastergui: Fix regex markup issues
bitbake: bitbake: Move to version 2.6.1 to mark runqueue changes
bitbake: toaster-eventreplay: Remove ordering assumptions
sanity.conf: Require bitbake 2.6.1 for recent runqueue change
sstate: Remove unneeded code from setscene_depvalid() related to useradd
oeqa/runtime/systemd: Ensure test runs only on systemd images
bitbake: toaster: Update to use qemux86-64 machine by default
bitbake: toaster/tests/builds: Add BB_HASHSERVE passthrough
pseudo: Update to pull in syncfs probe fix
useradd: Fix useradd do_populate_sysroot dependency bug
sstate: Fix dir ownership issues in SSTATE_DIR
oeqa/sstatetests: Disable gcc source printdiff test for now
build-appliance-image: Update to master head revision
bitbake: utils: Fix mkdir with PosixPath
bitbake: runqueue: Remove tie between rqexe and starts_worker
build-appliance-image: Update to master head revision
testimage: Exclude wtmp from target-dumper commands
qemurunner: Improve stdout logging handling
qemurunner: Improve handling of serial port output blocking
oeqa/selftest/overlayfs: Don't overwrite DISTRO_FEATURES
testimage: Drop target_dumper and most of monitor_dumper
oeqa/selftest/overlayfs: Fix whitespace
qemu: Clean up DEPENDS
qemu: Ensure pip and the python venv aren't used for meson
curl: Disable two intermittently failing tests
linux/cve-exclusion6.1: Update to latest kernel point release
lib/prservice: Improve lock handling robustness
oeqa/selftest/prservice: Improve test robustness
scripts: Drop shell sstate-cache-management
oeqa/selftest/sstatetests: Update sstate management script tests to python script
curl: Disable test 1091 due to intermittent failures
bitbake: lib/bb: Add workaround for libgcc issues with python 3.8 and 3.9
bitbake: bitbake: Post release version bump to 2.7.0
bitbake: siggen: Ensure version of siggen is verified
bitbake: bitbake: Version bump for find_siginfo chanages
sstatesig: Add version information for find_sigingfo
sanity: Require bitbake 2.7.1
Robert Berger (1):
uninative-tarball.xz - reproducibility fix
Robert Yang (5):
gettext: Upgrade 0.22.3 -> 0.22.4
nfs-utils: Upgrade 2.6.3 -> 2.6.4
archiver.bbclass: Improve work-shared checking
nfs-utils: Update Upstream-Status
archiver.bbclass: Drop tarfile module to improve performance
Ross Burton (23):
avahi: update URL for new project location
oeqa/runtime/parselogs: load ignores from disk
oeqa/runtime/parselogs: migrate ignores
meta-yocto-bsp/oeqa/parselogs: add BSP-specific ignores
linux-yocto: update CVE exclusions
genericx86: remove redundant assignments
images: remove redundant IMAGE_BASENAME assignments
insane: ensure more paths have the workdir removed
tcl: skip timing-dependent tests in run-ptest
qemurunner: remove unused import
go: set vendor in CVE_PRODUCT
runqemu: add qmp socket support
linux-yocto: update CVE exclusions
tcl: skip async and event tests in run-ptest
images: add core-image-initramfs-boot
machine/arch-armv9: remove crc and sve tunes, they are mandatory
python3: re-enable profile guided optimisation
openssl: mark assembler sections as call targets for PAC/BTI support on aarch64
nativesdk: ensure features don't get backfilled
nativesdk: don't unset MACHINE_FEATURES, let machine-sdk/ set it
conf/machine-sdk: declare qemu-usermode SDK_MACHINE_FEATURE
libseccomp: remove redundant PV assignment
oeqa/parselogs-ignores-qemuarmv5: add comments and organise
Saul Wold (1):
package.py: OEHasPackage: Add MLPREFIX to packagename
Shubham Kulkarni (1):
tzdata: Upgrade to 2023d
Simone Weiß (2):
manuals: brief-yoctoprojectqs: align variable order with default local.conf
patchtest: Add test for deprecated CVE_CHECK_IGNORE
Soumya Sambu (1):
ncurses: Fix - tty is hung after reset
Sundeep KOKKONDA (1):
rust: rustdoc reproducibility issue fix - disable PGO
Tim Orling (12):
python3-bcrypt: upgrade 4.0.1 -> 4.1.1
python3-pygments: upgrade 2.16.1 -> 2.17.2
recipetool: pypi: do not clobber SRC_URI checksums
python3-setuptools-rust: BBCLASSEXTEND + nativesdk
python3-maturin: add v1.4.0
python3-maturin: bzip2-sys reproduciblility
classes-recipe: add python_maturin.bbclass
recipetool: add python_maturin support
oe-selfest: add maturn runtime (testimage) test
oeqa: add simple 'maturin' SDK (testsdk) test case
oeqa: add "maturin develop" SDK test case
oeqa: add runtime 'maturin develop' test case
Tom Rini (1):
inetutils: Update to the 2.5 release
Trevor Gamblin (1):
scripts/runqemu: fix regex escape sequences
Victor Kamensky (5):
systemtap: upgrade 4.9 -> 5.0
systemtap: do not install uprobes and uprobes sources
systemtap-uprobes: removed as obsolete
systemtap: explicit handling debuginfod library dependency
systemtap: fix libdebuginfod auto detection logic
Vijay Anusuri (1):
avahi: backport CVE-2023-1981 & CVE's follow-up patches
Viswanath Kraleti (2):
image-uefi.conf: Add EFI_UKI_PATH variable
systemd-boot: Add recipe to compile native
Wang Mingyu (38):
kbd: upgrade 2.6.3 -> 2.6.4
libatomic-ops: upgrade 7.8.0 -> 7.8.2
libnl: upgrade 3.8.0 -> 3.9.0
libseccomp: upgrade 2.5.4 -> 2.5.5
libva-utils: upgrade 2.20.0 -> 2.20.1
dnf: upgrade 4.18.1 -> 4.18.2
gpgme: upgrade 1.23.1 -> 1.23.2
kea: upgrade 2.4.0 -> 2.4.1
opkg-utils: upgrade 0.6.2 -> 0.6.3
repo: upgrade 2.39 -> 2.40
sysstat: upgrade 12.7.4 -> 12.7.5
p11-kit: upgrade 0.25.2 -> 0.25.3
python3-babel: upgrade 2.13.1 -> 2.14.0
python3-dbusmock: upgrade 0.29.1 -> 0.30.0
python3-hatchling: upgrade 1.18.0 -> 1.20.0
python3-hypothesis: upgrade 6.90.0 -> 6.92.1
python3-importlib-metadata: upgrade 6.8.0 -> 7.0.0
python3-license-expression: upgrade 30.1.1 -> 30.2.0
python3-pathspec: upgrade 0.11.2 -> 0.12.1
python3-pip: upgrade 23.3.1 -> 23.3.2
python3-psutil: upgrade 5.9.6 -> 5.9.7
python3-pytest-runner: upgrade 6.0.0 -> 6.0.1
python3-trove-classifiers: upgrade 2023.11.22 -> 2023.11.29
python3-typing-extensions: upgrade 4.8.0 -> 4.9.0
python3-wcwidth: upgrade 0.2.11 -> 0.2.12
ttyrun: upgrade 2.29.0 -> 2.30.0
xwayland: upgrade 23.2.2 -> 23.2.3
diffoscope: upgrade 252 -> 253
iputils: upgrade 20221126 -> 20231222
gstreamer1.0: upgrade 1.22.7 -> 1.22.8
dhcpcd: upgrade 10.0.5 -> 10.0.6
fontconfig: upgrade 2.14.2 -> 2.15.0
python3-setuptools: upgrade 69.0.2 -> 69.0.3
python3-dbusmock: upgrade 0.30.0 -> 0.30.1
python3-hatchling: upgrade 1.20.0 -> 1.21.0
python3-importlib-metadata: upgrade 7.0.0 -> 7.0.1
python3-lxml: upgrade 4.9.3 -> 4.9.4
aspell: upgrade 0.60.8 -> 0.60.8.1
Yash Shinde (1):
rust: Disable rust oe-selftest
Yi Zhao (3):
json-glib: upgrade 1.6.6 -> 1.8.0
psplash: upgrade to latest revision
debianutils: upgrade 5.14 -> 5.15
Yoann Congal (2):
lib/oe/patch: handle creating patches for CRLF sources
strace: Disable bluetooth support by default
Zang Ruochen (2):
ell: upgrade 0.60 -> 0.61
musl: add typedefs for Elf64_Relr and Elf32_Relr
Zoltan Boszormenyi (1):
update_gtk_icon_cache: Fix for GTK4-only builds
venkata pyla (1):
wic: use E2FSPROGS_FAKE_TIME and hash_seed to generate reproducible ext4 images
meta-openembedded: 5ad7203f68..7d8115d550:
Alex Kiernan (7):
mdns: Fix HOMEPAGE URL
mbedtls: Upgrade 3.5.0 -> 3.5.1
c-ares: Upgrade 1.22.1 -> 1.24.0
mdns: Upgrade 2200.40.37.0.1 -> 2200.60.25.0.4
c-ares: Move to tarballs, add ptest and static support
thin-provisioning-tools: Upgrade 1.0.4 -> 1.0.9
bearssl: Upgrade to latest
Alexander Kanavin (29):
python3-pyinotify: remove as unmaintained
python3-supervisor: do not rely on smtpd module
python3-meld3: do not rely on smtpd module
python3-m2crypto: do not rely on smtpd module
python3-uinput: remove as unmaintained
python3-mcrypto: rely on setuptools for distutils copy
python3-joblib: do not rely in distutils
python3-web3: remove distutils dependency
python3-cppy: remove unused distutils dependency
python3-pyroute2: remove unused distutils dependency
python3-eventlet: backport a patch to remove distutils dependency
python3-unoconv: rely on setuptools to obtain distutils copy
python3-astroid: remove unneeded distutils dependency
python3-django: remove unneeded distutils dependency
python3-pillow: remove unneeded distutils dependency
python3-grpcio: update 1.56.2 -> 1.59.3
gstd: correctly delete files in do_install
libplist: fix python 3.12 compatibility
libcamera: skip until upstream resolves python 3.12 compatibility
nodejs: backport (partially) python 3.12 support
nodejs: backport (partially) python 3.12 support
polkit: remove long obsolete 0.119 version
mozjs-115: split the way-too-long PYTHONPATH line
polkit: update mozjs dependency 102 -> 115
mozjs-115: backport py 3.12 compatibility
mozjs-102: remove the recipe
gthumb: update 3.12.2 -> 3.12.4
flatpak: do not rely on executables from the host
bolt: package systemd units
Archana Polampalli (1):
cjson: upgrade 1.7.16 -> 1.7.17
Bruce Ashfield (1):
zfs: update to 2.2.2
Changqing Li (2):
postgresql: upgrade 15.4 -> 15.5
redis: upgrade 6.2.13 -> 6.2.14
Derek Straka (70):
python3-greenlet: update to version 3.0.2
python3-ujson: update to version 5.9.0
python3-termcolor: update to version 2.4.0
python3-cmake: update to version 3.28.0
python3-pint: upgrade to 0.23
python3-gnupg: update to 0.5.2
python3-pyzmq: update to 25.1.2
python3-tox: update to version 4.11.4
python3-olefile: update to version 0.47
python3-distlib: update to version 0.3.8
python3-colorlog: update to version 6.8.0
python3-pymongo: update version to 4.6.1
python3-bandit: update to version 1.7.6
python3-gmqtt: update to version 0.6.13
python3-portion: update to version 2.4.2
python3-prompt-toolkit: update to version 3.0.43
python3-asyncinotify: update to version 4.0.4
python3-bitstring: update to version 4.1.4
python3-ipython: update to version 8.18.1
nginx: update versions for both the stable branch and mainline
python3-portalocker: update to version 2.8.2
python3-astroid: update to version 3.0.2
python3-alembic: update to version 1.13.1
python3-pymisp: update to verion 2.4.182
python3-ninja: update to version 1.11.1.1
python3-coverage: update to version 7.3.4
python3-pdm: update to version 2.11.1
python3-paramiko: update to version 3.4.0
python3-zeroconf: update to version 0.131.0
python3-wtforms: update to version 3.1.1
python3-isort: update to version 5.13.2
python3-protobuf: update to version 4.25.1
python3-lazy-object-proxy: update to version 1.10.0
python3-cantools: update to version 39.4.0
python3-sentry-sdk: update to version 1.39.1
python3-xmlschema: update to version 2.5.1
python3-apiflask: update to version 2.1.0
python3-rapidjson: update to version 1.14
python3-bitarray: update to version 2.9.0
python3-pyfanotify: update to version 0.2.2
python3-eventlet: update to version 0.34.1
python3-flask-wtf: update to version 1.2.1
python3-grpcio: update to version 1.60.0
python3-grpcio-tools: update to version 1.60.0
python3-cmake: update to version 3.28.1
python3-flask-sqlalchemy: fix upstream uri check
python3-wtforms: fix upstream uri and version check
gyp: update to the latest commit
python3-ipython-genutils: fix upstream uri and version check
python3-flask: fix upstream uri and version check
python3-wpa-supplicant: fix upstream uri and version check
python3-uswid: update to version 0.4.7
python3-flask-wtf: fix upstream uri and version check
python3-gspread: update to version 5.12.3
python3-pytest-html: update to version 4.1.1
python3-setuptools-scm-git-archive: remove obsolete package
python3-pyroute2: update to version 0.7.10
python3-constantly: update to version 23.10.4
python3-mypy: update to version 1.8.0
python3-flask-jwt-extended: update to version 4.6.0
python3-greenlet: update to version 3.0.3
python3-web3: update to version 6.13.0
python3-parse: update to version 1.20.0
python3-kmod: add comment about update to version 0.9.2
python3-engineio: update to version 4.8.1
python3-sqlalchemy: update to version 2.0.24
python3-pdm-backend: update to version 2.1.8
python3-cantools: update to version 39.4.1
python3-argh: update to version 0.30.5
python3-dominate: update to version 2.9.1
Dmitry Baryshkov (2):
android-tools: remove two Debianisms
networkmanager: drop libnewt dependency
Frederic Martinsons (3):
crash: factorize recipe with inc file to prepare cross-canadian version
crash: add cross canadian version
crash: update to 8.0.4
Jan Vermaete (1):
netdata: added Python as rdepends
Jean-Marc BOUCHE (1):
terminus-font: build compressed archives with -n
Jose Quaresma (1):
ostree: Upgrade 2023.7 -> 2023.8
Joshua Watt (1):
redis: Create state directory in systemd service
Jörg Sommer (1):
i2cdev: New recipe with i2c tools
Kai Kang (1):
lvm2: 2.03.16 -> 2.03.22
Khem Raj (3):
Revert "nodejs: backport (partially) python 3.12 support"
Revert "libcamera: skip until upstream resolves python 3.12 compatibility"
libcamera: Fix build with python 3.12
Leon Anavi (11):
sip: Upgrade 6.7.12 -> 6.8.0
python3-expandvars: add recipe
python3-frozenlist: upgrade 1.4.0 -> 1.4.1
python3-yarl: upgrade 1.9.2 -> 1.9.4
python3-coverage: upgrade 7.3.2 -> 7.3.3
python3-cycler: upgrade 0.11.0 -> 0.12.1
python3-aiohue: upgrade 4.6.2 -> 4.7.0
python3-sdbus: upgrade 0.11.0 -> 0.11.1
python3-zeroconf: upgrade 0.128.4 -> 0.130.0
python3-dominate: upgrade 2.8.0 -> 2.9.0
python3-rlp: upgrade 3.0.0 -> 4.0.0
Marek Vasut (1):
faad2: Upgrade 2.10.0 -> 2.11.1
Markus Volk (3):
wireplumber: update 0.4.15 -> 0.4.17
tracker: dont inherit gsettings
gnome-software: update 45.1 -> 45.2
Martin Jansa (4):
monocypher: pass LIBDIR to fix installed-vs-shipped QA issue with multilib
rygel: fix build with gtk+3 PACKAGECONFIG disabled
rygel: add x11 to DISTRO_FEATURES
driverctl: fix installed-vs-shipped
Meenali Gupta (1):
nginx: upgrade 1.25.2 -> 1.25.3
Mingli Yu (2):
mariadb: Upgrade to 10.11.6
tk: Remove buildpath issue
Nathan BRIENT (1):
cyaml: new recipe
Niko Mauno (1):
pkcs11-provider: Add recipe
Ny Antra Ranaivoarison (1):
python3-click-spinner: backport patch that fixes deprecated methods
Patrick Wicki (1):
poco: upgrade 1.12.4 -> 1.12.5p2
Petr Chernikov (1):
abseil-cpp: remove -Dcmake_cxx_standard=14 flag from extra_oecmake
Robert Yang (1):
minifi-cpp: Fix do_configure error builder aarch64
Ross Burton (13):
Remove unused SRC_DISTRIBUTE_LICENSES
gspell: inherit gtk-doc
gspell: update DEPENDS, switch iso-codes for icu
librest: remove spurious build dependencies
librest: inherit gtk-doc
keybinder: use autotools-brokensep instead of setting B
keybinder: disable gtk-doc documentation
gtksourceview3: remove obsolete DEPENDS
libgsf: remove obsolete DEPENDS
evolution-data-server: remove obsolete intltool DEPENDS
php: remove lemon-native build dependency
lemon: upgrade to 3.44.2
renderdoc: no need to depend on vim-native
Samuli Piippo (1):
jasper: enable opengl only wih x11
Theodore A. Roth (1):
python3-flask-sqlalchemy: upgrade 2.5.1 -> 3.1.1
Thomas Perrot (2):
networkmanager: add missing modemmanager rdepends
networkmanager: fix some missing pkgconfig
Tim Orling (8):
python3-pydantic-core: add v2.14.5
python3-annotated-types: add v0.6.0
python3-pydantic: fix RDEPENDS
python3-dirty-equals: add v0.7.1
python3-pydantic-core: enable ptest
python3-cloudpickle: add v3.0.0
python3-pydantic: enable ptest
python3-yappi: upgrade 1.4.0 -> 1.6.0; fix ptests
Wang Mingyu (61):
python3-alembic: upgrade 1.12.1 -> 1.13.0
python3-ansi2html: upgrade 1.8.0 -> 1.9.1
python3-argcomplete: upgrade 3.1.6 -> 3.2.1
python3-dbus-fast: upgrade 2.15.0 -> 2.21.0
python3-django: upgrade 4.2.7 -> 5.0
python3-flask-restx: upgrade 1.2.0 -> 1.3.0
python3-google-api-core: upgrade 2.14.0 -> 2.15.0
python3-google-api-python-client: upgrade 2.108.0 -> 2.111.0
python3-googleapis-common-protos: upgrade 1.61.0 -> 1.62.0
python3-google-auth: upgrade 2.23.4 -> 2.25.2
python3-imageio: upgrade 2.33.0 -> 2.33.1
python3-isort: upgrade 5.12.0 -> 5.13.1
python3-path: upgrade 16.7.1 -> 16.9.0
python3-platformdirs: upgrade 4.0.0 -> 4.1.0
python3-pytest-asyncio: upgrade 0.22.0 -> 0.23.2
python3-sentry-sdk: upgrade 1.37.1 -> 1.39.0
python3-bitarray: upgrade 2.8.3 -> 2.8.5
python3-eth-keyfile: upgrade 0.6.1 -> 0.7.0
python3-eth-rlp: upgrade 0.3.0 -> 1.0.0
python3-fastnumbers: upgrade 5.0.1 -> 5.1.0
python3-pylint: upgrade 3.0.2 -> 3.0.3
python3-tornado: upgrade 6.3.3 -> 6.4
python3-traitlets: upgrade 5.13.0 -> 5.14.0
python3-types-setuptools: upgrade 68.2.0.2 -> 69.0.0.0
python3-virtualenv: upgrade 20.24.7 -> 20.25.0
python3-web3: upgrade 6.11.3 -> 6.12.0
python3-websocket-client: upgrade 1.6.4 -> 1.7.0
python3-zeroconf: upgrade 0.127.0 -> 0.128.4
ctags: upgrade 6.0.20231126.0 -> 6.0.20231210.0
gensio: upgrade 2.8.0 -> 2.8.2
hwdata: upgrade 0.376 -> 0.377
lvgl: upgrade 8.3.10 -> 8.3.11
gjs: upgrade 1.78.0 -> 1.78.1
ifenslave: upgrade 2.13 -> 2.14
libei: upgrade 1.1.0 -> 1.2.0
pkcs11-helper: upgrade 1.29.0 -> 1.30.0
strongswan: upgrade 5.9.12 -> 5.9.13
webkitgtk3: upgrade 2.42.2 -> 2.42.3
sip: upgrade 6.8.0 -> 6.8.1
paho-mqtt-cpp: upgrade 1.3.1 -> 1.3.2
dbus-cxx: upgrade 2.4.0 -> 2.5.0
exiftool: upgrade 12.70 -> 12.71
uftp: upgrade 5.0.2 -> 5.0.3
ctags: upgrade 6.0.20231210.0 -> 6.0.20231224.0
jasper: Fix install conflict when enable multilib.
jq: upgrade 1.7 -> 1.7.1
libmbim: upgrade 1.31.1 -> 1.31.2
libqmi: upgrade 1.34.0 -> 1.35.1
opencl-headers: upgrade 2023.04.17 -> 2023.12.14
valijson: upgrade 1.0.1 -> 1.0.2
python3-apispec: upgrade 6.3.0 -> 6.3.1
python3-asyncinotify: upgrade 4.0.4 -> 4.0.5
python3-bitarray: upgrade 2.9.0 -> 2.9.1
python3-cassandra-driver: upgrade 3.28.0 -> 3.29.0
python3-ipython: upgrade 8.18.1 -> 8.19.0
python3-pydantic: upgrade 2.5.2 -> 2.5.3
python3-regex: upgrade 2023.10.3 -> 2023.12.25
opencl-icd-loader: upgrade 2023.04.17 -> 2023.12.14
python3-distro: upgrade 1.8.0 -> 1.9.0
zchunk: upgrade 1.3.2 -> 1.4.0
python3-eventlet: upgrade 0.34.1 -> 0.34.2
William Lyu (1):
networkmanager: Improved SUMMARY and added DESCRIPTION
Xiangyu Chen (1):
layer.conf: add libbpf to NON_MULTILIB_RECIPES
Yi Zhao (2):
open-vm-tools: upgrade 12.1.5 -> 12.3.5
samba: upgrade 4.18.8 -> 4.18.9
Zoltán Böszörményi (2):
mutter: Make gnome-desktop and libcanberra dependencies optional
zenity: Upgrade to 4.0.0
alperak (29):
jasper: upgrade 2.0.33 -> 4.1.1
xcursorgen: upgrade 1.0.7 -> 1.0.8
xstdcmap: upgrade 1.0.4 -> 1.0.5
xlsclients: upgrade 1.1.4 -> 1.1.5
xlsatoms: upgrade 1.1.3 -> 1.1.4
xkbevd: upgrade 1.1.4 -> 1.1.5
xgamma: upgrade 1.0.6 -> 1.0.7
sessreg: upgrade 1.1.2 -> 1.1.3
xbitmaps: upgrade 1.1.2 -> 1.1.3
xcursor-themes: add recipe
xorg-docs: add recipe
xorg-sgml-doctools: update summary depends and inc file
xf86-video-ati: upgrade 19.1.0 -> 22.0.0
xf86-input-void: upgrade 1.4.1 -> 1.4.2
libxaw: upgrade 1.0.14 -> 1.0.15
xf86-video-mga: upgrade 2.0.0 -> 2.0.1
snappy: upgrade 1.1.9 -> 1.1.10
xsetroot: upgrade 1.1.2 -> 1.1.3
libbytesize: Removed unnecessary setting of B
libmxml: use autotools-brokensep instead of setting B
libsombok3: use autotools-brokensep instead of setting B
pgpool2: use autotools-brokensep instead of setting B
qpdf: upgrade 11.6.3 -> 11.6.4
cpprest: upgrade 2.10.18 -> 2.10.19
avro-c: upgrade 1.11.2 -> 1.11.3
dool: upgrade 1.1.0 -> 1.3.1
driverctl: upgrade 0.111 -> 0.115
hstr: upgrade 2.5.0 -> 3.1.0
libharu: upgrade 2.3.0 -> 2.4.4
meta-security: 070a1e82cc..b2e1511338:
Armin Kuster (6):
libgssglue: update to 0.8
python3-privacyidea: Update to 3.9.1
lynis: Update SRC_URI to improve updater
layers: Move READMEs to markdown format
arpwatch: adjust CONFIGURE params to allow to build again.
python3-pyinotify: fail2ban needs this module
Dawid Dabrowski (1):
libhoth recipe update
Erik Schilling (2):
dm-verity-img.bbclass: use bc-native
dm-verity-img.bbclass: remove IMAGE_NAME_SUFFIX
Mikko Rapeli (2):
tpm2-tss: support native builds
dm-verity-img.bbclass: add DM_VERITY_DEPLOY_DIR
Change-Id: I94d7f1ee5ff2da4555c05fbf63a1293ec8f249c2
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
diff --git a/meta-openembedded/meta-python/recipes-devtools/python/python3-yappi/0001-test_functionality-convert-line-endings-to-Unix.patch b/meta-openembedded/meta-python/recipes-devtools/python/python3-yappi/0001-test_functionality-convert-line-endings-to-Unix.patch
new file mode 100644
index 0000000..70d4607
--- /dev/null
+++ b/meta-openembedded/meta-python/recipes-devtools/python/python3-yappi/0001-test_functionality-convert-line-endings-to-Unix.patch
@@ -0,0 +1,3845 @@
+From 0136ca731cba8b056b3f2ff0e7df3953b94f1e87 Mon Sep 17 00:00:00 2001
+From: Tim Orling <tim.orling@konsulko.com>
+Date: Sun, 24 Dec 2023 09:41:57 -0800
+Subject: [PATCH 1/2] test_functionality: convert line endings to Unix
+
+Convert the Windows line endings with dos2unix to be like the
+other files in tests/*
+
+Upstream-Status: Submitted [https://github.com/sumerc/yappi/pull/164]
+
+Signed-off-by: Tim Orling <tim.orling@konsulko.com>
+---
+ tests/test_functionality.py | 3822 +++++++++++++++++------------------
+ 1 file changed, 1911 insertions(+), 1911 deletions(-)
+
+diff --git a/tests/test_functionality.py b/tests/test_functionality.py
+index 0e99c47..38bbe67 100644
+--- a/tests/test_functionality.py
++++ b/tests/test_functionality.py
+@@ -1,1911 +1,1911 @@
+-import os
+-import sys
+-import time
+-import threading
+-import unittest
+-import yappi
+-import _yappi
+-import utils
+-import multiprocessing
+-import subprocess
+-
+-_counter = 0
+-
+-
+-class BasicUsage(utils.YappiUnitTestCase):
+-
+- def test_callback_function_int_return_overflow(self):
+- # this test is just here to check if any errors are generated, as the err
+- # is printed in C side, I did not include it here. THere are ways to test
+- # this deterministically, I did not bother
+- import ctypes
+-
+- def _unsigned_overflow_margin():
+- return 2**(ctypes.sizeof(ctypes.c_void_p) * 8) - 1
+-
+- def foo():
+- pass
+-
+- #with utils.captured_output() as (out, err):
+- yappi.set_context_id_callback(_unsigned_overflow_margin)
+- yappi.set_tag_callback(_unsigned_overflow_margin)
+- yappi.start()
+- foo()
+-
+- def test_issue60(self):
+-
+- def foo():
+- buf = bytearray()
+- buf += b't' * 200
+- view = memoryview(buf)[10:]
+- view = view.tobytes()
+- del buf[:10] # this throws exception
+- return view
+-
+- yappi.start(builtins=True)
+- foo()
+- self.assertTrue(
+- len(
+- yappi.get_func_stats(
+- filter_callback=lambda x: yappi.
+- func_matches(x, [memoryview.tobytes])
+- )
+- ) > 0
+- )
+- yappi.stop()
+-
+- def test_issue54(self):
+-
+- def _tag_cbk():
+- global _counter
+- _counter += 1
+- return _counter
+-
+- def a():
+- pass
+-
+- def b():
+- pass
+-
+- yappi.set_tag_callback(_tag_cbk)
+- yappi.start()
+- a()
+- a()
+- a()
+- yappi.stop()
+- stats = yappi.get_func_stats()
+- self.assertEqual(stats.pop().ncall, 3) # aggregated if no tag is given
+- stats = yappi.get_func_stats(tag=1)
+-
+- for i in range(1, 3):
+- stats = yappi.get_func_stats(tag=i)
+- stats = yappi.get_func_stats(
+- tag=i, filter_callback=lambda x: yappi.func_matches(x, [a])
+- )
+-
+- stat = stats.pop()
+- self.assertEqual(stat.ncall, 1)
+-
+- yappi.set_tag_callback(None)
+- yappi.clear_stats()
+- yappi.start()
+- b()
+- b()
+- stats = yappi.get_func_stats()
+- self.assertEqual(len(stats), 1)
+- stat = stats.pop()
+- self.assertEqual(stat.ncall, 2)
+-
+- def test_filter(self):
+-
+- def a():
+- pass
+-
+- def b():
+- a()
+-
+- def c():
+- b()
+-
+- _TCOUNT = 5
+-
+- ts = []
+- yappi.start()
+- for i in range(_TCOUNT):
+- t = threading.Thread(target=c)
+- t.start()
+- ts.append(t)
+-
+- for t in ts:
+- t.join()
+-
+- yappi.stop()
+-
+- ctx_ids = []
+- for tstat in yappi.get_thread_stats():
+- if tstat.name == '_MainThread':
+- main_ctx_id = tstat.id
+- else:
+- ctx_ids.append(tstat.id)
+-
+- fstats = yappi.get_func_stats(filter={"ctx_id": 9})
+- self.assertTrue(fstats.empty())
+- fstats = yappi.get_func_stats(
+- filter={
+- "ctx_id": main_ctx_id,
+- "name": "c"
+- }
+- ) # main thread
+- self.assertTrue(fstats.empty())
+-
+- for i in ctx_ids:
+- fstats = yappi.get_func_stats(
+- filter={
+- "ctx_id": i,
+- "name": "a",
+- "ncall": 1
+- }
+- )
+- self.assertEqual(fstats.pop().ncall, 1)
+- fstats = yappi.get_func_stats(filter={"ctx_id": i, "name": "b"})
+- self.assertEqual(fstats.pop().ncall, 1)
+- fstats = yappi.get_func_stats(filter={"ctx_id": i, "name": "c"})
+- self.assertEqual(fstats.pop().ncall, 1)
+-
+- yappi.clear_stats()
+- yappi.start(builtins=True)
+- time.sleep(0.1)
+- yappi.stop()
+- fstats = yappi.get_func_stats(filter={"module": "time"})
+- self.assertEqual(len(fstats), 1)
+-
+- # invalid filters`
+- self.assertRaises(
+- Exception, yappi.get_func_stats, filter={'tag': "sss"}
+- )
+- self.assertRaises(
+- Exception, yappi.get_func_stats, filter={'ctx_id': "None"}
+- )
+-
+- def test_filter_callback(self):
+-
+- def a():
+- time.sleep(0.1)
+-
+- def b():
+- a()
+-
+- def c():
+- pass
+-
+- def d():
+- pass
+-
+- yappi.set_clock_type("wall")
+- yappi.start(builtins=True)
+- a()
+- b()
+- c()
+- d()
+- stats = yappi.get_func_stats(
+- filter_callback=lambda x: yappi.func_matches(x, [a, b])
+- )
+- #stats.print_all()
+- r1 = '''
+- tests/test_functionality.py:98 a 2 0.000000 0.200350 0.100175
+- tests/test_functionality.py:101 b 1 0.000000 0.120000 0.100197
+- '''
+- self.assert_traces_almost_equal(r1, stats)
+- self.assertEqual(len(stats), 2)
+- stats = yappi.get_func_stats(
+- filter_callback=lambda x: yappi.
+- module_matches(x, [sys.modules[__name__]])
+- )
+- r1 = '''
+- tests/test_functionality.py:98 a 2 0.000000 0.230130 0.115065
+- tests/test_functionality.py:101 b 1 0.000000 0.120000 0.109011
+- tests/test_functionality.py:104 c 1 0.000000 0.000002 0.000002
+- tests/test_functionality.py:107 d 1 0.000000 0.000001 0.000001
+- '''
+- self.assert_traces_almost_equal(r1, stats)
+- self.assertEqual(len(stats), 4)
+-
+- stats = yappi.get_func_stats(
+- filter_callback=lambda x: yappi.func_matches(x, [time.sleep])
+- )
+- self.assertEqual(len(stats), 1)
+- r1 = '''
+- time.sleep 2 0.206804 0.220000 0.103402
+- '''
+- self.assert_traces_almost_equal(r1, stats)
+-
+- def test_print_formatting(self):
+-
+- def a():
+- pass
+-
+- def b():
+- a()
+-
+- func_cols = {
+- 1: ("name", 48),
+- 0: ("ncall", 5),
+- 2: ("tsub", 8),
+- }
+- thread_cols = {
+- 1: ("name", 48),
+- 0: ("ttot", 8),
+- }
+-
+- yappi.start()
+- a()
+- b()
+- yappi.stop()
+- fs = yappi.get_func_stats()
+- cs = fs[1].children
+- ts = yappi.get_thread_stats()
+- #fs.print_all(out=sys.stderr, columns={1:("name", 70), })
+- #cs.print_all(out=sys.stderr, columns=func_cols)
+- #ts.print_all(out=sys.stderr, columns=thread_cols)
+- #cs.print_all(out=sys.stderr, columns={})
+-
+- self.assertRaises(
+- yappi.YappiError, fs.print_all, columns={1: ("namee", 9)}
+- )
+- self.assertRaises(
+- yappi.YappiError, cs.print_all, columns={1: ("dd", 0)}
+- )
+- self.assertRaises(
+- yappi.YappiError, ts.print_all, columns={1: ("tidd", 0)}
+- )
+-
+- def test_get_clock(self):
+- yappi.set_clock_type('cpu')
+- self.assertEqual('cpu', yappi.get_clock_type())
+- clock_info = yappi.get_clock_info()
+- self.assertTrue('api' in clock_info)
+- self.assertTrue('resolution' in clock_info)
+-
+- yappi.set_clock_type('wall')
+- self.assertEqual('wall', yappi.get_clock_type())
+-
+- t0 = yappi.get_clock_time()
+- time.sleep(0.1)
+- duration = yappi.get_clock_time() - t0
+- self.assertTrue(0.05 < duration < 0.3)
+-
+- def test_profile_decorator(self):
+-
+- def aggregate(func, stats):
+- fname = f"tests/{func.__name__}.profile"
+- try:
+- stats.add(fname)
+- except OSError:
+- pass
+- stats.save(fname)
+- raise Exception("messing around")
+-
+- @yappi.profile(return_callback=aggregate)
+- def a(x, y):
+- if x + y == 25:
+- raise Exception("")
+- return x + y
+-
+- def b():
+- pass
+-
+- try:
+- os.remove(
+- "tests/a.profile"
+- ) # remove the one from prev test, if available
+- except:
+- pass
+-
+- # global profile is on to mess things up
+- yappi.start()
+- b()
+-
+- # assert functionality and call function at same time
+- try:
+- self.assertEqual(a(1, 2), 3)
+- except:
+- pass
+- try:
+- self.assertEqual(a(2, 5), 7)
+- except:
+- pass
+- try:
+- a(4, 21)
+- except:
+- pass
+- stats = yappi.get_func_stats().add("tests/a.profile")
+- fsa = utils.find_stat_by_name(stats, 'a')
+- self.assertEqual(fsa.ncall, 3)
+- self.assertEqual(len(stats), 1) # b() should be cleared out.
+-
+- @yappi.profile(return_callback=aggregate)
+- def count_down_rec(n):
+- if n == 0:
+- return
+- count_down_rec(n - 1)
+-
+- try:
+- os.remove(
+- "tests/count_down_rec.profile"
+- ) # remove the one from prev test, if available
+- except:
+- pass
+-
+- try:
+- count_down_rec(4)
+- except:
+- pass
+- try:
+- count_down_rec(3)
+- except:
+- pass
+-
+- stats = yappi.YFuncStats("tests/count_down_rec.profile")
+- fsrec = utils.find_stat_by_name(stats, 'count_down_rec')
+- self.assertEqual(fsrec.ncall, 9)
+- self.assertEqual(fsrec.nactualcall, 2)
+-
+- def test_strip_dirs(self):
+-
+- def a():
+- pass
+-
+- stats = utils.run_and_get_func_stats(a, )
+- stats.strip_dirs()
+- fsa = utils.find_stat_by_name(stats, "a")
+- self.assertEqual(fsa.module, os.path.basename(fsa.module))
+-
+- @unittest.skipIf(os.name == "nt", "do not run on Windows")
+- def test_run_as_script(self):
+- import re
+- p = subprocess.Popen(
+- ['yappi', os.path.join('./tests', 'run_as_script.py')],
+- stdout=subprocess.PIPE
+- )
+- out, err = p.communicate()
+- self.assertEqual(p.returncode, 0)
+- func_stats, thread_stats = re.split(
+- b'name\\s+id\\s+tid\\s+ttot\\s+scnt\\s*\n', out
+- )
+- self.assertTrue(b'FancyThread' in thread_stats)
+-
+- def test_yappi_overhead(self):
+- LOOP_COUNT = 100000
+-
+- def a():
+- pass
+-
+- def b():
+- for i in range(LOOP_COUNT):
+- a()
+-
+- t0 = time.time()
+- yappi.start()
+- b()
+- yappi.stop()
+- time_with_yappi = time.time() - t0
+- t0 = time.time()
+- b()
+- time_without_yappi = time.time() - t0
+- if time_without_yappi == 0:
+- time_without_yappi = 0.000001
+-
+- # in latest v0.82, I calculated this as close to "7.0" in my machine.
+- # however, %83 of this overhead is coming from tickcount(). The other %17
+- # seems to have been evenly distributed to the internal bookkeeping
+- # structures/algorithms which seems acceptable. Note that our test only
+- # tests one function being profiled at-a-time in a short interval.
+- # profiling high number of functions in a small time
+- # is a different beast, (which is pretty unlikely in most applications)
+- # So as a conclusion: I cannot see any optimization window for Yappi that
+- # is worth implementing as we will only optimize %17 of the time.
+- sys.stderr.write("\r\nYappi puts %0.1f times overhead to the profiled application in average.\r\n" % \
+- (time_with_yappi / time_without_yappi))
+-
+- def test_clear_stats_while_running(self):
+-
+- def a():
+- pass
+-
+- yappi.start()
+- a()
+- yappi.clear_stats()
+- a()
+- stats = yappi.get_func_stats()
+- fsa = utils.find_stat_by_name(stats, 'a')
+- self.assertEqual(fsa.ncall, 1)
+-
+- def test_generator(self):
+-
+- def _gen(n):
+- while (n > 0):
+- yield n
+- n -= 1
+-
+- yappi.start()
+- for x in _gen(5):
+- pass
+- self.assertTrue(
+- yappi.convert2pstats(yappi.get_func_stats()) is not None
+- )
+-
+- def test_slice_child_stats_and_strip_dirs(self):
+-
+- def b():
+- for i in range(10000000):
+- pass
+-
+- def a():
+- b()
+-
+- yappi.start(builtins=True)
+- a()
+- stats = yappi.get_func_stats()
+- fsa = utils.find_stat_by_name(stats, 'a')
+- fsb = utils.find_stat_by_name(stats, 'b')
+- self.assertTrue(fsa.children[0:1] is not None)
+- prev_afullname = fsa.full_name
+- prev_bchildfullname = fsa.children[fsb].full_name
+- stats.strip_dirs()
+- self.assertTrue(len(prev_afullname) > len(fsa.full_name))
+- self.assertTrue(
+- len(prev_bchildfullname) > len(fsa.children[fsb].full_name)
+- )
+-
+- def test_children_stat_functions(self):
+- _timings = {"a_1": 5, "b_1": 3, "c_1": 1}
+- _yappi._set_test_timings(_timings)
+-
+- def b():
+- pass
+-
+- def c():
+- pass
+-
+- def a():
+- b()
+- c()
+-
+- yappi.start()
+- a()
+- b() # non-child call
+- c() # non-child call
+- stats = yappi.get_func_stats()
+- fsa = utils.find_stat_by_name(stats, 'a')
+- childs_of_a = fsa.children.get().sort("tavg", "desc")
+- prev_item = None
+- for item in childs_of_a:
+- if prev_item:
+- self.assertTrue(prev_item.tavg > item.tavg)
+- prev_item = item
+- childs_of_a.sort("name", "desc")
+- prev_item = None
+- for item in childs_of_a:
+- if prev_item:
+- self.assertTrue(prev_item.name > item.name)
+- prev_item = item
+- childs_of_a.clear()
+- self.assertTrue(childs_of_a.empty())
+-
+- def test_no_stats_different_clock_type_load(self):
+-
+- def a():
+- pass
+-
+- yappi.start()
+- a()
+- yappi.stop()
+- yappi.get_func_stats().save("tests/ystats1.ys")
+- yappi.clear_stats()
+- yappi.set_clock_type("WALL")
+- yappi.start()
+- yappi.stop()
+- stats = yappi.get_func_stats().add("tests/ystats1.ys")
+- fsa = utils.find_stat_by_name(stats, 'a')
+- self.assertTrue(fsa is not None)
+-
+- def test_subsequent_profile(self):
+- _timings = {"a_1": 1, "b_1": 1}
+- _yappi._set_test_timings(_timings)
+-
+- def a():
+- pass
+-
+- def b():
+- pass
+-
+- yappi.start()
+- a()
+- yappi.stop()
+- yappi.start()
+- b()
+- yappi.stop()
+- stats = yappi.get_func_stats()
+- fsa = utils.find_stat_by_name(stats, 'a')
+- fsb = utils.find_stat_by_name(stats, 'b')
+- self.assertTrue(fsa is not None)
+- self.assertTrue(fsb is not None)
+- self.assertEqual(fsa.ttot, 1)
+- self.assertEqual(fsb.ttot, 1)
+-
+- def test_lambda(self):
+- f = lambda: time.sleep(0.3)
+- yappi.set_clock_type("wall")
+- yappi.start()
+- f()
+- stats = yappi.get_func_stats()
+- fsa = utils.find_stat_by_name(stats, '<lambda>')
+- self.assertTrue(fsa.ttot > 0.1)
+-
+- def test_module_stress(self):
+- self.assertEqual(yappi.is_running(), False)
+-
+- yappi.start()
+- yappi.clear_stats()
+- self.assertRaises(_yappi.error, yappi.set_clock_type, "wall")
+-
+- yappi.stop()
+- yappi.clear_stats()
+- yappi.set_clock_type("cpu")
+- self.assertRaises(yappi.YappiError, yappi.set_clock_type, "dummy")
+- self.assertEqual(yappi.is_running(), False)
+- yappi.clear_stats()
+- yappi.clear_stats()
+-
+- def test_stat_sorting(self):
+- _timings = {"a_1": 13, "b_1": 10, "a_2": 6, "b_2": 1}
+- _yappi._set_test_timings(_timings)
+-
+- self._ncall = 1
+-
+- def a():
+- b()
+-
+- def b():
+- if self._ncall == 2:
+- return
+- self._ncall += 1
+- a()
+-
+- stats = utils.run_and_get_func_stats(a)
+- stats = stats.sort("totaltime", "desc")
+- prev_stat = None
+- for stat in stats:
+- if prev_stat:
+- self.assertTrue(prev_stat.ttot >= stat.ttot)
+- prev_stat = stat
+- stats = stats.sort("totaltime", "asc")
+- prev_stat = None
+- for stat in stats:
+- if prev_stat:
+- self.assertTrue(prev_stat.ttot <= stat.ttot)
+- prev_stat = stat
+- stats = stats.sort("avgtime", "asc")
+- prev_stat = None
+- for stat in stats:
+- if prev_stat:
+- self.assertTrue(prev_stat.tavg <= stat.tavg)
+- prev_stat = stat
+- stats = stats.sort("name", "asc")
+- prev_stat = None
+- for stat in stats:
+- if prev_stat:
+- self.assertTrue(prev_stat.name <= stat.name)
+- prev_stat = stat
+- stats = stats.sort("subtime", "asc")
+- prev_stat = None
+- for stat in stats:
+- if prev_stat:
+- self.assertTrue(prev_stat.tsub <= stat.tsub)
+- prev_stat = stat
+-
+- self.assertRaises(
+- yappi.YappiError, stats.sort, "invalid_func_sorttype_arg"
+- )
+- self.assertRaises(
+- yappi.YappiError, stats.sort, "totaltime",
+- "invalid_func_sortorder_arg"
+- )
+-
+- def test_start_flags(self):
+- self.assertEqual(_yappi._get_start_flags(), None)
+- yappi.start()
+-
+- def a():
+- pass
+-
+- a()
+- self.assertEqual(_yappi._get_start_flags()["profile_builtins"], 0)
+- self.assertEqual(_yappi._get_start_flags()["profile_multicontext"], 1)
+- self.assertEqual(len(yappi.get_thread_stats()), 1)
+-
+- def test_builtin_profiling(self):
+-
+- def a():
+- time.sleep(0.4) # is a builtin function
+-
+- yappi.set_clock_type('wall')
+-
+- yappi.start(builtins=True)
+- a()
+- stats = yappi.get_func_stats()
+- fsa = utils.find_stat_by_name(stats, 'sleep')
+- self.assertTrue(fsa is not None)
+- self.assertTrue(fsa.ttot > 0.3)
+- yappi.stop()
+- yappi.clear_stats()
+-
+- def a():
+- pass
+-
+- yappi.start()
+- t = threading.Thread(target=a)
+- t.start()
+- t.join()
+- stats = yappi.get_func_stats()
+-
+- def test_singlethread_profiling(self):
+- yappi.set_clock_type('wall')
+-
+- def a():
+- time.sleep(0.2)
+-
+- class Worker1(threading.Thread):
+-
+- def a(self):
+- time.sleep(0.3)
+-
+- def run(self):
+- self.a()
+-
+- yappi.start(profile_threads=False)
+-
+- c = Worker1()
+- c.start()
+- c.join()
+- a()
+- stats = yappi.get_func_stats()
+- fsa1 = utils.find_stat_by_name(stats, 'Worker1.a')
+- fsa2 = utils.find_stat_by_name(stats, 'a')
+- self.assertTrue(fsa1 is None)
+- self.assertTrue(fsa2 is not None)
+- self.assertTrue(fsa2.ttot > 0.1)
+-
+- def test_run(self):
+-
+- def profiled():
+- pass
+-
+- yappi.clear_stats()
+- try:
+- with yappi.run():
+- profiled()
+- stats = yappi.get_func_stats()
+- finally:
+- yappi.clear_stats()
+-
+- self.assertIsNotNone(utils.find_stat_by_name(stats, 'profiled'))
+-
+- def test_run_recursive(self):
+-
+- def profiled():
+- pass
+-
+- def not_profiled():
+- pass
+-
+- yappi.clear_stats()
+- try:
+- with yappi.run():
+- with yappi.run():
+- profiled()
+- # Profiling stopped here
+- not_profiled()
+- stats = yappi.get_func_stats()
+- finally:
+- yappi.clear_stats()
+-
+- self.assertIsNotNone(utils.find_stat_by_name(stats, 'profiled'))
+- self.assertIsNone(utils.find_stat_by_name(stats, 'not_profiled'))
+-
+-
+-class StatSaveScenarios(utils.YappiUnitTestCase):
+-
+- def test_pstats_conversion(self):
+-
+- def pstat_id(fs):
+- return (fs.module, fs.lineno, fs.name)
+-
+- def a():
+- d()
+-
+- def b():
+- d()
+-
+- def c():
+- pass
+-
+- def d():
+- pass
+-
+- _timings = {"a_1": 12, "b_1": 7, "c_1": 5, "d_1": 2}
+- _yappi._set_test_timings(_timings)
+- stats = utils.run_and_get_func_stats(a, )
+- stats.strip_dirs()
+- stats.save("tests/a1.pstats", type="pstat")
+- fsa_pid = pstat_id(utils.find_stat_by_name(stats, "a"))
+- fsd_pid = pstat_id(utils.find_stat_by_name(stats, "d"))
+- yappi.clear_stats()
+- _yappi._set_test_timings(_timings)
+- stats = utils.run_and_get_func_stats(a, )
+- stats.strip_dirs()
+- stats.save("tests/a2.pstats", type="pstat")
+- yappi.clear_stats()
+- _yappi._set_test_timings(_timings)
+- stats = utils.run_and_get_func_stats(b, )
+- stats.strip_dirs()
+- stats.save("tests/b1.pstats", type="pstat")
+- fsb_pid = pstat_id(utils.find_stat_by_name(stats, "b"))
+- yappi.clear_stats()
+- _yappi._set_test_timings(_timings)
+- stats = utils.run_and_get_func_stats(c, )
+- stats.strip_dirs()
+- stats.save("tests/c1.pstats", type="pstat")
+- fsc_pid = pstat_id(utils.find_stat_by_name(stats, "c"))
+-
+- # merge saved stats and check pstats values are correct
+- import pstats
+- p = pstats.Stats(
+- 'tests/a1.pstats', 'tests/a2.pstats', 'tests/b1.pstats',
+- 'tests/c1.pstats'
+- )
+- p.strip_dirs()
+- # ct = ttot, tt = tsub
+- (cc, nc, tt, ct, callers) = p.stats[fsa_pid]
+- self.assertEqual(cc, nc, 2)
+- self.assertEqual(tt, 20)
+- self.assertEqual(ct, 24)
+- (cc, nc, tt, ct, callers) = p.stats[fsd_pid]
+- self.assertEqual(cc, nc, 3)
+- self.assertEqual(tt, 6)
+- self.assertEqual(ct, 6)
+- self.assertEqual(len(callers), 2)
+- (cc, nc, tt, ct) = callers[fsa_pid]
+- self.assertEqual(cc, nc, 2)
+- self.assertEqual(tt, 4)
+- self.assertEqual(ct, 4)
+- (cc, nc, tt, ct) = callers[fsb_pid]
+- self.assertEqual(cc, nc, 1)
+- self.assertEqual(tt, 2)
+- self.assertEqual(ct, 2)
+-
+- def test_merge_stats(self):
+- _timings = {
+- "a_1": 15,
+- "b_1": 14,
+- "c_1": 12,
+- "d_1": 10,
+- "e_1": 9,
+- "f_1": 7,
+- "g_1": 6,
+- "h_1": 5,
+- "i_1": 1
+- }
+- _yappi._set_test_timings(_timings)
+-
+- def a():
+- b()
+-
+- def b():
+- c()
+-
+- def c():
+- d()
+-
+- def d():
+- e()
+-
+- def e():
+- f()
+-
+- def f():
+- g()
+-
+- def g():
+- h()
+-
+- def h():
+- i()
+-
+- def i():
+- pass
+-
+- yappi.start()
+- a()
+- a()
+- yappi.stop()
+- stats = yappi.get_func_stats()
+- self.assertRaises(
+- NotImplementedError, stats.save, "", "INVALID_SAVE_TYPE"
+- )
+- stats.save("tests/ystats2.ys")
+- yappi.clear_stats()
+- _yappi._set_test_timings(_timings)
+- yappi.start()
+- a()
+- stats = yappi.get_func_stats().add("tests/ystats2.ys")
+- fsa = utils.find_stat_by_name(stats, "a")
+- fsb = utils.find_stat_by_name(stats, "b")
+- fsc = utils.find_stat_by_name(stats, "c")
+- fsd = utils.find_stat_by_name(stats, "d")
+- fse = utils.find_stat_by_name(stats, "e")
+- fsf = utils.find_stat_by_name(stats, "f")
+- fsg = utils.find_stat_by_name(stats, "g")
+- fsh = utils.find_stat_by_name(stats, "h")
+- fsi = utils.find_stat_by_name(stats, "i")
+- self.assertEqual(fsa.ttot, 45)
+- self.assertEqual(fsa.ncall, 3)
+- self.assertEqual(fsa.nactualcall, 3)
+- self.assertEqual(fsa.tsub, 3)
+- self.assertEqual(fsa.children[fsb].ttot, fsb.ttot)
+- self.assertEqual(fsa.children[fsb].tsub, fsb.tsub)
+- self.assertEqual(fsb.children[fsc].ttot, fsc.ttot)
+- self.assertEqual(fsb.children[fsc].tsub, fsc.tsub)
+- self.assertEqual(fsc.tsub, 6)
+- self.assertEqual(fsc.children[fsd].ttot, fsd.ttot)
+- self.assertEqual(fsc.children[fsd].tsub, fsd.tsub)
+- self.assertEqual(fsd.children[fse].ttot, fse.ttot)
+- self.assertEqual(fsd.children[fse].tsub, fse.tsub)
+- self.assertEqual(fse.children[fsf].ttot, fsf.ttot)
+- self.assertEqual(fse.children[fsf].tsub, fsf.tsub)
+- self.assertEqual(fsf.children[fsg].ttot, fsg.ttot)
+- self.assertEqual(fsf.children[fsg].tsub, fsg.tsub)
+- self.assertEqual(fsg.ttot, 18)
+- self.assertEqual(fsg.tsub, 3)
+- self.assertEqual(fsg.children[fsh].ttot, fsh.ttot)
+- self.assertEqual(fsg.children[fsh].tsub, fsh.tsub)
+- self.assertEqual(fsh.ttot, 15)
+- self.assertEqual(fsh.tsub, 12)
+- self.assertEqual(fsh.tavg, 5)
+- self.assertEqual(fsh.children[fsi].ttot, fsi.ttot)
+- self.assertEqual(fsh.children[fsi].tsub, fsi.tsub)
+- #stats.debug_print()
+-
+- def test_merge_multithreaded_stats(self):
+- import _yappi
+- timings = {"a_1": 2, "b_1": 1}
+- _yappi._set_test_timings(timings)
+-
+- def a():
+- pass
+-
+- def b():
+- pass
+-
+- yappi.start()
+- t = threading.Thread(target=a)
+- t.start()
+- t.join()
+- t = threading.Thread(target=b)
+- t.start()
+- t.join()
+- yappi.get_func_stats().save("tests/ystats1.ys")
+- yappi.clear_stats()
+- _yappi._set_test_timings(timings)
+- self.assertEqual(len(yappi.get_func_stats()), 0)
+- self.assertEqual(len(yappi.get_thread_stats()), 1)
+- t = threading.Thread(target=a)
+- t.start()
+- t.join()
+-
+- self.assertEqual(_yappi._get_start_flags()["profile_builtins"], 0)
+- self.assertEqual(_yappi._get_start_flags()["profile_multicontext"], 1)
+- yappi.get_func_stats().save("tests/ystats2.ys")
+-
+- stats = yappi.YFuncStats([
+- "tests/ystats1.ys",
+- "tests/ystats2.ys",
+- ])
+- fsa = utils.find_stat_by_name(stats, "a")
+- fsb = utils.find_stat_by_name(stats, "b")
+- self.assertEqual(fsa.ncall, 2)
+- self.assertEqual(fsb.ncall, 1)
+- self.assertEqual(fsa.tsub, fsa.ttot, 4)
+- self.assertEqual(fsb.tsub, fsb.ttot, 1)
+-
+- def test_merge_load_different_clock_types(self):
+- yappi.start(builtins=True)
+-
+- def a():
+- b()
+-
+- def b():
+- c()
+-
+- def c():
+- pass
+-
+- t = threading.Thread(target=a)
+- t.start()
+- t.join()
+- yappi.get_func_stats().sort("name", "asc").save("tests/ystats1.ys")
+- yappi.stop()
+- yappi.clear_stats()
+- yappi.start(builtins=False)
+- t = threading.Thread(target=a)
+- t.start()
+- t.join()
+- yappi.get_func_stats().save("tests/ystats2.ys")
+- yappi.stop()
+- self.assertRaises(_yappi.error, yappi.set_clock_type, "wall")
+- yappi.clear_stats()
+- yappi.set_clock_type("wall")
+- yappi.start()
+- t = threading.Thread(target=a)
+- t.start()
+- t.join()
+- yappi.get_func_stats().save("tests/ystats3.ys")
+- self.assertRaises(
+- yappi.YappiError,
+- yappi.YFuncStats().add("tests/ystats1.ys").add, "tests/ystats3.ys"
+- )
+- stats = yappi.YFuncStats(["tests/ystats1.ys",
+- "tests/ystats2.ys"]).sort("name")
+- fsa = utils.find_stat_by_name(stats, "a")
+- fsb = utils.find_stat_by_name(stats, "b")
+- fsc = utils.find_stat_by_name(stats, "c")
+- self.assertEqual(fsa.ncall, 2)
+- self.assertEqual(fsa.ncall, fsb.ncall, fsc.ncall)
+-
+- def test_merge_aabab_aabbc(self):
+- _timings = {
+- "a_1": 15,
+- "a_2": 14,
+- "b_1": 12,
+- "a_3": 10,
+- "b_2": 9,
+- "c_1": 4
+- }
+- _yappi._set_test_timings(_timings)
+-
+- def a():
+- if self._ncall == 1:
+- self._ncall += 1
+- a()
+- elif self._ncall == 5:
+- self._ncall += 1
+- a()
+- else:
+- b()
+-
+- def b():
+- if self._ncall == 2:
+- self._ncall += 1
+- a()
+- elif self._ncall == 6:
+- self._ncall += 1
+- b()
+- elif self._ncall == 7:
+- c()
+- else:
+- return
+-
+- def c():
+- pass
+-
+- self._ncall = 1
+- stats = utils.run_and_get_func_stats(a, )
+- stats.save("tests/ystats1.ys")
+- yappi.clear_stats()
+- _yappi._set_test_timings(_timings)
+- #stats.print_all()
+-
+- self._ncall = 5
+- stats = utils.run_and_get_func_stats(a, )
+- stats.save("tests/ystats2.ys")
+-
+- #stats.print_all()
+-
+- def a(): # same name but another function(code object)
+- pass
+-
+- yappi.start()
+- a()
+- stats = yappi.get_func_stats().add(
+- ["tests/ystats1.ys", "tests/ystats2.ys"]
+- )
+- #stats.print_all()
+- self.assertEqual(len(stats), 4)
+-
+- fsa = None
+- for stat in stats:
+- if stat.name == "a" and stat.ttot == 45:
+- fsa = stat
+- break
+- self.assertTrue(fsa is not None)
+-
+- self.assertEqual(fsa.ncall, 7)
+- self.assertEqual(fsa.nactualcall, 3)
+- self.assertEqual(fsa.ttot, 45)
+- self.assertEqual(fsa.tsub, 10)
+- fsb = utils.find_stat_by_name(stats, "b")
+- fsc = utils.find_stat_by_name(stats, "c")
+- self.assertEqual(fsb.ncall, 6)
+- self.assertEqual(fsb.nactualcall, 3)
+- self.assertEqual(fsb.ttot, 36)
+- self.assertEqual(fsb.tsub, 27)
+- self.assertEqual(fsb.tavg, 6)
+- self.assertEqual(fsc.ttot, 8)
+- self.assertEqual(fsc.tsub, 8)
+- self.assertEqual(fsc.tavg, 4)
+- self.assertEqual(fsc.nactualcall, fsc.ncall, 2)
+-
+-
+-class MultithreadedScenarios(utils.YappiUnitTestCase):
+-
+- def test_issue_32(self):
+- '''
+- Start yappi from different thread and we get Internal Error(15) as
+- the current_ctx_id() called while enumerating the threads in start()
+- and as it does not swap to the enumerated ThreadState* the THreadState_GetDict()
+- returns wrong object and thus sets an invalid id for the _ctx structure.
+-
+- When this issue happens multiple Threads have same tid as the internal ts_ptr
+- will be same for different contexts. So, let's see if that happens
+- '''
+-
+- def foo():
+- time.sleep(0.2)
+-
+- def bar():
+- time.sleep(0.1)
+-
+- def thread_func():
+- yappi.set_clock_type("wall")
+- yappi.start()
+-
+- bar()
+-
+- t = threading.Thread(target=thread_func)
+- t.start()
+- t.join()
+-
+- foo()
+-
+- yappi.stop()
+-
+- thread_ids = set()
+- for tstat in yappi.get_thread_stats():
+- self.assertTrue(tstat.tid not in thread_ids)
+- thread_ids.add(tstat.tid)
+-
+- def test_subsequent_profile(self):
+- WORKER_COUNT = 5
+-
+- def a():
+- pass
+-
+- def b():
+- pass
+-
+- def c():
+- pass
+-
+- _timings = {
+- "a_1": 3,
+- "b_1": 2,
+- "c_1": 1,
+- }
+-
+- yappi.start()
+-
+- def g():
+- pass
+-
+- g()
+- yappi.stop()
+- yappi.clear_stats()
+- _yappi._set_test_timings(_timings)
+- yappi.start()
+-
+- _dummy = []
+- for i in range(WORKER_COUNT):
+- t = threading.Thread(target=a)
+- t.start()
+- t.join()
+- for i in range(WORKER_COUNT):
+- t = threading.Thread(target=b)
+- t.start()
+- _dummy.append(t)
+- t.join()
+- for i in range(WORKER_COUNT):
+- t = threading.Thread(target=a)
+- t.start()
+- t.join()
+- for i in range(WORKER_COUNT):
+- t = threading.Thread(target=c)
+- t.start()
+- t.join()
+- yappi.stop()
+- yappi.start()
+-
+- def f():
+- pass
+-
+- f()
+- stats = yappi.get_func_stats()
+- fsa = utils.find_stat_by_name(stats, 'a')
+- fsb = utils.find_stat_by_name(stats, 'b')
+- fsc = utils.find_stat_by_name(stats, 'c')
+- self.assertEqual(fsa.ncall, 10)
+- self.assertEqual(fsb.ncall, 5)
+- self.assertEqual(fsc.ncall, 5)
+- self.assertEqual(fsa.ttot, fsa.tsub, 30)
+- self.assertEqual(fsb.ttot, fsb.tsub, 10)
+- self.assertEqual(fsc.ttot, fsc.tsub, 5)
+-
+- # MACOSx optimizes by only creating one worker thread
+- self.assertTrue(len(yappi.get_thread_stats()) >= 2)
+-
+- def test_basic(self):
+- yappi.set_clock_type('wall')
+-
+- def dummy():
+- pass
+-
+- def a():
+- time.sleep(0.2)
+-
+- class Worker1(threading.Thread):
+-
+- def a(self):
+- time.sleep(0.3)
+-
+- def run(self):
+- self.a()
+-
+- yappi.start(builtins=False, profile_threads=True)
+-
+- c = Worker1()
+- c.start()
+- c.join()
+- a()
+- stats = yappi.get_func_stats()
+- fsa1 = utils.find_stat_by_name(stats, 'Worker1.a')
+- fsa2 = utils.find_stat_by_name(stats, 'a')
+- self.assertTrue(fsa1 is not None)
+- self.assertTrue(fsa2 is not None)
+- self.assertTrue(fsa1.ttot > 0.2)
+- self.assertTrue(fsa2.ttot > 0.1)
+- tstats = yappi.get_thread_stats()
+- self.assertEqual(len(tstats), 2)
+- tsa = utils.find_stat_by_name(tstats, 'Worker1')
+- tsm = utils.find_stat_by_name(tstats, '_MainThread')
+- dummy() # call dummy to force ctx name to be retrieved again.
+- self.assertTrue(tsa is not None)
+- # TODO: I put dummy() to fix below, remove the comments after a while.
+- self.assertTrue( # FIX: I see this fails sometimes?
+- tsm is not None,
+- f"Could not find \"_MainThread\". Found: {', '.join(utils.get_stat_names(tstats))}")
+-
+- def test_ctx_stats(self):
+- from threading import Thread
+- DUMMY_WORKER_COUNT = 5
+- yappi.start()
+-
+- class DummyThread(Thread):
+- pass
+-
+- def dummy():
+- pass
+-
+- def dummy_worker():
+- pass
+-
+- for i in range(DUMMY_WORKER_COUNT):
+- t = DummyThread(target=dummy_worker)
+- t.start()
+- t.join()
+- yappi.stop()
+- stats = yappi.get_thread_stats()
+- tsa = utils.find_stat_by_name(stats, "DummyThread")
+- self.assertTrue(tsa is not None)
+- yappi.clear_stats()
+- time.sleep(1.0)
+- _timings = {
+- "a_1": 6,
+- "b_1": 5,
+- "c_1": 3,
+- "d_1": 1,
+- "a_2": 4,
+- "b_2": 3,
+- "c_2": 2,
+- "d_2": 1
+- }
+- _yappi._set_test_timings(_timings)
+-
+- class Thread1(Thread):
+- pass
+-
+- class Thread2(Thread):
+- pass
+-
+- def a():
+- b()
+-
+- def b():
+- c()
+-
+- def c():
+- d()
+-
+- def d():
+- time.sleep(0.6)
+-
+- yappi.set_clock_type("wall")
+- yappi.start()
+- t1 = Thread1(target=a)
+- t1.start()
+- t2 = Thread2(target=a)
+- t2.start()
+- t1.join()
+- t2.join()
+- stats = yappi.get_thread_stats()
+-
+- # the fist clear_stats clears the context table?
+- tsa = utils.find_stat_by_name(stats, "DummyThread")
+- self.assertTrue(tsa is None)
+-
+- tst1 = utils.find_stat_by_name(stats, "Thread1")
+- tst2 = utils.find_stat_by_name(stats, "Thread2")
+- tsmain = utils.find_stat_by_name(stats, "_MainThread")
+- dummy() # call dummy to force ctx name to be retrieved again.
+- self.assertTrue(len(stats) == 3)
+- self.assertTrue(tst1 is not None)
+- self.assertTrue(tst2 is not None)
+- # TODO: I put dummy() to fix below, remove the comments after a while.
+- self.assertTrue( # FIX: I see this fails sometimes
+- tsmain is not None,
+- f"Could not find \"_MainThread\". Found: {', '.join(utils.get_stat_names(stats))}")
+- self.assertTrue(1.0 > tst2.ttot >= 0.5)
+- self.assertTrue(1.0 > tst1.ttot >= 0.5)
+-
+- # test sorting of the ctx stats
+- stats = stats.sort("totaltime", "desc")
+- prev_stat = None
+- for stat in stats:
+- if prev_stat:
+- self.assertTrue(prev_stat.ttot >= stat.ttot)
+- prev_stat = stat
+- stats = stats.sort("totaltime", "asc")
+- prev_stat = None
+- for stat in stats:
+- if prev_stat:
+- self.assertTrue(prev_stat.ttot <= stat.ttot)
+- prev_stat = stat
+- stats = stats.sort("schedcount", "desc")
+- prev_stat = None
+- for stat in stats:
+- if prev_stat:
+- self.assertTrue(prev_stat.sched_count >= stat.sched_count)
+- prev_stat = stat
+- stats = stats.sort("name", "desc")
+- prev_stat = None
+- for stat in stats:
+- if prev_stat:
+- self.assertTrue(prev_stat.name.lower() >= stat.name.lower())
+- prev_stat = stat
+- self.assertRaises(
+- yappi.YappiError, stats.sort, "invalid_thread_sorttype_arg"
+- )
+- self.assertRaises(
+- yappi.YappiError, stats.sort, "invalid_thread_sortorder_arg"
+- )
+-
+- def test_ctx_stats_cpu(self):
+-
+- def get_thread_name():
+- try:
+- return threading.current_thread().name
+- except AttributeError:
+- return "Anonymous"
+-
+- def burn_cpu(sec):
+- t0 = yappi.get_clock_time()
+- elapsed = 0
+- while (elapsed < sec):
+- for _ in range(1000):
+- pass
+- elapsed = yappi.get_clock_time() - t0
+-
+- def test():
+-
+- ts = []
+- for i in (0.01, 0.05, 0.1):
+- t = threading.Thread(target=burn_cpu, args=(i, ))
+- t.name = f"burn_cpu-{str(i)}"
+- t.start()
+- ts.append(t)
+- for t in ts:
+- t.join()
+-
+- yappi.set_clock_type("cpu")
+- yappi.set_context_name_callback(get_thread_name)
+-
+- yappi.start()
+-
+- test()
+-
+- yappi.stop()
+-
+- tstats = yappi.get_thread_stats()
+- r1 = '''
+- burn_cpu-0.1 3 123145356058624 0.100105 8
+- burn_cpu-0.05 2 123145361313792 0.050149 8
+- burn_cpu-0.01 1 123145356058624 0.010127 2
+- MainThread 0 4321620864 0.001632 6
+- '''
+- self.assert_ctx_stats_almost_equal(r1, tstats)
+-
+- def test_producer_consumer_with_queues(self):
+- # we currently just stress yappi, no functionality test is done here.
+- yappi.start()
+- from queue import Queue
+- from threading import Thread
+- WORKER_THREAD_COUNT = 50
+- WORK_ITEM_COUNT = 2000
+-
+- def worker():
+- while True:
+- item = q.get()
+- # do the work with item
+- q.task_done()
+-
+- q = Queue()
+- for i in range(WORKER_THREAD_COUNT):
+- t = Thread(target=worker)
+- t.daemon = True
+- t.start()
+-
+- for item in range(WORK_ITEM_COUNT):
+- q.put(item)
+- q.join() # block until all tasks are done
+- #yappi.get_func_stats().sort("callcount").print_all()
+- yappi.stop()
+-
+- def test_temporary_lock_waiting(self):
+- yappi.start()
+- _lock = threading.Lock()
+-
+- def worker():
+- _lock.acquire()
+- try:
+- time.sleep(1.0)
+- finally:
+- _lock.release()
+-
+- t1 = threading.Thread(target=worker)
+- t2 = threading.Thread(target=worker)
+- t1.start()
+- t2.start()
+- t1.join()
+- t2.join()
+- #yappi.get_func_stats().sort("callcount").print_all()
+- yappi.stop()
+-
+- @unittest.skipIf(os.name != "posix", "requires Posix compliant OS")
+- def test_signals_with_blocking_calls(self):
+- import signal, os, time
+-
+- # just to verify if signal is handled correctly and stats/yappi are not corrupted.
+- def handler(signum, frame):
+- raise Exception("Signal handler executed!")
+-
+- yappi.start()
+- signal.signal(signal.SIGALRM, handler)
+- signal.alarm(1)
+- self.assertRaises(Exception, time.sleep, 2)
+- stats = yappi.get_func_stats()
+- fsh = utils.find_stat_by_name(stats, "handler")
+- self.assertTrue(fsh is not None)
+-
+- def test_concurrent_futures(self):
+- yappi.start()
+- from concurrent.futures import ThreadPoolExecutor
+- with ThreadPoolExecutor(max_workers=5) as executor:
+- f = executor.submit(pow, 5, 2)
+- self.assertEqual(f.result(), 25)
+- time.sleep(1.0)
+- yappi.stop()
+-
+- def test_barrier(self):
+- yappi.start()
+- b = threading.Barrier(2, timeout=1)
+-
+- def worker():
+- try:
+- b.wait()
+- except threading.BrokenBarrierError:
+- pass
+- except Exception:
+- raise Exception("BrokenBarrierError not raised")
+-
+- t1 = threading.Thread(target=worker)
+- t1.start()
+- #b.wait()
+- t1.join()
+- yappi.stop()
+-
+-
+-class NonRecursiveFunctions(utils.YappiUnitTestCase):
+-
+- def test_abcd(self):
+- _timings = {"a_1": 6, "b_1": 5, "c_1": 3, "d_1": 1}
+- _yappi._set_test_timings(_timings)
+-
+- def a():
+- b()
+-
+- def b():
+- c()
+-
+- def c():
+- d()
+-
+- def d():
+- pass
+-
+- stats = utils.run_and_get_func_stats(a)
+- fsa = utils.find_stat_by_name(stats, 'a')
+- fsb = utils.find_stat_by_name(stats, 'b')
+- fsc = utils.find_stat_by_name(stats, 'c')
+- fsd = utils.find_stat_by_name(stats, 'd')
+- cfsab = fsa.children[fsb]
+- cfsbc = fsb.children[fsc]
+- cfscd = fsc.children[fsd]
+-
+- self.assertEqual(fsa.ttot, 6)
+- self.assertEqual(fsa.tsub, 1)
+- self.assertEqual(fsb.ttot, 5)
+- self.assertEqual(fsb.tsub, 2)
+- self.assertEqual(fsc.ttot, 3)
+- self.assertEqual(fsc.tsub, 2)
+- self.assertEqual(fsd.ttot, 1)
+- self.assertEqual(fsd.tsub, 1)
+- self.assertEqual(cfsab.ttot, 5)
+- self.assertEqual(cfsab.tsub, 2)
+- self.assertEqual(cfsbc.ttot, 3)
+- self.assertEqual(cfsbc.tsub, 2)
+- self.assertEqual(cfscd.ttot, 1)
+- self.assertEqual(cfscd.tsub, 1)
+-
+- def test_stop_in_middle(self):
+- _timings = {"a_1": 6, "b_1": 4}
+- _yappi._set_test_timings(_timings)
+-
+- def a():
+- b()
+- yappi.stop()
+-
+- def b():
+- time.sleep(0.2)
+-
+- yappi.start()
+- a()
+- stats = yappi.get_func_stats()
+- fsa = utils.find_stat_by_name(stats, 'a')
+- fsb = utils.find_stat_by_name(stats, 'b')
+-
+- self.assertEqual(fsa.ncall, 1)
+- self.assertEqual(fsa.nactualcall, 0)
+- self.assertEqual(fsa.ttot, 0) # no call_leave called
+- self.assertEqual(fsa.tsub, 0) # no call_leave called
+- self.assertEqual(fsb.ttot, 4)
+-
+-
+-class RecursiveFunctions(utils.YappiUnitTestCase):
+-
+- def test_fibonacci(self):
+-
+- def fib(n):
+- if n > 1:
+- return fib(n - 1) + fib(n - 2)
+- else:
+- return n
+-
+- stats = utils.run_and_get_func_stats(fib, 22)
+- fs = utils.find_stat_by_name(stats, 'fib')
+- self.assertEqual(fs.ncall, 57313)
+- self.assertEqual(fs.ttot, fs.tsub)
+-
+- def test_abcadc(self):
+- _timings = {
+- "a_1": 20,
+- "b_1": 19,
+- "c_1": 17,
+- "a_2": 13,
+- "d_1": 12,
+- "c_2": 10,
+- "a_3": 5
+- }
+- _yappi._set_test_timings(_timings)
+-
+- def a(n):
+- if n == 3:
+- return
+- if n == 1 + 1:
+- d(n)
+- else:
+- b(n)
+-
+- def b(n):
+- c(n)
+-
+- def c(n):
+- a(n + 1)
+-
+- def d(n):
+- c(n)
+-
+- stats = utils.run_and_get_func_stats(a, 1)
+- fsa = utils.find_stat_by_name(stats, 'a')
+- fsb = utils.find_stat_by_name(stats, 'b')
+- fsc = utils.find_stat_by_name(stats, 'c')
+- fsd = utils.find_stat_by_name(stats, 'd')
+- self.assertEqual(fsa.ncall, 3)
+- self.assertEqual(fsa.nactualcall, 1)
+- self.assertEqual(fsa.ttot, 20)
+- self.assertEqual(fsa.tsub, 7)
+- self.assertEqual(fsb.ttot, 19)
+- self.assertEqual(fsb.tsub, 2)
+- self.assertEqual(fsc.ttot, 17)
+- self.assertEqual(fsc.tsub, 9)
+- self.assertEqual(fsd.ttot, 12)
+- self.assertEqual(fsd.tsub, 2)
+- cfsca = fsc.children[fsa]
+- self.assertEqual(cfsca.nactualcall, 0)
+- self.assertEqual(cfsca.ncall, 2)
+- self.assertEqual(cfsca.ttot, 13)
+- self.assertEqual(cfsca.tsub, 6)
+-
+- def test_aaaa(self):
+- _timings = {"d_1": 9, "d_2": 7, "d_3": 3, "d_4": 2}
+- _yappi._set_test_timings(_timings)
+-
+- def d(n):
+- if n == 3:
+- return
+- d(n + 1)
+-
+- stats = utils.run_and_get_func_stats(d, 0)
+- fsd = utils.find_stat_by_name(stats, 'd')
+- self.assertEqual(fsd.ncall, 4)
+- self.assertEqual(fsd.nactualcall, 1)
+- self.assertEqual(fsd.ttot, 9)
+- self.assertEqual(fsd.tsub, 9)
+- cfsdd = fsd.children[fsd]
+- self.assertEqual(cfsdd.ttot, 7)
+- self.assertEqual(cfsdd.tsub, 7)
+- self.assertEqual(cfsdd.ncall, 3)
+- self.assertEqual(cfsdd.nactualcall, 0)
+-
+- def test_abcabc(self):
+- _timings = {
+- "a_1": 20,
+- "b_1": 19,
+- "c_1": 17,
+- "a_2": 13,
+- "b_2": 11,
+- "c_2": 9,
+- "a_3": 6
+- }
+- _yappi._set_test_timings(_timings)
+-
+- def a(n):
+- if n == 3:
+- return
+- else:
+- b(n)
+-
+- def b(n):
+- c(n)
+-
+- def c(n):
+- a(n + 1)
+-
+- stats = utils.run_and_get_func_stats(a, 1)
+- fsa = utils.find_stat_by_name(stats, 'a')
+- fsb = utils.find_stat_by_name(stats, 'b')
+- fsc = utils.find_stat_by_name(stats, 'c')
+- self.assertEqual(fsa.ncall, 3)
+- self.assertEqual(fsa.nactualcall, 1)
+- self.assertEqual(fsa.ttot, 20)
+- self.assertEqual(fsa.tsub, 9)
+- self.assertEqual(fsb.ttot, 19)
+- self.assertEqual(fsb.tsub, 4)
+- self.assertEqual(fsc.ttot, 17)
+- self.assertEqual(fsc.tsub, 7)
+- cfsab = fsa.children[fsb]
+- cfsbc = fsb.children[fsc]
+- cfsca = fsc.children[fsa]
+- self.assertEqual(cfsab.ttot, 19)
+- self.assertEqual(cfsab.tsub, 4)
+- self.assertEqual(cfsbc.ttot, 17)
+- self.assertEqual(cfsbc.tsub, 7)
+- self.assertEqual(cfsca.ttot, 13)
+- self.assertEqual(cfsca.tsub, 8)
+-
+- def test_abcbca(self):
+- _timings = {"a_1": 10, "b_1": 9, "c_1": 7, "b_2": 4, "c_2": 2, "a_2": 1}
+- _yappi._set_test_timings(_timings)
+- self._ncall = 1
+-
+- def a():
+- if self._ncall == 1:
+- b()
+- else:
+- return
+-
+- def b():
+- c()
+-
+- def c():
+- if self._ncall == 1:
+- self._ncall += 1
+- b()
+- else:
+- a()
+-
+- stats = utils.run_and_get_func_stats(a)
+- fsa = utils.find_stat_by_name(stats, 'a')
+- fsb = utils.find_stat_by_name(stats, 'b')
+- fsc = utils.find_stat_by_name(stats, 'c')
+- cfsab = fsa.children[fsb]
+- cfsbc = fsb.children[fsc]
+- cfsca = fsc.children[fsa]
+- self.assertEqual(fsa.ttot, 10)
+- self.assertEqual(fsa.tsub, 2)
+- self.assertEqual(fsb.ttot, 9)
+- self.assertEqual(fsb.tsub, 4)
+- self.assertEqual(fsc.ttot, 7)
+- self.assertEqual(fsc.tsub, 4)
+- self.assertEqual(cfsab.ttot, 9)
+- self.assertEqual(cfsab.tsub, 2)
+- self.assertEqual(cfsbc.ttot, 7)
+- self.assertEqual(cfsbc.tsub, 4)
+- self.assertEqual(cfsca.ttot, 1)
+- self.assertEqual(cfsca.tsub, 1)
+- self.assertEqual(cfsca.ncall, 1)
+- self.assertEqual(cfsca.nactualcall, 0)
+-
+- def test_aabccb(self):
+- _timings = {
+- "a_1": 13,
+- "a_2": 11,
+- "b_1": 9,
+- "c_1": 5,
+- "c_2": 3,
+- "b_2": 1
+- }
+- _yappi._set_test_timings(_timings)
+- self._ncall = 1
+-
+- def a():
+- if self._ncall == 1:
+- self._ncall += 1
+- a()
+- else:
+- b()
+-
+- def b():
+- if self._ncall == 3:
+- return
+- else:
+- c()
+-
+- def c():
+- if self._ncall == 2:
+- self._ncall += 1
+- c()
+- else:
+- b()
+-
+- stats = utils.run_and_get_func_stats(a)
+- fsa = utils.find_stat_by_name(stats, 'a')
+- fsb = utils.find_stat_by_name(stats, 'b')
+- fsc = utils.find_stat_by_name(stats, 'c')
+- cfsaa = fsa.children[fsa.index]
+- cfsab = fsa.children[fsb]
+- cfsbc = fsb.children[fsc.full_name]
+- cfscc = fsc.children[fsc]
+- cfscb = fsc.children[fsb]
+- self.assertEqual(fsb.ttot, 9)
+- self.assertEqual(fsb.tsub, 5)
+- self.assertEqual(cfsbc.ttot, 5)
+- self.assertEqual(cfsbc.tsub, 2)
+- self.assertEqual(fsa.ttot, 13)
+- self.assertEqual(fsa.tsub, 4)
+- self.assertEqual(cfsab.ttot, 9)
+- self.assertEqual(cfsab.tsub, 4)
+- self.assertEqual(cfsaa.ttot, 11)
+- self.assertEqual(cfsaa.tsub, 2)
+- self.assertEqual(fsc.ttot, 5)
+- self.assertEqual(fsc.tsub, 4)
+-
+- def test_abaa(self):
+- _timings = {"a_1": 13, "b_1": 10, "a_2": 9, "a_3": 5}
+- _yappi._set_test_timings(_timings)
+-
+- self._ncall = 1
+-
+- def a():
+- if self._ncall == 1:
+- b()
+- elif self._ncall == 2:
+- self._ncall += 1
+- a()
+- else:
+- return
+-
+- def b():
+- self._ncall += 1
+- a()
+-
+- stats = utils.run_and_get_func_stats(a)
+- fsa = utils.find_stat_by_name(stats, 'a')
+- fsb = utils.find_stat_by_name(stats, 'b')
+- cfsaa = fsa.children[fsa]
+- cfsba = fsb.children[fsa]
+- self.assertEqual(fsb.ttot, 10)
+- self.assertEqual(fsb.tsub, 1)
+- self.assertEqual(fsa.ttot, 13)
+- self.assertEqual(fsa.tsub, 12)
+- self.assertEqual(cfsaa.ttot, 5)
+- self.assertEqual(cfsaa.tsub, 5)
+- self.assertEqual(cfsba.ttot, 9)
+- self.assertEqual(cfsba.tsub, 4)
+-
+- def test_aabb(self):
+- _timings = {"a_1": 13, "a_2": 10, "b_1": 9, "b_2": 5}
+- _yappi._set_test_timings(_timings)
+-
+- self._ncall = 1
+-
+- def a():
+- if self._ncall == 1:
+- self._ncall += 1
+- a()
+- elif self._ncall == 2:
+- b()
+- else:
+- return
+-
+- def b():
+- if self._ncall == 2:
+- self._ncall += 1
+- b()
+- else:
+- return
+-
+- stats = utils.run_and_get_func_stats(a)
+- fsa = utils.find_stat_by_name(stats, 'a')
+- fsb = utils.find_stat_by_name(stats, 'b')
+- cfsaa = fsa.children[fsa]
+- cfsab = fsa.children[fsb]
+- cfsbb = fsb.children[fsb]
+- self.assertEqual(fsa.ttot, 13)
+- self.assertEqual(fsa.tsub, 4)
+- self.assertEqual(fsb.ttot, 9)
+- self.assertEqual(fsb.tsub, 9)
+- self.assertEqual(cfsaa.ttot, 10)
+- self.assertEqual(cfsaa.tsub, 1)
+- self.assertEqual(cfsab.ttot, 9)
+- self.assertEqual(cfsab.tsub, 4)
+- self.assertEqual(cfsbb.ttot, 5)
+- self.assertEqual(cfsbb.tsub, 5)
+-
+- def test_abbb(self):
+- _timings = {"a_1": 13, "b_1": 10, "b_2": 6, "b_3": 1}
+- _yappi._set_test_timings(_timings)
+-
+- self._ncall = 1
+-
+- def a():
+- if self._ncall == 1:
+- b()
+-
+- def b():
+- if self._ncall == 3:
+- return
+- self._ncall += 1
+- b()
+-
+- stats = utils.run_and_get_func_stats(a)
+- fsa = utils.find_stat_by_name(stats, 'a')
+- fsb = utils.find_stat_by_name(stats, 'b')
+- cfsab = fsa.children[fsb]
+- cfsbb = fsb.children[fsb]
+- self.assertEqual(fsa.ttot, 13)
+- self.assertEqual(fsa.tsub, 3)
+- self.assertEqual(fsb.ttot, 10)
+- self.assertEqual(fsb.tsub, 10)
+- self.assertEqual(fsb.ncall, 3)
+- self.assertEqual(fsb.nactualcall, 1)
+- self.assertEqual(cfsab.ttot, 10)
+- self.assertEqual(cfsab.tsub, 4)
+- self.assertEqual(cfsbb.ttot, 6)
+- self.assertEqual(cfsbb.tsub, 6)
+- self.assertEqual(cfsbb.nactualcall, 0)
+- self.assertEqual(cfsbb.ncall, 2)
+-
+- def test_aaab(self):
+- _timings = {"a_1": 13, "a_2": 10, "a_3": 6, "b_1": 1}
+- _yappi._set_test_timings(_timings)
+-
+- self._ncall = 1
+-
+- def a():
+- if self._ncall == 3:
+- b()
+- return
+- self._ncall += 1
+- a()
+-
+- def b():
+- return
+-
+- stats = utils.run_and_get_func_stats(a)
+- fsa = utils.find_stat_by_name(stats, 'a')
+- fsb = utils.find_stat_by_name(stats, 'b')
+- cfsaa = fsa.children[fsa]
+- cfsab = fsa.children[fsb]
+- self.assertEqual(fsa.ttot, 13)
+- self.assertEqual(fsa.tsub, 12)
+- self.assertEqual(fsb.ttot, 1)
+- self.assertEqual(fsb.tsub, 1)
+- self.assertEqual(cfsaa.ttot, 10)
+- self.assertEqual(cfsaa.tsub, 9)
+- self.assertEqual(cfsab.ttot, 1)
+- self.assertEqual(cfsab.tsub, 1)
+-
+- def test_abab(self):
+- _timings = {"a_1": 13, "b_1": 10, "a_2": 6, "b_2": 1}
+- _yappi._set_test_timings(_timings)
+-
+- self._ncall = 1
+-
+- def a():
+- b()
+-
+- def b():
+- if self._ncall == 2:
+- return
+- self._ncall += 1
+- a()
+-
+- stats = utils.run_and_get_func_stats(a)
+- fsa = utils.find_stat_by_name(stats, 'a')
+- fsb = utils.find_stat_by_name(stats, 'b')
+- cfsab = fsa.children[fsb]
+- cfsba = fsb.children[fsa]
+- self.assertEqual(fsa.ttot, 13)
+- self.assertEqual(fsa.tsub, 8)
+- self.assertEqual(fsb.ttot, 10)
+- self.assertEqual(fsb.tsub, 5)
+- self.assertEqual(cfsab.ttot, 10)
+- self.assertEqual(cfsab.tsub, 5)
+- self.assertEqual(cfsab.ncall, 2)
+- self.assertEqual(cfsab.nactualcall, 1)
+- self.assertEqual(cfsba.ttot, 6)
+- self.assertEqual(cfsba.tsub, 5)
+-
+-
+-if __name__ == '__main__':
+- # import sys;sys.argv = ['', 'BasicUsage.test_run_as_script']
+- # import sys;sys.argv = ['', 'MultithreadedScenarios.test_subsequent_profile']
+- unittest.main()
++import os
++import sys
++import time
++import threading
++import unittest
++import yappi
++import _yappi
++import utils
++import multiprocessing
++import subprocess
++
++_counter = 0
++
++
++class BasicUsage(utils.YappiUnitTestCase):
++
++ def test_callback_function_int_return_overflow(self):
++ # this test is just here to check if any errors are generated, as the err
++ # is printed in C side, I did not include it here. THere are ways to test
++ # this deterministically, I did not bother
++ import ctypes
++
++ def _unsigned_overflow_margin():
++ return 2**(ctypes.sizeof(ctypes.c_void_p) * 8) - 1
++
++ def foo():
++ pass
++
++ #with utils.captured_output() as (out, err):
++ yappi.set_context_id_callback(_unsigned_overflow_margin)
++ yappi.set_tag_callback(_unsigned_overflow_margin)
++ yappi.start()
++ foo()
++
++ def test_issue60(self):
++
++ def foo():
++ buf = bytearray()
++ buf += b't' * 200
++ view = memoryview(buf)[10:]
++ view = view.tobytes()
++ del buf[:10] # this throws exception
++ return view
++
++ yappi.start(builtins=True)
++ foo()
++ self.assertTrue(
++ len(
++ yappi.get_func_stats(
++ filter_callback=lambda x: yappi.
++ func_matches(x, [memoryview.tobytes])
++ )
++ ) > 0
++ )
++ yappi.stop()
++
++ def test_issue54(self):
++
++ def _tag_cbk():
++ global _counter
++ _counter += 1
++ return _counter
++
++ def a():
++ pass
++
++ def b():
++ pass
++
++ yappi.set_tag_callback(_tag_cbk)
++ yappi.start()
++ a()
++ a()
++ a()
++ yappi.stop()
++ stats = yappi.get_func_stats()
++ self.assertEqual(stats.pop().ncall, 3) # aggregated if no tag is given
++ stats = yappi.get_func_stats(tag=1)
++
++ for i in range(1, 3):
++ stats = yappi.get_func_stats(tag=i)
++ stats = yappi.get_func_stats(
++ tag=i, filter_callback=lambda x: yappi.func_matches(x, [a])
++ )
++
++ stat = stats.pop()
++ self.assertEqual(stat.ncall, 1)
++
++ yappi.set_tag_callback(None)
++ yappi.clear_stats()
++ yappi.start()
++ b()
++ b()
++ stats = yappi.get_func_stats()
++ self.assertEqual(len(stats), 1)
++ stat = stats.pop()
++ self.assertEqual(stat.ncall, 2)
++
++ def test_filter(self):
++
++ def a():
++ pass
++
++ def b():
++ a()
++
++ def c():
++ b()
++
++ _TCOUNT = 5
++
++ ts = []
++ yappi.start()
++ for i in range(_TCOUNT):
++ t = threading.Thread(target=c)
++ t.start()
++ ts.append(t)
++
++ for t in ts:
++ t.join()
++
++ yappi.stop()
++
++ ctx_ids = []
++ for tstat in yappi.get_thread_stats():
++ if tstat.name == '_MainThread':
++ main_ctx_id = tstat.id
++ else:
++ ctx_ids.append(tstat.id)
++
++ fstats = yappi.get_func_stats(filter={"ctx_id": 9})
++ self.assertTrue(fstats.empty())
++ fstats = yappi.get_func_stats(
++ filter={
++ "ctx_id": main_ctx_id,
++ "name": "c"
++ }
++ ) # main thread
++ self.assertTrue(fstats.empty())
++
++ for i in ctx_ids:
++ fstats = yappi.get_func_stats(
++ filter={
++ "ctx_id": i,
++ "name": "a",
++ "ncall": 1
++ }
++ )
++ self.assertEqual(fstats.pop().ncall, 1)
++ fstats = yappi.get_func_stats(filter={"ctx_id": i, "name": "b"})
++ self.assertEqual(fstats.pop().ncall, 1)
++ fstats = yappi.get_func_stats(filter={"ctx_id": i, "name": "c"})
++ self.assertEqual(fstats.pop().ncall, 1)
++
++ yappi.clear_stats()
++ yappi.start(builtins=True)
++ time.sleep(0.1)
++ yappi.stop()
++ fstats = yappi.get_func_stats(filter={"module": "time"})
++ self.assertEqual(len(fstats), 1)
++
++ # invalid filters`
++ self.assertRaises(
++ Exception, yappi.get_func_stats, filter={'tag': "sss"}
++ )
++ self.assertRaises(
++ Exception, yappi.get_func_stats, filter={'ctx_id': "None"}
++ )
++
++ def test_filter_callback(self):
++
++ def a():
++ time.sleep(0.1)
++
++ def b():
++ a()
++
++ def c():
++ pass
++
++ def d():
++ pass
++
++ yappi.set_clock_type("wall")
++ yappi.start(builtins=True)
++ a()
++ b()
++ c()
++ d()
++ stats = yappi.get_func_stats(
++ filter_callback=lambda x: yappi.func_matches(x, [a, b])
++ )
++ #stats.print_all()
++ r1 = '''
++ tests/test_functionality.py:98 a 2 0.000000 0.200350 0.100175
++ tests/test_functionality.py:101 b 1 0.000000 0.120000 0.100197
++ '''
++ self.assert_traces_almost_equal(r1, stats)
++ self.assertEqual(len(stats), 2)
++ stats = yappi.get_func_stats(
++ filter_callback=lambda x: yappi.
++ module_matches(x, [sys.modules[__name__]])
++ )
++ r1 = '''
++ tests/test_functionality.py:98 a 2 0.000000 0.230130 0.115065
++ tests/test_functionality.py:101 b 1 0.000000 0.120000 0.109011
++ tests/test_functionality.py:104 c 1 0.000000 0.000002 0.000002
++ tests/test_functionality.py:107 d 1 0.000000 0.000001 0.000001
++ '''
++ self.assert_traces_almost_equal(r1, stats)
++ self.assertEqual(len(stats), 4)
++
++ stats = yappi.get_func_stats(
++ filter_callback=lambda x: yappi.func_matches(x, [time.sleep])
++ )
++ self.assertEqual(len(stats), 1)
++ r1 = '''
++ time.sleep 2 0.206804 0.220000 0.103402
++ '''
++ self.assert_traces_almost_equal(r1, stats)
++
++ def test_print_formatting(self):
++
++ def a():
++ pass
++
++ def b():
++ a()
++
++ func_cols = {
++ 1: ("name", 48),
++ 0: ("ncall", 5),
++ 2: ("tsub", 8),
++ }
++ thread_cols = {
++ 1: ("name", 48),
++ 0: ("ttot", 8),
++ }
++
++ yappi.start()
++ a()
++ b()
++ yappi.stop()
++ fs = yappi.get_func_stats()
++ cs = fs[1].children
++ ts = yappi.get_thread_stats()
++ #fs.print_all(out=sys.stderr, columns={1:("name", 70), })
++ #cs.print_all(out=sys.stderr, columns=func_cols)
++ #ts.print_all(out=sys.stderr, columns=thread_cols)
++ #cs.print_all(out=sys.stderr, columns={})
++
++ self.assertRaises(
++ yappi.YappiError, fs.print_all, columns={1: ("namee", 9)}
++ )
++ self.assertRaises(
++ yappi.YappiError, cs.print_all, columns={1: ("dd", 0)}
++ )
++ self.assertRaises(
++ yappi.YappiError, ts.print_all, columns={1: ("tidd", 0)}
++ )
++
++ def test_get_clock(self):
++ yappi.set_clock_type('cpu')
++ self.assertEqual('cpu', yappi.get_clock_type())
++ clock_info = yappi.get_clock_info()
++ self.assertTrue('api' in clock_info)
++ self.assertTrue('resolution' in clock_info)
++
++ yappi.set_clock_type('wall')
++ self.assertEqual('wall', yappi.get_clock_type())
++
++ t0 = yappi.get_clock_time()
++ time.sleep(0.1)
++ duration = yappi.get_clock_time() - t0
++ self.assertTrue(0.05 < duration < 0.3)
++
++ def test_profile_decorator(self):
++
++ def aggregate(func, stats):
++ fname = f"tests/{func.__name__}.profile"
++ try:
++ stats.add(fname)
++ except OSError:
++ pass
++ stats.save(fname)
++ raise Exception("messing around")
++
++ @yappi.profile(return_callback=aggregate)
++ def a(x, y):
++ if x + y == 25:
++ raise Exception("")
++ return x + y
++
++ def b():
++ pass
++
++ try:
++ os.remove(
++ "tests/a.profile"
++ ) # remove the one from prev test, if available
++ except:
++ pass
++
++ # global profile is on to mess things up
++ yappi.start()
++ b()
++
++ # assert functionality and call function at same time
++ try:
++ self.assertEqual(a(1, 2), 3)
++ except:
++ pass
++ try:
++ self.assertEqual(a(2, 5), 7)
++ except:
++ pass
++ try:
++ a(4, 21)
++ except:
++ pass
++ stats = yappi.get_func_stats().add("tests/a.profile")
++ fsa = utils.find_stat_by_name(stats, 'a')
++ self.assertEqual(fsa.ncall, 3)
++ self.assertEqual(len(stats), 1) # b() should be cleared out.
++
++ @yappi.profile(return_callback=aggregate)
++ def count_down_rec(n):
++ if n == 0:
++ return
++ count_down_rec(n - 1)
++
++ try:
++ os.remove(
++ "tests/count_down_rec.profile"
++ ) # remove the one from prev test, if available
++ except:
++ pass
++
++ try:
++ count_down_rec(4)
++ except:
++ pass
++ try:
++ count_down_rec(3)
++ except:
++ pass
++
++ stats = yappi.YFuncStats("tests/count_down_rec.profile")
++ fsrec = utils.find_stat_by_name(stats, 'count_down_rec')
++ self.assertEqual(fsrec.ncall, 9)
++ self.assertEqual(fsrec.nactualcall, 2)
++
++ def test_strip_dirs(self):
++
++ def a():
++ pass
++
++ stats = utils.run_and_get_func_stats(a, )
++ stats.strip_dirs()
++ fsa = utils.find_stat_by_name(stats, "a")
++ self.assertEqual(fsa.module, os.path.basename(fsa.module))
++
++ @unittest.skipIf(os.name == "nt", "do not run on Windows")
++ def test_run_as_script(self):
++ import re
++ p = subprocess.Popen(
++ ['yappi', os.path.join('./tests', 'run_as_script.py')],
++ stdout=subprocess.PIPE
++ )
++ out, err = p.communicate()
++ self.assertEqual(p.returncode, 0)
++ func_stats, thread_stats = re.split(
++ b'name\\s+id\\s+tid\\s+ttot\\s+scnt\\s*\n', out
++ )
++ self.assertTrue(b'FancyThread' in thread_stats)
++
++ def test_yappi_overhead(self):
++ LOOP_COUNT = 100000
++
++ def a():
++ pass
++
++ def b():
++ for i in range(LOOP_COUNT):
++ a()
++
++ t0 = time.time()
++ yappi.start()
++ b()
++ yappi.stop()
++ time_with_yappi = time.time() - t0
++ t0 = time.time()
++ b()
++ time_without_yappi = time.time() - t0
++ if time_without_yappi == 0:
++ time_without_yappi = 0.000001
++
++ # in latest v0.82, I calculated this as close to "7.0" in my machine.
++ # however, %83 of this overhead is coming from tickcount(). The other %17
++ # seems to have been evenly distributed to the internal bookkeeping
++ # structures/algorithms which seems acceptable. Note that our test only
++ # tests one function being profiled at-a-time in a short interval.
++ # profiling high number of functions in a small time
++ # is a different beast, (which is pretty unlikely in most applications)
++ # So as a conclusion: I cannot see any optimization window for Yappi that
++ # is worth implementing as we will only optimize %17 of the time.
++ sys.stderr.write("\r\nYappi puts %0.1f times overhead to the profiled application in average.\r\n" % \
++ (time_with_yappi / time_without_yappi))
++
++ def test_clear_stats_while_running(self):
++
++ def a():
++ pass
++
++ yappi.start()
++ a()
++ yappi.clear_stats()
++ a()
++ stats = yappi.get_func_stats()
++ fsa = utils.find_stat_by_name(stats, 'a')
++ self.assertEqual(fsa.ncall, 1)
++
++ def test_generator(self):
++
++ def _gen(n):
++ while (n > 0):
++ yield n
++ n -= 1
++
++ yappi.start()
++ for x in _gen(5):
++ pass
++ self.assertTrue(
++ yappi.convert2pstats(yappi.get_func_stats()) is not None
++ )
++
++ def test_slice_child_stats_and_strip_dirs(self):
++
++ def b():
++ for i in range(10000000):
++ pass
++
++ def a():
++ b()
++
++ yappi.start(builtins=True)
++ a()
++ stats = yappi.get_func_stats()
++ fsa = utils.find_stat_by_name(stats, 'a')
++ fsb = utils.find_stat_by_name(stats, 'b')
++ self.assertTrue(fsa.children[0:1] is not None)
++ prev_afullname = fsa.full_name
++ prev_bchildfullname = fsa.children[fsb].full_name
++ stats.strip_dirs()
++ self.assertTrue(len(prev_afullname) > len(fsa.full_name))
++ self.assertTrue(
++ len(prev_bchildfullname) > len(fsa.children[fsb].full_name)
++ )
++
++ def test_children_stat_functions(self):
++ _timings = {"a_1": 5, "b_1": 3, "c_1": 1}
++ _yappi._set_test_timings(_timings)
++
++ def b():
++ pass
++
++ def c():
++ pass
++
++ def a():
++ b()
++ c()
++
++ yappi.start()
++ a()
++ b() # non-child call
++ c() # non-child call
++ stats = yappi.get_func_stats()
++ fsa = utils.find_stat_by_name(stats, 'a')
++ childs_of_a = fsa.children.get().sort("tavg", "desc")
++ prev_item = None
++ for item in childs_of_a:
++ if prev_item:
++ self.assertTrue(prev_item.tavg > item.tavg)
++ prev_item = item
++ childs_of_a.sort("name", "desc")
++ prev_item = None
++ for item in childs_of_a:
++ if prev_item:
++ self.assertTrue(prev_item.name > item.name)
++ prev_item = item
++ childs_of_a.clear()
++ self.assertTrue(childs_of_a.empty())
++
++ def test_no_stats_different_clock_type_load(self):
++
++ def a():
++ pass
++
++ yappi.start()
++ a()
++ yappi.stop()
++ yappi.get_func_stats().save("tests/ystats1.ys")
++ yappi.clear_stats()
++ yappi.set_clock_type("WALL")
++ yappi.start()
++ yappi.stop()
++ stats = yappi.get_func_stats().add("tests/ystats1.ys")
++ fsa = utils.find_stat_by_name(stats, 'a')
++ self.assertTrue(fsa is not None)
++
++ def test_subsequent_profile(self):
++ _timings = {"a_1": 1, "b_1": 1}
++ _yappi._set_test_timings(_timings)
++
++ def a():
++ pass
++
++ def b():
++ pass
++
++ yappi.start()
++ a()
++ yappi.stop()
++ yappi.start()
++ b()
++ yappi.stop()
++ stats = yappi.get_func_stats()
++ fsa = utils.find_stat_by_name(stats, 'a')
++ fsb = utils.find_stat_by_name(stats, 'b')
++ self.assertTrue(fsa is not None)
++ self.assertTrue(fsb is not None)
++ self.assertEqual(fsa.ttot, 1)
++ self.assertEqual(fsb.ttot, 1)
++
++ def test_lambda(self):
++ f = lambda: time.sleep(0.3)
++ yappi.set_clock_type("wall")
++ yappi.start()
++ f()
++ stats = yappi.get_func_stats()
++ fsa = utils.find_stat_by_name(stats, '<lambda>')
++ self.assertTrue(fsa.ttot > 0.1)
++
++ def test_module_stress(self):
++ self.assertEqual(yappi.is_running(), False)
++
++ yappi.start()
++ yappi.clear_stats()
++ self.assertRaises(_yappi.error, yappi.set_clock_type, "wall")
++
++ yappi.stop()
++ yappi.clear_stats()
++ yappi.set_clock_type("cpu")
++ self.assertRaises(yappi.YappiError, yappi.set_clock_type, "dummy")
++ self.assertEqual(yappi.is_running(), False)
++ yappi.clear_stats()
++ yappi.clear_stats()
++
++ def test_stat_sorting(self):
++ _timings = {"a_1": 13, "b_1": 10, "a_2": 6, "b_2": 1}
++ _yappi._set_test_timings(_timings)
++
++ self._ncall = 1
++
++ def a():
++ b()
++
++ def b():
++ if self._ncall == 2:
++ return
++ self._ncall += 1
++ a()
++
++ stats = utils.run_and_get_func_stats(a)
++ stats = stats.sort("totaltime", "desc")
++ prev_stat = None
++ for stat in stats:
++ if prev_stat:
++ self.assertTrue(prev_stat.ttot >= stat.ttot)
++ prev_stat = stat
++ stats = stats.sort("totaltime", "asc")
++ prev_stat = None
++ for stat in stats:
++ if prev_stat:
++ self.assertTrue(prev_stat.ttot <= stat.ttot)
++ prev_stat = stat
++ stats = stats.sort("avgtime", "asc")
++ prev_stat = None
++ for stat in stats:
++ if prev_stat:
++ self.assertTrue(prev_stat.tavg <= stat.tavg)
++ prev_stat = stat
++ stats = stats.sort("name", "asc")
++ prev_stat = None
++ for stat in stats:
++ if prev_stat:
++ self.assertTrue(prev_stat.name <= stat.name)
++ prev_stat = stat
++ stats = stats.sort("subtime", "asc")
++ prev_stat = None
++ for stat in stats:
++ if prev_stat:
++ self.assertTrue(prev_stat.tsub <= stat.tsub)
++ prev_stat = stat
++
++ self.assertRaises(
++ yappi.YappiError, stats.sort, "invalid_func_sorttype_arg"
++ )
++ self.assertRaises(
++ yappi.YappiError, stats.sort, "totaltime",
++ "invalid_func_sortorder_arg"
++ )
++
++ def test_start_flags(self):
++ self.assertEqual(_yappi._get_start_flags(), None)
++ yappi.start()
++
++ def a():
++ pass
++
++ a()
++ self.assertEqual(_yappi._get_start_flags()["profile_builtins"], 0)
++ self.assertEqual(_yappi._get_start_flags()["profile_multicontext"], 1)
++ self.assertEqual(len(yappi.get_thread_stats()), 1)
++
++ def test_builtin_profiling(self):
++
++ def a():
++ time.sleep(0.4) # is a builtin function
++
++ yappi.set_clock_type('wall')
++
++ yappi.start(builtins=True)
++ a()
++ stats = yappi.get_func_stats()
++ fsa = utils.find_stat_by_name(stats, 'sleep')
++ self.assertTrue(fsa is not None)
++ self.assertTrue(fsa.ttot > 0.3)
++ yappi.stop()
++ yappi.clear_stats()
++
++ def a():
++ pass
++
++ yappi.start()
++ t = threading.Thread(target=a)
++ t.start()
++ t.join()
++ stats = yappi.get_func_stats()
++
++ def test_singlethread_profiling(self):
++ yappi.set_clock_type('wall')
++
++ def a():
++ time.sleep(0.2)
++
++ class Worker1(threading.Thread):
++
++ def a(self):
++ time.sleep(0.3)
++
++ def run(self):
++ self.a()
++
++ yappi.start(profile_threads=False)
++
++ c = Worker1()
++ c.start()
++ c.join()
++ a()
++ stats = yappi.get_func_stats()
++ fsa1 = utils.find_stat_by_name(stats, 'Worker1.a')
++ fsa2 = utils.find_stat_by_name(stats, 'a')
++ self.assertTrue(fsa1 is None)
++ self.assertTrue(fsa2 is not None)
++ self.assertTrue(fsa2.ttot > 0.1)
++
++ def test_run(self):
++
++ def profiled():
++ pass
++
++ yappi.clear_stats()
++ try:
++ with yappi.run():
++ profiled()
++ stats = yappi.get_func_stats()
++ finally:
++ yappi.clear_stats()
++
++ self.assertIsNotNone(utils.find_stat_by_name(stats, 'profiled'))
++
++ def test_run_recursive(self):
++
++ def profiled():
++ pass
++
++ def not_profiled():
++ pass
++
++ yappi.clear_stats()
++ try:
++ with yappi.run():
++ with yappi.run():
++ profiled()
++ # Profiling stopped here
++ not_profiled()
++ stats = yappi.get_func_stats()
++ finally:
++ yappi.clear_stats()
++
++ self.assertIsNotNone(utils.find_stat_by_name(stats, 'profiled'))
++ self.assertIsNone(utils.find_stat_by_name(stats, 'not_profiled'))
++
++
++class StatSaveScenarios(utils.YappiUnitTestCase):
++
++ def test_pstats_conversion(self):
++
++ def pstat_id(fs):
++ return (fs.module, fs.lineno, fs.name)
++
++ def a():
++ d()
++
++ def b():
++ d()
++
++ def c():
++ pass
++
++ def d():
++ pass
++
++ _timings = {"a_1": 12, "b_1": 7, "c_1": 5, "d_1": 2}
++ _yappi._set_test_timings(_timings)
++ stats = utils.run_and_get_func_stats(a, )
++ stats.strip_dirs()
++ stats.save("tests/a1.pstats", type="pstat")
++ fsa_pid = pstat_id(utils.find_stat_by_name(stats, "a"))
++ fsd_pid = pstat_id(utils.find_stat_by_name(stats, "d"))
++ yappi.clear_stats()
++ _yappi._set_test_timings(_timings)
++ stats = utils.run_and_get_func_stats(a, )
++ stats.strip_dirs()
++ stats.save("tests/a2.pstats", type="pstat")
++ yappi.clear_stats()
++ _yappi._set_test_timings(_timings)
++ stats = utils.run_and_get_func_stats(b, )
++ stats.strip_dirs()
++ stats.save("tests/b1.pstats", type="pstat")
++ fsb_pid = pstat_id(utils.find_stat_by_name(stats, "b"))
++ yappi.clear_stats()
++ _yappi._set_test_timings(_timings)
++ stats = utils.run_and_get_func_stats(c, )
++ stats.strip_dirs()
++ stats.save("tests/c1.pstats", type="pstat")
++ fsc_pid = pstat_id(utils.find_stat_by_name(stats, "c"))
++
++ # merge saved stats and check pstats values are correct
++ import pstats
++ p = pstats.Stats(
++ 'tests/a1.pstats', 'tests/a2.pstats', 'tests/b1.pstats',
++ 'tests/c1.pstats'
++ )
++ p.strip_dirs()
++ # ct = ttot, tt = tsub
++ (cc, nc, tt, ct, callers) = p.stats[fsa_pid]
++ self.assertEqual(cc, nc, 2)
++ self.assertEqual(tt, 20)
++ self.assertEqual(ct, 24)
++ (cc, nc, tt, ct, callers) = p.stats[fsd_pid]
++ self.assertEqual(cc, nc, 3)
++ self.assertEqual(tt, 6)
++ self.assertEqual(ct, 6)
++ self.assertEqual(len(callers), 2)
++ (cc, nc, tt, ct) = callers[fsa_pid]
++ self.assertEqual(cc, nc, 2)
++ self.assertEqual(tt, 4)
++ self.assertEqual(ct, 4)
++ (cc, nc, tt, ct) = callers[fsb_pid]
++ self.assertEqual(cc, nc, 1)
++ self.assertEqual(tt, 2)
++ self.assertEqual(ct, 2)
++
++ def test_merge_stats(self):
++ _timings = {
++ "a_1": 15,
++ "b_1": 14,
++ "c_1": 12,
++ "d_1": 10,
++ "e_1": 9,
++ "f_1": 7,
++ "g_1": 6,
++ "h_1": 5,
++ "i_1": 1
++ }
++ _yappi._set_test_timings(_timings)
++
++ def a():
++ b()
++
++ def b():
++ c()
++
++ def c():
++ d()
++
++ def d():
++ e()
++
++ def e():
++ f()
++
++ def f():
++ g()
++
++ def g():
++ h()
++
++ def h():
++ i()
++
++ def i():
++ pass
++
++ yappi.start()
++ a()
++ a()
++ yappi.stop()
++ stats = yappi.get_func_stats()
++ self.assertRaises(
++ NotImplementedError, stats.save, "", "INVALID_SAVE_TYPE"
++ )
++ stats.save("tests/ystats2.ys")
++ yappi.clear_stats()
++ _yappi._set_test_timings(_timings)
++ yappi.start()
++ a()
++ stats = yappi.get_func_stats().add("tests/ystats2.ys")
++ fsa = utils.find_stat_by_name(stats, "a")
++ fsb = utils.find_stat_by_name(stats, "b")
++ fsc = utils.find_stat_by_name(stats, "c")
++ fsd = utils.find_stat_by_name(stats, "d")
++ fse = utils.find_stat_by_name(stats, "e")
++ fsf = utils.find_stat_by_name(stats, "f")
++ fsg = utils.find_stat_by_name(stats, "g")
++ fsh = utils.find_stat_by_name(stats, "h")
++ fsi = utils.find_stat_by_name(stats, "i")
++ self.assertEqual(fsa.ttot, 45)
++ self.assertEqual(fsa.ncall, 3)
++ self.assertEqual(fsa.nactualcall, 3)
++ self.assertEqual(fsa.tsub, 3)
++ self.assertEqual(fsa.children[fsb].ttot, fsb.ttot)
++ self.assertEqual(fsa.children[fsb].tsub, fsb.tsub)
++ self.assertEqual(fsb.children[fsc].ttot, fsc.ttot)
++ self.assertEqual(fsb.children[fsc].tsub, fsc.tsub)
++ self.assertEqual(fsc.tsub, 6)
++ self.assertEqual(fsc.children[fsd].ttot, fsd.ttot)
++ self.assertEqual(fsc.children[fsd].tsub, fsd.tsub)
++ self.assertEqual(fsd.children[fse].ttot, fse.ttot)
++ self.assertEqual(fsd.children[fse].tsub, fse.tsub)
++ self.assertEqual(fse.children[fsf].ttot, fsf.ttot)
++ self.assertEqual(fse.children[fsf].tsub, fsf.tsub)
++ self.assertEqual(fsf.children[fsg].ttot, fsg.ttot)
++ self.assertEqual(fsf.children[fsg].tsub, fsg.tsub)
++ self.assertEqual(fsg.ttot, 18)
++ self.assertEqual(fsg.tsub, 3)
++ self.assertEqual(fsg.children[fsh].ttot, fsh.ttot)
++ self.assertEqual(fsg.children[fsh].tsub, fsh.tsub)
++ self.assertEqual(fsh.ttot, 15)
++ self.assertEqual(fsh.tsub, 12)
++ self.assertEqual(fsh.tavg, 5)
++ self.assertEqual(fsh.children[fsi].ttot, fsi.ttot)
++ self.assertEqual(fsh.children[fsi].tsub, fsi.tsub)
++ #stats.debug_print()
++
++ def test_merge_multithreaded_stats(self):
++ import _yappi
++ timings = {"a_1": 2, "b_1": 1}
++ _yappi._set_test_timings(timings)
++
++ def a():
++ pass
++
++ def b():
++ pass
++
++ yappi.start()
++ t = threading.Thread(target=a)
++ t.start()
++ t.join()
++ t = threading.Thread(target=b)
++ t.start()
++ t.join()
++ yappi.get_func_stats().save("tests/ystats1.ys")
++ yappi.clear_stats()
++ _yappi._set_test_timings(timings)
++ self.assertEqual(len(yappi.get_func_stats()), 0)
++ self.assertEqual(len(yappi.get_thread_stats()), 1)
++ t = threading.Thread(target=a)
++ t.start()
++ t.join()
++
++ self.assertEqual(_yappi._get_start_flags()["profile_builtins"], 0)
++ self.assertEqual(_yappi._get_start_flags()["profile_multicontext"], 1)
++ yappi.get_func_stats().save("tests/ystats2.ys")
++
++ stats = yappi.YFuncStats([
++ "tests/ystats1.ys",
++ "tests/ystats2.ys",
++ ])
++ fsa = utils.find_stat_by_name(stats, "a")
++ fsb = utils.find_stat_by_name(stats, "b")
++ self.assertEqual(fsa.ncall, 2)
++ self.assertEqual(fsb.ncall, 1)
++ self.assertEqual(fsa.tsub, fsa.ttot, 4)
++ self.assertEqual(fsb.tsub, fsb.ttot, 1)
++
++ def test_merge_load_different_clock_types(self):
++ yappi.start(builtins=True)
++
++ def a():
++ b()
++
++ def b():
++ c()
++
++ def c():
++ pass
++
++ t = threading.Thread(target=a)
++ t.start()
++ t.join()
++ yappi.get_func_stats().sort("name", "asc").save("tests/ystats1.ys")
++ yappi.stop()
++ yappi.clear_stats()
++ yappi.start(builtins=False)
++ t = threading.Thread(target=a)
++ t.start()
++ t.join()
++ yappi.get_func_stats().save("tests/ystats2.ys")
++ yappi.stop()
++ self.assertRaises(_yappi.error, yappi.set_clock_type, "wall")
++ yappi.clear_stats()
++ yappi.set_clock_type("wall")
++ yappi.start()
++ t = threading.Thread(target=a)
++ t.start()
++ t.join()
++ yappi.get_func_stats().save("tests/ystats3.ys")
++ self.assertRaises(
++ yappi.YappiError,
++ yappi.YFuncStats().add("tests/ystats1.ys").add, "tests/ystats3.ys"
++ )
++ stats = yappi.YFuncStats(["tests/ystats1.ys",
++ "tests/ystats2.ys"]).sort("name")
++ fsa = utils.find_stat_by_name(stats, "a")
++ fsb = utils.find_stat_by_name(stats, "b")
++ fsc = utils.find_stat_by_name(stats, "c")
++ self.assertEqual(fsa.ncall, 2)
++ self.assertEqual(fsa.ncall, fsb.ncall, fsc.ncall)
++
++ def test_merge_aabab_aabbc(self):
++ _timings = {
++ "a_1": 15,
++ "a_2": 14,
++ "b_1": 12,
++ "a_3": 10,
++ "b_2": 9,
++ "c_1": 4
++ }
++ _yappi._set_test_timings(_timings)
++
++ def a():
++ if self._ncall == 1:
++ self._ncall += 1
++ a()
++ elif self._ncall == 5:
++ self._ncall += 1
++ a()
++ else:
++ b()
++
++ def b():
++ if self._ncall == 2:
++ self._ncall += 1
++ a()
++ elif self._ncall == 6:
++ self._ncall += 1
++ b()
++ elif self._ncall == 7:
++ c()
++ else:
++ return
++
++ def c():
++ pass
++
++ self._ncall = 1
++ stats = utils.run_and_get_func_stats(a, )
++ stats.save("tests/ystats1.ys")
++ yappi.clear_stats()
++ _yappi._set_test_timings(_timings)
++ #stats.print_all()
++
++ self._ncall = 5
++ stats = utils.run_and_get_func_stats(a, )
++ stats.save("tests/ystats2.ys")
++
++ #stats.print_all()
++
++ def a(): # same name but another function(code object)
++ pass
++
++ yappi.start()
++ a()
++ stats = yappi.get_func_stats().add(
++ ["tests/ystats1.ys", "tests/ystats2.ys"]
++ )
++ #stats.print_all()
++ self.assertEqual(len(stats), 4)
++
++ fsa = None
++ for stat in stats:
++ if stat.name == "a" and stat.ttot == 45:
++ fsa = stat
++ break
++ self.assertTrue(fsa is not None)
++
++ self.assertEqual(fsa.ncall, 7)
++ self.assertEqual(fsa.nactualcall, 3)
++ self.assertEqual(fsa.ttot, 45)
++ self.assertEqual(fsa.tsub, 10)
++ fsb = utils.find_stat_by_name(stats, "b")
++ fsc = utils.find_stat_by_name(stats, "c")
++ self.assertEqual(fsb.ncall, 6)
++ self.assertEqual(fsb.nactualcall, 3)
++ self.assertEqual(fsb.ttot, 36)
++ self.assertEqual(fsb.tsub, 27)
++ self.assertEqual(fsb.tavg, 6)
++ self.assertEqual(fsc.ttot, 8)
++ self.assertEqual(fsc.tsub, 8)
++ self.assertEqual(fsc.tavg, 4)
++ self.assertEqual(fsc.nactualcall, fsc.ncall, 2)
++
++
++class MultithreadedScenarios(utils.YappiUnitTestCase):
++
++ def test_issue_32(self):
++ '''
++ Start yappi from different thread and we get Internal Error(15) as
++ the current_ctx_id() called while enumerating the threads in start()
++ and as it does not swap to the enumerated ThreadState* the THreadState_GetDict()
++ returns wrong object and thus sets an invalid id for the _ctx structure.
++
++ When this issue happens multiple Threads have same tid as the internal ts_ptr
++ will be same for different contexts. So, let's see if that happens
++ '''
++
++ def foo():
++ time.sleep(0.2)
++
++ def bar():
++ time.sleep(0.1)
++
++ def thread_func():
++ yappi.set_clock_type("wall")
++ yappi.start()
++
++ bar()
++
++ t = threading.Thread(target=thread_func)
++ t.start()
++ t.join()
++
++ foo()
++
++ yappi.stop()
++
++ thread_ids = set()
++ for tstat in yappi.get_thread_stats():
++ self.assertTrue(tstat.tid not in thread_ids)
++ thread_ids.add(tstat.tid)
++
++ def test_subsequent_profile(self):
++ WORKER_COUNT = 5
++
++ def a():
++ pass
++
++ def b():
++ pass
++
++ def c():
++ pass
++
++ _timings = {
++ "a_1": 3,
++ "b_1": 2,
++ "c_1": 1,
++ }
++
++ yappi.start()
++
++ def g():
++ pass
++
++ g()
++ yappi.stop()
++ yappi.clear_stats()
++ _yappi._set_test_timings(_timings)
++ yappi.start()
++
++ _dummy = []
++ for i in range(WORKER_COUNT):
++ t = threading.Thread(target=a)
++ t.start()
++ t.join()
++ for i in range(WORKER_COUNT):
++ t = threading.Thread(target=b)
++ t.start()
++ _dummy.append(t)
++ t.join()
++ for i in range(WORKER_COUNT):
++ t = threading.Thread(target=a)
++ t.start()
++ t.join()
++ for i in range(WORKER_COUNT):
++ t = threading.Thread(target=c)
++ t.start()
++ t.join()
++ yappi.stop()
++ yappi.start()
++
++ def f():
++ pass
++
++ f()
++ stats = yappi.get_func_stats()
++ fsa = utils.find_stat_by_name(stats, 'a')
++ fsb = utils.find_stat_by_name(stats, 'b')
++ fsc = utils.find_stat_by_name(stats, 'c')
++ self.assertEqual(fsa.ncall, 10)
++ self.assertEqual(fsb.ncall, 5)
++ self.assertEqual(fsc.ncall, 5)
++ self.assertEqual(fsa.ttot, fsa.tsub, 30)
++ self.assertEqual(fsb.ttot, fsb.tsub, 10)
++ self.assertEqual(fsc.ttot, fsc.tsub, 5)
++
++ # MACOSx optimizes by only creating one worker thread
++ self.assertTrue(len(yappi.get_thread_stats()) >= 2)
++
++ def test_basic(self):
++ yappi.set_clock_type('wall')
++
++ def dummy():
++ pass
++
++ def a():
++ time.sleep(0.2)
++
++ class Worker1(threading.Thread):
++
++ def a(self):
++ time.sleep(0.3)
++
++ def run(self):
++ self.a()
++
++ yappi.start(builtins=False, profile_threads=True)
++
++ c = Worker1()
++ c.start()
++ c.join()
++ a()
++ stats = yappi.get_func_stats()
++ fsa1 = utils.find_stat_by_name(stats, 'Worker1.a')
++ fsa2 = utils.find_stat_by_name(stats, 'a')
++ self.assertTrue(fsa1 is not None)
++ self.assertTrue(fsa2 is not None)
++ self.assertTrue(fsa1.ttot > 0.2)
++ self.assertTrue(fsa2.ttot > 0.1)
++ tstats = yappi.get_thread_stats()
++ self.assertEqual(len(tstats), 2)
++ tsa = utils.find_stat_by_name(tstats, 'Worker1')
++ tsm = utils.find_stat_by_name(tstats, '_MainThread')
++ dummy() # call dummy to force ctx name to be retrieved again.
++ self.assertTrue(tsa is not None)
++ # TODO: I put dummy() to fix below, remove the comments after a while.
++ self.assertTrue( # FIX: I see this fails sometimes?
++ tsm is not None,
++ f"Could not find \"_MainThread\". Found: {', '.join(utils.get_stat_names(tstats))}")
++
++ def test_ctx_stats(self):
++ from threading import Thread
++ DUMMY_WORKER_COUNT = 5
++ yappi.start()
++
++ class DummyThread(Thread):
++ pass
++
++ def dummy():
++ pass
++
++ def dummy_worker():
++ pass
++
++ for i in range(DUMMY_WORKER_COUNT):
++ t = DummyThread(target=dummy_worker)
++ t.start()
++ t.join()
++ yappi.stop()
++ stats = yappi.get_thread_stats()
++ tsa = utils.find_stat_by_name(stats, "DummyThread")
++ self.assertTrue(tsa is not None)
++ yappi.clear_stats()
++ time.sleep(1.0)
++ _timings = {
++ "a_1": 6,
++ "b_1": 5,
++ "c_1": 3,
++ "d_1": 1,
++ "a_2": 4,
++ "b_2": 3,
++ "c_2": 2,
++ "d_2": 1
++ }
++ _yappi._set_test_timings(_timings)
++
++ class Thread1(Thread):
++ pass
++
++ class Thread2(Thread):
++ pass
++
++ def a():
++ b()
++
++ def b():
++ c()
++
++ def c():
++ d()
++
++ def d():
++ time.sleep(0.6)
++
++ yappi.set_clock_type("wall")
++ yappi.start()
++ t1 = Thread1(target=a)
++ t1.start()
++ t2 = Thread2(target=a)
++ t2.start()
++ t1.join()
++ t2.join()
++ stats = yappi.get_thread_stats()
++
++ # the fist clear_stats clears the context table?
++ tsa = utils.find_stat_by_name(stats, "DummyThread")
++ self.assertTrue(tsa is None)
++
++ tst1 = utils.find_stat_by_name(stats, "Thread1")
++ tst2 = utils.find_stat_by_name(stats, "Thread2")
++ tsmain = utils.find_stat_by_name(stats, "_MainThread")
++ dummy() # call dummy to force ctx name to be retrieved again.
++ self.assertTrue(len(stats) == 3)
++ self.assertTrue(tst1 is not None)
++ self.assertTrue(tst2 is not None)
++ # TODO: I put dummy() to fix below, remove the comments after a while.
++ self.assertTrue( # FIX: I see this fails sometimes
++ tsmain is not None,
++ f"Could not find \"_MainThread\". Found: {', '.join(utils.get_stat_names(stats))}")
++ self.assertTrue(1.0 > tst2.ttot >= 0.5)
++ self.assertTrue(1.0 > tst1.ttot >= 0.5)
++
++ # test sorting of the ctx stats
++ stats = stats.sort("totaltime", "desc")
++ prev_stat = None
++ for stat in stats:
++ if prev_stat:
++ self.assertTrue(prev_stat.ttot >= stat.ttot)
++ prev_stat = stat
++ stats = stats.sort("totaltime", "asc")
++ prev_stat = None
++ for stat in stats:
++ if prev_stat:
++ self.assertTrue(prev_stat.ttot <= stat.ttot)
++ prev_stat = stat
++ stats = stats.sort("schedcount", "desc")
++ prev_stat = None
++ for stat in stats:
++ if prev_stat:
++ self.assertTrue(prev_stat.sched_count >= stat.sched_count)
++ prev_stat = stat
++ stats = stats.sort("name", "desc")
++ prev_stat = None
++ for stat in stats:
++ if prev_stat:
++ self.assertTrue(prev_stat.name.lower() >= stat.name.lower())
++ prev_stat = stat
++ self.assertRaises(
++ yappi.YappiError, stats.sort, "invalid_thread_sorttype_arg"
++ )
++ self.assertRaises(
++ yappi.YappiError, stats.sort, "invalid_thread_sortorder_arg"
++ )
++
++ def test_ctx_stats_cpu(self):
++
++ def get_thread_name():
++ try:
++ return threading.current_thread().name
++ except AttributeError:
++ return "Anonymous"
++
++ def burn_cpu(sec):
++ t0 = yappi.get_clock_time()
++ elapsed = 0
++ while (elapsed < sec):
++ for _ in range(1000):
++ pass
++ elapsed = yappi.get_clock_time() - t0
++
++ def test():
++
++ ts = []
++ for i in (0.01, 0.05, 0.1):
++ t = threading.Thread(target=burn_cpu, args=(i, ))
++ t.name = f"burn_cpu-{str(i)}"
++ t.start()
++ ts.append(t)
++ for t in ts:
++ t.join()
++
++ yappi.set_clock_type("cpu")
++ yappi.set_context_name_callback(get_thread_name)
++
++ yappi.start()
++
++ test()
++
++ yappi.stop()
++
++ tstats = yappi.get_thread_stats()
++ r1 = '''
++ burn_cpu-0.1 3 123145356058624 0.100105 8
++ burn_cpu-0.05 2 123145361313792 0.050149 8
++ burn_cpu-0.01 1 123145356058624 0.010127 2
++ MainThread 0 4321620864 0.001632 6
++ '''
++ self.assert_ctx_stats_almost_equal(r1, tstats)
++
++ def test_producer_consumer_with_queues(self):
++ # we currently just stress yappi, no functionality test is done here.
++ yappi.start()
++ from queue import Queue
++ from threading import Thread
++ WORKER_THREAD_COUNT = 50
++ WORK_ITEM_COUNT = 2000
++
++ def worker():
++ while True:
++ item = q.get()
++ # do the work with item
++ q.task_done()
++
++ q = Queue()
++ for i in range(WORKER_THREAD_COUNT):
++ t = Thread(target=worker)
++ t.daemon = True
++ t.start()
++
++ for item in range(WORK_ITEM_COUNT):
++ q.put(item)
++ q.join() # block until all tasks are done
++ #yappi.get_func_stats().sort("callcount").print_all()
++ yappi.stop()
++
++ def test_temporary_lock_waiting(self):
++ yappi.start()
++ _lock = threading.Lock()
++
++ def worker():
++ _lock.acquire()
++ try:
++ time.sleep(1.0)
++ finally:
++ _lock.release()
++
++ t1 = threading.Thread(target=worker)
++ t2 = threading.Thread(target=worker)
++ t1.start()
++ t2.start()
++ t1.join()
++ t2.join()
++ #yappi.get_func_stats().sort("callcount").print_all()
++ yappi.stop()
++
++ @unittest.skipIf(os.name != "posix", "requires Posix compliant OS")
++ def test_signals_with_blocking_calls(self):
++ import signal, os, time
++
++ # just to verify if signal is handled correctly and stats/yappi are not corrupted.
++ def handler(signum, frame):
++ raise Exception("Signal handler executed!")
++
++ yappi.start()
++ signal.signal(signal.SIGALRM, handler)
++ signal.alarm(1)
++ self.assertRaises(Exception, time.sleep, 2)
++ stats = yappi.get_func_stats()
++ fsh = utils.find_stat_by_name(stats, "handler")
++ self.assertTrue(fsh is not None)
++
++ def test_concurrent_futures(self):
++ yappi.start()
++ from concurrent.futures import ThreadPoolExecutor
++ with ThreadPoolExecutor(max_workers=5) as executor:
++ f = executor.submit(pow, 5, 2)
++ self.assertEqual(f.result(), 25)
++ time.sleep(1.0)
++ yappi.stop()
++
++ def test_barrier(self):
++ yappi.start()
++ b = threading.Barrier(2, timeout=1)
++
++ def worker():
++ try:
++ b.wait()
++ except threading.BrokenBarrierError:
++ pass
++ except Exception:
++ raise Exception("BrokenBarrierError not raised")
++
++ t1 = threading.Thread(target=worker)
++ t1.start()
++ #b.wait()
++ t1.join()
++ yappi.stop()
++
++
++class NonRecursiveFunctions(utils.YappiUnitTestCase):
++
++ def test_abcd(self):
++ _timings = {"a_1": 6, "b_1": 5, "c_1": 3, "d_1": 1}
++ _yappi._set_test_timings(_timings)
++
++ def a():
++ b()
++
++ def b():
++ c()
++
++ def c():
++ d()
++
++ def d():
++ pass
++
++ stats = utils.run_and_get_func_stats(a)
++ fsa = utils.find_stat_by_name(stats, 'a')
++ fsb = utils.find_stat_by_name(stats, 'b')
++ fsc = utils.find_stat_by_name(stats, 'c')
++ fsd = utils.find_stat_by_name(stats, 'd')
++ cfsab = fsa.children[fsb]
++ cfsbc = fsb.children[fsc]
++ cfscd = fsc.children[fsd]
++
++ self.assertEqual(fsa.ttot, 6)
++ self.assertEqual(fsa.tsub, 1)
++ self.assertEqual(fsb.ttot, 5)
++ self.assertEqual(fsb.tsub, 2)
++ self.assertEqual(fsc.ttot, 3)
++ self.assertEqual(fsc.tsub, 2)
++ self.assertEqual(fsd.ttot, 1)
++ self.assertEqual(fsd.tsub, 1)
++ self.assertEqual(cfsab.ttot, 5)
++ self.assertEqual(cfsab.tsub, 2)
++ self.assertEqual(cfsbc.ttot, 3)
++ self.assertEqual(cfsbc.tsub, 2)
++ self.assertEqual(cfscd.ttot, 1)
++ self.assertEqual(cfscd.tsub, 1)
++
++ def test_stop_in_middle(self):
++ _timings = {"a_1": 6, "b_1": 4}
++ _yappi._set_test_timings(_timings)
++
++ def a():
++ b()
++ yappi.stop()
++
++ def b():
++ time.sleep(0.2)
++
++ yappi.start()
++ a()
++ stats = yappi.get_func_stats()
++ fsa = utils.find_stat_by_name(stats, 'a')
++ fsb = utils.find_stat_by_name(stats, 'b')
++
++ self.assertEqual(fsa.ncall, 1)
++ self.assertEqual(fsa.nactualcall, 0)
++ self.assertEqual(fsa.ttot, 0) # no call_leave called
++ self.assertEqual(fsa.tsub, 0) # no call_leave called
++ self.assertEqual(fsb.ttot, 4)
++
++
++class RecursiveFunctions(utils.YappiUnitTestCase):
++
++ def test_fibonacci(self):
++
++ def fib(n):
++ if n > 1:
++ return fib(n - 1) + fib(n - 2)
++ else:
++ return n
++
++ stats = utils.run_and_get_func_stats(fib, 22)
++ fs = utils.find_stat_by_name(stats, 'fib')
++ self.assertEqual(fs.ncall, 57313)
++ self.assertEqual(fs.ttot, fs.tsub)
++
++ def test_abcadc(self):
++ _timings = {
++ "a_1": 20,
++ "b_1": 19,
++ "c_1": 17,
++ "a_2": 13,
++ "d_1": 12,
++ "c_2": 10,
++ "a_3": 5
++ }
++ _yappi._set_test_timings(_timings)
++
++ def a(n):
++ if n == 3:
++ return
++ if n == 1 + 1:
++ d(n)
++ else:
++ b(n)
++
++ def b(n):
++ c(n)
++
++ def c(n):
++ a(n + 1)
++
++ def d(n):
++ c(n)
++
++ stats = utils.run_and_get_func_stats(a, 1)
++ fsa = utils.find_stat_by_name(stats, 'a')
++ fsb = utils.find_stat_by_name(stats, 'b')
++ fsc = utils.find_stat_by_name(stats, 'c')
++ fsd = utils.find_stat_by_name(stats, 'd')
++ self.assertEqual(fsa.ncall, 3)
++ self.assertEqual(fsa.nactualcall, 1)
++ self.assertEqual(fsa.ttot, 20)
++ self.assertEqual(fsa.tsub, 7)
++ self.assertEqual(fsb.ttot, 19)
++ self.assertEqual(fsb.tsub, 2)
++ self.assertEqual(fsc.ttot, 17)
++ self.assertEqual(fsc.tsub, 9)
++ self.assertEqual(fsd.ttot, 12)
++ self.assertEqual(fsd.tsub, 2)
++ cfsca = fsc.children[fsa]
++ self.assertEqual(cfsca.nactualcall, 0)
++ self.assertEqual(cfsca.ncall, 2)
++ self.assertEqual(cfsca.ttot, 13)
++ self.assertEqual(cfsca.tsub, 6)
++
++ def test_aaaa(self):
++ _timings = {"d_1": 9, "d_2": 7, "d_3": 3, "d_4": 2}
++ _yappi._set_test_timings(_timings)
++
++ def d(n):
++ if n == 3:
++ return
++ d(n + 1)
++
++ stats = utils.run_and_get_func_stats(d, 0)
++ fsd = utils.find_stat_by_name(stats, 'd')
++ self.assertEqual(fsd.ncall, 4)
++ self.assertEqual(fsd.nactualcall, 1)
++ self.assertEqual(fsd.ttot, 9)
++ self.assertEqual(fsd.tsub, 9)
++ cfsdd = fsd.children[fsd]
++ self.assertEqual(cfsdd.ttot, 7)
++ self.assertEqual(cfsdd.tsub, 7)
++ self.assertEqual(cfsdd.ncall, 3)
++ self.assertEqual(cfsdd.nactualcall, 0)
++
++ def test_abcabc(self):
++ _timings = {
++ "a_1": 20,
++ "b_1": 19,
++ "c_1": 17,
++ "a_2": 13,
++ "b_2": 11,
++ "c_2": 9,
++ "a_3": 6
++ }
++ _yappi._set_test_timings(_timings)
++
++ def a(n):
++ if n == 3:
++ return
++ else:
++ b(n)
++
++ def b(n):
++ c(n)
++
++ def c(n):
++ a(n + 1)
++
++ stats = utils.run_and_get_func_stats(a, 1)
++ fsa = utils.find_stat_by_name(stats, 'a')
++ fsb = utils.find_stat_by_name(stats, 'b')
++ fsc = utils.find_stat_by_name(stats, 'c')
++ self.assertEqual(fsa.ncall, 3)
++ self.assertEqual(fsa.nactualcall, 1)
++ self.assertEqual(fsa.ttot, 20)
++ self.assertEqual(fsa.tsub, 9)
++ self.assertEqual(fsb.ttot, 19)
++ self.assertEqual(fsb.tsub, 4)
++ self.assertEqual(fsc.ttot, 17)
++ self.assertEqual(fsc.tsub, 7)
++ cfsab = fsa.children[fsb]
++ cfsbc = fsb.children[fsc]
++ cfsca = fsc.children[fsa]
++ self.assertEqual(cfsab.ttot, 19)
++ self.assertEqual(cfsab.tsub, 4)
++ self.assertEqual(cfsbc.ttot, 17)
++ self.assertEqual(cfsbc.tsub, 7)
++ self.assertEqual(cfsca.ttot, 13)
++ self.assertEqual(cfsca.tsub, 8)
++
++ def test_abcbca(self):
++ _timings = {"a_1": 10, "b_1": 9, "c_1": 7, "b_2": 4, "c_2": 2, "a_2": 1}
++ _yappi._set_test_timings(_timings)
++ self._ncall = 1
++
++ def a():
++ if self._ncall == 1:
++ b()
++ else:
++ return
++
++ def b():
++ c()
++
++ def c():
++ if self._ncall == 1:
++ self._ncall += 1
++ b()
++ else:
++ a()
++
++ stats = utils.run_and_get_func_stats(a)
++ fsa = utils.find_stat_by_name(stats, 'a')
++ fsb = utils.find_stat_by_name(stats, 'b')
++ fsc = utils.find_stat_by_name(stats, 'c')
++ cfsab = fsa.children[fsb]
++ cfsbc = fsb.children[fsc]
++ cfsca = fsc.children[fsa]
++ self.assertEqual(fsa.ttot, 10)
++ self.assertEqual(fsa.tsub, 2)
++ self.assertEqual(fsb.ttot, 9)
++ self.assertEqual(fsb.tsub, 4)
++ self.assertEqual(fsc.ttot, 7)
++ self.assertEqual(fsc.tsub, 4)
++ self.assertEqual(cfsab.ttot, 9)
++ self.assertEqual(cfsab.tsub, 2)
++ self.assertEqual(cfsbc.ttot, 7)
++ self.assertEqual(cfsbc.tsub, 4)
++ self.assertEqual(cfsca.ttot, 1)
++ self.assertEqual(cfsca.tsub, 1)
++ self.assertEqual(cfsca.ncall, 1)
++ self.assertEqual(cfsca.nactualcall, 0)
++
++ def test_aabccb(self):
++ _timings = {
++ "a_1": 13,
++ "a_2": 11,
++ "b_1": 9,
++ "c_1": 5,
++ "c_2": 3,
++ "b_2": 1
++ }
++ _yappi._set_test_timings(_timings)
++ self._ncall = 1
++
++ def a():
++ if self._ncall == 1:
++ self._ncall += 1
++ a()
++ else:
++ b()
++
++ def b():
++ if self._ncall == 3:
++ return
++ else:
++ c()
++
++ def c():
++ if self._ncall == 2:
++ self._ncall += 1
++ c()
++ else:
++ b()
++
++ stats = utils.run_and_get_func_stats(a)
++ fsa = utils.find_stat_by_name(stats, 'a')
++ fsb = utils.find_stat_by_name(stats, 'b')
++ fsc = utils.find_stat_by_name(stats, 'c')
++ cfsaa = fsa.children[fsa.index]
++ cfsab = fsa.children[fsb]
++ cfsbc = fsb.children[fsc.full_name]
++ cfscc = fsc.children[fsc]
++ cfscb = fsc.children[fsb]
++ self.assertEqual(fsb.ttot, 9)
++ self.assertEqual(fsb.tsub, 5)
++ self.assertEqual(cfsbc.ttot, 5)
++ self.assertEqual(cfsbc.tsub, 2)
++ self.assertEqual(fsa.ttot, 13)
++ self.assertEqual(fsa.tsub, 4)
++ self.assertEqual(cfsab.ttot, 9)
++ self.assertEqual(cfsab.tsub, 4)
++ self.assertEqual(cfsaa.ttot, 11)
++ self.assertEqual(cfsaa.tsub, 2)
++ self.assertEqual(fsc.ttot, 5)
++ self.assertEqual(fsc.tsub, 4)
++
++ def test_abaa(self):
++ _timings = {"a_1": 13, "b_1": 10, "a_2": 9, "a_3": 5}
++ _yappi._set_test_timings(_timings)
++
++ self._ncall = 1
++
++ def a():
++ if self._ncall == 1:
++ b()
++ elif self._ncall == 2:
++ self._ncall += 1
++ a()
++ else:
++ return
++
++ def b():
++ self._ncall += 1
++ a()
++
++ stats = utils.run_and_get_func_stats(a)
++ fsa = utils.find_stat_by_name(stats, 'a')
++ fsb = utils.find_stat_by_name(stats, 'b')
++ cfsaa = fsa.children[fsa]
++ cfsba = fsb.children[fsa]
++ self.assertEqual(fsb.ttot, 10)
++ self.assertEqual(fsb.tsub, 1)
++ self.assertEqual(fsa.ttot, 13)
++ self.assertEqual(fsa.tsub, 12)
++ self.assertEqual(cfsaa.ttot, 5)
++ self.assertEqual(cfsaa.tsub, 5)
++ self.assertEqual(cfsba.ttot, 9)
++ self.assertEqual(cfsba.tsub, 4)
++
++ def test_aabb(self):
++ _timings = {"a_1": 13, "a_2": 10, "b_1": 9, "b_2": 5}
++ _yappi._set_test_timings(_timings)
++
++ self._ncall = 1
++
++ def a():
++ if self._ncall == 1:
++ self._ncall += 1
++ a()
++ elif self._ncall == 2:
++ b()
++ else:
++ return
++
++ def b():
++ if self._ncall == 2:
++ self._ncall += 1
++ b()
++ else:
++ return
++
++ stats = utils.run_and_get_func_stats(a)
++ fsa = utils.find_stat_by_name(stats, 'a')
++ fsb = utils.find_stat_by_name(stats, 'b')
++ cfsaa = fsa.children[fsa]
++ cfsab = fsa.children[fsb]
++ cfsbb = fsb.children[fsb]
++ self.assertEqual(fsa.ttot, 13)
++ self.assertEqual(fsa.tsub, 4)
++ self.assertEqual(fsb.ttot, 9)
++ self.assertEqual(fsb.tsub, 9)
++ self.assertEqual(cfsaa.ttot, 10)
++ self.assertEqual(cfsaa.tsub, 1)
++ self.assertEqual(cfsab.ttot, 9)
++ self.assertEqual(cfsab.tsub, 4)
++ self.assertEqual(cfsbb.ttot, 5)
++ self.assertEqual(cfsbb.tsub, 5)
++
++ def test_abbb(self):
++ _timings = {"a_1": 13, "b_1": 10, "b_2": 6, "b_3": 1}
++ _yappi._set_test_timings(_timings)
++
++ self._ncall = 1
++
++ def a():
++ if self._ncall == 1:
++ b()
++
++ def b():
++ if self._ncall == 3:
++ return
++ self._ncall += 1
++ b()
++
++ stats = utils.run_and_get_func_stats(a)
++ fsa = utils.find_stat_by_name(stats, 'a')
++ fsb = utils.find_stat_by_name(stats, 'b')
++ cfsab = fsa.children[fsb]
++ cfsbb = fsb.children[fsb]
++ self.assertEqual(fsa.ttot, 13)
++ self.assertEqual(fsa.tsub, 3)
++ self.assertEqual(fsb.ttot, 10)
++ self.assertEqual(fsb.tsub, 10)
++ self.assertEqual(fsb.ncall, 3)
++ self.assertEqual(fsb.nactualcall, 1)
++ self.assertEqual(cfsab.ttot, 10)
++ self.assertEqual(cfsab.tsub, 4)
++ self.assertEqual(cfsbb.ttot, 6)
++ self.assertEqual(cfsbb.tsub, 6)
++ self.assertEqual(cfsbb.nactualcall, 0)
++ self.assertEqual(cfsbb.ncall, 2)
++
++ def test_aaab(self):
++ _timings = {"a_1": 13, "a_2": 10, "a_3": 6, "b_1": 1}
++ _yappi._set_test_timings(_timings)
++
++ self._ncall = 1
++
++ def a():
++ if self._ncall == 3:
++ b()
++ return
++ self._ncall += 1
++ a()
++
++ def b():
++ return
++
++ stats = utils.run_and_get_func_stats(a)
++ fsa = utils.find_stat_by_name(stats, 'a')
++ fsb = utils.find_stat_by_name(stats, 'b')
++ cfsaa = fsa.children[fsa]
++ cfsab = fsa.children[fsb]
++ self.assertEqual(fsa.ttot, 13)
++ self.assertEqual(fsa.tsub, 12)
++ self.assertEqual(fsb.ttot, 1)
++ self.assertEqual(fsb.tsub, 1)
++ self.assertEqual(cfsaa.ttot, 10)
++ self.assertEqual(cfsaa.tsub, 9)
++ self.assertEqual(cfsab.ttot, 1)
++ self.assertEqual(cfsab.tsub, 1)
++
++ def test_abab(self):
++ _timings = {"a_1": 13, "b_1": 10, "a_2": 6, "b_2": 1}
++ _yappi._set_test_timings(_timings)
++
++ self._ncall = 1
++
++ def a():
++ b()
++
++ def b():
++ if self._ncall == 2:
++ return
++ self._ncall += 1
++ a()
++
++ stats = utils.run_and_get_func_stats(a)
++ fsa = utils.find_stat_by_name(stats, 'a')
++ fsb = utils.find_stat_by_name(stats, 'b')
++ cfsab = fsa.children[fsb]
++ cfsba = fsb.children[fsa]
++ self.assertEqual(fsa.ttot, 13)
++ self.assertEqual(fsa.tsub, 8)
++ self.assertEqual(fsb.ttot, 10)
++ self.assertEqual(fsb.tsub, 5)
++ self.assertEqual(cfsab.ttot, 10)
++ self.assertEqual(cfsab.tsub, 5)
++ self.assertEqual(cfsab.ncall, 2)
++ self.assertEqual(cfsab.nactualcall, 1)
++ self.assertEqual(cfsba.ttot, 6)
++ self.assertEqual(cfsba.tsub, 5)
++
++
++if __name__ == '__main__':
++ # import sys;sys.argv = ['', 'BasicUsage.test_run_as_script']
++ # import sys;sys.argv = ['', 'MultithreadedScenarios.test_subsequent_profile']
++ unittest.main()
+--
+2.34.1
+