Skip to content

Commit

Permalink
Add opclass_owner_is()`.
Browse files Browse the repository at this point in the history
Ref #40.
  • Loading branch information
theory committed Jan 26, 2013
1 parent 0048f4a commit e544477
Show file tree
Hide file tree
Showing 6 changed files with 314 additions and 7 deletions.
1 change: 1 addition & 0 deletions Changes
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Revision history for pgTAP
+ `schema_owner_is()`
+ `index_owner_is()`
+ `language_owner_is()`
+ `opclass_owner_is()`
* Fixed misselling of "constraint" in constraint test diagnostic output.
* Fixed `fk_ok()` so that the table must be visible in the search path when
the schema name is not specified.
Expand Down
54 changes: 49 additions & 5 deletions doc/pgtap.mmd
Original file line number Diff line number Diff line change
Expand Up @@ -5543,15 +5543,15 @@ omitted, an appropriate description will be created. Examples:
);
SELECT foreign_table_owner_is( 'widgets', current_user );

In the event that the test fails because the table in question does not
actually exist or is not visible, you will see an appropriate diagnostic such
as:
In the event that the test fails because the foreign table in question does
not actually exist or is not visible, you will see an appropriate diagnostic
such as:

# Failed test 16: "Foreign table foo should be owned by www"
# Foreign table foo does not exist

If the test fails because the table is not owned by the specified user, the
diagnostics will look something like:
If the test fails because the foreign table is not owned by the specified
user, the diagnostics will look something like:

# Failed test 17: "Foreign table bar should be owned by root"
# have: postgres
Expand Down Expand Up @@ -5686,6 +5686,50 @@ the diagnostics will look something like:
# have: postgres
# want: mats

## `opclass_owner_is ()` ###

SELECT opclass_owner_is ( :schema, :opclass, :user, :description );
SELECT opclass_owner_is ( :opclass, :user, :description );
SELECT opclass_owner_is ( :schema, :opclass, :user );
SELECT opclass_owner_is ( :opclass, :user );

**Parameters**

`:schema`
: Name of a schema in which to find the `:opclass`.

`:opclass`
: Name of an operator class.

`:user`
: Name of a user.

`:description`
: A short description of the test.

Tests the ownership of an operator class. If the `:description` argument is
omitted, an appropriate description will be created. Examples:

SELECT opclass_owner_is(
'pg_catalog', 'int4_ops', 'postgres',
'Operator class int4_ops should be owned by postgres'
);
SELECT opclass_owner_is( 'my_ops', current_user );

In the event that the test fails because the operator class in question does
not actually exist or is not visible, you will see an appropriate diagnostic
such as:

# Failed test 16: "operator class foo should be owned by www"
# operator class foo does not exist

If the test fails because the operator class is not owned by the specified
user, the diagnostics will look something like:

# Failed test 17: "operator class bar should be owned by root"
# have: postgres
# want: root

Prvileged Access
----------------

Expand Down
71 changes: 71 additions & 0 deletions sql/pgtap--0.92.0--0.93.0.sql
Original file line number Diff line number Diff line change
Expand Up @@ -504,3 +504,74 @@ RETURNS TEXT AS $$
'Language ' || quote_ident($1) || ' should be owned by ' || quote_ident($2)
);
$$ LANGUAGE sql;

CREATE OR REPLACE FUNCTION _get_opclass_owner ( NAME, NAME )
RETURNS NAME AS $$
SELECT pg_catalog.pg_get_userbyid(opcowner)
FROM pg_catalog.pg_opclass oc
JOIN pg_catalog.pg_namespace n ON oc.opcnamespace = n.oid
WHERE n.nspname = $1
AND opcname = $2;
$$ LANGUAGE SQL;

CREATE OR REPLACE FUNCTION _get_opclass_owner ( NAME )
RETURNS NAME AS $$
SELECT pg_catalog.pg_get_userbyid(opcowner)
FROM pg_catalog.pg_opclass
WHERE opcname = $1
AND pg_opclass_is_visible(oid);
$$ LANGUAGE SQL;

-- opclass_owner_is( schema, opclass, user, description )
CREATE OR REPLACE FUNCTION opclass_owner_is ( NAME, NAME, NAME, TEXT )
RETURNS TEXT AS $$
DECLARE
owner NAME := _get_opclass_owner($1, $2);
BEGIN
-- Make sure the opclass exists.
IF owner IS NULL THEN
RETURN ok(FALSE, $4) || E'\n' || diag(
E' Operator class ' || quote_ident($1) || '.' || quote_ident($2)
|| ' not found'
);
END IF;

RETURN is(owner, $3, $4);
END;
$$ LANGUAGE plpgsql;

-- opclass_owner_is( schema, opclass, user )
CREATE OR REPLACE FUNCTION opclass_owner_is( NAME, NAME, NAME )
RETURNS TEXT AS $$
SELECT opclass_owner_is(
$1, $2, $3,
'Operator class ' || quote_ident($1) || '.' || quote_ident($2) ||
' should be owned by ' || quote_ident($3)
);
$$ LANGUAGE sql;

-- opclass_owner_is( opclass, user, description )
CREATE OR REPLACE FUNCTION opclass_owner_is ( NAME, NAME, TEXT )
RETURNS TEXT AS $$
DECLARE
owner NAME := _get_opclass_owner($1);
BEGIN
-- Make sure the opclass exists.
IF owner IS NULL THEN
RETURN ok(FALSE, $3) || E'\n' || diag(
E' Operator class ' || quote_ident($1) || ' not found'
);
END IF;

RETURN is(owner, $2, $3);
END;
$$ LANGUAGE plpgsql;

-- opclass_owner_is( opclass, user )
CREATE OR REPLACE FUNCTION opclass_owner_is( NAME, NAME )
RETURNS TEXT AS $$
SELECT opclass_owner_is(
$1, $2,
'Operator class ' || quote_ident($1) || ' should be owned by ' || quote_ident($2)
);
$$ LANGUAGE sql;
71 changes: 71 additions & 0 deletions sql/pgtap.sql.in
Original file line number Diff line number Diff line change
Expand Up @@ -8090,6 +8090,77 @@ RETURNS TEXT AS $$
);
$$ LANGUAGE sql;

CREATE OR REPLACE FUNCTION _get_opclass_owner ( NAME, NAME )
RETURNS NAME AS $$
SELECT pg_catalog.pg_get_userbyid(opcowner)
FROM pg_catalog.pg_opclass oc
JOIN pg_catalog.pg_namespace n ON oc.opcnamespace = n.oid
WHERE n.nspname = $1
AND opcname = $2;
$$ LANGUAGE SQL;

CREATE OR REPLACE FUNCTION _get_opclass_owner ( NAME )
RETURNS NAME AS $$
SELECT pg_catalog.pg_get_userbyid(opcowner)
FROM pg_catalog.pg_opclass
WHERE opcname = $1
AND pg_opclass_is_visible(oid);
$$ LANGUAGE SQL;

-- opclass_owner_is( schema, opclass, user, description )
CREATE OR REPLACE FUNCTION opclass_owner_is ( NAME, NAME, NAME, TEXT )
RETURNS TEXT AS $$
DECLARE
owner NAME := _get_opclass_owner($1, $2);
BEGIN
-- Make sure the opclass exists.
IF owner IS NULL THEN
RETURN ok(FALSE, $4) || E'\n' || diag(
E' Operator class ' || quote_ident($1) || '.' || quote_ident($2)
|| ' not found'
);
END IF;

RETURN is(owner, $3, $4);
END;
$$ LANGUAGE plpgsql;

-- opclass_owner_is( schema, opclass, user )
CREATE OR REPLACE FUNCTION opclass_owner_is( NAME, NAME, NAME )
RETURNS TEXT AS $$
SELECT opclass_owner_is(
$1, $2, $3,
'Operator class ' || quote_ident($1) || '.' || quote_ident($2) ||
' should be owned by ' || quote_ident($3)
);
$$ LANGUAGE sql;

-- opclass_owner_is( opclass, user, description )
CREATE OR REPLACE FUNCTION opclass_owner_is ( NAME, NAME, TEXT )
RETURNS TEXT AS $$
DECLARE
owner NAME := _get_opclass_owner($1);
BEGIN
-- Make sure the opclass exists.
IF owner IS NULL THEN
RETURN ok(FALSE, $3) || E'\n' || diag(
E' Operator class ' || quote_ident($1) || ' not found'
);
END IF;

RETURN is(owner, $2, $3);
END;
$$ LANGUAGE plpgsql;

-- opclass_owner_is( opclass, user )
CREATE OR REPLACE FUNCTION opclass_owner_is( NAME, NAME )
RETURNS TEXT AS $$
SELECT opclass_owner_is(
$1, $2,
'Operator class ' || quote_ident($1) || ' should be owned by ' || quote_ident($2)
);
$$ LANGUAGE sql;

CREATE OR REPLACE FUNCTION _assets_are ( text, text[], text[], TEXT )
RETURNS TEXT AS $$
SELECT _areni(
Expand Down
29 changes: 28 additions & 1 deletion test/expected/ownership.out
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
\unset ECHO
1..300
1..327
ok 1 - db_owner_is(db, user, desc) should pass
ok 2 - db_owner_is(db, user, desc) should have the proper description
ok 3 - db_owner_is(db, user, desc) should have the proper diagnostics
Expand Down Expand Up @@ -300,3 +300,30 @@ ok 297 - language_owner_is(non-language, user) should have the proper diagnostic
ok 298 - language_owner_is(language, non-user) should fail
ok 299 - language_owner_is(language, non-user) should have the proper description
ok 300 - language_owner_is(language, non-user) should have the proper diagnostics
ok 301 - opclass_owner_is(schema, opclass, user, desc) should pass
ok 302 - opclass_owner_is(schema, opclass, user, desc) should have the proper description
ok 303 - opclass_owner_is(schema, opclass, user, desc) should have the proper diagnostics
ok 304 - opclass_owner_is(schema, opclass, user) should pass
ok 305 - opclass_owner_is(schema, opclass, user) should have the proper description
ok 306 - opclass_owner_is(schema, opclass, user) should have the proper diagnostics
ok 307 - opclass_owner_is(non-schema, opclass, user, desc) should fail
ok 308 - opclass_owner_is(non-schema, opclass, user, desc) should have the proper description
ok 309 - opclass_owner_is(non-schema, opclass, user, desc) should have the proper diagnostics
ok 310 - opclass_owner_is(schema, not-opclass, user, desc) should fail
ok 311 - opclass_owner_is(schema, not-opclass, user, desc) should have the proper description
ok 312 - opclass_owner_is(schema, not-opclass, user, desc) should have the proper diagnostics
ok 313 - opclass_owner_is(schema, opclass, non-user, desc) should fail
ok 314 - opclass_owner_is(schema, opclass, non-user, desc) should have the proper description
ok 315 - opclass_owner_is(schema, opclass, non-user, desc) should have the proper diagnostics
ok 316 - opclass_owner_is(opclass, user, desc) should pass
ok 317 - opclass_owner_is(opclass, user, desc) should have the proper description
ok 318 - opclass_owner_is(opclass, user, desc) should have the proper diagnostics
ok 319 - opclass_owner_is(opclass, user) should pass
ok 320 - opclass_owner_is(opclass, user) should have the proper description
ok 321 - opclass_owner_is(opclass, user) should have the proper diagnostics
ok 322 - opclass_owner_is(non-opclass, user, desc) should fail
ok 323 - opclass_owner_is(non-opclass, user, desc) should have the proper description
ok 324 - opclass_owner_is(non-opclass, user, desc) should have the proper diagnostics
ok 325 - opclass_owner_is(opclass, non-user, desc) should fail
ok 326 - opclass_owner_is(opclass, non-user, desc) should have the proper description
ok 327 - opclass_owner_is(opclass, non-user, desc) should have the proper diagnostics
95 changes: 94 additions & 1 deletion test/sql/ownership.sql
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
\unset ECHO
\i test/setup.sql

SELECT plan(300);
SELECT plan(327);
--SELECT * FROM no_plan();

-- This will be rolled back. :-)
Expand Down Expand Up @@ -967,6 +967,99 @@ SELECT * FROM check_test(
want: __not__' || _get_language_owner('plpgsql')
);

/****************************************************************************/
-- Test opclass_owner_is().
SELECT * FROM check_test(
opclass_owner_is(
'pg_catalog', 'int4_ops',
_get_opclass_owner('pg_catalog', 'int4_ops'),
'mumble'
),
true,
'opclass_owner_is(schema, opclass, user, desc)',
'mumble',
''
);

SELECT * FROM check_test(
opclass_owner_is(
'pg_catalog', 'int4_ops',
_get_opclass_owner('pg_catalog', 'int4_ops')
),
true,
'opclass_owner_is(schema, opclass, user)',
'Operator class pg_catalog.int4_ops should be owned by ' || _get_opclass_owner('pg_catalog', 'int4_ops'),
''
);

SELECT * FROM check_test(
opclass_owner_is(
'not_pg_catalog', 'int4_ops',
_get_opclass_owner('pg_catalog', 'int4_ops'),
'mumble'
),
false,
'opclass_owner_is(non-schema, opclass, user, desc)',
'mumble',
' Operator class not_pg_catalog.int4_ops not found'
);

SELECT * FROM check_test(
opclass_owner_is(
'pg_catalog', 'int4_nots',
_get_opclass_owner('pg_catalog', 'int4_ops'),
'mumble'
),
false,
'opclass_owner_is(schema, not-opclass, user, desc)',
'mumble',
' Operator class pg_catalog.int4_nots not found'
);

SELECT * FROM check_test(
opclass_owner_is(
'pg_catalog', 'int4_ops', '__no-one', 'mumble'
),
false,
'opclass_owner_is(schema, opclass, non-user, desc)',
'mumble',
' have: ' || _get_opclass_owner('pg_catalog', 'int4_ops') || '
want: __no-one'
);

SELECT * FROM check_test(
opclass_owner_is('int4_ops', _get_opclass_owner('int4_ops'), 'mumble'),
true,
'opclass_owner_is(opclass, user, desc)',
'mumble',
''
);

SELECT * FROM check_test(
opclass_owner_is('int4_ops', _get_opclass_owner('int4_ops')),
true,
'opclass_owner_is(opclass, user)',
'Operator class int4_ops should be owned by ' || _get_opclass_owner('int4_ops'),
''
);

SELECT * FROM check_test(
opclass_owner_is('int4_nots', _get_opclass_owner('int4_ops'), 'mumble'),
false,
'opclass_owner_is(non-opclass, user, desc)',
'mumble',
' Operator class int4_nots not found'
);

SELECT * FROM check_test(
opclass_owner_is('int4_ops', '__no-one', 'mumble'),
false,
'opclass_owner_is(opclass, non-user, desc)',
'mumble',
' have: ' || _get_opclass_owner('int4_ops') || '
want: __no-one'
);

/****************************************************************************/
-- Finish the tests and clean up.
SELECT * FROM finish();
Expand Down

0 comments on commit e544477

Please sign in to comment.