<matrixBuild _class='hudson.matrix.MatrixBuild'><action _class='hudson.model.CauseAction'><cause _class='hudson.triggers.SCMTrigger$SCMTriggerCause'><shortDescription>Started by an SCM change</shortDescription></cause></action><action></action><action _class='hudson.model.ParametersAction'><parameter _class='hudson.model.StringParameterValue'><name>BRANCH</name><value>master</value></parameter><parameter _class='hudson.model.StringParameterValue'><name>EMAIL_NOTIFICATIONS</name><value>jenkins-notifications@lists.osmocom.org laforge@gnumonks.org</value></parameter></action><action _class='jenkins.metrics.impl.TimeInQueueAction'><blockedDurationMillis>0</blockedDurationMillis><blockedTimeMillis>0</blockedTimeMillis><buildableDurationMillis>0</buildableDurationMillis><buildableTimeMillis>0</buildableTimeMillis><buildingDurationMillis>939532</buildingDurationMillis><executingTimeMillis>939532</executingTimeMillis><executorUtilization>1.0</executorUtilization><queuingDurationMillis>5001</queuingDurationMillis><queuingTimeMillis>5001</queuingTimeMillis><subTaskCount>0</subTaskCount><totalDurationMillis>944533</totalDurationMillis><waitingDurationMillis>5000</waitingDurationMillis><waitingTimeMillis>5000</waitingTimeMillis></action><action></action><action _class='hudson.plugins.git.util.BuildData'><buildsByBranchName><refsremotesoriginpmaierfixgr _class='hudson.plugins.git.util.Build'><buildNumber>2045</buildNumber><marked><SHA1>e5f56dd35f1b2347a59f88b401b59997798fff67</SHA1><branch><SHA1>e5f56dd35f1b2347a59f88b401b59997798fff67</SHA1><name>refs/remotes/origin/pmaier/fixgr</name></branch></marked><revision><SHA1>e5f56dd35f1b2347a59f88b401b59997798fff67</SHA1><branch><SHA1>e5f56dd35f1b2347a59f88b401b59997798fff67</SHA1><name>refs/remotes/origin/pmaier/fixgr</name></branch></revision></refsremotesoriginpmaierfixgr><originmaster _class='hudson.plugins.git.util.Build'><buildNumber>2117</buildNumber><marked><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><branch><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><name>origin/master</name></branch></marked><revision><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><branch><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><name>origin/master</name></branch></revision></originmaster><refsremotesoriginpmaierara-m _class='hudson.plugins.git.util.Build'><buildNumber>1320</buildNumber><marked><SHA1>8f289234f74045496c3752bf1bb9397302f3e912</SHA1><branch><SHA1>8f289234f74045496c3752bf1bb9397302f3e912</SHA1><name>refs/remotes/origin/pmaier/ara-m</name></branch></marked><revision><SHA1>8f289234f74045496c3752bf1bb9397302f3e912</SHA1><branch><SHA1>8f289234f74045496c3752bf1bb9397302f3e912</SHA1><name>refs/remotes/origin/pmaier/ara-m</name></branch></revision></refsremotesoriginpmaierara-m><refsremotesoriginpmaierkeepfiles _class='hudson.plugins.git.util.Build'><buildNumber>1353</buildNumber><marked><SHA1>3d815859830197b9c55e0a49a1bd2532f71285e1</SHA1><branch><SHA1>3d815859830197b9c55e0a49a1bd2532f71285e1</SHA1><name>refs/remotes/origin/pmaier/keepfiles</name></branch></marked><revision><SHA1>3d815859830197b9c55e0a49a1bd2532f71285e1</SHA1><branch><SHA1>3d815859830197b9c55e0a49a1bd2532f71285e1</SHA1><name>refs/remotes/origin/pmaier/keepfiles</name></branch></revision></refsremotesoriginpmaierkeepfiles><refsremotesoriginpmaierfixapdu _class='hudson.plugins.git.util.Build'><buildNumber>1421</buildNumber><marked><SHA1>568e8ae9b817ec2473907bfdd30870410890ffb0</SHA1><branch><SHA1>568e8ae9b817ec2473907bfdd30870410890ffb0</SHA1><name>refs/remotes/origin/pmaier/fixapdu</name></branch></marked><revision><SHA1>568e8ae9b817ec2473907bfdd30870410890ffb0</SHA1><branch><SHA1>568e8ae9b817ec2473907bfdd30870410890ffb0</SHA1><name>refs/remotes/origin/pmaier/fixapdu</name></branch></revision></refsremotesoriginpmaierfixapdu><refsremotesoriginpmaieraramtest _class='hudson.plugins.git.util.Build'><buildNumber>1467</buildNumber><marked><SHA1>6a555ac5ccad9ee2cae5e0ba247990f824f8e9b6</SHA1><branch><SHA1>6a555ac5ccad9ee2cae5e0ba247990f824f8e9b6</SHA1><name>refs/remotes/origin/pmaier/aramtest</name></branch></marked><revision><SHA1>6a555ac5ccad9ee2cae5e0ba247990f824f8e9b6</SHA1><branch><SHA1>6a555ac5ccad9ee2cae5e0ba247990f824f8e9b6</SHA1><name>refs/remotes/origin/pmaier/aramtest</name></branch></revision></refsremotesoriginpmaieraramtest><refsremotesoriginosmithwip _class='hudson.plugins.git.util.Build'><buildNumber>1816</buildNumber><marked><SHA1>e4ea1c997348370ba1d7415bfd926ac873b58c87</SHA1><branch><SHA1>e4ea1c997348370ba1d7415bfd926ac873b58c87</SHA1><name>refs/remotes/origin/osmith/wip</name></branch></marked><revision><SHA1>e4ea1c997348370ba1d7415bfd926ac873b58c87</SHA1><branch><SHA1>e4ea1c997348370ba1d7415bfd926ac873b58c87</SHA1><name>refs/remotes/origin/osmith/wip</name></branch></revision></refsremotesoriginosmithwip><refsremotesoriginpmaierotatest _class='hudson.plugins.git.util.Build'><buildNumber>2022</buildNumber><marked><SHA1>f57f047c627392c40fbe349b1a73ccebe05dc005</SHA1><branch><SHA1>f57f047c627392c40fbe349b1a73ccebe05dc005</SHA1><name>refs/remotes/origin/pmaier/otatest</name></branch></marked><revision><SHA1>f57f047c627392c40fbe349b1a73ccebe05dc005</SHA1><branch><SHA1>f57f047c627392c40fbe349b1a73ccebe05dc005</SHA1><name>refs/remotes/origin/pmaier/otatest</name></branch></revision></refsremotesoriginpmaierotatest><refsremotesoriginmaster _class='hudson.plugins.git.util.Build'><buildNumber>402</buildNumber><marked><SHA1>4f888a0414101dee4f20aa12579491fcc71707b3</SHA1><branch><SHA1>4f888a0414101dee4f20aa12579491fcc71707b3</SHA1><name>refs/remotes/origin/master</name></branch></marked><revision><SHA1>4f888a0414101dee4f20aa12579491fcc71707b3</SHA1><branch><SHA1>4f888a0414101dee4f20aa12579491fcc71707b3</SHA1><name>refs/remotes/origin/master</name></branch></revision></refsremotesoriginmaster></buildsByBranchName><lastBuiltRevision><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><branch><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><name>origin/master</name></branch></lastBuiltRevision><remoteUrl>https://gerrit.osmocom.org/pysim</remoteUrl><scmName></scmName></action><action></action><action></action><action></action><action _class='org.jenkinsci.plugins.displayurlapi.actions.RunDisplayAction'><artifactsUrl>https://jenkins.osmocom.org/jenkins/job/master-pysim/2117/artifact</artifactsUrl><changesUrl>https://jenkins.osmocom.org/jenkins/job/master-pysim/changes</changesUrl><displayUrl>https://jenkins.osmocom.org/jenkins/job/master-pysim/2117/</displayUrl><testsUrl>https://jenkins.osmocom.org/jenkins/job/master-pysim/2117/testReport</testsUrl></action><building>false</building><displayName>#2117</displayName><duration>939532</duration><estimatedDuration>951977</estimatedDuration><fullDisplayName>master-pysim #2117</fullDisplayName><id>2117</id><inProgress>false</inProgress><keepLog>false</keepLog><number>2117</number><queueId>102158</queueId><result>SUCCESS</result><timestamp>1777332607420</timestamp><url>https://jenkins.osmocom.org/jenkins/job/master-pysim/2117/</url><builtOn></builtOn><changeSet _class='hudson.plugins.git.GitChangeSetList'><item _class='hudson.plugins.git.GitChangeSet'><affectedPath>pySim/esim/saip/batch.py</affectedPath><affectedPath>pySim/esim/saip/param_source.py</affectedPath><commitId>a95622a022204cc097303d203df408ea8edc6a5c</commitId><timestamp>1777068914000</timestamp><author><absoluteUrl>https://jenkins.osmocom.org/jenkins/user/fixeria</absoluteUrl><fullName>Vadim Yanitskiy</fullName></author><authorEmail>vyanitskiy@sysmocom.de</authorEmail><comment>personalization: add param_source.py, add batch.py

Implement pySim.esim.saip.batch.BatchPersonalization,
generating N eSIM profiles from a preset configuration.

Batch parameters can be fed by a constant, incrementing, random or from
CSV rows: add pySim.esim.saip.param_source.* classes to feed such input
to each of the BatchPersonalization's ConfigurableParameter instances.

Related: SYS#6768
Change-Id: I01ae40a06605eb205bfb409189fcd2b3a128855a
Jenkins: skip-card-test
</comment><date>2026-04-25 05:15:14 +0700</date><id>a95622a022204cc097303d203df408ea8edc6a5c</id><msg>personalization: add param_source.py, add batch.py</msg><path><editType>add</editType><file>pySim/esim/saip/param_source.py</file></path><path><editType>add</editType><file>pySim/esim/saip/batch.py</file></path></item><item _class='hudson.plugins.git.GitChangeSet'><affectedPath>pySim/esim/saip/personalization.py</affectedPath><commitId>ac593bb14d387003563ea17cd7d3e3ddbd693d8d</commitId><timestamp>1777068914000</timestamp><author><absoluteUrl>https://jenkins.osmocom.org/jenkins/user/fixeria</absoluteUrl><fullName>Vadim Yanitskiy</fullName></author><authorEmail>vyanitskiy@sysmocom.de</authorEmail><comment>personalization: implement reading back values from a PES

Implement get_values_from_pes(), the reverse direction of apply_val():
read back and return values from a ProfileElementSequence. Implement for
all ConfigurableParameter subclasses.

Future: SdKey.get_values_from_pes() is reading pe.decoded[], which works
fine, but I07dfc378705eba1318e9e8652796cbde106c6a52 will change this
implementation to use the higher level ProfileElementSD members.

Implementation detail:

Implement get_values_from_pes() as classmethod that returns a generator.
Subclasses should yield all occurences of their parameter in a given
PES.

For example, the ICCID can appear in multiple places.
Iccid.get_values_from_pes() yields all of the individual values. A set()
of the results quickly tells whether the PES is consistent.

Rationales for reading back values:

This allows auditing an eSIM profile, particularly for producing an
output.csv from a batch personalization (that generated lots of random
key material which now needs to be fed to an HLR...).

Reading back from a binary result is more reliable than storing the
values that were fed into a personalization.
By auditing final DER results with this code, I discovered:
- "oh, there already was some key material in my UPP template."
- "all IMSIs ended up the same, forgot to set up the parameter."
- the SdKey.apply() implementations currently don't work, see
  I07dfc378705eba1318e9e8652796cbde106c6a52 for a fix.

Change-Id: I234fc4317f0bdc1a486f0cee4fa432c1dce9b463
Jenkins: skip-card-test
</comment><date>2026-04-25 05:15:14 +0700</date><id>ac593bb14d387003563ea17cd7d3e3ddbd693d8d</id><msg>personalization: implement reading back values from a PES</msg><path><editType>edit</editType><file>pySim/esim/saip/personalization.py</file></path></item><item _class='hudson.plugins.git.GitChangeSet'><affectedPath>pySim/esim/saip/personalization.py</affectedPath><commitId>d7072e92635e6733552f25f526da55e2fc62412d</commitId><timestamp>1777068914000</timestamp><author><absoluteUrl>https://jenkins.osmocom.org/jenkins/user/fixeria</absoluteUrl><fullName>Vadim Yanitskiy</fullName></author><authorEmail>vyanitskiy@sysmocom.de</authorEmail><comment>personalization: indicate default ParamSource per ConfigurableParameter

Add default_source class members pointing to ParamSource classes to all
ConfigurableParameter subclasses.

This is useful to automatically set up a default ParamSource for a given
ConfigurableParameter subclass, during user interaction to produce a
batch personalization.

For example, if the user selects a Pin1 parameter, a calling program can
implicitly set this to a RandomDigitSource, which will magically make it
work the way that most users need.

BTW, default_source and default_value can be combined to configure a
matching ParamSource instance:

  my_source = MyParam.default_source.from_str( MyParam.default_value )

Change-Id: Ie58d13bce3fa1aa2547cf3cee918c2f5b30a8b32
Jenkins: skip-card-test
</comment><date>2026-04-25 05:15:14 +0700</date><id>d7072e92635e6733552f25f526da55e2fc62412d</id><msg>personalization: indicate default ParamSource per ConfigurableParameter</msg><path><editType>edit</editType><file>pySim/esim/saip/personalization.py</file></path></item><kind>git</kind></changeSet><culprit><absoluteUrl>https://jenkins.osmocom.org/jenkins/user/fixeria</absoluteUrl><description></description><fullName>Vadim Yanitskiy</fullName><id>fixeria</id></culprit><run><action _class='hudson.matrix.MatrixChildParametersAction'><parameter _class='hudson.model.StringParameterValue'><name>BRANCH</name><value>master</value></parameter><parameter _class='hudson.model.StringParameterValue'><name>EMAIL_NOTIFICATIONS</name><value>jenkins-notifications@lists.osmocom.org laforge@gnumonks.org</value></parameter></action><action></action><action _class='hudson.model.CauseAction'><cause _class='hudson.model.Cause$UpstreamCause'><shortDescription>Started by upstream project "master-pysim" build number 2,117</shortDescription><upstreamBuild>2117</upstreamBuild><upstreamProject>master-pysim</upstreamProject><upstreamUrl>job/master-pysim/</upstreamUrl></cause></action><action _class='jenkins.metrics.impl.TimeInQueueAction'><blockedDurationMillis>0</blockedDurationMillis><blockedTimeMillis>0</blockedTimeMillis><buildableDurationMillis>0</buildableDurationMillis><buildableTimeMillis>0</buildableTimeMillis><buildingDurationMillis>935901</buildingDurationMillis><executingTimeMillis>935901</executingTimeMillis><executorUtilization>1.0</executorUtilization><subTaskCount>0</subTaskCount><waitingDurationMillis>72</waitingDurationMillis><waitingTimeMillis>72</waitingTimeMillis></action><action></action><action _class='hudson.plugins.git.util.BuildData'><buildsByBranchName><originmaster _class='hudson.plugins.git.util.Build'><buildNumber>2117</buildNumber><marked><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><branch><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><name>origin/master</name></branch></marked><revision><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><branch><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><name>origin/master</name></branch></revision></originmaster></buildsByBranchName><lastBuiltRevision><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><branch><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><name>origin/master</name></branch></lastBuiltRevision><remoteUrl>https://gerrit.osmocom.org/pysim</remoteUrl><scmName></scmName></action><action></action><action></action><action _class='org.jenkinsci.plugins.displayurlapi.actions.RunDisplayAction'></action><building>false</building><displayName>#2117</displayName><duration>935901</duration><estimatedDuration>942336</estimatedDuration><fullDisplayName>master-pysim » card-test,a1=default,a3=default,a4=default,simtester #2117</fullDisplayName><id>2117</id><inProgress>false</inProgress><keepLog>false</keepLog><number>2117</number><queueId>102162</queueId><result>SUCCESS</result><timestamp>1777332607420</timestamp><url>https://jenkins.osmocom.org/jenkins/job/master-pysim/JOB_TYPE=card-test,a1=default,a3=default,a4=default,label=simtester/2117/</url><builtOn>simtester</builtOn><changeSet _class='hudson.plugins.git.GitChangeSetList'><item _class='hudson.plugins.git.GitChangeSet'><affectedPath>pySim/esim/saip/batch.py</affectedPath><affectedPath>pySim/esim/saip/param_source.py</affectedPath><commitId>a95622a022204cc097303d203df408ea8edc6a5c</commitId><timestamp>1777068914000</timestamp><author><absoluteUrl>https://jenkins.osmocom.org/jenkins/user/fixeria</absoluteUrl><fullName>Vadim Yanitskiy</fullName></author><authorEmail>vyanitskiy@sysmocom.de</authorEmail><comment>personalization: add param_source.py, add batch.py

Implement pySim.esim.saip.batch.BatchPersonalization,
generating N eSIM profiles from a preset configuration.

Batch parameters can be fed by a constant, incrementing, random or from
CSV rows: add pySim.esim.saip.param_source.* classes to feed such input
to each of the BatchPersonalization's ConfigurableParameter instances.

Related: SYS#6768
Change-Id: I01ae40a06605eb205bfb409189fcd2b3a128855a
Jenkins: skip-card-test
</comment><date>2026-04-25 05:15:14 +0700</date><id>a95622a022204cc097303d203df408ea8edc6a5c</id><msg>personalization: add param_source.py, add batch.py</msg><path><editType>add</editType><file>pySim/esim/saip/batch.py</file></path><path><editType>add</editType><file>pySim/esim/saip/param_source.py</file></path></item><item _class='hudson.plugins.git.GitChangeSet'><affectedPath>pySim/esim/saip/personalization.py</affectedPath><commitId>ac593bb14d387003563ea17cd7d3e3ddbd693d8d</commitId><timestamp>1777068914000</timestamp><author><absoluteUrl>https://jenkins.osmocom.org/jenkins/user/fixeria</absoluteUrl><fullName>Vadim Yanitskiy</fullName></author><authorEmail>vyanitskiy@sysmocom.de</authorEmail><comment>personalization: implement reading back values from a PES

Implement get_values_from_pes(), the reverse direction of apply_val():
read back and return values from a ProfileElementSequence. Implement for
all ConfigurableParameter subclasses.

Future: SdKey.get_values_from_pes() is reading pe.decoded[], which works
fine, but I07dfc378705eba1318e9e8652796cbde106c6a52 will change this
implementation to use the higher level ProfileElementSD members.

Implementation detail:

Implement get_values_from_pes() as classmethod that returns a generator.
Subclasses should yield all occurences of their parameter in a given
PES.

For example, the ICCID can appear in multiple places.
Iccid.get_values_from_pes() yields all of the individual values. A set()
of the results quickly tells whether the PES is consistent.

Rationales for reading back values:

This allows auditing an eSIM profile, particularly for producing an
output.csv from a batch personalization (that generated lots of random
key material which now needs to be fed to an HLR...).

Reading back from a binary result is more reliable than storing the
values that were fed into a personalization.
By auditing final DER results with this code, I discovered:
- "oh, there already was some key material in my UPP template."
- "all IMSIs ended up the same, forgot to set up the parameter."
- the SdKey.apply() implementations currently don't work, see
  I07dfc378705eba1318e9e8652796cbde106c6a52 for a fix.

Change-Id: I234fc4317f0bdc1a486f0cee4fa432c1dce9b463
Jenkins: skip-card-test
</comment><date>2026-04-25 05:15:14 +0700</date><id>ac593bb14d387003563ea17cd7d3e3ddbd693d8d</id><msg>personalization: implement reading back values from a PES</msg><path><editType>edit</editType><file>pySim/esim/saip/personalization.py</file></path></item><item _class='hudson.plugins.git.GitChangeSet'><affectedPath>pySim/esim/saip/personalization.py</affectedPath><commitId>d7072e92635e6733552f25f526da55e2fc62412d</commitId><timestamp>1777068914000</timestamp><author><absoluteUrl>https://jenkins.osmocom.org/jenkins/user/fixeria</absoluteUrl><fullName>Vadim Yanitskiy</fullName></author><authorEmail>vyanitskiy@sysmocom.de</authorEmail><comment>personalization: indicate default ParamSource per ConfigurableParameter

Add default_source class members pointing to ParamSource classes to all
ConfigurableParameter subclasses.

This is useful to automatically set up a default ParamSource for a given
ConfigurableParameter subclass, during user interaction to produce a
batch personalization.

For example, if the user selects a Pin1 parameter, a calling program can
implicitly set this to a RandomDigitSource, which will magically make it
work the way that most users need.

BTW, default_source and default_value can be combined to configure a
matching ParamSource instance:

  my_source = MyParam.default_source.from_str( MyParam.default_value )

Change-Id: Ie58d13bce3fa1aa2547cf3cee918c2f5b30a8b32
Jenkins: skip-card-test
</comment><date>2026-04-25 05:15:14 +0700</date><id>d7072e92635e6733552f25f526da55e2fc62412d</id><msg>personalization: indicate default ParamSource per ConfigurableParameter</msg><path><editType>edit</editType><file>pySim/esim/saip/personalization.py</file></path></item><kind>git</kind></changeSet><culprit><absoluteUrl>https://jenkins.osmocom.org/jenkins/user/fixeria</absoluteUrl><fullName>Vadim Yanitskiy</fullName></culprit></run><run><action _class='hudson.matrix.MatrixChildParametersAction'><parameter _class='hudson.model.StringParameterValue'><name>BRANCH</name><value>master</value></parameter><parameter _class='hudson.model.StringParameterValue'><name>EMAIL_NOTIFICATIONS</name><value>jenkins-notifications@lists.osmocom.org laforge@gnumonks.org</value></parameter></action><action></action><action _class='hudson.model.CauseAction'><cause _class='hudson.model.Cause$UpstreamCause'><shortDescription>Started by upstream project "master-pysim" build number 2,117</shortDescription><upstreamBuild>2117</upstreamBuild><upstreamProject>master-pysim</upstreamProject><upstreamUrl>job/master-pysim/</upstreamUrl></cause></action><action _class='jenkins.metrics.impl.TimeInQueueAction'><blockedDurationMillis>0</blockedDurationMillis><blockedTimeMillis>0</blockedTimeMillis><buildableDurationMillis>0</buildableDurationMillis><buildableTimeMillis>0</buildableTimeMillis><buildingDurationMillis>14535</buildingDurationMillis><executingTimeMillis>14535</executingTimeMillis><executorUtilization>1.0</executorUtilization><subTaskCount>0</subTaskCount><waitingDurationMillis>2</waitingDurationMillis><waitingTimeMillis>2</waitingTimeMillis></action><action></action><action _class='hudson.plugins.git.util.BuildData'><buildsByBranchName><originmaster _class='hudson.plugins.git.util.Build'><buildNumber>2117</buildNumber><marked><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><branch><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><name>origin/master</name></branch></marked><revision><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><branch><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><name>origin/master</name></branch></revision></originmaster></buildsByBranchName><lastBuiltRevision><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><branch><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><name>origin/master</name></branch></lastBuiltRevision><remoteUrl>https://gerrit.osmocom.org/pysim</remoteUrl><scmName></scmName></action><action></action><action></action><action _class='org.jenkinsci.plugins.displayurlapi.actions.RunDisplayAction'></action><building>false</building><displayName>#2117</displayName><duration>14535</duration><estimatedDuration>15685</estimatedDuration><fullDisplayName>master-pysim » distcheck,a1=default,a3=default,a4=default,osmocom-master #2117</fullDisplayName><id>2117</id><inProgress>false</inProgress><keepLog>false</keepLog><number>2117</number><queueId>102163</queueId><result>SUCCESS</result><timestamp>1777332607420</timestamp><url>https://jenkins.osmocom.org/jenkins/job/master-pysim/JOB_TYPE=distcheck,a1=default,a3=default,a4=default,label=osmocom-master/2117/</url><builtOn>build4-deb12build-ansible</builtOn><changeSet _class='hudson.plugins.git.GitChangeSetList'><item _class='hudson.plugins.git.GitChangeSet'><affectedPath>pySim/esim/saip/batch.py</affectedPath><affectedPath>pySim/esim/saip/param_source.py</affectedPath><commitId>a95622a022204cc097303d203df408ea8edc6a5c</commitId><timestamp>1777068914000</timestamp><author><absoluteUrl>https://jenkins.osmocom.org/jenkins/user/fixeria</absoluteUrl><fullName>Vadim Yanitskiy</fullName></author><authorEmail>vyanitskiy@sysmocom.de</authorEmail><comment>personalization: add param_source.py, add batch.py

Implement pySim.esim.saip.batch.BatchPersonalization,
generating N eSIM profiles from a preset configuration.

Batch parameters can be fed by a constant, incrementing, random or from
CSV rows: add pySim.esim.saip.param_source.* classes to feed such input
to each of the BatchPersonalization's ConfigurableParameter instances.

Related: SYS#6768
Change-Id: I01ae40a06605eb205bfb409189fcd2b3a128855a
Jenkins: skip-card-test
</comment><date>2026-04-25 05:15:14 +0700</date><id>a95622a022204cc097303d203df408ea8edc6a5c</id><msg>personalization: add param_source.py, add batch.py</msg><path><editType>add</editType><file>pySim/esim/saip/param_source.py</file></path><path><editType>add</editType><file>pySim/esim/saip/batch.py</file></path></item><item _class='hudson.plugins.git.GitChangeSet'><affectedPath>pySim/esim/saip/personalization.py</affectedPath><commitId>ac593bb14d387003563ea17cd7d3e3ddbd693d8d</commitId><timestamp>1777068914000</timestamp><author><absoluteUrl>https://jenkins.osmocom.org/jenkins/user/fixeria</absoluteUrl><fullName>Vadim Yanitskiy</fullName></author><authorEmail>vyanitskiy@sysmocom.de</authorEmail><comment>personalization: implement reading back values from a PES

Implement get_values_from_pes(), the reverse direction of apply_val():
read back and return values from a ProfileElementSequence. Implement for
all ConfigurableParameter subclasses.

Future: SdKey.get_values_from_pes() is reading pe.decoded[], which works
fine, but I07dfc378705eba1318e9e8652796cbde106c6a52 will change this
implementation to use the higher level ProfileElementSD members.

Implementation detail:

Implement get_values_from_pes() as classmethod that returns a generator.
Subclasses should yield all occurences of their parameter in a given
PES.

For example, the ICCID can appear in multiple places.
Iccid.get_values_from_pes() yields all of the individual values. A set()
of the results quickly tells whether the PES is consistent.

Rationales for reading back values:

This allows auditing an eSIM profile, particularly for producing an
output.csv from a batch personalization (that generated lots of random
key material which now needs to be fed to an HLR...).

Reading back from a binary result is more reliable than storing the
values that were fed into a personalization.
By auditing final DER results with this code, I discovered:
- "oh, there already was some key material in my UPP template."
- "all IMSIs ended up the same, forgot to set up the parameter."
- the SdKey.apply() implementations currently don't work, see
  I07dfc378705eba1318e9e8652796cbde106c6a52 for a fix.

Change-Id: I234fc4317f0bdc1a486f0cee4fa432c1dce9b463
Jenkins: skip-card-test
</comment><date>2026-04-25 05:15:14 +0700</date><id>ac593bb14d387003563ea17cd7d3e3ddbd693d8d</id><msg>personalization: implement reading back values from a PES</msg><path><editType>edit</editType><file>pySim/esim/saip/personalization.py</file></path></item><item _class='hudson.plugins.git.GitChangeSet'><affectedPath>pySim/esim/saip/personalization.py</affectedPath><commitId>d7072e92635e6733552f25f526da55e2fc62412d</commitId><timestamp>1777068914000</timestamp><author><absoluteUrl>https://jenkins.osmocom.org/jenkins/user/fixeria</absoluteUrl><fullName>Vadim Yanitskiy</fullName></author><authorEmail>vyanitskiy@sysmocom.de</authorEmail><comment>personalization: indicate default ParamSource per ConfigurableParameter

Add default_source class members pointing to ParamSource classes to all
ConfigurableParameter subclasses.

This is useful to automatically set up a default ParamSource for a given
ConfigurableParameter subclass, during user interaction to produce a
batch personalization.

For example, if the user selects a Pin1 parameter, a calling program can
implicitly set this to a RandomDigitSource, which will magically make it
work the way that most users need.

BTW, default_source and default_value can be combined to configure a
matching ParamSource instance:

  my_source = MyParam.default_source.from_str( MyParam.default_value )

Change-Id: Ie58d13bce3fa1aa2547cf3cee918c2f5b30a8b32
Jenkins: skip-card-test
</comment><date>2026-04-25 05:15:14 +0700</date><id>d7072e92635e6733552f25f526da55e2fc62412d</id><msg>personalization: indicate default ParamSource per ConfigurableParameter</msg><path><editType>edit</editType><file>pySim/esim/saip/personalization.py</file></path></item><kind>git</kind></changeSet><culprit><absoluteUrl>https://jenkins.osmocom.org/jenkins/user/fixeria</absoluteUrl><fullName>Vadim Yanitskiy</fullName></culprit></run><run><action _class='hudson.matrix.MatrixChildParametersAction'><parameter _class='hudson.model.StringParameterValue'><name>BRANCH</name><value>master</value></parameter><parameter _class='hudson.model.StringParameterValue'><name>EMAIL_NOTIFICATIONS</name><value>jenkins-notifications@lists.osmocom.org laforge@gnumonks.org</value></parameter></action><action></action><action _class='hudson.model.CauseAction'><cause _class='hudson.model.Cause$UpstreamCause'><shortDescription>Started by upstream project "master-pysim" build number 2,117</shortDescription><upstreamBuild>2117</upstreamBuild><upstreamProject>master-pysim</upstreamProject><upstreamUrl>job/master-pysim/</upstreamUrl></cause></action><action _class='jenkins.metrics.impl.TimeInQueueAction'><blockedDurationMillis>0</blockedDurationMillis><blockedTimeMillis>0</blockedTimeMillis><buildableDurationMillis>0</buildableDurationMillis><buildableTimeMillis>0</buildableTimeMillis><buildingDurationMillis>43010</buildingDurationMillis><executingTimeMillis>43010</executingTimeMillis><executorUtilization>1.0</executorUtilization><subTaskCount>0</subTaskCount><waitingDurationMillis>0</waitingDurationMillis><waitingTimeMillis>0</waitingTimeMillis></action><action></action><action _class='hudson.plugins.git.util.BuildData'><buildsByBranchName><refsremotesoriginpmaierfixgr _class='hudson.plugins.git.util.Build'><buildNumber>2045</buildNumber><marked><SHA1>e5f56dd35f1b2347a59f88b401b59997798fff67</SHA1><branch><SHA1>e5f56dd35f1b2347a59f88b401b59997798fff67</SHA1><name>refs/remotes/origin/pmaier/fixgr</name></branch></marked><revision><SHA1>e5f56dd35f1b2347a59f88b401b59997798fff67</SHA1><branch><SHA1>e5f56dd35f1b2347a59f88b401b59997798fff67</SHA1><name>refs/remotes/origin/pmaier/fixgr</name></branch></revision></refsremotesoriginpmaierfixgr><originmaster _class='hudson.plugins.git.util.Build'><buildNumber>2117</buildNumber><marked><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><branch><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><name>origin/master</name></branch></marked><revision><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><branch><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><name>origin/master</name></branch></revision></originmaster><refsremotesoriginpmaierara-m _class='hudson.plugins.git.util.Build'><buildNumber>1320</buildNumber><marked><SHA1>8f289234f74045496c3752bf1bb9397302f3e912</SHA1><branch><SHA1>8f289234f74045496c3752bf1bb9397302f3e912</SHA1><name>refs/remotes/origin/pmaier/ara-m</name></branch></marked><revision><SHA1>8f289234f74045496c3752bf1bb9397302f3e912</SHA1><branch><SHA1>8f289234f74045496c3752bf1bb9397302f3e912</SHA1><name>refs/remotes/origin/pmaier/ara-m</name></branch></revision></refsremotesoriginpmaierara-m><refsremotesoriginpmaierkeepfiles _class='hudson.plugins.git.util.Build'><buildNumber>1353</buildNumber><marked><SHA1>3d815859830197b9c55e0a49a1bd2532f71285e1</SHA1><branch><SHA1>3d815859830197b9c55e0a49a1bd2532f71285e1</SHA1><name>refs/remotes/origin/pmaier/keepfiles</name></branch></marked><revision><SHA1>3d815859830197b9c55e0a49a1bd2532f71285e1</SHA1><branch><SHA1>3d815859830197b9c55e0a49a1bd2532f71285e1</SHA1><name>refs/remotes/origin/pmaier/keepfiles</name></branch></revision></refsremotesoriginpmaierkeepfiles><refsremotesoriginpmaierfixapdu _class='hudson.plugins.git.util.Build'><buildNumber>1421</buildNumber><marked><SHA1>568e8ae9b817ec2473907bfdd30870410890ffb0</SHA1><branch><SHA1>568e8ae9b817ec2473907bfdd30870410890ffb0</SHA1><name>refs/remotes/origin/pmaier/fixapdu</name></branch></marked><revision><SHA1>568e8ae9b817ec2473907bfdd30870410890ffb0</SHA1><branch><SHA1>568e8ae9b817ec2473907bfdd30870410890ffb0</SHA1><name>refs/remotes/origin/pmaier/fixapdu</name></branch></revision></refsremotesoriginpmaierfixapdu><refsremotesoriginpmaieraramtest _class='hudson.plugins.git.util.Build'><buildNumber>1467</buildNumber><marked><SHA1>6a555ac5ccad9ee2cae5e0ba247990f824f8e9b6</SHA1><branch><SHA1>6a555ac5ccad9ee2cae5e0ba247990f824f8e9b6</SHA1><name>refs/remotes/origin/pmaier/aramtest</name></branch></marked><revision><SHA1>6a555ac5ccad9ee2cae5e0ba247990f824f8e9b6</SHA1><branch><SHA1>6a555ac5ccad9ee2cae5e0ba247990f824f8e9b6</SHA1><name>refs/remotes/origin/pmaier/aramtest</name></branch></revision></refsremotesoriginpmaieraramtest><refsremotesoriginosmithwip _class='hudson.plugins.git.util.Build'><buildNumber>1816</buildNumber><marked><SHA1>e4ea1c997348370ba1d7415bfd926ac873b58c87</SHA1><branch><SHA1>e4ea1c997348370ba1d7415bfd926ac873b58c87</SHA1><name>refs/remotes/origin/osmith/wip</name></branch></marked><revision><SHA1>e4ea1c997348370ba1d7415bfd926ac873b58c87</SHA1><branch><SHA1>e4ea1c997348370ba1d7415bfd926ac873b58c87</SHA1><name>refs/remotes/origin/osmith/wip</name></branch></revision></refsremotesoriginosmithwip><refsremotesoriginpmaierotatest _class='hudson.plugins.git.util.Build'><buildNumber>2022</buildNumber><marked><SHA1>f57f047c627392c40fbe349b1a73ccebe05dc005</SHA1><branch><SHA1>f57f047c627392c40fbe349b1a73ccebe05dc005</SHA1><name>refs/remotes/origin/pmaier/otatest</name></branch></marked><revision><SHA1>f57f047c627392c40fbe349b1a73ccebe05dc005</SHA1><branch><SHA1>f57f047c627392c40fbe349b1a73ccebe05dc005</SHA1><name>refs/remotes/origin/pmaier/otatest</name></branch></revision></refsremotesoriginpmaierotatest><refsremotesoriginmaster _class='hudson.plugins.git.util.Build'><buildNumber>402</buildNumber><marked><SHA1>4f888a0414101dee4f20aa12579491fcc71707b3</SHA1><branch><SHA1>4f888a0414101dee4f20aa12579491fcc71707b3</SHA1><name>refs/remotes/origin/master</name></branch></marked><revision><SHA1>4f888a0414101dee4f20aa12579491fcc71707b3</SHA1><branch><SHA1>4f888a0414101dee4f20aa12579491fcc71707b3</SHA1><name>refs/remotes/origin/master</name></branch></revision></refsremotesoriginmaster></buildsByBranchName><lastBuiltRevision><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><branch><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><name>origin/master</name></branch></lastBuiltRevision><remoteUrl>https://gerrit.osmocom.org/pysim</remoteUrl><scmName></scmName></action><action></action><action></action><action _class='org.jenkinsci.plugins.displayurlapi.actions.RunDisplayAction'></action><building>false</building><displayName>#2117</displayName><duration>43010</duration><estimatedDuration>42794</estimatedDuration><fullDisplayName>master-pysim » docs,a1=default,a3=default,a4=default,osmocom-master #2117</fullDisplayName><id>2117</id><inProgress>false</inProgress><keepLog>false</keepLog><number>2117</number><queueId>102161</queueId><result>SUCCESS</result><timestamp>1777332607420</timestamp><url>https://jenkins.osmocom.org/jenkins/job/master-pysim/JOB_TYPE=docs,a1=default,a3=default,a4=default,label=osmocom-master/2117/</url><builtOn>build5-deb12build-ansible</builtOn><changeSet _class='hudson.plugins.git.GitChangeSetList'><item _class='hudson.plugins.git.GitChangeSet'><affectedPath>pySim/esim/saip/batch.py</affectedPath><affectedPath>pySim/esim/saip/param_source.py</affectedPath><commitId>a95622a022204cc097303d203df408ea8edc6a5c</commitId><timestamp>1777068914000</timestamp><author><absoluteUrl>https://jenkins.osmocom.org/jenkins/user/fixeria</absoluteUrl><fullName>Vadim Yanitskiy</fullName></author><authorEmail>vyanitskiy@sysmocom.de</authorEmail><comment>personalization: add param_source.py, add batch.py

Implement pySim.esim.saip.batch.BatchPersonalization,
generating N eSIM profiles from a preset configuration.

Batch parameters can be fed by a constant, incrementing, random or from
CSV rows: add pySim.esim.saip.param_source.* classes to feed such input
to each of the BatchPersonalization's ConfigurableParameter instances.

Related: SYS#6768
Change-Id: I01ae40a06605eb205bfb409189fcd2b3a128855a
Jenkins: skip-card-test
</comment><date>2026-04-25 05:15:14 +0700</date><id>a95622a022204cc097303d203df408ea8edc6a5c</id><msg>personalization: add param_source.py, add batch.py</msg><path><editType>add</editType><file>pySim/esim/saip/batch.py</file></path><path><editType>add</editType><file>pySim/esim/saip/param_source.py</file></path></item><item _class='hudson.plugins.git.GitChangeSet'><affectedPath>pySim/esim/saip/personalization.py</affectedPath><commitId>ac593bb14d387003563ea17cd7d3e3ddbd693d8d</commitId><timestamp>1777068914000</timestamp><author><absoluteUrl>https://jenkins.osmocom.org/jenkins/user/fixeria</absoluteUrl><fullName>Vadim Yanitskiy</fullName></author><authorEmail>vyanitskiy@sysmocom.de</authorEmail><comment>personalization: implement reading back values from a PES

Implement get_values_from_pes(), the reverse direction of apply_val():
read back and return values from a ProfileElementSequence. Implement for
all ConfigurableParameter subclasses.

Future: SdKey.get_values_from_pes() is reading pe.decoded[], which works
fine, but I07dfc378705eba1318e9e8652796cbde106c6a52 will change this
implementation to use the higher level ProfileElementSD members.

Implementation detail:

Implement get_values_from_pes() as classmethod that returns a generator.
Subclasses should yield all occurences of their parameter in a given
PES.

For example, the ICCID can appear in multiple places.
Iccid.get_values_from_pes() yields all of the individual values. A set()
of the results quickly tells whether the PES is consistent.

Rationales for reading back values:

This allows auditing an eSIM profile, particularly for producing an
output.csv from a batch personalization (that generated lots of random
key material which now needs to be fed to an HLR...).

Reading back from a binary result is more reliable than storing the
values that were fed into a personalization.
By auditing final DER results with this code, I discovered:
- "oh, there already was some key material in my UPP template."
- "all IMSIs ended up the same, forgot to set up the parameter."
- the SdKey.apply() implementations currently don't work, see
  I07dfc378705eba1318e9e8652796cbde106c6a52 for a fix.

Change-Id: I234fc4317f0bdc1a486f0cee4fa432c1dce9b463
Jenkins: skip-card-test
</comment><date>2026-04-25 05:15:14 +0700</date><id>ac593bb14d387003563ea17cd7d3e3ddbd693d8d</id><msg>personalization: implement reading back values from a PES</msg><path><editType>edit</editType><file>pySim/esim/saip/personalization.py</file></path></item><item _class='hudson.plugins.git.GitChangeSet'><affectedPath>pySim/esim/saip/personalization.py</affectedPath><commitId>d7072e92635e6733552f25f526da55e2fc62412d</commitId><timestamp>1777068914000</timestamp><author><absoluteUrl>https://jenkins.osmocom.org/jenkins/user/fixeria</absoluteUrl><fullName>Vadim Yanitskiy</fullName></author><authorEmail>vyanitskiy@sysmocom.de</authorEmail><comment>personalization: indicate default ParamSource per ConfigurableParameter

Add default_source class members pointing to ParamSource classes to all
ConfigurableParameter subclasses.

This is useful to automatically set up a default ParamSource for a given
ConfigurableParameter subclass, during user interaction to produce a
batch personalization.

For example, if the user selects a Pin1 parameter, a calling program can
implicitly set this to a RandomDigitSource, which will magically make it
work the way that most users need.

BTW, default_source and default_value can be combined to configure a
matching ParamSource instance:

  my_source = MyParam.default_source.from_str( MyParam.default_value )

Change-Id: Ie58d13bce3fa1aa2547cf3cee918c2f5b30a8b32
Jenkins: skip-card-test
</comment><date>2026-04-25 05:15:14 +0700</date><id>d7072e92635e6733552f25f526da55e2fc62412d</id><msg>personalization: indicate default ParamSource per ConfigurableParameter</msg><path><editType>edit</editType><file>pySim/esim/saip/personalization.py</file></path></item><kind>git</kind></changeSet><culprit><absoluteUrl>https://jenkins.osmocom.org/jenkins/user/fixeria</absoluteUrl><fullName>Vadim Yanitskiy</fullName></culprit></run><run><action _class='hudson.matrix.MatrixChildParametersAction'><parameter _class='hudson.model.StringParameterValue'><name>BRANCH</name><value>master</value></parameter><parameter _class='hudson.model.StringParameterValue'><name>EMAIL_NOTIFICATIONS</name><value>jenkins-notifications@lists.osmocom.org laforge@gnumonks.org</value></parameter></action><action></action><action _class='hudson.model.CauseAction'><cause _class='hudson.model.Cause$UpstreamCause'><shortDescription>Started by upstream project "master-pysim" build number 2,117</shortDescription><upstreamBuild>2117</upstreamBuild><upstreamProject>master-pysim</upstreamProject><upstreamUrl>job/master-pysim/</upstreamUrl></cause></action><action _class='jenkins.metrics.impl.TimeInQueueAction'><blockedDurationMillis>0</blockedDurationMillis><blockedTimeMillis>0</blockedTimeMillis><buildableDurationMillis>0</buildableDurationMillis><buildableTimeMillis>0</buildableTimeMillis><buildingDurationMillis>15771</buildingDurationMillis><executingTimeMillis>15771</executingTimeMillis><executorUtilization>1.0</executorUtilization><subTaskCount>0</subTaskCount><waitingDurationMillis>0</waitingDurationMillis><waitingTimeMillis>0</waitingTimeMillis></action><action></action><action _class='hudson.plugins.git.util.BuildData'><buildsByBranchName><refsremotesoriginpmaierfixgr _class='hudson.plugins.git.util.Build'><buildNumber>2045</buildNumber><marked><SHA1>e5f56dd35f1b2347a59f88b401b59997798fff67</SHA1><branch><SHA1>e5f56dd35f1b2347a59f88b401b59997798fff67</SHA1><name>refs/remotes/origin/pmaier/fixgr</name></branch></marked><revision><SHA1>e5f56dd35f1b2347a59f88b401b59997798fff67</SHA1><branch><SHA1>e5f56dd35f1b2347a59f88b401b59997798fff67</SHA1><name>refs/remotes/origin/pmaier/fixgr</name></branch></revision></refsremotesoriginpmaierfixgr><originmaster _class='hudson.plugins.git.util.Build'><buildNumber>2117</buildNumber><marked><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><branch><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><name>origin/master</name></branch></marked><revision><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><branch><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><name>origin/master</name></branch></revision></originmaster><refsremotesoriginpmaierara-m _class='hudson.plugins.git.util.Build'><buildNumber>1320</buildNumber><marked><SHA1>8f289234f74045496c3752bf1bb9397302f3e912</SHA1><branch><SHA1>8f289234f74045496c3752bf1bb9397302f3e912</SHA1><name>refs/remotes/origin/pmaier/ara-m</name></branch></marked><revision><SHA1>8f289234f74045496c3752bf1bb9397302f3e912</SHA1><branch><SHA1>8f289234f74045496c3752bf1bb9397302f3e912</SHA1><name>refs/remotes/origin/pmaier/ara-m</name></branch></revision></refsremotesoriginpmaierara-m><refsremotesoriginpmaierkeepfiles _class='hudson.plugins.git.util.Build'><buildNumber>1353</buildNumber><marked><SHA1>3d815859830197b9c55e0a49a1bd2532f71285e1</SHA1><branch><SHA1>3d815859830197b9c55e0a49a1bd2532f71285e1</SHA1><name>refs/remotes/origin/pmaier/keepfiles</name></branch></marked><revision><SHA1>3d815859830197b9c55e0a49a1bd2532f71285e1</SHA1><branch><SHA1>3d815859830197b9c55e0a49a1bd2532f71285e1</SHA1><name>refs/remotes/origin/pmaier/keepfiles</name></branch></revision></refsremotesoriginpmaierkeepfiles><refsremotesoriginpmaierfixapdu _class='hudson.plugins.git.util.Build'><buildNumber>1421</buildNumber><marked><SHA1>568e8ae9b817ec2473907bfdd30870410890ffb0</SHA1><branch><SHA1>568e8ae9b817ec2473907bfdd30870410890ffb0</SHA1><name>refs/remotes/origin/pmaier/fixapdu</name></branch></marked><revision><SHA1>568e8ae9b817ec2473907bfdd30870410890ffb0</SHA1><branch><SHA1>568e8ae9b817ec2473907bfdd30870410890ffb0</SHA1><name>refs/remotes/origin/pmaier/fixapdu</name></branch></revision></refsremotesoriginpmaierfixapdu><refsremotesoriginpmaieraramtest _class='hudson.plugins.git.util.Build'><buildNumber>1467</buildNumber><marked><SHA1>6a555ac5ccad9ee2cae5e0ba247990f824f8e9b6</SHA1><branch><SHA1>6a555ac5ccad9ee2cae5e0ba247990f824f8e9b6</SHA1><name>refs/remotes/origin/pmaier/aramtest</name></branch></marked><revision><SHA1>6a555ac5ccad9ee2cae5e0ba247990f824f8e9b6</SHA1><branch><SHA1>6a555ac5ccad9ee2cae5e0ba247990f824f8e9b6</SHA1><name>refs/remotes/origin/pmaier/aramtest</name></branch></revision></refsremotesoriginpmaieraramtest><refsremotesoriginosmithwip _class='hudson.plugins.git.util.Build'><buildNumber>1816</buildNumber><marked><SHA1>e4ea1c997348370ba1d7415bfd926ac873b58c87</SHA1><branch><SHA1>e4ea1c997348370ba1d7415bfd926ac873b58c87</SHA1><name>refs/remotes/origin/osmith/wip</name></branch></marked><revision><SHA1>e4ea1c997348370ba1d7415bfd926ac873b58c87</SHA1><branch><SHA1>e4ea1c997348370ba1d7415bfd926ac873b58c87</SHA1><name>refs/remotes/origin/osmith/wip</name></branch></revision></refsremotesoriginosmithwip><refsremotesoriginpmaierotatest _class='hudson.plugins.git.util.Build'><buildNumber>2022</buildNumber><marked><SHA1>f57f047c627392c40fbe349b1a73ccebe05dc005</SHA1><branch><SHA1>f57f047c627392c40fbe349b1a73ccebe05dc005</SHA1><name>refs/remotes/origin/pmaier/otatest</name></branch></marked><revision><SHA1>f57f047c627392c40fbe349b1a73ccebe05dc005</SHA1><branch><SHA1>f57f047c627392c40fbe349b1a73ccebe05dc005</SHA1><name>refs/remotes/origin/pmaier/otatest</name></branch></revision></refsremotesoriginpmaierotatest><refsremotesoriginmaster _class='hudson.plugins.git.util.Build'><buildNumber>402</buildNumber><marked><SHA1>4f888a0414101dee4f20aa12579491fcc71707b3</SHA1><branch><SHA1>4f888a0414101dee4f20aa12579491fcc71707b3</SHA1><name>refs/remotes/origin/master</name></branch></marked><revision><SHA1>4f888a0414101dee4f20aa12579491fcc71707b3</SHA1><branch><SHA1>4f888a0414101dee4f20aa12579491fcc71707b3</SHA1><name>refs/remotes/origin/master</name></branch></revision></refsremotesoriginmaster></buildsByBranchName><lastBuiltRevision><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><branch><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><name>origin/master</name></branch></lastBuiltRevision><remoteUrl>https://gerrit.osmocom.org/pysim</remoteUrl><scmName></scmName></action><action></action><action></action><action _class='org.jenkinsci.plugins.displayurlapi.actions.RunDisplayAction'></action><building>false</building><displayName>#2117</displayName><duration>15771</duration><estimatedDuration>19506</estimatedDuration><fullDisplayName>master-pysim » pylint,a1=default,a3=default,a4=default,osmocom-master #2117</fullDisplayName><id>2117</id><inProgress>false</inProgress><keepLog>false</keepLog><number>2117</number><queueId>102160</queueId><result>SUCCESS</result><timestamp>1777332607420</timestamp><url>https://jenkins.osmocom.org/jenkins/job/master-pysim/JOB_TYPE=pylint,a1=default,a3=default,a4=default,label=osmocom-master/2117/</url><builtOn>build4-deb12build-ansible</builtOn><changeSet _class='hudson.plugins.git.GitChangeSetList'><item _class='hudson.plugins.git.GitChangeSet'><affectedPath>pySim/esim/saip/batch.py</affectedPath><affectedPath>pySim/esim/saip/param_source.py</affectedPath><commitId>a95622a022204cc097303d203df408ea8edc6a5c</commitId><timestamp>1777068914000</timestamp><author><absoluteUrl>https://jenkins.osmocom.org/jenkins/user/fixeria</absoluteUrl><fullName>Vadim Yanitskiy</fullName></author><authorEmail>vyanitskiy@sysmocom.de</authorEmail><comment>personalization: add param_source.py, add batch.py

Implement pySim.esim.saip.batch.BatchPersonalization,
generating N eSIM profiles from a preset configuration.

Batch parameters can be fed by a constant, incrementing, random or from
CSV rows: add pySim.esim.saip.param_source.* classes to feed such input
to each of the BatchPersonalization's ConfigurableParameter instances.

Related: SYS#6768
Change-Id: I01ae40a06605eb205bfb409189fcd2b3a128855a
Jenkins: skip-card-test
</comment><date>2026-04-25 05:15:14 +0700</date><id>a95622a022204cc097303d203df408ea8edc6a5c</id><msg>personalization: add param_source.py, add batch.py</msg><path><editType>add</editType><file>pySim/esim/saip/batch.py</file></path><path><editType>add</editType><file>pySim/esim/saip/param_source.py</file></path></item><item _class='hudson.plugins.git.GitChangeSet'><affectedPath>pySim/esim/saip/personalization.py</affectedPath><commitId>ac593bb14d387003563ea17cd7d3e3ddbd693d8d</commitId><timestamp>1777068914000</timestamp><author><absoluteUrl>https://jenkins.osmocom.org/jenkins/user/fixeria</absoluteUrl><fullName>Vadim Yanitskiy</fullName></author><authorEmail>vyanitskiy@sysmocom.de</authorEmail><comment>personalization: implement reading back values from a PES

Implement get_values_from_pes(), the reverse direction of apply_val():
read back and return values from a ProfileElementSequence. Implement for
all ConfigurableParameter subclasses.

Future: SdKey.get_values_from_pes() is reading pe.decoded[], which works
fine, but I07dfc378705eba1318e9e8652796cbde106c6a52 will change this
implementation to use the higher level ProfileElementSD members.

Implementation detail:

Implement get_values_from_pes() as classmethod that returns a generator.
Subclasses should yield all occurences of their parameter in a given
PES.

For example, the ICCID can appear in multiple places.
Iccid.get_values_from_pes() yields all of the individual values. A set()
of the results quickly tells whether the PES is consistent.

Rationales for reading back values:

This allows auditing an eSIM profile, particularly for producing an
output.csv from a batch personalization (that generated lots of random
key material which now needs to be fed to an HLR...).

Reading back from a binary result is more reliable than storing the
values that were fed into a personalization.
By auditing final DER results with this code, I discovered:
- "oh, there already was some key material in my UPP template."
- "all IMSIs ended up the same, forgot to set up the parameter."
- the SdKey.apply() implementations currently don't work, see
  I07dfc378705eba1318e9e8652796cbde106c6a52 for a fix.

Change-Id: I234fc4317f0bdc1a486f0cee4fa432c1dce9b463
Jenkins: skip-card-test
</comment><date>2026-04-25 05:15:14 +0700</date><id>ac593bb14d387003563ea17cd7d3e3ddbd693d8d</id><msg>personalization: implement reading back values from a PES</msg><path><editType>edit</editType><file>pySim/esim/saip/personalization.py</file></path></item><item _class='hudson.plugins.git.GitChangeSet'><affectedPath>pySim/esim/saip/personalization.py</affectedPath><commitId>d7072e92635e6733552f25f526da55e2fc62412d</commitId><timestamp>1777068914000</timestamp><author><absoluteUrl>https://jenkins.osmocom.org/jenkins/user/fixeria</absoluteUrl><fullName>Vadim Yanitskiy</fullName></author><authorEmail>vyanitskiy@sysmocom.de</authorEmail><comment>personalization: indicate default ParamSource per ConfigurableParameter

Add default_source class members pointing to ParamSource classes to all
ConfigurableParameter subclasses.

This is useful to automatically set up a default ParamSource for a given
ConfigurableParameter subclass, during user interaction to produce a
batch personalization.

For example, if the user selects a Pin1 parameter, a calling program can
implicitly set this to a RandomDigitSource, which will magically make it
work the way that most users need.

BTW, default_source and default_value can be combined to configure a
matching ParamSource instance:

  my_source = MyParam.default_source.from_str( MyParam.default_value )

Change-Id: Ie58d13bce3fa1aa2547cf3cee918c2f5b30a8b32
Jenkins: skip-card-test
</comment><date>2026-04-25 05:15:14 +0700</date><id>d7072e92635e6733552f25f526da55e2fc62412d</id><msg>personalization: indicate default ParamSource per ConfigurableParameter</msg><path><editType>edit</editType><file>pySim/esim/saip/personalization.py</file></path></item><kind>git</kind></changeSet><culprit><absoluteUrl>https://jenkins.osmocom.org/jenkins/user/fixeria</absoluteUrl><fullName>Vadim Yanitskiy</fullName></culprit></run><run><action _class='hudson.matrix.MatrixChildParametersAction'><parameter _class='hudson.model.StringParameterValue'><name>BRANCH</name><value>master</value></parameter><parameter _class='hudson.model.StringParameterValue'><name>EMAIL_NOTIFICATIONS</name><value>jenkins-notifications@lists.osmocom.org laforge@gnumonks.org</value></parameter></action><action></action><action _class='hudson.model.CauseAction'><cause _class='hudson.model.Cause$UpstreamCause'><shortDescription>Started by upstream project "master-pysim" build number 2,117</shortDescription><upstreamBuild>2117</upstreamBuild><upstreamProject>master-pysim</upstreamProject><upstreamUrl>job/master-pysim/</upstreamUrl></cause></action><action _class='jenkins.metrics.impl.TimeInQueueAction'><blockedDurationMillis>0</blockedDurationMillis><blockedTimeMillis>0</blockedTimeMillis><buildableDurationMillis>0</buildableDurationMillis><buildableTimeMillis>0</buildableTimeMillis><buildingDurationMillis>13780</buildingDurationMillis><executingTimeMillis>13780</executingTimeMillis><executorUtilization>1.0</executorUtilization><subTaskCount>0</subTaskCount><waitingDurationMillis>0</waitingDurationMillis><waitingTimeMillis>0</waitingTimeMillis></action><action></action><action _class='hudson.plugins.git.util.BuildData'><buildsByBranchName><originmaster _class='hudson.plugins.git.util.Build'><buildNumber>2117</buildNumber><marked><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><branch><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><name>origin/master</name></branch></marked><revision><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><branch><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><name>origin/master</name></branch></revision></originmaster></buildsByBranchName><lastBuiltRevision><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><branch><SHA1>d7072e92635e6733552f25f526da55e2fc62412d</SHA1><name>origin/master</name></branch></lastBuiltRevision><remoteUrl>https://gerrit.osmocom.org/pysim</remoteUrl><scmName></scmName></action><action></action><action></action><action _class='org.jenkinsci.plugins.displayurlapi.actions.RunDisplayAction'></action><building>false</building><displayName>#2117</displayName><duration>13780</duration><estimatedDuration>16944</estimatedDuration><fullDisplayName>master-pysim » test,a1=default,a3=default,a4=default,osmocom-master #2117</fullDisplayName><id>2117</id><inProgress>false</inProgress><keepLog>false</keepLog><number>2117</number><queueId>102159</queueId><result>SUCCESS</result><timestamp>1777332607420</timestamp><url>https://jenkins.osmocom.org/jenkins/job/master-pysim/JOB_TYPE=test,a1=default,a3=default,a4=default,label=osmocom-master/2117/</url><builtOn>build5-deb12build-ansible</builtOn><changeSet _class='hudson.plugins.git.GitChangeSetList'><item _class='hudson.plugins.git.GitChangeSet'><affectedPath>pySim/esim/saip/batch.py</affectedPath><affectedPath>pySim/esim/saip/param_source.py</affectedPath><commitId>a95622a022204cc097303d203df408ea8edc6a5c</commitId><timestamp>1777068914000</timestamp><author><absoluteUrl>https://jenkins.osmocom.org/jenkins/user/fixeria</absoluteUrl><fullName>Vadim Yanitskiy</fullName></author><authorEmail>vyanitskiy@sysmocom.de</authorEmail><comment>personalization: add param_source.py, add batch.py

Implement pySim.esim.saip.batch.BatchPersonalization,
generating N eSIM profiles from a preset configuration.

Batch parameters can be fed by a constant, incrementing, random or from
CSV rows: add pySim.esim.saip.param_source.* classes to feed such input
to each of the BatchPersonalization's ConfigurableParameter instances.

Related: SYS#6768
Change-Id: I01ae40a06605eb205bfb409189fcd2b3a128855a
Jenkins: skip-card-test
</comment><date>2026-04-25 05:15:14 +0700</date><id>a95622a022204cc097303d203df408ea8edc6a5c</id><msg>personalization: add param_source.py, add batch.py</msg><path><editType>add</editType><file>pySim/esim/saip/batch.py</file></path><path><editType>add</editType><file>pySim/esim/saip/param_source.py</file></path></item><item _class='hudson.plugins.git.GitChangeSet'><affectedPath>pySim/esim/saip/personalization.py</affectedPath><commitId>ac593bb14d387003563ea17cd7d3e3ddbd693d8d</commitId><timestamp>1777068914000</timestamp><author><absoluteUrl>https://jenkins.osmocom.org/jenkins/user/fixeria</absoluteUrl><fullName>Vadim Yanitskiy</fullName></author><authorEmail>vyanitskiy@sysmocom.de</authorEmail><comment>personalization: implement reading back values from a PES

Implement get_values_from_pes(), the reverse direction of apply_val():
read back and return values from a ProfileElementSequence. Implement for
all ConfigurableParameter subclasses.

Future: SdKey.get_values_from_pes() is reading pe.decoded[], which works
fine, but I07dfc378705eba1318e9e8652796cbde106c6a52 will change this
implementation to use the higher level ProfileElementSD members.

Implementation detail:

Implement get_values_from_pes() as classmethod that returns a generator.
Subclasses should yield all occurences of their parameter in a given
PES.

For example, the ICCID can appear in multiple places.
Iccid.get_values_from_pes() yields all of the individual values. A set()
of the results quickly tells whether the PES is consistent.

Rationales for reading back values:

This allows auditing an eSIM profile, particularly for producing an
output.csv from a batch personalization (that generated lots of random
key material which now needs to be fed to an HLR...).

Reading back from a binary result is more reliable than storing the
values that were fed into a personalization.
By auditing final DER results with this code, I discovered:
- "oh, there already was some key material in my UPP template."
- "all IMSIs ended up the same, forgot to set up the parameter."
- the SdKey.apply() implementations currently don't work, see
  I07dfc378705eba1318e9e8652796cbde106c6a52 for a fix.

Change-Id: I234fc4317f0bdc1a486f0cee4fa432c1dce9b463
Jenkins: skip-card-test
</comment><date>2026-04-25 05:15:14 +0700</date><id>ac593bb14d387003563ea17cd7d3e3ddbd693d8d</id><msg>personalization: implement reading back values from a PES</msg><path><editType>edit</editType><file>pySim/esim/saip/personalization.py</file></path></item><item _class='hudson.plugins.git.GitChangeSet'><affectedPath>pySim/esim/saip/personalization.py</affectedPath><commitId>d7072e92635e6733552f25f526da55e2fc62412d</commitId><timestamp>1777068914000</timestamp><author><absoluteUrl>https://jenkins.osmocom.org/jenkins/user/fixeria</absoluteUrl><fullName>Vadim Yanitskiy</fullName></author><authorEmail>vyanitskiy@sysmocom.de</authorEmail><comment>personalization: indicate default ParamSource per ConfigurableParameter

Add default_source class members pointing to ParamSource classes to all
ConfigurableParameter subclasses.

This is useful to automatically set up a default ParamSource for a given
ConfigurableParameter subclass, during user interaction to produce a
batch personalization.

For example, if the user selects a Pin1 parameter, a calling program can
implicitly set this to a RandomDigitSource, which will magically make it
work the way that most users need.

BTW, default_source and default_value can be combined to configure a
matching ParamSource instance:

  my_source = MyParam.default_source.from_str( MyParam.default_value )

Change-Id: Ie58d13bce3fa1aa2547cf3cee918c2f5b30a8b32
Jenkins: skip-card-test
</comment><date>2026-04-25 05:15:14 +0700</date><id>d7072e92635e6733552f25f526da55e2fc62412d</id><msg>personalization: indicate default ParamSource per ConfigurableParameter</msg><path><editType>edit</editType><file>pySim/esim/saip/personalization.py</file></path></item><kind>git</kind></changeSet><culprit><absoluteUrl>https://jenkins.osmocom.org/jenkins/user/fixeria</absoluteUrl><fullName>Vadim Yanitskiy</fullName></culprit></run><run><action _class='hudson.matrix.MatrixChildParametersAction'><parameter _class='hudson.model.StringParameterValue'><name>BRANCH</name><value>master</value></parameter><parameter _class='hudson.model.StringParameterValue'><name>EMAIL_NOTIFICATIONS</name><value>jenkins-notifications@lists.osmocom.org laforge@gnumonks.org</value></parameter></action><action></action><action _class='hudson.model.CauseAction'><cause _class='hudson.model.Cause$UpstreamCause'><shortDescription>Started by upstream project "master-pysim" build number 2,112</shortDescription><upstreamBuild>2112</upstreamBuild><upstreamProject>master-pysim</upstreamProject><upstreamUrl>job/master-pysim/</upstreamUrl></cause></action><action _class='jenkins.metrics.impl.TimeInQueueAction'><blockedDurationMillis>0</blockedDurationMillis><blockedTimeMillis>0</blockedTimeMillis><buildableDurationMillis>939063</buildableDurationMillis><buildableTimeMillis>939063</buildableTimeMillis><buildingDurationMillis>6575</buildingDurationMillis><executingTimeMillis>6575</executingTimeMillis><executorUtilization>1.0</executorUtilization><subTaskCount>0</subTaskCount><waitingDurationMillis>113</waitingDurationMillis><waitingTimeMillis>113</waitingTimeMillis></action><action></action><action _class='hudson.plugins.git.util.BuildData'><buildsByBranchName><refsremotesoriginpmaierfixgr _class='hudson.plugins.git.util.Build'><buildNumber>2045</buildNumber><marked><SHA1>e5f56dd35f1b2347a59f88b401b59997798fff67</SHA1><branch><SHA1>e5f56dd35f1b2347a59f88b401b59997798fff67</SHA1><name>refs/remotes/origin/pmaier/fixgr</name></branch></marked><revision><SHA1>e5f56dd35f1b2347a59f88b401b59997798fff67</SHA1><branch><SHA1>e5f56dd35f1b2347a59f88b401b59997798fff67</SHA1><name>refs/remotes/origin/pmaier/fixgr</name></branch></revision></refsremotesoriginpmaierfixgr><originmaster _class='hudson.plugins.git.util.Build'><buildNumber>2112</buildNumber><marked><SHA1>03b58985a51ab39ff4f6edc82b3e7fdd923a782b</SHA1><branch><SHA1>03b58985a51ab39ff4f6edc82b3e7fdd923a782b</SHA1><name>origin/master</name></branch></marked><revision><SHA1>03b58985a51ab39ff4f6edc82b3e7fdd923a782b</SHA1><branch><SHA1>03b58985a51ab39ff4f6edc82b3e7fdd923a782b</SHA1><name>origin/master</name></branch></revision></originmaster><refsremotesoriginpmaierara-m _class='hudson.plugins.git.util.Build'><buildNumber>1320</buildNumber><marked><SHA1>8f289234f74045496c3752bf1bb9397302f3e912</SHA1><branch><SHA1>8f289234f74045496c3752bf1bb9397302f3e912</SHA1><name>refs/remotes/origin/pmaier/ara-m</name></branch></marked><revision><SHA1>8f289234f74045496c3752bf1bb9397302f3e912</SHA1><branch><SHA1>8f289234f74045496c3752bf1bb9397302f3e912</SHA1><name>refs/remotes/origin/pmaier/ara-m</name></branch></revision></refsremotesoriginpmaierara-m><refsremotesoriginpmaierkeepfiles _class='hudson.plugins.git.util.Build'><buildNumber>1353</buildNumber><marked><SHA1>3d815859830197b9c55e0a49a1bd2532f71285e1</SHA1><branch><SHA1>3d815859830197b9c55e0a49a1bd2532f71285e1</SHA1><name>refs/remotes/origin/pmaier/keepfiles</name></branch></marked><revision><SHA1>3d815859830197b9c55e0a49a1bd2532f71285e1</SHA1><branch><SHA1>3d815859830197b9c55e0a49a1bd2532f71285e1</SHA1><name>refs/remotes/origin/pmaier/keepfiles</name></branch></revision></refsremotesoriginpmaierkeepfiles><refsremotesoriginpmaierfixapdu _class='hudson.plugins.git.util.Build'><buildNumber>1421</buildNumber><marked><SHA1>568e8ae9b817ec2473907bfdd30870410890ffb0</SHA1><branch><SHA1>568e8ae9b817ec2473907bfdd30870410890ffb0</SHA1><name>refs/remotes/origin/pmaier/fixapdu</name></branch></marked><revision><SHA1>568e8ae9b817ec2473907bfdd30870410890ffb0</SHA1><branch><SHA1>568e8ae9b817ec2473907bfdd30870410890ffb0</SHA1><name>refs/remotes/origin/pmaier/fixapdu</name></branch></revision></refsremotesoriginpmaierfixapdu><refsremotesoriginpmaieraramtest _class='hudson.plugins.git.util.Build'><buildNumber>1467</buildNumber><marked><SHA1>6a555ac5ccad9ee2cae5e0ba247990f824f8e9b6</SHA1><branch><SHA1>6a555ac5ccad9ee2cae5e0ba247990f824f8e9b6</SHA1><name>refs/remotes/origin/pmaier/aramtest</name></branch></marked><revision><SHA1>6a555ac5ccad9ee2cae5e0ba247990f824f8e9b6</SHA1><branch><SHA1>6a555ac5ccad9ee2cae5e0ba247990f824f8e9b6</SHA1><name>refs/remotes/origin/pmaier/aramtest</name></branch></revision></refsremotesoriginpmaieraramtest><refsremotesoriginosmithwip _class='hudson.plugins.git.util.Build'><buildNumber>1816</buildNumber><marked><SHA1>e4ea1c997348370ba1d7415bfd926ac873b58c87</SHA1><branch><SHA1>e4ea1c997348370ba1d7415bfd926ac873b58c87</SHA1><name>refs/remotes/origin/osmith/wip</name></branch></marked><revision><SHA1>e4ea1c997348370ba1d7415bfd926ac873b58c87</SHA1><branch><SHA1>e4ea1c997348370ba1d7415bfd926ac873b58c87</SHA1><name>refs/remotes/origin/osmith/wip</name></branch></revision></refsremotesoriginosmithwip><refsremotesoriginpmaierotatest _class='hudson.plugins.git.util.Build'><buildNumber>2022</buildNumber><marked><SHA1>f57f047c627392c40fbe349b1a73ccebe05dc005</SHA1><branch><SHA1>f57f047c627392c40fbe349b1a73ccebe05dc005</SHA1><name>refs/remotes/origin/pmaier/otatest</name></branch></marked><revision><SHA1>f57f047c627392c40fbe349b1a73ccebe05dc005</SHA1><branch><SHA1>f57f047c627392c40fbe349b1a73ccebe05dc005</SHA1><name>refs/remotes/origin/pmaier/otatest</name></branch></revision></refsremotesoriginpmaierotatest><refsremotesoriginmaster _class='hudson.plugins.git.util.Build'><buildNumber>402</buildNumber><marked><SHA1>4f888a0414101dee4f20aa12579491fcc71707b3</SHA1><branch><SHA1>4f888a0414101dee4f20aa12579491fcc71707b3</SHA1><name>refs/remotes/origin/master</name></branch></marked><revision><SHA1>4f888a0414101dee4f20aa12579491fcc71707b3</SHA1><branch><SHA1>4f888a0414101dee4f20aa12579491fcc71707b3</SHA1><name>refs/remotes/origin/master</name></branch></revision></refsremotesoriginmaster></buildsByBranchName><lastBuiltRevision><SHA1>03b58985a51ab39ff4f6edc82b3e7fdd923a782b</SHA1><branch><SHA1>03b58985a51ab39ff4f6edc82b3e7fdd923a782b</SHA1><name>origin/master</name></branch></lastBuiltRevision><remoteUrl>https://gerrit.osmocom.org/pysim</remoteUrl><scmName></scmName></action><action></action><action></action><action></action><action _class='org.jenkinsci.plugins.displayurlapi.actions.RunDisplayAction'></action><building>false</building><displayName>#2112</displayName><duration>6575</duration><estimatedDuration>708812</estimatedDuration><fullDisplayName>master-pysim » test,a1=default,a3=default,a4=default,simtester #2112</fullDisplayName><id>2112</id><inProgress>false</inProgress><keepLog>false</keepLog><number>2112</number><queueId>97234</queueId><result>FAILURE</result><timestamp>1777027801994</timestamp><url>https://jenkins.osmocom.org/jenkins/job/master-pysim/JOB_TYPE=test,a1=default,a3=default,a4=default,label=simtester/2112/</url><builtOn>simtester</builtOn><changeSet _class='hudson.plugins.git.GitChangeSetList'><kind>git</kind></changeSet></run></matrixBuild>