mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-07-26 13:47:40 +00:00
Fix flakey tests related to identity name ordering.
This commit is contained in:
committed by
Andrey Smirnov
parent
f0a370db24
commit
021b6f694b
@@ -7,6 +7,7 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
@@ -351,7 +352,13 @@ func (g *GoVerifier) printLog(signers []signatureResult) {
|
|||||||
|
|
||||||
if signer.Entity != nil {
|
if signer.Entity != nil {
|
||||||
i := 0
|
i := 0
|
||||||
|
names := make([]string, 0, len(signer.Entity.Identities))
|
||||||
for name := range signer.Entity.Identities {
|
for name := range signer.Entity.Identities {
|
||||||
|
names = append(names, name)
|
||||||
|
}
|
||||||
|
sort.Strings(names)
|
||||||
|
|
||||||
|
for _, name := range names {
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
fmt.Printf("openpgp: Good signature from \"%s\"\n", name)
|
fmt.Printf("openpgp: Good signature from \"%s\"\n", name)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,89 +1,17 @@
|
|||||||
|
|
||||||
|
|
||||||
aka "Johannes Ranke (Wissenschaftlicher Berater) <johannes.ranke@jrwb.de>"
|
aka "Johannes Ranke <jranke@uni-bremen.de>"
|
||||||
|
Applying filter...
|
||||||
Building download queue...
|
Building download queue...
|
||||||
Download queue: 78 items (200.63 MiB)
|
Download queue: 4 items (338.12 KiB)
|
||||||
Downloading & parsing package files...
|
Downloading & parsing package files...
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/InRelease...
|
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/InRelease...
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/Packages.bz2...
|
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/Packages.bz2...
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/dh-r_20180403~jessiecran.0_all.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/littler_0.3.5-1~jessiecran.0_all.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/littler_0.3.6-1~jessiecran.0_all.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/pkg-r-autopkgtest_20180403~jessiecran.0_all.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/python3-rpy2_2.9.5-1~jessiecran.0_amd64.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/python3-rpy2_2.9.5-1~jessiecran.0_i386.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-base-core-dbg_3.5.2-1~jessiecran.0_amd64.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-base-core-dbg_3.5.2-1~jessiecran.0_i386.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-base-core-dbg_3.5.3-1~jessiecran.0_amd64.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-base-core-dbg_3.5.3-1~jessiecran.0_i386.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-base-core_3.5.2-1~jessiecran.0_amd64.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-base-core_3.5.2-1~jessiecran.0_i386.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-base-core_3.5.3-1~jessiecran.0_amd64.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-base-core_3.5.3-1~jessiecran.0_i386.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-base-dev_3.5.2-1~jessiecran.0_all.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-base-dev_3.5.3-1~jessiecran.0_all.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-base-html_3.5.2-1~jessiecran.0_all.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-base-html_3.5.3-1~jessiecran.0_all.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-base_3.5.2-1~jessiecran.0_all.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-base_3.5.3-1~jessiecran.0_all.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-boot_1.3-20-2~jessiecran.0_all.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-class_7.3-14-2~jessiecran.0_amd64.deb...
|
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-class_7.3-14-2~jessiecran.0_amd64.deb...
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-class_7.3-14-2~jessiecran.0_i386.deb...
|
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-class_7.3-14-2~jessiecran.0_i386.deb...
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-class_7.3-15-1~jessiecran.0_amd64.deb...
|
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-class_7.3-15-1~jessiecran.0_amd64.deb...
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-class_7.3-15-1~jessiecran.0_i386.deb...
|
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-class_7.3-15-1~jessiecran.0_i386.deb...
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-cluster_2.0.7-1-1~jessiecran.0_amd64.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-cluster_2.0.7-1-1~jessiecran.0_i386.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-coda_0.19-1-2~jessiecran.0_all.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-codetools_0.2-15-2~jessiecran.0_all.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-codetools_0.2-16-1~jessiecran.0_all.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-foreign_0.8.71-1~jessiecran.0_amd64.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-foreign_0.8.71-1~jessiecran.0_i386.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-kernsmooth_2.23-15-3~jessiecran.0_amd64.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-kernsmooth_2.23-15-3~jessiecran.0_i386.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-lattice_0.20-35-1~jessiecran.0_amd64.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-lattice_0.20-35-1~jessiecran.0_i386.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-lattice_0.20-38-1~jessiecran.0_amd64.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-lattice_0.20-38-1~jessiecran.0_i386.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-littler_0.3.5-1~jessiecran.0_amd64.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-littler_0.3.5-1~jessiecran.0_i386.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-littler_0.3.6-1~jessiecran.0_i386.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-mass_7.3-51.1-1~jessiecran.0_amd64.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-mass_7.3-51.1-1~jessiecran.0_i386.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-matrix_1.2-15-1~jessiecran.0_amd64.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-matrix_1.2-15-1~jessiecran.0_i386.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-matrix_1.2-16-1~jessiecran.0_amd64.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-matrix_1.2-16-1~jessiecran.0_i386.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-mgcv_1.8-26-1~jessiecran.0_amd64.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-mgcv_1.8-26-1~jessiecran.0_i386.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-mgcv_1.8-27-1~jessiecran.0_amd64.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-mgcv_1.8-27-1~jessiecran.0_i386.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-nlme_3.1.137-1~jessiecran.0_amd64.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-nlme_3.1.137-1~jessiecran.0_i386.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-nnet_7.3-12-2~jessiecran.0_amd64.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-nnet_7.3-12-2~jessiecran.0_i386.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-rodbc_1.3-15-1~jessiecran.0_amd64.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-rodbc_1.3-15-1~jessiecran.0_i386.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-rpart_4.1-13-1~jessiecran.0_amd64.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-rpart_4.1-13-1~jessiecran.0_i386.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-spatial_7.3-11-2~jessiecran.0_amd64.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-spatial_7.3-11-2~jessiecran.0_i386.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-survival_2.43-3-1~jessiecran.0_amd64.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-cran-survival_2.43-3-1~jessiecran.0_i386.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-doc-html_3.5.2-1~jessiecran.0_all.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-doc-html_3.5.3-1~jessiecran.0_all.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-doc-info_3.5.2-1~jessiecran.0_all.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-doc-info_3.5.3-1~jessiecran.0_all.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-doc-pdf_3.5.2-1~jessiecran.0_all.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-doc-pdf_3.5.3-1~jessiecran.0_all.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-mathlib_3.5.2-1~jessiecran.0_amd64.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-mathlib_3.5.2-1~jessiecran.0_i386.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-mathlib_3.5.3-1~jessiecran.0_amd64.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-mathlib_3.5.3-1~jessiecran.0_i386.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-recommended_3.5.2-1~jessiecran.0_all.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/r-recommended_3.5.3-1~jessiecran.0_all.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/rkward-data_0.6.5-1~jessiecran.0_all.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/rkward_0.6.5-1~jessiecran.0_amd64.deb...
|
|
||||||
Downloading https://cloud.r-project.org/bin/linux/debian/jessie-cran35/rkward_0.6.5-1~jessiecran.0_i386.deb...
|
|
||||||
Mirror `flat` has been successfully updated.
|
Mirror `flat` has been successfully updated.
|
||||||
openpgp: Good signature from "Johannes Ranke <jranke@uni-bremen.de>"
|
Packages filtered: 78 -> 4.
|
||||||
|
openpgp: Good signature from "Johannes Ranke (Wissenschaftlicher Berater) <johannes.ranke@jrwb.de>"
|
||||||
openpgp: RSA key ID FCAE2A0E115C3D8A
|
openpgp: RSA key ID FCAE2A0E115C3D8A
|
||||||
@@ -227,7 +227,8 @@ class UpdateMirror15Test(BaseTest):
|
|||||||
def check(self):
|
def check(self):
|
||||||
super(UpdateMirror15Test, self).check()
|
super(UpdateMirror15Test, self).check()
|
||||||
# check pool
|
# check pool
|
||||||
self.check_exists('pool/c7/6b/4bd12fd92e4dfe1b55b18a67a669_libboost-program-options-dev_1.49.0.1_i386.deb')
|
self.check_exists(
|
||||||
|
'pool/c7/6b/4bd12fd92e4dfe1b55b18a67a669_libboost-program-options-dev_1.49.0.1_i386.deb')
|
||||||
|
|
||||||
|
|
||||||
class UpdateMirror16Test(BaseTest):
|
class UpdateMirror16Test(BaseTest):
|
||||||
@@ -248,7 +249,8 @@ class UpdateMirror16Test(BaseTest):
|
|||||||
def prepare(self):
|
def prepare(self):
|
||||||
super(UpdateMirror16Test, self).prepare()
|
super(UpdateMirror16Test, self).prepare()
|
||||||
|
|
||||||
os.makedirs(os.path.join(os.environ["HOME"], ".aptly", "pool", "00", "35"))
|
os.makedirs(os.path.join(
|
||||||
|
os.environ["HOME"], ".aptly", "pool", "00", "35"))
|
||||||
|
|
||||||
shutil.copy(os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "files", "libboost-program-options-dev_1.49.0.1_i386.deb"),
|
shutil.copy(os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "files", "libboost-program-options-dev_1.49.0.1_i386.deb"),
|
||||||
os.path.join(os.environ["HOME"], ".aptly", "pool", "00", "35"))
|
os.path.join(os.environ["HOME"], ".aptly", "pool", "00", "35"))
|
||||||
@@ -256,7 +258,8 @@ class UpdateMirror16Test(BaseTest):
|
|||||||
def check(self):
|
def check(self):
|
||||||
super(UpdateMirror16Test, self).check()
|
super(UpdateMirror16Test, self).check()
|
||||||
# check pool
|
# check pool
|
||||||
self.check_not_exists('pool/c7/6b/4bd12fd92e4dfe1b55b18a67a669_libboost-program-options-dev_1.49.0.1_i386.deb')
|
self.check_not_exists(
|
||||||
|
'pool/c7/6b/4bd12fd92e4dfe1b55b18a67a669_libboost-program-options-dev_1.49.0.1_i386.deb')
|
||||||
|
|
||||||
|
|
||||||
class UpdateMirror17Test(BaseTest):
|
class UpdateMirror17Test(BaseTest):
|
||||||
@@ -275,7 +278,8 @@ class UpdateMirror17Test(BaseTest):
|
|||||||
def prepare(self):
|
def prepare(self):
|
||||||
super(UpdateMirror17Test, self).prepare()
|
super(UpdateMirror17Test, self).prepare()
|
||||||
|
|
||||||
os.makedirs(os.path.join(os.environ["HOME"], ".aptly", "pool", "e0", "bb"))
|
os.makedirs(os.path.join(
|
||||||
|
os.environ["HOME"], ".aptly", "pool", "e0", "bb"))
|
||||||
|
|
||||||
shutil.copy(os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "files", "libboost-program-options-dev_1.62.0.1_i386.deb"),
|
shutil.copy(os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "files", "libboost-program-options-dev_1.62.0.1_i386.deb"),
|
||||||
os.path.join(os.environ["HOME"], ".aptly", "pool", "e0", "bb"))
|
os.path.join(os.environ["HOME"], ".aptly", "pool", "e0", "bb"))
|
||||||
@@ -283,7 +287,8 @@ class UpdateMirror17Test(BaseTest):
|
|||||||
def check(self):
|
def check(self):
|
||||||
super(UpdateMirror17Test, self).check()
|
super(UpdateMirror17Test, self).check()
|
||||||
# check pool
|
# check pool
|
||||||
self.check_not_exists('pool/db/a2/f225645a2a8bd8378e2f64bd1faa_libboost-program-options-dev_1.62.0.1_i386.deb')
|
self.check_not_exists(
|
||||||
|
'pool/db/a2/f225645a2a8bd8378e2f64bd1faa_libboost-program-options-dev_1.62.0.1_i386.deb')
|
||||||
|
|
||||||
|
|
||||||
class UpdateMirror18Test(BaseTest):
|
class UpdateMirror18Test(BaseTest):
|
||||||
@@ -303,7 +308,8 @@ class UpdateMirror18Test(BaseTest):
|
|||||||
def prepare(self):
|
def prepare(self):
|
||||||
super(UpdateMirror18Test, self).prepare()
|
super(UpdateMirror18Test, self).prepare()
|
||||||
|
|
||||||
os.makedirs(os.path.join(os.environ["HOME"], ".aptly", "pool", "e0", "bb"))
|
os.makedirs(os.path.join(
|
||||||
|
os.environ["HOME"], ".aptly", "pool", "e0", "bb"))
|
||||||
|
|
||||||
shutil.copy(os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "files", "libboost-program-options-dev_1.62.0.1_i386.deb"),
|
shutil.copy(os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "files", "libboost-program-options-dev_1.62.0.1_i386.deb"),
|
||||||
os.path.join(os.environ["HOME"], ".aptly", "pool", "e0", "bb"))
|
os.path.join(os.environ["HOME"], ".aptly", "pool", "e0", "bb"))
|
||||||
@@ -311,7 +317,8 @@ class UpdateMirror18Test(BaseTest):
|
|||||||
def check(self):
|
def check(self):
|
||||||
super(UpdateMirror18Test, self).check()
|
super(UpdateMirror18Test, self).check()
|
||||||
# check pool
|
# check pool
|
||||||
self.check_exists('pool/db/a2/f225645a2a8bd8378e2f64bd1faa_libboost-program-options-dev_1.62.0.1_i386.deb')
|
self.check_exists(
|
||||||
|
'pool/db/a2/f225645a2a8bd8378e2f64bd1faa_libboost-program-options-dev_1.62.0.1_i386.deb')
|
||||||
|
|
||||||
|
|
||||||
class UpdateMirror19Test(BaseTest):
|
class UpdateMirror19Test(BaseTest):
|
||||||
@@ -336,7 +343,7 @@ class UpdateMirror20Test(BaseTest):
|
|||||||
"""
|
"""
|
||||||
fixtureGpg = True
|
fixtureGpg = True
|
||||||
fixtureCmds = [
|
fixtureCmds = [
|
||||||
"aptly mirror create --keyring=aptlytest.gpg -architectures=amd64 flat https://cloud.r-project.org/bin/linux/debian jessie-cran35/",
|
"aptly mirror create --keyring=aptlytest.gpg -architectures=amd64 --filter='r-cran-class' flat https://cloud.r-project.org/bin/linux/debian jessie-cran35/",
|
||||||
]
|
]
|
||||||
configOverride = {"gpgProvider": "internal"}
|
configOverride = {"gpgProvider": "internal"}
|
||||||
runCmd = "aptly mirror update --keyring=aptlytest.gpg flat"
|
runCmd = "aptly mirror update --keyring=aptlytest.gpg flat"
|
||||||
|
|||||||
Reference in New Issue
Block a user