Clément Stéphane Mischler
email: mischler@ceremade.dauphine.fr

Clément Mouhot
email: c.mouhot@dpmms.cam.ac.uk

Partial Differential Equations/Probability About Kac's Program in Kinetic Theory

teaching and research institutions in France or abroad, or from public or private research centers.

nombre de particules. Le but de ce programme est de comprendre la notion de ≪ chaos moléculaire ≫ dans un cadre plus simple que celui de la dynamique complète des particules, ainsi que de donner une justification microscopique au théorème H (croissance de l'entropie) et au processus de retour vers l'équilibre. Nous renvoyons à la version complète pour l'introduction de l'équation de Boltzmann [START_REF] Boltzmann | Weitere Studien über das Wärme gleichgenicht unfer Gasmoläkuler[END_REF], des processus de saut considérés, ainsi que pour les définitions de la notion de chaos et de la distance de Wasserstein W 1 .

Théorème 1 (Résumé des résultats principaux) On considère d ≥ 2 et une distribution initiale f 0 ∈ P (R d ) ∩ L ∞ à support compact ou possédant suffisamment de moments polynômiaux bornés, et que l'on suppose centrée sans perte de généralité. Soit f t la solution correspondante de l'équation de Boltzmann [START_REF] Boltzmann | Weitere Studien über das Wärme gleichgenicht unfer Gasmoläkuler[END_REF] pour les sphères dures ou les molécules maxwelliennes (sans troncature angulaire), et soit f N t la solution du processus de saut à N particules correspondant, avec pour donnée initiale f N 0 : soit (a) la tensorisation de f ⊗N 0 de f 0 , ou (b) la tensorisée f ⊗N 0 conditionnée à la sphère S N (définie par [START_REF] Boltzmann | Lectures on gas theory[END_REF]).

(i) Propagation de chaos quantifiée et uniforme en temps : On considère le cas (a) où

f N 0 = f ⊗N 0 . Alors ∀ N ≥ 1, ∀ 1 ≤ ℓ ≤ N, sup t≥0 W 1 Π ℓ f N t , f ⊗ℓ t ℓ ≤ α(N )
avec α(N ) → 0 lorsque N → ∞, et où Π ℓ g N désigne la ℓ-marginale d'une probabilité g sur (R d ) N . (ii) Propagation du chaos entropique : On considère le cas (b) où f N 0 est conditionnée à S N . Alors la solution est entropie-chaotique :

∀ t ≥ 0, 1 N H f N t |γ N → H (f t |γ) , N → +∞
(voir (3) pour les définitions des fonctionnelles H) avec γ la probabilité gaussienne centrée d'énergie E égale à l'énergie de f 0 et γ N la mesure de probabilité uniforme sur S N . Cela fournit une dérivation microscopique du théorème H dans ce contexte. (iii) Taux de relaxation indépendants du nombre de particules : On considère le cas (b) où f N 0 est conditionnée à S N . Alors

∀ N ≥ 1, ∀ 1 ≤ ℓ ≤ N, ∀ t ≥ 0, W 1 Π ℓ f N t , Π ℓ γ N ℓ ≤ β(t) avec β(t) → 0, t → 0.
Dans le cas des molécules maxwelliennes, et si la donnée initiale possède une information de Fisher finie (voir (4)), on prouve également

∀ N ≥ 1, 0 ≤ 1 N H f N t |γ N ≤ β(t) avec β(t) → 0, t → 0.

Introduction

Motivated by the understanding of irreversibility and "molecular chaos" in the Boltzmann equation [13,1,2] Mark Kac proposed in 1956 [START_REF] Kac | Foundations of kinetic theory[END_REF][START_REF] Kac | Probability and related topics in physical sciences[END_REF] the simpler and seemingly more tractable question of deriving the spatially homogeneous Boltzmann equation from a many-particle jump process, and he introduced a rigorous notion of molecular chaos in this context. He proposed the first proof of the propagation of chaos along time for a simplified collision process for which series expansions of the solution are available, and he showed how the many-particle limit rigorously follows from it. A key motivation for Kac was the microscopic derivation of the H-theorem (monotonicity of the Boltzmann entropy) in this context which has remained open so far. Kac also raised the natural question of connecting the asymptotic behavior of the many-particle process and that of the limit nonlinear equation. In his mind this program was to be achieved by understanding dissipativity at the level of the linear many-particle jump process and he insisted on the importance of estimating its rate of relaxation. This has motivated beautiful works on this "Kac's spectral gap problem" [START_REF] Janvresse | Spectral gap for Kac's model of Boltzmann equation[END_REF][START_REF] Maslen | The eigenvalues of Kac's master equation[END_REF][START_REF] Carlen | Determination of the spectral gap for Kac's master equation and related stochastic evolution[END_REF], but so far this strategy has proved unsuccessful in obtaining relaxation rates which do not degenerate in the many-particle limit, see the interesting discussion in [START_REF] Carlen | Entropy and chaos in the Kac model[END_REF].

In this Note we present the main results in [START_REF] Mischler | Kac's Program in Kinetic Theory[END_REF]. In this paper we develop a quantitative theory of meanfield limit which strongly relies on detailed knowledge of the limit nonlinear equation, rather than on detailed properties of the many-particle Markov process. As the main outcome of this theory we prove uniform in time quantitative propagation of chaos as well as propagation of entropic chaos, and we prove relaxation rates independent of the number of particles (measured in Wasserstein distance and relative entropy). All this is done for the two important realistic and achetypal models of collision, namely hard spheres and true (without cutoff) Maxwell molecules. This provides a first complete answer to the questions raised by Kac, however our answer is an "inverse" answer in the sense that our methodology is "top-down" from the limit equation to the many-particle system rather than "bottom-up" as was proposed by Kac.

The Boltzmann equation

The spatially homogeneous Boltzmann equation reads

∂f ∂t (t, v) = Q(f, f )(t, v), v ∈ R d , t ≥ 0, (1)
where d ≥ 2 is the dimension and Q is defined by

Q(g, f )(v) = 1 2 R d ×S d-1 B(|v -v * |, cos θ) (g ′ * f ′ + g ′ f ′ * -g * f -gf * ) dv * dσ,
where we have used the shorthands

f = f (v), f ′ = f (v ′ ), g * = g(v * ) and g ′ * = g(v ′ * ). Moreover, v ′ and v ′ * are parametrized by v ′ = v + v * 2 + |v -v * | 2 σ, v ′ * = v + v * 2 - |v -v * | 2 σ, σ ∈ S d-1 . Finally, θ ∈ [0, π] is the deviation angle between v ′ -v ′ * and v -v * defined by cos θ = σ • û, u = v -v * , û = u/|u|,
and B is the Boltzmann collision kernel determined by physics (related to the cross-section

Σ(v -v * , σ) by the formula B = |v -v * | Σ).
Boltzmann's collision operator has the fundamental properties of conserving mass, momentum and energy

d dt R d f φ(v) dv = R d Q(f, f ) φ(v) dv = 0, φ(v) = 1, v, |v| 2 ,
and satisfying the so-called Boltzmann's H theorem which writes (at the formal level)

- d dt H(f ) := - d dt R d f log f dv = - d dt H(f |γ) := - d dt R d f log f γ dv = - R d Q(f, f ) log(f ) dv ≥ 0
where γ is the gaussian with same mass, momentum and energy as f . Note that the H functional is the opposite of the physical entropy. We shall consider the folllowing important physical cases for B (see [START_REF] Mischler | Kac's Program in Kinetic Theory[END_REF] for more details)

B = Γ(|v -v * |) b(cos θ) with Γ, b ≥ 0
given by one of the following formulas:

(1) (HS) Hard Spheres collision kernel:

B(|v -v * |, cos θ) = Γ(|v -v * |) = C |v -v * | for some C > 0.
(2) (tMM) True Maxwell Molecules collision kernel:

B(|v -v * |, cos θ) = b(cos θ) ∼ θ∼0 C θ -5/2
for some C > 0.

(

) (GMM) Grad's cutoff Maxwell Molecules kernel: B(|v -v * |, cos θ) = 1. 3

Kac's program

Kac's jump process runs as follows: consider N particles with velocities v 1 , . . . , v N ∈ R d . Compute random times for each pair of particles (v i , v j ) following an exponential law with parameter Γ(|v i -v j |), take the smallest, and perform a collision

(v i , v j ) → (v * i , v * j )
given by a random choice of a direction parameter whose law is related to b(cos θ), then recommence. This process can be considered on R dN , however it leaves invariant some submanifolds of R dN (depending on the number of conserved quantities during collision) and can be restricted to them. In the original simplified model of Kac d = 1 (scalar velocities), the direction parameter is θ with collision rule

v * i = v i cos θ + v j sin θ, v * j = -v i sin θ + v j sin θ
and the collision process can be restricted to S N -1 ( √ EN ) the sphere with radius √ EN , for any given value of the energy E. For the more realistic hard spheres of Maxwell molecules models, d = 3, the direction parameter is σ ∈ S 2 with collision rule

v * i = v i + v j 2 + |v i -v j | 2 σ, v * j = v i + v j 2 - |v i -v j | 2 σ with σ • (v i -v j ) |v i -v j | = cos θ
and the collision process can be restricted to the sphere

S N := S dN -1 √ N E ∩ {v 1 + . . . + v N = 0} . (2)
Kac formulated the notion of propagation of chaos that we shall now explain. Consider a sequence (f N ) N ≥1 of probabilities on R dN : the sequence is said f -chaotic if f N ∼ f ⊗N when N → ∞ for some given oneparticle probability f on R d . The meaning of this convergence is the following: convergence in the weak measure topology for any marginal depending on a finite number of variables. This is a low correlation assumption. It was clear since Boltzmann that in the case when the joint probability density f N of the N -particle system is tensorized during some time interval into N copies f ⊗N of a 1-particle probability density, then the latter would satisfy the limit nonlinear Boltzmann equation during this time interval. In general interactions between particles prevent any possibility of propagation of the "tensorization" property, however if the weaker property of chaoticity can be propagated along time in the correct scaling limit it is sufficient for deriving the limit equation. Kac hence proved the propagation of chaos (with no rate) on the simplified collision rule above (with B = 1). His beautiful combinatorial argument is based on an infinite series "tree" representation of the solution according to the collision history of particles, and a Leibniz derivation-like formula for the iterated N -particle operator acting on tensor products.

He then raises several questions that we schematize as follows:

(i) The first one is concerned with the restriction of the models as compared to realistic collision processes: can one prove propagation of chaos for the hard spheres collision process?

(ii) Following closely the spirit of the previous question it seems to us very natural to ask whether one can prove propagation of chaos for the true Maxwell molecules collision process? This is related with long-range interactions and fractional derivative operators.

(iii) Kac conjectures the propagation of the convergence of the N -particle H-functional towards the limit H-functional of the solution to the limit equation along time in the mean-field limit. Since the latter always decays for a many-particle jump process, in his words "If the above steps could be made rigorous we would have a thoroughly satisfactory justification of Boltzmann's Htheorem."

(iv) He finally discusses the relaxation times, with the goal of deriving relaxation times of the limit equation from the many-particle system. This imposes to have estimates independent of the number of particles on this relaxation times: can one prove relaxation times independent of the number of particles in Wasserstein distance and/or relative entropy?

This paper is concerned with solving the four questions outlined above.

Main results

A few words on previous results

For Boltzmann collision processes, Kac [START_REF] Kac | Foundations of kinetic theory[END_REF] has proved the propagation of chaos in the case of his baby one-dimensional model. It was generalized by McKean [START_REF] Jr | An exponential formula for solving Boltmann's equation for a Maxwellian gas[END_REF] to the Boltzmann collision operator for "Maxwell molecules with cutoff", i.e. the case (GMM) above (see also [START_REF] Tanaka | Some probabilistic problems in the spatially homogeneous Boltzmann equation[END_REF] for a partial result for non-cutoff Maxwell molecules). Grünbaum [START_REF] Grünbaum | Propagation of chaos for the Boltzmann equation[END_REF] then proposed in a very compact and abstract paper another method for dealing with hard spheres, based on the Trotter-Kato formula for semigroups and a clever functional framework. Unfortunately this paper was incomplete for several reasons (see the discussion in [START_REF] Mischler | Kac's Program in Kinetic Theory[END_REF]). A completely different approach was undertaken by Sznitman in the eighties [START_REF] Sznitman | Équations de type de Boltzmann, spatialement homogènes[END_REF][START_REF] Sznitman | Topics in propagation of chaos[END_REF] and he gave a full proof of propagation of chaos for hard spheres by a probabilistic (non-constructive) approach. Let us also emphasize several quantitative results on a finite time interval by Graham, Méléard and Fournier for Maxwell molecules models [START_REF] Graham | Stochastic particle approximations for generalized Boltzmann models and convergence estimates[END_REF][START_REF] Fournier | Monte Carlo approximations and fluctuations for 2D Boltzmann equations without cutoff[END_REF][START_REF] Fournier | A stochastic particle numerical method for 3D Boltzmann equation without cutoff[END_REF], and the works on the so-called "Kac's spectral gap problem" [START_REF] Janvresse | Spectral gap for Kac's model of Boltzmann equation[END_REF][START_REF] Maslen | The eigenvalues of Kac's master equation[END_REF][START_REF] Carlen | Determination of the spectral gap for Kac's master equation and related stochastic evolution[END_REF][START_REF] Carlen | Entropy and chaos in the Kac model[END_REF].

Main results

Theorem 2.1 (Summary of the main results) Consider some initial distribution f 0 ∈ P (R d ) ∩ L ∞ with compact support or polynomial moment bounds, taken to be centered without loss of generality. Consider the corresponding solution f t to the spatially homogeneous Boltzmann equation for hard spheres of Maxwell molecules, and the solution f N t of the corresponding Kac's jump process starting either (a) from the tensorization f ⊗N 0 of f 0 or (b) the latter conditionned to S N (defined in ( 2)). The results in [START_REF] Mischler | Kac's Program in Kinetic Theory[END_REF] can be classified into three main statements:

(i) Quantitative uniform in time propagation of chaos (with any number of marginals):

∀ N ≥ 1, ∀ 1 ≤ ℓ ≤ N, sup t≥0 W 1 Π ℓ f N t , f ⊗ℓ t ℓ ≤ α(N )
for some α(N ) → 0 as N → ∞, where Π ℓ g N stands for the ℓ-marginal of an N -particle distribution g N , and where W 1 is the Wasserstein distance between probabilities on R dℓ :

W 1 (p 1 , p 2 ) := sup [ϕ] Lip(R dℓ ) ≤1 R dℓ ϕ (dp 1 -dp 2 )
where [•] Lip denotes the Lipschitz semi-norm.

In the case (a) f N 0 = f ⊗N 0 one has moreover explicit power law rate (for Maxwell molecules) or logarithmic rate (for hard spheres) estimates on α.

(ii) Propagation of entropic chaos: Consider the case (b) where the initial datum of the many-particle system is restricted to S N . Then if the initial datum is entropy-chaotic in the sense

1 N H f N 0 |γ N → H (f 0 |γ) , N → +∞ with H f N 0 |γ N := S N df N 0 dγ N log df N 0 dγ N γ N (dV ) and H (f 0 |γ) := R d f 0 log f 0 γ dv (3)
and where γ is the gaussian equilibrium with energy E and γ N is the uniform probability measure on S N , then the solution is also entropy-chaotic for any later time:

∀ t ≥ 0, 1 N H f N t |γ N → H (f t |γ) , N → +∞.
Since our f N 0 is entropy-chaotic, this proves the derivation of the H-theorem in this context.

(iii) Quantitative estimates on relaxation times, independent of the number of particles: Consider the case (b) where the initial datum of the many-particle system is restricted to S N . Then

∀ N ≥ 1, ∀ 1 ≤ ℓ ≤ N, ∀ t ≥ 0, W 1 Π ℓ f N t , Π ℓ γ N ℓ ≤ β(t) with β(t) → 0, t → 0.
Moreover in the case of Maxwell molecules, and assuming moreover that the Fisher information of the initial datum f 0 is finite:

R d |∇ v f 0 | 2 f 0 dv < +∞, (4)
the following estimate also holds:

∀ N ≥ 1, 0 ≤ 1 N H f N t |γ N ≤ β(t) with β(t) → 0, t → 0.

A few words on the methods and proofs

Let us briefly explain some ideas underlying the result Theorem 2.1-(i). The other results are then obtained on the basis of this key estimate, combined with the other latest results obtained in this field.

-We aim at reducing the problem to a stability analysis when approximating a linear semigroup. To this purpose a key idea is to compare the linear N -particle dual evolution in C b (R dN ) with the (linear!) push-forward evolution associated with the limit equation. -This push-forward semigroup is defined as follows: if S NL t denotes the nonlinear semigroup of (1), this push-forward semigroup is defined on P

(P (R d )) by T ∞ t [Φ](f ) = Φ(S NL t (f )).
-In order to make this comparison between semigroups, we use the empirical measure µ N V = ( N i=1 δ vi )/N in order to embed the dynamics in P (R dN ) into a dynamics in P (P (R d )).

-One then considers the following term to be estimated

S N t (f N 0 ) -S N L t (f 0 ) ⊗N , ϕ ⊗ 1 ⊗N -ℓ
for some test function ϕ only depending on ℓ variables. -The approximation of these marginals by empirical measure estimates yields a first error term on the N -particle semigroup

S N t (f N 0 ), ϕ ⊗ 1 ⊗N -ℓ -S N t (f N 0 ), R ℓ ϕ • µ N V with R ℓ ϕ (f ) := R dℓ ϕ f ⊗ℓ (dv 1 . . . dv ℓ )
which is controlled by combinatorial arguments, and then a second error term

f N 0 , (T ∞ t R ℓ ϕ ) • µ N V ) -(S N L t (f 0 )) ⊗ℓ , ϕ
which is controlled thanks a stability for measure solutions of the limit equation. -Finally there remains the most important term where the two dynamics are effectively compared

f N 0 , T N t (R ℓ ϕ • µ N V ) -f N 0 , (T ∞ t R ℓ ϕ ) • µ N V )
. This term is controlled by using (1) a quantitative argument à la Trotter-Kato in order to express the difference of semigroups in terms of the difference of their generators G N and G ∞ , (2) a consistency estimate between those generators, (3) a stability estimate on the limit equation.

-There is a loss of derivative in the consistency estimate in the sense of differentiable functions acting on P (R d ), which lead us to develop a differential calculus on this space adapted to our purpose. -The stability estimate means, once translated on the original nonlinear semigroup S NL t of (1), a propagation of a bound C 1+θ (P (R d )) on S NL t . The role played by such stability estimates is a key novelty of our study. Proving them for Boltzmann is also one of the most technical aspects of [START_REF] Mischler | Kac's Program in Kinetic Theory[END_REF]. -There are many possible choices of distances on the space of probabilities (total variation but also many non-equivalent weak measure distances), and it is a crucial point that our method is flexible enough to allow for many such different choices adapted to the equations it is applied to.


Romain Delamare

Benoit Baudry

Sudipto Ghosh

Shashank Gupta

Yves Le Traon

An Approach for Testing Pointcut Descriptors in AspectJ

Keywords: Reliab. 0, 0:0-0 Prepared using stvrauth.cls Reliab. 0, 0:0-0 Prepared using stvrauth.cls 0, 0:0-0 Prepared using stvrauth.cls

come   L'archive ouverte pluridisciplinaire

develop test cases for PCDs. This paper proposes an approach for testing PCDs based on AdviceTracer to capture faults that miss join points or that match unintended join points.

AdviceTracer is evaluated in terms of its effectiveness and utility for writing test cases that target faults in AspectJ PCDs. The study is performed as a comparison between test cases that use JUnit only and test cases that use AdviceTracer with JUnit. Previous work [START_REF] Delamare | A test-driven approach to developing pointcut descriptors in AspectJ[END_REF] reported an initial evaluation of AdviceTracer. However, it only considered the ability of test cases that use AdviceTracer to detect faults. Moreover, the subjects used in the study had a small number of PCDs and AdviceTracer was not compared with another technique. This paper reports a comparison using the HealthWatcher system that has 93 classes and 19 PCDs. HealthWatcher is a popular benchmark and has been used in several research studies on aspect-oriented software development. For example, Soares et al. [START_REF] Soares | Distribution and persistence as aspects[END_REF] evaluate the impact of AspectJ to implement persistence aspects in HealthWatcher and Hoffman et al. [START_REF] Hoffman | Towards reusable components with aspects: an empirical study on modularity and obliviousness[END_REF] evaluate their proposal for explicit join points.

The empirical study considers two questions. First, the study evaluates the ability of AdviceTracer to decrease the effort for writing the test cases. This effort is evaluated through the number of test cases, the complexity of the test cases, and the precision of the oracle. The second question evaluates the ability of AdviceTracer to improve the fault revealing abilities of test cases. A mutation analysis is performed and the number of mutants killed, the time taken to kill them, and the number of equivalent mutants detected is compared for the two approaches. This study reveals that test cases written with AdviceTracer are simpler than pure JUnit test cases (shorter test scenario, more compact oracles, less lines of code) and detect more faults. Section 2 presents aspect-oriented programming (AOP) and the challenges to test PCDs. Section 3 details the approach and AdviceTracer, the tool that supports it. Section 4 presents AjMutator, a tool for the mutation analysis of AspectJ PCDs that was used to validate the approach. Section 5 describes an empirical study that was conducted to compare the approach with traditional JUnit testing of PCDs. Section 6 presents the related work. Finally Section 7 concludes this paper.

Testing Pointcut Descriptors in AspectJ

Aspect-Oriented Programming (AOP) is a programming paradigm that encapsulates crosscutting concerns into modules called aspects. This work uses AspectJ, a popular and mature implementation of AOP for Java. This section first presents the core concepts of AspectJ through a running example.

Then, it illustrates the consequence of a fault in the pointcut descriptors (PCDs) and the difficulties in using JUnit to test these PCDs.

Bank Example

AOP is illustrated through a simple example. Figure 1 shows the UML class diagram of a simple bank system. The Bank class has methods to log in, create or delete an account, and a method to get an account with its number. The class Account has two methods to withdraw or deposit money. public aspect AccessControl { pointcut controlledAccess(): execution( * Account. * (int)); @AdviceName("AccessControl") before(): controlledAccess() { if(!checkAccess(thisJoinPoint.getTarget())) throw new DeniedAccessException(); } } Listing 1. An example of an AspectJ aspect for the Bank example.

Listing 1 shows the code of an AspectJ aspect that controls the access to an account to ensure that only authorized accesses are made. Whenever a method of the Account class is executed, the aspect checks if the access is authorized; otherwise it throws an exception.

Aspect Oriented Programming with AspectJ

AOP encapsulates crosscutting behaviors into units called aspects. An aspect is composed of advices and pointcut descriptors (PCDs). A PCD selects a set of points in the execution flow (called join points)

where an advice is woven. An advice is a piece of code that implements the crosscutting behavior.

In AspectJ, a PCD is defined using primitive PCDs. The primitive PCDs can be combined using conjunction ("&&") or disjunction ("||"); a PCD can be negated ("!"). A primitive PCD selects a set of join points, depending on its parameters. Some PCDs require a pattern as a parameter. This pattern describes an element in the code, a class, a method, a constructor, or an attribute. Wildcards can be used in a pattern to make it select different elements. The " * " wildcard matches any sequence of characters; the ".." wildcard matches any sequence of parameters. For instance, the PCD on line 2 of Listing 1 has a pattern that describes a method (" * Account. * (int)"). This pattern selects all the methods of the Account class that takes a single integer parameter, irrespective of their return type (the first " * " wildcard) and their PCDs such as this, target, args, cflow, cflowbelow, and if are dynamic because the exact set of join points can only be computed at runtime. A dynamic PCD always has a static part and a dynamic part.

The dynamic part only constrains at runtime the set of join points selected by the static part.

Advices are woven, before, after, or around the join points selected by the PCD. Around means that the join point is not executed and the advice is executed instead; the advice can still execute the join point by calling a special method (proceed).

Challenges for Testing PCDs

When testing a PCD, four kinds of faults, defined by Lemos et al. [START_REF] Lemos | Testing aspect-oriented programming pointcut descriptors[END_REF] are targeted. The AccessControl aspect modifies the control flow. An if statement has been added at the beginning of the control flow. If the condition is fulfilled an exception is thrown, otherwise the original control flow is executed. This means that in some cases the original behavior may not be executed anymore. If the PCD is not correct it can introduce critical problems. If the PCD matches more join points than it should, then access to functionalities of the system will be reduced by the advice. Even worse, if the PCD does not match the intended join points, it introduces a critical security hole, as anyone can withdraw money from any account.

The test case in Listing 5 illustrates the challenges of testing a PCD using JUnit only. Testing that the PCD is correct requires checking that the advice has been woven at the correct places. One way to do it is to check that the behavior of the advice executes correctly. The test case logs a user who is not authorized to withdraw money from a particular account, and attempts to withdraw money on that account. If an exception is thrown, the test case ends and succeeds, but if no exception is thrown, then the test case fails (the assertion of line 5 always fails). This test case is simple and seems to be a good way to test the PCD, but there are several problems with this test case. The first problem is that if the test case fails, the oracle is not precise enough to conclude if there is a fault in the PCD or in a different part of the program. This can hinder fault localization.

• If the first " * " wildcard of line 3 of Listing 1 is replaced by "void", the withdraw method is not selected, and testAccessControl will fail because there is a fault in the PCD.

• If on line 7 of Listing 1 the negation ("!") is removed, the behavior of the advice is inverted, and testAccessControl will fail. However, the test failure will reveal a fault in the advice, but not in the PCD, which is correct. The second problem is that testAccessControl will not detect all the faults in the PCD. For example, suppose that in the method pattern of Listing 1, line 3, the name Account is replaced by a wildcard. Then the advice will be woven before the executions of Bank.deleteAccount, and testAccessControl will pass even if there is a fault in the PCD. This fault is of type 3 as defined in Figure 2, which means that the expected join points are matched, but the PCD also matches unintended join points. To detect that fault, test cases must be written that specify that no advice should be woven in some places of the code. However, test cases such as testAccessControl cannot check this, they do not explicitly mention the presence or absence of an advice by testing its behavior; they just implicitly assume the presence of an advice. Not allowing explicit mention of an advice is a limitation of JUnit-based unit testing when it is used to precisely capture faults in the PCD.

Finally, a fault in a PCD can lead to the same observable behavior as the original PCD. In this case, it is not possible to write a JUnit test case that can detect different functional behavior between the original and the faulty PCD. One could argue that if functionalities are the same there is no fault.

However, the set of matched join points is actually different and it can lead to problems with nonfunctional requirements, such as higher execution time or space. Moreover, as we show in Section 5, with the proposed approach, it is possible to exhibit the fault with a test case.

To overcome these problems, a new approach is needed to define oracles that directly target faults in the PCDs, and that does not rely on the behavior of the advice. The next section proposes a solution for the definition of oracles dedicated to PCDs. This solution is based on monitoring the execution of advices when running the test cases and on the definition of a set of dedicated assertions to query these executions. This solution is implemented as a tool called AdviceTracer and the assertions can be used to define an automatic oracle for PCD test cases.

AdviceTracer

The AdviceTracer † tool allows a programmer to write test cases that focus on checking whether or not a join point has been matched by the PCD. More precisely, AdviceTracer is used to specify an oracle that expects the presence or absence of an advice at a particular point in the base program. Test cases can specify the join points expected to be matched by a PCD without requiring the execution of advice behavior.

Approach

AdviceTracer implements an approach for testing PCDs. The key idea is that executions of the advice during test scenarios are traced and assertions are made on these execution traces instead of on the behavior of the advices.

The general approach is separated in two steps, one for checking that all intended join points have been matched by the PCDs, and one for checking that no unintended join points have been matched.

The following paragraphs describe (1) how to write the test cases for the intended and unintended join points, and (2) how to interpret the results of these test cases to locate the faults. Each test case consists of a test scenario and an oracle (using assertions).

Test cases for the intended join points

In the first step, test cases are written to check that all intended join points are matched by the PCDs.

It is necessary to write one test case for each join point. While it may seem demanding, a previous study [START_REF] Munoz | Inquiring the usage of aspect-oriented programming: an empirical study[END_REF] showed that most of the advices are woven only at few places. The test scenario of a test case that targets an intended join point should be as simple as possible.

The sole purpose of the test scenario is to trigger the intended join point.

The oracle should verify that the advice associated with the PCD under test has been executed, and that it has been executed at the correct place. Thus, the assertions need to be specific to make sure the intended join point has been matched by the PCD.

Enumerating the intended join points contradicts one of the goal of using declarative PCDs (such as AspectJ PCDs), which is to avoid the enumeration of numerous join points. However, there exists no other specification for a PCD against which we can check conformance. Thus, enumerating all the join points is the only way to thoroughly verify the PCDs. One advantage of using AdviceTracer is that it allows for a coarser verification by just counting the number of matched join points, which greatly reduce the cost.

Test cases for the unintended join points

In the second step, test cases are written to check that no unintended join points have been matched by the PCDs. The unintended join points can be located anywhere in the program so it can be difficult to write such test cases. The proposed approach can reduce the cost of writing test cases for the unintended join points.

In order to limit the number of test cases that validate the absence of unintended join points, it is necessary to build test cases that cover large portions of the program. Since AdviceTracer is based on execution traces, the larger the execution trace, the more can one test case check. AdviceTracer offers an assertion that checks the number of occurrences of a specific advice in an execution trace. It can be used to validate that the advice has not been woven more than expected in large execution traces.

Determining the expected number of executions of an advice in a specific test scenario is not an easy task but not harder than determining what assertions need to be specified in JUnit test cases. The tester needs to determine this number of executions by inspecting the code or by using the specifications of the system and the aspects (e.g., design models and requirement documents). if the number of executed advices is as expected by the test case, it may still not be clear if they are actually executed at the correct join points. That is why it is important to test the intended join points before the unintended ones. If it is known that the intended join points were correctly matched, then the number in a large execution trace must correspond to the intended join points (and not to any arbitrary join point). This way, the oracle remains simple even if the test scenario is complex.

Testing that a PCD does not match any unintended join point is more difficult than testing that the PCD matches every intended join point. In general, there are far more unintended join points than intended join points. Indeed, each instruction contains at least a possible join point, and can contain dozens of possible joinpoints. Thus if the first step fails to guarantee that intended join points have been matched, testing that no unintended have been matched is almost impossible. This is why we propose a two-step approach. the first step is required for the second step to succeed.

Fault localization

If a fault is detected, it is possible to know which type of fault (as presented in figure 2) and where it is located by interpreting the test results.

First, the tester inspects the results of the test cases for the intended join points. If some test cases for the intended join points fail, it means that the intended join points they target have not been selected by the PCDs they test. The fault is easily located as each test case targets one PCD and one intended join point.

Then the tester inspects the results of the test cases for the unintended join points. If some test cases for the unintended join points fail, the PCDs they target match unintended join points. Each assertion in the test case specifies how many times an advice must be executed. If an assertion fails, then the PCD associated with the advice checked by the assertion matches unintended join points. For the unintended join points, the tester must find a compromise between large and small test scenarios. A large test scenario means fewer test cases, but a small test scenario means better fault localization.

To summarize, if some test cases for the intended join points fail, then there is a fault of type 1 or type 2, and if some test cases for the unintended join points fail, then there is a fault of type 1 or type 3. To facilitate the identification and designation of advices it is required to use the @AdviceName annotation. This annotation, provided by AspectJ, takes a string parameter to specify the name of the advice it is associated with.

Illustrative Example

Listing 8 shows two test cases that specify the set of expected join points. In textual form, the specification of the expected join points can be expressed as, "the advice A1 should be executed only before the executions of m1 in the control flow of m2". This means that the test must specify that the advice A1 is expected when m2 calls m1, and also that it should not be executed when m1 is executed outside the control flow of m2.

• test1 specifies that no advices should be executed (line 9) when only m1 is called (line 7).

Thus, test1 will pass only if weaving an aspect (here aspect A) does not lead to the execution ", both test cases will fail as the weaving context changes: with call the join point is located within the calling method whereas with execution the join point is the called method.

This example also illustrates how AdviceTracer can handle dynamic PCDs. The PCD of Listing 7 is dynamic: it statically matches all the executions of m1, but the advice is executed only if m1 is executed in the control flow of m2. To specify this PCD, the test first executes m1 outside the control flow of m2 and checks that the advice is not executed (test1 of Listing 8). Then the test executes m1 in the control flow of m2 and checks that the advice is executed at the correct join point (test2 of Listing 8).

AdviceTracer makes it possible to specify the expected join points in order to check that there are no neglected join points. In such an approach, there must be test cases that specify every place in the base program that should be matched by each PCD. As shown in test1, it is also possible to write test cases that specify unintended join points.

Primitive Methods of AdviceTracer

The above two test cases illustrate how the primitive methods of AdviceTracer are used. These primitives are of three distinct types: those that start or stop AdviceTracer, those that configure the traced advices, and those that define assertions to specify the oracle.

Starting AdviceTracer

By default, AdviceTracer does not trace anything. To make assertions on the number of executions of the advices, AdviceTracer needs to know when the test scenario begins and when it ends. Thus, in each test case, AdviceTracer must be set on before the test scenario, and off thereafter.

AdviceTracer is set on by calling the static method, setAdviceTracerOn. The static method, setAdviceTracerOff, stops tracing. Between setAdviceTracerOn and setAdviceTracerOff,

AdviceTracer stores information about which advices were executed and where they were executed.

Restricting the traced advices

Using AdviceTracer each test can specify the advices to be traced. If a test case does not specify a particular advice, then all the advices are traced. On lines 5 and 15 of Listing 8, the method addTracedAdvice is called. It adds the advice as a parameter to the collection of traced advices.

Another method, setTracedAdvices, specifies a collection of advices to be traced. In listing 8, test1 specifies the absence of advice A1, and test2 specifies the presence of advice A1.

The test cases test1 and test2 are said to be modular because they specify a set of join points where a specific advice must or must not be woven. A test case is not modular when it is not specific to a particular advice; it passes as long as some advice is woven (or no advice is woven) instead of passing when a specific advice is woven (or when a specific advice is not woven). Restricting the traced advices improves the modularity of the test cases. Passes if the specified advice was executed at the specified join point, fails otherwise. The format of the join point parameter is: className.methodName:lineNumber where lineNumber refers to the line number in the source where the join point is expected. The class name and the line number alone are sufficient to identify a join point, but the method name makes it easier to understand the assertion.

Implementation of AdviceTracer

The monitoring part of AdviceTracer is implemented with an aspect, which can be woven at compile time or at runtime. Compile time weaving offers better performance, but runtime weaving allows running the test case without modifying the byte code.

Information that is stored by AdviceTracer can be accessed through an API that offers a set of static methods used to define test cases. Figure 4 shows the class diagram of AdviceTracer. The advice in this aspect retrieves the name of the advice that is being traced and the location of the join point that triggered the advice execution. This information is stored in a TraceElement object, which is a pair of strings, one for the advice (e.g., A1) and one for the join point (e.g., C.m1:2). The string for the advice is its name, specified with the @AdviceName annotation. The string for the join point is built with the qualified name of the method and the line number where it is located (separated by the ':' character).

The advice is woven before each join point matched by all the aspects under test (i.e., before each execution of an advice). The PCD in the AdviceTracer aspect is "adviceexecution()&& !within(AdviceTracer)".

This PCD matches the execution of all the tested advices and not AdviceTracer's own advice. in Section 5, mutation analysis was used. Thus, a tool for the mutation analysis of AspectJ PCDs was developed.

In mutation analysis [START_REF] Demillo | Hints on test data selection: Help for the practicing programmer[END_REF][START_REF] Geist | Estimation and enhancement of real-time software reliability through mutation analysis[END_REF] I shows the operators that were implemented in AjMutator.

Classification of the mutants

The mutant PCDs are automatically classified by comparing the set of join points they match with the set of join points matched by the original PCD. The classification of the mutants is similar to the classification of the faults of Figure 2, in Section 2.3.

A mutant that matches unintended join points and does not match some intended join points, and thus introduces a type 1 fault, is a mutant of class 1. A mutant that does not match some intended join points, and thus introduces a type 2 fault, is a mutant of class 2. A mutant that matches unintended join points, and thus introduces a type 3 fault, is a mutant of class 3. Finally a mutant that matches the same set of join points as the original is an equivalent mutant, as it introduces no fault.

It is important to note that the classification of a mutant is system-dependent, i.e., the same mutant can have two different classifications in two different systems, even if the original PCD is the same.

Adding or removing lines of code can add or remove join points, and can thus change the set of join points matched by a PCD.

AjMutator

AjMutator is a tool for the mutation analysis of AspectJ pointcut descriptors. It produces mutants of AspectJ aspects by inserting faults in the PCDs.

AjMutator consists of three distinct parts, corresponding to the following three phases:

1. the generation of mutant source files from the AspectJ source file 2. the compilation of the mutant source files

Generation of the mutants

Figure 6 shows how AjMutator generates the mutants. A parser builds an abstract-syntax tree (AST) for each PCD in the AspectJ source files. The operators insert faults in copies of the AST, so there is an AST for the original PCD and an AST for each mutant PCD. A pretty-printer then produces a mutant AspectJ source file for each mutant AST.

The parser has been developed using SableCC [START_REF] Cagnon | Sablecc, an object-oriented compiler framework[END_REF], an open-source compiler generator. The parser directly produces an AST from a PCD. Only the PCD is parsed in the AspectJ source file, as the PCD has a different grammar from the rest of the AspectJ syntax, which is close to the Java syntax.

The mutation operators are implemented using the visitor pattern [START_REF] Gamma | Design patterns: elements of reusable object-oriented software[END_REF]. Each operator extends the abstract class Operator, which is a visitor for the AST. When an operator encounters a place in the AST where a fault can be injected, a mutant of the AST is generated. The mutant AST is then inserted in a copy of the original AspectJ source file using a pretty printer. To reduce the memory consumption the mutant AST is immediately saved into a file and the reference is not kept so that the garbage collector can free its memory space.

Compilation of the mutants

After the mutants have been generated, they need to be compiled. The compilation is required to run the test cases on the mutant systems, but also to classify the mutants automatically. Figure 8 shows the process for the classification of the mutants. Mutation analysis only considers compilable mutants. Thus, if the mutant is non-compilable, it is not selected as for mutation analysis. If

the mutant system has both neglected and unintended join points, the mutant is in class 1. If the mutant system has neglected join points but no unintended join points, the mutant is in class 2. If the mutant system has unintended join points but no neglected join points, the mutant is in class 3. Finally, if the mutant system has no unintended join points and no neglected join points, the mutant is equivalent and not selected for mutation analysis. The accuracy of the classification process depends on whether the original PCD of the mutant is static or dynamic. Static PCD: the set of matched join points can be computed statically, so the classification is exact.

Dynamic PCD: the set of matched join points can only be over-approximated, so the classification is not perfectly accurate. Two cases may arise:

Non-equivalent: if the mutant is classified as non-equivalent, it means that the fault was inserted in its static part, thus it is actually non-equivalent.

Equivalent: if the mutant is classified as equivalent it just means that the static part is semantically equivalent, but the dynamic part might be different. In this case, the mutant must be selected for mutation analysis because one cannot be sure that it is actually equivalent.

Execution of the test cases

A mutant is considered killed if a test suite can exhibit a difference between the original system and the mutant system. So if the mutant is killed, the test suite can detect the inserted fault, whereas if the mutant is still alive, the test suite is not able to detect this fault and it needs to be improved, either with new test data or better oracles.

AjMutator assumes that all JUnit test cases succeed on the original version. Thus, a mutant is killed if at least one assertion in a JUnit test case is violated when the test case is executed against the mutant.

Empirical study

The goal of the empirical study is to determine if AdviceTracer actually improves the testing of PCDs.

The HealthWatcher system

The system under test is the HealthWatcher system § . This system has been developed at the University incorporates the state and command patterns [START_REF] Gamma | Design patterns: elements of reusable object-oriented software[END_REF].

The HealthWatcher software was slightly modified for this study. In the HealthWatcher system, there is a persistence mechanism which can be turned on or off. The persistence mechanism relies on a distributed data base that is only compatible with Microsoft Windows. As the developers do not give any information on the structure of the data base (tables, fields, etc.), it is not possible to create or reset the database. The only way to use the persistence is to use Windows and the given data base file, which means that the state of the database at the beginning of a test case is the state of the database at the end of the previous test case. This can introduce a lot of side effects between the test cases and reduce the testability, so it was turned off. Four aspects were also removed because they have no effect when the persistence is turned off.

Two design patterns are used in the HealthWatcher system. The first pattern is the state pattern [START_REF] Gamma | Design patterns: elements of reusable object-oriented software[END_REF].

This pattern encapsulates the state of an object in another object. It is used to manage the different states of a complaint. As there are different types of complaints, different state classes coexist in the system. The second pattern [START_REF] Gamma | Design patterns: elements of reusable object-oriented software[END_REF] is the command design pattern, which encapsulates a method call into an object. In the HealthWatcher system, commands are used to represent different requests that can be received by the server. For each request there is a corresponding class and an instance of each class is stored in a table and called depending on the received HTTP requests.

The HealthWatcher system contains nine aspects, which fulfill four different goals. Two aspects are in charge of synchronization to avoid concurrent access on some classes. Two aspects manage exceptions in the HealthWatcher by catching thrown exceptions. One aspect implements the command design pattern by registering the set of available commands. Finally, four aspects implement the state design pattern to add a state object to the different types of complaints. of occurrences for each primitive PCD in the HeatlthWatcher system. It shows that some primitives are not represented, while others are used often.

Research Questions

This empirical study attempts to answer the following two research questions:

Question 1 Does AdviceTracer reduce the testing effort for testing PCDs compared to JUnit ?

Testing PCDs using only JUnit assertions can be difficult, AdviceTracer aims to reduce the effort required to write the test cases. Thus, the study verifies that AdviceTracer actually achieves this goal.

The testing effort can be evaluated by comparing the time spent on writing the test suites. When testing a system, time is often critical. Also, time is often a good indicator of the required effort.

The testing effort can also be evaluated by comparing the size of the two test suites, in terms of number of test cases and in terms of the number of lines of code. If a test suite detects the same faults with fewer test cases, it means that its test cases are more effective as they detect more faults. On the other hand, if a test suite detects the same faults with smaller test cases, it is likely that its test cases are simpler to write. Thus, the study compares the number of test cases, the total number of lines of code, and the average number of lines per test case.

Question 2 Does AdviceTracer increase the ability of the test cases to detect faults in the PCDs compared to JUnit ? Some faults may be hard or impossible to detect using only JUnit assertions. As AdviceTracer targets testing often PCDs, it is necessary to verify that the AdviceTracer test suite can detect at least as many faults as the JUnit test suite. Since mutation analysis is used here, the study compares JUnit and AdviceTracer with respect to the difficulty at detecting equivalent mutants.

Experimental Protocol

Delamare and Gupta, two graduate students and co-authors of this paper, built the two test suites in parallel. They have comparable advanced programming skills in Java, AspectJ, and JUnit. None of them were familiar with the HealthWatcher system.

The developers were given a set of mutants of the HealthWatcher system. One was asked to detect all the faults with JUnit and the other with AdviceTracer. Both of them had to record the time taken to detect all the faults. One developer recorded the time to test each class, whereas the other recorded the number of mutants killed after each hour. They were given no instruction on the order in which the classes were to be tested.

The oracle the developers had to write was related to the PCD, so the oracle had to capture how well the advices were woven. In order to write the oracle, the developers had to understand the interactions between the aspects and the base code, not so much the global functionality of HW.

The generation of the two test suites had to be driven by a certain test adequacy criterion. The mutation score was used as a criterion for the test suites. The goal was to achieve a 100% mutation score if possible, or the highest possible mutation score otherwise. Before stating that a mutant was not possible to kill, a developer had to found the reason why. This mitigates the risk that a team gives up the experiment early on simply because they cannot kill the mutant. Mutants of the pointcut descriptor were generated using AjMutator as described in Section 4.

AjMutator generated 343 mutants. AjMutator is able to automatically detect some of the equivalent mutants, and some mutants are not compilable. After compiling the mutants, 243 were left as compilable and not detected as equivalent by AjMutator. There were, however, equivalent mutants remaining that were not detected by AjMutator.

The two developers had to find the equivalent mutants on their own, without communicating the results one to another. Because finding the equivalent mutants can take a lot of time, it would influence the results if the developers shared the results. At the end of the study, 76 mutants were identified as non-equivalent.

Results

Question 1

The T JU test suite took longer to write. The T AT test suite was written in approximately 420 minutes (seven hours), whereas T JU was written in approximately 480 minutes (eight hours). Figure 9 shows the evolution of the mutation score for the two test suites. The mutation score of the T AT is always higher than the mutation score of T JU , which means that it is faster to find faults with AdviceTracer. The mutation score of the AdviceTracer test suite is greater than the mutation score of T JU (Figure 9).

T AT achieved a 100% mutation score, which means it was able to kill all the mutants, and thus the test suite detects all the inserted faults. T JU only achieved a 81.59% mutation score. This means that T JU was not able to detect all the faults. The following paragraphs discuss the faults that were not detected.

There are 14 mutants that were not killed by T JU , although they were killed by T AT . These mutants are impossible or very hard to kill without AdviceTracer.

Four of the mutants not killed by T JU are mutants of the aspects that implement the state design pattern. After the initialization of an object, its state is initialized by the advice. With the mutants the advice is executed several times, which can be detected by AdviceTracer, with the assertion on line 8 of Listing 10. For T JU it is not possible as the result of the initialization is the same with the mutants as with the original.

Two of the mutants not killed by T JU are mutants of the aspect that implement the command design pattern. The commands are registered in the table at the initialization of the system. One mutant weaves the advice in several unintended join points so the table is reinitialized several times, but as the command table is private and not accessible with public methods, it is not possible to kill this mutant without AdviceTracer. The other mutant weaves the advice that is responsible for executing the command after the removal of a command. So with this mutant, the advice tries to execute a command just after it is removed and fails, but the failure is not observable (no events, e.g., exception, error message). As the command is actually removed, there is no observable behavior and the mutant cannot be killed without AdviceTracer.

The last eight mutants are related to an aspect that synchronizes several methods to prevent concurrent executions. While it is possible to kill these mutants with JUnit alone, creating a deterministic test for concurrent behavior is difficult. With AdviceTracer these mutants are easily killed, as there is no need to check the behavior of the advice in the oracle. It has to be noted that faults that do not modify the observable behavior do not necessarily reveal an equivalent mutant. Since mutation analysis is performed on PCDs, an equivalent mutant is a PCD that matches exactly the same set of join points as the original one. Thus, if a mutant matches a different set of join points, the mutant is not equivalent, but can still lead to the same global behavior as the original PCD.

Threats to validity

This section discusses the internal and external threats to validity.

The threats to internal validity are those that can bias the measurements made during this study. Another threat to validity is the fact that HealthWatcher was modified to improve its testability.

However, this modification actually favors JUnit. Since AdviceTracer does not require tests to verify the behavior of the advices, it is less sensitive to testability issues than JUnit.

The threats to external validity are biases that affect the generalization of the results to other systems.

HealthWatcher does not include all the types of primitive PCDs as shown in Table II The interval validity is also threatens by the subjects of this study. Having two subjects is a threat to internal validity, as such a small number may not be representative of the developers in the industry.

Also, both testers wrote the test suite alone, which means that the results of this study may not generalize to bigger group of testers. Finally, both developers were students familiar with software testing techniques, which may not be the case of all the developers in the industry.

Related Work

Ye et al. [START_REF] Ye | Tool support for understanding and diagnosing pointcut expressions[END_REF] tackle the issue of correctness of a PCD. They propose tools to assist developers in diagnosing faults and fixing PCDs. First, they compute a set of join points from a PCD that are almost matched by this PCD. This means they compute the set of join points that would be matched if the PCD was slightly different. That way, a developer who analyzes these join points can check whether he/she expected one of these join points to be matched. If this is the case, then the PCD must be fixed.

For this step, Ye et al. also propose a tool that can explain why a join point is not matched by the PCD.

The solution proposed by Ye et al. to tackle the problem of faulty PCDs is thus different from the proposed approach. Instead of specifying the set of expected join points a priori, they provide assistance for manual inspection by the developer. The benefit of their approach is that it does not require additional work from the developer.

In case the aspects evolve, with their approach the developer has to manually check all the PCDs to be sure that there are no regressions. The approach proposed in this paper is automatic, so the developer can run all the test cases again. they are meant to replace the regular expression. This should allow PCDs to be more robust with respect to evolution. However, these PCDs can still be erroneous and the authors do not tackle the issue of the correctness of their PCDs.

Lemos et al. [START_REF] Lemos | Control and data flow structural testing criteria for aspect-oriented programs[END_REF] have proposed a test adequacy criterion for testing advices. This criterion, called all-crosscutting-node, requires to execute each advice at each join point where it is woven. Wedyan

and Ghosh [START_REF] Wedyan | A joinpoint coverage measurement tool for evaluating the effectiveness of test inputs for aspectj programs[END_REF] call this criterion join point coverage and have proposed a tool for measuring it.

This criterion is intended for testing advices, but test suites targeting the PCDs should satisfy this test adequacy criterion, as the test case have to specify each intended join point.

There exist several studies related to mutation analysis in the context of AOP. Anbalagan et al. [START_REF] Anbalagan | Automated generation of pointcut mutants for testing pointcuts in aspectj programs[END_REF] present a tool for the generation of mutant PCDs. This tool produces mutants that are rated following their resemblance with the original PCD. This rating process also automatically detects the equivalent mutants.

Although the work of Anbalagan et al. is related to the mutation analysis approach used in AjMutator, they focused on a particular type of mutation analysis. One of their goals is to rank and select mutants so that the developer can choose a mutant, which is close to the PCD written in the aspect, to help develop the PCD.

To rank the mutant, their tools computes the difference between the mutant and the original PCD as an integer. This is possible because they have only two operators, one that only generates mutants of class 2 (only neglected join points) and one that only generates mutants of class 3 (only unintended join points). AjMutator is more general and extensible. It has more operators and operators can easily be added by implementing a visitor of the PCD AST.

Ferrari et al. [START_REF] Ferrari | Mutation testing for aspect-oriented programs[END_REF] identified fault types for aspect-oriented programs and provided a set of mutation operators. This operators can insert faults in various parts of an AspectJ system, such as the advice or the PCD. Lopes et al. [START_REF] Lopes | Unit testing aspectual behavior[END_REF] focus on unit-testing the advices. Their approach relies on JAML (Java Aspect Markup Language), an aspect language for Java where the advices are implemented in regular Java classes and the PCDs are described in XML. This allows advices to be called as regular methods, and thus to be unit-tested. They also provide JamlUnit, a JUnit extension to test JAML advices.

Conclusion

Pointcut descriptors (PCD) in AspectJ offer a flexible way of introducing crosscutting behavior in Java programs. However, they are also a major source of faults; a fault in one PCD can result in the introduction of the crosscutting behavior at several unintended places or miss certain desired places.

PCDs must be thoroughly verified in order to ensure the correctness of aspect-oriented programs. With the current state of testing techniques, JUnit is the only possibility to automatically check the validity of a PCD. However, it has been shown that this is not sufficient, mainly because this does not allow a tester to precisely target faults in the PCD. As a consequence, a JUnit test case that is meant to capture faults in a PCD can miss faults. It can also capture faults that are not in the PCD, but in the advice, leading to an interpretation issue for diagnosis.

This work proposed the AdviceTracer tool. It monitors the execution of advices in AspectJ programs and offers the possibility to retrieve information about this execution through a small set of assertions.

These assertions can in turn be used to build test cases that target faults in PCDs. For evaluation purposes, an empirical analysis was performed that compares AdviceTracer with JUnit for writing effective test cases for AspectJ test cases. Two dimensions of effectiveness were investigated: The complexity of test cases and their ability at detecting faults. The empirical study was performed on a

HealthWatcher system that is frequently used as benchmark for aspect-oriented software development

+Figure 1 .

 1 Figure 1. The UML class diagram of the Bank example.

Figure 2 .

 2 Figure 2. The four types of PCD faults

Figure 3 .

 3 Figure 3. The control flow graphs of the Account.withdraw method before (a) and after (b) weaving.

Copyright c 0

 0 John Wiley & Sons, Ltd. Softw. Test. Verif. Reliab. 0; 0:0-0 Prepared using stvrauth.cls DOI: 10.1002/stvr

Copyright c 0 0

 00 John Wiley & Sons, Ltd. Softw. Test. Verif. Reliab. 0; 0:0-Prepared using stvrauth.cls DOI: 10.1002/stvr

Copyright c 0

 0 John Wiley & Sons, Ltd. Softw. Test. Verif. Reliab. 0; 0:0-0 Prepared using stvrauth.cls DOI: 10.1002/stvr It might seem difficult to interpret a result based on a simple count of occurrences of advices. Indeed,

Copyright c 0

 0 John Wiley & Sons, Ltd. Softw. Test. Verif. Reliab. 0; 0:0-0 Prepared using stvrauth.cls DOI: 10.1002/stvr public class C { public void m1() { ... } public void m2(execution(void C.m1()) && cflow(execution(void C.m2())) { ... } } Listing 7. An AspectJ aspect example

Listings 6 , 7 ,

 67 and 8 illustrate the use of AdviceTracer. Listing 6 shows a Java class C with two methods m1 and m2; m2 calls m1. Listing 7 shows an Aspect A, in which an annotation has been added in order to name the advice, A1. The advice is woven before the executions of m1 which are in the control flow of m2. Copyright c 0 John Wiley & Sons, Ltd. Softw. Test. Verif. Reliab. 0; 0:0-0 Prepared using stvrauth.cls DOI: 10.1002/stvr new C(); addTracedAdvice("A1"); setAdviceTracerOn(); c.m2(); setAdviceTracerOff(); assertAdviceExecutionsEquals("A1",1); assertExecutedAdviceAtJoinpoint("A1","C.m1:2"); } Listing 8. A JUnit test class illustrating how to use AdviceTracer

Copyright c 0

 0 John Wiley & Sons, Ltd. Softw. Test. Verif. Reliab. 0; 0:0-0 Prepared using stvrauth.cls DOI: 10.1002/stvr

Copyright c 0 Figure 4 .

 04 Figure 4. The class diagram of AdviceTracer.

Figure 5 Figure 5 .

 55 Figure5shows the control flow graph of the Account.withdraw method after AdviceTracer has been woven. AdviceTracer is woven before the execution of other advices. As there are no conditional statements in the added control flow, AdviceTracer do not affect the behavior of the program with its own aspect. Here, when Account.withdraw is executed, AdviceTracer is executed first, then the AccessControl advice. The original control flow may or may not be executed, depending on the AccessControl advice.All the TraceElement objects are stored in a list that can be retrieved in each test case by calling a static method (getExecutedAdvices). This list is reset each time AdviceTracer is set on, and thus

  , mutation operators produce mutants of the original program. A mutant is a modified version of the program where one and only one simple fault has been introduced by the operator. Each operator introduces one type of fault. Mutation analysis relies on the assumption that if a set of test cases can kill all the mutants, then it is adequate for testing the original program. A mutant is considered killed if the result of the execution of the test cases on the mutant is different from that of the execution of the test cases on the original program. The operators introduce faults corresponding to identified fault types wherever possible in the original program. If all the mutants are killed, the set of test cases can detect all the introduced faults. Mutation analysis results in a mutation score which indicates the adequacy of a test suite. The mutation score is the number of killed mutants divided by the number of non-equivalent mutants. Equivalent mutants are mutants that are semantically equivalent to the original program. The higher the mutation score, the better the adequacy of the test suite. A mutant PCD is a PCD that matches a set of join points different from the set of join points matched by the original PCD. Ferrari et al. [9] have presented several operators for the mutation analysis of Copyright c 0 John Wiley & Sons, Ltd. Softw. Test. Verif. Reliab. 0; 0:0-0 Prepared using stvrauth.cls DOI: 10.1002/stvr AspectJ programs. These operators are based on fault types that have been identified in previous work. The authors presented three kinds of operators: operators for PCDs, operators for AspectJ declarations, and operators for advice definitions and implementations. This work only considered operators for PCDs. Table

Figure 6 .

 6 Figure 6. The AjMutator process of generation of the mutants.

Copyright c 0 0 Figure 7 .

 007 Figure 7. The AjMutator process of compilation and classification of the mutants.

Figure 7 0 Figure 8 .

 708 Figure7shows the process of compiling and classifying the mutants. It relies on the ajc compiler ‡ , the compiler of AspectJ. The ajc compiler produces a jar file of the system for each mutant. It also provides information on the join points matched by the PCDs. The information is then used by AjMutator to classify the mutants.As a single modification of an aspect can affect various classes throughout the whole system, it is necessary to keep a complete version of the system for each mutant, not only the class file of the mutant aspect.

Copyright c 0 0

 00 John Wiley & Sons, Ltd. Softw. Test. Verif. Reliab. 0; 0:0-Prepared using stvrauth.cls DOI: 10.1002/stvr

Copyright c 0

 0 John Wiley & Sons, Ltd. Softw. Test. Verif. Reliab. 0; 0:0-0 Prepared using stvrauth.cls DOI: 10.1002/stvr

Copyright c 0

 0 John Wiley & Sons, Ltd. Softw. Test. Verif. Reliab. 0; 0:0-0 Prepared using stvrauth.cls DOI: 10.1002/stvr

Figure 9 .

 9 Figure 9. Evolution of the mutation score for each test suite.

Copyright c 0

 0 John Wiley & Sons, Ltd. Softw. Test. Verif. Reliab. 0; 0:0-0 Prepared using stvrauth.cls DOI: 10.1002/stvr

Copyright c 0

 0 John Wiley & Sons, Ltd. Softw. Test. Verif. Reliab. 0; 0:0-0 Prepared using stvrauth.cls DOI: 10.1002/stvr In summary, AdviceTracer increases the ability of the test cases to detect faults in PCDs. With JUnit some faults in PCDs cannot be detected as the observable behavior of the associated advice cannot exhibit a fault. AdviceTracer on the other hand does not rely on the behavior of the advices and is able to detect all the kinds of faults inserted by the operators of AjMutator.

Copyright c 0

 0 John Wiley & Sons, Ltd. Softw. Test. Verif. Reliab. 0; 0:0-0 Prepared using stvrauth.cls DOI: 10.1002/stvr data to cover the paths in the composed statechart that correspond to interactions between the base program and the advice.

  Listing 5. A test case for the AccessControl aspect.

	public void testAccessControl() {
	bank.login(nonAuthorizedUser,password);
	try {
		account.withdraw(30);
		fail("Access should not be authorized");
	} catch(DeniedAccessException() {}
	}
	Copyright c	0 John Wiley & Sons, Ltd.	Softw. Test. Verif. Reliab. 0; 0:0-0
	Prepared using stvrauth.cls	DOI: 10.1002/stvr

  The test case will fail if a join point of m1 is matched by the advice (unintended join point).• test2 calls m2 and then specifies (at lines[START_REF] Lopes | Unit testing aspectual behavior[END_REF][START_REF] Mceachen | Distributing classes with woven concerns: an exploration of potential fault scenarios[END_REF] that advice A1 should be executed from a join point at line 2 of C, within m1. So if test2 passes, it is clear that the advice was executed within the context of execution of m1.If the PCD of Listing 7 is replaced by "execution(void C.m1())", test1 fails because the advice is executed in this test scenario. If the pointcut is replaced by "execution(void C.m2() )", the advice is executed but test2 fails because it is woven within m2 instead of m1. Finally, if

	Copyright c	0 John Wiley & Sons, Ltd.

Softw. Test. Verif. Reliab. 0; 0:0-0 Prepared using stvrauth.cls DOI: 10.1002/stvr of an advice when executing m1. the pointcut is replaced by "call(void C.m1())&& cflow(execution(void C.m2()))

  The benefit of modular test cases is that they are less affected by removal or addition of advices in the aspects. They are only affected by changes made in the PCDs of the advices they trace. For instance, if during the course of software evolution, a new advice is woven within C.m1, then the test cases of Listing 8 will still pass because they only consider advice A1.

	3.3.3. Assertions provided by AdviceTracer
	AdviceTracer provides three new assertions that are extensions of JUnit assertions.
	assertAdviceExecutionsEquals(String advice, int n) : Passes if the number of executions of the
	specified advice is equal to n, fails otherwise. This assertion is needed to detect unintended
	join points, as explained in Section 3.1.
	assertExecutedAdvice(String advice) : Passes if the advice, whose name is passed as the parameter,
	was executed, fails otherwise.
	Copyright c	0 John Wiley & Sons, Ltd.	Softw. Test. Verif. Reliab. 0; 0:0-0
	Prepared using stvrauth.cls	DOI: 10.1002/stvr

assertExecutedAdviceAtJoinpoint(String advice, String joinpoint) :

Table I .

 I Operators implemented in AjMutator.

	Operator Description
	PCCC	Replaces a cflow PCD with a cflowbelow PCD, or the contrary
	PCCE	Replaces a call PCD with an execution PCD, or the contrary
	PCGS	Replaces a get PCD with a set PCD, or the contrary
	PCLO	Changes the logical operators in a composition of PCDs
	PCTT	Replaces a this PCD with a target PCD, or the contrary
	POEC	Adds, removes or changes exception throwing clauses
	POPL	Changes the parameter list of primary PCDs
	PSWR	Removes wildcards
	PWAR	Removes annotation from type, field method and constructor patterns
	PWIW	Adds wildcards

  3. the execution of test cases on the mutants to calculate the mutation score.

		AspectJ		Pointcut
		source files		Descriptors
			Parser	Abstract-Syntax Trees of PCDs
			AjMutator Mutant Generator
		Pretty-Printer	Mutant ASTs	Operators
			Mutant AspectJ
			source files
	Copyright c	0 John Wiley & Sons, Ltd.		Softw. Test. Verif. Reliab. 0; 0:0-0
	Prepared using stvrauth.cls		DOI: 10.1002/stvr

Table II .

 II This is done by comparing two test suites, one written only with regular JUnit assertions, and the other written using AdviceTracer and JUnit. The two test suites specify the pointcut descriptors of the same system under test. In the following, the JUnit-only test suite is called T JU , and the AdviceTracer test suite is called T AT . Number of occurrences of each primitive PCD in the HealthWatcher system, as well as the locations of the advices.

		Primitive PCD	Number of Occurrences
		adviceexecution	0
		args	12
		call	2
		cflow	0
		cflowbelow	0
		execution	10
		get	0
		handler	0
		if	0
		initialization	8
		preinitialization	0
		set	0
		staticinitialization	0
		target	12
		this	1
		within	3
		withincode	0
		Advice location	Number of Occurrences
		before	3
		after	13
		around	4
	Copyright c	0 John Wiley & Sons, Ltd.	Softw. Test. Verif. Reliab. 0; 0:0-0
	Prepared using stvrauth.cls	DOI: 10.1002/stvr

  of Lancaster in the context of the AOSD European Network of Excellence. It was initially intended to serve as a benchmark in the Network to compare different AOSD techniques at different levels in the development process. It has then been reused in various experiments outside the Network[START_REF] Hoffman | Towards reusable components with aspects: an empirical study on modularity and obliviousness[END_REF][START_REF] Soares | Distribution and persistence as aspects[END_REF].It is a web-based application that collects and manages health complaints. It has been implemented in different languages, including AspectJ. There are different versions of the HeatlthWatcher system, §

	which vary according to various design decisions and functionalities. This study used a version which
	http://www.comp.lancs.ac.uk/ ˜greenwop/tao/implementation.htm
	Copyright c	0 John Wiley & Sons, Ltd.	Softw. Test. Verif. Reliab. 0; 0:0-0
	Prepared using stvrauth.cls	DOI: 10.1002/stvr

  The system test has 93 classes, with 530 methods, 9 aspects, and 19 advices (and thus 19 PCDs). It has 6435 total lines of code, of which 438 lines of code are for the aspects. TableIIshows the number

	Copyright c	0 John Wiley & Sons, Ltd.	Softw. Test. Verif. Reliab. 0; 0:0-0
	Prepared using stvrauth.cls	DOI: 10.1002/stvr

Table III .

 III Metrics of the two test suites.

		JUnit only AdviceTracer
	Test Cases	26	24
	Lines of Code	1298	324
	Lines per Test Case Mean	49.92	13.50
	Lines per Test Case Standard Deviation	27.66	7.76
	Time (minutes)	480	420

Table

  III shows metrics of the two test suites. Although they have a similar number of test cases[START_REF] Tourwé | On the existence of the aosd-evolution paradox[END_REF] for T JU , 24 for T AT ), T JU has significantly more lines of code than T AT (respectively 1298 and 324 lines of code).The test cases written with AdviceTracer are smaller than the test cases written only with JUnit. JUnit only test cases have a mean of 49.92 lines per test cases whereas AdviceTracer test cases have a mean of 13.50 lines per test cases. The standard deviation of the lines per test cases is also smaller with AdviceTracer, with 7.76 compared to 27.66 with JUnit only. This means that AdviceTracer test cases have very similar sizes (from 7 to 30 lines of code) whereas JUnit only test cases can have very different sizes (from 19 to 137 lines of code). There is no obvious relation between a PCD and the size of the test cases that test it. In order to illustrate why JUnit test cases can become much larger than AdviceTracer test cases, the development of test cases for one PCD in HealthWatcher is analyzed in detail in the following paragraphs.Listings 9 and 10 show two examples of test case that test the PCD of the adviceAnimalComplaintStateAspect3 (Listing 11), in AnimalComplaintStateAspect. This advice is responsible for changing the state of an AnimalComplaint object when AnimalCom-plaintState.setStatus is called. The HealthWatcher system manages different kinds of complaints. An AnimalComplaint is a type of complaint relative to an animal. It contains information, such as the type of animal, date of event, date of the complaint. The status can be tracked, i.e., if the complaint is still being investigated or if it has been dealt with.When using JUnit only (Listing 9), the test case must check that the state is correctly changed when setStatus is called. The problem is that the state is a private attribute. The only way to check that the state has changed is to trigger a method whose behavior changes according to the state. This is the case of the method setAnimal which actually changes the string attribute animal if Prepared using stvrauth.cls DOI: 10.1002/stvr change the value of animal to "tiger". If the state has been correctly changed by the advice, the value of animal should remain "elephant", as verified by the assertion on line 30.AdviceTracer offers a set of assertions to check the presence of an advice, which allows the tester to specifically target faults in the PCD and reduce the complexity of the test cases. Since it is not required to test the behavior of the object under test, the empty constructor can be used to instantiate a complaint, as on line 3. On line 4, the test case specifies that only the AnimalComplaintStateAspect3 advice should be traced. Then on line 5 AdviceTracer is set on. The method AnimalComplaint.setStatus is called on line 6; this method calls AnimalComplaintState.setStatus where the advice should be woven. Once the test scenario is over, the AdviceTracer is set to off in line 7. Finally, there are two assertions on lines 8 and 9. The first assertion checks that the advice has been executed once, and the second assertion checks that it has been executed from the correct location.This example shows several benefits of AdviceTracer. The test scenario is simpler with AdviceTracer. As it is not necessary to check the behavior of the advice, test cases only have to trigger behaviors where the advice is expected. On the other hand, using JUnit alone, it is necessary to set up a complex test scenario to be able to observe the behavior of the advice. The oracle written withAdviceTracer is more precise. The AdviceTracer test case can pass only if the PCD captures the correct set of join points, and thus if the advice has been woven at the correct place. The JUnit-only test cases pass if the value of animal has not changed, which can occur both because the advice is woven at the correct place but its behavior is faulty, or because the advice is not woven at the correct place.In summary, AdviceTracer reduces the required effort to test the PCDs. The test cases written with AdviceTracer were written faster than the test cases written only with JUnit. AdviceTracer test cases are also simpler, as they have smaller size than JUnit test cases.

	5.4.2. Question 2
	Copyright c Copyright c 0 John Wiley & Sons, Ltd. 0 John Wiley & Sons, Ltd.	Softw. Test. Verif. Reliab. 0; 0:0-0 Softw. Test. Verif. Reliab. 0; 0:0-0
	Prepared using stvrauth.cls	DOI: 10.1002/stvr

  HealthWatcher are typical of what is used in most AspectJ projects. The primitive PCDs that are not used by HealthWatcher are also not used by most of the other projects.

			. Previous work
	reported a study on 38 AspectJ projects [22]. This study shows that the primitive PCDs used in
	Copyright c	0 John Wiley & Sons, Ltd.	Softw. Test. Verif. Reliab. 0; 0:0-0
	Prepared using stvrauth.cls	DOI: 10.1002/stvr

  If a new advice is added, new test cases must be added to check its PCD. If existing PCDs are modified, the test cases for that PCD must be changed. All the other test cases remain unchanged. Another work related to the proposed approach is Sakurai et al. [23], who specify pointcuts in the form of unit test cases. Although their approach at first glance appears to be similar to the proposed Prepared using stvrauth.cls DOI: 10.1002/stvr approach, it is actually different. They propose a new language for pointcut description based on unit test cases. The test cases are not meant to validate a pointcut described as a regular expression. Instead,

	Copyright c	0 John Wiley & Sons, Ltd.	Softw. Test. Verif. Reliab. 0; 0:0-0

  work. It was observed that test cases that use AdviceTracer to test PCDs are smaller, require less time to build, have oracles more focused on faults in PCDs, and detect more faults than test cases that use Prepared using stvrauth.cls DOI: 10.1002/stvr JUnit only. Also, oracles that use AdviceTracer capture only faults in PCDs and cannot capture faults in the advice. This reduces the interpretation issue when a test case delivers a verdict. However, this oracle is based on the line number where the advice should occur and this might make the oracle fragile when the base program evolves. In future work, the evolution of test cases needs to be explored. PCDs are particularly vulnerable to evolution. If new join points are added because the base program evolved, join points could be improperly matched by the existing PCDs, or on the contrary, join points could be improperly ignored by the existing PCDs. It would be useful to conduct an empirical study to see how test suites written with different techniques can detect such faults and can evolve with the program.

	Copyright c	0 John Wiley & Sons, Ltd.	Softw. Test. Verif. Reliab. 0; 0:0-0