diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
commit | 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch) | |
tree | e5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /qa/suites/upgrade/luminous-x/parallel | |
parent | Initial commit. (diff) | |
download | ceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.tar.xz ceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.zip |
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
37 files changed, 403 insertions, 0 deletions
diff --git a/qa/suites/upgrade/luminous-x/parallel/% b/qa/suites/upgrade/luminous-x/parallel/% new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/% diff --git a/qa/suites/upgrade/luminous-x/parallel/.qa b/qa/suites/upgrade/luminous-x/parallel/.qa new file mode 120000 index 00000000..a602a035 --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/.qa @@ -0,0 +1 @@ +../.qa/
\ No newline at end of file diff --git a/qa/suites/upgrade/luminous-x/parallel/0-cluster/+ b/qa/suites/upgrade/luminous-x/parallel/0-cluster/+ new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/0-cluster/+ diff --git a/qa/suites/upgrade/luminous-x/parallel/0-cluster/.qa b/qa/suites/upgrade/luminous-x/parallel/0-cluster/.qa new file mode 120000 index 00000000..a602a035 --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/0-cluster/.qa @@ -0,0 +1 @@ +../.qa/
\ No newline at end of file diff --git a/qa/suites/upgrade/luminous-x/parallel/0-cluster/openstack.yaml b/qa/suites/upgrade/luminous-x/parallel/0-cluster/openstack.yaml new file mode 100644 index 00000000..f4d1349b --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/0-cluster/openstack.yaml @@ -0,0 +1,4 @@ +openstack: + - volumes: # attached to each instance + count: 3 + size: 30 # GB diff --git a/qa/suites/upgrade/luminous-x/parallel/0-cluster/start.yaml b/qa/suites/upgrade/luminous-x/parallel/0-cluster/start.yaml new file mode 100644 index 00000000..b86ddcdc --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/0-cluster/start.yaml @@ -0,0 +1,50 @@ +meta: +- desc: | + Run ceph on two nodes, + with a separate client 0,1,2 third node. + Use xfs beneath the osds. + CephFS tests running on client 2,3 +roles: +- - mon.a + - mgr.x + - mds.a + - osd.0 + - osd.1 + - osd.2 + - osd.3 +- - mon.b + - osd.4 + - osd.5 + - osd.6 + - osd.7 +- - mon.c + - osd.8 + - osd.9 + - osd.10 + - osd.11 +- - client.0 + - client.1 + - client.2 + - client.3 +overrides: + ceph: + mon_bind_msgr2: false + mon_bind_addrvec: false + log-whitelist: + - scrub mismatch + - ScrubResult + - wrongly marked + - \(POOL_APP_NOT_ENABLED\) + - \(SLOW_OPS\) + - overall HEALTH_ + - slow request + - \(MON_MSGR2_NOT_ENABLED\) + conf: + global: + enable experimental unrecoverable data corrupting features: "*" + mon: + mon warn on osd down out interval zero: false + osd: + osd class load list: "*" + osd class default list: "*" + fs: xfs diff --git a/qa/suites/upgrade/luminous-x/parallel/1-ceph-install/.qa b/qa/suites/upgrade/luminous-x/parallel/1-ceph-install/.qa new file mode 120000 index 00000000..a602a035 --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/1-ceph-install/.qa @@ -0,0 +1 @@ +../.qa/
\ No newline at end of file diff --git a/qa/suites/upgrade/luminous-x/parallel/1-ceph-install/luminous.yaml b/qa/suites/upgrade/luminous-x/parallel/1-ceph-install/luminous.yaml new file mode 100644 index 00000000..468d07c2 --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/1-ceph-install/luminous.yaml @@ -0,0 +1,54 @@ +meta: +- desc: | + install ceph/luminous latest + run workload and upgrade-sequence in parallel + upgrade the client node +tasks: +- install: + branch: luminous + exclude_packages: + - librados3 + - ceph-mgr-dashboard + - ceph-mgr-diskprediction-local + - ceph-mgr-diskprediction-cloud + - ceph-mgr-rook + - ceph-mgr-ssh + extra_packages: ['librados2'] +- print: "**** done installing luminous" +- ceph: + log-whitelist: + - overall HEALTH_ + - \(FS_ + - \(MDS_ + - \(OSD_ + - \(MON_DOWN\) + - \(CACHE_POOL_ + - \(POOL_ + - \(MGR_DOWN\) + - \(PG_ + - \(SMALLER_PGP_NUM\) + - Monitor daemon marked osd + - Behind on trimming + - Manager daemon + conf: + global: + mon warn on pool no app: false + bluestore_warn_on_legacy_statfs: false + mon pg warn min per osd: 0 +- exec: + osd.0: + - ceph osd require-osd-release luminous + - ceph osd set-require-min-compat-client luminous +- print: "**** done ceph" +- install.upgrade: + mon.a: + mon.b: + mon.c: +- print: "**** done install.upgrade non-client hosts" +- parallel: + - workload + - upgrade-sequence +- print: "**** done parallel" +- install.upgrade: + client.0: +- print: "**** done install.upgrade on client.0" diff --git a/qa/suites/upgrade/luminous-x/parallel/1.1-pg-log-overrides/normal_pg_log.yaml b/qa/suites/upgrade/luminous-x/parallel/1.1-pg-log-overrides/normal_pg_log.yaml new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/1.1-pg-log-overrides/normal_pg_log.yaml @@ -0,0 +1 @@ + diff --git a/qa/suites/upgrade/luminous-x/parallel/1.1-pg-log-overrides/short_pg_log.yaml b/qa/suites/upgrade/luminous-x/parallel/1.1-pg-log-overrides/short_pg_log.yaml new file mode 100644 index 00000000..e31e37ba --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/1.1-pg-log-overrides/short_pg_log.yaml @@ -0,0 +1,6 @@ +overrides: + ceph: + conf: + osd: + osd min pg log entries: 1 + osd max pg log entries: 2 diff --git a/qa/suites/upgrade/luminous-x/parallel/2-workload/+ b/qa/suites/upgrade/luminous-x/parallel/2-workload/+ new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/2-workload/+ diff --git a/qa/suites/upgrade/luminous-x/parallel/2-workload/.qa b/qa/suites/upgrade/luminous-x/parallel/2-workload/.qa new file mode 120000 index 00000000..a602a035 --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/2-workload/.qa @@ -0,0 +1 @@ +../.qa/
\ No newline at end of file diff --git a/qa/suites/upgrade/luminous-x/parallel/2-workload/blogbench.yaml b/qa/suites/upgrade/luminous-x/parallel/2-workload/blogbench.yaml new file mode 100644 index 00000000..021fcc68 --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/2-workload/blogbench.yaml @@ -0,0 +1,14 @@ +meta: +- desc: | + run a cephfs stress test + mount ceph-fuse on client.2 before running workunit +workload: + full_sequential: + - sequential: + - ceph-fuse: + - print: "**** done ceph-fuse 2-workload" + - workunit: + clients: + client.2: + - suites/blogbench.sh + - print: "**** done suites/blogbench.sh 2-workload" diff --git a/qa/suites/upgrade/luminous-x/parallel/2-workload/ec-rados-default.yaml b/qa/suites/upgrade/luminous-x/parallel/2-workload/ec-rados-default.yaml new file mode 100644 index 00000000..5c5a9588 --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/2-workload/ec-rados-default.yaml @@ -0,0 +1,24 @@ +meta: +- desc: | + run run randomized correctness test for rados operations + on an erasure-coded pool +workload: + full_sequential: + - rados: + clients: [client.0] + ops: 4000 + objects: 50 + ec_pool: true + write_append_excl: false + op_weights: + read: 100 + write: 0 + append: 100 + delete: 50 + snap_create: 50 + snap_remove: 50 + rollback: 50 + copy_from: 50 + setattr: 25 + rmattr: 25 + - print: "**** done rados ec task" diff --git a/qa/suites/upgrade/luminous-x/parallel/2-workload/rados_api.yaml b/qa/suites/upgrade/luminous-x/parallel/2-workload/rados_api.yaml new file mode 100644 index 00000000..e4cc9f96 --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/2-workload/rados_api.yaml @@ -0,0 +1,11 @@ +meta: +- desc: | + object class functional tests +workload: + full_sequential: + - workunit: + branch: luminous + clients: + client.0: + - cls + - print: "**** done cls 2-workload" diff --git a/qa/suites/upgrade/luminous-x/parallel/2-workload/rados_loadgenbig.yaml b/qa/suites/upgrade/luminous-x/parallel/2-workload/rados_loadgenbig.yaml new file mode 100644 index 00000000..874a8c5e --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/2-workload/rados_loadgenbig.yaml @@ -0,0 +1,11 @@ +meta: +- desc: | + generate read/write load with rados objects ranging from 1MB to 25MB +workload: + full_sequential: + - workunit: + branch: luminous + clients: + client.0: + - rados/load-gen-big.sh + - print: "**** done rados/load-gen-big.sh 2-workload" diff --git a/qa/suites/upgrade/luminous-x/parallel/2-workload/rgw_ragweed_prepare.yaml b/qa/suites/upgrade/luminous-x/parallel/2-workload/rgw_ragweed_prepare.yaml new file mode 100644 index 00000000..b95711fe --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/2-workload/rgw_ragweed_prepare.yaml @@ -0,0 +1,14 @@ +meta: +- desc: | + rgw ragweed prepare +workload: + full_sequential: + - sequential: + - rgw: + - client.1 + - ragweed: + client.1: + default-branch: ceph-nautilus + rgw_server: client.1 + stages: prepare + - print: "**** done rgw ragweed prepare 2-workload" diff --git a/qa/suites/upgrade/luminous-x/parallel/2-workload/test_rbd_api.yaml b/qa/suites/upgrade/luminous-x/parallel/2-workload/test_rbd_api.yaml new file mode 100644 index 00000000..81563c90 --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/2-workload/test_rbd_api.yaml @@ -0,0 +1,11 @@ +meta: +- desc: | + librbd C and C++ api tests +workload: + full_sequential: + - workunit: + branch: luminous + clients: + client.0: + - rbd/test_librbd.sh + - print: "**** done rbd/test_librbd.sh 2-workload" diff --git a/qa/suites/upgrade/luminous-x/parallel/2-workload/test_rbd_python.yaml b/qa/suites/upgrade/luminous-x/parallel/2-workload/test_rbd_python.yaml new file mode 100644 index 00000000..e17207d2 --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/2-workload/test_rbd_python.yaml @@ -0,0 +1,11 @@ +meta: +- desc: | + librbd python api tests +workload: + full_sequential: + - workunit: + branch: luminous + clients: + client.0: + - rbd/test_librbd_python.sh + - print: "**** done rbd/test_librbd_python.sh 2-workload" diff --git a/qa/suites/upgrade/luminous-x/parallel/3-upgrade-sequence/.qa b/qa/suites/upgrade/luminous-x/parallel/3-upgrade-sequence/.qa new file mode 120000 index 00000000..a602a035 --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/3-upgrade-sequence/.qa @@ -0,0 +1 @@ +../.qa/
\ No newline at end of file diff --git a/qa/suites/upgrade/luminous-x/parallel/3-upgrade-sequence/upgrade-all.yaml b/qa/suites/upgrade/luminous-x/parallel/3-upgrade-sequence/upgrade-all.yaml new file mode 100644 index 00000000..7fb9829a --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/3-upgrade-sequence/upgrade-all.yaml @@ -0,0 +1,22 @@ +meta: +- desc: | + upgrade the ceph cluster +upgrade-sequence: + sequential: + - ceph.restart: + daemons: [mon.a, mon.b, mon.c, mgr.x] + mon-health-to-clog: false + wait-for-healthy: false + - exec: + mon.a: + - ceph config set global mon_warn_on_msgr2_not_enabled false + - ceph.healthy: + - ceph.restart: + daemons: [osd.0, osd.1, osd.2, osd.3, osd.4, osd.5, osd.6, osd.7, osd.8, osd.9, osd.10, osd.11] + wait-for-healthy: false + wait-for-osds-up: true + - ceph.restart: + daemons: [mds.a] + wait-for-healthy: false + wait-for-osds-up: true + - print: "**** done ceph.restart all" diff --git a/qa/suites/upgrade/luminous-x/parallel/3-upgrade-sequence/upgrade-mon-osd-mds.yaml b/qa/suites/upgrade/luminous-x/parallel/3-upgrade-sequence/upgrade-mon-osd-mds.yaml new file mode 100644 index 00000000..4f9aac75 --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/3-upgrade-sequence/upgrade-mon-osd-mds.yaml @@ -0,0 +1,50 @@ +meta: +- desc: | + upgrade the ceph cluster, + upgrate in two steps + step one ordering: mon.a, osd.0, osd.1, mds.a + step two ordering: mon.b, mon.c, osd.2, osd.3 + ceph expected to be healthy state after each step +upgrade-sequence: + sequential: + - ceph.restart: + daemons: [mon.a] + wait-for-healthy: true + - sleep: + duration: 60 + - ceph.restart: + daemons: [mon.b, mgr.x] + wait-for-healthy: true + mon-health-to-clog: false + - sleep: + duration: 60 + - ceph.restart: + daemons: [mon.c] + wait-for-healthy: false + mon-health-to-clog: false + - exec: + mon.a: + - ceph config set global mon_warn_on_msgr2_not_enabled false + - ceph.healthy: + - sleep: + duration: 60 + - ceph.restart: + daemons: [osd.0, osd.1, osd.2, osd.3] + wait-for-healthy: true + - sleep: + duration: 60 + - ceph.restart: [mds.a] + - sleep: + duration: 60 + - sleep: + duration: 60 + - ceph.restart: + daemons: [osd.4, osd.5, osd.6, osd.7] + wait-for-healthy: true + - sleep: + duration: 60 + - ceph.restart: + daemons: [osd.8, osd.9, osd.10, osd.11] + wait-for-healthy: true + - sleep: + duration: 60 diff --git a/qa/suites/upgrade/luminous-x/parallel/4-msgr2.yaml b/qa/suites/upgrade/luminous-x/parallel/4-msgr2.yaml new file mode 100644 index 00000000..60e3e200 --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/4-msgr2.yaml @@ -0,0 +1,5 @@ +tasks: +- exec: + mon.a: + - ceph mon enable-msgr2 + - ceph config rm global mon_warn_on_msgr2_not_enabled diff --git a/qa/suites/upgrade/luminous-x/parallel/4-nautilus.yaml b/qa/suites/upgrade/luminous-x/parallel/4-nautilus.yaml new file mode 120000 index 00000000..9e99b7d2 --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/4-nautilus.yaml @@ -0,0 +1 @@ +.qa/releases/nautilus.yaml
\ No newline at end of file diff --git a/qa/suites/upgrade/luminous-x/parallel/5-final-workload/+ b/qa/suites/upgrade/luminous-x/parallel/5-final-workload/+ new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/5-final-workload/+ diff --git a/qa/suites/upgrade/luminous-x/parallel/5-final-workload/.qa b/qa/suites/upgrade/luminous-x/parallel/5-final-workload/.qa new file mode 120000 index 00000000..a602a035 --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/5-final-workload/.qa @@ -0,0 +1 @@ +../.qa/
\ No newline at end of file diff --git a/qa/suites/upgrade/luminous-x/parallel/5-final-workload/blogbench.yaml b/qa/suites/upgrade/luminous-x/parallel/5-final-workload/blogbench.yaml new file mode 100644 index 00000000..205f72e8 --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/5-final-workload/blogbench.yaml @@ -0,0 +1,13 @@ +meta: +- desc: | + run a cephfs stress test + mount ceph-fuse on client.3 before running workunit +tasks: +- sequential: + - ceph-fuse: + - print: "**** done ceph-fuse 4-final-workload" + - workunit: + clients: + client.3: + - suites/blogbench.sh + - print: "**** done suites/blogbench.sh 4-final-workload" diff --git a/qa/suites/upgrade/luminous-x/parallel/5-final-workload/rados-snaps-few-objects.yaml b/qa/suites/upgrade/luminous-x/parallel/5-final-workload/rados-snaps-few-objects.yaml new file mode 100644 index 00000000..d8b3dcb3 --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/5-final-workload/rados-snaps-few-objects.yaml @@ -0,0 +1,17 @@ +meta: +- desc: | + randomized correctness test for rados operations on a replicated pool with snapshots +tasks: + - rados: + clients: [client.1] + ops: 4000 + objects: 50 + write_append_excl: false + op_weights: + read: 100 + write: 100 + delete: 50 + snap_create: 50 + snap_remove: 50 + rollback: 50 + - print: "**** done rados 4-final-workload" diff --git a/qa/suites/upgrade/luminous-x/parallel/5-final-workload/rados_loadgenmix.yaml b/qa/suites/upgrade/luminous-x/parallel/5-final-workload/rados_loadgenmix.yaml new file mode 100644 index 00000000..922a9da4 --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/5-final-workload/rados_loadgenmix.yaml @@ -0,0 +1,9 @@ +meta: +- desc: | + generate read/write load with rados objects ranging from 1 byte to 1MB +tasks: + - workunit: + clients: + client.1: + - rados/load-gen-mix.sh + - print: "**** done rados/load-gen-mix.sh 4-final-workload" diff --git a/qa/suites/upgrade/luminous-x/parallel/5-final-workload/rados_mon_thrash.yaml b/qa/suites/upgrade/luminous-x/parallel/5-final-workload/rados_mon_thrash.yaml new file mode 100644 index 00000000..129d1386 --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/5-final-workload/rados_mon_thrash.yaml @@ -0,0 +1,18 @@ +meta: +- desc: | + librados C and C++ api tests +overrides: + ceph: + log-whitelist: + - reached quota + - \(REQUEST_SLOW\) +tasks: + - mon_thrash: + revive_delay: 20 + thrash_delay: 1 + - print: "**** done mon_thrash 4-final-workload" + - workunit: + clients: + client.1: + - rados/test.sh + - print: "**** done rados/test.sh 4-final-workload" diff --git a/qa/suites/upgrade/luminous-x/parallel/5-final-workload/rbd_cls.yaml b/qa/suites/upgrade/luminous-x/parallel/5-final-workload/rbd_cls.yaml new file mode 100644 index 00000000..aaf0a377 --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/5-final-workload/rbd_cls.yaml @@ -0,0 +1,9 @@ +meta: +- desc: | + rbd object class functional tests +tasks: + - workunit: + clients: + client.1: + - cls/test_cls_rbd.sh + - print: "**** done cls/test_cls_rbd.sh 4-final-workload" diff --git a/qa/suites/upgrade/luminous-x/parallel/5-final-workload/rbd_import_export.yaml b/qa/suites/upgrade/luminous-x/parallel/5-final-workload/rbd_import_export.yaml new file mode 100644 index 00000000..46e13550 --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/5-final-workload/rbd_import_export.yaml @@ -0,0 +1,11 @@ +meta: +- desc: | + run basic import/export cli tests for rbd +tasks: + - workunit: + clients: + client.1: + - rbd/import_export.sh + env: + RBD_CREATE_ARGS: --new-format + - print: "**** done rbd/import_export.sh 4-final-workload" diff --git a/qa/suites/upgrade/luminous-x/parallel/5-final-workload/rgw.yaml b/qa/suites/upgrade/luminous-x/parallel/5-final-workload/rgw.yaml new file mode 100644 index 00000000..00855dc5 --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/5-final-workload/rgw.yaml @@ -0,0 +1,8 @@ +overrides: + rgw: + frontend: civetweb +tasks: + - sequential: + - rgw: [client.1] + - print: "**** done rgw 4-final-workload" + - rgw-final-workload diff --git a/qa/suites/upgrade/luminous-x/parallel/5-final-workload/rgw_ragweed_check.yaml b/qa/suites/upgrade/luminous-x/parallel/5-final-workload/rgw_ragweed_check.yaml new file mode 100644 index 00000000..c91d91f6 --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/5-final-workload/rgw_ragweed_check.yaml @@ -0,0 +1,11 @@ +meta: +- desc: | + ragweed check for rgw +rgw-final-workload: + full_sequential: + - ragweed: + client.1: + default-branch: ceph-nautilus + rgw_server: client.1 + stages: check + - print: "**** done ragweed check 4-final-workload" diff --git a/qa/suites/upgrade/luminous-x/parallel/5-final-workload/rgw_swift.yaml b/qa/suites/upgrade/luminous-x/parallel/5-final-workload/rgw_swift.yaml new file mode 100644 index 00000000..e91ccc82 --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/5-final-workload/rgw_swift.yaml @@ -0,0 +1,10 @@ +meta: +- desc: | + swift api tests for rgw +rgw-final-workload: + full_sequential: + - swift: + client.1: + force-branch: ceph-nautilus + rgw_server: client.1 + - print: "**** done swift 4-final-workload" diff --git a/qa/suites/upgrade/luminous-x/parallel/objectstore b/qa/suites/upgrade/luminous-x/parallel/objectstore new file mode 120000 index 00000000..016cbf96 --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/objectstore @@ -0,0 +1 @@ +../stress-split/objectstore/
\ No newline at end of file diff --git a/qa/suites/upgrade/luminous-x/parallel/supported-all-distro b/qa/suites/upgrade/luminous-x/parallel/supported-all-distro new file mode 120000 index 00000000..ca82dde5 --- /dev/null +++ b/qa/suites/upgrade/luminous-x/parallel/supported-all-distro @@ -0,0 +1 @@ +.qa/distros/supported-all-distro
\ No newline at end of file |